ByteRepr.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. /* globals app */
  2. /**
  3. * Byte representation operations.
  4. *
  5. * @author n1474335 [n1474335@gmail.com]
  6. * @copyright Crown Copyright 2016
  7. * @license Apache-2.0
  8. *
  9. * @namespace
  10. */
  11. var ByteRepr = {
  12. /**
  13. * @constant
  14. * @default
  15. */
  16. DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF"],
  17. /**
  18. * @constant
  19. * @default
  20. */
  21. HEX_DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"],
  22. /**
  23. * @constant
  24. * @default
  25. */
  26. BIN_DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "None"],
  27. /**
  28. * To Hex operation.
  29. *
  30. * @param {byteArray} input
  31. * @param {Object[]} args
  32. * @returns {string}
  33. */
  34. runToHex: function(input, args) {
  35. var delim = Utils.charRep[args[0] || "Space"];
  36. return Utils.toHex(input, delim, 2);
  37. },
  38. /**
  39. * From Hex operation.
  40. *
  41. * @param {string} input
  42. * @param {Object[]} args
  43. * @returns {byteArray}
  44. */
  45. runFromHex: function(input, args) {
  46. var delim = args[0] || "Space";
  47. return Utils.fromHex(input, delim, 2);
  48. },
  49. /**
  50. * @constant
  51. * @default
  52. */
  53. CHARCODE_BASE: 16,
  54. /**
  55. * To Charcode operation.
  56. *
  57. * @param {string} input
  58. * @param {Object[]} args
  59. * @returns {string}
  60. */
  61. runToCharcode: function(input, args) {
  62. var delim = Utils.charRep[args[0] || "Space"],
  63. base = args[1],
  64. output = "",
  65. padding = 2,
  66. ordinal;
  67. if (base < 2 || base > 36) {
  68. throw "Error: Base argument must be between 2 and 36";
  69. }
  70. for (var i = 0; i < input.length; i++) {
  71. ordinal = Utils.ord(input[i]);
  72. if (base === 16) {
  73. if (ordinal < 256) padding = 2;
  74. else if (ordinal < 65536) padding = 4;
  75. else if (ordinal < 16777216) padding = 6;
  76. else if (ordinal < 4294967296) padding = 8;
  77. else padding = 2;
  78. if (padding > 2) app.options.attemptHighlight = false;
  79. output += Utils.hex(ordinal, padding) + delim;
  80. } else {
  81. app.options.attemptHighlight = false;
  82. output += ordinal.toString(base) + delim;
  83. }
  84. }
  85. return output.slice(0, -delim.length);
  86. },
  87. /**
  88. * From Charcode operation.
  89. *
  90. * @param {string} input
  91. * @param {Object[]} args
  92. * @returns {byteArray}
  93. */
  94. runFromCharcode: function(input, args) {
  95. var delim = Utils.charRep[args[0] || "Space"],
  96. base = args[1],
  97. bites = input.split(delim),
  98. i = 0;
  99. if (base < 2 || base > 36) {
  100. throw "Error: Base argument must be between 2 and 36";
  101. }
  102. if (base !== 16) {
  103. app.options.attemptHighlight = false;
  104. }
  105. // Split into groups of 2 if the whole string is concatenated and
  106. // too long to be a single character
  107. if (bites.length === 1 && input.length > 17) {
  108. bites = [];
  109. for (i = 0; i < input.length; i += 2) {
  110. bites.push(input.slice(i, i+2));
  111. }
  112. }
  113. var latin1 = "";
  114. for (i = 0; i < bites.length; i++) {
  115. latin1 += Utils.chr(parseInt(bites[i], base));
  116. }
  117. return Utils.strToByteArray(latin1);
  118. },
  119. /**
  120. * Highlight to hex
  121. *
  122. * @param {Object[]} pos
  123. * @param {number} pos[].start
  124. * @param {number} pos[].end
  125. * @param {Object[]} args
  126. * @returns {Object[]} pos
  127. */
  128. highlightTo: function(pos, args) {
  129. var delim = Utils.charRep[args[0] || "Space"],
  130. len = delim === "\r\n" ? 1 : delim.length;
  131. pos[0].start = pos[0].start * (2 + len);
  132. pos[0].end = pos[0].end * (2 + len) - len;
  133. // 0x and \x are added to the beginning if they are selected, so increment the positions accordingly
  134. if (delim === "0x" || delim === "\\x") {
  135. pos[0].start += 2;
  136. pos[0].end += 2;
  137. }
  138. return pos;
  139. },
  140. /**
  141. * Highlight to hex
  142. *
  143. * @param {Object[]} pos
  144. * @param {number} pos[].start
  145. * @param {number} pos[].end
  146. * @param {Object[]} args
  147. * @returns {Object[]} pos
  148. */
  149. highlightFrom: function(pos, args) {
  150. var delim = Utils.charRep[args[0] || "Space"],
  151. len = delim === "\r\n" ? 1 : delim.length,
  152. width = len + 2;
  153. // 0x and \x are added to the beginning if they are selected, so increment the positions accordingly
  154. if (delim === "0x" || delim === "\\x") {
  155. if (pos[0].start > 1) pos[0].start -= 2;
  156. else pos[0].start = 0;
  157. if (pos[0].end > 1) pos[0].end -= 2;
  158. else pos[0].end = 0;
  159. }
  160. pos[0].start = pos[0].start === 0 ? 0 : Math.round(pos[0].start / width);
  161. pos[0].end = pos[0].end === 0 ? 0 : Math.ceil(pos[0].end / width);
  162. return pos;
  163. },
  164. /**
  165. * To Decimal operation.
  166. *
  167. * @param {byteArray} input
  168. * @param {Object[]} args
  169. * @returns {string}
  170. */
  171. runToDecimal: function(input, args) {
  172. var delim = Utils.charRep[args[0]];
  173. return input.join(delim);
  174. },
  175. /**
  176. * From Decimal operation.
  177. *
  178. * @param {string} input
  179. * @param {Object[]} args
  180. * @returns {byteArray}
  181. */
  182. runFromDecimal: function(input, args) {
  183. var delim = Utils.charRep[args[0]];
  184. var byteStr = input.split(delim), output = [];
  185. if (byteStr[byteStr.length-1] === "")
  186. byteStr = byteStr.slice(0, byteStr.length-1);
  187. for (var i = 0; i < byteStr.length; i++) {
  188. output[i] = parseInt(byteStr[i], 10);
  189. }
  190. return output;
  191. },
  192. /**
  193. * To Binary operation.
  194. *
  195. * @param {byteArray} input
  196. * @param {Object[]} args
  197. * @returns {string}
  198. */
  199. runToBinary: function(input, args) {
  200. var delim = Utils.charRep[args[0] || "Space"],
  201. output = "",
  202. padding = 8;
  203. for (var i = 0; i < input.length; i++) {
  204. output += Utils.pad(input[i].toString(2), padding) + delim;
  205. }
  206. if (delim.length) {
  207. return output.slice(0, -delim.length);
  208. } else {
  209. return output;
  210. }
  211. },
  212. /**
  213. * From Binary operation.
  214. *
  215. * @param {string} input
  216. * @param {Object[]} args
  217. * @returns {byteArray}
  218. */
  219. runFromBinary: function(input, args) {
  220. if (args[0] !== "None") {
  221. var delimRegex = Utils.regexRep[args[0] || "Space"];
  222. input = input.replace(delimRegex, "");
  223. }
  224. var output = [];
  225. var byteLen = 8;
  226. for (var i = 0; i < input.length; i += byteLen) {
  227. output.push(parseInt(input.substr(i, byteLen), 2));
  228. }
  229. return output;
  230. },
  231. /**
  232. * Highlight to binary
  233. *
  234. * @param {Object[]} pos
  235. * @param {number} pos[].start
  236. * @param {number} pos[].end
  237. * @param {Object[]} args
  238. * @returns {Object[]} pos
  239. */
  240. highlightToBinary: function(pos, args) {
  241. var delim = Utils.charRep[args[0] || "Space"];
  242. pos[0].start = pos[0].start * (8 + delim.length);
  243. pos[0].end = pos[0].end * (8 + delim.length) - delim.length;
  244. return pos;
  245. },
  246. /**
  247. * Highlight from binary
  248. *
  249. * @param {Object[]} pos
  250. * @param {number} pos[].start
  251. * @param {number} pos[].end
  252. * @param {Object[]} args
  253. * @returns {Object[]} pos
  254. */
  255. highlightFromBinary: function(pos, args) {
  256. var delim = Utils.charRep[args[0] || "Space"];
  257. pos[0].start = pos[0].start === 0 ? 0 : Math.floor(pos[0].start / (8 + delim.length));
  258. pos[0].end = pos[0].end === 0 ? 0 : Math.ceil(pos[0].end / (8 + delim.length));
  259. return pos;
  260. },
  261. /**
  262. * @constant
  263. * @default
  264. */
  265. HEX_CONTENT_CONVERT_WHICH: ["Only special chars", "Only special chars including spaces", "All chars"],
  266. /**
  267. * @constant
  268. * @default
  269. */
  270. HEX_CONTENT_SPACES_BETWEEN_BYTES: false,
  271. /**
  272. * To Hex Content operation.
  273. *
  274. * @param {byteArray} input
  275. * @param {Object[]} args
  276. * @returns {string}
  277. */
  278. runToHexContent: function(input, args) {
  279. var convert = args[0];
  280. var spaces = args[1];
  281. if (convert === "All chars") {
  282. var result = "|" + Utils.toHex(input) + "|";
  283. if (!spaces) result = result.replace(/ /g, "");
  284. return result;
  285. }
  286. var output = "",
  287. inHex = false,
  288. convertSpaces = convert === "Only special chars including spaces",
  289. b;
  290. for (var i = 0; i < input.length; i++) {
  291. b = input[i];
  292. if ((b === 32 && convertSpaces) || (b < 48 && b !== 32) || (b > 57 && b < 65) || (b > 90 && b < 97) || b > 122) {
  293. if (!inHex) {
  294. output += "|";
  295. inHex = true;
  296. } else if (spaces) output += " ";
  297. output += Utils.toHex([b]);
  298. } else {
  299. if (inHex) {
  300. output += "|";
  301. inHex = false;
  302. }
  303. output += Utils.chr(input[i]);
  304. }
  305. }
  306. if (inHex) output += "|";
  307. return output;
  308. },
  309. /**
  310. * From Hex Content operation.
  311. *
  312. * @param {string} input
  313. * @param {Object[]} args
  314. * @returns {byteArray}
  315. */
  316. runFromHexContent: function(input, args) {
  317. var regex = /\|([a-f\d ]{2,})\|/gi;
  318. var output = [], m, i = 0;
  319. while ((m = regex.exec(input))) {
  320. // Add up to match
  321. for (; i < m.index;)
  322. output.push(Utils.ord(input[i++]));
  323. // Add match
  324. var bytes = Utils.fromHex(m[1]);
  325. if (bytes) {
  326. for (var a = 0; a < bytes.length;)
  327. output.push(bytes[a++]);
  328. } else {
  329. // Not valid hex, print as normal
  330. for (; i < regex.lastIndex;)
  331. output.push(Utils.ord(input[i++]));
  332. }
  333. i = regex.lastIndex;
  334. }
  335. // Add all after final match
  336. for (; i < input.length;)
  337. output.push(Utils.ord(input[i++]));
  338. return output;
  339. },
  340. };