<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>JSDoc: Source: BinaryObject.js</title>

    <script src="scripts/prettify/prettify.js"> </script>
    <script src="scripts/prettify/lang-css.js"> </script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>

<body>

<div id="main">

    <h1 class="page-title">Source: BinaryObject.js</h1>

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

const Util = require('util');
const ObjectType = require('./ObjectType').ObjectType;
const ComplexObjectType = require('./ObjectType').ComplexObjectType;
const Errors = require('./Errors');
const BinaryUtils = require('./internal/BinaryUtils');
const BinaryType = require('./internal/BinaryType');
const BinaryField = require('./internal/BinaryType').BinaryField;
const BinaryTypeBuilder = require('./internal/BinaryType').BinaryTypeBuilder;
const BinaryWriter = require('./internal/BinaryWriter');
const ArgumentChecker = require('./internal/ArgumentChecker');
const Logger = require('./internal/Logger');

const HEADER_LENGTH = 24;
const VERSION = 1;

// user type
const FLAG_USER_TYPE = 0x0001;
// schema exists
const FLAG_HAS_SCHEMA = 0x0002;
// object contains raw data
const FLAG_HAS_RAW_DATA = 0x0004;
// offsets take 1 byte
const FLAG_OFFSET_ONE_BYTE = 0x0008;
// offsets take 2 bytes
const FLAG_OFFSET_TWO_BYTES = 0x0010;
// compact footer, no field IDs
const FLAG_COMPACT_FOOTER = 0x0020;

/**
 * Class representing a complex Ignite object in the binary form.
 *
 * It corresponds to COMPOSITE_TYPE.COMPLEX_OBJECT {@link ObjectType.COMPOSITE_TYPE},
 * has mandatory type Id, which corresponds to a name of the complex type,
 * and includes optional fields.
 *
 * An instance of the BinaryObject can be obtained/created by the following ways:
 *   - returned by the client when a complex object is received from Ignite cache
 * and is not deserialized to another JavaScript object.
 *   - created using the public constructor. Fields may be added to such an instance using setField() method.
 *   - created from a JavaScript object using static fromObject() method.
 */
class BinaryObject {

    /**
     * Creates an instance of the BinaryObject without any fields.
     *
     * Fields may be added later using setField() method.
     *
     * @param {string} typeName - name of the complex type to generate the type Id.
     *
     * @return {BinaryObject} - new BinaryObject instance.
     *
     * @throws {IgniteClientError} if error.
     */
    constructor(typeName) {
        ArgumentChecker.notEmpty(typeName, 'typeName');
        this._buffer = null;
        this._fields = new Map();
        this._typeBuilder = BinaryTypeBuilder.fromTypeName(typeName);
        this._modified = false;
        this._schemaOffset = null;
        this._compactFooter = false;
    }

    /**
     * Creates an instance of the BinaryObject from the specified instance of JavaScript Object.
     *
     * All fields of the JavaScript Object instance with their values are added to the BinaryObject.
     * Fields may be added or removed later using setField() and removeField() methods.
     *
     * If complexObjectType parameter is specified, then the type Id is taken from it.
     * Otherwise, the type Id is generated from the name of the JavaScript Object.
     *
     * @async
     *
     * @param {object} jsObject - instance of JavaScript Object
     *   which adds and initializes the fields of the BinaryObject instance.
     * @param {ComplexObjectType} [complexObjectType] - instance of complex type definition
     *   which specifies non-standard mapping of the fields of the BinaryObject instance
     *   to/from the Ignite types.
     *
     * @return {BinaryObject} - new BinaryObject instance.
     *
     * @throws {IgniteClientError} if error.
     */
    static async fromObject(jsObject, complexObjectType = null) {
        ArgumentChecker.notEmpty(jsObject, 'jsObject');
        ArgumentChecker.hasType(complexObjectType, 'complexObjectType', false, ComplexObjectType);
        const typeBuilder = BinaryTypeBuilder.fromObject(jsObject, complexObjectType);
        const result = new BinaryObject(typeBuilder.getTypeName());
        result._typeBuilder = typeBuilder;
        let fieldName;
        for (let field of result._typeBuilder.getFields()) {
            fieldName = field.name;
            if (jsObject &amp;&amp; jsObject[fieldName] !== undefined) {
                result.setField(
                    fieldName,
                    jsObject[fieldName],
                    complexObjectType ? complexObjectType._getFieldType(fieldName) : null);
            }
            else {
                throw Errors.IgniteClientError.serializationError(
                    true, Util.format('field "%s" is undefined', fieldName));
            }
        }
        return result;
    }

