cnf-qrcode
Version:
generate qrcode,support svg base64 utf8
512 lines (427 loc) • 12.8 kB
JavaScript
/**
* Implementation of a subset of node.js Buffer methods for the browser.
* Based on https://github.com/feross/buffer
*/
/* eslint-disable no-proto */
const isArray = require('isarray');
function typedArraySupport() {
// Can typed array instances be augmented?
try {
const arr = new Uint8Array(1);
arr.__proto__ = { __proto__: Uint8Array.prototype, foo() { return 42; } };
return arr.foo() === 42;
} catch (e) {
return false;
}
}
Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport();
const K_MAX_LENGTH = Buffer.TYPED_ARRAY_SUPPORT
? 0x7fffffff
: 0x3fffffff;
function Buffer(arg, offset, length) {
if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {
return new Buffer(arg, offset, length);
}
if (typeof arg === 'number') {
return allocUnsafe(this, arg);
}
return from(this, arg, offset, length);
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
Buffer.prototype.__proto__ = Uint8Array.prototype;
Buffer.__proto__ = Uint8Array;
// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
if (typeof Symbol !== 'undefined' && Symbol.species
&& Buffer[Symbol.species] === Buffer) {
Object.defineProperty(Buffer, Symbol.species, {
value: null,
configurable: true,
enumerable: false,
writable: false,
});
}
}
function checked(length) {
// Note: cannot use `length < K_MAX_LENGTH` here because that fails when
// length is NaN (which is otherwise coerced to zero.)
if (length >= K_MAX_LENGTH) {
throw new RangeError(`${'Attempt to allocate Buffer larger than maximum '
+ 'size: 0x'}${K_MAX_LENGTH.toString(16)} bytes`);
}
return length | 0;
}
function isnan(val) {
return val !== val; // eslint-disable-line no-self-compare
}
function createBuffer(that, length) {
let buf;
if (Buffer.TYPED_ARRAY_SUPPORT) {
buf = new Uint8Array(length);
buf.__proto__ = Buffer.prototype;
} else {
// Fallback: Return an object instance of the Buffer class
buf = that;
if (buf === null) {
buf = new Buffer(length);
}
buf.length = length;
}
return buf;
}
function allocUnsafe(that, size) {
const buf = createBuffer(that, size < 0 ? 0 : checked(size) | 0);
if (!Buffer.TYPED_ARRAY_SUPPORT) {
for (let i = 0; i < size; ++i) {
buf[i] = 0;
}
}
return buf;
}
function fromString(that, string) {
const length = byteLength(string) | 0;
let buf = createBuffer(that, length);
const actual = buf.write(string);
if (actual !== length) {
// Writing a hex string, for example, that contains invalid characters will
// cause everything after the first invalid character to be ignored. (e.g.
// 'abxxcd' will be treated as 'ab')
buf = buf.slice(0, actual);
}
return buf;
}
function fromArrayLike(that, array) {
const length = array.length < 0 ? 0 : checked(array.length) | 0;
const buf = createBuffer(that, length);
for (let i = 0; i < length; i += 1) {
buf[i] = array[i] & 255;
}
return buf;
}
function fromArrayBuffer(that, array, byteOffset, length) {
if (byteOffset < 0 || array.byteLength < byteOffset) {
throw new RangeError('\'offset\' is out of bounds');
}
if (array.byteLength < byteOffset + (length || 0)) {
throw new RangeError('\'length\' is out of bounds');
}
let buf;
if (byteOffset === undefined && length === undefined) {
buf = new Uint8Array(array);
} else if (length === undefined) {
buf = new Uint8Array(array, byteOffset);
} else {
buf = new Uint8Array(array, byteOffset, length);
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
buf.__proto__ = Buffer.prototype;
} else {
// Fallback: Return an object instance of the Buffer class
buf = fromArrayLike(that, buf);
}
return buf;
}
function fromObject(that, obj) {
if (Buffer.isBuffer(obj)) {
const len = checked(obj.length) | 0;
const buf = createBuffer(that, len);
if (buf.length === 0) {
return buf;
}
obj.copy(buf, 0, 0, len);
return buf;
}
if (obj) {
if ((typeof ArrayBuffer !== 'undefined'
&& obj.buffer instanceof ArrayBuffer) || 'length' in obj) {
if (typeof obj.length !== 'number' || isnan(obj.length)) {
return createBuffer(that, 0);
}
return fromArrayLike(that, obj);
}
if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
return fromArrayLike(that, obj.data);
}
}
throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.');
}
function utf8ToBytes(string, units) {
units = units || Infinity;
let codePoint;
const { length } = string;
let leadSurrogate = null;
const bytes = [];
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;
}
function byteLength(string) {
if (Buffer.isBuffer(string)) {
return string.length;
}
if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function'
&& (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {
return string.byteLength;
}
if (typeof string !== 'string') {
string = `${string}`;
}
const len = string.length;
if (len === 0) return 0;
return utf8ToBytes(string).length;
}
function blitBuffer(src, dst, offset, length) {
for (var i = 0; i < length; ++i) {
if ((i + offset >= dst.length) || (i >= src.length)) break;
dst[i + offset] = src[i];
}
return i;
}
function utf8Write(buf, string, offset, length) {
return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length);
}
function from(that, value, offset, length) {
if (typeof value === 'number') {
throw new TypeError('"value" argument must not be a number');
}
if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
return fromArrayBuffer(that, value, offset, length);
}
if (typeof value === 'string') {
return fromString(that, value, offset);
}
return fromObject(that, value);
}
Buffer.prototype.write = function write(string, offset, length) {
// Buffer#write(string)
if (offset === undefined) {
length = this.length;
offset = 0;
// Buffer#write(string, encoding)
} else if (length === undefined && typeof offset === 'string') {
length = this.length;
offset = 0;
// Buffer#write(string, offset[, length])
} else if (isFinite(offset)) {
offset |= 0;
if (isFinite(length)) {
length |= 0;
} else {
length = undefined;
}
}
const remaining = this.length - offset;
if (length === undefined || length > remaining) length = remaining;
if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
throw new RangeError('Attempt to write outside buffer bounds');
}
return utf8Write(this, string, offset, length);
};
Buffer.prototype.slice = function slice(start, end) {
const len = this.length;
start = ~~start;
end = end === undefined ? len : ~~end;
if (start < 0) {
start += len;
if (start < 0) start = 0;
} else if (start > len) {
start = len;
}
if (end < 0) {
end += len;
if (end < 0) end = 0;
} else if (end > len) {
end = len;
}
if (end < start) end = start;
let newBuf;
if (Buffer.TYPED_ARRAY_SUPPORT) {
newBuf = this.subarray(start, end);
// Return an augmented `Uint8Array` instance
newBuf.__proto__ = Buffer.prototype;
} else {
const sliceLen = end - start;
newBuf = new Buffer(sliceLen, undefined);
for (let i = 0; i < sliceLen; ++i) {
newBuf[i] = this[i + start];
}
}
return newBuf;
};
Buffer.prototype.copy = function copy(target, targetStart, start, end) {
if (!start) start = 0;
if (!end && end !== 0) end = this.length;
if (targetStart >= target.length) targetStart = target.length;
if (!targetStart) targetStart = 0;
if (end > 0 && end < start) end = start;
// Copy 0 bytes; we're done
if (end === start) return 0;
if (target.length === 0 || this.length === 0) return 0;
// Fatal error conditions
if (targetStart < 0) {
throw new RangeError('targetStart out of bounds');
}
if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds');
if (end < 0) throw new RangeError('sourceEnd out of bounds');
// Are we oob?
if (end > this.length) end = this.length;
if (target.length - targetStart < end - start) {
end = target.length - targetStart + start;
}
const len = end - start;
let i;
if (this === target && start < targetStart && targetStart < end) {
// descending copy from end
for (i = len - 1; i >= 0; --i) {
target[i + targetStart] = this[i + start];
}
} else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
// ascending copy from start
for (i = 0; i < len; ++i) {
target[i + targetStart] = this[i + start];
}
} else {
Uint8Array.prototype.set.call(
target,
this.subarray(start, start + len),
targetStart,
);
}
return len;
};
Buffer.prototype.fill = function fill(val, start, end) {
// Handle string cases:
if (typeof val === 'string') {
if (typeof start === 'string') {
start = 0;
end = this.length;
} else if (typeof end === 'string') {
end = this.length;
}
if (val.length === 1) {
const code = val.charCodeAt(0);
if (code < 256) {
val = code;
}
}
} else if (typeof val === 'number') {
val &= 255;
}
// Invalid ranges are not set to a default, so can range check early.
if (start < 0 || this.length < start || this.length < end) {
throw new RangeError('Out of range index');
}
if (end <= start) {
return this;
}
start >>>= 0;
end = end === undefined ? this.length : end >>> 0;
if (!val) val = 0;
let i;
if (typeof val === 'number') {
for (i = start; i < end; ++i) {
this[i] = val;
}
} else {
const bytes = Buffer.isBuffer(val)
? val
: new Buffer(val);
const len = bytes.length;
for (i = 0; i < end - start; ++i) {
this[i + start] = bytes[i % len];
}
}
return this;
};
Buffer.concat = function concat(list, length) {
if (!isArray(list)) {
throw new TypeError('"list" argument must be an Array of Buffers');
}
if (list.length === 0) {
return createBuffer(null, 0);
}
let i;
if (length === undefined) {
length = 0;
for (i = 0; i < list.length; ++i) {
length += list[i].length;
}
}
const buffer = allocUnsafe(null, length);
let pos = 0;
for (i = 0; i < list.length; ++i) {
const buf = list[i];
if (!Buffer.isBuffer(buf)) {
throw new TypeError('"list" argument must be an Array of Buffers');
}
buf.copy(buffer, pos);
pos += buf.length;
}
return buffer;
};
Buffer.byteLength = byteLength;
Buffer.prototype._isBuffer = true;
Buffer.isBuffer = function isBuffer(b) {
return !!(b != null && b._isBuffer);
};
module.exports = Buffer;