diff options
Diffstat (limited to 'ndb/src/common/util/Properties.cpp')
-rw-r--r-- | ndb/src/common/util/Properties.cpp | 1019 |
1 files changed, 1019 insertions, 0 deletions
diff --git a/ndb/src/common/util/Properties.cpp b/ndb/src/common/util/Properties.cpp new file mode 100644 index 00000000000..4841d6e5e9e --- /dev/null +++ b/ndb/src/common/util/Properties.cpp @@ -0,0 +1,1019 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include <Properties.hpp> + +#include <NdbTCP.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> +#include <NdbString.h> + +#include <NdbOut.hpp> + +/** + * Note has to be a multiple of 4 bytes + */ +const char Properties::version[] = { 2, 0, 0, 1, 1, 1, 1, 4 }; + +/** + * PropertyImpl + */ +struct PropertyImpl{ + PropertiesType valueType; + const char * name; + void * value; + + ~PropertyImpl(); + PropertyImpl(const char * name, Uint32 value); + PropertyImpl(const char * name, const char * value); + PropertyImpl(const char * name, const Properties * value); + + static PropertyImpl * copyPropertyImpl(const PropertyImpl &); +}; + +/** + * PropertiesImpl + */ +class PropertiesImpl { + PropertiesImpl(const PropertiesImpl &); // Not implemented + PropertiesImpl& operator=(const PropertiesImpl&); // Not implemented +public: + PropertiesImpl(Properties *); + PropertiesImpl(Properties *, const PropertiesImpl &); + ~PropertiesImpl(); + + Properties * properties; + + Uint32 size; + Uint32 items; + PropertyImpl **content; + + bool m_insensitive; + int (* compare)(const char *s1, const char *s2); + + void grow(int sizeToAdd); + + PropertyImpl * get(const char * name) const; + PropertyImpl * put(PropertyImpl *); + void remove(const char * name); + + Uint32 getPackedSize(Uint32 pLen) const; + bool pack(Uint32 *& buf, const char * prefix, Uint32 prefixLen) const; + bool unpack(const Uint32 * buf, Uint32 &bufLen, Properties * top, int items); + + Uint32 getTotalItems() const; + + void setErrno(Uint32 pErr, Uint32 osErr = 0){ + properties->setErrno(pErr, osErr); + } + + const char * getProps(const char * name, const PropertiesImpl ** impl) const; + const char * getPropsPut(const char * name, PropertiesImpl ** impl); +}; + +/** + * Methods for Property + */ +Property::Property(const char * name, Uint32 value){ + impl = new PropertyImpl(name, value); +} + +Property::Property(const char * name, const char * value){ + impl = new PropertyImpl(name, value); +} + +Property::Property(const char * name, const class Properties * value){ + impl = new PropertyImpl(name, value); + + ((Properties*)impl->value)->setCaseInsensitiveNames(value->getCaseInsensitiveNames()); +} + +Property::~Property(){ + delete impl; +} + +/** + * Methods for Properties + */ +Properties::Properties(){ + parent = 0; + impl = new PropertiesImpl(this); +} + +Properties::Properties(const Properties & org){ + parent = 0; + impl = new PropertiesImpl(this, * org.impl); +} + +Properties::Properties(const Property * anArray, int arrayLen){ + impl = new PropertiesImpl(this); + + put(anArray, arrayLen); +} + +Properties::~Properties(){ + clear(); + delete impl; +} + +void +Properties::put(const Property * anArray, int arrayLen){ + if(anArray == 0) + return; + for(int i = 0; i<arrayLen; i++) + impl->put(anArray[i].impl); +} + +template <class T> +bool +put(PropertiesImpl * impl, const char * name, T value, bool replace){ + if(name == 0){ + impl->setErrno(E_PROPERTIES_INVALID_NAME); + return false; + } + + PropertiesImpl * tmp = 0; + const char * short_name = impl->getPropsPut(name, &tmp); + + if(tmp == 0){ + impl->setErrno(E_PROPERTIES_NO_SUCH_ELEMENT); + return false; + } + + if(tmp->get(short_name) != 0){ + if(replace){ + tmp->remove(short_name); + } else { + impl->setErrno(E_PROPERTIES_ELEMENT_ALREADY_EXISTS); + return false; + } + } + return tmp->put(new PropertyImpl(short_name, value)); +} + +bool +Properties::put(const char * name, Uint32 value, bool replace){ + return ::put(impl, name, value, replace); +} + +bool +Properties::put(const char * name, const char * value, bool replace){ + return ::put(impl, name, value, replace); +} + +bool +Properties::put(const char * name, const Properties * value, bool replace){ + return ::put(impl, name, value, replace); +} + +bool +Properties::getTypeOf(const char * name, PropertiesType * type) const { + PropertyImpl * nvp = impl->get(name); + if(nvp == 0){ + setErrno(E_PROPERTIES_NO_SUCH_ELEMENT); + return false; + } + setErrno(E_PROPERTIES_OK); + * type = nvp->valueType; + return true; +} + +bool +Properties::contains(const char * name) const { + PropertyImpl * nvp = impl->get(name); + return nvp != 0; +} + +bool +Properties::get(const char * name, Uint32 * value) const { + PropertyImpl * nvp = impl->get(name); + if(nvp == 0){ + setErrno(E_PROPERTIES_NO_SUCH_ELEMENT); + return false; + } + + if(nvp->valueType == PropertiesType_Uint32){ + * value = * (Uint32 *)nvp->value; + setErrno(E_PROPERTIES_OK); + return true; + } + setErrno(E_PROPERTIES_INVALID_TYPE); + return false; +} + +bool +Properties::get(const char * name, const char ** value) const { + PropertyImpl * nvp = impl->get(name); + if(nvp == 0){ + setErrno(E_PROPERTIES_NO_SUCH_ELEMENT); + return false; + } + + if(nvp->valueType == PropertiesType_char){ + * value = (const char *)nvp->value; + setErrno(E_PROPERTIES_OK); + return true; + } + setErrno(E_PROPERTIES_INVALID_TYPE); + return false; +} + +bool +Properties::get(const char * name, BaseString& value) const { + const char *tmp = ""; + bool ret; + ret = get(name, &tmp); + value.assign(tmp); + return ret; +} + +bool +Properties::get(const char * name, const Properties ** value) const { + PropertyImpl * nvp = impl->get(name); + if(nvp == 0){ + setErrno(E_PROPERTIES_NO_SUCH_ELEMENT); + return false; + } + if(nvp->valueType == PropertiesType_Properties){ + * value = (const Properties *)nvp->value; + setErrno(E_PROPERTIES_OK); + return true; + } + setErrno(E_PROPERTIES_INVALID_TYPE); + return false; +} + +bool +Properties::getCopy(const char * name, char ** value) const { + PropertyImpl * nvp = impl->get(name); + if(nvp == 0){ + setErrno(E_PROPERTIES_NO_SUCH_ELEMENT); + return false; + } + + if(nvp->valueType == PropertiesType_char){ + * value = strdup((const char *)nvp->value); + setErrno(E_PROPERTIES_OK); + return true; + } + setErrno(E_PROPERTIES_INVALID_TYPE); + return false; +} + +bool +Properties::getCopy(const char * name, Properties ** value) const { + PropertyImpl * nvp = impl->get(name); + if(nvp == 0){ + setErrno(E_PROPERTIES_NO_SUCH_ELEMENT); + return false; + } + + if(nvp->valueType == PropertiesType_Properties){ + * value = new Properties(* (const Properties *)nvp->value); + setErrno(E_PROPERTIES_OK); + return true; + } + setErrno(E_PROPERTIES_INVALID_TYPE); + return false; +} + +void +Properties::clear(){ + while(impl->items > 0) + impl->remove(impl->content[0]->name); +} + +void +Properties::remove(const char * name) { + impl->remove(name); +} + +void +Properties::print(FILE * out, const char * prefix) const{ + char buf[1024]; + if(prefix == 0) + buf[0] = 0; + else + strncpy(buf, prefix, 1024); + + for(unsigned int i = 0; i<impl->items; i++){ + switch(impl->content[i]->valueType){ + case PropertiesType_Uint32: + fprintf(out, "%s%s = (Uint32) %d\n", buf, impl->content[i]->name, + *(Uint32 *)impl->content[i]->value); + break; + case PropertiesType_char: + fprintf(out, "%s%s = (char*) \"%s\"\n", buf, impl->content[i]->name, + (char *)impl->content[i]->value); + break; + case PropertiesType_Properties: + char buf2 [1024]; + snprintf(buf2, sizeof(buf2), "%s%s%c",buf, impl->content[i]->name, + Properties::delimiter); + ((Properties *)impl->content[i]->value)->print(out, buf2); + break; + } + } +} + +Properties::Iterator::Iterator(const Properties* prop) : + m_prop(prop), + m_iterator(0) { +} + +const char* +Properties::Iterator::first() { + m_iterator = 0; + return next(); +} + +const char* +Properties::Iterator::next() { + if (m_iterator < m_prop->impl->items) + return m_prop->impl->content[m_iterator++]->name; + else + return NULL; +} + +Uint32 +Properties::getPackedSize() const { + Uint32 sz = 0; + + sz += sizeof(version); // Version id of properties object + sz += 4; // No Of Items + sz += 4; // Checksum + + return sz + impl->getPackedSize(0); +} + +static +Uint32 +computeChecksum(const Uint32 * buf, Uint32 words){ + Uint32 sum = 0; + for(unsigned int i = 0; i<words; i++) + sum ^= htonl(buf[i]); + + return sum; +} + +bool +Properties::pack(Uint32 * buf) const { + Uint32 * bufStart = buf; + + memcpy(buf, version, sizeof(version)); + + // Note that version must be a multiple of 4 + buf += (sizeof(version) / 4); + + * buf = htonl(impl->getTotalItems()); + buf++; + bool res = impl->pack(buf, "", 0); + if(!res) + return res; + + * buf = htonl(computeChecksum(bufStart, (buf - bufStart))); + + return true; +} + +bool +Properties::unpack(const Uint32 * buf, Uint32 bufLen){ + const Uint32 * bufStart = buf; + Uint32 bufLenOrg = bufLen; + + if(bufLen < sizeof(version)){ + setErrno(E_PROPERTIES_INVALID_BUFFER_TO_SHORT); + return false; + } + + if(memcmp(buf, version, sizeof(version)) != 0){ + setErrno(E_PROPERTIES_INVALID_VERSION_WHILE_UNPACKING); + return false; + } + bufLen -= sizeof(version); + + // Note that version must be a multiple of 4 + buf += (sizeof(version) / 4); + + if(bufLen < 4){ + setErrno(E_PROPERTIES_INVALID_BUFFER_TO_SHORT); + return false; + } + + Uint32 totalItems = ntohl(* buf); + buf++; bufLen -= 4; + bool res = impl->unpack(buf, bufLen, this, totalItems); + if(!res) + return res; + + Uint32 sum = computeChecksum(bufStart, (bufLenOrg-bufLen)/4); + if(sum != ntohl(bufStart[(bufLenOrg-bufLen)/4])){ + setErrno(E_PROPERTIES_INVALID_CHECKSUM); + return false; + } + return true; +} + +/** + * Methods for PropertiesImpl + */ +PropertiesImpl::PropertiesImpl(Properties * p){ + this->properties = p; + items = 0; + size = 25; + content = new PropertyImpl * [size]; + this->m_insensitive = false; + this->compare = strcmp; +} + +PropertiesImpl::PropertiesImpl(Properties * p, const PropertiesImpl & org){ + this->properties = p; + this->size = org.size; + this->items = org.items; + this->m_insensitive = org.m_insensitive; + this->compare = org.compare; + content = new PropertyImpl * [size]; + for(unsigned int i = 0; i<items; i++){ + content[i] = PropertyImpl::copyPropertyImpl(* org.content[i]); + } +} + +PropertiesImpl::~PropertiesImpl(){ + for(unsigned int i = 0; i<items; i++) + delete content[i]; + delete [] content; +} + +void +PropertiesImpl::grow(int sizeToAdd){ + PropertyImpl ** newContent = new PropertyImpl * [size + sizeToAdd]; + memcpy(newContent, content, items * sizeof(PropertyImpl *)); + delete [] content; + content = newContent; + size += sizeToAdd; +} + +PropertyImpl * +PropertiesImpl::get(const char * name) const { + const PropertiesImpl * tmp = 0; + const char * short_name = getProps(name, &tmp); + if(tmp == 0){ + return 0; + } + + for(unsigned int i = 0; i<tmp->items; i++) + if((* compare)(tmp->content[i]->name, short_name) == 0) + return tmp->content[i]; + return 0; +} + +PropertyImpl * +PropertiesImpl::put(PropertyImpl * nvp){ + if(items == size) + grow(size); + content[items] = nvp; + + items ++; + + if(nvp->valueType == PropertiesType_Properties){ + ((Properties*)nvp->value)->parent = properties; + } + return nvp; +} + +void +PropertiesImpl::remove(const char * name){ + for(unsigned int i = 0; i<items; i++){ + if((* compare)(content[i]->name, name) == 0){ + delete content[i]; + memmove(&content[i], &content[i+1], (items-i-1)*sizeof(PropertyImpl *)); + items --; + return; + } + } +} + +Uint32 +PropertiesImpl::getTotalItems() const { + int ret = 0; + for(unsigned int i = 0; i<items; i++) + if(content[i]->valueType == PropertiesType_Properties){ + ret += ((Properties*)content[i]->value)->impl->getTotalItems(); + } else { + ret ++; + } + return ret; +} + +const char * +PropertiesImpl::getProps(const char * name, + const PropertiesImpl ** impl) const { + const char * ret = name; + const char * tmp = strchr(name, Properties::delimiter); + if(tmp == 0){ + * impl = this; + return ret; + } else { + Uint32 sz = tmp - name; + char * tmp2 = (char*)malloc(sz + 1); + memcpy(tmp2, name, sz); + tmp2[sz] = 0; + + PropertyImpl * nvp = get(tmp2); + + free(tmp2); + + if(nvp == 0){ + * impl = 0; + return 0; + } + if(nvp->valueType != PropertiesType_Properties){ + * impl = 0; + return name; + } + return ((Properties*)nvp->value)->impl->getProps(tmp+1, impl); + } +} + +const char * +PropertiesImpl::getPropsPut(const char * name, + PropertiesImpl ** impl) { + const char * ret = name; + const char * tmp = strchr(name, Properties::delimiter); + if(tmp == 0){ + * impl = this; + return ret; + } else { + Uint32 sz = tmp - name; + char * tmp2 = (char*)malloc(sz + 1); + memcpy(tmp2, name, sz); + tmp2[sz] = 0; + + PropertyImpl * nvp = get(tmp2); + + if(nvp == 0){ + Properties * tmpP = new Properties(); + PropertyImpl * tmpPI = new PropertyImpl(tmp2, tmpP); + PropertyImpl * nvp = put(tmpPI); + + delete tmpP; + free(tmp2); + return ((Properties*)nvp->value)->impl->getPropsPut(tmp+1, impl); + } + free(tmp2); + if(nvp->valueType != PropertiesType_Properties){ + * impl = 0; + return name; + } + return ((Properties*)nvp->value)->impl->getPropsPut(tmp+1, impl); + } +} + +int +mod4(unsigned int i){ + int res = i + (4 - (i % 4)); + return res; +} + +Uint32 +PropertiesImpl::getPackedSize(Uint32 pLen) const { + Uint32 sz = 0; + for(unsigned int i = 0; i<items; i++){ + if(content[i]->valueType == PropertiesType_Properties){ + Properties * p = (Properties*)content[i]->value; + sz += p->impl->getPackedSize(pLen+strlen(content[i]->name)+1); + } else { + sz += 4; // Type + sz += 4; // Name Len + sz += 4; // Value Len + sz += mod4(pLen + strlen(content[i]->name)); // Name + if(content[i]->valueType == PropertiesType_char){ + sz += mod4(strlen((char *)content[i]->value)); + } else if(content[i]->valueType == PropertiesType_Uint32){ + sz += mod4(4); + } else { + assert(0); + } + } + } + return sz; +} + +struct CharBuf { + char * buffer; + Uint32 bufLen; + Uint32 contentLen; + + CharBuf(){ + buffer = 0; + bufLen = 0; + contentLen = 0; + } + + ~CharBuf(){ + free(buffer); + } + + void clear() { contentLen = 0;} + bool add(const char * str, Uint32 strLen){ + if(!expand(contentLen + strLen + 1)) + return false; + memcpy(&buffer[contentLen], str, strLen); + contentLen += strLen; + buffer[contentLen] = 0; + return true; + } + + bool add(char c){ + return add(&c, 1); + } + + bool expand(Uint32 newSize){ + if(newSize >= bufLen){ + + char * tmp = (char*)malloc(newSize + 1024); + memset(tmp, 0, newSize + 1024); + if(tmp == 0) + return false; + if(contentLen > 0) + memcpy(tmp, buffer, contentLen); + if(buffer != 0) + free(buffer); + buffer = tmp; + bufLen = newSize + 1024; + } + return true; + } +}; + +bool +PropertiesImpl::pack(Uint32 *& buf, const char * prefix, Uint32 pLen) const { + CharBuf charBuf; + + for(unsigned int i = 0; i<items; i++){ + const int strLenName = strlen(content[i]->name); + + if(content[i]->valueType == PropertiesType_Properties){ + charBuf.clear(); + if(!charBuf.add(prefix, pLen)){ + properties->setErrno(E_PROPERTIES_ERROR_MALLOC_WHILE_PACKING, + errno); + return false; + } + + if(!charBuf.add(content[i]->name, strLenName)){ + properties->setErrno(E_PROPERTIES_ERROR_MALLOC_WHILE_PACKING, + errno); + return false; + } + + if(!charBuf.add(Properties::delimiter)){ + properties->setErrno(E_PROPERTIES_ERROR_MALLOC_WHILE_PACKING, + errno); + return false; + } + + if(!((Properties*)(content[i]->value))->impl->pack(buf, + charBuf.buffer, + charBuf.contentLen)){ + + return false; + } + continue; + } + + Uint32 valLenData = 0; + Uint32 valLenWrite = 0; + Uint32 sz = 4 + 4 + 4 + mod4(pLen + strLenName); + switch(content[i]->valueType){ + case PropertiesType_Uint32: + valLenData = 4; + break; + case PropertiesType_char: + valLenData = strlen((char *)content[i]->value); + break; + case PropertiesType_Properties: + assert(0); + } + valLenWrite = mod4(valLenData); + sz += valLenWrite; + + * (buf + 0) = htonl(content[i]->valueType); + * (buf + 1) = htonl(pLen + strLenName); + * (buf + 2) = htonl(valLenData); + + char * valBuf = (char*)(buf + 3); + char * nameBuf = (char*)(buf + 3 + (valLenWrite / 4)); + + memset(valBuf, 0, sz-12); + + switch(content[i]->valueType){ + case PropertiesType_Uint32: + * (Uint32 *)valBuf = htonl(* (Uint32 *)content[i]->value); + break; + case PropertiesType_char: + memcpy(valBuf, content[i]->value, strlen((char*)content[i]->value)); + break; + case PropertiesType_Properties: + assert(0); + } + if(pLen > 0) + memcpy(nameBuf, prefix, pLen); + memcpy(nameBuf + pLen, content[i]->name, strLenName); + + buf += (sz / 4); + } + + return true; +} + +bool +PropertiesImpl::unpack(const Uint32 * buf, Uint32 &bufLen, Properties * top, + int _items){ + CharBuf charBuf; + while(_items > 0){ + Uint32 tmp[3]; + + if(bufLen <= 12){ + top->setErrno(E_PROPERTIES_BUFFER_TO_SMALL_WHILE_UNPACKING); + return false; + } + + tmp[0] = ntohl(buf[0]); + tmp[1] = ntohl(buf[1]); + tmp[2] = ntohl(buf[2]); + buf += 3; + bufLen -= 12; + + PropertiesType pt = (PropertiesType)tmp[0]; + Uint32 nameLen = tmp[1]; + Uint32 valueLen = tmp[2]; + Uint32 nameLenRead = mod4(nameLen); + Uint32 valueLenRead = mod4(valueLen); + + Uint32 sz = nameLenRead + valueLenRead; + if(bufLen < sz){ + top->setErrno(E_PROPERTIES_BUFFER_TO_SMALL_WHILE_UNPACKING); + return false; + } + + if(!charBuf.expand(sz)){ + top->setErrno(E_PROPERTIES_ERROR_MALLOC_WHILE_UNPACKING, errno); + return false; + } + + memcpy(charBuf.buffer, buf, sz); + buf += (sz / 4); + bufLen -= sz ; + + char * valBuf = charBuf.buffer; + char * nameBuf = charBuf.buffer + valueLenRead; + + nameBuf[nameLen] = 0; + valBuf[valueLen] = 0; + + bool res3 = false; + switch(pt){ + case PropertiesType_Uint32: + res3 = top->put(nameBuf, ntohl(* (Uint32 *)valBuf), true); + break; + case PropertiesType_char: + res3 = top->put(nameBuf, valBuf, true); + break; + case PropertiesType_Properties: + assert(0); + } + if(res3 != true){ + return false; + } + _items--; + } + return true; +} + +PropertyImpl::~PropertyImpl(){ + free((char*)name); + switch(valueType){ + case PropertiesType_Uint32: + delete (Uint32 *)value; + break; + case PropertiesType_char: + free((char *)value); + break; + case PropertiesType_Properties: + delete (Properties *)value; + break; + } +} + +PropertyImpl * +PropertyImpl::copyPropertyImpl(const PropertyImpl & org){ + switch(org.valueType){ + case PropertiesType_Uint32: + return new PropertyImpl(org.name, * (Uint32 *)org.value); + break; + case PropertiesType_char: + return new PropertyImpl(org.name, (char *)org.value); + break; + case PropertiesType_Properties: + return new PropertyImpl(org.name, (Properties *)org.value); + break; + default: + assert(0); + } + return 0; +} + +PropertyImpl::PropertyImpl(const char * _name, Uint32 _value){ + this->name = strdup(_name); + this->value = new Uint32; + * ((Uint32 *)this->value) = _value; + this->valueType = PropertiesType_Uint32; +} + +PropertyImpl::PropertyImpl(const char * _name, const char * _value){ + this->name = strdup(_name); + this->value = strdup(_value); + this->valueType = PropertiesType_char; + +} + +PropertyImpl::PropertyImpl(const char * _name, const Properties * _value){ + this->name = strdup(_name); + this->value = new Properties(* _value); + this->valueType = PropertiesType_Properties; +} + +const Uint32 E_PROPERTIES_OK = 0; +const Uint32 E_PROPERTIES_INVALID_NAME = 1; +const Uint32 E_PROPERTIES_NO_SUCH_ELEMENT = 2; +const Uint32 E_PROPERTIES_INVALID_TYPE = 3; +const Uint32 E_PROPERTIES_ELEMENT_ALREADY_EXISTS = 4; + +const Uint32 E_PROPERTIES_ERROR_MALLOC_WHILE_PACKING = 5; +const Uint32 E_PROPERTIES_INVALID_VERSION_WHILE_UNPACKING = 6; +const Uint32 E_PROPERTIES_INVALID_BUFFER_TO_SHORT = 7; +const Uint32 E_PROPERTIES_ERROR_MALLOC_WHILE_UNPACKING = 8; +const Uint32 E_PROPERTIES_INVALID_CHECKSUM = 9; +const Uint32 E_PROPERTIES_BUFFER_TO_SMALL_WHILE_UNPACKING = 10; + +/** + * These are methods that used to be inline + * + * But Diab 4.1f could not compile -release with to many inlines + */ +void +Properties::setErrno(Uint32 pErr, Uint32 osErr) const { + if(parent != 0){ + parent->setErrno(pErr, osErr); + return ; + } + + /** + * propErrno & osErrno used to be mutable, + * but diab didn't know what mutable meant. + */ + *((Uint32*)&propErrno) = pErr; + *((Uint32*)&osErrno) = osErr; +} + +/** + * Inlined get/put(name, no, ...) - methods + */ + +bool +Properties::put(const char * name, Uint32 no, Uint32 val, bool replace){ + size_t tmp_len = strlen(name)+20; + char * tmp = (char*)malloc(tmp_len); + snprintf(tmp, tmp_len, "%s_%d", name, no); + bool res = put(tmp, val, replace); + free(tmp); + return res; +} + + +bool +Properties::put(const char * name, Uint32 no, const char * val, bool replace){ + size_t tmp_len = strlen(name)+20; + char * tmp = (char*)malloc(tmp_len); + snprintf(tmp, tmp_len, "%s_%d", name, no); + bool res = put(tmp, val, replace); + free(tmp); + return res; +} + + +bool +Properties::put(const char * name, Uint32 no, const Properties * val, + bool replace){ + size_t tmp_len = strlen(name)+20; + char * tmp = (char*)malloc(tmp_len); + snprintf(tmp, tmp_len, "%s_%d", name, no); + bool res = put(tmp, val, replace); + free(tmp); + return res; +} + + +bool +Properties::getTypeOf(const char * name, Uint32 no, + PropertiesType * type) const { + size_t tmp_len = strlen(name)+20; + char * tmp = (char*)malloc(tmp_len); + snprintf(tmp, tmp_len, "%s_%d", name, no); + bool res = getTypeOf(tmp, type); + free(tmp); + return res; +} + +bool +Properties::contains(const char * name, Uint32 no) const { + size_t tmp_len = strlen(name)+20; + char * tmp = (char*)malloc(tmp_len); + snprintf(tmp, tmp_len, "%s_%d", name, no); + bool res = contains(tmp); + free(tmp); + return res; +} + +bool +Properties::get(const char * name, Uint32 no, Uint32 * value) const{ + size_t tmp_len = strlen(name)+20; + char * tmp = (char*)malloc(tmp_len); + snprintf(tmp, tmp_len, "%s_%d", name, no); + bool res = get(tmp, value); + free(tmp); + return res; +} + + +bool +Properties::get(const char * name, Uint32 no, const char ** value) const { + size_t tmp_len = strlen(name)+20; + char * tmp = (char*)malloc(tmp_len); + snprintf(tmp, tmp_len, "%s_%d", name, no); + bool res = get(tmp, value); + free(tmp); + return res; +} + + +bool +Properties::get(const char * name, Uint32 no, const Properties ** value) const{ + size_t tmp_len = strlen(name)+20; + char * tmp = (char*)malloc(tmp_len); + snprintf(tmp, tmp_len, "%s_%d", name, no); + bool res = get(tmp, value); + free(tmp); + return res; +} + + +bool +Properties::getCopy(const char * name, Uint32 no, char ** value) const { + size_t tmp_len = strlen(name)+20; + char * tmp = (char*)malloc(tmp_len); + snprintf(tmp, tmp_len, "%s_%d", name, no); + bool res = getCopy(tmp, value); + free(tmp); + return res; +} + + +bool +Properties::getCopy(const char * name, Uint32 no, Properties ** value) const { + size_t tmp_len = strlen(name)+20; + char * tmp = (char*)malloc(tmp_len); + snprintf(tmp, tmp_len, "%s_%d", name, no); + bool res = getCopy(tmp, value); + free(tmp); + return res; +} + +void +Properties::setCaseInsensitiveNames(bool value){ + impl->m_insensitive = value; + if(value) + impl->compare = strcasecmp; + else + impl->compare = strcmp; +} + +bool +Properties::getCaseInsensitiveNames() const { + return impl->m_insensitive; +} |