@@ -19,7 +19,9 @@ public enum CborDataItemType
1919 ByteString ,
2020 Array ,
2121 Map ,
22- Break
22+ Break ,
23+
24+ Decimal
2325 }
2426
2527 public interface ICborMapReader < TC >
@@ -149,6 +151,9 @@ public CborDataItemType GetCurrentDataItemType()
149151 case CborPrimitive . DoubleFloat :
150152 return CborDataItemType . Double ;
151153
154+ case CborPrimitive . DecimalFloat :
155+ return CborDataItemType . Decimal ;
156+
152157 case CborPrimitive . Break :
153158 return CborDataItemType . Break ;
154159
@@ -416,6 +421,46 @@ public double ReadDouble()
416421 }
417422 }
418423
424+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
425+ public decimal ReadDecimal ( )
426+ {
427+ SkipSemanticTag ( ) ;
428+ CborReaderHeader header = GetHeader ( ) ;
429+
430+ switch ( header . MajorType )
431+ {
432+ case CborMajorType . PositiveInteger :
433+ return ReadInteger ( ) ;
434+
435+ case CborMajorType . NegativeInteger :
436+ return - 1L - ( long ) ReadInteger ( ) ;
437+
438+ case CborMajorType . Primitive :
439+ {
440+ switch ( header . Primitive )
441+ {
442+ case CborPrimitive . HalfFloat :
443+ return ( decimal ) InternalReadHalf ( ) ;
444+
445+ case CborPrimitive . SingleFloat :
446+ return Convert . ToDecimal ( InternalReadSingle ( ) ) ;
447+
448+ case CborPrimitive . DoubleFloat :
449+ return Convert . ToDecimal ( InternalReadDouble ( ) ) ;
450+
451+ case CborPrimitive . DecimalFloat :
452+ return InternalReadDecimal ( ) ;
453+
454+ default :
455+ throw new CborException ( $ "Invalid primitive { header . Primitive } ") ;
456+ }
457+ }
458+
459+ default :
460+ throw new CborException ( $ "Invalid major type { header . MajorType } ") ;
461+ }
462+ }
463+
419464 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
420465 public int ReadSize ( )
421466 {
@@ -603,6 +648,26 @@ private double InternalReadDouble()
603648 }
604649 }
605650
651+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
652+ private decimal InternalReadDecimal ( )
653+ {
654+ ReadOnlySpan < byte > bytes = ReadBytes ( 16 ) ;
655+
656+ if ( BitConverter . IsLittleEndian )
657+ {
658+ int i1 = BinaryPrimitives . ReadInt32BigEndian ( bytes . Slice ( 0 , 4 ) ) ;
659+ int i0 = BinaryPrimitives . ReadInt32BigEndian ( bytes . Slice ( 4 , 4 ) ) ;
660+ int i2 = BinaryPrimitives . ReadInt32BigEndian ( bytes . Slice ( 8 , 4 ) ) ;
661+ int i3 = BinaryPrimitives . ReadInt32BigEndian ( bytes . Slice ( 12 , 4 ) ) ;
662+
663+ return new decimal ( new int [ ] { i0 , i1 , i2 , i3 } ) ;
664+ }
665+ else
666+ {
667+ return MemoryMarshal . Read < decimal > ( bytes ) ;
668+ }
669+ }
670+
606671 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
607672 private ReadOnlySpan < byte > ReadSizeAndBytes ( )
608673 {
@@ -727,6 +792,10 @@ public void SkipDataItem()
727792 case CborPrimitive . DoubleFloat :
728793 Advance ( 8 ) ;
729794 break ;
795+
796+ case CborPrimitive . DecimalFloat :
797+ Advance ( 16 ) ;
798+ break ;
730799 }
731800 break ;
732801 }
0 commit comments