1'use strict'; 2 3const { 4 ArrayBufferPrototypeSlice, 5 ArrayPrototypePush, 6 ArrayPrototypeShift, 7 AsyncIteratorPrototype, 8 FunctionPrototypeCall, 9 MathMax, 10 NumberIsNaN, 11 ObjectCreate, 12 PromisePrototypeThen, 13 PromiseResolve, 14 PromiseReject, 15 ReflectGet, 16 Symbol, 17 Uint8Array, 18} = primordials; 19 20const { 21 codes: { 22 ERR_INVALID_ARG_VALUE, 23 ERR_OPERATION_FAILED, 24 }, 25} = require('internal/errors'); 26 27const { 28 copyArrayBuffer, 29 detachArrayBuffer, 30} = internalBinding('buffer'); 31 32const { 33 isPromise, 34} = require('internal/util/types'); 35 36const { 37 inspect, 38} = require('util'); 39 40const { 41 constants: { 42 kPending, 43 }, 44 getPromiseDetails, 45} = internalBinding('util'); 46 47const assert = require('internal/assert'); 48const { isArrayBufferDetached } = require('internal/util'); 49 50const { 51 validateFunction, 52} = require('internal/validators'); 53 54const kState = Symbol('kState'); 55const kType = Symbol('kType'); 56 57const AsyncIterator = ObjectCreate(AsyncIteratorPrototype, { 58 next: { 59 __proto__: null, 60 configurable: true, 61 enumerable: true, 62 writable: true, 63 }, 64 return: { 65 __proto__: null, 66 configurable: true, 67 enumerable: true, 68 writable: true, 69 }, 70}); 71 72function extractHighWaterMark(value, defaultHWM) { 73 if (value === undefined) return defaultHWM; 74 value = +value; 75 if (typeof value !== 'number' || 76 NumberIsNaN(value) || 77 value < 0) 78 throw new ERR_INVALID_ARG_VALUE.RangeError('strategy.highWaterMark', value); 79 return value; 80} 81 82function extractSizeAlgorithm(size) { 83 if (size === undefined) return () => 1; 84 validateFunction(size, 'strategy.size'); 85 return size; 86} 87 88function customInspect(depth, options, name, data) { 89 if (depth < 0) 90 return this; 91 92 const opts = { 93 ...options, 94 depth: options.depth == null ? null : options.depth - 1, 95 }; 96 97 return `${name} ${inspect(data, opts)}`; 98} 99 100// These are defensive to work around the possibility that 101// the buffer, byteLength, and byteOffset properties on 102// ArrayBuffer and ArrayBufferView's may have been tampered with. 103 104function ArrayBufferViewGetBuffer(view) { 105 return ReflectGet(view.constructor.prototype, 'buffer', view); 106} 107 108function ArrayBufferViewGetByteLength(view) { 109 return ReflectGet(view.constructor.prototype, 'byteLength', view); 110} 111 112function ArrayBufferViewGetByteOffset(view) { 113 return ReflectGet(view.constructor.prototype, 'byteOffset', view); 114} 115 116function cloneAsUint8Array(view) { 117 const buffer = ArrayBufferViewGetBuffer(view); 118 const byteOffset = ArrayBufferViewGetByteOffset(view); 119 const byteLength = ArrayBufferViewGetByteLength(view); 120 return new Uint8Array( 121 ArrayBufferPrototypeSlice(buffer, byteOffset, byteOffset + byteLength), 122 ); 123} 124 125function isBrandCheck(brand) { 126 return (value) => { 127 return value != null && 128 value[kState] !== undefined && 129 value[kType] === brand; 130 }; 131} 132 133function transferArrayBuffer(buffer) { 134 const res = detachArrayBuffer(buffer); 135 if (res === undefined) { 136 throw new ERR_OPERATION_FAILED.TypeError( 137 'The ArrayBuffer could not be transferred'); 138 } 139 return res; 140} 141 142function isViewedArrayBufferDetached(view) { 143 return ( 144 ArrayBufferViewGetByteLength(view) === 0 && 145 isArrayBufferDetached(ArrayBufferViewGetBuffer(view)) 146 ); 147} 148 149function dequeueValue(controller) { 150 assert(controller[kState].queue !== undefined); 151 assert(controller[kState].queueTotalSize !== undefined); 152 assert(controller[kState].queue.length); 153 const { 154 value, 155 size, 156 } = ArrayPrototypeShift(controller[kState].queue); 157 controller[kState].queueTotalSize = 158 MathMax(0, controller[kState].queueTotalSize - size); 159 return value; 160} 161 162function resetQueue(controller) { 163 assert(controller[kState].queue !== undefined); 164 assert(controller[kState].queueTotalSize !== undefined); 165 controller[kState].queue = []; 166 controller[kState].queueTotalSize = 0; 167} 168 169function peekQueueValue(controller) { 170 assert(controller[kState].queue !== undefined); 171 assert(controller[kState].queueTotalSize !== undefined); 172 assert(controller[kState].queue.length); 173 return controller[kState].queue[0].value; 174} 175 176function enqueueValueWithSize(controller, value, size) { 177 assert(controller[kState].queue !== undefined); 178 assert(controller[kState].queueTotalSize !== undefined); 179 size = +size; 180 if (typeof size !== 'number' || 181 size < 0 || 182 NumberIsNaN(size) || 183 size === Infinity) { 184 throw new ERR_INVALID_ARG_VALUE.RangeError('size', size); 185 } 186 ArrayPrototypePush(controller[kState].queue, { value, size }); 187 controller[kState].queueTotalSize += size; 188} 189 190function ensureIsPromise(fn, thisArg, ...args) { 191 try { 192 const value = FunctionPrototypeCall(fn, thisArg, ...args); 193 return isPromise(value) ? value : PromiseResolve(value); 194 } catch (error) { 195 return PromiseReject(error); 196 } 197} 198 199function isPromisePending(promise) { 200 if (promise === undefined) return false; 201 const details = getPromiseDetails(promise); 202 return details?.[0] === kPending; 203} 204 205function setPromiseHandled(promise) { 206 // Alternatively, we could use the native API 207 // MarkAsHandled, but this avoids the extra boundary cross 208 // and is hopefully faster at the cost of an extra Promise 209 // allocation. 210 PromisePrototypeThen(promise, () => {}, () => {}); 211} 212 213async function nonOpFlush() {} 214 215function nonOpStart() {} 216 217async function nonOpPull() {} 218 219async function nonOpCancel() {} 220 221async function nonOpWrite() {} 222 223let transfer; 224function lazyTransfer() { 225 if (transfer === undefined) 226 transfer = require('internal/webstreams/transfer'); 227 return transfer; 228} 229 230module.exports = { 231 ArrayBufferViewGetBuffer, 232 ArrayBufferViewGetByteLength, 233 ArrayBufferViewGetByteOffset, 234 AsyncIterator, 235 cloneAsUint8Array, 236 copyArrayBuffer, 237 customInspect, 238 dequeueValue, 239 ensureIsPromise, 240 enqueueValueWithSize, 241 extractHighWaterMark, 242 extractSizeAlgorithm, 243 lazyTransfer, 244 isBrandCheck, 245 isPromisePending, 246 isViewedArrayBufferDetached, 247 peekQueueValue, 248 resetQueue, 249 setPromiseHandled, 250 transferArrayBuffer, 251 nonOpCancel, 252 nonOpFlush, 253 nonOpPull, 254 nonOpStart, 255 nonOpWrite, 256 kType, 257 kState, 258}; 259