-
Notifications
You must be signed in to change notification settings - Fork 0
/
nbt.go
105 lines (94 loc) · 1.91 KB
/
nbt.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package nbt
import (
"compress/gzip"
"compress/zlib"
"errors"
"io"
)
type tagID byte
const (
TagEnd tagID = iota
TagByte
TagShort
TagInt
TagLong
TagFloat
TagDouble
TagByteArray
TagString
TagList
TagCompound
TagIntArray
TagLongArray
)
type Compound map[string]interface{}
type List []interface{}
// readFunc describes a function which can decode nbt payload
type readFunc func(io.Reader) (interface{}, error)
type writeFunc func(io.Writer) error
func readFuncFactory(id tagID) readFunc {
switch id {
case TagEnd:
return nil
case TagByte:
return readByte
case TagShort:
return readShort
case TagInt:
return readInt
case TagLong:
return readLong
case TagFloat:
return readFloat
case TagDouble:
return readDouble
case TagByteArray:
return readByteArray
case TagString:
return readString
case TagIntArray:
return readIntArray
case TagLongArray:
return readLongArray
case TagCompound:
return readCompound
case TagList:
return readList
default:
return nil
}
}
// Parse parses nbt from io.Reader
func Parse(r io.Reader) (out Compound, err error) {
v, err := readByte(r)
id := tagID(v.(byte))
if id != TagCompound {
return nil, errors.New("nbt isn't contained in compound")
}
// we use compoundWrapRead because every nbt file is implicitly inside one
v, err = compoundWrapRead(readCompound)(r)
if v == nil {
return nil, errors.New("parse: v can't be nil")
}
v = v.(compoundField).value
if v == nil {
return nil, errors.New("parse: v can't be nil")
}
return v.(Compound), err
}
// ParseGzip parses a gzip compressed nbt input stream
func ParseGzip(r io.Reader) (out Compound, err error) {
gr, err := gzip.NewReader(r)
if err != nil {
return nil, err
}
return Parse(gr)
}
// ParseGzip parses a zlib compressed nbt input stream
func ParseZlib(r io.Reader) (out Compound, err error) {
zr, err := zlib.NewReader(r)
if err != nil {
return nil, err
}
return Parse(zr)
}