1 package nbt 2 3 import ( 4 "io" 5 6 "vimagination.zapto.org/byteio" 7 ) 8 9 // Decoder is a type used to decode NBT streams 10 type Decoder struct { 11 r byteio.EndianReader 12 } 13 14 // NewDecoder returns a Decoder using Big Endian 15 func NewDecoder(r io.Reader) Decoder { 16 return NewDecoderEndian(&byteio.BigEndianReader{Reader: r}) 17 } 18 19 // NewDecoderEndian allows you to specify your own Endian Reader 20 func NewDecoderEndian(e byteio.EndianReader) Decoder { 21 return Decoder{r: e} 22 } 23 24 // Decode will eencode a single tag from the reader using the default settings 25 func Decode(r io.Reader) (Tag, error) { 26 return NewDecoder(r).Decode() 27 } 28 29 // Decode will read a whole tag out of the decoding stream 30 func (d Decoder) Decode() (Tag, error) { 31 t, _, err := d.r.ReadUint8() 32 if err != nil { 33 err = ReadError{"named TagId", err} 34 return Tag{}, err 35 } 36 tagID := TagID(t) 37 if tagID == TagEnd { 38 return Tag{data: end{}}, nil 39 } 40 n, err := d.decodeString() 41 if err != nil { 42 return Tag{}, ReadError{"name", err} 43 } 44 data, err := d.decodeData(tagID) 45 if err != nil { 46 return Tag{}, err 47 } 48 return Tag{name: string(n), data: data}, nil 49 } 50 51 func (d Decoder) decodeData(tagID TagID) (Data, error) { 52 var ( 53 data Data 54 err error 55 ) 56 switch tagID { 57 case TagByte: 58 data, err = d.decodeByte() 59 case TagShort: 60 data, err = d.decodeShort() 61 case TagInt: 62 data, err = d.decodeInt() 63 case TagLong: 64 data, err = d.decodeLong() 65 case TagFloat: 66 data, err = d.decodeFloat() 67 case TagDouble: 68 data, err = d.decodeDouble() 69 case TagByteArray: 70 data, err = d.decodeByteArray() 71 case TagString: 72 data, err = d.decodeString() 73 case TagList: 74 data, err = d.decodeList() 75 case TagCompound: 76 data, err = d.decodeCompound() 77 case TagIntArray: 78 data, err = d.decodeIntArray() 79 case TagBool: 80 data, err = d.decodeBool() 81 case TagUint8: 82 data, err = d.decodeUint8() 83 case TagUint16: 84 data, err = d.decodeUint16() 85 case TagUint32: 86 data, err = d.decodeUint32() 87 case TagUint64: 88 data, err = d.decodeUint64() 89 case TagComplex64: 90 data, err = d.decodeComplex64() 91 case TagComplex128: 92 data, err = d.decodeComplex128() 93 default: 94 err = UnknownTag{tagID} 95 } 96 if err != nil { 97 if _, ok := err.(ReadError); !ok { 98 err = ReadError{tagID.String(), err} 99 } 100 return nil, err 101 } 102 return data, nil 103 } 104 105 // DecodeByte will read a single Byte Data 106 func (d Decoder) decodeByte() (Byte, error) { 107 b, _, err := d.r.ReadInt8() 108 return Byte(b), err 109 } 110 111 // DecodeShort will read a single Short Data 112 func (d Decoder) decodeShort() (Short, error) { 113 s, _, err := d.r.ReadInt16() 114 return Short(s), err 115 } 116 117 // DecodeInt will read a single Int Data 118 func (d Decoder) decodeInt() (Int, error) { 119 i, _, err := d.r.ReadInt32() 120 return Int(i), err 121 } 122 123 // DecodeLong will read a single Long Data 124 func (d Decoder) decodeLong() (Long, error) { 125 l, _, err := d.r.ReadInt64() 126 return Long(l), err 127 } 128 129 // DecodeFloat will read a single Float Data 130 func (d Decoder) decodeFloat() (Float, error) { 131 f, _, err := d.r.ReadFloat32() 132 return Float(f), err 133 } 134 135 // DecodeDouble will read a single Double Data 136 func (d Decoder) decodeDouble() (Double, error) { 137 do, _, err := d.r.ReadFloat64() 138 return Double(do), err 139 } 140 141 // DecodeByteArray will read a ByteArray Data 142 func (d Decoder) decodeByteArray() (ByteArray, error) { 143 l, _, err := d.r.ReadUint32() 144 if err != nil { 145 return nil, err 146 } 147 data := make(ByteArray, l) 148 err = data.readFrom(d.r) 149 if err != nil { 150 return nil, err 151 } 152 return data, nil 153 } 154 155 // DecodeString will read a String Data 156 func (d Decoder) decodeString() (String, error) { 157 str, _, err := d.r.ReadString16() 158 return String(str), err 159 } 160 161 // DecodeList will read a List Data 162 func (d Decoder) decodeList() (List, error) { 163 t, _, err := d.r.ReadUint8() 164 if err != nil { 165 return nil, err 166 } 167 tagID := TagID(t) 168 length, _, err := d.r.ReadUint32() 169 if err != nil { 170 return nil, err 171 } 172 l := newListWithLength(tagID, length) 173 var data Data 174 for i := uint32(0); i < length; i++ { 175 data, err = d.decodeData(tagID) 176 if err != nil { 177 return nil, err 178 } 179 l.Append(data) 180 } 181 return l, nil 182 } 183 184 // DecodeCompound will read a Compound Data 185 func (d Decoder) decodeCompound() (Compound, error) { 186 data := make(Compound, 0) 187 for { 188 t, err := d.Decode() 189 if err != nil { 190 return nil, err 191 } 192 if t.TagID() == TagEnd { 193 break 194 } 195 data = append(data, t) 196 } 197 return data, nil 198 } 199 200 // DecodeIntArray will read an IntArray Data 201 func (d Decoder) decodeIntArray() (IntArray, error) { 202 l, _, err := d.r.ReadUint32() 203 if err != nil { 204 return nil, err 205 } 206 ints := make(IntArray, l) 207 for i := uint32(0); i < l; i++ { 208 ints[i], _, err = d.r.ReadInt32() 209 if err != nil { 210 return nil, err 211 } 212 } 213 return ints, nil 214 } 215 216 func (d Decoder) decodeBool() (Bool, error) { 217 b, _, err := d.r.ReadUint8() 218 return b == 1, err 219 } 220 221 func (d Decoder) decodeUint8() (Uint8, error) { 222 u, _, err := d.r.ReadUint8() 223 if err != nil { 224 return 0, err 225 } 226 return Uint8(u), err 227 } 228 229 func (d Decoder) decodeUint16() (Uint16, error) { 230 u, _, err := d.r.ReadUint16() 231 if err != nil { 232 return 0, err 233 } 234 return Uint16(u), err 235 } 236 237 func (d Decoder) decodeUint32() (Uint32, error) { 238 u, _, err := d.r.ReadUint32() 239 if err != nil { 240 return 0, err 241 } 242 return Uint32(u), err 243 } 244 245 func (d Decoder) decodeUint64() (Uint64, error) { 246 u, _, err := d.r.ReadUint64() 247 if err != nil { 248 return 0, err 249 } 250 return Uint64(u), err 251 } 252 253 func (d Decoder) decodeComplex64() (Complex64, error) { 254 r, _, err := d.r.ReadFloat32() 255 if err != nil { 256 return 0, err 257 } 258 i, _, err := d.r.ReadFloat32() 259 if err != nil { 260 return 0, err 261 } 262 return Complex64(complex(r, i)), nil 263 } 264 265 func (d Decoder) decodeComplex128() (Complex128, error) { 266 r, _, err := d.r.ReadFloat64() 267 if err != nil { 268 return 0, err 269 } 270 i, _, err := d.r.ReadFloat64() 271 if err != nil { 272 return 0, err 273 } 274 return Complex128(complex(r, i)), nil 275 } 276