mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 780108 - Get rid of the double switch in XPCConvert::JSData2Native; r=bholley
This commit is contained in:
parent
cc3b2a1e47
commit
2b7b31e7c2
@ -1,4 +1,4 @@
|
|||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
* vim: set ts=8 sw=4 et tw=78:
|
* vim: set ts=8 sw=4 et tw=78:
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
@ -430,365 +430,361 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s,
|
|||||||
*((bool*)d) = tb;
|
*((bool*)d) = tb;
|
||||||
break;
|
break;
|
||||||
case nsXPTType::T_CHAR :
|
case nsXPTType::T_CHAR :
|
||||||
{
|
{
|
||||||
JSString* str = JS_ValueToString(cx, s);
|
JSString* str = JS_ValueToString(cx, s);
|
||||||
if (!str) {
|
if (!str) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
size_t length;
|
size_t length;
|
||||||
const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
|
const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
|
||||||
if (!chars) {
|
if (!chars) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
jschar ch = length ? chars[0] : 0;
|
jschar ch = length ? chars[0] : 0;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
CheckJSCharInCharRange(ch);
|
CheckJSCharInCharRange(ch);
|
||||||
#endif
|
#endif
|
||||||
*((char*)d) = char(ch);
|
*((char*)d) = char(ch);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case nsXPTType::T_WCHAR :
|
case nsXPTType::T_WCHAR :
|
||||||
{
|
{
|
||||||
JSString* str;
|
JSString* str;
|
||||||
if (!(str = JS_ValueToString(cx, s))) {
|
if (!(str = JS_ValueToString(cx, s))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
size_t length;
|
size_t length;
|
||||||
const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
|
const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
|
||||||
if (!chars) {
|
if (!chars) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
*((uint16_t*)d) = 0;
|
*((uint16_t*)d) = 0;
|
||||||
break;
|
|
||||||
}
|
|
||||||
*((uint16_t*)d) = uint16_t(chars[0]);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
*((uint16_t*)d) = uint16_t(chars[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case nsXPTType::T_JSVAL :
|
case nsXPTType::T_JSVAL :
|
||||||
*((jsval*)d) = s;
|
*((jsval*)d) = s;
|
||||||
break;
|
break;
|
||||||
default:
|
case nsXPTType::T_VOID:
|
||||||
|
XPC_LOG_ERROR(("XPCConvert::JSData2Native : void* params not supported"));
|
||||||
|
NS_ERROR("void* params not supported");
|
||||||
|
return false;
|
||||||
|
case nsXPTType::T_IID:
|
||||||
|
{
|
||||||
|
const nsID* pid = nullptr;
|
||||||
|
|
||||||
switch (type.TagPart()) {
|
// There's no good reason to pass a null IID.
|
||||||
case nsXPTType::T_VOID:
|
if (s.isNullOrUndefined()) {
|
||||||
XPC_LOG_ERROR(("XPCConvert::JSData2Native : void* params not supported"));
|
if (pErr)
|
||||||
NS_ERROR("void* params not supported");
|
*pErr = NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||||
return false;
|
return false;
|
||||||
case nsXPTType::T_IID:
|
|
||||||
{
|
|
||||||
const nsID* pid = nullptr;
|
|
||||||
|
|
||||||
// There's no good reason to pass a null IID.
|
|
||||||
if (s.isNullOrUndefined()) {
|
|
||||||
if (pErr)
|
|
||||||
*pErr = NS_ERROR_XPC_BAD_CONVERT_JS;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!s.isObject() ||
|
|
||||||
(!(pid = xpc_JSObjectToID(cx, &s.toObject()))) ||
|
|
||||||
(!(pid = (const nsID*) nsMemory::Clone(pid, sizeof(nsID))))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*((const nsID**)d) = pid;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case nsXPTType::T_ASTRING:
|
if (!s.isObject() ||
|
||||||
{
|
(!(pid = xpc_JSObjectToID(cx, &s.toObject()))) ||
|
||||||
isDOMString = false;
|
(!(pid = (const nsID*) nsMemory::Clone(pid, sizeof(nsID))))) {
|
||||||
// Fall through to T_DOMSTRING case.
|
return false;
|
||||||
}
|
}
|
||||||
case nsXPTType::T_DOMSTRING:
|
*((const nsID**)d) = pid;
|
||||||
{
|
return true;
|
||||||
static const PRUnichar EMPTY_STRING[] = { '\0' };
|
}
|
||||||
static const PRUnichar VOID_STRING[] = { 'u', 'n', 'd', 'e', 'f', 'i', 'n', 'e', 'd', '\0' };
|
|
||||||
|
|
||||||
const PRUnichar* chars = nullptr;
|
case nsXPTType::T_ASTRING:
|
||||||
JSString* str = nullptr;
|
{
|
||||||
JSBool isNewString = false;
|
isDOMString = false;
|
||||||
PRUint32 length = 0;
|
// Fall through to T_DOMSTRING case.
|
||||||
|
}
|
||||||
|
case nsXPTType::T_DOMSTRING:
|
||||||
|
{
|
||||||
|
static const PRUnichar EMPTY_STRING[] = { '\0' };
|
||||||
|
static const PRUnichar VOID_STRING[] = { 'u', 'n', 'd', 'e', 'f', 'i', 'n', 'e', 'd', '\0' };
|
||||||
|
|
||||||
if (JSVAL_IS_VOID(s)) {
|
const PRUnichar* chars = nullptr;
|
||||||
if (isDOMString) {
|
JSString* str = nullptr;
|
||||||
chars = VOID_STRING;
|
JSBool isNewString = false;
|
||||||
length = ArrayLength(VOID_STRING) - 1;
|
PRUint32 length = 0;
|
||||||
} else {
|
|
||||||
chars = EMPTY_STRING;
|
if (JSVAL_IS_VOID(s)) {
|
||||||
length = 0;
|
if (isDOMString) {
|
||||||
}
|
chars = VOID_STRING;
|
||||||
} else if (!JSVAL_IS_NULL(s)) {
|
length = ArrayLength(VOID_STRING) - 1;
|
||||||
str = JS_ValueToString(cx, s);
|
} else {
|
||||||
if (!str)
|
chars = EMPTY_STRING;
|
||||||
|
length = 0;
|
||||||
|
}
|
||||||
|
} else if (!JSVAL_IS_NULL(s)) {
|
||||||
|
str = JS_ValueToString(cx, s);
|
||||||
|
if (!str)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
length = (PRUint32) JS_GetStringLength(str);
|
||||||
|
if (length) {
|
||||||
|
chars = JS_GetStringCharsZ(cx, str);
|
||||||
|
if (!chars)
|
||||||
|
return false;
|
||||||
|
if (STRING_TO_JSVAL(str) != s)
|
||||||
|
isNewString = true;
|
||||||
|
} else {
|
||||||
|
str = nullptr;
|
||||||
|
chars = EMPTY_STRING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useAllocator) {
|
||||||
|
// XXX extra string copy when isNewString
|
||||||
|
if (str && !isNewString) {
|
||||||
|
size_t strLength;
|
||||||
|
const jschar *strChars = JS_GetStringCharsZAndLength(cx, str, &strLength);
|
||||||
|
if (!strChars)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
length = (PRUint32) JS_GetStringLength(str);
|
XPCReadableJSStringWrapper *wrapper =
|
||||||
if (length) {
|
ccx.NewStringWrapper(strChars, strLength);
|
||||||
chars = JS_GetStringCharsZ(cx, str);
|
if (!wrapper)
|
||||||
if (!chars)
|
return false;
|
||||||
return false;
|
|
||||||
if (STRING_TO_JSVAL(str) != s)
|
|
||||||
isNewString = true;
|
|
||||||
} else {
|
|
||||||
str = nullptr;
|
|
||||||
chars = EMPTY_STRING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useAllocator) {
|
*((const nsAString**)d) = wrapper;
|
||||||
// XXX extra string copy when isNewString
|
} else if (JSVAL_IS_NULL(s)) {
|
||||||
if (str && !isNewString) {
|
XPCReadableJSStringWrapper *wrapper =
|
||||||
size_t strLength;
|
new XPCReadableJSStringWrapper();
|
||||||
const jschar *strChars = JS_GetStringCharsZAndLength(cx, str, &strLength);
|
if (!wrapper)
|
||||||
if (!strChars)
|
return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
XPCReadableJSStringWrapper *wrapper =
|
*((const nsAString**)d) = wrapper;
|
||||||
ccx.NewStringWrapper(strChars, strLength);
|
|
||||||
if (!wrapper)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*((const nsAString**)d) = wrapper;
|
|
||||||
} else if (JSVAL_IS_NULL(s)) {
|
|
||||||
XPCReadableJSStringWrapper *wrapper =
|
|
||||||
new XPCReadableJSStringWrapper();
|
|
||||||
if (!wrapper)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*((const nsAString**)d) = wrapper;
|
|
||||||
} else {
|
|
||||||
// use nsString to encourage sharing
|
|
||||||
const nsAString *rs = new nsString(chars, length);
|
|
||||||
if (!rs)
|
|
||||||
return false;
|
|
||||||
*((const nsAString**)d) = rs;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
nsAString* ws = *((nsAString**)d);
|
// use nsString to encourage sharing
|
||||||
|
const nsAString *rs = new nsString(chars, length);
|
||||||
if (JSVAL_IS_NULL(s) || (!isDOMString && JSVAL_IS_VOID(s))) {
|
if (!rs)
|
||||||
ws->Truncate();
|
return false;
|
||||||
ws->SetIsVoid(true);
|
*((const nsAString**)d) = rs;
|
||||||
} else
|
|
||||||
ws->Assign(chars, length);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
nsAString* ws = *((nsAString**)d);
|
||||||
|
|
||||||
|
if (JSVAL_IS_NULL(s) || (!isDOMString && JSVAL_IS_VOID(s))) {
|
||||||
|
ws->Truncate();
|
||||||
|
ws->SetIsVoid(true);
|
||||||
|
} else
|
||||||
|
ws->Assign(chars, length);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case nsXPTType::T_CHAR_STR:
|
||||||
|
{
|
||||||
|
if (JSVAL_IS_VOID(s) || JSVAL_IS_NULL(s)) {
|
||||||
|
*((char**)d) = nullptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case nsXPTType::T_CHAR_STR:
|
JSString* str = JS_ValueToString(cx, s);
|
||||||
{
|
if (!str) {
|
||||||
if (JSVAL_IS_VOID(s) || JSVAL_IS_NULL(s)) {
|
return false;
|
||||||
*((char**)d) = nullptr;
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSString* str = JS_ValueToString(cx, s);
|
|
||||||
if (!str) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
const jschar* chars=nullptr;
|
const jschar* chars=nullptr;
|
||||||
if (nullptr != (chars = JS_GetStringCharsZ(cx, str))) {
|
if (nullptr != (chars = JS_GetStringCharsZ(cx, str))) {
|
||||||
bool legalRange = true;
|
bool legalRange = true;
|
||||||
int len = JS_GetStringLength(str);
|
|
||||||
const jschar* t;
|
|
||||||
PRInt32 i=0;
|
|
||||||
for (t=chars; (i< len) && legalRange ; i++,t++) {
|
|
||||||
if (!CheckJSCharInCharRange(*t))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // DEBUG
|
|
||||||
size_t length = JS_GetStringEncodingLength(cx, str);
|
|
||||||
if (length == size_t(-1)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
char *buffer = static_cast<char *>(nsMemory::Alloc(length + 1));
|
|
||||||
if (!buffer) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
JS_EncodeStringToBuffer(str, buffer, length);
|
|
||||||
buffer[length] = '\0';
|
|
||||||
*((void**)d) = buffer;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case nsXPTType::T_WCHAR_STR:
|
|
||||||
{
|
|
||||||
const jschar* chars=nullptr;
|
|
||||||
JSString* str;
|
|
||||||
|
|
||||||
if (JSVAL_IS_VOID(s) || JSVAL_IS_NULL(s)) {
|
|
||||||
*((jschar**)d) = nullptr;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(str = JS_ValueToString(cx, s))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(chars = JS_GetStringCharsZ(cx, str))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int len = JS_GetStringLength(str);
|
int len = JS_GetStringLength(str);
|
||||||
int byte_len = (len+1)*sizeof(jschar);
|
const jschar* t;
|
||||||
if (!(*((void**)d) = nsMemory::Alloc(byte_len))) {
|
PRInt32 i=0;
|
||||||
// XXX should report error
|
for (t=chars; (i< len) && legalRange ; i++,t++) {
|
||||||
return false;
|
if (!CheckJSCharInCharRange(*t))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
jschar* destchars = *((jschar**)d);
|
|
||||||
memcpy(destchars, chars, byte_len);
|
|
||||||
destchars[len] = 0;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
#endif // DEBUG
|
||||||
case nsXPTType::T_UTF8STRING:
|
size_t length = JS_GetStringEncodingLength(cx, str);
|
||||||
{
|
if (length == size_t(-1)) {
|
||||||
const jschar* chars;
|
|
||||||
PRUint32 length;
|
|
||||||
JSString* str;
|
|
||||||
|
|
||||||
if (JSVAL_IS_NULL(s) || JSVAL_IS_VOID(s)) {
|
|
||||||
if (useAllocator) {
|
|
||||||
nsACString *rs = new nsCString();
|
|
||||||
if (!rs)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
rs->SetIsVoid(true);
|
|
||||||
*((nsACString**)d) = rs;
|
|
||||||
} else {
|
|
||||||
nsCString* rs = *((nsCString**)d);
|
|
||||||
rs->Truncate();
|
|
||||||
rs->SetIsVoid(true);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The JS val is neither null nor void...
|
|
||||||
|
|
||||||
if (!(str = JS_ValueToString(cx, s))||
|
|
||||||
!(chars = JS_GetStringCharsZ(cx, str))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
length = JS_GetStringLength(str);
|
|
||||||
|
|
||||||
nsCString *rs;
|
|
||||||
if (useAllocator) {
|
|
||||||
// Use nsCString to enable sharing
|
|
||||||
rs = new nsCString();
|
|
||||||
if (!rs)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*((const nsCString**)d) = rs;
|
|
||||||
} else {
|
|
||||||
rs = *((nsCString**)d);
|
|
||||||
}
|
|
||||||
const PRUnichar* start = (const PRUnichar*)chars;
|
|
||||||
const PRUnichar* end = start + length;
|
|
||||||
CopyUTF16toUTF8(nsDependentSubstring(start, end), *rs);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case nsXPTType::T_CSTRING:
|
|
||||||
{
|
|
||||||
if (JSVAL_IS_NULL(s) || JSVAL_IS_VOID(s)) {
|
|
||||||
if (useAllocator) {
|
|
||||||
nsACString *rs = new nsCString();
|
|
||||||
if (!rs)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
rs->SetIsVoid(true);
|
|
||||||
*((nsACString**)d) = rs;
|
|
||||||
} else {
|
|
||||||
nsACString* rs = *((nsACString**)d);
|
|
||||||
rs->Truncate();
|
|
||||||
rs->SetIsVoid(true);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The JS val is neither null nor void...
|
|
||||||
JSString* str = JS_ValueToString(cx, s);
|
|
||||||
if (!str) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t length = JS_GetStringEncodingLength(cx, str);
|
|
||||||
if (length == size_t(-1)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsACString *rs;
|
|
||||||
if (useAllocator) {
|
|
||||||
rs = new nsCString();
|
|
||||||
if (!rs)
|
|
||||||
return false;
|
|
||||||
*((const nsACString**)d) = rs;
|
|
||||||
} else {
|
|
||||||
rs = *((nsACString**)d);
|
|
||||||
}
|
|
||||||
|
|
||||||
rs->SetLength(PRUint32(length));
|
|
||||||
if (rs->Length() != PRUint32(length)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
JS_EncodeStringToBuffer(str, rs->BeginWriting(), length);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case nsXPTType::T_INTERFACE:
|
|
||||||
case nsXPTType::T_INTERFACE_IS:
|
|
||||||
{
|
|
||||||
NS_ASSERTION(iid,"can't do interface conversions without iid");
|
|
||||||
|
|
||||||
if (iid->Equals(NS_GET_IID(nsIVariant))) {
|
|
||||||
XPCVariant* variant = XPCVariant::newVariant(ccx, s);
|
|
||||||
if (!variant)
|
|
||||||
return false;
|
|
||||||
*((nsISupports**)d) = static_cast<nsIVariant*>(variant);
|
|
||||||
return true;
|
|
||||||
} else if (iid->Equals(NS_GET_IID(nsIAtom)) &&
|
|
||||||
JSVAL_IS_STRING(s)) {
|
|
||||||
// We're trying to pass a string as an nsIAtom. Let's atomize!
|
|
||||||
JSString* str = JSVAL_TO_STRING(s);
|
|
||||||
const PRUnichar* chars = JS_GetStringCharsZ(cx, str);
|
|
||||||
if (!chars) {
|
|
||||||
if (pErr)
|
|
||||||
*pErr = NS_ERROR_XPC_BAD_CONVERT_JS_NULL_REF;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
PRUint32 length = JS_GetStringLength(str);
|
|
||||||
nsIAtom* atom = NS_NewAtom(nsDependentSubstring(chars,
|
|
||||||
chars + length));
|
|
||||||
if (!atom && pErr)
|
|
||||||
*pErr = NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
*((nsISupports**)d) = atom;
|
|
||||||
return atom != nullptr;
|
|
||||||
}
|
|
||||||
//else ...
|
|
||||||
|
|
||||||
if (s.isNullOrUndefined()) {
|
|
||||||
*((nsISupports**)d) = nullptr;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// only wrap JSObjects
|
|
||||||
if (!s.isObject()) {
|
|
||||||
if (pErr && s.isInt32() && 0 == s.toInt32())
|
|
||||||
*pErr = NS_ERROR_XPC_BAD_CONVERT_JS_ZERO_ISNOT_NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JSObject2NativeInterface(ccx, (void**)d, &s.toObject(), iid,
|
|
||||||
nullptr, pErr);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
NS_ERROR("bad type");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
char *buffer = static_cast<char *>(nsMemory::Alloc(length + 1));
|
||||||
|
if (!buffer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
JS_EncodeStringToBuffer(str, buffer, length);
|
||||||
|
buffer[length] = '\0';
|
||||||
|
*((void**)d) = buffer;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case nsXPTType::T_WCHAR_STR:
|
||||||
|
{
|
||||||
|
const jschar* chars=nullptr;
|
||||||
|
JSString* str;
|
||||||
|
|
||||||
|
if (JSVAL_IS_VOID(s) || JSVAL_IS_NULL(s)) {
|
||||||
|
*((jschar**)d) = nullptr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(str = JS_ValueToString(cx, s))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(chars = JS_GetStringCharsZ(cx, str))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int len = JS_GetStringLength(str);
|
||||||
|
int byte_len = (len+1)*sizeof(jschar);
|
||||||
|
if (!(*((void**)d) = nsMemory::Alloc(byte_len))) {
|
||||||
|
// XXX should report error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
jschar* destchars = *((jschar**)d);
|
||||||
|
memcpy(destchars, chars, byte_len);
|
||||||
|
destchars[len] = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case nsXPTType::T_UTF8STRING:
|
||||||
|
{
|
||||||
|
const jschar* chars;
|
||||||
|
PRUint32 length;
|
||||||
|
JSString* str;
|
||||||
|
|
||||||
|
if (JSVAL_IS_NULL(s) || JSVAL_IS_VOID(s)) {
|
||||||
|
if (useAllocator) {
|
||||||
|
nsACString *rs = new nsCString();
|
||||||
|
if (!rs)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
rs->SetIsVoid(true);
|
||||||
|
*((nsACString**)d) = rs;
|
||||||
|
} else {
|
||||||
|
nsCString* rs = *((nsCString**)d);
|
||||||
|
rs->Truncate();
|
||||||
|
rs->SetIsVoid(true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The JS val is neither null nor void...
|
||||||
|
|
||||||
|
if (!(str = JS_ValueToString(cx, s))||
|
||||||
|
!(chars = JS_GetStringCharsZ(cx, str))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
length = JS_GetStringLength(str);
|
||||||
|
|
||||||
|
nsCString *rs;
|
||||||
|
if (useAllocator) {
|
||||||
|
// Use nsCString to enable sharing
|
||||||
|
rs = new nsCString();
|
||||||
|
if (!rs)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*((const nsCString**)d) = rs;
|
||||||
|
} else {
|
||||||
|
rs = *((nsCString**)d);
|
||||||
|
}
|
||||||
|
const PRUnichar* start = (const PRUnichar*)chars;
|
||||||
|
const PRUnichar* end = start + length;
|
||||||
|
CopyUTF16toUTF8(nsDependentSubstring(start, end), *rs);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case nsXPTType::T_CSTRING:
|
||||||
|
{
|
||||||
|
if (JSVAL_IS_NULL(s) || JSVAL_IS_VOID(s)) {
|
||||||
|
if (useAllocator) {
|
||||||
|
nsACString *rs = new nsCString();
|
||||||
|
if (!rs)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
rs->SetIsVoid(true);
|
||||||
|
*((nsACString**)d) = rs;
|
||||||
|
} else {
|
||||||
|
nsACString* rs = *((nsACString**)d);
|
||||||
|
rs->Truncate();
|
||||||
|
rs->SetIsVoid(true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The JS val is neither null nor void...
|
||||||
|
JSString* str = JS_ValueToString(cx, s);
|
||||||
|
if (!str) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t length = JS_GetStringEncodingLength(cx, str);
|
||||||
|
if (length == size_t(-1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsACString *rs;
|
||||||
|
if (useAllocator) {
|
||||||
|
rs = new nsCString();
|
||||||
|
if (!rs)
|
||||||
|
return false;
|
||||||
|
*((const nsACString**)d) = rs;
|
||||||
|
} else {
|
||||||
|
rs = *((nsACString**)d);
|
||||||
|
}
|
||||||
|
|
||||||
|
rs->SetLength(PRUint32(length));
|
||||||
|
if (rs->Length() != PRUint32(length)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
JS_EncodeStringToBuffer(str, rs->BeginWriting(), length);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case nsXPTType::T_INTERFACE:
|
||||||
|
case nsXPTType::T_INTERFACE_IS:
|
||||||
|
{
|
||||||
|
NS_ASSERTION(iid,"can't do interface conversions without iid");
|
||||||
|
|
||||||
|
if (iid->Equals(NS_GET_IID(nsIVariant))) {
|
||||||
|
XPCVariant* variant = XPCVariant::newVariant(ccx, s);
|
||||||
|
if (!variant)
|
||||||
|
return false;
|
||||||
|
*((nsISupports**)d) = static_cast<nsIVariant*>(variant);
|
||||||
|
return true;
|
||||||
|
} else if (iid->Equals(NS_GET_IID(nsIAtom)) &&
|
||||||
|
JSVAL_IS_STRING(s)) {
|
||||||
|
// We're trying to pass a string as an nsIAtom. Let's atomize!
|
||||||
|
JSString* str = JSVAL_TO_STRING(s);
|
||||||
|
const PRUnichar* chars = JS_GetStringCharsZ(cx, str);
|
||||||
|
if (!chars) {
|
||||||
|
if (pErr)
|
||||||
|
*pErr = NS_ERROR_XPC_BAD_CONVERT_JS_NULL_REF;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PRUint32 length = JS_GetStringLength(str);
|
||||||
|
nsIAtom* atom = NS_NewAtom(nsDependentSubstring(chars,
|
||||||
|
chars + length));
|
||||||
|
if (!atom && pErr)
|
||||||
|
*pErr = NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
*((nsISupports**)d) = atom;
|
||||||
|
return atom != nullptr;
|
||||||
|
}
|
||||||
|
//else ...
|
||||||
|
|
||||||
|
if (s.isNullOrUndefined()) {
|
||||||
|
*((nsISupports**)d) = nullptr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// only wrap JSObjects
|
||||||
|
if (!s.isObject()) {
|
||||||
|
if (pErr && s.isInt32() && 0 == s.toInt32())
|
||||||
|
*pErr = NS_ERROR_XPC_BAD_CONVERT_JS_ZERO_ISNOT_NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSObject2NativeInterface(ccx, (void**)d, &s.toObject(), iid,
|
||||||
|
nullptr, pErr);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
NS_ERROR("bad type");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user