filestorage.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. "use strict";
  2. /** @interface */
  3. function FileStorageInterface() {}
  4. /**
  5. * Read a portion of a file.
  6. * @param {string} sha256sum
  7. * @param {number} offset
  8. * @param {number} count
  9. * @return {!Promise<Uint8Array>} null if file does not exist.
  10. */
  11. FileStorageInterface.prototype.read = function(sha256sum, offset, count) {};
  12. /**
  13. * Add a read-only file to the filestorage.
  14. * @param {string} sha256sum
  15. * @param {!Uint8Array} data
  16. * @return {!Promise}
  17. */
  18. FileStorageInterface.prototype.cache = function(sha256sum, data) {};
  19. /**
  20. * Call this when the file won't be used soon, e.g. when a file closes or when this immutable
  21. * version is already out of date. It is used to help prevent accumulation of unused files in
  22. * memory in the long run for some FileStorage mediums.
  23. */
  24. FileStorageInterface.prototype.uncache = function(sha256sum) {};
  25. /**
  26. * @constructor
  27. * @implements {FileStorageInterface}
  28. */
  29. function MemoryFileStorage()
  30. {
  31. /**
  32. * From sha256sum to file data.
  33. * @type {Map<string,Uint8Array>}
  34. */
  35. this.filedata = new Map();
  36. }
  37. /**
  38. * @param {string} sha256sum
  39. * @param {number} offset
  40. * @param {number} count
  41. * @return {!Promise<Uint8Array>} null if file does not exist.
  42. */
  43. MemoryFileStorage.prototype.read = async function(sha256sum, offset, count)
  44. {
  45. dbg_assert(sha256sum, "MemoryFileStorage read: sha256sum should be a non-empty string");
  46. const data = this.filedata.get(sha256sum);
  47. if(!data)
  48. {
  49. return null;
  50. }
  51. return data.subarray(offset, offset + count);
  52. };
  53. /**
  54. * @param {string} sha256sum
  55. * @param {!Uint8Array} data
  56. */
  57. MemoryFileStorage.prototype.cache = async function(sha256sum, data)
  58. {
  59. dbg_assert(sha256sum, "MemoryFileStorage cache: sha256sum should be a non-empty string");
  60. this.filedata.set(sha256sum, data);
  61. };
  62. /**
  63. * @param {string} sha256sum
  64. */
  65. MemoryFileStorage.prototype.uncache = function(sha256sum)
  66. {
  67. this.filedata.delete(sha256sum);
  68. };
  69. /**
  70. * @constructor
  71. * @implements {FileStorageInterface}
  72. * @param {FileStorageInterface} file_storage
  73. * @param {string} baseurl
  74. */
  75. function ServerFileStorageWrapper(file_storage, baseurl)
  76. {
  77. dbg_assert(baseurl, "ServerMemoryFileStorage: baseurl should not be empty");
  78. this.storage = file_storage;
  79. this.baseurl = baseurl;
  80. }
  81. /**
  82. * @param {string} sha256sum
  83. * @return {!Promise<Uint8Array>}
  84. */
  85. ServerFileStorageWrapper.prototype.load_from_server = function(sha256sum)
  86. {
  87. return new Promise((resolve, reject) =>
  88. {
  89. v86util.load_file(this.baseurl + sha256sum, { done: buffer =>
  90. {
  91. const data = new Uint8Array(buffer);
  92. this.cache(sha256sum, data).then(() => resolve(data));
  93. }});
  94. });
  95. };
  96. /**
  97. * @param {string} sha256sum
  98. * @param {number} offset
  99. * @param {number} count
  100. * @return {!Promise<Uint8Array>}
  101. */
  102. ServerFileStorageWrapper.prototype.read = async function(sha256sum, offset, count)
  103. {
  104. const data = await this.storage.read(sha256sum, offset, count);
  105. if(!data)
  106. {
  107. const full_file = await this.load_from_server(sha256sum);
  108. return full_file.subarray(offset, offset + count);
  109. }
  110. return data;
  111. };
  112. /**
  113. * @param {string} sha256sum
  114. * @param {!Uint8Array} data
  115. */
  116. ServerFileStorageWrapper.prototype.cache = async function(sha256sum, data)
  117. {
  118. return await this.storage.cache(sha256sum, data);
  119. };
  120. /**
  121. * @param {string} sha256sum
  122. */
  123. ServerFileStorageWrapper.prototype.uncache = function(sha256sum)
  124. {
  125. this.storage.uncache(sha256sum);
  126. };
  127. // Closure Compiler's way of exporting
  128. if(typeof window !== "undefined")
  129. {
  130. window["MemoryFileStorage"] = MemoryFileStorage;
  131. window["ServerFileStorageWrapper"] = ServerFileStorageWrapper;
  132. }
  133. else if(typeof module !== "undefined" && typeof module.exports !== "undefined")
  134. {
  135. module.exports["MemoryFileStorage"] = MemoryFileStorage;
  136. module.exports["ServerFileStorageWrapper"] = ServerFileStorageWrapper;
  137. }
  138. else if(typeof importScripts === "function")
  139. {
  140. // web worker
  141. self["MemoryFileStorage"] = MemoryFileStorage;
  142. self["ServerFileStorageWrapper"] = ServerFileStorageWrapper;
  143. }