Source: lib/util/text_parser.js

  1. /**
  2. * @license
  3. * Copyright 2016 Google Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. goog.provide('shaka.util.TextParser');
  18. goog.require('goog.asserts');
  19. /**
  20. * Reads elements from strings.
  21. *
  22. * @param {string} data
  23. * @constructor
  24. * @struct
  25. */
  26. shaka.util.TextParser = function(data) {
  27. /**
  28. * @const
  29. * @private {string}
  30. */
  31. this.data_ = data;
  32. /** @private {number} */
  33. this.position_ = 0;
  34. };
  35. /** @return {boolean} Whether it is at the end of the string. */
  36. shaka.util.TextParser.prototype.atEnd = function() {
  37. return this.position_ == this.data_.length;
  38. };
  39. /**
  40. * Reads a line from the parser. This will read but not return the newline.
  41. * Returns null at the end.
  42. *
  43. * @return {?string}
  44. */
  45. shaka.util.TextParser.prototype.readLine = function() {
  46. return this.readRegexReturnCapture_(/(.*?)(\n|$)/gm, 1);
  47. };
  48. /**
  49. * Reads a word from the parser. This will not read or return any whitespace
  50. * before or after the word (including newlines). Returns null at the end.
  51. *
  52. * @return {?string}
  53. */
  54. shaka.util.TextParser.prototype.readWord = function() {
  55. return this.readRegexReturnCapture_(/[^ \t\n]*/gm, 0);
  56. };
  57. /**
  58. * Skips any continuous whitespace from the parser. Returns null at the end.
  59. */
  60. shaka.util.TextParser.prototype.skipWhitespace = function() {
  61. this.readRegex(/[ \t]+/gm);
  62. };
  63. /**
  64. * Reads the given regular expression from the parser. This requires the match
  65. * to be at the current position; there is no need to include a head anchor.
  66. * This requires that the regex have the global flag to be set so that it can
  67. * set lastIndex to start the search at the current position. Returns null at
  68. * the end or if the regex does not match the current position.
  69. *
  70. * @param {!RegExp} regex
  71. * @return {Array.<string>}
  72. */
  73. shaka.util.TextParser.prototype.readRegex = function(regex) {
  74. var index = this.indexOf_(regex);
  75. if (this.atEnd() || index == null || index.position != this.position_)
  76. return null;
  77. this.position_ += index.length;
  78. return index.results;
  79. };
  80. /**
  81. * Reads a regex from the parser and returns the given capture.
  82. *
  83. * @param {!RegExp} regex
  84. * @param {number} index
  85. * @return {?string}
  86. * @private
  87. */
  88. shaka.util.TextParser.prototype.readRegexReturnCapture_ =
  89. function(regex, index) {
  90. if (this.atEnd())
  91. return null;
  92. var ret = this.readRegex(regex);
  93. if (!ret)
  94. return null;
  95. else
  96. return ret[index];
  97. };
  98. /**
  99. * Returns the index info about a regular expression match.
  100. *
  101. * @param {!RegExp} regex
  102. * @return {?{position: number, length: number, results: !Array.<string>}}
  103. * @private
  104. */
  105. shaka.util.TextParser.prototype.indexOf_ = function(regex) {
  106. // The global flag is required to use lastIndex.
  107. goog.asserts.assert(regex.global, 'global flag should be set');
  108. regex.lastIndex = this.position_;
  109. var results = regex.exec(this.data_);
  110. if (results == null)
  111. return null;
  112. else
  113. return {
  114. position: results.index,
  115. length: results[0].length,
  116. results: results
  117. };
  118. };