diff --git a/src/lib/device.ts b/src/lib/device.ts index 18f6f91d2fd9f78fbb0bf953734e3a6fdfc12d6f..e71125bedebd01dcc31821f495c877924e686c25 100644 --- a/src/lib/device.ts +++ b/src/lib/device.ts @@ -14,6 +14,49 @@ export function getRandomId(): number { return Math.floor(Math.random() * 4294967295); } +function chunkText(str: string): string[] { + const arr = str.trim().split(/(\s+)/); + const ret: string[] = []; + let s: string = ''; + // @ts-expect-error shut up + const t = new TextEncoder(); + for (let n = 0; n < arr.length; n++) { + const ss = s + arr[n]; + const u8a = t.encode(ss); + if (u8a.byteLength < MAX_PAYLOAD) { // We are not yet at capacity + s = ss; // Grow the current string, do not append to ret since we still have space left + } else if (u8a.byteLength === MAX_PAYLOAD) { // We've reached capacity, + ret.push(ss.trim()); // Append current string to ret + s = ''; // Reset current string + } else { // Appending this word to the current string would exceed capacity + const st = s.trim(); + if (st !== '') ret.push(st); // Append the current string to ret as long as it isn't empty + s = ''; // Reset current string + const u8a = t.encode(arr[n]); + if (u8a.byteLength > MAX_PAYLOAD) { // This word alone exceeds payload length, break it up + for (let l = 0; l < arr[n].length; l++) { // Walk it character-by-character + const ss = s + arr[n].substring(l, l + 1); // Temp value for current string + this char + const u8a = t.encode(ss); + if (u8a.byteLength > MAX_PAYLOAD) { // If adding this char to the current string would exceed capacity + const st = s.trim(); + if (st !== '') ret.push(st); // Push the current string to ret if non empty + s = arr[n].substring(l, l + 1); // Set current string to this char + } else { // We can add this char to the current string + s = ss; + } + } + } else { // Add this word to the current string + s += arr[n]; + } + } + if (n === arr.length - 1) { + const st = s.trim(); // Ditto + if (st !== '') ret.push(s); + } + } + return ret; +} + export default abstract class Device extends js.global.EventEmitter { /** @param debug Enable debug logging (all sent and received frames, etc. - noisy) */