@@ -87,6 +87,39 @@ func (f FieldIntFixed) String() string {
8787 return fmt .Sprintf ("0x%x" , f .Value )
8888}
8989
90+ func (f * FieldIntFixed ) decode (data []byte , pos uint64 ) (uint64 , error ) {
91+ var b bytes.Buffer
92+ b .Grow (f .Length * 2 ) // output is between 1 and 2 times that of the input
93+
94+ for {
95+ if len (data ) < int (pos )+ 1 {
96+ return pos , errors .New ("data truncated" )
97+ }
98+ if data [pos ]% 2 == 0 {
99+ b .WriteByte (data [pos ] >> 1 )
100+ } else {
101+ if len (data ) < int (pos )+ 2 {
102+ return pos , errors .New ("data truncated" )
103+ }
104+ switch data [pos + 1 ] {
105+ case 0x2 :
106+ b .WriteByte ((data [pos ] >> 2 ) + 0x80 )
107+ case 0x3 :
108+ b .WriteByte ((data [pos ] >> 2 ) + 0xc0 )
109+ default :
110+ return pos , fmt .Errorf ("unknown decoding for %v" , data [pos ])
111+ }
112+ pos ++
113+ }
114+ pos ++
115+ if b .Len () == f .Length {
116+ break
117+ }
118+ }
119+ f .Value = b .Bytes ()
120+ return pos , nil
121+ }
122+
90123// FieldIntVar is using the signed integer variant of the 'varlen_integer_format'
91124// and encodes a value as a byte sequence of 1-9 bytes depending on the value.
92125type FieldIntVar struct {
@@ -97,6 +130,20 @@ func (f FieldIntVar) String() string {
97130 return fmt .Sprintf ("%d" , f .Value )
98131}
99132
133+ func (f * FieldIntVar ) decode (data []byte , pos uint64 ) (uint64 , error ) {
134+ var val interface {}
135+ val , pos , err := decodeVar (data , pos , false )
136+ if err != nil {
137+ return pos , err
138+ }
139+ if intval , ok := val .(int64 ); ok {
140+ f .Value = intval
141+ } else {
142+ return pos , errors .New ("unexpected type, expecting int64" )
143+ }
144+ return pos , nil
145+ }
146+
100147// FieldUintVar is using the unsigned integer variant of the 'varlen_integer_format'
101148// and encodes a value as a byte sequence of 1-9 bytes depending on the value.
102149type FieldUintVar struct {
@@ -107,11 +154,38 @@ func (f FieldUintVar) String() string {
107154 return fmt .Sprintf ("%d" , f .Value )
108155}
109156
157+ func (f * FieldUintVar ) decode (data []byte , pos uint64 ) (uint64 , error ) {
158+ var val interface {}
159+ val , pos , err := decodeVar (data , pos , true )
160+ if err != nil {
161+ return pos , err
162+ }
163+ if uintval , ok := val .(uint64 ); ok {
164+ f .Value = uintval
165+ } else {
166+ return pos , errors .New ("unexpected type, expecting uint64" )
167+ }
168+ return pos , nil
169+ }
170+
110171// FieldString is a 'string_format' field
111172type FieldString struct {
112173 Value string
113174}
114175
176+ func (f * FieldString ) decode (data []byte , pos uint64 ) (uint64 , error ) {
177+ if len (data ) < int (pos )+ 1 {
178+ return pos , errors .New ("string truncated, expected at least one byte" )
179+ }
180+ strLen := int (data [pos ] >> 1 )
181+ pos ++
182+ if len (data ) < int (pos )+ strLen {
183+ return pos , fmt .Errorf ("string truncated, expected length: %d" , strLen )
184+ }
185+ f .Value = string (data [pos : pos + uint64 (strLen )])
186+ return pos + uint64 (strLen ), nil
187+ }
188+
115189func (f FieldString ) String () string {
116190 return f .Value
117191}
@@ -151,37 +225,25 @@ func Unmarshal(data []byte, v interface{}) error {
151225 var err error
152226 switch f := m .Fields [i ].Type .(type ) {
153227 case FieldIntFixed :
154- f . Value , n , err = decodeFixed (data , pos , f . Length )
228+ n , err = f . decode (data , pos )
155229 if err != nil {
156230 return err
157231 }
158232 m .Fields [i ].Type = f
159233 case FieldUintVar :
160- var val interface {}
161- val , n , err = decodeVar (data , pos , true )
234+ n , err = f .decode (data , pos )
162235 if err != nil {
163236 return err
164237 }
165- if uintval , ok := val .(uint64 ); ok {
166- f .Value = uintval
167- } else {
168- return errors .New ("unexpected type, expecting uint64" )
169- }
170238 m .Fields [i ].Type = f
171239 case FieldIntVar :
172- var val interface {}
173- val , n , err = decodeVar (data , pos , false )
240+ n , err = f .decode (data , pos )
174241 if err != nil {
175242 return err
176243 }
177- if intval , ok := val .(int64 ); ok {
178- f .Value = intval
179- } else {
180- return errors .New ("unexpected type, expecting int64" )
181- }
182244 m .Fields [i ].Type = f
183245 case FieldString :
184- f . Value , n , err = decodeString (data , pos )
246+ n , err = f . decode (data , pos )
185247 if err != nil {
186248 return err
187249 }
@@ -198,50 +260,6 @@ func Unmarshal(data []byte, v interface{}) error {
198260 return nil
199261}
200262
201- func decodeString (data []byte , pos uint64 ) (string , uint64 , error ) {
202- if len (data ) < int (pos )+ 1 {
203- return "" , pos , errors .New ("string truncated, expected at least one byte" )
204- }
205- strLen := int (data [pos ] >> 1 )
206- pos ++
207- if len (data ) < int (pos )+ strLen {
208- return "" , pos , fmt .Errorf ("string truncated, expected length: %d" , strLen )
209- }
210- return string (data [pos : pos + uint64 (strLen )]), pos + uint64 (strLen ), nil
211- }
212-
213- func decodeFixed (data []byte , pos uint64 , intlen int ) ([]byte , uint64 , error ) {
214- var b bytes.Buffer
215- b .Grow (intlen * 2 ) // output is between 1 and 2 times that of the input
216-
217- for {
218- if len (data ) < int (pos )+ 1 {
219- return b .Bytes (), pos , errors .New ("data truncated" )
220- }
221- if data [pos ]% 2 == 0 {
222- b .WriteByte (data [pos ] >> 1 )
223- } else {
224- if len (data ) < int (pos )+ 2 {
225- return b .Bytes (), pos , errors .New ("data truncated" )
226- }
227- switch data [pos + 1 ] {
228- case 0x2 :
229- b .WriteByte ((data [pos ] >> 2 ) + 0x80 )
230- case 0x3 :
231- b .WriteByte ((data [pos ] >> 2 ) + 0xc0 )
232- default :
233- return nil , pos , fmt .Errorf ("unknown decoding for %v" , data [pos ])
234- }
235- pos ++
236- }
237- pos ++
238- if b .Len () == intlen {
239- break
240- }
241- }
242- return b .Bytes (), pos , nil
243- }
244-
245263func decodeVar (data []byte , pos uint64 , unsigned bool ) (interface {}, uint64 , error ) {
246264 if len (data ) < int (pos )+ 1 {
247265 return 0 , pos , errors .New ("data truncated" )
0 commit comments