Forráskód Böngészése

Added size argument for string output functions

Sergey Lyubka 11 éve
szülő
commit
908bebede8
4 módosított fájl, 41 hozzáadás és 27 törlés
  1. 6 3
      README.md
  2. 20 11
      frozen.c
  3. 2 2
      frozen.h
  4. 13 11
      unit_test.c

+ 6 - 3
README.md

@@ -140,8 +140,10 @@ Characters allowed in `format` string:
 are appended to the output buffer as-is  
 are appended to the output buffer as-is  
 `i`: argument must be an `long` value, outputs number  
 `i`: argument must be an `long` value, outputs number  
 `f`: argument must be a `double` value, outputs number  
 `f`: argument must be a `double` value, outputs number  
-`s`: argument must be a `\0`-terminated `char *` value, outputs quoted string  
-`S`: argument must be a `\0`-terminated `char *` value, outputs unquoted string  
+`s`: arguments must be a `char *` value, followed by `size_t` value,
+     outputs quoted string  
+`S`: arguments must be a `char *` value, followed by `size_t` value,
+     outputs unquoted string  
 `N`: outputs `null`  
 `N`: outputs `null`  
 `T`: outputs `true`  
 `T`: outputs `true`  
 `F`: outputs `false`  
 `F`: outputs `false`  
@@ -174,7 +176,8 @@ are appended to the output buffer as-is
 ## Example: generating JSON string `{ "foo": [-123, true, false, null] }`
 ## Example: generating JSON string `{ "foo": [-123, true, false, null] }`
 
 
     char buf[1000];
     char buf[1000];
-    json_emit(buf, sizeof(buf), "{ s: [i, T, F, N] }", "foo", (long) -123);
+    json_emit(buf, sizeof(buf), "{ s: [i, T, F, N] }",
+              "foo", (size_t) 3, (long) -123);
 
 
 # License
 # License
 
 

+ 20 - 11
frozen.c

@@ -366,14 +366,15 @@ int json_emit_double(char *buf, int buf_len, double value) {
   return snprintf(buf, buf_len > 0 ? buf_len : 0, "%g", value);
   return snprintf(buf, buf_len > 0 ? buf_len : 0, "%g", value);
 }
 }
 
 
