michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "SmsFilter.h" michael@0: #include "jsapi.h" michael@0: #include "jsfriendapi.h" // For js_DateGetMsecSinceEpoch. michael@0: #include "js/Utility.h" michael@0: #include "mozilla/dom/mobilemessage/Constants.h" // For MessageType michael@0: #include "mozilla/dom/ToJSValue.h" michael@0: #include "nsDOMString.h" michael@0: #include "nsError.h" michael@0: #include "nsIDOMClassInfo.h" michael@0: #include "nsJSUtils.h" michael@0: michael@0: using namespace mozilla::dom::mobilemessage; michael@0: michael@0: DOMCI_DATA(MozSmsFilter, mozilla::dom::SmsFilter) michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: michael@0: NS_INTERFACE_MAP_BEGIN(SmsFilter) michael@0: NS_INTERFACE_MAP_ENTRY(nsIDOMMozSmsFilter) michael@0: NS_INTERFACE_MAP_ENTRY(nsISupports) michael@0: NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozSmsFilter) michael@0: NS_INTERFACE_MAP_END michael@0: michael@0: NS_IMPL_ADDREF(SmsFilter) michael@0: NS_IMPL_RELEASE(SmsFilter) michael@0: michael@0: SmsFilter::SmsFilter() michael@0: { michael@0: mData.startDate() = 0; michael@0: mData.endDate() = 0; michael@0: mData.delivery() = eDeliveryState_Unknown; michael@0: mData.read() = eReadState_Unknown; michael@0: mData.threadId() = 0; michael@0: } michael@0: michael@0: SmsFilter::SmsFilter(const SmsFilterData& aData) michael@0: : mData(aData) michael@0: { michael@0: } michael@0: michael@0: /* static */ nsresult michael@0: SmsFilter::NewSmsFilter(nsISupports** aSmsFilter) michael@0: { michael@0: NS_ADDREF(*aSmsFilter = new SmsFilter()); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: SmsFilter::GetStartDate(JSContext* aCx, JS::MutableHandle aStartDate) michael@0: { michael@0: if (mData.startDate() == 0) { michael@0: aStartDate.setNull(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: aStartDate.setObjectOrNull(JS_NewDateObjectMsec(aCx, mData.startDate())); michael@0: NS_ENSURE_TRUE(aStartDate.isObject(), NS_ERROR_FAILURE); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: SmsFilter::SetStartDate(JSContext* aCx, JS::Handle aStartDate) michael@0: { michael@0: if (aStartDate.isNull()) { michael@0: mData.startDate() = 0; michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (!aStartDate.isObject()) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: JS::Rooted obj(aCx, &aStartDate.toObject()); michael@0: if (!JS_ObjectIsDate(aCx, obj)) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: mData.startDate() = js_DateGetMsecSinceEpoch(obj); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: SmsFilter::GetEndDate(JSContext* aCx, JS::MutableHandle aEndDate) michael@0: { michael@0: if (mData.endDate() == 0) { michael@0: aEndDate.setNull(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: aEndDate.setObjectOrNull(JS_NewDateObjectMsec(aCx, mData.endDate())); michael@0: NS_ENSURE_TRUE(aEndDate.isObject(), NS_ERROR_FAILURE); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: SmsFilter::SetEndDate(JSContext* aCx, JS::Handle aEndDate) michael@0: { michael@0: if (aEndDate.isNull()) { michael@0: mData.endDate() = 0; michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (!aEndDate.isObject()) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: JS::Rooted obj(aCx, &aEndDate.toObject()); michael@0: if (!JS_ObjectIsDate(aCx, obj)) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: mData.endDate() = js_DateGetMsecSinceEpoch(obj); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: SmsFilter::GetNumbers(JSContext* aCx, JS::MutableHandle aNumbers) michael@0: { michael@0: uint32_t length = mData.numbers().Length(); michael@0: michael@0: if (length == 0) { michael@0: aNumbers.setNull(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (!ToJSValue(aCx, mData.numbers(), aNumbers)) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: SmsFilter::SetNumbers(JSContext* aCx, JS::Handle aNumbers) michael@0: { michael@0: if (aNumbers.isNull()) { michael@0: mData.numbers().Clear(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (!aNumbers.isObject()) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: JS::Rooted obj(aCx, &aNumbers.toObject()); michael@0: if (!JS_IsArrayObject(aCx, obj)) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: uint32_t size; michael@0: MOZ_ALWAYS_TRUE(JS_GetArrayLength(aCx, obj, &size)); michael@0: michael@0: nsTArray numbers; michael@0: michael@0: for (uint32_t i=0; i jsNumber(aCx); michael@0: if (!JS_GetElement(aCx, obj, i, &jsNumber)) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: if (!jsNumber.isString()) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: nsDependentJSString number; michael@0: number.init(aCx, jsNumber.toString()); michael@0: michael@0: numbers.AppendElement(number); michael@0: } michael@0: michael@0: mData.numbers().Clear(); michael@0: mData.numbers().AppendElements(numbers); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: SmsFilter::GetDelivery(nsAString& aDelivery) michael@0: { michael@0: switch (mData.delivery()) { michael@0: case eDeliveryState_Received: michael@0: aDelivery = DELIVERY_RECEIVED; michael@0: break; michael@0: case eDeliveryState_Sent: michael@0: aDelivery = DELIVERY_SENT; michael@0: break; michael@0: case eDeliveryState_Unknown: michael@0: SetDOMStringToNull(aDelivery); michael@0: break; michael@0: default: michael@0: NS_ASSERTION(false, "We shouldn't get another delivery state!"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: SmsFilter::SetDelivery(const nsAString& aDelivery) michael@0: { michael@0: if (aDelivery.IsEmpty()) { michael@0: mData.delivery() = eDeliveryState_Unknown; michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (aDelivery.Equals(DELIVERY_RECEIVED)) { michael@0: mData.delivery() = eDeliveryState_Received; michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (aDelivery.Equals(DELIVERY_SENT)) { michael@0: mData.delivery() = eDeliveryState_Sent; michael@0: return NS_OK; michael@0: } michael@0: michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: SmsFilter::GetRead(JSContext* aCx, JS::MutableHandle aRead) michael@0: { michael@0: if (mData.read() == eReadState_Unknown) { michael@0: aRead.setNull(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: aRead.setBoolean(mData.read()); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: SmsFilter::SetRead(JSContext* aCx, JS::Handle aRead) michael@0: { michael@0: if (aRead.isNull()) { michael@0: mData.read() = eReadState_Unknown; michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (!aRead.isBoolean()) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: mData.read() = aRead.toBoolean() ? eReadState_Read : eReadState_Unread; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: SmsFilter::GetThreadId(JSContext* aCx, JS::MutableHandle aThreadId) michael@0: { michael@0: if (!mData.threadId()) { michael@0: aThreadId.setNull(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: aThreadId.setNumber(static_cast(mData.threadId())); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: SmsFilter::SetThreadId(JSContext* aCx, JS::Handle aThreadId) michael@0: { michael@0: if (aThreadId.isNull()) { michael@0: mData.threadId() = 0; michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (!aThreadId.isNumber()) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: double number = aThreadId.toNumber(); michael@0: uint64_t integer = static_cast(number); michael@0: if (integer == 0 || integer != number) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: mData.threadId() = integer; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: } // namespace dom michael@0: } // namespace mozilla