Skip to content

Commit 9d7a78e

Browse files
authored
Merge pull request #48 from shamaton/fix_ext
Fix calcuration size of Ext format
2 parents 8b38235 + af3ecf2 commit 9d7a78e

23 files changed

Lines changed: 612 additions & 240 deletions

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2024 Masayuki Shamoto
3+
Copyright (c) 2025 Masayuki Shamoto
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Renaming fields via `msgpack:"field_name"`
1212
* Omitting fields via `msgpack:"-"`
1313
* Omitting empty fields via `msgpack:"field_name,omitempty"`
14-
* Supports extend encoder / decoder
14+
* Supports extend encoder / decoder [(example)](./msgpack_example_test.go)
1515
* Can also Encoding / Decoding struct as array
1616

1717
## Installation

ext/decode.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,56 @@ import (
66
"github.com/shamaton/msgpack/v2/def"
77
)
88

9+
// Decoder defines an interface for decoding values from bytes.
10+
// It provides methods to get the decoder type, check if the data matches the type,
11+
// and convert the data into a Go value.
912
type Decoder interface {
13+
// Code returns the unique code representing the decoder type.
1014
Code() int8
15+
16+
// IsType checks if the data at the given offset matches the expected type.
17+
// Returns true if the type matches, false otherwise.
1118
IsType(offset int, d *[]byte) bool
19+
20+
// AsValue decodes the data at the given offset into a Go value of the specified kind.
21+
// Returns the decoded value, the new offset, and an error if decoding fails.
1222
AsValue(offset int, k reflect.Kind, d *[]byte) (interface{}, int, error)
1323
}
1424

25+
// DecoderCommon provides common utility methods for decoding data from bytes.
1526
type DecoderCommon struct {
1627
}
1728

29+
// ReadSize1 reads a single byte from the given index in the byte slice.
30+
// Returns the byte and the new index after reading.
1831
func (cd *DecoderCommon) ReadSize1(index int, d *[]byte) (byte, int) {
1932
rb := def.Byte1
2033
return (*d)[index], index + rb
2134
}
2235

36+
// ReadSize2 reads two bytes from the given index in the byte slice.
37+
// Returns the bytes as a slice and the new index after reading.
2338
func (cd *DecoderCommon) ReadSize2(index int, d *[]byte) ([]byte, int) {
2439
rb := def.Byte2
2540
return (*d)[index : index+rb], index + rb
2641
}
2742

43+
// ReadSize4 reads four bytes from the given index in the byte slice.
44+
// Returns the bytes as a slice and the new index after reading.
2845
func (cd *DecoderCommon) ReadSize4(index int, d *[]byte) ([]byte, int) {
2946
rb := def.Byte4
3047
return (*d)[index : index+rb], index + rb
3148
}
3249

50+
// ReadSize8 reads eight bytes from the given index in the byte slice.
51+
// Returns the bytes as a slice and the new index after reading.
3352
func (cd *DecoderCommon) ReadSize8(index int, d *[]byte) ([]byte, int) {
3453
rb := def.Byte8
3554
return (*d)[index : index+rb], index + rb
3655
}
3756

57+
// ReadSizeN reads a specified number of bytes (n) from the given index in the byte slice.
58+
// Returns the bytes as a slice and the new index after reading.
3859
func (cd *DecoderCommon) ReadSizeN(index, n int, d *[]byte) ([]byte, int) {
3960
return (*d)[index : index+n], index + n
4061
}

ext/decoder_stream.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,19 @@ import (
44
"reflect"
55
)
66

7+
// StreamDecoder defines an interface for decoding streams of data.
8+
// It provides methods to retrieve the decoder's code, check type compatibility,
9+
// and convert raw data into a Go value of a specified kind.
710
type StreamDecoder interface {
11+
// Code returns the unique identifier for the decoder.
812
Code() int8
13+
14+
// IsType checks if the provided code, inner type, and data length match the expected type.
15+
// Returns true if the type matches, otherwise false.
916
IsType(code byte, innerType int8, dataLength int) bool
17+
18+
// ToValue converts the raw data into a Go value of the specified kind.
19+
// Takes the code, raw data, and the target kind as input.
20+
// Returns the decoded value or an error if the conversion fails.
1021
ToValue(code byte, data []byte, k reflect.Kind) (any, error)
1122
}

ext/encode.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,48 @@ import (
44
"reflect"
55
)
66

