Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party CJSON
提交
74d05252
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看板
体验新版 GitCode,发现更多精彩内容 >>
提交
74d05252
编写于
4月 08, 2017
作者:
M
Max Bruckner
提交者:
GitHub
4月 08, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #146 from DaveGamble/locale-independence
Locale independence
上级
50b3c30d
3efef58c
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
106 addition
and
55 deletion
+106
-55
README.md
README.md
+3
-2
cJSON.c
cJSON.c
+95
-39
cJSON.h
cJSON.h
+1
-1
test.c
test.c
+2
-2
tests/print_number.c
tests/print_number.c
+5
-11
未找到文件。
README.md
浏览文件 @
74d05252
...
...
@@ -392,8 +392,9 @@ The maximum length of a floating point literal that cJSON supports is currently
In general cJSON is
**not thread safe**
.
However it is thread safe under the following conditions:
*
You don't use
`cJSON_GetErrorPtr`
(you can use the
`return_parse_end`
parameter of
`cJSON_ParseWithOpts`
instead)
*
You only ever call
`cJSON_InitHooks`
before using cJSON in any threads.
*
`cJSON_GetErrorPtr`
is never used (the
`return_parse_end`
parameter of
`cJSON_ParseWithOpts`
can be used instead)
*
`cJSON_InitHooks`
is only ever called before using cJSON in any threads.
*
`setlocale`
is never called before all calls to cJSON functions have returned.
# Enjoy cJSON!
...
...
cJSON.c
浏览文件 @
74d05252
...
...
@@ -31,6 +31,7 @@
#include <float.h>
#include <limits.h>
#include <ctype.h>
#include <locale.h>
#pragma GCC visibility pop
#include "cJSON.h"
...
...
@@ -177,19 +178,63 @@ CJSON_PUBLIC(void) cJSON_Delete(cJSON *c)
}
}
/* get the decimal point character of the current locale */
static
unsigned
char
get_decimal_point
(
void
)
{
struct
lconv
*
lconv
=
localeconv
();
return
(
unsigned
char
)
lconv
->
decimal_point
[
0
];
}
/* Parse the input text to generate a number, and populate the result into item. */
static
const
unsigned
char
*
parse_number
(
cJSON
*
const
item
,
const
unsigned
char
*
const
input
)
{
double
number
=
0
;
unsigned
char
*
after_end
=
NULL
;
unsigned
char
number_c_string
[
64
];
unsigned
char
decimal_point
=
get_decimal_point
();
size_t
i
=
0
;
if
(
input
==
NULL
)
{
return
NULL
;
}
number
=
strtod
((
const
char
*
)
input
,
(
char
**
)
&
after_end
);
if
(
input
==
after_end
)
/* copy the number into a temporary buffer and replace '.' with the decimal point
* of the current locale (for strtod) */
for
(
i
=
0
;
(
i
<
(
sizeof
(
number_c_string
)
-
1
))
&&
(
input
[
i
]
!=
'\0'
);
i
++
)
{
switch
(
input
[
i
])
{
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
case
'+'
:
case
'-'
:
case
'e'
:
case
'E'
:
number_c_string
[
i
]
=
input
[
i
];
break
;
case
'.'
:
number_c_string
[
i
]
=
decimal_point
;
break
;
default:
goto
loop_end
;
}
}
loop_end:
number_c_string
[
i
]
=
'\0'
;
number
=
strtod
((
const
char
*
)
number_c_string
,
(
char
**
)
&
after_end
);
if
(
number_c_string
==
after_end
)
{
return
NULL
;
/* parse_error */
}
...
...
@@ -212,7 +257,7 @@ static const unsigned char *parse_number(cJSON * const item, const unsigned char
item
->
type
=
cJSON_Number
;
return
after_end
;
return
input
+
(
after_end
-
number_c_string
)
;
}
/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
...
...
@@ -336,34 +381,24 @@ static void update_offset(printbuffer * const buffer)
}
/* Removes trailing zeroes from the end of a printed number */
static
cJSON_bool
trim_trailing_zeroes
(
printbuffer
*
const
buffer
)
static
int
trim_trailing_zeroes
(
const
unsigned
char
*
const
number
,
int
length
,
const
unsigned
char
decimal_point
)
{
size_t
offset
=
0
;
unsigned
char
*
content
=
NULL
;
if
((
buffer
==
NULL
)
||
(
buffer
->
buffer
==
NULL
)
||
(
buffer
->
offset
<
1
))
if
((
number
==
NULL
)
||
(
length
<=
0
))
{
return
false
;
return
-
1
;
}
offset
=
buffer
->
offset
-
1
;
content
=
buffer
->
buffer
;
while
((
offset
>
0
)
&&
(
content
[
offset
]
==
'0'
))
while
((
length
>
0
)
&&
(
number
[
length
-
1
]
==
'0'
))
{
offset
--
;
length
--
;
}
if
((
offset
>
0
)
&&
(
content
[
offset
]
==
'.'
))
if
((
length
>
0
)
&&
(
number
[
length
-
1
]
==
decimal_point
))
{
offset
--
;
/* remove trailing decimal_point */
length
--
;
}
offset
++
;
content
[
offset
]
=
'\0'
;
buffer
->
offset
=
offset
;
return
true
;
return
length
;
}
/* Render the number nicely from the given item into a string. */
...
...
@@ -372,53 +407,74 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
unsigned
char
*
output_pointer
=
NULL
;
double
d
=
item
->
valuedouble
;
int
length
=
0
;
cJSON_bool
trim_zeroes
=
true
;
/* should at the end be removed? */
size_t
i
=
0
;
cJSON_bool
trim_zeroes
=
true
;
/* should zeroes at the end be removed? */
unsigned
char
number_buffer
[
64
];
/* temporary buffer to print the number into */
unsigned
char
decimal_point
=
get_decimal_point
();
if
(
output_buffer
==
NULL
)
{
return
false
;
}
/* This is a nice tradeoff. */
output_pointer
=
ensure
(
output_buffer
,
64
,
hooks
);
if
(
output_pointer
==
NULL
)
{
return
false
;
}
/* This checks for NaN and Infinity */
if
((
d
*
0
)
!=
0
)
{
length
=
sprintf
((
char
*
)
output_point
er
,
"null"
);
length
=
sprintf
((
char
*
)
number_buff
er
,
"null"
);
}
else
if
((
fabs
(
floor
(
d
)
-
d
)
<=
DBL_EPSILON
)
&&
(
fabs
(
d
)
<
1.0e60
))
{
/* integer */
length
=
sprintf
((
char
*
)
output_point
er
,
"%.0f"
,
d
);
length
=
sprintf
((
char
*
)
number_buff
er
,
"%.0f"
,
d
);
trim_zeroes
=
false
;
/* don't remove zeroes for "big integers" */
}
else
if
((
fabs
(
d
)
<
1.0e-6
)
||
(
fabs
(
d
)
>
1.0e9
))
{
length
=
sprintf
((
char
*
)
output_point
er
,
"%e"
,
d
);
length
=
sprintf
((
char
*
)
number_buff
er
,
"%e"
,
d
);
trim_zeroes
=
false
;
/* don't remove zeroes in engineering notation */
}
else
{
length
=
sprintf
((
char
*
)
output_point
er
,
"%f"
,
d
);
length
=
sprintf
((
char
*
)
number_buff
er
,
"%f"
,
d
);
}
/* sprintf failed */
if
(
length
<
0
)
/* sprintf failed
or buffer overrun occured
*/
if
(
(
length
<
0
)
||
(
length
>
(
int
)(
sizeof
(
number_buffer
)
-
1
))
)
{
return
false
;
}
output_buffer
->
offset
+=
(
size_t
)
length
;
if
(
trim_zeroes
)
{
return
trim_trailing_zeroes
(
output_buffer
);
length
=
trim_trailing_zeroes
(
number_buffer
,
length
,
decimal_point
);
if
(
length
<=
0
)
{
return
false
;
}
}
/* reserve appropriate space in the output */
output_pointer
=
ensure
(
output_buffer
,
(
size_t
)
length
,
hooks
);
if
(
output_pointer
==
NULL
)
{
return
false
;
}
/* copy the printed number to the output and replace locale
* dependent decimal point with '.' */
for
(
i
=
0
;
i
<
((
size_t
)
length
);
i
++
)
{
if
(
number_buffer
[
i
]
==
decimal_point
)
{
output_pointer
[
i
]
=
'.'
;
continue
;
}
output_pointer
[
i
]
=
number_buffer
[
i
];
}
output_pointer
[
i
]
=
'\0'
;
output_buffer
->
offset
+=
(
size_t
)
length
;
return
true
;
}
...
...
cJSON.h
浏览文件 @
74d05252
...
...
@@ -133,7 +133,7 @@ CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
CJSON_PUBLIC
(
char
*
)
cJSON_PrintBuffered
(
const
cJSON
*
item
,
int
prebuffer
,
cJSON_bool
fmt
);
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
/* NOTE:
If you are printing numbers, the buffer hat to be 63 bytes bigger then the printed JSON (worst case)
*/
/* NOTE:
cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need
*/
CJSON_PUBLIC
(
cJSON_bool
)
cJSON_PrintPreallocated
(
cJSON
*
item
,
char
*
buffer
,
const
int
length
,
const
cJSON_bool
format
);
/* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC
(
void
)
cJSON_Delete
(
cJSON
*
c
);
...
...
test.c
浏览文件 @
74d05252
...
...
@@ -53,8 +53,8 @@ static int print_preallocated(cJSON *root)
out
=
cJSON_Print
(
root
);
/* create buffer to succeed */
/* the extra
64 bytes are in case a floating point value is printed
*/
len
=
strlen
(
out
)
+
64
;
/* the extra
5 bytes are because of inaccuracies when reserving memory
*/
len
=
strlen
(
out
)
+
5
;
buf
=
(
char
*
)
malloc
(
len
);
if
(
buf
==
NULL
)
{
...
...
tests/print_number.c
浏览文件 @
74d05252
...
...
@@ -89,17 +89,11 @@ static void print_number_should_print_non_number(void)
static
void
trim_trailing_zeroes_should_trim_trailing_zeroes
(
void
)
{
printbuffer
buffer
;
unsigned
char
number
[
100
];
buffer
.
length
=
sizeof
(
number
);
buffer
.
buffer
=
number
;
strcpy
((
char
*
)
number
,
"10.00"
);
buffer
.
offset
=
sizeof
(
"10.00"
)
-
1
;
TEST_ASSERT_TRUE
(
trim_trailing_zeroes
(
&
buffer
));
TEST_ASSERT_EQUAL_UINT8
(
'\0'
,
buffer
.
buffer
[
buffer
.
offset
]);
TEST_ASSERT_EQUAL_STRING
(
"10"
,
number
);
TEST_ASSERT_EQUAL_UINT
(
sizeof
(
"10"
)
-
1
,
buffer
.
offset
);
TEST_ASSERT_EQUAL_INT
(
2
,
trim_trailing_zeroes
((
const
unsigned
char
*
)
"10.00"
,
(
int
)(
sizeof
(
"10.00"
)
-
1
),
'.'
));
TEST_ASSERT_EQUAL_INT
(
0
,
trim_trailing_zeroes
((
const
unsigned
char
*
)
".00"
,
(
int
)(
sizeof
(
".00"
)
-
1
),
'.'
));
TEST_ASSERT_EQUAL_INT
(
0
,
trim_trailing_zeroes
((
const
unsigned
char
*
)
"00"
,
(
int
)(
sizeof
(
"00"
)
-
1
),
'.'
));
TEST_ASSERT_EQUAL_INT
(
-
1
,
trim_trailing_zeroes
(
NULL
,
10
,
'.'
));
TEST_ASSERT_EQUAL_INT
(
-
1
,
trim_trailing_zeroes
((
const
unsigned
char
*
)
""
,
0
,
'.'
));
}
int
main
(
void
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录