Find, Filter, FindInRange and Incremental search methods

develop
Petr Mrázek 2010-06-19 03:47:09 +02:00
parent f90e3c15b7
commit bbb29fe3d5
5 changed files with 137 additions and 79 deletions

@ -41,7 +41,7 @@ namespace DFHack
{
private:
class Private;
Private * d;
Private * d;
public:
enum OSType
{
@ -66,7 +66,7 @@ namespace DFHack
uint32_t getAddress (const char *);
uint32_t getHexValue (const char *);
std::string getMood(const uint32_t moodID);
std::string getMood(const uint32_t moodID);
std::string getString (const std::string&);
std::string getProfession(const uint32_t) const;
std::string getJob(const uint32_t) const;
@ -74,9 +74,9 @@ namespace DFHack
std::string getTrait (const uint32_t, const uint32_t) const;
std::string getTraitName(const uint32_t) const;
std::string getLabor (const uint32_t);
std::vector< std::vector<std::string> > const& getAllTraits();
std::vector< std::vector<std::string> > const& getAllTraits();
DFHack::t_level getLevelInfo(const uint32_t level) const;
DFHack::t_level getLevelInfo(const uint32_t level) const;
void setVersion(const char *);
void setVersion(const std::string&);
@ -105,12 +105,12 @@ namespace DFHack
void setJob(const std::string &, const std::string &);
void setSkill(const std::string &, const std::string &);
void setTrait(const std::string &, const std::string &, const std::string &,
const std::string &, const std::string &,
const std::string &, const std::string &, const std::string &);
const std::string &, const std::string &,
const std::string &, const std::string &, const std::string &);
void setLabor(const std::string &, const std::string &);
void setLevel(const std::string &nLevel, const std::string &nName,
const std::string &nXp);
void setMood(const std::string &id, const std::string &mood);
void setLevel(const std::string &nLevel, const std::string &nName,
const std::string &nXp);
void setMood(const std::string &id, const std::string &mood);
void RebaseVTable(const int32_t offset);
void setParentProcess(Process * _p);

@ -301,8 +301,8 @@ bool Materials::ReadCreatureTypesEx (void)
uint32_t bodypart_id_offset = mem->getOffset ("bodypart_id");
uint32_t bodypart_category_offset = mem->getOffset ("bodypart_category");
uint32_t bodypart_layers_offset = mem->getOffset ("bodypart_layers_vector");
uint32_t bodypart_singular_offset = mem->getOffset ("bodypart_singular_vector");
uint32_t bodypart_plural_offset = mem->getOffset ("bodypart_plural_vector");
uint32_t bodypart_singular_offset = mem->getOffset ("bodypart_singular_vector"); // unused
uint32_t bodypart_plural_offset = mem->getOffset ("bodypart_plural_vector"); // unused
uint32_t color_modifier_part_offset = mem->getOffset ("color_modifier_part");
uint32_t color_modifier_startdate_offset = mem->getOffset ("color_modifier_startdate");
uint32_t color_modifier_enddate_offset = mem->getOffset ("color_modifier_enddate");
@ -318,7 +318,18 @@ bool Materials::ReadCreatureTypesEx (void)
for (uint32_t i = 0; i < size;i++)
{
t_creaturetype mat;
// FROM race READ
// std::string rawname AT 0,
// char tile_character AT tile_offset,
// word tilecolor.fore : tile_color_offset,
// word tilecolor.back : tile_color_offset + 2,
// word tilecolor.bright : tile_color_offset + 4
p->readSTLString (p_races[i], mat.rawname, sizeof(mat.rawname));
mat.tile_character = p->readByte( p_races[i] + tile_offset );
mat.tilecolor.fore = p->readWord( p_races[i] + tile_color_offset );
mat.tilecolor.back = p->readWord( p_races[i] + tile_color_offset + 2 );
mat.tilecolor.bright = p->readWord( p_races[i] + tile_color_offset + 4 );
DfVector <uint32_t> p_castes(p, p_races[i] + castes_vector_offset);
sizecas = p_castes.size();
for (uint32_t j = 0; j < sizecas;j++)
@ -364,11 +375,6 @@ bool Materials::ReadCreatureTypesEx (void)
mat.castes.push_back(caste);
}
mat.tile_character = p->readByte( p_races[i] + tile_offset );
mat.tilecolor.fore = p->readWord( p_races[i] + tile_color_offset );
mat.tilecolor.back = p->readWord( p_races[i] + tile_color_offset + 2 );
mat.tilecolor.bright = p->readWord( p_races[i] + tile_color_offset + 4 );
DfVector <uint32_t> p_extract(p, p_races[i] + extract_vector_offset);
for(uint32_t j = 0; j < p_extract.size(); j++)
{

@ -1844,6 +1844,13 @@ dwarf_race_index = 0x014abef4
<Offset name="creature_type_extract_vector">0x1A14</Offset>
<Offset name="creature_tile">0xE0</Offset>
<Offset name="creature_tile_color">0xF6</Offset>
<!--
<Offset name="creature_type_caste_vector">0x138</Offset>
<Offset name="creature_type_extract_vector">0x1A14</Offset>
<Offset name="creature_tile">0xE0</Offset>
<Offset name="creature_tile_color">0xF6</Offset>
-->
<!--
struct CreatureType
{

@ -17,31 +17,46 @@ class SegmentFinder
{
delete mr_.buffer;
}
template <class needleType, class hayType, typename comparator >
bool Find (needleType needle, const uint8_t increment ,vector <uint64_t> &found, vector <uint64_t> &newfound, comparator oper)
bool Find (needleType needle, const uint8_t increment , vector <uint64_t> &newfound, comparator oper)
{
if(found.empty())
//loop
for(uint64_t offset = 0; offset < (mr_.end - mr_.start) - sizeof(hayType); offset += increment)
{
//loop
for(uint64_t offset = 0; offset < (mr_.end - mr_.start) - sizeof(hayType); offset += increment)
{
if( oper(_SF,(hayType *)(mr_.buffer + offset), needle) )
newfound.push_back(mr_.start + offset);
}
if( oper(_SF,(hayType *)(mr_.buffer + offset), needle) )
newfound.push_back(mr_.start + offset);
}
else
return !newfound.empty();
}
template < class needleType, class hayType, typename comparator >
uint64_t FindInRange (needleType needle, comparator oper, uint64_t start, uint64_t length)
{
mr_.buffer + start - mr_.start;
uint64_t stopper = min((mr_.end - mr_.start) - sizeof(hayType), (start - mr_.start) - sizeof(hayType));
//loop
for(uint64_t offset = start - mr_.start; offset < stopper; offset +=1)
{
if( oper(_SF,(hayType *)(mr_.buffer + offset), needle) )
return mr_.start + offset;
}
return 0;
}
template <class needleType, class hayType, typename comparator >
bool Filter (needleType needle, vector <uint64_t> &found, vector <uint64_t> &newfound, comparator oper)
{
for( uint64_t i = 0; i < found.size(); i++)
{
for( uint64_t i = 0; i < found.size(); i++)
if(mr_.isInRange(found[i]))
{
if(mr_.isInRange(found[i]))
{
uint64_t corrected = found[i] - mr_.start;
if( oper(_SF,(hayType *)(mr_.buffer + corrected), needle) )
newfound.push_back(found[i]);
}
uint64_t corrected = found[i] - mr_.start;
if( oper(_SF,(hayType *)(mr_.buffer + corrected), needle) )
newfound.push_back(found[i]);
}
}
return true;
return !newfound.empty();
}
private:
friend class SegmentedFinder;
@ -81,16 +96,52 @@ class SegmentedFinder
}
template <class needleType, class hayType, typename comparator >
bool Find (const needleType needle, const uint8_t increment, vector <uint64_t> &found, comparator oper)
{
found.clear();
for(int i = 0; i < segments.size(); i++)
{
segments[i]->Find<needleType,hayType,comparator>(needle, increment, found, oper);
}
return !(found.empty());
}
template < class needleType, class hayType, typename comparator >
uint64_t FindInRange (needleType needle, comparator oper, uint64_t start, uint64_t length)
{
SegmentFinder * sf = getSegmentForAddress(start);
if(sf)
{
return sf->FindInRange<needleType,hayType,comparator>(needle, oper, start, length);
}
return 0;
}
template <class needleType, class hayType, typename comparator >
bool Filter (const needleType needle, vector <uint64_t> &found, comparator oper)
{
vector <uint64_t> newfound;
for(int i = 0; i < segments.size(); i++)
{
segments[i]->Find<needleType,hayType,comparator>(needle, increment, found, newfound, oper);
segments[i]->Filter<needleType,hayType,comparator>(needle, found, newfound, oper);
}
found.clear();
found = newfound;
return !(found.empty());
}
template <class needleType, class hayType, typename comparator >
bool Incremental (needleType needle, const uint8_t increment ,vector <uint64_t> &found, comparator oper)
{
if(found.empty())
{
return Find <needleType, hayType, comparator>(needle,increment,found,oper);
}
else
{
return Filter <needleType, hayType, comparator>(needle,found,oper);
}
}
template <typename T>
T * Translate(uint64_t address)
{
@ -103,11 +154,13 @@ class SegmentedFinder
}
return 0;
}
template <typename T>
T Read(uint64_t address)
{
return *Translate<T>(address);
}
template <typename T>
bool Read(uint64_t address, T& target)
{

@ -188,8 +188,8 @@ bool getRanges(DFHack::Process * p, vector <DFHack::t_memrange>& selected_ranges
}
else if(p->getDescriptor()->getOS() == DFHack::memory_info::OS_LINUX)
{
start = min(11, (int)ranges.size());
end = min(14, (int)ranges.size());
start = min(2, (int)ranges.size());
end = min(4, (int)ranges.size());
}
else
{
@ -367,13 +367,13 @@ void FindIntegers(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& r
switch(size)
{
case 1:
sf.Find<uint8_t,uint8_t>(test1,alignment,found, equalityP<uint8_t>);
sf.Incremental<uint8_t,uint8_t>(test1,alignment,found, equalityP<uint8_t>);
break;
case 2:
sf.Find<uint16_t,uint16_t>(test1,alignment,found, equalityP<uint16_t>);
sf.Incremental<uint16_t,uint16_t>(test1,alignment,found, equalityP<uint16_t>);
break;
case 4:
sf.Find<uint32_t,uint32_t>(test1,alignment,found, equalityP<uint32_t>);
sf.Incremental<uint32_t,uint32_t>(test1,alignment,found, equalityP<uint32_t>);
break;
}
DF->Detach();
@ -397,8 +397,8 @@ void FindVectorByLength(DFHack::ContextManager & DFMgr, vector <DFHack::t_memran
DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach();
SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found,vectorAll);
sf.Find<uint32_t,vecTriplet>(length * element_size,4,found,vectorLength<uint32_t>);
sf.Incremental<int ,vecTriplet>(0,4,found,vectorAll);
sf.Filter<uint32_t,vecTriplet>(length * element_size,found,vectorLength<uint32_t>);
DF->Detach();
}
}
@ -409,14 +409,12 @@ void FindVectorByObjectRawname(DFHack::ContextManager & DFMgr, vector <DFHack::t
string select;
while (Incremental(found, "raw name",select,"vector","vectors"))
{
// clear the list of found addresses -- this is a one-shot
found.clear();
DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach();
SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found, vectorAll);
sf.Find<const char * ,vecTriplet>(select.c_str(),4,found, vectorString);
sf.Filter<const char * ,vecTriplet>(select.c_str(),found, vectorString);
DF->Detach();
}
}
@ -427,14 +425,12 @@ void FindVectorByFirstObjectRawname(DFHack::ContextManager & DFMgr, vector <DFHa
string select;
while (Incremental(found, "raw name",select,"vector","vectors"))
{
// clear the list of found addresses -- this is a one-shot
found.clear();
DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach();
SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found, vectorAll);
sf.Find<const char * ,vecTriplet>(select.c_str(),4,found, vectorStringFirst);
sf.Filter<const char * ,vecTriplet>(select.c_str(),found, vectorStringFirst);
DF->Detach();
}
}
@ -457,14 +453,12 @@ void FindVectorByBounds(DFHack::ContextManager & DFMgr, vector <DFHack::t_memran
uint32_t select;
while (Incremental(found, "address between vector.start and vector.end",select,"vector","vectors"))
{
// clear the list of found addresses -- this is a one-shot
found.clear();
DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach();
SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found, vectorAll);
sf.Find<uint32_t ,vecTriplet>(select,4,found, vectorAddrWithin);
sf.Filter<uint32_t ,vecTriplet>(select,found, vectorAddrWithin);
// sort by size of vector
std::sort(found.begin(), found.end(), VectorSizeFunctor(sf));
DF->Detach();
@ -477,14 +471,12 @@ void FindPtrVectorsByObjectAddress(DFHack::ContextManager & DFMgr, vector <DFHac
uint32_t select;
while (Incremental(found, "object address",select,"vector","vectors"))
{
// clear the list of found addresses -- this is a one-shot
found.clear();
DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach();
SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found, vectorAll);
sf.Find<uint32_t ,vecTriplet>(select,4,found, vectorOfPtrWithin);
sf.Filter<uint32_t ,vecTriplet>(select,found, vectorOfPtrWithin);
DF->Detach();
}
}
@ -500,7 +492,7 @@ void FindStrings(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ra
DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach();
SegmentedFinder sf(ranges,DF);
sf.Find< const char * ,uint32_t>(select.c_str(),1,found, findString);
sf.Incremental< const char * ,uint32_t>(select.c_str(),1,found, findString);
DF->Detach();
}
}
@ -599,17 +591,17 @@ void automatedLangtables(DFHack::Context * DF, vector <DFHack::t_memrange>& rang
// find lang vector (neutral word table)
to_filter = filtVectors;
sf.Find<const char * ,vecTriplet>("ABBEY",4,to_filter, vectorStringFirst);
sf.Filter<const char * ,vecTriplet>("ABBEY",to_filter, vectorStringFirst);
uint64_t lang_addr = to_filter[0];
// find dwarven language word table
to_filter = filtVectors;
sf.Find<const char * ,vecTriplet>("kulet",4,to_filter, vectorStringFirst);
sf.Filter<const char * ,vecTriplet>("kulet",to_filter, vectorStringFirst);
kulet_vector = to_filter[0];
// find vector of languages
to_filter = filtVectors;
sf.Find<const char * ,vecTriplet>("DWARF",4,to_filter, vectorStringFirst);
sf.Filter<const char * ,vecTriplet>("DWARF",to_filter, vectorStringFirst);
// verify
for(int i = 0; i < to_filter.size(); i++)
@ -634,35 +626,35 @@ void automatedLangtables(DFHack::Context * DF, vector <DFHack::t_memrange>& rang
// inorganics vector
to_filter = filtVectors;
//sf.Find<uint32_t,vecTriplet>(257 * 4,4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("IRON",4,to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("ONYX",4,to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("RAW_ADAMANTINE",4,to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("BLOODSTONE",4,to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("IRON",to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("ONYX",to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("RAW_ADAMANTINE",to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("BLOODSTONE",to_filter, vectorString);
printFound(to_filter,"inorganics");
// organics vector
to_filter = filtVectors;
sf.Find<uint32_t,vecTriplet>(52 * 4,4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("MUSHROOM_HELMET_PLUMP",4,to_filter, vectorStringFirst);
sf.Filter<uint32_t,vecTriplet>(52 * 4,to_filter,vectorLength<uint32_t>);
sf.Filter<const char * ,vecTriplet>("MUSHROOM_HELMET_PLUMP",to_filter, vectorStringFirst);
printFound(to_filter,"organics");
// tree vector
to_filter = filtVectors;
sf.Find<uint32_t,vecTriplet>(31 * 4,4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("MANGROVE",4,to_filter, vectorStringFirst);
sf.Filter<uint32_t,vecTriplet>(31 * 4,to_filter,vectorLength<uint32_t>);
sf.Filter<const char * ,vecTriplet>("MANGROVE",to_filter, vectorStringFirst);
printFound(to_filter,"trees");
// plant vector
to_filter = filtVectors;
sf.Find<uint32_t,vecTriplet>(21 * 4,4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("MUSHROOM_HELMET_PLUMP",4,to_filter, vectorStringFirst);
sf.Filter<uint32_t,vecTriplet>(21 * 4,to_filter,vectorLength<uint32_t>);
sf.Filter<const char * ,vecTriplet>("MUSHROOM_HELMET_PLUMP",to_filter, vectorStringFirst);
printFound(to_filter,"plants");
// color descriptors
//AMBER, 112
to_filter = filtVectors;
sf.Find<uint32_t,vecTriplet>(112 * 4,4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("AMBER",4,to_filter, vectorStringFirst);
sf.Filter<uint32_t,vecTriplet>(112 * 4,to_filter,vectorLength<uint32_t>);
sf.Filter<const char * ,vecTriplet>("AMBER",to_filter, vectorStringFirst);
printFound(to_filter,"color descriptors");
if(!to_filter.empty())
{
@ -676,25 +668,25 @@ void automatedLangtables(DFHack::Context * DF, vector <DFHack::t_memrange>& rang
// all descriptors
//AMBER, 338
to_filter = filtVectors;
sf.Find<uint32_t,vecTriplet>(338 * 4,4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("AMBER",4,to_filter, vectorStringFirst);
sf.Filter<uint32_t,vecTriplet>(338 * 4,to_filter,vectorLength<uint32_t>);
sf.Filter<const char * ,vecTriplet>("AMBER",to_filter, vectorStringFirst);
printFound(to_filter,"all descriptors");
// creature type
//ELEPHANT, ?? (demons abound)
to_filter = filtVectors;
//sf.Find<uint32_t,vecTriplet>(338 * 4,4,to_filter,vectorLength<uint32_t>);
sf.Find<const char * ,vecTriplet>("ELEPHANT",4,to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("CAT",4,to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("DWARF",4,to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("WAMBLER_FLUFFY",4,to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("TOAD",4,to_filter, vectorString);
sf.Find<const char * ,vecTriplet>("DEMON_1",4,to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("ELEPHANT",to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("CAT",to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("DWARF",to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("WAMBLER_FLUFFY",to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("TOAD",to_filter, vectorString);
sf.Filter<const char * ,vecTriplet>("DEMON_1",to_filter, vectorString);
vector <uint64_t> toad_first = to_filter;
vector <uint64_t> elephant_first = to_filter;
sf.Find<const char * ,vecTriplet>("TOAD",4,toad_first, vectorStringFirst);
sf.Find<const char * ,vecTriplet>("ELEPHANT",4,elephant_first, vectorStringFirst);
sf.Filter<const char * ,vecTriplet>("TOAD",toad_first, vectorStringFirst);
sf.Filter<const char * ,vecTriplet>("ELEPHANT",elephant_first, vectorStringFirst);
printFoundStrVec(toad_first,"toad-first creature types",sf);
printFound(elephant_first,"elephant-first creature types");
printFound(to_filter,"all creature types");