Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
mongoose
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
esp
mongoose
Commits
bda05d93
Commit
bda05d93
authored
9 years ago
by
Marko Mikulicic
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import frozen
PUBLISHED_FROM=9f6f38e92b5952b9571d73569c2752b6805f15c5
parent
59bc2af4
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
150 additions
and
55 deletions
+150
-55
mongoose.c
mongoose.c
+134
-39
mongoose.h
mongoose.h
+16
-16
No files found.
mongoose.c
View file @
bda05d93
...
...
@@ -543,7 +543,7 @@ double cs_time() {
* See the GNU General Public License for more details.
*
* Alternatively, you can license this library under a commercial
* license, as set out in <http
s://www.cesanta.com/license
>.
* license, as set out in <http
://cesanta.com/products.html
>.
*/
#define _CRT_SECURE_NO_WARNINGS
/* Disable deprecation warning in VS2005+ */
...
...
@@ -578,8 +578,15 @@ struct frozen {
static
int
parse_object
(
struct
frozen
*
f
);
static
int
parse_value
(
struct
frozen
*
f
);
#define EXPECT(cond, err_code) do { if (!(cond)) return (err_code); } while (0)
#define TRY(expr) do { int _n = expr; if (_n < 0) return _n; } while (0)
#define EXPECT(cond, err_code) \
do { \
if (!(cond)) return (err_code); \
} while (0)
#define TRY(expr) \
do { \
int _n = expr; \
if (_n < 0) return _n; \
} while (0)
#define END_OF_STRING (-1)
static
int
left
(
const
struct
frozen
*
f
)
{
...
...
@@ -596,12 +603,23 @@ static void skip_whitespaces(struct frozen *f) {
static
int
cur
(
struct
frozen
*
f
)
{
skip_whitespaces
(
f
);
return
f
->
cur
>=
f
->
end
?
END_OF_STRING
:
*
(
unsigned
char
*
)
f
->
cur
;
return
f
->
cur
>=
f
->
end
?
END_OF_STRING
:
*
(
unsigned
char
*
)
f
->
cur
;
}
static
int
test_and_skip
(
struct
frozen
*
f
,
int
expected
)
{
int
ch
=
cur
(
f
);
if
(
ch
==
expected
)
{
f
->
cur
++
;
return
0
;
}
if
(
ch
==
expected
)
{
f
->
cur
++
;
return
0
;
}
return
ch
==
END_OF_STRING
?
JSON_STRING_INCOMPLETE
:
JSON_STRING_INVALID
;
}
static
int
test_no_skip
(
struct
frozen
*
f
,
int
expected
)
{
int
ch
=
cur
(
f
);
if
(
ch
==
expected
)
{
return
0
;
}
return
ch
==
END_OF_STRING
?
JSON_STRING_INCOMPLETE
:
JSON_STRING_INVALID
;
}
...
...
@@ -620,11 +638,19 @@ static int is_hex_digit(int ch) {
static
int
get_escape_len
(
const
char
*
s
,
int
len
)
{
switch
(
*
s
)
{
case
'u'
:
return
len
<
6
?
JSON_STRING_INCOMPLETE
:
is_hex_digit
(
s
[
1
])
&&
is_hex_digit
(
s
[
2
])
&&
is_hex_digit
(
s
[
3
])
&&
is_hex_digit
(
s
[
4
])
?
5
:
JSON_STRING_INVALID
;
case
'"'
:
case
'\\'
:
case
'/'
:
case
'b'
:
case
'f'
:
case
'n'
:
case
'r'
:
case
't'
:
return
len
<
6
?
JSON_STRING_INCOMPLETE
:
is_hex_digit
(
s
[
1
])
&&
is_hex_digit
(
s
[
2
])
&&
is_hex_digit
(
s
[
3
])
&&
is_hex_digit
(
s
[
4
])
?
5
:
JSON_STRING_INVALID
;
case
'"'
:
case
'\\'
:
case
'/'
:
case
'b'
:
case
'f'
:
case
'n'
:
case
'r'
:
case
't'
:
return
len
<
2
?
JSON_STRING_INCOMPLETE
:
1
;
default:
return
JSON_STRING_INVALID
;
...
...
@@ -670,9 +696,12 @@ static int parse_identifier(struct frozen *f) {
static
int
get_utf8_char_len
(
unsigned
char
ch
)
{
if
((
ch
&
0x80
)
==
0
)
return
1
;
switch
(
ch
&
0xf0
)
{
case
0xf0
:
return
4
;
case
0xe0
:
return
3
;
default:
return
2
;
case
0xf0
:
return
4
;
case
0xe0
:
return
3
;
default:
return
2
;
}
}
...
...
@@ -682,9 +711,9 @@ static int parse_string(struct frozen *f) {
TRY
(
test_and_skip
(
f
,
'"'
));
TRY
(
capture_ptr
(
f
,
f
->
cur
,
JSON_TYPE_STRING
));
for
(;
f
->
cur
<
f
->
end
;
f
->
cur
+=
len
)
{
ch
=
*
(
unsigned
char
*
)
f
->
cur
;
ch
=
*
(
unsigned
char
*
)
f
->
cur
;
len
=
get_utf8_char_len
((
unsigned
char
)
ch
);
EXPECT
(
ch
>=
32
&&
len
>
0
,
JSON_STRING_INVALID
);
/* No control chars */
EXPECT
(
ch
>=
32
&&
len
>
0
,
JSON_STRING_INVALID
);
/* No control chars */
EXPECT
(
len
<
left
(
f
),
JSON_STRING_INCOMPLETE
);
if
(
ch
==
'\\'
)
{
EXPECT
((
n
=
get_escape_len
(
f
->
cur
+
1
,
left
(
f
)))
>
0
,
n
);
...
...
@@ -764,14 +793,35 @@ static int parse_value(struct frozen *f) {
int
ch
=
cur
(
f
);
switch
(
ch
)
{
case
'"'
:
TRY
(
parse_string
(
f
));
break
;
case
'{'
:
TRY
(
parse_object
(
f
));
break
;
case
'['
:
TRY
(
parse_array
(
f
));
break
;
case
'n'
:
TRY
(
expect
(
f
,
"null"
,
4
,
JSON_TYPE_NULL
));
break
;
case
't'
:
TRY
(
expect
(
f
,
"true"
,
4
,
JSON_TYPE_TRUE
));
break
;
case
'f'
:
TRY
(
expect
(
f
,
"false"
,
5
,
JSON_TYPE_FALSE
));
break
;
case
'-'
:
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
case
'"'
:
TRY
(
parse_string
(
f
));
break
;
case
'{'
:
TRY
(
parse_object
(
f
));
break
;
case
'['
:
TRY
(
parse_array
(
f
));
break
;
case
'n'
:
TRY
(
expect
(
f
,
"null"
,
4
,
JSON_TYPE_NULL
));
break
;
case
't'
:
TRY
(
expect
(
f
,
"true"
,
4
,
JSON_TYPE_TRUE
));
break
;
case
'f'
:
TRY
(
expect
(
f
,
"false"
,
5
,
JSON_TYPE_FALSE
));
break
;
case
'-'
:
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
TRY
(
parse_number
(
f
));
break
;
default:
...
...
@@ -821,9 +871,19 @@ static int parse_object(struct frozen *f) {
}
static
int
doit
(
struct
frozen
*
f
)
{
int
ret
=
0
;
if
(
f
->
cur
==
0
||
f
->
end
<
f
->
cur
)
return
JSON_STRING_INVALID
;
if
(
f
->
end
==
f
->
cur
)
return
JSON_STRING_INCOMPLETE
;
TRY
(
parse_object
(
f
));
if
(
0
==
(
ret
=
test_no_skip
(
f
,
'{'
)))
{
TRY
(
parse_object
(
f
));
}
else
if
(
0
==
(
ret
=
test_no_skip
(
f
,
'['
)))
{
TRY
(
parse_array
(
f
));
}
else
{
return
ret
;
}
TRY
(
capture_ptr
(
f
,
f
->
cur
,
JSON_TYPE_EOF
));
capture_len
(
f
,
f
->
num_tokens
,
f
->
cur
);
return
0
;
...
...
@@ -876,8 +936,9 @@ struct json_token *find_json_token(struct json_token *toks, const char *path) {
ind
+=
path
[
n
]
-
'0'
;
}
if
(
path
[
n
++
]
!=
']'
)
return
0
;
skip
=
1
;
/* In objects, we skip 2 elems while iterating, in arrays 1. */
}
else
if
(
toks
->
type
!=
JSON_TYPE_OBJECT
)
return
0
;
skip
=
1
;
/* In objects, we skip 2 elems while iterating, in arrays 1. */
}
else
if
(
toks
->
type
!=
JSON_TYPE_OBJECT
)
return
0
;
toks
++
;
for
(
i
=
0
;
i
<
toks
[
-
1
].
num_desc
;
i
+=
skip
,
ind2
++
)
{
/* ind == -1 indicated that we're iterating an array, not object */
...
...
@@ -919,20 +980,46 @@ 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
;
#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
(
'"'
);
while
(
str
<
str_end
)
{
ch
=
*
str
++
;
switch
(
ch
)
{
case
'"'
:
EMIT
(
'\\'
);
EMIT
(
'"'
);
break
;
case
'\\'
:
EMIT
(
'\\'
);
EMIT
(
'\\'
);
break
;
case
'\b'
:
EMIT
(
'\\'
);
EMIT
(
'b'
);
break
;
case
'\f'
:
EMIT
(
'\\'
);
EMIT
(
'f'
);
break
;
case
'\n'
:
EMIT
(
'\\'
);
EMIT
(
'n'
);
break
;
case
'\r'
:
EMIT
(
'\\'
);
EMIT
(
'r'
);
break
;
case
'\t'
:
EMIT
(
'\\'
);
EMIT
(
't'
);
break
;
default:
EMIT
(
ch
);
case
'"'
:
EMIT
(
'\\'
);
EMIT
(
'"'
);
break
;
case
'\\'
:
EMIT
(
'\\'
);
EMIT
(
'\\'
);
break
;
case
'\b'
:
EMIT
(
'\\'
);
EMIT
(
'b'
);
break
;
case
'\f'
:
EMIT
(
'\\'
);
EMIT
(
'f'
);
break
;
case
'\n'
:
EMIT
(
'\\'
);
EMIT
(
'n'
);
break
;
case
'\r'
:
EMIT
(
'\\'
);
EMIT
(
'r'
);
break
;
case
'\t'
:
EMIT
(
'\\'
);
EMIT
(
't'
);
break
;
default:
EMIT
(
ch
);
}
}
EMIT
(
'"'
);
...
...
@@ -960,18 +1047,26 @@ int json_emit_va(char *s, int s_len, const char *fmt, va_list ap) {
while
(
*
fmt
!=
'\0'
)
{
switch
(
*
fmt
)
{
case
'['
:
case
']'
:
case
'{'
:
case
'}'
:
case
','
:
case
':'
:
case
' '
:
case
'\r'
:
case
'\n'
:
case
'\t'
:
case
'['
:
case
']'
:
case
'{'
:
case
'}'
:
case
','
:
case
':'
:
case
' '
:
case
'\r'
:
case
'\n'
:
case
'\t'
:
if
(
s
<
end
)
{
*
s
=
*
fmt
;
}
s
++
;
break
;
case
'i'
:
s
+=
json_emit_long
(
s
,
end
-
s
,
va_arg
(
ap
,
long
));
s
+=
json_emit_long
(
s
,
end
-
s
,
va_arg
(
ap
,
long
)
);
break
;
case
'f'
:
s
+=
json_emit_double
(
s
,
end
-
s
,
va_arg
(
ap
,
double
));
s
+=
json_emit_double
(
s
,
end
-
s
,
va_arg
(
ap
,
double
)
);
break
;
case
'v'
:
str
=
va_arg
(
ap
,
char
*
);
...
...
This diff is collapsed.
Click to expand it.
mongoose.h
View file @
bda05d93
...
...
@@ -840,7 +840,7 @@ size_t strnlen(const char *s, size_t maxlen);
* See the GNU General Public License for more details.
*
* Alternatively, you can license this library under a commercial
* license, as set out in <http
s://www.cesanta.com/license
>.
* license, as set out in <http
://cesanta.com/products.html
>.
*/
#ifndef FROZEN_HEADER_INCLUDED
...
...
@@ -853,27 +853,27 @@ extern "C" {
#include <stdarg.h>
enum
json_type
{
JSON_TYPE_EOF
=
0
,
/* End of parsed tokens marker */
JSON_TYPE_STRING
=
1
,
JSON_TYPE_NUMBER
=
2
,
JSON_TYPE_OBJECT
=
3
,
JSON_TYPE_TRUE
=
4
,
JSON_TYPE_FALSE
=
5
,
JSON_TYPE_NULL
=
6
,
JSON_TYPE_ARRAY
=
7
JSON_TYPE_EOF
=
0
,
/* End of parsed tokens marker */
JSON_TYPE_STRING
=
1
,
JSON_TYPE_NUMBER
=
2
,
JSON_TYPE_OBJECT
=
3
,
JSON_TYPE_TRUE
=
4
,
JSON_TYPE_FALSE
=
5
,
JSON_TYPE_NULL
=
6
,
JSON_TYPE_ARRAY
=
7
};
struct
json_token
{
const
char
*
ptr
;
/* Points to the beginning of the token */
int
len
;
/* Token length */
int
num_desc
;
/* For arrays and object, total number of descendants */
enum
json_type
type
;
/* Type of the token, possible values above */
const
char
*
ptr
;
/* Points to the beginning of the token */
int
len
;
/* Token length */
int
num_desc
;
/* For arrays and object, total number of descendants */
enum
json_type
type
;
/* Type of the token, possible values above */
};
/* Error codes */
#define JSON_STRING_INVALID
-1
#define JSON_STRING_INCOMPLETE
-2
#define JSON_TOKEN_ARRAY_TOO_SMALL
-3
#define JSON_STRING_INVALID -1
#define JSON_STRING_INCOMPLETE -2
#define JSON_TOKEN_ARRAY_TOO_SMALL -3
int
parse_json
(
const
char
*
json_string
,
int
json_string_length
,
struct
json_token
*
tokens_array
,
int
size_of_tokens_array
);
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment