From accbd3b63a78a034b014b79feca498470e9dff21 Mon Sep 17 00:00:00 2001 From: JustinAJ Date: Sat, 18 Oct 2014 08:14:05 -0400 Subject: [PATCH] Various optimizations and bug fixes. --- Jupiter/INIFile.cpp | 170 ++++++++++++++++++++++++++++++-------------- Jupiter/INIFile.h | 14 ++++ Release/Jupiter.lib | Bin 245800 -> 246592 bytes 3 files changed, 130 insertions(+), 54 deletions(-) diff --git a/Jupiter/INIFile.cpp b/Jupiter/INIFile.cpp index a7f1d0c..a3e18f9 100644 --- a/Jupiter/INIFile.cpp +++ b/Jupiter/INIFile.cpp @@ -29,6 +29,7 @@ struct Jupiter::INIFile::Section::KeyValuePair::Data { + unsigned int keySum = 0; Jupiter::StringS key; Jupiter::StringS value; }; @@ -43,6 +44,7 @@ Jupiter::INIFile::Section::KeyValuePair::KeyValuePair(const KeyValuePair &source Jupiter::INIFile::Section::KeyValuePair::data_ = new Jupiter::INIFile::Section::KeyValuePair::Data(); Jupiter::INIFile::Section::KeyValuePair::data_->key = source.data_->key; Jupiter::INIFile::Section::KeyValuePair::data_->value = source.data_->value; + Jupiter::INIFile::Section::KeyValuePair::data_->keySum = Jupiter::INIFile::Section::KeyValuePair::data_->key.calcChecksumi(); } Jupiter::INIFile::Section::KeyValuePair::~KeyValuePair() @@ -50,6 +52,11 @@ Jupiter::INIFile::Section::KeyValuePair::~KeyValuePair() delete Jupiter::INIFile::Section::KeyValuePair::data_; } +unsigned int Jupiter::INIFile::Section::KeyValuePair::getKeyChecksum() const +{ + return Jupiter::INIFile::Section::KeyValuePair::data_->keySum; +} + const Jupiter::ReadableString &Jupiter::INIFile::Section::KeyValuePair::getKey() const { return Jupiter::INIFile::Section::KeyValuePair::data_->key; @@ -69,6 +76,7 @@ void Jupiter::INIFile::Section::KeyValuePair::setValue(const Jupiter::ReadableSt struct Jupiter::INIFile::Section::Data { + unsigned int nameSum = 0; Jupiter::StringS name; Jupiter::ArrayList data; ~Data(); @@ -87,6 +95,7 @@ Jupiter::INIFile::Section::Section() Jupiter::INIFile::Section::Section(const Jupiter::ReadableString &name) { Jupiter::INIFile::Section::data_ = new Jupiter::INIFile::Section::Data(); + Jupiter::INIFile::Section::data_->nameSum = name.calcChecksumi(); Jupiter::INIFile::Section::data_->name = name; } @@ -94,10 +103,8 @@ Jupiter::INIFile::Section::Section(const Jupiter::INIFile::Section &source) { Jupiter::INIFile::Section::data_ = new Jupiter::INIFile::Section::Data(); Jupiter::INIFile::Section::data_->name = source.data_->name; - for (size_t i = 0; i != Jupiter::INIFile::Section::data_->data.size(); i++) - { + for (size_t i = 0, sourceSize = source.data_->data.size(); i != sourceSize; i++) Jupiter::INIFile::Section::data_->data.add(new Jupiter::INIFile::Section::KeyValuePair(*source.data_->data.get(i))); - } } Jupiter::INIFile::Section::~Section() @@ -105,6 +112,11 @@ Jupiter::INIFile::Section::~Section() delete Jupiter::INIFile::Section::data_; } +unsigned int Jupiter::INIFile::Section::getNameChecksum() const +{ + return Jupiter::INIFile::Section::data_->nameSum; +} + const Jupiter::ReadableString &Jupiter::INIFile::Section::getName() const { return Jupiter::INIFile::Section::data_->name; @@ -118,10 +130,13 @@ const Jupiter::ReadableString &Jupiter::INIFile::Section::getValue(size_t index) const Jupiter::ReadableString &Jupiter::INIFile::Section::getValue(const Jupiter::ReadableString &key) const { Jupiter::INIFile::Section::KeyValuePair *pair; - for (size_t i = 0; i != Jupiter::INIFile::Section::data_->data.size(); i++) + const unsigned int keySum = key.calcChecksumi(); + size_t index = Jupiter::INIFile::Section::data_->data.size(); + while (index != 0) { - pair = Jupiter::INIFile::Section::data_->data.get(i); - if (pair->getKey().equalsi(key)) return pair->getValue(); + pair = Jupiter::INIFile::Section::data_->data.get(--index); + if (keySum == pair->getKeyChecksum() && pair->getKey().equalsi(key)) + return pair->getValue(); } return Jupiter::ReferenceString::empty; } @@ -134,10 +149,13 @@ Jupiter::INIFile::Section::KeyValuePair *Jupiter::INIFile::Section::getPair(size Jupiter::INIFile::Section::KeyValuePair *Jupiter::INIFile::Section::getPair(const Jupiter::ReadableString &key) const { Jupiter::INIFile::Section::KeyValuePair *pair; - for (size_t i = 0; i != Jupiter::INIFile::Section::data_->data.size(); i++) + const unsigned int keySum = key.calcChecksumi(); + size_t index = Jupiter::INIFile::Section::data_->data.size(); + while (index != 0) { - pair = Jupiter::INIFile::Section::data_->data.get(i); - if (pair->getKey().equalsi(key)) return pair; + pair = Jupiter::INIFile::Section::data_->data.get(--index); + if (keySum == pair->getKeyChecksum() && pair->getKey().equalsi(key)) + return pair; } return nullptr; } @@ -150,10 +168,13 @@ size_t Jupiter::INIFile::Section::size() const bool Jupiter::INIFile::Section::hasKey(const Jupiter::ReadableString &key) const { Jupiter::INIFile::Section::KeyValuePair *pair; - for (size_t i = 0; i != Jupiter::INIFile::Section::data_->data.size(); i++) + const unsigned int keySum = key.calcChecksumi(); + size_t index = Jupiter::INIFile::Section::data_->data.size(); + while (index != 0) { - pair = Jupiter::INIFile::Section::data_->data.get(i); - if (pair->getKey().equalsi(key)) return true; + pair = Jupiter::INIFile::Section::data_->data.get(--index); + if (keySum == pair->getKeyChecksum() && pair->getKey().equalsi(key)) + return true; } return false; } @@ -161,16 +182,19 @@ bool Jupiter::INIFile::Section::hasKey(const Jupiter::ReadableString &key) const bool Jupiter::INIFile::Section::set(const Jupiter::ReadableString &key, const Jupiter::ReadableString &value) { Jupiter::INIFile::Section::KeyValuePair *pair; - for (size_t i = 0; i != Jupiter::INIFile::Section::data_->data.size(); i++) + const unsigned int keySum = key.calcChecksumi(); + size_t index = Jupiter::INIFile::Section::data_->data.size(); + while (index != 0) { - pair = Jupiter::INIFile::Section::data_->data.get(i); - if (pair->getKey().equalsi(key)) + pair = Jupiter::INIFile::Section::data_->data.get(--index); + if (keySum == pair->getKeyChecksum() && pair->getKey().equalsi(key)) { pair->data_->value = value; return false; } } pair = new Jupiter::INIFile::Section::KeyValuePair(); + pair->data_->keySum = keySum; pair->data_->key = key; pair->data_->value = value; Jupiter::INIFile::Section::data_->data.add(pair); @@ -179,16 +203,21 @@ bool Jupiter::INIFile::Section::set(const Jupiter::ReadableString &key, const Ju void Jupiter::INIFile::Section::setName(const Jupiter::ReadableString &name) { + Jupiter::INIFile::Section::data_->nameSum = name.calcChecksumi(); Jupiter::INIFile::Section::data_->name = name; } bool Jupiter::INIFile::Section::remove(const Jupiter::ReadableString &key) { - for (size_t i = 0; i != Jupiter::INIFile::Section::data_->data.size(); i++) + Jupiter::INIFile::Section::KeyValuePair *pair; + const unsigned int keySum = key.calcChecksumi(); + size_t index = Jupiter::INIFile::Section::data_->data.size(); + while (index != 0) { - if (Jupiter::INIFile::Section::data_->data.get(i)->getKey().equalsi(key)) + pair = Jupiter::INIFile::Section::data_->data.get(--index); + if (keySum == pair->getKeyChecksum() && pair->getKey().equalsi(key)) { - delete Jupiter::INIFile::Section::data_->data.remove(i); + delete Jupiter::INIFile::Section::data_->data.remove(index); return true; } } @@ -218,10 +247,8 @@ Jupiter::INIFile::INIFile(const INIFile &source) { Jupiter::INIFile::data_ = new Jupiter::INIFile::Data; Jupiter::INIFile::data_->fName = source.data_->fName; - for (size_t i = 0; i != Jupiter::INIFile::data_->data.size(); i++) - { + for (size_t i = 0, sourceSize = source.data_->data.size(); i != sourceSize; i++) Jupiter::INIFile::data_->data.add(new Jupiter::INIFile::Section(*source.data_->data.get(i))); - } } Jupiter::INIFile::~INIFile() @@ -235,7 +262,6 @@ void Jupiter::INIFile::flushData() Jupiter::INIFile::data_ = new Jupiter::INIFile::Data(); } -// TODO: Rewrite this. unsigned int Jupiter::INIFile::readFile(const char *fileName) { size_t total = 0; @@ -344,10 +370,12 @@ bool Jupiter::INIFile::sync() bool Jupiter::INIFile::set(const Jupiter::ReadableString §ion, const Jupiter::ReadableString &key, const Jupiter::ReadableString &value) { Jupiter::INIFile::Section *sec; - for (size_t i = 0; i != Jupiter::INIFile::data_->data.size(); i++) + unsigned int nameSum = section.calcChecksumi(); + size_t index = Jupiter::INIFile::data_->data.size(); + while (index != 0) { - sec = Jupiter::INIFile::data_->data.get(i); - if (sec->getName().equalsi(section)) + sec = Jupiter::INIFile::data_->data.get(--index); + if (nameSum == sec->getNameChecksum() && sec->getName().equalsi(section)) return sec->set(key, value); } sec = new Jupiter::INIFile::Section(section); @@ -359,11 +387,13 @@ bool Jupiter::INIFile::set(const Jupiter::ReadableString §ion, const Jupiter bool Jupiter::INIFile::remove(const Jupiter::ReadableString §ion, const Jupiter::ReadableString &key) { Jupiter::INIFile::Section *sec; - for (size_t i = 0; i != Jupiter::INIFile::data_->data.size(); i++) + unsigned int nameSum = section.calcChecksumi(); + size_t index = Jupiter::INIFile::data_->data.size(); + while (index != 0) { - sec = Jupiter::INIFile::data_->data.get(i); - if (sec->getName().equalsi(section)) return sec->remove(key); - i++; + sec = Jupiter::INIFile::data_->data.get(--index); + if (nameSum == sec->getNameChecksum() && sec->getName().equalsi(section)) + return sec->remove(key); } return false; } @@ -380,17 +410,29 @@ Jupiter::INIFile::Section *Jupiter::INIFile::getSection(size_t index) const Jupiter::INIFile::Section *Jupiter::INIFile::getSection(const Jupiter::ReadableString §ion) const { - for (size_t i = 0; i != Jupiter::INIFile::data_->data.size(); i++) - if (Jupiter::INIFile::data_->data.get(i)->getName().equalsi(section)) - return Jupiter::INIFile::data_->data.get(i); + Jupiter::INIFile::Section *sec; + unsigned int nameSum = section.calcChecksumi(); + size_t index = Jupiter::INIFile::data_->data.size(); + while (index != 0) + { + sec = Jupiter::INIFile::data_->data.get(--index); + if (nameSum == sec->getNameChecksum() && sec->getName().equalsi(section)) + return Jupiter::INIFile::data_->data.get(index); + } return nullptr; } size_t Jupiter::INIFile::getSectionIndex(const Jupiter::ReadableString §ion) const { - for (size_t i = 0; i != Jupiter::INIFile::data_->data.size(); i++) - if (Jupiter::INIFile::data_->data.get(i)->getName().equalsi(section)) - return i; + Jupiter::INIFile::Section *sec; + unsigned int nameSum = section.calcChecksumi(); + size_t index = Jupiter::INIFile::data_->data.size(); + while (index != 0) + { + sec = Jupiter::INIFile::data_->data.get(--index); + if (nameSum == sec->getNameChecksum() && sec->getName().equalsi(section)) + return index; + } return Jupiter::INVALID_INDEX; } @@ -402,30 +444,43 @@ size_t Jupiter::INIFile::getSectionLength(size_t index) const const Jupiter::ReadableString &Jupiter::INIFile::getKey(const Jupiter::ReadableString §ion, size_t index) const { size_t sectionIndex = Jupiter::INIFile::getSectionIndex(section); - if (sectionIndex == Jupiter::INVALID_INDEX) return Jupiter::ReferenceString::empty; + if (sectionIndex == Jupiter::INVALID_INDEX) + return Jupiter::ReferenceString::empty; return Jupiter::INIFile::data_->data.get(sectionIndex)->getPair(index)->getKey(); } size_t Jupiter::INIFile::getKeyIndex(const Jupiter::ReadableString §ion, const Jupiter::ReadableString &key) const { size_t sectionIndex = Jupiter::INIFile::getSectionIndex(section); - if (sectionIndex == Jupiter::INVALID_INDEX) return Jupiter::INVALID_INDEX; - Jupiter::INIFile::Section *sect = Jupiter::INIFile::data_->data.get(sectionIndex); - size_t sectionSize = sect->size(); - for (size_t i = 0; i != sectionSize; i++) if (sect->getPair(i)->getKey().equalsi(key)) return i; + if (sectionIndex == Jupiter::INVALID_INDEX) + return Jupiter::INVALID_INDEX; + + Jupiter::INIFile::Section::KeyValuePair *pair; + Jupiter::INIFile::Section *sec = Jupiter::INIFile::data_->data.get(sectionIndex); + unsigned int keySum = key.calcChecksumi(); + size_t index = sec->size(); + while (index != 0) + { + pair = sec->getPair(--index); + if (keySum == pair->getKeyChecksum() && pair->getKey().equalsi(key)) + return index; + } return Jupiter::INVALID_INDEX; } const Jupiter::ReadableString &Jupiter::INIFile::get(const Jupiter::ReadableString §ion, const Jupiter::ReadableString &key, const Jupiter::ReadableString &defaultValue) const { - Jupiter::INIFile::Section *sect; - for (size_t i = 0; i != Jupiter::INIFile::data_->data.size(); i++) + Jupiter::INIFile::Section *sec; + unsigned int nameSum = section.calcChecksumi(); + size_t index = Jupiter::INIFile::data_->data.size(); + while (index != 0) { - sect = Jupiter::INIFile::data_->data.get(i); - if (sect->getName().equalsi(section)) + sec = Jupiter::INIFile::data_->data.get(--index); + if (nameSum == sec->getNameChecksum() && sec->getName().equalsi(section)) { - Jupiter::INIFile::Section::KeyValuePair *pair = sect->getPair(key); - if (pair == nullptr) return defaultValue; + Jupiter::INIFile::Section::KeyValuePair *pair = sec->getPair(key); + if (pair == nullptr) + return defaultValue; return pair->getValue(); } } @@ -435,53 +490,60 @@ const Jupiter::ReadableString &Jupiter::INIFile::get(const Jupiter::ReadableStri bool Jupiter::INIFile::getBool(const Jupiter::ReadableString §ion, const Jupiter::ReadableString &key, bool defaultValue) const { const Jupiter::ReadableString &val = Jupiter::INIFile::get(section, key); - if (val.size() != 0) return val.asBool(); + if (val.isEmpty() == false) + return val.asBool(); return defaultValue; } short Jupiter::INIFile::getShort(const Jupiter::ReadableString §ion, const Jupiter::ReadableString &key, short defaultValue) const { - return (short)Jupiter::INIFile::getInt(section, key, defaultValue); + return static_cast(Jupiter::INIFile::getInt(section, key, defaultValue)); } int Jupiter::INIFile::getInt(const Jupiter::ReadableString §ion, const Jupiter::ReadableString &key, int defaultValue) const { const Jupiter::ReadableString &val = Jupiter::INIFile::get(section, key); - if (val.size() != 0) return val.asInt(); + if (val.isEmpty() == false) + return val.asInt(); return defaultValue; } long Jupiter::INIFile::getLong(const Jupiter::ReadableString §ion, const Jupiter::ReadableString &key, long defaultValue) const { const Jupiter::ReadableString &val = Jupiter::INIFile::get(section, key); - if (val.size() != 0) return val.asInt(); + if (val.isEmpty() == false) + return val.asInt(); return defaultValue; } long long Jupiter::INIFile::getLongLong(const Jupiter::ReadableString §ion, const Jupiter::ReadableString &key, long long defaultValue) const { const Jupiter::ReadableString &val = Jupiter::INIFile::get(section, key); - if (val.size() != 0) return val.asInt(); + if (val.isEmpty() == false) + return val.asLongLong(); return defaultValue; } float Jupiter::INIFile::getFloat(const Jupiter::ReadableString §ion, const Jupiter::ReadableString &key, float defaultValue) const { const Jupiter::ReadableString &val = Jupiter::INIFile::get(section, key); - if (val.size() != 0) return float(val.asDouble()); + if (val.isEmpty() == false) + return float(val.asDouble()); return defaultValue; } double Jupiter::INIFile::getDouble(const Jupiter::ReadableString §ion, const Jupiter::ReadableString &key, double defaultValue) const { const Jupiter::ReadableString &val = Jupiter::INIFile::get(section, key); - if (val.size() != 0) return val.asDouble(); + if (val.isEmpty() == false) + return val.asDouble(); return defaultValue; } long double Jupiter::INIFile::getLongDouble(const Jupiter::ReadableString §ion, const Jupiter::ReadableString &key, long double defaultValue) const { const Jupiter::ReadableString &val = Jupiter::INIFile::get(section, key); - if (val.size() != 0) return val.asDouble(); + if (val.isEmpty() == false) + return val.asDouble(); return defaultValue; } diff --git a/Jupiter/INIFile.h b/Jupiter/INIFile.h index 3e43b16..9c73d33 100644 --- a/Jupiter/INIFile.h +++ b/Jupiter/INIFile.h @@ -50,6 +50,13 @@ namespace Jupiter friend class Jupiter::INIFile::Section; public: + /** + * @brief Fetches the checksum of the key in a key-value pair. + * + * @return Checksum of the key. + */ + unsigned int getKeyChecksum() const; + /** * @brief Fetches the key in the key-value pair. * @@ -91,6 +98,13 @@ namespace Jupiter Data *data_; }; + /** + * @brief Fetches the checksum of the name of a section. + * + * @return Checmsum of the name. + */ + unsigned int getNameChecksum() const; + /** * @brief Fetches the name of a section. * diff --git a/Release/Jupiter.lib b/Release/Jupiter.lib index 1c26bb5cef893429e7e07bef65d8aee61b47f7fb..85172ef2a73c3a9624b5cda8440e9b7dd49270ef 100644 GIT binary patch delta 31699 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 delta 31439 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 I2M=cd3;su8&Hw-a