Branch data Line data Source code
1 : : /*
2 : : * Copyright 2006-2009 Savarese Software Research Corporation
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at
7 : : *
8 : : * https://www.savarese.com/software/ApacheLicense-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : #include <ssrc/wispers/utility/PropertiesToString.h>
18 : :
19 : : #include <cstring>
20 : : #include <cctype>
21 : :
22 : : namespace {
23 : : const char * const lua_escape_chars = "\a\b\t\n\v\f\r\"\\";
24 : : const char lua_escaped_chars[] = {
25 : : 'a', 'b', 't', 'n', 'v', 'f', 'r', '"', '\\'
26 : : };
27 : :
28 : : enum { Assignment, OpenQuotedKey, CloseQuotedKey,
29 : : OpenArray, CloseArray, ValueKey, NumTokens };
30 : :
31 : : const char * const OutputToken[2][NumTokens] = {
32 : : { "=", "[\"", "\"]=", "{", "}", "_value=" },
33 : : { ":", "\"", "\":", "[", "]", "_value:" }
34 : : };
35 : : }
36 : :
37 : : __BEGIN_NS_SSRC_WSPR_UTILITY
38 : :
39 : 10 : void escape_lua(string & result,
40 : : const char *text, const unsigned int text_size)
41 : : {
42 : 10 : const char * const end = text + text_size;
43 : : const char *pos;
44 : 10 : result.reserve(2*text_size);
45 : :
46 [ + - + + : 28 : while(text < end && (pos = std::strpbrk(text, lua_escape_chars)) != 0) {
+ + ]
47 : 8 : result.append(text, (pos - text)).append(1, '\\')
48 : 16 : .append(1, lua_escaped_chars[std::strchr(lua_escape_chars, *pos) - lua_escape_chars]);
49 : 8 : text = pos + 1;
50 : : }
51 : :
52 [ + - ]: 10 : if(text < end) {
53 : 10 : result.append(text, (end - text));
54 : : }
55 : 10 : }
56 : :
57 : 2 : void PropertiesToString::operator()(const primitive_property_vector & v) const {
58 : 2 : _out << _token[OpenArray];
59 : :
60 [ + + ]: 26 : for(primitive_property_vector::const_iterator && it = v.begin(),
61 : 2 : && end = v.end(); it != end; )
62 : : {
63 : 20 : boost::apply_visitor(*this, *it);
64 : 20 : ++it;
65 [ + + ]: 20 : if(it != end) {
66 : 18 : _out << ",";
67 : : }
68 : : }
69 : :
70 : 2 : _out << _token[CloseArray];
71 : 2 : }
72 : :
73 : 3 : void PropertiesToString::operator()(const property_vector & v) const {
74 : 3 : _out << _token[OpenArray];
75 : :
76 [ + + ]: 28 : for(property_vector::const_iterator && it = v.begin(), && end = v.end();
77 : : it != end; )
78 : : {
79 : 22 : PropertiesToString::operator()(*it);
80 : 22 : ++it;
81 [ + + ]: 22 : if(it != end) {
82 : 19 : _out << ",";
83 : : }
84 : : }
85 : :
86 : 3 : _out << _token[CloseArray];
87 : 3 : }
88 : :
89 : 54 : void PropertiesToString::enter(const std::string & key,
90 : : const Properties *props,
91 : : const bool is_last_child) const
92 : : {
93 : 54 : const property_type *v = props->value();
94 : :
95 : : // Always quote keys because 1. required by JSON and 2. keys may contain
96 : : // characters comprising invalid identifiers.
97 : 54 : _out << _token[OpenQuotedKey] << key << _token[CloseQuotedKey];
98 : :
99 [ + + ]: 54 : if(props->is_leaf()) {
100 [ + - ]: 43 : if(v != 0) {
101 : 43 : boost::apply_visitor(*this, *v);
102 : : }
103 : : } else {
104 : 11 : _out << "{";
105 [ - + ]: 11 : if(v != 0) {
106 : 0 : _out << _token[ValueKey];
107 : 0 : boost::apply_visitor(*this, *v);
108 : 0 : _out << ",";
109 : : }
110 : : }
111 : 54 : }
112 : :
113 : 4 : PropertiesToString::PropertiesToString(std::ostream & out,
114 : : const ToFormat to_format) :
115 : 4 : _token(OutputToken[to_format]), _out(out)
116 : 4 : { }
117 : :
118 [ + - + - ]: 9 : __END_NS_SSRC_WSPR_UTILITY
|