📄 properties.cpp
字号:
/* 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 <ndb_global.h>#include <Properties.hpp>#include <NdbTCP.h>#include <NdbOut.hpp>staticchar * f_strdup(const char * s){ if(!s) return 0; return strdup(s);}/** * Note has to be a multiple of 4 bytes */const char Properties::version[] = { 2, 0, 0, 1, 1, 1, 1, 4 };const char Properties::delimiter = ':';/** * PropertyImpl */struct PropertyImpl{ PropertiesType valueType; const char * name; void * value; ~PropertyImpl(); PropertyImpl(const char * name, Uint32 value); PropertyImpl(const char * name, Uint64 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 implementedpublic: PropertiesImpl(Properties *, bool case_insensitive); 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 setCaseInsensitiveNames(bool value); 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(bool case_insensitive){ parent = 0; impl = new PropertiesImpl(this, case_insensitive);}Properties::Properties(const Properties & org){ parent = 0; impl = new PropertiesImpl(this, * org.impl);}Properties::Properties(const Property * anArray, int arrayLen){ impl = new PropertiesImpl(this, false); put(anArray, arrayLen);}Properties::~Properties(){ clear(); delete impl;}voidProperties::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>boolput(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)); }boolProperties::put(const char * name, Uint32 value, bool replace){ return ::put(impl, name, value, replace);}boolProperties::put64(const char * name, Uint64 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);}boolProperties::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;}boolProperties::contains(const char * name) const { PropertyImpl * nvp = impl->get(name); return nvp != 0;}boolProperties::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; } if(nvp->valueType == PropertiesType_Uint64){ Uint64 tmp = * (Uint64 *)nvp->value; Uint64 max = 1; max <<= 32; if(tmp < max){ * value = (Uint32)tmp; setErrno(E_PROPERTIES_OK); return true; } } setErrno(E_PROPERTIES_INVALID_TYPE); return false;}boolProperties::get(const char * name, Uint64 * value) const { PropertyImpl * nvp = impl->get(name); if(nvp == 0){ setErrno(E_PROPERTIES_NO_SUCH_ELEMENT); return false; } if(nvp->valueType == PropertiesType_Uint32){ Uint32 tmp = * (Uint32 *)nvp->value; * value = (Uint64)tmp; setErrno(E_PROPERTIES_OK); return true; } if(nvp->valueType == PropertiesType_Uint64){ * value = * (Uint64 *)nvp->value; setErrno(E_PROPERTIES_OK); return true; } setErrno(E_PROPERTIES_INVALID_TYPE); return false;}boolProperties::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;}boolProperties::get(const char * name, BaseString& value) const { const char *tmp = ""; bool ret; ret = get(name, &tmp); value.assign(tmp); return ret;}boolProperties::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;}boolProperties::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 = f_strdup((const char *)nvp->value); setErrno(E_PROPERTIES_OK); return true; } setErrno(E_PROPERTIES_INVALID_TYPE); return false;}boolProperties::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);}voidProperties::remove(const char * name) { impl->remove(name);}voidProperties::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_Uint64: fprintf(out, "%s%s = (Uint64) %lld\n", buf, impl->content[i]->name, *(Uint64 *)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]; BaseString::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;}Uint32Properties::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);}staticUint32computeChecksum(const Uint32 * buf, Uint32 words){ Uint32 sum = 0; for(unsigned int i = 0; i<words; i++) sum ^= htonl(buf[i]); return sum;}boolProperties::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;}boolProperties::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, bool case_insensitive){ this->properties = p; items = 0; size = 25; content = new PropertyImpl * [size]; setCaseInsensitiveNames(case_insensitive);}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;}voidPropertiesImpl::setCaseInsensitiveNames(bool value){ m_insensitive = value; if(value) compare = strcasecmp; else compare = strcmp;}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;}voidPropertiesImpl::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; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -