couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dav...@apache.org
Subject [09/50] [abbrv] git commit: Add pretty print
Date Fri, 17 Jan 2014 22:11:40 GMT
Add pretty print

jiffy:encode/2 now accepts a 'pretty' option that will format the JSON
output using two-space indents.


Project: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/commit/fa362cf4
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/tree/fa362cf4
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/diff/fa362cf4

Branch: refs/heads/import
Commit: fa362cf4511263cef852fe5fd96e8ee7cee285d7
Parents: a30cbeb
Author: Sergey Urbanovich <sergey.urbanovich@gmail.com>
Authored: Sun Dec 11 18:11:56 2011 +0400
Committer: Paul J. Davis <paul.joseph.davis@gmail.com>
Committed: Sun Jan 8 16:09:44 2012 -0600

----------------------------------------------------------------------
 c_src/encoder.c      | 75 +++++++++++++++++++++++++++++++++++++++++++++--
 c_src/jiffy.c        |  1 +
 c_src/jiffy.h        |  1 +
 test/jiffy_tests.erl |  7 +++++
 4 files changed, 81 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/fa362cf4/c_src/encoder.c
----------------------------------------------------------------------
diff --git a/c_src/encoder.c b/c_src/encoder.c
index a751fd7..c3281d2 100644
--- a/c_src/encoder.c
+++ b/c_src/encoder.c
@@ -10,12 +10,24 @@
 
 #define BIN_INC_SIZE 2048
 
+#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
+
+#define MAYBE_PRETTY(e)             \
+do {                                \
+    if(e->pretty) {                 \
+        if(!enc_shift(e))           \
+            return 0;               \
+    }                               \
+} while(0)
+
 
 typedef struct {
     ErlNifEnv*      env;
     jiffy_st*       atoms;
     int             uescape;
+    int             pretty;
 
+    int             shiftcnt;
     int             count;
 
     int             iolen;
@@ -28,6 +40,22 @@ typedef struct {
     size_t          i;
 } Encoder;
 
+
+// String constants for pretty printing.
+// Every string starts with its length.
+#define NUM_SHIFTS 8
+static char* shifts[NUM_SHIFTS] = {
+    "\x01\n",
+    "\x03\n  ",
+    "\x05\n    ",
+    "\x07\n      ",
+    "\x09\n        ",
+    "\x0b\n          ",
+    "\x0d\n            ",
+    "\x0f\n              "
+};
+
+
 int
 enc_init(Encoder* e, ErlNifEnv* env, ERL_NIF_TERM opts, ErlNifBinary* bin)
 {
@@ -36,6 +64,8 @@ enc_init(Encoder* e, ErlNifEnv* env, ERL_NIF_TERM opts, ErlNifBinary* bin)
     e->env = env;
     e->atoms = enif_priv_data(env);
     e->uescape = 0;
+    e->pretty = 0;
+    e->shiftcnt = 0;
     e->count = 0;
 
     if(!enif_is_list(env, opts)) {
@@ -45,6 +75,8 @@ enc_init(Encoder* e, ErlNifEnv* env, ERL_NIF_TERM opts, ErlNifBinary* bin)
     while(enif_get_list_cell(env, opts, &val, &opts)) {
         if(enif_compare(val, e->atoms->atom_uescape) == 0) {
             e->uescape = 1;
+        } else if(enif_compare(val, e->atoms->atom_pretty) == 0) {
+            e->pretty = 1;
         } else {
             return 0;
         }
@@ -376,16 +408,42 @@ enc_char(Encoder* e, char c)
     return 1;
 }
 
+static int
+enc_shift(Encoder* e) {
+    int i;
+    char* shift;
+    assert(e->shiftcnt >= 0 && "Invalid shift count.");
+    shift = shifts[MIN(e->shiftcnt, NUM_SHIFTS-1)];
+
+    if(!enc_literal(e, shift + 1, *shift))
+        return 0;
+
+    // Finish the rest of this shift it's it bigger than
+    // our largest predefined constant.
+    for(i = NUM_SHIFTS - 1; i < e->shiftcnt; i++) {
+        if(!enc_literal(e, "  ", 2))
+            return 0;
+    }
+
+    return 1;
+}
+
 static inline int
 enc_start_object(Encoder* e)
 {
     e->count++;
-    return enc_char(e, '{');
+    e->shiftcnt++;
+    if(!enc_char(e, '{'))
+        return 0;
+    MAYBE_PRETTY(e);
+    return 1;
 }
 
 static inline int
 enc_end_object(Encoder* e)
 {
+    e->shiftcnt--;
+    MAYBE_PRETTY(e);
     return enc_char(e, '}');
 }
 
@@ -393,25 +451,36 @@ static inline int
 enc_start_array(Encoder* e)
 {
     e->count++;
-    return enc_char(e, '[');
+    e->shiftcnt++;
+    if(!enc_char(e, '['))
+        return 0;
+    MAYBE_PRETTY(e);
+    return 1;
 }
 
 static inline int
 enc_end_array(Encoder* e)
 {
+    e->shiftcnt--;
+    MAYBE_PRETTY(e);
     return enc_char(e, ']');
 }
 
 static inline int
 enc_colon(Encoder* e)
 {
+    if(e->pretty)
+        return enc_literal(e, " : ", 3);
     return enc_char(e, ':');
 }
 
 static inline int
 enc_comma(Encoder* e)
 {
-    return enc_char(e, ',');
+    if(!enc_char(e, ','))
+        return 0;
+    MAYBE_PRETTY(e);
+    return 1;
 }
 
 ERL_NIF_TERM

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/fa362cf4/c_src/jiffy.c
----------------------------------------------------------------------
diff --git a/c_src/jiffy.c b/c_src/jiffy.c
index c1dd8b1..8fdde2f 100644
--- a/c_src/jiffy.c
+++ b/c_src/jiffy.c
@@ -21,6 +21,7 @@ load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info)
     st->atom_bigdbl = make_atom(env, "bigdbl");
     st->atom_partial = make_atom(env, "partial");
     st->atom_uescape = make_atom(env, "uescape");
+    st->atom_pretty = make_atom(env, "pretty");
 
     // Markers used in encoding
     st->ref_object = make_atom(env, "$object_ref$");

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/fa362cf4/c_src/jiffy.h
----------------------------------------------------------------------
diff --git a/c_src/jiffy.h b/c_src/jiffy.h
index 9b1f700..327657a 100644
--- a/c_src/jiffy.h
+++ b/c_src/jiffy.h
@@ -17,6 +17,7 @@ typedef struct {
     ERL_NIF_TERM    atom_bigdbl;
     ERL_NIF_TERM    atom_partial;
     ERL_NIF_TERM    atom_uescape;
+    ERL_NIF_TERM    atom_pretty;
 
     ERL_NIF_TERM    ref_object;
     ERL_NIF_TERM    ref_array;

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/fa362cf4/test/jiffy_tests.erl
----------------------------------------------------------------------
diff --git a/test/jiffy_tests.erl b/test/jiffy_tests.erl
index 0997bc7..8d3929a 100644
--- a/test/jiffy_tests.erl
+++ b/test/jiffy_tests.erl
@@ -24,6 +24,13 @@ prop_encode_decode() ->
         end
     ).
 
+prop_encode_decode_pretty() ->
+    ?FORALL(Data, json(),
+        begin
+            Data == jiffy:decode(jiffy:encode(Data, [pretty]))
+        end
+    ).
+
 prop_encode_not_crash() ->
     ?FORALL(Data, any(), begin catch jiffy:encode(Data), true end).
 


Mime
View raw message