Remove FieldsUnmarshaler and FieldsMarshaler

This commit is contained in:
Tnze
2023-04-27 01:27:41 +08:00
parent 078aaba156
commit e435ab18f7
4 changed files with 51 additions and 64 deletions

View File

@ -44,7 +44,7 @@ func (e *Encoder) Encode(v any, tagName string) error {
} }
func (e *Encoder) marshal(val reflect.Value, tagType byte, tagName string) error { func (e *Encoder) marshal(val reflect.Value, tagType byte, tagName string) error {
if err := e.writeTag(tagType, tagName); err != nil { if err := writeTag(e.w, tagType, tagName); err != nil {
return err return err
} }
if val.CanInterface() { if val.CanInterface() {
@ -75,18 +75,18 @@ func (e *Encoder) writeValue(val reflect.Value, tagType byte) error {
} }
return err return err
case TagShort: case TagShort:
return e.writeInt16(int16(val.Int())) return writeInt16(e.w, int16(val.Int()))
case TagInt: case TagInt:
return e.writeInt32(int32(val.Int())) return writeInt32(e.w, int32(val.Int()))
case TagFloat: case TagFloat:
return e.writeInt32(int32(math.Float32bits(float32(val.Float())))) return writeInt32(e.w, int32(math.Float32bits(float32(val.Float()))))
case TagLong: case TagLong:
return e.writeInt64(val.Int()) return writeInt64(e.w, val.Int())
case TagDouble: case TagDouble:
return e.writeInt64(int64(math.Float64bits(val.Float()))) return writeInt64(e.w, int64(math.Float64bits(val.Float())))
case TagByteArray, TagIntArray, TagLongArray: case TagByteArray, TagIntArray, TagLongArray:
n := val.Len() n := val.Len()
if err := e.writeInt32(int32(n)); err != nil { if err := writeInt32(e.w, int32(n)); err != nil {
return err return err
} }
@ -126,9 +126,9 @@ func (e *Encoder) writeValue(val reflect.Value, tagType byte) error {
return errors.New("value typed " + elem.Type().String() + "is not allowed in Tag 0x" + strconv.FormatUint(uint64(tagType), 16)) return errors.New("value typed " + elem.Type().String() + "is not allowed in Tag 0x" + strconv.FormatUint(uint64(tagType), 16))
} }
if tagType == TagIntArray { if tagType == TagIntArray {
err = e.writeInt32(int32(v)) err = writeInt32(e.w, int32(v))
} else if tagType == TagLongArray { } else if tagType == TagLongArray {
err = e.writeInt64(v) err = writeInt64(e.w, v)
} }
if err != nil { if err != nil {
return err return err
@ -168,7 +168,7 @@ func (e *Encoder) writeValue(val reflect.Value, tagType byte) error {
} else { } else {
str = []byte(val.String()) str = []byte(val.String())
} }
if err := e.writeInt16(int16(len(str))); err != nil { if err := writeInt16(e.w, int16(len(str))); err != nil {
return err return err
} }
_, err := e.w.Write(str) _, err := e.w.Write(str)
@ -334,15 +334,15 @@ func getTagTypeByType(vk reflect.Type) byte {
} }
} }
func (e *Encoder) writeTag(tagType byte, tagName string) error { func writeTag(w io.Writer, tagType byte, tagName string) error {
if _, err := e.w.Write([]byte{tagType}); err != nil { if _, err := w.Write([]byte{tagType}); err != nil {
return err return err
} }
bName := []byte(tagName) bName := []byte(tagName)
if err := e.writeInt16(int16(len(bName))); err != nil { if err := writeInt16(w, int16(len(bName))); err != nil {
return err return err
} }
_, err := e.w.Write(bName) _, err := w.Write(bName)
return err return err
} }
@ -351,24 +351,24 @@ func (e *Encoder) writeListHeader(elementType byte, n int) (err error) {
return return
} }
// Write length of strings // Write length of strings
if err = e.writeInt32(int32(n)); err != nil { if err = writeInt32(e.w, int32(n)); err != nil {
return return
} }
return nil return nil
} }
func (e *Encoder) writeInt16(n int16) error { func writeInt16(w io.Writer, n int16) error {
_, err := e.w.Write([]byte{byte(n >> 8), byte(n)}) _, err := w.Write([]byte{byte(n >> 8), byte(n)})
return err return err
} }
func (e *Encoder) writeInt32(n int32) error { func writeInt32(w io.Writer, n int32) error {
_, err := e.w.Write([]byte{byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n)}) _, err := w.Write([]byte{byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n)})
return err return err
} }
func (e *Encoder) writeInt64(n int64) error { func writeInt64(w io.Writer, n int64) error {
_, err := e.w.Write([]byte{ _, err := w.Write([]byte{
byte(n >> 56), byte(n >> 48), byte(n >> 40), byte(n >> 32), byte(n >> 56), byte(n >> 48), byte(n >> 40), byte(n >> 32),
byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n), byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n),
}) })

