| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- /* eslint-disable @typescript-eslint/no-unnecessary-condition */
- /* eslint-disable @typescript-eslint/init-declarations */
- /* eslint-disable prefer-spread */
- /* eslint-disable @typescript-eslint/no-invalid-this */
- /* eslint-disable @typescript-eslint/no-use-before-define */
- /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
- // Based on http://stackoverflow.com/a/22747272/680742, the browser with
- // the lowest limit is Chrome, with 0x10000 args.
- // We go 1 magnitude less, for safety
- const MAX_ARGUMENTS_LENGTH = 0x1000
- const base64 = require('base64-js')
- function blitBuffer (src, dst, offset, length) {
- let i
- for (i = 0; i < length; ++i) {
- if (i + offset >= dst.length || i >= src.length) {break}
- dst[i + offset] = src[i]
- }
- return i
- }
- export function utf8Write (string, offset, length) {
- return blitBuffer(utf8ToBytes(string, this.length - offset), this, offset, length)
- }
- export function base64Slice (start, end) {
- if (start === 0 && end === this.length) {
- return base64.fromByteArray(this)
- } else {
- return base64.fromByteArray(this.slice(start, end))
- }
- }
- function decodeCodePointsArray (codePoints) {
- const len = codePoints.length
- if (len <= MAX_ARGUMENTS_LENGTH) {
- return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
- }
- // Decode in chunks to avoid "call stack size exceeded".
- let res = ''
- let i = 0
- while (i < len) {
- res += String.fromCharCode.apply(
- String,
- codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
- )
- }
- return res
- }
- export function latin1Slice (start, end) {
- let ret = ''
- end = Math.min(this.length, end)
- for (let i = start; i < end; ++i) {
- ret += String.fromCharCode(this[i])
- }
- return ret
- }
- export function utf8Slice (this, start, end) {
- end = Math.min(this.length, end)
- const res: number[] = []
- let i = start
- while (i < end) {
- const firstByte = this[i]
- let codePoint: number|null = null
- let bytesPerSequence = firstByte > 0xEF ? 4 : firstByte > 0xDF ? 3 : firstByte > 0xBF ? 2 : 1
- if (i + bytesPerSequence <= end) {
- let secondByte, thirdByte, fourthByte, tempCodePoint
- switch (bytesPerSequence) {
- case 1:
- if (firstByte < 0x80) {
- codePoint = firstByte
- }
- break
- case 2:
- secondByte = this[i + 1]
- if ((secondByte & 0xC0) === 0x80) {
- tempCodePoint = (firstByte & 0x1F) << 0x6 | secondByte & 0x3F
- if (tempCodePoint > 0x7F) {
- codePoint = tempCodePoint
- }
- }
- break
- case 3:
- secondByte = this[i + 1]
- thirdByte = this[i + 2]
- if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
- tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | thirdByte & 0x3F
- if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
- codePoint = tempCodePoint
- }
- }
- break
- case 4:
- secondByte = this[i + 1]
- thirdByte = this[i + 2]
- fourthByte = this[i + 3]
- if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
- tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | fourthByte & 0x3F
- if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
- codePoint = tempCodePoint
- }
- }
- }
- }
- if (codePoint === null) {
- // we did not generate a valid codePoint so insert a
- // replacement char (U+FFFD) and advance only 1 byte
- codePoint = 0xFFFD
- bytesPerSequence = 1
- } else if (codePoint > 0xFFFF) {
- // encode to utf16 (surrogate pair dance)
- codePoint -= 0x10000
- res.push(codePoint >>> 10 & 0x3FF | 0xD800)
- codePoint = 0xDC00 | codePoint & 0x3FF
- }
- res.push(codePoint)
- i += bytesPerSequence
- }
- return decodeCodePointsArray(res)
- }
- function utf8ToBytes (string, units) {
- units = units || Infinity
- let codePoint
- const length = string.length
- let leadSurrogate = null
- const bytes: number[] = []
- for (let i = 0; i < length; ++i) {
- codePoint = string.charCodeAt(i)
- // is surrogate component
- if (codePoint > 0xD7FF && codePoint < 0xE000) {
- // last char was a lead
- if (!leadSurrogate) {
- // no lead yet
- if (codePoint > 0xDBFF) {
- // unexpected trail
- if ((units -= 3) > -1) {bytes.push(0xEF, 0xBF, 0xBD)}
- continue
- } else if (i + 1 === length) {
- // unpaired lead
- if ((units -= 3) > -1) {bytes.push(0xEF, 0xBF, 0xBD)}
- continue
- }
- // valid lead
- leadSurrogate = codePoint
- continue
- }
- // 2 leads in a row
- if (codePoint < 0xDC00) {
- if ((units -= 3) > -1) {bytes.push(0xEF, 0xBF, 0xBD)}
- leadSurrogate = codePoint
- continue
- }
- // valid surrogate pair
- codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
- } else if (leadSurrogate) {
- // valid bmp char, but last char was a lead
- if ((units -= 3) > -1) {bytes.push(0xEF, 0xBF, 0xBD)}
- }
- leadSurrogate = null
- // encode utf8
- if (codePoint < 0x80) {
- if ((units -= 1) < 0) {break}
- bytes.push(codePoint)
- } else if (codePoint < 0x800) {
- if ((units -= 2) < 0) {break}
- bytes.push(
- codePoint >> 0x6 | 0xC0,
- codePoint & 0x3F | 0x80
- )
- } else if (codePoint < 0x10000) {
- if ((units -= 3) < 0) {break}
- bytes.push(
- codePoint >> 0xC | 0xE0,
- codePoint >> 0x6 & 0x3F | 0x80,
- codePoint & 0x3F | 0x80
- )
- } else if (codePoint < 0x110000) {
- if ((units -= 4) < 0) {break}
- bytes.push(
- codePoint >> 0x12 | 0xF0,
- codePoint >> 0xC & 0x3F | 0x80,
- codePoint >> 0x6 & 0x3F | 0x80,
- codePoint & 0x3F | 0x80
- )
- } else {
- throw new Error('Invalid code point')
- }
- }
- return bytes
- }
- // Create lookup table for `toString('hex')`
- // See: https://github.com/feross/buffer/issues/219
- const hexSliceLookupTable = (function () {
- const alphabet = '0123456789abcdef'
- const table = new Array(256)
- for (let i = 0; i < 16; ++i) {
- const i16 = i * 16
- for (let j = 0; j < 16; ++j) {
- table[i16 + j] = alphabet[i] + alphabet[j]
- }
- }
- return table
- })()
- export function hexSlice (start, end) {
- const len = this.length
- if (!start || start < 0) {start = 0}
- if (!end || end < 0 || end > len) {end = len}
- let out = ''
- for (let i = start; i < end; ++i) {
- out += hexSliceLookupTable[this[i]]
- }
- return out
- }
- import { Buffer } from 'buffer'
- Buffer.prototype['latin1Slice'] = latin1Slice
- Buffer.prototype['utf8Slice'] = utf8Slice
- Buffer.prototype['base64Slice'] = base64Slice
- Buffer.prototype['utf8Write'] = utf8Write
- Buffer.prototype['hexSlice'] = hexSlice
- window['Buffer'] = Buffer
|