func (cOff chunkOffTs) readPreChunk(r io.ReadSeeker) (*preChunk, error) { pc := preChunk{ts: cOff.ts} if _, err := r.Seek(cOff.offset, 0); err != nil { return nil, err } lr := io.LimitReader(r, cOff.size) var length uint32 if err := binary.Read(lr, binary.BigEndian, &length); err != nil { return nil, err } lr = io.LimitReader(lr, int64(length)) compType, err := kagus.ReadByte(lr) if err != nil { return nil, err } pc.compression = compType buf := new(bytes.Buffer) if _, err := io.Copy(buf, lr); err != nil { return nil, err } pc.data = buf.Bytes() return &pc, err }
// ReadNamedTag reads a named Tag from an io.Reader. It returns the Tag, the tags Name and an error. func ReadNamedTag(r io.Reader) (Tag, string, error) { _tt, err := kagus.ReadByte(r) if err != nil { return Tag{}, "", err } tt := TagType(_tt) if tt == TAG_End { return Tag{Type: tt}, "", nil } name, err := readTagData(r, TAG_String) if err != nil { return Tag{}, "", err } td, err := readTagData(r, tt) return Tag{Type: tt, Payload: td}, name.(string), err }
func (sur *SimpleUnitReader) ReadUnit() (UnitType, interface{}, error) { r := sur.r sur.mu.Lock() doUnlock := true defer func() { if doUnlock { sur.mu.Unlock() } }() _ut, err := kagus.ReadByte(r) if err != nil { return 0, nil, err } ut := UnitType(_ut) switch ut { case UTNil: return ut, nil, nil case UTRequest, UTAnswer, UTEvent: var code uint16 if err := binary.Read(r, binary.LittleEndian, &code); err != nil { return ut, nil, err } return ut, code, nil case UTBin: var l uint32 if err := binary.Read(r, binary.LittleEndian, &l); err != nil { return ut, nil, err } buf := make([]byte, l) _, err := io.ReadFull(r, buf) if err != nil { return ut, nil, err } return ut, buf, nil case UTNumber: var n int64 if err := binary.Read(r, binary.LittleEndian, &n); err != nil { return ut, nil, err } return ut, n, nil case UTList, UTTextKVMap, UTIdKVMap: return ut, nil, nil case UTUKey, UTByte: k, err := kagus.ReadByte(r) return ut, k, err case UTBinStream: doUnlock = false return ut, &BinstreamReader{r: r, surMu: sur.mu}, nil case UTTerm: return ut, nil, nil case UTBool: _b, err := kagus.ReadByte(r) b := true if _b == 0 { b = false } return ut, b, err } return ut, nil, UnknownUnit }
func readTagData(r io.Reader, tt TagType) (interface{}, error) { switch tt { case TAG_End: case TAG_Byte: var v uint8 err := binary.Read(r, binary.BigEndian, &v) return v, err case TAG_Short: var v int16 err := binary.Read(r, binary.BigEndian, &v) return v, err case TAG_Int: var v int32 err := binary.Read(r, binary.BigEndian, &v) return v, err case TAG_Long: var v int64 err := binary.Read(r, binary.BigEndian, &v) return v, err case TAG_Float: var v float32 err := binary.Read(r, binary.BigEndian, &v) return v, err case TAG_Double: var v float64 err := binary.Read(r, binary.BigEndian, &v) return v, err case TAG_Byte_Array: var l int32 if err := binary.Read(r, binary.BigEndian, &l); err != nil { return nil, err } if l < 0 { return nil, errors.New("Byte array has negative length?") } data := make([]byte, l) _, err := io.ReadFull(r, data) return data, err case TAG_String: var l int16 if err := binary.Read(r, binary.BigEndian, &l); err != nil { return nil, err } if l < 0 { return nil, errors.New("String has negative length?") } data := make([]byte, l) _, err := io.ReadFull(r, data) return string(data), err case TAG_List: _ltt, err := kagus.ReadByte(r) if err != nil { return nil, err } ltt := TagType(_ltt) var l int32 if err := binary.Read(r, binary.BigEndian, &l); err != nil { return nil, err } if l < 0 { return nil, errors.New("List has negative length?") } tl := TagList{Type: ltt, Elems: make([]interface{}, l)} for i := 0; i < int(l); i++ { if tl.Elems[i], err = readTagData(r, ltt); err != nil { return nil, err } } return tl, nil case TAG_Compound: comp := make(TagCompound) for { tag, name, err := ReadNamedTag(r) if err != nil { return nil, err } if tag.Type == TAG_End { break } comp[name] = tag } return comp, nil case TAG_Int_Array: var l int32 if err := binary.Read(r, binary.BigEndian, &l); err != nil { return nil, err } if l < 0 { return nil, errors.New("Int Array has negative length?") } data := make([]int32, l) for i := 0; i < int(l); i++ { var e int32 if err := binary.Read(r, binary.BigEndian, &e); err != nil { return nil, err } data[i] = e } return data, nil } return nil, errors.New("Unknown tag type") }