dataReader.js 3.3 KB

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