LCOV - code coverage report
Current view: top level - vpp/api - json_format.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 0 144 0.0 %
Date: 2023-10-26 01:39:38 Functions: 0 8 0.0 %

          Line data    Source code
       1             : /*
       2             :  *------------------------------------------------------------------
       3             :  * json_format.c
       4             :  *
       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:
       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             : */
      20             : #include <inttypes.h>
      21             : #include "json_format.h"
      22             : #include <vnet/ip/ip.h>
      23             : #include <vppinfra/vec.h>
      24             : 
      25             : #define VAT_TAB_WIDTH               2
      26             : 
      27             : typedef struct vat_print_ctx_s
      28             : {
      29             :   FILE *ofp;
      30             :   u32 indent;
      31             : } vat_print_ctx_t;
      32             : 
      33             : /* Format an IP4 address. */
      34             : static u8 *
      35           0 : vat_json_format_ip4_address (u8 * s, va_list * args)
      36             : {
      37           0 :   u8 *a = va_arg (*args, u8 *);
      38           0 :   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
      39             : }
      40             : 
      41             : /* Format an IP6 address. */
      42             : static u8 *
      43           0 : vat_json_format_ip6_address (u8 * s, va_list * args)
      44             : {
      45           0 :   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;
      47             : 
      48           0 :   i_max_n_zero = ARRAY_LEN (a->as_u16);
      49           0 :   max_n_zeros = 0;
      50           0 :   i_first_zero = i_max_n_zero;
      51           0 :   n_zeros = 0;
      52           0 :   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
      53             :     {
      54           0 :       u32 is_zero = a->as_u16[i] == 0;
      55           0 :       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
      56             :         {
      57           0 :           i_first_zero = i;
      58           0 :           n_zeros = 0;
      59             :         }
      60           0 :       n_zeros += is_zero;
      61           0 :       if ((!is_zero && n_zeros > max_n_zeros)
      62           0 :           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
      63             :         {
      64           0 :           i_max_n_zero = i_first_zero;
      65           0 :           max_n_zeros = n_zeros;
      66           0 :           i_first_zero = ARRAY_LEN (a->as_u16);
      67           0 :           n_zeros = 0;
      68             :         }
      69             :     }
      70             : 
      71           0 :   last_double_colon = 0;
      72           0 :   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
      73             :     {
      74           0 :       if (i == i_max_n_zero && max_n_zeros > 1)
      75             :         {
      76           0 :           s = format (s, "::");
      77           0 :           i += max_n_zeros - 1;
      78           0 :           last_double_colon = 1;
      79             :         }
      80             :       else
      81             :         {
      82           0 :           s = format (s, "%s%x",
      83           0 :                       (last_double_colon || i == 0) ? "" : ":",
      84           0 :                       clib_net_to_host_u16 (a->as_u16[i]));
      85           0 :           last_double_colon = 0;
      86             :         }
      87             :     }
      88             : 
      89           0 :   return s;
      90             : }
      91             : 
      92             : static void
      93           0 : vat_json_indent_print (vat_print_ctx_t * ctx)
      94             : {
      95             :   int i;
      96           0 :   for (i = 0; i < ctx->indent * VAT_TAB_WIDTH; i++)
      97             :     {
      98           0 :       fformat (ctx->ofp, " ");
      99             :     }
     100           0 : }
     101             : 
     102             : static void
     103           0 : vat_json_indent_line (vat_print_ctx_t * ctx, char *fmt, ...)
     104             : {
     105             :   va_list va;
     106             : 
     107           0 :   vat_json_indent_print (ctx);
     108           0 :   va_start (va, fmt);
     109           0 :   va_fformat (ctx->ofp, fmt, &va);
     110           0 :   va_end (va);
     111           0 : }
     112             : 
     113             : static u8
     114           0 : is_num_only (vat_json_node_t * p)
     115             : {
     116             :   vat_json_node_t *elem;
     117           0 :   vec_foreach (elem, p)
     118             :   {
     119           0 :     if (VAT_JSON_INT != elem->type && VAT_JSON_UINT != elem->type)
     120             :       {
     121           0 :         return 0;
     122             :       }
     123             :   }
     124           0 :   return 1;
     125             : }
     126             : 
     127             : static void
     128           0 : vat_json_print_internal (vat_print_ctx_t * ctx, vat_json_node_t * node)
     129             : {
     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--)
     136             : 
     137             :   vat_json_pair_t *pair;
     138             :   u32 i, count;
     139             :   vat_json_node_t *elem;
     140           0 :   u8 num_only = 0;
     141             : 
     142           0 :   if (!node)
     143             :     {
     144           0 :       return;
     145             :     }
     146             : 
     147           0 :   switch (node->type)
     148             :     {
     149           0 :     case VAT_JSON_OBJECT:
     150           0 :       count = vec_len (node->pairs);
     151           0 :       if (count >= 1)
     152             :         {
     153           0 :           PL ("{");
     154           0 :           INCR;
     155           0 :           for (i = 0; i < count; i++)
     156             :             {
     157           0 :               pair = &node->pairs[i];
     158           0 :               PP ("\"%s\": ", pair->name);
     159           0 :               vat_json_print_internal (ctx, &pair->value);
     160           0 :               if (i < count - 1)
     161             :                 {
     162           0 :                   P (",");
     163             :                 }
     164           0 :               PL ();
     165             :             }
     166           0 :           DECR;
     167           0 :           PP ("}");
     168             :         }
     169             :       else
     170             :         {
     171           0 :           P ("{}");
     172             :         }
     173           0 :       break;
     174           0 :     case VAT_JSON_ARRAY:
     175           0 :       num_only = is_num_only (node->array);
     176           0 :       count = vec_len (node->array);
     177           0 :       if (count >= 1)
     178             :         {
     179           0 :           if (num_only)
     180           0 :             P ("[");
     181             :           else
     182           0 :             PL ("[ ");
     183           0 :           INCR;
     184           0 :           for (i = 0; i < count; i++)
     185             :             {
     186           0 :               elem = &node->array[i];
     187           0 :               if (!num_only)
     188             :                 {
     189           0 :                   vat_json_indent_print (ctx);
     190             :                 }
     191           0 :               vat_json_print_internal (ctx, elem);
     192           0 :               if (i < count - 1)
     193             :                 {
     194           0 :                   if (num_only)
     195             :                     {
     196           0 :                       P (", ");
     197             :                     }
     198             :                   else
     199             :                     {
     200           0 :                       P (",");
     201             :                     }
     202             :                 }
     203           0 :               if (!num_only)
     204           0 :                 PL ();
     205             :             }
     206           0 :           DECR;
     207           0 :           if (!num_only)
     208           0 :             PP ("]");
     209             :           else
     210           0 :             P ("]");
     211             :         }
     212             :       else
     213             :         {
     214           0 :           P ("[]");
     215             :         }
     216           0 :       break;
     217           0 :     case VAT_JSON_INT:
     218           0 :       P ("%d", node->sint);
     219           0 :       break;
     220           0 :     case VAT_JSON_UINT:
     221           0 :       P ("%" PRIu64, node->uint);
     222           0 :       break;
     223           0 :     case VAT_JSON_REAL:
     224           0 :       P ("%f", node->real);
     225           0 :       break;
     226           0 :     case VAT_JSON_STRING:
     227           0 :       P ("\"%s\"", node->string);
     228           0 :       break;
     229           0 :     case VAT_JSON_IPV4:
     230           0 :       P ("\"%U\"", vat_json_format_ip4_address, &node->ip4);
     231           0 :       break;
     232           0 :     case VAT_JSON_IPV6:
     233           0 :       P ("\"%U\"", vat_json_format_ip6_address, &node->ip6);
     234           0 :       break;
     235           0 :     default:
     236           0 :       break;
     237             :     }
     238             : #undef PPL
     239             : #undef PP
     240             : #undef PL
     241             : #undef P
     242             : }
     243             : 
     244             : void
     245           0 : vat_json_print (FILE * ofp, vat_json_node_t * node)
     246             : {
     247             :   vat_print_ctx_t ctx;
     248           0 :   clib_memset (&ctx, 0, sizeof ctx);
     249           0 :   ctx.indent = 0;
     250           0 :   ctx.ofp = ofp;
     251           0 :   fformat (ofp, "\n");
     252           0 :   vat_json_print_internal (&ctx, node);
     253           0 :   fformat (ofp, "\n");
     254           0 : }
     255             : 
     256             : void
     257           0 : vat_json_free (vat_json_node_t * node)
     258             : {
     259           0 :   int i = 0;
     260             : 
     261           0 :   if (NULL == node)
     262             :     {
     263           0 :       return;
     264             :     }
     265           0 :   switch (node->type)
     266             :     {
     267           0 :     case VAT_JSON_OBJECT:
     268           0 :       for (i = 0; i < vec_len (node->pairs); i++)
     269             :         {
     270           0 :           vat_json_free (&node->pairs[i].value);
     271             :         }
     272           0 :       if (NULL != node->pairs)
     273             :         {
     274           0 :           vec_free (node->pairs);
     275             :         }
     276           0 :       break;
     277           0 :     case VAT_JSON_ARRAY:
     278           0 :       for (i = 0; i < vec_len (node->array); i++)
     279             :         {
     280           0 :           vat_json_free (&node->array[i]);
     281             :         }
     282           0 :       if (NULL != node->array)
     283             :         {
     284           0 :           vec_free (node->array);
     285             :         }
     286           0 :       break;
     287           0 :     case VAT_JSON_STRING:
     288           0 :       if (NULL != node->string)
     289             :         {
     290           0 :           vec_free (node->string);
     291             :         }
     292           0 :       break;
     293           0 :     default:
     294           0 :       break;
     295             :     }
     296             : }
     297             : 
     298             : /*
     299             :  * fd.io coding-style-patch-verification: ON
     300             :  *
     301             :  * Local Variables:
     302             :  * eval: (c-set-style "gnu")
     303             :  * End:
     304             :  */

Generated by: LCOV version 1.14