mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-01 07:33:12 +08:00
Decode an untyped stream unshift's string chunk with its encoding
`s.unshift("e9", "hex")` on a native stream held as an untyped value
dropped the encoding argument and put the string's UTF-8 bytes at the
front. A byte-mode stream now takes a string chunk with an encoding as the
bytes Buffer.from(chunk, encoding) holds, as Node's
readableAddChunkUnshift converts it, and an unknown encoding throws
ERR_UNKNOWN_ENCODING. Object-mode streams keep the string as the entry.
This commit is contained in:
@@ -8101,10 +8101,25 @@ static ScrDyn *scr_stream_dyn_push(ScrStream *stream, ScrDyn *const *args, size_
|
||||
return scr_exc_pending() ? NULL : scr_dyn_new_bool(more);
|
||||
}
|
||||
|
||||
/* unshift(chunk): whether the stream takes more data afterwards, Node's
|
||||
* canPushMore. */
|
||||
static ScrDyn *scr_stream_dyn_unshift(ScrStream *stream, const ScrDyn *chunk) {
|
||||
scr_stream_unshift_dyn(stream, chunk);
|
||||
/* unshift(chunk[, encoding]): a byte-mode stream takes a string chunk with
|
||||
* an encoding as the bytes Buffer.from(chunk, encoding) holds, as Node's
|
||||
* readableAddChunkUnshift converts it; an unknown encoding throws
|
||||
* ERR_UNKNOWN_ENCODING. Answers whether the stream takes more data
|
||||
* afterwards, Node's canPushMore. */
|
||||
static ScrDyn *scr_stream_dyn_unshift(ScrStream *stream, ScrDyn *const *args, size_t argc) {
|
||||
ScrDyn *chunk = argc ? args[0] : scr_dyn_undefined();
|
||||
ScrDyn *encoding = argc > 1 ? args[1] : scr_dyn_undefined();
|
||||
if (chunk->kind == SCR_DYN_STR && encoding->kind == SCR_DYN_STR &&
|
||||
!(stream->st->has_r && stream->st->r.object_entries)) {
|
||||
ScrStr *canonical = scr_bytes_normalize_encoding(encoding->v.str);
|
||||
if (!canonical) return NULL;
|
||||
ScrBytes *b = scr_stream_buffer(scr_bytes_from_str(chunk->v.str, canonical));
|
||||
scr_str_release(canonical);
|
||||
scr_stream_unshift(stream, b);
|
||||
scr_bytes_release(b);
|
||||
} else {
|
||||
scr_stream_unshift_dyn(stream, chunk);
|
||||
}
|
||||
if (scr_exc_pending()) return NULL;
|
||||
ScrStreamState *st = stream->st;
|
||||
bool more = chunk->kind != SCR_DYN_NULL && st->has_r && !st->destroyed && !st->errored &&
|
||||
@@ -8169,7 +8184,7 @@ static ScrDyn *scr_stream_dyn_call(ScrStream *stream, ScrDyn *self, const char *
|
||||
}
|
||||
} else if (!strcmp(method, "eventNames")) result = scr_stream_dyn_event_names(stream);
|
||||
else if (!strcmp(method, "push")) result = scr_stream_dyn_push(stream, args, argc);
|
||||
else if (!strcmp(method, "unshift")) result = scr_stream_dyn_unshift(stream, first);
|
||||
else if (!strcmp(method, "unshift")) result = scr_stream_dyn_unshift(stream, args, argc);
|
||||
else if (!strcmp(method, "setDefaultEncoding")) {
|
||||
ScrStream *returned = scr_stream_set_default_encoding(stream, first);
|
||||
if (returned) scr_stream_release(returned);
|
||||
|
||||
@@ -54,3 +54,27 @@ const w = new Writable({
|
||||
});
|
||||
w.on("finish", () => console.log("finish"));
|
||||
drain(w);
|
||||
|
||||
// unshift(string, encoding) puts the decoded bytes at the front; an
|
||||
// unknown encoding throws.
|
||||
const bytes = new Readable({ read() {} });
|
||||
const parts = [];
|
||||
bytes.on("data", (c) => parts.push(c.toString("hex")));
|
||||
bytes.on("end", () => console.log("unshift bytes", parts.join("|")));
|
||||
(function (s) {
|
||||
console.log(s.unshift("e9", "hex"), s.unshift("aGk=", "base64"), s.unshift("é", "latin1"), s.unshift("x", "utf8"));
|
||||
try {
|
||||
s.unshift("x", "bogus");
|
||||
} catch (e) {
|
||||
console.log(e.code, e.message);
|
||||
}
|
||||
s.push(null);
|
||||
})(bytes);
|
||||
const text = new Readable({ read() {} });
|
||||
text.setEncoding("utf8");
|
||||
text.on("data", (c) => console.log("unshift text", JSON.stringify(c)));
|
||||
(function (s) {
|
||||
s.unshift("c3a9", "hex");
|
||||
s.unshift("41", "hex");
|
||||
s.push(null);
|
||||
})(text);
|
||||
|
||||
Reference in New Issue
Block a user