Skip to content

Commit

Permalink
Add native support for Uint8Array types (qzind#1098)
Browse files Browse the repository at this point in the history
Add native support for Uint8Array types
Closes qzind#1088
Related qzind#1087
  • Loading branch information
tresf authored Apr 20, 2023
1 parent 61b90ae commit a4cebe5
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 2 deletions.
59 changes: 57 additions & 2 deletions js/qz-tray.js
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ var qz = (function() {
if (data[i].constructor === Object) {
var absolute = false;

if (data[i].data && data[i].data.search(/data:image\/\w+;base64,/) === 0) {
if (data[i].data && data[i].data.search && data[i].data.search(/data:image\/\w+;base64,/) === 0) {
//upgrade from old base64 behavior
data[i].flavor = "base64";
data[i].data = data[i].data.replace(/^data:image\/\w+;base64,/, "");
Expand Down Expand Up @@ -767,12 +767,67 @@ var qz = (function() {
}
// Promise won't reject on throw; yet better than 'undefined'
throw new Error("A connection to QZ has not been established yet");
}
},

uint8ArrayToHex: function(uint8) {
return Array.from(uint8)
.map(function(i) { return i.toString(16).padStart(2, '0'); })
.join('');
},

uint8ArrayToBase64: function(uint8) {
/**
* Adapted from Egor Nepomnyaschih's code under MIT Licence (C) 2020
* see https://gist.github.com/enepomnyaschih/72c423f727d395eeaa09697058238727
*/
var map = [
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U",
"V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p",
"q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"
];

var result = '', i, l = uint8.length;
for (i = 2; i < l; i += 3) {
result += map[uint8[i - 2] >> 2];
result += map[((uint8[i - 2] & 0x03) << 4) | (uint8[i - 1] >> 4)];
result += map[((uint8[i - 1] & 0x0F) << 2) | (uint8[i] >> 6)];
result += map[uint8[i] & 0x3F];
}
if (i === l + 1) { // 1 octet yet to write
result += map[uint8[i - 2] >> 2];
result += map[(uint8[i - 2] & 0x03) << 4];
result += "==";
}
if (i === l) { // 2 octets yet to write
result += map[uint8[i - 2] >> 2];
result += map[((uint8[i - 2] & 0x03) << 4) | (uint8[i - 1] >> 4)];
result += map[(uint8[i - 1] & 0x0F) << 2];
result += "=";
}
return result;
},
},

compatible: {
/** Converts message format to a previous version's */
data: function(printData) {
// special handling for Uint8Array
if (printData.constructor === Object && printData.data instanceof Uint8Array) {
if (printData.flavor) {
var flavor = printData.flavor.toString().toUpperCase();
switch(flavor) {
case 'BASE64':
printData.data = _qz.tools.uint8ArrayToBase64(printData.data);
break;
case 'HEX':
printData.data = _qz.tools.uint8ArrayToHex(printData.data);
break;
default:
throw new Error("Uint8Array conversion to '" + flavor + "' is not supported.");
}
}
}

if (_qz.tools.isVersion(2, 0)) {
/*
2.0.x conversion
Expand Down
76 changes: 76 additions & 0 deletions js/sample/array-from-pollyfill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
if (!Array.from) {
Array.from = (function () {
var toStr = Object.prototype.toString;
var isCallable = function (fn) {
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
};
var toInteger = function (value) {
var number = Number(value);
if (isNaN(number)) { return 0; }
if (number === 0 || !isFinite(number)) { return number; }
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
};
var maxSafeInteger = Math.pow(2, 53) - 1;
var toLength = function (value) {
var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
};

// The length property of the from method is 1.
return function from(arrayLike/*, mapFn, thisArg */) {
// 1. Let C be the this value.
var C = this;

// 2. Let items be ToObject(arrayLike).
var items = Object(arrayLike);

// 3. ReturnIfAbrupt(items).
if (arrayLike == null) {
throw new TypeError("Array.from requires an array-like object - not null or undefined");
}

// 4. If mapfn is undefined, then let mapping be false.
var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
var T;
if (typeof mapFn !== 'undefined') {
// 5. else
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
if (!isCallable(mapFn)) {
throw new TypeError('Array.from: when provided, the second argument must be a function');
}

// 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (arguments.length > 2) {
T = arguments[2];
}
}

// 10. Let lenValue be Get(items, "length").
// 11. Let len be ToLength(lenValue).
var len = toLength(items.length);

// 13. If IsConstructor(C) is true, then
// 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.
// 14. a. Else, Let A be ArrayCreate(len).
var A = isCallable(C) ? Object(new C(len)) : new Array(len);

// 16. Let k be 0.
var k = 0;
// 17. Repeat, while k < len… (also steps a - h)
var kValue;
while (k < len) {
kValue = items[k];
if (mapFn) {
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
} else {
A[k] = kValue;
}
k += 1;
}
// 18. Let putStatus be Put(A, "length", len, true).
A.length = len;
// 20. Return A.
return A;
};
}());
}
21 changes: 21 additions & 0 deletions js/sample/padstart-pollyfill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* String.prototype.padStart() polyfill
* https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
*/
if (!String.prototype.padStart) {
String.prototype.padStart = function padStart(targetLength,padString) {
targetLength = targetLength>>0; //truncate if number or convert non-number to 0;
padString = String((typeof padString !== 'undefined' ? padString : ' '));
if (this.length > targetLength) {
return String(this);
}
else {
targetLength = targetLength-this.length;
if (targetLength > padString.length) {
padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed
}
return padString.slice(0,targetLength) + String(this);
}
};
}
2 changes: 2 additions & 0 deletions sample.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
<!-- Pollyfills -->
<script type="text/javascript" src="js/sample/promise-polyfill-8.1.3.min.js"></script>
<script type="text/javascript" src="js/sample/whatwg-fetch-3.0.0.min.js"></script>
<script type="text/javascript" src="js/sample/padstart-pollyfill.js"></script>
<script type="text/javascript" src="js/sample/array-from-pollyfill.js"></script>

<!-- Page styling -->
<script type="text/javascript" src="js/sample/jquery-1.11.3.min.js"></script>
Expand Down

0 comments on commit a4cebe5

Please sign in to comment.