1
1
/* **
2
2
* ==++==
3
3
*
4
- * Copyright (c) Microsoft Corporation. All rights reserved.
4
+ * Copyright (c) Microsoft Corporation. All rights reserved.
5
5
* Licensed under the Apache License, Version 2.0 (the "License");
6
6
* you may not use this file except in compliance with the License.
7
7
* You may obtain a copy of the License at
8
8
* http://www.apache.org/licenses/LICENSE-2.0
9
- *
9
+ *
10
10
* Unless required by applicable law or agreed to in writing, software
11
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31
31
#include < array>
32
32
33
33
#if defined(_MSC_VER)
34
- #pragma warning(disable : 4127) // allow expressions like while(true) pass
34
+ #pragma warning(disable : 4127) // allow expressions like while(true) pass
35
35
#endif
36
36
using namespace web ;
37
37
using namespace web ::json;
38
38
using namespace utility ;
39
39
using namespace utility ::conversions;
40
40
41
- std::array<signed char ,128 > _hexval = {{ -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
41
+ std::array<signed char ,128 > _hexval = {{ -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
42
42
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
43
43
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
44
44
0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , -1 , -1 , -1 , -1 , -1 , -1 ,
@@ -74,7 +74,7 @@ template <typename CharType>
74
74
class JSON_Parser
75
75
{
76
76
public:
77
- JSON_Parser ()
77
+ JSON_Parser ()
78
78
: m_currentLine(1 ),
79
79
m_eof (std::char_traits<CharType>::eof()),
80
80
m_currentColumn(1 ),
@@ -171,15 +171,15 @@ class JSON_Parser
171
171
void CreateToken (typename JSON_Parser<CharType>::Token& tk, typename Token::Kind kind, Location &start)
172
172
{
173
173
tk.kind = kind;
174
- tk.start = start;
174
+ tk.start = start;
175
175
tk.string_val .clear ();
176
176
}
177
177
178
178
void CreateToken (typename JSON_Parser<CharType>::Token& tk, typename Token::Kind kind)
179
179
{
180
180
tk.kind = kind;
181
- tk.start .m_line = m_currentLine;
182
- tk.start .m_column = m_currentColumn;
181
+ tk.start .m_line = m_currentLine;
182
+ tk.start .m_column = m_currentColumn;
183
183
tk.string_val .clear ();
184
184
}
185
185
@@ -405,16 +405,16 @@ namespace
405
405
}
406
406
#endif
407
407
408
- static double anystod (const char * str)
408
+ static double anystod (const char * str)
409
409
{
410
410
#ifdef _MS_WINDOWS
411
411
return _strtod_l (str, nullptr , utility::details::scoped_c_thread_locale::c_locale ());
412
412
#else
413
- return strtod (str, nullptr );
413
+ return strtod (str, nullptr );
414
414
#endif
415
415
}
416
- static double anystod (const wchar_t * str)
417
- {
416
+ static double anystod (const wchar_t * str)
417
+ {
418
418
#ifdef _MS_WINDOWS
419
419
return _wcstod_l (str, nullptr , utility::details::scoped_c_thread_locale::c_locale ());
420
420
#else
@@ -697,10 +697,20 @@ bool JSON_StringParser<CharType>::CompleteComment(typename JSON_Parser<CharType>
697
697
return true ;
698
698
}
699
699
700
+ void convert_append_unicode_code_unit (JSON_Parser<wchar_t >::Token &token, char16_t value)
701
+ {
702
+ token.string_val .push_back (value);
703
+ }
704
+ void convert_append_unicode_code_unit (JSON_Parser<char >::Token &token, char16_t value)
705
+ {
706
+ utf16string utf16 (reinterpret_cast <utf16char *>(&value), 1 );
707
+ token.string_val .append (::utility::conversions::utf16_to_utf8 (utf16));
708
+ }
709
+
700
710
template <typename CharType>
701
711
inline bool JSON_Parser<CharType>::handle_unescape_char(Token &token)
702
712
{
703
- // This function converts unescape character pairs (e.g. "\t") into their ASCII or UNICODE representations (e.g. tab sign)
713
+ // This function converts unescape character pairs (e.g. "\t") into their ASCII or Unicode representations (e.g. tab sign)
704
714
// Also it handles \u + 4 hexadecimal digits
705
715
CharType ch = NextCharacter ();
706
716
switch (ch)
@@ -731,7 +741,8 @@ inline bool JSON_Parser<CharType>::handle_unescape_char(Token &token)
731
741
return true ;
732
742
case ' u' :
733
743
{
734
- // A four-hexdigit unicode character
744
+ // A four-hexdigit Unicode character.
745
+ // Transform into a 16 bit code point.
735
746
int decoded = 0 ;
736
747
for (int i = 0 ; i < 4 ; ++i)
737
748
{
@@ -755,8 +766,8 @@ inline bool JSON_Parser<CharType>::handle_unescape_char(Token &token)
755
766
}
756
767
757
768
// Construct the character based on the decoded number
758
- ch = static_cast <CharType >(decoded & 0xFFFF );
759
- token. string_val . push_back (ch);
769
+ convert_append_unicode_code_unit (token, static_cast <char16_t >(decoded) );
770
+
760
771
return true ;
761
772
}
762
773
default :
@@ -966,14 +977,14 @@ std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject
966
977
auto obj = utility::details::make_unique<web::json::details::_Object>(g_keep_json_object_unsorted);
967
978
auto & elems = obj->m_object .m_elements ;
968
979
969
- if ( tkn.kind != JSON_Parser<CharType>::Token::TKN_CloseBrace )
980
+ if ( tkn.kind != JSON_Parser<CharType>::Token::TKN_CloseBrace )
970
981
{
971
982
while ( true )
972
983
{
973
984
// State 1: New field or end of object, looking for field name or closing brace
974
985
975
986
std::basic_string<CharType> fieldName;
976
-
987
+
977
988
switch ( tkn.kind )
978
989
{
979
990
case JSON_Parser<CharType>::Token::TKN_StringLiteral:
@@ -1038,7 +1049,7 @@ std::unique_ptr<web::json::details::_Array> JSON_Parser<CharType>::_ParseArray(t
1038
1049
1039
1050
auto result = utility::details::make_unique<web::json::details::_Array>();
1040
1051
1041
- if ( tkn.kind != JSON_Parser<CharType>::Token::TKN_CloseBracket )
1052
+ if ( tkn.kind != JSON_Parser<CharType>::Token::TKN_CloseBracket )
1042
1053
{
1043
1054
while ( true )
1044
1055
{
@@ -1096,7 +1107,7 @@ std::unique_ptr<web::json::details::_Value> JSON_Parser<CharType>::_ParseValue(t
1096
1107
return std::move (value);
1097
1108
}
1098
1109
1099
- case JSON_Parser<CharType>::Token::TKN_NumberLiteral:
1110
+ case JSON_Parser<CharType>::Token::TKN_NumberLiteral:
1100
1111
{
1101
1112
auto value = utility::details::make_unique<web::json::details::_Number>(tkn.double_val );
1102
1113
GetNextToken (tkn);
0 commit comments