diff options
author | 2020-11-16 00:10:28 +0100 | |
---|---|---|
committer | 2020-11-16 00:10:28 +0100 | |
commit | e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d (patch) | |
tree | 55713f725f77b44ebfec86e4eec3ce33e71458ca /node_modules/mongodb/lib/gridfs/chunk.js | |
download | website_creator-e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d.tar.gz website_creator-e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d.tar.bz2 website_creator-e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d.zip |
api, login, auth
Diffstat (limited to 'node_modules/mongodb/lib/gridfs/chunk.js')
-rw-r--r-- | node_modules/mongodb/lib/gridfs/chunk.js | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/node_modules/mongodb/lib/gridfs/chunk.js b/node_modules/mongodb/lib/gridfs/chunk.js new file mode 100644 index 0000000..d276d72 --- /dev/null +++ b/node_modules/mongodb/lib/gridfs/chunk.js @@ -0,0 +1,236 @@ +'use strict'; + +var Binary = require('../core').BSON.Binary, + ObjectID = require('../core').BSON.ObjectID; + +var Buffer = require('safe-buffer').Buffer; + +/** + * Class for representing a single chunk in GridFS. + * + * @class + * + * @param file {GridStore} The {@link GridStore} object holding this chunk. + * @param mongoObject {object} The mongo object representation of this chunk. + * + * @throws Error when the type of data field for {@link mongoObject} is not + * supported. Currently supported types for data field are instances of + * {@link String}, {@link Array}, {@link Binary} and {@link Binary} + * from the bson module + * + * @see Chunk#buildMongoObject + */ +var Chunk = function(file, mongoObject, writeConcern) { + if (!(this instanceof Chunk)) return new Chunk(file, mongoObject); + + this.file = file; + var mongoObjectFinal = mongoObject == null ? {} : mongoObject; + this.writeConcern = writeConcern || { w: 1 }; + this.objectId = mongoObjectFinal._id == null ? new ObjectID() : mongoObjectFinal._id; + this.chunkNumber = mongoObjectFinal.n == null ? 0 : mongoObjectFinal.n; + this.data = new Binary(); + + if (typeof mongoObjectFinal.data === 'string') { + var buffer = Buffer.alloc(mongoObjectFinal.data.length); + buffer.write(mongoObjectFinal.data, 0, mongoObjectFinal.data.length, 'binary'); + this.data = new Binary(buffer); + } else if (Array.isArray(mongoObjectFinal.data)) { + buffer = Buffer.alloc(mongoObjectFinal.data.length); + var data = mongoObjectFinal.data.join(''); + buffer.write(data, 0, data.length, 'binary'); + this.data = new Binary(buffer); + } else if (mongoObjectFinal.data && mongoObjectFinal.data._bsontype === 'Binary') { + this.data = mongoObjectFinal.data; + } else if (!Buffer.isBuffer(mongoObjectFinal.data) && !(mongoObjectFinal.data == null)) { + throw Error('Illegal chunk format'); + } + + // Update position + this.internalPosition = 0; +}; + +/** + * Writes a data to this object and advance the read/write head. + * + * @param data {string} the data to write + * @param callback {function(*, GridStore)} This will be called after executing + * this method. The first parameter will contain null and the second one + * will contain a reference to this object. + */ +Chunk.prototype.write = function(data, callback) { + this.data.write(data, this.internalPosition, data.length, 'binary'); + this.internalPosition = this.data.length(); + if (callback != null) return callback(null, this); + return this; +}; + +/** + * Reads data and advances the read/write head. + * + * @param length {number} The length of data to read. + * + * @return {string} The data read if the given length will not exceed the end of + * the chunk. Returns an empty String otherwise. + */ +Chunk.prototype.read = function(length) { + // Default to full read if no index defined + length = length == null || length === 0 ? this.length() : length; + + if (this.length() - this.internalPosition + 1 >= length) { + var data = this.data.read(this.internalPosition, length); + this.internalPosition = this.internalPosition + length; + return data; + } else { + return ''; + } +}; + +Chunk.prototype.readSlice = function(length) { + if (this.length() - this.internalPosition >= length) { + var data = null; + if (this.data.buffer != null) { + //Pure BSON + data = this.data.buffer.slice(this.internalPosition, this.internalPosition + length); + } else { + //Native BSON + data = Buffer.alloc(length); + length = this.data.readInto(data, this.internalPosition); + } + this.internalPosition = this.internalPosition + length; + return data; + } else { + return null; + } +}; + +/** + * Checks if the read/write head is at the end. + * + * @return {boolean} Whether the read/write head has reached the end of this + * chunk. + */ +Chunk.prototype.eof = function() { + return this.internalPosition === this.length() ? true : false; +}; + +/** + * Reads one character from the data of this chunk and advances the read/write + * head. + * + * @return {string} a single character data read if the the read/write head is + * not at the end of the chunk. Returns an empty String otherwise. + */ +Chunk.prototype.getc = function() { + return this.read(1); +}; + +/** + * Clears the contents of the data in this chunk and resets the read/write head + * to the initial position. + */ +Chunk.prototype.rewind = function() { + this.internalPosition = 0; + this.data = new Binary(); +}; + +/** + * Saves this chunk to the database. Also overwrites existing entries having the + * same id as this chunk. + * + * @param callback {function(*, GridStore)} This will be called after executing + * this method. The first parameter will contain null and the second one + * will contain a reference to this object. + */ +Chunk.prototype.save = function(options, callback) { + var self = this; + if (typeof options === 'function') { + callback = options; + options = {}; + } + + self.file.chunkCollection(function(err, collection) { + if (err) return callback(err); + + // Merge the options + var writeOptions = { upsert: true }; + for (var name in options) writeOptions[name] = options[name]; + for (name in self.writeConcern) writeOptions[name] = self.writeConcern[name]; + + if (self.data.length() > 0) { + self.buildMongoObject(function(mongoObject) { + var options = { forceServerObjectId: true }; + for (var name in self.writeConcern) { + options[name] = self.writeConcern[name]; + } + + collection.replaceOne({ _id: self.objectId }, mongoObject, writeOptions, function(err) { + callback(err, self); + }); + }); + } else { + callback(null, self); + } + // }); + }); +}; + +/** + * Creates a mongoDB object representation of this chunk. + * + * @param callback {function(Object)} This will be called after executing this + * method. The object will be passed to the first parameter and will have + * the structure: + * + * <pre><code> + * { + * '_id' : , // {number} id for this chunk + * 'files_id' : , // {number} foreign key to the file collection + * 'n' : , // {number} chunk number + * 'data' : , // {bson#Binary} the chunk data itself + * } + * </code></pre> + * + * @see <a href="http://www.mongodb.org/display/DOCS/GridFS+Specification#GridFSSpecification-{{chunks}}">MongoDB GridFS Chunk Object Structure</a> + */ +Chunk.prototype.buildMongoObject = function(callback) { + var mongoObject = { + files_id: this.file.fileId, + n: this.chunkNumber, + data: this.data + }; + // If we are saving using a specific ObjectId + if (this.objectId != null) mongoObject._id = this.objectId; + + callback(mongoObject); +}; + +/** + * @return {number} the length of the data + */ +Chunk.prototype.length = function() { + return this.data.length(); +}; + +/** + * The position of the read/write head + * @name position + * @lends Chunk# + * @field + */ +Object.defineProperty(Chunk.prototype, 'position', { + enumerable: true, + get: function() { + return this.internalPosition; + }, + set: function(value) { + this.internalPosition = value; + } +}); + +/** + * The default chunk size + * @constant + */ +Chunk.DEFAULT_CHUNK_SIZE = 1024 * 255; + +module.exports = Chunk; |