browser.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. const ascii = require('./lib/ascii')
  2. const base64 = require('./lib/base64')
  3. const hex = require('./lib/hex')
  4. const utf8 = require('./lib/utf8')
  5. const utf16le = require('./lib/utf16le')
  6. const LE = new Uint8Array(Uint16Array.of(0xff).buffer)[0] === 0xff
  7. function codecFor (encoding) {
  8. switch (encoding) {
  9. case 'ascii':
  10. return ascii
  11. case 'base64':
  12. return base64
  13. case 'hex':
  14. return hex
  15. case 'utf8':
  16. case 'utf-8':
  17. case undefined:
  18. return utf8
  19. case 'ucs2':
  20. case 'ucs-2':
  21. case 'utf16le':
  22. case 'utf-16le':
  23. return utf16le
  24. default:
  25. throw new Error(`Unknown encoding: ${encoding}`)
  26. }
  27. }
  28. function isBuffer (value) {
  29. return value instanceof Uint8Array
  30. }
  31. function isEncoding (encoding) {
  32. try {
  33. codecFor(encoding)
  34. return true
  35. } catch {
  36. return false
  37. }
  38. }
  39. function alloc (size, fill, encoding) {
  40. const buffer = new Uint8Array(size)
  41. if (fill !== undefined) exports.fill(buffer, fill, 0, buffer.byteLength, encoding)
  42. return buffer
  43. }
  44. function allocUnsafe (size) {
  45. return new Uint8Array(size)
  46. }
  47. function allocUnsafeSlow (size) {
  48. return new Uint8Array(size)
  49. }
  50. function byteLength (string, encoding) {
  51. return codecFor(encoding).byteLength(string)
  52. }
  53. function compare (a, b) {
  54. if (a === b) return 0
  55. const len = Math.min(a.byteLength, b.byteLength)
  56. a = new DataView(a.buffer, a.byteOffset, a.byteLength)
  57. b = new DataView(b.buffer, b.byteOffset, b.byteLength)
  58. let i = 0
  59. for (let n = len - (len % 4); i < n; i += 4) {
  60. const x = a.getUint32(i, LE)
  61. const y = b.getUint32(i, LE)
  62. if (x !== y) break
  63. }
  64. for (; i < len; i++) {
  65. const x = a.getUint8(i)
  66. const y = b.getUint8(i)
  67. if (x < y) return -1
  68. if (x > y) return 1
  69. }
  70. return a.byteLength > b.byteLength ? 1 : a.byteLength < b.byteLength ? -1 : 0
  71. }
  72. function concat (buffers, totalLength) {
  73. if (totalLength === undefined) {
  74. totalLength = buffers.reduce((len, buffer) => len + buffer.byteLength, 0)
  75. }
  76. const result = new Uint8Array(totalLength)
  77. let offset = 0
  78. for (const buffer of buffers) {
  79. if (offset + buffer.byteLength > result.byteLength) {
  80. const sub = buffer.subarray(0, result.byteLength - offset)
  81. result.set(sub, offset)
  82. return result
  83. }
  84. result.set(buffer, offset)
  85. offset += buffer.byteLength
  86. }
  87. return result
  88. }
  89. function copy (source, target, targetStart = 0, start = 0, end = source.byteLength) {
  90. if (end > 0 && end < start) return 0
  91. if (end === start) return 0
  92. if (source.byteLength === 0 || target.byteLength === 0) return 0
  93. if (targetStart < 0) throw new RangeError('targetStart is out of range')
  94. if (start < 0 || start >= source.byteLength) throw new RangeError('sourceStart is out of range')
  95. if (end < 0) throw new RangeError('sourceEnd is out of range')
  96. if (targetStart >= target.byteLength) targetStart = target.byteLength
  97. if (end > source.byteLength) end = source.byteLength
  98. if (target.byteLength - targetStart < end - start) {
  99. end = target.length - targetStart + start
  100. }
  101. const len = end - start
  102. if (source === target) {
  103. target.copyWithin(targetStart, start, end)
  104. } else {
  105. target.set(source.subarray(start, end), targetStart)
  106. }
  107. return len
  108. }
  109. function equals (a, b) {
  110. if (a === b) return true
  111. if (a.byteLength !== b.byteLength) return false
  112. const len = a.byteLength
  113. a = new DataView(a.buffer, a.byteOffset, a.byteLength)
  114. b = new DataView(b.buffer, b.byteOffset, b.byteLength)
  115. let i = 0
  116. for (let n = len - (len % 4); i < n; i += 4) {
  117. if (a.getUint32(i, LE) !== b.getUint32(i, LE)) return false
  118. }
  119. for (; i < len; i++) {
  120. if (a.getUint8(i) !== b.getUint8(i)) return false
  121. }
  122. return true
  123. }
  124. function fill (buffer, value, offset, end, encoding) {
  125. if (typeof value === 'string') {
  126. // fill(buffer, string, encoding)
  127. if (typeof offset === 'string') {
  128. encoding = offset
  129. offset = 0
  130. end = buffer.byteLength
  131. // fill(buffer, string, offset, encoding)
  132. } else if (typeof end === 'string') {
  133. encoding = end
  134. end = buffer.byteLength
  135. }
  136. } else if (typeof value === 'number') {
  137. value = value & 0xff
  138. } else if (typeof value === 'boolean') {
  139. value = +value
  140. }
  141. if (offset < 0 || buffer.byteLength < offset || buffer.byteLength < end) {
  142. throw new RangeError('Out of range index')
  143. }
  144. if (offset === undefined) offset = 0
  145. if (end === undefined) end = buffer.byteLength
  146. if (end <= offset) return buffer
  147. if (!value) value = 0
  148. if (typeof value === 'number') {
  149. for (let i = offset; i < end; ++i) {
  150. buffer[i] = value
  151. }
  152. } else {
  153. value = isBuffer(value) ? value : from(value, encoding)
  154. const len = value.byteLength
  155. for (let i = 0; i < end - offset; ++i) {
  156. buffer[i + offset] = value[i % len]
  157. }
  158. }
  159. return buffer
  160. }
  161. function from (value, encodingOrOffset, length) {
  162. // from(string, encoding)
  163. if (typeof value === 'string') return fromString(value, encodingOrOffset)
  164. // from(array)
  165. if (Array.isArray(value)) return fromArray(value)
  166. // from(buffer)
  167. if (ArrayBuffer.isView(value)) return fromBuffer(value)
  168. // from(arrayBuffer[, byteOffset[, length]])
  169. return fromArrayBuffer(value, encodingOrOffset, length)
  170. }
  171. function fromString (string, encoding) {
  172. const codec = codecFor(encoding)
  173. const buffer = new Uint8Array(codec.byteLength(string))
  174. codec.write(buffer, string, 0, buffer.byteLength)
  175. return buffer
  176. }
  177. function fromArray (array) {
  178. const buffer = new Uint8Array(array.length)
  179. buffer.set(array)
  180. return buffer
  181. }
  182. function fromBuffer (buffer) {
  183. const copy = new Uint8Array(buffer.byteLength)
  184. copy.set(buffer)
  185. return copy
  186. }
  187. function fromArrayBuffer (arrayBuffer, byteOffset, length) {
  188. return new Uint8Array(arrayBuffer, byteOffset, length)
  189. }
  190. function includes (buffer, value, byteOffset, encoding) {
  191. return indexOf(buffer, value, byteOffset, encoding) !== -1
  192. }
  193. function bidirectionalIndexOf (buffer, value, byteOffset, encoding, first) {
  194. if (buffer.byteLength === 0) return -1
  195. if (typeof byteOffset === 'string') {
  196. encoding = byteOffset
  197. byteOffset = 0
  198. } else if (byteOffset === undefined) {
  199. byteOffset = first ? 0 : (buffer.length - 1)
  200. } else if (byteOffset < 0) {
  201. byteOffset += buffer.byteLength
  202. }
  203. if (byteOffset >= buffer.byteLength) {
  204. if (first) return -1
  205. else byteOffset = buffer.byteLength - 1
  206. } else if (byteOffset < 0) {
  207. if (first) byteOffset = 0
  208. else return -1
  209. }
  210. if (typeof value === 'string') {
  211. value = from(value, encoding)
  212. } else if (typeof value === 'number') {
  213. value = value & 0xff
  214. if (first) {
  215. return buffer.indexOf(value, byteOffset)
  216. } else {
  217. return buffer.lastIndexOf(value, byteOffset)
  218. }
  219. }
  220. if (value.byteLength === 0) return -1
  221. if (first) {
  222. let foundIndex = -1
  223. for (let i = byteOffset; i < buffer.byteLength; i++) {
  224. if (buffer[i] === value[foundIndex === -1 ? 0 : i - foundIndex]) {
  225. if (foundIndex === -1) foundIndex = i
  226. if (i - foundIndex + 1 === value.byteLength) return foundIndex
  227. } else {
  228. if (foundIndex !== -1) i -= i - foundIndex
  229. foundIndex = -1
  230. }
  231. }
  232. } else {
  233. if (byteOffset + value.byteLength > buffer.byteLength) {
  234. byteOffset = buffer.byteLength - value.byteLength
  235. }
  236. for (let i = byteOffset; i >= 0; i--) {
  237. let found = true
  238. for (let j = 0; j < value.byteLength; j++) {
  239. if (buffer[i + j] !== value[j]) {
  240. found = false
  241. break
  242. }
  243. }
  244. if (found) return i
  245. }
  246. }
  247. return -1
  248. }
  249. function indexOf (buffer, value, byteOffset, encoding) {
  250. return bidirectionalIndexOf(buffer, value, byteOffset, encoding, true /* first */)
  251. }
  252. function lastIndexOf (buffer, value, byteOffset, encoding) {
  253. return bidirectionalIndexOf(buffer, value, byteOffset, encoding, false /* last */)
  254. }
  255. function swap (buffer, n, m) {
  256. const i = buffer[n]
  257. buffer[n] = buffer[m]
  258. buffer[m] = i
  259. }
  260. function swap16 (buffer) {
  261. const len = buffer.byteLength
  262. if (len % 2 !== 0) throw new RangeError('Buffer size must be a multiple of 16-bits')
  263. for (let i = 0; i < len; i += 2) swap(buffer, i, i + 1)
  264. return buffer
  265. }
  266. function swap32 (buffer) {
  267. const len = buffer.byteLength
  268. if (len % 4 !== 0) throw new RangeError('Buffer size must be a multiple of 32-bits')
  269. for (let i = 0; i < len; i += 4) {
  270. swap(buffer, i, i + 3)
  271. swap(buffer, i + 1, i + 2)
  272. }
  273. return buffer
  274. }
  275. function swap64 (buffer) {
  276. const len = buffer.byteLength
  277. if (len % 8 !== 0) throw new RangeError('Buffer size must be a multiple of 64-bits')
  278. for (let i = 0; i < len; i += 8) {
  279. swap(buffer, i, i + 7)
  280. swap(buffer, i + 1, i + 6)
  281. swap(buffer, i + 2, i + 5)
  282. swap(buffer, i + 3, i + 4)
  283. }
  284. return buffer
  285. }
  286. function toBuffer (buffer) {
  287. return buffer
  288. }
  289. function toString (buffer, encoding, start = 0, end = buffer.byteLength) {
  290. const len = buffer.byteLength
  291. if (start >= len) return ''
  292. if (end <= start) return ''
  293. if (start < 0) start = 0
  294. if (end > len) end = len
  295. if (start !== 0 || end < len) buffer = buffer.subarray(start, end)
  296. return codecFor(encoding).toString(buffer)
  297. }
  298. function write (buffer, string, offset, length, encoding) {
  299. // write(buffer, string)
  300. if (offset === undefined) {
  301. encoding = 'utf8'
  302. // write(buffer, string, encoding)
  303. } else if (length === undefined && typeof offset === 'string') {
  304. encoding = offset
  305. offset = undefined
  306. // write(buffer, string, offset, encoding)
  307. } else if (encoding === undefined && typeof length === 'string') {
  308. encoding = length
  309. length = undefined
  310. }
  311. return codecFor(encoding).write(buffer, string, offset, length)
  312. }
  313. function writeDoubleLE (buffer, value, offset) {
  314. if (offset === undefined) offset = 0
  315. const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
  316. view.setFloat64(offset, value, true)
  317. return offset + 8
  318. }
  319. function writeFloatLE (buffer, value, offset) {
  320. if (offset === undefined) offset = 0
  321. const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
  322. view.setFloat32(offset, value, true)
  323. return offset + 4
  324. }
  325. function writeUInt32LE (buffer, value, offset) {
  326. if (offset === undefined) offset = 0
  327. const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
  328. view.setUint32(offset, value, true)
  329. return offset + 4
  330. }
  331. function writeInt32LE (buffer, value, offset) {
  332. if (offset === undefined) offset = 0
  333. const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
  334. view.setInt32(offset, value, true)
  335. return offset + 4
  336. }
  337. function readDoubleLE (buffer, offset) {
  338. if (offset === undefined) offset = 0
  339. const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
  340. return view.getFloat64(offset, true)
  341. }
  342. function readFloatLE (buffer, offset) {
  343. if (offset === undefined) offset = 0
  344. const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
  345. return view.getFloat32(offset, true)
  346. }
  347. function readUInt32LE (buffer, offset) {
  348. if (offset === undefined) offset = 0
  349. const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
  350. return view.getUint32(offset, true)
  351. }
  352. function readInt32LE (buffer, offset) {
  353. if (offset === undefined) offset = 0
  354. const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
  355. return view.getInt32(offset, true)
  356. }
  357. module.exports = exports = {
  358. isBuffer,
  359. isEncoding,
  360. alloc,
  361. allocUnsafe,
  362. allocUnsafeSlow,
  363. byteLength,
  364. compare,
  365. concat,
  366. copy,
  367. equals,
  368. fill,
  369. from,
  370. includes,
  371. indexOf,
  372. lastIndexOf,
  373. swap16,
  374. swap32,
  375. swap64,
  376. toBuffer,
  377. toString,
  378. write,
  379. writeDoubleLE,
  380. writeFloatLE,
  381. writeUInt32LE,
  382. writeInt32LE,
  383. readDoubleLE,
  384. readFloatLE,
  385. readUInt32LE,
  386. readInt32LE
  387. }