// Copyright (c) 2002 David Muse
// See the COPYING file for more information
#define EXCLUDE_RUDIMENTS_TEMPLATE_IMPLEMENTATIONS
#include <rudiments/parameterstring.h>
// for NULL
#include <stdlib.h>
#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<pvt->_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<paircount; i++) {
char *namebuffer;
char *valuebuffer;
ptr=parseName(ptr,&namebuffer);
if (*ptr=='=') {
ptr++;
} else {
pvt->_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<char *>(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
syntax highlighted by Code2HTML, v. 0.9.1