blob: 1af5c0440cf4f32f55a93267d77cce930979845a [file] [log] [blame]
//===------- LockedMap.cpp - Implementation of the UTF8 map ---------------===//
//
// N3
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <map>
#include "Assembly.h"
#include "LockedMap.h"
#include "MSCorlib.h"
#include "N3.h"
#include "VMArray.h"
#include "VMClass.h"
#include <string.h>
using namespace n3;
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);
}
static uint32 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->at(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)));
}
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 = UTF8::acons(size, MSCorlib::arrayChar);
for (sint32 i = 0; i < size; i++) {
tmp->setAt(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 = 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 = UTF8::acons(size, MSCorlib::arrayChar);
memcpy(tmp->elements, buf, len * sizeof(uint16));
res = (const UTF8*)tmp;
map.insert(std::make_pair(key, res));
}
lock->unlock();
return res;
}