got rid of many temporary objects in string reading

develop
Petr Mrázek 2009-11-24 10:34:42 +00:00
parent 6cb7c4a636
commit 5c93d339db
5 changed files with 84 additions and 11 deletions

@ -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;
};

@ -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 <class T>
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);
};

@ -371,7 +371,10 @@ bool API::ReadWoodMatgloss(vector<t_matgloss> & 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<t_matgloss> & 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<t_matgloss> & 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<t_matgloss> & 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<t_matgloss> & 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);

@ -173,6 +173,7 @@ Process::~Process()
}
// destroy data model. this is assigned by processmanager
delete d->my_datamodel;
delete d;
}

@ -144,7 +144,7 @@ Process::~Process()
{
CloseHandle(d->my_main_thread);
}
delete d;
}