mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-14 15:56:38 +03:00
ac4fdfd0cd
Now the EbmlParser and DataViewReader types can accept BufferSource objects to avoid the caller having to convert it at each callsite. Change-Id: I527fbc638485214bfe976d7da89b79b6098033a8
266 lines
7.7 KiB
JavaScript
266 lines
7.7 KiB
JavaScript
/**
|
|
* @license
|
|
* Copyright 2016 Google Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
describe('DataViewReader', () => {
|
|
const Util = shaka.test.Util;
|
|
|
|
// |data| as interpreted as a 64 bit integer must not be larger than 2^53-1.
|
|
// decimal digits.
|
|
const data = new Uint8Array([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]);
|
|
// |data2| is small enough in little-endian to be read as a 64-bit number,
|
|
// and has the sign bit set on the first 6 bytes to prove that we don't
|
|
// return negative values.
|
|
const data2 =
|
|
new Uint8Array([0xde, 0xad, 0xbe, 0xef, 0xff, 0xff, 0x01, 0x00]);
|
|
|
|
/** @type {!shaka.util.DataViewReader} */
|
|
let bigEndianReader;
|
|
/** @type {!shaka.util.DataViewReader} */
|
|
let littleEndianReader;
|
|
/** @type {!shaka.util.DataViewReader} */
|
|
let bigEndianReader2;
|
|
/** @type {!shaka.util.DataViewReader} */
|
|
let littleEndianReader2;
|
|
|
|
beforeEach(() => {
|
|
bigEndianReader = new shaka.util.DataViewReader(
|
|
data, shaka.util.DataViewReader.Endianness.BIG_ENDIAN);
|
|
bigEndianReader2 = new shaka.util.DataViewReader(
|
|
data2, shaka.util.DataViewReader.Endianness.BIG_ENDIAN);
|
|
littleEndianReader = new shaka.util.DataViewReader(
|
|
data, shaka.util.DataViewReader.Endianness.LITTLE_ENDIAN);
|
|
littleEndianReader2 = new shaka.util.DataViewReader(
|
|
data2, shaka.util.DataViewReader.Endianness.LITTLE_ENDIAN);
|
|
});
|
|
|
|
it('reads a uint8 in big endian', () => {
|
|
const value1 = bigEndianReader.readUint8();
|
|
expect(value1).toBe(0x00);
|
|
|
|
const value2 = bigEndianReader.readUint8();
|
|
expect(value2).toBe(0x01);
|
|
|
|
const value3 = bigEndianReader2.readUint8();
|
|
expect(value3).toBe(0xde);
|
|
|
|
const value4 = bigEndianReader2.readUint8();
|
|
expect(value4).toBe(0xad);
|
|
});
|
|
|
|
it('reads a uint16 in big endian', () => {
|
|
const value1 = bigEndianReader.readUint16();
|
|
expect(value1).toBe(0x0001);
|
|
|
|
const value2 = bigEndianReader.readUint16();
|
|
expect(value2).toBe(0x0203);
|
|
|
|
const value3 = bigEndianReader2.readUint16();
|
|
expect(value3).toBe(0xdead);
|
|
|
|
const value4 = bigEndianReader2.readUint16();
|
|
expect(value4).toBe(0xbeef);
|
|
});
|
|
|
|
it('reads a uint32 in big endian', () => {
|
|
const value1 = bigEndianReader.readUint32();
|
|
expect(value1).toBe(0x00010203);
|
|
|
|
const value2 = bigEndianReader.readUint32();
|
|
expect(value2).toBe(0x04050607);
|
|
|
|
const value3 = bigEndianReader2.readUint32();
|
|
expect(value3).toBe(0xdeadbeef);
|
|
|
|
const value4 = bigEndianReader2.readUint32();
|
|
expect(value4).toBe(0xffff0100);
|
|
});
|
|
|
|
it('reads an int32 in big endian', () => {
|
|
const value1 = bigEndianReader.readInt32();
|
|
expect(value1).toBe(66051);
|
|
|
|
const value2 = bigEndianReader.readInt32();
|
|
expect(value2).toBe(67438087);
|
|
|
|
const value3 = bigEndianReader2.readInt32();
|
|
expect(value3).toBe(-559038737);
|
|
|
|
const value4 = bigEndianReader2.readInt32();
|
|
expect(value4).toBe(-65280);
|
|
});
|
|
|
|
it('reads a uint64 in big endian', () => {
|
|
const value = bigEndianReader.readUint64();
|
|
expect(value).toBe(0x0001020304050607);
|
|
});
|
|
|
|
it('reads a uint8 in little endian', () => {
|
|
const value1 = littleEndianReader.readUint8();
|
|
expect(value1).toBe(0x00);
|
|
|
|
const value2 = littleEndianReader.readUint8();
|
|
expect(value2).toBe(0x01);
|
|
|
|
const value3 = littleEndianReader2.readUint8();
|
|
expect(value3).toBe(0xde);
|
|
|
|
const value4 = littleEndianReader2.readUint8();
|
|
expect(value4).toBe(0xad);
|
|
});
|
|
|
|
it('reads a uint16 in little endian', () => {
|
|
const value1 = littleEndianReader.readUint16();
|
|
expect(value1).toBe(0x0100);
|
|
|
|
const value2 = littleEndianReader.readUint16();
|
|
expect(value2).toBe(0x0302);
|
|
|
|
const value3 = littleEndianReader2.readUint16();
|
|
expect(value3).toBe(0xadde);
|
|
|
|
const value4 = littleEndianReader2.readUint16();
|
|
expect(value4).toBe(0xefbe);
|
|
});
|
|
|
|
it('reads a uint32 in little endian', () => {
|
|
const value1 = littleEndianReader.readUint32();
|
|
expect(value1).toBe(0x03020100);
|
|
|
|
const value2 = littleEndianReader.readUint32();
|
|
expect(value2).toBe(0x07060504);
|
|
|
|
const value3 = littleEndianReader2.readUint32();
|
|
expect(value3).toBe(0xefbeadde);
|
|
|
|
const value4 = littleEndianReader2.readUint32();
|
|
expect(value4).toBe(0x0001ffff);
|
|
});
|
|
|
|
it('reads an int32 in little endian', () => {
|
|
const value1 = littleEndianReader.readInt32();
|
|
expect(value1).toBe(50462976);
|
|
|
|
const value2 = littleEndianReader.readInt32();
|
|
expect(value2).toBe(117835012);
|
|
|
|
const value3 = littleEndianReader2.readInt32();
|
|
expect(value3).toBe(-272716322);
|
|
|
|
const value4 = littleEndianReader2.readInt32();
|
|
expect(value4).toBe(131071);
|
|
});
|
|
|
|
it('reads a uint64 in little endian', () => {
|
|
const value = littleEndianReader2.readUint64();
|
|
expect(value).toBe(0x0001ffffefbeadde);
|
|
});
|
|
|
|
it('skips bytes', () => {
|
|
bigEndianReader.skip(1);
|
|
const value = bigEndianReader.readUint8();
|
|
expect(value).toBe(0x01);
|
|
});
|
|
|
|
it('determines the end of the data view', () => {
|
|
bigEndianReader.skip(7);
|
|
expect(bigEndianReader.hasMoreData()).toBe(true);
|
|
|
|
bigEndianReader.skip(1);
|
|
expect(bigEndianReader.hasMoreData()).toBe(false);
|
|
});
|
|
|
|
it('gets the byte position', () => {
|
|
expect(bigEndianReader.getPosition()).toBe(0);
|
|
|
|
bigEndianReader.skip(1);
|
|
expect(bigEndianReader.getPosition()).toBe(1);
|
|
|
|
bigEndianReader.skip(7);
|
|
expect(bigEndianReader.getPosition()).toBe(8);
|
|
});
|
|
|
|
describe('end-of-stream', () => {
|
|
it('detects when reading a uint8', () => {
|
|
bigEndianReader.skip(7);
|
|
bigEndianReader.readUint8();
|
|
runTest(() => {
|
|
bigEndianReader.readUint8();
|
|
});
|
|
});
|
|
|
|
it('detects when reading a uint16', () => {
|
|
bigEndianReader.skip(7);
|
|
runTest(() => {
|
|
bigEndianReader.readUint16();
|
|
});
|
|
});
|
|
|
|
it('detects when reading a uint32', () => {
|
|
bigEndianReader.skip(5);
|
|
runTest(() => {
|
|
bigEndianReader.readUint32();
|
|
});
|
|
});
|
|
|
|
it('detects when reading a int32', () => {
|
|
bigEndianReader.skip(5);
|
|
runTest(() => {
|
|
bigEndianReader.readInt32();
|
|
});
|
|
});
|
|
|
|
it('detects when reading a uint64', () => {
|
|
bigEndianReader.skip(3);
|
|
runTest(() => {
|
|
bigEndianReader.readUint64();
|
|
});
|
|
});
|
|
|
|
it('detects when skipping bytes', () => {
|
|
bigEndianReader.skip(8);
|
|
runTest(() => {
|
|
bigEndianReader.skip(1);
|
|
});
|
|
});
|
|
|
|
it('detects when reading bytes', () => {
|
|
bigEndianReader.skip(8);
|
|
runTest(() => {
|
|
bigEndianReader.readBytes(1);
|
|
});
|
|
});
|
|
|
|
function runTest(test) {
|
|
const expected = Util.jasmineError(new shaka.util.Error(
|
|
shaka.util.Error.Severity.CRITICAL,
|
|
shaka.util.Error.Category.MEDIA,
|
|
shaka.util.Error.Code.BUFFER_READ_OUT_OF_BOUNDS));
|
|
expect(test).toThrow(expected);
|
|
}
|
|
});
|
|
|
|
it('detects uint64s too large for JavaScript', () => {
|
|
const expected = Util.jasmineError(new shaka.util.Error(
|
|
shaka.util.Error.Severity.CRITICAL,
|
|
shaka.util.Error.Category.MEDIA,
|
|
shaka.util.Error.Code.JS_INTEGER_OVERFLOW));
|
|
|
|
expect(() => littleEndianReader.readUint64()).toThrow(expected);
|
|
expect(() => bigEndianReader2.readUint64()).toThrow(expected);
|
|
});
|
|
});
|