(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 { label.length = 0; len = ui8[total]; if (0xc0 === len) { var cpptr = ui8[total + 1]; // we're not coming back! ptr = cpptr; q.cpcount += 1; q.byteLength += 2; // cp and len 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])); } if (label.length) { 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; } return q; }; }('undefined' !== typeof window ? window : exports));