1 // Copyright Maciej Sobczak 2008-2019. 2 // This file is part of YAMI4. 3 // 4 // YAMI4 is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // YAMI4 is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with YAMI4. If not, see <http://www.gnu.org/licenses/>. 16 17 #ifndef YAMICORE_PARAMETERS_DETAILS_H_INCLUDED 18 #define YAMICORE_PARAMETERS_DETAILS_H_INCLUDED 19 20 #include "core.h" 21 #include "details-fwd.h" 22 #include "parameter_type.h" 23 #include <cstddef> 24 25 namespace yami 26 { 27 28 namespace core 29 { 30 class parameters; 31 } // namespace core 32 33 namespace details 34 { 35 36 const std::size_t short_name_optimization_threshold = 16; 37 const std::size_t initial_number_of_entries = 4; 38 const std::size_t max_nesting_level = 5; 39 40 struct entry_name 41 { 42 std::size_t name_length; 43 union packed 44 { 45 const char * long_value; 46 char short_value[short_name_optimization_threshold]; 47 } buffer; 48 49 core::result set(const char * value, std::size_t length, 50 allocator & alloc); 51 52 const char * value() const; 53 54 void clear(allocator & alloc); 55 56 bool equals(const char * value, std::size_t length) const; 57 58 // for unit tests 59 void dump(details::dump_sink & sink) const; 60 }; 61 62 struct string_array_element 63 { 64 const char * value; 65 std::size_t length; 66 67 void clear(allocator & alloc); 68 }; 69 70 struct binary_array_element 71 { 72 const void * value; 73 std::size_t length; 74 75 void clear(allocator & alloc); 76 }; 77 78 struct entry 79 { 80 entry_name name; 81 82 core::parameter_type type; 83 84 union packed 85 { 86 bool b; 87 int i; 88 long long L; 89 double d; 90 struct string_data 91 { 92 const char * value; 93 std::size_t length; 94 bool own; 95 } str; 96 struct binary_data 97 { 98 const void * value; 99 std::size_t length; 100 bool own; 101 } bin; 102 struct boolean_array_data 103 { 104 bool * values; 105 std::size_t length; 106 bool own; 107 } ba; 108 struct integer_array_data 109 { 110 int * values; 111 std::size_t length; 112 bool own; 113 } ia; 114 struct long_long_array_data 115 { 116 long long * values; 117 std::size_t length; 118 bool own; 119 } La; 120 struct double_float_array_data 121 { 122 double * values; 123 std::size_t length; 124 bool own; 125 } da; 126 struct string_array_data 127 { 128 string_array_element * values; 129 std::size_t length; 130 bool own; 131 } sa; 132 struct binary_array_data 133 { 134 binary_array_element * values; 135 std::size_t length; 136 bool own; 137 } bina; 138 core::parameters * nested; 139 struct nested_array_data 140 { 141 core::parameters * values; 142 std::size_t length; 143 bool own; 144 } nesteda; 145 } item; 146 set_nameentry147 core::result set_name(const char * value, std::size_t length, 148 allocator & alloc) 149 { 150 return name.set(value, length, alloc); 151 } 152 clear_nameentry153 void clear_name(allocator & alloc) 154 { 155 name.clear(alloc); 156 } 157 name_equalsentry158 bool name_equals(const char * value, std::size_t length) const 159 { 160 return name.equals(value, length); 161 } 162 163 void clear_item(allocator & alloc); 164 }; 165 166 void get_serialize_buffer_size( 167 const core::parameters & params, 168 std::size_t & size); // starts with 0 (for root) and gets updated 169 170 core::result serialize_entry( 171 const details::entry & e, 172 char * * buffers, 173 const std::size_t * buffer_sizes, 174 std::size_t num_of_buffers, 175 std::size_t & current_buffer, char * & buffer_position); 176 177 core::result serialize( 178 const core::parameters & params, 179 char * * buffers, 180 const std::size_t * buffer_sizes, 181 std::size_t num_of_buffers, 182 std::size_t & current_buffer, char * & buffer_position); 183 184 core::result deserialize_entry( 185 core::parameters & params, 186 const char * * buffers, 187 const std::size_t * buffer_sizes, 188 std::size_t num_of_buffers, 189 std::size_t & current_buffer, const char * & buffer_position); 190 191 core::result deserialize( 192 core::parameters & params, 193 const char * * buffers, 194 const std::size_t * buffer_sizes, 195 std::size_t num_of_buffers, 196 std::size_t & current_buffer, const char * & buffer_position); 197 198 int type_code(core::parameter_type t); 199 200 core::result get_type_from_code(int code, core::parameter_type & type); 201 202 // find the entry with given name 203 // returns the index or num_of_entries if not found 204 std::size_t find_entry(const entry * data, std::size_t num_of_entries, 205 const char * name, std::size_t name_length); 206 207 // find an appropriate place for a new entry 208 // by either locating an unused entry 209 // or by extending the set 210 core::result find_empty_entry(entry * & data, std::size_t & num_of_entries, 211 std::size_t & index, allocator & alloc); 212 213 // finds an existing entry with the given name and clears its item 214 // or creates a new entry with this name already set 215 core::result prepare_for_set(entry * & data, std::size_t & num_of_entries, 216 const char * name, std::size_t name_length, 217 std::size_t & index, allocator & alloc); 218 219 // finds the next used entry or returns num_of_entries if nothing was found 220 std::size_t find_next_used(const entry * data, std::size_t num_of_entries, 221 std::size_t current_index); 222 223 core::result do_set_string(const char * name, std::size_t name_length, 224 const char * value, std::size_t value_length, 225 entry * & data, std::size_t & num_of_entries, 226 allocator & alloc, bool own); 227 228 core::result do_set_binary(const char * name, std::size_t name_length, 229 const void * value, std::size_t value_length, 230 entry * & data, std::size_t & num_of_entries, 231 allocator & alloc, bool own); 232 233 core::result do_set_boolean_array(const char * name, std::size_t name_length, 234 const bool * values, std::size_t array_length, 235 entry * & data, std::size_t & num_of_entries, 236 allocator & alloc, bool own); 237 238 core::result do_set_integer_array(const char * name, std::size_t name_length, 239 const int * values, std::size_t array_length, 240 entry * & data, std::size_t & num_of_entries, 241 allocator & alloc, bool own); 242 243 core::result do_set_long_long_array( 244 const char * name, std::size_t name_length, 245 const long long * values, std::size_t array_length, 246 entry * & data, std::size_t & num_of_entries, 247 allocator & alloc, bool own); 248 249 core::result do_set_double_float_array( 250 const char * name, std::size_t name_length, 251 const double * values, std::size_t array_length, 252 entry * & data, std::size_t & num_of_entries, 253 allocator & alloc, bool own); 254 255 core::result do_create_string_array( 256 const char * name, std::size_t name_length, 257 std::size_t array_length, std::size_t & index, 258 entry * & data, std::size_t & num_of_entries, 259 allocator & alloc); 260 261 core::result do_set_string_in_array( 262 std::size_t item_index, std::size_t array_index, 263 const char * value, std::size_t value_length, 264 entry * data, allocator & alloc); 265 266 core::result do_place_string_in_array( 267 std::size_t item_index, std::size_t array_index, 268 const char * value, std::size_t value_length, 269 entry * data, allocator & alloc); 270 271 core::result do_create_binary_array( 272 const char * name, std::size_t name_length, 273 std::size_t array_length, std::size_t & index, 274 entry * & data, std::size_t & num_of_entries, 275 allocator & alloc); 276 277 core::result do_set_binary_in_array( 278 std::size_t item_index, std::size_t array_index, 279 const void * value, std::size_t value_length, 280 entry * data, allocator & alloc); 281 282 core::result do_place_binary_in_array( 283 std::size_t item_index, std::size_t array_index, 284 const void * value, std::size_t value_length, 285 entry * data, allocator & alloc); 286 287 core::result do_create_nested_array( 288 const char * name, std::size_t name_length, 289 std::size_t array_length, std::size_t & index, 290 entry * & data, std::size_t & num_of_entries, 291 allocator & alloc); 292 293 core::result do_access_nested_in_array( 294 std::size_t item_index, std::size_t array_index, 295 core::parameters * & nested, 296 entry * data); 297 298 } // namespace details 299 300 } // namespace yami 301 302 #endif // YAMICORE_PARAMETERS_DETAILS_H_INCLUDED 303