/*
* node-qtdatastream
* https://github.com/magne4000/node-qtdatastream
*
* Copyright (c) 2017 Joël Charles
* Licensed under the MIT license.
*/
/** @module qtdatastream/types */
const { Int64BE, Uint64BE } = require('int64-buffer');
const { dateToJulianDay, julianDayToDate, str: bstr } = require('./util');
/**
* Abstract class that all Qt types must implement.
* Subclasses are used to dictate how a value is represented
* as a Buffer, and vice-versa.
* @abstract
* @static
* @param {*} obj underlying data that will be used by toBuffer() method
*/
class QClass {
constructor(obj) {
this.__obj = obj;
}
/**
* @function from
* @memberof module:qtdatastream/types.QClass
* @abstract
* @static
* @param {*} subject
* @param {boolean} [force=false]
* @returns {QClass}
*/
static from(subject, force = false) {
if (subject instanceof this && !force) {
return subject;
}
subject = prepare(subject);
if (subject instanceof this) {
return subject;
}
return new this(subject);
}
}
/**
* Decorator that affect QDatastream ID to classes.
* Used for serialization and deserialization.
* @example
* // ES7
* \@qtype(Types.QUInt)
* class QUInt extends QClass {}
* // ES6
* class QUInt extends QClass {}
* qtype(Types.QUInt)(QUInt);
*/
function qtype(qvarianttype) {
return function(target) {
if (!QClass.types) {
QClass.types = new Map;
}
if (qvarianttype !== undefined) {
QClass.types.set(qvarianttype, target);
}
target.qtype = qvarianttype;
};
}
/**
* Qt types contants
* @readonly
* @static
* @enum {number}
* @name Types
* @see {@link http://doc.qt.io/qt-4.8/qvariant.html#Type-enum|enum QVariant::Type}
* @see {@link http://doc.qt.io/qt-4.8/datastreamformat.html|Serializing Qt Data Types}
*/
const Types = {
INVALID: 0,
BOOL: 1,
INT: 2,
UINT: 3,
INT64: 4,
UINT64: 5,
DOUBLE: 6,
CHAR: 7,
MAP: 8,
LIST: 9,
STRING: 10,
STRINGLIST: 11,
BYTEARRAY: 12,
TIME: 15,
DATETIME: 16,
USERTYPE: 127,
SHORT: 133
};
function prepare(obj) {
return (obj !== undefined && obj !== null && typeof obj.export === 'function') ? obj.export() : obj;
}
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QInvalid extends QClass {
/**
* @function read
* @memberof module:qtdatastream/types.QInvalid
* @static
* @param {?Buffer} buffer
* @returns {undefined} Always return `undefined`
*/
static read(_buffer) {
return undefined;
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QInvalid
* @inner
* @returns {Buffer} Empty Buffer
*/
toBuffer() {
return Buffer.alloc(0);
}
/**
* Wraps subject into `QInvalid` object
* @function from
* @memberof module:qtdatastream/types.QInvalid
* @static
* @param {*} subject
* @returns {QInvalid}
*/
}
qtype(Types.INVALID)(QInvalid);
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QBool extends QClass {
/**
* @function read
* @memberof module:qtdatastream/types.QBool
* @static
* @param {Buffer} buffer
* @returns {boolean} Buffer coerced to boolean
*/
static read(buffer) {
return Boolean(buffer.readInt8());
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QBool
* @inner
* @returns {Buffer}
*/
toBuffer() {
const buf = Buffer.alloc(1);
buf.writeInt8(this.__obj, 0);
return buf;
}
/**
* Wraps subject into `QBool` object
* @function from
* @memberof module:qtdatastream/types.QBool
* @static
* @param {*} subject
* @returns {QBool}
*/
}
qtype(Types.BOOL)(QBool);
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QShort extends QClass {
/**
* @function read
* @memberof module:qtdatastream/types.QShort
* @static
* @param {Buffer} buffer
* @returns {number} Buffer coerced to number
*/
static read(buffer) {
return buffer.readInt16BE();
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QShort
* @inner
* @returns {Buffer}
*/
toBuffer() {
const buf = Buffer.alloc(2);
buf.writeUInt16BE(this.__obj, 0, true);
return buf;
}
/**
* Wraps subject into `QShort` object
* @function from
* @memberof module:qtdatastream/types.QShort
* @static
* @param {*} subject
* @returns {QShort}
*/
}
qtype(Types.SHORT)(QShort);
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QInt extends QClass {
/**
* @function read
* @memberof module:qtdatastream/types.QInt
* @static
* @param {Buffer} buffer
* @returns {number} Buffer coerced to number
*/
static read(buffer) {
return buffer.readInt32BE();
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QInt
* @inner
* @returns {Buffer}
*/
toBuffer() {
const buf = Buffer.alloc(4);
buf.writeInt32BE(this.__obj, 0, true);
return buf;
}
/**
* Wraps subject into `QInt` object
* @function from
* @memberof module:qtdatastream/types.QInt
* @static
* @param {*} subject
* @returns {QInt}
*/
}
qtype(Types.INT)(QInt);
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QUInt extends QClass {
/**
* @function read
* @memberof module:qtdatastream/types.QUInt
* @static
* @param {Buffer} buffer
* @returns {number} Buffer coerced to number
*/
static read(buffer) {
return buffer.readUInt32BE();
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QUInt
* @inner
* @returns {Buffer}
*/
toBuffer() {
const buf = Buffer.alloc(4);
buf.writeUInt32BE(this.__obj, 0, true);
return buf;
}
/**
* Wraps subject into `QUInt` object
* @function from
* @memberof module:qtdatastream/types.QUInt
* @static
* @param {*} subject
* @returns {QUInt}
*/
}
qtype(Types.UINT)(QUInt);
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QInt64 extends QClass {
/**
* @function read
* @memberof module:qtdatastream/types.QInt64
* @static
* @param {Buffer} buffer
* @returns {number} Buffer coerced to number
*/
static read(buffer) {
return buffer.readInt64BE();
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QInt64
* @inner
* @returns {Buffer}
*/
toBuffer() {
return (new Int64BE(this.__obj)).toBuffer();
}
/**
* Wraps subject into `QInt64` object
* @function from
* @memberof module:qtdatastream/types.QInt64
* @static
* @param {*} subject
* @returns {QInt64}
*/
}
qtype(Types.INT64)(QInt64);
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QUInt64 extends QClass {
/**
* @function read
* @memberof module:qtdatastream/types.QUInt64
* @static
* @param {Buffer} buffer
* @returns {number} Buffer coerced to number
*/
static read(buffer) {
return buffer.readUInt64BE();
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QUInt64
* @inner
* @returns {Buffer}
*/
toBuffer() {
return (new Uint64BE(this.__obj)).toBuffer();
}
/**
* Wraps subject into `QUInt64` object
* @function from
* @memberof module:qtdatastream/types.QUInt64
* @static
* @param {*} subject
* @returns {QUInt64}
*/
}
qtype(Types.UINT64)(QUInt64);
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QDouble extends QClass {
/**
* @function read
* @memberof module:qtdatastream/types.QDouble
* @static
* @param {Buffer} buffer
* @returns {number} Buffer coerced to number
*/
static read(buffer) {
return buffer.readDoubleBE();
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QDouble
* @inner
* @returns {Buffer}
*/
toBuffer() {
const buf = Buffer.alloc(8);
buf.writeDoubleBE(this.__obj, 0, true);
return buf;
}
/**
* Wraps subject into `QDouble` object
* @function from
* @memberof module:qtdatastream/types.QDouble
* @static
* @param {*} subject
* @returns {QDouble}
*/
}
qtype(Types.DOUBLE)(QDouble);
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QChar extends QClass {
constructor(obj){
super(obj);
if (typeof this.__obj !== 'string') throw new Error(`${this.__obj} is not a string`);
if (this.__obj.length !== 1) throw new Error(`${this.__obj} length must equal 1`);
}
/**
* @function read
* @memberof module:qtdatastream/types.QChar
* @static
* @param {Buffer} buffer
* @returns {string} Buffer coerced to string
*/
static read(buffer) {
const stringBuffer = buffer.slice(2);
return stringBuffer.swap16().toString('ucs2');
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QChar
* @inner
* @returns {Buffer}
*/
toBuffer() {
return Buffer.from(this.__obj, 'ucs2').swap16();
}
/**
* Wraps subject into `QChar` object
* @function from
* @memberof module:qtdatastream/types.QChar
* @static
* @param {*} subject
* @returns {QChar}
*/
}
qtype(Types.CHAR)(QChar);
/**
* @extends module:qtdatastream/types.QUInt
* @static
* @param {*} obj
* @see {@link module:qtdatastream/types.QUInt}
*/
class QTime extends QUInt {}
qtype(Types.TIME)(QTime);
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QByteArray extends QClass {
/**
* Use {@link module:qtdatastream/util.str} to convert the returned Buffer
* to a string.
* @function read
* @memberof module:qtdatastream/types.QByteArray
* @static
* @param {Buffer} buffer
* @returns {Buffer}
*/
static read(buffer) {
const arraySize = QUInt.read(buffer);
if (arraySize === 0 || arraySize === 0xffffffff) return null;
return buffer.slice(arraySize);
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QByteArray
* @inner
* @returns {Buffer}
*/
toBuffer() {
if (this.__obj === null) {
return QUInt.from(0xffffffff).toBuffer();
}
const buf = Buffer.from(this.__obj);
const buflength = QUInt.from(buf.length).toBuffer();
return Buffer.concat([ buflength, buf ]);
}
/**
* Wraps subject into `QByteArray` object
* @function from
* @memberof module:qtdatastream/types.QByteArray
* @static
* @param {*} subject
* @returns {QByteArray}
*/
}
qtype(Types.BYTEARRAY)(QByteArray);
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QString extends QClass {
/**
* @function read
* @memberof module:qtdatastream/types.QString
* @static
* @param {Buffer} buffer
* @returns {string} Buffer coerced to string
*/
static read(buffer) {
const stringSize = QUInt.read(buffer);
if (stringSize === 0 || stringSize === 0xffffffff) return '';
const stringBuffer = buffer.slice(stringSize);
return stringBuffer.swap16().toString('ucs2');
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QString
* @inner
* @returns {Buffer}
*/
toBuffer() {
if (this.__obj === null) {
return QUInt.from(0xffffffff).toBuffer();
}
let bufstring;
if (typeof this.__obj === 'number') {
bufstring = Buffer.from(String(this.__obj), 'ucs2');
} else {
bufstring = Buffer.from(this.__obj, 'ucs2');
}
bufstring.swap16();
const buflength = QUInt.from(bufstring.length).toBuffer();
return Buffer.concat([ buflength, bufstring ]);
}
/**
* Wraps subject into `QString` object
* @function from
* @memberof module:qtdatastream/types.QString
* @static
* @param {*} subject
* @returns {QString}
*/
}
qtype(Types.STRING)(QString);
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QList extends QClass {
/**
* @function read
* @memberof module:qtdatastream/types.QList
* @static
* @param {Buffer} buffer
* @returns {Array} Buffer coerced to an array
*/
static read(buffer) {
const listSize = QUInt.read(buffer), l = Array(listSize);
for (let i=0; i<listSize; i++) {
l[i] = QVariant.read(buffer);
}
return l;
}
/**
* @function of
* @memberof module:qtdatastream/types.QList
* @static
* @param {(string|module:qtdatastream/types.QClass)} qclass
* @example
* // TODO
* // CustomClass must implement Exportable
* QList.of(CustomClass)
* QList.of('myUserType')
*/
static ['of'](qclass) {
if (typeof qclass === 'string') {
qclass = QUserType.get(qclass);
}
const parent = this;
return class extends parent {
static from(subject) {
if (Array.isArray(subject)) {
subject = subject.map(elt => {
return prepare(qclass.from(elt));
});
}
return parent.from(subject);
}
};
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QList
* @inner
* @returns {Buffer}
*/
toBuffer() {
const bufs = [];
// nb of elements in the list
bufs.push(QUInt.from(this.__obj.length).toBuffer());
for (let el of this.__obj) {
// Values are QVariant
bufs.push(QVariant.from(el).toBuffer());
}
return Buffer.concat(bufs);
}
/**
* Wraps subject into `QList` object
* @function from
* @memberof module:qtdatastream/types.QList
* @static
* @param {*} subject
* @returns {QList}
*/
}
qtype(Types.LIST)(QList);
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QStringList extends QClass {
/**
* @function read
* @memberof module:qtdatastream/types.QStringList
* @static
* @param {Buffer} buffer
* @returns {Array.<string>} Buffer coerced to an array of strings
*/
static read(buffer) {
const listSize = QUInt.read(buffer), l = Array(listSize);
for (let i=0; i<listSize; i++) {
l[i] = QString.read(buffer);
}
return l;
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QStringList
* @inner
* @returns {Buffer}
*/
toBuffer() {
const bufs = [];
// nb of elements in the list
bufs.push(QUInt.from(this.__obj.length).toBuffer());
for (let el of this.__obj) {
// Values are QString
bufs.push(QString.from(el).toBuffer());
}
return Buffer.concat(bufs);
}
/**
* Wraps subject into `QStringList` object
* @function from
* @memberof module:qtdatastream/types.QStringList
* @static
* @param {*} subject
* @returns {QStringList}
*/
}
qtype(Types.STRINGLIST)(QStringList);
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QDateTime extends QClass {
/**
* @function read
* @memberof module:qtdatastream/types.QDateTime
* @static
* @param {Buffer} buffer
* @returns {Date} Buffer coerced to a Date
*/
static read(buffer) {
const julianDay = QUInt.read(buffer);
const msecondsSinceMidnight = QUInt.read(buffer);
const _isUTC = QBool.read(buffer);
const dateAtMidnight = julianDayToDate(julianDay);
dateAtMidnight.setMilliseconds(msecondsSinceMidnight);
return dateAtMidnight;
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QDateTime
* @inner
* @returns {Buffer}
*/
toBuffer() {
const bufs = [];
const milliseconds = (this.__obj.getTime() - (this.__obj.getTimezoneOffset() * 60000)) % 86400000;
const julianday = dateToJulianDay(this.__obj);
bufs.push(QUInt.from(julianday).toBuffer());
bufs.push(QUInt.from(milliseconds).toBuffer());
bufs.push(QBool.from(this.__obj.getTimezoneOffset() === 0).toBuffer());
return Buffer.concat(bufs);
}
/**
* Wraps subject into `QDateTime` object
* @function from
* @memberof module:qtdatastream/types.QDateTime
* @static
* @param {*} subject
* @returns {QDateTime}
*/
}
qtype(Types.DATETIME)(QDateTime);
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QMap extends QClass {
/**
* @function read
* @memberof module:qtdatastream/types.QMap
* @static
* @param {Buffer} buffer
* @returns {Object} Buffer coerced to an Object
*/
static read(buffer) {
const mapSize = QUInt.read(buffer);
let map = {}, key, value;
for (let i=0; i<mapSize; i++) {
key = QString.read(buffer);
value = QVariant.read(buffer);
map[key] = value;
}
return map;
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QMap
* @inner
* @returns {Buffer}
*/
toBuffer() {
const bufs = [];
// keys are all QString
// values are all QVariant
if (this.__obj instanceof Map) {
// Map number of elements
bufs.push(QUInt.from(this.__obj.size).toBuffer());
for (let [ key, value ] of this.__obj) {
// write key
bufs.push(QString.from(key).toBuffer());
// write value
bufs.push(QVariant.from(value).toBuffer());
}
} else {
const keys = Object.keys(this.__obj);
// Map number of elements
bufs.push(QUInt.from(keys.length).toBuffer());
for (let key of keys) {
// write key
bufs.push(QString.from(key).toBuffer());
// write value
bufs.push(QVariant.from(this.__obj[key]).toBuffer());
}
}
return Buffer.concat(bufs);
}
/**
* Wraps subject into `QMap` object
* @function from
* @memberof module:qtdatastream/types.QMap
* @static
* @param {*} subject
* @returns {QMap}
*/
}
qtype(Types.MAP)(QMap);
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QUserType extends QClass {
constructor(name, obj) {
super(obj);
this.name = name;
}
static from(subject) {
if (subject instanceof QUserType) {
return subject;
}
return new this(subject);
}
/**
* @function createComplexUserType
* @memberof module:qtdatastream/types.QUserType
* @static
* @protected
* @param {String} name
* @param {*} value
* @returns {QUserType} a new class that extends QUserType
*/
static createComplexUserType(name, value) {
const compiled = [];
let key, keys, type;
for (type of value) {
[ key ] = Object.keys(type);
keys = { key };
if (typeof type[key] === 'string') {
// It's a QUserType
keys.quserclassname = type[key];
keys.quserclass = QUserType.usertypes.get(type[key]);
} else {
keys.quserclass = QClass.types.get(type[key]);
}
if (!keys.quserclass) {
throw new Error(`Type ${type[key]} does not exists`);
}
compiled.push(keys);
}
return class extends QUserType {
constructor(obj) {
super(name, obj);
}
static read(buffer) {
const obj = {};
for (let elt of compiled) {
Object.defineProperty(obj, elt.key, {
enumerable: true,
configurable: true,
writable: true,
value: elt.quserclass.read(buffer, keys.quserclassname)
});
}
return obj;
}
toBuffer(skipname = false) {
const bufs = [ this._getNameBuffer(skipname) ];
for (let elt of compiled) {
bufs.push(elt.quserclass.from(this.__obj[elt.key]).toBuffer(true));
}
return Buffer.concat(bufs);
}
};
}
/**
* @function createUserType
* @memberof module:qtdatastream/types.QUserType
* @static
* @protected
* @param {String} name
* @param {*} value
* @returns {QUserType} a new class that extends QUserType
*/
static createUserType(name, value) {
if (Array.isArray(value)) {
return QUserType.createComplexUserType(name, value);
}
const qclass = QClass.types.get(value);
return class extends QUserType {
constructor(obj) {
super(name, obj);
}
static read(buffer) {
return qclass.read(buffer);
}
toBuffer(skipname = false) {
const bufs = [ this._getNameBuffer(skipname), qclass.from(this.__obj).toBuffer(true) ];
return Buffer.concat(bufs);
}
};
}
/**
* Register a custom usertype
* @function register
* @memberof module:qtdatastream/types.QUserType
* @static
* @param {string} name
* @param {*} value
* @example
* const { QUserType } = require('qtdatastream').types;
* QUserType.register('NWI', types.Types.INT);
* QUserType.register('BufferInfo', [
* { type: types.Types.SHORT },
* { name: types.Types.BYTEARRAY },
* { ni1: 'NWI' },
* { ni2: 'NWI' }
* ]);
*/
static register(name, value) {
if (!QUserType.usertypes) {
QUserType.usertypes = new Map;
}
QUserType.usertypes.set(name, QUserType.createUserType(name, value));
}
/**
* Get a previously registered usertype
* @function get
* @memberof module:qtdatastream/types.QUserType
* @static
* @param {string} name
*/
static get(name) {
return QUserType.usertypes.get(name);
}
/**
* @function read
* @memberof module:qtdatastream/types.QUserType
* @static
* @param {Buffer} buffer
* @param {string} name name with which the usertype has been registered
* @returns {*} Buffer coerced to whatever have been registered
*/
static read(buffer, name) {
if (!name) {
const bname = QByteArray.read(buffer);
name = bstr(bname);
}
const usertype = QUserType.usertypes.get(name);
if (!usertype) {
throw new Error(`Unregistered usertype ${name}`);
}
return usertype.read(buffer);
}
_getNameBuffer(skipname) {
if (!this.name) {
throw new Error('Abstract QUserType cannot be converted to a buffer');
}
if (!skipname) {
return QByteArray.from(this.name).toBuffer();
}
return Buffer.alloc(0);
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QUserType
* @inner
* @returns {Buffer}
*/
toBuffer(skipname = false) {
const bufs = [ this._getNameBuffer(skipname), QUserType.usertypes.get(this.name).from(this.__obj).toBuffer(true) ];
return Buffer.concat(bufs);
}
/**
* Wraps subject into `QUserType` object
* @function from
* @memberof module:qtdatastream/types.QUserType
* @static
* @param {*} subject
* @returns {QUserType}
*/
}
qtype(Types.USERTYPE)(QUserType);
/**
* @extends module:qtdatastream/types.QClass
* @static
* @param {*} obj
*/
class QVariant extends QClass {
/**
* By default, numbers are coerced to QUInt (unsigned 32bit ints).
* This method allows to change this default behavior to coerce numbers
* to any other QClass by default
* @function coerceNumbersTo
* @memberof module:qtdatastream/types.QVariant
* @static
* @param {Types} type
* @example
* const { QVariant, Types } = require('qtdatastream').types;
* QVariant.coerceNumbersTo(Types.DOUBLE);
*/
static coerceNumbersTo(type) {
const qclass = QClass.types.get(type);
if (qclass === undefined) {
throw new Error(`undefined type ${type}`);
}
QVariant.coerceNumbersClass = qclass;
}
/**
* @function read
* @memberof module:qtdatastream/types.QVariant
* @static
* @param {Buffer} buffer
* @returns {*} Buffer coerced to underlying QVariant type
*/
static read(buffer){
const type = QUInt.read(buffer);
const _isNull = QBool.read(buffer);
return QClass.types.get(type).read(buffer);
}
/**
* @function toBuffer
* @memberof module:qtdatastream/types.QVariant
* @inner
* @returns {Buffer}
*/
toBuffer() {
const isNull = (this.__obj === undefined || this.__obj === null);
const typeofobj = typeof this.__obj;
let qclass;
if (this.__obj === undefined) {
qclass = QInvalid;
} else if (this.__obj instanceof QUserType) {
qclass = QUserType;
} else if (this.__obj instanceof QVariant) {
throw new Error(`Can't nest QVariant`);
} else if (this.__obj instanceof QClass) {
qclass = this.__obj.constructor;
} else if (typeofobj === 'string') {
qclass = QString;
} else if (typeofobj === 'number') {
qclass = QVariant.coerceNumbersClass;
} else if (typeofobj === 'boolean') {
qclass = QBool;
} else if (this.__obj instanceof Date) {
qclass = QDateTime;
} else if (this.__obj instanceof Array) {
qclass = QList;
} else {
qclass = QMap;
}
const bufqvarianttype = QUInt.from(qclass.qtype).toBuffer();
const bufqvariantisnull = QBool.from(isNull).toBuffer();
const bufs = [ bufqvarianttype, bufqvariantisnull ];
if (!isNull) {
bufs.push(qclass.from(this.__obj).toBuffer());
}
return Buffer.concat(bufs);
}
/**
* Wraps subject into `QVariant` object
* @function from
* @memberof module:qtdatastream/types.QVariant
* @static
* @param {*} subject
* @returns {QVariant}
*/
}
QVariant.coerceNumbersClass = QUInt;
module.exports = {
qtype,
Types,
QClass,
QInvalid,
QBool,
QShort,
QInt,
QUInt,
QInt64,
QUInt64,
QDouble,
QChar,
QTime,
QByteArray,
QString,
QList,
QStringList,
QDateTime,
QMap,
QUserType,
QVariant
};