( maxPayload: number, binaryType: BinaryType, )
| 111 | } |
| 112 | |
| 113 | export function createPacketDecoderStream( |
| 114 | maxPayload: number, |
| 115 | binaryType: BinaryType, |
| 116 | ): any { |
| 117 | if (!TEXT_DECODER) { |
| 118 | TEXT_DECODER = new TextDecoder(); |
| 119 | } |
| 120 | const chunks: Uint8Array[] = []; |
| 121 | let state = State.READ_HEADER; |
| 122 | let expectedLength = -1; |
| 123 | let isBinary = false; |
| 124 | |
| 125 | return new TransformStream({ |
| 126 | transform(chunk: Uint8Array, controller) { |
| 127 | chunks.push(chunk); |
| 128 | while (true) { |
| 129 | if (state === State.READ_HEADER) { |
| 130 | if (totalLength(chunks) < 1) { |
| 131 | break; |
| 132 | } |
| 133 | const header = concatChunks(chunks, 1); |
| 134 | isBinary = (header[0] & 0x80) === 0x80; |
| 135 | expectedLength = header[0] & 0x7f; |
| 136 | if (expectedLength < 126) { |
| 137 | state = State.READ_PAYLOAD; |
| 138 | } else if (expectedLength === 126) { |
| 139 | state = State.READ_EXTENDED_LENGTH_16; |
| 140 | } else { |
| 141 | state = State.READ_EXTENDED_LENGTH_64; |
| 142 | } |
| 143 | } else if (state === State.READ_EXTENDED_LENGTH_16) { |
| 144 | if (totalLength(chunks) < 2) { |
| 145 | break; |
| 146 | } |
| 147 | const headerArray = concatChunks(chunks, 2); |
| 148 | expectedLength = new DataView( |
| 149 | headerArray.buffer, |
| 150 | headerArray.byteOffset, |
| 151 | headerArray.length, |
| 152 | ).getUint16(0); |
| 153 | state = State.READ_PAYLOAD; |
| 154 | } else if (state === State.READ_EXTENDED_LENGTH_64) { |
| 155 | if (totalLength(chunks) < 8) { |
| 156 | break; |
| 157 | } |
| 158 | const headerArray = concatChunks(chunks, 8); |
| 159 | |
| 160 | const view = new DataView( |
| 161 | headerArray.buffer, |
| 162 | headerArray.byteOffset, |
| 163 | headerArray.length, |
| 164 | ); |
| 165 | |
| 166 | const n = view.getUint32(0); |
| 167 | |
| 168 | if (n > Math.pow(2, 53 - 32) - 1) { |
| 169 | // the maximum safe integer in JavaScript is 2^53 - 1 |
| 170 | controller.enqueue(ERROR_PACKET); |
no outgoing calls
no test coverage detected