const ArrayBufferTools = { delete: arrayBufferDelete, insert: arrayBufferInsert, replaceByPosition: arrayBufferReplaceByPosition, replaceByData: arrayBufferReplaceByData, find: arrayBufferFind, toArrayBuffer, toString: arrayBufferToString, } export { ArrayBufferTools } /** 删除指定范围的数据 */ export function arrayBufferDelete(buffer: ArrayBuffer, start: number, end: number): ArrayBuffer { const view = new Uint8Array(buffer) const newArray = new Uint8Array(view.length - (end - start)) newArray.set(view.subarray(0, start)) newArray.set(view.subarray(end), start) return newArray.buffer } /** 插入数据到指定位置 */ export function arrayBufferInsert(buffer: ArrayBuffer, start: number, data: ArrayBuffer | string): ArrayBuffer { const view = new Uint8Array(buffer) const insertView = typeof data === "string" ? new TextEncoder().encode(data) : new Uint8Array(data) if (insertView.length === 0) return buffer.slice(0) const insertPos = Math.max(0, Math.min(view.length, start)) const newArray = new Uint8Array(view.length + insertView.length) newArray.set(view.subarray(0, insertPos)) newArray.set(insertView, insertPos) newArray.set(view.subarray(insertPos), insertPos + insertView.length) return newArray.buffer } /** 替换指定范围的数据 */ export function arrayBufferReplaceByPosition( buffer: ArrayBuffer, start: number, end: number, data: ArrayBuffer | string ): ArrayBuffer { const view = new Uint8Array(buffer) const replaceView = typeof data === "string" ? new TextEncoder().encode(data) : new Uint8Array(data) if (replaceView.length === 0) return buffer.slice(0) const replaceStart = Math.max(0, Math.min(view.length, start)) const replaceEnd = Math.max(replaceStart, Math.min(view.length, end)) const newArray = new Uint8Array(view.length - (replaceEnd - replaceStart) + replaceView.length) newArray.set(view.subarray(0, replaceStart)) newArray.set(replaceView, replaceStart) newArray.set(view.subarray(replaceEnd), replaceStart + replaceView.length) return newArray.buffer } /** 替换数据中指定部分为新内容 */ export function arrayBufferReplaceByData( buffer: ArrayBuffer, find: ArrayBuffer | string, replace: ArrayBuffer | string | ((findIndex: number) => ArrayBuffer | string), options?: { start?: number end?: number all?: boolean } ): ArrayBuffer { const view = new Uint8Array(buffer) const pattern = typeof find === "string" ? new TextEncoder().encode(find) : new Uint8Array(find) if (pattern.length === 0) return buffer.slice(0) const start = Math.max(0, Math.min(view.length, options?.start ?? 0)) const end = Math.max(start, Math.min(view.length, options?.end ?? view.length)) if (pattern.length > end - start) return buffer.slice(0) // 先收集所有匹配位置(基于原始 buffer 的索引) const matches: number[] = [] let i = start while (i <= end - pattern.length) { let matched = true for (let j = 0; j < pattern.length; j++) { if (view[i + j] !== pattern[j]) { matched = false break } } if (matched) { matches.push(i) if (!options?.all) break i += pattern.length } else { i++ } } if (matches.length === 0) return buffer.slice(0) // 分两种情况处理:replace 为函数 vs 固定数据 if (typeof replace === "function") { let result = buffer let offset = 0 for (const match of matches) { // 针对该次匹配生成替换内容 const out = replace(match) const replaceBytes = typeof out === "string" ? new TextEncoder().encode(out) : new Uint8Array(out) // 与原实现保持一致:若替换内容长度为 0,则不作修改 if (replaceBytes.length === 0) { continue } const replaceStart = match + offset const replaceEnd = replaceStart + pattern.length // 确保传入的 ArrayBuffer 与 replaceBytes 的可见区间一致 const replaceAB = replaceBytes.byteOffset === 0 && replaceBytes.byteLength === replaceBytes.buffer.byteLength ? replaceBytes.buffer : replaceBytes.buffer.slice( replaceBytes.byteOffset, replaceBytes.byteOffset + replaceBytes.byteLength ) result = arrayBufferReplaceByPosition(result, replaceStart, replaceEnd, replaceAB) offset += replaceBytes.length - pattern.length } return result } else { // 固定数据路径(保持原有逻辑与行为) const replaceView = typeof replace === "string" ? new TextEncoder().encode(replace) : new Uint8Array(replace) if (replaceView.length === 0) return buffer.slice(0) let result = buffer let offset = 0 const delta = replaceView.length - pattern.length for (const match of matches) { const replaceStart = match + offset const replaceEnd = replaceStart + pattern.length result = arrayBufferReplaceByPosition(result, replaceStart, replaceEnd, replace) offset += delta } return result } } /** 在数据中查找指定内容,未找到时返回 -1 */ export function arrayBufferFind( buffer: ArrayBuffer, find: ArrayBuffer | string, options?: { start?: number end?: number } ): number { const view = new Uint8Array(buffer) const pattern = typeof find === "string" ? new TextEncoder().encode(find) : new Uint8Array(find) const start = Math.max(0, Math.min(view.length, options?.start ?? 0)) const end = Math.max(start, Math.min(view.length, options?.end ?? view.length)) if (pattern.length === 0) return start if (pattern.length > end - start) return -1 for (let i = start; i <= end - pattern.length; i++) { let matched = true for (let j = 0; j < pattern.length; j++) { if (view[i + j] !== pattern[j]) { matched = false break } } if (matched) return i } return -1 } /** 将 Buffer、ArrayBuffer 或 Uint8Array 转换为 ArrayBuffer */ export function toArrayBuffer(buffer: Buffer | ArrayBuffer | Uint8Array): ArrayBuffer { if (buffer instanceof ArrayBuffer) return buffer if (buffer instanceof Uint8Array) return buffer.buffer as ArrayBuffer return buffer } /** 将 ArrayBuffer 转换为字符串 */ export function arrayBufferToString(buffer: ArrayBuffer, encoding?: string): string { const uint8Array = new Uint8Array(buffer) const decoder = new TextDecoder(encoding || "utf-8") return decoder.decode(uint8Array) }