1 /* 2 * LibrePCB - Professional EDA for everyone! 3 * Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors. 4 * https://librepcb.org/ 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef LIBREPCB_SERIALIZABLEOBJECT_H 21 #define LIBREPCB_SERIALIZABLEOBJECT_H 22 23 /******************************************************************************* 24 * Includes 25 ******************************************************************************/ 26 #include "sexpression.h" 27 28 #include <QtCore> 29 30 /******************************************************************************* 31 * Namespace / Forward Declarations 32 ******************************************************************************/ 33 namespace librepcb { 34 35 /******************************************************************************* 36 * Class SerializableObject 37 ******************************************************************************/ 38 39 /** 40 * @brief The SerializableObject class is the base class for all classes which 41 * need to be serializable/deserializable from/to librepcb::SExpression nodes 42 */ 43 class SerializableObject { 44 public: SerializableObject()45 SerializableObject() noexcept {} ~SerializableObject()46 virtual ~SerializableObject() noexcept {} 47 48 /** 49 * @brief Serialize the object to a new S-Expression node 50 * 51 * This method creates a new S-Expression node, serializes the whole object 52 * into it and then returns the whole S-Expression node. See #serialize() for 53 * details. 54 * 55 * @param name The root name of the returned S-Expression node 56 * 57 * @return The created S-Expression node (the caller takes the ownership!) 58 * 59 * @throw Exception This method throws an exception if an error occurs. 60 * 61 * @see #serialize() 62 */ serializeToDomElement(const QString & name)63 SExpression serializeToDomElement(const QString& name) const { 64 SExpression root = SExpression::createList(name); 65 serialize(root); 66 return root; 67 } 68 69 /** 70 * @brief Serialize the object into an existing S-Expression node 71 * 72 * This method inserts/appends all attributes and childs of the object to an 73 * existing S-Expression node. The content which already exists in the given 74 * S-Expression node will not be removed. 75 * 76 * @note The generated S-Expression node has always the format of the 77 * application's major version (it's not possible to generate DOMs of 78 * older versions). 79 * 80 * @param root The target DOM root node 81 * 82 * @throw Exception This method throws an exception if an error occurs. 83 */ 84 virtual void serialize(SExpression& root) const = 0; 85 86 template <typename T> serializeObjectContainer(SExpression & root,const T & container,const QString & itemName)87 static void serializeObjectContainer(SExpression& root, const T& container, 88 const QString& itemName) { 89 for (const auto& object : container) { 90 root.appendChild(object.serializeToDomElement(itemName), 91 true); // can throw 92 } 93 } 94 95 template <typename T> serializePointerContainer(SExpression & root,const T & container,const QString & itemName)96 static void serializePointerContainer(SExpression& root, const T& container, 97 const QString& itemName) { 98 for (const auto& pointer : container) { 99 root.appendChild(pointer->serializeToDomElement(itemName), 100 true); // can throw 101 } 102 } 103 104 template <typename T> serializePointerContainerUuidSorted(SExpression & root,const T & container,const QString & itemName)105 static void serializePointerContainerUuidSorted(SExpression& root, 106 const T& container, 107 const QString& itemName) { 108 T copy = container; 109 std::sort( 110 copy.begin(), copy.end(), 111 [](const typename T::value_type& a, const typename T::value_type& b) { 112 return a->getUuid() < b->getUuid(); 113 }); 114 serializePointerContainer(root, copy, itemName); 115 } 116 }; 117 118 // Make sure that the SerializableObject class does not contain any data (except 119 // the vptr). Otherwise it could introduce issues when using multiple 120 // inheritance. 121 static_assert(sizeof(SerializableObject) == sizeof(void*), 122 "SerializableObject must not contain any data!"); 123 124 /******************************************************************************* 125 * End of File 126 ******************************************************************************/ 127 128 } // namespace librepcb 129 130 #endif // LIBREPCB_SERIALIZABLEOBJECT_H 131