1 /*------------------------------------------------------------------------------
2 Name: ClientProperty.cpp
3 Project: xmlBlaster.org
4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
5 Comment: Handling one client property of QosData
6 ------------------------------------------------------------------------------*/
7 #include <typeinfo>
8 #include <vector>
9 //#include <algorithm>
10 #include <sstream>
11 #include <iostream>
12 #include <util/qos/ClientProperty.h>
13 #include <util/Base64.h>
14 #include <util/Constants.h>
15 #include <util/lexical_cast.h>
16 #include <cstring> // strlen()
17
18 using namespace org::xmlBlaster::util::qos;
19 using namespace org::xmlBlaster::util;
20 using namespace std;
21
22 namespace org { namespace xmlBlaster { namespace util { namespace qos {
23
24 ClientProperty::ClientProperty(bool /*dummy*/,
25 const std::string& name,
26 const std::string& type,
27 const std::string& encoding,
28 const std::string& charset
29 )
30 : name_(name),
31 value_(""),
32 encoding_(encoding),
33 type_(type),
34 charset_(charset)
35 {
36 }
37
38 ClientProperty::ClientProperty(const std::string& name,
39 const char *value,
40 const std::string& type)
41 : name_(name),
42 value_(value),
43 encoding_(""),
44 type_(type),
45 charset_("")
46 {
47 if (needsEncoding()) {
48 //# if defined(__sun)
49 # if defined(__SUNPRO_CC)
50 std::vector<unsigned char> vec; // TODO: Better workaround for SunOS CC Sun C++ 5.5 2003/03/12
51 int len = strlen(value);
52 for (int i=0; i<len; i++) {
53 vec.push_back(value[i]);
54 }
55 # else
56 std::vector<unsigned char> vec(value, value+strlen(value));
57 # endif
58 encoding_ = Constants::ENCODING_BASE64;
59 value_ = Base64::Encode(vec);
60 }
61 else
62 value_ = value;
63 }
64
65 ClientProperty::ClientProperty(const std::string& name,
66 const std::vector<unsigned char>& value,
67 const std::string& type)
68 : name_(name),
69 value_(""),
70 encoding_(""),
71 type_(type),
72 charset_("")
73 {
74 if (type_ == "") {
75 type_ = Constants::TYPE_BLOB;
76 }
77 encoding_ = Constants::ENCODING_BASE64;
78 value_ = Base64::Encode(value);
79 }
80 /*
81 ClientProperty::ClientProperty(const std::string& name,
82 const std::string& value,
83 const std::string& type,
84 const std::string& encoding)
85 : name_(name),
86 value_(value),
87 encoding_(encoding),
88 type_(type)
89 {
90 }
91 */
92 bool ClientProperty::needsEncoding() const {
93 if (type_ == Constants::TYPE_BLOB || encoding_ == Constants::ENCODING_BASE64)
94 return true;
95 else if (
96 value_.find("<") != std::string::npos ||
97 value_.find("&") != std::string::npos ||
98 value_.find("]]>") != std::string::npos
99 ) {
100 return true;
101 }
102 return false;
103 }
104
105 const std::string& ClientProperty::getName() const {
106 return name_;
107 }
108
109 std::string ClientProperty::getType() const {
110 return type_;
111 }
112
113 void ClientProperty::setCharset(const string& charset) {
114 charset_ = charset;
115 }
116
117 std::string ClientProperty::getEncoding() const {
118 return encoding_;
119 }
120
121 std::string ClientProperty::getCharset() const {
122 return charset_;
123 }
124
125 bool ClientProperty::isBase64() const {
126 return encoding_ == Constants::ENCODING_BASE64;
127 }
128
129 std::string ClientProperty::getValueRaw() const {
130 return value_;
131 }
132
133 std::string ClientProperty::getStringValue() const {
134 if (value_ == "") return "";
135 if (Constants::ENCODING_BASE64 == encoding_) {
136 std::vector<unsigned char> vec = Base64::Decode(value_);
137 std::string str;
138 str.reserve(vec.size());
139 # if defined(__sun)
140 std::vector<unsigned char>::const_iterator it;
141 for(it = vec.begin(); it != vec.end(); ++it) {
142 unsigned char c = (*it);
143 str += c;
144 }
145 # else
146 str.assign(vec.begin(),vec.end());
147 # endif
148 return str;
149 }
150 return value_;
151 }
152
153 std::vector<unsigned char> ClientProperty::getValue() const {
154 if (value_ == "") std::vector<unsigned char>();
155 if (Constants::ENCODING_BASE64 == encoding_) {
156 return Base64::Decode(value_);
157 }
158 std::vector<unsigned char>vec;
159 vec.reserve(value_.size());
160 copy(value_.begin(), value_.end(), vec.begin());
161 return vec;
162 }
163
164 void ClientProperty::setValue(const string& value) {
165 value_ = value;
166 if (needsEncoding()) {
167 std::vector<unsigned char>vec;
168 vec.reserve(value.size());
169 copy(value.begin(), value.end(), vec.begin());
170 value_ = Base64::Encode(vec);
171 }
172 }
173
174 void ClientProperty::setValueRaw(const string& value) {
175 value_ = value;
176 }
177
178 std::string ClientProperty::toXml(std::string extraOffset, bool clearText, std::string tagName) const {
179 std::string sb = std::string();
180 sb.reserve(256);
181 std::string offset = Constants::OFFSET + extraOffset;
182
183 sb += offset + "<" + tagName;
184 if (getName() != "") {
185 sb += " name='" + getName() + "'";
186 }
187 if (getType() != "") {
188 sb += " type='" + getType() + "'";
189 }
190 if (getEncoding() != "") {
191 sb += " encoding='" + getEncoding() + "'";
192 }
193 if (getCharset() != "") {
194 sb += " charset='" + getCharset() + "'";
195 }
196
197 std::string val = getValueRaw();
198 if (val == "")
199 sb += "/>";
200 else {
201 //if (encoding_ == Constants.ENCODING_NONE &&
202 // (
203 // val.find("%") != std::string::npos ||
204 // val.find(">") != std::string::npos ||
205 // val.find("&") != std::string::npos
206 // )
207 // sb += "><![CDATA�[" + val + "]]></clientProperty>";
208 //else
209 sb += ">" + (clearText?getStringValue():val) + "</" + tagName + ">";
210 }
211
212 return sb;
213 }
214
215 }}}}
216
217 //g++ -o ClientProperty -Wall -g -DCLIENTPROPERTY_MAIN ClientProperty.cpp ../Base64.cpp ../Constants.cpp -I ~/xmlBlaster/src/c++
218 #ifdef CLIENTPROPERTY_MAIN
219 # include <iostream>
220
221 namespace org { namespace xmlBlaster { namespace util {
222 template<> std::string lexical_cast(std::string arg) { return arg; }
223 }}}
224
225 int main(int argc, char **argv) {
226 try {
227 {
228 ClientProperty cp("key", string("string"));
229 char *p = setlocale(LC_CTYPE, ""); // Returns "en_US.UTF-8" on Linux
230 cp.setCharset(p);
231
232 cout << "name=" << cp.getName()
233 << ", valueB64=" << cp.getValueRaw()
234 << ", value=" << cp.getStringValue()
235 << ", type=" << cp.getType()
236 << ", charset=" << cp.getCharset()
237 << ", isBase64=" << cp.isBase64()
238 << cp.toXml("")
239 << endl << endl;
240 }
241 {
242 vector<unsigned char> v;
243 v.push_back('H');
244 v.push_back('a');
245 v.push_back('l');
246 v.push_back('l');
247 v.push_back('o');
248 ClientProperty cp("key", v);
249 cp.setCharset("windows-1252");
250 cout << "name=" << cp.getName()
251 << ", valueB64=" << cp.getValueRaw()
252 << ", value=" << cp.getStringValue()
253 << ", type=" << cp.getType()
254 << ", encoding=" << cp.getEncoding()
255 << ", charset=" << cp.getCharset()
256 << ", isBase64=" << cp.isBase64()
257 << cp.toXml("")
258 << endl;
259 {
260 std::vector<unsigned char> ret = cp.getValue();
261 std::string str;
262 str.assign(v.begin(),v.end());
263 cout << "NEW=" << str << endl;
264 }
265 }
266 }
267 catch(bad_cast b) {
268 cout << "EXCEPTION: " << b.what() << endl;
269 }
270 return 0;
271 }
272 #endif
syntax highlighted by Code2HTML, v. 0.9.1