index.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. // @ts-check
  2. 'use strict'
  3. const assert = require('check-types').assert
  4. const Blob = require('../blob')
  5. // Dependencies are loaded at the bottom of the file to mitigate circular
  6. // dependency
  7. let BinaryFileData = null
  8. let HashFileData = null
  9. let HollowBinaryFileData = null
  10. let HollowStringFileData = null
  11. let LazyStringFileData = null
  12. let StringFileData = null
  13. /**
  14. * @typedef {import("../types").BlobStore} BlobStore
  15. * @typedef {import("../types").ReadonlyBlobStore} ReadonlyBlobStore
  16. * @typedef {import("../operation/edit_operation")} EditOperation
  17. * @typedef {import("../file_data/comment_list")} CommentList
  18. * @typedef {import("../types").CommentRawData} CommentRawData
  19. */
  20. /**
  21. * Helper to represent the content of a file. This class and its subclasses
  22. * should be used only through {@link File}.
  23. */
  24. class FileData {
  25. /** @see File.fromRaw */
  26. static fromRaw(raw) {
  27. if (Object.prototype.hasOwnProperty.call(raw, 'hash')) {
  28. if (Object.prototype.hasOwnProperty.call(raw, 'byteLength'))
  29. return BinaryFileData.fromRaw(raw)
  30. if (Object.prototype.hasOwnProperty.call(raw, 'stringLength'))
  31. return LazyStringFileData.fromRaw(raw)
  32. return HashFileData.fromRaw(raw)
  33. }
  34. if (Object.prototype.hasOwnProperty.call(raw, 'byteLength'))
  35. return HollowBinaryFileData.fromRaw(raw)
  36. if (Object.prototype.hasOwnProperty.call(raw, 'stringLength'))
  37. return HollowStringFileData.fromRaw(raw)
  38. if (Object.prototype.hasOwnProperty.call(raw, 'content'))
  39. return StringFileData.fromRaw(raw)
  40. throw new Error('FileData: bad raw object ' + JSON.stringify(raw))
  41. }
  42. /** @see File.createHollow */
  43. static createHollow(byteLength, stringLength) {
  44. if (stringLength == null) {
  45. return new HollowBinaryFileData(byteLength)
  46. }
  47. return new HollowStringFileData(stringLength)
  48. }
  49. /**
  50. * @see File.createLazyFromBlob
  51. * @param {Blob} blob
  52. * @param {Blob} [rangesBlob]
  53. */
  54. static createLazyFromBlobs(blob, rangesBlob) {
  55. assert.instance(blob, Blob, 'FileData: bad blob')
  56. if (blob.getStringLength() == null) {
  57. return new BinaryFileData(blob.getHash(), blob.getByteLength())
  58. }
  59. return new LazyStringFileData(
  60. blob.getHash(),
  61. rangesBlob?.getHash(),
  62. blob.getStringLength()
  63. )
  64. }
  65. toRaw() {
  66. throw new Error('FileData: toRaw not implemented')
  67. }
  68. /**
  69. * @see File#getHash
  70. * @return {string | null | undefined}
  71. */
  72. getHash() {
  73. return null
  74. }
  75. /**
  76. * @see File#getHash
  77. * @return {string | null | undefined}
  78. */
  79. getRangesHash() {
  80. return null
  81. }
  82. /**
  83. * @see File#getContent
  84. * @param {import('../file').FileGetContentOptions} [opts]
  85. * @return {string | null | undefined}
  86. */
  87. getContent(opts = {}) {
  88. return null
  89. }
  90. /**
  91. * @see File#isEditable
  92. * @return {boolean | null | undefined} null if it is not currently known
  93. */
  94. isEditable() {
  95. return null
  96. }
  97. /**
  98. * @see File#getByteLength
  99. * @return {number | null | undefined}
  100. */
  101. getByteLength() {
  102. return null
  103. }
  104. /**
  105. * @see File#getStringLength
  106. * @return {number | null | undefined}
  107. */
  108. getStringLength() {
  109. return null
  110. }
  111. /**
  112. * @see File#edit
  113. * @param {EditOperation} editOperation
  114. */
  115. edit(editOperation) {
  116. throw new Error('edit not implemented for ' + JSON.stringify(this))
  117. }
  118. /**
  119. * @function
  120. * @param {ReadonlyBlobStore} blobStore
  121. * @return {Promise<FileData>}
  122. * @abstract
  123. * @see FileData#load
  124. */
  125. async toEager(blobStore) {
  126. throw new Error('toEager not implemented for ' + JSON.stringify(this))
  127. }
  128. /**
  129. * @function
  130. * @param {ReadonlyBlobStore} blobStore
  131. * @return {Promise<FileData>}
  132. * @abstract
  133. * @see FileData#load
  134. */
  135. async toLazy(blobStore) {
  136. throw new Error('toLazy not implemented for ' + JSON.stringify(this))
  137. }
  138. /**
  139. * @function
  140. * @param {ReadonlyBlobStore} blobStore
  141. * @return {Promise<FileData>}
  142. * @abstract
  143. * @see FileData#load
  144. */
  145. async toHollow(blobStore) {
  146. throw new Error('toHollow not implemented for ' + JSON.stringify(this))
  147. }
  148. /**
  149. * @see File#load
  150. * @param {string} kind
  151. * @param {ReadonlyBlobStore} blobStore
  152. * @return {Promise<FileData>}
  153. */
  154. async load(kind, blobStore) {
  155. if (kind === 'eager') return await this.toEager(blobStore)
  156. if (kind === 'lazy') return await this.toLazy(blobStore)
  157. if (kind === 'hollow') return await this.toHollow(blobStore)
  158. throw new Error('bad file data load kind: ' + kind)
  159. }
  160. /**
  161. * @see File#store
  162. * @function
  163. * @param {BlobStore} blobStore
  164. * @return {Promise<Object>} a raw HashFile
  165. * @abstract
  166. */
  167. async store(blobStore) {
  168. throw new Error('store not implemented for ' + JSON.stringify(this))
  169. }
  170. /**
  171. * @see File#getComments
  172. * @function
  173. * @return {CommentList}
  174. * @abstract
  175. */
  176. getComments() {
  177. throw new Error('getComments not implemented for ' + JSON.stringify(this))
  178. }
  179. }
  180. module.exports = FileData
  181. BinaryFileData = require('./binary_file_data')
  182. HashFileData = require('./hash_file_data')
  183. HollowBinaryFileData = require('./hollow_binary_file_data')
  184. HollowStringFileData = require('./hollow_string_file_data')
  185. LazyStringFileData = require('./lazy_string_file_data')
  186. StringFileData = require('./string_file_data')