#include <c_instance.h>
#include <c_utility.h>
#include <internal.h>
#include <npruntime_impl.h>
#include <npruntime_priv.h>
#include <runtime.h>
#include <runtime_object.h>
#include <runtime_root.h>
#include <value.h>
#include <NP_jsobject.h>
using namespace KJS;
using namespace KJS::Bindings;
void convertNPStringToUTF16 (const NPString *string, NPUTF16 **UTF16Chars, unsigned int *UTF16Length)
{
convertUTF8ToUTF16 (string->UTF8Characters, string->UTF8Length, UTF16Chars, UTF16Length);
}
void convertUTF8ToUTF16 (const NPUTF8 *UTF8Chars, int UTF8Length, NPUTF16 **UTF16Chars, unsigned int *UTF16Length)
{
assert (UTF8Chars);
if (UTF8Length == -1)
UTF8Length = strlen(UTF8Chars);
CFStringRef stringRef = CFStringCreateWithBytes (NULL, (const UInt8*)UTF8Chars, (CFIndex)UTF8Length, kCFStringEncodingUTF8, false);
*UTF16Length = (unsigned int)CFStringGetLength (stringRef);
*UTF16Chars = (NPUTF16 *)malloc (sizeof(NPUTF16) * (*UTF16Length));
CFRange range = { 0, *UTF16Length };
CFStringGetCharacters (stringRef, range, (UniChar *)*UTF16Chars);
CFRelease (stringRef);
}
void coerceValueToNPVariantStringType (KJS::ExecState *exec, const KJS::Value &value, NPVariant *result)
{
UString ustring = value.toString(exec);
CString cstring = ustring.UTF8String();
NPString string = { (const NPUTF8 *)cstring.c_str(), cstring.size() };
NPN_InitializeVariantWithStringCopy (result, &string);
}
void convertValueToNPVariant (KJS::ExecState *exec, const KJS::Value &value, NPVariant *result)
{
Type type = value.type();
if (type == StringType) {
UString ustring = value.toString(exec);
CString cstring = ustring.UTF8String();
NPString string = { (const NPUTF8 *)cstring.c_str(), cstring.size() };
NPN_InitializeVariantWithStringCopy (result, &string );
}
else if (type == NumberType) {
NPN_InitializeVariantWithDouble (result, value.toNumber(exec));
}
else if (type == BooleanType) {
NPN_InitializeVariantWithBool (result, value.toBoolean(exec));
}
else if (type == UnspecifiedType) {
NPN_InitializeVariantAsUndefined(result);
}
else if (type == NullType) {
NPN_InitializeVariantAsNull(result);
}
else if (type == ObjectType) {
KJS::ObjectImp *objectImp = static_cast<KJS::ObjectImp*>(value.imp());
if (objectImp->classInfo() == &KJS::RuntimeObjectImp::info) {
KJS::RuntimeObjectImp *imp = static_cast<KJS::RuntimeObjectImp *>(value.imp());
CInstance *instance = static_cast<CInstance*>(imp->getInternalInstance());
NPN_InitializeVariantWithObject (result, instance->getObject());
}
else {
KJS::Interpreter *originInterpreter = exec->interpreter();
const Bindings::RootObject *originExecutionContext = rootForInterpreter(originInterpreter);
KJS::Interpreter *interpreter = 0;
if (originInterpreter->isGlobalObject(value)) {
interpreter = originInterpreter->interpreterForGlobalObject (value.imp());
}
if (!interpreter)
interpreter = originInterpreter;
const Bindings::RootObject *executionContext = rootForInterpreter(interpreter);
if (!executionContext) {
Bindings::RootObject *newExecutionContext = new KJS::Bindings::RootObject(0);
newExecutionContext->setInterpreter (interpreter);
executionContext = newExecutionContext;
}
NPObject *obj = (NPObject *)exec->interpreter()->createLanguageInstanceForValue (exec, Instance::CLanguage, value.toObject(exec), originExecutionContext, executionContext);
NPN_InitializeVariantWithObject (result, obj);
_NPN_ReleaseObject (obj);
}
}
else
NPN_InitializeVariantAsUndefined(result);
}
Value convertNPVariantToValue (KJS::ExecState *exec, const NPVariant *variant)
{
NPVariantType type = variant->type;
if (type == NPVariantType_Bool) {
NPBool aBool;
if (NPN_VariantToBool (variant, &aBool))
return KJS::Boolean (aBool);
return KJS::Boolean (false);
}
else if (type == NPVariantType_Null) {
return Null();
}
else if (type == NPVariantType_Void) {
return Undefined();
}
else if (type == NPVariantType_Int32) {
int32_t anInt;
if (NPN_VariantToInt32 (variant, &anInt))
return Number (anInt);
return Number (0);
}
else if (type == NPVariantType_Double) {
double aDouble;
if (NPN_VariantToDouble (variant, &aDouble))
return Number (aDouble);
return Number (0);
}
else if (type == NPVariantType_String) {
NPUTF16 *stringValue;
unsigned int UTF16Length;
convertNPStringToUTF16 (&variant->value.stringValue, &stringValue, &UTF16Length); String resultString(UString((const UChar *)stringValue,UTF16Length));
free (stringValue);
return resultString;
}
else if (type == NPVariantType_Object) {
NPObject *obj = variant->value.objectValue;
if (obj->_class == NPScriptObjectClass) {
JavaScriptObject *o = (JavaScriptObject *)obj;
return Object(const_cast<ObjectImp*>(o->imp));
}
else {
return Instance::createRuntimeObject(Instance::CLanguage, (void *)obj);
}
}
return Undefined();
}