未验证 提交 c2986891 编写于 作者: Y Yusuke Sakurai 提交者: GitHub

remove non-null assertion operator from std (part1) (#3900)

上级 ea6179f7
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { pad } from "../strings/pad.ts";
import { assert } from "../testing/mod.ts";
export type DateFormat = "mm-dd-yyyy" | "dd-mm-yyyy" | "yyyy-mm-dd";
function execForce(reg: RegExp, pat: string): RegExpExecArray {
const v = reg.exec(pat);
assert(v != null);
return v;
}
/**
* Parse date from string using format string
* @param dateStr Date string
......@@ -16,15 +22,15 @@ export function parseDate(dateStr: string, format: DateFormat): Date {
switch (format) {
case "mm-dd-yyyy":
datePattern = /^(\d{2})-(\d{2})-(\d{4})$/;
[, m, d, y] = datePattern.exec(dateStr)!;
[, m, d, y] = execForce(datePattern, dateStr);
break;
case "dd-mm-yyyy":
datePattern = /^(\d{2})-(\d{2})-(\d{4})$/;
[, d, m, y] = datePattern.exec(dateStr)!;
[, d, m, y] = execForce(datePattern, dateStr);
break;
case "yyyy-mm-dd":
datePattern = /^(\d{4})-(\d{2})-(\d{2})$/;
[, y, m, d] = datePattern.exec(dateStr)!;
[, y, m, d] = execForce(datePattern, dateStr);
break;
default:
throw new Error("Invalid date format!");
......@@ -57,27 +63,27 @@ export function parseDateTime(
switch (format) {
case "mm-dd-yyyy hh:mm":
datePattern = /^(\d{2})-(\d{2})-(\d{4}) (\d{2}):(\d{2})$/;
[, m, d, y, ho, mi] = datePattern.exec(datetimeStr)!;
[, m, d, y, ho, mi] = execForce(datePattern, datetimeStr);
break;
case "dd-mm-yyyy hh:mm":
datePattern = /^(\d{2})-(\d{2})-(\d{4}) (\d{2}):(\d{2})$/;
[, d, m, y, ho, mi] = datePattern.exec(datetimeStr)!;
[, d, m, y, ho, mi] = execForce(datePattern, datetimeStr);
break;
case "yyyy-mm-dd hh:mm":
datePattern = /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})$/;
[, y, m, d, ho, mi] = datePattern.exec(datetimeStr)!;
[, y, m, d, ho, mi] = execForce(datePattern, datetimeStr);
break;
case "hh:mm mm-dd-yyyy":
datePattern = /^(\d{2}):(\d{2}) (\d{2})-(\d{2})-(\d{4})$/;
[, ho, mi, m, d, y] = datePattern.exec(datetimeStr)!;
[, ho, mi, m, d, y] = execForce(datePattern, datetimeStr);
break;
case "hh:mm dd-mm-yyyy":
datePattern = /^(\d{2}):(\d{2}) (\d{2})-(\d{2})-(\d{4})$/;
[, ho, mi, d, m, y] = datePattern.exec(datetimeStr)!;
[, ho, mi, d, m, y] = execForce(datePattern, datetimeStr);
break;
case "hh:mm yyyy-mm-dd":
datePattern = /^(\d{2}):(\d{2}) (\d{4})-(\d{2})-(\d{2})$/;
[, ho, mi, y, m, d] = datePattern.exec(datetimeStr)!;
[, ho, mi, y, m, d] = execForce(datePattern, datetimeStr);
break;
default:
throw new Error("Invalid datetime format!");
......
......@@ -14,10 +14,10 @@ for (let i = 0, len = code.length; i < len; ++i) {
const placeHolderPadLookup = [0, 1, , 2, 3, , 4];
function _getPadLen(placeHoldersLen: number): number {
const maybeLen = placeHolderPadLookup[placeHoldersLen];
if (maybeLen === undefined) {
if (typeof maybeLen !== "number") {
throw new Error("Invalid pad length");
}
return maybeLen!;
return maybeLen;
}
function getLens(b32: string): [number, number] {
......
import { xeval } from "../xeval.ts";
import { stringsReader } from "../../io/util.ts";
import { decode, encode } from "../../strings/mod.ts";
import { assertEquals, assertStrContains } from "../../testing/asserts.ts";
import {
assertEquals,
assertStrContains,
assert
} from "../../testing/asserts.ts";
import { test } from "../../testing/mod.ts";
const { execPath, run } = Deno;
......@@ -29,8 +33,9 @@ test(async function xevalCliReplvar(): Promise<void> {
stdout: "piped",
stderr: "null"
});
await p.stdin!.write(encode("hello"));
await p.stdin!.close();
assert(p.stdin != null);
await p.stdin.write(encode("hello"));
await p.stdin.close();
assertEquals(await p.status(), { code: 0, success: true });
assertEquals(decode(await p.output()).trimEnd(), "hello");
});
......
......@@ -9,6 +9,7 @@ import {
normalize
} from "../path/mod.ts";
import { WalkInfo, walk, walkSync } from "./walk.ts";
import { assert } from "../testing/mod.ts";
const { ErrorKind, cwd, stat, statSync } = Deno;
type ErrorKind = Deno.ErrorKind;
type DenoError = Deno.DenoError<ErrorKind>;
......@@ -80,7 +81,9 @@ export async function* expandGlob(
let fixedRoot = winRoot != undefined ? winRoot : "/";
while (segments.length > 0 && !isGlob(segments[0])) {
fixedRoot = joinGlobs([fixedRoot, segments.shift()!], globOptions);
const seg = segments.shift();
assert(seg != null);
fixedRoot = joinGlobs([fixedRoot, seg], globOptions);
}
let fixedRootInfo: WalkInfo;
......@@ -182,7 +185,9 @@ export function* expandGlobSync(
let fixedRoot = winRoot != undefined ? winRoot : "/";
while (segments.length > 0 && !isGlob(segments[0])) {
fixedRoot = joinGlobs([fixedRoot, segments.shift()!], globOptions);
const seg = segments.shift();
assert(seg != null);
fixedRoot = joinGlobs([fixedRoot, seg], globOptions);
}
let fixedRootInfo: WalkInfo;
......
// Documentation and interface for walk were adapted from Go
// https://golang.org/pkg/path/filepath/#Walk
// Copyright 2009 The Go Authors. All rights reserved. BSD license.
import { unimplemented } from "../testing/asserts.ts";
import { unimplemented, assert } from "../testing/asserts.ts";
import { join } from "../path/mod.ts";
const { readDir, readDirSync, stat, statSync } = Deno;
type FileInfo = Deno.FileInfo;
......@@ -90,7 +90,8 @@ export async function* walk(
}
}
const filename = join(root, info.name!);
assert(info.name != null);
const filename = join(root, info.name);
if (info.isFile()) {
if (includeFiles && include(filename, exts, match, skip)) {
......@@ -142,7 +143,8 @@ export function* walkSync(
}
}
const filename = join(root, info.name!);
assert(info.name != null);
const filename = join(root, info.name);
if (info.isFile()) {
if (includeFiles && include(filename, exts, match, skip)) {
......
......@@ -45,8 +45,8 @@ function toString(cookie: Cookie): string {
if (cookie.httpOnly) {
out.push("HttpOnly");
}
if (Number.isInteger(cookie.maxAge!)) {
assert(cookie.maxAge! > 0, "Max-Age must be an integer superior to 0");
if (Number.isInteger(cookie.maxAge)) {
assert(cookie.maxAge > 0, "Max-Age must be an integer superior to 0");
out.push(`Max-Age=${cookie.maxAge}`);
}
if (cookie.domain) {
......@@ -73,12 +73,14 @@ function toString(cookie: Cookie): string {
* @param req Server Request
*/
export function getCookies(req: ServerRequest): Cookies {
if (req.headers.has("Cookie")) {
const cookie = req.headers.get("Cookie");
if (cookie != null) {
const out: Cookies = {};
const c = req.headers.get("Cookie")!.split(";");
const c = cookie.split(";");
for (const kv of c) {
const cookieVal = kv.split("=");
const key = cookieVal.shift()!.trim();
const [cookieKey, ...cookieVal] = kv.split("=");
assert(cookieKey != null);
const key = cookieKey.trim();
out[key] = cookieVal.join("=");
}
return out;
......
......@@ -38,7 +38,7 @@ test({
const res: Response = {};
delCookie(res, "deno");
assertEquals(
res.headers!.get("Set-Cookie"),
res.headers?.get("Set-Cookie"),
"deno=; Expires=Thu, 01 Jan 1970 00:00:00 GMT"
);
}
......
......@@ -66,7 +66,7 @@ function modeToString(isDir: boolean, maybeMode: number | null): string {
if (maybeMode === null) {
return "(unknown mode)";
}
const mode = maybeMode!.toString(8);
const mode = maybeMode.toString(8);
if (mode.length < 3) {
return "(unknown mode)";
}
......@@ -186,8 +186,8 @@ function setCORS(res: Response): void {
if (!res.headers) {
res.headers = new Headers();
}
res.headers!.append("access-control-allow-origin", "*");
res.headers!.append(
res.headers.append("access-control-allow-origin", "*");
res.headers.append(
"access-control-allow-headers",
"Origin, X-Requested-With, Content-Type, Accept, Range"
);
......
......@@ -20,14 +20,15 @@ async function startFileServer(): Promise<void> {
stdout: "piped"
});
// Once fileServer is ready it will write to its stdout.
const r = new TextProtoReader(new BufReader(fileServer.stdout!));
assert(fileServer.stdout != null);
const r = new TextProtoReader(new BufReader(fileServer.stdout));
const s = await r.readLine();
assert(s !== Deno.EOF && s.includes("server listening"));
}
function killFileServer(): void {
fileServer.close();
fileServer.stdout!.close();
fileServer.stdout?.close();
}
test(async function serveFile(): Promise<void> {
......@@ -102,8 +103,10 @@ test(async function servePermissionDenied(): Promise<void> {
stdout: "piped",
stderr: "piped"
});
const reader = new TextProtoReader(new BufReader(deniedServer.stdout!));
const errReader = new TextProtoReader(new BufReader(deniedServer.stderr!));
assert(deniedServer.stdout != null);
const reader = new TextProtoReader(new BufReader(deniedServer.stdout));
assert(deniedServer.stderr != null);
const errReader = new TextProtoReader(new BufReader(deniedServer.stderr));
const s = await reader.readLine();
assert(s !== Deno.EOF && s.includes("server listening"));
......@@ -115,8 +118,8 @@ test(async function servePermissionDenied(): Promise<void> {
);
} finally {
deniedServer.close();
deniedServer.stdout!.close();
deniedServer.stderr!.close();
deniedServer.stdout.close();
deniedServer.stderr.close();
}
});
......@@ -125,9 +128,10 @@ test(async function printHelp(): Promise<void> {
args: [Deno.execPath(), "run", "http/file_server.ts", "--help"],
stdout: "piped"
});
const r = new TextProtoReader(new BufReader(helpProcess.stdout!));
assert(helpProcess.stdout != null);
const r = new TextProtoReader(new BufReader(helpProcess.stdout));
const s = await r.readLine();
assert(s !== Deno.EOF && s.includes("Deno File Server"));
helpProcess.close();
helpProcess.stdout!.close();
helpProcess.stdout.close();
});
......@@ -12,13 +12,14 @@ async function startServer(): Promise<void> {
stdout: "piped"
});
// Once racing server is ready it will write to its stdout.
const r = new TextProtoReader(new BufReader(server.stdout!));
assert(server.stdout != null);
const r = new TextProtoReader(new BufReader(server.stdout));
const s = await r.readLine();
assert(s !== Deno.EOF && s.includes("Racing server listening..."));
}
function killServer(): void {
server.close();
server.stdout!.close();
server.stdout?.close();
}
const input = `GET / HTTP/1.1
......
......@@ -73,9 +73,10 @@ export async function writeResponse(w: Writer, r: Response): Promise<void> {
let out = `HTTP/${protoMajor}.${protoMinor} ${statusCode} ${statusText}\r\n`;
setContentLength(r);
const headers = r.headers!;
assert(r.headers != null);
const headers = r.headers;
for (const [key, value] of headers!) {
for (const [key, value] of headers) {
out += `${key}: ${value}\r\n`;
}
out += "\r\n";
......@@ -88,7 +89,9 @@ export async function writeResponse(w: Writer, r: Response): Promise<void> {
const n = await writer.write(r.body);
assert(n === r.body.byteLength);
} else if (headers.has("content-length")) {
const bodyLength = parseInt(headers.get("content-length")!);
const contentLength = headers.get("content-length");
assert(contentLength != null);
const bodyLength = parseInt(contentLength);
const n = await copy(writer, r.body);
assert(n === bodyLength);
} else {
......@@ -129,8 +132,9 @@ export class ServerRequest {
// undefined means not cached.
// null means invalid or not provided.
if (this._contentLength === undefined) {
if (this.headers.has("content-length")) {
this._contentLength = +this.headers.get("content-length")!;
const cl = this.headers.get("content-length");
if (cl) {
this._contentLength = parseInt(cl);
// Convert NaN to null (as NaN harder to test)
if (Number.isNaN(this._contentLength)) {
this._contentLength = null;
......@@ -190,12 +194,12 @@ export class ServerRequest {
}
yield nread;
} else {
if (this.headers.has("transfer-encoding")) {
const transferEncodings = this.headers
.get("transfer-encoding")!
const transferEncoding = this.headers.get("transfer-encoding");
if (transferEncoding) {
const parts = transferEncoding
.split(",")
.map((e): string => e.trim().toLowerCase());
if (transferEncodings.includes("chunked")) {
if (parts.includes("chunked")) {
// Based on https://tools.ietf.org/html/rfc2616#section-19.4.6
const tp = new TextProtoReader(this.r);
let line = await tp.readLine();
......@@ -413,7 +417,7 @@ export class Server implements AsyncIterable<ServerRequest> {
// Wait for the request to be processed before we accept a new request on
// this connection.
const procError = await req!.done;
const procError = await req.done;
if (procError) {
// Something bad happened during response.
// (likely other side closed during pipelined req)
......@@ -422,12 +426,12 @@ export class Server implements AsyncIterable<ServerRequest> {
}
}
if (req! === Deno.EOF) {
if (req === Deno.EOF) {
// The connection was gracefully closed.
} else if (err) {
} else if (err && req) {
// An error was thrown while parsing request headers.
try {
await writeResponse(req!.w, {
await writeResponse(req.w, {
status: 400,
body: encoder.encode(`${err.message}\r\n\r\n`)
});
......
......@@ -506,8 +506,7 @@ test(async function testReadRequestError(): Promise<void> {
for (const test of testCases) {
const reader = new BufReader(new StringReader(test.in));
let err;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let req: any;
let req: ServerRequest | Deno.EOF;
try {
req = await readRequest(mockConn as Deno.Conn, reader);
} catch (e) {
......@@ -520,10 +519,12 @@ test(async function testReadRequestError(): Promise<void> {
} else if (test.err) {
assert(err instanceof (test.err as typeof UnexpectedEOFError));
} else {
assert(req instanceof ServerRequest);
assert(test.headers != null);
assertEquals(err, undefined);
assertNotEquals(req, Deno.EOF);
for (const h of test.headers!) {
assertEquals((req! as ServerRequest).headers.get(h.key), h.value);
for (const h of test.headers) {
assertEquals(req.headers.get(h.key), h.value);
}
}
}
......
......@@ -32,6 +32,6 @@ export class StringWriter implements Writer {
offs += chunk.byteLength;
}
this.cache = decode(buf);
return this.cache!;
return this.cache;
}
}
......@@ -6,6 +6,7 @@ import {
WriterHandler,
FileHandler
} from "./handlers.ts";
import { assert } from "../testing/mod.ts";
export class LoggerConfig {
level?: string;
......@@ -50,16 +51,20 @@ export const handlers = {
export function getLogger(name?: string): Logger {
if (!name) {
return state.loggers.get("default")!;
const d = state.loggers.get("default");
assert(
d != null,
`"default" logger must be set for getting logger without name`
);
return d;
}
if (!state.loggers.has(name)) {
const result = state.loggers.get(name);
if (!result) {
const logger = new Logger("NOTSET", []);
state.loggers.set(name, logger);
return logger;
}
return state.loggers.get(name)!;
return result;
}
export const debug = (msg: string, ...args: unknown[]): void =>
......@@ -105,8 +110,9 @@ export async function setup(config: LogConfig): Promise<void> {
const handlers: BaseHandler[] = [];
handlerNames.forEach((handlerName): void => {
if (state.handlers.has(handlerName)) {
handlers.push(state.handlers.get(handlerName)!);
const handler = state.handlers.get(handlerName);
if (handler) {
handlers.push(handler);
}
});
......
......@@ -56,8 +56,8 @@ function populateMaps(
extensions.set(type, exts);
for (const ext of exts) {
if (types.has(ext)) {
const current = types.get(ext)!;
const current = types.get(ext);
if (current) {
const from = preference.indexOf(db[current].source);
const to = preference.indexOf(mime.source);
......
......@@ -12,7 +12,7 @@ import { extname } from "../path/mod.ts";
import { tempFile } from "../io/util.ts";
import { BufReader, BufWriter, UnexpectedEOFError } from "../io/bufio.ts";
import { encoder } from "../strings/mod.ts";
import { assertStrictEq } from "../testing/asserts.ts";
import { assertStrictEq, assert } from "../testing/asserts.ts";
import { TextProtoReader } from "../textproto/mod.ts";
import { hasOwnProperty } from "../util/has_own_property.ts";
......@@ -205,7 +205,8 @@ class PartReader implements Reader, Closer {
if (this.contentDispositionParams) return this.contentDispositionParams;
const cd = this.headers.get("content-disposition");
const params: { [key: string]: string } = {};
const comps = cd!.split(";");
assert(cd != null, "content-disposition must be set");
const comps = cd.split(";");
this.contentDisposition = comps[0];
comps
.slice(1)
......@@ -265,10 +266,12 @@ export class MultipartReader {
/** Read all form data from stream.
* If total size of stored data in memory exceed maxMemory,
* overflowed file data will be written to temporal files.
* String field values are never written to files */
* String field values are never written to files.
* null value means parsing or writing to file was failed in some reason.
* */
async readForm(
maxMemory: number
): Promise<{ [key: string]: string | FormFile }> {
): Promise<{ [key: string]: null | string | FormFile }> {
const result = Object.create(null);
let maxValueBytes = maxMemory + (10 << 20);
const buf = new Buffer(new Uint8Array(maxValueBytes));
......@@ -293,8 +296,10 @@ export class MultipartReader {
continue;
}
// file
let formFile: FormFile;
let formFile: FormFile | null = null;
const n = await copy(buf, p);
const contentType = p.headers.get("content-type");
assert(contentType != null, "content-type must be set");
if (n > maxMemory) {
// too big, write to disk and flush buffer
const ext = extname(p.fileName);
......@@ -311,7 +316,7 @@ export class MultipartReader {
file.close();
formFile = {
filename: p.fileName,
type: p.headers.get("content-type")!,
type: contentType,
tempfile: filepath,
size
};
......@@ -321,14 +326,14 @@ export class MultipartReader {
} else {
formFile = {
filename: p.fileName,
type: p.headers.get("content-type")!,
type: contentType,
content: buf.bytes(),
size: buf.length
};
maxMemory -= n;
maxValueBytes -= n;
}
result[p.formName] = formFile!;
result[p.formName] = formFile;
}
return result;
}
......
......@@ -199,7 +199,8 @@ test(async function multipartMultipartReader2(): Promise<void> {
assertEquals(form["bar"], "bar");
const file = form["file"] as FormFile;
assertEquals(file.type, "application/octet-stream");
const f = await open(file.tempfile!);
assert(file.tempfile != null);
const f = await open(file.tempfile);
const w = new StringWriter();
await copy(w, f);
const json = JSON.parse(w.toString());
......@@ -207,7 +208,9 @@ test(async function multipartMultipartReader2(): Promise<void> {
f.close();
} finally {
const file = form["file"] as FormFile;
await remove(file.tempfile!);
if (file.tempfile) {
await remove(file.tempfile);
}
}
});
......
import { SEP, SEP_PATTERN } from "./constants.ts";
import { globrex } from "./globrex.ts";
import { join, normalize } from "./mod.ts";
import { assert } from "../testing/asserts.ts";
const { DenoError, ErrorKind } = Deno;
export interface GlobOptions {
......@@ -46,7 +48,8 @@ export function globToRegExp(
strict: false,
filepath: true
});
return result.path!.regex;
assert(result.path != null);
return result.path.regex;
}
/** Test whether the given string is a glob */
......
......@@ -49,7 +49,7 @@ export function normalizeString(
let code: number;
for (let i = 0, len = path.length; i <= len; ++i) {
if (i < len) code = path.charCodeAt(i);
else if (isPathSeparator(code!)) break;
else if (isPathSeparator(code)) break;
else code = CHAR_FORWARD_SLASH;
if (isPathSeparator(code)) {
......
......@@ -17,6 +17,7 @@ import {
normalizeString,
_format
} from "./utils.ts";
import { assert } from "../testing/asserts.ts";
export const sep = "\\";
export const delimiter = ";";
......@@ -329,7 +330,7 @@ export function join(...paths: string[]): string {
// path.join('//server', 'share') -> '\\\\server\\share\\')
let needsReplace = true;
let slashCount = 0;
firstPart = firstPart!;
assert(firstPart != null);
if (isPathSeparator(firstPart.charCodeAt(0))) {
++slashCount;
const firstLen = firstPart.length;
......
import { assert } from "./asserts.ts";
// This file is ported from pretty-format@24.0.0
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
......@@ -361,7 +363,9 @@ const getKeysOfEnumerableProperties = (object: {}): Array<string | symbol> => {
if (Object.getOwnPropertySymbols) {
Object.getOwnPropertySymbols(object).forEach((symbol): void => {
if (Object.getOwnPropertyDescriptor(object, symbol)!.enumerable) {
const d = Object.getOwnPropertyDescriptor(object, symbol);
assert(d != null);
if (d.enumerable) {
keys.push(symbol);
}
});
......
......@@ -261,11 +261,14 @@ function printResults(
}
function previousPrinted(name: string, results: TestResults): boolean {
const curIndex: number = results.keys.get(name)!;
const curIndex = results.keys.get(name);
assert(curIndex != null);
if (curIndex === 0) {
return true;
}
return results.cases.get(curIndex - 1)!.printed;
const prev = results.cases.get(curIndex - 1);
assert(prev != null);
return prev.printed;
}
async function createTestCase(
......@@ -274,7 +277,10 @@ async function createTestCase(
exitOnFail: boolean,
{ fn, name }: TestDefinition
): Promise<void> {
const result: TestResult = results.cases.get(results.keys.get(name)!)!;
const i = results.keys.get(name);
assert(i != null);
const result = results.cases.get(i);
assert(result != null);
try {
const start = performance.now();
await fn();
......
......@@ -7,7 +7,7 @@ import { BufReader, UnexpectedEOFError } from "../io/bufio.ts";
import { charCode } from "../io/util.ts";
const asciiDecoder = new TextDecoder();
function str(buf: Uint8Array): string {
function str(buf: Uint8Array | null | undefined): string {
if (buf == null) {
return "";
} else {
......@@ -82,7 +82,7 @@ export class TextProtoReader {
throw new UnexpectedEOFError();
} else if (buf[0] == charCode(" ") || buf[0] == charCode("\t")) {
throw new ProtocolError(
`malformed MIME header initial line: ${str(line!)}`
`malformed MIME header initial line: ${str(line)}`
);
}
......@@ -142,7 +142,7 @@ export class TextProtoReader {
const { line: l, more } = r;
// Avoid the copy if the first call produced a full line.
if (!line! && !more) {
if (!line && !more) {
// TODO(ry):
// This skipSpace() is definitely misplaced, but I don't know where it
// comes from nor how to fix it.
......
......@@ -23,7 +23,7 @@ export function deferred<T>(): Deferred<T> {
const promise = new Promise<T>((resolve, reject): void => {
methods = { resolve, reject };
});
return Object.assign(promise, methods)! as Deferred<T>;
return Object.assign(promise, methods) as Deferred<T>;
}
interface TaggedYieldedValue<T> {
......
......@@ -24,7 +24,7 @@ export function deepAssign(
if (typeof target[key] !== `object` || !target[key]) {
target[key] = {};
}
deepAssign(target[key] as Record<string, unknown>, value!);
deepAssign(target[key] as Record<string, unknown>, value);
});
}
return target;
......
......@@ -97,7 +97,7 @@ export interface WebSocket {
export function unmask(payload: Uint8Array, mask?: Uint8Array): void {
if (mask) {
for (let i = 0, len = payload.length; i < len; i++) {
payload[i] ^= mask![i & 3];
payload[i] ^= mask[i & 3];
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册