зеркало из https://github.com/mozilla/gecko-dev.git
Bug 749856 - Part 6: add WSP/MMS encoding, r=philikon
This commit is contained in:
Родитель
7dd2b5099d
Коммит
53dac012d5
|
@ -50,6 +50,16 @@ let BooleanValue = {
|
|||
|
||||
return value == 128;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* A wrapped object to store encoded raw data.
|
||||
* @param value
|
||||
* A boolean value to be encoded.
|
||||
*/
|
||||
encode: function encode(data, value) {
|
||||
WSP.Octet.encode(data, value ? 128 : 129);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -105,6 +115,19 @@ let HeaderField = {
|
|||
return WSP.decodeAlternatives(data, options,
|
||||
MmsHeader, WSP.ApplicationHeader);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* A wrapped object to store encoded raw data.
|
||||
* @param octet
|
||||
* Octet value to be encoded.
|
||||
* @param options
|
||||
* Extra context for encoding.
|
||||
*/
|
||||
encode: function encode(data, value, options) {
|
||||
WSP.encodeAlternatives(data, value, options,
|
||||
MmsHeader, WSP.ApplicationHeader);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -155,6 +178,32 @@ let MmsHeader = {
|
|||
value: value,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* A wrapped object to store encoded raw data.
|
||||
* @param header
|
||||
* An object containing two attributes: a string-typed `name` and a
|
||||
* `value` of arbitrary type.
|
||||
*
|
||||
* @throws CodeError if got an empty header name.
|
||||
* @throws NotWellKnownEncodingError if the well-known header field number is
|
||||
* not registered or supported.
|
||||
*/
|
||||
encode: function encode(data, header) {
|
||||
if (!header.name) {
|
||||
throw new WSP.CodeError("MMS-header: empty header name");
|
||||
}
|
||||
|
||||
let entry = MMS_HEADER_FIELDS[header.name.toLowerCase()];
|
||||
if (!entry) {
|
||||
throw new WSP.NotWellKnownEncodingError(
|
||||
"MMS-header: not well known header " + header.name);
|
||||
}
|
||||
|
||||
WSP.ShortInteger.encode(data, entry.number);
|
||||
entry.coder.encode(data, header.value);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -639,6 +688,22 @@ let MessageTypeValue = {
|
|||
|
||||
throw new WSP.CodeError("Message-type-value: invalid type " + type);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* A wrapped object to store encoded raw data.
|
||||
* @param type
|
||||
* A numeric message type value to be encoded.
|
||||
*
|
||||
* @throws CodeError if the value is not in the range 128..151.
|
||||
*/
|
||||
encode: function encode(data, type) {
|
||||
if ((type < 128) || (type > 151)) {
|
||||
throw new WSP.CodeError("Message-type-value: invalid type " + type);
|
||||
}
|
||||
|
||||
WSP.Octet.encode(data, type);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -866,6 +931,22 @@ let StatusValue = {
|
|||
|
||||
throw new WSP.CodeError("Status-value: invalid status " + status);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* A wrapped object to store encoded raw data.
|
||||
* @param value
|
||||
* A numeric status value to be encoded.
|
||||
*
|
||||
* @throws CodeError if the value is not in the range 128..135.
|
||||
*/
|
||||
encode: function encode(data, value) {
|
||||
if ((value < 128) || (value > 135)) {
|
||||
throw new WSP.CodeError("Status-value: invalid status " + value);
|
||||
}
|
||||
|
||||
WSP.Octet.encode(data, value);
|
||||
},
|
||||
};
|
||||
|
||||
let PduHelper = {
|
||||
|
@ -985,6 +1066,107 @@ let PduHelper = {
|
|||
|
||||
return msg;
|
||||
},
|
||||
|
||||
/**
|
||||
* Convert javascript Array to an nsIInputStream.
|
||||
*/
|
||||
convertArrayToInputStream: function convertDataToInputStream(array) {
|
||||
let storageStream = Cc["@mozilla.org/storagestream;1"]
|
||||
.createInstance(Ci.nsIStorageStream);
|
||||
storageStream.init(4096, array.length, null);
|
||||
|
||||
let boStream = Cc["@mozilla.org/binaryoutputstream;1"]
|
||||
.createInstance(Ci.nsIBinaryOutputStream);
|
||||
boStream.setOutputStream(storageStream.getOutputStream(0));
|
||||
boStream.writeByteArray(array, array.length)
|
||||
boStream.close();
|
||||
|
||||
return storageStream.newInputStream(0);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param data [optional]
|
||||
* A wrapped object to store encoded raw data. Created if undefined.
|
||||
* @param headers
|
||||
* A dictionary object containing multiple name/value mapping.
|
||||
*
|
||||
* @return the passed data parameter or a created one.
|
||||
*/
|
||||
encodeHeaders: function encodeHeaders(data, headers) {
|
||||
if (!data) {
|
||||
data = {array: [], offset: 0};
|
||||
}
|
||||
|
||||
function encodeHeader(name) {
|
||||
HeaderField.encode(data, {name: name, value: headers[name]});
|
||||
}
|
||||
|
||||
function encodeHeaderIfExists(name) {
|
||||
// Header value could be zero or null.
|
||||
if (headers[name] !== undefined) {
|
||||
encodeHeader(name);
|
||||
}
|
||||
}
|
||||
|
||||
// `In the encoding of the header fields, the order of the fields is not
|
||||
// significant, except that X-Mms-Message-Type, X-Mms-Transaction-ID (when
|
||||
// present) and X-Mms-MMS-Version MUST be at the beginning of the message
|
||||
// headers, in that order, and if the PDU contains a message body the
|
||||
// Content Type MUST be the last header field, followed by message body.`
|
||||
// ~ OMA-TS-MMS_ENC-V1_3-20110913-A section 7
|
||||
encodeHeader("x-mms-message-type");
|
||||
encodeHeaderIfExists("x-mms-transaction-id");
|
||||
encodeHeaderIfExists("x-mms-mms-version");
|
||||
|
||||
for (let key in headers) {
|
||||
if ((key == "x-mms-message-type")
|
||||
|| (key == "x-mms-transaction-id")
|
||||
|| (key == "x-mms-mms-version")
|
||||
|| (key == "content-type")) {
|
||||
continue;
|
||||
}
|
||||
encodeHeader(key);
|
||||
}
|
||||
|
||||
encodeHeaderIfExists("content-type");
|
||||
|
||||
// Remove extra space consumed during encoding.
|
||||
while (data.array.length > data.offset) {
|
||||
data.array.pop();
|
||||
}
|
||||
|
||||
return data;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param multiStream
|
||||
* An exsiting nsIMultiplexInputStream.
|
||||
* @param msg
|
||||
* A MMS message object.
|
||||
*
|
||||
* @return An instance of nsIMultiplexInputStream or null in case of errors.
|
||||
*/
|
||||
compose: function compose(multiStream, msg) {
|
||||
if (!multiStream) {
|
||||
multiStream = Cc["@mozilla.org/io/multiplex-input-stream;1"]
|
||||
.createInstance(Ci.nsIMultiplexInputStream);
|
||||
}
|
||||
|
||||
try {
|
||||
// Validity checks
|
||||
this.checkMandatoryFields(msg);
|
||||
|
||||
let data = this.encodeHeaders(null, msg.headers);
|
||||
debug("Composed PDU Header: " + JSON.stringify(data.array));
|
||||
let headerStream = this.convertArrayToInputStream(data.array);
|
||||
multiStream.appendStream(headerStream);
|
||||
|
||||
return multiStream;
|
||||
} catch (e) {
|
||||
debug("Failed to compose MMS message, error message: " + e.message);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const MMS_PDU_TYPES = (function () {
|
||||
|
|
|
@ -181,6 +181,33 @@ function decodeAlternatives(data, options) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for encoding multiple alternative forms.
|
||||
*
|
||||
* @param data
|
||||
* A wrapped object to store encoded raw data.
|
||||
* @param value
|
||||
* Object value of arbitrary type to be encoded.
|
||||
* @param options
|
||||
* Extra context for encoding.
|
||||
*/
|
||||
function encodeAlternatives(data, value, options) {
|
||||
let begin = data.offset;
|
||||
for (let i = 3; i < arguments.length; i++) {
|
||||
try {
|
||||
arguments[i].encode(data, value, options);
|
||||
return;
|
||||
} catch (e) {
|
||||
// Throw the last exception we get
|
||||
if (i == (arguments.length - 1)) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
data.offset = begin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let Octet = {
|
||||
/**
|
||||
* @param data
|
||||
|
@ -247,6 +274,21 @@ let Octet = {
|
|||
|
||||
return expected;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* A wrapped object to store encoded raw data.
|
||||
* @param octet
|
||||
* Octet value to be encoded.
|
||||
*/
|
||||
encode: function encode(data, octet) {
|
||||
if (data.offset >= data.array.length) {
|
||||
data.array.push(octet);
|
||||
data.offset++;
|
||||
} else {
|
||||
data.array[data.offset++] = octet;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -323,6 +365,26 @@ let Text = {
|
|||
data.offset = begin;
|
||||
return " ";
|
||||
},
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* A wrapped object to store encoded raw data.
|
||||
* @param text
|
||||
* String text of one character to be encoded.
|
||||
*
|
||||
* @throws CodeError if a control character got.
|
||||
*/
|
||||
encode: function encode(data, text) {
|
||||
if (!text) {
|
||||
throw new CodeError("Text: empty string");
|
||||
}
|
||||
|
||||
let code = text.charCodeAt(0);
|
||||
if ((code < CTLS) || (code == DEL) || (code > 255)) {
|
||||
throw new CodeError("Text: invalid char code " + code);
|
||||
}
|
||||
Octet.encode(data, code);
|
||||
},
|
||||
};
|
||||
|
||||
let NullTerminatedTexts = {
|
||||
|
@ -345,6 +407,21 @@ let NullTerminatedTexts = {
|
|||
return str;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* A wrapped object to store encoded raw data.
|
||||
* @param str
|
||||
* A String to be encoded.
|
||||
*/
|
||||
encode: function encode(data, str) {
|
||||
if (str) {
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
Text.encode(data, str.charAt(i));
|
||||
}
|
||||
}
|
||||
Octet.encode(data, 0);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -385,6 +462,37 @@ let Token = {
|
|||
|
||||
throw new CodeError("Token: invalid char code " + code);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* A wrapped object to store encoded raw data.
|
||||
* @param token
|
||||
* String text of one character to be encoded.
|
||||
*
|
||||
* @throws CodeError if an invalid character got.
|
||||
*/
|
||||
encode: function encode(data, token) {
|
||||
if (!token) {
|
||||
throw new CodeError("Token: empty string");
|
||||
}
|
||||
|
||||
let code = token.charCodeAt(0);
|
||||
if ((code < ASCIIS) && (code >= CTLS)) {
|
||||
if ((code == HT) || (code == SP)
|
||||
|| (code == 34) || (code == 40) || (code == 41) // ASCII "()
|
||||
|| (code == 44) || (code == 47) // ASCII ,/
|
||||
|| ((code >= 58) && (code <= 64)) // ASCII :;<=>?@
|
||||
|| ((code >= 91) && (code <= 93)) // ASCII [\]
|
||||
|| (code == 123) || (code == 125)) { // ASCII {}
|
||||
// Fallback to throw CodeError
|
||||
} else {
|
||||
Octet.encode(data, token.charCodeAt(0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new CodeError("Token: invalid char code " + code);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -464,6 +572,26 @@ let TextString = {
|
|||
data.offset = begin;
|
||||
return NullTerminatedTexts.decode(data);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* A wrapped object to store encoded raw data.
|
||||
* @param str
|
||||
* A String to be encoded.
|
||||
*/
|
||||
encode: function encode(data, str) {
|
||||
if (!str) {
|
||||
Octet.encode(data, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
let firstCharCode = str.charCodeAt(0);
|
||||
if (firstCharCode >= 128) {
|
||||
Octet.encode(data, 127);
|
||||
}
|
||||
|
||||
NullTerminatedTexts.encode(data, str);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -489,6 +617,21 @@ let TokenText = {
|
|||
return str;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* A wrapped object to store encoded raw data.
|
||||
* @param str
|
||||
* A String to be encoded.
|
||||
*/
|
||||
encode: function encode(data, str) {
|
||||
if (str) {
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
Token.encode(data, str.charAt(i));
|
||||
}
|
||||
}
|
||||
Octet.encode(data, 0);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -544,6 +687,22 @@ let ShortInteger = {
|
|||
|
||||
return (value & 0x7F);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* A wrapped object to store encoded raw data.
|
||||
* @param value
|
||||
* A numeric value to be encoded.
|
||||
*
|
||||
* @throws CodeError if the octet read is larger-equal than 0x80.
|
||||
*/
|
||||
encode: function encode(data, value) {
|
||||
if (value & 0x80) {
|
||||
throw new CodeError("Short-integer: invalid value " + value);
|
||||
}
|
||||
|
||||
Octet.encode(data, value | 0x80);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1152,6 +1311,24 @@ let ApplicationHeader = {
|
|||
value: value,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* A wrapped object to store encoded raw data.
|
||||
* @param header
|
||||
* An object containing two attributes: a string-typed `name` and a
|
||||
* `value` of arbitrary type.
|
||||
*
|
||||
* @throws CodeError if got an empty header name.
|
||||
*/
|
||||
encode: function encode(data, header) {
|
||||
if (!header.name) {
|
||||
throw new CodeError("Application-header: empty header name");
|
||||
}
|
||||
|
||||
TokenText.encode(data, header.name);
|
||||
TextString.encode(data, header.value);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1908,6 +2085,7 @@ const EXPORTED_SYMBOLS = ALL_CONST_SYMBOLS.concat([
|
|||
"ensureHeader",
|
||||
"skipValue",
|
||||
"decodeAlternatives",
|
||||
"encodeAlternatives",
|
||||
|
||||
// Decoders
|
||||
"Octet",
|
||||
|
|
|
@ -95,6 +95,52 @@ function wsp_decode_test(target, input, expect, exception) {
|
|||
wsp_decode_test_ex(func, input, expect, exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test customized WSP PDU encoding.
|
||||
*
|
||||
* @param func
|
||||
* Encoding func under test. It should return an encoded octet array if
|
||||
* invoked.
|
||||
* @param input
|
||||
* An object to be encoded.
|
||||
* @param expect
|
||||
* Expected encoded octet array, use null if expecting errors instead.
|
||||
* @param exception
|
||||
* Expected class name of thrown exception. Use null for no throws.
|
||||
*/
|
||||
function wsp_encode_test_ex(func, input, expect, exception) {
|
||||
let data = {array: [], offset: 0};
|
||||
do_check_throws(wsp_test_func.bind(null, func.bind(null, data), input,
|
||||
expect), exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test default WSP PDU encoding.
|
||||
*
|
||||
* @param target
|
||||
* Target decoding object, ie. TextValue.
|
||||
* @param input
|
||||
* An object to be encoded.
|
||||
* @param expect
|
||||
* Expected encoded octet array, use null if expecting errors instead.
|
||||
* @param exception
|
||||
* Expected class name of thrown exception. Use null for no throws.
|
||||
*/
|
||||
function wsp_encode_test(target, input, expect, exception) {
|
||||
let func = function encode_func(data, input) {
|
||||
target.encode(data, input);
|
||||
|
||||
// Remove extra space consumed during encoding.
|
||||
while (data.array.length > data.offset) {
|
||||
data.array.pop();
|
||||
}
|
||||
|
||||
return data.array;
|
||||
}
|
||||
|
||||
wsp_encode_test_ex(func, input, expect, exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param str
|
||||
* A string.
|
||||
|
|
|
@ -29,6 +29,15 @@ add_test(function test_BooleanValue_decode() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
//// BooleanValue.encode ////
|
||||
|
||||
add_test(function test_BooleanValue_encode() {
|
||||
wsp_encode_test(MMS.BooleanValue, true, [128]);
|
||||
wsp_encode_test(MMS.BooleanValue, false, [129]);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
//
|
||||
// Test target: Address
|
||||
//
|
||||
|
@ -83,6 +92,19 @@ add_test(function test_HeaderField_decode() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
//// HeaderField.encode ////
|
||||
|
||||
add_test(function test_HeaderField_encode() {
|
||||
// Test for MmsHeader
|
||||
wsp_encode_test(MMS.HeaderField, {name: "X-Mms-Message-Type",
|
||||
value: MMS.MMS_PDU_TYPE_SEND_REQ},
|
||||
[0x80 | 0x0C, MMS.MMS_PDU_TYPE_SEND_REQ]);
|
||||
// Test for ApplicationHeader
|
||||
wsp_encode_test(MMS.HeaderField, {name: "a", value: "B"}, [97, 0, 66, 0]);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
//
|
||||
// Test target: MmsHeader
|
||||
//
|
||||
|
@ -98,6 +120,24 @@ add_test(function test_MmsHeader_decode() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
//// MmsHeader.encode ////
|
||||
|
||||
add_test(function test_MmsHeader_encode() {
|
||||
// Test for empty header name:
|
||||
wsp_encode_test(MMS.MmsHeader, {name: undefined, value: null}, null, "CodeError");
|
||||
wsp_encode_test(MMS.MmsHeader, {name: null, value: null}, null, "CodeError");
|
||||
wsp_encode_test(MMS.MmsHeader, {name: "", value: null}, null, "CodeError");
|
||||
// Test for non-well-known header name:
|
||||
wsp_encode_test(MMS.MmsHeader, {name: "X-No-Such-Field", value: null},
|
||||
null, "NotWellKnownEncodingError");
|
||||
// Test for normal header
|
||||
wsp_encode_test(MMS.MmsHeader, {name: "X-Mms-Message-Type",
|
||||
value: MMS.MMS_PDU_TYPE_SEND_REQ},
|
||||
[0x80 | 0x0C, MMS.MMS_PDU_TYPE_SEND_REQ]);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
//
|
||||
// Test target: ContentClassValue
|
||||
//
|
||||
|
@ -225,7 +265,7 @@ add_test(function test_EncodedStringValue_decode() {
|
|||
|
||||
let raw;
|
||||
try {
|
||||
let raw = conv.convertToByteArray(str);
|
||||
let raw = conv.convertToByteArray(str).concat([0]);
|
||||
if (raw[0] >= 128) {
|
||||
wsp_decode_test(MMS.EncodedStringValue,
|
||||
[raw.length + 2, 0x80 | entry.number, 127].concat(raw), str);
|
||||
|
@ -352,6 +392,20 @@ add_test(function test_MessageTypeValue_decode() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
//// MessageTypeValue.encode ////
|
||||
|
||||
add_test(function test_MessageTypeValue_encode() {
|
||||
for (let i = 0; i < 256; i++) {
|
||||
if ((i >= 128) && (i <= 151)) {
|
||||
wsp_encode_test(MMS.MessageTypeValue, i, [i]);
|
||||
} else {
|
||||
wsp_encode_test(MMS.MessageTypeValue, i, null, "CodeError");
|
||||
}
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
//
|
||||
// Test target: MmFlagsValue
|
||||
//
|
||||
|
@ -482,3 +536,17 @@ add_test(function test_StatusValue_decode() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
//// StatusValue.encode ////
|
||||
|
||||
add_test(function test_StatusValue_encode() {
|
||||
for (let i = 0; i < 256; i++) {
|
||||
if ((i >= 128) && (i <= 135)) {
|
||||
wsp_encode_test(MMS.StatusValue, i, [i]);
|
||||
} else {
|
||||
wsp_encode_test(MMS.StatusValue, i, null, "CodeError");
|
||||
}
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
|
|
|
@ -111,6 +111,16 @@ add_test(function test_Octet_decodeEqualTo() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
//// Octet.encode ////
|
||||
|
||||
add_test(function test_Octet_encode() {
|
||||
for (let i = 0; i < 256; i++) {
|
||||
wsp_encode_test(WSP.Octet, i, [i]);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
//
|
||||
// Test target: Text
|
||||
//
|
||||
|
@ -135,6 +145,20 @@ add_test(function test_Text_decode() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
//// Text.encode ////
|
||||
|
||||
add_test(function test_Text_encode() {
|
||||
for (let i = 0; i < 256; i++) {
|
||||
if ((i < WSP.CTLS) || (i == WSP.DEL)) {
|
||||
wsp_encode_test(WSP.Text, String.fromCharCode(i), null, "CodeError");
|
||||
} else {
|
||||
wsp_encode_test(WSP.Text, String.fromCharCode(i), [i]);
|
||||
}
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
//
|
||||
// Test target: NullTerminatedTexts
|
||||
//
|
||||
|
@ -155,19 +179,30 @@ add_test(function test_NullTerminatedTexts_decode() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
//// NullTerminatedTexts.encode ////
|
||||
|
||||
add_test(function test_NullTerminatedTexts_encode() {
|
||||
wsp_encode_test(WSP.NullTerminatedTexts, "", [0]);
|
||||
wsp_encode_test(WSP.NullTerminatedTexts, "Hello, World!",
|
||||
strToCharCodeArray("Hello, World!"));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
//
|
||||
// Test target: Token
|
||||
//
|
||||
|
||||
let TOKEN_SEPS = "()<>@,;:\\\"/[]?={} \t";
|
||||
|
||||
//// Token.decode ////
|
||||
|
||||
add_test(function test_Token_decode() {
|
||||
let seps = "()<>@,;:\\\"/[]?={} \t";
|
||||
for (let i = 0; i < 256; i++) {
|
||||
if (i == 0) {
|
||||
wsp_decode_test(WSP.Token, [i], null, "NullCharError");
|
||||
} else if ((i < WSP.CTLS) || (i >= WSP.ASCIIS)
|
||||
|| (seps.indexOf(String.fromCharCode(i)) >= 0)) {
|
||||
|| (TOKEN_SEPS.indexOf(String.fromCharCode(i)) >= 0)) {
|
||||
wsp_decode_test(WSP.Token, [i], null, "CodeError");
|
||||
} else {
|
||||
wsp_decode_test(WSP.Token, [i], String.fromCharCode(i));
|
||||
|
@ -177,6 +212,21 @@ add_test(function test_Token_decode() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
//// Token.encode ////
|
||||
|
||||
add_test(function test_Token_encode() {
|
||||
for (let i = 0; i < 256; i++) {
|
||||
if ((i < WSP.CTLS) || (i >= WSP.ASCIIS)
|
||||
|| (TOKEN_SEPS.indexOf(String.fromCharCode(i)) >= 0)) {
|
||||
wsp_encode_test(WSP.Token, String.fromCharCode(i), null, "CodeError");
|
||||
} else {
|
||||
wsp_encode_test(WSP.Token, String.fromCharCode(i), [i]);
|
||||
}
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
//
|
||||
// Test target: URIC
|
||||
//
|
||||
|
@ -218,6 +268,17 @@ add_test(function test_TextString_decode() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
//// TextString.encode ////
|
||||
|
||||
add_test(function test_TextString_encode() {
|
||||
// Test quoted string
|
||||
wsp_encode_test(WSP.TextString, String.fromCharCode(128), [127, 128, 0]);
|
||||
// Test normal string
|
||||
wsp_encode_test(WSP.TextString, "Mozilla", strToCharCodeArray("Mozilla"));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
//
|
||||
// Test target: TokenText
|
||||
//
|
||||
|
@ -232,6 +293,14 @@ add_test(function test_TokenText_decode() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
//// TokenText.encode ////
|
||||
|
||||
add_test(function test_TokenText_encode() {
|
||||
wsp_encode_test(WSP.TokenText, "B2G", strToCharCodeArray("B2G"));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
//
|
||||
// Test target: QuotedString
|
||||
//
|
||||
|
@ -266,6 +335,20 @@ add_test(function test_ShortInteger_decode() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
//// ShortInteger.encode ////
|
||||
|
||||
add_test(function test_ShortInteger_encode() {
|
||||
for (let i = 0; i < 256; i++) {
|
||||
if (i & 0x80) {
|
||||
wsp_encode_test(WSP.ShortInteger, i, null, "CodeError");
|
||||
} else {
|
||||
wsp_encode_test(WSP.ShortInteger, i, [0x80 | i]);
|
||||
}
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
//
|
||||
// Test target: LongInteger
|
||||
//
|
||||
|
@ -624,6 +707,27 @@ add_test(function test_ApplicationHeader_decode() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
//// ApplicationHeader.encode ////
|
||||
|
||||
add_test(function test_ApplicationHeader_encode() {
|
||||
// Test invalid header name string:
|
||||
wsp_encode_test(WSP.ApplicationHeader, {name: undefined, value: "asdf"}, null, "CodeError");
|
||||
wsp_encode_test(WSP.ApplicationHeader, {name: null, value: "asdf"}, null, "CodeError");
|
||||
wsp_encode_test(WSP.ApplicationHeader, {name: "", value: "asdf"}, null, "CodeError");
|
||||
wsp_encode_test(WSP.ApplicationHeader, {name: "a b", value: "asdf"}, null, "CodeError");
|
||||
// Test value string:
|
||||
wsp_encode_test(WSP.ApplicationHeader, {name: "asdf", value: undefined},
|
||||
strToCharCodeArray("asdf").concat([0]));
|
||||
wsp_encode_test(WSP.ApplicationHeader, {name: "asdf", value: null},
|
||||
strToCharCodeArray("asdf").concat([0]));
|
||||
wsp_encode_test(WSP.ApplicationHeader, {name: "asdf", value: ""},
|
||||
strToCharCodeArray("asdf").concat([0]));
|
||||
wsp_encode_test(WSP.ApplicationHeader, {name: "asdf", value: "fdsa"},
|
||||
strToCharCodeArray("asdf").concat(strToCharCodeArray("fdsa")));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
//
|
||||
// Test target: FieldName
|
||||
//
|
||||
|
|
Загрузка…
Ссылка в новой задаче