/** * @file GoOutput.c * * @internal * Copyright (C) 2016-2021 by LMI Technologies Inc. * Licensed under the MIT License. * Redistributed files must retain the above copyright notice. */ #include #include kBeginClassEx(Go, GoOutput) kAddVMethod(GoOutput, kObject, VRelease) kEndClassEx() GoFx(kStatus) GoOutput_Construct(GoOutput* output, kObject sensor, kAlloc allocator) { kAlloc alloc = kAlloc_Fallback(allocator); kStatus status; kCheck(kAlloc_GetObject(alloc, kTypeOf(GoOutput), output)); if (!kSuccess(status = GoOutput_Init(*output, kTypeOf(GoOutput), sensor, alloc))) { kAlloc_FreeRef(alloc, output); } return status; } GoFx(kStatus) GoOutput_Init(GoOutput output, kType type, kObject sensor, kAlloc alloc) { kObjR(GoOutput, output); k32u i; kStatus exception; kCheck(kObject_Init(output, type, alloc)); obj->sensor = sensor; obj->xml = obj->xmlItem = obj->ethernet = obj->serial = obj->analog = kNULL; for (i = 0; i < kCountOf(obj->digital); ++i) obj->digital[i] = kNULL; kTry { kTest(GoEthernet_Construct(&obj->ethernet, sensor, alloc)); kTest(GoSerial_Construct(&obj->serial, sensor, alloc)); kTest(GoAnalog_Construct(&obj->analog, sensor, alloc)); for (i = 0; i < kCountOf(obj->digital); ++i) { kTest(GoDigital_Construct(&obj->digital[i], sensor, alloc)); } } kCatch(&exception) { GoOutput_VRelease(output); kEndCatch(exception); } return kOK; } GoFx(kStatus) GoOutput_VRelease(GoOutput output) { kObjR(GoOutput, output); k32u i; kCheck(kDestroyRef(&obj->ethernet)); kCheck(kDestroyRef(&obj->serial)); kCheck(kDestroyRef(&obj->analog)); for (i = 0; i < kCountOf(obj->digital); ++i) { kCheck(kDestroyRef(&obj->digital[i])); } kCheck(kObject_VRelease(output)); return kOK; } GoFx(kStatus) GoOutput_Read(GoOutput output, kXml xml, kXmlItem item) { kObjR(GoOutput, output); kXmlItem ethernetItem = kNULL; kXmlItem serialItem = kNULL; kXmlItem digitalItem = kNULL; kXmlItem analogItem = kNULL; k32u i; kString digitalString = kNULL; obj->xml = xml; obj->xmlItem = item; kCheck(!kIsNull(ethernetItem = kXml_Child(xml, item, "Ethernet"))); kCheck(GoEthernet_Read(obj->ethernet, xml, ethernetItem)); kCheck(!kIsNull(serialItem = kXml_Child(xml, item, "Serial"))); kCheck(GoSerial_Read(obj->serial, xml, serialItem)); kCheck(!kIsNull(analogItem = kXml_Child(xml, item, "Analog"))); kCheck(GoAnalog_Read(obj->analog, xml, analogItem)); kTry { kTest(kString_Construct(&digitalString, "", kObject_Alloc(output))); for (i = 0; i < kCountOf(obj->digital); ++i) { kTest(kString_Setf(digitalString, "Digital%u", i)); digitalItem = kXml_Child(xml, item, kString_Chars(digitalString)); kTest(!kIsNull(digitalItem)); kTest(GoDigital_Read(obj->digital[i], xml, digitalItem)); } } kFinally { kDestroyRef(&digitalString); kEndFinally(); } return kOK; } GoFx(kStatus) GoOutput_Write(GoOutput output, kXml xml, kXmlItem item) { kObjR(GoOutput, output); kXmlItem ethernetItem = kNULL; kXmlItem serialItem = kNULL; kXmlItem digitalItem = kNULL; kXmlItem analogItem = kNULL; k32u i; kString digitalString = kNULL; if (kIsNull(obj->xml) || kIsNull(obj->xmlItem)) return kERROR_STATE; kCheck(kXml_AddItem(xml, item, "Ethernet", ðernetItem)); kCheck(GoEthernet_Write(obj->ethernet, xml, ethernetItem)); kCheck(kXml_AddItem(xml, item, "Serial", &serialItem)); kCheck(GoSerial_Write(obj->serial, xml, serialItem)); kCheck(kXml_AddItem(xml, item, "Analog", &analogItem)); kCheck(GoAnalog_Write(obj->analog, xml, analogItem)); kTry { kTest(kString_Construct(&digitalString, "", kObject_Alloc(output))); for (i = 0; i < kCountOf(obj->digital); ++i) { kTest(kString_Setf(digitalString, "Digital%u", i)); kTest(kXml_AddItem(xml, item, kString_Chars(digitalString), &digitalItem)); kTest(GoDigital_Write(obj->digital[i], xml, digitalItem)); } } kFinally { kDestroyRef(&digitalString); kEndFinally(); } //Forwards Compatibility kCheck(GoUtils_XmlMerge(obj->xml, obj->xmlItem, xml, item)); return kOK; } GoFx(GoEthernet) GoOutput_Ethernet(GoOutput output) { kObjR(GoOutput, output); return obj->ethernet; } GoFx(k32u) GoOutput_EthernetCount(GoOutput output) { kObjR(GoOutput, output); kObjNR(GoEthernet, ethernet, obj->ethernet); return (k32u) ethernet->outputUsed; } GoFx(GoEthernet) GoOutput_EthernetAt(GoOutput output, kSize index) { kObjR(GoOutput, output); kAssert(index < GoOutput_EthernetCount(output)); return obj->ethernet; } GoFx(GoSerial) GoOutput_Serial(GoOutput output) { kObjR(GoOutput, output); return obj->serial; } GoFx(k32u) GoOutput_SerialCount(GoOutput output) { kObjR(GoOutput, output); kObjNR(GoSerial, serial, obj->serial); return (k32u) serial->outputUsed; } GoFx(GoSerial) GoOutput_SerialAt(GoOutput output, kSize index) { kObjR(GoOutput, output); kAssert(index < GoOutput_SerialCount(output)); return obj->serial; } GoFx(k32u) GoOutput_DigitalCount(GoOutput output) { kObjR(GoOutput, output); kObjNR(GoDigital, digital, kNULL); k32u i, numEnabled = 0; for (i = 0; i < kCountOf(obj->digital); i++){ digital = obj->digital[i]; if (digital->outputUsed){ numEnabled++; } } return numEnabled; } GoFx(GoDigital) GoOutput_DigitalAt(GoOutput output, kSize index) { kObjR(GoOutput, output); kAssert(index < GoOutput_DigitalCount(output)); return obj->digital[index]; } GoFx(GoAnalog) GoOutput_Analog(GoOutput output) { kObjR(GoOutput, output); return obj->analog; } GoFx(k32u) GoOutput_AnalogCount(GoOutput output) { kObjR(GoOutput, output); kObjNR(GoAnalog, analog, obj->analog); return (k32u) analog->outputUsed; } GoFx(GoAnalog) GoOutput_AnalogAt(GoOutput output, kSize index) { kObjR(GoOutput, output); kAssert(index < GoOutput_AnalogCount(output)); return obj->analog; }