• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 
22 #include <grpc/support/alloc.h>
23 #include <grpc/support/log.h>
24 
25 #include "src/core/lib/json/json_reader.h"
26 #include "src/core/lib/json/json_writer.h"
27 #include "test/core/util/cmdline.h"
28 
29 typedef struct json_writer_userdata {
30   FILE* out;
31 } json_writer_userdata;
32 
33 typedef struct stacked_container {
34   grpc_json_type type;
35   struct stacked_container* next;
36 } stacked_container;
37 
38 typedef struct json_reader_userdata {
39   FILE* in;
40   grpc_json_writer* writer;
41   char* scratchpad;
42   char* ptr;
43   size_t free_space;
44   size_t allocated;
45   size_t string_len;
46   stacked_container* top;
47 } json_reader_userdata;
48 
json_writer_output_char(void * userdata,char c)49 static void json_writer_output_char(void* userdata, char c) {
50   json_writer_userdata* state = static_cast<json_writer_userdata*>(userdata);
51   fputc(c, state->out);
52 }
53 
json_writer_output_string(void * userdata,const char * str)54 static void json_writer_output_string(void* userdata, const char* str) {
55   json_writer_userdata* state = static_cast<json_writer_userdata*>(userdata);
56   fputs(str, state->out);
57 }
58 
json_writer_output_string_with_len(void * userdata,const char * str,size_t len)59 static void json_writer_output_string_with_len(void* userdata, const char* str,
60                                                size_t len) {
61   json_writer_userdata* state = static_cast<json_writer_userdata*>(userdata);
62   fwrite(str, len, 1, state->out);
63 }
64 
65 grpc_json_writer_vtable writer_vtable = {json_writer_output_char,
66                                          json_writer_output_string,
67                                          json_writer_output_string_with_len};
68 
check_string(json_reader_userdata * state,size_t needed)69 static void check_string(json_reader_userdata* state, size_t needed) {
70   if (state->free_space >= needed) return;
71   needed -= state->free_space;
72   needed = (needed + 0xffu) & ~0xffu;
73   state->scratchpad = static_cast<char*>(
74       gpr_realloc(state->scratchpad, state->allocated + needed));
75   state->free_space += needed;
76   state->allocated += needed;
77 }
78 
json_reader_string_clear(void * userdata)79 static void json_reader_string_clear(void* userdata) {
80   json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata);
81   state->free_space = state->allocated;
82   state->string_len = 0;
83 }
84 
json_reader_string_add_char(void * userdata,uint32_t c)85 static void json_reader_string_add_char(void* userdata, uint32_t c) {
86   json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata);
87   check_string(state, 1);
88   GPR_ASSERT(c < 256);
89   state->scratchpad[state->string_len++] = static_cast<char>(c);
90 }
91 
json_reader_string_add_utf32(void * userdata,uint32_t c)92 static void json_reader_string_add_utf32(void* userdata, uint32_t c) {
93   if (c <= 0x7f) {
94     json_reader_string_add_char(userdata, c);
95   } else if (c <= 0x7ff) {
96     uint32_t b1 = 0xc0u | ((c >> 6u) & 0x1fu);
97     uint32_t b2 = 0x80u | (c & 0x3fu);
98     json_reader_string_add_char(userdata, b1);
99     json_reader_string_add_char(userdata, b2);
100   } else if (c <= 0xffffu) {
101     uint32_t b1 = 0xe0u | ((c >> 12u) & 0x0fu);
102     uint32_t b2 = 0x80u | ((c >> 6u) & 0x3fu);
103     uint32_t b3 = 0x80u | (c & 0x3fu);
104     json_reader_string_add_char(userdata, b1);
105     json_reader_string_add_char(userdata, b2);
106     json_reader_string_add_char(userdata, b3);
107   } else if (c <= 0x1fffffu) {
108     uint32_t b1 = 0xf0u | ((c >> 18u) & 0x07u);
109     uint32_t b2 = 0x80u | ((c >> 12u) & 0x3fu);
110     uint32_t b3 = 0x80u | ((c >> 6u) & 0x3fu);
111     uint32_t b4 = 0x80u | (c & 0x3fu);
112     json_reader_string_add_char(userdata, b1);
113     json_reader_string_add_char(userdata, b2);
114     json_reader_string_add_char(userdata, b3);
115     json_reader_string_add_char(userdata, b4);
116   }
117 }
118 
json_reader_read_char(void * userdata)119 static uint32_t json_reader_read_char(void* userdata) {
120   int r;
121   json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata);
122 
123   r = fgetc(state->in);
124   if (r == EOF) r = GRPC_JSON_READ_CHAR_EOF;
125   return static_cast<uint32_t>(r);
126 }
127 
json_reader_container_begins(void * userdata,grpc_json_type type)128 static void json_reader_container_begins(void* userdata, grpc_json_type type) {
129   json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata);
130   stacked_container* container =
131       static_cast<stacked_container*>(gpr_malloc(sizeof(stacked_container)));
132 
133   container->type = type;
134   container->next = state->top;
135   state->top = container;
136 
137   grpc_json_writer_container_begins(state->writer, type);
138 }
139 
json_reader_container_ends(void * userdata)140 static grpc_json_type json_reader_container_ends(void* userdata) {
141   json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata);
142   stacked_container* container = state->top;
143 
144   grpc_json_writer_container_ends(state->writer, container->type);
145   state->top = container->next;
146   gpr_free(container);
147   return state->top ? state->top->type : GRPC_JSON_TOP_LEVEL;
148 }
149 
json_reader_set_key(void * userdata)150 static void json_reader_set_key(void* userdata) {
151   json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata);
152   json_reader_string_add_char(userdata, 0);
153 
154   grpc_json_writer_object_key(state->writer, state->scratchpad);
155 }
156 
json_reader_set_string(void * userdata)157 static void json_reader_set_string(void* userdata) {
158   json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata);
159   json_reader_string_add_char(userdata, 0);
160 
161   grpc_json_writer_value_string(state->writer, state->scratchpad);
162 }
163 
json_reader_set_number(void * userdata)164 static int json_reader_set_number(void* userdata) {
165   json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata);
166 
167   grpc_json_writer_value_raw_with_len(state->writer, state->scratchpad,
168                                       state->string_len);
169 
170   return 1;
171 }
172 
json_reader_set_true(void * userdata)173 static void json_reader_set_true(void* userdata) {
174   json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata);
175 
176   grpc_json_writer_value_raw_with_len(state->writer, "true", 4);
177 }
178 
json_reader_set_false(void * userdata)179 static void json_reader_set_false(void* userdata) {
180   json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata);
181 
182   grpc_json_writer_value_raw_with_len(state->writer, "false", 5);
183 }
184 
json_reader_set_null(void * userdata)185 static void json_reader_set_null(void* userdata) {
186   json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata);
187 
188   grpc_json_writer_value_raw_with_len(state->writer, "null", 4);
189 }
190 
191 static grpc_json_reader_vtable reader_vtable = {
192     json_reader_string_clear,     json_reader_string_add_char,
193     json_reader_string_add_utf32, json_reader_read_char,
194     json_reader_container_begins, json_reader_container_ends,
195     json_reader_set_key,          json_reader_set_string,
196     json_reader_set_number,       json_reader_set_true,
197     json_reader_set_false,        json_reader_set_null};
198 
rewrite(FILE * in,FILE * out,int indent)199 int rewrite(FILE* in, FILE* out, int indent) {
200   grpc_json_writer writer;
201   grpc_json_reader reader;
202   grpc_json_reader_status status;
203   json_writer_userdata writer_user;
204   json_reader_userdata reader_user;
205 
206   reader_user.writer = &writer;
207   reader_user.in = in;
208   reader_user.top = nullptr;
209   reader_user.scratchpad = nullptr;
210   reader_user.string_len = 0;
211   reader_user.free_space = 0;
212   reader_user.allocated = 0;
213 
214   writer_user.out = out;
215 
216   grpc_json_writer_init(&writer, indent, &writer_vtable, &writer_user);
217   grpc_json_reader_init(&reader, &reader_vtable, &reader_user);
218 
219   status = grpc_json_reader_run(&reader);
220 
221   free(reader_user.scratchpad);
222   while (reader_user.top) {
223     stacked_container* container = reader_user.top;
224     reader_user.top = container->next;
225     free(container);
226   }
227 
228   return status == GRPC_JSON_DONE;
229 }
230 
main(int argc,char ** argv)231 int main(int argc, char** argv) {
232   int indent = 2;
233   gpr_cmdline* cl;
234 
235   cl = gpr_cmdline_create(nullptr);
236   gpr_cmdline_add_int(cl, "indent", nullptr, &indent);
237   gpr_cmdline_parse(cl, argc, argv);
238   gpr_cmdline_destroy(cl);
239 
240   return rewrite(stdin, stdout, indent) ? 0 : 1;
241 }
242