7+
// Encoder defines an interface for encoding values into bytes.
8+
// It provides methods to get the encoding type, calculate the byte size of a value,
9+
// and write the encoded value into a byte slice.
710
type Encoder interface {
11+
// Code returns the unique code representing the encoder type.
812
Code() int8
13+
14+
// Type returns the reflect.Type of the value that the encoder handles.
915
Type() reflect.Type
16+
17+
// CalcByteSize calculates the number of bytes required to encode the given value.
18+
// Returns the size and an error if the calculation fails.
1019
CalcByteSize(value reflect.Value) (int, error)
20+
21+
// WriteToBytes encodes the given value into a byte slice starting at the specified offset.
22+
// Returns the new offset after writing the bytes.
1123
WriteToBytes(value reflect.Value, offset int, bytes *[]byte) int
1224
}
1325

26+
// EncoderCommon provides utility methods for encoding various types of values into bytes.
27+
// It includes methods to encode integers and unsigned integers of different sizes,
28+
// as well as methods to write raw byte slices into a target byte slice.
1429
type EncoderCommon struct {
1530
}
1631

32+
// SetByte1Int64 encodes a single byte from the given int64 value into the byte slice at the specified offset.
33+
// Returns the new offset after writing the byte.
1734
func (c *EncoderCommon) SetByte1Int64(value int64, offset int, d *[]byte) int {
1835
(*d)[offset] = byte(value)
1936
return offset + 1
2037
}
2138

39+
// SetByte2Int64 encodes the lower two bytes of the given int64 value into the byte slice at the specified offset.
40+
// Returns the new offset after writing the bytes.
2241
func (c *EncoderCommon) SetByte2Int64(value int64, offset int, d *[]byte) int {
2342
(*d)[offset+0] = byte(value >> 8)
2443
(*d)[offset+1] = byte(value)
2544
return offset + 2
2645
}
2746

