@sap/odata-v4
Version:
OData V4.0 server library
166 lines (143 loc) • 4.51 kB
JavaScript
'use strict';
/**
* Creates a FIFO cache using a buffer as input. This cache offers functions for consuming bytes from the cache.
* Used while deserialization of streamed multipart requests.
* The buffer object used to store the cached bytes is not constant and will change (e.g. while appending bytes
* to the cache)
*/
// TODO add getter for getReadPos, SerachPos and length
class Cache {
/**
* Creates a cache from a given buffer
*
* @param {Buffer} buffer - Buffer containing the initial content
*/
constructor(buffer) {
this._cache = buffer;
/**
* The read position
* @type {number}
* @private
*/
this._readPos = 0;
/**
* The search position. The search position may be used to improve performance with not searching
* already searched data again after more data has been received.
* @type {number}
* @private
*/
this._searchPosition = 0;
/**
* Amount of byte inside the cache. Used to avoid a get length getter.
* The length must be updated if the cache content changes.
* @type {number}
*/
this._length = this._cache.length;
/**
* Consumed bytes
* @type {number}
*/
this._consumedBytes = 0;
}
/**
* The read position
* @returns {number} - Read position
*/
getReadPos() {
return this._readPos;
}
/**
* Amount of byte inside the cache. Used to avoid a get length getter.
* The length must be updated if the cache content changes.
* @returns {number}
*/
getLength() {
return this._length;
}
/**
* The search position. The search position may be used to improve performance with not searching
* already searched data again after more data has been received.
* @returns {number} - Search position
*/
getSearchPosition() {
return this._searchPosition;
}
/**
* Appends data to the cache
*
* @param {Buffer} buffer - Data to be appended
*/
append(buffer) {
this._cache = Buffer.concat([this._cache, buffer], this._cache.length + buffer.length);
this._length = this._cache.length;
}
/**
* Removes the consumed bytes from the cache
*/
shrink() {
if (this._consumedBytes) {
this._cache = this._cache.slice(this._consumedBytes);
this._readPos -= this._consumedBytes;
this._searchPosition -= this._consumedBytes;
this._consumedBytes = 0;
this._length = this._cache.length;
}
}
/**
* Consumes bytes from the cache.
*
* @param {number} consumed - Bytes to consume
*/
advance(consumed) {
this._consumedBytes += consumed;
this._readPos = this._readPos + consumed;
this._searchPosition = this._readPos;
}
/**
* Updates the search position. The search position may be used to improve performance with not searching
* already searched data again after more data has been received.
*
* @param {number} consumed
*/
advanceSearchPosition(consumed) {
this._searchPosition += consumed;
}
/**
* Returns a byte at the read position + offset
*
* @param {number} [offset=0] - Offset
* @returns {Buffer}
*/
getByte(offset = 0) {
return this._cache[this._readPos + offset];
}
/**
* Returns count bytes from the current read position onwards
*
* @param {number} count - Bytes to return
* @returns {Buffer} Bytes
*/
getBytes(count) {
return this._cache.slice(this._readPos, this._readPos + count);
}
/**
* Returns the bytes between the read position an the upTo position
*
* @param {number} upTo - End position
* @returns {Buffer} Bytes, excluding the byte at the upTo position
*/
getBytesTo(upTo) {
return this._cache.slice(this._readPos, upTo);
}
/**
* Returns the index of the first occurrence of search. See buffer.index of for more details.
*
* @param {Buffer} search - Bytes to be searched
* @param {number} from - Start position for searching
* @returns {number} the index of the first occurrence of search
*/
indexOf(search, from) {
return this._cache.indexOf(search, from);
}
}
module.exports = Cache;