diff --git a/dom/nfc/MozNDEFRecord.cpp b/dom/nfc/MozNDEFRecord.cpp index ef8e60d5f48d..f73e07121b61 100644 --- a/dom/nfc/MozNDEFRecord.cpp +++ b/dom/nfc/MozNDEFRecord.cpp @@ -10,12 +10,11 @@ #include "mozilla/dom/MozNDEFRecordBinding.h" #include "mozilla/HoldDropJSObjects.h" #include "nsContentUtils.h" - +#include "nsString.h" namespace mozilla { namespace dom { - NS_IMPL_CYCLE_COLLECTION_CLASS(MozNDEFRecord) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(MozNDEFRecord) @@ -123,6 +122,28 @@ MozNDEFRecord::Constructor(const GlobalObject& aGlobal, return ndefRecord.forget(); } +/* static */ already_AddRefed +MozNDEFRecord::Constructor(const GlobalObject& aGlobal, + const nsAString& aUri, + ErrorResult& aRv) +{ + if (aUri.IsVoid()) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + nsCOMPtr win = do_QueryInterface(aGlobal.GetAsSupports()); + if (!win) { + aRv.Throw(NS_ERROR_FAILURE); + return nullptr; + } + + nsRefPtr ndefRecord = new MozNDEFRecord(win, TNF::Well_known); + ndefRecord->InitType(aGlobal.Context(), RTD::U); + ndefRecord->InitPayload(aGlobal.Context(), aUri); + return ndefRecord.forget(); +} + MozNDEFRecord::MozNDEFRecord(nsPIDOMWindow* aWindow, TNF aTnf) : mWindow(aWindow) // For GetParentObject() , mTnf(aTnf) @@ -144,6 +165,15 @@ MozNDEFRecord::InitType(JSContext* aCx, const Optional& aType) IncSize(type.Length()); } +void +MozNDEFRecord::InitType(JSContext* aCx, RTD rtd) +{ + EnumEntry rtdType = RTDValues::strings[static_cast(rtd)]; + mType = Uint8Array::Create(aCx, rtdType.length, + reinterpret_cast(rtdType.value)); + IncSize(rtdType.length); +} + void MozNDEFRecord::InitId(JSContext* aCx, const Optional& aId) { @@ -170,6 +200,23 @@ MozNDEFRecord::InitPayload(JSContext* aCx, const Optional& aPayload) IncSizeForPayload(payload.Length()); } +void +MozNDEFRecord::InitPayload(JSContext* aCx, const nsAString& aUri) +{ + using namespace mozilla::dom::WellKnownURIPrefixValues; + + nsCString uri = NS_ConvertUTF16toUTF8(aUri); + uint8_t id = GetURIIdentifier(uri); + uri = Substring(uri, strings[id].length); + mPayload = Uint8Array::Create(aCx, this, uri.Length() + 1); + + JS::AutoCheckCannotGC nogc; + uint8_t* data = JS_GetUint8ArrayData(mPayload, nogc); + data[0] = id; + memcpy(&data[1], reinterpret_cast(uri.Data()), uri.Length()); + IncSizeForPayload(uri.Length() + 1); +} + void MozNDEFRecord::IncSize(uint32_t aCount) { @@ -186,6 +233,21 @@ MozNDEFRecord::IncSizeForPayload(uint32_t aLen) IncSize(aLen); } +/* static */ uint32_t +MozNDEFRecord::GetURIIdentifier(const nsCString& aUri) +{ + using namespace mozilla::dom::WellKnownURIPrefixValues; + + // strings[0] is "", so we start from 1. + for (uint32_t i = 1; i < static_cast(WellKnownURIPrefix::EndGuard_); i++) { + if (StringBeginsWith(aUri, nsDependentCString(strings[i].value))) { + return i; + } + } + + return 0; +} + MozNDEFRecord::~MozNDEFRecord() { DropData(); diff --git a/dom/nfc/MozNDEFRecord.h b/dom/nfc/MozNDEFRecord.h index 9e1eaa9807a6..1132c0432049 100644 --- a/dom/nfc/MozNDEFRecord.h +++ b/dom/nfc/MozNDEFRecord.h @@ -52,6 +52,11 @@ public: const MozNDEFRecordOptions& aOptions, ErrorResult& aRv); + static already_AddRefed + Constructor(const GlobalObject& aGlobal, + const nsAString& aURI, + ErrorResult& aRv); + TNF Tnf() const { return mTnf; @@ -92,13 +97,16 @@ private: void HoldData(); void DropData(); void InitType(JSContext* aCx, const Optional& aType); + void InitType(JSContext* aCx, const RTD rtd); void InitId(JSContext* aCx, const Optional& aId); void InitPayload(JSContext* aCx, const Optional& aPayload); + void InitPayload(JSContext* aCx, const nsAString& aUri); void IncSize(uint32_t aCount); void IncSizeForPayload(uint32_t aLen); static bool ValidateTNF(const MozNDEFRecordOptions& aOptions, ErrorResult& aRv); + static uint32_t GetURIIdentifier(const nsCString& aUri); TNF mTnf; JS::Heap mType; diff --git a/dom/webidl/MozNDEFRecord.webidl b/dom/webidl/MozNDEFRecord.webidl index 0448f7be0e49..c48fa9c8deac 100644 --- a/dom/webidl/MozNDEFRecord.webidl +++ b/dom/webidl/MozNDEFRecord.webidl @@ -5,6 +5,11 @@ /* Copyright © 2013 Deutsche Telekom, Inc. */ +/** + * Type Name Format. + * + * @see NFCForum-TS-NDEF 3.2.6 TNF + */ enum TNF { "empty", "well-known", @@ -15,7 +20,62 @@ enum TNF { "unchanged" }; -[Constructor(optional MozNDEFRecordOptions options)] +/** + * Prefixes of well-known URI. + * + * @see NFCForum-TS-RTD_URI Table 3. Abbreviation Table. + */ +enum WellKnownURIPrefix { + "", + "http://www.", + "https://www.", + "http://", + "https://", + "tel:", + "mailto:", + "ftp://anonymous:anonymous@", + "ftp://ftp.", + "ftps://", + "sftp://", + "smb://", + "nfs://", + "ftp://", + "dav://", + "news:", + "telnet://", + "imap:", + "rtsp://", + "urn:", + "pop:", + "sip:", + "sips:", + "tftp:", + "btspp://", + "btl2cap://", + "btgoep://", + "tcpobex://", + "irdaobex://", + "file://", + "urn:epc:id:", + "urn:epc:tag:", + "urn:epc:pat:", + "urn:epc:raw:", + "urn:epc:", + "urn:nfc:" +}; + +/** + * Record Type Description. + * + * Record Types from well-known NDEF Records. + * @see NFCForum-TS-RTD + */ +enum RTD { + "U", // URI +}; + +[Constructor(optional MozNDEFRecordOptions options), + Constructor(DOMString uri)] interface MozNDEFRecord { /**