@@ -204,6 +204,23 @@ func (c *genericCodec) size(value reflect.Value) (int, bool, error) {
204
204
}
205
205
return size , constSize , nil
206
206
207
+ case reflect .Map :
208
+ keys := value .MapKeys ()
209
+ size := wrappers .IntLen
210
+ for _ , key := range keys {
211
+ innerSize , _ , err := c .size (key )
212
+ if err != nil {
213
+ return 0 , false , err
214
+ }
215
+ size += innerSize
216
+ innerSize , _ , err = c .size (value .MapIndex (key ))
217
+ if err != nil {
218
+ return 0 , false , err
219
+ }
220
+ size += innerSize
221
+ }
222
+ return size , false , nil
223
+
207
224
default :
208
225
return 0 , false , fmt .Errorf ("can't evaluate marshal length of unknown kind %s" , valueKind )
209
226
}
@@ -332,6 +349,30 @@ func (c *genericCodec) marshal(value reflect.Value, p *wrappers.Packer, maxSlice
332
349
return err
333
350
}
334
351
}
352
+ return nil
353
+ case reflect .Map :
354
+ keys := value .MapKeys ()
355
+ numElts := len (keys ) * 2
356
+ if uint32 (numElts ) > maxSliceLen {
357
+ return fmt .Errorf ("%w; slice length, %d, exceeds maximum length, %d" ,
358
+ codec .ErrMaxSliceLenExceeded ,
359
+ numElts ,
360
+ maxSliceLen ,
361
+ )
362
+ }
363
+ p .PackInt (uint32 (numElts )) // pack # elements
364
+
365
+ for _ , key := range keys {
366
+ // serialize key
367
+ if err := c .marshal (key , p , c .maxSliceLen ); err != nil {
368
+ return err
369
+ }
370
+ // serialize value
371
+ if err := c .marshal (value .MapIndex (key ), p , c .maxSliceLen ); err != nil {
372
+ return err
373
+ }
374
+ }
375
+
335
376
return nil
336
377
default :
337
378
return fmt .Errorf ("%w: %s" , codec .ErrUnsupportedType , valueKind )
@@ -520,6 +561,36 @@ func (c *genericCodec) unmarshal(p *wrappers.Packer, value reflect.Value, maxSli
520
561
// Assign to the top-level struct's member
521
562
value .Set (v )
522
563
return nil
564
+ case reflect .Map :
565
+ numElts32 := p .UnpackInt ()
566
+ if numElts32 > c .maxSliceLen || numElts32 % 2 != 0 {
567
+ return fmt .Errorf ("%w; array length, %d, exceeds maximum length, %d" ,
568
+ codec .ErrMaxSliceLenExceeded ,
569
+ numElts32 ,
570
+ c .maxSliceLen ,
571
+ )
572
+ }
573
+
574
+ numElts := int (numElts32 / 2 )
575
+ value .Set (reflect .MakeMapWithSize (value .Type (), numElts ))
576
+ keyType := value .Type ().Key ()
577
+ valueType := value .Type ().Elem ()
578
+
579
+ for i := 0 ; i < numElts ; i ++ {
580
+ keyValue := reflect .New (keyType ).Elem ()
581
+ valueValue := reflect .New (valueType ).Elem ()
582
+
583
+ if err := c .unmarshal (p , keyValue , c .maxSliceLen ); err != nil {
584
+ return fmt .Errorf ("couldn't unmarshal map key: %w" , err )
585
+ }
586
+ if err := c .unmarshal (p , valueValue , c .maxSliceLen ); err != nil {
587
+ return fmt .Errorf ("couldn't unmarshal map element: %w" , err )
588
+ }
589
+ value .SetMapIndex (keyValue , valueValue )
590
+ }
591
+
592
+ return nil
593
+
523
594
default :
524
595
return fmt .Errorf ("can't unmarshal unknown type %s" , value .Kind ().String ())
525
596
}
0 commit comments