diff --git a/src/puz.js b/src/puz.js index 3aa7fdd..2fe6444 100644 --- a/src/puz.js +++ b/src/puz.js @@ -18,11 +18,8 @@ function strToBytes(str, end) { end = '\0'; } str += end; - var result = new Uint8Array(str.length); - for (var i = 0; i < str.length; i += 1) { - result[i] = str.charCodeAt(i); - } - return result; + const encoder = new TextEncoder('ISO-8859-1'); + return encoder.encode(str); } function concat(byteArrays) { @@ -280,7 +277,7 @@ function getExtension(bytes, code) { return null; // could not find } -function getRebus(bytes) { +function getRebus(bytes, encoding) { var grbs = 'GRBS'; var rtbl = 'RTBL'; @@ -289,7 +286,7 @@ function getRebus(bytes) { return; // no rebus } var solbytes = getExtension(bytes, rtbl); - var enc = new TextDecoder('ISO-8859-1'); + var enc = new TextDecoder(encoding); var solstring = enc.decode(new Uint8Array(solbytes)); if (!solstring) { return; @@ -356,7 +353,6 @@ function addRebusToGrid(grid, rebus) { function PUZtoJSON(buffer) { var grid = []; - var info = {}; var across = []; var down = []; var bytes = new Uint8Array(buffer); @@ -398,20 +394,34 @@ function PUZtoJSON(buffer) { } } - var ibyte = 52 + ncol * nrow * 2; + var ibyte; function readString() { - var result = ""; - var b = bytes[ibyte++]; - while (b !== 0) { - result += String.fromCharCode(b); - b = bytes[ibyte++]; + const start = ibyte; + while (bytes[ibyte] !== 0) { + ibyte++; } - return result; + ibyte++; + + const slice = bytes.slice(start, ibyte - 1); + return new TextDecoder(encoding).decode(slice); } - info.title = readString(); - info.author = readString(); - info.copyright = readString(); + function readInfo() { + ibyte = 52 + ncol * nrow * 2; + var title = readString(); + var author = readString(); + var copyright = readString(); + return { title, author, copyright }; + } + + // The PUZ spec reqiures ISO-8859-1 not UTF-8, but some files don't follow the spec. + // Sniff the copyright string for the © unicode which is only encoded correctly once. + var encoding = 'utf-8'; + var info = readInfo(); + if (!info.copyright.includes('©')) { + encoding = 'ISO-8859-1'; + info = readInfo(); + } for (var _i2 = 1; _i2 <= n; _i2++) { if (isAcross[_i2]) { @@ -424,7 +434,7 @@ function PUZtoJSON(buffer) { info.description = readString(); - var rebus = getRebus(bytes); + var rebus = getRebus(bytes, encoding); var circles = getCircles(bytes); var shades = getShades(bytes); if (rebus) {