    /**
     * Sets the new value of the specified field.
     * Adds the specified field, if it did not exist before.
     *
     * Optionally, specifies a type of the field.
     * If the type is not specified then during operations the Ignite client
     * will try to make automatic mapping between JavaScript types and Ignite object types -
     * according to the mapping table defined in the description of the {@link ObjectType} class.
     *
     * @param {string} fieldName - name of the field.
     * @param {*} fieldValue - new value of the field.
     * @param {ObjectType.PRIMITIVE_TYPE | CompositeType} [fieldType] - type of the field:
     *   - either a type code of primitive (simple) type
     *   - or an instance of class representing non-primitive (composite) type
     *   - or null (or not specified) that means the type is not specified.
     *
     * @return {BinaryObject} - the same instance of BinaryObject
     *
     * @throws {IgniteClientError} if error.
     */
    setField(fieldName, fieldValue, fieldType = null) {
        ArgumentChecker.notEmpty(fieldName, 'fieldName');
        this._modified = true;
        const field = new BinaryObjectField(fieldName, fieldValue, fieldType);
        this._fields.set(field.id, field);
        this._typeBuilder.setField(fieldName, field.typeCode);
        return this;
    }

    /**
     * Removes the specified field.
     * Does nothing if the field does not exist.
     *
     * @param {string} fieldName - name of the field.
     *
     * @return {BinaryObject} - the same instance of BinaryObject
     *
     * @throws {IgniteClientError} if error.
     */
    removeField(fieldName) {
        ArgumentChecker.notEmpty(fieldName, 'fieldName');
        this._modified = true;
        this._fields.delete(BinaryField._calculateId(fieldName));
        this._typeBuilder.removeField(fieldName);
        return this;
    }

    /**
     * Checks if the specified field exists in this BinaryObject instance.
     *
     * @param {string} fieldName - name of the field.
     *
     * @return {boolean} - true if exists, false otherwise.
     *
     * @throws {IgniteClientError} if error.
     */
    hasField(fieldName) {
        ArgumentChecker.notEmpty(fieldName, 'fieldName');
        return this._fields.has(BinaryField._calculateId(fieldName));
    }

    /**
     * Returns a value of the specified field.
     *
     * Optionally, specifies a type of the field.
     * If the type is not specified then the Ignite client
     * will try to make automatic mapping between JavaScript types and Ignite object types -
     * according to the mapping table defined in the description of the {@link ObjectType} class.
     *
     * @async
     *
     * @param {string} fieldName - name of the field.
     * @param {ObjectType.PRIMITIVE_TYPE | CompositeType} [fieldType] - type of the field:
     *   - either a type code of primitive (simple) type
     *   - or an instance of class representing non-primitive (composite) type
     *   - or null (or not specified) that means the type is not specified.
     *
     * @return {*} - value of the field or JavaScript undefined if the field does not exist.
     *
     * @throws {IgniteClientError} if error.
     */
    async getField(fieldName, fieldType = null) {
        ArgumentChecker.notEmpty(fieldName, 'fieldName');
        const field = this._fields.get(BinaryField._calculateId(fieldName));
        return field ? await field.getValue(fieldType) : undefined;
    }

    /**
     * Deserializes this BinaryObject instance into an instance of the specified complex object type.
     *
     * @async
     *
     * @param {ComplexObjectType} complexObjectType - instance of class representing complex object type.
     *
     * @return {object} - instance of the JavaScript object
     *   which corresponds to the specified complex object type.
     *
     * @throws {IgniteClientError} if error.
     */
    async toObject(complexObjectType) {
        ArgumentChecker.notNull(complexObjectType, 'complexObjectType');
        ArgumentChecker.hasType(complexObjectType, 'complexObjectType', false, ComplexObjectType);
        const result = new (complexObjectType._objectConstructor);
        let binaryField;
        let fieldName;
        for (let field of this._fields.values()) {
            binaryField = this._typeBuilder.getField(field.id);
            if (!binaryField) {
                throw Errors.IgniteClientError.serializationError(
                    false, Util.format('field with id "%s" can not be deserialized', field.id));
            }
            fieldName = binaryField.name;
            result[fieldName] = await field.getValue(complexObjectType._getFieldType(fieldName));
        }
        return result;
    }

    /**
     * Returns type name of this BinaryObject instance.
     *
     * @return {string} - type name.
     */
    getTypeName() {
        return this._typeBuilder.getTypeName();
    }

    /**
     * Returns names of all fields of this BinaryObject instance.
     *
     * @return {Array&lt;string>} - names of all fields.
     *
     * @throws {IgniteClientError} if error.
     */
    getFieldNames() {
        return this._typeBuilder._schema.fieldIds.map(fieldId => {
            const field = this._typeBuilder.getField(fieldId);
            if (field) {
                return field.name;
            }
            else {
                throw Errors.IgniteClientError.internalError(
                    Util.format('Field "%s" is absent in binary type fields', fieldId));
            }
        });
    }

