blob: f4075c64c885abcb3e69015e3d3d4ab305d263dd [file] [log] [blame]
#include "mvm/UTF8.h"
#include "mvm/PrintBuffer.h"
using namespace mvm;
void UTF8::print(PrintBuffer *pb) const {
pb->writeUTF8(this);
}
const UTF8* UTF8::extract(UTF8Map* map, uint32 start, uint32 end) const {
uint32 len = end - start;
uint16* buf = (uint16*)alloca(sizeof(uint16) * len);
for (uint32 i = 0; i < len; i++) {
buf[i] = elements[i + start];
}
return map->lookupOrCreateReader(buf, len);
}
static uint32 asciizHasher(const char* asciiz, sint32 size) {
uint32 r0 = 0, r1 = 0;
for (sint32 i = 0; i < size; i++) {
char c = asciiz[i];
r0 += c;
r1 ^= c;
}
return (r1 & 255) + ((r0 & 255) << 8);
}
uint32 UTF8::readerHasher(const uint16* buf, sint32 size) {
uint32 r0 = 0, r1 = 0;
for (sint32 i = 0; i < size; i++) {
uint16 c = buf[i];
r0 += c;
r1 ^= c;
}
return (r1 & 255) + ((r0 & 255) << 8);
}
static bool asciizEqual(const UTF8* val, const char* asciiz, sint32 size) {
sint32 len = val->size;
if (len != size) return false;
else {
for (sint32 i = 0; i < len; i++) {
if (asciiz[i] != val->elements[i]) return false;
}
return true;
}
}
static bool readerEqual(const UTF8* val, const uint16* buf, sint32 size) {
sint32 len = val->size;
if (len != size) return false;
else return !(memcmp(val->elements, buf, len * sizeof(uint16)));
}
void UTF8Map::replace(const UTF8* oldUTF8, const UTF8* newUTF8) {
lock.lock();
uint32 key = oldUTF8->hash();
std::pair<UTF8Map::iterator, UTF8Map::iterator> p = map.equal_range(key);
for (UTF8Map::iterator i = p.first; i != p.second; i++) {
if (i->second == oldUTF8) {
map.erase(i);
break;
}
}
map.insert(std::make_pair(key, newUTF8));
lock.unlock();
}
const UTF8* UTF8Map::lookupOrCreateAsciiz(const char* asciiz) {
sint32 size = strlen(asciiz);
uint32 key = asciizHasher(asciiz, size);
const UTF8* res = 0;
lock.lock();
std::pair<UTF8Map::iterator, UTF8Map::iterator> p = map.equal_range(key);
for (UTF8Map::iterator i = p.first; i != p.second; i++) {
if (asciizEqual(i->second, asciiz, size)) {
res = i->second;
break;
}
}
if (res == 0) {
UTF8* tmp = new(allocator, size) UTF8(size);
for (sint32 i = 0; i < size; i++) {
tmp->elements[i] = asciiz[i];
}
res = (const UTF8*)tmp;
map.insert(std::make_pair(key, res));
}
lock.unlock();
return res;
}
const UTF8* UTF8Map::lookupOrCreateReader(const uint16* buf, uint32 len) {
sint32 size = (sint32)len;
uint32 key = UTF8::readerHasher(buf, size);
const UTF8* res = 0;
lock.lock();
std::pair<UTF8Map::iterator, UTF8Map::iterator> p = map.equal_range(key);
for (UTF8Map::iterator i = p.first; i != p.second; i++) {
if (readerEqual(i->second, buf, size)) {
res = i->second;
break;
}
}
if (res == 0) {
UTF8* tmp = new(allocator, size) UTF8(size);
memcpy(tmp->elements, buf, len * sizeof(uint16));
res = (const UTF8*)tmp;
map.insert(std::make_pair(key, res));
}
lock.unlock();
return res;
}
const UTF8* UTF8Map::lookupAsciiz(const char* asciiz) {
sint32 size = strlen(asciiz);
uint32 key = asciizHasher(asciiz, size);
const UTF8* res = 0;
lock.lock();
std::pair<UTF8Map::iterator, UTF8Map::iterator> p = map.equal_range(key);
for (UTF8Map::iterator i = p.first; i != p.second; i++) {
if (asciizEqual(i->second, asciiz, size)) {
res = i->second;
break;
}
}
lock.unlock();
return res;
}
const UTF8* UTF8Map::lookupReader(const uint16* buf, uint32 len) {
sint32 size = (sint32)len;
uint32 key = UTF8::readerHasher(buf, size);
const UTF8* res = 0;
lock.lock();
std::pair<UTF8Map::iterator, UTF8Map::iterator> p = map.equal_range(key);
for (UTF8Map::iterator i = p.first; i != p.second; i++) {
if (readerEqual(i->second, buf, size)) {
res = i->second;
break;
}
}
lock.unlock();
return res;
}
void UTF8Map::insert(const UTF8* val) {
map.insert(std::make_pair(val->hash(), val));
}