UNPKG

shaka-player

Version:
168 lines (151 loc) 4.79 kB
/*! @license * Shaka Player * Copyright 2016 Google LLC * SPDX-License-Identifier: Apache-2.0 */ goog.provide('shaka.util.Uint8ArrayUtils'); goog.require('shaka.util.BufferUtils'); goog.require('shaka.util.StringUtils'); // TODO: revisit this when Closure Compiler supports partially-exported classes. /** * @summary A set of Uint8Array utility functions. * @export */ shaka.util.Uint8ArrayUtils = class { /** * Convert a buffer to a base64 string. The output will be standard * alphabet as opposed to base64url safe alphabet. * @param {BufferSource} data * @return {string} * @export */ static toStandardBase64(data) { const arr = shaka.util.BufferUtils.toUint8(data); // eslint-disable-next-line no-restricted-syntax if (!Uint8Array.prototype.toBase64) { const bytes = shaka.util.StringUtils.fromCharCode(arr); return btoa(bytes); } return arr.toBase64({alphabet: 'base64', omitPadding: false}); } /** * Convert a buffer to a base64 string. The output will always use the * alternate encoding/alphabet also known as "base64url". * @param {BufferSource} data * @param {boolean=} padding If true, pad the output with equals signs. * Defaults to true. * @return {string} * @export */ static toBase64(data, padding) { padding = (padding == undefined) ? true : padding; // eslint-disable-next-line no-restricted-syntax if (!Uint8Array.prototype.toBase64) { const base64 = shaka.util.Uint8ArrayUtils.toStandardBase64(data) .replace(/\+/g, '-').replace(/\//g, '_'); return padding ? base64 : base64.replace(/[=]*$/, ''); } const arr = shaka.util.BufferUtils.toUint8(data); return arr.toBase64({alphabet: 'base64url', omitPadding: !padding}); } /** * Convert a base64 string to a Uint8Array. Accepts either the standard * alphabet or the alternate "base64url" alphabet. * @param {string} str * @return {!Uint8Array} * @export */ static fromBase64(str) { if (!('fromBase64' in Uint8Array)) { // atob creates a "raw string" where each character is interpreted as a // byte. const bytes = window.atob(str.replace(/-/g, '+').replace(/_/g, '/')); const result = new Uint8Array(bytes.length); for (let i = 0; i < bytes.length; ++i) { result[i] = bytes.charCodeAt(i); } return result; } const input = str.replace(/\s+/g, ''); const usesUrlAlphabet = /[-_]/.test(input); return Uint8Array.fromBase64(input, { alphabet: usesUrlAlphabet ? 'base64url' : 'base64', }); } /** * Convert a hex string to a Uint8Array. * @param {string} str * @return {!Uint8Array} * @export */ static fromHex(str) { if (!('fromHex' in Uint8Array)) { const size = str.length / 2; const arr = new Uint8Array(size); for (let i = 0; i < size; i++) { arr[i] = window.parseInt(str.substr(i * 2, 2), 16); } return arr; } return Uint8Array.fromHex(str); } /** * Convert a buffer to a hex string. * @param {BufferSource} data * @return {string} * @export */ static toHex(data) { const arr = shaka.util.BufferUtils.toUint8(data); // eslint-disable-next-line no-restricted-syntax if (!Uint8Array.prototype.toHex) { let hex = ''; for (let value of arr) { value = value.toString(16); if (value.length == 1) { value = '0' + value; } hex += value; } return hex; } return arr.toHex(); } /** * Concatenate buffers. * @param {...BufferSource} varArgs * @return {!Uint8Array} * @export */ static concat(...varArgs) { return shaka.util.Uint8ArrayUtils.concatRange(varArgs, 0, varArgs.length); } /** * Concatenate a range of buffers from a flat array. * Avoids a subarray allocation compared to concat(...array.slice(s, e)). * @param {!Array<!BufferSource>} array * @param {number=} start Inclusive start index. * @param {number=} end Exclusive end index. * @return {!Uint8Array} */ static concatRange(array, start = 0, end = array.length) { const BufferUtils = shaka.util.BufferUtils; let totalLength = 0; for (let i = start; i < end; ++i) { totalLength += array[i].byteLength; } const result = new Uint8Array(totalLength); let offset = 0; for (let i = start; i < end; ++i) { const value = array[i]; if (ArrayBuffer.isView(value) && /** @type {TypedArray} */ (value).BYTES_PER_ELEMENT === 1) { result.set(/** @type {!Uint8Array} */(value), offset); } else { result.set(BufferUtils.toUint8(value), offset); } offset += value.byteLength; } return result; } };