1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/** @fileoverview Various string utility functions */
6'use strict';
7
8/**
9 * Converts a string to an array of bytes.
10 * @param {string} s The string to convert.
11 * @param {(Array|Uint8Array)=} bytes The Array-like object into which to store
12 *     the bytes. A new Array will be created if not provided.
13 * @return {(Array|Uint8Array)} An array of bytes representing the string.
14 */
15function UTIL_StringToBytes(s, bytes) {
16  bytes = bytes || new Array(s.length);
17  for (var i = 0; i < s.length; ++i)
18    bytes[i] = s.charCodeAt(i);
19  return bytes;
20}
21
22function UTIL_BytesToString(b) {
23  return String.fromCharCode.apply(null, b);
24}
25
26function UTIL_BytesToHex(b) {
27  if (!b) return '(null)';
28  var hexchars = '0123456789ABCDEF';
29  var hexrep = new Array(b.length * 2);
30
31  for (var i = 0; i < b.length; ++i) {
32    hexrep[i * 2 + 0] = hexchars.charAt((b[i] >> 4) & 15);
33    hexrep[i * 2 + 1] = hexchars.charAt(b[i] & 15);
34  }
35  return hexrep.join('');
36}
37
38function UTIL_BytesToHexWithSeparator(b, sep) {
39  var hexchars = '0123456789ABCDEF';
40  var stride = 2 + (sep ? 1 : 0);
41  var hexrep = new Array(b.length * stride);
42
43  for (var i = 0; i < b.length; ++i) {
44    if (sep) hexrep[i * stride + 0] = sep;
45    hexrep[i * stride + stride - 2] = hexchars.charAt((b[i] >> 4) & 15);
46    hexrep[i * stride + stride - 1] = hexchars.charAt(b[i] & 15);
47  }
48  return (sep ? hexrep.slice(1) : hexrep).join('');
49}
50
51function UTIL_HexToBytes(h) {
52  var hexchars = '0123456789ABCDEFabcdef';
53  var res = new Uint8Array(h.length / 2);
54  for (var i = 0; i < h.length; i += 2) {
55    if (hexchars.indexOf(h.substring(i, i + 1)) == -1) break;
56    res[i / 2] = parseInt(h.substring(i, i + 2), 16);
57  }
58  return res;
59}
60
61function UTIL_equalArrays(a, b) {
62  if (!a || !b) return false;
63  if (a.length != b.length) return false;
64  var accu = 0;
65  for (var i = 0; i < a.length; ++i)
66    accu |= a[i] ^ b[i];
67  return accu === 0;
68}
69
70function UTIL_ltArrays(a, b) {
71  if (a.length < b.length) return true;
72  if (a.length > b.length) return false;
73  for (var i = 0; i < a.length; ++i) {
74    if (a[i] < b[i]) return true;
75    if (a[i] > b[i]) return false;
76  }
77  return false;
78}
79
80function UTIL_gtArrays(a, b) {
81  return UTIL_ltArrays(b, a);
82}
83
84function UTIL_geArrays(a, b) {
85  return !UTIL_ltArrays(a, b);
86}
87
88function UTIL_unionArrays(a, b) {
89  var obj = {};
90  for (var i = 0; i < a.length; i++) {
91    obj[a[i]] = a[i];
92  }
93  for (var i = 0; i < b.length; i++) {
94    obj[b[i]] = b[i];
95  }
96  var union = [];
97  for (var k in obj) {
98    union.push(obj[k]);
99  }
100  return union;
101}
102
103function UTIL_getRandom(a) {
104  var tmp = new Array(a);
105  var rnd = new Uint8Array(a);
106  window.crypto.getRandomValues(rnd);  // Yay!
107  for (var i = 0; i < a; ++i) tmp[i] = rnd[i] & 255;
108  return tmp;
109}
110
111function UTIL_setFavicon(icon) {
112  // Construct a new favion link tag
113  var faviconLink = document.createElement('link');
114  faviconLink.rel = 'Shortcut Icon';
115  faviconLink.type = 'image/x-icon';
116  faviconLink.href = icon;
117
118  // Remove the old favion, if it exists
119  var head = document.getElementsByTagName('head')[0];
120  var links = head.getElementsByTagName('link');
121  for (var i = 0; i < links.length; i++) {
122    var link = links[i];
123    if (link.type == faviconLink.type && link.rel == faviconLink.rel) {
124      head.removeChild(link);
125    }
126  }
127
128  // Add in the new one
129  head.appendChild(faviconLink);
130}
131
132// Erase all entries in array
133function UTIL_clear(a) {
134  if (a instanceof Array) {
135    for (var i = 0; i < a.length; ++i)
136      a[i] = 0;
137  }
138}
139
140// hr:min:sec.milli string
141function UTIL_time() {
142  var d = new Date();
143  var m = '000' + d.getMilliseconds();
144  var s = d.toTimeString().substring(0, 8) + '.' + m.substring(m.length - 3);
145  return s;
146}
147var UTIL_events = [];
148var UTIL_max_events = 500;
149
150function UTIL_fmt(s) {
151  var line = UTIL_time() + ' ' + s;
152  if (UTIL_events.push(line) > UTIL_max_events) {
153    // Drop from head.
154    UTIL_events.splice(0, UTIL_events.length - UTIL_max_events);
155  }
156  return line;
157}
158