diff --git a/library/DFProcess-linux-SHM.cpp b/library/DFProcess-linux-SHM.cpp index d87ebb8bc..3d13f0397 100644 --- a/library/DFProcess-linux-SHM.cpp +++ b/library/DFProcess-linux-SHM.cpp @@ -382,6 +382,11 @@ void SHMProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet) read(address + d->vector_start, sizeof(triplet), (uint8_t *) &triplet); } +void SHMProcess::writeSTLVector(const uint32_t address, t_vecTriplet & triplet) +{ + write(address + d->vector_start, sizeof(triplet), (uint8_t *) &triplet); +} + string SHMProcess::doReadClassName (uint32_t vptr) { diff --git a/library/DFProcess-linux-wine.cpp b/library/DFProcess-linux-wine.cpp index 58c309173..0fb56d88f 100644 --- a/library/DFProcess-linux-wine.cpp +++ b/library/DFProcess-linux-wine.cpp @@ -69,6 +69,7 @@ namespace { bool forceresume(); void readSTLVector(const uint32_t address, t_vecTriplet & triplet); + void writeSTLVector(const uint32_t address, t_vecTriplet & triplet); const std::string readSTLString (uint32_t offset); size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); size_t writeSTLString(const uint32_t address, const std::string writeString); @@ -152,6 +153,11 @@ void WineProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet) read(address + vector_start, sizeof(triplet), (uint8_t *) &triplet); } +void WineProcess::writeSTLVector(const uint32_t address, t_vecTriplet & triplet) +{ + write(address + vector_start, sizeof(triplet), (uint8_t *) &triplet); +} + size_t WineProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) { return stl.readSTLString(offset, buffer, bufcapacity); diff --git a/library/DFProcess-linux.cpp b/library/DFProcess-linux.cpp index 6926d229e..f1f99ee64 100644 --- a/library/DFProcess-linux.cpp +++ b/library/DFProcess-linux.cpp @@ -68,6 +68,7 @@ namespace { bool forceresume(); void readSTLVector(const uint32_t address, t_vecTriplet & triplet); + void writeSTLVector(const uint32_t address, t_vecTriplet & triplet); const std::string readSTLString (uint32_t offset); size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); size_t writeSTLString(const uint32_t address, const std::string writeString); @@ -178,6 +179,11 @@ void NormalProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet read(address + vector_start, sizeof(triplet), (uint8_t *) &triplet); } +void NormalProcess::writeSTLVector(const uint32_t address, t_vecTriplet & triplet) +{ + write(address + vector_start, sizeof(triplet), (uint8_t *) &triplet); +} + const string NormalProcess::readSTLString (uint32_t offset) { _Rep_base header; diff --git a/library/DFProcess-windows-SHM.cpp b/library/DFProcess-windows-SHM.cpp index 9ce4fa2cf..ae5b71e77 100644 --- a/library/DFProcess-windows-SHM.cpp +++ b/library/DFProcess-windows-SHM.cpp @@ -394,6 +394,11 @@ void SHMProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet) read(address + d->vector_start, sizeof(triplet), (uint8_t *) &triplet); } +void SHMProcess::writeSTLVector(const uint32_t address, t_vecTriplet & triplet) +{ + write(address + d->vector_start, sizeof(triplet), (uint8_t *) &triplet); +} + string SHMProcess::doReadClassName (uint32_t vptr) { int rtti = Process::readDWord(vptr - 0x4); diff --git a/library/DFProcess-windows.cpp b/library/DFProcess-windows.cpp index 10a5d1459..cb651e3af 100644 --- a/library/DFProcess-windows.cpp +++ b/library/DFProcess-windows.cpp @@ -85,6 +85,7 @@ namespace void write(uint32_t address, uint32_t length, uint8_t* buffer); void readSTLVector(const uint32_t address, t_vecTriplet & triplet); + void writeSTLVector(const uint32_t address, t_vecTriplet & triplet); const std::string readSTLString (uint32_t offset); size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); size_t writeSTLString(const uint32_t address, const std::string writeString); @@ -575,6 +576,11 @@ void NormalProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet read(address + vector_start, sizeof(triplet), (uint8_t *) &triplet); } +void NormalProcess::writeSTLVector(const uint32_t address, t_vecTriplet & triplet) +{ + write(address + vector_start, sizeof(triplet), (uint8_t *) &triplet); +} + size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) { return stl.readSTLString(offset, buffer, bufcapacity); diff --git a/library/include/dfhack/DFProcess.h b/library/include/dfhack/DFProcess.h index 32c24b554..9fddd8f18 100644 --- a/library/include/dfhack/DFProcess.h +++ b/library/include/dfhack/DFProcess.h @@ -182,6 +182,7 @@ namespace DFHack /// read a STL vector virtual void readSTLVector(const uint32_t address, t_vecTriplet & triplet) = 0; + virtual void writeSTLVector(const uint32_t address, t_vecTriplet & triplet) = 0; /// get class name of an object with rtti/type info virtual std::string doReadClassName(uint32_t vptr) = 0; diff --git a/library/include/dfhack/DFVector.h b/library/include/dfhack/DFVector.h index cbe32d8c9..b9e4d698e 100644 --- a/library/include/dfhack/DFVector.h +++ b/library/include/dfhack/DFVector.h @@ -31,18 +31,30 @@ distribution. #include "DFExport.h" #include "VersionInfo.h" #include "DFProcess.h" + +#include + namespace DFHack { template class DFHACK_EXPORT DfVector { private: + Process *_p; + uint32_t _address; t_vecTriplet t; uint32_t _size;// vector size T * data; // cached data + + bool isMetadataInSync() + { + t_vecTriplet t2; + _p->readSTLVector(_address,t2); + return (t2.start == t.start || t2.end == t.end || t2.alloc_end == t.alloc_end); + } public: - DfVector(Process * p, uint32_t address) + DfVector(Process *p, uint32_t address) : _p(p), _address(address) { p->readSTLVector(address,t); uint32_t byte_size = t.end - t.start; @@ -60,18 +72,43 @@ namespace DFHack delete [] data; }; // get offset of the specified index - inline T& operator[] (uint32_t index) + inline const T& operator[] (uint32_t index) { // FIXME: vector out of bounds exception //assert(index < size); return data[index]; }; // get offset of the specified index - inline T& at (uint32_t index) + inline const T& at (uint32_t index) { //assert(index < size); return data[index]; }; + // update value at index + bool set(uint32_t index, T value) + { + if (index >= _size) + return false; + data[index] = value; + _p->write(t.start + sizeof(T)*index, sizeof(T), (uint8_t *)&data[index]); + return true; + } + // remove value + bool remove(uint32_t index) + { + if (index >= _size || !isMetadataInSync()) + return false; + // Remove the item + _size--; + t.end -= sizeof(T); + int tail = (_size-index)*sizeof(T); + memmove(&data[index], &data[index+1], tail); + // Write back the data + if (tail) + _p->write(t.start + sizeof(T)*index, tail, (uint8_t *)&data[index]); + _p->writeSTLVector(_address,t); + return true; + } // get vector size inline uint32_t size () { diff --git a/library/private/SHMProcess.h b/library/private/SHMProcess.h index 560a259e5..7ff463189 100644 --- a/library/private/SHMProcess.h +++ b/library/private/SHMProcess.h @@ -73,6 +73,7 @@ namespace DFHack size_t writeSTLString(const uint32_t address, const std::string writeString); void readSTLVector(const uint32_t address, t_vecTriplet & triplet); + void writeSTLVector(const uint32_t address, t_vecTriplet & triplet); // get class name of an object with rtti/type info std::string doReadClassName(uint32_t vptr);