isoxml-angular
Version:
JavaScript library to parse and generate ISOXML (ISO11783-10) files
211 lines (210 loc) • 9.64 kB
JavaScript
;
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;