func toUTF16(data []byte) ([]uint16, error) { if len(data) < 2 { return []uint16{}, nil } if len(data)%2 > 0 { // TODO: if this is UTF-16 BE then this is likely encoded wrong data = append(data, 0) } var bo binary.ByteOrder if data[0] == 0xFF && data[1] == 0xFE { // UTF-16 LE bo = binary.LittleEndian } else if data[0] == 0xFE && data[1] == 0xFF { // UTF-16 BE bo = binary.BigEndian } else { return []uint16{}, nil } s := make([]uint16, 0, len(data)/2) for i := 2; i < len(data); i += 2 { s = append(s, bo.Uint16(data[i:i+2])) } return s, nil }
// ReadUInt32 reads a uint32 from r. func ReadUInt32(r io.Reader, byteOrder binary.ByteOrder) (uint32, error) { var buf [4]byte if _, err := io.ReadFull(r, buf[:]); err != nil { return 0, err } return byteOrder.Uint32(buf[:]), nil }
func ReadFloat32(buf []byte, format byte, endianness binary.ByteOrder) float32 { encoding := format & EncodingMask if encoding == EncodingFloatingPoint { return math.Float32frombits(endianness.Uint32(buf)) } else { offset := 0 if endianness == binary.LittleEndian { offset = len(buf) - 1 } var neg byte = 0 if encoding == EncodingSignedInt && buf[offset]&(1<<7) != 0 { neg = 0xFF } tmp := []byte{neg, neg, neg, neg} if endianness == binary.BigEndian { copy(tmp[4-len(buf):], buf) } else { copy(tmp, buf) } sample := endianness.Uint32(tmp) div := math.Pow(2, float64(len(buf)*8-1)) if encoding == EncodingSignedInt { return float32(float64(int32(sample)) / div) } else { return float32(float64(sample)/div - 1.0) } } }
// PutUint64 serializes the provided uint64 using the given byte order into a // buffer from the free list and writes the resulting eight bytes to the given // writer. func (l binaryFreeList) PutUint64(w io.Writer, byteOrder binary.ByteOrder, val uint64) error { buf := l.Borrow()[:8] byteOrder.PutUint64(buf, val) _, err := w.Write(buf) l.Return(buf) return err }
// Open a CDataFile func OpenRawDataFile(name string, readOnly bool, byteOrder binary.ByteOrder, byteAlignment uint64, valueSize int) (*RawDataFile, error) { flag := os.O_RDWR if readOnly { flag = os.O_RDONLY } file, err := os.OpenFile(name, flag, 0644) if err != nil { return nil, err } var univalToBytes func([]byte, unival) var bytesToUnival func([]byte) unival switch valueSize { case 8: univalToBytes = func(dst []byte, src unival) { byteOrder.PutUint64(dst, src.AsUnsignedLong()) } bytesToUnival = func(src []byte) unival { return unival(byteOrder.Uint64(src)) } default: return nil, errors.Errorf("Invalid value size %d", valueSize) } return &RawDataFile{ file: file, // byteOrder: byteOrder, byteAlignment: byteAlignment, valueSize: valueSize, univalToBytes: univalToBytes, bytesToUnival: bytesToUnival, }, nil }
func NewNullFrame(data []byte, byteOrder binary.ByteOrder) (*NullFrame, error) { if len(data) < NULL_FRAME_HEADER_LENGTH { return nil, errors.New(fmt.Sprintf("required at least %d bytes of data.", NULL_FRAME_HEADER_LENGTH)) } return &NullFrame{byteOrder.Uint32(data), data[4:]}, nil }
func durationToBytes(d time.Duration, order binary.ByteOrder) []byte { buf := make([]byte, 8) nsec := d.Nanoseconds() order.PutUint32(buf, uint32(nsec/nanosPerSec)) order.PutUint32(buf[4:], uint32(nsec%nanosPerSec)) return buf }
func packParamString(bin binary.ByteOrder, s string) []byte { b := make([]byte, (4+len(s)+1+3) & ^0x3) // must be 32-bit aligned bin.PutUint32(b[0:], uint32(len(s)+1)) copy(b[4:], []byte(s)) b[4+len(s)] = 0 return b }
func decodeUTF16(b []byte, bo binary.ByteOrder) string { s := make([]uint16, 0, len(b)/2) for i := 0; i < len(b); i += 2 { s = append(s, bo.Uint16(b[i:i+2])) } return string(utf16.Decode(s)) }
func (b *Buffer) ReadUint32(order binary.ByteOrder) (uint32, error) { if b.readPos >= len(b.Buf)-4 { return 0, io.EOF } u := order.Uint32(b.Buf[b.readPos:]) b.readPos += 4 return u, nil }
func (b *Buffer) ReadUint16(order binary.ByteOrder) (uint16, error) { if b.readPos >= len(b.buf)-2 { return 0, io.EOF } u := order.Uint16(b.buf[b.readPos:]) b.readPos += 2 return u, nil }
func benchUpdate(b *testing.B, e binary.ByteOrder) *Trie { trie := newEmpty() k := make([]byte, 32) for i := 0; i < b.N; i++ { e.PutUint64(k, uint64(i)) trie.Update(k, k) } return trie }
func newQosHistoryFromBytes(bin binary.ByteOrder, b []byte) (qosHistory, error) { if len(b) < 4+4 { return qosHistory{}, io.EOF } return qosHistory{ kind: bin.Uint32(b[0:]), depth: bin.Uint32(b[4:]), }, nil }
func timeFromBytes(order binary.ByteOrder, b []byte) (time.Time, error) { if len(b) < 8 { return timeInvalid, io.EOF } sec := int64(order.Uint32(b[0:])) frac := int64(order.Uint32(b[4:])) return time.Unix(sec, (frac*nanosPerSec)>>32).UTC(), nil }
func parseUtf16(strBytes []byte, bo binary.ByteOrder) (string, error) { shorts := make([]uint16, 0, len(strBytes)/2) for i := 0; i < len(strBytes); i += 2 { short := bo.Uint16(strBytes[i : i+2]) shorts = append(shorts, short) } return string(utf16.Decode(shorts)), nil }
func timeToBytes(t time.Time, order binary.ByteOrder) []byte { sec := uint32(t.Unix()) frac := uint32((nanosPerSec - 1 + (int64(t.Nanosecond()) << 32)) / nanosPerSec) b := make([]byte, 8) order.PutUint32(b[0:], sec) order.PutUint32(b[4:], frac) return b }
func UTF16ToUTF8String(b []byte, o binary.ByteOrder) dna.String { utf := make([]uint16, (len(b)+(2-1))/2) for i := 0; i+(2-1) < len(b); i += 2 { utf[i/2] = o.Uint16(b[i:]) } if len(b)/2 < len(utf) { utf[len(utf)-1] = utf8.RuneError } return dna.String(string(utf16.Decode(utf))) }
func durationFromBytes(order binary.ByteOrder, b []byte) (time.Duration, error) { if len(b) < 8 { return time.Duration(0), io.EOF } sec := order.Uint32(b[0:]) nsec := order.Uint32(b[4:]) return time.Duration(sec*nanosPerSec + nsec), nil }
func makeGuid(b []byte, order binary.ByteOrder) Guid { g := Guid{ DataA: order.Uint32(b[:4]), DataB: order.Uint16(b[4:6]), DataC: order.Uint16(b[6:8]), DataD: [8]byte{}, } copy(g.DataD[:], b[8:]) return g }
func rvalSRational(in []byte, bo binary.ByteOrder) reflect.Value { denom := int64(int32(bo.Uint32(in[4:]))) if denom == 0 { // Prevent panics due to poorly written Rational fields with a // denominator of 0. Their usable value would likely be 0. return reflect.New(reflect.TypeOf(big.Rat{})) } numer := int64(int32(bo.Uint32(in))) return reflect.ValueOf(big.NewRat(numer, denom)) }
// Uint16 reads two bytes from the provided reader using a buffer from the // free list, converts it to a number using the provided byte order, and returns // the resulting uint16. func (l binaryFreeList) Uint16(r io.Reader, byteOrder binary.ByteOrder) (uint16, error) { buf := l.Borrow()[:2] if _, err := io.ReadFull(r, buf); err != nil { l.Return(buf) return 0, err } rv := byteOrder.Uint16(buf) l.Return(buf) return rv, nil }
func newUDPv4LocFromBytes(bin binary.ByteOrder, b []byte) (locator, error) { if len(b) < 4+4+16 { return locator{}, io.EOF } return locator{ kind: int32(bin.Uint32(b[0:])), port: bin.Uint32(b[4:]), addr: net.IPv4(b[20], b[21], b[22], b[23]), // xxx: ipv6 support }, nil }
func newParamListItemFromBytes(bin binary.ByteOrder, b []byte) (*paramListItem, error) { sz := bin.Uint16(b[2:]) if len(b) < int(sz+4) { return nil, io.EOF } return ¶mListItem{ pid: paramID(bin.Uint16(b[0:])), value: b[4 : 4+sz], }, nil }
func parseOptions(data []byte, byteOrder binary.ByteOrder) (*RawOptions, error) { if len(data) == 0 { return nil, nil } var options *RawOptions curData := data for { // // Read code + length // if len(curData) < 4 { return nil, io.ErrUnexpectedEOF } optionCode := OptionCode(byteOrder.Uint16(curData[:2])) optionLen := byteOrder.Uint16(curData[2:4]) if optionCode == OPTION_CODE_END_OF_OPT { break } curData = curData[4:] // // read value // if len(curData) < int(optionLen) { return nil, io.ErrUnexpectedEOF } optionValue := curData[:optionLen] // // check if this is new option // if options == nil { v := make(RawOptions) options = &v } optionValueArray, ok := (*options)[optionCode] if !ok { optionValueArray = make([]OptionValue, 0) (*options)[optionCode] = optionValueArray } (*options)[optionCode] = append(optionValueArray, optionValue) boundary := alignUint16(optionLen) curData = curData[boundary:] } return options, nil }
func (p *paramListItem) valToString(bin binary.ByteOrder) (string, error) { if len(p.value) < 4 { return "", io.EOF } sz := int(bin.Uint32(p.value[0:])) if len(p.value) < 4+sz { return "", io.EOF } // encoded with null terminator, strip that out return string(p.value[4 : 4+sz-1]), nil }
func newIPv6Address(byteOrder binary.ByteOrder, data []byte) IPv6Address { return IPv6Address{ byteOrder.Uint16(data[0:2]), byteOrder.Uint16(data[2:4]), byteOrder.Uint16(data[4:6]), byteOrder.Uint16(data[6:8]), byteOrder.Uint16(data[8:10]), byteOrder.Uint16(data[10:12]), byteOrder.Uint16(data[12:14]), byteOrder.Uint16(data[14:16]), } }
func walksymtab(data []byte, ptrsz int, fn func(sym) error) error { var order binary.ByteOrder = binary.BigEndian var s sym p := data for len(p) >= 4 { // Symbol type, value. if len(p) < ptrsz { return &formatError{len(data), "unexpected EOF", nil} } // fixed-width value if ptrsz == 8 { s.value = order.Uint64(p[0:8]) p = p[8:] } else { s.value = uint64(order.Uint32(p[0:4])) p = p[4:] } var typ byte typ = p[0] & 0x7F s.typ = typ p = p[1:] // Name. var i int var nnul int for i = 0; i < len(p); i++ { if p[i] == 0 { nnul = 1 break } } switch typ { case 'z', 'Z': p = p[i+nnul:] for i = 0; i+2 <= len(p); i += 2 { if p[i] == 0 && p[i+1] == 0 { nnul = 2 break } } } if len(p) < i+nnul { return &formatError{len(data), "unexpected EOF", nil} } s.name = p[0:i] i += nnul p = p[i:] fn(s) } return nil }
// decodeTag assumes len(buf) >= 8 func decodeTag(buf []byte, bo binary.ByteOrder) tag { var t tag smallTag := bo.Uint32(buf[:]) t.dataType = dataType(smallTag) t.smallFormat = (smallTag >> 16) != 0 if t.smallFormat == true { t.nBytes = uint32(smallTag >> 16) } else { t.nBytes = bo.Uint32(buf[4:]) } return t }
func newQosReliabilityFromBytes(bin binary.ByteOrder, b []byte) (qosReliability, error) { if len(b) < 4+4+4 { return qosReliability{}, io.EOF } dur, err := durationFromBytes(bin, b[4:]) if err != nil { return qosReliability{}, err } return qosReliability{ kind: bin.Uint32(b[0:]), maxBlockingTime: dur, }, nil }
func benchHash(b *testing.B, e binary.ByteOrder) { trie := newEmpty() k := make([]byte, 32) for i := 0; i < benchElemCount; i++ { e.PutUint64(k, uint64(i)) trie.Update(k, k) } b.ResetTimer() for i := 0; i < b.N; i++ { trie.Hash() } }