Skip to content

Commit 19ee2ae

Browse files
committed
CBOR: Implement 16bit float decoding
1 parent 492a197 commit 19ee2ae

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

include/tao/json/events/cbor/grammar.hpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#ifndef TAOCPP_JSON_INCLUDE_EVENTS_CBOR_GRAMMAR_HPP
55
#define TAOCPP_JSON_INCLUDE_EVENTS_CBOR_GRAMMAR_HPP
66

7+
#include <cmath>
78
#include <cstdint>
89
#include <utility>
910

@@ -321,6 +322,32 @@ namespace tao
321322
throw json_pegtl::parse_error( "unexpected end of input", in );
322323
}
323324

325+
template< typename Input >
326+
static double read_floating_half_impl( Input& in )
327+
{
328+
if( in.size( 3 ) < 3 ) {
329+
throw json_pegtl::parse_error( "unexpected end of input", in );
330+
}
331+
332+
const int half = ( in.peek_byte( 1 ) << 8 ) + in.peek_byte( 2 );
333+
const int exp = ( half >> 10 ) & 0x1f;
334+
const int mant = half & 0x3ff;
335+
336+
double val;
337+
if( exp == 0 ) {
338+
val = std::ldexp( mant, -24 );
339+
}
340+
else if( exp != 31 ) {
341+
val = std::ldexp( mant + 1024, exp - 25 );
342+
}
343+
else {
344+
val = ( mant == 0 ) ? INFINITY : NAN;
345+
}
346+
347+
in.bump_in_this_line( 3 );
348+
return half & 0x8000 ? -val : val;
349+
}
350+
324351
template< typename Input, typename Consumer >
325352
static bool match_other( Input& in, Consumer& consumer )
326353
{
@@ -337,14 +364,16 @@ namespace tao
337364
consumer.null();
338365
in.bump_in_this_line();
339366
return true;
367+
case 25:
368+
consumer.number( read_floating_half_impl( in ) );
369+
return true;
340370
case 26:
341371
consumer.number( read_floating_impl< float >( in ) );
342372
return true;
343373
case 27:
344374
consumer.number( read_floating_impl< double >( in ) );
345375
return true;
346376
case 24:
347-
case 25: // TODO: 16bit float?
348377
default:
349378
throw json_pegtl::parse_error( "unsupported minor for major 7", in );
350379
}

src/test/json/cbor.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ namespace tao
7272
cbor_decode( "9f80ff", "[[]]" );
7373
cbor_decode( "9f9fffff", "[[]]" );
7474
cbor_decode( "819fff", "[[]]" );
75+
76+
cbor_decode( "f90400", "0.00006103515625" );
77+
cbor_decode( "f9c400", "-4.0" );
78+
7579
cbor_decode( "8a00010203040506070809", "[0,1,2,3,4,5,6,7,8,9]" );
7680
cbor_decode( "9f00010203040506070809ff", "[0,1,2,3,4,5,6,7,8,9]" );
7781
cbor_decode( "a0", "{}" );

0 commit comments

Comments
 (0)