Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party CJSON
提交
415962da
T
Third Party CJSON
项目概览
OpenHarmony
/
Third Party CJSON
大约 1 年 前同步成功
通知
6
Star
22
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
Third Party CJSON
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
415962da
编写于
2月 16, 2017
作者:
M
Max Bruckner
提交者:
GitHub
2月 16, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #109 from DaveGamble/simplify-parse
Simplify parsing
上级
b6974ecb
b41264d1
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
339 addition
and
293 deletion
+339
-293
cJSON.c
cJSON.c
+339
-293
未找到文件。
cJSON.c
浏览文件 @
415962da
...
@@ -153,21 +153,20 @@ void cJSON_Delete(cJSON *c)
...
@@ -153,21 +153,20 @@ void cJSON_Delete(cJSON *c)
}
}
/* Parse the input text to generate a number, and populate the result into item. */
/* Parse the input text to generate a number, and populate the result into item. */
static
const
unsigned
char
*
parse_number
(
cJSON
*
item
,
const
unsigned
char
*
num
)
static
const
unsigned
char
*
parse_number
(
cJSON
*
const
item
,
const
unsigned
char
*
const
input
)
{
{
double
number
=
0
;
double
number
=
0
;
unsigned
char
*
endpointer
=
NULL
;
unsigned
char
*
after_end
=
NULL
;
if
(
num
==
NULL
)
if
(
input
==
NULL
)
{
{
return
NULL
;
return
NULL
;
}
}
number
=
strtod
((
const
char
*
)
num
,
(
char
**
)
&
endpointer
);
number
=
strtod
((
const
char
*
)
input
,
(
char
**
)
&
after_end
);
if
(
(
num
==
endpointer
)
||
(
num
==
NULL
)
)
if
(
input
==
after_end
)
{
{
/* parse_error */
return
NULL
;
/* parse_error */
return
NULL
;
}
}
item
->
valuedouble
=
number
;
item
->
valuedouble
=
number
;
...
@@ -185,9 +184,10 @@ static const unsigned char *parse_number(cJSON *item, const unsigned char *num)
...
@@ -185,9 +184,10 @@ static const unsigned char *parse_number(cJSON *item, const unsigned char *num)
{
{
item
->
valueint
=
(
int
)
number
;
item
->
valueint
=
(
int
)
number
;
}
}
item
->
type
=
cJSON_Number
;
item
->
type
=
cJSON_Number
;
return
endpointer
;
return
after_end
;
}
}
/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
...
@@ -367,7 +367,7 @@ static unsigned char *print_number(const cJSON *item, printbuffer *p)
...
@@ -367,7 +367,7 @@ static unsigned char *print_number(const cJSON *item, printbuffer *p)
}
}
/* parse 4 digit hexadecimal number */
/* parse 4 digit hexadecimal number */
static
unsigned
parse_hex4
(
const
unsigned
char
*
str
)
static
unsigned
parse_hex4
(
const
unsigned
char
*
const
input
)
{
{
unsigned
int
h
=
0
;
unsigned
int
h
=
0
;
size_t
i
=
0
;
size_t
i
=
0
;
...
@@ -375,17 +375,17 @@ static unsigned parse_hex4(const unsigned char *str)
...
@@ -375,17 +375,17 @@ static unsigned parse_hex4(const unsigned char *str)
for
(
i
=
0
;
i
<
4
;
i
++
)
for
(
i
=
0
;
i
<
4
;
i
++
)
{
{
/* parse digit */
/* parse digit */
if
((
*
str
>=
'0'
)
&&
(
*
str
<=
'9'
))
if
((
input
[
i
]
>=
'0'
)
&&
(
input
[
i
]
<=
'9'
))
{
{
h
+=
(
unsigned
int
)
(
*
str
)
-
'0'
;
h
+=
(
unsigned
int
)
input
[
i
]
-
'0'
;
}
}
else
if
((
*
str
>=
'A'
)
&&
(
*
str
<=
'F'
))
else
if
((
input
[
i
]
>=
'A'
)
&&
(
input
[
i
]
<=
'F'
))
{
{
h
+=
(
unsigned
int
)
10
+
(
*
str
)
-
'A'
;
h
+=
(
unsigned
int
)
10
+
input
[
i
]
-
'A'
;
}
}
else
if
((
*
str
>=
'a'
)
&&
(
*
str
<=
'f'
))
else
if
((
input
[
i
]
>=
'a'
)
&&
(
input
[
i
]
<=
'f'
))
{
{
h
+=
(
unsigned
int
)
10
+
(
*
str
)
-
'a'
;
h
+=
(
unsigned
int
)
10
+
input
[
i
]
-
'a'
;
}
}
else
/* invalid */
else
/* invalid */
{
{
...
@@ -396,208 +396,263 @@ static unsigned parse_hex4(const unsigned char *str)
...
@@ -396,208 +396,263 @@ static unsigned parse_hex4(const unsigned char *str)
{
{
/* shift left to make place for the next nibble */
/* shift left to make place for the next nibble */
h
=
h
<<
4
;
h
=
h
<<
4
;
str
++
;
}
}
}
}
return
h
;
return
h
;
}
}
/* first bytes of UTF8 encoding for a given length in bytes */
/* converts a UTF-16 literal to UTF-8
static
const
unsigned
char
firstByteMark
[
5
]
=
* A literal can be one or two sequences of the form \uXXXX */
static
unsigned
char
utf16_literal_to_utf8
(
const
unsigned
char
*
const
input_pointer
,
const
unsigned
char
*
const
input_end
,
unsigned
char
**
output_pointer
,
const
unsigned
char
**
error_pointer
)
{
{
/* first bytes of UTF8 encoding for a given length in bytes */
static
const
unsigned
char
firstByteMark
[
5
]
=
{
0x00
,
/* should never happen */
0x00
,
/* should never happen */
0x00
,
/* 0xxxxxxx */
0x00
,
/* 0xxxxxxx */
0xC0
,
/* 110xxxxx */
0xC0
,
/* 110xxxxx */
0xE0
,
/* 1110xxxx */
0xE0
,
/* 1110xxxx */
0xF0
/* 11110xxx */
0xF0
/* 11110xxx */
};
};
/* Parse the input text into an unescaped cstring, and populate item. */
long
unsigned
int
codepoint
=
0
;
static
const
unsigned
char
*
parse_string
(
cJSON
*
item
,
const
unsigned
char
*
str
,
const
unsigned
char
**
ep
)
unsigned
int
first_code
=
0
;
{
const
unsigned
char
*
first_sequence
=
input_pointer
;
const
unsigned
char
*
ptr
=
str
+
1
;
unsigned
char
utf8_length
=
0
;
const
unsigned
char
*
end_ptr
=
str
+
1
;
unsigned
char
sequence_length
=
0
;
unsigned
char
*
ptr2
=
NULL
;
unsigned
char
*
out
=
NULL
;
size_t
len
=
0
;
unsigned
uc
=
0
;
unsigned
uc2
=
0
;
/* not a string! */
/* get the first utf16 sequence */
if
(
*
str
!=
'\"'
)
first_code
=
parse_hex4
(
first_sequence
+
2
);
if
((
input_end
-
first_sequence
)
<
6
)
{
{
*
ep
=
str
;
/* input ends unexpectedly */
*
error_pointer
=
first_sequence
;
goto
fail
;
goto
fail
;
}
}
while
((
*
end_ptr
!=
'\"'
)
&&
*
end_ptr
)
/* check that the code is valid */
{
if
(((
first_code
>=
0xDC00
)
&&
(
first_code
<=
0xDFFF
))
||
(
first_code
==
0
))
if
(
*
end_ptr
++
==
'\\'
)
{
if
(
*
end_ptr
==
'\0'
)
{
{
/* prevent buffer overflow when last input character is a backslash */
*
error_pointer
=
first_sequence
;
goto
fail
;
goto
fail
;
}
}
/* Skip escaped quotes. */
end_ptr
++
;
}
len
++
;
}
/* This is at most how long we need for the string, roughly. */
/* UTF16 surrogate pair */
out
=
(
unsigned
char
*
)
cJSON_malloc
(
len
+
1
);
if
((
first_code
>=
0xD800
)
&&
(
first_code
<=
0xDBFF
))
if
(
!
out
)
{
{
goto
fail
;
const
unsigned
char
*
second_sequence
=
first_sequence
+
6
;
}
unsigned
int
second_code
=
0
;
sequence_length
=
12
;
/* \uXXXX\uXXXX */
ptr2
=
out
;
if
((
input_end
-
second_sequence
)
<
6
)
/* loop through the string literal */
while
(
ptr
<
end_ptr
)
{
if
(
*
ptr
!=
'\\'
)
{
*
ptr2
++
=
*
ptr
++
;
}
/* escape sequence */
else
{
ptr
++
;
switch
(
*
ptr
)
{
case
'b'
:
*
ptr2
++
=
'\b'
;
break
;
case
'f'
:
*
ptr2
++
=
'\f'
;
break
;
case
'n'
:
*
ptr2
++
=
'\n'
;
break
;
case
'r'
:
*
ptr2
++
=
'\r'
;
break
;
case
't'
:
*
ptr2
++
=
'\t'
;
break
;
case
'\"'
:
case
'\\'
:
case
'/'
:
*
ptr2
++
=
*
ptr
;
break
;
case
'u'
:
/* transcode utf16 to utf8. See RFC2781 and RFC3629. */
uc
=
parse_hex4
(
ptr
+
1
);
/* get the unicode char. */
ptr
+=
4
;
if
(
ptr
>=
end_ptr
)
{
{
/* invalid
*/
/* input ends unexpectedly
*/
*
ep
=
str
;
*
error_pointer
=
first_sequence
;
goto
fail
;
goto
fail
;
}
}
/* check for invalid. */
if
(((
uc
>=
0xDC00
)
&&
(
uc
<=
0xDFFF
))
||
(
uc
==
0
))
if
((
second_sequence
[
0
]
!=
'\\'
)
||
(
second_sequence
[
1
]
!=
'u'
))
{
{
*
ep
=
str
;
/* missing second half of the surrogate pair */
*
error_pointer
=
first_sequence
;
goto
fail
;
goto
fail
;
}
}
/* UTF16 surrogate pairs. */
/* get the second utf16 sequence */
if
((
uc
>=
0xD800
)
&&
(
uc
<=
0xDBFF
))
second_code
=
parse_hex4
(
second_sequence
+
2
);
/* check that the code is valid */
if
((
second_code
<
0xDC00
)
||
(
second_code
>
0xDFFF
))
{
{
if
((
ptr
+
6
)
>
end_ptr
)
/* invalid second half of the surrogate pair */
{
*
error_pointer
=
first_sequence
;
/* invalid */
*
ep
=
str
;
goto
fail
;
goto
fail
;
}
}
if
((
ptr
[
1
]
!=
'\\'
)
||
(
ptr
[
2
]
!=
'u'
))
{
/* missing second-half of surrogate. */
/* calculate the unicode codepoint from the surrogate pair */
*
ep
=
str
;
codepoint
=
0x10000
+
(((
first_code
&
0x3FF
)
<<
10
)
|
(
second_code
&
0x3FF
));
goto
fail
;
}
}
uc2
=
parse_hex4
(
ptr
+
3
);
else
ptr
+=
6
;
/* \uXXXX */
if
((
uc2
<
0xDC00
)
||
(
uc2
>
0xDFFF
))
{
{
/* invalid second-half of surrogate. */
sequence_length
=
6
;
/* \uXXXX */
*
ep
=
str
;
codepoint
=
first_code
;
goto
fail
;
}
/* calculate unicode codepoint from the surrogate pair */
uc
=
0x10000
+
(((
uc
&
0x3FF
)
<<
10
)
|
(
uc2
&
0x3FF
));
}
}
/* encode as UTF
8
/* encode as UTF-
8
* takes at maximum 4 bytes to encode:
* takes at maximum 4 bytes to encode:
* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
len
=
4
;
if
(
codepoint
<
0x80
)
if
(
uc
<
0x80
)
{
{
/* normal ascii, encoding 0xxxxxxx */
/* normal ascii, encoding 0xxxxxxx */
len
=
1
;
utf8_length
=
1
;
}
}
else
if
(
uc
<
0x800
)
else
if
(
codepoint
<
0x800
)
{
{
/* two bytes, encoding 110xxxxx 10xxxxxx */
/* two bytes, encoding 110xxxxx 10xxxxxx */
len
=
2
;
utf8_length
=
2
;
}
}
else
if
(
uc
<
0x10000
)
else
if
(
codepoint
<
0x10000
)
{
{
/* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */
/* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */
len
=
3
;
utf8_length
=
3
;
}
else
if
(
codepoint
<=
0x10FFFF
)
{
/* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */
utf8_length
=
4
;
}
else
{
/* invalid unicode codepoint */
*
error_pointer
=
first_sequence
;
goto
fail
;
}
}
ptr2
+=
len
;
switch
(
len
)
{
/* encode as utf8 */
switch
(
utf8_length
)
{
case
4
:
case
4
:
/* 10xxxxxx */
/* 10xxxxxx */
*--
ptr2
=
(
unsigned
char
)((
uc
|
0x80
)
&
0xBF
);
(
*
output_pointer
)[
3
]
=
(
unsigned
char
)((
codepoint
|
0x80
)
&
0xBF
);
uc
>>=
6
;
codepoint
>>=
6
;
case
3
:
case
3
:
/* 10xxxxxx */
/* 10xxxxxx */
*--
ptr2
=
(
unsigned
char
)((
uc
|
0x80
)
&
0xBF
);
(
*
output_pointer
)[
2
]
=
(
unsigned
char
)((
codepoint
|
0x80
)
&
0xBF
);
uc
>>=
6
;
codepoint
>>=
6
;
case
2
:
case
2
:
/* 10xxxxxx */
(
*
output_pointer
)[
1
]
=
(
unsigned
char
)((
codepoint
|
0x80
)
&
0xBF
);
*--
ptr2
=
(
unsigned
char
)((
uc
|
0x80
)
&
0xBF
);
codepoint
>>=
6
;
uc
>>=
6
;
case
1
:
case
1
:
/* depending on the length in bytes this determines the
/* depending on the length in bytes this determines the
* encoding of
the first UTF8 byte */
encoding of
the first UTF8 byte */
*--
ptr2
=
(
unsigned
char
)((
uc
|
firstByteMark
[
len
])
&
0xFF
);
(
*
output_pointer
)[
0
]
=
(
unsigned
char
)((
codepoint
|
firstByteMark
[
utf8_length
])
&
0xFF
);
break
;
break
;
default:
default:
*
ep
=
str
;
*
error_pointer
=
first_sequence
;
goto
fail
;
goto
fail
;
}
}
ptr2
+=
len
;
*
output_pointer
+=
utf8_length
;
break
;
default:
return
sequence_length
;
*
ep
=
str
;
fail:
return
0
;
}
/* Parse the input text into an unescaped cinput, and populate item. */
static
const
unsigned
char
*
parse_string
(
cJSON
*
const
item
,
const
unsigned
char
*
const
input
,
const
unsigned
char
**
const
error_pointer
)
{
const
unsigned
char
*
input_pointer
=
input
+
1
;
const
unsigned
char
*
input_end
=
input
+
1
;
unsigned
char
*
output_pointer
=
NULL
;
unsigned
char
*
output
=
NULL
;
/* not a string */
if
(
*
input
!=
'\"'
)
{
*
error_pointer
=
input
;
goto
fail
;
goto
fail
;
}
}
ptr
++
;
{
/* calculate approximate size of the output (overestimate) */
size_t
allocation_length
=
0
;
size_t
skipped_bytes
=
0
;
while
((
*
input_end
!=
'\"'
)
&&
(
*
input_end
!=
'\0'
))
{
/* is escape sequence */
if
(
input_end
[
0
]
==
'\\'
)
{
if
(
input_end
[
1
]
==
'\0'
)
{
/* prevent buffer overflow when last input character is a backslash */
goto
fail
;
}
}
skipped_bytes
++
;
input_end
++
;
}
}
*
ptr2
=
'\0'
;
input_end
++
;
if
(
*
ptr
==
'\"'
)
}
if
(
*
input_end
==
'\0'
)
{
{
ptr
++
;
goto
fail
;
/* string ended unexpectedly */
}
}
/* This is at most how much we need for the output */
allocation_length
=
(
size_t
)
(
input_end
-
input
)
-
skipped_bytes
;
output
=
(
unsigned
char
*
)
cJSON_malloc
(
allocation_length
+
sizeof
(
'\0'
));
if
(
output
==
NULL
)
{
goto
fail
;
/* allocation failure */
}
}
output_pointer
=
output
;
/* loop through the string literal */
while
(
input_pointer
<
input_end
)
{
if
(
*
input_pointer
!=
'\\'
)
{
*
output_pointer
++
=
*
input_pointer
++
;
}
/* escape sequence */
else
{
unsigned
char
sequence_length
=
2
;
switch
(
input_pointer
[
1
])
{
case
'b'
:
*
output_pointer
++
=
'\b'
;
break
;
case
'f'
:
*
output_pointer
++
=
'\f'
;
break
;
case
'n'
:
*
output_pointer
++
=
'\n'
;
break
;
case
'r'
:
*
output_pointer
++
=
'\r'
;
break
;
case
't'
:
*
output_pointer
++
=
'\t'
;
break
;
case
'\"'
:
case
'\\'
:
case
'/'
:
*
output_pointer
++
=
input_pointer
[
1
];
break
;
/* UTF-16 literal */
case
'u'
:
sequence_length
=
utf16_literal_to_utf8
(
input_pointer
,
input_end
,
&
output_pointer
,
error_pointer
);
if
(
sequence_length
==
0
)
{
/* failed to convert UTF16-literal to UTF-8 */
goto
fail
;
}
break
;
default:
*
error_pointer
=
input_pointer
;
goto
fail
;
}
input_pointer
+=
sequence_length
;
}
}
/* zero terminate the output */
*
output_pointer
=
'\0'
;
item
->
type
=
cJSON_String
;
item
->
type
=
cJSON_String
;
item
->
valuestring
=
(
char
*
)
out
;
item
->
valuestring
=
(
char
*
)
out
put
;
return
ptr
;
return
input_end
+
1
;
fail:
fail:
if
(
out
!=
NULL
)
if
(
out
put
!=
NULL
)
{
{
cJSON_free
(
out
);
cJSON_free
(
out
put
);
}
}
return
NULL
;
return
NULL
;
...
@@ -756,11 +811,11 @@ static unsigned char *print_string(const cJSON *item, printbuffer *p)
...
@@ -756,11 +811,11 @@ static unsigned char *print_string(const cJSON *item, printbuffer *p)
}
}
/* Predeclare these prototypes. */
/* Predeclare these prototypes. */
static
const
unsigned
char
*
parse_value
(
cJSON
*
item
,
const
unsigned
char
*
value
,
const
unsigned
char
**
ep
);
static
const
unsigned
char
*
parse_value
(
cJSON
*
const
item
,
const
unsigned
char
*
const
input
,
const
unsigned
char
**
const
ep
);
static
unsigned
char
*
print_value
(
const
cJSON
*
item
,
size_t
depth
,
cjbool
fmt
,
printbuffer
*
p
);
static
unsigned
char
*
print_value
(
const
cJSON
*
item
,
size_t
depth
,
cjbool
fmt
,
printbuffer
*
p
);
static
const
unsigned
char
*
parse_array
(
cJSON
*
item
,
const
unsigned
char
*
value
,
const
unsigned
char
**
ep
);
static
const
unsigned
char
*
parse_array
(
cJSON
*
const
item
,
const
unsigned
char
*
input
,
const
unsigned
char
**
const
ep
);
static
unsigned
char
*
print_array
(
const
cJSON
*
item
,
size_t
depth
,
cjbool
fmt
,
printbuffer
*
p
);
static
unsigned
char
*
print_array
(
const
cJSON
*
item
,
size_t
depth
,
cjbool
fmt
,
printbuffer
*
p
);
static
const
unsigned
char
*
parse_object
(
cJSON
*
item
,
const
unsigned
char
*
value
,
const
unsigned
char
**
ep
);
static
const
unsigned
char
*
parse_object
(
cJSON
*
const
item
,
const
unsigned
char
*
input
,
const
unsigned
char
**
const
ep
);
static
unsigned
char
*
print_object
(
const
cJSON
*
item
,
size_t
depth
,
cjbool
fmt
,
printbuffer
*
p
);
static
unsigned
char
*
print_object
(
const
cJSON
*
item
,
size_t
depth
,
cjbool
fmt
,
printbuffer
*
p
);
/* Utility to jump whitespace and cr/lf */
/* Utility to jump whitespace and cr/lf */
...
@@ -870,50 +925,56 @@ int cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const cjbool
...
@@ -870,50 +925,56 @@ int cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const cjbool
}
}
/* Parser core - when encountering text, process appropriately. */
/* Parser core - when encountering text, process appropriately. */
static
const
unsigned
char
*
parse_value
(
cJSON
*
item
,
const
unsigned
char
*
value
,
const
unsigned
char
**
ep
)
static
const
unsigned
char
*
parse_value
(
cJSON
*
const
item
,
const
unsigned
char
*
const
input
,
const
unsigned
char
**
const
error_pointer
)
{
{
if
(
!
value
)
if
(
input
==
NULL
)
{
{
/* Fail on null. */
return
NULL
;
/* no input */
return
NULL
;
}
}
/* parse the different types of values */
/* parse the different types of values */
if
(
!
strncmp
((
const
char
*
)
value
,
"null"
,
4
))
/* null */
if
(
!
strncmp
((
const
char
*
)
input
,
"null"
,
4
))
{
{
item
->
type
=
cJSON_NULL
;
item
->
type
=
cJSON_NULL
;
return
value
+
4
;
return
input
+
4
;
}
}
if
(
!
strncmp
((
const
char
*
)
value
,
"false"
,
5
))
/* false */
if
(
!
strncmp
((
const
char
*
)
input
,
"false"
,
5
))
{
{
item
->
type
=
cJSON_False
;
item
->
type
=
cJSON_False
;
return
value
+
5
;
return
input
+
5
;
}
}
if
(
!
strncmp
((
const
char
*
)
value
,
"true"
,
4
))
/* true */
if
(
!
strncmp
((
const
char
*
)
input
,
"true"
,
4
))
{
{
item
->
type
=
cJSON_True
;
item
->
type
=
cJSON_True
;
item
->
valueint
=
1
;
item
->
valueint
=
1
;
return
value
+
4
;
return
input
+
4
;
}
}
if
(
*
value
==
'\"'
)
/* string */
if
(
*
input
==
'\"'
)
{
{
return
parse_string
(
item
,
value
,
ep
);
return
parse_string
(
item
,
input
,
error_pointer
);
}
}
if
((
*
value
==
'-'
)
||
((
*
value
>=
'0'
)
&&
(
*
value
<=
'9'
)))
/* number */
if
((
*
input
==
'-'
)
||
((
*
input
>=
'0'
)
&&
(
*
input
<=
'9'
)))
{
{
return
parse_number
(
item
,
value
);
return
parse_number
(
item
,
input
);
}
}
if
(
*
value
==
'['
)
/* array */
if
(
*
input
==
'['
)
{
{
return
parse_array
(
item
,
value
,
ep
);
return
parse_array
(
item
,
input
,
error_pointer
);
}
}
if
(
*
value
==
'{'
)
/* object */
if
(
*
input
==
'{'
)
{
{
return
parse_object
(
item
,
value
,
ep
);
return
parse_object
(
item
,
input
,
error_pointer
);
}
}
/* failure. */
/* failure. */
*
e
p
=
value
;
*
e
rror_pointer
=
input
;
return
NULL
;
return
NULL
;
}
}
...
@@ -1027,80 +1088,78 @@ static unsigned char *print_value(const cJSON *item, size_t depth, cjbool fmt, p
...
@@ -1027,80 +1088,78 @@ static unsigned char *print_value(const cJSON *item, size_t depth, cjbool fmt, p
}
}
/* Build an array from input text. */
/* Build an array from input text. */
static
const
unsigned
char
*
parse_array
(
cJSON
*
item
,
const
unsigned
char
*
value
,
const
unsigned
char
**
ep
)
static
const
unsigned
char
*
parse_array
(
cJSON
*
const
item
,
const
unsigned
char
*
input
,
const
unsigned
char
**
const
error_pointer
)
{
{
cJSON
*
head
=
NULL
;
/* head of the linked list */
cJSON
*
head
=
NULL
;
/* head of the linked list */
cJSON
*
child
=
NULL
;
cJSON
*
current_item
=
NULL
;
if
(
*
value
!=
'['
)
if
(
*
input
!=
'['
)
{
{
/* not an array
!
*/
/* not an array */
*
e
p
=
value
;
*
e
rror_pointer
=
input
;
goto
fail
;
goto
fail
;
}
}
value
=
skip
(
value
+
1
);
input
=
skip
(
input
+
1
);
/* skip whitespace */
if
(
*
value
==
']'
)
if
(
*
input
==
']'
)
{
{
/* empty array
.
*/
/* empty array */
goto
success
;
goto
success
;
}
}
head
=
child
=
cJSON_New_Item
();
/* step back to character in front of the first element */
if
(
!
child
)
input
--
;
/* loop through the comma separated array elements */
do
{
{
/* memory fail */
/* allocate next item */
goto
fail
;
cJSON
*
new_item
=
cJSON_New_Item
();
}
if
(
new_item
==
NULL
)
/* skip any spacing, get the value. */
value
=
skip
(
parse_value
(
child
,
skip
(
value
),
ep
));
if
(
!
value
)
{
{
goto
fail
;
goto
fail
;
/* allocation failure */
}
}
/* loop through the comma separated array elements
*/
/* attach next item to list
*/
while
(
*
value
==
','
)
if
(
head
==
NULL
)
{
{
cJSON
*
new_item
=
NULL
;
/* start the linked list */
if
(
!
(
new_item
=
cJSON_New_Item
()))
current_item
=
head
=
new_item
;
}
else
{
{
/* memory fail */
/* add to the end and advance */
goto
fail
;
current_item
->
next
=
new_item
;
new_item
->
prev
=
current_item
;
current_item
=
new_item
;
}
}
/* add new item to end of the linked list */
child
->
next
=
new_item
;
new_item
->
prev
=
child
;
child
=
new_item
;
/* go to the next comma */
/* parse next value */
value
=
skip
(
parse_value
(
child
,
skip
(
value
+
1
),
ep
));
input
=
skip
(
input
+
1
);
/* skip whitespace before value */
if
(
!
value
)
input
=
parse_value
(
current_item
,
input
,
error_pointer
);
input
=
skip
(
input
);
/* skip whitespace after value */
if
(
input
==
NULL
)
{
{
/* memory fail */
goto
fail
;
/* failed to parse value */
goto
fail
;
}
}
}
}
while
(
*
input
==
','
);
if
(
*
value
=
=
']'
)
if
(
*
input
!
=
']'
)
{
{
/* end of array */
*
error_pointer
=
input
;
goto
success
;
goto
fail
;
/* expected end of array */
}
}
/* malformed. */
*
ep
=
value
;
goto
fail
;
success:
success:
item
->
type
=
cJSON_Array
;
item
->
type
=
cJSON_Array
;
item
->
child
=
head
;
item
->
child
=
head
;
return
value
+
1
;
return
input
+
1
;
fail:
fail:
if
(
chil
d
!=
NULL
)
if
(
hea
d
!=
NULL
)
{
{
cJSON_Delete
(
chil
d
);
cJSON_Delete
(
hea
d
);
}
}
return
NULL
;
return
NULL
;
...
@@ -1276,108 +1335,95 @@ static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, p
...
@@ -1276,108 +1335,95 @@ static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, p
}
}
/* Build an object from the text. */
/* Build an object from the text. */
static
const
unsigned
char
*
parse_object
(
cJSON
*
item
,
const
unsigned
char
*
value
,
const
unsigned
char
**
ep
)
static
const
unsigned
char
*
parse_object
(
cJSON
*
const
item
,
const
unsigned
char
*
input
,
const
unsigned
char
**
const
error_pointer
)
{
{
cJSON
*
head
=
NULL
;
/* linked list head */
cJSON
*
head
=
NULL
;
/* linked list head */
cJSON
*
child
=
NULL
;
cJSON
*
current_item
=
NULL
;
if
(
*
value
!=
'{'
)
{
/* not an object! */
*
ep
=
value
;
goto
fail
;
}
value
=
skip
(
value
+
1
);
if
(
*
input
!=
'{'
)
if
(
*
value
==
'}'
)
{
{
/* empty object. */
*
error_pointer
=
input
;
goto
success
;
goto
fail
;
/* not an object */
}
}
head
=
child
=
cJSON_New_Item
();
input
=
skip
(
input
+
1
);
/* skip whitespace */
if
(
!
child
)
if
(
*
input
==
'}'
)
{
{
goto
fail
;
goto
success
;
/* empty object */
}
}
/* parse first key */
value
=
skip
(
parse_string
(
child
,
skip
(
value
),
ep
));
if
(
!
value
)
{
goto
fail
;
}
/* use string as key, not value */
child
->
string
=
child
->
valuestring
;
child
->
valuestring
=
NULL
;
if
(
*
value
!=
':'
)
/* step back to character in front of the first element */
input
--
;
/* loop through the comma separated array elements */
do
{
{
/* invalid object. */
/* allocate next item */
*
ep
=
value
;
cJSON
*
new_item
=
cJSON_New_Item
();
goto
fail
;
if
(
new_item
==
NULL
)
}
/* skip any spacing, get the value. */
value
=
skip
(
parse_value
(
child
,
skip
(
value
+
1
),
ep
));
if
(
!
value
)
{
{
goto
fail
;
goto
fail
;
/* allocation failure */
}
}
while
(
*
value
==
','
)
/* attach next item to list */
if
(
head
==
NULL
)
{
{
cJSON
*
new_item
=
NULL
;
/* start the linked list */
if
(
!
(
new_item
=
cJSON_New_Item
()))
current_item
=
head
=
new_item
;
}
else
{
{
/* memory fail */
/* add to the end and advance */
goto
fail
;
current_item
->
next
=
new_item
;
new_item
->
prev
=
current_item
;
current_item
=
new_item
;
}
}
/* add to linked list */
child
->
next
=
new_item
;
new_item
->
prev
=
child
;
child
=
new_item
;
/* parse the name of the child */
value
=
skip
(
parse_string
(
child
,
skip
(
value
+
1
),
ep
));
input
=
skip
(
input
+
1
);
/* skip whitespaces before name */
if
(
!
value
)
input
=
parse_string
(
current_item
,
input
,
error_pointer
);
input
=
skip
(
input
);
/* skip whitespaces after name */
if
(
input
==
NULL
)
{
{
goto
fail
;
goto
fail
;
/* faile to parse name */
}
}
/*
use string as key, not valu
e */
/*
swap valuestring and string, because we parsed the nam
e */
c
hild
->
string
=
child
->
valuestring
;
c
urrent_item
->
string
=
current_item
->
valuestring
;
c
hild
->
valuestring
=
NULL
;
c
urrent_item
->
valuestring
=
NULL
;
if
(
*
value
!=
':'
)
if
(
*
input
!=
':'
)
{
{
/* invalid object. */
*
error_pointer
=
input
;
*
ep
=
value
;
goto
fail
;
/* invalid object */
goto
fail
;
}
}
/* skip any spacing, get the value. */
value
=
skip
(
parse_value
(
child
,
skip
(
value
+
1
),
ep
));
/* parse the value */
if
(
!
value
)
input
=
skip
(
input
+
1
);
/* skip whitespaces before value */
input
=
parse_value
(
current_item
,
input
,
error_pointer
);
input
=
skip
(
input
);
/* skip whitespaces after the value */
if
(
input
==
NULL
)
{
{
goto
fail
;
goto
fail
;
/* failed to parse value */
}
}
}
}
/* end of object */
while
(
*
input
==
','
);
if
(
*
value
==
'}'
)
if
(
*
input
!=
'}'
)
{
{
goto
success
;
*
error_pointer
=
input
;
goto
fail
;
/* expected end of object */
}
}
/* malformed */
*
ep
=
value
;
goto
fail
;
success:
success:
item
->
type
=
cJSON_Object
;
item
->
type
=
cJSON_Object
;
item
->
child
=
head
;
item
->
child
=
head
;
return
value
+
1
;
return
input
+
1
;
fail:
fail:
if
(
chil
d
!=
NULL
)
if
(
hea
d
!=
NULL
)
{
{
cJSON_Delete
(
chil
d
);
cJSON_Delete
(
hea
d
);
}
}
return
NULL
;
return
NULL
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录