ascii_hex_stream.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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 { DecodeStream } from "./decode_stream.js";
  16. class AsciiHexStream extends DecodeStream {
  17. constructor(str, maybeLength) {
  18. // Most streams increase in size when decoded, but AsciiHex streams shrink
  19. // by 50%.
  20. if (maybeLength) {
  21. maybeLength *= 0.5;
  22. }
  23. super(maybeLength);
  24. this.str = str;
  25. this.dict = str.dict;
  26. this.firstDigit = -1;
  27. }
  28. readBlock() {
  29. const UPSTREAM_BLOCK_SIZE = 8000;
  30. const bytes = this.str.getBytes(UPSTREAM_BLOCK_SIZE);
  31. if (!bytes.length) {
  32. this.eof = true;
  33. return;
  34. }
  35. const maxDecodeLength = (bytes.length + 1) >> 1;
  36. const buffer = this.ensureBuffer(this.bufferLength + maxDecodeLength);
  37. let bufferLength = this.bufferLength;
  38. let firstDigit = this.firstDigit;
  39. for (const ch of bytes) {
  40. let digit;
  41. if (ch >= /* '0' = */ 0x30 && ch <= /* '9' = */ 0x39) {
  42. digit = ch & 0x0f;
  43. } else if (
  44. (ch >= /* 'A' = */ 0x41 && ch <= /* 'Z' = */ 0x46) ||
  45. (ch >= /* 'a' = */ 0x61 && ch <= /* 'z' = */ 0x66)
  46. ) {
  47. digit = (ch & 0x0f) + 9;
  48. } else if (ch === /* '>' = */ 0x3e) {
  49. this.eof = true;
  50. break;
  51. } else {
  52. // Probably whitespace, ignoring.
  53. continue;
  54. }
  55. if (firstDigit < 0) {
  56. firstDigit = digit;
  57. } else {
  58. buffer[bufferLength++] = (firstDigit << 4) | digit;
  59. firstDigit = -1;
  60. }
  61. }
  62. if (firstDigit >= 0 && this.eof) {
  63. // incomplete byte
  64. buffer[bufferLength++] = firstDigit << 4;
  65. firstDigit = -1;
  66. }
  67. this.firstDigit = firstDigit;
  68. this.bufferLength = bufferLength;
  69. }
  70. }
  71. export { AsciiHexStream };