Fix OpenChange server code and access to Samba4 databases.
[OpenChange-git-clone.git] / libmapi++ / property_container.h
blob3f21629f06f9859fae28517f5881aa7b2cc2557f
1 /*
2 libmapi C++ Wrapper
3 Property Tag Container Class
5 Copyright (C) Alan Alvarez 2008.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #ifndef LIBMAPIPP__PROPERTY_CONTAINER_H__
22 #define LIBMAPIPP__PROPERTY_CONTAINER_H__
24 #include <stdint.h>
25 #include <iostream> // for debugging only.
27 #include <libmapi++/clibmapi.h>
28 #include <libmapi++/mapi_exception.h>
30 // This is not declared in any of libmapi's headers, but it is defined in libmapi/property.c
31 extern "C" {
32 extern const void *get_mapi_SPropValue_data(struct mapi_SPropValue *lpProp);
35 namespace libmapipp
37 /// Iterator to use with Property Container
38 class property_container_iterator {
39 public:
40 /// Default Constructor. Creates an invalid iterator.
41 property_container_iterator() : m_property_values(NULL), m_mapi_property_values(NULL)
44 property_container_iterator(SPropValue* property_values) : m_property_values(property_values),
45 m_mapi_property_values(NULL)
48 property_container_iterator(mapi_SPropValue* mapi_property_values) : m_property_values(NULL),
49 m_mapi_property_values(mapi_property_values)
52 /** \brief Get Property Tag Type.
53 * \return Type of property this iterator points to or MAPI_PROP_RESERVED if this is an invalid iterator.
54 * Valid Types are:
55 * - PT_BOOLEAN
56 * - PT_I2
57 * - PT_LONG
58 * - PT_DOUBLE
59 * - PT_I8
60 * - PT_SYSTIME
61 * - PT_ERROR
62 * - PT_STRING8
63 * - PT_UNICODE
64 * - PT_BINARY
65 * - PT_CLSID
66 * - PT_ERROR
67 * - PT_MV_SHORT
68 * - PT_MV_LONG
69 * - PT_MV_STRING8
70 * - PT_MV_BINARY
71 * - PT_MV_CLSID
72 * - PT_MV_UNICODE
73 * - PT_MV_SYSTIME
74 * - PT_NULL
75 * - PT_OBJECT
77 int get_type()
79 if (m_property_values) {
80 return m_property_values->ulPropTag & 0xffff;
81 } else if (m_mapi_property_values) {
82 return m_mapi_property_values->ulPropTag & 0xffff;
83 } else {
84 return MAPI_PROP_RESERVED;
88 /**
89 * \brief Get Property Tag of the Property Value this operator points to.
91 * \return Property Tag of Property this iterator points to or MAPI_PROP_RESERVED if this is an invalid iterator.
93 int get_tag()
95 if (m_property_values) {
96 return m_property_values->ulPropTag;
97 } else if (m_mapi_property_values) {
98 return m_mapi_property_values->ulPropTag;
99 } else {
100 return MAPI_PROP_RESERVED;
104 /// operator++
105 property_container_iterator& operator++() // prefix
107 if (m_property_values)
108 ++m_property_values;
109 else if (m_mapi_property_values)
110 ++m_mapi_property_values;
112 return *this;
115 /// operator++ postfix
116 property_container_iterator operator++(int postfix) // postfix
118 property_container_iterator retval = *this;
119 if (m_property_values)
120 ++m_property_values;
121 else if (m_mapi_property_values)
122 ++m_mapi_property_values;
124 return retval;
127 /// operator==
128 bool operator==(const property_container_iterator& rhs) const
130 return ( (m_property_values == rhs.m_property_values) && (m_mapi_property_values == rhs.m_mapi_property_values) );
133 /// operator!=
134 bool operator!=(const property_container_iterator& rhs) const
136 return !(*this == rhs);
140 * \brief operator*
142 * \return The property value as a void pointer.
144 const void* operator*()
146 if (m_property_values)
147 return get_SPropValue_data(m_property_values);
148 else
149 return get_mapi_SPropValue_data(m_mapi_property_values);
152 private:
153 SPropValue* m_property_values;
154 mapi_SPropValue* m_mapi_property_values;
158 /// A container of properties to be used with classes derived from object.
159 class property_container {
161 public:
162 typedef property_container_iterator iterator;
163 typedef const void* value_type;
165 /// Constructor
166 property_container(TALLOC_CTX* memory_ctx, mapi_object_t& mapi_object) :
167 m_memory_ctx(memory_ctx), m_mapi_object(mapi_object), m_fetched(false), m_property_tag_array(NULL), m_cn_vals(0), m_property_values(0)
169 m_property_value_array.cValues = 0;
170 m_property_value_array.lpProps = NULL;
174 * \brief Fetches properties with the tags supplied using operator<<
176 * \return The number of objects that were fetched.
178 uint32_t fetch()
180 if (GetProps(&m_mapi_object, m_property_tag_array, &m_property_values, &m_cn_vals) != MAPI_E_SUCCESS)
181 throw mapi_exception(GetLastError(), "property_container::fetch : GetProps");
183 MAPIFreeBuffer(m_property_tag_array);
184 m_property_tag_array = NULL;
186 m_fetched = true;
187 return m_cn_vals;
190 /// \brief Fetches \b ALL properties of the object associated with this container.
191 void fetch_all()
193 if (GetPropsAll(&m_mapi_object, &m_property_value_array) != MAPI_E_SUCCESS)
194 throw mapi_exception(GetLastError(), "property_container::fetch_all : GetPropsAll");
196 // Free property_tag_array in case user used operator<< by mistake.
197 if (m_property_tag_array) {
198 MAPIFreeBuffer(m_property_tag_array);
199 m_property_tag_array = NULL;
202 m_fetched = true;
205 /// \brief Adds a Property Tag to be fetched by fetch().
206 property_container& operator<<(uint32_t property_tag)
208 if (!m_property_tag_array) {
209 m_property_tag_array = set_SPropTagArray(m_memory_ctx, 1, property_tag);
210 } else {
211 if (SPropTagArray_add(m_memory_ctx, m_property_tag_array, property_tag) != MAPI_E_SUCCESS)
212 throw mapi_exception(GetLastError(), "property_container::operator<< : SPropTagArray_add");
215 return *this;
219 * \brief Finds the property value associated with a property tag
221 * \param property_tag The Property Tag to be searched for
223 * \return Property Value as a const void pointer
225 const void* operator[](uint32_t property_tag)
227 if (!m_fetched) return NULL;
229 if (m_property_values)
230 return find_SPropValue_value(property_tag);
231 else
232 return find_mapi_SPropValue_data(&m_property_value_array, property_tag);
235 enum MAPITAGS get_tag_at(uint32_t pos)
237 if (m_property_values)
238 return m_property_values[pos].ulPropTag;
239 else
240 return m_property_value_array.lpProps[pos].ulPropTag;
243 iterator begin() const
245 if (!m_fetched) return iterator();
247 if (m_property_values)
248 return iterator(m_property_values);
249 else
250 return iterator(m_property_value_array.lpProps);
253 iterator end() const
255 if (!m_fetched) return iterator();
257 if (m_property_values)
258 return iterator(m_property_values + m_cn_vals);
259 else
260 return iterator(m_property_value_array.lpProps + m_property_value_array.cValues);
263 /// \brief Get number of properties in container.
264 size_t size() const
266 if (!m_fetched) return 0;
268 if (m_property_values)
269 return m_cn_vals;
270 else
271 return m_property_value_array.cValues;
274 /// Destructor
275 ~property_container()
277 if (m_property_tag_array) MAPIFreeBuffer(m_property_tag_array);
280 private:
281 TALLOC_CTX* m_memory_ctx;
282 mapi_object_t& m_mapi_object;
284 bool m_fetched;
286 SPropTagArray* m_property_tag_array;
288 // Used when calling GetProps (fetch)
289 uint32_t m_cn_vals;
290 SPropValue* m_property_values;
292 // Used when calling GetPropsAll (fetch_all)
293 mapi_SPropValue_array m_property_value_array;
295 const void* find_SPropValue_value(uint32_t property_tag)
297 for (uint32_t i = 0; i < m_cn_vals; ++i)
299 if ((uint32_t)m_property_values[i].ulPropTag == property_tag)
300 return get_SPropValue_data(&m_property_values[i]);
303 return NULL;
307 } // namespace libmapipp
309 #endif //!LIBMAPIPP__PROPERTY_CONTAINER_H__