Back to the main page.

    1: /* See one of the index files for license and other details. */
    2: #ifndef jsoncvt_json_h
    3: #define jsoncvt_json_h
    4: #pragma once
    5: #include <stdio.h>
    6:
    7: /** The different types of values in our JSON parser. Unlike the
    8:  *  standard, we discriminate between integer and real values. */
    9: enum jtypes {
   10:     jnull,      /**< The JSON "null" value. */
   11:     jtrue,      /**< Just a simple "true" value. */
   12:     jfalse,     /**< Just a simple "false" value. */
   13:     jstring,    /**< Just your run of the mill string. */
   14:     jnumber,    /**< A JSON number (still just a string). */
   15:     jarray,     /**< A vector of values. */
   16:     jobject,    /**< An assoc. array of names and arbitrary values. */
   17:     jint,       /**< A JSON number parsed into a native integer. */
   18:     jreal,      /**< A JSON number parsed into a long double. */
   19: };
   20:
   21: /** A jvalue represents the different values found in a parse of a
   22:  *  JSON doc. A value can be terminal, like a string or a number, or
   23:  *  it can nest, as with arrays and objects. The value of #d reflects
   24:  *  which part of the union is value. */
   25: typedef struct jvalue {
   26:
   27:     /** Just your basic discriminator, describing which part of the
   28:      *  union below is active. When this is jtrue, jfalse, or jnull,
   29:      *  nothing in #u is valid (being unnecessary); all other values
   30:      *  correspond to one of the #u members as described below. */
   31:     enum jtypes d;
   32:
   33:     /** Some values have a name associated with them; in a JSON
   34:      *  object, for example, the value is assigned to a specific name.
   35:      *  When #d is jobject, this string should point to the name of a
   36:      *  member (whose value is in #u). For other values of #d, this
   37:      *  member should be null. A previous implementation used a
   38:      *  separate structure for these pairings, but placing the name
   39:      *  inside each value only costs an extra 4 or 8 bytes yet
   40:      *  simplifies the tree quite a bit for our client. */
   41:     char *n;
   42:
   43:     /** According to #d above, one or none of these are the active value. */
   44:     union {
   45:         /** When #d is jstring or jnumber, this string is active in
   46:          *  the union. While obvious for jstring, why would this be
   47:          *  used for jnumber? Because, often, there's no need to parse
   48:          *  the number value into something native. While integers are
   49:          *  exact, there's often an unavoidable loss of precision
   50:          *  when converting real numbers. So, we defer it as long as
   51:          *  we can. If the client application actually *wants* a
   52:          *  parsed value, it can convert the string to a native value,
   53:          *  cache it away in the #i or #r members, and change the
   54:          *  discriminator to jint or jreal accordingly. This avoids
   55:          *  unnecessary parsing work and loss of precision, but
   56:          *  doesn't make it unduly hard for a client to deal with. See
   57:          *  jupdate() as a function the client can call to do just
   58:          *  that. */
   59:         char *s;
   60:
   61:         /** When the discriminator is jint, this integer is active. */
   62:         long long i;
   63:
   64:         /** When the discriminator is jreal, this long double is
   65:          *  active. */
   66:         long double r;
   67:
   68:         /** When the discriminator is jarray or jobject, this
   69:          *  zero-terminated vector of pointers to jvalue is active.
   70:          *  You'll find the ptrvec routines make building these
   71:          *  easy. */
   72:         struct jvalue **v;
   73:     } u;
   74: } jvalue;
   75:
   76: extern jvalue *jnew();
   77: extern jvalue *jclear( jvalue * );
   78: extern void jdel( jvalue * );
   79: extern jvalue *jparse( FILE *fp );
   80: extern jvalue *jupdate(  jvalue * );
   81: extern int jdump( FILE *fp, const jvalue *j );
   82:
   83: #endif
   84: 

Back to the main page.