(function (exports) { 'use strict'; // unpack labels with 0x20 compression pointer support // ui8 is the ArrayBuffer of the entire packet // ptr is the current index of the packet // q = { byteLength: 0, cpcount: 0, labels: [], name: '' } exports.DNS_UNPACK_LABELS = function (ui8, ptr, q) { if (q.cpcount > 25) { throw new Error("compression pointer loop detected (over 25 pointers seems like a loop)"); } var total = ptr; var i; var len; var label = []; do { console.log("total: " + total); label.length = 0; len = ui8[total]; console.log("len: " + len); if (len === undefined){ console.log("error!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); } if (0xc0 === len) { var cpptr = ui8[total + 1]; // we're not coming back! ptr = cpptr; q.cpcount += 1; q.byteLength += 2; // cp and len // recursion return exports.DNS_UNPACK_LABELS(ui8, ptr, q); } //str.length = 0; // fast empty array if (ui8.byteLength - total < len) { throw new Error( "Expected a string of length " + len + " but packet itself has " + (ui8.byteLength - total) + " bytes remaining" ); } for (i = 0; i < len; i += 1) { total += 1; // TODO check url-allowable characters label.push(String.fromCharCode(ui8[total])); console.log("pushed (ui8) " + ui8[total] + " to labels at i = " + i); console.log("in char: " + String.fromCharCode(ui8[total])); } if (label.length) { console.log("pushed a label " + q.labels + " at index " + i); q.labels.push(label.join('')); } total += 1; // console.log('total', total, ui8[total], String.fromCharCode(ui8[total])); } while (len); //str.pop(); // remove trailing '.' q.name = q.labels.join('.'); if (0 === q.cpcount) { q.byteLength = total - ptr; } console.log("returning q! " + JSON.stringify(q)); return q; }; }('undefined' !== typeof window ? window : exports));