2 *------------------------------------------------------------------
5 * Copyright (c) 2015 Cisco and/or its affiliates.
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:
10 * http://www.apache.org/licenses/LICENSE-2.0
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 *------------------------------------------------------------------
21 #include <vat/json_format.h>
22 #include <vnet/ip/ip.h>
23 #include <vppinfra/vec.h>
25 #define VAT_TAB_WIDTH 2
27 typedef struct vat_print_ctx_s
33 /* Format an IP4 address. */
35 vat_json_format_ip4_address (u8 * s, va_list * args)
37 u8 *a = va_arg (*args, u8 *);
38 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
41 /* Format an IP6 address. */
43 vat_json_format_ip6_address (u8 * s, va_list * args)
45 ip6_address_t *a = va_arg (*args, ip6_address_t *);
46 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
48 i_max_n_zero = ARRAY_LEN (a->as_u16);
50 i_first_zero = i_max_n_zero;
52 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
54 u32 is_zero = a->as_u16[i] == 0;
55 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
61 if ((!is_zero && n_zeros > max_n_zeros)
62 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
64 i_max_n_zero = i_first_zero;
65 max_n_zeros = n_zeros;
66 i_first_zero = ARRAY_LEN (a->as_u16);
71 last_double_colon = 0;
72 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
74 if (i == i_max_n_zero && max_n_zeros > 1)
78 last_double_colon = 1;
82 s = format (s, "%s%x",
83 (last_double_colon || i == 0) ? "" : ":",
84 clib_net_to_host_u16 (a->as_u16[i]));
85 last_double_colon = 0;
93 vat_json_indent_print (vat_print_ctx_t * ctx)
96 for (i = 0; i < ctx->indent * VAT_TAB_WIDTH; i++)
98 fformat (ctx->ofp, " ");
103 vat_json_indent_line (vat_print_ctx_t * ctx, char *fmt, ...)
107 vat_json_indent_print (ctx);
109 va_fformat (ctx->ofp, fmt, &va);
114 is_num_only (vat_json_node_t * p)
116 vat_json_node_t *elem;
117 vec_foreach (elem, p)
119 if (VAT_JSON_INT != elem->type && VAT_JSON_UINT != elem->type)
128 vat_json_print_internal (vat_print_ctx_t * ctx, vat_json_node_t * node)
130 #define P(fmt,...) fformat(ctx->ofp, fmt, ##__VA_ARGS__)
131 #define PL(fmt,...) fformat(ctx->ofp, fmt"\n", ##__VA_ARGS__)
132 #define PPL(fmt,...) vat_json_indent_line(ctx, fmt"\n", ##__VA_ARGS__)
133 #define PP(fmt,...) vat_json_indent_line(ctx, fmt, ##__VA_ARGS__)
134 #define INCR (ctx->indent++)
135 #define DECR (ctx->indent--)
137 vat_json_pair_t *pair;
139 vat_json_node_t *elem;
149 case VAT_JSON_OBJECT:
150 count = vec_len (node->pairs);
155 for (i = 0; i < count; i++)
157 pair = &node->pairs[i];
158 PP ("\"%s\": ", pair->name);
159 vat_json_print_internal (ctx, &pair->value);
175 num_only = is_num_only (node->array);
176 count = vec_len (node->array);
184 for (i = 0; i < count; i++)
186 elem = &node->array[i];
189 vat_json_indent_print (ctx);
191 vat_json_print_internal (ctx, elem);
218 P ("%d", node->sint);
221 P ("%" PRIu64, node->uint);
224 P ("%f", node->real);
226 case VAT_JSON_STRING:
227 P ("\"%s\"", node->string);
230 P ("\"%U\"", vat_json_format_ip4_address, &node->ip4);
233 P ("\"%U\"", vat_json_format_ip6_address, &node->ip6);
245 vat_json_print (FILE * ofp, vat_json_node_t * node)
248 clib_memset (&ctx, 0, sizeof ctx);
252 vat_json_print_internal (&ctx, node);
257 vat_json_free (vat_json_node_t * node)
267 case VAT_JSON_OBJECT:
268 for (i = 0; i < vec_len (node->pairs); i++)
270 vat_json_free (&node->pairs[i].value);
272 if (NULL != node->pairs)
274 vec_free (node->pairs);
278 for (i = 0; i < vec_len (node->array); i++)
280 vat_json_free (&node->array[i]);
282 if (NULL != node->array)
284 vec_free (node->array);
287 case VAT_JSON_STRING:
288 if (NULL != node->string)
290 vec_free (node->string);
299 * fd.io coding-style-patch-verification: ON
302 * eval: (c-set-style "gnu")