/**************************************************************************** * This file is part of the project AqHome. * AqHome (c) by 2024 Martin Preuss, all rights reserved. * * The license for this file can be found in the file COPYING which you * should have received along with this file. ****************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include "aqhome/data/storage_writexml.h" #include "aqhome/data/storage_p.h" #include #include #include #include #include #include #include /* ------------------------------------------------------------------------------------------------ * forward declarations * ------------------------------------------------------------------------------------------------ */ static void _writeLastIdsToXml(const AQH_STORAGE *sto, GWEN_XMLNODE *rootNode); static void _writeValuesToXml(const AQH_STORAGE *sto, GWEN_XMLNODE *rootNode); static void _writeDevicesToXml(const AQH_STORAGE *sto, GWEN_XMLNODE *rootNode); /* ------------------------------------------------------------------------------------------------ * implementations * ------------------------------------------------------------------------------------------------ */ int AQH_Storage_WriteStateFile(const AQH_STORAGE *sto, const char *sFilename) { GWEN_XMLNODE *rootNode; int rv; GWEN_BUFFER *nbuf; rootNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root"); _writeLastIdsToXml(sto, rootNode); _writeValuesToXml(sto, rootNode); _writeDevicesToXml(sto, rootNode); nbuf=GWEN_Buffer_new(0, 256, 0, 1); GWEN_Buffer_AppendString(nbuf, sFilename); GWEN_Buffer_AppendString(nbuf, ".tmp"); unlink(GWEN_Buffer_GetStart(nbuf)); rv=GWEN_XMLNode_WriteFile(rootNode, GWEN_Buffer_GetStart(nbuf), GWEN_XML_FLAGS_SIMPLE | GWEN_XML_FLAGS_HANDLE_HEADERS | GWEN_XML_FLAGS_INDENT); if (rv<0) { DBG_ERROR(AQH_LOGDOMAIN, "Error writing XML file \"%s\": %d", GWEN_Buffer_GetStart(nbuf), rv); GWEN_Buffer_free(nbuf); GWEN_XMLNode_free(rootNode); return rv; } if (rename(GWEN_Buffer_GetStart(nbuf), sFilename)<0) { DBG_ERROR(AQH_LOGDOMAIN, "Error renaming \"%s\"->\"%s\": %d (%s)", GWEN_Buffer_GetStart(nbuf), sFilename, errno, strerror(errno)); GWEN_Buffer_free(nbuf); GWEN_XMLNode_free(rootNode); return rv; } GWEN_Buffer_free(nbuf); GWEN_XMLNode_free(rootNode); return 0; } void _writeLastIdsToXml(const AQH_STORAGE *sto, GWEN_XMLNODE *rootNode) { GWEN_XMLNODE *nLastIds; nLastIds=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, AQH_STORAGE_XML_ELEMENTNAME_LASTIDS); GWEN_XMLNode_SetIntValue(nLastIds, "lastValueId", sto->lastValueId); GWEN_XMLNode_SetIntValue(nLastIds, "lastDeviceId", sto->lastDeviceId); GWEN_XMLNode_AddChild(rootNode, nLastIds); } void _writeValuesToXml(const AQH_STORAGE *sto, GWEN_XMLNODE *rootNode) { GWEN_XMLNODE *nElems; AQH_VALUE *elem; nElems=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, AQH_STORAGE_XML_ELEMENTNAME_VALUES); elem=AQH_Value_List_First(sto->valueList); while(elem) { GWEN_XMLNODE *nElem; nElem=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, AQH_STORAGE_XML_ELEMENTNAME_VALUE); AQH_Value_toXml(elem, nElem); GWEN_XMLNode_AddChild(nElems, nElem); elem=AQH_Value_List_Next(elem); } GWEN_XMLNode_AddChild(rootNode, nElems); } void _writeDevicesToXml(const AQH_STORAGE *sto, GWEN_XMLNODE *rootNode) { GWEN_XMLNODE *nElems; AQH_DEVICE *elem; nElems=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, AQH_STORAGE_XML_ELEMENTNAME_DEVICES); elem=AQH_Device_List_First(sto->deviceList); while(elem) { GWEN_XMLNODE *nElem; nElem=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, AQH_STORAGE_XML_ELEMENTNAME_DEVICE); AQH_Device_toXml(elem, nElem); GWEN_XMLNode_AddChild(nElems, nElem); elem=AQH_Device_List_Next(elem); } GWEN_XMLNode_AddChild(rootNode, nElems); }