-int json_emit_quoted_str(char *s, int s_len, const char *str) {
-  const char *begin = s, *end = s + s_len;
+int json_emit_quoted_str(char *s, int s_len, const char *str, int len) {
+  const char *begin = s, *end = s + s_len, *str_end = str + len;
   char ch;
   char ch;
 
 
 #define EMIT(x) do { if (s < end) *s = x; s++; } while (0)
 #define EMIT(x) do { if (s < end) *s = x; s++; } while (0)
 
 
   EMIT('"');
   EMIT('"');
-  while ((ch = *str++) != '\0') {
+  while (str < str_end) {
+    ch = *str++;
     switch (ch) {
     switch (ch) {
       case '"':  EMIT('\\'); EMIT('"'); break;
       case '"':  EMIT('\\'); EMIT('"'); break;
       case '\\': EMIT('\\'); EMIT('\\'); break;
       case '\\': EMIT('\\'); EMIT('\\'); break;
@@ -391,12 +392,16 @@ int json_emit_quoted_str(char *s, int s_len, const char *str) {
   return s - begin;
   return s - begin;
 }
 }
 
 
-int json_emit_unquoted_str(char *buf, int buf_len, const char *str) {
-  return snprintf(buf, buf_len > 0 ? buf_len : 0, "%s", str);
+int json_emit_unquoted_str(char *buf, int buf_len, const char *str, int len) {
+  if (buf_len > 0 && len > 0) {
+    memcpy(buf, str, len < buf_len ? len : buf_len);
+  }
+  return len;
 }
 }
 
 
 int json_emit(char *s, int s_len, const char *fmt, ...) {
 int json_emit(char *s, int s_len, const char *fmt, ...) {
-  const char *end = s + s_len;
+  const char *end = s + s_len, *str;
+  size_t len;
   va_list ap;
   va_list ap;
 
 
   va_start(ap, fmt);
   va_start(ap, fmt);
@@ -414,19 +419,23 @@ int json_emit(char *s, int s_len, const char *fmt, ...) {
         s += json_emit_double(s, end - s, va_arg(ap, double));
         s += json_emit_double(s, end - s, va_arg(ap, double));
         break;
         break;
       case 's':
       case 's':
-        s += json_emit_quoted_str(s, end - s, va_arg(ap, char *));
+        str = va_arg(ap, char *);
+        len = va_arg(ap, size_t);
+        s += json_emit_quoted_str(s, end - s, str, len);
         break;
         break;
       case 'S':
       case 'S':
-        s += json_emit_unquoted_str(s, end - s, va_arg(ap, char *));
+        str = va_arg(ap, char *);
+        len = va_arg(ap, size_t);
+        s += json_emit_unquoted_str(s, end - s, str, len);
         break;
         break;
       case 'T':
       case 'T':
-        s += json_emit_unquoted_str(s, end - s, "true");
+        s += json_emit_unquoted_str(s, end - s, "true", 4);
         break;
         break;
       case 'F':
       case 'F':
-        s += json_emit_unquoted_str(s, end - s, "false");
+        s += json_emit_unquoted_str(s, end - s, "false", 5);
         break;
         break;
       case 'N':
       case 'N':
-        s += json_emit_unquoted_str(s, end - s, "null");
+        s += json_emit_unquoted_str(s, end - s, "null", 4);
         break;
         break;
       default:
       default:
         return 0;
         return 0;

+ 2 - 2
frozen.h

@@ -55,8 +55,8 @@ const struct json_token *find_json_token(const struct json_token *toks,
 
 
 int json_emit_long(char *buf, int buf_len, long value);
 int json_emit_long(char *buf, int buf_len, long value);
 int json_emit_double(char *buf, int buf_len, double value);
 int json_emit_double(char *buf, int buf_len, double value);
-int json_emit_quoted_str(char *buf, int buf_len, const char *str);
-int json_emit_unquoted_str(char *buf, int buf_len, const char *str);
+int json_emit_quoted_str(char *buf, int buf_len, const char *str, int len);
+int json_emit_unquoted_str(char *buf, int buf_len, const char *str, int len);
 int json_emit(char *buf, int buf_len, const char *fmt, ...);
 int json_emit(char *buf, int buf_len, const char *fmt, ...);
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus

+ 13 - 11
unit_test.c

@@ -184,8 +184,8 @@ static const char *test_emit_overflow(void) {
   char buf[1000];
   char buf[1000];
 
 
   memset(buf, 0, sizeof(buf));
   memset(buf, 0, sizeof(buf));
-  ASSERT(json_emit_unquoted_str(buf, 0, "hi") == 2);
-  ASSERT(json_emit_quoted_str(buf, 0, "hi") == 4);
+  ASSERT(json_emit_unquoted_str(buf, 0, "hi", 2) == 2);
+  ASSERT(json_emit_quoted_str(buf, 0, "hi", 2) == 4);
   ASSERT(buf[0] == '\0');
   ASSERT(buf[0] == '\0');
 
 
   return NULL;
   return NULL;
@@ -194,7 +194,7 @@ static const char *test_emit_overflow(void) {
 static const char *test_emit_escapes(void) {
 static const char *test_emit_escapes(void) {
   const char *s4 = "\"\\\"\\\\\\b\\f\\n\\r\\t\"";
   const char *s4 = "\"\\\"\\\\\\b\\f\\n\\r\\t\"";
   char buf[1000];
   char buf[1000];
-  ASSERT(json_emit_quoted_str(buf, sizeof(buf), "\"\\\b\f\n\r\t") > 0);
+  ASSERT(json_emit_quoted_str(buf, sizeof(buf), "\"\\\b\f\n\r\t", 7) > 0);
   ASSERT(strcmp(buf, s4) == 0);
   ASSERT(strcmp(buf, s4) == 0);
   return NULL;
   return NULL;
 }
 }
@@ -203,15 +203,15 @@ static const char *test_emit(void) {
   char buf[1000], *p = buf;
   char buf[1000], *p = buf;
   const char *s5 = "{\"foo\":[-123,1.23,true]}";
   const char *s5 = "{\"foo\":[-123,1.23,true]}";
 
 
-  p += json_emit_unquoted_str(p, &buf[sizeof(buf)] - p, "{");
-  p += json_emit_quoted_str(p, &buf[sizeof(buf)] - p, "foo");
-  p += json_emit_unquoted_str(p, &buf[sizeof(buf)] - p, ":[");
+  p += json_emit_unquoted_str(p, &buf[sizeof(buf)] - p, "{", 1);
+  p += json_emit_quoted_str(p, &buf[sizeof(buf)] - p, "foo", 3);
+  p += json_emit_unquoted_str(p, &buf[sizeof(buf)] - p, ":[", 2);
   p += json_emit_long(p, &buf[sizeof(buf)] - p, -123);
   p += json_emit_long(p, &buf[sizeof(buf)] - p, -123);
-  p += json_emit_unquoted_str(p, &buf[sizeof(buf)] - p, ",");
+  p += json_emit_unquoted_str(p, &buf[sizeof(buf)] - p, ",", 1);
   p += json_emit_double(p, &buf[sizeof(buf)] - p, 1.23);
   p += json_emit_double(p, &buf[sizeof(buf)] - p, 1.23);
-  p += json_emit_unquoted_str(p, &buf[sizeof(buf)] - p, ",");
-  p += json_emit_unquoted_str(p, &buf[sizeof(buf)] - p, "true");
-  p += json_emit_unquoted_str(p, &buf[sizeof(buf)] - p, "]}");
+  p += json_emit_unquoted_str(p, &buf[sizeof(buf)] - p, ",", 1);
+  p += json_emit_unquoted_str(p, &buf[sizeof(buf)] - p, "true", 4);
+  p += json_emit_unquoted_str(p, &buf[sizeof(buf)] - p, "]}", 2);
   ASSERT(strcmp(buf, s5) == 0);
   ASSERT(strcmp(buf, s5) == 0);
   ASSERT(p < &buf[sizeof(buf)]);
   ASSERT(p < &buf[sizeof(buf)]);
 
 
@@ -220,7 +220,9 @@ static const char *test_emit(void) {
   ASSERT(json_emit(buf, 4, "{S:i}", "a", 12345) < 0);
   ASSERT(json_emit(buf, 4, "{S:i}", "a", 12345) < 0);
   ASSERT(json_emit(buf, sizeof(buf), "{S:d}", "a", 12345) == 0);
   ASSERT(json_emit(buf, sizeof(buf), "{S:d}", "a", 12345) == 0);
 
 
-  ASSERT(json_emit(buf, sizeof(buf), "{s:[i,T, F,N]}", "foo", (long) -7) > 0);
+  ASSERT(json_emit(buf, sizeof(buf), "{s:[i,T, F,N]}", "foo",
+         (long) 3, (long) -7) > 0);
+  printf("[%s]\n", buf);
   ASSERT(strcmp(buf, "{\"foo\":[-7,true, false,null]}") == 0);
   ASSERT(strcmp(buf, "{\"foo\":[-7,true, false,null]}") == 0);
 
 
   return NULL;
   return NULL;