From 5c93d339db966f2e549224aea0c60fb6739dfb41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Tue, 24 Nov 2009 10:34:42 +0000 Subject: [PATCH] got rid of many temporary objects in string reading --- library/DFDataModel.cpp | 63 +++++++++++++++++++++++++++++++++-- library/DFDataModel.h | 3 ++ library/DFHackAPI.cpp | 26 ++++++++++----- library/DFProcess-linux.cpp | 1 + library/DFProcess-windows.cpp | 2 +- 5 files changed, 84 insertions(+), 11 deletions(-) diff --git a/library/DFDataModel.cpp b/library/DFDataModel.cpp index 9e684315e..364e9d9a4 100644 --- a/library/DFDataModel.cpp +++ b/library/DFDataModel.cpp @@ -44,6 +44,40 @@ DfVector DMWindows40d::readVector (uint32_t offset, uint32_t item_size) }; +size_t DMWindows40d::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) +{ + /* + MSVC++ string + ptr allocator + union + { + char[16] start; + char * start_ptr +} +Uint32 length +Uint32 capacity +*/ + uint32_t start_offset = offset + 4; + size_t length = MreadDWord(offset + 20); + + size_t capacity = MreadDWord(offset + 24); + size_t read_real = min(length, bufcapacity-1);// keep space for null termination + + // read data from inside the string structure + if(capacity < 16) + { + Mread(start_offset, read_real , (uint8_t *)buffer); + } + else // read data from what the offset + 4 dword points to + { + start_offset = MreadDWord(start_offset);// dereference the start offset + Mread(start_offset, read_real, (uint8_t *)buffer); + } + + buffer[read_real] = 0; + return read_real; +}; + const string DMWindows40d::readSTLString (uint32_t offset) { /* @@ -96,10 +130,35 @@ DfVector DMLinux40d::readVector (uint32_t offset, uint32_t item_size) return DfVector(start,size,item_size); }; +struct _Rep_base +{ + uint32_t _M_length; + uint32_t _M_capacity; + uint32_t _M_refcount; +}; + +size_t DMLinux40d::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) +{ + _Rep_base header; + offset = MreadDWord(offset); + Mread(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); + size_t read_real = min((size_t)header._M_length, bufcapacity-1);// keep space for null termination + Mread(offset,read_real,(uint8_t * )buffer); + buffer[read_real] = 0; + return read_real; +}; const string DMLinux40d::readSTLString (uint32_t offset) { - // GNU std::string is a single pointer (as far as we are concerned) + _Rep_base header; + offset = MreadDWord(offset); - return MreadCString(offset); + Mread(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); + + // FIXME: use char* everywhere, avoid string + char * temp = new char[header._M_length+1]; + Mread(offset,header._M_length+1,(uint8_t * )temp); + string ret(temp); + delete temp; + return ret; }; diff --git a/library/DFDataModel.h b/library/DFDataModel.h index 7dbc9ec75..479e8bb5e 100644 --- a/library/DFDataModel.h +++ b/library/DFDataModel.h @@ -35,6 +35,7 @@ namespace DFHack public: // read a string virtual const string readSTLString (uint32_t offset) = 0; + virtual size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) = 0; // read a vector from memory //template virtual DfVector readVector (uint32_t offset, uint32_t item_size) = 0; @@ -43,6 +44,7 @@ namespace DFHack class DMWindows40d : public DataModel { virtual const string readSTLString (uint32_t offset); + virtual size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); // read a vector from memory virtual DfVector readVector (uint32_t offset, uint32_t item_size); }; @@ -50,6 +52,7 @@ namespace DFHack class DMLinux40d : public DataModel { virtual const string readSTLString (uint32_t offset); + virtual size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); // read a vector from memory virtual DfVector readVector (uint32_t offset, uint32_t item_size); }; diff --git a/library/DFHackAPI.cpp b/library/DFHackAPI.cpp index cab02fdc1..949e4d164 100644 --- a/library/DFHackAPI.cpp +++ b/library/DFHackAPI.cpp @@ -371,7 +371,10 @@ bool API::ReadWoodMatgloss(vector & woods) // read the matgloss pointer from the vector into temp uint32_t temp = *(uint32_t *) p_matgloss[i]; // read the string pointed at by + /* fill_char_buf(mat.id, d->dm->readSTLString(temp)); // reads a C string given an address + */ + d->dm->readSTLString(temp,mat.id,128); woods.push_back(mat); } return true; @@ -394,7 +397,8 @@ bool API::ReadStoneMatgloss(vector & stones) uint32_t temp = *(uint32_t *) p_matgloss[i]; // read the string pointed at by t_matgloss mat; - fill_char_buf(mat.id, d->dm->readSTLString(temp)); // reads a C string given an address + //fill_char_buf(mat.id, d->dm->readSTLString(temp)); // reads a C string given an address + d->dm->readSTLString(temp,mat.id,128); mat.fore = (uint8_t)MreadWord(temp + matgloss_colors); mat.back = (uint8_t)MreadWord(temp + matgloss_colors + 2); mat.bright = (uint8_t)MreadWord(temp + matgloss_colors + 4); @@ -420,7 +424,8 @@ bool API::ReadMetalMatgloss(vector & metals) uint32_t temp = *(uint32_t *) p_matgloss[i]; // read the string pointed at by t_matgloss mat; - fill_char_buf(mat.id, d->dm->readSTLString(temp)); // reads a C string given an address + //fill_char_buf(mat.id, d->dm->readSTLString(temp)); // reads a C string given an address + d->dm->readSTLString(temp,mat.id,128); mat.fore = (uint8_t)MreadWord(temp + matgloss_colors); mat.back = (uint8_t)MreadWord(temp + matgloss_colors + 2); mat.bright = (uint8_t)MreadWord(temp + matgloss_colors + 4); @@ -448,7 +453,8 @@ bool API::ReadPlantMatgloss(vector & plants) // read the matgloss pointer from the vector into temp uint32_t temp = *(uint32_t *) p_matgloss[i]; // read the string pointed at by - fill_char_buf(mat.id, d->dm->readSTLString(temp)); // reads a C string given an address + //fill_char_buf(mat.id, d->dm->readSTLString(temp)); // reads a C string given an address + d->dm->readSTLString(temp,mat.id,128); plants.push_back(mat); } return true; @@ -473,7 +479,8 @@ bool API::ReadCreatureMatgloss(vector & creatures) // read the matgloss pointer from the vector into temp uint32_t temp = *(uint32_t *) p_matgloss[i]; // read the string pointed at by - fill_char_buf(mat.id, d->dm->readSTLString(temp)); // reads a C string given an address + //fill_char_buf(mat.id, d->dm->readSTLString(temp)); // reads a C string given an address + d->dm->readSTLString(temp,mat.id,128); creatures.push_back(mat); } return true; @@ -997,13 +1004,16 @@ bool API::ReadCreature(const int32_t &index, t_creature & furball) MreadDWord(temp + d->creature_flags1_offset, furball.flags1.whole); MreadDWord(temp + d->creature_flags2_offset, furball.flags2.whole); // normal names - fill_char_buf(furball.first_name, d->dm->readSTLString(temp+d->creature_first_name_offset)); - fill_char_buf(furball.nick_name, d->dm->readSTLString(temp+d->creature_nick_name_offset)); + d->dm->readSTLString(temp+d->creature_first_name_offset,furball.first_name,128); + d->dm->readSTLString(temp+d->creature_nick_name_offset,furball.nick_name,128); + // custom profession + d->dm->readSTLString(temp+d->creature_nick_name_offset,furball.nick_name,128); + fill_char_buf(furball.custom_profession, d->dm->readSTLString(temp+d->creature_custom_profession_offset)); // crazy composited names Mread(temp + d->creature_last_name_offset,sizeof(t_lastname), (uint8_t *) &furball.last_name ); Mread(temp + d->creature_squad_name_offset,sizeof(t_squadname), (uint8_t *) &furball.squad_name ); - // custom profession - fill_char_buf(furball.custom_profession, d->dm->readSTLString(temp+d->creature_custom_profession_offset)); + + // labors Mread(temp+d->creature_labors_offset, NUM_CREATURE_LABORS, furball.labors); diff --git a/library/DFProcess-linux.cpp b/library/DFProcess-linux.cpp index 9da19a8b3..19fa0c0eb 100644 --- a/library/DFProcess-linux.cpp +++ b/library/DFProcess-linux.cpp @@ -173,6 +173,7 @@ Process::~Process() } // destroy data model. this is assigned by processmanager delete d->my_datamodel; + delete d; } diff --git a/library/DFProcess-windows.cpp b/library/DFProcess-windows.cpp index f2bdbc253..bab4c7de1 100644 --- a/library/DFProcess-windows.cpp +++ b/library/DFProcess-windows.cpp @@ -144,7 +144,7 @@ Process::~Process() { CloseHandle(d->my_main_thread); } - + delete d; }