JST: JSON tools  1.0.0
JSON tools dynamic library for reading, manipulating and writing JSON tree
JST_save.c
Go to the documentation of this file.
1 #include "jstools.h"
2 
3 #include <stdio.h>
4 
5 static JST_Error save_element( const JST_Element * elt, FILE * stream, unsigned left_margin, unsigned indent );
6 
7 static JST_Error save_object( const JST_Object * object, FILE * stream, unsigned left_margin, unsigned indent ) {
8  for( JST_Pair * iter = object->first; iter; iter = iter->next ) {
9  fprintf( stream, "%*s\"%s\": ", left_margin, "", iter->name );
10  save_element( &(iter->element), stream, left_margin, indent );
11  fprintf( stream, "%s", ( iter->next == NULL ) ? "\n" : ",\n" );
12  }
13  return JST_ERR_NONE;
14 }
15 
16 static JST_Error save_array( const JST_Array * array, FILE * stream, unsigned left_margin, unsigned indent ) {
17  for( unsigned i = 0; i < array->count; ++i ) {
18  fprintf( stream, "%*s", left_margin, "" );
19  save_element( &(array->items[i]->element), stream, left_margin, indent );
20  fprintf( stream, "%s", ( i < array->count - 1 ) ? ",\n" : "\n" );
21  }
22  return JST_ERR_NONE;
23 }
24 
25 static JST_Error save_element( const JST_Element * elt, FILE * stream, unsigned left_margin, unsigned indent ) {
26  switch( elt->type ) {
27  case JST_OBJECT:
28  fprintf( stream, "{\n" );
29  save_object( &(elt->value.object), stream, left_margin+indent, indent );
30  fprintf( stream, "%*s}", left_margin, "" );
31  break;
32  case JST_ARRAY:
33  fprintf( stream, "[\n" );
34  save_array ( &(elt->value.array ), stream, left_margin+indent, indent );
35  fprintf( stream, "%*s]", left_margin, "" );
36  break;
37  case JST_BOOLEAN: fprintf( stream, "%s" , elt->value.boolean ? "true" : "false" ); break;
38  case JST_INTEGER: fprintf( stream, "%ld" , elt->value.integer ); break;
39  case JST_DOUBLE : fprintf( stream, "%G" , elt->value.dbl ); break;
40  case JST_STRING : fprintf( stream, "\"%s\"", elt->value.string ); break;
41  case JST_NULL : fprintf( stream, "null" ); break;
42  default: return JST_ERR_NULL_TYPE;
43  }
44  return JST_ERR_NONE;
45 }
46 
47 JST_Error JST_save_to_stream( FILE * stream, const JST_Element * root, unsigned indent ) {
48  if(( stream == NULL )||( root == NULL )) {
49  return JST_ERR_NULL_ARGUMENT;
50  }
51  save_element( root, stream, 0, indent );
52  fprintf( stream, "\n" );
53  return fclose( stream ) ? JST_ERR_ERRNO : JST_ERR_NONE;
54 }
55 
56 JST_Error JST_save_to_file( const char * path, const JST_Element * root, unsigned indent ) {
57  if(( path == NULL )||( root == NULL )) {
58  return JST_ERR_NULL_ARGUMENT;
59  }
60  FILE * stream = fopen( path, "wt" );
61  if( stream == NULL ) {
62  return JST_ERR_ERRNO;
63  }
64  return JST_save_to_stream( stream, root, indent );
65 }
66 
67 static JST_Error save_element_compact( const JST_Element * elt, FILE * stream );
68 
69 static JST_Error save_object_compact( const JST_Object * object, FILE * stream ) {
70  for( JST_Pair * iter = object->first; iter; iter = iter->next ) {
71  fprintf( stream, "\"%s\":", iter->name );
72  save_element_compact( &(iter->element), stream );
73  if( iter->next ) {
74  fputc( ',', stream );
75  }
76  }
77  return JST_ERR_NONE;
78 }
79 
80 static JST_Error save_array_compact( const JST_Array * array, FILE * stream ) {
81  for( unsigned i = 0; i < array->count; ++i ) {
82  save_element_compact( &(array->items[i]->element), stream );
83  if( i < array->count - 1 ) {
84  fputc( ',', stream );
85  }
86  }
87  return JST_ERR_NONE;
88 }
89 
90 static JST_Error save_element_compact( const JST_Element * elt, FILE * stream ) {
91  switch( elt->type ) {
92  case JST_OBJECT:
93  fprintf( stream, "{" );
94  save_object_compact( &(elt->value.object), stream );
95  fprintf( stream, "}" );
96  break;
97  case JST_ARRAY:
98  fprintf( stream, "[" );
99  save_array_compact( &(elt->value.array), stream );
100  fprintf( stream, "]" );
101  break;
102  case JST_BOOLEAN: fprintf( stream, "%s" , elt->value.boolean ? "true" : "false" ); break;
103  case JST_INTEGER: fprintf( stream, "%ld" , elt->value.integer ); break;
104  case JST_DOUBLE : fprintf( stream, "%G" , elt->value.dbl ); break;
105  case JST_STRING : fprintf( stream, "\"%s\"", elt->value.string ); break;
106  case JST_NULL : fprintf( stream, "null" ); break;
107  default: return JST_ERR_NULL_TYPE;
108  }
109  return JST_ERR_NONE;
110 }
111 
112 JST_Error JST_save_to_stream_compact( FILE * stream, const JST_Element * root ) {
113  if(( stream == NULL )||( root == NULL )) {
114  return JST_ERR_NULL_ARGUMENT;
115  }
116  save_element_compact( root, stream );
117  return fclose( stream ) ? JST_ERR_ERRNO : JST_ERR_NONE;
118 }
119 
120 JST_Error JST_save_to_file_compact( const char * path, const JST_Element * root ) {
121  if(( path == NULL )||( root == NULL )) {
122  return JST_ERR_NULL_ARGUMENT;
123  }
124  FILE * stream = fopen( path, "wt" );
125  if( stream == NULL ) {
126  return JST_ERR_ERRNO;
127  }
128  return JST_save_to_stream_compact( stream, root );
129 }
JST_Error JST_save_to_stream_compact(FILE *stream, const JST_Element *root)
Save the JSON tree to a stream, as a single line of text, without whitespaces.
Definition: JST_save.c:112
A object attribute item has a parent and is a named-typed-value pair.
Definition: jstools.h:93
A JSON array.
Definition: jstools.h:10
JST_Element element
Definition: jstools.h:85
A type field has been set to JST_NONE.
Definition: jstools.h:111
char * string
Definition: jstools.h:46
A JSON object, a sorted set of named-value pairs.
Definition: jstools.h:24
JST_Object object
Definition: jstools.h:41
JST_Error JST_save_to_file_compact(const char *path, const JST_Element *root)
Save the JSON tree to a file, as a single line of text, without whitespaces.
Definition: JST_save.c:120
bool boolean
Definition: jstools.h:43
JST_Value value
Definition: jstools.h:72
JST_Error
When things goes wrong, an error information is given.
Definition: jstools.h:108
struct JST_Pair_ * first
A linked list is mandatory to preserve the properties&#39;s order.
Definition: jstools.h:28
strerror() or perror() can be used to show the operating system layer error
Definition: jstools.h:112
An element is a typed value.
Definition: jstools.h:70
JST_Array array
Definition: jstools.h:42
JST_Error JST_save_to_stream(FILE *stream, const JST_Element *root, unsigned indent)
Save the JSON tree to a stream, pretty-printed.
Definition: JST_save.c:47
double dbl
Definition: jstools.h:45
struct JST_Pair_ * next
A linked list is mandatory to preserve the properties&#39;s order.
Definition: jstools.h:97
int64_t integer
Definition: jstools.h:44
Function misused.
Definition: jstools.h:110
struct JST_ArrayItem_ ** items
Array of JST_ArrayItem.
Definition: jstools.h:11
unsigned count
Cardinality of the previous array.
Definition: jstools.h:12
JST_ValueType type
Definition: jstools.h:71
JST_Error JST_save_to_file(const char *path, const JST_Element *root, unsigned indent)
Save the JSON tree to a file, pretty-printed.
Definition: JST_save.c:56