-
Notifications
You must be signed in to change notification settings - Fork 633
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(io): un-deprecate
readerFromStreamReader()
(#4343)
* feat(io): un-deprecate `readerFromStreamReader()` * adjust removal version
- Loading branch information
Showing
4 changed files
with
140 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. | ||
// This module is browser compatible. | ||
|
||
import { Buffer } from "./buffer.ts"; | ||
import { writeAll } from "./write_all.ts"; | ||
import type { Reader } from "./types.ts"; | ||
|
||
/** | ||
* Create a {@linkcode Reader} from a {@linkcode ReadableStreamDefaultReader}. | ||
* | ||
* @example | ||
* ```ts | ||
* import { copy } from "https://deno.land/std@$STD_VERSION/io/copy.ts"; | ||
* import { readerFromStreamReader } from "https://deno.land/std@$STD_VERSION/io/reader_from_stream_reader.ts"; | ||
* | ||
* const res = await fetch("https://deno.land"); | ||
* using file = await Deno.open("./deno.land.html", { create: true, write: true }); | ||
* | ||
* const reader = readerFromStreamReader(res.body!.getReader()); | ||
* await copy(reader, file); | ||
* ``` | ||
*/ | ||
export function readerFromStreamReader( | ||
streamReader: ReadableStreamDefaultReader<Uint8Array>, | ||
): Reader { | ||
const buffer = new Buffer(); | ||
|
||
return { | ||
async read(p: Uint8Array): Promise<number | null> { | ||
if (buffer.empty()) { | ||
const res = await streamReader.read(); | ||
if (res.done) { | ||
return null; // EOF | ||
} | ||
|
||
await writeAll(buffer, res.value); | ||
} | ||
|
||
return buffer.read(p); | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. | ||
|
||
import { assert, assertEquals } from "../assert/mod.ts"; | ||
import { copy } from "./copy.ts"; | ||
import { readerFromStreamReader } from "./reader_from_stream_reader.ts"; | ||
import { Buffer } from "./buffer.ts"; | ||
|
||
function repeat(c: string, bytes: number): Uint8Array { | ||
assertEquals(c.length, 1); | ||
const ui8 = new Uint8Array(bytes); | ||
ui8.fill(c.charCodeAt(0)); | ||
return ui8; | ||
} | ||
|
||
Deno.test("[streams] readerFromStreamReader()", async function () { | ||
const chunks: string[] = ["hello", "deno", "land"]; | ||
const expected = chunks.slice(); | ||
const readChunks: Uint8Array[] = []; | ||
const readableStream = ReadableStream.from(chunks) | ||
.pipeThrough(new TextEncoderStream()); | ||
|
||
const decoder = new TextDecoder(); | ||
const reader = readerFromStreamReader(readableStream.getReader()); | ||
|
||
let i = 0; | ||
|
||
while (true) { | ||
const b = new Uint8Array(1024); | ||
const n = await reader.read(b); | ||
|
||
if (n === null) break; | ||
|
||
readChunks.push(b.subarray(0, n)); | ||
assert(i < expected.length); | ||
|
||
i++; | ||
} | ||
|
||
assertEquals( | ||
expected, | ||
readChunks.map((chunk) => decoder.decode(chunk)), | ||
); | ||
}); | ||
|
||
Deno.test("[streams] readerFromStreamReader() big chunks", async function () { | ||
const bufSize = 1024; | ||
const chunkSize = 3 * bufSize; | ||
const writer = new Buffer(); | ||
|
||
// A readable stream can enqueue chunks bigger than Copy bufSize | ||
// Reader returned by toReader should enqueue exceeding bytes | ||
const chunks: string[] = [ | ||
"a".repeat(chunkSize), | ||
"b".repeat(chunkSize), | ||
"c".repeat(chunkSize), | ||
]; | ||
const expected = chunks.slice(); | ||
const readableStream = ReadableStream.from(chunks) | ||
.pipeThrough(new TextEncoderStream()); | ||
|
||
const reader = readerFromStreamReader(readableStream.getReader()); | ||
const n = await copy(reader, writer, { bufSize }); | ||
|
||
const expectedWritten = chunkSize * expected.length; | ||
assertEquals(n, chunkSize * expected.length); | ||
assertEquals(writer.length, expectedWritten); | ||
}); | ||
|
||
Deno.test("[streams] readerFromStreamReader() irregular chunks", async function () { | ||
const bufSize = 1024; | ||
const chunkSize = 3 * bufSize; | ||
const writer = new Buffer(); | ||
|
||
// A readable stream can enqueue chunks bigger than Copy bufSize | ||
// Reader returned by toReader should enqueue exceeding bytes | ||
const chunks: Uint8Array[] = [ | ||
repeat("a", chunkSize), | ||
repeat("b", chunkSize + 253), | ||
repeat("c", chunkSize + 8), | ||
]; | ||
const expected = new Uint8Array( | ||
chunks | ||
.slice() | ||
.map((chunk) => [...chunk]) | ||
.flat(), | ||
); | ||
const readableStream = ReadableStream.from(chunks); | ||
|
||
const reader = readerFromStreamReader(readableStream.getReader()); | ||
|
||
const n = await copy(reader, writer, { bufSize }); | ||
assertEquals(n, expected.length); | ||
assertEquals(expected, writer.bytes()); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters