ucl.h (262975) | ucl.h (263648) |
---|---|
1/* Copyright (c) 2013, Vsevolod Stakhov 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright --- 124 unchanged lines hidden (view full) --- 133/** 134 * These flags defines parser behaviour. If you specify #UCL_PARSER_ZEROCOPY you must ensure 135 * that the input memory is not freed if an object is in use. Moreover, if you want to use 136 * zero-terminated keys and string values then you should not use zero-copy mode, as in this case 137 * UCL still has to perform copying implicitly. 138 */ 139typedef enum ucl_parser_flags { 140 UCL_PARSER_KEY_LOWERCASE = 0x1, /**< Convert all keys to lower case */ | 1/* Copyright (c) 2013, Vsevolod Stakhov 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright --- 124 unchanged lines hidden (view full) --- 133/** 134 * These flags defines parser behaviour. If you specify #UCL_PARSER_ZEROCOPY you must ensure 135 * that the input memory is not freed if an object is in use. Moreover, if you want to use 136 * zero-terminated keys and string values then you should not use zero-copy mode, as in this case 137 * UCL still has to perform copying implicitly. 138 */ 139typedef enum ucl_parser_flags { 140 UCL_PARSER_KEY_LOWERCASE = 0x1, /**< Convert all keys to lower case */ |
141 UCL_PARSER_ZEROCOPY = 0x2 /**< Parse input in zero-copy mode if possible */ | 141 UCL_PARSER_ZEROCOPY = 0x2, /**< Parse input in zero-copy mode if possible */ 142 UCL_PARSER_NO_TIME = 0x4 /**< Do not parse time and treat time values as strings */ |
142} ucl_parser_flags_t; 143 144/** 145 * String conversion flags, that are used in #ucl_object_fromstring_common function. 146 */ 147typedef enum ucl_string_flags { 148 UCL_STRING_ESCAPE = 0x1, /**< Perform JSON escape */ 149 UCL_STRING_TRIM = 0x2, /**< Trim leading and trailing whitespaces */ 150 UCL_STRING_PARSE_BOOLEAN = 0x4, /**< Parse passed string and detect boolean */ 151 UCL_STRING_PARSE_INT = 0x8, /**< Parse passed string and detect integer number */ 152 UCL_STRING_PARSE_DOUBLE = 0x10, /**< Parse passed string and detect integer or float number */ | 143} ucl_parser_flags_t; 144 145/** 146 * String conversion flags, that are used in #ucl_object_fromstring_common function. 147 */ 148typedef enum ucl_string_flags { 149 UCL_STRING_ESCAPE = 0x1, /**< Perform JSON escape */ 150 UCL_STRING_TRIM = 0x2, /**< Trim leading and trailing whitespaces */ 151 UCL_STRING_PARSE_BOOLEAN = 0x4, /**< Parse passed string and detect boolean */ 152 UCL_STRING_PARSE_INT = 0x8, /**< Parse passed string and detect integer number */ 153 UCL_STRING_PARSE_DOUBLE = 0x10, /**< Parse passed string and detect integer or float number */ |
153 UCL_STRING_PARSE_NUMBER = UCL_STRING_PARSE_INT|UCL_STRING_PARSE_DOUBLE , /**< | 154 UCL_STRING_PARSE_TIME = 0x20, /**< Parse time strings */ 155 UCL_STRING_PARSE_NUMBER = UCL_STRING_PARSE_INT|UCL_STRING_PARSE_DOUBLE|UCL_STRING_PARSE_TIME, /**< |
154 Parse passed string and detect number */ 155 UCL_STRING_PARSE = UCL_STRING_PARSE_BOOLEAN|UCL_STRING_PARSE_NUMBER, /**< 156 Parse passed string (and detect booleans and numbers) */ | 156 Parse passed string and detect number */ 157 UCL_STRING_PARSE = UCL_STRING_PARSE_BOOLEAN|UCL_STRING_PARSE_NUMBER, /**< 158 Parse passed string (and detect booleans and numbers) */ |
157 UCL_STRING_PARSE_BYTES = 0x20 /**< Treat numbers as bytes */ | 159 UCL_STRING_PARSE_BYTES = 0x40 /**< Treat numbers as bytes */ |
158} ucl_string_flags_t; 159 160/** 161 * Basic flags for an object 162 */ 163typedef enum ucl_object_flags { 164 UCL_OBJECT_ALLOCATED_KEY = 1, /**< An object has key allocated internally */ 165 UCL_OBJECT_ALLOCATED_VALUE = 2, /**< An object has a string value allocated internally */ --- 48 unchanged lines hidden (view full) --- 214 * @return zero terminated string representation of object value 215 */ 216UCL_EXTERN char* ucl_copy_value_trash (ucl_object_t *obj); 217 218/** 219 * Creates a new object 220 * @return new object 221 */ | 160} ucl_string_flags_t; 161 162/** 163 * Basic flags for an object 164 */ 165typedef enum ucl_object_flags { 166 UCL_OBJECT_ALLOCATED_KEY = 1, /**< An object has key allocated internally */ 167 UCL_OBJECT_ALLOCATED_VALUE = 2, /**< An object has a string value allocated internally */ --- 48 unchanged lines hidden (view full) --- 216 * @return zero terminated string representation of object value 217 */ 218UCL_EXTERN char* ucl_copy_value_trash (ucl_object_t *obj); 219 220/** 221 * Creates a new object 222 * @return new object 223 */ |
222static inline ucl_object_t* ucl_object_new (void) UCL_WARN_UNUSED_RESULT; 223static inline ucl_object_t * 224ucl_object_new (void) 225{ 226 ucl_object_t *new; 227 new = malloc (sizeof (ucl_object_t)); 228 if (new != NULL) { 229 memset (new, 0, sizeof (ucl_object_t)); 230 new->ref = 1; 231 new->type = UCL_NULL; 232 } 233 return new; 234} | 224UCL_EXTERN ucl_object_t* ucl_object_new (void) UCL_WARN_UNUSED_RESULT; |
235 236/** 237 * Create new object with type specified 238 * @param type type of a new object 239 * @return new object 240 */ | 225 226/** 227 * Create new object with type specified 228 * @param type type of a new object 229 * @return new object 230 */ |
241static inline ucl_object_t* ucl_object_typed_new (unsigned int type) UCL_WARN_UNUSED_RESULT; 242static inline ucl_object_t * 243ucl_object_typed_new (unsigned int type) 244{ 245 ucl_object_t *new; 246 new = malloc (sizeof (ucl_object_t)); 247 if (new != NULL) { 248 memset (new, 0, sizeof (ucl_object_t)); 249 new->ref = 1; 250 new->type = (type <= UCL_NULL ? type : UCL_NULL); 251 } 252 return new; 253} | 231UCL_EXTERN ucl_object_t* ucl_object_typed_new (unsigned int type) UCL_WARN_UNUSED_RESULT; |
254 255/** 256 * Convert any string to an ucl object making the specified transformations 257 * @param str fixed size or NULL terminated string 258 * @param len length (if len is zero, than str is treated as NULL terminated) 259 * @param flags conversion flags 260 * @return new object 261 */ 262UCL_EXTERN ucl_object_t * ucl_object_fromstring_common (const char *str, size_t len, 263 enum ucl_string_flags flags) UCL_WARN_UNUSED_RESULT; 264 265/** 266 * Create a UCL object from the specified string 267 * @param str NULL terminated string, will be json escaped 268 * @return new object 269 */ | 232 233/** 234 * Convert any string to an ucl object making the specified transformations 235 * @param str fixed size or NULL terminated string 236 * @param len length (if len is zero, than str is treated as NULL terminated) 237 * @param flags conversion flags 238 * @return new object 239 */ 240UCL_EXTERN ucl_object_t * ucl_object_fromstring_common (const char *str, size_t len, 241 enum ucl_string_flags flags) UCL_WARN_UNUSED_RESULT; 242 243/** 244 * Create a UCL object from the specified string 245 * @param str NULL terminated string, will be json escaped 246 * @return new object 247 */ |
270static inline ucl_object_t * 271ucl_object_fromstring (const char *str) 272{ 273 return ucl_object_fromstring_common (str, 0, UCL_STRING_ESCAPE); 274} | 248UCL_EXTERN ucl_object_t *ucl_object_fromstring (const char *str); |
275 276/** 277 * Create a UCL object from the specified string 278 * @param str fixed size string, will be json escaped 279 * @param len length of a string 280 * @return new object 281 */ | 249 250/** 251 * Create a UCL object from the specified string 252 * @param str fixed size string, will be json escaped 253 * @param len length of a string 254 * @return new object 255 */ |
282static inline ucl_object_t * 283ucl_object_fromlstring (const char *str, size_t len) 284{ 285 return ucl_object_fromstring_common (str, len, UCL_STRING_ESCAPE); 286} | 256UCL_EXTERN ucl_object_t *ucl_object_fromlstring (const char *str, size_t len); |
287 288/** 289 * Create an object from an integer number 290 * @param iv number 291 * @return new object 292 */ | 257 258/** 259 * Create an object from an integer number 260 * @param iv number 261 * @return new object 262 */ |
293static inline ucl_object_t * 294ucl_object_fromint (int64_t iv) 295{ 296 ucl_object_t *obj; | 263UCL_EXTERN ucl_object_t* ucl_object_fromint (int64_t iv); |
297 | 264 |
298 obj = ucl_object_new (); 299 if (obj != NULL) { 300 obj->type = UCL_INT; 301 obj->value.iv = iv; 302 } 303 304 return obj; 305} 306 | |
307/** 308 * Create an object from a float number 309 * @param dv number 310 * @return new object 311 */ | 265/** 266 * Create an object from a float number 267 * @param dv number 268 * @return new object 269 */ |
312static inline ucl_object_t * 313ucl_object_fromdouble (double dv) 314{ 315 ucl_object_t *obj; | 270UCL_EXTERN ucl_object_t* ucl_object_fromdouble (double dv); |
316 | 271 |
317 obj = ucl_object_new (); 318 if (obj != NULL) { 319 obj->type = UCL_FLOAT; 320 obj->value.dv = dv; 321 } 322 323 return obj; 324} 325 | |
326/** 327 * Create an object from a boolean 328 * @param bv bool value 329 * @return new object 330 */ | 272/** 273 * Create an object from a boolean 274 * @param bv bool value 275 * @return new object 276 */ |
331static inline ucl_object_t * 332ucl_object_frombool (bool bv) 333{ 334 ucl_object_t *obj; | 277UCL_EXTERN ucl_object_t* ucl_object_frombool (bool bv); |
335 | 278 |
336 obj = ucl_object_new (); 337 if (obj != NULL) { 338 obj->type = UCL_BOOLEAN; 339 obj->value.iv = bv; 340 } 341 342 return obj; 343} 344 | |
345/** 346 * Insert a object 'elt' to the hash 'top' and associate it with key 'key' 347 * @param top destination object (will be created automatically if top is NULL) 348 * @param elt element to insert (must NOT be NULL) 349 * @param key key to associate with this object (either const or preallocated) 350 * @param keylen length of the key (or 0 for NULL terminated keys) 351 * @param copy_key make an internal copy of key 352 * @return new value of top object --- 24 unchanged lines hidden (view full) --- 377 378/** 379 * Delete a object associated with key 'key', old object will be unrefered, 380 * @param top object 381 * @param key key associated to the object to remove 382 */ 383UCL_EXTERN bool ucl_object_delete_key (ucl_object_t *top, const char *key); 384 | 279/** 280 * Insert a object 'elt' to the hash 'top' and associate it with key 'key' 281 * @param top destination object (will be created automatically if top is NULL) 282 * @param elt element to insert (must NOT be NULL) 283 * @param key key to associate with this object (either const or preallocated) 284 * @param keylen length of the key (or 0 for NULL terminated keys) 285 * @param copy_key make an internal copy of key 286 * @return new value of top object --- 24 unchanged lines hidden (view full) --- 311 312/** 313 * Delete a object associated with key 'key', old object will be unrefered, 314 * @param top object 315 * @param key key associated to the object to remove 316 */ 317UCL_EXTERN bool ucl_object_delete_key (ucl_object_t *top, const char *key); 318 |
319 |
|
385/** | 320/** |
321 * Delete key from `top` object returning the object deleted. This object is not 322 * released 323 * @param top object 324 * @param key key to remove 325 * @param keylen length of the key (or 0 for NULL terminated keys) 326 * @return removed object or NULL if object has not been found 327 */ 328UCL_EXTERN ucl_object_t* ucl_object_pop_keyl (ucl_object_t *top, const char *key, 329 size_t keylen) UCL_WARN_UNUSED_RESULT; 330 331/** 332 * Delete key from `top` object returning the object deleted. This object is not 333 * released 334 * @param top object 335 * @param key key to remove 336 * @return removed object or NULL if object has not been found 337 */ 338UCL_EXTERN ucl_object_t* ucl_object_pop_key (ucl_object_t *top, const char *key) 339 UCL_WARN_UNUSED_RESULT; 340 341/** |
|
386 * Insert a object 'elt' to the hash 'top' and associate it with key 'key', if the specified key exist, 387 * try to merge its content 388 * @param top destination object (will be created automatically if top is NULL) 389 * @param elt element to insert (must NOT be NULL) 390 * @param key key to associate with this object (either const or preallocated) 391 * @param keylen length of the key (or 0 for NULL terminated keys) 392 * @param copy_key make an internal copy of key 393 * @return new value of top object 394 */ 395UCL_EXTERN ucl_object_t* ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *elt, 396 const char *key, size_t keylen, bool copy_key) UCL_WARN_UNUSED_RESULT; 397 398/** 399 * Append an element to the front of array object 400 * @param top destination object (will be created automatically if top is NULL) 401 * @param elt element to append (must NOT be NULL) 402 * @return new value of top object 403 */ | 342 * Insert a object 'elt' to the hash 'top' and associate it with key 'key', if the specified key exist, 343 * try to merge its content 344 * @param top destination object (will be created automatically if top is NULL) 345 * @param elt element to insert (must NOT be NULL) 346 * @param key key to associate with this object (either const or preallocated) 347 * @param keylen length of the key (or 0 for NULL terminated keys) 348 * @param copy_key make an internal copy of key 349 * @return new value of top object 350 */ 351UCL_EXTERN ucl_object_t* ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *elt, 352 const char *key, size_t keylen, bool copy_key) UCL_WARN_UNUSED_RESULT; 353 354/** 355 * Append an element to the front of array object 356 * @param top destination object (will be created automatically if top is NULL) 357 * @param elt element to append (must NOT be NULL) 358 * @return new value of top object 359 */ |
404static inline ucl_object_t * ucl_array_append (ucl_object_t *top, | 360UCL_EXTERN ucl_object_t* ucl_array_append (ucl_object_t *top, |
405 ucl_object_t *elt) UCL_WARN_UNUSED_RESULT; | 361 ucl_object_t *elt) UCL_WARN_UNUSED_RESULT; |
406static inline ucl_object_t * 407ucl_array_append (ucl_object_t *top, ucl_object_t *elt) 408{ 409 ucl_object_t *head; | |
410 | 362 |
411 if (elt == NULL) { 412 return NULL; 413 } 414 415 if (top == NULL) { 416 top = ucl_object_typed_new (UCL_ARRAY); 417 top->value.av = elt; 418 elt->next = NULL; 419 elt->prev = elt; 420 top->len = 1; 421 } 422 else { 423 head = top->value.av; 424 if (head == NULL) { 425 top->value.av = elt; 426 elt->prev = elt; 427 } 428 else { 429 elt->prev = head->prev; 430 head->prev->next = elt; 431 head->prev = elt; 432 } 433 elt->next = NULL; 434 top->len ++; 435 } 436 437 return top; 438} 439 | |
440/** 441 * Append an element to the start of array object 442 * @param top destination object (will be created automatically if top is NULL) 443 * @param elt element to append (must NOT be NULL) 444 * @return new value of top object 445 */ | 363/** 364 * Append an element to the start of array object 365 * @param top destination object (will be created automatically if top is NULL) 366 * @param elt element to append (must NOT be NULL) 367 * @return new value of top object 368 */ |
446static inline ucl_object_t * ucl_array_prepend (ucl_object_t *top, | 369UCL_EXTERN ucl_object_t* ucl_array_prepend (ucl_object_t *top, |
447 ucl_object_t *elt) UCL_WARN_UNUSED_RESULT; | 370 ucl_object_t *elt) UCL_WARN_UNUSED_RESULT; |
448static inline ucl_object_t * 449ucl_array_prepend (ucl_object_t *top, ucl_object_t *elt) 450{ 451 ucl_object_t *head; | |
452 | 371 |
453 if (elt == NULL) { 454 return NULL; 455 } 456 457 if (top == NULL) { 458 top = ucl_object_typed_new (UCL_ARRAY); 459 top->value.av = elt; 460 elt->next = NULL; 461 elt->prev = elt; 462 top->len = 1; 463 } 464 else { 465 head = top->value.av; 466 if (head == NULL) { 467 top->value.av = elt; 468 elt->prev = elt; 469 } 470 else { 471 elt->prev = head->prev; 472 head->prev = elt; 473 } 474 elt->next = head; 475 top->value.av = elt; 476 top->len ++; 477 } 478 479 return top; 480} 481 | |
482/** 483 * Removes an element `elt` from the array `top`. Caller must unref the returned object when it is not 484 * needed. 485 * @param top array ucl object 486 * @param elt element to remove 487 * @return removed element or NULL if `top` is NULL or not an array 488 */ | 372/** 373 * Removes an element `elt` from the array `top`. Caller must unref the returned object when it is not 374 * needed. 375 * @param top array ucl object 376 * @param elt element to remove 377 * @return removed element or NULL if `top` is NULL or not an array 378 */ |
489static inline ucl_object_t * 490ucl_array_delete (ucl_object_t *top, ucl_object_t *elt) 491{ 492 ucl_object_t *head; | 379UCL_EXTERN ucl_object_t* ucl_array_delete (ucl_object_t *top, ucl_object_t *elt); |
493 | 380 |
494 if (top == NULL || top->type != UCL_ARRAY || top->value.av == NULL) { 495 return NULL; 496 } 497 head = top->value.av; 498 499 if (elt->prev == elt) { 500 top->value.av = NULL; 501 } 502 else if (elt == head) { 503 elt->next->prev = elt->prev; 504 top->value.av = elt->next; 505 } 506 else { 507 elt->prev->next = elt->next; 508 if (elt->next) { 509 elt->next->prev = elt->prev; 510 } 511 else { 512 head->prev = elt->prev; 513 } 514 } 515 elt->next = NULL; 516 elt->prev = elt; 517 top->len --; 518 519 return elt; 520} 521 | |
522/** 523 * Returns the first element of the array `top` 524 * @param top array ucl object 525 * @return element or NULL if `top` is NULL or not an array 526 */ | 381/** 382 * Returns the first element of the array `top` 383 * @param top array ucl object 384 * @return element or NULL if `top` is NULL or not an array 385 */ |
527static inline ucl_object_t * 528ucl_array_head (ucl_object_t *top) 529{ 530 if (top == NULL || top->type != UCL_ARRAY || top->value.av == NULL) { 531 return NULL; 532 } 533 return top->value.av; 534} | 386UCL_EXTERN ucl_object_t* ucl_array_head (ucl_object_t *top); |
535 536/** 537 * Returns the last element of the array `top` 538 * @param top array ucl object 539 * @return element or NULL if `top` is NULL or not an array 540 */ | 387 388/** 389 * Returns the last element of the array `top` 390 * @param top array ucl object 391 * @return element or NULL if `top` is NULL or not an array 392 */ |
541static inline ucl_object_t * 542ucl_array_tail (ucl_object_t *top) 543{ 544 if (top == NULL || top->type != UCL_ARRAY || top->value.av == NULL) { 545 return NULL; 546 } 547 return top->value.av->prev; 548} | 393UCL_EXTERN ucl_object_t* ucl_array_tail (ucl_object_t *top); |
549 550/** 551 * Removes the last element from the array `top`. Caller must unref the returned object when it is not 552 * needed. 553 * @param top array ucl object 554 * @return removed element or NULL if `top` is NULL or not an array 555 */ | 394 395/** 396 * Removes the last element from the array `top`. Caller must unref the returned object when it is not 397 * needed. 398 * @param top array ucl object 399 * @return removed element or NULL if `top` is NULL or not an array 400 */ |
556static inline ucl_object_t * 557ucl_array_pop_last (ucl_object_t *top) 558{ 559 return ucl_array_delete (top, ucl_array_tail (top)); 560} | 401UCL_EXTERN ucl_object_t* ucl_array_pop_last (ucl_object_t *top); |
561 562/** 563 * Removes the first element from the array `top`. Caller must unref the returned object when it is not 564 * needed. 565 * @param top array ucl object 566 * @return removed element or NULL if `top` is NULL or not an array 567 */ | 402 403/** 404 * Removes the first element from the array `top`. Caller must unref the returned object when it is not 405 * needed. 406 * @param top array ucl object 407 * @return removed element or NULL if `top` is NULL or not an array 408 */ |
568static inline ucl_object_t * 569ucl_array_pop_first (ucl_object_t *top) 570{ 571 return ucl_array_delete (top, ucl_array_head (top)); 572} | 409UCL_EXTERN ucl_object_t* ucl_array_pop_first (ucl_object_t *top); |
573 574/** 575 * Append a element to another element forming an implicit array 576 * @param head head to append (may be NULL) 577 * @param elt new element 578 * @return new head if applicable 579 */ | 410 411/** 412 * Append a element to another element forming an implicit array 413 * @param head head to append (may be NULL) 414 * @param elt new element 415 * @return new head if applicable 416 */ |
580static inline ucl_object_t * ucl_elt_append (ucl_object_t *head, | 417UCL_EXTERN ucl_object_t* ucl_elt_append (ucl_object_t *head, |
581 ucl_object_t *elt) UCL_WARN_UNUSED_RESULT; | 418 ucl_object_t *elt) UCL_WARN_UNUSED_RESULT; |
582static inline ucl_object_t * 583ucl_elt_append (ucl_object_t *head, ucl_object_t *elt) 584{ | |
585 | 419 |
586 if (head == NULL) { 587 elt->next = NULL; 588 elt->prev = elt; 589 head = elt; 590 } 591 else { 592 elt->prev = head->prev; 593 head->prev->next = elt; 594 head->prev = elt; 595 elt->next = NULL; 596 } 597 598 return head; 599} 600 | |
601/** 602 * Converts an object to double value 603 * @param obj CL object 604 * @param target target double variable 605 * @return true if conversion was successful 606 */ | 420/** 421 * Converts an object to double value 422 * @param obj CL object 423 * @param target target double variable 424 * @return true if conversion was successful 425 */ |
607static inline bool 608ucl_object_todouble_safe (ucl_object_t *obj, double *target) 609{ 610 if (obj == NULL) { 611 return false; 612 } 613 switch (obj->type) { 614 case UCL_INT: 615 *target = obj->value.iv; /* Probaly could cause overflow */ 616 break; 617 case UCL_FLOAT: 618 case UCL_TIME: 619 *target = obj->value.dv; 620 break; 621 default: 622 return false; 623 } | 426UCL_EXTERN bool ucl_object_todouble_safe (ucl_object_t *obj, double *target); |
624 | 427 |
625 return true; 626} 627 | |
628/** 629 * Unsafe version of \ref ucl_obj_todouble_safe 630 * @param obj CL object 631 * @return double value 632 */ | 428/** 429 * Unsafe version of \ref ucl_obj_todouble_safe 430 * @param obj CL object 431 * @return double value 432 */ |
633static inline double 634ucl_object_todouble (ucl_object_t *obj) 635{ 636 double result = 0.; | 433UCL_EXTERN double ucl_object_todouble (ucl_object_t *obj); |
637 | 434 |
638 ucl_object_todouble_safe (obj, &result); 639 return result; 640} 641 | |
642/** 643 * Converts an object to integer value 644 * @param obj CL object 645 * @param target target integer variable 646 * @return true if conversion was successful 647 */ | 435/** 436 * Converts an object to integer value 437 * @param obj CL object 438 * @param target target integer variable 439 * @return true if conversion was successful 440 */ |
648static inline bool 649ucl_object_toint_safe (ucl_object_t *obj, int64_t *target) 650{ 651 if (obj == NULL) { 652 return false; 653 } 654 switch (obj->type) { 655 case UCL_INT: 656 *target = obj->value.iv; 657 break; 658 case UCL_FLOAT: 659 case UCL_TIME: 660 *target = obj->value.dv; /* Loosing of decimal points */ 661 break; 662 default: 663 return false; 664 } | 441UCL_EXTERN bool ucl_object_toint_safe (ucl_object_t *obj, int64_t *target); |
665 | 442 |
666 return true; 667} 668 | |
669/** 670 * Unsafe version of \ref ucl_obj_toint_safe 671 * @param obj CL object 672 * @return int value 673 */ | 443/** 444 * Unsafe version of \ref ucl_obj_toint_safe 445 * @param obj CL object 446 * @return int value 447 */ |
674static inline int64_t 675ucl_object_toint (ucl_object_t *obj) 676{ 677 int64_t result = 0; | 448UCL_EXTERN int64_t ucl_object_toint (ucl_object_t *obj); |
678 | 449 |
679 ucl_object_toint_safe (obj, &result); 680 return result; 681} 682 | |
683/** 684 * Converts an object to boolean value 685 * @param obj CL object 686 * @param target target boolean variable 687 * @return true if conversion was successful 688 */ | 450/** 451 * Converts an object to boolean value 452 * @param obj CL object 453 * @param target target boolean variable 454 * @return true if conversion was successful 455 */ |
689static inline bool 690ucl_object_toboolean_safe (ucl_object_t *obj, bool *target) 691{ 692 if (obj == NULL) { 693 return false; 694 } 695 switch (obj->type) { 696 case UCL_BOOLEAN: 697 *target = (obj->value.iv == true); 698 break; 699 default: 700 return false; 701 } | 456UCL_EXTERN bool ucl_object_toboolean_safe (ucl_object_t *obj, bool *target); |
702 | 457 |
703 return true; 704} 705 | |
706/** 707 * Unsafe version of \ref ucl_obj_toboolean_safe 708 * @param obj CL object 709 * @return boolean value 710 */ | 458/** 459 * Unsafe version of \ref ucl_obj_toboolean_safe 460 * @param obj CL object 461 * @return boolean value 462 */ |
711static inline bool 712ucl_object_toboolean (ucl_object_t *obj) 713{ 714 bool result = false; | 463UCL_EXTERN bool ucl_object_toboolean (ucl_object_t *obj); |
715 | 464 |
716 ucl_object_toboolean_safe (obj, &result); 717 return result; 718} 719 | |
720/** 721 * Converts an object to string value 722 * @param obj CL object 723 * @param target target string variable, no need to free value 724 * @return true if conversion was successful 725 */ | 465/** 466 * Converts an object to string value 467 * @param obj CL object 468 * @param target target string variable, no need to free value 469 * @return true if conversion was successful 470 */ |
726static inline bool 727ucl_object_tostring_safe (ucl_object_t *obj, const char **target) 728{ 729 if (obj == NULL) { 730 return false; 731 } | 471UCL_EXTERN bool ucl_object_tostring_safe (ucl_object_t *obj, const char **target); |
732 | 472 |
733 switch (obj->type) { 734 case UCL_STRING: 735 *target = ucl_copy_value_trash (obj); 736 break; 737 default: 738 return false; 739 } 740 741 return true; 742} 743 | |
744/** 745 * Unsafe version of \ref ucl_obj_tostring_safe 746 * @param obj CL object 747 * @return string value 748 */ | 473/** 474 * Unsafe version of \ref ucl_obj_tostring_safe 475 * @param obj CL object 476 * @return string value 477 */ |
749static inline const char * 750ucl_object_tostring (ucl_object_t *obj) 751{ 752 const char *result = NULL; | 478UCL_EXTERN const char* ucl_object_tostring (ucl_object_t *obj); |
753 | 479 |
754 ucl_object_tostring_safe (obj, &result); 755 return result; 756} 757 | |
758/** 759 * Convert any object to a string in JSON notation if needed 760 * @param obj CL object 761 * @return string value 762 */ | 480/** 481 * Convert any object to a string in JSON notation if needed 482 * @param obj CL object 483 * @return string value 484 */ |
763static inline const char * 764ucl_object_tostring_forced (ucl_object_t *obj) 765{ 766 return ucl_copy_value_trash (obj); 767} | 485UCL_EXTERN const char* ucl_object_tostring_forced (ucl_object_t *obj); |
768 769/** 770 * Return string as char * and len, string may be not zero terminated, more efficient that \ref ucl_obj_tostring as it 771 * allows zero-copy (if #UCL_PARSER_ZEROCOPY has been used during parsing) 772 * @param obj CL object 773 * @param target target string variable, no need to free value 774 * @param tlen target length 775 * @return true if conversion was successful 776 */ | 486 487/** 488 * Return string as char * and len, string may be not zero terminated, more efficient that \ref ucl_obj_tostring as it 489 * allows zero-copy (if #UCL_PARSER_ZEROCOPY has been used during parsing) 490 * @param obj CL object 491 * @param target target string variable, no need to free value 492 * @param tlen target length 493 * @return true if conversion was successful 494 */ |
777static inline bool 778ucl_object_tolstring_safe (ucl_object_t *obj, const char **target, size_t *tlen) 779{ 780 if (obj == NULL) { 781 return false; 782 } 783 switch (obj->type) { 784 case UCL_STRING: 785 *target = obj->value.sv; 786 *tlen = obj->len; 787 break; 788 default: 789 return false; 790 } | 495UCL_EXTERN bool ucl_object_tolstring_safe (ucl_object_t *obj, 496 const char **target, size_t *tlen); |
791 | 497 |
792 return true; 793} 794 | |
795/** 796 * Unsafe version of \ref ucl_obj_tolstring_safe 797 * @param obj CL object 798 * @return string value 799 */ | 498/** 499 * Unsafe version of \ref ucl_obj_tolstring_safe 500 * @param obj CL object 501 * @return string value 502 */ |
800static inline const char * 801ucl_object_tolstring (ucl_object_t *obj, size_t *tlen) 802{ 803 const char *result = NULL; | 503UCL_EXTERN const char* ucl_object_tolstring (ucl_object_t *obj, size_t *tlen); |
804 | 504 |
805 ucl_object_tolstring_safe (obj, &result, tlen); 806 return result; 807} 808 | |
809/** 810 * Return object identified by a key in the specified object 811 * @param obj object to get a key from (must be of type UCL_OBJECT) 812 * @param key key to search 813 * @return object matched the specified key or NULL if key is not found 814 */ | 505/** 506 * Return object identified by a key in the specified object 507 * @param obj object to get a key from (must be of type UCL_OBJECT) 508 * @param key key to search 509 * @return object matched the specified key or NULL if key is not found 510 */ |
815UCL_EXTERN ucl_object_t * ucl_object_find_key (ucl_object_t *obj, const char *key); | 511UCL_EXTERN ucl_object_t* ucl_object_find_key (ucl_object_t *obj, const char *key); |
816 817/** 818 * Return object identified by a fixed size key in the specified object 819 * @param obj object to get a key from (must be of type UCL_OBJECT) 820 * @param key key to search 821 * @param klen length of a key 822 * @return object matched the specified key or NULL if key is not found 823 */ | 512 513/** 514 * Return object identified by a fixed size key in the specified object 515 * @param obj object to get a key from (must be of type UCL_OBJECT) 516 * @param key key to search 517 * @param klen length of a key 518 * @return object matched the specified key or NULL if key is not found 519 */ |
824UCL_EXTERN ucl_object_t *ucl_object_find_keyl (ucl_object_t *obj, const char *key, size_t klen); | 520UCL_EXTERN ucl_object_t* ucl_object_find_keyl (ucl_object_t *obj, const char *key, size_t klen); |
825 826/** 827 * Returns a key of an object as a NULL terminated string 828 * @param obj CL object 829 * @return key or NULL if there is no key 830 */ | 521 522/** 523 * Returns a key of an object as a NULL terminated string 524 * @param obj CL object 525 * @return key or NULL if there is no key 526 */ |
831static inline const char * 832ucl_object_key (ucl_object_t *obj) 833{ 834 return ucl_copy_key_trash (obj); 835} | 527UCL_EXTERN const char* ucl_object_key (ucl_object_t *obj); |
836 837/** 838 * Returns a key of an object as a fixed size string (may be more efficient) 839 * @param obj CL object 840 * @param len target key length 841 * @return key pointer 842 */ | 528 529/** 530 * Returns a key of an object as a fixed size string (may be more efficient) 531 * @param obj CL object 532 * @param len target key length 533 * @return key pointer 534 */ |
843static inline const char * 844ucl_object_keyl (ucl_object_t *obj, size_t *len) 845{ 846 *len = obj->keylen; 847 return obj->key; 848} | 535UCL_EXTERN const char* ucl_object_keyl (ucl_object_t *obj, size_t *len); |
849 850/** 851 * Free ucl object 852 * @param obj ucl object to free 853 */ 854UCL_EXTERN void ucl_object_free (ucl_object_t *obj); 855 856/** 857 * Increase reference count for an object 858 * @param obj object to ref 859 */ | 536 537/** 538 * Free ucl object 539 * @param obj ucl object to free 540 */ 541UCL_EXTERN void ucl_object_free (ucl_object_t *obj); 542 543/** 544 * Increase reference count for an object 545 * @param obj object to ref 546 */ |
860static inline ucl_object_t * 861ucl_object_ref (ucl_object_t *obj) { 862 obj->ref ++; 863 return obj; 864} | 547UCL_EXTERN ucl_object_t* ucl_object_ref (ucl_object_t *obj); |
865 866/** 867 * Decrease reference count for an object 868 * @param obj object to unref 869 */ | 548 549/** 550 * Decrease reference count for an object 551 * @param obj object to unref 552 */ |
870static inline void 871ucl_object_unref (ucl_object_t *obj) { 872 if (obj != NULL && --obj->ref <= 0) { 873 ucl_object_free (obj); 874 } 875} | 553UCL_EXTERN void ucl_object_unref (ucl_object_t *obj); 554 |
876/** | 555/** |
556 * Compare objects `o1` and `o2` 557 * @param o1 the first object 558 * @param o2 the second object 559 * @return values >0, 0 and <0 if `o1` is more than, equal and less than `o2`. 560 * The order of comparison: 561 * 1) Type of objects 562 * 2) Size of objects 563 * 3) Content of objects 564 */ 565UCL_EXTERN int ucl_object_compare (ucl_object_t *o1, ucl_object_t *o2); 566 567/** 568 * Sort UCL array using `cmp` compare function 569 * @param ar 570 * @param cmp 571 */ 572UCL_EXTERN void ucl_object_array_sort (ucl_object_t *ar, 573 int (*cmp)(ucl_object_t *o1, ucl_object_t *o2)); 574 575/** |
|
877 * Opaque iterator object 878 */ 879typedef void* ucl_object_iter_t; 880 881/** 882 * Get next key from an object 883 * @param obj object to iterate 884 * @param iter opaque iterator, must be set to NULL on the first call: --- 54 unchanged lines hidden (view full) --- 939/** 940 * Load new chunk to a parser 941 * @param parser parser structure 942 * @param data the pointer to the beginning of a chunk 943 * @param len the length of a chunk 944 * @param err if *err is NULL it is set to parser error 945 * @return true if chunk has been added and false in case of error 946 */ | 576 * Opaque iterator object 577 */ 578typedef void* ucl_object_iter_t; 579 580/** 581 * Get next key from an object 582 * @param obj object to iterate 583 * @param iter opaque iterator, must be set to NULL on the first call: --- 54 unchanged lines hidden (view full) --- 638/** 639 * Load new chunk to a parser 640 * @param parser parser structure 641 * @param data the pointer to the beginning of a chunk 642 * @param len the length of a chunk 643 * @param err if *err is NULL it is set to parser error 644 * @return true if chunk has been added and false in case of error 645 */ |
947UCL_EXTERN bool ucl_parser_add_chunk (struct ucl_parser *parser, const unsigned char *data, size_t len); | 646UCL_EXTERN bool ucl_parser_add_chunk (struct ucl_parser *parser, 647 const unsigned char *data, size_t len); |
948 949/** | 648 649/** |
650 * Load ucl object from a string 651 * @param parser parser structure 652 * @param data the pointer to the string 653 * @param len the length of the string, if `len` is 0 then `data` must be zero-terminated string 654 * @return true if string has been added and false in case of error 655 */ 656UCL_EXTERN bool ucl_parser_add_string (struct ucl_parser *parser, 657 const char *data,size_t len); 658 659/** |
|
950 * Load and add data from a file 951 * @param parser parser structure 952 * @param filename the name of file 953 * @param err if *err is NULL it is set to parser error 954 * @return true if chunk has been added and false in case of error 955 */ 956UCL_EXTERN bool ucl_parser_add_file (struct ucl_parser *parser, const char *filename); 957 --- 76 unchanged lines hidden (view full) --- 1034 * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is 1035 * #UCL_EMIT_CONFIG then emit config like object 1036 * @return dump of an object (must be freed after using) or NULL in case of error 1037 */ 1038UCL_EXTERN bool ucl_object_emit_full (ucl_object_t *obj, enum ucl_emitter emit_type, 1039 struct ucl_emitter_functions *emitter); 1040/** @} */ 1041 | 660 * Load and add data from a file 661 * @param parser parser structure 662 * @param filename the name of file 663 * @param err if *err is NULL it is set to parser error 664 * @return true if chunk has been added and false in case of error 665 */ 666UCL_EXTERN bool ucl_parser_add_file (struct ucl_parser *parser, const char *filename); 667 --- 76 unchanged lines hidden (view full) --- 744 * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is 745 * #UCL_EMIT_CONFIG then emit config like object 746 * @return dump of an object (must be freed after using) or NULL in case of error 747 */ 748UCL_EXTERN bool ucl_object_emit_full (ucl_object_t *obj, enum ucl_emitter emit_type, 749 struct ucl_emitter_functions *emitter); 750/** @} */ 751 |
752/** 753 * @defgroup schema Schema functions 754 * These functions are used to validate UCL objects using json schema format 755 * 756 * @{ 757 */ 758 759/** 760 * Used to define UCL schema error 761 */ 762enum ucl_schema_error_code { 763 UCL_SCHEMA_OK = 0, /**< no error */ 764 UCL_SCHEMA_TYPE_MISMATCH, /**< type of object is incorrect */ 765 UCL_SCHEMA_INVALID_SCHEMA, /**< schema is invalid */ 766 UCL_SCHEMA_MISSING_PROPERTY,/**< one or more missing properties */ 767 UCL_SCHEMA_CONSTRAINT, /**< constraint found */ 768 UCL_SCHEMA_MISSING_DEPENDENCY, /**< missing dependency */ 769 UCL_SCHEMA_UNKNOWN /**< generic error */ 770}; 771 772/** 773 * Generic ucl schema error 774 */ 775struct ucl_schema_error { 776 enum ucl_schema_error_code code; /**< error code */ 777 char msg[128]; /**< error message */ 778 ucl_object_t *obj; /**< object where error occured */ 779}; 780 781/** 782 * Validate object `obj` using schema object `schema`. 783 * @param schema schema object 784 * @param obj object to validate 785 * @param err error pointer, if this parameter is not NULL and error has been 786 * occured, then `err` is filled with the exact error definition. 787 * @return true if `obj` is valid using `schema` 788 */ 789UCL_EXTERN bool ucl_object_validate (ucl_object_t *schema, 790 ucl_object_t *obj, struct ucl_schema_error *err); 791 792/** @} */ 793 |
|
1042#ifdef __cplusplus 1043} 1044#endif 1045/* 1046 * XXX: Poorly named API functions, need to replace them with the appropriate 1047 * named function. All API functions *must* use naming ucl_object_*. Usage of 1048 * ucl_obj* should be avoided. 1049 */ --- 17 unchanged lines hidden --- | 794#ifdef __cplusplus 795} 796#endif 797/* 798 * XXX: Poorly named API functions, need to replace them with the appropriate 799 * named function. All API functions *must* use naming ucl_object_*. Usage of 800 * ucl_obj* should be avoided. 801 */ --- 17 unchanged lines hidden --- |