overleaf/libraries/overleaf-editor-core/lib/blob.js
Alf Eaton ee85d948e2 Avoid duplicating a math-closing dollar sign (#11227)
GitOrigin-RevId: ef2ef77e26df59d1af3df6dc664e284d3c70102d
2023-01-16 08:41:42 +00:00

100 lines
2.7 KiB
JavaScript

'use strict'
const assert = require('check-types').assert
const OError = require('@overleaf/o-error')
const TextOperation = require('./operation/text_operation')
/**
* @constructor
* @classdesc
* Metadata record for the content of a file.
*/
function Blob(hash, byteLength, stringLength) {
this.setHash(hash)
this.setByteLength(byteLength)
this.setStringLength(stringLength)
}
class NotFoundError extends OError {
constructor(hash) {
super(`blob ${hash} not found`, { hash })
this.hash = hash
}
}
Blob.NotFoundError = NotFoundError
Blob.HEX_HASH_RX_STRING = '^[0-9a-f]{40,40}$'
Blob.HEX_HASH_RX = new RegExp(Blob.HEX_HASH_RX_STRING)
module.exports = Blob
Blob.fromRaw = function blobFromRaw(raw) {
if (raw) {
return new Blob(raw.hash, raw.byteLength, raw.stringLength)
}
return null
}
Blob.prototype.toRaw = function blobToRaw() {
return {
hash: this.hash,
byteLength: this.byteLength,
stringLength: this.stringLength,
}
}
/**
* Hex hash.
* @return {?String}
*/
Blob.prototype.getHash = function () {
return this.hash
}
Blob.prototype.setHash = function (hash) {
assert.maybe.match(hash, Blob.HEX_HASH_RX, 'bad hash')
this.hash = hash
}
/**
* Length of the blob in bytes.
* @return {number}
*/
Blob.prototype.getByteLength = function () {
return this.byteLength
}
Blob.prototype.setByteLength = function (byteLength) {
assert.maybe.integer(byteLength, 'bad byteLength')
this.byteLength = byteLength
}
/**
* Utf-8 length of the blob content, if it appears to be valid UTF-8.
* @return {?number}
*/
Blob.prototype.getStringLength = function () {
return this.stringLength
}
Blob.prototype.setStringLength = function (stringLength) {
assert.maybe.integer(stringLength, 'bad stringLength')
this.stringLength = stringLength
}
/**
* Size of the largest file that we'll read to determine whether we can edit it
* or not, in bytes. The final decision on whether a file is editable or not is
* based on the number of characters it contains, but we need to read the file
* in to determine that; so it is useful to have an upper bound on the byte
* length of a file that might be editable.
*
* The reason for the factor of 3 is as follows. We cannot currently edit files
* that contain characters outside of the basic multilingual plane, so we're
* limited to characters that can be represented in a single, two-byte UCS-2
* code unit. Encoding the largest such value, 0xFFFF (which is not actually
* a valid character), takes three bytes in UTF-8: 0xEF 0xBF 0xBF. A file
* composed entirely of three-byte UTF-8 codepoints is the worst case; in
* practice, this is a very conservative upper bound.
*
* @type {number}
*/
Blob.MAX_EDITABLE_BYTE_LENGTH_BOUND = 3 * TextOperation.MAX_STRING_LENGTH