chrome-devtools-frontend
Version:
Chrome DevTools UI
73 lines (65 loc) • 2.63 kB
text/typescript
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* Quickly determine if gzipped, by seeing if the first 3 bytes of the file header match the gzip signature
*/
export function isGzip(ab: ArrayBuffer): boolean {
const buf = new Uint8Array(ab);
if (!buf || buf.length < 3) {
return false;
}
// https://www.rfc-editor.org/rfc/rfc1952#page-6
return buf[0] === 0x1F && buf[1] === 0x8B && buf[2] === 0x08;
}
/** Decode a gzipped _or_ plain text ArrayBuffer to a decoded string */
export async function arrayBufferToString(ab: ArrayBuffer): Promise<string> {
if (isGzip(ab)) {
return await decompress(ab);
}
const str = new TextDecoder('utf-8').decode(ab);
return str;
}
export async function fileToString(file: File): Promise<string> {
let stream = file.stream();
if (file.type.endsWith('gzip')) {
stream = decompressStream(stream);
}
const arrayBuffer = await new Response(stream).arrayBuffer();
const str = new TextDecoder('utf-8').decode(arrayBuffer);
return str;
}
/**
* Decompress a gzipped ArrayBuffer to a string.
* Consider using `arrayBufferToString` instead, which can handle both gzipped and plain text buffers.
*/
export async function decompress(gzippedBuffer: ArrayBuffer): Promise<string> {
const buffer = await gzipCodec(gzippedBuffer, new DecompressionStream('gzip'));
const str = new TextDecoder('utf-8').decode(buffer);
return str;
}
export async function compress(str: string): Promise<ArrayBuffer> {
const encoded = new TextEncoder().encode(str);
const buffer = await gzipCodec(encoded, new CompressionStream('gzip'));
return buffer;
}
/** Private coder/decoder **/
function gzipCodec(buffer: Uint8Array<ArrayBufferLike>|ArrayBuffer, codecStream: CompressionStream|DecompressionStream):
Promise<ArrayBuffer> {
const {readable, writable} = new TransformStream();
const codecReadable = readable.pipeThrough(codecStream);
const writer = writable.getWriter();
void writer.write(buffer);
void writer.close();
// A response is a convenient way to get an ArrayBuffer from a ReadableStream.
return new Response(codecReadable).arrayBuffer();
}
export function decompressStream(stream: ReadableStream): ReadableStream {
// https://github.com/wicg/compression/blob/main/explainer.md#deflate-compress-an-arraybuffer
const ds = new DecompressionStream('gzip');
return stream.pipeThrough(ds);
}
export function compressStream(stream: ReadableStream): ReadableStream {
const cs = new CompressionStream('gzip');
return stream.pipeThrough(cs);
}