Skip to content

Commit

Permalink
Rudimentary number parsing and other goodies
Browse files Browse the repository at this point in the history
  • Loading branch information
mnunberg committed Apr 4, 2012
1 parent 5af74ba commit 101cdb4
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 6 deletions.
5 changes: 5 additions & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
Doxyfile
LICENSE
MANIFEST
Makefile
README.pod
examples/Makefile
Expand All @@ -8,7 +9,11 @@ examples/glib-datatypes.h
json_samples.tgz
jsonsl.c
jsonsl.h
perf/Makefile
perf/bench.c
perf/documents.c
perf/documents.h
perf/perftest.c
srcutil/genchartables.pl
tests/Makefile
tests/jpr_test.c
Expand Down
Binary file modified json_samples.tgz
Binary file not shown.
52 changes: 50 additions & 2 deletions jsonsl.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ struct jsonsl_metrics_st {
};

static struct jsonsl_metrics_st GlobalMetrics = { 0 };

static unsigned long GenericCounter[0x100] = { 0 };
static unsigned long StringyCatchCounter[0x100] = { 0 };

Expand Down Expand Up @@ -214,6 +213,9 @@ jsonsl_feed(jsonsl_t jsn, const jsonsl_char_t *bytes, size_t nbytes)
INVOKE_ERROR(HKEY_EXPECTED); \
}

#define EXTRACT_NUMERIC \


const jsonsl_uchar_t *c = (jsonsl_uchar_t*)bytes;
size_t levels_max = jsn->levels_max;
struct jsonsl_state_st *state = jsn->stack + jsn->level;
Expand Down Expand Up @@ -243,7 +245,11 @@ jsonsl_feed(jsonsl_t jsn, const jsonsl_char_t *bytes, size_t nbytes)
/* check if our character cannot ever change our current string state
* or throw an error
*/
if (!chrt_string_nopass[CUR_CHAR]) {
if (
#ifdef JSONSL_USE_WCHAR
CUR_CHAR >= 0x100 ||
#endif /* JSONSL_USE_WCHAR */
(!chrt_string_nopass[CUR_CHAR & 0xff])) {
INCR_METRIC(STRINGY_INSIGNIFICANT);
goto GT_NEXT;
} else if (CUR_CHAR == '"') {
Expand All @@ -256,6 +262,43 @@ jsonsl_feed(jsonsl_t jsn, const jsonsl_char_t *bytes, size_t nbytes)
INCR_METRIC(STRINGY_SLOWPATH);

} else if (state->type == JSONSL_T_SPECIAL) {
if (state->special_flags & (JSONSL_SPECIALf_SIGNED|JSONSL_SPECIALf_UNSIGNED)) {
switch (CUR_CHAR) {
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '0':
state->nelem = (state->nelem*10) + (CUR_CHAR-0x30);
goto GT_NEXT;

case 'e':
case 'E':
case '-':
case '+':
state->special_flags |= JSONSL_SPECIALf_EXPONENT;
goto GT_NEXT;
case '.':
state->special_flags |= JSONSL_SPECIALf_FLOAT;
goto GT_NEXT;
default:
if (is_special_end(CUR_CHAR)) {
SPECIAL_POP;
jsn->expecting = ',';
if (is_allowed_whitespace(CUR_CHAR)) {
goto GT_NEXT;
}
goto GT_STRUCTURAL_TOKEN;
}
INVOKE_ERROR(INVALID_NUMBER);
break;
}
}
if (!is_special_end(CUR_CHAR)) {
INCR_METRIC(SPECIAL_FASTPATH);
/* Most common case. Inside a number */
Expand Down Expand Up @@ -483,6 +526,11 @@ jsonsl_feed(jsonsl_t jsn, const jsonsl_char_t *bytes, size_t nbytes)
STACK_PUSH;
state->type = JSONSL_T_SPECIAL;
state->special_flags = special_flags;
if (special_flags == JSONSL_SPECIALf_UNSIGNED) {
state->nelem = CUR_CHAR - 0x30;
} else {
state->nelem = 0;
}
CALLBACK(SPECIAL, PUSH);
}
goto GT_NEXT;
Expand Down
11 changes: 8 additions & 3 deletions jsonsl.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ typedef enum {
X(ESCAPE_INVALID) \
/* Trailing comma */ \
X(TRAILING_COMMA) \
/* An invalid number was passed in a numeric field */ \
X(INVALID_NUMBER) \
/* The following are for JPR Stuff */ \
\
/* Found a literal '%' but it was only followed by a single valid hex digit */ \
Expand Down Expand Up @@ -195,9 +197,13 @@ struct jsonsl_state_st {
* For objects (hashes), an element is either
* a key or a value. Thus for one complete pair,
* nelem will be 2.
* This field has no meaning for string/hkey/special types
*
* For special types, this will hold the sum of the digits.
* This only holds true for values which are simple signed/unsigned
* numbers. Otherwise a special flag is set, and extra handling is not
* performed.
*/
unsigned int nelem;
unsigned long nelem;


/**
Expand All @@ -209,7 +215,6 @@ struct jsonsl_state_st {

/*TODO: merge this and special_flags into a union */


/**
* Position offset variables. These are relative to jsn->pos.
* pos_begin is the position at which this state was first pushed
Expand Down
2 changes: 1 addition & 1 deletion perf/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
all: bench yajl-perftest

CFLAGS+= -Wno-overlength-strings -fvisibility=hidden -DNDEBUG -mtune=native
CFLAGS+= -Wno-overlength-strings -fvisibility=hidden -DJSONSL_NO_JPR -DNDEBUG
#CFLAGS+=-DJSONSL_USE_METRICS
BENCH_LFLAGS=

Expand Down

0 comments on commit 101cdb4

Please sign in to comment.