DataWriter.jsm 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil; tab-width: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  4. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /* jshint esnext: true, moz: true */
  6. 'use strict';
  7. this.EXPORTED_SYMBOLS = ['DataWriter'];
  8. class DataWriter {
  9. constructor(data, maxBytes = 512) {
  10. if (typeof data === 'number') {
  11. maxBytes = data;
  12. data = undefined;
  13. }
  14. this._buffer = new ArrayBuffer(maxBytes);
  15. this._data = new Uint8Array(this._buffer);
  16. this._cursor = 0;
  17. if (data) {
  18. this.putBytes(data);
  19. }
  20. }
  21. get buffer() {
  22. return this._buffer.slice(0, this._cursor);
  23. }
  24. get data() {
  25. return new Uint8Array(this.buffer);
  26. }
  27. // `data` is `Uint8Array`
  28. putBytes(data) {
  29. if (this._cursor + data.length > this._data.length) {
  30. throw new Error('DataWriter buffer is exceeded');
  31. }
  32. for (let i = 0, length = data.length; i < length; i++) {
  33. this._data[this._cursor] = data[i];
  34. this._cursor++;
  35. }
  36. }
  37. putByte(byte) {
  38. if (this._cursor + 1 > this._data.length) {
  39. throw new Error('DataWriter buffer is exceeded');
  40. }
  41. this._data[this._cursor] = byte
  42. this._cursor++;
  43. }
  44. putValue(value, length) {
  45. length = length || 1;
  46. if (length == 1) {
  47. this.putByte(value);
  48. } else {
  49. this.putBytes(_valueToUint8Array(value, length));
  50. }
  51. }
  52. putLabel(label) {
  53. // Eliminate any trailing '.'s in the label (valid in text representation).
  54. label = label.replace(/\.$/, '');
  55. let parts = label.split('.');
  56. parts.forEach((part) => {
  57. this.putLengthString(part);
  58. });
  59. this.putValue(0);
  60. }
  61. putLengthString(string) {
  62. if (string.length > 0xff) {
  63. throw new Error("String too long.");
  64. }
  65. this.putValue(string.length);
  66. for (let i = 0; i < string.length; i++) {
  67. this.putValue(string.charCodeAt(i));
  68. }
  69. }
  70. }
  71. /**
  72. * @private
  73. */
  74. function _valueToUint8Array(value, length) {
  75. let arrayBuffer = new ArrayBuffer(length);
  76. let uint8Array = new Uint8Array(arrayBuffer);
  77. for (let i = length - 1; i >= 0; i--) {
  78. uint8Array[i] = value & 0xff;
  79. value = value >> 8;
  80. }
  81. return uint8Array;
  82. }