47+
// SetByte4Int64 encodes the lower four bytes of the given int64 value into the byte slice at the specified offset.
48+
// Returns the new offset after writing the bytes.
2849
func (c *EncoderCommon) SetByte4Int64(value int64, offset int, d *[]byte) int {
2950
(*d)[offset+0] = byte(value >> 24)
3051
(*d)[offset+1] = byte(value >> 16)
@@ -33,6 +54,8 @@ func (c *EncoderCommon) SetByte4Int64(value int64, offset int, d *[]byte) int {
3354
return offset + 4
3455
}
3556

57+
// SetByte8Int64 encodes all eight bytes of the given int64 value into the byte slice at the specified offset.
58+
// Returns the new offset after writing the bytes.
3659
func (c *EncoderCommon) SetByte8Int64(value int64, offset int, d *[]byte) int {
3760
(*d)[offset] = byte(value >> 56)
3861
(*d)[offset+1] = byte(value >> 48)
@@ -45,17 +68,23 @@ func (c *EncoderCommon) SetByte8Int64(value int64, offset int, d *[]byte) int {
4568
return offset + 8
4669
}
4770

71+
// SetByte1Uint64 encodes a single byte from the given uint64 value into the byte slice at the specified offset.
72+
// Returns the new offset after writing the byte.
4873
func (c *EncoderCommon) SetByte1Uint64(value uint64, offset int, d *[]byte) int {
4974
(*d)[offset] = byte(value)
5075
return offset + 1
5176
}
5277

78+
// SetByte2Uint64 encodes the lower two bytes of the given uint64 value into the byte slice at the specified offset.
79+
// Returns the new offset after writing the bytes.
5380
func (c *EncoderCommon) SetByte2Uint64(value uint64, offset int, d *[]byte) int {
5481
(*d)[offset] = byte(value >> 8)
5582
(*d)[offset+1] = byte(value)
5683
return offset + 2
5784
}
5885

86+
// SetByte4Uint64 encodes the lower four bytes of the given uint64 value into the byte slice at the specified offset.
87+
// Returns the new offset after writing the bytes.
5988
func (c *EncoderCommon) SetByte4Uint64(value uint64, offset int, d *[]byte) int {
6089
(*d)[offset] = byte(value >> 24)
6190
(*d)[offset+1] = byte(value >> 16)
@@ -64,6 +93,8 @@ func (c *EncoderCommon) SetByte4Uint64(value uint64, offset int, d *[]byte) int
6493
return offset + 4
6594
}
6695

96+
// SetByte8Uint64 encodes all eight bytes of the given uint64 value into the byte slice at the specified offset.
97+
// Returns the new offset after writing the bytes.
6798
func (c *EncoderCommon) SetByte8Uint64(value uint64, offset int, d *[]byte) int {
6899
(*d)[offset] = byte(value >> 56)
69100
(*d)[offset+1] = byte(value >> 48)
@@ -76,17 +107,23 @@ func (c *EncoderCommon) SetByte8Uint64(value uint64, offset int, d *[]byte) int
76107
return offset + 8
77108
}
78109

110+
// SetByte1Int encodes a single byte from the given int value into the byte slice at the specified offset.
111+
// Returns the new offset after writing the byte.
79112
func (c *EncoderCommon) SetByte1Int(code, offset int, d *[]byte) int {
80113
(*d)[offset] = byte(code)
81114
return offset + 1
82115
}
83116

117+
// SetByte2Int encodes the lower two bytes of the given int value into the byte slice at the specified offset.
118+
// Returns the new offset after writing the bytes.
84119
func (c *EncoderCommon) SetByte2Int(value int, offset int, d *[]byte) int {
85120
(*d)[offset] = byte(value >> 8)
86121
(*d)[offset+1] = byte(value)
87122
return offset + 2
88123
}
89124

125+
// SetByte4Int encodes the lower four bytes of the given int value into the byte slice at the specified offset.
126+
// Returns the new offset after writing the bytes.
90127
func (c *EncoderCommon) SetByte4Int(value int, offset int, d *[]byte) int {
91128
(*d)[offset] = byte(value >> 24)
92129
(*d)[offset+1] = byte(value >> 16)
@@ -95,6 +132,8 @@ func (c *EncoderCommon) SetByte4Int(value int, offset int, d *[]byte) int {
95132
return offset + 4
96133
}
97134

135+
// SetByte4Uint32 encodes the lower four bytes of the given uint32 value into the byte slice at the specified offset.
136+
// Returns the new offset after writing the bytes.
98137
func (c *EncoderCommon) SetByte4Uint32(value uint32, offset int, d *[]byte) int {
99138
(*d)[offset] = byte(value >> 24)
100139
(*d)[offset+1] = byte(value >> 16)
@@ -103,6 +142,8 @@ func (c *EncoderCommon) SetByte4Uint32(value uint32, offset int, d *[]byte) int
103142
return offset + 4
104143
}
105144

145+
// SetBytes writes the given byte slice `bs` into the target byte slice at the specified offset.
146+
// Returns the new offset after writing the bytes.
106147
func (c *EncoderCommon) SetBytes(bs []byte, offset int, d *[]byte) int {
107148
for i := range bs {
108149
(*d)[offset+i] = bs[i]

ext/encode_stream.go

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,45 @@ import (
77
"github.com/shamaton/msgpack/v2/internal/common"
88
)
99

10-
// StreamEncoder is interface that extended encoder should implement
10+
// StreamEncoder is an interface that extended encoders should implement.
11+
// It defines methods for encoding data into a stream.
1112
type StreamEncoder interface {
13+
// Code returns the unique code for the encoder.
1214
Code() int8
15+
// Type returns the reflect.Type of the value being encoded.
1316
Type() reflect.Type
17+
// Write encodes the given value and writes it to the provided StreamWriter.
1418
Write(w StreamWriter, value reflect.Value) error
1519
}
1620

17-
// StreamWriter is provided some writing functions for extended format by user
21+
// StreamWriter provides methods for writing data in extended formats.
22+
// It wraps an io.Writer and a buffer for efficient writing.
1823
type StreamWriter struct {
19-
w io.Writer
20-
buf *common.Buffer
24+
w io.Writer // The underlying writer to write data to.
25+
buf *common.Buffer // A buffer used for temporary storage during writing.
2126
}
2227

28+
// CreateStreamWriter creates and returns a new StreamWriter instance.
2329
func CreateStreamWriter(w io.Writer, buf *common.Buffer) StreamWriter {
2430
return StreamWriter{w, buf}
2531
}
2632

33+
// WriteByte1Int64 writes a single byte representation of an int64 value.
2734
func (w *StreamWriter) WriteByte1Int64(value int64) error {
2835
return w.buf.Write(w.w,
2936
byte(value),
3037
)
3138
}
3239

40+
// WriteByte2Int64 writes a two-byte representation of an int64 value.
3341
func (w *StreamWriter) WriteByte2Int64(value int64) error {
3442
return w.buf.Write(w.w,
3543
byte(value>>8),
3644
byte(value),
3745
)
3846
}
3947

48+
// WriteByte4Int64 writes a four-byte representation of an int64 value.
4049
func (w *StreamWriter) WriteByte4Int64(value int64) error {
4150
return w.buf.Write(w.w,
4251
byte(value>>24),
@@ -46,6 +55,7 @@ func (w *StreamWriter) WriteByte4Int64(value int64) error {
4655
)
4756
}
4857

58+
// WriteByte8Int64 writes an eight-byte representation of an int64 value.
4959
func (w *StreamWriter) WriteByte8Int64(value int64) error {
5060
return w.buf.Write(w.w,
5161
byte(value>>56),
@@ -59,19 +69,22 @@ func (w *StreamWriter) WriteByte8Int64(value int64) error {
5969
)
6070
}
6171

72+
// WriteByte1Uint64 writes a single byte representation of a uint64 value.
6273
func (w *StreamWriter) WriteByte1Uint64(value uint64) error {
6374
return w.buf.Write(w.w,
6475
byte(value),
6576
)
6677
}
6778

79+
// WriteByte2Uint64 writes a two-byte representation of a uint64 value.
6880
func (w *StreamWriter) WriteByte2Uint64(value uint64) error {
6981
return w.buf.Write(w.w,
7082
byte(value>>8),
7183
byte(value),
7284
)
7385
}
7486

87+
// WriteByte4Uint64 writes a four-byte representation of a uint64 value.
7588
func (w *StreamWriter) WriteByte4Uint64(value uint64) error {
7689
return w.buf.Write(w.w,
7790
byte(value>>24),
@@ -81,6 +94,7 @@ func (w *StreamWriter) WriteByte4Uint64(value uint64) error {
8194
)
8295
}
8396

97+
// WriteByte8Uint64 writes an eight-byte representation of a uint64 value.
8498
func (w *StreamWriter) WriteByte8Uint64(value uint64) error {
8599
return w.buf.Write(w.w,
86100
byte(value>>56),
@@ -94,19 +108,22 @@ func (w *StreamWriter) WriteByte8Uint64(value uint64) error {
94108
)
95109
}
96110

111+
// WriteByte1Int writes a single byte representation of an int value.
97112
func (w *StreamWriter) WriteByte1Int(value int) error {
98113
return w.buf.Write(w.w,
99114
byte(value),
100115
)
101116
}
102117

118+
// WriteByte2Int writes a two-byte representation of an int value.
103119
func (w *StreamWriter) WriteByte2Int(value int) error {
104120
return w.buf.Write(w.w,
105121
byte(value>>8),
106122
byte(value),
107123
)
108124
}
109125

126+
// WriteByte4Int writes a four-byte representation of an int value.
110127
func (w *StreamWriter) WriteByte4Int(value int) error {
111128
return w.buf.Write(w.w,
112129
byte(value>>24),
@@ -116,6 +133,7 @@ func (w *StreamWriter) WriteByte4Int(value int) error {
116133
)
117134
}
118135

136+
// WriteByte4Uint32 writes a four-byte representation of a uint32 value.
119137
func (w *StreamWriter) WriteByte4Uint32(value uint32) error {
120138
return w.buf.Write(w.w,
121139
byte(value>>24),
@@ -125,6 +143,7 @@ func (w *StreamWriter) WriteByte4Uint32(value uint32) error {
125143
)
126144
}
127145

146+
// WriteBytes writes a slice of bytes to the underlying writer.
128147
func (w *StreamWriter) WriteBytes(bs []byte) error {
129148
return w.buf.Write(w.w, bs...)
130149
}

internal/encoding/byte.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ func (e *encoder) isByteSlice(rv reflect.Value) bool {
1616

1717
func (e *encoder) calcByteSlice(l int) (int, error) {
1818
if l <= math.MaxUint8 {
19-
return def.Byte1 + l, nil
19+
return def.Byte1 + def.Byte1 + l, nil
2020
} else if l <= math.MaxUint16 {
21-
return def.Byte2 + l, nil
21+
return def.Byte1 + def.Byte2 + l, nil
2222
} else if uint(l) <= math.MaxUint32 {
23-
return def.Byte4 + l, nil
23+
return def.Byte1 + def.Byte4 + l, nil
2424
}
2525
// not supported error
2626
return 0, fmt.Errorf("%w slice length : %d", def.ErrUnsupportedType, l)

internal/encoding/byte_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,17 @@ func Test_calcByteSlice(t *testing.T) {
1919
{
2020
name: "u8",
2121
value: math.MaxUint8,
22-
result: def.Byte1 + math.MaxUint8,
22+
result: def.Byte1 + def.Byte1 + math.MaxUint8,
2323
},
2424
{
2525
name: "u16",
2626
value: math.MaxUint16,
27-
result: def.Byte2 + math.MaxUint16,
27+
result: def.Byte1 + def.Byte2 + math.MaxUint16,
2828
},
2929
{
3030
name: "u32",
3131
value: math.MaxUint32,
32-
result: def.Byte4 + math.MaxUint32,
32+
result: def.Byte1 + def.Byte4 + math.MaxUint32,
3333
},
3434
{
3535
name: "u32over",

0 commit comments

Comments
 (0)