UNPKG

isoxml-angular

Version:

JavaScript library to parse and generate ISOXML (ISO11783-10) files

211 lines (210 loc) 9.64 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.constructValueInformation = exports.DDIToString = exports.toXML = exports.fromXML = exports.childTags2Xml = exports.xml2ChildTags = void 0; const DDEntities_1 = __importDefault(require("./DDEntities")); function idrefParser(value, attrDescription, isoxmlManager) { return isoxmlManager.registerEntity(null, value); } function integerParser(value, attrDescription) { if (value === '' && attrDescription.allowEmptyString) { return null; } return parseInt(value, 10); } function floatParser(value, attrDescription) { if (value === '' && attrDescription.allowEmptyString) { return null; } return parseFloat(value); } function dateTimeParser(value) { return new Date(value); } function idrefGenerator(value) { return value.xmlId; } function numberGenerator(value, attrDescription) { if (attrDescription.allowEmptyString && value === null) { return ''; } if ('fractionDigits' in attrDescription) { return parseFloat(value.toFixed(attrDescription.fractionDigits)).toString(); } else { return value.toString(); } } function dateTimeGenerator(value) { return value.toISOString(); } const PARSERS = { 'xs:IDREF': idrefParser, 'xs:unsignedByte': integerParser, 'xs:long': integerParser, 'xs:unsignedShort': integerParser, 'xs:unsignedLong': integerParser, 'xs:decimal': floatParser, 'xs:double': floatParser, 'xs:dateTime': dateTimeParser }; const GENERATORS = { 'xs:IDREF': idrefGenerator, 'xs:unsignedByte': numberGenerator, 'xs:long': numberGenerator, 'xs:unsignedShort': numberGenerator, 'xs:unsignedLong': numberGenerator, 'xs:decimal': numberGenerator, 'xs:double': numberGenerator, 'xs:dateTime': dateTimeGenerator }; const PROPRIETARY_NAME = /^P\d+_/; function xml2attrs(xml, attributesDescription, isoxmlManager, internalId) { const result = {}; Object.keys(xml._attributes || {}).forEach(xmlAttr => { const attrDescription = attributesDescription[xmlAttr]; if (!attrDescription) { if (xmlAttr.match(PROPRIETARY_NAME)) { result['ProprietaryAttributes'] = result['ProprietaryAttributes'] || []; result['ProprietaryAttributes'][xmlAttr] = xml._attributes[xmlAttr]; } else { // warn about unknown non-proprietary attributes isoxmlManager.addWarning(`[${internalId}] Unknown attribute "${xmlAttr}"`); } return; } if (attrDescription.isPrimaryId) { return; } const parser = PARSERS[attrDescription.type]; result[attrDescription.name] = parser ? parser(xml._attributes[xmlAttr], attrDescription, isoxmlManager) : xml._attributes[xmlAttr]; }); // validation Object.keys(attributesDescription).forEach(xmlAttr => { if (!attributesDescription[xmlAttr].isOptional && (!xml._attributes || !(xmlAttr in xml._attributes))) { isoxmlManager.addWarning(`[${internalId}] Missing required attribute "${xmlAttr}"`); } }); return result; } function attrs2xml(entity, attributesDescription) { const version = entity.isoxmlManager.options.version; const result = Object.assign({}, entity.attributes.ProprietaryAttributes); const primaryXmlId = Object.keys(attributesDescription).find(xmlTag => attributesDescription[xmlTag].isPrimaryId); if (primaryXmlId && !(version === 3 && attributesDescription[primaryXmlId].isOnlyV4)) { const ref = entity.isoxmlManager.getReferenceByEntity(entity); if (ref) { result[primaryXmlId] = ref.xmlId; } } Object.keys(entity.attributes).forEach(attrName => { const xmlAttr = Object.keys(attributesDescription).find(xmlId => attributesDescription[xmlId].name === attrName); const attrDescription = attributesDescription[xmlAttr]; if (!attrDescription || (version === 3 && attrDescription.isOnlyV4)) { return; } const generator = GENERATORS[attrDescription.type]; result[xmlAttr] = generator ? generator(entity.attributes[attrName], attrDescription, entity.isoxmlManager) : entity.attributes[attrName]; }); return result; } function xml2ChildTags(xml, referencesDescription, isoxmlManager, internalId) { return __awaiter(this, void 0, void 0, function* () { const result = {}; for (const tagName of Object.keys(xml)) { const refDescription = referencesDescription[tagName]; if (!refDescription) { if (tagName.match(PROPRIETARY_NAME)) { result['ProprietaryTags'] = result['ProprietaryTags'] || {}; result['ProprietaryTags'][tagName] = result['ProprietaryTags'][tagName] || []; result['ProprietaryTags'][tagName].push(...xml[tagName]); } continue; } result[refDescription.name] = []; for (const [idx, childXml] of xml[tagName].entries()) { const childInternalId = `${internalId}->${tagName}[${idx}]`; result[refDescription.name].push(yield isoxmlManager.createEntityFromXML(tagName, childXml, childInternalId)); } } return result; }); } exports.xml2ChildTags = xml2ChildTags; function childTags2Xml(entity, referencesDescription) { const version = entity.isoxmlManager.options.version; const result = Object.assign({}, entity.attributes.ProprietaryTags); Object.keys(entity.attributes).forEach(attrName => { const tagName = Object.keys(referencesDescription).find(tag => referencesDescription[tag].name === attrName); const refDescription = referencesDescription[tagName]; if (!refDescription || (version === 3 && refDescription.isOnlyV4)) { return; } result[tagName] = entity.attributes[attrName].map(entity => entity.toXML()); }); return result; } exports.childTags2Xml = childTags2Xml; function fromXML(xml, isoxmlManager, entityClass, attributesDescription, referencesDescription, internalId) { return __awaiter(this, void 0, void 0, function* () { const idAttr = Object.keys(attributesDescription).find(attrId => attributesDescription[attrId].isPrimaryId); const xmlId = idAttr ? xml._attributes[idAttr] : null; const updatedInternalId = xmlId || internalId; const children = yield xml2ChildTags(xml, referencesDescription, isoxmlManager, updatedInternalId); const entity = new entityClass(Object.assign(Object.assign({}, xml2attrs(xml, attributesDescription, isoxmlManager, updatedInternalId)), children), isoxmlManager, updatedInternalId); xmlId && entity.isoxmlManager.registerEntity(entity, xmlId); return entity; }); } exports.fromXML = fromXML; function toXML(entity, attributesDescription, referencesDescription) { return Object.assign({ _attributes: attrs2xml(entity, attributesDescription) }, childTags2Xml(entity, referencesDescription)); } exports.toXML = toXML; function DDIToString(DDI) { return DDI.toString(16).toUpperCase().padStart(4, '0'); } exports.DDIToString = DDIToString; function constructValueInformation(ddiString, vpn, dpd) { var _a, _b; const ddiNumber = parseInt(ddiString, 16); const ddEntity = DDEntities_1.default[ddiNumber]; const unit = vpn ? (vpn.attributes.UnitDesignator || '') : ((ddEntity === null || ddEntity === void 0 ? void 0 : ddEntity.unit) || ''); const scale = vpn ? vpn.attributes.Scale : ((_a = ddEntity === null || ddEntity === void 0 ? void 0 : ddEntity.bitResolution) !== null && _a !== void 0 ? _a : 1); const offset = vpn ? vpn.attributes.Offset : 0; const numberOfDecimals = vpn ? vpn.attributes.NumberOfDecimals : Math.ceil(-Math.log10((ddEntity === null || ddEntity === void 0 ? void 0 : ddEntity.bitResolution) || 1)); const ddiName = ddEntity === null || ddEntity === void 0 ? void 0 : ddEntity.name; const dpdDesignator = dpd === null || dpd === void 0 ? void 0 : dpd.attributes.DeviceProcessDataDesignator; const DDEntityName = ddiName && dpdDesignator ? `${dpdDesignator} (${ddiName})` : ((_b = ddiName !== null && ddiName !== void 0 ? ddiName : dpdDesignator) !== null && _b !== void 0 ? _b : ''); return { DDINumber: ddiNumber, DDIString: ddiString, DDEntityName, unit, scale, offset, numberOfDecimals, isProprietary: ddiNumber >= 57344 && ddiNumber <= 65534 }; } exports.constructValueInformation = constructValueInformation;