blob: 2965a9c743b21d033c057f6aef9a3537420ab262 [file] [log] [blame]
Wentao Shangbd63e462012-12-03 16:19:33 -08001/**
Meki Cherkaouif441d3a2012-04-22 15:17:52 -07002 * This class contains utilities to help parse the data
Jeff Thompson146d7de2012-11-17 16:15:28 -08003 * author: Meki Cheraoui, Jeff Thompson
Jeff Thompson745026e2012-10-13 12:49:20 -07004 * See COPYING for copyright and distribution information.
Meki Cherkaouif441d3a2012-04-22 15:17:52 -07005 */
6
7var DataUtils = function DataUtils(){
8
9
10};
11
12
13/*
14 * NOTE THIS IS CURRENTLY NOT BEHING USED
15 *
16 */
17
Meki Cherkaoui8f173612012-06-06 01:05:40 -070018DataUtils.keyStr = "ABCDEFGHIJKLMNOP" +
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070019 "QRSTUVWXYZabcdef" +
20 "ghijklmnopqrstuv" +
21 "wxyz0123456789+/" +
22 "=";
23
Meki Cherkaoui8f173612012-06-06 01:05:40 -070024
25/**
26 * Raw String to Base 64
27 */
Meki Cherkaouib21911b2012-05-18 16:54:37 -070028DataUtils.stringtoBase64=function stringtoBase64(input) {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070029 input = escape(input);
30 var output = "";
31 var chr1, chr2, chr3 = "";
32 var enc1, enc2, enc3, enc4 = "";
33 var i = 0;
34
35 do {
36 chr1 = input.charCodeAt(i++);
37 chr2 = input.charCodeAt(i++);
38 chr3 = input.charCodeAt(i++);
39
40 enc1 = chr1 >> 2;
41 enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
42 enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
43 enc4 = chr3 & 63;
44
45 if (isNaN(chr2)) {
46 enc3 = enc4 = 64;
47 } else if (isNaN(chr3)) {
48 enc4 = 64;
49 }
50
51 output = output +
Meki Cherkaoui8f173612012-06-06 01:05:40 -070052 DataUtils.keyStr.charAt(enc1) +
53 DataUtils.keyStr.charAt(enc2) +
54 DataUtils.keyStr.charAt(enc3) +
55 DataUtils.keyStr.charAt(enc4);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070056 chr1 = chr2 = chr3 = "";
57 enc1 = enc2 = enc3 = enc4 = "";
58 } while (i < input.length);
59
60 return output;
61 }
62
Meki Cherkaoui8f173612012-06-06 01:05:40 -070063/**
64 * Base 64 to Raw String
65 */
Meki Cherkaouib21911b2012-05-18 16:54:37 -070066DataUtils.base64toString = function base64toString(input) {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070067 var output = "";
68 var chr1, chr2, chr3 = "";
69 var enc1, enc2, enc3, enc4 = "";
70 var i = 0;
71
72 // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
73 var base64test = /[^A-Za-z0-9\+\/\=]/g;
Jeff Thompson74957972012-10-07 21:14:32 -070074 /* Test for invalid characters. */
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070075 if (base64test.exec(input)) {
76 alert("There were invalid base64 characters in the input text.\n" +
77 "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
78 "Expect errors in decoding.");
79 }
Meki Cherkaoui8f173612012-06-06 01:05:40 -070080
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070081 input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
82
83 do {
Meki Cherkaoui8f173612012-06-06 01:05:40 -070084 enc1 = DataUtils.keyStr.indexOf(input.charAt(i++));
85 enc2 = DataUtils.keyStr.indexOf(input.charAt(i++));
86 enc3 = DataUtils.keyStr.indexOf(input.charAt(i++));
87 enc4 = DataUtils.keyStr.indexOf(input.charAt(i++));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070088
89 chr1 = (enc1 << 2) | (enc2 >> 4);
90 chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
91 chr3 = ((enc3 & 3) << 6) | enc4;
92
93 output = output + String.fromCharCode(chr1);
94
95 if (enc3 != 64) {
96 output = output + String.fromCharCode(chr2);
97 }
98 if (enc4 != 64) {
99 output = output + String.fromCharCode(chr3);
100 }
101
102 chr1 = chr2 = chr3 = "";
103 enc1 = enc2 = enc3 = enc4 = "";
104
105 } while (i < input.length);
106
107 return unescape(output);
108 };
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700109
110//byte []
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700111
112/**
113 * NOT WORKING!!!!!
114 *
115 * Unsiged Long Number to Byte Array
116 */
117
118 /*
119DataUtils.unsignedLongToByteArray= function( value) {
120
121 if(LOG>4)console.log('INPUT IS '+value);
122
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700123 if( 0 == value )
124 return [0];
125
126 if( 0 <= value && value <= 0x00FF ) {
127 //byte []
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700128 var bb = new Array(1);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700129 bb[0] = (value & 0x00FF);
130 return bb;
131 }
132
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700133 if(LOG>4) console.log('type of value is '+typeof value);
134 if(LOG>4) console.log('value is '+value);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700135 //byte []
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700136 var out = null;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700137 //int
138 var offset = -1;
139 for(var i = 7; i >=0; --i) {
140 //byte
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700141 console.log(i);
142 console.log('value is '+value);
143 console.log('(value >> (i * 8)) '+ (value >> (i * 8)) );
144 console.log(' ((value >> (i * 8)) & 0xFF) '+ ((value >> (i * 8)) & 0xFF) );
145
146 var b = ((value >> (i * 8)) & 0xFF) ;
147
148 if(LOG>4) console.log('b is '+b);
149
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700150 if( out == null && b != 0 ) {
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700151 //out = new byte[i+1];
152 out = new Array(i+1);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700153 offset = i;
154 }
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700155
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700156 if( out != null )
157 out[ offset - i ] = b;
158 }
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700159 if(LOG>4)console.log('OUTPUT IS ');
160 if(LOG>4)console.log(out);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700161 return out;
162}
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700163*/
164
165/**
166 * NOT WORKING!!!!!
167 *
168 * Unsiged Long Number to Byte Array
169 *//*
170DataUtils.byteArrayToUnsignedLong = function(//final byte []
171 src) {
172 if(LOG>4) console.log('INPUT IS ');
173 if(LOG>4) console.log(src);
174
175 var value = 0;
176 for(var i = 0; i < src.length; i++) {
177 value = value << 8;
178 // Java will assume the byte is signed, so extend it and trim it.
179
180
181 var b = ((src[i]) & 0xFF );
182 value |= b;
183 }
184
185 if(LOG>4) console.log('OUTPUT IS ');
186
187 if(LOG>4) console.log(value);
188
189 return value;
190 }*/
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700191
192
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700193/**
194 * Hex String to Byte Array
195 */
196 //THIS IS NOT WORKING
197/*
198DataUtils.HexStringtoByteArray = function(str) {
Meki Cherkaouiabb973b2012-05-09 14:25:57 -0700199 var byteArray = [];
200 for (var i = 0; i < str.length; i++)
201 if (str.charCodeAt(i) <= 0x7F)
202 byteArray.push(str.charCodeAt(i));
203 else {
204 var h = encodeURIComponent(str.charAt(i)).substr(1).split('%');
205 for (var j = 0; j < h.length; j++)
206 byteArray.push(parseInt(h[j], 16));
207 }
208 return byteArray;
209};
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700210*/
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700211
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700212/**
Jeff Thompson34a585f2012-11-11 19:16:02 -0800213 * Uint8Array to Hex String
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700214 */
Meki Cherkaouib21911b2012-05-18 16:54:37 -0700215//http://ejohn.org/blog/numbers-hex-and-colors/
Wentao Shang0e291c82012-12-02 23:36:29 -0800216DataUtils.toHex = function(args){
217 if (LOG>4) console.log('ABOUT TO CONVERT '+ args);
218 //console.log(args);
Jeff Thompson8b44aa12012-11-11 18:39:47 -0800219 var ret = "";
Wentao Shang0e291c82012-12-02 23:36:29 -0800220 for ( var i = 0; i < args.length; i++ )
221 ret += (args[i] < 16 ? "0" : "") + args[i].toString(16);
Jeff Thompson8b44aa12012-11-11 18:39:47 -0800222 if (LOG>4) console.log('Converted to: ' + ret);
223 return ret; //.toUpperCase();
Meki Cherkaouib21911b2012-05-18 16:54:37 -0700224}
225
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700226/**
Jeff Thompsona566e792012-10-06 21:46:34 -0700227 * Raw string to hex string.
228 */
Wentao Shang0e291c82012-12-02 23:36:29 -0800229DataUtils.stringToHex = function(args){
Jeff Thompsona566e792012-10-06 21:46:34 -0700230 var ret = "";
Wentao Shang0e291c82012-12-02 23:36:29 -0800231 for (var i = 0; i < args.length; ++i) {
232 var value = args.charCodeAt(i);
Jeff Thompsona566e792012-10-06 21:46:34 -0700233 ret += (value < 16 ? "0" : "") + value.toString(16);
234 }
235 return ret;
236}
237
238/**
Jeff Thompson34a585f2012-11-11 19:16:02 -0800239 * Uint8Array to raw string.
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700240 */
Wentao Shang0e291c82012-12-02 23:36:29 -0800241DataUtils.toString = function(args){
Meki Cherkaouib21911b2012-05-18 16:54:37 -0700242 //console.log(arguments);
243 var ret = "";
Wentao Shang0e291c82012-12-02 23:36:29 -0800244 for ( var i = 0; i < args.length; i++ )
245 ret += String.fromCharCode(args[i]);
Meki Cherkaouib21911b2012-05-18 16:54:37 -0700246 return ret;
247}
248
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700249/**
Jeff Thompson34a585f2012-11-11 19:16:02 -0800250 * Hex String to Uint8Array.
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700251 */
Jeff Thompson34a585f2012-11-11 19:16:02 -0800252DataUtils.toNumbers = function(str) {
253 if (typeof str == 'string') {
254 var ret = new Uint8Array(Math.floor(str.length / 2));
255 var i = 0;
256 str.replace(/(..)/g, function(str) {
257 ret[i++] = parseInt(str, 16);
258 });
259 return ret;
Meki Cherkaouib21911b2012-05-18 16:54:37 -0700260 }
261}
262
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700263/**
Jeff Thompson74957972012-10-07 21:14:32 -0700264 * Hex String to raw string.
265 */
266DataUtils.hexToRawString = function(str) {
267 if(typeof str =='string') {
268 var ret = "";
269 str.replace(/(..)/g, function(s) {
270 ret += String.fromCharCode(parseInt(s, 16));
271 });
272 return ret;
273 }
274}
275
276/**
Jeff Thompson34a585f2012-11-11 19:16:02 -0800277 * Raw String to Uint8Array.
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700278 */
279DataUtils.toNumbersFromString = function( str ){
Jeff Thompson34a585f2012-11-11 19:16:02 -0800280 var bytes = new Uint8Array(str.length);
Meki Cherkaouib21911b2012-05-18 16:54:37 -0700281 for(var i=0;i<str.length;i++)
282 bytes[i] = str.charCodeAt(i);
283 return bytes;
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700284}
285
Jeff Thompson95f935b2012-11-11 20:29:01 -0800286/*
Jeff Thompsonadba4912012-11-15 22:29:13 -0800287 * Encode str as utf8 and return as Uint8Array.
Jeff Thompson3a782592012-11-18 17:34:33 -0800288 * TODO: Use TextEncoder when available.
Jeff Thompsonadba4912012-11-15 22:29:13 -0800289 */
290DataUtils.stringToUtf8Array = function(str) {
291 return DataUtils.toNumbersFromString(str2rstr_utf8(str));
292}
293
294/*
Jeff Thompson5e6ab9a2012-11-28 21:19:59 -0800295 * arrays is an array of Uint8Array. Return a new Uint8Array which is the concatenation of all.
Jeff Thompson95f935b2012-11-11 20:29:01 -0800296 */
Jeff Thompson5e6ab9a2012-11-28 21:19:59 -0800297DataUtils.concatArrays = function(arrays) {
298 var totalLength = 0;
299 for (var i = 0; i < arrays.length; ++i)
300 totalLength += arrays[i].length;
301
302 var result = new Uint8Array(totalLength);
303 var offset = 0;
304 for (var i = 0; i < arrays.length; ++i) {
305 result.set(arrays[i], offset);
306 offset += arrays[i].length;
307 }
308 return result;
309
Jeff Thompson95f935b2012-11-11 20:29:01 -0800310}
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700311
Jeff Thompson3a782592012-11-18 17:34:33 -0800312// TODO: Take Uint8Array and use TextDecoder when available.
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700313DataUtils.decodeUtf8 = function (utftext) {
314 var string = "";
315 var i = 0;
Jeff Thompsondeda95e2012-10-21 19:17:56 -0700316 var c = 0;
317 var c1 = 0;
318 var c2 = 0;
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700319
320 while ( i < utftext.length ) {
321
322 c = utftext.charCodeAt(i);
323
324 if (c < 128) {
325 string += String.fromCharCode(c);
326 i++;
327 }
328 else if((c > 191) && (c < 224)) {
329 c2 = utftext.charCodeAt(i+1);
330 string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
331 i += 2;
332 }
333 else {
334 c2 = utftext.charCodeAt(i+1);
Jeff Thompsondeda95e2012-10-21 19:17:56 -0700335 var c3 = utftext.charCodeAt(i+2);
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700336 string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
337 i += 3;
338 }
339
340 }
341
342 return string;
343 };
344
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700345//NOT WORKING
346/*
347DataUtils.getUTF8StringFromBytes = function(bytes) {
348
349 bytes = toString(bytes);
350
351 var ix = 0;
352
353 if( bytes.slice(0,3) == "\xEF\xBB\xBF") {
354 ix = 3;
355 }
356
357 var string = "";
358 for( ; ix < bytes.length; ix++ ) {
359 var byte1 = bytes[ix].charCodeAt(0);
360 if( byte1 < 0x80 ) {
361 string += String.fromCharCode(byte1);
362 } else if( byte1 >= 0xC2 && byte1 < 0xE0 ) {
363 var byte2 = bytes[++ix].charCodeAt(0);
364 string += String.fromCharCode(((byte1&0x1F)<<6) + (byte2&0x3F));
365 } else if( byte1 >= 0xE0 && byte1 < 0xF0 ) {
366 var byte2 = bytes[++ix].charCodeAt(0);
367 var byte3 = bytes[++ix].charCodeAt(0);
368 string += String.fromCharCode(((byte1&0xFF)<<12) + ((byte2&0x3F)<<6) + (byte3&0x3F));
369 } else if( byte1 >= 0xF0 && byte1 < 0xF5) {
370 var byte2 = bytes[++ix].charCodeAt(0);
371 var byte3 = bytes[++ix].charCodeAt(0);
372 var byte4 = bytes[++ix].charCodeAt(0);
373 var codepoint = ((byte1&0x07)<<18) + ((byte2&0x3F)<<12)+ ((byte3&0x3F)<<6) + (byte4&0x3F);
374 codepoint -= 0x10000;
375 string += String.fromCharCode(
376 (codepoint>>10) + 0xD800,
377 (codepoint&0x3FF) + 0xDC00
378 );
379 }
380 }
381
382 return string;
383}*/
384
Jeff Thompsonbb976092012-09-29 17:01:38 -0700385/**
386 * Return true if a1 and a2 are the same length with equal elements.
387 */
388DataUtils.arraysEqual = function(a1, a2){
389 if (a1.length != a2.length)
390 return false;
391
392 for (var i = 0; i < a1.length; ++i) {
393 if (a1[i] != a2[i])
394 return false;
395 }
396
397 return true;
Jeff Thompsondeda95e2012-10-21 19:17:56 -0700398};
399
400/*
Jeff Thompson95f935b2012-11-11 20:29:01 -0800401 * Convert the big endian Uint8Array to an unsigned int.
Jeff Thompsondeda95e2012-10-21 19:17:56 -0700402 * Don't check for overflow.
403 */
404DataUtils.bigEndianToUnsignedInt = function(bytes) {
405 var result = 0;
406 for (var i = 0; i < bytes.length; ++i) {
407 result <<= 8;
408 result += bytes[i];
409 }
410 return result;
411};
412
413/*
Jeff Thompson95f935b2012-11-11 20:29:01 -0800414 * Convert the int value to a new big endian Uint8Array and return.
415 * If value is 0 or negative, return Uint8Array(0).
Jeff Thompsondeda95e2012-10-21 19:17:56 -0700416 */
417DataUtils.nonNegativeIntToBigEndian = function(value) {
Jeff Thompson40df2fa2012-11-24 09:59:12 -0800418 value = Math.round(value);
Jeff Thompsondeda95e2012-10-21 19:17:56 -0700419 if (value <= 0)
Jeff Thompson95f935b2012-11-11 20:29:01 -0800420 return new Uint8Array(0);
Jeff Thompsondeda95e2012-10-21 19:17:56 -0700421
Jeff Thompson95f935b2012-11-11 20:29:01 -0800422 // Assume value is not over 64 bits.
Jeff Thompson40df2fa2012-11-24 09:59:12 -0800423 var size = 8;
424 var result = new Uint8Array(size);
Jeff Thompson95f935b2012-11-11 20:29:01 -0800425 var i = 0;
Jeff Thompsondeda95e2012-10-21 19:17:56 -0700426 while (value != 0) {
Jeff Thompson40df2fa2012-11-24 09:59:12 -0800427 ++i;
428 result[size - i] = value & 0xff;
Jeff Thompsondeda95e2012-10-21 19:17:56 -0700429 value >>= 8;
430 }
Jeff Thompson40df2fa2012-11-24 09:59:12 -0800431 return result.subarray(size - i, size);
Jeff Thompsondeda95e2012-10-21 19:17:56 -0700432};