Skip to content

Commit 05f7422

Browse files
committed
Add binary literals
1 parent 12a1f4f commit 05f7422

File tree

8 files changed

+122
-70
lines changed

8 files changed

+122
-70
lines changed

include/tao/json.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@
5757
// Relaxed JSON
5858
#include "json/jaxn.hpp"
5959

60+
// Binary literals
61+
#include "json/binary.hpp"
62+
6063
// Binary formats
6164
#include "json/cbor.hpp"
6265
#include "json/msgpack.hpp"

include/tao/json/binary.hpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright (c) 2017 Dr. Colin Hirsch and Daniel Frey
2+
// Please see LICENSE for license or visit https://github.com/taocpp/json/
3+
4+
#ifndef TAOCPP_JSON_INCLUDE_BINARY_HPP
5+
#define TAOCPP_JSON_INCLUDE_BINARY_HPP
6+
7+
#include <vector>
8+
9+
#include "byte.hpp"
10+
#include "internal/integer_sequence.hpp"
11+
12+
namespace tao
13+
{
14+
namespace json
15+
{
16+
namespace internal
17+
{
18+
constexpr char unhex( const char c ) noexcept
19+
{
20+
return ( c < 'A' ) ? ( c - '0' ) : ( ( c < 'a' ) ? ( c - 'A' + 10 ) : ( c - 'a' + 10 ) );
21+
}
22+
23+
template< typename T, typename V, char... Cs, std::size_t... Is >
24+
constexpr T unhex( index_sequence< Is... > )
25+
{
26+
const char a[] = { unhex( Cs )... };
27+
return T{ V( ( a[ 2 * Is ] << 4 ) + a[ 2 * Is + 1 ] )... };
28+
}
29+
30+
template< typename T, typename V, char C0, char C1, char... Cs >
31+
constexpr T unhex()
32+
{
33+
static_assert( C0 == '0', "not a hex literal" );
34+
static_assert( C1 == 'x' || C1 == 'X', "not a hex literal" );
35+
static_assert( sizeof...( Cs ) % 2 == 0, "invalid number of hexadecimal digits" );
36+
return unhex< T, V, Cs... >( make_index_sequence< sizeof...( Cs ) / 2 >() );
37+
}
38+
39+
} // namespace internal
40+
41+
inline namespace literals
42+
{
43+
template< char... Cs >
44+
std::vector< byte > operator"" _binary()
45+
{
46+
return internal::unhex< std::vector< byte >, byte, Cs... >();
47+
}
48+
49+
} // namespace literals
50+
51+
} // namespace json
52+
53+
} // namespace tao
54+
55+
#endif

src/test/json/cbor.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Please see LICENSE for license or visit https://github.com/taocpp/json/
33

44
#include "test.hpp"
5-
#include "unhex.hpp"
5+
#include "test_unhex.hpp"
66

77
#include <tao/json.hpp>
88

