index.js 4.7 KB

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