blob: e0e47b9af6e115d833bd248f4b372ee6f6dd3f65 [file] [log] [blame]
//===-- JavaString.cpp - Internal correspondance with Java Strings --------===//
//
// The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "JavaArray.h"
#include "JavaClass.h"
#include "JavaString.h"
#include "JavaThread.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"
namespace j3 {
JavaString* JavaString::create(const ArrayUInt16 * array, Jnjvm* vm) {
JavaString* res = 0;
llvm_gcroot(array, 0);
llvm_gcroot(res, 0);
UserClass* cl = vm->upcalls->newString;
res = (JavaString*)cl->doNew(vm);
// No need to call the Java function: both the Java function and
// this function do the same thing.
JavaString::setValue(res, array);
res->count = ArrayUInt16::getSize(array);
res->offset = 0;
res->cachedHashCode = 0;
return res;
}
char* JavaString::strToAsciiz(const JavaString* self) {
const ArrayUInt16* value = NULL;
llvm_gcroot(self, 0);
llvm_gcroot(value, 0);
value = JavaString::getValue(self);
char* buf = new char[self->count + 1];
for (sint32 i = 0; i < self->count; ++i) {
buf[i] = ArrayUInt16::getElement(value, i + self->offset);
}
buf[self->count] = 0;
return buf;
}
char* JavaString::strToAsciiz(const JavaString* self,
vmkit::ThreadAllocator* allocator) {
const ArrayUInt16* value = NULL;
llvm_gcroot(self, 0);
llvm_gcroot(value, 0);
value = JavaString::getValue(self);
char* buf = (char*)allocator->Allocate((self->count + 1) * sizeof(char));
for (sint32 i = 0; i < self->count; ++i) {
buf[i] = ArrayUInt16::getElement(value, i + self->offset);
}
buf[self->count] = 0;
return buf;
}
const ArrayUInt16* JavaString::strToArray(JavaString* self, Jnjvm* vm) {
ArrayUInt16* array = NULL;
const ArrayUInt16* value = NULL;
llvm_gcroot(self, 0);
llvm_gcroot(array, 0);
llvm_gcroot(value, 0);
value = JavaString::getValue(self);
assert(getValue(self) && "String without an array?");
if (self->offset || (self->count != ArrayUInt16::getSize(getValue(self)))) {
array = (ArrayUInt16*)vm->upcalls->ArrayOfChar->doNew(self->count, vm);
for (sint32 i = 0; i < self->count; i++) {
ArrayUInt16::setElement(
array, ArrayUInt16::getElement(value, i + self->offset), i);
}
return array;
} else {
return value;
}
}
JavaString* JavaString::internalToJava(const UTF8* name, Jnjvm* vm) {
ArrayUInt16* array = 0;
llvm_gcroot(array, 0);
array = (ArrayUInt16*)vm->upcalls->ArrayOfChar->doNew(name->size, vm);
for (sint32 i = 0; i < name->size; i++) {
uint16 cur = name->elements[i];
if (cur == '/') {
ArrayUInt16::setElement(array, '.', i);
} else {
ArrayUInt16::setElement(array, cur, i);
}
}
return vm->constructString(array);
}
const UTF8* JavaString::javaToInternal(const JavaString* self, UTF8Map* map) {
const ArrayUInt16* value = NULL;
llvm_gcroot(self, 0);
llvm_gcroot(value, 0);
value = JavaString::getValue(self);
vmkit::ThreadAllocator allocator;
uint16* java = (uint16*)allocator.Allocate(self->count * sizeof(uint16));
for (sint32 i = 0; i < self->count; ++i) {
uint16 cur = ArrayUInt16::getElement(value, self->offset + i);
if (cur == '.') java[i] = '/';
else java[i] = cur;
}
const UTF8* res = map->lookupOrCreateReader(java, self->count);
return res;
}
}