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__
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
32 extern const void *get_mapi_SPropValue_data(struct mapi_SPropValue
*lpProp
);
37 /// Iterator to use with Property Container
38 class property_container_iterator
{
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.
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;
84 return MAPI_PROP_RESERVED
;
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.
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
;
100 return MAPI_PROP_RESERVED
;
105 property_container_iterator
& operator++() // prefix
107 if (m_property_values
)
109 else if (m_mapi_property_values
)
110 ++m_mapi_property_values
;
115 /// operator++ postfix
116 property_container_iterator
operator++(int postfix
) // postfix
118 property_container_iterator retval
= *this;
119 if (m_property_values
)
121 else if (m_mapi_property_values
)
122 ++m_mapi_property_values
;
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
) );
134 bool operator!=(const property_container_iterator
& rhs
) const
136 return !(*this == rhs
);
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
);
149 return get_mapi_SPropValue_data(m_mapi_property_values
);
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
{
162 typedef property_container_iterator iterator
;
163 typedef const void* value_type
;
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.
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
;
190 /// \brief Fetches \b ALL properties of the object associated with this container.
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
;
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
);
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");
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
);
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
;
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
);
250 return iterator(m_property_value_array
.lpProps
);
255 if (!m_fetched
) return iterator();
257 if (m_property_values
)
258 return iterator(m_property_values
+ m_cn_vals
);
260 return iterator(m_property_value_array
.lpProps
+ m_property_value_array
.cValues
);
263 /// \brief Get number of properties in container.
266 if (!m_fetched
) return 0;
268 if (m_property_values
)
271 return m_property_value_array
.cValues
;
275 ~property_container()
277 if (m_property_tag_array
) MAPIFreeBuffer(m_property_tag_array
);
281 TALLOC_CTX
* m_memory_ctx
;
282 mapi_object_t
& m_mapi_object
;
286 SPropTagArray
* m_property_tag_array
;
288 // Used when calling GetProps (fetch)
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
]);
307 } // namespace libmapipp
309 #endif //!LIBMAPIPP__PROPERTY_CONTAINER_H__