    /** Private methods */

    /**
     * @ignore
     */
    static _isFlagSet(flags, flag) {
        return (flags &amp; flag) === flag;
    }

    /**
     * @ignore
     */
    static async _fromBuffer(buffer) {
        const result = new BinaryObject(new ComplexObjectType({})._typeName);
        result._buffer = buffer;
        result._startPos = buffer.position;
        await result._read();
        return result;
    }

    /**
     * @ignore
     */
    async _write(buffer) {
        if (this._buffer &amp;&amp; !this._modified) {
            buffer.writeBuffer(this._buffer.buffer, this._startPos, this._startPos + this._length);
        }
        else {
            await this._typeBuilder.finalize();
            this._startPos = buffer.position;
            buffer.position = this._startPos + HEADER_LENGTH;
            // write fields
            for (let field of this._fields.values()) {
                await field._writeValue(buffer, this._typeBuilder.getField(field.id).typeCode);
            }
            this._schemaOffset = buffer.position - this._startPos;
            // write schema
            for (let field of this._fields.values()) {
                field._writeOffset(buffer, this._startPos);
            }
            this._length = buffer.position - this._startPos;
            this._buffer = buffer;
            // write header
            this._writeHeader();
            this._buffer.position = this._startPos + this._length;
            this._modified = false;
        }

        if (Logger.debug) {
            Logger.logDebug('BinaryObject._write [' + [...this._buffer.getSlice(this._startPos, this._startPos + this._length)] + ']');
        }
    }

    /**
     * @ignore
     */
    _writeHeader() {
        this._buffer.position = this._startPos;
        // type code
        this._buffer.writeByte(BinaryUtils.TYPE_CODE.COMPLEX_OBJECT);
        // version
        this._buffer.writeByte(VERSION);
        // flags
        this._buffer.writeShort(FLAG_USER_TYPE | FLAG_HAS_SCHEMA | FLAG_COMPACT_FOOTER);
        // type id
        this._buffer.writeInteger(this._typeBuilder.getTypeId());
        // hash code
        this._buffer.writeInteger(BinaryUtils.contentHashCode(
            this._buffer, this._startPos + HEADER_LENGTH, this._schemaOffset - 1));
        // length
        this._buffer.writeInteger(this._length);
        // schema id
        this._buffer.writeInteger(this._typeBuilder.getSchemaId());
        // schema offset
        this._buffer.writeInteger(this._schemaOffset);
    }

    /**
     * @ignore
     */
    async _read() {
        await this._readHeader();
        this._buffer.position = this._startPos + this._schemaOffset;
        const fieldOffsets = new Array();
        const fieldIds = this._typeBuilder._schema.fieldIds;
        let index = 0;
        let fieldId;
        while (this._buffer.position &lt; this._startPos + this._length) {
            if (!this._compactFooter) {
                fieldId = this._buffer.readInteger();
                this._typeBuilder._schema.addField(fieldId);
            }
            else {
                if (index >= fieldIds.length) {
                    throw Errors.IgniteClientError.serializationError(
                        false, 'wrong number of fields in schema');
                }
                fieldId = fieldIds[index];
                index++;
            }
            fieldOffsets.push([fieldId, this._buffer.readNumber(this._offsetType)]);
        }
        fieldOffsets.sort((val1, val2) => val1[1] - val2[1]);
        let offset;
        let nextOffset;
        let field;
        for (let i = 0; i &lt; fieldOffsets.length; i++) {
            fieldId = fieldOffsets[i][0];
            offset = fieldOffsets[i][1];
            nextOffset = i + 1 &lt; fieldOffsets.length ? fieldOffsets[i + 1][1] : this._schemaOffset;
            field = BinaryObjectField._fromBuffer(
                this._buffer, this._startPos + offset, nextOffset - offset, fieldId);
            this._fields.set(field.id, field);
        }
        this._buffer.position = this._startPos + this._length;
    }

