diff options
| author | Alexander Gavrilov | 2012-03-17 12:52:22 +0400 |
|---|---|---|
| committer | Alexander Gavrilov | 2012-03-17 12:52:22 +0400 |
| commit | 58eb199036db3662ec2f7a2d6d301e7f432d5639 (patch) | |
| tree | c01d46ab4d403cd900ddbf6e0c31c22946c02a7c /library/DataDefs.cpp | |
| parent | 14d6a62e1d212808623f1a71b3c559ac4a8dada3 (diff) | |
| download | dfhack-58eb199036db3662ec2f7a2d6d301e7f432d5639.tar.gz dfhack-58eb199036db3662ec2f7a2d6d301e7f432d5639.tar.bz2 dfhack-58eb199036db3662ec2f7a2d6d301e7f432d5639.tar.xz | |
Add many new template functions for enums & bitfields.
An incompatible change: ENUM_KEY_STR returns std::string now.
The old behavior is available via enum_item_key_str function.
Diffstat (limited to 'library/DataDefs.cpp')
| -rw-r--r-- | library/DataDefs.cpp | 93 |
1 files changed, 64 insertions, 29 deletions
diff --git a/library/DataDefs.cpp b/library/DataDefs.cpp index 2396e03f..30a4da27 100644 --- a/library/DataDefs.cpp +++ b/library/DataDefs.cpp @@ -164,57 +164,92 @@ void virtual_identity::Init(Core *core) */ } -std::string DFHack::bitfieldToString(const void *p, int size, const bitfield_item_info *items) +bool DFHack::findBitfieldField(unsigned *idx, const std::string &name, + unsigned size, const bitfield_item_info *items) { - std::string res; - const char *data = (const char*)p; + for (unsigned i = 0; i < size; i++) { + if (items[i].name && items[i].name == name) + { + *idx = i; + return true; + } + } - for (int i = 0; i < size; i++) { - unsigned v; + return false; +} - if (items[i].size > 1) { - unsigned pdv = *(unsigned*)&data[i/8]; - v = (pdv >> (i%8)) & ((1 << items[i].size)-1); - } else { - v = (data[i/8]>>(i%8)) & 1; - } +void DFHack::setBitfieldField(void *p, unsigned idx, unsigned size, int value) +{ + uint8_t *data = ((uint8_t*)p) + (idx/8); + unsigned shift = idx%8; + uint32_t mask = ((1<<size)-1) << shift; + uint32_t vmask = ((value << shift) & mask); - if (v) { - if (!res.empty()) - res += ' '; +#define ACCESS(type) *(type*)data = type((*(type*)data & ~mask) | vmask) - if (items[i].name) - res += items[i].name; - else - res += stl_sprintf("UNK_%d", i); + if (!(mask & ~0xFFU)) ACCESS(uint8_t); + else if (!(mask & ~0xFFFFU)) ACCESS(uint16_t); + else ACCESS(uint32_t); + +#undef ACCESS +} + +int DFHack::getBitfieldField(const void *p, unsigned idx, unsigned size) +{ + const uint8_t *data = ((const uint8_t*)p) + (idx/8); + unsigned shift = idx%8; + uint32_t mask = ((1<<size)-1) << shift; + +#define ACCESS(type) return int((*(type*)data & mask) >> shift) + + if (!(mask & ~0xFFU)) ACCESS(uint8_t); + else if (!(mask & ~0xFFFFU)) ACCESS(uint16_t); + else ACCESS(uint32_t); + +#undef ACCESS +} + +void DFHack::bitfieldToString(std::vector<std::string> *pvec, const void *p, + unsigned size, const bitfield_item_info *items) +{ + for (unsigned i = 0; i < size; i++) { + int value = getBitfieldField(p, i, std::min(1,items[i].size)); + + if (value) { + std::string name = format_key(items[i].name, i); if (items[i].size > 1) - res += stl_sprintf("=%u", v); + name += stl_sprintf("=%u", value); + + pvec->push_back(name); } if (items[i].size > 1) i += items[i].size-1; } - - return res; } -int DFHack::findBitfieldField_(const std::string &name, int size, const bitfield_item_info *items) +int DFHack::findEnumItem(const std::string &name, int size, const char *const *items) { for (int i = 0; i < size; i++) { - if (items[i].name && items[i].name == name) + if (items[i] && items[i] == name) return i; } return -1; } -int DFHack::findEnumItem_(const std::string &name, int size, const char *const *items) +void DFHack::flagarrayToString(std::vector<std::string> *pvec, const void *p, + int bytes, int base, int size, const char *const *items) { - for (int i = 0; i < size; i++) { - if (items[i] && items[i] == name) - return i; + for (unsigned i = 0; i < bytes*8; i++) { + int value = getBitfieldField(p, i, 1); + + if (value) + { + int ridx = int(i) - base; + const char *name = (ridx >= 0 && ridx < size) ? items[ridx] : NULL; + pvec->push_back(format_key(name, i)); + } } - - return -1; } |