View File

@ -10,16 +10,3 @@ type Marshaler interface {
TagType() byte TagType() byte
MarshalNBT(w io.Writer) error MarshalNBT(w io.Writer) error
} }
// FieldsUnmarshaler is a type can hold many Tags just like a TagCompound.
//
// If and only if a type which implements this interface is used as an anonymous field of a struct,
// and didn't set a struct tag, the content it holds will be considered as in the outer struct.
type FieldsUnmarshaler interface {
UnmarshalField(tagType byte, tagName string, r DecoderReader) (ok bool, err error)
}
// FieldsMarshaler is similar to FieldsUnmarshaler, but for marshaling.
type FieldsMarshaler interface {
MarshalFields(w io.Writer) (ok bool, err error)
}

View File

@ -44,10 +44,10 @@ func (m *RawMessage) UnmarshalNBT(tagType byte, r DecoderReader) error {
return nil return nil
} }
// String convert the data into the SNBT(Stringified NBT) format. // String converts the data into the SNBT(Stringified NBT) format.
// The output is valid for using in in-game command. // The output is valid for using in in-game command.
// Expect two exceptions: // Expect two exceptions:
// - Empty string "" if there is only an TagEnd in the NBT (aka: []byte{0}). // - Empty string "" if there is only a TagEnd in the NBT (aka: []byte{0}).
// - "<Invalid: $Err>" if the content is not valid NBT data. // - "<Invalid: $Err>" if the content is not valid NBT data.
func (m RawMessage) String() string { func (m RawMessage) String() string {
if m.Type == TagEnd { if m.Type == TagEnd {

View File

@ -16,7 +16,7 @@ type decodeState struct {
const phasePanicMsg = "SNBT decoder out of sync - data changing underfoot?" const phasePanicMsg = "SNBT decoder out of sync - data changing underfoot?"
func writeValue(e *Encoder, d *decodeState, writeTag bool, tagName string) error { func writeValue(e *Encoder, d *decodeState, ifWriteTag bool, tagName string) error {
d.scanWhile(scanSkipSpace) d.scanWhile(scanSkipSpace)
switch d.opcode { switch d.opcode {
case scanError: case scanError:
@ -34,23 +34,23 @@ func writeValue(e *Encoder, d *decodeState, writeTag bool, tagName string) error
if err != nil { if err != nil {
return err return err
} }
if writeTag { if ifWriteTag {
if err := e.writeTag(tagType, tagName); err != nil { if err := writeTag(e.w, tagType, tagName); err != nil {
return err return err
} }
} }
return writeLiteralPayload(e, litVal) return writeLiteralPayload(e, litVal)
case scanBeginCompound: case scanBeginCompound:
if writeTag { if ifWriteTag {
if err := e.writeTag(TagCompound, tagName); err != nil { if err := writeTag(e.w, TagCompound, tagName); err != nil {
return err return err
} }
} }
return writeCompoundPayload(e, d) return writeCompoundPayload(e, d)
case scanBeginList: case scanBeginList:
_, err := writeListOrArray(e, d, writeTag, tagName) _, err := writeListOrArray(e, d, ifWriteTag, tagName)
return err return err
} }
} }
@ -59,7 +59,7 @@ func writeLiteralPayload(e *Encoder, v any) (err error) {
switch v.(type) { switch v.(type) {
case string: case string:
str := v.(string) str := v.(string)
err = e.writeInt16(int16(len(str))) err = writeInt16(e.w, int16(len(str)))
if err != nil { if err != nil {
return return
} }
@ -67,15 +67,15 @@ func writeLiteralPayload(e *Encoder, v any) (err error) {
case int8: case int8:
_, err = e.w.Write([]byte{byte(v.(int8))}) _, err = e.w.Write([]byte{byte(v.(int8))})
case int16: case int16:
err = e.writeInt16(v.(int16)) err = writeInt16(e.w, v.(int16))
case int32: case int32:
err = e.writeInt32(v.(int32)) err = writeInt32(e.w, v.(int32))
case int64: case int64:
err = e.writeInt64(v.(int64)) err = writeInt64(e.w, v.(int64))
case float32: case float32:
err = e.writeInt32(int32(math.Float32bits(v.(float32)))) err = writeInt32(e.w, int32(math.Float32bits(v.(float32))))
case float64: case float64:
err = e.writeInt64(int64(math.Float64bits(v.(float64)))) err = writeInt64(e.w, int64(math.Float64bits(v.(float64))))
} }
return return
} }
@ -139,11 +139,11 @@ func writeCompoundPayload(e *Encoder, d *decodeState) error {
return err return err
} }
func writeListOrArray(e *Encoder, d *decodeState, writeTag bool, tagName string) (tagType byte, err error) { func writeListOrArray(e *Encoder, d *decodeState, ifWriteTag bool, tagName string) (tagType byte, err error) {
d.scanWhile(scanSkipSpace) d.scanWhile(scanSkipSpace)
if d.opcode == scanEndValue { // ']', empty TAG_List if d.opcode == scanEndValue { // ']', empty TAG_List
if writeTag { if ifWriteTag {
err = e.writeTag(TagList, tagName) err = writeTag(e.w, TagList, tagName)
if err != nil { if err != nil {
return tagType, err return tagType, err
} }
@ -187,8 +187,8 @@ func writeListOrArray(e *Encoder, d *decodeState, writeTag bool, tagName string)
default: default:
return TagList, d.error("unknown Array type") return TagList, d.error("unknown Array type")
} }
if writeTag { if ifWriteTag {
err = e.writeTag(tagType, tagName) err = writeTag(e.w, tagType, tagName)
if err != nil { if err != nil {
return tagType, err return tagType, err
} }
@ -199,8 +199,8 @@ func writeListOrArray(e *Encoder, d *decodeState, writeTag bool, tagName string)
} }
break break
} }
if writeTag { if ifWriteTag {
err = e.writeTag(TagList, tagName) err = writeTag(e.w, TagList, tagName)
if err != nil { if err != nil {
return tagType, err return tagType, err
} }
@ -254,8 +254,8 @@ func writeListOrArray(e *Encoder, d *decodeState, writeTag bool, tagName string)
return tagType, err return tagType, err
} }
case scanBeginList: // TAG_List<TAG_List> case scanBeginList: // TAG_List<TAG_List>
if writeTag { if ifWriteTag {
err = e.writeTag(TagList, tagName) err = writeTag(e.w, TagList, tagName)
if err != nil { if err != nil {
return tagType, err return tagType, err
} }
@ -297,8 +297,8 @@ func writeListOrArray(e *Encoder, d *decodeState, writeTag bool, tagName string)
return return
} }
case scanBeginCompound: // TAG_List<TAG_Compound> case scanBeginCompound: // TAG_List<TAG_Compound>
if writeTag { if ifWriteTag {
err = e.writeTag(TagList, tagName) err = writeTag(e.w, TagList, tagName)
if err != nil { if err != nil {
return tagType, err return tagType, err
} }
@ -354,7 +354,7 @@ func writeArray(e, e2 *Encoder, d *decodeState, elemType byte, count *int, buf *
d.scanWhile(scanSkipSpace) // ; d.scanWhile(scanSkipSpace) // ;
if d.opcode == scanEndValue { // ] if d.opcode == scanEndValue { // ]
// empty array // empty array
if err = e.writeInt32(0); err != nil { if err = writeInt32(e.w, 0); err != nil {
return return
} }
return return
@ -386,9 +386,9 @@ func writeArray(e, e2 *Encoder, d *decodeState, elemType byte, count *int, buf *
case TagByte: case TagByte:
_, err = e2.w.Write([]byte{byte(litVal.(int8))}) _, err = e2.w.Write([]byte{byte(litVal.(int8))})
case TagInt: case TagInt:
err = e2.writeInt32(litVal.(int32)) err = writeInt32(e2.w, litVal.(int32))
case TagLong: case TagLong:
err = e2.writeInt64(litVal.(int64)) err = writeInt64(e2.w, litVal.(int64))
} }
if err != nil { if err != nil {
return return
@ -410,7 +410,7 @@ func writeArray(e, e2 *Encoder, d *decodeState, elemType byte, count *int, buf *
d.scanWhile(scanSkipSpace) // , d.scanWhile(scanSkipSpace) // ,
} }
if err = e.writeInt32(int32(*count)); err != nil { if err = writeInt32(e.w, int32(*count)); err != nil {
return err return err
} }
_, err = e.w.Write(buf.Bytes()) _, err = e.w.Write(buf.Bytes())
@ -453,7 +453,7 @@ func (d *decodeState) scanWhile(op int) {
// parseLiteral parse an SNBT literal, might be // parseLiteral parse an SNBT literal, might be
// TAG_String, TAG_Int, TAG_Float, ... etc. // TAG_String, TAG_Int, TAG_Float, ... etc.
// so returned value is one of string, int32, float32 ... // so the returned value is one of string, int32, float32 ...
func parseLiteral(literal []byte) (byte, any, error) { func parseLiteral(literal []byte) (byte, any, error) {
switch literal[0] { switch literal[0] {
case '"', '\'': // Quoted String case '"', '\'': // Quoted String