No Description

DataReader.js 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. 'use strict';
  2. var utils = require('../utils');
  3. function DataReader(data) {
  4. this.data = data; // type : see implementation
  5. this.length = data.length;
  6. this.index = 0;
  7. this.zero = 0;
  8. }
  9. DataReader.prototype = {
  10. /**
  11. * Check that the offset will not go too far.
  12. * @param {string} offset the additional offset to check.
  13. * @throws {Error} an Error if the offset is out of bounds.
  14. */
  15. checkOffset: function(offset) {
  16. this.checkIndex(this.index + offset);
  17. },
  18. /**
  19. * Check that the specified index will not be too far.
  20. * @param {string} newIndex the index to check.
  21. * @throws {Error} an Error if the index is out of bounds.
  22. */
  23. checkIndex: function(newIndex) {
  24. if (this.length < this.zero + newIndex || newIndex < 0) {
  25. throw new Error("End of data reached (data length = " + this.length + ", asked index = " + (newIndex) + "). Corrupted zip ?");
  26. }
  27. },
  28. /**
  29. * Change the index.
  30. * @param {number} newIndex The new index.
  31. * @throws {Error} if the new index is out of the data.
  32. */
  33. setIndex: function(newIndex) {
  34. this.checkIndex(newIndex);
  35. this.index = newIndex;
  36. },
  37. /**
  38. * Skip the next n bytes.
  39. * @param {number} n the number of bytes to skip.
  40. * @throws {Error} if the new index is out of the data.
  41. */
  42. skip: function(n) {
  43. this.setIndex(this.index + n);
  44. },
  45. /**
  46. * Get the byte at the specified index.
  47. * @param {number} i the index to use.
  48. * @return {number} a byte.
  49. */
  50. byteAt: function(i) {
  51. // see implementations
  52. },
  53. /**
  54. * Get the next number with a given byte size.
  55. * @param {number} size the number of bytes to read.
  56. * @return {number} the corresponding number.
  57. */
  58. readInt: function(size) {
  59. var result = 0,
  60. i;
  61. this.checkOffset(size);
  62. for (i = this.index + size - 1; i >= this.index; i--) {
  63. result = (result << 8) + this.byteAt(i);
  64. }
  65. this.index += size;
  66. return result;
  67. },
  68. /**
  69. * Get the next string with a given byte size.
  70. * @param {number} size the number of bytes to read.
  71. * @return {string} the corresponding string.
  72. */
  73. readString: function(size) {
  74. return utils.transformTo("string", this.readData(size));
  75. },
  76. /**
  77. * Get raw data without conversion, <size> bytes.
  78. * @param {number} size the number of bytes to read.
  79. * @return {Object} the raw data, implementation specific.
  80. */
  81. readData: function(size) {
  82. // see implementations
  83. },
  84. /**
  85. * Find the last occurence of a zip signature (4 bytes).
  86. * @param {string} sig the signature to find.
  87. * @return {number} the index of the last occurence, -1 if not found.
  88. */
  89. lastIndexOfSignature: function(sig) {
  90. // see implementations
  91. },
  92. /**
  93. * Read the signature (4 bytes) at the current position and compare it with sig.
  94. * @param {string} sig the expected signature
  95. * @return {boolean} true if the signature matches, false otherwise.
  96. */
  97. readAndCheckSignature: function(sig) {
  98. // see implementations
  99. },
  100. /**
  101. * Get the next date.
  102. * @return {Date} the date.
  103. */
  104. readDate: function() {
  105. var dostime = this.readInt(4);
  106. return new Date(Date.UTC(
  107. ((dostime >> 25) & 0x7f) + 1980, // year
  108. ((dostime >> 21) & 0x0f) - 1, // month
  109. (dostime >> 16) & 0x1f, // day
  110. (dostime >> 11) & 0x1f, // hour
  111. (dostime >> 5) & 0x3f, // minute
  112. (dostime & 0x1f) << 1)); // second
  113. }
  114. };
  115. module.exports = DataReader;