    /**
     * @ignore
     */
    async _readHeader() {
        // type code
        this._buffer.readByte();
        // version
        const version = this._buffer.readByte();
        if (version !== VERSION) {
            throw Errors.IgniteClientError.internalError();
        }
        // flags
        const flags = this._buffer.readShort();
        // type id
        const typeId = this._buffer.readInteger();
        // hash code
        this._buffer.readInteger();
        // length
        this._length = this._buffer.readInteger();
        // schema id
        const schemaId = this._buffer.readInteger();
        // schema offset
        this._schemaOffset = this._buffer.readInteger();
        const hasSchema = BinaryObject._isFlagSet(flags, FLAG_HAS_SCHEMA);
        this._compactFooter = BinaryObject._isFlagSet(flags, FLAG_COMPACT_FOOTER);
        this._offsetType = BinaryObject._isFlagSet(flags, FLAG_OFFSET_ONE_BYTE) ?
            BinaryUtils.TYPE_CODE.BYTE :
            BinaryObject._isFlagSet(flags, FLAG_OFFSET_TWO_BYTES) ?
                BinaryUtils.TYPE_CODE.SHORT :
                BinaryUtils.TYPE_CODE.INTEGER;

        if (BinaryObject._isFlagSet(FLAG_HAS_RAW_DATA)) {
            throw Errors.IgniteClientError.serializationError(
                false, 'complex objects with raw data are not supported');
        }
        if (this._compactFooter &amp;&amp; !hasSchema) {
            throw Errors.IgniteClientError.serializationError(
                false, 'schema is absent for object with compact footer');
        }
        this._typeBuilder = await BinaryTypeBuilder.fromTypeId(typeId, schemaId, hasSchema);
    }
}

/**
 * @ignore
 */
class BinaryObjectField {
    constructor(name, value = undefined, type = null) {
        this._name = name;
        this._id = BinaryField._calculateId(name);
        this._value = value;
        this._type = type;
        if (!type &amp;&amp; value !== undefined &amp;&amp; value !== null) {
            this._type = BinaryUtils.calcObjectType(value);
        }
        this._typeCode = null;
        if (this._type) {
            this._typeCode = BinaryUtils.getTypeCode(this._type);
        }
    }

    get id() {
        return this._id;
    }

    get typeCode() {
        return this._typeCode;
    }

    async getValue(type = null) {
        if (this._value === undefined || this._buffer &amp;&amp; this._type !== type) {
            this._buffer.position = this._offset;
            const BinaryReader = require('./internal/BinaryReader');
            this._value = await BinaryReader.readObject(this._buffer, type);
            this._type = type;
        }
        return this._value;
    }

    static _fromBuffer(buffer, offset, length, id) {
        const result = new BinaryObjectField(null);
        result._id = id;
        result._buffer = buffer;
        result._offset = offset;
        result._length = length;
        return result;
    }

    async _writeValue(buffer, expectedTypeCode) {
        const offset = buffer.position;
        if (this._buffer) {
            buffer.writeBuffer(this._buffer.buffer, this._offset, this._offset + this._length);
        }
        else {
            BinaryUtils.checkCompatibility(this._value, expectedTypeCode);
            await BinaryWriter.writeObject(buffer, this._value, this._type);
        }
        this._buffer = buffer;
        this._length = buffer.position - offset;
        this._offset = offset;
    }

    _writeOffset(buffer, headerStartPos) {
        buffer.writeInteger(this._offset - headerStartPos);
    }
}

module.exports = BinaryObject;
</code></pre>
        </article>
    </section>




</div>

<nav>
    <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="BinaryObject.html">BinaryObject</a></li><li><a href="CacheClient.html">CacheClient</a></li><li><a href="CacheConfiguration.html">CacheConfiguration</a></li><li><a href="CacheEntry.html">CacheEntry</a></li><li><a href="CacheKeyConfiguration.html">CacheKeyConfiguration</a></li><li><a href="CollectionObjectType.html">CollectionObjectType</a></li><li><a href="ComplexObjectType.html">ComplexObjectType</a></li><li><a href="CompositeType.html">CompositeType</a></li><li><a href="Cursor.html">Cursor</a></li><li><a href="EnumItem.html">EnumItem</a></li><li><a href="IgniteClient.html">IgniteClient</a></li><li><a href="IgniteClientConfiguration.html">IgniteClientConfiguration</a></li><li><a href="IgniteClientError.html">IgniteClientError</a></li><li><a href="IllegalStateError.html">IllegalStateError</a></li><li><a href="LostConnectionError.html">LostConnectionError</a></li><li><a href="MapObjectType.html">MapObjectType</a></li><li><a href="ObjectArrayType.html">ObjectArrayType</a></li><li><a href="ObjectType.html">ObjectType</a></li><li><a href="OperationError.html">OperationError</a></li><li><a href="Query.html">Query</a></li><li><a href="QueryEntity.html">QueryEntity</a></li><li><a href="QueryField.html">QueryField</a></li><li><a href="QueryIndex.html">QueryIndex</a></li><li><a href="ScanQuery.html">ScanQuery</a></li><li><a href="SqlFieldsCursor.html">SqlFieldsCursor</a></li><li><a href="SqlFieldsQuery.html">SqlFieldsQuery</a></li><li><a href="SqlQuery.html">SqlQuery</a></li><li><a href="Timestamp.html">Timestamp</a></li></ul>
</nav>

<br class="clear">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Tue May 22 2018 12:08:48 GMT+0300 (Russia TZ 2 Standard Time)
</footer>

<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>
