|
| 1 | +// Copyright (c) 2016 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_INTERNAL_VALUE_BUILDER_HH |
| 5 | +#define TAOCPP_JSON_INCLUDE_INTERNAL_VALUE_BUILDER_HH |
| 6 | + |
| 7 | +#include "../value.hh" |
| 8 | + |
| 9 | +namespace tao |
| 10 | +{ |
| 11 | + namespace json |
| 12 | + { |
| 13 | + namespace internal |
| 14 | + { |
| 15 | + // General interface for a SAX handler: |
| 16 | + // |
| 17 | + // template< template< typename ... > class Traits > |
| 18 | + // class value_handler |
| 19 | + // { |
| 20 | + // void null() {} |
| 21 | + // void bool_( const bool v ) {} |
| 22 | + // void number( const std::int64_t v ) {} |
| 23 | + // void number( const std::uint64_t v ) {} |
| 24 | + // void number( const double v ) {} |
| 25 | + // void string( std::string && v ) {} |
| 26 | + // void begin_array() {} |
| 27 | + // void commit_element() {} |
| 28 | + // void end_array() {} |
| 29 | + // void begin_object() {} |
| 30 | + // void commit_key( std::string && key ) {} |
| 31 | + // void commit_member() {} |
| 32 | + // void end_object() {} |
| 33 | + // }; |
| 34 | + |
| 35 | + template< template< typename ... > class Traits > |
| 36 | + struct value_builder |
| 37 | + { |
| 38 | + basic_value< Traits > value; |
| 39 | + |
| 40 | + basic_value< Traits > * current; |
| 41 | + std::vector< basic_value< Traits > * > stack; |
| 42 | + |
| 43 | + value_builder() : current( & value ) {} |
| 44 | + |
| 45 | + void null() { current->unsafe_assign_null(); } |
| 46 | + void bool_( const bool v ) { current->unsafe_assign_bool( v ); } |
| 47 | + void number( const std::int64_t v ) { current->unsafe_assign_signed( v ); } |
| 48 | + void number( const std::uint64_t v ) { current->unsafe_assign_unsigned( v ); } |
| 49 | + void number( const double v ) { current->unsafe_assign_double( v ); } |
| 50 | + void string( std::string && v ) { current->unsafe_emplace_string( std::move( v ) ); } |
| 51 | + |
| 52 | + // array |
| 53 | + void begin_array() |
| 54 | + { |
| 55 | + current->unsafe_emplace_array(); |
| 56 | + current->unsafe_emplace_back( json::null ); |
| 57 | + stack.push_back( current ); |
| 58 | + current = & current->unsafe_get_array().back(); |
| 59 | + } |
| 60 | + |
| 61 | + void commit_element() |
| 62 | + { |
| 63 | + stack.back()->unsafe_emplace_back( json::null ); |
| 64 | + current = & stack.back()->unsafe_get_array().back(); |
| 65 | + } |
| 66 | + |
| 67 | + void end_array() |
| 68 | + { |
| 69 | + current = stack.back(); |
| 70 | + current->unsafe_get_array().pop_back(); |
| 71 | + stack.pop_back(); |
| 72 | + } |
| 73 | + |
| 74 | + // object |
| 75 | + void begin_object() |
| 76 | + { |
| 77 | + current->unsafe_emplace_object(); |
| 78 | + } |
| 79 | + |
| 80 | + void commit_key( std::string && key ) |
| 81 | + { |
| 82 | + const auto r = current->unsafe_emplace( std::move( key ), json::null ); |
| 83 | + if ( ! r.second ) { |
| 84 | + // TODO: throw on duplicate key? offer a choice? |
| 85 | + r.first->second = json::null; |
| 86 | + } |
| 87 | + stack.push_back( current ); |
| 88 | + current = & r.first->second; |
| 89 | + } |
| 90 | + |
| 91 | + void commit_member() |
| 92 | + { |
| 93 | + current = stack.back(); |
| 94 | + stack.pop_back(); |
| 95 | + } |
| 96 | + |
| 97 | + void end_object() {} |
| 98 | + }; |
| 99 | + |
| 100 | + } // internal |
| 101 | + |
| 102 | + } // json |
| 103 | + |
| 104 | +} // tao |
| 105 | + |
| 106 | +#endif |
0 commit comments