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