bool EventListenerInfo::GetJSVal(JSContext* aCx, Maybe<JSAutoCompartment>& aAc, JS::MutableHandle<JS::Value> aJSVal) { aJSVal.setNull(); nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS = do_QueryInterface(mListener); if (wrappedJS) { JS::Rooted<JSObject*> object(aCx, wrappedJS->GetJSObject()); if (!object) { return false; } aAc.emplace(aCx, object); aJSVal.setObject(*object); return true; } nsCOMPtr<JSEventHandler> jsHandler = do_QueryInterface(mListener); if (jsHandler && jsHandler->GetTypedEventHandler().HasEventHandler()) { JS::Handle<JSObject*> handler = jsHandler->GetTypedEventHandler().Ptr()->CallableOrNull(); if (handler) { aAc.emplace(aCx, handler); aJSVal.setObject(*handler); return true; } } return false; }
NS_IMETHODIMP nsDOMFileFile::GetLastModifiedDate(JSContext* cx, JS::MutableHandle<JS::Value> aLastModifiedDate) { NS_ASSERTION(mIsFile, "Should only be called on files"); PRTime msecs; if (IsDateUnknown()) { nsresult rv = mFile->GetLastModifiedTime(&msecs); NS_ENSURE_SUCCESS(rv, rv); mLastModificationDate = msecs; } else { msecs = mLastModificationDate; } JSObject* date = JS_NewDateObjectMsec(cx, msecs); if (date) { aLastModifiedDate.setObject(*date); } else { date = JS_NewDateObjectMsec(cx, JS_Now() / PR_USEC_PER_MSEC); aLastModifiedDate.setObject(*date); } return NS_OK; }
bool ToJSValue(JSContext* aCx, Promise& aArgument, JS::MutableHandle<JS::Value> aValue) { aValue.setObject(*aArgument.PromiseObj()); return true; }
nsresult ArchiveRequest::GetFilesResult(JSContext* aCx, JS::MutableHandle<JS::Value> aValue, nsTArray<RefPtr<File>>& aFileList) { JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, aFileList.Length())); if (!array) { return NS_ERROR_OUT_OF_MEMORY; } for (uint32_t i = 0; i < aFileList.Length(); ++i) { RefPtr<File> file = aFileList[i]; JS::Rooted<JS::Value> value(aCx); if (!ToJSValue(aCx, file, &value)) { return NS_ERROR_FAILURE; } if (!JS_DefineElement(aCx, array, i, value, JSPROP_ENUMERATE)) { return NS_ERROR_FAILURE; } } aValue.setObject(*array); return NS_OK; }
NS_IMETHODIMP nsScriptableRegion::GetRects(JSContext* aCx, JS::MutableHandle<JS::Value> aRects) { uint32_t numRects = mRegion.GetNumRects(); if (!numRects) { aRects.setNull(); return NS_OK; } JS::Rooted<JSObject*> destArray(aCx, JS_NewArrayObject(aCx, numRects * 4)); if (!destArray) { return NS_ERROR_OUT_OF_MEMORY; } aRects.setObject(*destArray); uint32_t n = 0; nsIntRegionRectIterator iter(mRegion); const nsIntRect *rect; while ((rect = iter.Next())) { if (!JS_DefineElement(aCx, destArray, n, rect->x, JSPROP_ENUMERATE) || !JS_DefineElement(aCx, destArray, n + 1, rect->y, JSPROP_ENUMERATE) || !JS_DefineElement(aCx, destArray, n + 2, rect->width, JSPROP_ENUMERATE) || !JS_DefineElement(aCx, destArray, n + 3, rect->height, JSPROP_ENUMERATE)) { return NS_ERROR_FAILURE; } n += 4; } return NS_OK; }
nsresult ArchiveRequest::GetFilesResult(JSContext* aCx, JS::MutableHandle<JS::Value> aValue, nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList) { JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, aFileList.Length())); if (!array) { return NS_ERROR_OUT_OF_MEMORY; } for (uint32_t i = 0; i < aFileList.Length(); ++i) { nsCOMPtr<nsIDOMFile> file = aFileList[i]; JS::Rooted<JS::Value> value(aCx); nsresult rv = nsContentUtils::WrapNative(aCx, file, &NS_GET_IID(nsIDOMFile), &value); if (NS_FAILED(rv) || !JS_DefineElement(aCx, array, i, value, JSPROP_ENUMERATE)) { return NS_ERROR_FAILURE; } } aValue.setObject(*array); return NS_OK; }
NS_IMETHODIMP MmsMessage::GetAttachments(JSContext* aCx, JS::MutableHandle<JS::Value> aAttachments) { uint32_t length = mAttachments.Length(); JS::Rooted<JSObject*> attachments( aCx, JS_NewArrayObject(aCx, length)); NS_ENSURE_TRUE(attachments, NS_ERROR_OUT_OF_MEMORY); for (uint32_t i = 0; i < length; ++i) { const Attachment &attachment = mAttachments[i]; JS::Rooted<JSObject*> attachmentObj( aCx, JS_NewObject(aCx, nullptr, JS::NullPtr(), JS::NullPtr())); NS_ENSURE_TRUE(attachmentObj, NS_ERROR_OUT_OF_MEMORY); JS::Rooted<JSString*> tmpJsStr(aCx); // Get |attachment.mId|. tmpJsStr = JS_NewUCStringCopyN(aCx, attachment.id.get(), attachment.id.Length()); NS_ENSURE_TRUE(tmpJsStr, NS_ERROR_OUT_OF_MEMORY); if (!JS_DefineProperty(aCx, attachmentObj, "id", tmpJsStr, JSPROP_ENUMERATE)) { return NS_ERROR_FAILURE; } // Get |attachment.mLocation|. tmpJsStr = JS_NewUCStringCopyN(aCx, attachment.location.get(), attachment.location.Length()); NS_ENSURE_TRUE(tmpJsStr, NS_ERROR_OUT_OF_MEMORY); if (!JS_DefineProperty(aCx, attachmentObj, "location", tmpJsStr, JSPROP_ENUMERATE)) { return NS_ERROR_FAILURE; } // Get |attachment.mContent|. JS::Rooted<JS::Value> tmpJsVal(aCx); nsresult rv = nsContentUtils::WrapNative(aCx, attachment.content, &NS_GET_IID(nsIDOMBlob), &tmpJsVal); NS_ENSURE_SUCCESS(rv, rv); if (!JS_DefineProperty(aCx, attachmentObj, "content", tmpJsVal, JSPROP_ENUMERATE)) { return NS_ERROR_FAILURE; } if (!JS_SetElement(aCx, attachments, i, attachmentObj)) { return NS_ERROR_FAILURE; } } aAttachments.setObject(*attachments); return NS_OK; }
NS_IMETHODIMP nsProfiler::GetProfileData(JSContext* aCx, JS::MutableHandle<JS::Value> aResult) { JSObject *obj = profiler_get_profile_jsobject(aCx); if (!obj) return NS_ERROR_FAILURE; aResult.setObject(*obj); return NS_OK; }
NS_IMETHODIMP MmsMessage::GetReceivers(JSContext* aCx, JS::MutableHandle<JS::Value> aReceivers) { JS::Rooted<JSObject*> receiversObj(aCx); nsresult rv = nsTArrayToJSArray(aCx, mReceivers, &receiversObj); NS_ENSURE_SUCCESS(rv, rv); aReceivers.setObject(*receiversObj); return NS_OK; }
NS_IMETHODIMP nsDOMFileBase::GetLastModifiedDate(JSContext* cx, JS::MutableHandle<JS::Value> aLastModifiedDate) { JS::Rooted<JSObject*> date(cx, JS_NewDateObjectMsec(cx, JS_Now() / PR_USEC_PER_MSEC)); if (!date) { return NS_ERROR_OUT_OF_MEMORY; } aLastModifiedDate.setObject(*date); return NS_OK; }
NS_IMETHODIMP nsProfiler::GetProfileData(float aSinceTime, JSContext* aCx, JS::MutableHandle<JS::Value> aResult) { JS::RootedObject obj(aCx, profiler_get_profile_jsobject(aCx, aSinceTime)); if (!obj) { return NS_ERROR_FAILURE; } aResult.setObject(*obj); return NS_OK; }
NS_IMETHODIMP nsAppStartup::GetStartupInfo(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval) { JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx)); aRetval.setObject(*obj); TimeStamp procTime = StartupTimeline::Get(StartupTimeline::PROCESS_CREATION); TimeStamp now = TimeStamp::Now(); PRTime absNow = PR_Now(); if (procTime.IsNull()) { bool error = false; procTime = TimeStamp::ProcessCreation(error); if (error) { Telemetry::Accumulate(Telemetry::STARTUP_MEASUREMENT_ERRORS, StartupTimeline::PROCESS_CREATION); } StartupTimeline::Record(StartupTimeline::PROCESS_CREATION, procTime); } for (int i = StartupTimeline::PROCESS_CREATION; i < StartupTimeline::MAX_EVENT_ID; ++i) { StartupTimeline::Event ev = static_cast<StartupTimeline::Event>(i); TimeStamp stamp = StartupTimeline::Get(ev); if (stamp.IsNull() && (ev == StartupTimeline::MAIN)) { // Always define main to aid with bug 689256. stamp = procTime; MOZ_ASSERT(!stamp.IsNull()); Telemetry::Accumulate(Telemetry::STARTUP_MEASUREMENT_ERRORS, StartupTimeline::MAIN); } if (!stamp.IsNull()) { if (stamp >= procTime) { PRTime prStamp = ComputeAbsoluteTimestamp(absNow, now, stamp) / PR_USEC_PER_MSEC; JS::Rooted<JSObject*> date(aCx, JS::NewDateObject(aCx, JS::TimeClip(prStamp))); JS_DefineProperty(aCx, obj, StartupTimeline::Describe(ev), date, JSPROP_ENUMERATE); } else { Telemetry::Accumulate(Telemetry::STARTUP_MEASUREMENT_ERRORS, ev); } } } return NS_OK; }
NS_IMETHODIMP MobileMessageThread::GetParticipants(JSContext* aCx, JS::MutableHandle<JS::Value> aParticipants) { JS::Rooted<JSObject*> obj(aCx); nsresult rv = nsTArrayToJSArray(aCx, mData.participants(), obj.address()); NS_ENSURE_SUCCESS(rv, rv); aParticipants.setObject(*obj); return NS_OK; }
nsresult DOMFileImplBase::GetLastModifiedDate(JSContext* aCx, JS::MutableHandle<JS::Value> aDate) { JS::Rooted<JSObject*> date(aCx, JS_NewDateObjectMsec(aCx, JS_Now() / PR_USEC_PER_MSEC)); if (!date) { return NS_ERROR_OUT_OF_MEMORY; } aDate.setObject(*date); return NS_OK; }
nsresult ReadHelper::GetSuccessResult(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) { JS::Rooted<JSObject*> arrayBuffer(aCx); nsresult rv = nsContentUtils::CreateArrayBuffer(aCx, mStream->Data(), arrayBuffer.address()); NS_ENSURE_SUCCESS(rv, rv); aVal.setObject(*arrayBuffer); return NS_OK; }
void BluetoothAdapter::GetDevices(JSContext* aContext, JS::MutableHandle<JS::Value> aDevices, ErrorResult& aRv) { if (!mJsDeviceAddresses) { BT_WARNING("Devices not yet set!\n"); aRv.Throw(NS_ERROR_FAILURE); return; } JS::ExposeObjectToActiveJS(mJsDeviceAddresses); aDevices.setObject(*mJsDeviceAddresses); }
void BluetoothDevice::GetServices(JSContext* aCx, JS::MutableHandle<JS::Value> aServices, ErrorResult& aRv) { if (!mJsServices) { BT_WARNING("Services not yet set!"); aRv.Throw(NS_ERROR_FAILURE); return; } JS::ExposeObjectToActiveJS(mJsServices); aServices.setObject(*mJsServices); }
void BluetoothAdapter::GetUuids(JSContext* aContext, JS::MutableHandle<JS::Value> aUuids, ErrorResult& aRv) { if (!mJsUuids) { BT_WARNING("UUIDs not yet set!\n"); aRv.Throw(NS_ERROR_FAILURE); return; } JS::ExposeObjectToActiveJS(mJsUuids); aUuids.setObject(*mJsUuids); }
bool EventListenerInfo::GetJSVal(JSContext* aCx, Maybe<JSAutoRealm>& aAr, JS::MutableHandle<JS::Value> aJSVal) { if (mScriptedListener) { aJSVal.setObject(*mScriptedListener); aAr.emplace(aCx, mScriptedListener); return true; } aJSVal.setNull(); return false; }
void Promise::Then(JSContext* aCx, // aCalleeGlobal may not be in the compartment of aCx, when called over // Xrays. JS::Handle<JSObject*> aCalleeGlobal, AnyCallback* aResolveCallback, AnyCallback* aRejectCallback, JS::MutableHandle<JS::Value> aRetval, ErrorResult& aRv) { NS_ASSERT_OWNINGTHREAD(Promise); // Let's hope this does the right thing with Xrays... Ensure everything is // just in the caller compartment; that ought to do the trick. In theory we // should consider aCalleeGlobal, but in practice our only caller is // DOMRequest::Then, which is not working with a Promise subclass, so things // should be OK. JS::Rooted<JSObject*> promise(aCx, PromiseObj()); if (!JS_WrapObject(aCx, &promise)) { aRv.NoteJSContextException(aCx); return; } JS::Rooted<JSObject*> resolveCallback(aCx); if (aResolveCallback) { resolveCallback = aResolveCallback->CallbackOrNull(); if (!JS_WrapObject(aCx, &resolveCallback)) { aRv.NoteJSContextException(aCx); return; } } JS::Rooted<JSObject*> rejectCallback(aCx); if (aRejectCallback) { rejectCallback = aRejectCallback->CallbackOrNull(); if (!JS_WrapObject(aCx, &rejectCallback)) { aRv.NoteJSContextException(aCx); return; } } JS::Rooted<JSObject*> retval(aCx); retval = JS::CallOriginalPromiseThen(aCx, promise, resolveCallback, rejectCallback); if (!retval) { aRv.NoteJSContextException(aCx); return; } aRetval.setObject(*retval); }
virtual bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) { aValue.setUndefined(); const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value(); if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue) { BT_WARNING("Not a BluetoothNamedValue array!"); SetError(NS_LITERAL_STRING("BluetoothReplyTypeError")); return false; } const InfallibleTArray<BluetoothNamedValue>& values = v.get_ArrayOfBluetoothNamedValue(); nsTArray<nsRefPtr<BluetoothDevice> > devices; for (uint32_t i = 0; i < values.Length(); i++) { const BluetoothValue properties = values[i].value(); if (properties.type() != BluetoothValue::TArrayOfBluetoothNamedValue) { BT_WARNING("Not a BluetoothNamedValue array!"); SetError(NS_LITERAL_STRING("BluetoothReplyTypeError")); return false; } nsRefPtr<BluetoothDevice> d = BluetoothDevice::Create(mAdapterPtr->GetOwner(), mAdapterPtr->GetPath(), properties); devices.AppendElement(d); } nsresult rv; nsIScriptContext* sc = mAdapterPtr->GetContextForEventHandlers(&rv); if (!sc) { BT_WARNING("Cannot create script context!"); SetError(NS_LITERAL_STRING("BluetoothScriptContextError")); return false; } AutoPushJSContext cx(sc->GetNativeContext()); JSObject* JsDevices = nullptr; rv = nsTArrayToJSArray(cx, devices, &JsDevices); if (!JsDevices) { BT_WARNING("Cannot create JS array!"); SetError(NS_LITERAL_STRING("BluetoothError")); return false; } aValue.setObject(*JsDevices); return true; }
nsresult GetResult(JSContext* aCx, const nsCString* aString, JS::MutableHandle<JS::Value> aResult) { const nsCString& data = *aString; nsresult rv; if (!mFileRequest->HasEncoding()) { JS::Rooted<JSObject*> arrayBuffer(aCx); rv = nsContentUtils::CreateArrayBuffer(aCx, data, arrayBuffer.address()); if (NS_WARN_IF(NS_FAILED(rv))) { return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR; } aResult.setObject(*arrayBuffer); return NS_OK; } nsAutoCString encoding; // The BOM sniffing is baked into the "decode" part of the Encoding // Standard, which the File API references. if (!nsContentUtils::CheckForBOM( reinterpret_cast<const unsigned char *>(data.get()), data.Length(), encoding)) { // BOM sniffing failed. Try the API argument. if (!EncodingUtils::FindEncodingForLabel(mFileRequest->GetEncoding(), encoding)) { // API argument failed. Since we are dealing with a file system file, // we don't have a meaningful type attribute for the blob available, // so proceeding to the next step, which is defaulting to UTF-8. encoding.AssignLiteral("UTF-8"); } } nsString tmpString; rv = nsContentUtils::ConvertStringFromEncoding(encoding, data, tmpString); if (NS_WARN_IF(NS_FAILED(rv))) { return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR; } if (NS_WARN_IF(!xpc::StringToJsval(aCx, tmpString, aResult))) { return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR; } return NS_OK; }
virtual bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) { aValue.setUndefined(); const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value(); if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue) { BT_WARNING("Not a BluetoothNamedValue array!"); SetError(NS_LITERAL_STRING("BluetoothReplyTypeError")); return false; } const InfallibleTArray<BluetoothNamedValue>& values = v.get_ArrayOfBluetoothNamedValue(); nsTArray<nsRefPtr<BluetoothDevice> > devices; for (uint32_t i = 0; i < values.Length(); i++) { const BluetoothValue properties = values[i].value(); if (properties.type() != BluetoothValue::TArrayOfBluetoothNamedValue) { BT_WARNING("Not a BluetoothNamedValue array!"); SetError(NS_LITERAL_STRING("BluetoothReplyTypeError")); return false; } nsRefPtr<BluetoothDevice> d = BluetoothDevice::Create(mAdapterPtr->GetOwner(), mAdapterPtr->GetPath(), properties); devices.AppendElement(d); } AutoJSAPI jsapi; if (!jsapi.Init(mAdapterPtr->GetOwner())) { BT_WARNING("Failed to initialise AutoJSAPI!"); SetError(NS_LITERAL_STRING("BluetoothAutoJSAPIInitError")); return false; } JSContext* cx = jsapi.cx(); JS::Rooted<JSObject*> JsDevices(cx); if (NS_FAILED(nsTArrayToJSArray(cx, devices, &JsDevices))) { BT_WARNING("Cannot create JS array!"); SetError(NS_LITERAL_STRING("BluetoothError")); return false; } aValue.setObject(*JsDevices); return true; }
bool DeserializeArrayBuffer(JSContext* cx, const InfallibleTArray<uint8_t>& aBuffer, JS::MutableHandle<JS::Value> aVal) { mozilla::UniquePtr<uint8_t[], JS::FreePolicy> data(js_pod_malloc<uint8_t>(aBuffer.Length())); if (!data) return false; memcpy(data.get(), aBuffer.Elements(), aBuffer.Length()); JSObject* obj = JS_NewArrayBufferWithContents(cx, aBuffer.Length(), data.get()); if (!obj) return false; // If JS_NewArrayBufferWithContents returns non-null, the ownership of // the data is transfered to obj, so we release the ownership here. mozilla::Unused << data.release(); aVal.setObject(*obj); return true; }
nsresult KeyPath::ToJSVal(JSContext* aCx, JS::MutableHandle<JS::Value> aValue) const { if (IsArray()) { uint32_t len = mStrings.Length(); JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, len)); if (!array) { IDB_WARNING("Failed to make array!"); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } for (uint32_t i = 0; i < len; ++i) { JS::Rooted<JS::Value> val(aCx); nsString tmp(mStrings[i]); if (!xpc::StringToJsval(aCx, tmp, &val)) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } if (!JS_SetElement(aCx, array, i, val)) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } } aValue.setObject(*array); return NS_OK; } if (IsString()) { nsString tmp(mStrings[0]); if (!xpc::StringToJsval(aCx, tmp, aValue)) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } return NS_OK; } aValue.setNull(); return NS_OK; }
bool WebrtcTelemetry::GetWebrtcStats(JSContext *cx, JS::MutableHandle<JS::Value> ret) { JS::Rooted<JSObject*> root_obj(cx, JS_NewPlainObject(cx)); if (!root_obj) return false; ret.setObject(*root_obj); JS::Rooted<JSObject*> ice_obj(cx, JS_NewPlainObject(cx)); if (!ice_obj) return false; JS_DefineProperty(cx, root_obj, "IceCandidatesStats", ice_obj, JSPROP_ENUMERATE); if (!AddIceInfo(cx, ice_obj, false)) return false; if (!AddIceInfo(cx, ice_obj, true)) return false; return true; }
NS_IMETHODIMP PlaceInfo::GetVisits(JSContext* aContext, JS::MutableHandle<JS::Value> _visits) { // If the visits data was not provided, return null rather // than an empty array to distinguish this case from the case // of a place without any visit. if (!mVisitsAvailable) { _visits.setNull(); return NS_OK; } // TODO bug 625913 when we use this in situations that have more than one // visit here, we will likely want to make this cache the value. JS::Rooted<JSObject*> visits(aContext, JS_NewArrayObject(aContext, 0)); NS_ENSURE_TRUE(visits, NS_ERROR_OUT_OF_MEMORY); JS::Rooted<JSObject*> global(aContext, JS::CurrentGlobalOrNull(aContext)); NS_ENSURE_TRUE(global, NS_ERROR_UNEXPECTED); nsCOMPtr<nsIXPConnect> xpc = mozilla::services::GetXPConnect(); for (VisitsArray::size_type idx = 0; idx < mVisits.Length(); idx++) { nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper; nsresult rv = xpc->WrapNative(aContext, global, mVisits[idx], NS_GET_IID(mozIVisitInfo), getter_AddRefs(wrapper)); NS_ENSURE_SUCCESS(rv, rv); JS::Rooted<JSObject*> jsobj(aContext, wrapper->GetJSObject()); NS_ENSURE_STATE(jsobj); bool rc = JS_SetElement(aContext, visits, idx, jsobj); NS_ENSURE_TRUE(rc, NS_ERROR_UNEXPECTED); } _visits.setObject(*visits); return NS_OK; }
nsresult GetResult(JSContext* aCx, const FileRequestMetadata* aMetadata, JS::MutableHandle<JS::Value> aResult) { JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx)); if (NS_WARN_IF(!obj)) { return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR; } const FileRequestSize& size = aMetadata->size(); if (size.type() != FileRequestSize::Tvoid_t) { MOZ_ASSERT(size.type() == FileRequestSize::Tuint64_t); JS::Rooted<JS::Value> number(aCx, JS_NumberValue(size.get_uint64_t())); if (NS_WARN_IF(!JS_DefineProperty(aCx, obj, "size", number, 0))) { return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR; } } const FileRequestLastModified& lastModified = aMetadata->lastModified(); if (lastModified.type() != FileRequestLastModified::Tvoid_t) { MOZ_ASSERT(lastModified.type() == FileRequestLastModified::Tint64_t); JS::Rooted<JSObject*> date(aCx, JS::NewDateObject(aCx, JS::TimeClip(lastModified.get_int64_t()))); if (NS_WARN_IF(!date)) { return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR; } if (NS_WARN_IF(!JS_DefineProperty(aCx, obj, "lastModified", date, 0))) { return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR; } } aResult.setObject(*obj); return NS_OK; }
NS_IMETHODIMP MmsMessage::GetAttachments(JSContext* aCx, JS::MutableHandle<JS::Value> aAttachments) { uint32_t length = mAttachments.Length(); JS::Rooted<JSObject*> attachments( aCx, JS_NewArrayObject(aCx, length)); NS_ENSURE_TRUE(attachments, NS_ERROR_OUT_OF_MEMORY); for (uint32_t i = 0; i < length; ++i) { const Attachment &attachment = mAttachments[i]; JS::Rooted<JSObject*> attachmentObj(aCx, JS_NewPlainObject(aCx)); NS_ENSURE_TRUE(attachmentObj, NS_ERROR_OUT_OF_MEMORY); JS::Rooted<JSString*> tmpJsStr(aCx); // Get |attachment.mId|. tmpJsStr = JS_NewUCStringCopyN(aCx, attachment.id.get(), attachment.id.Length()); NS_ENSURE_TRUE(tmpJsStr, NS_ERROR_OUT_OF_MEMORY); if (!JS_DefineProperty(aCx, attachmentObj, "id", tmpJsStr, JSPROP_ENUMERATE)) { return NS_ERROR_FAILURE; } // Get |attachment.mLocation|. tmpJsStr = JS_NewUCStringCopyN(aCx, attachment.location.get(), attachment.location.Length()); NS_ENSURE_TRUE(tmpJsStr, NS_ERROR_OUT_OF_MEMORY); if (!JS_DefineProperty(aCx, attachmentObj, "location", tmpJsStr, JSPROP_ENUMERATE)) { return NS_ERROR_FAILURE; } // Get |attachment.mContent|. // Duplicating the File with the correct parent object. nsIGlobalObject *global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx)); MOZ_ASSERT(global); nsRefPtr<Blob> newBlob = Blob::Create(global, attachment.content->Impl()); JS::Rooted<JS::Value> val(aCx); if (!ToJSValue(aCx, newBlob, &val)) { return NS_ERROR_FAILURE; } if (!JS_DefineProperty(aCx, attachmentObj, "content", val, JSPROP_ENUMERATE)) { return NS_ERROR_FAILURE; } if (!JS_DefineElement(aCx, attachments, i, attachmentObj, JSPROP_ENUMERATE)) { return NS_ERROR_FAILURE; } } aAttachments.setObject(*attachments); return NS_OK; }
// static nsresult Key::DecodeJSValInternal(const unsigned char*& aPos, const unsigned char* aEnd, JSContext* aCx, uint8_t aTypeOffset, JS::MutableHandle<JS::Value> aVal, uint16_t aRecursionDepth) { NS_ENSURE_TRUE(aRecursionDepth < MaxRecursionDepth, NS_ERROR_DOM_INDEXEDDB_DATA_ERR); if (*aPos - aTypeOffset >= eArray) { JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0, nullptr)); if (!array) { NS_WARNING("Failed to make array!"); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } aTypeOffset += eMaxType; if (aTypeOffset == eMaxType * MaxArrayCollapse) { ++aPos; aTypeOffset = 0; } uint32_t index = 0; JS::Rooted<JS::Value> val(aCx); while (aPos < aEnd && *aPos - aTypeOffset != eTerminator) { nsresult rv = DecodeJSValInternal(aPos, aEnd, aCx, aTypeOffset, &val, aRecursionDepth + 1); NS_ENSURE_SUCCESS(rv, rv); aTypeOffset = 0; if (!JS_SetElement(aCx, array, index++, &val)) { NS_WARNING("Failed to set array element!"); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } } NS_ASSERTION(aPos >= aEnd || (*aPos % eMaxType) == eTerminator, "Should have found end-of-array marker"); ++aPos; aVal.setObject(*array); } else if (*aPos - aTypeOffset == eString) { nsString key; DecodeString(aPos, aEnd, key); if (!xpc::StringToJsval(aCx, key, aVal)) { return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } } else if (*aPos - aTypeOffset == eDate) { double msec = static_cast<double>(DecodeNumber(aPos, aEnd)); JSObject* date = JS_NewDateObjectMsec(aCx, msec); if (!date) { NS_WARNING("Failed to make date!"); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } aVal.setObject(*date); } else if (*aPos - aTypeOffset == eFloat) { aVal.setDouble(DecodeNumber(aPos, aEnd)); } else { NS_NOTREACHED("Unknown key type!"); } return NS_OK; }