@@ -12,12 +12,12 @@ namespace tao
1212
{
1313
void cbor_encode( const std::string& text, const std::string& data )
1414
{
15-
TEST_ASSERT( cbor::to_string( from_string( text ) ) == internal::unhex( data ) );
15+
TEST_ASSERT( cbor::to_string( from_string( text ) ) == test_unhex( data ) );
1616
}
1717

1818
void cbor_decode( const std::string& data, const std::string& text )
1919
{
20-
TEST_ASSERT( to_string( cbor::from_string( internal::unhex( data ) ) ) == to_string( from_string( text ) ) );
20+
TEST_ASSERT( to_string( cbor::from_string( test_unhex( data ) ) ) == to_string( from_string( text ) ) );
2121
}
2222

2323
void cbor_roundtrip( const std::string& text )

src/test/json/msgpack.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Please see LICENSE for license or visit https://github.com/taocpp/json/
33

44
#include "test.hpp"
5-
#include "unhex.hpp"
5+
#include "test_unhex.hpp"
66

77
#include <tao/json.hpp>
88

@@ -12,12 +12,12 @@ namespace tao
1212
{
1313
void msgpack_encode( const std::string& text, const std::string& data )
1414
{
15-
TEST_ASSERT( msgpack::to_string( from_string( text ) ) == internal::unhex( data ) );
15+
TEST_ASSERT( msgpack::to_string( from_string( text ) ) == test_unhex( data ) );
1616
}
1717

1818
void msgpack_decode( const std::string& data, const std::string& text )
1919
{
20-
TEST_ASSERT( to_string( msgpack::from_string( internal::unhex( data ) ) ) == to_string( from_string( text ) ) );
20+
TEST_ASSERT( to_string( msgpack::from_string( test_unhex( data ) ) ) == to_string( from_string( text ) ) );
2121
}
2222

2323
void unit_test()

src/test/json/parse_jaxn.cpp

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "test.hpp"
55

6+
#include <tao/json/binary.hpp>
67
#include <tao/json/jaxn/from_string.hpp>
78
#include <tao/json/value.hpp>
89

@@ -178,20 +179,17 @@ namespace tao
178179
TEST_ASSERT( jaxn::from_string( "$+$''" ) == std::vector< json::byte >{} );
179180
TEST_ASSERT( jaxn::from_string( "$''+$" ) == std::vector< json::byte >{} );
180181

181-
const auto a = json::byte( 'a' );
182-
const auto b = json::byte( 'b' );
182+
TEST_ASSERT( jaxn::from_string( "$'a'" ) == 0x61_binary );
183+
TEST_ASSERT( jaxn::from_string( "$+$'a'" ) == 0x61_binary );
184+
TEST_ASSERT( jaxn::from_string( "$'a'+$" ) == 0x61_binary );
183185

184-
TEST_ASSERT( jaxn::from_string( "$'a'" ) == std::vector< json::byte >{ a } );
185-
TEST_ASSERT( jaxn::from_string( "$+$'a'" ) == std::vector< json::byte >{ a } );
186-
TEST_ASSERT( jaxn::from_string( "$'a'+$" ) == std::vector< json::byte >{ a } );
186+
TEST_ASSERT( jaxn::from_string( "$62" ) == 0x62_binary );
187+
TEST_ASSERT( jaxn::from_string( "$62+$'a'" ) == 0x6261_binary );
188+
TEST_ASSERT( jaxn::from_string( "$'a'+$62" ) == 0x6162_binary );
187189

188-
TEST_ASSERT( jaxn::from_string( "$62" ) == std::vector< json::byte >{ b } );
189-
TEST_ASSERT( jaxn::from_string( "$62+$'a'" ) == std::vector< json::byte >{ b, a } );
190-
TEST_ASSERT( jaxn::from_string( "$'a'+$62" ) == std::vector< json::byte >{ a, b } );
191-
192-
TEST_ASSERT( jaxn::from_string( "$6162" ) == std::vector< json::byte >{ a, b } );
193-
TEST_ASSERT( jaxn::from_string( "$61.62" ) == std::vector< json::byte >{ a, b } );
194-
TEST_ASSERT( jaxn::from_string( "$61+$62" ) == std::vector< json::byte >{ a, b } );
190+
TEST_ASSERT( jaxn::from_string( "$6162" ) == 0x6162_binary );
191+
TEST_ASSERT( jaxn::from_string( "$61.62" ) == 0x6162_binary );
192+
TEST_ASSERT( jaxn::from_string( "$61+$62" ) == 0x6162_binary );
195193
}
196194

197195
} // namespace json

src/test/json/test_unhex.hpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) 2017 Dr. Colin Hirsch and Daniel Frey
2+
// Please see LICENSE for license or visit https://github.com/taocpp/json/
3+
4+
#ifndef TAOCPP_JSON_INCLUDE_SRC_TEST_UNHEX_HPP
5+
#define TAOCPP_JSON_INCLUDE_SRC_TEST_UNHEX_HPP
6+
7+
#include <cassert>
8+
#include <string>
9+
10+
namespace tao
11+
{
12+
namespace json
13+
{
14+
inline char test_unhex( const char c )
15+
{
16+
if( ( '0' <= c ) && ( c <= '9' ) ) {
17+
return c - '0';
18+
}
19+
if( ( 'a' <= c ) && ( c <= 'f' ) ) {
20+
return c - 'a' + 10;
21+
}
22+
if( ( 'A' <= c ) && ( c <= 'F' ) ) {
23+
return c - 'A' + 10;
24+
}
25+
// LCOV_EXCL_START
26+
assert( false );
27+
return 0;
28+
// LCOV_EXCL_STOP
29+
}
30+
31+
inline std::string test_unhex( const std::string& data )
32+
{
33+
assert( !( data.size() & 1 ) );
34+
std::string result;
35+
result.reserve( data.size() / 2 );
36+
for( std::string::size_type i = 0; i < data.size(); i += 2 ) {
37+
result += ( test_unhex( data[ i ] ) << 4 ) + test_unhex( data[ i + 1 ] );
38+
}
39+
return result;
40+
}
41+
42+
} // namespace json
43+
44+
} // namespace tao
45+
46+
#endif

src/test/json/ubjson.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Please see LICENSE for license or visit https://github.com/taocpp/json/
33

44
#include "test.hpp"
5-
#include "unhex.hpp"
5+
#include "test_unhex.hpp"
66

77
#include <tao/json.hpp>
88

@@ -12,7 +12,7 @@ namespace tao
1212
{
1313
void ubjson_encode( const std::string& text, const std::string& data )
1414
{
15-
TEST_ASSERT( ubjson::to_string( from_string( text ) ) == internal::unhex( data ) );
15+
TEST_ASSERT( ubjson::to_string( from_string( text ) ) == test_unhex( data ) );
1616
}
1717

1818
void unit_test()

src/test/json/unhex.hpp

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)