// Copyright (c) 2002 David Muse // See the COPYING file for more information #define EXCLUDE_RUDIMENTS_TEMPLATE_IMPLEMENTATIONS #include // for NULL #include #ifdef RUDIMENTS_NAMESPACE namespace rudiments { #endif class parameterstringprivate { friend class parameterstring; private: namevaluepairs _nvp; char _delim; }; parameterstring::parameterstring() { pvt=new parameterstringprivate; pvt->_delim=';'; } parameterstring::~parameterstring() { // delete each name and value in the list for (unsigned long i=0; i_nvp.getList()->getLength(); i++) { delete[] pvt->_nvp.getList()-> getNodeByIndex(i)->getData()->getKey(); delete[] pvt->_nvp.getList()-> getNodeByIndex(i)->getData()->getData(); } delete pvt; } void parameterstring::setDelimiter(char delim) { pvt->_delim=delim; } bool parameterstring::parse(const char *paramstring) { pvt->_nvp.getList()->clear(); int paircount=countPairs(paramstring); const char *ptr=paramstring; for (int i=0; i_nvp.setData(namebuffer,NULL); return false; } ptr=parseValue(ptr,&valuebuffer); pvt->_nvp.setData(namebuffer,valuebuffer); if (*ptr==pvt->_delim) { ptr++; } else if (!*ptr) { break; } else { return false; } } return true; } const char *parameterstring::getValue(const char *name) { char *retval; return (pvt->_nvp.getData(const_cast(name),&retval))? retval:NULL; } void parameterstring::clear() { pvt->_nvp.clear(); } int parameterstring::countPairs(const char *paramstring) { // count ;'s that are not inside of quotes const char *ptr; int paircount=0; int inquotes=0; for (ptr=paramstring; (*ptr); ptr++) { // handle quotes if (*ptr=='\'') { inquotes=!inquotes; continue; } // handle escaped characters if (*ptr=='\\') { ptr++; continue; } if (!inquotes && *ptr==pvt->_delim) { paircount++; } } // handle case where final character wasn't a ; if (*(ptr-1)!=pvt->_delim) { paircount++; } return paircount; } const char *parameterstring::parsePart(int len, char delimiter, const char *data, char **outbuffer, int quotes, int escapedchars) { const char *ptr=data; char *buffer=new char[len+1]; buffer[len]='\0'; int inquotes=0; int index=0; while (*ptr && *ptr!=delimiter) { // handle quotes if (quotes && *ptr=='\'') { ptr++; if (inquotes) { break; } else { inquotes=1; continue; } } // handle escaped characters if (escapedchars && *ptr=='\\') { ptr++; if (!(*ptr)) { break; } } buffer[index]=*ptr; index++; ptr++; } *outbuffer=buffer; return ptr; } int parameterstring::parsePartLength(const char *data, char delimiter, int quotes, int escapedchars) { const char *ptr=data; int counter=0; int inquotes=0; while (*ptr && *ptr!=delimiter) { // handle quotes if (quotes && *ptr=='\'') { ptr++; if (inquotes) { break; } else { inquotes=1; continue; } } // handle escaped characters if (escapedchars && *ptr=='\\') { ptr++; if (!(*ptr)) { break; } } counter++; ptr++; } return counter; } const char *parameterstring::parseName(const char *data, char **outbuffer) { return parsePart(parseNameLength(data),'=',data,outbuffer,0,0); } const char *parameterstring::parseValue(const char *data, char **outbuffer) { return parsePart(parseValueLength(data),pvt->_delim,data,outbuffer,1,1); } int parameterstring::parseNameLength(const char *data) { return parsePartLength(data,'=',0,0); } int parameterstring::parseValueLength(const char *data) { return parsePartLength(data,pvt->_delim,1,1); } #ifdef RUDIMENTS_NAMESPACE } #endif