functions/raw_to_type.js

const { DataType } = require('../types');
const { timeToDate } = require('./date');

/**
 * Convert a Buffer to a string.
 *
 * @param {Buffer} raw - data to convert.
 * @returns {string} converted string.
 * @private
 */
function rawToString(raw) {
    raw = raw.toString();

    const end = raw.indexOf('\0');
    if (end != -1)
        raw = raw.substring(0, end);

    return raw;
}

/**
 * Convert a Buffer object to a Date.
 *
 * @param {Buffer} raw - data to convert.
 * @returns {Date} converted Date.
 * @private
 */
function rawToDate(raw) {
    const ms = raw.readUInt32LE(0);
    const days = raw.readUInt16LE(4);
    return timeToDate(days, ms);
}

/**
 * Convert a Buffer to a value based on type.
 *
 * @param {Buffer} raw - data to convert.
 * @param {DataType | string} type - how to interpret the data.
 * @param {number} [scaleFactor] - optional multiplier for numeric types.
 * @returns {number | bigint | string | Date} converted data.
 */
function rawToType(raw, type, scaleFactor=1.0) {
    if (typeof type === 'string')
        type = DataType[type];

    switch (type) {
        case DataType.BOOLEAN:
            return !!raw.readUInt8();
        case DataType.INTEGER8:
            return raw.readInt8() * scaleFactor;
        case DataType.INTEGER16:
            return raw.readInt16LE() * scaleFactor;
        case DataType.INTEGER24:
            return raw.readIntLE(0, 3) * scaleFactor;
        case DataType.INTEGER32:
            return raw.readInt32LE() * scaleFactor;
        case DataType.INTEGER40:
            return raw.readIntLE(0, 5) * scaleFactor;
        case DataType.INTEGER48:
            return raw.readIntLE(0, 6) * scaleFactor;
        case DataType.INTEGER64:
            return raw.readBigInt64LE() * BigInt(scaleFactor);
        case DataType.UNSIGNED8:
            return raw.readUInt8() * scaleFactor;
        case DataType.UNSIGNED16:
            return raw.readUInt16LE() * scaleFactor;
        case DataType.UNSIGNED24:
            return raw.readUIntLE(0, 3) * scaleFactor;
        case DataType.UNSIGNED32:
            return raw.readUInt32LE() * scaleFactor;
        case DataType.UNSIGNED40:
            return raw.readUIntLE(0, 5) * scaleFactor;
        case DataType.UNSIGNED48:
            return raw.readUIntLE(0, 6) * scaleFactor;
        case DataType.UNSIGNED64:
            return raw.readBigUInt64LE() * BigInt(scaleFactor);
        case DataType.REAL32:
            return raw.readFloatLE() * scaleFactor;
        case DataType.REAL64:
            return raw.readDoubleLE() * scaleFactor;
        case DataType.VISIBLE_STRING:
        case DataType.UNICODE_STRING:
            return rawToString(raw);
        case DataType.TIME_OF_DAY:
        case DataType.TIME_DIFFERENCE:
            return rawToDate(raw);
        default:
            return raw;
    }
}

module.exports = exports = rawToType;