Soletta™ Framework
Framework for making IoT devices

Full online documentation | C API Index
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sol-json.h
Go to the documentation of this file.
1 /*
2  * This file is part of the Soletta (TM) Project
3  *
4  * Copyright (C) 2015 Intel Corporation. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #pragma once
20 
21 #include <assert.h>
22 #include <ctype.h>
23 #include <stdbool.h>
24 #include <stddef.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <stdint.h>
28 #include <sol-buffer.h>
29 #include <sol-macros.h>
30 #include <sol-str-slice.h>
31 #include <sol-buffer.h>
32 #include <sol-memdesc.h>
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
62 typedef struct sol_json_scanner {
63  const char *mem;
64  const char *mem_end;
65  const char *current;
67 
73 typedef struct sol_json_token {
74  const char *start;
75  const char *end;
77 
94 };
95 
107 };
108 
121 #define SOL_JSON_SCANNER_ARRAY_LOOP_TYPE_NESTED(scanner_, token_, element_type_, status_) \
122  for (status_ = SOL_JSON_LOOP_REASON_OK; \
123  sol_json_loop_iterate_array(scanner_, token_, &status_, element_type_);)
124 
135 #define SOL_JSON_SCANNER_ARRAY_LOOP_TYPE(scanner_, token_, element_type_, status_) \
136  for (status_ = sol_json_loop_iterate_init(scanner_, token_, SOL_JSON_TYPE_ARRAY_START); \
137  sol_json_loop_iterate_array(scanner_, token_, &status_, element_type_);)
138 
151 #define SOL_JSON_SCANNER_ARRAY_LOOP_NESTED(scanner_, token_, status_) \
152  for (status_ = SOL_JSON_LOOP_REASON_OK; \
153  sol_json_loop_iterate_generic(scanner_, token_, SOL_JSON_TYPE_ARRAY_END, &status_);)
154 
163 #define SOL_JSON_SCANNER_ARRAY_LOOP(scanner_, token_, status_) \
164  for (status_ = sol_json_loop_iterate_init(scanner_, token_, SOL_JSON_TYPE_ARRAY_START); \
165  sol_json_loop_iterate_generic(scanner_, token_, SOL_JSON_TYPE_ARRAY_END, &status_);)
166 
180 #define SOL_JSON_SCANNER_OBJECT_LOOP_NESTED(scanner_, token_, key_, value_, status_) \
181  for (status_ = SOL_JSON_LOOP_REASON_OK; \
182  sol_json_loop_iterate_object(scanner_, token_, key_, value_, &status_);)
183 
195 #define SOL_JSON_SCANNER_OBJECT_LOOP(scanner_, token_, key_, value_, status_) \
196  for (status_ = sol_json_loop_iterate_init(scanner_, token_, SOL_JSON_TYPE_OBJECT_START); \
197  sol_json_loop_iterate_object(scanner_, token_, key_, value_, &status_);)
198 
208 static inline void
209 sol_json_scanner_init(struct sol_json_scanner *scanner, const void *mem, size_t size)
210 {
211  scanner->mem = (const char *)mem;
212  scanner->mem_end = scanner->mem + size;
213  scanner->current = (const char *)mem;
214 }
215 
221 static inline void
223 {
224  scanner->mem = NULL;
225  scanner->mem_end = NULL;
226  scanner->current = NULL;
227 }
228 
235 static inline void
237 {
238  sol_json_scanner_init(scanner, slice.data, slice.len);
239 }
240 
247 static inline void
249 {
250  token->start = slice.data;
251  token->end = slice.data + slice.len;
252 }
253 
262 static inline void
264  const struct sol_json_scanner *other)
265 {
266  scanner->mem = other->mem;
267  scanner->mem_end = other->mem_end;
268  scanner->current = scanner->mem;
269 }
270 
279 static inline void
281  const struct sol_json_token *token)
282 {
283  scanner->mem = token->start;
284  scanner->mem_end = token->end;
285  scanner->current = scanner->mem;
286 }
287 
295 static inline size_t
297 {
298  return scanner->mem_end - scanner->current;
299 }
300 
311 static inline size_t
312 sol_json_scanner_get_mem_offset(const struct sol_json_scanner *scanner, const void *mem)
313 {
314  const char *p = (const char *)mem;
315 
316  if (p < scanner->mem || p > scanner->mem_end)
317  return (size_t)-1;
318  return p - scanner->mem;
319 }
320 
328 static inline enum sol_json_type
329 sol_json_mem_get_type(const void *mem)
330 {
331  const char *p = (const char *)mem;
332 
333  if (strchr("{}[],:tfn\"", *p))
334  return (enum sol_json_type)*p;
335  if (isdigit((uint8_t)*p) || *p == '-' || *p == '+')
336  return SOL_JSON_TYPE_NUMBER;
337  return SOL_JSON_TYPE_UNKNOWN;
338 }
339 
347 static inline enum sol_json_type
349 {
350  return sol_json_mem_get_type(token->start);
351 }
352 
360 static inline size_t
362 {
363  return token->end - token->start;
364 }
365 
378 static inline bool
379 sol_json_token_str_eq(const struct sol_json_token *token, const char *str, size_t len)
380 {
381  size_t size;
382 
384 
385  size = sol_json_token_get_size(token);
386  return (size == len + 2) && memcmp(token->start + 1, str, len) == 0;
387 }
388 
400 #define SOL_JSON_TOKEN_STR_LITERAL_EQ(token_, str_) \
401  sol_json_token_str_eq(token_, str_, sizeof(str_) - 1)
402 
417 int sol_json_token_get_uint64(const struct sol_json_token *token, uint64_t *value)
418 #ifndef DOXYGEN_RUN
420 #endif
421  ;
422 
437 int sol_json_token_get_int64(const struct sol_json_token *token, int64_t *value)
438 #ifndef DOXYGEN_RUN
439  SOL_ATTR_WARN_UNUSED_RESULT
440 #endif
441  ;
442 
457 static inline int
458 sol_json_token_get_uint32(const struct sol_json_token *token, uint32_t *value)
459 {
460  uint64_t tmp;
461  int r = sol_json_token_get_uint64(token, &tmp);
462 
463  if (tmp > UINT32_MAX) {
464  tmp = UINT32_MAX;
465  if (r == 0)
466  r = -ERANGE;
467  }
468 
469  *value = tmp;
470  return r;
471 }
472 
487 static inline int
488 sol_json_token_get_int32(const struct sol_json_token *token, int32_t *value)
489 {
490  int64_t tmp;
491  int r = sol_json_token_get_int64(token, &tmp);
492 
493  if (tmp > INT32_MAX) {
494  tmp = INT32_MAX;
495  if (r == 0)
496  r = -ERANGE;
497  } else if (tmp < INT32_MIN) {
498  tmp = INT32_MIN;
499  if (r == 0)
500  r = -ERANGE;
501  }
502 
503  *value = tmp;
504  return r;
505 }
506 
522 int sol_json_token_get_double(const struct sol_json_token *token, double *value) SOL_ATTR_WARN_UNUSED_RESULT;
523 
533 static inline struct sol_str_slice
535 {
536  return SOL_STR_SLICE_STR(token->start, (size_t)(token->end - token->start));
537 }
538 
547 bool sol_json_scanner_next(struct sol_json_scanner *scanner,
548  struct sol_json_token *token)
549 #ifndef DOXYGEN_RUN
550  SOL_ATTR_WARN_UNUSED_RESULT SOL_ATTR_NON_NULL(1, 2)
551 #endif
552  ;
553 
569 bool sol_json_scanner_skip(struct sol_json_scanner *scanner,
570  struct sol_json_token *token)
571 #ifndef DOXYGEN_RUN
572  SOL_ATTR_WARN_UNUSED_RESULT SOL_ATTR_NON_NULL(1, 2)
573 #endif
574  ;
575 
589  struct sol_json_token *key, struct sol_json_token *value)
590 #ifndef DOXYGEN_RUN
591  SOL_ATTR_WARN_UNUSED_RESULT SOL_ATTR_NON_NULL(1, 2, 3)
592 #endif
593  ;
594 
605 static inline bool
607  enum sol_json_type end_type, enum sol_json_loop_status *reason)
608 {
609  if (*reason != SOL_JSON_LOOP_REASON_OK)
610  return false;
611 
612  if (!sol_json_scanner_next(scanner, token)) {
614  return false;
615  }
616 
617  if (sol_json_token_get_type(token) == end_type) {
618  *reason = SOL_JSON_LOOP_REASON_OK;
619  return false;
620  }
621 
623  if (!sol_json_scanner_next(scanner, token)) {
625  return false;
626  }
627  }
628 
629  return true;
630 }
631 
642 static inline bool
644  enum sol_json_loop_status *reason, enum sol_json_type element_type)
645 {
646  if (!sol_json_loop_iterate_generic(scanner, token, SOL_JSON_TYPE_ARRAY_END, reason))
647  return false;
648 
649  if (sol_json_token_get_type(token) == element_type) {
650  *reason = SOL_JSON_LOOP_REASON_OK;
651  return true;
652  }
653 
655  return false;
656 }
657 
669 static inline bool
671  struct sol_json_token *key, struct sol_json_token *value, enum sol_json_loop_status *reason)
672 {
673  if (!sol_json_loop_iterate_generic(scanner, token, SOL_JSON_TYPE_OBJECT_END, reason))
674  return false;
675 
676  *key = *token;
677  if (!sol_json_scanner_get_dict_pair(scanner, key, value)) {
679  return false;
680  }
681 
682  *reason = SOL_JSON_LOOP_REASON_OK;
683  return true;
684 }
685 
695 static inline enum sol_json_loop_status
697  enum sol_json_type start_type)
698 {
699  if (!sol_json_scanner_next(scanner, token))
701  if (sol_json_token_get_type(token) != start_type)
704 }
705 
713 size_t sol_json_calculate_escaped_string_len(const char *str);
714 
723 char *sol_json_escape_string(const char *str, struct sol_buffer *buf);
724 
733 int sol_json_double_to_str(const double value, struct sol_buffer *buf);
734 
746 bool sol_json_is_valid_type(struct sol_json_scanner *scanner, enum sol_json_type start_type)
747 #ifndef DOXYGEN_RUN
749 #endif
750  ;
751 
763 int sol_json_serialize_string(struct sol_buffer *buffer, const char *str);
764 
774 int sol_json_serialize_double(struct sol_buffer *buffer, double val);
775 
785 int sol_json_serialize_int32(struct sol_buffer *buffer, int32_t val);
786 
796 int sol_json_serialize_uint32(struct sol_buffer *buffer, uint32_t val);
797 
807 int sol_json_serialize_int64(struct sol_buffer *buffer, int64_t val);
808 
818 int sol_json_serialize_uint64(struct sol_buffer *buffer, uint64_t val);
819 
829 int sol_json_serialize_bool(struct sol_buffer *buffer, bool val);
830 
838 static inline int
840 {
841  static const struct sol_str_slice null = SOL_STR_SLICE_LITERAL("null");
842 
843  return sol_buffer_append_slice(buffer, null);
844 }
845 
863 int sol_json_serialize_memdesc(struct sol_buffer *buffer, const struct sol_memdesc *desc, const void *memory, bool detailed_structures);
864 
889 int sol_json_load_memdesc(const struct sol_json_token *token, const struct sol_memdesc *desc, void *memory);
890 
908 int sol_json_token_get_unescaped_string(const struct sol_json_token *token, struct sol_buffer *buffer);
909 
921 
938 int sol_json_object_get_value_by_key(struct sol_json_scanner *scanner, const struct sol_str_slice key_slice, struct sol_json_token *value);
939 
955 int sol_json_array_get_at_index(struct sol_json_scanner *scanner, uint16_t i, struct sol_json_token *value);
956 
966 typedef struct sol_json_path_scanner {
967  const char *path;
968  const char *end;
973  const char *current;
975 
995 int sol_json_get_value_by_path(struct sol_json_scanner *scanner, struct sol_str_slice path, struct sol_json_token *value);
996 
1010 int sol_json_path_scanner_init(struct sol_json_path_scanner *scanner, struct sol_str_slice path)
1011 #ifndef DOXYGEN_RUN
1013 #endif
1014  ;
1015 
1033 bool sol_json_path_get_next_segment(struct sol_json_path_scanner *scanner, struct sol_str_slice *slice, enum sol_json_loop_status *status)
1034 #ifndef DOXYGEN_RUN
1035  SOL_ATTR_NON_NULL(1, 2, 3)
1036 #endif
1037  ;
1038 
1055 
1066 static inline bool
1068 {
1069  return slice.data && slice.len >= 2 &&
1070  slice.data[0] == '[' && //is between brackets or
1071  slice.data[1] != '\''; //index is not a string
1072 }
1073 
1118 #define SOL_JSON_PATH_FOREACH(scanner, key, status) \
1119  for (status = SOL_JSON_LOOP_REASON_OK; \
1120  sol_json_path_get_next_segment(&scanner, &key_slice, &status);)
1121 
1126 #ifdef __cplusplus
1127 }
1128 #endif
static size_t sol_json_scanner_get_size_remaining(const struct sol_json_scanner *scanner)
Returns the size of the JSON document that wasn't scanned yet.
Definition: sol-json.h:296
int sol_json_token_get_int64(const struct sol_json_token *token, int64_t *value)
Get the numeric value of the given token as an 64 bits signed integer.
static void sol_json_scanner_init_from_slice(struct sol_json_scanner *scanner, const struct sol_str_slice slice)
Initialized a JSON scanner from a struct sol_str_slice.
Definition: sol-json.h:236
'null' value
Definition: sol-json.h:91
static int sol_json_token_get_uint32(const struct sol_json_token *token, uint32_t *value)
Get the numeric value of the given token as an 32 bits unsigned integer.
Definition: sol-json.h:458
Unknown token.
Definition: sol-json.h:82
static void sol_json_scanner_init(struct sol_json_scanner *scanner, const void *mem, size_t size)
Initializes a JSON scanner.
Definition: sol-json.h:209
int sol_json_serialize_uint32(struct sol_buffer *buffer, uint32_t val)
Inserts the string of the unsigned 32-bit integer val in the end of the JSON document contained in bu...
const char * start
Token start.
Definition: sol-json.h:74
JSON Pair separator.
Definition: sol-json.h:88
static size_t sol_json_scanner_get_mem_offset(const struct sol_json_scanner *scanner, const void *mem)
Returns the offset of mem in the data managed by scanner.
Definition: sol-json.h:312
const char * end
Points to last character from path.
Definition: sol-json.h:968
int sol_json_get_value_by_path(struct sol_json_scanner *scanner, struct sol_str_slice path, struct sol_json_token *value)
Get the element referenced by the JSON Path path in a JSON Object or Array.
static void sol_json_scanner_init_from_scanner(struct sol_json_scanner *scanner, const struct sol_json_scanner *other)
Initializes a JSON scanner based on the information of a second scanner.
Definition: sol-json.h:263
int sol_json_token_get_uint64(const struct sol_json_token *token, uint64_t *value)
Get the numeric value of the given token as an 64 bits unsigned integer.
const char * mem_end
End of this portion of the JSON document.
Definition: sol-json.h:64
char * sol_json_escape_string(const char *str, struct sol_buffer *buf)
Escapes JSON special and control characters from the string content.
int sol_json_load_memdesc(const struct sol_json_token *token, const struct sol_memdesc *desc, void *memory)
Loads the members of a memory from JSON according to its description.
int sol_json_array_get_at_index(struct sol_json_scanner *scanner, uint16_t i, struct sol_json_token *value)
Get the element in position i in JSON Array contained in scanner.
int32_t sol_json_path_array_get_segment_index(struct sol_str_slice key)
Get the integer index from a JSON Path array segment.
size_t sol_json_calculate_escaped_string_len(const char *str)
Calculate the size in bytes of the escaped version of a string.
Scanner used to go through segments of a JSON Path.
Definition: sol-json.h:966
bool sol_json_scanner_skip(struct sol_json_scanner *scanner, struct sol_json_token *token)
Modifies scanner to point to token end, skipping over the token content.
Failed to parse the content.
Definition: sol-json.h:106
const char * current
Points to last visited position from path and the beginning of next segment.
Definition: sol-json.h:973
struct sol_json_token sol_json_token
Type describing a JSON token.
static bool sol_json_loop_iterate_object(struct sol_json_scanner *scanner, struct sol_json_token *token, struct sol_json_token *key, struct sol_json_token *value, enum sol_json_loop_status *reason)
Function to help iterate over a JSON object.
Definition: sol-json.h:670
bool sol_json_is_valid_type(struct sol_json_scanner *scanner, enum sol_json_type start_type)
Check if scanner content is pointing to a valid JSON element of type start_type.
static int sol_json_serialize_null(struct sol_buffer *buffer)
Inserts the string "null" in the end of the JSON document contained in buffer.
Definition: sol-json.h:839
These are common Soletta macros.
const char * current
Current point in the JSON document that needs to be processed.
Definition: sol-json.h:65
JSON Array start.
Definition: sol-json.h:85
static struct sol_buffer value
Definition: server.c:42
const char * path
The JSONPath string.
Definition: sol-json.h:967
static bool sol_json_loop_iterate_array(struct sol_json_scanner *scanner, struct sol_json_token *token, enum sol_json_loop_status *reason, enum sol_json_type element_type)
Function to help iterate over a JSON array.
Definition: sol-json.h:643
static void sol_json_token_init_from_slice(struct sol_json_token *token, const struct sol_str_slice slice)
Initialized a JSON token from a struct sol_str_slice.
Definition: sol-json.h:248
int sol_json_serialize_int64(struct sol_buffer *buffer, int64_t val)
Inserts the string of the 64-bit integer val in the end of the JSON document contained in buffer...
String slice type.
Definition: sol-str-slice.h:84
static struct sol_cert * key
Definition: server-https.c:51
These are routines that Soletta provides for its buffer implementation.
bool sol_json_scanner_get_dict_pair(struct sol_json_scanner *scanner, struct sol_json_token *key, struct sol_json_token *value)
Retrieve <key, value> pair currently pointed by scanner.
static enum sol_json_type sol_json_mem_get_type(const void *mem)
Returns the type of the token pointed by mem.
Definition: sol-json.h:329
#define SOL_ATTR_WARN_UNUSED_RESULT
Causes a warning to be emitted if a caller of the function with this attribute does not use its retur...
Definition: sol-macros.h:187
int sol_json_serialize_double(struct sol_buffer *buffer, double val)
Inserts the string of the double val in the end of the JSON document contained in buffer...
These are routines that Soletta provides for its memory description (memdesc) implementation.
Type describing a JSON token.
Definition: sol-json.h:73
char * sol_json_token_get_unescaped_string_copy(const struct sol_json_token *value)
Creates a copy of the unescaped and no-quotes string produced by sol_json_token_get_unescaped_string...
int sol_json_serialize_string(struct sol_buffer *buffer, const char *str)
Inserts the string str in the end of the JSON document contained in buffer.
int sol_json_path_scanner_init(struct sol_json_path_scanner *scanner, struct sol_str_slice path)
Initialize a JSON Path scanner with path.
int sol_json_object_get_value_by_key(struct sol_json_scanner *scanner, const struct sol_str_slice key_slice, struct sol_json_token *value)
Get the value of the JSON Object child element referenced by key_slice.
static enum sol_json_type sol_json_token_get_type(const struct sol_json_token *token)
Returns the type of the token pointed by token.
Definition: sol-json.h:348
int sol_json_token_get_double(const struct sol_json_token *token, double *value) SOL_ATTR_WARN_UNUSED_RESULT
Get the numeric value of the given token as double-precision floating point.
JSON Array end.
Definition: sol-json.h:86
int sol_buffer_append_slice(struct sol_buffer *buf, const struct sol_str_slice slice)
Appends slice into the end of buf, reallocating if necessary.
const char * data
Slice data.
Definition: sol-str-slice.h:86
struct sol_json_path_scanner sol_json_path_scanner
Scanner used to go through segments of a JSON Path.
bool sol_json_scanner_next(struct sol_json_scanner *scanner, struct sol_json_token *token)
Advance the scanner to the next JSON token.
int sol_json_serialize_uint64(struct sol_buffer *buffer, uint64_t val)
Inserts the string of the unsigned 64-bit integer val in the end of the JSON document contained in bu...
#define SOL_ATTR_NON_NULL(...)
Specifies that some function parameters should be non-null pointers.
Definition: sol-macros.h:193
int sol_json_serialize_memdesc(struct sol_buffer *buffer, const struct sol_memdesc *desc, const void *memory, bool detailed_structures)
Appends the serialization of the given memory based on its description.
#define SOL_STR_SLICE_STR(_s, _len)
Helper macro to make easier to declare a string slice from a string.
Definition: sol-str-slice.h:67
'true' value
Definition: sol-json.h:89
static bool sol_json_path_is_array_key(struct sol_str_slice slice)
Check if slice is a valid JSON Path array segment.
Definition: sol-json.h:1067
static void sol_json_scanner_init_from_token(struct sol_json_scanner *scanner, const struct sol_json_token *token)
Initializes a JSON scanner based on the information of a JSON Token.
Definition: sol-json.h:280
int sol_json_serialize_bool(struct sol_buffer *buffer, bool val)
Inserts the string of the boolean value val in the end of the JSON document contained in buffer...
const char * mem
Start of this portion of the JSON document.
Definition: sol-json.h:63
#define SOL_STR_SLICE_LITERAL(_s)
Helper macro to make easier to declare a string slice from a string literal.
Definition: sol-str-slice.h:62
Structure to track a JSON document (or a portion of it) being parsed.
Definition: sol-json.h:62
static bool sol_json_token_str_eq(const struct sol_json_token *token, const char *str, size_t len)
Checks if the string pointed by token is equal to the string str.
Definition: sol-json.h:379
JSON number token.
Definition: sol-json.h:93
static size_t sol_json_token_get_size(const struct sol_json_token *token)
Returns the token size.
Definition: sol-json.h:361
JSON Element separator.
Definition: sol-json.h:87
JSON string token.
Definition: sol-json.h:92
static bool sol_json_loop_iterate_generic(struct sol_json_scanner *scanner, struct sol_json_token *token, enum sol_json_type end_type, enum sol_json_loop_status *reason)
Function to help iterate over a generic JSON sequence.
Definition: sol-json.h:606
Data type to describe a memory region.
Definition: sol-memdesc.h:514
bool sol_json_path_get_next_segment(struct sol_json_path_scanner *scanner, struct sol_str_slice *slice, enum sol_json_loop_status *status)
Get next segment from JSON Path in scanner.
int sol_json_serialize_int32(struct sol_buffer *buffer, int32_t val)
Inserts the string of the 32-bit integer val in the end of the JSON document contained in buffer...
static int sol_json_token_get_int32(const struct sol_json_token *token, int32_t *value)
Get the numeric value of the given token as an 32 bits signed integer.
Definition: sol-json.h:488
int sol_json_token_get_unescaped_string(const struct sol_json_token *token, struct sol_buffer *buffer)
Copy to a sol_buffer the string pointed by token.
Content successfully parsed.
Definition: sol-json.h:105
These are routines that Soletta provides for its string slice implementation.
static enum sol_json_loop_status sol_json_loop_iterate_init(struct sol_json_scanner *scanner, struct sol_json_token *token, enum sol_json_type start_type)
Function to bootstrap an iteration over a JSON sequence.
Definition: sol-json.h:696
JSON Object start.
Definition: sol-json.h:83
sol_json_type
Token type enumeration.
Definition: sol-json.h:81
sol_json_loop_status
Return values used by the parser 'loop' macros.
Definition: sol-json.h:104
const char * end
Token end.
Definition: sol-json.h:75
static struct sol_str_slice sol_json_token_to_slice(const struct sol_json_token *token)
Converts a JSON token to a string slice.
Definition: sol-json.h:534
'false' value
Definition: sol-json.h:90
JSON Object end.
Definition: sol-json.h:84
A sol_buffer is a dynamic array, that can be resized if needed.
Definition: sol-buffer.h:130
struct sol_json_scanner sol_json_scanner
Structure to track a JSON document (or a portion of it) being parsed.
int sol_json_double_to_str(const double value, struct sol_buffer *buf)
Converts a double into a string suited for use in a JSON Document.
size_t len
Slice length.
Definition: sol-str-slice.h:85
static void sol_json_scanner_init_null(struct sol_json_scanner *scanner)
Initializes a JSON scanner with empty information.
Definition: sol-json.h:222