00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #define ULXR_NEED_EXPORTS
00033 #include <ulxmlrpcpp/ulxmlrpcpp.h>
00034
00035 #include <ulxmlrpcpp/ulxr_valueparse.h>
00036 #include <ulxmlrpcpp/ulxr_except.h>
00037
00038 #ifdef DEBUG
00039 #include <iostream>
00040 #endif
00041
00042
00043 namespace ulxr {
00044
00045
00046 ULXR_API_IMPL0 ValueParser::ValueParser()
00047 : ValueParserBase()
00048 {
00049 ULXR_TRACE(ULXR_PCHAR("ValueParser::ValueParser()"));
00050 states.push(new ValueState(eNone));
00051 }
00052
00053
00054 ULXR_API_IMPL0 ValueParser::~ValueParser()
00055 {
00056 ULXR_TRACE(ULXR_PCHAR("ValueParser::~ValueParser()"));
00057
00058 #ifdef DEBUG
00059 if (states.size() != 1)
00060 std::cerr << ulxr_i18n("########## abnormal program behaviour: states.size() != 1: ")
00061 << states.size()
00062 << std::endl;
00063
00064 if (getTopValueState()->getParserState() != eNone)
00065 std::cerr << ulxr_i18n("########## abnormal program behaviour: getTopState()->getState() != eNone: ")
00066 << getTopValueState()->getParserState()
00067 << std::endl;
00068 #endif
00069
00070 while (states.size() != 0)
00071 {
00072 delete getTopValueState()->getValue();
00073 delete getTopValueState();
00074 states.pop();
00075 }
00076 }
00077
00078
00079
00080 ULXR_API_IMPL(ValueParserBase::ValueState *) ValueParser::getTopValueState() const
00081 {
00082 ULXR_TRACE(ULXR_PCHAR("ValueParser::getTopState() size: ") << states.size());
00083 #ifdef DEBUG
00084 ValueState *vs = dynamic_cast<ValueState*> (states.top());
00085 if (vs == 0)
00086 {
00087 ULXR_TRACE(ULXR_PCHAR("ValueParser::getTopState(), top state: ") << (void*) states.top());
00088 ULXR_TRACE(ULXR_PCHAR("ValueParser::getTopState(): state <> ValueState"));
00089 ULXR_TRACE(ULXR_PCHAR("ValueParser::getTopState(): state == ") << ULXR_GET_STRING(typeid(states.top()).name()));
00090 }
00091 return vs;
00092 #else
00093 return reinterpret_cast<ValueParserBase::ValueState*> (states.top());
00094 #endif
00095 }
00096
00097
00098 ULXR_API_IMPL(void)
00099 ValueParser::startElement(const XML_Char* name, const XML_Char** atts)
00100 {
00101 ULXR_TRACE(ULXR_PCHAR("ValueParser::startElement(const XML_Char*, const char**)"));
00102 if (!testStartElement(name, atts))
00103 XmlParser::testStartElement(name, atts);
00104 }
00105
00106
00107 ULXR_API_IMPL(bool)
00108 ValueParser::testStartElement(const XML_Char* name, const XML_Char** )
00109 {
00110 ULXR_TRACE(ULXR_PCHAR("ValueParser::testStartElement(const XML_Char*, const char**)")
00111 << ULXR_PCHAR("\n name: ")
00112 << ULXR_GET_STRING(name)
00113 );
00114 switch(getTopValueState()->getParserState() )
00115 {
00116 case eNone:
00117 if (strcmp(name, "value") == 0)
00118 states.push(new ValueState(eValue));
00119 else
00120 return false;
00121 break;
00122
00123 case eValue:
00124 if (strcmp(name, "array") == 0)
00125 states.push(new ValueState(eArray));
00126
00127 else if (strcmp(name, "struct") == 0)
00128 states.push(new ValueState(eStruct));
00129
00130 else if (strcmp(name, "boolean") == 0)
00131 states.push(new ValueState(eBoolean));
00132
00133 else if (strcmp(name, "int") == 0)
00134 states.push(new ValueState(eInt));
00135
00136 else if (strcmp(name, "i4") == 0)
00137 states.push(new ValueState(eI4));
00138
00139 else if (strcmp(name, "double") == 0)
00140 states.push(new ValueState(eDouble));
00141
00142 else if (strcmp(name, "string") == 0)
00143 states.push(new ValueState(eString));
00144
00145 else if (strcmp(name, "base64") == 0)
00146 states.push(new ValueState(eBase64));
00147
00148 else if (strcmp(name, "dateTime.iso8601") == 0)
00149 states.push(new ValueState(eDate));
00150
00151 else
00152 return false;
00153 break;
00154
00155 case eStruct:
00156 if (strcmp(name, "member") == 0)
00157 {
00158 if (getTopValueState()->getValue() == 0)
00159 getTopValueState()->takeValue(new Value(Struct()) );
00160 states.push(new MemberState(eMember, getTopValueState()->getValue()));
00161 }
00162 else
00163 return false;
00164 break;
00165
00166 case eMember:
00167 if (strcmp(name, "name") == 0)
00168 states.push(new ValueState(eName));
00169
00170 else if (strcmp(name, "value") == 0)
00171 states.push(new ValueState(eValue));
00172
00173 else
00174 return false;
00175
00176 break;
00177
00178 case eArray:
00179 if (strcmp(name, "data") == 0)
00180 states.push(new ArrayState(eData));
00181 else
00182 return false;
00183 break;
00184
00185 case eData:
00186 if (strcmp(name, "value") == 0)
00187 states.push(new ValueState(eValue));
00188 else
00189 return false;
00190 break;
00191
00192 default:
00193 return false;
00194 }
00195
00196 return true;
00197 }
00198
00199
00200 ULXR_API_IMPL(void) ValueParser::endElement(const XML_Char *name)
00201 {
00202 ULXR_TRACE(ULXR_PCHAR("ValueParser::endElement(const XML_Char*)"));
00203 if (!testEndElement(name))
00204 XmlParser::testEndElement(name);
00205 }
00206
00207
00208 ULXR_API_IMPL(bool) ValueParser::testEndElement(const XML_Char *name)
00209 {
00210 ULXR_TRACE(ULXR_PCHAR("ValueParser::testEndElement(const XML_Char*)"));
00211
00212 if (states.size() <= 1)
00213 throw RuntimeException(ApplicationError, ulxr_i18n(ULXR_PCHAR("abnormal program behaviour: ValueParser::testEndElement() had no states left")));
00214
00215 ValueState *curr = getTopValueState();
00216 states.pop();
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 states.top()->setPrevParserState(curr->getParserState());
00228 switch(curr->getParserState() )
00229 {
00230 case eBoolean:
00231 assertEndElement(name, "boolean");
00232 getTopValueState()->takeValue(new Value(Boolean(curr->getCharData())) );
00233 break;
00234
00235 case eInt:
00236 assertEndElement(name, "int");
00237 getTopValueState()->takeValue(new Value(Integer(curr->getCharData())) );
00238 break;
00239
00240 case eI4:
00241 assertEndElement(name, "i4");
00242 getTopValueState()->takeValue(new Value(Integer(curr->getCharData())) );
00243 break;
00244
00245 case eDouble:
00246 assertEndElement(name, "double");
00247 getTopValueState()->takeValue(new Value(Double(curr->getCharData())) );
00248 break;
00249
00250 case eString:
00251 assertEndElement(name, "string");
00252 getTopValueState()->takeValue(new Value(RpcString(curr->getCharData())) );
00253 break;
00254
00255 case eBase64:
00256 {
00257 assertEndElement(name, "base64");
00258 Base64 b64;
00259 b64.setBase64(curr->getCharData());
00260 getTopValueState()->takeValue(new Value(b64));
00261 }
00262 break;
00263
00264 case eDate:
00265 assertEndElement(name , "dateTime.iso8601");
00266 getTopValueState()->takeValue(new Value(DateTime(curr->getCharData())) );
00267 break;
00268
00269 case eMember:
00270 assertEndElement(name, "member");
00271 getTopValueState()->takeValue (curr->getValue());
00272 break;
00273
00274 case eName:
00275 assertEndElement(name, "name");
00276 getTopValueState()->takeName((curr->getCharData()) );
00277 break;
00278
00279 case eValue:
00280 assertEndElement(name, "value");
00281 if (curr->getValue() == 0)
00282 {
00283 if(curr->getPrevParserState() == eArray)
00284 getTopValueState()->takeValue (new Value(Array()));
00285
00286 else if (curr->getPrevParserState() == eStruct)
00287 getTopValueState()->takeValue (new Value(Struct()));
00288
00289 else
00290 getTopValueState()->takeValue (new Value(RpcString(curr->getCharData())));
00291 }
00292 else
00293 getTopValueState()->takeValue (curr->getValue());
00294 break;
00295
00296 case eStruct:
00297 assertEndElement(name, "struct");
00298 getTopValueState()->takeValue (curr->getValue());
00299 break;
00300
00301 case eArray:
00302 assertEndElement(name, "array");
00303 getTopValueState()->takeValue (curr->getValue());
00304 break;
00305
00306 case eData:
00307 assertEndElement(name, "data");
00308 getTopValueState()->takeValue (curr->getValue());
00309 break;
00310
00311 default:
00312 states.push(curr);
00313 return false;
00314 }
00315 delete curr;
00316 return true;
00317 }
00318
00319
00320 }
00321
00322