encoding.js 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350
  1. (function(global) {
  2. 'use strict';
  3. //
  4. // Utilities
  5. //
  6. /**
  7. * @param {number} a The number to test.
  8. * @param {number} min The minimum value in the range, inclusive.
  9. * @param {number} max The maximum value in the range, inclusive.
  10. * @return {boolean} True if a >= min and a <= max.
  11. */
  12. function inRange(a, min, max) {
  13. return min <= a && a <= max;
  14. }
  15. /**
  16. * @param {number} n The numerator.
  17. * @param {number} d The denominator.
  18. * @return {number} The result of the integer division of n by d.
  19. */
  20. function div(n, d) {
  21. return Math.floor(n / d);
  22. }
  23. //
  24. // Implementation of Encoding specification
  25. // http://dvcs.w3.org/hg/encoding/raw-file/tip/Overview.html
  26. //
  27. //
  28. // 3. Terminology
  29. //
  30. //
  31. // 4. Encodings
  32. //
  33. /** @const */ var EOF_byte = -1;
  34. /** @const */ var EOF_code_point = -1;
  35. /**
  36. * @constructor
  37. * @param {Uint8Array} bytes Array of bytes that provide the stream.
  38. */
  39. function ByteInputStream(bytes) {
  40. /** @type {number} */
  41. var pos = 0;
  42. /**
  43. * @this {ByteInputStream}
  44. * @return {number} Get the next byte from the stream.
  45. */
  46. this.get = function() {
  47. return (pos >= bytes.length) ? EOF_byte : Number(bytes[pos]);
  48. };
  49. /** @param {number} n Number (positive or negative) by which to
  50. * offset the byte pointer. */
  51. this.offset = function(n) {
  52. pos += n;
  53. if (pos < 0) {
  54. throw new Error('Seeking past start of the buffer');
  55. }
  56. if (pos > bytes.length) {
  57. throw new Error('Seeking past EOF');
  58. }
  59. };
  60. /**
  61. * @param {Array.<number>} test Array of bytes to compare against.
  62. * @return {boolean} True if the start of the stream matches the test
  63. * bytes.
  64. */
  65. this.match = function(test) {
  66. if (test.length > pos + bytes.length) {
  67. return false;
  68. }
  69. var i;
  70. for (i = 0; i < test.length; i += 1) {
  71. if (Number(bytes[pos + i]) !== test[i]) {
  72. return false;
  73. }
  74. }
  75. return true;
  76. };
  77. }
  78. /**
  79. * @constructor
  80. * @param {Array.<number>} bytes The array to write bytes into.
  81. */
  82. function ByteOutputStream(bytes) {
  83. /** @type {number} */
  84. var pos = 0;
  85. /**
  86. * @param {...number} var_args The byte or bytes to emit into the stream.
  87. * @return {number} The last byte emitted.
  88. */
  89. this.emit = function(var_args) {
  90. /** @type {number} */
  91. var last = EOF_byte;
  92. var i;
  93. for (i = 0; i < arguments.length; ++i) {
  94. last = Number(arguments[i]);
  95. bytes[pos++] = last;
  96. }
  97. return last;
  98. };
  99. }
  100. /**
  101. * @constructor
  102. * @param {string} string The source of code units for the stream.
  103. */
  104. function CodePointInputStream(string) {
  105. /**
  106. * @param {string} string Input string of UTF-16 code units.
  107. * @return {Array.<number>} Code points.
  108. */
  109. function stringToCodePoints(string) {
  110. /** @type {Array.<number>} */
  111. var cps = [];
  112. // Based on http://www.w3.org/TR/WebIDL/#idl-DOMString
  113. var i = 0, n = string.length;
  114. while (i < string.length) {
  115. var c = string.charCodeAt(i);
  116. if (!inRange(c, 0xD800, 0xDFFF)) {
  117. cps.push(c);
  118. } else if (inRange(c, 0xDC00, 0xDFFF)) {
  119. cps.push(0xFFFD);
  120. } else { // (inRange(cu, 0xD800, 0xDBFF))
  121. if (i === n - 1) {
  122. cps.push(0xFFFD);
  123. } else {
  124. var d = string.charCodeAt(i + 1);
  125. if (inRange(d, 0xDC00, 0xDFFF)) {
  126. var a = c & 0x3FF;
  127. var b = d & 0x3FF;
  128. i += 1;
  129. cps.push(0x10000 + (a << 10) + b);
  130. } else {
  131. cps.push(0xFFFD);
  132. }
  133. }
  134. }
  135. i += 1;
  136. }
  137. return cps;
  138. }
  139. /** @type {number} */
  140. var pos = 0;
  141. /** @type {Array.<number>} */
  142. var cps = stringToCodePoints(string);
  143. /** @param {number} n The number of bytes (positive or negative)
  144. * to advance the code point pointer by.*/
  145. this.offset = function(n) {
  146. pos += n;
  147. if (pos < 0) {
  148. throw new Error('Seeking past start of the buffer');
  149. }
  150. if (pos > cps.length) {
  151. throw new Error('Seeking past EOF');
  152. }
  153. };
  154. /** @return {number} Get the next code point from the stream. */
  155. this.get = function() {
  156. if (pos >= cps.length) {
  157. return EOF_code_point;
  158. }
  159. return cps[pos];
  160. };
  161. }
  162. /**
  163. * @constructor
  164. */
  165. function CodePointOutputStream() {
  166. /** @type {string} */
  167. var string = '';
  168. /** @return {string} The accumulated string. */
  169. this.string = function() {
  170. return string;
  171. };
  172. /** @param {number} c The code point to encode into the stream. */
  173. this.emit = function(c) {
  174. if (c <= 0xFFFF) {
  175. string += String.fromCharCode(c);
  176. } else {
  177. c -= 0x10000;
  178. string += String.fromCharCode(0xD800 + ((c >> 10) & 0x3ff));
  179. string += String.fromCharCode(0xDC00 + (c & 0x3ff));
  180. }
  181. };
  182. }
  183. /**
  184. * @constructor
  185. * @param {string} message Description of the error.
  186. */
  187. function EncodingError(message) {
  188. this.name = 'EncodingError';
  189. this.message = message;
  190. this.code = 0;
  191. }
  192. EncodingError.prototype = Error.prototype;
  193. /**
  194. * @param {boolean} fatal If true, decoding errors raise an exception.
  195. * @param {number=} opt_code_point Override the standard fallback code point.
  196. * @return {number} The code point to insert on a decoding error.
  197. */
  198. function decoderError(fatal, opt_code_point) {
  199. if (fatal) {
  200. throw new EncodingError('Decoder error');
  201. }
  202. return opt_code_point || 0xFFFD;
  203. }
  204. /**
  205. * @param {number} code_point The code point that could not be encoded.
  206. * @return {number} Always throws, no value is actually returned.
  207. */
  208. function encoderError(code_point) {
  209. throw new EncodingError('The code point ' + code_point +
  210. ' could not be encoded.');
  211. }
  212. /**
  213. * @param {string} label The encoding label.
  214. * @return {?{name:string,labels:Array.<string>}}
  215. */
  216. function getEncoding(label) {
  217. label = String(label).trim().toLowerCase();
  218. if (Object.prototype.hasOwnProperty.call(label_to_encoding, label)) {
  219. return label_to_encoding[label];
  220. }
  221. return null;
  222. }
  223. /** @type {Array.<{encodings: Array.<{name:string,labels:Array.<string>}>,
  224. * heading: string}>} */
  225. var encodings = [
  226. {
  227. "encodings": [
  228. {
  229. "labels": [
  230. "unicode-1-1-utf-8",
  231. "utf-8",
  232. "utf8"
  233. ],
  234. "name": "utf-8"
  235. }
  236. ],
  237. "heading": "The Encoding"
  238. },
  239. {
  240. "encodings": [
  241. {
  242. "labels": [
  243. "866",
  244. "cp866",
  245. "csibm866",
  246. "ibm866"
  247. ],
  248. "name": "ibm866"
  249. },
  250. {
  251. "labels": [
  252. "csisolatin2",
  253. "iso-8859-2",
  254. "iso-ir-101",
  255. "iso8859-2",
  256. "iso88592",
  257. "iso_8859-2",
  258. "iso_8859-2:1987",
  259. "l2",
  260. "latin2"
  261. ],
  262. "name": "iso-8859-2"
  263. },
  264. {
  265. "labels": [
  266. "csisolatin3",
  267. "iso-8859-3",
  268. "iso-ir-109",
  269. "iso8859-3",
  270. "iso88593",
  271. "iso_8859-3",
  272. "iso_8859-3:1988",
  273. "l3",
  274. "latin3"
  275. ],
  276. "name": "iso-8859-3"
  277. },
  278. {
  279. "labels": [
  280. "csisolatin4",
  281. "iso-8859-4",
  282. "iso-ir-110",
  283. "iso8859-4",
  284. "iso88594",
  285. "iso_8859-4",
  286. "iso_8859-4:1988",
  287. "l4",
  288. "latin4"
  289. ],
  290. "name": "iso-8859-4"
  291. },
  292. {
  293. "labels": [
  294. "csisolatincyrillic",
  295. "cyrillic",
  296. "iso-8859-5",
  297. "iso-ir-144",
  298. "iso8859-5",
  299. "iso88595",
  300. "iso_8859-5",
  301. "iso_8859-5:1988"
  302. ],
  303. "name": "iso-8859-5"
  304. },
  305. {
  306. "labels": [
  307. "arabic",
  308. "asmo-708",
  309. "csiso88596e",
  310. "csiso88596i",
  311. "csisolatinarabic",
  312. "ecma-114",
  313. "iso-8859-6",
  314. "iso-8859-6-e",
  315. "iso-8859-6-i",
  316. "iso-ir-127",
  317. "iso8859-6",
  318. "iso88596",
  319. "iso_8859-6",
  320. "iso_8859-6:1987"
  321. ],
  322. "name": "iso-8859-6"
  323. },
  324. {
  325. "labels": [
  326. "csisolatingreek",
  327. "ecma-118",
  328. "elot_928",
  329. "greek",
  330. "greek8",
  331. "iso-8859-7",
  332. "iso-ir-126",
  333. "iso8859-7",
  334. "iso88597",
  335. "iso_8859-7",
  336. "iso_8859-7:1987",
  337. "sun_eu_greek"
  338. ],
  339. "name": "iso-8859-7"
  340. },
  341. {
  342. "labels": [
  343. "csiso88598e",
  344. "csisolatinhebrew",
  345. "hebrew",
  346. "iso-8859-8",
  347. "iso-8859-8-e",
  348. "iso-ir-138",
  349. "iso8859-8",
  350. "iso88598",
  351. "iso_8859-8",
  352. "iso_8859-8:1988",
  353. "visual"
  354. ],
  355. "name": "iso-8859-8"
  356. },
  357. {
  358. "labels": [
  359. "csiso88598i",
  360. "iso-8859-8-i",
  361. "logical"
  362. ],
  363. "name": "iso-8859-8-i"
  364. },
  365. {
  366. "labels": [
  367. "csisolatin6",
  368. "iso-8859-10",
  369. "iso-ir-157",
  370. "iso8859-10",
  371. "iso885910",
  372. "l6",
  373. "latin6"
  374. ],
  375. "name": "iso-8859-10"
  376. },
  377. {
  378. "labels": [
  379. "iso-8859-13",
  380. "iso8859-13",
  381. "iso885913"
  382. ],
  383. "name": "iso-8859-13"
  384. },
  385. {
  386. "labels": [
  387. "iso-8859-14",
  388. "iso8859-14",
  389. "iso885914"
  390. ],
  391. "name": "iso-8859-14"
  392. },
  393. {
  394. "labels": [
  395. "csisolatin9",
  396. "iso-8859-15",
  397. "iso8859-15",
  398. "iso885915",
  399. "iso_8859-15",
  400. "l9"
  401. ],
  402. "name": "iso-8859-15"
  403. },
  404. {
  405. "labels": [
  406. "iso-8859-16"
  407. ],
  408. "name": "iso-8859-16"
  409. },
  410. {
  411. "labels": [
  412. "cskoi8r",
  413. "koi",
  414. "koi8",
  415. "koi8-r",
  416. "koi8_r"
  417. ],
  418. "name": "koi8-r"
  419. },
  420. {
  421. "labels": [
  422. "koi8-u"
  423. ],
  424. "name": "koi8-u"
  425. },
  426. {
  427. "labels": [
  428. "csmacintosh",
  429. "mac",
  430. "macintosh",
  431. "x-mac-roman"
  432. ],
  433. "name": "macintosh"
  434. },
  435. {
  436. "labels": [
  437. "dos-874",
  438. "iso-8859-11",
  439. "iso8859-11",
  440. "iso885911",
  441. "tis-620",
  442. "windows-874"
  443. ],
  444. "name": "windows-874"
  445. },
  446. {
  447. "labels": [
  448. "cp1250",
  449. "windows-1250",
  450. "x-cp1250"
  451. ],
  452. "name": "windows-1250"
  453. },
  454. {
  455. "labels": [
  456. "cp1251",
  457. "windows-1251",
  458. "x-cp1251"
  459. ],
  460. "name": "windows-1251"
  461. },
  462. {
  463. "labels": [
  464. "ansi_x3.4-1968",
  465. "ascii",
  466. "cp1252",
  467. "cp819",
  468. "csisolatin1",
  469. "ibm819",
  470. "iso-8859-1",
  471. "iso-ir-100",
  472. "iso8859-1",
  473. "iso88591",
  474. "iso_8859-1",
  475. "iso_8859-1:1987",
  476. "l1",
  477. "latin1",
  478. "us-ascii",
  479. "windows-1252",
  480. "x-cp1252"
  481. ],
  482. "name": "windows-1252"
  483. },
  484. {
  485. "labels": [
  486. "cp1253",
  487. "windows-1253",
  488. "x-cp1253"
  489. ],
  490. "name": "windows-1253"
  491. },
  492. {
  493. "labels": [
  494. "cp1254",
  495. "csisolatin5",
  496. "iso-8859-9",
  497. "iso-ir-148",
  498. "iso8859-9",
  499. "iso88599",
  500. "iso_8859-9",
  501. "iso_8859-9:1989",
  502. "l5",
  503. "latin5",
  504. "windows-1254",
  505. "x-cp1254"
  506. ],
  507. "name": "windows-1254"
  508. },
  509. {
  510. "labels": [
  511. "cp1255",
  512. "windows-1255",
  513. "x-cp1255"
  514. ],
  515. "name": "windows-1255"
  516. },
  517. {
  518. "labels": [
  519. "cp1256",
  520. "windows-1256",
  521. "x-cp1256"
  522. ],
  523. "name": "windows-1256"
  524. },
  525. {
  526. "labels": [
  527. "cp1257",
  528. "windows-1257",
  529. "x-cp1257"
  530. ],
  531. "name": "windows-1257"
  532. },
  533. {
  534. "labels": [
  535. "cp1258",
  536. "windows-1258",
  537. "x-cp1258"
  538. ],
  539. "name": "windows-1258"
  540. },
  541. {
  542. "labels": [
  543. "x-mac-cyrillic",
  544. "x-mac-ukrainian"
  545. ],
  546. "name": "x-mac-cyrillic"
  547. }
  548. ],
  549. "heading": "Legacy single-byte encodings"
  550. },
  551. {
  552. "encodings": [
  553. {
  554. "labels": [
  555. "chinese",
  556. "csgb2312",
  557. "csiso58gb231280",
  558. "gb2312",
  559. "gb_2312",
  560. "gb_2312-80",
  561. "gbk",
  562. "iso-ir-58",
  563. "x-gbk"
  564. ],
  565. "name": "gbk"
  566. },
  567. {
  568. "labels": [
  569. "gb18030"
  570. ],
  571. "name": "gb18030"
  572. },
  573. {
  574. "labels": [
  575. "hz-gb-2312"
  576. ],
  577. "name": "hz-gb-2312"
  578. }
  579. ],
  580. "heading": "Legacy multi-byte Chinese (simplified) encodings"
  581. },
  582. {
  583. "encodings": [
  584. {
  585. "labels": [
  586. "big5",
  587. "big5-hkscs",
  588. "cn-big5",
  589. "csbig5",
  590. "x-x-big5"
  591. ],
  592. "name": "big5"
  593. }
  594. ],
  595. "heading": "Legacy multi-byte Chinese (traditional) encodings"
  596. },
  597. {
  598. "encodings": [
  599. {
  600. "labels": [
  601. "cseucpkdfmtjapanese",
  602. "euc-jp",
  603. "x-euc-jp"
  604. ],
  605. "name": "euc-jp"
  606. },
  607. {
  608. "labels": [
  609. "csiso2022jp",
  610. "iso-2022-jp"
  611. ],
  612. "name": "iso-2022-jp"
  613. },
  614. {
  615. "labels": [
  616. "csshiftjis",
  617. "ms_kanji",
  618. "shift-jis",
  619. "shift_jis",
  620. "sjis",
  621. "windows-31j",
  622. "x-sjis"
  623. ],
  624. "name": "shift_jis"
  625. }
  626. ],
  627. "heading": "Legacy multi-byte Japanese encodings"
  628. },
  629. {
  630. "encodings": [
  631. {
  632. "labels": [
  633. "cseuckr",
  634. "csksc56011987",
  635. "euc-kr",
  636. "iso-ir-149",
  637. "korean",
  638. "ks_c_5601-1987",
  639. "ks_c_5601-1989",
  640. "ksc5601",
  641. "ksc_5601",
  642. "windows-949"
  643. ],
  644. "name": "euc-kr"
  645. }
  646. ],
  647. "heading": "Legacy multi-byte Korean encodings"
  648. },
  649. {
  650. "encodings": [
  651. {
  652. "labels": [
  653. "csiso2022kr",
  654. "iso-2022-kr",
  655. "iso-2022-cn",
  656. "iso-2022-cn-ext"
  657. ],
  658. "name": "replacement"
  659. },
  660. {
  661. "labels": [
  662. "utf-16be"
  663. ],
  664. "name": "utf-16be"
  665. },
  666. {
  667. "labels": [
  668. "utf-16",
  669. "utf-16le"
  670. ],
  671. "name": "utf-16le"
  672. },
  673. {
  674. "labels": [
  675. "x-user-defined"
  676. ],
  677. "name": "x-user-defined"
  678. }
  679. ],
  680. "heading": "Legacy miscellaneous encodings"
  681. }
  682. ];
  683. var name_to_encoding = {};
  684. var label_to_encoding = {};
  685. encodings.forEach(function(category) {
  686. category.encodings.forEach(function(encoding) {
  687. name_to_encoding[encoding.name] = encoding;
  688. encoding.labels.forEach(function(label) {
  689. label_to_encoding[label] = encoding;
  690. });
  691. });
  692. });
  693. //
  694. // 5. Indexes
  695. //
  696. /**
  697. * @param {number} pointer The |pointer| to search for.
  698. * @param {Array.<?number>|undefined} index The |index| to search within.
  699. * @return {?number} The code point corresponding to |pointer| in |index|,
  700. * or null if |code point| is not in |index|.
  701. */
  702. function indexCodePointFor(pointer, index) {
  703. if (!index) return null;
  704. return index[pointer] || null;
  705. }
  706. /**
  707. * @param {number} code_point The |code point| to search for.
  708. * @param {Array.<?number>} index The |index| to search within.
  709. * @return {?number} The first pointer corresponding to |code point| in
  710. * |index|, or null if |code point| is not in |index|.
  711. */
  712. function indexPointerFor(code_point, index) {
  713. var pointer = index.indexOf(code_point);
  714. return pointer === -1 ? null : pointer;
  715. }
  716. /**
  717. * @param {string} name Name of the index.
  718. * @return {(Array.<number>|Array.<Array.<number>>)}
  719. * */
  720. function index(name) {
  721. if (!('encoding-indexes' in global))
  722. throw new Error("Indexes missing. Did you forget to include encoding-indexes.js?");
  723. return global['encoding-indexes'][name];
  724. }
  725. /**
  726. * @param {number} pointer The |pointer| to search for in the gb18030 index.
  727. * @return {?number} The code point corresponding to |pointer| in |index|,
  728. * or null if |code point| is not in the gb18030 index.
  729. */
  730. function indexGB18030CodePointFor(pointer) {
  731. if ((pointer > 39419 && pointer < 189000) || (pointer > 1237575)) {
  732. return null;
  733. }
  734. var /** @type {number} */ offset = 0,
  735. /** @type {number} */ code_point_offset = 0,
  736. /** @type {Array.<Array.<number>>} */ idx = index('gb18030');
  737. var i;
  738. for (i = 0; i < idx.length; ++i) {
  739. var entry = idx[i];
  740. if (entry[0] <= pointer) {
  741. offset = entry[0];
  742. code_point_offset = entry[1];
  743. } else {
  744. break;
  745. }
  746. }
  747. return code_point_offset + pointer - offset;
  748. }
  749. /**
  750. * @param {number} code_point The |code point| to locate in the gb18030 index.
  751. * @return {number} The first pointer corresponding to |code point| in the
  752. * gb18030 index.
  753. */
  754. function indexGB18030PointerFor(code_point) {
  755. var /** @type {number} */ offset = 0,
  756. /** @type {number} */ pointer_offset = 0,
  757. /** @type {Array.<Array.<number>>} */ idx = index('gb18030');
  758. var i;
  759. for (i = 0; i < idx.length; ++i) {
  760. var entry = idx[i];
  761. if (entry[1] <= code_point) {
  762. offset = entry[1];
  763. pointer_offset = entry[0];
  764. } else {
  765. break;
  766. }
  767. }
  768. return pointer_offset + code_point - offset;
  769. }
  770. //
  771. // 7. The encoding
  772. //
  773. // 7.1 utf-8
  774. /**
  775. * @constructor
  776. * @param {{fatal: boolean}} options
  777. */
  778. function UTF8Decoder(options) {
  779. var fatal = options.fatal;
  780. var /** @type {number} */ utf8_code_point = 0,
  781. /** @type {number} */ utf8_bytes_needed = 0,
  782. /** @type {number} */ utf8_bytes_seen = 0,
  783. /** @type {number} */ utf8_lower_boundary = 0;
  784. /**
  785. * @param {ByteInputStream} byte_pointer The byte stream to decode.
  786. * @return {?number} The next code point decoded, or null if not enough
  787. * data exists in the input stream to decode a complete code point.
  788. */
  789. this.decode = function(byte_pointer) {
  790. var bite = byte_pointer.get();
  791. if (bite === EOF_byte) {
  792. if (utf8_bytes_needed !== 0) {
  793. return decoderError(fatal);
  794. }
  795. return EOF_code_point;
  796. }
  797. byte_pointer.offset(1);
  798. if (utf8_bytes_needed === 0) {
  799. if (inRange(bite, 0x00, 0x7F)) {
  800. return bite;
  801. }
  802. if (inRange(bite, 0xC2, 0xDF)) {
  803. utf8_bytes_needed = 1;
  804. utf8_lower_boundary = 0x80;
  805. utf8_code_point = bite - 0xC0;
  806. } else if (inRange(bite, 0xE0, 0xEF)) {
  807. utf8_bytes_needed = 2;
  808. utf8_lower_boundary = 0x800;
  809. utf8_code_point = bite - 0xE0;
  810. } else if (inRange(bite, 0xF0, 0xF4)) {
  811. utf8_bytes_needed = 3;
  812. utf8_lower_boundary = 0x10000;
  813. utf8_code_point = bite - 0xF0;
  814. } else {
  815. return decoderError(fatal);
  816. }
  817. utf8_code_point = utf8_code_point * Math.pow(64, utf8_bytes_needed);
  818. return null;
  819. }
  820. if (!inRange(bite, 0x80, 0xBF)) {
  821. utf8_code_point = 0;
  822. utf8_bytes_needed = 0;
  823. utf8_bytes_seen = 0;
  824. utf8_lower_boundary = 0;
  825. byte_pointer.offset(-1);
  826. return decoderError(fatal);
  827. }
  828. utf8_bytes_seen += 1;
  829. utf8_code_point = utf8_code_point + (bite - 0x80) *
  830. Math.pow(64, utf8_bytes_needed - utf8_bytes_seen);
  831. if (utf8_bytes_seen !== utf8_bytes_needed) {
  832. return null;
  833. }
  834. var code_point = utf8_code_point;
  835. var lower_boundary = utf8_lower_boundary;
  836. utf8_code_point = 0;
  837. utf8_bytes_needed = 0;
  838. utf8_bytes_seen = 0;
  839. utf8_lower_boundary = 0;
  840. if (inRange(code_point, lower_boundary, 0x10FFFF) &&
  841. !inRange(code_point, 0xD800, 0xDFFF)) {
  842. return code_point;
  843. }
  844. return decoderError(fatal);
  845. };
  846. }
  847. /**
  848. * @constructor
  849. * @param {{fatal: boolean}} options
  850. */
  851. function UTF8Encoder(options) {
  852. var fatal = options.fatal;
  853. /**
  854. * @param {ByteOutputStream} output_byte_stream Output byte stream.
  855. * @param {CodePointInputStream} code_point_pointer Input stream.
  856. * @return {number} The last byte emitted.
  857. */
  858. this.encode = function(output_byte_stream, code_point_pointer) {
  859. /** @type {number} */
  860. var code_point = code_point_pointer.get();
  861. if (code_point === EOF_code_point) {
  862. return EOF_byte;
  863. }
  864. code_point_pointer.offset(1);
  865. if (inRange(code_point, 0xD800, 0xDFFF)) {
  866. return encoderError(code_point);
  867. }
  868. if (inRange(code_point, 0x0000, 0x007f)) {
  869. return output_byte_stream.emit(code_point);
  870. }
  871. var count, offset;
  872. if (inRange(code_point, 0x0080, 0x07FF)) {
  873. count = 1;
  874. offset = 0xC0;
  875. } else if (inRange(code_point, 0x0800, 0xFFFF)) {
  876. count = 2;
  877. offset = 0xE0;
  878. } else if (inRange(code_point, 0x10000, 0x10FFFF)) {
  879. count = 3;
  880. offset = 0xF0;
  881. }
  882. var result = output_byte_stream.emit(
  883. div(code_point, Math.pow(64, count)) + offset);
  884. while (count > 0) {
  885. var temp = div(code_point, Math.pow(64, count - 1));
  886. result = output_byte_stream.emit(0x80 + (temp % 64));
  887. count -= 1;
  888. }
  889. return result;
  890. };
  891. }
  892. /** @param {{fatal: boolean}} options */
  893. name_to_encoding['utf-8'].getEncoder = function(options) {
  894. return new UTF8Encoder(options);
  895. };
  896. /** @param {{fatal: boolean}} options */
  897. name_to_encoding['utf-8'].getDecoder = function(options) {
  898. return new UTF8Decoder(options);
  899. };
  900. //
  901. // 8. Legacy single-byte encodings
  902. //
  903. /**
  904. * @constructor
  905. * @param {Array.<number>} index The encoding index.
  906. * @param {{fatal: boolean}} options
  907. */
  908. function SingleByteDecoder(index, options) {
  909. var fatal = options.fatal;
  910. /**
  911. * @param {ByteInputStream} byte_pointer The byte stream to decode.
  912. * @return {?number} The next code point decoded, or null if not enough
  913. * data exists in the input stream to decode a complete code point.
  914. */
  915. this.decode = function(byte_pointer) {
  916. var bite = byte_pointer.get();
  917. if (bite === EOF_byte) {
  918. return EOF_code_point;
  919. }
  920. byte_pointer.offset(1);
  921. if (inRange(bite, 0x00, 0x7F)) {
  922. return bite;
  923. }
  924. var code_point = index[bite - 0x80];
  925. if (code_point === null) {
  926. return decoderError(fatal);
  927. }
  928. return code_point;
  929. };
  930. }
  931. /**
  932. * @constructor
  933. * @param {Array.<?number>} index The encoding index.
  934. * @param {{fatal: boolean}} options
  935. */
  936. function SingleByteEncoder(index, options) {
  937. var fatal = options.fatal;
  938. /**
  939. * @param {ByteOutputStream} output_byte_stream Output byte stream.
  940. * @param {CodePointInputStream} code_point_pointer Input stream.
  941. * @return {number} The last byte emitted.
  942. */
  943. this.encode = function(output_byte_stream, code_point_pointer) {
  944. var code_point = code_point_pointer.get();
  945. if (code_point === EOF_code_point) {
  946. return EOF_byte;
  947. }
  948. code_point_pointer.offset(1);
  949. if (inRange(code_point, 0x0000, 0x007F)) {
  950. return output_byte_stream.emit(code_point);
  951. }
  952. var pointer = indexPointerFor(code_point, index);
  953. if (pointer === null) {
  954. encoderError(code_point);
  955. }
  956. return output_byte_stream.emit(pointer + 0x80);
  957. };
  958. }
  959. (function() {
  960. encodings.forEach(function(category) {
  961. if (category.heading !== 'Legacy single-byte encodings')
  962. return;
  963. category.encodings.forEach(function(encoding) {
  964. var idx = index(encoding.name);
  965. /** @param {{fatal: boolean}} options */
  966. encoding.getDecoder = function(options) {
  967. return new SingleByteDecoder(idx, options);
  968. };
  969. /** @param {{fatal: boolean}} options */
  970. encoding.getEncoder = function(options) {
  971. return new SingleByteEncoder(idx, options);
  972. };
  973. });
  974. });
  975. }());
  976. //
  977. // 9. Legacy multi-byte Chinese (simplified) encodings
  978. //
  979. // 9.1 gbk
  980. /**
  981. * @constructor
  982. * @param {boolean} gb18030 True if decoding gb18030, false otherwise.
  983. * @param {{fatal: boolean}} options
  984. */
  985. function GBKDecoder(gb18030, options) {
  986. var fatal = options.fatal;
  987. var /** @type {number} */ gbk_first = 0x00,
  988. /** @type {number} */ gbk_second = 0x00,
  989. /** @type {number} */ gbk_third = 0x00;
  990. /**
  991. * @param {ByteInputStream} byte_pointer The byte stream to decode.
  992. * @return {?number} The next code point decoded, or null if not enough
  993. * data exists in the input stream to decode a complete code point.
  994. */
  995. this.decode = function(byte_pointer) {
  996. var bite = byte_pointer.get();
  997. if (bite === EOF_byte && gbk_first === 0x00 &&
  998. gbk_second === 0x00 && gbk_third === 0x00) {
  999. return EOF_code_point;
  1000. }
  1001. if (bite === EOF_byte &&
  1002. (gbk_first !== 0x00 || gbk_second !== 0x00 || gbk_third !== 0x00)) {
  1003. gbk_first = 0x00;
  1004. gbk_second = 0x00;
  1005. gbk_third = 0x00;
  1006. decoderError(fatal);
  1007. }
  1008. byte_pointer.offset(1);
  1009. var code_point;
  1010. if (gbk_third !== 0x00) {
  1011. code_point = null;
  1012. if (inRange(bite, 0x30, 0x39)) {
  1013. code_point = indexGB18030CodePointFor(
  1014. (((gbk_first - 0x81) * 10 + (gbk_second - 0x30)) * 126 +
  1015. (gbk_third - 0x81)) * 10 + bite - 0x30);
  1016. }
  1017. gbk_first = 0x00;
  1018. gbk_second = 0x00;
  1019. gbk_third = 0x00;
  1020. if (code_point === null) {
  1021. byte_pointer.offset(-3);
  1022. return decoderError(fatal);
  1023. }
  1024. return code_point;
  1025. }
  1026. if (gbk_second !== 0x00) {
  1027. if (inRange(bite, 0x81, 0xFE)) {
  1028. gbk_third = bite;
  1029. return null;
  1030. }
  1031. byte_pointer.offset(-2);
  1032. gbk_first = 0x00;
  1033. gbk_second = 0x00;
  1034. return decoderError(fatal);
  1035. }
  1036. if (gbk_first !== 0x00) {
  1037. if (inRange(bite, 0x30, 0x39) && gb18030) {
  1038. gbk_second = bite;
  1039. return null;
  1040. }
  1041. var lead = gbk_first;
  1042. var pointer = null;
  1043. gbk_first = 0x00;
  1044. var offset = bite < 0x7F ? 0x40 : 0x41;
  1045. if (inRange(bite, 0x40, 0x7E) || inRange(bite, 0x80, 0xFE)) {
  1046. pointer = (lead - 0x81) * 190 + (bite - offset);
  1047. }
  1048. code_point = pointer === null ? null :
  1049. indexCodePointFor(pointer, index('gbk'));
  1050. if (pointer === null) {
  1051. byte_pointer.offset(-1);
  1052. }
  1053. if (code_point === null) {
  1054. return decoderError(fatal);
  1055. }
  1056. return code_point;
  1057. }
  1058. if (inRange(bite, 0x00, 0x7F)) {
  1059. return bite;
  1060. }
  1061. if (bite === 0x80) {
  1062. return 0x20AC;
  1063. }
  1064. if (inRange(bite, 0x81, 0xFE)) {
  1065. gbk_first = bite;
  1066. return null;
  1067. }
  1068. return decoderError(fatal);
  1069. };
  1070. }
  1071. /**
  1072. * @constructor
  1073. * @param {boolean} gb18030 True if decoding gb18030, false otherwise.
  1074. * @param {{fatal: boolean}} options
  1075. */
  1076. function GBKEncoder(gb18030, options) {
  1077. var fatal = options.fatal;
  1078. /**
  1079. * @param {ByteOutputStream} output_byte_stream Output byte stream.
  1080. * @param {CodePointInputStream} code_point_pointer Input stream.
  1081. * @return {number} The last byte emitted.
  1082. */
  1083. this.encode = function(output_byte_stream, code_point_pointer) {
  1084. var code_point = code_point_pointer.get();
  1085. if (code_point === EOF_code_point) {
  1086. return EOF_byte;
  1087. }
  1088. code_point_pointer.offset(1);
  1089. if (inRange(code_point, 0x0000, 0x007F)) {
  1090. return output_byte_stream.emit(code_point);
  1091. }
  1092. var pointer = indexPointerFor(code_point, index('gbk'));
  1093. if (pointer !== null) {
  1094. var lead = div(pointer, 190) + 0x81;
  1095. var trail = pointer % 190;
  1096. var offset = trail < 0x3F ? 0x40 : 0x41;
  1097. return output_byte_stream.emit(lead, trail + offset);
  1098. }
  1099. if (pointer === null && !gb18030) {
  1100. return encoderError(code_point);
  1101. }
  1102. pointer = indexGB18030PointerFor(code_point);
  1103. var byte1 = div(div(div(pointer, 10), 126), 10);
  1104. pointer = pointer - byte1 * 10 * 126 * 10;
  1105. var byte2 = div(div(pointer, 10), 126);
  1106. pointer = pointer - byte2 * 10 * 126;
  1107. var byte3 = div(pointer, 10);
  1108. var byte4 = pointer - byte3 * 10;
  1109. return output_byte_stream.emit(byte1 + 0x81,
  1110. byte2 + 0x30,
  1111. byte3 + 0x81,
  1112. byte4 + 0x30);
  1113. };
  1114. }
  1115. /** @param {{fatal: boolean}} options */
  1116. name_to_encoding['gbk'].getEncoder = function(options) {
  1117. return new GBKEncoder(false, options);
  1118. };
  1119. /** @param {{fatal: boolean}} options */
  1120. name_to_encoding['gbk'].getDecoder = function(options) {
  1121. return new GBKDecoder(false, options);
  1122. };
  1123. // 9.2 gb18030
  1124. /** @param {{fatal: boolean}} options */
  1125. name_to_encoding['gb18030'].getEncoder = function(options) {
  1126. return new GBKEncoder(true, options);
  1127. };
  1128. /** @param {{fatal: boolean}} options */
  1129. name_to_encoding['gb18030'].getDecoder = function(options) {
  1130. return new GBKDecoder(true, options);
  1131. };
  1132. // 9.3 hz-gb-2312
  1133. /**
  1134. * @constructor
  1135. * @param {{fatal: boolean}} options
  1136. */
  1137. function HZGB2312Decoder(options) {
  1138. var fatal = options.fatal;
  1139. var /** @type {boolean} */ hzgb2312 = false,
  1140. /** @type {number} */ hzgb2312_lead = 0x00;
  1141. /**
  1142. * @param {ByteInputStream} byte_pointer The byte stream to decode.
  1143. * @return {?number} The next code point decoded, or null if not enough
  1144. * data exists in the input stream to decode a complete code point.
  1145. */
  1146. this.decode = function(byte_pointer) {
  1147. var bite = byte_pointer.get();
  1148. if (bite === EOF_byte && hzgb2312_lead === 0x00) {
  1149. return EOF_code_point;
  1150. }
  1151. if (bite === EOF_byte && hzgb2312_lead !== 0x00) {
  1152. hzgb2312_lead = 0x00;
  1153. return decoderError(fatal);
  1154. }
  1155. byte_pointer.offset(1);
  1156. if (hzgb2312_lead === 0x7E) {
  1157. hzgb2312_lead = 0x00;
  1158. if (bite === 0x7B) {
  1159. hzgb2312 = true;
  1160. return null;
  1161. }
  1162. if (bite === 0x7D) {
  1163. hzgb2312 = false;
  1164. return null;
  1165. }
  1166. if (bite === 0x7E) {
  1167. return 0x007E;
  1168. }
  1169. if (bite === 0x0A) {
  1170. return null;
  1171. }
  1172. byte_pointer.offset(-1);
  1173. return decoderError(fatal);
  1174. }
  1175. if (hzgb2312_lead !== 0x00) {
  1176. var lead = hzgb2312_lead;
  1177. hzgb2312_lead = 0x00;
  1178. var code_point = null;
  1179. if (inRange(bite, 0x21, 0x7E)) {
  1180. code_point = indexCodePointFor((lead - 1) * 190 +
  1181. (bite + 0x3F), index('gbk'));
  1182. }
  1183. if (bite === 0x0A) {
  1184. hzgb2312 = false;
  1185. }
  1186. if (code_point === null) {
  1187. return decoderError(fatal);
  1188. }
  1189. return code_point;
  1190. }
  1191. if (bite === 0x7E) {
  1192. hzgb2312_lead = 0x7E;
  1193. return null;
  1194. }
  1195. if (hzgb2312) {
  1196. if (inRange(bite, 0x20, 0x7F)) {
  1197. hzgb2312_lead = bite;
  1198. return null;
  1199. }
  1200. if (bite === 0x0A) {
  1201. hzgb2312 = false;
  1202. }
  1203. return decoderError(fatal);
  1204. }
  1205. if (inRange(bite, 0x00, 0x7F)) {
  1206. return bite;
  1207. }
  1208. return decoderError(fatal);
  1209. };
  1210. }
  1211. /**
  1212. * @constructor
  1213. * @param {{fatal: boolean}} options
  1214. */
  1215. function HZGB2312Encoder(options) {
  1216. var fatal = options.fatal;
  1217. /** @type {boolean} */
  1218. var hzgb2312 = false;
  1219. /**
  1220. * @param {ByteOutputStream} output_byte_stream Output byte stream.
  1221. * @param {CodePointInputStream} code_point_pointer Input stream.
  1222. * @return {number} The last byte emitted.
  1223. */
  1224. this.encode = function(output_byte_stream, code_point_pointer) {
  1225. var code_point = code_point_pointer.get();
  1226. if (code_point === EOF_code_point) {
  1227. return EOF_byte;
  1228. }
  1229. code_point_pointer.offset(1);
  1230. if (inRange(code_point, 0x0000, 0x007F) && hzgb2312) {
  1231. code_point_pointer.offset(-1);
  1232. hzgb2312 = false;
  1233. return output_byte_stream.emit(0x7E, 0x7D);
  1234. }
  1235. if (code_point === 0x007E) {
  1236. return output_byte_stream.emit(0x7E, 0x7E);
  1237. }
  1238. if (inRange(code_point, 0x0000, 0x007F)) {
  1239. return output_byte_stream.emit(code_point);
  1240. }
  1241. if (!hzgb2312) {
  1242. code_point_pointer.offset(-1);
  1243. hzgb2312 = true;
  1244. return output_byte_stream.emit(0x7E, 0x7B);
  1245. }
  1246. var pointer = indexPointerFor(code_point, index('gbk'));
  1247. if (pointer === null) {
  1248. return encoderError(code_point);
  1249. }
  1250. var lead = div(pointer, 190) + 1;
  1251. var trail = pointer % 190 - 0x3F;
  1252. if (!inRange(lead, 0x21, 0x7E) || !inRange(trail, 0x21, 0x7E)) {
  1253. return encoderError(code_point);
  1254. }
  1255. return output_byte_stream.emit(lead, trail);
  1256. };
  1257. }
  1258. /** @param {{fatal: boolean}} options */
  1259. name_to_encoding['hz-gb-2312'].getEncoder = function(options) {
  1260. return new HZGB2312Encoder(options);
  1261. };
  1262. /** @param {{fatal: boolean}} options */
  1263. name_to_encoding['hz-gb-2312'].getDecoder = function(options) {
  1264. return new HZGB2312Decoder(options);
  1265. };
  1266. //
  1267. // 10. Legacy multi-byte Chinese (traditional) encodings
  1268. //
  1269. // 10.1 big5
  1270. /**
  1271. * @constructor
  1272. * @param {{fatal: boolean}} options
  1273. */
  1274. function Big5Decoder(options) {
  1275. var fatal = options.fatal;
  1276. var /** @type {number} */ big5_lead = 0x00,
  1277. /** @type {?number} */ big5_pending = null;
  1278. /**
  1279. * @param {ByteInputStream} byte_pointer The byte steram to decode.
  1280. * @return {?number} The next code point decoded, or null if not enough
  1281. * data exists in the input stream to decode a complete code point.
  1282. */
  1283. this.decode = function(byte_pointer) {
  1284. // NOTE: Hack to support emitting two code points
  1285. if (big5_pending !== null) {
  1286. var pending = big5_pending;
  1287. big5_pending = null;
  1288. return pending;
  1289. }
  1290. var bite = byte_pointer.get();
  1291. if (bite === EOF_byte && big5_lead === 0x00) {
  1292. return EOF_code_point;
  1293. }
  1294. if (bite === EOF_byte && big5_lead !== 0x00) {
  1295. big5_lead = 0x00;
  1296. return decoderError(fatal);
  1297. }
  1298. byte_pointer.offset(1);
  1299. if (big5_lead !== 0x00) {
  1300. var lead = big5_lead;
  1301. var pointer = null;
  1302. big5_lead = 0x00;
  1303. var offset = bite < 0x7F ? 0x40 : 0x62;
  1304. if (inRange(bite, 0x40, 0x7E) || inRange(bite, 0xA1, 0xFE)) {
  1305. pointer = (lead - 0x81) * 157 + (bite - offset);
  1306. }
  1307. if (pointer === 1133) {
  1308. big5_pending = 0x0304;
  1309. return 0x00CA;
  1310. }
  1311. if (pointer === 1135) {
  1312. big5_pending = 0x030C;
  1313. return 0x00CA;
  1314. }
  1315. if (pointer === 1164) {
  1316. big5_pending = 0x0304;
  1317. return 0x00EA;
  1318. }
  1319. if (pointer === 1166) {
  1320. big5_pending = 0x030C;
  1321. return 0x00EA;
  1322. }
  1323. var code_point = (pointer === null) ? null :
  1324. indexCodePointFor(pointer, index('big5'));
  1325. if (pointer === null) {
  1326. byte_pointer.offset(-1);
  1327. }
  1328. if (code_point === null) {
  1329. return decoderError(fatal);
  1330. }
  1331. return code_point;
  1332. }
  1333. if (inRange(bite, 0x00, 0x7F)) {
  1334. return bite;
  1335. }
  1336. if (inRange(bite, 0x81, 0xFE)) {
  1337. big5_lead = bite;
  1338. return null;
  1339. }
  1340. return decoderError(fatal);
  1341. };
  1342. }
  1343. /**
  1344. * @constructor
  1345. * @param {{fatal: boolean}} options
  1346. */
  1347. function Big5Encoder(options) {
  1348. var fatal = options.fatal;
  1349. /**
  1350. * @param {ByteOutputStream} output_byte_stream Output byte stream.
  1351. * @param {CodePointInputStream} code_point_pointer Input stream.
  1352. * @return {number} The last byte emitted.
  1353. */
  1354. this.encode = function(output_byte_stream, code_point_pointer) {
  1355. var code_point = code_point_pointer.get();
  1356. if (code_point === EOF_code_point) {
  1357. return EOF_byte;
  1358. }
  1359. code_point_pointer.offset(1);
  1360. if (inRange(code_point, 0x0000, 0x007F)) {
  1361. return output_byte_stream.emit(code_point);
  1362. }
  1363. var pointer = indexPointerFor(code_point, index('big5'));
  1364. if (pointer === null) {
  1365. return encoderError(code_point);
  1366. }
  1367. var lead = div(pointer, 157) + 0x81;
  1368. //if (lead < 0xA1) {
  1369. // return encoderError(code_point);
  1370. //}
  1371. var trail = pointer % 157;
  1372. var offset = trail < 0x3F ? 0x40 : 0x62;
  1373. return output_byte_stream.emit(lead, trail + offset);
  1374. };
  1375. }
  1376. /** @param {{fatal: boolean}} options */
  1377. name_to_encoding['big5'].getEncoder = function(options) {
  1378. return new Big5Encoder(options);
  1379. };
  1380. /** @param {{fatal: boolean}} options */
  1381. name_to_encoding['big5'].getDecoder = function(options) {
  1382. return new Big5Decoder(options);
  1383. };
  1384. //
  1385. // 11. Legacy multi-byte Japanese encodings
  1386. //
  1387. // 11.1 euc.jp
  1388. /**
  1389. * @constructor
  1390. * @param {{fatal: boolean}} options
  1391. */
  1392. function EUCJPDecoder(options) {
  1393. var fatal = options.fatal;
  1394. var /** @type {number} */ eucjp_first = 0x00,
  1395. /** @type {number} */ eucjp_second = 0x00;
  1396. /**
  1397. * @param {ByteInputStream} byte_pointer The byte stream to decode.
  1398. * @return {?number} The next code point decoded, or null if not enough
  1399. * data exists in the input stream to decode a complete code point.
  1400. */
  1401. this.decode = function(byte_pointer) {
  1402. var bite = byte_pointer.get();
  1403. if (bite === EOF_byte) {
  1404. if (eucjp_first === 0x00 && eucjp_second === 0x00) {
  1405. return EOF_code_point;
  1406. }
  1407. eucjp_first = 0x00;
  1408. eucjp_second = 0x00;
  1409. return decoderError(fatal);
  1410. }
  1411. byte_pointer.offset(1);
  1412. var lead, code_point;
  1413. if (eucjp_second !== 0x00) {
  1414. lead = eucjp_second;
  1415. eucjp_second = 0x00;
  1416. code_point = null;
  1417. if (inRange(lead, 0xA1, 0xFE) && inRange(bite, 0xA1, 0xFE)) {
  1418. code_point = indexCodePointFor((lead - 0xA1) * 94 + bite - 0xA1,
  1419. index('jis0212'));
  1420. }
  1421. if (!inRange(bite, 0xA1, 0xFE)) {
  1422. byte_pointer.offset(-1);
  1423. }
  1424. if (code_point === null) {
  1425. return decoderError(fatal);
  1426. }
  1427. return code_point;
  1428. }
  1429. if (eucjp_first === 0x8E && inRange(bite, 0xA1, 0xDF)) {
  1430. eucjp_first = 0x00;
  1431. return 0xFF61 + bite - 0xA1;
  1432. }
  1433. if (eucjp_first === 0x8F && inRange(bite, 0xA1, 0xFE)) {
  1434. eucjp_first = 0x00;
  1435. eucjp_second = bite;
  1436. return null;
  1437. }
  1438. if (eucjp_first !== 0x00) {
  1439. lead = eucjp_first;
  1440. eucjp_first = 0x00;
  1441. code_point = null;
  1442. if (inRange(lead, 0xA1, 0xFE) && inRange(bite, 0xA1, 0xFE)) {
  1443. code_point = indexCodePointFor((lead - 0xA1) * 94 + bite - 0xA1,
  1444. index('jis0208'));
  1445. }
  1446. if (!inRange(bite, 0xA1, 0xFE)) {
  1447. byte_pointer.offset(-1);
  1448. }
  1449. if (code_point === null) {
  1450. return decoderError(fatal);
  1451. }
  1452. return code_point;
  1453. }
  1454. if (inRange(bite, 0x00, 0x7F)) {
  1455. return bite;
  1456. }
  1457. if (bite === 0x8E || bite === 0x8F || (inRange(bite, 0xA1, 0xFE))) {
  1458. eucjp_first = bite;
  1459. return null;
  1460. }
  1461. return decoderError(fatal);
  1462. };
  1463. }
  1464. /**
  1465. * @constructor
  1466. * @param {{fatal: boolean}} options
  1467. */
  1468. function EUCJPEncoder(options) {
  1469. var fatal = options.fatal;
  1470. /**
  1471. * @param {ByteOutputStream} output_byte_stream Output byte stream.
  1472. * @param {CodePointInputStream} code_point_pointer Input stream.
  1473. * @return {number} The last byte emitted.
  1474. */
  1475. this.encode = function(output_byte_stream, code_point_pointer) {
  1476. var code_point = code_point_pointer.get();
  1477. if (code_point === EOF_code_point) {
  1478. return EOF_byte;
  1479. }
  1480. code_point_pointer.offset(1);
  1481. if (inRange(code_point, 0x0000, 0x007F)) {
  1482. return output_byte_stream.emit(code_point);
  1483. }
  1484. if (code_point === 0x00A5) {
  1485. return output_byte_stream.emit(0x5C);
  1486. }
  1487. if (code_point === 0x203E) {
  1488. return output_byte_stream.emit(0x7E);
  1489. }
  1490. if (inRange(code_point, 0xFF61, 0xFF9F)) {
  1491. return output_byte_stream.emit(0x8E, code_point - 0xFF61 + 0xA1);
  1492. }
  1493. var pointer = indexPointerFor(code_point, index('jis0208'));
  1494. if (pointer === null) {
  1495. return encoderError(code_point);
  1496. }
  1497. var lead = div(pointer, 94) + 0xA1;
  1498. var trail = pointer % 94 + 0xA1;
  1499. return output_byte_stream.emit(lead, trail);
  1500. };
  1501. }
  1502. /** @param {{fatal: boolean}} options */
  1503. name_to_encoding['euc-jp'].getEncoder = function(options) {
  1504. return new EUCJPEncoder(options);
  1505. };
  1506. /** @param {{fatal: boolean}} options */
  1507. name_to_encoding['euc-jp'].getDecoder = function(options) {
  1508. return new EUCJPDecoder(options);
  1509. };
  1510. // 11.2 iso-2022-jp
  1511. /**
  1512. * @constructor
  1513. * @param {{fatal: boolean}} options
  1514. */
  1515. function ISO2022JPDecoder(options) {
  1516. var fatal = options.fatal;
  1517. /** @enum */
  1518. var state = {
  1519. ASCII: 0,
  1520. escape_start: 1,
  1521. escape_middle: 2,
  1522. escape_final: 3,
  1523. lead: 4,
  1524. trail: 5,
  1525. Katakana: 6
  1526. };
  1527. var /** @type {number} */ iso2022jp_state = state.ASCII,
  1528. /** @type {boolean} */ iso2022jp_jis0212 = false,
  1529. /** @type {number} */ iso2022jp_lead = 0x00;
  1530. /**
  1531. * @param {ByteInputStream} byte_pointer The byte stream to decode.
  1532. * @return {?number} The next code point decoded, or null if not enough
  1533. * data exists in the input stream to decode a complete code point.
  1534. */
  1535. this.decode = function(byte_pointer) {
  1536. var bite = byte_pointer.get();
  1537. if (bite !== EOF_byte) {
  1538. byte_pointer.offset(1);
  1539. }
  1540. switch (iso2022jp_state) {
  1541. default:
  1542. case state.ASCII:
  1543. if (bite === 0x1B) {
  1544. iso2022jp_state = state.escape_start;
  1545. return null;
  1546. }
  1547. if (inRange(bite, 0x00, 0x7F)) {
  1548. return bite;
  1549. }
  1550. if (bite === EOF_byte) {
  1551. return EOF_code_point;
  1552. }
  1553. return decoderError(fatal);
  1554. case state.escape_start:
  1555. if (bite === 0x24 || bite === 0x28) {
  1556. iso2022jp_lead = bite;
  1557. iso2022jp_state = state.escape_middle;
  1558. return null;
  1559. }
  1560. if (bite !== EOF_byte) {
  1561. byte_pointer.offset(-1);
  1562. }
  1563. iso2022jp_state = state.ASCII;
  1564. return decoderError(fatal);
  1565. case state.escape_middle:
  1566. var lead = iso2022jp_lead;
  1567. iso2022jp_lead = 0x00;
  1568. if (lead === 0x24 && (bite === 0x40 || bite === 0x42)) {
  1569. iso2022jp_jis0212 = false;
  1570. iso2022jp_state = state.lead;
  1571. return null;
  1572. }
  1573. if (lead === 0x24 && bite === 0x28) {
  1574. iso2022jp_state = state.escape_final;
  1575. return null;
  1576. }
  1577. if (lead === 0x28 && (bite === 0x42 || bite === 0x4A)) {
  1578. iso2022jp_state = state.ASCII;
  1579. return null;
  1580. }
  1581. if (lead === 0x28 && bite === 0x49) {
  1582. iso2022jp_state = state.Katakana;
  1583. return null;
  1584. }
  1585. if (bite === EOF_byte) {
  1586. byte_pointer.offset(-1);
  1587. } else {
  1588. byte_pointer.offset(-2);
  1589. }
  1590. iso2022jp_state = state.ASCII;
  1591. return decoderError(fatal);
  1592. case state.escape_final:
  1593. if (bite === 0x44) {
  1594. iso2022jp_jis0212 = true;
  1595. iso2022jp_state = state.lead;
  1596. return null;
  1597. }
  1598. if (bite === EOF_byte) {
  1599. byte_pointer.offset(-2);
  1600. } else {
  1601. byte_pointer.offset(-3);
  1602. }
  1603. iso2022jp_state = state.ASCII;
  1604. return decoderError(fatal);
  1605. case state.lead:
  1606. if (bite === 0x0A) {
  1607. iso2022jp_state = state.ASCII;
  1608. return decoderError(fatal, 0x000A);
  1609. }
  1610. if (bite === 0x1B) {
  1611. iso2022jp_state = state.escape_start;
  1612. return null;
  1613. }
  1614. if (bite === EOF_byte) {
  1615. return EOF_code_point;
  1616. }
  1617. iso2022jp_lead = bite;
  1618. iso2022jp_state = state.trail;
  1619. return null;
  1620. case state.trail:
  1621. iso2022jp_state = state.lead;
  1622. if (bite === EOF_byte) {
  1623. return decoderError(fatal);
  1624. }
  1625. var code_point = null;
  1626. var pointer = (iso2022jp_lead - 0x21) * 94 + bite - 0x21;
  1627. if (inRange(iso2022jp_lead, 0x21, 0x7E) &&
  1628. inRange(bite, 0x21, 0x7E)) {
  1629. code_point = (iso2022jp_jis0212 === false) ?
  1630. indexCodePointFor(pointer, index('jis0208')) :
  1631. indexCodePointFor(pointer, index('jis0212'));
  1632. }
  1633. if (code_point === null) {
  1634. return decoderError(fatal);
  1635. }
  1636. return code_point;
  1637. case state.Katakana:
  1638. if (bite === 0x1B) {
  1639. iso2022jp_state = state.escape_start;
  1640. return null;
  1641. }
  1642. if (inRange(bite, 0x21, 0x5F)) {
  1643. return 0xFF61 + bite - 0x21;
  1644. }
  1645. if (bite === EOF_byte) {
  1646. return EOF_code_point;
  1647. }
  1648. return decoderError(fatal);
  1649. }
  1650. };
  1651. }
  1652. /**
  1653. * @constructor
  1654. * @param {{fatal: boolean}} options
  1655. */
  1656. function ISO2022JPEncoder(options) {
  1657. var fatal = options.fatal;
  1658. /** @enum */
  1659. var state = {
  1660. ASCII: 0,
  1661. lead: 1,
  1662. Katakana: 2
  1663. };
  1664. var /** @type {number} */ iso2022jp_state = state.ASCII;
  1665. /**
  1666. * @param {ByteOutputStream} output_byte_stream Output byte stream.
  1667. * @param {CodePointInputStream} code_point_pointer Input stream.
  1668. * @return {number} The last byte emitted.
  1669. */
  1670. this.encode = function(output_byte_stream, code_point_pointer) {
  1671. var code_point = code_point_pointer.get();
  1672. if (code_point === EOF_code_point) {
  1673. return EOF_byte;
  1674. }
  1675. code_point_pointer.offset(1);
  1676. if ((inRange(code_point, 0x0000, 0x007F) ||
  1677. code_point === 0x00A5 || code_point === 0x203E) &&
  1678. iso2022jp_state !== state.ASCII) {
  1679. code_point_pointer.offset(-1);
  1680. iso2022jp_state = state.ASCII;
  1681. return output_byte_stream.emit(0x1B, 0x28, 0x42);
  1682. }
  1683. if (inRange(code_point, 0x0000, 0x007F)) {
  1684. return output_byte_stream.emit(code_point);
  1685. }
  1686. if (code_point === 0x00A5) {
  1687. return output_byte_stream.emit(0x5C);
  1688. }
  1689. if (code_point === 0x203E) {
  1690. return output_byte_stream.emit(0x7E);
  1691. }
  1692. if (inRange(code_point, 0xFF61, 0xFF9F) &&
  1693. iso2022jp_state !== state.Katakana) {
  1694. code_point_pointer.offset(-1);
  1695. iso2022jp_state = state.Katakana;
  1696. return output_byte_stream.emit(0x1B, 0x28, 0x49);
  1697. }
  1698. if (inRange(code_point, 0xFF61, 0xFF9F)) {
  1699. return output_byte_stream.emit(code_point - 0xFF61 - 0x21);
  1700. }
  1701. if (iso2022jp_state !== state.lead) {
  1702. code_point_pointer.offset(-1);
  1703. iso2022jp_state = state.lead;
  1704. return output_byte_stream.emit(0x1B, 0x24, 0x42);
  1705. }
  1706. var pointer = indexPointerFor(code_point, index('jis0208'));
  1707. if (pointer === null) {
  1708. return encoderError(code_point);
  1709. }
  1710. var lead = div(pointer, 94) + 0x21;
  1711. var trail = pointer % 94 + 0x21;
  1712. return output_byte_stream.emit(lead, trail);
  1713. };
  1714. }
  1715. /** @param {{fatal: boolean}} options */
  1716. name_to_encoding['iso-2022-jp'].getEncoder = function(options) {
  1717. return new ISO2022JPEncoder(options);
  1718. };
  1719. /** @param {{fatal: boolean}} options */
  1720. name_to_encoding['iso-2022-jp'].getDecoder = function(options) {
  1721. return new ISO2022JPDecoder(options);
  1722. };
  1723. // 11.3 shift_jis
  1724. /**
  1725. * @constructor
  1726. * @param {{fatal: boolean}} options
  1727. */
  1728. function ShiftJISDecoder(options) {
  1729. var fatal = options.fatal;
  1730. var /** @type {number} */ shiftjis_lead = 0x00;
  1731. /**
  1732. * @param {ByteInputStream} byte_pointer The byte stream to decode.
  1733. * @return {?number} The next code point decoded, or null if not enough
  1734. * data exists in the input stream to decode a complete code point.
  1735. */
  1736. this.decode = function(byte_pointer) {
  1737. var bite = byte_pointer.get();
  1738. if (bite === EOF_byte && shiftjis_lead === 0x00) {
  1739. return EOF_code_point;
  1740. }
  1741. if (bite === EOF_byte && shiftjis_lead !== 0x00) {
  1742. shiftjis_lead = 0x00;
  1743. return decoderError(fatal);
  1744. }
  1745. byte_pointer.offset(1);
  1746. if (shiftjis_lead !== 0x00) {
  1747. var lead = shiftjis_lead;
  1748. shiftjis_lead = 0x00;
  1749. if (inRange(bite, 0x40, 0x7E) || inRange(bite, 0x80, 0xFC)) {
  1750. var offset = (bite < 0x7F) ? 0x40 : 0x41;
  1751. var lead_offset = (lead < 0xA0) ? 0x81 : 0xC1;
  1752. var code_point = indexCodePointFor((lead - lead_offset) * 188 +
  1753. bite - offset, index('jis0208'));
  1754. if (code_point === null) {
  1755. return decoderError(fatal);
  1756. }
  1757. return code_point;
  1758. }
  1759. byte_pointer.offset(-1);
  1760. return decoderError(fatal);
  1761. }
  1762. if (inRange(bite, 0x00, 0x80)) {
  1763. return bite;
  1764. }
  1765. if (inRange(bite, 0xA1, 0xDF)) {
  1766. return 0xFF61 + bite - 0xA1;
  1767. }
  1768. if (inRange(bite, 0x81, 0x9F) || inRange(bite, 0xE0, 0xFC)) {
  1769. shiftjis_lead = bite;
  1770. return null;
  1771. }
  1772. return decoderError(fatal);
  1773. };
  1774. }
  1775. /**
  1776. * @constructor
  1777. * @param {{fatal: boolean}} options
  1778. */
  1779. function ShiftJISEncoder(options) {
  1780. var fatal = options.fatal;
  1781. /**
  1782. * @param {ByteOutputStream} output_byte_stream Output byte stream.
  1783. * @param {CodePointInputStream} code_point_pointer Input stream.
  1784. * @return {number} The last byte emitted.
  1785. */
  1786. this.encode = function(output_byte_stream, code_point_pointer) {
  1787. var code_point = code_point_pointer.get();
  1788. if (code_point === EOF_code_point) {
  1789. return EOF_byte;
  1790. }
  1791. code_point_pointer.offset(1);
  1792. if (inRange(code_point, 0x0000, 0x0080)) {
  1793. return output_byte_stream.emit(code_point);
  1794. }
  1795. if (code_point === 0x00A5) {
  1796. return output_byte_stream.emit(0x5C);
  1797. }
  1798. if (code_point === 0x203E) {
  1799. return output_byte_stream.emit(0x7E);
  1800. }
  1801. if (inRange(code_point, 0xFF61, 0xFF9F)) {
  1802. return output_byte_stream.emit(code_point - 0xFF61 + 0xA1);
  1803. }
  1804. var pointer = indexPointerFor(code_point, index('jis0208'));
  1805. if (pointer === null) {
  1806. return encoderError(code_point);
  1807. }
  1808. var lead = div(pointer, 188);
  1809. var lead_offset = lead < 0x1F ? 0x81 : 0xC1;
  1810. var trail = pointer % 188;
  1811. var offset = trail < 0x3F ? 0x40 : 0x41;
  1812. return output_byte_stream.emit(lead + lead_offset, trail + offset);
  1813. };
  1814. }
  1815. /** @param {{fatal: boolean}} options */
  1816. name_to_encoding['shift_jis'].getEncoder = function(options) {
  1817. return new ShiftJISEncoder(options);
  1818. };
  1819. /** @param {{fatal: boolean}} options */
  1820. name_to_encoding['shift_jis'].getDecoder = function(options) {
  1821. return new ShiftJISDecoder(options);
  1822. };
  1823. //
  1824. // 12. Legacy multi-byte Korean encodings
  1825. //
  1826. // 12.1 euc-kr
  1827. /**
  1828. * @constructor
  1829. * @param {{fatal: boolean}} options
  1830. */
  1831. function EUCKRDecoder(options) {
  1832. var fatal = options.fatal;
  1833. var /** @type {number} */ euckr_lead = 0x00;
  1834. /**
  1835. * @param {ByteInputStream} byte_pointer The byte stream to decode.
  1836. * @return {?number} The next code point decoded, or null if not enough
  1837. * data exists in the input stream to decode a complete code point.
  1838. */
  1839. this.decode = function(byte_pointer) {
  1840. var bite = byte_pointer.get();
  1841. if (bite === EOF_byte && euckr_lead === 0) {
  1842. return EOF_code_point;
  1843. }
  1844. if (bite === EOF_byte && euckr_lead !== 0) {
  1845. euckr_lead = 0x00;
  1846. return decoderError(fatal);
  1847. }
  1848. byte_pointer.offset(1);
  1849. if (euckr_lead !== 0x00) {
  1850. var lead = euckr_lead;
  1851. var pointer = null;
  1852. euckr_lead = 0x00;
  1853. if (inRange(lead, 0x81, 0xC6)) {
  1854. var temp = (26 + 26 + 126) * (lead - 0x81);
  1855. if (inRange(bite, 0x41, 0x5A)) {
  1856. pointer = temp + bite - 0x41;
  1857. } else if (inRange(bite, 0x61, 0x7A)) {
  1858. pointer = temp + 26 + bite - 0x61;
  1859. } else if (inRange(bite, 0x81, 0xFE)) {
  1860. pointer = temp + 26 + 26 + bite - 0x81;
  1861. }
  1862. }
  1863. if (inRange(lead, 0xC7, 0xFD) && inRange(bite, 0xA1, 0xFE)) {
  1864. pointer = (26 + 26 + 126) * (0xC7 - 0x81) + (lead - 0xC7) * 94 +
  1865. (bite - 0xA1);
  1866. }
  1867. var code_point = (pointer === null) ? null :
  1868. indexCodePointFor(pointer, index('euc-kr'));
  1869. if (pointer === null) {
  1870. byte_pointer.offset(-1);
  1871. }
  1872. if (code_point === null) {
  1873. return decoderError(fatal);
  1874. }
  1875. return code_point;
  1876. }
  1877. if (inRange(bite, 0x00, 0x7F)) {
  1878. return bite;
  1879. }
  1880. if (inRange(bite, 0x81, 0xFD)) {
  1881. euckr_lead = bite;
  1882. return null;
  1883. }
  1884. return decoderError(fatal);
  1885. };
  1886. }
  1887. /**
  1888. * @constructor
  1889. * @param {{fatal: boolean}} options
  1890. */
  1891. function EUCKREncoder(options) {
  1892. var fatal = options.fatal;
  1893. /**
  1894. * @param {ByteOutputStream} output_byte_stream Output byte stream.
  1895. * @param {CodePointInputStream} code_point_pointer Input stream.
  1896. * @return {number} The last byte emitted.
  1897. */
  1898. this.encode = function(output_byte_stream, code_point_pointer) {
  1899. var code_point = code_point_pointer.get();
  1900. if (code_point === EOF_code_point) {
  1901. return EOF_byte;
  1902. }
  1903. code_point_pointer.offset(1);
  1904. if (inRange(code_point, 0x0000, 0x007F)) {
  1905. return output_byte_stream.emit(code_point);
  1906. }
  1907. var pointer = indexPointerFor(code_point, index('euc-kr'));
  1908. if (pointer === null) {
  1909. return encoderError(code_point);
  1910. }
  1911. var lead, trail;
  1912. if (pointer < ((26 + 26 + 126) * (0xC7 - 0x81))) {
  1913. lead = div(pointer, (26 + 26 + 126)) + 0x81;
  1914. trail = pointer % (26 + 26 + 126);
  1915. var offset = trail < 26 ? 0x41 : trail < 26 + 26 ? 0x47 : 0x4D;
  1916. return output_byte_stream.emit(lead, trail + offset);
  1917. }
  1918. pointer = pointer - (26 + 26 + 126) * (0xC7 - 0x81);
  1919. lead = div(pointer, 94) + 0xC7;
  1920. trail = pointer % 94 + 0xA1;
  1921. return output_byte_stream.emit(lead, trail);
  1922. };
  1923. }
  1924. /** @param {{fatal: boolean}} options */
  1925. name_to_encoding['euc-kr'].getEncoder = function(options) {
  1926. return new EUCKREncoder(options);
  1927. };
  1928. /** @param {{fatal: boolean}} options */
  1929. name_to_encoding['euc-kr'].getDecoder = function(options) {
  1930. return new EUCKRDecoder(options);
  1931. };
  1932. //
  1933. // 13. Legacy utf-16 encodings
  1934. //
  1935. // 13.1 utf-16
  1936. /**
  1937. * @constructor
  1938. * @param {boolean} utf16_be True if big-endian, false if little-endian.
  1939. * @param {{fatal: boolean}} options
  1940. */
  1941. function UTF16Decoder(utf16_be, options) {
  1942. var fatal = options.fatal;
  1943. var /** @type {?number} */ utf16_lead_byte = null,
  1944. /** @type {?number} */ utf16_lead_surrogate = null;
  1945. /**
  1946. * @param {ByteInputStream} byte_pointer The byte stream to decode.
  1947. * @return {?number} The next code point decoded, or null if not enough
  1948. * data exists in the input stream to decode a complete code point.
  1949. */
  1950. this.decode = function(byte_pointer) {
  1951. var bite = byte_pointer.get();
  1952. if (bite === EOF_byte && utf16_lead_byte === null &&
  1953. utf16_lead_surrogate === null) {
  1954. return EOF_code_point;
  1955. }
  1956. if (bite === EOF_byte && (utf16_lead_byte !== null ||
  1957. utf16_lead_surrogate !== null)) {
  1958. return decoderError(fatal);
  1959. }
  1960. byte_pointer.offset(1);
  1961. if (utf16_lead_byte === null) {
  1962. utf16_lead_byte = bite;
  1963. return null;
  1964. }
  1965. var code_point;
  1966. if (utf16_be) {
  1967. code_point = (utf16_lead_byte << 8) + bite;
  1968. } else {
  1969. code_point = (bite << 8) + utf16_lead_byte;
  1970. }
  1971. utf16_lead_byte = null;
  1972. if (utf16_lead_surrogate !== null) {
  1973. var lead_surrogate = utf16_lead_surrogate;
  1974. utf16_lead_surrogate = null;
  1975. if (inRange(code_point, 0xDC00, 0xDFFF)) {
  1976. return 0x10000 + (lead_surrogate - 0xD800) * 0x400 +
  1977. (code_point - 0xDC00);
  1978. }
  1979. byte_pointer.offset(-2);
  1980. return decoderError(fatal);
  1981. }
  1982. if (inRange(code_point, 0xD800, 0xDBFF)) {
  1983. utf16_lead_surrogate = code_point;
  1984. return null;
  1985. }
  1986. if (inRange(code_point, 0xDC00, 0xDFFF)) {
  1987. return decoderError(fatal);
  1988. }
  1989. return code_point;
  1990. };
  1991. }
  1992. /**
  1993. * @constructor
  1994. * @param {boolean} utf16_be True if big-endian, false if little-endian.
  1995. * @param {{fatal: boolean}} options
  1996. */
  1997. function UTF16Encoder(utf16_be, options) {
  1998. var fatal = options.fatal;
  1999. /**
  2000. * @param {ByteOutputStream} output_byte_stream Output byte stream.
  2001. * @param {CodePointInputStream} code_point_pointer Input stream.
  2002. * @return {number} The last byte emitted.
  2003. */
  2004. this.encode = function(output_byte_stream, code_point_pointer) {
  2005. /**
  2006. * @param {number} code_unit
  2007. * @return {number} last byte emitted
  2008. */
  2009. function convert_to_bytes(code_unit) {
  2010. var byte1 = code_unit >> 8;
  2011. var byte2 = code_unit & 0x00FF;
  2012. if (utf16_be) {
  2013. return output_byte_stream.emit(byte1, byte2);
  2014. }
  2015. return output_byte_stream.emit(byte2, byte1);
  2016. }
  2017. var code_point = code_point_pointer.get();
  2018. if (code_point === EOF_code_point) {
  2019. return EOF_byte;
  2020. }
  2021. code_point_pointer.offset(1);
  2022. if (inRange(code_point, 0xD800, 0xDFFF)) {
  2023. encoderError(code_point);
  2024. }
  2025. if (code_point <= 0xFFFF) {
  2026. return convert_to_bytes(code_point);
  2027. }
  2028. var lead = div((code_point - 0x10000), 0x400) + 0xD800;
  2029. var trail = ((code_point - 0x10000) % 0x400) + 0xDC00;
  2030. convert_to_bytes(lead);
  2031. return convert_to_bytes(trail);
  2032. };
  2033. }
  2034. /** @param {{fatal: boolean}} options */
  2035. name_to_encoding['utf-16le'].getEncoder = function(options) {
  2036. return new UTF16Encoder(false, options);
  2037. };
  2038. /** @param {{fatal: boolean}} options */
  2039. name_to_encoding['utf-16le'].getDecoder = function(options) {
  2040. return new UTF16Decoder(false, options);
  2041. };
  2042. // 13.2 utf-16be
  2043. /** @param {{fatal: boolean}} options */
  2044. name_to_encoding['utf-16be'].getEncoder = function(options) {
  2045. return new UTF16Encoder(true, options);
  2046. };
  2047. /** @param {{fatal: boolean}} options */
  2048. name_to_encoding['utf-16be'].getDecoder = function(options) {
  2049. return new UTF16Decoder(true, options);
  2050. };
  2051. // NOTE: currently unused
  2052. /**
  2053. * @param {string} label The encoding label.
  2054. * @param {ByteInputStream} input_stream The byte stream to test.
  2055. */
  2056. function detectEncoding(label, input_stream) {
  2057. if (input_stream.match([0xFF, 0xFE])) {
  2058. input_stream.offset(2);
  2059. return 'utf-16le';
  2060. }
  2061. if (input_stream.match([0xFE, 0xFF])) {
  2062. input_stream.offset(2);
  2063. return 'utf-16be';
  2064. }
  2065. if (input_stream.match([0xEF, 0xBB, 0xBF])) {
  2066. input_stream.offset(3);
  2067. return 'utf-8';
  2068. }
  2069. return label;
  2070. }
  2071. //
  2072. // Implementation of Text Encoding Web API
  2073. //
  2074. /** @const */ var DEFAULT_ENCODING = 'utf-8';
  2075. /**
  2076. * @constructor
  2077. * @param {string=} opt_encoding The label of the encoding;
  2078. * defaults to 'utf-8'.
  2079. * @param {{fatal: boolean}=} options
  2080. */
  2081. function TextEncoderEx(opt_encoding, options) {
  2082. if (!(this instanceof TextEncoderEx)) {
  2083. return new TextEncoderEx(opt_encoding, options);
  2084. }
  2085. opt_encoding = opt_encoding ? String(opt_encoding) : DEFAULT_ENCODING;
  2086. options = Object(options);
  2087. /** @private */
  2088. this._encoding = getEncoding(opt_encoding);
  2089. if (this._encoding === null)
  2090. throw new TypeError('Unknown encoding: ' + opt_encoding);
  2091. /** @private @type {boolean} */
  2092. this._streaming = false;
  2093. /** @private */
  2094. this._encoder = null;
  2095. /** @private @type {{fatal: boolean}=} */
  2096. this._options = { fatal: Boolean(options.fatal) };
  2097. if (Object.defineProperty) {
  2098. Object.defineProperty(
  2099. this, 'encoding',
  2100. { get: function() { return this._encoding.name; } });
  2101. } else {
  2102. this.encoding = this._encoding.name;
  2103. }
  2104. return this;
  2105. }
  2106. TextEncoderEx.prototype = {
  2107. /**
  2108. * @param {string=} opt_string The string to encode.
  2109. * @param {{stream: boolean}=} options
  2110. */
  2111. encode: function encode(opt_string, options) {
  2112. opt_string = opt_string ? String(opt_string) : '';
  2113. options = Object(options);
  2114. // TODO: any options?
  2115. if (!this._streaming) {
  2116. this._encoder = this._encoding.getEncoder(this._options);
  2117. }
  2118. this._streaming = Boolean(options.stream);
  2119. var bytes = [];
  2120. var output_stream = new ByteOutputStream(bytes);
  2121. var input_stream = new CodePointInputStream(opt_string);
  2122. while (input_stream.get() !== EOF_code_point) {
  2123. this._encoder.encode(output_stream, input_stream);
  2124. }
  2125. if (!this._streaming) {
  2126. /** @type {number} */
  2127. var last_byte;
  2128. do {
  2129. last_byte = this._encoder.encode(output_stream, input_stream);
  2130. } while (last_byte !== EOF_byte);
  2131. this._encoder = null;
  2132. }
  2133. return new Uint8Array(bytes);
  2134. }
  2135. };
  2136. /**
  2137. * @constructor
  2138. * @param {string=} opt_encoding The label of the encoding;
  2139. * defaults to 'utf-8'.
  2140. * @param {{fatal: boolean}=} options
  2141. */
  2142. function TextDecoder(opt_encoding, options) {
  2143. if (!(this instanceof TextDecoder)) {
  2144. return new TextDecoder(opt_encoding, options);
  2145. }
  2146. opt_encoding = opt_encoding ? String(opt_encoding) : DEFAULT_ENCODING;
  2147. options = Object(options);
  2148. /** @private */
  2149. this._encoding = getEncoding(opt_encoding);
  2150. if (this._encoding === null)
  2151. throw new TypeError('Unknown encoding: ' + opt_encoding);
  2152. /** @private @type {boolean} */
  2153. this._streaming = false;
  2154. /** @private @type {boolean} */
  2155. this._BOMseen = false;
  2156. /** @private */
  2157. this._decoder = null;
  2158. /** @private @type {{fatal: boolean}=} */
  2159. this._options = { fatal: Boolean(options.fatal) };
  2160. if (Object.defineProperty) {
  2161. Object.defineProperty(
  2162. this, 'encoding',
  2163. { get: function() { return this._encoding.name; } });
  2164. } else {
  2165. this.encoding = this._encoding.name;
  2166. }
  2167. return this;
  2168. }
  2169. // TODO: Issue if input byte stream is offset by decoder
  2170. // TODO: BOM detection will not work if stream header spans multiple calls
  2171. // (last N bytes of previous stream may need to be retained?)
  2172. TextDecoder.prototype = {
  2173. /**
  2174. * @param {ArrayBufferView=} opt_view The buffer of bytes to decode.
  2175. * @param {{stream: boolean}=} options
  2176. */
  2177. decode: function decode(opt_view, options) {
  2178. if (opt_view && !('buffer' in opt_view && 'byteOffset' in opt_view &&
  2179. 'byteLength' in opt_view)) {
  2180. throw new TypeError('Expected ArrayBufferView');
  2181. } else if (!opt_view) {
  2182. opt_view = new Uint8Array(0);
  2183. }
  2184. options = Object(options);
  2185. if (!this._streaming) {
  2186. this._decoder = this._encoding.getDecoder(this._options);
  2187. this._BOMseen = false;
  2188. }
  2189. this._streaming = Boolean(options.stream);
  2190. var bytes = new Uint8Array(opt_view.buffer,
  2191. opt_view.byteOffset,
  2192. opt_view.byteLength);
  2193. var input_stream = new ByteInputStream(bytes);
  2194. var output_stream = new CodePointOutputStream();
  2195. /** @type {number} */
  2196. var code_point;
  2197. while (input_stream.get() !== EOF_byte) {
  2198. code_point = this._decoder.decode(input_stream);
  2199. if (code_point !== null && code_point !== EOF_code_point) {
  2200. output_stream.emit(code_point);
  2201. }
  2202. }
  2203. if (!this._streaming) {
  2204. do {
  2205. code_point = this._decoder.decode(input_stream);
  2206. if (code_point !== null && code_point !== EOF_code_point) {
  2207. output_stream.emit(code_point);
  2208. }
  2209. } while (code_point !== EOF_code_point &&
  2210. input_stream.get() != EOF_byte);
  2211. this._decoder = null;
  2212. }
  2213. var result = output_stream.string();
  2214. if (!this._BOMseen && result.length) {
  2215. this._BOMseen = true;
  2216. if (['utf-8', 'utf-16le', 'utf-16be'].indexOf(this.encoding) !== -1 &&
  2217. result.charCodeAt(0) === 0xFEFF) {
  2218. result = result.substring(1);
  2219. }
  2220. }
  2221. return result;
  2222. }
  2223. };
  2224. if (!('TextEncoderEx' in global)) global['TextEncoderEx'] = TextEncoderEx;
  2225. if (!('TextDecoder' in global)) global['TextDecoder'] = TextDecoder;
  2226. }(this));