mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-15 16:06:41 +03:00
6e55a3b21b
Fixes #2643 Happy reviewing!
181 lines
4.0 KiB
JavaScript
181 lines
4.0 KiB
JavaScript
/*! @license
|
|
* Shaka Player
|
|
* Copyright 2016 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
goog.provide('shaka.util.TextParser');
|
|
|
|
goog.require('goog.asserts');
|
|
|
|
|
|
/**
|
|
* Reads elements from strings.
|
|
*/
|
|
shaka.util.TextParser = class {
|
|
/**
|
|
* @param {string} data
|
|
*/
|
|
constructor(data) {
|
|
/**
|
|
* @const
|
|
* @private {string}
|
|
*/
|
|
this.data_ = data || '';
|
|
|
|
/** @private {number} */
|
|
this.position_ = 0;
|
|
}
|
|
|
|
|
|
/** @return {boolean} Whether it is at the end of the string. */
|
|
atEnd() {
|
|
return this.position_ == this.data_.length;
|
|
}
|
|
|
|
|
|
/**
|
|
* Reads a line from the parser. This will read but not return the newline.
|
|
* Returns null at the end.
|
|
*
|
|
* @return {?string}
|
|
*/
|
|
readLine() {
|
|
return this.readRegexReturnCapture_(/(.*?)(\n|$)/gm, 1);
|
|
}
|
|
|
|
|
|
/**
|
|
* Reads a word from the parser. This will not read or return any whitespace
|
|
* before or after the word (including newlines). Returns null at the end.
|
|
*
|
|
* @return {?string}
|
|
*/
|
|
readWord() {
|
|
return this.readRegexReturnCapture_(/[^ \t\n]*/gm, 0);
|
|
}
|
|
|
|
|
|
/**
|
|
* Skips any continuous whitespace from the parser. Returns null at the end.
|
|
*/
|
|
skipWhitespace() {
|
|
this.readRegex(/[ \t]+/gm);
|
|
}
|
|
|
|
|
|
/**
|
|
* Reads the given regular expression from the parser. This requires the
|
|
* match to be at the current position; there is no need to include a head
|
|
* anchor.
|
|
* This requires that the regex have the global flag to be set so that it can
|
|
* set lastIndex to start the search at the current position. Returns null at
|
|
* the end or if the regex does not match the current position.
|
|
*
|
|
* @param {!RegExp} regex
|
|
* @return {Array<string>}
|
|
*/
|
|
readRegex(regex) {
|
|
const index = this.indexOf_(regex);
|
|
if (this.atEnd() || index == null || index.position != this.position_) {
|
|
return null;
|
|
}
|
|
|
|
this.position_ += index.length;
|
|
return index.results;
|
|
}
|
|
|
|
|
|
/**
|
|
* Reads a regex from the parser and returns the given capture.
|
|
*
|
|
* @param {!RegExp} regex
|
|
* @param {number} index
|
|
* @return {?string}
|
|
* @private
|
|
*/
|
|
readRegexReturnCapture_(regex, index) {
|
|
if (this.atEnd()) {
|
|
return null;
|
|
}
|
|
|
|
const ret = this.readRegex(regex);
|
|
if (!ret) {
|
|
return null;
|
|
} else {
|
|
return ret[index];
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the index info about a regular expression match.
|
|
*
|
|
* @param {!RegExp} regex
|
|
* @return {?{position: number, length: number, results: !Array<string>}}
|
|
* @private
|
|
*/
|
|
indexOf_(regex) {
|
|
// The global flag is required to use lastIndex.
|
|
goog.asserts.assert(regex.global, 'global flag should be set');
|
|
|
|
regex.lastIndex = this.position_;
|
|
const results = regex.exec(this.data_);
|
|
if (results == null) {
|
|
return null;
|
|
} else {
|
|
return {
|
|
position: results.index,
|
|
length: results[0].length,
|
|
results: results,
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Parses a time.
|
|
*
|
|
* @return {?number}
|
|
*/
|
|
parseTime() {
|
|
const results = this.readRegex(shaka.util.TextParser.timeFormat_);
|
|
if (results == null) {
|
|
return null;
|
|
}
|
|
// This capture is optional, but will still be in the array as undefined,
|
|
// in which case it is 0.
|
|
const hours = Number(results[1]) || 0;
|
|
const minutes = Number(results[2]);
|
|
const seconds = Number(results[3]);
|
|
const milliseconds = Number(results[6]) || 0;
|
|
if (minutes > 59 || seconds > 59) {
|
|
return null;
|
|
}
|
|
|
|
return (milliseconds / 1000) + seconds + (minutes * 60) + (hours * 3600);
|
|
}
|
|
|
|
/**
|
|
* Parses a time from string.
|
|
*
|
|
* @param {?string} time
|
|
* @return {?number}
|
|
*/
|
|
static parseTime(time) {
|
|
if (!time) {
|
|
return null;
|
|
}
|
|
const parser = new shaka.util.TextParser(time);
|
|
return parser.parseTime();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @const
|
|
* @private {!RegExp}
|
|
* @example 00:00.000 or 00:00:00.000 or 0:00:00.000 or
|
|
* 00:00.00 or 00:00:00.00 or 0:00:00.00 or 00:00:00
|
|
*/
|
|
shaka.util.TextParser.timeFormat_ =
|
|
/(?:(\d{1,}):)?(\d{2}):(\d{2})((\.(\d{1,3})))?/g;
|