mirror of
https://github.com/LukeHagar/yotocol.git
synced 2025-12-06 04:22:12 +00:00
849 lines
29 KiB
JavaScript
849 lines
29 KiB
JavaScript
|
|
(function (root, factory) {
|
|
if (typeof define === 'function' && define.amd) {
|
|
// AMD
|
|
define([], factory);
|
|
} else if (typeof exports === 'object') {
|
|
module.exports = factory();
|
|
} else {
|
|
// Browser globals (root is window)
|
|
root.Ndef= factory();
|
|
}
|
|
}(this, function () {
|
|
/**
|
|
* Utility functions used for working with NDEF
|
|
*
|
|
* @constructor
|
|
* @throws if you attempt to intsantiate NdefUtils
|
|
*/
|
|
var NdefUtils = function() {
|
|
throw "Dont construct NdefUtils!";
|
|
};
|
|
|
|
/**
|
|
* Check if a value has a bit flag
|
|
*
|
|
* @param {!integer} value
|
|
* @param {!integer} flag
|
|
* @return {!boolean} true if flag is set, false otherwise
|
|
*/
|
|
NdefUtils.hasFlag = function(value,flag) {
|
|
return (value & flag) === flag;
|
|
};
|
|
|
|
/**
|
|
* Get the type from this NDEF Record
|
|
*
|
|
* @constructor
|
|
* @this {NdefRecord}
|
|
* @param {!boolean} chunked if this record has a chunked flag
|
|
* @param {!integer} tnf the Type Name Format for this record
|
|
* @param {!Uint8Array} type the type data for this record
|
|
* @param {?Uint8Array} id the id for this record, if present
|
|
* @param {!payload} payload the payload contained in this record
|
|
*/
|
|
var NdefRecord = function (chunked,tnf,type,id,payload) {
|
|
if(typeof chunked == "undefined" ||
|
|
typeof tnf == "undefined" ||
|
|
typeof type == "undefined" ||
|
|
typeof id == "undefined" ||
|
|
typeof payload == "undefined") {
|
|
throw "Parameters missing from NdefRecord constructor call";
|
|
}
|
|
|
|
if(chunked === null ||
|
|
tnf === null ||
|
|
type === null ||
|
|
payload === null) {
|
|
throw "Passed null to non-nullable constructor parameter in NdefRecord";
|
|
}
|
|
|
|
|
|
this.chunked = chunked;
|
|
this.tnf = tnf;
|
|
this.type = type;
|
|
this.id = id;
|
|
this.payload = payload;
|
|
};
|
|
|
|
/**
|
|
* These flags and masks are used for packing/unpacking
|
|
* the record header
|
|
*/
|
|
NdefRecord.HDR_FLAG_MESSAGE_BEGIN = 0x80;
|
|
NdefRecord.HDR_FLAG_MESSAGE_END = 0x40;
|
|
NdefRecord.HDR_FLAG_CHUNKED = 0x20;
|
|
NdefRecord.HDR_FLAG_SHORT_RECORD = 0x10;
|
|
NdefRecord.HDR_FLAG_ID_LENGTH_PRESENT = 0x08;
|
|
NdefRecord.HDR_MASK_TNF = 0x07;
|
|
|
|
/**
|
|
* Type Name Format values
|
|
*/
|
|
NdefRecord.TNF_EMPTY = 0x00;
|
|
NdefRecord.TNF_WELL_KNOWN = 0x01;
|
|
NdefRecord.TNF_MEDIA = 0x02;
|
|
NdefRecord.TNF_ABSOLUTE_URI = 0x03;
|
|
NdefRecord.TNF_EXTERNAL = 0x04;
|
|
NdefRecord.TNF_UNKNOWN = 0x05;
|
|
NdefRecord.TNF_UNCHANGED = 0x06;
|
|
NdefRecord.TNF_RESERVED = 0x07;
|
|
|
|
/**
|
|
* NDEF URI Prefixes
|
|
*/
|
|
NdefRecord.URI_PRE_NONE = 0x00;
|
|
NdefRecord.URI_PRE_HTTP_WWW = 0x01;
|
|
NdefRecord.URI_PRE_HTTPS_WWW = 0x02;
|
|
NdefRecord.URI_PRE_HTTP = 0x03;
|
|
NdefRecord.URI_PRE_HTTPS = 0x04;
|
|
NdefRecord.URI_PRE_TEL = 0x05;
|
|
NdefRecord.URI_PRE_MAILTO = 0x06;
|
|
NdefRecord.URI_PRE_FTP_ANON = 0x07;
|
|
NdefRecord.URI_PRE_FTP_FTP = 0x08; // ftp://ftp
|
|
NdefRecord.URI_PRE_FTPS = 0x09;
|
|
NdefRecord.URI_PRE_SFTP = 0x0A;
|
|
NdefRecord.URI_PRE_SMB = 0x0B;
|
|
NdefRecord.URI_PRE_NFS = 0x0C;
|
|
NdefRecord.URI_PRE_FTP = 0x0D;
|
|
NdefRecord.URI_PRE_DAV = 0x0E;
|
|
NdefRecord.URI_PRE_NEWS = 0x0F;
|
|
NdefRecord.URI_PRE_TELNET = 0x10;
|
|
NdefRecord.URI_PRE_IMAP = 0x11;
|
|
NdefRecord.URI_PRE_RTSP = 0x12;
|
|
NdefRecord.URI_PRE_URN = 0x13;
|
|
NdefRecord.URI_PRE_POP = 0x14;
|
|
NdefRecord.URI_PRE_SIP = 0x15;
|
|
NdefRecord.URI_PRE_SIPS = 0x16;
|
|
NdefRecord.URI_PRE_TFTP = 0x17;
|
|
NdefRecord.URI_PRE_BTSPP = 0x18;
|
|
NdefRecord.URI_PRE_BTL2CAP = 0x19;
|
|
NdefRecord.URI_PRE_BTGOEP = 0x1A;
|
|
NdefRecord.URI_PRE_TCPOBEX = 0x1B;
|
|
NdefRecord.URI_PRE_IRDAOBEX = 0x1C;
|
|
NdefRecord.URI_PRE_FILE = 0x1D;
|
|
NdefRecord.URI_PRE_URN_EPC_ID = 0x1E;
|
|
NdefRecord.URI_PRE_URN_EPC_TAG = 0x1F;
|
|
NdefRecord.URI_PRE_URN_EPC_PAT = 0x20;
|
|
NdefRecord.URI_PRE_URN_EPC_RAW = 0x21;
|
|
NdefRecord.URI_PRE_URN_EPC = 0x22;
|
|
NdefRecord.URI_PRE_URN_NFC = 0x23;
|
|
|
|
/**
|
|
* Indicate if this record has its chunked flag set
|
|
*
|
|
* @return {!boolean} isChunked;
|
|
*/
|
|
NdefRecord.prototype.isChunked = function() {
|
|
return this.chunked;
|
|
};
|
|
|
|
/**
|
|
* Get the TNF for this record
|
|
*
|
|
* @return {!integer} tnf;
|
|
*/
|
|
NdefRecord.prototype.getTnf = function() {
|
|
return this.tnf;
|
|
};
|
|
|
|
/**
|
|
* Get the type from this NDEF Record
|
|
*
|
|
* @return {!Uint8Array} type;
|
|
*/
|
|
NdefRecord.prototype.getType = function() {
|
|
return this.type;
|
|
};
|
|
|
|
/**
|
|
* Get the id from this NDEF Record
|
|
*
|
|
* @return {?Uint8Array} id;
|
|
*/
|
|
NdefRecord.prototype.getId = function() {
|
|
return this.id;
|
|
};
|
|
|
|
/**
|
|
* Get the payload from this NDEF Record
|
|
*
|
|
* @return {!Uint8Array} payload;
|
|
*/
|
|
NdefRecord.prototype.getPayload = function() {
|
|
return this.payload;
|
|
};
|
|
|
|
/**
|
|
* Convert an NDEF Record to a byte array for writing
|
|
*
|
|
* @param {boolean} isBegin if this record starts a message
|
|
* @param {boolean} isEnd if this record concludes a message
|
|
* @return {Uint8Array} byte array representation
|
|
*/
|
|
NdefRecord.prototype.toByteArray = function(isBegin, isEnd) {
|
|
var shortRecord = true;
|
|
var hasId = true;
|
|
|
|
if(this.payload.length >= 255) {
|
|
shortRecord = false;
|
|
}
|
|
|
|
if(typeof this.id === "undefined" || this.id === null || this.id.length === 0) {
|
|
hasId = false;
|
|
}
|
|
|
|
var messageSize = 2; // control byte, type length
|
|
|
|
messageSize += this.type.length;
|
|
if(shortRecord) {
|
|
messageSize += 1; // single byte length
|
|
}
|
|
else {
|
|
messageSize += 4; // four byte length
|
|
}
|
|
|
|
if(hasId) {
|
|
messageSize += 1; // id length
|
|
messageSize += this.id.length;
|
|
}
|
|
|
|
messageSize += this.payload.length;
|
|
|
|
var result = new Uint8Array(messageSize);
|
|
|
|
// this mask should be unecessary
|
|
var firstByte = (this.tnf & NdefRecord.HDR_MASK_TNF);
|
|
|
|
if(shortRecord) {
|
|
firstByte |= NdefRecord.HDR_FLAG_SHORT_RECORD;
|
|
}
|
|
|
|
if(hasId) {
|
|
firstByte |= NdefRecord.HDR_FLAG_ID_LENGTH_PRESENT;
|
|
}
|
|
|
|
if(isBegin) {
|
|
firstByte |= NdefRecord.HDR_FLAG_MESSAGE_BEGIN;
|
|
}
|
|
|
|
if(isEnd) {
|
|
firstByte |= NdefRecord.HDR_FLAG_MESSAGE_END;
|
|
}
|
|
|
|
if(this.isChunked()) {
|
|
firstByte |= NdefRecord.HDR_FLAG_CHUNKED;
|
|
}
|
|
|
|
var count = 0;
|
|
|
|
result[count++] = firstByte;
|
|
result[count++] = this.type.length;
|
|
|
|
if(shortRecord) {
|
|
result[count++] = 0xff & this.payload.length;
|
|
}
|
|
else {
|
|
result[count++] = 0xff & (this.payload.length >>> 24);
|
|
result[count++] = 0xff & (this.payload.length >>> 16);
|
|
result[count++] = 0xff & (this.payload.length >>> 8);
|
|
result[count++] = 0xff & (this.payload.length >>> 0);
|
|
}
|
|
|
|
if(hasId) {
|
|
result[count++] = 0xff & this.id.length;
|
|
}
|
|
|
|
//add type bytes
|
|
for(var typeCntr = 0; typeCntr < this.type.length; typeCntr++) {
|
|
result[count++] = this.type[typeCntr];
|
|
}
|
|
|
|
if(hasId) {
|
|
for(var idCntr = 0; idCntr < this.id.length; idCntr++) {
|
|
result[count++] = this.id[idCntr];
|
|
}
|
|
}
|
|
|
|
for(var pldCntr = 0; pldCntr < this.payload.length; pldCntr++) {
|
|
result[count++] = this.payload[pldCntr];
|
|
}
|
|
|
|
if(result.length !== count) {
|
|
throw "NDEF Record was not successfully generated";
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Constructs an NdefMessage from an array of NdefRecord
|
|
*
|
|
* @constructor
|
|
* @param {!NdefRecord[]} ndefRecords the records this message contains
|
|
*/
|
|
var NdefMessage = function(ndefRecords) {
|
|
if(typeof ndefRecords === "undefined" ||
|
|
ndefRecords === null ||
|
|
ndefRecords.length === 0) {
|
|
throw "You must supply a non-zero length array of NdefRecords to construct an NdefMessage";
|
|
}
|
|
this.ndefRecords = ndefRecords;
|
|
};
|
|
|
|
|
|
/**
|
|
* Returns the array of records this NdefMessage contains
|
|
*
|
|
* @return {!NdefRecord[]} the NDEF records contained
|
|
*/
|
|
NdefMessage.prototype.getRecords = function() {
|
|
return this.ndefRecords;
|
|
};
|
|
|
|
/**
|
|
* Returns a byte array of the message ready to be written to a tag
|
|
*
|
|
* @return {!Uint8Array} byte array representation
|
|
*/
|
|
NdefMessage.prototype.toByteArray = function() {
|
|
var result = new Uint8Array(0);
|
|
for(var i = 0; i < this.ndefRecords.length; i++) {
|
|
// this is very inefficient, but it shouldn't really matter
|
|
// unless very large multi-record messages are being constructed
|
|
var recordBytes = this.ndefRecords[i].toByteArray(i===0, i===(this.ndefRecords.length - 1));
|
|
var grownArray = new Uint8Array(result.length + recordBytes.length);
|
|
grownArray.set(result);
|
|
grownArray.set(recordBytes,result.length);
|
|
result = grownArray;
|
|
}
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Creates an NdefMessage from a byte array
|
|
*
|
|
* @param {!Uint8Array} bytes
|
|
* @return {?NdefMessage} resulting message, null if a parse error occured
|
|
*/
|
|
NdefMessage.fromBytes = function(bytes) {
|
|
if(typeof bytes === "undefined" ||
|
|
bytes === null) {
|
|
throw "Bytes must be defined and non-null";
|
|
}
|
|
// fixes odd issue when normal arrays are passed
|
|
bytes = new Uint8Array(bytes);
|
|
// theoretical minimum is 3 bytes
|
|
if(bytes.length < 3) {
|
|
throw "Byte array is too short to contain any kind of NDEF message";
|
|
}
|
|
|
|
|
|
var throwOnMsgTooShort = function(bytes, idx) {
|
|
if(bytes.length < (idx+1)) {
|
|
throw "Message ended abruptly, trying to access index "+idx+" from an array of "+bytes.length+" items.";
|
|
}
|
|
};
|
|
|
|
var ndefRecords = [];
|
|
var done = false;
|
|
var foundStart = false;
|
|
|
|
var currentIndex = 0;
|
|
while(!done) {
|
|
if(currentIndex >= bytes.length) {
|
|
// ran out of bytes before message ended
|
|
throw "Ran out of bytes before message started";
|
|
}
|
|
|
|
var recordFirstByte = bytes[currentIndex];
|
|
|
|
|
|
// check for message beginning
|
|
foundStart = foundStart || NdefUtils.hasFlag(recordFirstByte,NdefRecord.HDR_FLAG_MESSAGE_BEGIN);
|
|
|
|
if(foundStart) {
|
|
done = NdefUtils.hasFlag(recordFirstByte,NdefRecord.HDR_FLAG_MESSAGE_END);
|
|
var isChunked = NdefUtils.hasFlag(recordFirstByte,NdefRecord.HDR_FLAG_CHUNKED);
|
|
var isShortRecord = NdefUtils.hasFlag(recordFirstByte,NdefRecord.HDR_FLAG_SHORT_RECORD);
|
|
var hasIdLength = NdefUtils.hasFlag(recordFirstByte,NdefRecord.HDR_FLAG_ID_LENGTH_PRESENT);
|
|
|
|
var tnf = recordFirstByte & NdefRecord.HDR_MASK_TNF;
|
|
|
|
var typeIdx = currentIndex + 1;
|
|
throwOnMsgTooShort(bytes,typeIdx);
|
|
var typeLength = bytes[typeIdx];
|
|
|
|
var payloadLength = 0;
|
|
var payloadLengthLength = isShortRecord ? 1 : 4;
|
|
var payloadLengthStartIdx = typeIdx+1;
|
|
|
|
if(isShortRecord) {
|
|
throwOnMsgTooShort(bytes,payloadLengthStartIdx);
|
|
payloadLength = bytes[payloadLengthStartIdx];
|
|
}
|
|
else {
|
|
throwOnMsgTooShort(bytes,payloadLengthStartIdx+3);
|
|
var valueArr = new Uint32Array(bytes.slice(payloadLengthStartIdx,payloadStartIdx+4));
|
|
payloadLength = valueArr[0];
|
|
}
|
|
|
|
var idLength = 0;
|
|
var idLengthStartIdx = payloadLengthStartIdx+payloadLengthLength;
|
|
|
|
throwOnMsgTooShort(bytes,idLengthStartIdx);
|
|
if(hasIdLength) {
|
|
idLength = bytes[idLengthStartIdx];
|
|
}
|
|
|
|
var idLengthEndIdx = idLengthStartIdx + (hasIdLength ? 1 : 0);
|
|
var typeEndIdx = idLengthEndIdx + typeLength;
|
|
throwOnMsgTooShort(bytes,typeEndIdx);
|
|
var type = new Uint8Array(bytes.buffer,idLengthEndIdx,typeLength);
|
|
|
|
var idStartIdx = typeEndIdx;
|
|
throwOnMsgTooShort(bytes,idStartIdx+idLength);
|
|
var id = new Uint8Array(bytes.buffer,idStartIdx,idLength);
|
|
|
|
var payloadStartIdx = idStartIdx+idLength;
|
|
throwOnMsgTooShort(bytes,payloadStartIdx+payloadLength-1);
|
|
var payload = new Uint8Array(bytes.buffer,payloadStartIdx,payloadLength);
|
|
|
|
currentIndex = payloadStartIdx+payloadLength;
|
|
ndefRecords.push(new NdefRecord(isChunked,tnf,type,id,payload));
|
|
}
|
|
else {
|
|
currentIndex++;
|
|
}
|
|
}
|
|
|
|
return new NdefMessage(ndefRecords);
|
|
};
|
|
|
|
/**
|
|
* Utility functions for Ndef operations and debugging
|
|
*
|
|
* @version 1.0.2
|
|
*/
|
|
var NdefRecordUtils = function() {
|
|
throw "Do not instantiate ndef record utils";
|
|
};
|
|
|
|
/**
|
|
* Resolves a URI into the appropriate NDEF record using
|
|
* the standard URI prefixes
|
|
*
|
|
* @param {string} uri uri to write
|
|
* @returns {NdefRecord} record with the uri prefix extracted
|
|
*/
|
|
NdefRecordUtils.createUriRecord = function(uri) {
|
|
var parsed = NdefRecordUtils.resolveUriToPrefix(uri);
|
|
var prefixCode = parsed.prefixCode;
|
|
var content = parsed.content;
|
|
|
|
var contentArray = NdefRecordUtils.stringToUint8Array(content);
|
|
|
|
var payload = new Uint8Array(contentArray.length+1);
|
|
payload[0] = prefixCode;
|
|
payload.set(contentArray,1);
|
|
|
|
return new NdefRecord(false,NdefRecord.TNF_WELL_KNOWN,new Uint8Array([0x55]),null,payload);
|
|
};
|
|
|
|
/**
|
|
* Resolves a string into the appropriate UTF8
|
|
* text record
|
|
*
|
|
* @param {string} content record contents
|
|
* @param {?string} language language code for record
|
|
* @returns {NdefRecord}
|
|
*/
|
|
NdefRecordUtils.createTextRecord = function(content, language) {
|
|
|
|
var contentArray = NdefRecordUtils.stringToUint8Array(content);
|
|
if(typeof language === "undefined") {
|
|
language = "en";
|
|
}
|
|
var languageArray = NdefRecordUtils.stringToUint8Array(language);
|
|
|
|
|
|
var payload = new Uint8Array(contentArray.length+languageArray.length+1);
|
|
payload[0] = languageArray.length;
|
|
payload.set(languageArray,1);
|
|
payload.set(contentArray,1+languageArray.length);
|
|
|
|
return new NdefRecord(false,NdefRecord.TNF_WELL_KNOWN,new Uint8Array([0x54]),null,payload);
|
|
};
|
|
|
|
/**
|
|
* Internal function for converting a string
|
|
* into a Uint8Array for creating NdefRecords
|
|
*
|
|
* @param {string} string record contents
|
|
* @return {Uint8Array} binary representation
|
|
*/
|
|
NdefRecordUtils.stringToUint8Array = function(string) {
|
|
var escstr = encodeURIComponent(string);
|
|
var binstr = escstr.replace(/%([0-9A-F]{2})/g, function(match, p1) {
|
|
return String.fromCharCode('0x' + p1);
|
|
});
|
|
var ua = new Uint8Array(binstr.length);
|
|
Array.prototype.forEach.call(binstr, function (ch, i) {
|
|
ua[i] = ch.charCodeAt(0);
|
|
});
|
|
return ua;
|
|
};
|
|
|
|
/**
|
|
* Internal function for converting a Uint8Array
|
|
* into a string for parsing NdefRecords
|
|
*
|
|
* @param {Uint8Array} binary representation
|
|
* @return {string} string record contents
|
|
*/
|
|
NdefRecordUtils.uint8ArrayToString = function(arr) {
|
|
var binstr = Array.prototype.map.call(arr, function (ch) {
|
|
return String.fromCharCode(ch);
|
|
}).join('');
|
|
|
|
var escstr = binstr.replace(/(.)/g, function (m, p) {
|
|
var code = p.charCodeAt(0).toString(16).toUpperCase();
|
|
if (code.length < 2) {
|
|
code = '0' + code;
|
|
}
|
|
return '%' + code;
|
|
});
|
|
return decodeURIComponent(escstr);
|
|
};
|
|
|
|
/**
|
|
* Resolves a URI into the appropriate prefix/data
|
|
* pair for NDEF writing
|
|
*
|
|
* @param {string} uri string of supposed uri
|
|
* @returns { prefixCode: int, prefix: string, content: string, fullUri: string}
|
|
*/
|
|
NdefRecordUtils.resolveUriString = function(uri) {
|
|
return NdefRecordUtils.resolveUriToPrefix(uri);
|
|
};
|
|
|
|
/**
|
|
* Resolves a URI into the appropriate prefix/data
|
|
* pair for NDEF writing
|
|
*
|
|
* @deprecated Use NdefRecordUtils.resolveUriString instead
|
|
* @param uri string of supposed uri
|
|
* @returns { prefixCode: int, prefix: string, content: string, fullUri: string}
|
|
*/
|
|
NdefRecordUtils.resolveUriToPrefix = function(url) {
|
|
var u = url;
|
|
var stripper = function(prefix,prefixCode,fullUri) {
|
|
return {
|
|
"prefixCode": prefixCode,
|
|
"prefix": prefix,
|
|
"content": fullUri.slice(prefix.length),
|
|
"fullUri": fullUri
|
|
};
|
|
};
|
|
|
|
if(u.startsWith("http")) {
|
|
if(u.startsWith("https://www.")) {
|
|
return stripper("https://www.",NdefRecord.URI_PRE_HTTPS_WWW,u);
|
|
} else if(u.startsWith("https://")) {
|
|
return stripper("https://",NdefRecord.URI_PRE_HTTPS,u);
|
|
} else if(u.startsWith("http://www.")) {
|
|
return stripper("http://www.",NdefRecord.URI_PRE_HTTP_WWW,u);
|
|
} else if(u.startsWith("http://")) {
|
|
return stripper("http://",NdefRecord.URI_PRE_HTTP,u);
|
|
}
|
|
}
|
|
else if(u.startsWith("ftp")) {
|
|
if(u.startsWith("ftp://ftp.")) {
|
|
return stripper("ftp://ftp.",NdefRecord.URI_PRE_FTP_FTP,u);
|
|
}
|
|
else if (u.startsWith("ftps://")) {
|
|
return stripper("ftps://",NdefRecord.URI_PRE_FTPS,u);
|
|
}
|
|
else if (u.startsWith("ftp://anonymous:anonymous@")) {
|
|
return stripper("ftp://anonymous:anonymous@",NdefRecord.URI_PRE_FTP_ANON,u);
|
|
}
|
|
else if(u.startsWith("ftp://")) {
|
|
return stripper("ftp://",NdefRecord.URI_PRE_FTP,u);
|
|
}
|
|
}
|
|
else if (u.startsWith("mailto:")) {
|
|
return stripper("mailto:",NdefRecord.URI_PRE_MAILTO,u);
|
|
}
|
|
else if (u.startsWith("tel:")) {
|
|
return stripper("tel:",NdefRecord.URI_PRE_TEL,u);
|
|
}
|
|
else if (u.startsWith("sftp://")) {
|
|
return stripper("sftp://",NdefRecord.URI_PRE_SFTP,u);
|
|
}
|
|
else if (u.startsWith("smb://")) {
|
|
return stripper("smb://",NdefRecord.URI_PRE_SMB,u);
|
|
}
|
|
else if (u.startsWith("nfs://")) {
|
|
return stripper("nfs://",NdefRecord.URI_PRE_NFS,u);
|
|
}
|
|
else if (u.startsWith("dav://")) {
|
|
return stripper("dav://",NdefRecord.URI_PRE_DAV,u);
|
|
}
|
|
else if (u.startsWith("news:")) {
|
|
return stripper("news:",NdefRecord.URI_PRE_NEWS,u);
|
|
}
|
|
else if (u.startsWith("telnet://")) {
|
|
return stripper("telnet://",NdefRecord.URI_PRE_TELNET,u);
|
|
}
|
|
else if (u.startsWith("imap:")) {
|
|
return stripper("imap:",NdefRecord.URI_PRE_IMAP,u);
|
|
}
|
|
else if (u.startsWith("rtsp://")) {
|
|
return stripper("rtsp://",NdefRecord.URI_PRE_RTSP,u);
|
|
}
|
|
else if (u.startsWith("pop:")) {
|
|
return stripper("pop:",NdefRecord.URI_PRE_POP,u);
|
|
}
|
|
else if (u.startsWith("sip:")) {
|
|
return stripper("sip:",NdefRecord.URI_PRE_SIP,u);
|
|
}
|
|
else if (u.startsWith("sips:")) {
|
|
return stripper("sips:",NdefRecord.URI_PRE_SIPS,u);
|
|
}
|
|
else if (u.startsWith("tftp:")) {
|
|
return stripper("tftp:",NdefRecord.URI_PRE_TFTP,u);
|
|
}
|
|
else if (u.startsWith("btspp://")) {
|
|
return stripper("btspp://",NdefRecord.URI_PRE_BTSPP,u);
|
|
}
|
|
else if (u.startsWith("btl2cap://")) {
|
|
return stripper("btl2cap://",NdefRecord.URI_PRE_BTL2CAP,u);
|
|
}
|
|
else if (u.startsWith("btgoep://")) {
|
|
return stripper("btgoep://",NdefRecord.URI_PRE_BTGOEP,u);
|
|
}
|
|
else if (u.startsWith("tcpobex://")) {
|
|
return stripper("tcpobex://",NdefRecord.URI_PRE_TCPOBEX,u);
|
|
}
|
|
else if (u.startsWith("irdaobex://")) {
|
|
return stripper("irdaobex://",NdefRecord.URI_PRE_IRDAOBEX,u);
|
|
}
|
|
else if (u.startsWith("file://")) {
|
|
return stripper("file://",NdefRecord.URI_PRE_FILE,u);
|
|
}
|
|
else if (u.startsWith("urn:epc:id:")) {
|
|
return stripper("urn:epc:id:",NdefRecord.URI_PRE_URN_EPC_ID,u);
|
|
}
|
|
else if (u.startsWith("urn:epc:tag:")) {
|
|
return stripper("urn:epc:tag:",NdefRecord.URI_PRE_URN_EPC_TAG,u);
|
|
}
|
|
else if (u.startsWith("urn:epc:pat:")) {
|
|
return stripper("urn:epc:pat:",NdefRecord.URI_PRE_URN_EPC_PAT,u);
|
|
}
|
|
else if (u.startsWith("urn:epc:raw:")) {
|
|
return stripper("urn:epc:raw:",NdefRecord.URI_PRE_EPC_RAW,u);
|
|
}
|
|
else if (u.startsWith("urn:epc:")) {
|
|
return stripper("urn:epc:",NdefRecord.URI_PRE_URN_EPC,u);
|
|
}
|
|
else if (u.startsWith("urn:nfc:")) {
|
|
return stripper("urn:nfc:",NdefRecord.URI_PRE_URN_NFC,u);
|
|
}
|
|
else if (u.startsWith("urn:")) {
|
|
return stripper("urn:",NdefRecord.URI_PRE_URN,u);
|
|
}
|
|
|
|
return stripper("",NdefRecord.URI_PRE_NONE,url);
|
|
};
|
|
|
|
/**
|
|
* Resolves the completely from a WELL_KNOWN URI record
|
|
* by prepending the appropriate URI prefix.
|
|
*
|
|
* @throws if record isn't a WELL_KNOWN URI
|
|
* @throws if the record prefix isn't known
|
|
* @param {NdefRecord} record to extract string
|
|
* @return {string} resulting URI string
|
|
*/
|
|
NdefRecordUtils.resolveUriRecordToString = function(ndefRecord) {
|
|
return NdefRecordUtils.resolveUrlFromPrefix(ndefRecord);
|
|
};
|
|
|
|
/**
|
|
* Resolves the completely from a WELL_KNOWN URI record
|
|
* by prepending the appropriate URI prefix.
|
|
*
|
|
* @deprecated use NdefRecordUtils.resolveUriToString instead
|
|
* @throws if record isn't a WELL_KNOWN URI
|
|
* @throws if the record prefix isn't known
|
|
* @param {NdefRecord} record to extract string
|
|
* @return {string} resulting URI string
|
|
*/
|
|
NdefRecordUtils.resolveUrlFromPrefix = function(ndefRecord) {
|
|
if(ndefRecord.getTnf() !== NdefRecord.TNF_WELL_KNOWN || (ndefRecord.getType())[0] !== 0x55) {
|
|
throw "Not a WELL_KNOWN URI record";
|
|
}
|
|
else {
|
|
var payload = ndefRecord.getPayload();
|
|
var prefixCode = payload[0];
|
|
var data = payload.slice(1);
|
|
var prefix = "";
|
|
|
|
switch(prefixCode) {
|
|
case NdefRecord.URI_PRE_NONE:
|
|
break;
|
|
case NdefRecord.URI_PRE_HTTP_WWW:
|
|
prefix = "http://www.";
|
|
break;
|
|
case NdefRecord.URI_PRE_HTTPS_WWW:
|
|
prefix = "https://www.";
|
|
break;
|
|
case NdefRecord.URI_PRE_HTTP:
|
|
prefix = "http://";
|
|
break;
|
|
case NdefRecord.URI_PRE_HTTPS:
|
|
prefix = "https://";
|
|
break;
|
|
case NdefRecord.URI_PRE_TEL:
|
|
prefix = "tel:";
|
|
break;
|
|
case NdefRecord.URI_PRE_MAILTO:
|
|
prefix = "mailto:";
|
|
break;
|
|
case NdefRecord.URI_PRE_FTP_ANON:
|
|
prefix = "ftp://anonymous:anonymous@";
|
|
break;
|
|
case NdefRecord.URI_PRE_FTP_FTP:
|
|
prefix = "ftp://ftp.";
|
|
break; // ftp://ftp
|
|
case NdefRecord.URI_PRE_FTPS:
|
|
prefix = "ftps://";
|
|
break;
|
|
case NdefRecord.URI_PRE_SFTP:
|
|
prefix = "sftp://";
|
|
break;
|
|
case NdefRecord.URI_PRE_SMB:
|
|
prefix = "smb://";
|
|
break;
|
|
case NdefRecord.URI_PRE_NFS:
|
|
prefix = "nfs://";
|
|
break;
|
|
case NdefRecord.URI_PRE_FTP:
|
|
prefix = "ftp://";
|
|
break;
|
|
case NdefRecord.URI_PRE_DAV:
|
|
prefix = "dav://";
|
|
break;
|
|
case NdefRecord.URI_PRE_NEWS:
|
|
prefix = "news:";
|
|
break;
|
|
case NdefRecord.URI_PRE_TELNET:
|
|
prefix = "telnet://";
|
|
break;
|
|
case NdefRecord.URI_PRE_IMAP:
|
|
prefix = "imap:";
|
|
break;
|
|
case NdefRecord.URI_PRE_RTSP:
|
|
prefix = "rtsp://";
|
|
break;
|
|
case NdefRecord.URI_PRE_URN:
|
|
prefix = "urn:";
|
|
break;
|
|
case NdefRecord.URI_PRE_POP:
|
|
prefix = "pop:";
|
|
break;
|
|
case NdefRecord.URI_PRE_SIP:
|
|
prefix = "sip:";
|
|
break;
|
|
case NdefRecord.URI_PRE_SIPS:
|
|
prefix = "sips:";
|
|
break;
|
|
case NdefRecord.URI_PRE_TFTP:
|
|
prefix = "tftp:";
|
|
break;
|
|
case NdefRecord.URI_PRE_BTSPP:
|
|
prefix = "btspp://";
|
|
break;
|
|
case NdefRecord.URI_PRE_BTL2CAP:
|
|
prefix = "btl2cap://";
|
|
break;
|
|
case NdefRecord.URI_PRE_BTGOEP:
|
|
prefix = "btgoep://";
|
|
break;
|
|
case NdefRecord.URI_PRE_TCPOBEX:
|
|
prefix = "tcpobex://";
|
|
break;
|
|
case NdefRecord.URI_PRE_IRDAOBEX:
|
|
prefix = "irdaobex://";
|
|
break;
|
|
case NdefRecord.URI_PRE_FILE:
|
|
prefix = "file://";
|
|
break;
|
|
case NdefRecord.URI_PRE_URN_EPC_ID:
|
|
prefix = "urn:epc:id:";
|
|
break;
|
|
case NdefRecord.URI_PRE_URN_EPC_TAG:
|
|
prefix = "urn:epc:tag:";
|
|
break;
|
|
case NdefRecord.URI_PRE_URN_EPC_PAT:
|
|
prefix = "urn:epc:pat:";
|
|
break;
|
|
case NdefRecord.URI_PRE_URN_EPC_RAW:
|
|
prefix = "urn:epc:raw:";
|
|
break;
|
|
case NdefRecord.URI_PRE_URN_EPC:
|
|
prefix = "urn:epc:";
|
|
break;
|
|
case NdefRecord.URI_PRE_URN_NFC:
|
|
prefix = "urn:nfc:";
|
|
break;
|
|
default:
|
|
throw "Invalid URI code";
|
|
}
|
|
|
|
return prefix + NdefRecordUtils.uint8ArrayToString(data);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Resolves a WELL_KNOWN text record
|
|
* extracting the language code and content
|
|
*
|
|
* @throws if record isn't a WELL_KNOWN TEXT
|
|
* @throws if the language code bytes are invalid
|
|
* @returns {language: language code string, content: text contained} or null
|
|
*/
|
|
NdefRecordUtils.resolveTextRecord = function(ndefRecord) {
|
|
if(ndefRecord.getTnf() !== NdefRecord.TNF_WELL_KNOWN || (ndefRecord.getType())[0] !== 0x54) {
|
|
throw "Not a WELL_KNOWN text record";
|
|
}
|
|
else {
|
|
var payload = ndefRecord.getPayload();
|
|
if(payload.length === 0) {
|
|
throw "Missing error code";
|
|
}
|
|
|
|
//masking out the utf bit
|
|
var languageCodeLength = payload[0] & 0x3F;
|
|
if(payload.length < (languageCodeLength+1)) {
|
|
throw "Payload too short to contain language code";
|
|
}
|
|
|
|
var language = NdefRecordUtils.uint8ArrayToString(payload.slice(1,1+languageCodeLength));
|
|
var content = "";
|
|
|
|
if(payload.length > 1+languageCodeLength) {
|
|
content = NdefRecordUtils.uint8ArrayToString(payload.slice(1+languageCodeLength));
|
|
}
|
|
|
|
return {language: language, content: content};
|
|
}
|
|
};
|
|
|
|
var Ndef = {};
|
|
Ndef.Message = NdefMessage;
|
|
Ndef.Record = NdefRecord;
|
|
Ndef.Utils = NdefRecordUtils;
|
|
return Ndef;
|
|
}));
|