libjson: added printing support (thanks spew)
This commit is contained in:
parent
f6e8b115d4
commit
a53ae2782a
4 changed files with 127 additions and 12 deletions
|
@ -4,6 +4,8 @@
|
|||
typedef struct JSONEl JSONEl;
|
||||
typedef struct JSON JSON;
|
||||
|
||||
#pragma varargck type "J" JSON*
|
||||
|
||||
enum {
|
||||
JSONNull,
|
||||
JSONBool,
|
||||
|
@ -33,3 +35,5 @@ JSON* jsonparse(char *);
|
|||
void jsonfree(JSON *);
|
||||
JSON* jsonbyname(JSON *, char *);
|
||||
char* jsonstr(JSON *);
|
||||
int JSONfmt(Fmt*);
|
||||
void JSONfmtinstall(void);
|
||||
|
|
|
@ -40,10 +40,12 @@ struct JSON
|
|||
};
|
||||
};
|
||||
|
||||
JSON* jsonparse(char *);
|
||||
void jsonfree(JSON *);
|
||||
JSON* jsonbyname(JSON *, char *);
|
||||
char* jsonstr(JSON *);
|
||||
JSON* jsonparse(char *s);
|
||||
void jsonfree(JSON *j);
|
||||
JSON* jsonbyname(JSON *j, char *s);
|
||||
char* jsonstr(JSON *j);
|
||||
int JSONfmt(Fmt *f)
|
||||
void JSONfmtinstall(void);
|
||||
.EE
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
|
@ -76,7 +78,7 @@ Dictionary objects have the
|
|||
member set to the key of the association.
|
||||
.P
|
||||
A json object is parsed by calling
|
||||
.B jsonparse
|
||||
.I jsonparse
|
||||
with a
|
||||
.B UTF-8
|
||||
string of the json encoded data. On success, a non-nil pointer to a
|
||||
|
@ -84,26 +86,41 @@ newly allocated
|
|||
.B JSON
|
||||
structure is returned.
|
||||
To free the parsed objects,
|
||||
.B jsonfree
|
||||
.I jsonfree
|
||||
has to be called.
|
||||
.P
|
||||
The
|
||||
.B jsonbyname
|
||||
.I jsonbyname
|
||||
function returns the associated value of a dictionary item.
|
||||
.P
|
||||
The function
|
||||
.B jsonstr
|
||||
.I jsonstr
|
||||
returns the string value of a json object or
|
||||
.B nil
|
||||
for any other object type.
|
||||
.P
|
||||
.I JSONfmt
|
||||
is a
|
||||
.IR print (2)
|
||||
formatting routine that prints a well-formatted JSON structure.
|
||||
It can be installed by hand but
|
||||
.I JSONfmtinstall
|
||||
installs it under the standard format character J. The header
|
||||
.B <json.h>
|
||||
contains a #pragma statement so the compiler can
|
||||
type-check uses of
|
||||
.B %J
|
||||
in
|
||||
.IR print (2)
|
||||
format strings.
|
||||
.SH SOURCE
|
||||
.B /sys/src/libjson
|
||||
.SH DIAGNOSTICS
|
||||
The functions
|
||||
.IB jsonparse ,
|
||||
.B jsonbyname
|
||||
.I jsonparse,
|
||||
.I jsonbyname
|
||||
and
|
||||
.B jsonstr
|
||||
.I jsonstr
|
||||
return
|
||||
.B nil
|
||||
on error and set an error string (see
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
LIB=/$objtype/lib/libjson.a
|
||||
OFILES=\
|
||||
json.$O
|
||||
json.$O\
|
||||
printjson.$O
|
||||
|
||||
HFILES=\
|
||||
/sys/include/json.h
|
||||
|
|
93
sys/src/libjson/printjson.c
Normal file
93
sys/src/libjson/printjson.c
Normal file
|
@ -0,0 +1,93 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <json.h>
|
||||
|
||||
static int printjson(Fmt*, JSON*, int);
|
||||
static int printarray(Fmt*, JSON*, int);
|
||||
static int printobject(Fmt*, JSON*, int);
|
||||
|
||||
static int
|
||||
printarray(Fmt *f, JSON *j, int indent)
|
||||
{
|
||||
JSONEl *jl;
|
||||
int i, r;
|
||||
|
||||
if(j->first == nil){
|
||||
return fmtprint(f, "[]");
|
||||
}
|
||||
r = fmtprint(f, "[\n");
|
||||
for(jl = j->first; jl != nil; jl = jl->next){
|
||||
for(i = 0; i < indent; i++)
|
||||
r += fmtprint(f, "\t");
|
||||
r += printjson(f, jl->val, indent);
|
||||
r += fmtprint(f, "%s\n", jl->next != nil ? "," : "");
|
||||
}
|
||||
for(i = 0; i < indent-1; i++)
|
||||
r += fmtprint(f, "\t");
|
||||
r += fmtprint(f, "]");
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
printobject(Fmt *f, JSON *j, int indent)
|
||||
{
|
||||
JSONEl *jl;
|
||||
int i, r;
|
||||
|
||||
if(j->first == nil){
|
||||
return fmtprint(f, "{}");
|
||||
}
|
||||
r = fmtprint(f, "{\n");
|
||||
for(jl = j->first; jl != nil; jl = jl->next){
|
||||
for(i = 0; i < indent; i++)
|
||||
fmtprint(f, "\t");
|
||||
r += fmtprint(f, "\"%s\": ", jl->name);
|
||||
r += printjson(f, jl->val, indent);
|
||||
r += fmtprint(f, "%s\n", jl->next != nil ? "," : "");
|
||||
}
|
||||
for(i = 0; i < indent-1; i++)
|
||||
r += fmtprint(f, "\t");
|
||||
r += fmtprint(f, "}");
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
printjson(Fmt *f, JSON *j, int indent)
|
||||
{
|
||||
switch(j->t){
|
||||
case JSONNull:
|
||||
return fmtprint(f, "null");
|
||||
break;
|
||||
case JSONBool:
|
||||
return fmtprint(f, "%s", j->n ? "true" : "false");
|
||||
break;
|
||||
case JSONNumber:
|
||||
return fmtprint(f, "%f", j->n);
|
||||
break;
|
||||
case JSONString:
|
||||
return fmtprint(f, "\"%s\"", j->s);
|
||||
break;
|
||||
case JSONArray:
|
||||
return printarray(f, j, indent+1);
|
||||
break;
|
||||
case JSONObject:
|
||||
return printobject(f, j, indent+1);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
JSONfmt(Fmt *f)
|
||||
{
|
||||
JSON *j;
|
||||
|
||||
j = va_arg(f->args, JSON*);
|
||||
return printjson(f, j, 0);
|
||||
}
|
||||
|
||||
void
|
||||
JSONfmtinstall(void)
|
||||
{
|
||||
fmtinstall('J', JSONfmt);
|
||||
}
|
Loading…
Reference in a new issue