Path: blob/main/extensions/copilot/src/util/common/hexdump.ts
13397 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45/**6* Formats a byte range from a Uint8Array in a hexdump-style format.7*8* Each line contains:9* - An 8-character hex offset10* - Up to 16 bytes shown as two-digit hex values (grouped in pairs of 8)11* - An ASCII representation where non-printable bytes are shown as '.'12*13* Example output:14* ```15* 00000000 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 |MZ..............|16* 00000010 b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 |........@.......|17* ```18*/19export function formatHexdump(data: Uint8Array, startOffset: number = 0, maxBytes?: number): string {20const bytesToFormat = maxBytes !== undefined ? Math.min(data.length - startOffset, maxBytes) : data.length - startOffset;21if (bytesToFormat <= 0) {22return '';23}2425const lines: string[] = [];26const bytesPerLine = 16;2728for (let i = 0; i < bytesToFormat; i += bytesPerLine) {29const offset = startOffset + i;30const lineBytes = Math.min(bytesPerLine, bytesToFormat - i);31const slice = data.subarray(startOffset + i, startOffset + i + lineBytes);3233// Offset column34const offsetStr = offset.toString(16).padStart(8, '0');3536// Hex columns (two groups of 8 bytes)37const hexParts: string[] = [];38for (let j = 0; j < bytesPerLine; j++) {39if (j === 8) {40hexParts.push('');41}42if (j < lineBytes) {43hexParts.push(slice[j].toString(16).padStart(2, '0'));44} else {45hexParts.push(' ');46}47}48const hexStr = hexParts.join(' ');4950// ASCII column51let ascii = '';52for (let j = 0; j < lineBytes; j++) {53const byte = slice[j];54ascii += (byte >= 0x20 && byte <= 0x7e) ? String.fromCharCode(byte) : '.';55}5657lines.push(`${offsetStr} ${hexStr} |${ascii}|`);58}5960return lines.join('\n');61}6263/**64* Returns true if the data appears to be binary content rather than valid text.65* Uses the same heuristic as git: the presence of any null byte (0x00) in the66* first 8KB indicates binary content.67*/68export function isBinaryContent(data: Uint8Array): boolean {69const checkLength = Math.min(data.length, 8192);70for (let i = 0; i < checkLength; i++) {71if (data[i] === 0) {72return true;73}74}75return false;76}777879