toolkit/components/url-classifier/content/moz/protocol4.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 # This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 # License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 4
michael@0 5
michael@0 6 // A helper class that knows how to parse from and serialize to
michael@0 7 // protocol4. This is a simple, historical format used by some Google
michael@0 8 // interfaces, for example the Toolbar (i.e., ancient services).
michael@0 9 //
michael@0 10 // Protocol4 consists of a newline-separated sequence of name/value
michael@0 11 // pairs (strings). Each line consists of the name, the value length,
michael@0 12 // and the value itself, all separated by colons. Example:
michael@0 13 //
michael@0 14 // foo:6:barbaz\n
michael@0 15 // fritz:33:issickofdynamicallytypedlanguages\n
michael@0 16
michael@0 17
michael@0 18 /**
michael@0 19 * This class knows how to serialize/deserialize maps to/from their
michael@0 20 * protocol4 representation.
michael@0 21 *
michael@0 22 * @constructor
michael@0 23 */
michael@0 24 function G_Protocol4Parser() {
michael@0 25 this.debugZone = "protocol4";
michael@0 26
michael@0 27 this.protocol4RegExp_ = new RegExp("([^:]+):\\d+:(.*)$");
michael@0 28 this.newlineRegExp_ = new RegExp("(\\r)?\\n");
michael@0 29 }
michael@0 30
michael@0 31 /**
michael@0 32 * Create a map from a protocol4 string. Silently skips invalid lines.
michael@0 33 *
michael@0 34 * @param text String holding the protocol4 representation
michael@0 35 *
michael@0 36 * @returns Object as an associative array with keys and values
michael@0 37 * given in text. The empty object is returned if none
michael@0 38 * are parsed.
michael@0 39 */
michael@0 40 G_Protocol4Parser.prototype.parse = function(text) {
michael@0 41
michael@0 42 var response = {};
michael@0 43 if (!text)
michael@0 44 return response;
michael@0 45
michael@0 46 // Responses are protocol4: (repeated) name:numcontentbytes:content\n
michael@0 47 var lines = text.split(this.newlineRegExp_);
michael@0 48 for (var i = 0; i < lines.length; i++)
michael@0 49 if (this.protocol4RegExp_.exec(lines[i]))
michael@0 50 response[RegExp.$1] = RegExp.$2;
michael@0 51
michael@0 52 return response;
michael@0 53 }
michael@0 54
michael@0 55 /**
michael@0 56 * Create a protocol4 string from a map (object). Throws an error on
michael@0 57 * an invalid input.
michael@0 58 *
michael@0 59 * @param map Object as an associative array with keys and values
michael@0 60 * given as strings.
michael@0 61 *
michael@0 62 * @returns text String holding the protocol4 representation
michael@0 63 */
michael@0 64 G_Protocol4Parser.prototype.serialize = function(map) {
michael@0 65 if (typeof map != "object")
michael@0 66 throw new Error("map must be an object");
michael@0 67
michael@0 68 var text = "";
michael@0 69 for (var key in map) {
michael@0 70 if (typeof map[key] != "string")
michael@0 71 throw new Error("Keys and values must be strings");
michael@0 72
michael@0 73 text += key + ":" + map[key].length + ":" + map[key] + "\n";
michael@0 74 }
michael@0 75
michael@0 76 return text;
michael@0 77 }
michael@0 78
michael@0 79 #ifdef DEBUG
michael@0 80 /**
michael@0 81 * Cheesey unittests
michael@0 82 */
michael@0 83 function TEST_G_Protocol4Parser() {
michael@0 84 if (G_GDEBUG) {
michael@0 85 var z = "protocol4 UNITTEST";
michael@0 86 G_debugService.enableZone(z);
michael@0 87
michael@0 88 G_Debug(z, "Starting");
michael@0 89
michael@0 90 var p = new G_Protocol4Parser();
michael@0 91
michael@0 92 function isEmpty(map) {
michael@0 93 for (var key in map)
michael@0 94 return false;
michael@0 95 return true;
michael@0 96 };
michael@0 97
michael@0 98 G_Assert(z, isEmpty(p.parse(null)), "Parsing null broken");
michael@0 99 G_Assert(z, isEmpty(p.parse("")), "Parsing nothing broken");
michael@0 100
michael@0 101 var t = "foo:3:bar";
michael@0 102 G_Assert(z, p.parse(t)["foo"] === "bar", "Parsing one line broken");
michael@0 103
michael@0 104 t = "foo:3:bar\n";
michael@0 105 G_Assert(z, p.parse(t)["foo"] === "bar", "Parsing line with lf broken");
michael@0 106
michael@0 107 t = "foo:3:bar\r\n";
michael@0 108 G_Assert(z, p.parse(t)["foo"] === "bar", "Parsing with crlf broken");
michael@0 109
michael@0 110
michael@0 111 t = "foo:3:bar\nbar:3:baz\r\nbom:3:yaz\n";
michael@0 112 G_Assert(z, p.parse(t)["foo"] === "bar", "First in multiline");
michael@0 113 G_Assert(z, p.parse(t)["bar"] === "baz", "Second in multiline");
michael@0 114 G_Assert(z, p.parse(t)["bom"] === "yaz", "Third in multiline");
michael@0 115 G_Assert(z, p.parse(t)[""] === undefined, "Nonexistent in multiline");
michael@0 116
michael@0 117 // Test serialization
michael@0 118
michael@0 119 var original = {
michael@0 120 "1": "1",
michael@0 121 "2": "2",
michael@0 122 "foobar": "baz",
michael@0 123 "hello there": "how are you?" ,
michael@0 124 };
michael@0 125 var deserialized = p.parse(p.serialize(original));
michael@0 126 for (var key in original)
michael@0 127 G_Assert(z, original[key] === deserialized[key],
michael@0 128 "Trouble (de)serializing " + key);
michael@0 129
michael@0 130 G_Debug(z, "PASSED");
michael@0 131 }
michael@0 132 }
michael@0 133 #endif

mercurial