Fix potential lisp-object ID generation overflow for excessive lisp-object creation.
Annotate for file src/lib/lisp-object.cpp
2010-01-10 tobias 1 #include "lisp-object.h"
08:52:49 ' 2
' 3 #include <QtGlobal>
' 4 #include <QtDebug>
' 5
' 6 namespace cl_smoke {
' 7 namespace qt {
' 8
' 9 /** @struct lisp_object::data
' 10 * @internal
' 11 * Holds a reference ID for a lisp object and calls
' 12 * the destructor callback when it is deleted.
' 13 */
' 14
' 15 /** @typedef lisp_object::destructor
' 16 * Destructor.
' 17 * @param id The ID
' 18 */
' 19
' 20 lisp_object::destructor lisp_object::destruct = NULL;
' 21
' 22
' 23 /** Constructor. */
' 24 lisp_object::data::data()
' 25 : id(id),
' 26 is_set(false)
' 27 { }
' 28
' 29 /** Constructor.
' 30 * @param id The ID.
' 31 */
2009-07-02 tobias 32 lisp_object::data::data(unsigned int id)
2010-01-10 tobias 33 : id(id),
08:52:49 ' 34 is_set(true)
' 35 { }
' 36
' 37 /** Destructor. */
' 38 lisp_object::data::~data()
' 39 {
' 40 Q_ASSERT_X(lisp_object::destruct, __func__,
' 41 "call setup_lisp_object() first.");
' 42
' 43 if (this->is_set)
' 44 (*lisp_object::destruct)(this->id);
' 45 }
' 46
' 47 /** @class lisp_object
' 48 * @brief Holds a reference ID to a lisp object.
' 49 *
' 50 * The registered destructor callback is called when
' 51 * the last instance for a specific lisp object is deleted.
' 52 *
' 53 * Used for lisp objects in QVariants and signal/slots.
' 54 */
' 55
' 56 /** Constructor. */
' 57 lisp_object::lisp_object()
' 58 : d(new data())
' 59 { }
' 60
' 61 /** Constructor.
' 62 * @param id the ID
' 63 */
2009-07-02 tobias 64 lisp_object::lisp_object(unsigned int id)
2010-01-10 tobias 65 : d(new data(id))
08:52:49 ' 66 { }
' 67
' 68 /** Constructor.
' 69 * @param other the lisp_object to copy
' 70 */
' 71 lisp_object::lisp_object(const lisp_object& other)
' 72 : d(other.d)
' 73 { }
' 74
' 75 /** @fn lisp_object::id() const
' 76 * Gets the ID.
' 77 *
' 78 * @return the ID
' 79 */
' 80
' 81 /** @fn lisp_object::set() const
' 82 * Determines werter the ID is set.
' 83 *
' 84 * @return @c true when the id is set and @c false otherwise.
' 85 */
' 86
' 87 /** Sets a new ID.
' 88 * @param id the ID
' 89 */
' 90 void
2009-07-02 tobias 91 lisp_object::set_id(unsigned int id)
2010-01-10 tobias 92 {
08:52:49 ' 93 Q_ASSERT(this->set() ? id != this->id() : true);
' 94
' 95 d = new data(id);
' 96 }
' 97
' 98 } // namespace qt
' 99 } // namespace cl_smoke
' 100
' 101 using namespace cl_smoke::qt;
' 102
' 103 /** Initialize the lisp_object.
' 104 * @relates cl_smoke::qt::lisp_object
' 105 * @param destruct destructor callback
' 106 *
' 107 * @return the QMetaType ID of lisp_object
' 108 */
' 109 int
' 110 qt_smoke_setup_lisp_object(void* destruct)
' 111 {
' 112 Q_ASSERT(destruct != NULL);
' 113 lisp_object::destruct = reinterpret_cast<lisp_object::destructor>(destruct);
' 114
' 115 return qRegisterMetaType<lisp_object>();
' 116 }
' 117
' 118 /** Gets the ID of @a object.
' 119 * @relates cl_smoke::qt::lisp_object
' 120 * @param object the lisp_object.
' 121 *
' 122 * @return the ID
' 123 */
2009-07-02 tobias 124 unsigned int
2010-01-10 tobias 125 qt_smoke_lisp_object_id(const void* object)
08:52:49 ' 126 {
' 127 return static_cast<const lisp_object*>(object)->id();
' 128 }
' 129
' 130
' 131 /** Determines werter the ID of @a object is set.
' 132 * @relates cl_smoke::qt::lisp_object
' 133 * @param object the object
' 134 *
' 135 * @return @c true when the ID is set and @c false otherwise.
' 136 */
' 137 int
2009-07-02 tobias 138 qt_smoke_lisp_object_is_set(const void* object)
2010-01-10 tobias 139 {
08:52:49 ' 140 return static_cast<const lisp_object*>(object)->set();
' 141 }
' 142
' 143 /** Makes a new lisp_object.
' 144 * @relates cl_smoke::qt::lisp_object
' 145 * @param id the ID
' 146 *
' 147 * @return A new lisp_object instance.
' 148 */
' 149 void*
2009-07-02 tobias 150 qt_smoke_make_lisp_object(unsigned int id)
2010-01-10 tobias 151 {
08:52:49 ' 152 return new lisp_object(id);
' 153 }
' 154
' 155 /** Deletes a lisp_object.
' 156 * @relates cl_smoke::qt::lisp_object
' 157 * @param object the lisp_object
' 158 */
' 159 void*
' 160 qt_smoke_free_lisp_object(void* object)
' 161 {
' 162 delete static_cast<lisp_object*>(object);
' 163 }
' 164
' 165 #include <QVariant>
' 166 /** Gets the lisp_object of a QVariant.
' 167 * @relates cl_smoke::qt::lisp_object
' 168 * @param variant the QVariant
' 169 *
' 170 * @return a new lisp_object.
' 171 */
' 172 void*
' 173 qt_smoke_lisp_object_value(const void* variant)
' 174 {
' 175 const QVariant* qvariant = static_cast<const QVariant*>(variant);
' 176 Q_ASSERT(QVariant::UserType == qvariant->type());
' 177
' 178 new lisp_object(qvariant->value<lisp_object>());
' 179 }