just-bash-mcp / src /utils /utf8.ts
victor's picture
victor HF Staff
Initial deploy of just-bash MCP server
548a458 verified
Raw
History Blame Contribute Delete
1.64 kB
export interface TruncationResult {
text: string;
bytes: number;
truncated: boolean;
}
export function truncateUtf8Safe(input: string, maxBytes: number): TruncationResult {
if (maxBytes <= 0) {
return { text: "", bytes: 0, truncated: input.length > 0 };
}
let used = 0;
let out = "";
for (const ch of input) {
const bytes = Buffer.byteLength(ch, "utf8");
if (used + bytes > maxBytes) {
return { text: out, bytes: used, truncated: true };
}
out += ch;
used += bytes;
}
return { text: out, bytes: used, truncated: false };
}
export function sliceUtf8Bytes(input: string, offset: number, maxBytes: number): {
text: string;
bytesRead: number;
totalBytes: number;
nextOffset: number | null;
} {
const buf = Buffer.from(input, "utf8");
const total = buf.length;
if (offset >= total) {
return { text: "", bytesRead: 0, totalBytes: total, nextOffset: null };
}
const end = Math.min(offset + maxBytes, total);
let safeEnd = end;
if (safeEnd < total) {
// Walk back until we are at a UTF-8 codepoint boundary.
while (safeEnd > offset && (buf[safeEnd] & 0xc0) === 0x80) {
safeEnd--;
}
}
const slice = buf.subarray(offset, safeEnd);
const text = slice.toString("utf8");
const nextOffset = safeEnd < total ? safeEnd : null;
return { text, bytesRead: safeEnd - offset, totalBytes: total, nextOffset };
}
export function isValidUtf8(buf: Uint8Array): boolean {
// Decode strict and re-encode; check round-trip.
try {
const td = new TextDecoder("utf-8", { fatal: true });
td.decode(buf);
return true;
} catch {
return false;
}
}