123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- goog.module('protobuf.runtime.BinaryStorage');
- const Storage = goog.require('protobuf.runtime.Storage');
- const {checkDefAndNotNull} = goog.require('protobuf.internal.checks');
- /**
- * Class storing all the fields of a binary protobuf message.
- *
- * @package
- * @template FieldType
- * @implements {Storage}
- */
- class BinaryStorage {
- /**
- * @param {number=} pivot
- */
- constructor(pivot = Storage.DEFAULT_PIVOT) {
- /**
- * Fields having a field number no greater than the pivot value are stored
- * into an array for fast access. A field with field number X is stored into
- * the array position X - 1.
- *
- * @private @const {!Array<!FieldType|undefined>}
- */
- this.array_ = new Array(pivot);
- /**
- * Fields having a field number higher than the pivot value are stored into
- * the map. We create the map only when it's needed, since even an empty map
- * takes up a significant amount of memory.
- *
- * @private {?Map<number, !FieldType>}
- */
- this.map_ = null;
- }
- /**
- * Fields having a field number no greater than the pivot value are stored
- * into an array for fast access. A field with field number X is stored into
- * the array position X - 1.
- * @return {number}
- * @override
- */
- getPivot() {
- return this.array_.length;
- }
- /**
- * Sets a field in the specified field number.
- *
- * @param {number} fieldNumber
- * @param {!FieldType} field
- * @override
- */
- set(fieldNumber, field) {
- if (fieldNumber <= this.getPivot()) {
- this.array_[fieldNumber - 1] = field;
- } else {
- if (this.map_) {
- this.map_.set(fieldNumber, field);
- } else {
- this.map_ = new Map([[fieldNumber, field]]);
- }
- }
- }
- /**
- * Returns a field at the specified field number.
- *
- * @param {number} fieldNumber
- * @return {!FieldType|undefined}
- * @override
- */
- get(fieldNumber) {
- if (fieldNumber <= this.getPivot()) {
- return this.array_[fieldNumber - 1];
- } else {
- return this.map_ ? this.map_.get(fieldNumber) : undefined;
- }
- }
- /**
- * Deletes a field from the specified field number.
- *
- * @param {number} fieldNumber
- * @override
- */
- delete(fieldNumber) {
- if (fieldNumber <= this.getPivot()) {
- delete this.array_[fieldNumber - 1];
- } else {
- if (this.map_) {
- this.map_.delete(fieldNumber);
- }
- }
- }
- /**
- * Executes the provided function once for each field.
- *
- * @param {function(!FieldType, number): void} callback
- * @override
- */
- forEach(callback) {
- this.array_.forEach((field, fieldNumber) => {
- if (field) {
- callback(checkDefAndNotNull(field), fieldNumber + 1);
- }
- });
- if (this.map_) {
- this.map_.forEach(callback);
- }
- }
- /**
- * Creates a shallow copy of the storage.
- *
- * @return {!BinaryStorage}
- * @override
- */
- shallowCopy() {
- const copy = new BinaryStorage(this.getPivot());
- this.forEach(
- (field, fieldNumber) =>
- void copy.set(fieldNumber, field.shallowCopy()));
- return copy;
- }
- }
- exports = BinaryStorage;
|