HEAD: removed mrwise debug crud from uniclientgen.cc.
[wvapps.git] / wvmapi / wvtnef.h
blob458e8b2b7f71fc6ead4f5092ad5ca3db45568071
1 /*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2004 Net Integration Technologies, Inc.
5 * This is the main TNEF handling class.
6 */
7 #ifndef __WVTNEF_H
8 #define __WVTNEF_H
10 #include <stdint.h>
11 #include <stdio.h>
12 #include <string>
14 #include "wvstring.h"
15 #include "wvlinklist.h"
16 #include "wvscatterhash.h"
17 #include "wvvector.h"
18 #include "wvlog.h"
19 #include "wvtnefdefs.h"
20 #include "wvmapipart.h"
22 using namespace std;
24 DeclareWvList2(WvMapiPartList, WvMapiPart);
25 DeclareWvList2(Uint32List, uint32_t);
27 enum TNEFStoreType
29 ATT_MAPI_PROPS,
30 ATT_ATTACHMENT,
31 ATT_RECIP_TABLE
34 /** Keys for the wvtnef internal hash table.
35 * These keys have 4 properties: tag, guid, name_id and name_string.
36 * At most, 2 of these are needed to find a MAPI property. If its
37 * MAPI ID is less than 0x8000, it is a "normal" MAPI property, and
38 * all you need to find it is the tag. If its MAPI ID is >= 0x8000,
39 * however, it is a "named" property, and you will need its GUID in
40 * addition to either the name ID (another 2-byte ID that is also
41 * usually, but not always, >= 0x8000) or the name string, which is
42 * a 2-byte string.
43 * @see str2guid() for how to get a GUID structure from a C string
44 * @see str2ustr() for how to get a 2-byte string from a C string. */
45 struct PropertyKey
47 PropertyKey()
48 { tag = 0; name_id = 0; }
49 PropertyKey(uint32_t t)
50 { tag = t; name_id = 0; }
51 PropertyKey(const string &g, uint32_t id)
52 { tag = 0; guid = g; name_id = id; }
53 PropertyKey(const string &g, const string &n)
54 { tag = 0; guid = g; name_id = 0; name_str = n; }
56 uint32_t tag;
57 string guid;
58 string name_str;
59 uint32_t name_id;
61 bool operator==(const PropertyKey &k) const
63 if(k.guid.length() > 0)
64 return guid == k.guid
65 && name_str == k.name_str
66 && name_id == k.name_id;
68 return tag == k.tag;
71 PropertyKey &operator=(const PropertyKey &k)
73 tag = k.tag;
74 guid = k.guid;
75 name_str = k.name_str;
76 name_id = k.name_id;
77 return *this;
81 /** Makes a GUID structure from a C string (or WvString).
82 * Takes a string in the format "ca7331d4-2c89-46a6-a173-eb06ec2367c7"
83 * and makes a GUID structure from it.
84 * @param str String to use for making a GUID.
85 * @return A GUID structure in a std::string. */
86 string str2guid(WvStringParm str);
88 /** Fakes a 2-byte string from a C string (or WvString).
89 * Takes a string and pads it with NULs between each character.
90 * @param str String to use for making "fake" 2-byte string.
91 * @return A "fake" 2-byte string in a std::string. */
92 string str2ustr(WvStringParm str);
94 class WvTnef
96 public:
97 /**
98 * Make a new WvTnef object.
99 * Constructs a new WvTnef object.
100 * @param istream The input stream containing the TNEF.
101 * @param ostream An optional output stream.
103 WvTnef(WvStream *istream, WvStream *ostream = NULL);
105 /**
106 * Make a new WvTnef object.
107 * Constructs a new WvTnef object (with no properties).
109 WvTnef();
111 ~WvTnef();
113 /**
114 * Rewrite a TNEF from the properties currently in memory.
115 * @param filename The file in which to place the re-written TNEF.
116 * @return Whether we were able to successfully re-write the TNEF.
118 bool rewrite(WvStringParm filename);
121 * Remove a single MAPI property.
122 * @param key The key of the property to remove.
123 * @return Whether the property was successfully removed.
125 bool remove_mapi_prop(const PropertyKey &key);
127 /**
128 * Get a single MAPI property.
129 * Looks up a MAPI property in the internal hash table using its
130 * MAPI tag. This will only work, of course, with tags whose
131 * MAPI IDs are less than 0x8000.
132 * @param tag The MAPI tag of the property to get.
133 * @return The value of the MAPI property, or NULL if not found.
135 const WvMapiPart *get_property(const uint32_t tag,
136 const TNEFStoreType store_type = ATT_MAPI_PROPS,
137 const int store_num = 0) const;
139 /**
140 * Get a single MAPI property.
141 * Looks up a MAPI property in the internal hash table using its
142 * MAPI GUID and name ID. This will only work, of course, with
143 * properties whose MAPI IDs are >= 0x8000.
144 * @param guid The MAPI GUID of the property to get.
145 * @param name_id The MAPI name ID of the property to get.
146 * @return The value of the MAPI property, or NULL if not found.
148 const WvMapiPart *get_property(const string &guid,
149 const uint32_t name_id,
150 const TNEFStoreType store_type = ATT_MAPI_PROPS,
151 const int store_num = 0) const;
152 /**
153 * Get a single MAPI property.
154 * Looks up a MAPI property in the internal hash table using its
155 * MAPI GUID and name string. This will only work, of course, with
156 * properties whose MAPI IDs are >= 0x8000.
157 * @param guid The MAPI GUID of the property to get.
158 * @param name_str The MAPI name string of the property to get.
159 * @return The value of the MAPI property, or NULL if not found.
161 const WvMapiPart *get_property(const string &guid,
162 const string &name_str,
163 const TNEFStoreType store_type = ATT_MAPI_PROPS,
164 const int store_num = 0) const;
166 /**
167 * Get a MAPI property list.
168 * Looks up a MAPI property in the internal hash table using its
169 * MAPI tag, and returns all values of that property. This only
170 * really makes sense for multivalue properties.
171 * @param tag The MAPI tag of the property list to get.
172 * @return A list of all the values of the specified property.
174 const WvMapiPartList *get_properties(const uint32_t tag,
175 const TNEFStoreType store_type = ATT_MAPI_PROPS,
176 const int store_num = 0) const;
178 /**
179 * Get a MAPI property list.
180 * Looks up a MAPI property in the internal hash table using its
181 * MAPI GUID and name ID, and returns all values of that property.
182 * This only really makes sense for multivalue properties.
183 * @param guid The MAPI GUID of the property list to get.
184 * @param name_id The MAPI name ID of the property list to get.
185 * @return A list of all the values of the specified property.
187 const WvMapiPartList *get_properties(const string &guid,
188 const uint32_t name_id,
189 const TNEFStoreType store_type = ATT_MAPI_PROPS,
190 const int store_num = 0) const;
192 /**
193 * Get a MAPI property list.
194 * Looks up a MAPI property in the internal hash table using its
195 * MAPI GUID and name string, and returns all values of that property.
196 * This only really makes sense for multivalue properties.
197 * @param guid The MAPI GUID of the property list to get.
198 * @param name_str The MAPI name string of the property list to get.
199 * @return A list of all the values of the specified property.
201 const WvMapiPartList *get_properties(const string &guid,
202 const string &name_str,
203 const TNEFStoreType store_type = ATT_MAPI_PROPS,
204 const int store_num = 0) const;
206 /**
207 * Set a MAPI property.
208 * Sets a MAPI property in the internal hash table using its MAPI tag
209 * for the key. If the property exists, it is overwritten. Otherwise
210 * it is added.
211 * @param tag The MAPI tag of the property to set.
212 * @param value The value of the MAPI property to set.
213 * @return Whether the property was successfully set. */
214 bool set_property(const uint32_t tag, string *value,
215 const TNEFStoreType store_type = ATT_MAPI_PROPS,
216 const int store_num = 0);
218 /**
219 * Set a MAPI property.
220 * Sets a MAPI property in the internal hash table using its MAPI tag
221 * for the key. If the property exists, it is overwritten. Otherwise
222 * it is added.
223 * @param tag The MAPI tag of the property to set.
224 * @param value The value of the MAPI property to set.
225 * @return Whether the property was successfully set. */
226 bool set_property(const uint32_t tag, const char *value,
227 const TNEFStoreType store_type = ATT_MAPI_PROPS,
228 const int store_num = 0);
230 /** Sets a MAPI property.
231 * Sets a MAPI property in the internal hash table using its MAPI
232 * GUID and name ID for the key. If the property exists, it is
233 * overwritten. Otherwise it is added.
234 * @param guid The MAPI GUID of the property to set.
235 * @param name_id The MAPI name ID of the property to set.
236 * @param value The value of the MAPI property to set.
237 * WvTnef takes ownership of this string.
238 * @return Whether the property was successfully set. */
239 bool set_property(const string &guid, const uint32_t name_id,
240 string *value, const uint32_t mapi_type,
241 const TNEFStoreType store_type = ATT_MAPI_PROPS,
242 const int store_num = 0);
244 /** Sets a MAPI property.
245 * Sets a MAPI property in the internal hash table using its MAPI
246 * GUID and name ID for the key. If the property exists, it is
247 * overwritten. Otherwise it is added.
248 * @param guid The MAPI GUID of the property to set.
249 * @param name_id The MAPI name ID of the property to set.
250 * @param value The value of the MAPI property to set.
251 * WvTnef takes ownership of this string.
252 * @return Whether the property was successfully set. */
253 bool set_property(const string &guid, const uint32_t name_id,
254 const char *value, const uint32_t mapi_type,
255 const TNEFStoreType store_type = ATT_MAPI_PROPS,
256 const int store_num = 0);
258 /** Sets a MAPI property.
259 * Sets a MAPI property in the internal hash table using its MAPI
260 * GUID and name string for the key. If the property exists, it is
261 * overwritten. Otherwise it is added.
262 * @param guid The MAPI GUID of the property to set.
263 * @param name_str The MAPI name string of the property to set.
264 * @param value The value of the MAPI property to set.
265 * WvTnef takes ownership of this string.
266 * @return Whether the property was successfully set. */
267 bool set_property(const string &guid, const string &name_str,
268 string *value, const uint32_t mapi_type,
269 const TNEFStoreType store_type = ATT_MAPI_PROPS,
270 const int store_num = 0);
272 /** Sets a MAPI property.
273 * Sets a MAPI property in the internal hash table using its MAPI
274 * GUID and name string for the key. If the property exists, it is
275 * overwritten. Otherwise it is added.
276 * @param guid The MAPI GUID of the property to set.
277 * @param name_str The MAPI name string of the property to set.
278 * @param value The value of the MAPI property to set.
279 * WvTnef takes ownership of this string.
280 * @return Whether the property was successfully set. */
281 bool set_property(const string &guid, const string &name_str,
282 const char *value, const uint32_t mapi_type,
283 const TNEFStoreType store_type = ATT_MAPI_PROPS,
284 const int store_num = 0);
286 /** Appends a value to a MAPI property list.
287 * Appends a value to the MAPI property in the internal hash table
288 * using its tag for the key. If the property doesn't exist, a new
289 * property is created, with the given value as its first element.
290 * @param tag The MAPI tag of the property list.
291 * @param value The value of the MAPI property to append.
292 * WvTnef takes ownership of this string.
293 * @return Whether the value was successfully appended. */
294 bool append_property(const uint32_t tag, string *value,
295 const TNEFStoreType store_type = ATT_MAPI_PROPS,
296 const int store_num = 0);
298 /** Appends a value to a MAPI property list.
299 * Appends a value to the MAPI property in the internal hash table
300 * using its MAPI GUID and name ID for the key. If the property
301 * doesn't exist, a new property is created, with the given value
302 * as its first element.
303 * @param guid The MAPI GUID of the property list.
304 * @param name_id The MAPI name ID of the property list.
305 * @param value The value of the MAPI property to append.
306 * WvTnef takes ownership of this string.
307 * @return Whether the value was successfully appended. */
308 bool append_property(const string &guid, const uint32_t name_id,
309 string *value, const uint32_t mapi_type,
310 const TNEFStoreType store_type = ATT_MAPI_PROPS,
311 const int store_num = 0);
313 /** Appends a value to a MAPI property list.
314 * Appends a value to the MAPI property in the internal hash table
315 * using its MAPI GUID and name string for the key. If the property
316 * doesn't exist, a new property is created, with the given value
317 * as its first element.
318 * @param guid The MAPI GUID of the property list.
319 * @param name_str The MAPI name string of the property list.
320 * @param value The value of the MAPI property to append.
321 * WvTnef takes ownership of this string.
322 * @return Whether the value was successfully appended. */
323 bool append_property(const string &guid, const string &name_str,
324 string *value, const uint32_t mapi_type,
325 const TNEFStoreType store_type = ATT_MAPI_PROPS,
326 const int store_num = 0);
328 /** Sets a MAPI property list.
329 * Sets the MAPI property list in the internal hash table using
330 * its MAPI tag for the key. If the property doesn't exist, a
331 * a new property is created, with the given list. Otherwise,
332 * the property is overwritten.
333 * @param tag The MAPI tag of the property.
334 * @param value The MAPI property list to set.
335 * WvTnef takes ownership of this list.
336 * @return Whether the value was successfully set. */
337 bool set_properties(const uint32_t tag, WvMapiPartList *list,
338 const TNEFStoreType store_type = ATT_MAPI_PROPS,
339 const int store_num = 0);
341 /** Sets a MAPI property list.
342 * Sets the MAPI property list in the internal hash table using
343 * its MAPI GUID and name ID for the key. If the property doesn't
344 * exist, a new property is created, with the given list.
345 * Otherwise, the property is overwritten.
346 * @param guid The MAPI GUID of the property.
347 * @param name_id The MAPI name ID of the property.
348 * @param value The MAPI property list to set.
349 * WvTnef takes ownership of this list.
350 * @return Whether the value was successfully set. */
351 bool set_properties(const string &guid, const uint32_t name_id,
352 WvMapiPartList *list, const uint32_t mapi_type,
353 const TNEFStoreType store_type = ATT_MAPI_PROPS,
354 const int store_num = 0);
356 /** Sets a MAPI property list.
357 * Sets the MAPI property list in the internal hash table using
358 * its MAPI GUID and name string for the key. If the property
359 * doesn't exist, a new property is created, with the given list.
360 * Otherwise, the property is overwritten.
361 * @param guid The MAPI GUID of the property.
362 * @param name_str The MAPI name string of the property.
363 * @param value The MAPI property list to set.
364 * WvTnef takes ownership of this list.
365 * @return Whether the list was successfully set. */
366 bool set_properties(const string &guid, const string &name_str,
367 WvMapiPartList *list, const uint32_t mapi_type,
368 const TNEFStoreType store_type = ATT_MAPI_PROPS,
369 const int store_num = 0);
371 /** Tells whether the TNEF stream was parsed properly.
372 * In order for this to return true, all checksums must match, the
373 * magic value must be present, etc.
374 * @return Whether the TNEF stream was parsed without errors. */
375 bool isok() const { return _isok; }
377 /** Parse the TNEF stream.
378 * This function will read the TNEF stream and parse it into the
379 * various MAPI properties present.
380 * @param istream The input stream containing the TNEF.
381 * @param ostream An optional output stream.
382 * @return Whether the parsing was successful. */
383 bool parse(WvStream *istream, WvStream *ostream = NULL);
385 /** Dumps a bunch of information about each MAPI property to the log.
386 * An iterator will be used to iterate through the internal hash
387 * table, printing out the MAPI ID, type and a hexdump of the value. */
388 void dump() const;
390 private:
391 typedef WvMap <PropertyKey, WvMapiPartList *, OpEqComp, WvScatterHash> PropertyHash;
392 mutable PropertyHash _properties; // HACK: this should _not_ be mutable
393 mutable WvVector <PropertyHash> _att_properties; // HACK: nor should this
394 mutable WvVector <PropertyHash> _recip_properties; // HACK: nor should this
396 static int _endian_test;
397 static bool _isbigendian;
398 mutable uint16_t _checksum;
399 uint32_t _max_id;
400 mutable WvLog log;
401 bool _isok;
402 mutable WvDynBuf tmp_buf;
405 // Check the checksum value against the one in the TNEF
406 bool check_sum(WvStream *istream, WvStream *ostream);
408 // Check the header of an attribute
409 bool check_header(const void *header);
411 // The heavy lifting happens here
412 bool parse_mapi_properties(WvStream *istream, WvStream *ostream = NULL);
415 /* These functions are all used to write out the TNEF
416 * from our internal structure, modelled off pphaneuf's
417 * TNEF.pm */
418 bool dump_attribute(unsigned char x, uint32_t att, uint32_t size,
419 FILE *file) const;
420 bool dump_attachments(FILE *file) const;
421 bool dump_recip_table(FILE *file) const;
422 bool dump_mapi_properties(FILE *file) const;
425 bool write_mapi_properties(PropertyHash *property_hash, uint32_t &size,
426 FILE *file) const;
428 const void *read_write_chk(const size_t num_bytes,
429 WvStream *istream,
430 WvStream *ostream = NULL) const;
432 // Reading, writing, checksumming independent of byte order
433 int16_t read_write2_chk(WvStream *istream, WvStream *ostream) const;
434 int32_t read_write4_chk(WvStream *istream, WvStream *ostream) const;
435 int64_t read_write8_chk(WvStream *istream, WvStream *ostream) const;
436 uint16_t read_write2u_chk(WvStream *istream, WvStream *ostream) const;
437 uint32_t read_write4u_chk(WvStream *istream, WvStream *ostream) const;
438 uint64_t read_write8u_chk(WvStream *istream, WvStream *ostream) const;
440 const void *read_write(const size_t num_bytes,
441 WvStream *istream,
442 WvStream *ostream = NULL) const;
444 // Reading, writing independent of byte order
445 // FIXME: these should be independant of the TNEF class
446 int16_t read_write2(WvStream *istream, WvStream *ostream) const;
447 int32_t read_write4(WvStream *istream, WvStream *ostream) const;
448 int64_t read_write8(WvStream *istream, WvStream *ostream) const;
449 uint16_t read_write2u(WvStream *istream, WvStream *ostream) const;
450 uint32_t read_write4u(WvStream *istream, WvStream *ostream) const;
451 uint64_t read_write8u(WvStream *istream, WvStream *ostream) const;
453 int16_t read2(FILE *file) const;
454 int32_t read4(FILE *file) const;
455 int64_t read8(FILE *file) const;
456 uint16_t read2u(FILE *file) const;
457 uint32_t read4u(FILE *file) const;
458 uint64_t read8u(FILE *file) const;
460 int16_t read2(WvStream *istream) const { return read_write2(istream, NULL); }
461 int32_t read4(WvStream *istream) const { return read_write4(istream, NULL); }
462 int64_t read8(WvStream *istream) const { return read_write8(istream, NULL); }
463 uint16_t read2u(WvStream *istream) const { return read_write2u(istream, NULL); }
464 uint32_t read4u(WvStream *istream) const { return read_write4u(istream, NULL); }
465 uint64_t read8u(WvStream *istream) const { return read_write8u(istream, NULL); }
467 // Reading 4 bytes from a buffer independent of byte-order
468 uint32_t read4u(WvDynBuf &buf) const;
470 // Appending integers to a buffer
471 uint32_t append2(uint16_t i, FILE *file) const;
472 uint32_t append4(uint32_t i, FILE *file) const;
473 uint32_t append8(uint64_t i, FILE *file) const;
475 // various helper functions for the public get and set property functions
476 const WvMapiPartList * WvTnef::get_properties_real(const PropertyKey key,
477 const TNEFStoreType store_type,
478 const int store_num) const;
479 void remove_property_and_set_tag(PropertyKey &key, const uint32_t mapi_type,
480 PropertyHash *property_hash);
481 void set_property_real(PropertyKey &key, string *value,
482 PropertyHash *property_hash);
483 void append_property_real(PropertyKey &key, string *value,
484 const uint32_t mapi_type,
485 const TNEFStoreType store_type,
486 const int store_num);
487 void set_properties_real(PropertyKey &key, WvMapiPartList *list,
488 const uint32_t mapi_type,
489 const TNEFStoreType store_type,
490 const int store_num);
491 PropertyHash * get_property_hash(const TNEFStoreType store_type,
492 const int store_num) const;
493 public:
494 // Used for some debug messages
495 static WvString inttohex(int value);
497 // Byte swapping functions for big-endian machines
498 static uint64_t swap8(const uint64_t i);
499 static uint32_t swap4(const uint32_t i);
500 static uint16_t swap2(const uint16_t i);
503 extern unsigned WvHash(const string &);
504 extern unsigned WvHash(const PropertyKey &);
506 #endif