123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include "ResStringPool.h"
- char* to_char_string(const char* data, uint32_t length) {
- char* string = (char*) calloc(length + 1, 1);
- for (int i = 0; i < length; ++i) {
- string[i] = *(data + (i * 2));
- }
- return string;
- }
- void to_wide_string(const char* string, uint16_t* dest) {
- uint32_t len = strlen(string);
- for (int i = 0; i < len; ++i) {
- dest[i] = string[i];
- }
- dest[len] = 0;
- }
- ResStringPool::ResStringPool() :
- _size(0), _strings(nullptr) {
- }
- ResStringPool::ResStringPool(const char* data) {
- ResStringPool_header header;
- uint32_t* entries;
- memcpy(&header, data, sizeof(ResStringPool_header));
- if (header.header.type != RES_STRING_POOL_TYPE) {
- printf("Not a ResStringPool!\n");
- return;
- }
- printf("ResStringPool stringCount: %i\n", header.stringCount);
- printf("ResStringPool styleCount: %i\n", header.styleCount);
- printf("ResStringPool stringsStart: %i\n", header.stringsStart);
- printf("ResStringPool flags: 0x%08X\n", header.flags);
- _size = header.stringCount;
- entries = (uint32_t*) (data + header.header.headerSize);
- _strings = (const char**)malloc(_size * sizeof(const char*));
- const char *stringdata = data + header.stringsStart;
- for (int i = 0; i < _size; ++i) {
- uint32_t offset = entries[i];
- size_t size = *((const uint16_t*)(stringdata + offset));
- if ((size & 0x8000) != 0) {
- offset += 2;
- size = ((size & 0x7FFF) << 16) | *((const uint16_t*)(stringdata + offset));
- }
- offset += 2;
- _strings[i] = to_char_string(stringdata + offset, size);
- }
- }
- const char* ResStringPool::get(int32_t index) const {
- if (index < 0 || index >= _size) {
- return nullptr;
- }
- return _strings[index];
- }
- ResStringPool_ref ResStringPool::put(const char* string) {
- ResStringPool_ref ref;
- if (! string) {
- printf("Empty string request\n");
- ref.index = -1;
- return ref;
- }
- for (int i = 0; i < _size; ++i) {
- if (strcmp(string, _strings[i]) == 0) {
- printf("Found string '%s' already returning %i\n", string, i);
- ref.index = i;
- return ref;
- }
- }
- ++_size;
- _strings = (const char **)realloc(_strings, _size * sizeof(const char**));
- _strings[_size - 1] = strdup(string);
- ref.index = _size - 1;
- printf("Adding new string : '%s' as %i\n", string, ref.index);
- return ref;
- }
- void ResStringPool::put_empty() {
- printf("Putting empty string at %i\n", _size);
- ++_size;
- _strings = (const char **)realloc(_strings, _size * sizeof(const char**));
- _strings[_size - 1] = strdup("" );
- }
- uint32_t ResStringPool::serialize(char** data) {
- uint32_t datasize = sizeof(ResStringPool_header) + _size * sizeof(uint32_t);
- *data = (char*)malloc(datasize);
- uint32_t stringloc = 0;
- uint32_t stringsStart = datasize;
- for (int i = 0; i < _size; ++i) {
- uint32_t stringlen = strlen(_strings[i]);
- datasize += (stringlen * 2) + 4;
- *data = (char*)realloc(*data, datasize);
- uint16_t* stringdata = (uint16_t*)((char*)*data + stringsStart + stringloc);
-
- *stringdata = stringlen;
- to_wide_string(_strings[i], stringdata + 1);
- uint32_t* entries = (uint32_t*)((char*)*data + sizeof(ResStringPool_header));
- entries[i] = stringloc;
- stringloc += (stringlen * 2) + 4;
- }
- datasize = datasize + (datasize % 4);
- *data = (char*)realloc(*data, datasize);
- ResStringPool_header* header = (ResStringPool_header*)*data;
- header->stringCount = _size;
- header->stringsStart = stringsStart;
- header->flags = 0;
- header->styleCount = 0;
- header->stylesStart = 0;
- header->header.headerSize = sizeof(ResStringPool_header);
- header->header.type = RES_STRING_POOL_TYPE;
- header->header.size = datasize;
- return datasize;
- }
- void ResStringPool::dump() {
- for (int i = 0; i < _size; ++i) {
- printf("String %i: '%s'\n", i, _strings[i]);
- }
- }
- ResStringPool::~ResStringPool() {
- for (int i = 0; i < _size; ++i) {
- free((void*)_strings[i]);
- }
- free(_strings);
- }
|