decode_stream.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /* Copyright 2012 Mozilla Foundation
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. import { BaseStream } from "./base_stream.js";
  16. import { Stream } from "./stream.js";
  17. // Lots of DecodeStreams are created whose buffers are never used. For these
  18. // we share a single empty buffer. This is (a) space-efficient and (b) avoids
  19. // having special cases that would be required if we used |null| for an empty
  20. // buffer.
  21. const emptyBuffer = new Uint8Array(0);
  22. // Super class for the decoding streams.
  23. class DecodeStream extends BaseStream {
  24. constructor(maybeMinBufferLength) {
  25. super();
  26. this._rawMinBufferLength = maybeMinBufferLength || 0;
  27. this.pos = 0;
  28. this.bufferLength = 0;
  29. this.eof = false;
  30. this.buffer = emptyBuffer;
  31. this.minBufferLength = 512;
  32. if (maybeMinBufferLength) {
  33. // Compute the first power of two that is as big as maybeMinBufferLength.
  34. while (this.minBufferLength < maybeMinBufferLength) {
  35. this.minBufferLength *= 2;
  36. }
  37. }
  38. }
  39. get isEmpty() {
  40. while (!this.eof && this.bufferLength === 0) {
  41. this.readBlock();
  42. }
  43. return this.bufferLength === 0;
  44. }
  45. ensureBuffer(requested) {
  46. const buffer = this.buffer;
  47. if (requested <= buffer.byteLength) {
  48. return buffer;
  49. }
  50. let size = this.minBufferLength;
  51. while (size < requested) {
  52. size *= 2;
  53. }
  54. const buffer2 = new Uint8Array(size);
  55. buffer2.set(buffer);
  56. return (this.buffer = buffer2);
  57. }
  58. getByte() {
  59. const pos = this.pos;
  60. while (this.bufferLength <= pos) {
  61. if (this.eof) {
  62. return -1;
  63. }
  64. this.readBlock();
  65. }
  66. return this.buffer[this.pos++];
  67. }
  68. getBytes(length) {
  69. const pos = this.pos;
  70. let end;
  71. if (length) {
  72. this.ensureBuffer(pos + length);
  73. end = pos + length;
  74. while (!this.eof && this.bufferLength < end) {
  75. this.readBlock();
  76. }
  77. const bufEnd = this.bufferLength;
  78. if (end > bufEnd) {
  79. end = bufEnd;
  80. }
  81. } else {
  82. while (!this.eof) {
  83. this.readBlock();
  84. }
  85. end = this.bufferLength;
  86. }
  87. this.pos = end;
  88. return this.buffer.subarray(pos, end);
  89. }
  90. reset() {
  91. this.pos = 0;
  92. }
  93. makeSubStream(start, length, dict = null) {
  94. if (length === undefined) {
  95. while (!this.eof) {
  96. this.readBlock();
  97. }
  98. } else {
  99. const end = start + length;
  100. while (this.bufferLength <= end && !this.eof) {
  101. this.readBlock();
  102. }
  103. }
  104. return new Stream(this.buffer, start, length, dict);
  105. }
  106. getBaseStreams() {
  107. return this.str ? this.str.getBaseStreams() : null;
  108. }
  109. }
  110. class StreamsSequenceStream extends DecodeStream {
  111. constructor(streams, onError = null) {
  112. let maybeLength = 0;
  113. for (const stream of streams) {
  114. maybeLength +=
  115. stream instanceof DecodeStream
  116. ? stream._rawMinBufferLength
  117. : stream.length;
  118. }
  119. super(maybeLength);
  120. this.streams = streams;
  121. this._onError = onError;
  122. }
  123. readBlock() {
  124. const streams = this.streams;
  125. if (streams.length === 0) {
  126. this.eof = true;
  127. return;
  128. }
  129. const stream = streams.shift();
  130. let chunk;
  131. try {
  132. chunk = stream.getBytes();
  133. } catch (reason) {
  134. if (this._onError) {
  135. this._onError(reason, stream.dict && stream.dict.objId);
  136. return;
  137. }
  138. throw reason;
  139. }
  140. const bufferLength = this.bufferLength;
  141. const newLength = bufferLength + chunk.length;
  142. const buffer = this.ensureBuffer(newLength);
  143. buffer.set(chunk, bufferLength);
  144. this.bufferLength = newLength;
  145. }
  146. getBaseStreams() {
  147. const baseStreamsBuf = [];
  148. for (const stream of this.streams) {
  149. const baseStreams = stream.getBaseStreams();
  150. if (baseStreams) {
  151. baseStreamsBuf.push(...baseStreams);
  152. }
  153. }
  154. return baseStreamsBuf.length > 0 ? baseStreamsBuf : null;
  155. }
  156. }
  157. export { DecodeStream, StreamsSequenceStream };