1. はじめに
この節は参考情報です。
本仕様で定義されているAPIは、データストリームの圧縮および展開に使用されます。"deflate"、"deflate-raw"、"gzip"の各圧縮アルゴリズムをサポートしており、Web開発者に広く利用されています。
2. インフラストラクチャー
本仕様はInfraに依存しています。[INFRA]
チャンクとはデータの断片です。CompressionStreamおよびDecompressionStreamの場合、出力チャンクの型はUint8Arrayです。入力としては、任意のBufferSource
型を受け付けます。
ストリームは、順序付けられたチャンクの列を表します。ReadableStream
およびWritableStream
という用語はStreamsで定義されています。[STREAMS]
圧縮コンテキストとは、圧縮または展開アルゴリズムによって管理される内部状態のことです。圧縮コンテキストの内容は、使用するフォーマット・アルゴリズム・実装によって異なります。本仕様の観点からは、不透明なオブジェクトです。圧縮コンテキストは、最初は入力の最初のバイトを待ち受ける開始状態です。
3. 対応フォーマット
deflate-
"ZLIB圧縮データフォーマット"[RFC1950]
注: このフォーマットは、HTTP Content-Encodingとの一貫性のために「deflate」と呼ばれます。[RFC7230] セクション4.2.2を参照してください。
-
実装は[RFC1950] セクション2.3で述べられている「適合」要件を満たさなければなりません。
-
[RFC1950]で無効とされるフィールド値はCompressionStreamにより生成してはならず、DecompressionStreamではエラーとなります。
-
CMFフィールドのCM(圧縮方式)部分の唯一の有効な値は8です。 -
FDICTフラグはこれらのAPIでサポートされず、設定されている場合はストリームがエラーになります。 -
FLEVELフラグはDecompressionStreamで無視されます。 -
ADLER32チェックサムが正しくない場合、DecompressionStreamではエラーとなります。 -
ADLER32チェックサムの後に追加の入力データがある場合はエラーとなります。
-
deflate-raw-
"DEFLATEアルゴリズム"[RFC1951]
gzip-
"GZIPファイルフォーマット"[RFC1952]
-
実装は[RFC1952] セクション2.3.1.2で述べられている「適合」要件を満たさなければなりません。
-
[RFC1952]で無効とされるフィールド値はCompressionStreamにより生成してはならず、DecompressionStreamではエラーとなります。
-
CM(圧縮方式)フィールドの唯一の有効な値は8です。 -
FTEXTフラグはDecompressionStreamで無視されなければなりません。 -
FHCRCフィールドが存在する場合、それが正しくないとエラーになります。 -
任意の
FEXTRA、FNAME、FCOMMENTフィールドの内容は、DecompressionStreamでは正しく終端されているかどうかの検証以外は無視されなければなりません。 -
MTIME、XFL、OSフィールドの内容はDecompressionStreamで無視されなければなりません。 -
CRC32またはISIZEが展開後のデータと一致しない場合はエラーとなります。 -
gzipストリームは1つの「メンバー」のみを含む必要があります。 -
「メンバー」の終了後に追加の入力データがある場合はエラーとなります。
-
4. インターフェース CompressionStream
enum {CompressionFormat ,"deflate" ,"deflate-raw" , }; [Exposed=*]"gzip" interface {CompressionStream constructor (CompressionFormat ); };format CompressionStream includes GenericTransformStream ;
CompressionStream
には、関連付けられたformat(フォーマット)および圧縮コンテキストとしてのcontext(コンテキスト)がある。
new CompressionStream(format)
の手順は以下の通り:
-
formatが
CompressionStreamでサポートされていない場合、TypeErrorをスローする。 -
transformAlgorithmを、chunk引数を受け取り、チャンクを圧縮してエンキューするアルゴリズムをthisとchunkで実行するアルゴリズムとする。
-
flushAlgorithmを、引数を取らず圧縮フラッシュしてエンキューするアルゴリズムをthisで実行するアルゴリズムとする。
-
thisのtransformを新しい
TransformStreamに設定する。 -
thisのtransformをセットアップし、transformAlgorithmにtransformAlgorithmを、flushAlgorithmにflushAlgorithmを設定する。
CompressionStream
オブジェクトcsとchunkを受け、以下の手順を実行する:
-
chunkが
BufferSource型でない場合、TypeErrorをスローする。 -
bufferが空なら、return する。
-
arraysに、bufferを1つ以上の非空部分に分割し、それぞれを
Uint8Arrayに変換した結果を格納する。 -
配列ごとに、
Uint8Arrayarrayについて、csのtransformにarrayをエンキューする。
ReadableStream
オブジェクトの終端時に、CompressionStream
オブジェクトcsに対して、以下の手順を実行する:
-
bufferが空なら、return する。
-
arraysに、bufferを1つ以上の非空部分に分割し、それぞれを
Uint8Arrayに変換した結果を格納する。 -
配列ごとに、
Uint8Arrayarrayについて、csのtransformにarrayをエンキューする。
5. インターフェース DecompressionStream
[Exposed=*]interface {DecompressionStream constructor (CompressionFormat ); };format DecompressionStream includes GenericTransformStream ;
DecompressionStream
には、関連付けられたformat(フォーマット)および圧縮コンテキストとしてのcontext(コンテキスト)がある。
new DecompressionStream(format)
の手順は以下の通り:
-
formatが
DecompressionStreamでサポートされていない場合、TypeErrorをスローする。 -
transformAlgorithmを、chunk引数を受け取り、チャンクを展開してエンキューするアルゴリズムをthisとchunkで実行するアルゴリズムとする。
-
flushAlgorithmを、引数を取らず展開フラッシュしてエンキューするアルゴリズムをthisで実行するアルゴリズムとする。
-
thisのtransformを新しい
TransformStreamに設定する。 -
thisのtransformをセットアップし、transformAlgorithmにtransformAlgorithmを、flushAlgorithmにflushAlgorithmを設定する。
DecompressionStream
オブジェクトdsとchunkを受け、以下の手順を実行する:
-
chunk が
BufferSource型でない場合、TypeErrorをスローする。 -
buffer を、ds の format および context で chunk を解凍した結果とする。この処理でエラーが発生した場合、
TypeErrorをスローする。 -
buffer が空の場合は、return する。
-
arrays を buffer を1つ以上の非空の部分に分割し、それらを
Uint8Arrayに変換した結果とする。 -
各
Uint8Arrayarray を arrays から取り出し、enqueue で array を ds の transform に追加する。 -
圧縮入力の終端に到達し、かつ ds の context が chunk を完全に消費していない場合、
TypeErrorをスローする。
ReadableStream
オブジェクトの終端時に、DecompressionStream
オブジェクトdsに対して、以下の手順を実行する:
-
buffer を、空の入力を ds の format および context で、finish フラグ付きで解凍した結果とする。
-
buffer が空でない場合:
-
arrays を buffer を1つ以上の非空の部分に分割し、それらを
Uint8Arrayに変換した結果とする。 -
各
Uint8Arrayarray を arrays から取り出し、enqueue で array を ds の transform に追加する。
-
-
圧縮入力の終端に到達していない場合は、
TypeErrorをスローする。
6. プライバシーおよびセキュリティの考慮事項
このAPIはWebプラットフォームに新たな権限を追加しません。
ただし、攻撃者がデータの長さを取得できる場合、Web開発者は注意する必要があります。その場合、データの内容を推測される可能性があります。
7. 例
7.1. ストリームをGzip圧縮する
7.2. ArrayBufferをDeflate圧縮してUint8Arrayに変換
async function compressArrayBuffer( input) { const cs= new CompressionStream( 'deflate' ); const writer= cs. writable. getWriter(); writer. write( input); writer. close(); const output= []; let totalSize= 0 ; for ( const chunkof cs. readable) { output. push( value); totalSize+= value. byteLength; } const concatenated= new Uint8Array( totalSize); let offset= 0 ; for ( const arrayof output) { concatenated. set( array, offset); offset+= array. byteLength; } return concatenated; }
7.3. BlobをGzip展開してBlobに変換
function decompressBlob( blob) { const ds= new DecompressionStream( 'gzip' ); const decompressionStream= blob. stream(). pipeThrough( ds); return new Response( decompressionStream). blob(); }
謝辞
Canon Mukai、Domenic Denicola、そして平野豊に感謝します。この標準はAdam Rice(Google、ricea@chromium.org)によって執筆されました。
知的財産権
Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). この作業はクリエイティブ・コモンズ 表示 4.0 国際 ライセンスの下で提供されます。その一部がソースコードに組み込まれている場合、ソースコード部分は代わりにBSD 3-Clause Licenseの下でライセンスされます。
これは現行標準です。 特許審査バージョンに関心のある方は、 現行標準審査ドラフトを参照してください。