• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #include "upb/lex/round_trip.h"
9 
10 #include <float.h>
11 #include <math.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 
15 // Must be last.
16 #include "upb/port/def.inc"
17 
18 /* Miscellaneous utilities ****************************************************/
19 
upb_FixLocale(char * p)20 static void upb_FixLocale(char* p) {
21   /* printf() is dependent on locales; sadly there is no easy and portable way
22    * to avoid this. This little post-processing step will translate 1,2 -> 1.2
23    * since JSON needs the latter. Arguably a hack, but it is simple and the
24    * alternatives are far more complicated, platform-dependent, and/or larger
25    * in code size. */
26   for (; *p; p++) {
27     if (*p == ',') *p = '.';
28   }
29 }
30 
_upb_EncodeRoundTripDouble(double val,char * buf,size_t size)31 void _upb_EncodeRoundTripDouble(double val, char* buf, size_t size) {
32   assert(size >= kUpb_RoundTripBufferSize);
33   if (isnan(val)) {
34     snprintf(buf, size, "%s", "nan");
35     return;
36   }
37   snprintf(buf, size, "%.*g", DBL_DIG, val);
38   if (strtod(buf, NULL) != val) {
39     snprintf(buf, size, "%.*g", DBL_DIG + 2, val);
40     assert(strtod(buf, NULL) == val);
41   }
42   upb_FixLocale(buf);
43 }
44 
_upb_EncodeRoundTripFloat(float val,char * buf,size_t size)45 void _upb_EncodeRoundTripFloat(float val, char* buf, size_t size) {
46   assert(size >= kUpb_RoundTripBufferSize);
47   if (isnan(val)) {
48     snprintf(buf, size, "%s", "nan");
49     return;
50   }
51   snprintf(buf, size, "%.*g", FLT_DIG, val);
52   if (strtof(buf, NULL) != val) {
53     snprintf(buf, size, "%.*g", FLT_DIG + 3, val);
54     assert(strtof(buf, NULL) == val);
55   }
56   upb_FixLocale(buf);
57 }
58