ulxr_valueparse.cpp

Go to the documentation of this file.
00001 /**************************************************************************
00002                ulxr_valueparse.cpp  -  parse xml-rpc primitive values
00003                              -------------------
00004     begin                : Wed Mar 13 2002
00005     copyright            : (C) 2002-2007 by Ewald Arnold
00006     email                : ulxmlrpcpp@ewald-arnold.de
00007 
00008     $Id: ulxr_valueparse.cpp 940 2006-12-30 18:22:05Z ewald-arnold $
00009 
00010  ***************************************************************************/
00011 
00012 /**************************************************************************
00013  *
00014  * This program is free software; you can redistribute it and/or modify
00015  * it under the terms of the GNU Lesser General Public License as
00016  * published by the Free Software Foundation; either version 2 of the License,
00017  * or (at your option) any later version.
00018  *
00019  * This program is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  * GNU General Public License for more details.
00023  *
00024  * You should have received a copy of the GNU Lesser General Public License
00025  * along with this program; if not, write to the Free Software
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00027  *
00028  ***************************************************************************/
00029 
00030 //#define ULXR_DEBUG_OUTPUT
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());      // be careful about type
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());  // dont care anymore
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** /* atts */)
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)  // first closing member adds struct-item
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)  // closing value adds data-items
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   ULXR_DOUT (ULXR_GET_STRING(name)
00219              << ULXR_PCHAR(" = cur-val: ")
00220              << std::hex << (void*) curr->getValue()
00221              << ULXR_PCHAR(" state: ")
00222              << std::hex << (void*) curr->getParserState()
00223              << ULXR_PCHAR(" prev state: ")
00224              << std::hex << (void*) curr->getPrevParserState()
00225              << std::dec);
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()); // move raw data!
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)     // special case
00282       {
00283         if(curr->getPrevParserState() == eArray)            // not empty Array
00284            getTopValueState()->takeValue (new Value(Array()));
00285 
00286         else if (curr->getPrevParserState() == eStruct)     // not empty Struct
00287            getTopValueState()->takeValue (new Value(Struct()));
00288 
00289         else                                                // no type tag defaults to string
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 }  // namespace ulxr
00321 
00322 

Generated on Sun Aug 19 20:08:58 2007 for ulxmlrpcpp by  doxygen 1.5.1