mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	
		
			
				
	
	
		
			114 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // +build 386 amd64,!appengine
 | |
| 
 | |
| package roaring
 | |
| 
 | |
| import (
 | |
| 	"io"
 | |
| 	"reflect"
 | |
| 	"unsafe"
 | |
| )
 | |
| 
 | |
| func (ac *arrayContainer) writeTo(stream io.Writer) (int, error) {
 | |
| 	buf := uint16SliceAsByteSlice(ac.content)
 | |
| 	return stream.Write(buf)
 | |
| }
 | |
| 
 | |
| func (bc *bitmapContainer) writeTo(stream io.Writer) (int, error) {
 | |
| 	buf := uint64SliceAsByteSlice(bc.bitmap)
 | |
| 	return stream.Write(buf)
 | |
| }
 | |
| 
 | |
| // readFrom reads an arrayContainer from stream.
 | |
| // PRE-REQUISITE: you must size the arrayContainer correctly (allocate b.content)
 | |
| // *before* you call readFrom. We can't guess the size in the stream
 | |
| // by this point.
 | |
| func (ac *arrayContainer) readFrom(stream io.Reader) (int, error) {
 | |
| 	buf := uint16SliceAsByteSlice(ac.content)
 | |
| 	return io.ReadFull(stream, buf)
 | |
| }
 | |
| 
 | |
| func (bc *bitmapContainer) readFrom(stream io.Reader) (int, error) {
 | |
| 	buf := uint64SliceAsByteSlice(bc.bitmap)
 | |
| 	n, err := io.ReadFull(stream, buf)
 | |
| 	bc.computeCardinality()
 | |
| 	return n, err
 | |
| }
 | |
| 
 | |
| func uint64SliceAsByteSlice(slice []uint64) []byte {
 | |
| 	// make a new slice header
 | |
| 	header := *(*reflect.SliceHeader)(unsafe.Pointer(&slice))
 | |
| 
 | |
| 	// update its capacity and length
 | |
| 	header.Len *= 8
 | |
| 	header.Cap *= 8
 | |
| 
 | |
| 	// return it
 | |
| 	return *(*[]byte)(unsafe.Pointer(&header))
 | |
| }
 | |
| 
 | |
| func uint16SliceAsByteSlice(slice []uint16) []byte {
 | |
| 	// make a new slice header
 | |
| 	header := *(*reflect.SliceHeader)(unsafe.Pointer(&slice))
 | |
| 
 | |
| 	// update its capacity and length
 | |
| 	header.Len *= 2
 | |
| 	header.Cap *= 2
 | |
| 
 | |
| 	// return it
 | |
| 	return *(*[]byte)(unsafe.Pointer(&header))
 | |
| }
 | |
| 
 | |
| func (bc *bitmapContainer) asLittleEndianByteSlice() []byte {
 | |
| 	return uint64SliceAsByteSlice(bc.bitmap)
 | |
| }
 | |
| 
 | |
| // Deserialization code follows
 | |
| 
 | |
| func byteSliceAsUint16Slice(slice []byte) []uint16 {
 | |
| 	if len(slice)%2 != 0 {
 | |
| 		panic("Slice size should be divisible by 2")
 | |
| 	}
 | |
| 
 | |
| 	// make a new slice header
 | |
| 	header := *(*reflect.SliceHeader)(unsafe.Pointer(&slice))
 | |
| 
 | |
| 	// update its capacity and length
 | |
| 	header.Len /= 2
 | |
| 	header.Cap /= 2
 | |
| 
 | |
| 	// return it
 | |
| 	return *(*[]uint16)(unsafe.Pointer(&header))
 | |
| }
 | |
| 
 | |
| func byteSliceAsUint64Slice(slice []byte) []uint64 {
 | |
| 	if len(slice)%8 != 0 {
 | |
| 		panic("Slice size should be divisible by 8")
 | |
| 	}
 | |
| 
 | |
| 	// make a new slice header
 | |
| 	header := *(*reflect.SliceHeader)(unsafe.Pointer(&slice))
 | |
| 
 | |
| 	// update its capacity and length
 | |
| 	header.Len /= 8
 | |
| 	header.Cap /= 8
 | |
| 
 | |
| 	// return it
 | |
| 	return *(*[]uint64)(unsafe.Pointer(&header))
 | |
| }
 | |
| 
 | |
| func byteSliceAsInterval16Slice(slice []byte) []interval16 {
 | |
| 	if len(slice)%4 != 0 {
 | |
| 		panic("Slice size should be divisible by 4")
 | |
| 	}
 | |
| 
 | |
| 	// make a new slice header
 | |
| 	header := *(*reflect.SliceHeader)(unsafe.Pointer(&slice))
 | |
| 
 | |
| 	// update its capacity and length
 | |
| 	header.Len /= 4
 | |
| 	header.Cap /= 4
 | |
| 
 | |
| 	// return it
 | |
| 	return *(*[]interval16)(unsafe.Pointer(&header))
 | |
| }
 |