Commit d1d6f118 authored by Leon Han's avatar Leon Han Committed by Commit Bot

[webnfc] NDEFRecordInit#encoding is only applicable for BufferSource data source

DOMString data source is always encoded as utf-8.

The spec change:
https://github.com/w3c/web-nfc/pull/522

BUG=520391

Change-Id: Iec3d923d169f7a61937eda5249a57c6803598678
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1991972
Commit-Queue: Leon Han <leon.han@intel.com>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarFrançois Beaufort <beaufort.francois@gmail.com>
Cr-Commit-Position: refs/heads/master@{#732272}
parent 7d9744e6
...@@ -151,21 +151,26 @@ static NDEFRecord* CreateTextRecord(const String& id, ...@@ -151,21 +151,26 @@ static NDEFRecord* CreateTextRecord(const String& id,
return nullptr; return nullptr;
} }
String encoding_label = !encoding.IsEmpty() ? encoding : "utf-8"; String encoding_label = encoding.IsNull() ? "utf-8" : encoding;
if (encoding_label != "utf-8" && encoding_label != "utf-16" &&
encoding_label != "utf-16be" && encoding_label != "utf-16le") {
exception_state.ThrowTypeError(
"Encoding must be either \"utf-8\", \"utf-16\", \"utf-16be\", or "
"\"utf-16le\".");
return nullptr;
}
WTF::Vector<uint8_t> bytes; WTF::Vector<uint8_t> bytes;
if (data.IsString()) { if (data.IsString()) {
if (encoding_label != "utf-8") {
exception_state.ThrowTypeError(
"A DOMString data source is always encoded as \"utf-8\" so other "
"encodings are not allowed.");
return nullptr;
}
StringUTF8Adaptor utf8_string(data.GetAsString()); StringUTF8Adaptor utf8_string(data.GetAsString());
bytes.Append(utf8_string.data(), utf8_string.size()); bytes.Append(utf8_string.data(), utf8_string.size());
} else { } else {
DCHECK(IsBufferSource(data)); DCHECK(IsBufferSource(data));
if (encoding_label != "utf-8" && encoding_label != "utf-16" &&
encoding_label != "utf-16be" && encoding_label != "utf-16le") {
exception_state.ThrowTypeError(
"Encoding must be either \"utf-8\", \"utf-16\", \"utf-16be\", or "
"\"utf-16le\".");
return nullptr;
}
if (!GetBytesOfBufferSource(data, &bytes, exception_state)) { if (!GetBytesOfBufferSource(data, &bytes, exception_state)) {
return nullptr; return nullptr;
} }
......
...@@ -107,6 +107,7 @@ ...@@ -107,6 +107,7 @@
assert_equals(record.recordType, 'text', 'recordType'); assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.mediaType, null, 'mediaType'); assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id'); assert_equals(record.id, test_record_id, 'id');
// By default, 'utf-8'.
assert_equals(record.encoding, 'utf-8', 'encoding'); assert_equals(record.encoding, 'utf-8', 'encoding');
assert_equals(record.lang, 'en', 'lang'); assert_equals(record.lang, 'en', 'lang');
const decoder = new TextDecoder(); const decoder = new TextDecoder();
...@@ -123,6 +124,7 @@ ...@@ -123,6 +124,7 @@
assert_equals(record.recordType, 'text', 'recordType'); assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.mediaType, null, 'mediaType'); assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id'); assert_equals(record.id, test_record_id, 'id');
// By default, 'utf-8'.
assert_equals(record.encoding, 'utf-8', 'encoding'); assert_equals(record.encoding, 'utf-8', 'encoding');
assert_equals(record.lang, 'en', 'lang'); assert_equals(record.lang, 'en', 'lang');
const decoder = new TextDecoder(); const decoder = new TextDecoder();
...@@ -133,18 +135,32 @@ ...@@ -133,18 +135,32 @@
}, 'NDEFRecord constructor with text record type and arrayBufferView data'); }, 'NDEFRecord constructor with text record type and arrayBufferView data');
test(() => { test(() => {
assert_throws(new TypeError, () => new NDEFRecord(createTextRecord(
test_text_data, 'random-encoding')));
assert_throws(new TypeError, () => new NDEFRecord(createTextRecord(
test_text_data, 'utf-16')));
// Only 'utf-8' is OK for a DOMString data source.
const record = new NDEFRecord(createTextRecord(test_text_data, 'utf-8', 'fr'));
assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.encoding, 'utf-8', 'encoding');
assert_equals(record.lang, 'fr', 'lang');
const decoder = new TextDecoder();
assert_equals(decoder.decode(record.data), test_text_data,
'data has the same content with the original text');
assert_throws(new TypeError, () => new NDEFRecord(createTextRecord(
encodeTextToArrayBuffer(test_text_data, 'utf-8'), 'random-encoding')));
// The encoding list valid for a BufferSource data source.
const encodings = ['utf-8', 'utf-16', 'utf-16be', 'utf-16le']; const encodings = ['utf-8', 'utf-16', 'utf-16be', 'utf-16le'];
for (const encoding of encodings) { for (const encoding of encodings) {
const lang = 'fr'; const record = new NDEFRecord(createTextRecord(encodeTextToArrayBuffer(
const record = new NDEFRecord(createTextRecord(test_text_data, encoding, lang)); test_text_data, encoding), encoding, 'fr'));
assert_equals(record.recordType, 'text', 'recordType'); assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
assert_equals(record.encoding, encoding, 'encoding'); assert_equals(record.encoding, encoding, 'encoding');
assert_equals(record.lang, lang, 'lang'); assert_equals(record.lang, 'fr', 'lang');
const decoder = new TextDecoder(); const decoder = new TextDecoder(record.encoding);
assert_equals(decoder.decode(record.data), test_text_data, assert_equals(decoder.decode(record.data), test_text_data,
'data has the same content with the original dictionary'); 'data has the same content with the original text. encoding: ' + encoding);
} }
}, 'NDEFRecord constructor with text record type, encoding, and lang'); }, 'NDEFRecord constructor with text record type, encoding, and lang');
......
...@@ -33,7 +33,7 @@ const invalid_type_messages = ...@@ -33,7 +33,7 @@ const invalid_type_messages =
// NDEFRecord.encoding for 'text' record must be either "utf-8", // NDEFRecord.encoding for 'text' record must be either "utf-8",
// "utf-16", "utf-16le" or "utf-16be". // "utf-16", "utf-16le" or "utf-16be".
createMessage([createTextRecord(test_text_data, "chinese")]), createMessage([createTextRecord(test_buffer_data, "chinese")]),
// https://w3c.github.io/web-nfc/#dfn-map-a-url-to-ndef // https://w3c.github.io/web-nfc/#dfn-map-a-url-to-ndef
// NDEFRecord must have data. // NDEFRecord must have data.
......
...@@ -74,6 +74,33 @@ NFCHWStatus.NOT_SUPPORTED = NFCHWStatus.ENABLED + 1; ...@@ -74,6 +74,33 @@ NFCHWStatus.NOT_SUPPORTED = NFCHWStatus.ENABLED + 1;
// OS-level NFC setting OFF // OS-level NFC setting OFF
NFCHWStatus.DISABLED = NFCHWStatus.NOT_SUPPORTED + 1; NFCHWStatus.DISABLED = NFCHWStatus.NOT_SUPPORTED + 1;
function encodeTextToArrayBuffer(string, encoding) {
// Only support 'utf-8', 'utf-16', 'utf-16be', and 'utf-16le'.
assert_true(
encoding === 'utf-8' || encoding === 'utf-16' ||
encoding === 'utf-16be' || encoding === 'utf-16le');
if (encoding === 'utf-8') {
return new TextEncoder().encode(string).buffer;
}
if (encoding === 'utf-16') {
let uint16array = new Uint16Array(string.length);
for (let i = 0; i < string.length; i++) {
uint16array[i] = string.codePointAt(i);
}
return uint16array.buffer;
}
const littleEndian = encoding === 'utf-16le';
const buffer = new ArrayBuffer(string.length * 2);
const view = new DataView(buffer);
for (let i = 0; i < string.length; i++) {
view.setUint16(i * 2, string.codePointAt(i), littleEndian);
}
return buffer;
}
function createMessage(records) { function createMessage(records) {
if (records !== undefined) { if (records !== undefined) {
let message = {}; let message = {};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment