1 #ifdef HAVE_CONFIG_H
2     #include "config.h"
3 #endif
4 
5 #include <iostream>
6 #include <boost/python.hpp>
7 // #include <boost/python/docstring_options.hpp>
8 // #include <iostream>
9 
10 extern "C" {
11     #include "libpst.h"
12     #include "timeconv.h"
13     #include "libstrfunc.h"
14     #include "vbuf.h"
15     #include "lzfu.h"
16 }
17 
18 using namespace std;
19 using namespace boost::python;
20 
21 
22 /** Python version of pst_binary, where Python is
23     responsible for freeing the underlying buffer */
24 struct ppst_binary : public pst_binary
25 {
26 };
27 
28 class pst {
29 public:
30                     pst(const string filename, const string charset);
31     virtual         ~pst();
32     pst_desc_tree*  pst_getTopOfFolders();
33     ppst_binary     pst_attach_to_mem(pst_item_attach *attach);
34     size_t          pst_attach_to_file(pst_item_attach *attach, FILE* fp);
35     size_t          pst_attach_to_file_base64(pst_item_attach *attach, FILE* fp);
36     pst_desc_tree*  pst_getNextDptr(pst_desc_tree* d);
37     pst_item*       pst_parse_item(pst_desc_tree *d_ptr, pst_id2_tree *m_head);
38     void            pst_freeItem(pst_item *item);
39     pst_index_ll*   pst_getID(uint64_t i_id);
40     size_t          pst_ff_getIDblock_dec(uint64_t i_id, char **buf);
41     string          pst_rfc2426_escape(char *str);
42     string          pst_rfc2425_datetime_format(const FILETIME *ft);
43     string          pst_rfc2445_datetime_format(const FILETIME *ft);
44     string          pst_default_charset(pst_item *item);
45     void            pst_convert_utf8_null(pst_item *item, pst_string *str);
46     void            pst_convert_utf8(pst_item *item, pst_string *str);
47     pst_recurrence* pst_convert_recurrence(pst_item_appointment *appt);
48     void            pst_free_recurrence(pst_recurrence* r);
49 
50     /** helper for Python access to fopen() */
51     FILE*          ppst_open_file(string filename, string mode);
52     /** helper for Python access to fclose() */
53     int            ppst_close_file(FILE* fp);
54 
55 private:
56     bool            is_open;
57     pst_file        pf;
58     pst_item*       root;
59     pst_desc_tree*  topf;
60 
61 };
62 
63 
pst(const string filename,const string charset)64 pst::pst(const string filename, const string charset) {
65     is_open = (::pst_open(&pf, filename.c_str(), charset.c_str()) == 0);
66     root = NULL;
67     topf = NULL;
68     if (is_open) {
69         ::pst_load_index(&pf);
70         ::pst_load_extended_attributes(&pf);
71         if (pf.d_head) root = ::pst_parse_item(&pf, pf.d_head, NULL);
72         if (root)      topf = ::pst_getTopOfFolders(&pf, root)->child;
73     }
74 }
75 
~pst()76 pst::~pst() {
77     if (root) pst_freeItem(root);
78     if (is_open) ::pst_close(&pf);
79 }
80 
pst_getTopOfFolders()81 pst_desc_tree*  pst::pst_getTopOfFolders() {
82     return topf;
83 }
84 
pst_attach_to_mem(pst_item_attach * attach)85 ppst_binary     pst::pst_attach_to_mem(pst_item_attach *attach) {
86     pst_binary r = ::pst_attach_to_mem(&pf, attach);
87     ppst_binary rc;
88     rc.size = r.size;
89     rc.data = r.data;
90     return rc;
91 }
92 
pst_attach_to_file(pst_item_attach * attach,FILE * fp)93 size_t          pst::pst_attach_to_file(pst_item_attach *attach, FILE* fp) {
94     return ::pst_attach_to_file(&pf, attach, fp);
95 }
96 
pst_attach_to_file_base64(pst_item_attach * attach,FILE * fp)97 size_t          pst::pst_attach_to_file_base64(pst_item_attach *attach, FILE* fp) {
98     return ::pst_attach_to_file_base64(&pf, attach, fp);
99 }
100 
pst_getNextDptr(pst_desc_tree * d)101 pst_desc_tree*  pst::pst_getNextDptr(pst_desc_tree* d) {
102     return ::pst_getNextDptr(d);
103 }
104 
pst_parse_item(pst_desc_tree * d_ptr,pst_id2_tree * m_head)105 pst_item*       pst::pst_parse_item (pst_desc_tree *d_ptr, pst_id2_tree *m_head) {
106     return ::pst_parse_item(&pf, d_ptr, m_head);
107 }
108 
pst_freeItem(pst_item * item)109 void            pst::pst_freeItem(pst_item *item) {
110     return ::pst_freeItem(item);
111 }
112 
pst_getID(uint64_t i_id)113 pst_index_ll*   pst::pst_getID(uint64_t i_id) {
114     return ::pst_getID(&pf, i_id);
115 }
116 
pst_ff_getIDblock_dec(uint64_t i_id,char ** buf)117 size_t          pst::pst_ff_getIDblock_dec(uint64_t i_id, char **buf) {
118     return ::pst_ff_getIDblock_dec(&pf, i_id, buf);
119 }
120 
pst_rfc2426_escape(char * str)121 string          pst::pst_rfc2426_escape(char *str) {
122     char  *result = NULL;
123     size_t resultlen = 0;
124     char  *rc = ::pst_rfc2426_escape(str, &result, &resultlen);
125     string rrc(rc);
126     if (result) free(result);
127     return rrc;
128 }
129 
pst_rfc2425_datetime_format(const FILETIME * ft)130 string          pst::pst_rfc2425_datetime_format(const FILETIME *ft) {
131     char buf[30];
132     ::pst_rfc2425_datetime_format(ft, sizeof(buf), buf);
133     return string(buf);
134 }
135 
pst_rfc2445_datetime_format(const FILETIME * ft)136 string          pst::pst_rfc2445_datetime_format(const FILETIME *ft) {
137     char buf[30];
138     ::pst_rfc2445_datetime_format(ft, sizeof(buf), buf);
139     return string(buf);
140 }
141 
pst_default_charset(pst_item * item)142 string          pst::pst_default_charset(pst_item *item) {
143     char buf[30];
144     return string(::pst_default_charset(item, sizeof(buf), buf));
145 }
146 
pst_convert_utf8_null(pst_item * item,pst_string * str)147 void            pst::pst_convert_utf8_null(pst_item *item, pst_string *str) {
148     ::pst_convert_utf8_null(item, str);
149 }
150 
pst_convert_utf8(pst_item * item,pst_string * str)151 void            pst::pst_convert_utf8(pst_item *item, pst_string *str) {
152     ::pst_convert_utf8(item, str);
153 }
154 
pst_convert_recurrence(pst_item_appointment * appt)155 pst_recurrence* pst::pst_convert_recurrence(pst_item_appointment *appt)
156 {
157     return ::pst_convert_recurrence(appt);
158 }
159 
pst_free_recurrence(pst_recurrence * r)160 void            pst::pst_free_recurrence(pst_recurrence* r)
161 {
162     ::pst_free_recurrence(r);
163 }
164 
ppst_open_file(string filename,string mode)165 FILE*          pst::ppst_open_file(string filename, string mode) {
166     return ::fopen(filename.c_str(), mode.c_str());
167 }
168 
ppst_close_file(FILE * fp)169 int            pst::ppst_close_file(FILE* fp) {
170     return ::fclose(fp);
171 }
172 
173 struct make_python_string {
174     /* we make no distinction between empty and null strings */
convertmake_python_string175     static PyObject* convert(char* const &s) {
176         string ss;
177         if (s) ss = string(s);
178         return boost::python::incref(boost::python::object(ss).ptr());
179     }
180 };
181 
182 struct make_python_pst_binary {
convertmake_python_pst_binary183     static PyObject* convert(pst_binary const &s) {
184         if (s.data) {
185             string ss;
186             ss = string(s.data, s.size);
187             return boost::python::incref(boost::python::object(ss).ptr());
188         }
189         return boost::python::incref(boost::python::object().ptr());
190     }
191 };
192 
193 struct make_python_ppst_binary {
convertmake_python_ppst_binary194     static PyObject* convert(ppst_binary const &s) {
195         if (s.data) {
196             string ss;
197             ss = string(s.data, s.size);
198             free(s.data);
199             return boost::python::incref(boost::python::object(ss).ptr());
200         }
201         return boost::python::incref(boost::python::object().ptr());
202     }
203 };
204 
205 struct make_python_pst_item_email {
convertmake_python_pst_item_email206     static PyObject* convert(pst_item_email* const &s) {
207         if (s) return to_python_indirect<pst_item_email*, detail::make_reference_holder>()(s);
208         return boost::python::incref(boost::python::object().ptr());
209     }
210 };
211 
212 struct make_python_pst_item_attach {
convertmake_python_pst_item_attach213     static PyObject* convert(pst_item_attach* const &s) {
214         if (s) return to_python_indirect<pst_item_attach*, detail::make_reference_holder>()(s);
215         return boost::python::incref(boost::python::object().ptr());
216     }
217 };
218 
219 struct make_python_pst_desc_tree {
convertmake_python_pst_desc_tree220     static PyObject* convert(pst_desc_tree* const &s) {
221         if (s) return to_python_indirect<pst_desc_tree*, detail::make_reference_holder>()(s);
222         return boost::python::incref(boost::python::object().ptr());
223     }
224 };
225 
226 struct make_python_pst_index_ll {
convertmake_python_pst_index_ll227     static PyObject* convert(pst_index_ll* const &s) {
228         if (s) return to_python_indirect<pst_index_ll*, detail::make_reference_holder>()(s);
229         return boost::python::incref(boost::python::object().ptr());
230     }
231 };
232 
233 struct make_python_FILE {
convertmake_python_FILE234     static PyObject* convert(FILE* const &s) {
235         if (s) return to_python_indirect<FILE*, detail::make_reference_holder>()(s);
236         return boost::python::incref(boost::python::object().ptr());
237     }
238 };
239 
BOOST_PYTHON_MODULE(_libpst)240 BOOST_PYTHON_MODULE(_libpst)
241 {
242     //boost::python::docstring_options doc_options();
243 
244     to_python_converter<pst_binary,       make_python_pst_binary>();
245     to_python_converter<ppst_binary,      make_python_ppst_binary>();
246     to_python_converter<char*,            make_python_string>();
247     to_python_converter<pst_item_email*,  make_python_pst_item_email>();
248     to_python_converter<pst_item_attach*, make_python_pst_item_attach>();
249     to_python_converter<pst_desc_tree*,   make_python_pst_desc_tree>();
250     to_python_converter<pst_index_ll*,    make_python_pst_index_ll>();
251     to_python_converter<FILE*,            make_python_FILE>();
252 
253     class_<FILE>("FILE")
254         ;
255 
256     class_<FILETIME>("FILETIME")
257         .def_readwrite("dwLowDateTime",         &FILETIME::dwLowDateTime)
258         .def_readwrite("dwHighDateTime",        &FILETIME::dwHighDateTime)
259         ;
260 
261     class_<pst_entryid>("pst_entryid")
262         .def_readonly("u1",                     &pst_entryid::u1)
263         .def_readonly("entryid",                &pst_entryid::entryid)
264         .def_readonly("id",                     &pst_entryid::id)
265         ;
266 
267     class_<pst_index_ll>("pst_index_ll")
268         .def_readonly("i_id",                   &pst_index_ll::i_id)
269         .def_readonly("offset",                 &pst_index_ll::offset)
270         .def_readonly("size",                   &pst_index_ll::size)
271         .def_readonly("u1",                     &pst_index_ll::u1)
272         ;
273 
274     class_<pst_id2_tree>("pst_id2_tree")
275         .def_readonly("id2",                    &pst_id2_tree::id2)
276         .add_property("id",                     make_getter(&pst_id2_tree::id,    return_value_policy<reference_existing_object>()))
277         .add_property("child",                  make_getter(&pst_id2_tree::child, return_value_policy<reference_existing_object>()))
278         .add_property("next",                   make_getter(&pst_id2_tree::next,  return_value_policy<reference_existing_object>()))
279         ;
280 
281     class_<pst_desc_tree>("pst_desc_tree")
282         .def_readonly("d_id",                   &pst_desc_tree::d_id)
283         .def_readonly("parent_d_id",            &pst_desc_tree::parent_d_id)
284         .add_property("desc",                   make_getter(&pst_desc_tree::desc,       return_value_policy<reference_existing_object>()))
285         .add_property("assoc_tree",             make_getter(&pst_desc_tree::assoc_tree, return_value_policy<reference_existing_object>()))
286         .def_readonly("no_child",               &pst_desc_tree::no_child)
287         .add_property("prev",                   make_getter(&pst_desc_tree::prev,       return_value_policy<reference_existing_object>()))
288         .add_property("next",                   make_getter(&pst_desc_tree::next,       return_value_policy<reference_existing_object>()))
289         .add_property("parent",                 make_getter(&pst_desc_tree::parent,     return_value_policy<reference_existing_object>()))
290         .add_property("child",                  make_getter(&pst_desc_tree::child,      return_value_policy<reference_existing_object>()))
291         .add_property("child_tail",             make_getter(&pst_desc_tree::child_tail, return_value_policy<reference_existing_object>()))
292         ;
293 
294     class_<pst_string>("pst_string")
295         .def_readonly("is_utf8",                &pst_string::is_utf8)
296         .def_readonly("str",                    &pst_string::str)
297         ;
298 
299     class_<pst_item_email>("pst_item_email")
300         .add_property("arrival_date",           make_getter(&pst_item_email::arrival_date, return_value_policy<reference_existing_object>()))
301         .def_readonly("autoforward",            &pst_item_email::autoforward)
302         .def_readonly("cc_address",             &pst_item_email::cc_address)
303         .def_readonly("bcc_address",            &pst_item_email::bcc_address)
304         .add_property("conversation_index",     make_getter(&pst_item_email::conversation_index, return_value_policy<return_by_value>()))
305         .def_readonly("conversion_prohibited",  &pst_item_email::conversion_prohibited)
306         .def_readonly("delete_after_submit",    &pst_item_email::delete_after_submit)
307         .def_readonly("delivery_report",        &pst_item_email::delivery_report)
308         .add_property("encrypted_body",         make_getter(&pst_item_email::encrypted_body, return_value_policy<return_by_value>()))
309         .add_property("encrypted_htmlbody",     make_getter(&pst_item_email::encrypted_htmlbody, return_value_policy<return_by_value>()))
310         .def_readonly("header",                 &pst_item_email::header)
311         .def_readonly("htmlbody",               &pst_item_email::htmlbody)
312         .def_readonly("importance",             &pst_item_email::importance)
313         .def_readonly("in_reply_to",            &pst_item_email::in_reply_to)
314         .def_readonly("message_cc_me",          &pst_item_email::message_cc_me)
315         .def_readonly("message_recip_me",       &pst_item_email::message_recip_me)
316         .def_readonly("message_to_me",          &pst_item_email::message_to_me)
317         .def_readonly("messageid",              &pst_item_email::messageid)
318         .def_readonly("original_sensitivity",   &pst_item_email::original_sensitivity)
319         .def_readonly("original_bcc",           &pst_item_email::original_bcc)
320         .def_readonly("original_cc",            &pst_item_email::original_cc)
321         .def_readonly("original_to",            &pst_item_email::original_to)
322         .def_readonly("outlook_recipient",      &pst_item_email::outlook_recipient)
323         .def_readonly("outlook_recipient_name", &pst_item_email::outlook_recipient_name)
324         .def_readonly("outlook_recipient2",     &pst_item_email::outlook_recipient2)
325         .def_readonly("outlook_sender",         &pst_item_email::outlook_sender)
326         .def_readonly("outlook_sender_name",    &pst_item_email::outlook_sender_name)
327         .def_readonly("outlook_sender2",        &pst_item_email::outlook_sender2)
328         .def_readonly("priority",               &pst_item_email::priority)
329         .def_readonly("processed_subject",      &pst_item_email::processed_subject)
330         .def_readonly("read_receipt",           &pst_item_email::read_receipt)
331         .def_readonly("recip_access",           &pst_item_email::recip_access)
332         .def_readonly("recip_address",          &pst_item_email::recip_address)
333         .def_readonly("recip2_access",          &pst_item_email::recip2_access)
334         .def_readonly("recip2_address",         &pst_item_email::recip2_address)
335         .def_readonly("reply_requested",        &pst_item_email::reply_requested)
336         .def_readonly("reply_to",               &pst_item_email::reply_to)
337         .def_readonly("return_path_address",    &pst_item_email::return_path_address)
338         .def_readonly("rtf_body_char_count",    &pst_item_email::rtf_body_char_count)
339         .def_readonly("rtf_body_crc",           &pst_item_email::rtf_body_crc)
340         .def_readonly("rtf_body_tag",           &pst_item_email::rtf_body_tag)
341         .add_property("rtf_compressed",         make_getter(&pst_item_email::rtf_compressed, return_value_policy<return_by_value>()))
342         .def_readonly("rtf_in_sync",            &pst_item_email::rtf_in_sync)
343         .def_readonly("rtf_ws_prefix_count",    &pst_item_email::rtf_ws_prefix_count)
344         .def_readonly("rtf_ws_trailing_count",  &pst_item_email::rtf_ws_trailing_count)
345         .def_readonly("sender_access",          &pst_item_email::sender_access)
346         .def_readonly("sender_address",         &pst_item_email::sender_address)
347         .def_readonly("sender2_access",         &pst_item_email::sender2_access)
348         .def_readonly("sender2_address",        &pst_item_email::sender2_address)
349         .def_readonly("sensitivity",            &pst_item_email::sensitivity)
350         .add_property("sent_date",              make_getter(&pst_item_email::sent_date, return_value_policy<reference_existing_object>()))
351         .add_property("sentmail_folder",        make_getter(&pst_item_email::sentmail_folder, return_value_policy<reference_existing_object>()))
352         .def_readonly("sentto_address",         &pst_item_email::sentto_address)
353         .def_readonly("report_text",            &pst_item_email::report_text)
354         .add_property("report_time",            make_getter(&pst_item_email::report_time, return_value_policy<reference_existing_object>()))
355         .def_readonly("ndr_reason_code",        &pst_item_email::ndr_reason_code)
356         .def_readonly("ndr_diag_code",          &pst_item_email::ndr_diag_code)
357         .def_readonly("supplementary_info",     &pst_item_email::supplementary_info)
358         .def_readonly("ndr_status_code",        &pst_item_email::ndr_status_code)
359         ;
360 
361     class_<pst_item_folder>("pst_item_folder")
362         .def_readonly("item_count",             &pst_item_folder::item_count)
363         .def_readonly("unseen_item_count",      &pst_item_folder::unseen_item_count)
364         .def_readonly("assoc_count",            &pst_item_folder::assoc_count)
365         .def_readonly("subfolder",              &pst_item_folder::subfolder)
366         ;
367 
368     class_<pst_item_message_store>("pst_item_message_store")
369         .add_property("top_of_personal_folder", make_getter(&pst_item_message_store::top_of_personal_folder, return_value_policy<reference_existing_object>()))
370         .add_property("default_outbox_folder",  make_getter(&pst_item_message_store::default_outbox_folder, return_value_policy<reference_existing_object>()))
371         .add_property("deleted_items_folder",   make_getter(&pst_item_message_store::deleted_items_folder, return_value_policy<reference_existing_object>()))
372         .add_property("sent_items_folder",      make_getter(&pst_item_message_store::sent_items_folder, return_value_policy<reference_existing_object>()))
373         .add_property("user_views_folder",      make_getter(&pst_item_message_store::user_views_folder, return_value_policy<reference_existing_object>()))
374         .add_property("common_view_folder",     make_getter(&pst_item_message_store::common_view_folder, return_value_policy<reference_existing_object>()))
375         .add_property("search_root_folder",     make_getter(&pst_item_message_store::search_root_folder, return_value_policy<reference_existing_object>()))
376         .add_property("top_of_folder",          make_getter(&pst_item_message_store::top_of_folder, return_value_policy<reference_existing_object>()))
377         .def_readonly("valid_mask",             &pst_item_message_store::valid_mask)
378         .def_readonly("pwd_chksum",             &pst_item_message_store::pwd_chksum)
379         ;
380 
381     class_<pst_item_contact>("pst_item_contact")
382         .def_readonly("account_name",           &pst_item_contact::account_name)
383         .def_readonly("address1",               &pst_item_contact::address1)
384         .def_readonly("address1a",              &pst_item_contact::address1a)
385         .def_readonly("address1_desc",          &pst_item_contact::address1_desc)
386         .def_readonly("address1_transport",     &pst_item_contact::address1_transport)
387         .def_readonly("address2",               &pst_item_contact::address2)
388         .def_readonly("address2a",              &pst_item_contact::address2a)
389         .def_readonly("address2_desc",          &pst_item_contact::address2_desc)
390         .def_readonly("address2_transport",     &pst_item_contact::address2_transport)
391         .def_readonly("address3",               &pst_item_contact::address3)
392         .def_readonly("address3a",              &pst_item_contact::address3a)
393         .def_readonly("address3_desc",          &pst_item_contact::address3_desc)
394         .def_readonly("address3_transport",     &pst_item_contact::address3_transport)
395         .def_readonly("assistant_name",         &pst_item_contact::assistant_name)
396         .def_readonly("assistant_phone",        &pst_item_contact::assistant_phone)
397         .def_readonly("billing_information",    &pst_item_contact::billing_information)
398         .add_property("birthday",               make_getter(&pst_item_contact::birthday, return_value_policy<reference_existing_object>()))
399         .def_readonly("business_address",       &pst_item_contact::business_address)
400         .def_readonly("business_city",          &pst_item_contact::business_city)
401         .def_readonly("business_country",       &pst_item_contact::business_country)
402         .def_readonly("business_fax",           &pst_item_contact::business_fax)
403         .def_readonly("business_homepage",      &pst_item_contact::business_homepage)
404         .def_readonly("business_phone",         &pst_item_contact::business_phone)
405         .def_readonly("business_phone2",        &pst_item_contact::business_phone2)
406         .def_readonly("business_po_box",        &pst_item_contact::business_po_box)
407         .def_readonly("business_postal_code",   &pst_item_contact::business_postal_code)
408         .def_readonly("business_state",         &pst_item_contact::business_state)
409         .def_readonly("business_street",        &pst_item_contact::business_street)
410         .def_readonly("callback_phone",         &pst_item_contact::callback_phone)
411         .def_readonly("car_phone",              &pst_item_contact::car_phone)
412         .def_readonly("company_main_phone",     &pst_item_contact::company_main_phone)
413         .def_readonly("company_name",           &pst_item_contact::company_name)
414         .def_readonly("computer_name",          &pst_item_contact::computer_name)
415         .def_readonly("customer_id",            &pst_item_contact::customer_id)
416         .def_readonly("def_postal_address",     &pst_item_contact::def_postal_address)
417         .def_readonly("department",             &pst_item_contact::department)
418         .def_readonly("display_name_prefix",    &pst_item_contact::display_name_prefix)
419         .def_readonly("first_name",             &pst_item_contact::first_name)
420         .def_readonly("followup",               &pst_item_contact::followup)
421         .def_readonly("free_busy_address",      &pst_item_contact::free_busy_address)
422         .def_readonly("ftp_site",               &pst_item_contact::ftp_site)
423         .def_readonly("fullname",               &pst_item_contact::fullname)
424         .def_readonly("gender",                 &pst_item_contact::gender)
425         .def_readonly("gov_id",                 &pst_item_contact::gov_id)
426         .def_readonly("hobbies",                &pst_item_contact::hobbies)
427         .def_readonly("home_address",           &pst_item_contact::home_address)
428         .def_readonly("home_city",              &pst_item_contact::home_city)
429         .def_readonly("home_country",           &pst_item_contact::home_country)
430         .def_readonly("home_fax",               &pst_item_contact::home_fax)
431         .def_readonly("home_phone",             &pst_item_contact::home_phone)
432         .def_readonly("home_phone2",            &pst_item_contact::home_phone2)
433         .def_readonly("home_po_box",            &pst_item_contact::home_po_box)
434         .def_readonly("home_postal_code",       &pst_item_contact::home_postal_code)
435         .def_readonly("home_state",             &pst_item_contact::home_state)
436         .def_readonly("home_street",            &pst_item_contact::home_street)
437         .def_readonly("initials",               &pst_item_contact::initials)
438         .def_readonly("isdn_phone",             &pst_item_contact::isdn_phone)
439         .def_readonly("job_title",              &pst_item_contact::job_title)
440         .def_readonly("keyword",                &pst_item_contact::keyword)
441         .def_readonly("language",               &pst_item_contact::language)
442         .def_readonly("location",               &pst_item_contact::location)
443         .def_readonly("mail_permission",        &pst_item_contact::mail_permission)
444         .def_readonly("manager_name",           &pst_item_contact::manager_name)
445         .def_readonly("middle_name",            &pst_item_contact::middle_name)
446         .def_readonly("mileage",                &pst_item_contact::mileage)
447         .def_readonly("mobile_phone",           &pst_item_contact::mobile_phone)
448         .def_readonly("nickname",               &pst_item_contact::nickname)
449         .def_readonly("office_loc",             &pst_item_contact::office_loc)
450         .def_readonly("common_name",            &pst_item_contact::common_name)
451         .def_readonly("org_id",                 &pst_item_contact::org_id)
452         .def_readonly("other_address",          &pst_item_contact::other_address)
453         .def_readonly("other_city",             &pst_item_contact::other_city)
454         .def_readonly("other_country",          &pst_item_contact::other_country)
455         .def_readonly("other_phone",            &pst_item_contact::other_phone)
456         .def_readonly("other_po_box",           &pst_item_contact::other_po_box)
457         .def_readonly("other_postal_code",      &pst_item_contact::other_postal_code)
458         .def_readonly("other_state",            &pst_item_contact::other_state)
459         .def_readonly("other_street",           &pst_item_contact::other_street)
460         .def_readonly("pager_phone",            &pst_item_contact::pager_phone)
461         .def_readonly("personal_homepage",      &pst_item_contact::personal_homepage)
462         .def_readonly("pref_name",              &pst_item_contact::pref_name)
463         .def_readonly("primary_fax",            &pst_item_contact::primary_fax)
464         .def_readonly("primary_phone",          &pst_item_contact::primary_phone)
465         .def_readonly("profession",             &pst_item_contact::profession)
466         .def_readonly("radio_phone",            &pst_item_contact::radio_phone)
467         .def_readonly("rich_text",              &pst_item_contact::rich_text)
468         .def_readonly("spouse_name",            &pst_item_contact::spouse_name)
469         .def_readonly("suffix",                 &pst_item_contact::suffix)
470         .def_readonly("surname",                &pst_item_contact::surname)
471         .def_readonly("telex",                  &pst_item_contact::telex)
472         .def_readonly("transmittable_display_name", &pst_item_contact::transmittable_display_name)
473         .def_readonly("ttytdd_phone",               &pst_item_contact::ttytdd_phone)
474         .add_property("wedding_anniversary",        make_getter(&pst_item_contact::wedding_anniversary, return_value_policy<reference_existing_object>()))
475         .def_readonly("work_address_street",        &pst_item_contact::work_address_street)
476         .def_readonly("work_address_city",          &pst_item_contact::work_address_city)
477         .def_readonly("work_address_state",         &pst_item_contact::work_address_state)
478         .def_readonly("work_address_postalcode",    &pst_item_contact::work_address_postalcode)
479         .def_readonly("work_address_country",       &pst_item_contact::work_address_country)
480         .def_readonly("work_address_postofficebox", &pst_item_contact::work_address_postofficebox)
481         ;
482 
483     class_<pst_item_attach>("pst_item_attach")
484         .def_readonly("filename1",              &pst_item_attach::filename1)
485         .def_readonly("filename2",              &pst_item_attach::filename2)
486         .def_readonly("mimetype",               &pst_item_attach::mimetype)
487         .add_property("data",                   make_getter(&pst_item_attach::data, return_value_policy<return_by_value>()))
488         .def_readonly("id2_val",                &pst_item_attach::id2_val)
489         .def_readonly("i_id",                   &pst_item_attach::i_id)
490         .add_property("id2_head",               make_getter(&pst_item_attach::id2_head, return_value_policy<reference_existing_object>()))
491         .def_readonly("method",                 &pst_item_attach::method)
492         .def_readonly("position",               &pst_item_attach::position)
493         .def_readonly("sequence",               &pst_item_attach::sequence)
494         .add_property("next",                   make_getter(&pst_item_attach::next, return_value_policy<reference_existing_object>()))
495         ;
496 
497     class_<pst_item_extra_field>("pst_item_extra_field")
498         .def_readonly("field_name",             &pst_item_extra_field::field_name)
499         .def_readonly("value",                  &pst_item_extra_field::value)
500         .add_property("next",                   make_getter(&pst_item_extra_field::next, return_value_policy<reference_existing_object>()))
501         ;
502 
503     class_<pst_item_journal>("pst_item_journal")
504         .add_property("start",                  make_getter(&pst_item_journal::start, return_value_policy<reference_existing_object>()))
505         .add_property("end",                    make_getter(&pst_item_journal::end, return_value_policy<reference_existing_object>()))
506         .def_readonly("type",                   &pst_item_journal::type)
507         .def_readonly("description",            &pst_item_journal::description)
508         ;
509 
510     class_<pst_recurrence>("pst_recurrence")
511         .def_readonly("signature",              &pst_recurrence::signature)
512         .def_readonly("type",                   &pst_recurrence::type)
513         .def_readonly("sub_type",               &pst_recurrence::sub_type)
514         .def_readonly("parm1",                  &pst_recurrence::parm1)
515         .def_readonly("parm2",                  &pst_recurrence::parm2)
516         .def_readonly("parm3",                  &pst_recurrence::parm3)
517         .def_readonly("parm4",                  &pst_recurrence::parm4)
518         .def_readonly("parm5",                  &pst_recurrence::parm5)
519         .def_readonly("termination",            &pst_recurrence::termination)
520         .def_readonly("interval",               &pst_recurrence::interval)
521         .def_readonly("bydaymask",              &pst_recurrence::bydaymask)
522         .def_readonly("dayofmonth",             &pst_recurrence::dayofmonth)
523         .def_readonly("monthofyear",            &pst_recurrence::monthofyear)
524         .def_readonly("position",               &pst_recurrence::position)
525         .def_readonly("count",                  &pst_recurrence::count)
526         ;
527 
528     class_<pst_item_appointment>("pst_item_appointment")
529         .add_property("start",                  make_getter(&pst_item_appointment::start, return_value_policy<reference_existing_object>()))
530         .add_property("end",                    make_getter(&pst_item_appointment::end, return_value_policy<reference_existing_object>()))
531         .def_readonly("location",               &pst_item_appointment::location)
532         .def_readonly("alarm",                  &pst_item_appointment::alarm)
533         .add_property("reminder",               make_getter(&pst_item_appointment::reminder, return_value_policy<reference_existing_object>()))
534         .def_readonly("alarm_minutes",          &pst_item_appointment::alarm_minutes)
535         .def_readonly("alarm_filename",         &pst_item_appointment::alarm_filename)
536         .def_readonly("timezonestring",         &pst_item_appointment::timezonestring)
537         .def_readonly("showas",                 &pst_item_appointment::showas)
538         .def_readonly("label",                  &pst_item_appointment::label)
539         .def_readonly("all_day",                &pst_item_appointment::all_day)
540         .def_readonly("is_recurring",           &pst_item_appointment::is_recurring)
541         .def_readonly("recurrence_type",        &pst_item_appointment::recurrence_type)
542         .def_readonly("recurrence_description", &pst_item_appointment::recurrence_description)
543         .add_property("recurrence_data",        make_getter(&pst_item_appointment::recurrence_data, return_value_policy<return_by_value>()))
544         .add_property("recurrence_start",       make_getter(&pst_item_appointment::recurrence_start, return_value_policy<reference_existing_object>()))
545         .add_property("recurrence_end",         make_getter(&pst_item_appointment::recurrence_end, return_value_policy<reference_existing_object>()))
546         ;
547 
548     class_<pst_item>("pst_item")
549         .add_property("email",                  make_getter(&pst_item::email,         return_value_policy<reference_existing_object>()))
550         .add_property("folder",                 make_getter(&pst_item::folder,        return_value_policy<reference_existing_object>()))
551         .add_property("contact",                make_getter(&pst_item::contact,       return_value_policy<reference_existing_object>()))
552         .add_property("attach",                 make_getter(&pst_item::attach,        return_value_policy<reference_existing_object>()))
553         .add_property("message_store",          make_getter(&pst_item::message_store, return_value_policy<reference_existing_object>()))
554         .add_property("extra_fields",           make_getter(&pst_item::extra_fields,  return_value_policy<reference_existing_object>()))
555         .add_property("journal",                make_getter(&pst_item::journal,       return_value_policy<reference_existing_object>()))
556         .add_property("appointment",            make_getter(&pst_item::appointment,   return_value_policy<reference_existing_object>()))
557         .def_readonly("block_id",               &pst_item::block_id)
558         .def_readonly("type",                   &pst_item::type)
559         .def_readonly("ascii_type",             &pst_item::ascii_type)
560         .def_readonly("flags",                  &pst_item::flags)
561         .def_readonly("file_as",                &pst_item::file_as)
562         .def_readonly("comment",                &pst_item::comment)
563         .def_readonly("body_charset",           &pst_item::body_charset)
564         .def_readonly("body",                   &pst_item::body)
565         .def_readonly("subject",                &pst_item::subject)
566         .def_readonly("internet_cpid",          &pst_item::internet_cpid)
567         .def_readonly("message_codepage",       &pst_item::message_codepage)
568         .def_readonly("message_size",           &pst_item::message_size)
569         .def_readonly("outlook_version",        &pst_item::outlook_version)
570         .add_property("record_key",             make_getter(&pst_item::record_key, return_value_policy<return_by_value>()))
571         .add_property("predecessor_change",     make_getter(&pst_item::predecessor_change, return_value_policy<return_by_value>()))
572         .def_readonly("response_requested",     &pst_item::response_requested)
573         .add_property("create_date",            make_getter(&pst_item::create_date, return_value_policy<reference_existing_object>()))
574         .add_property("modify_date",            make_getter(&pst_item::modify_date, return_value_policy<reference_existing_object>()))
575         .def_readonly("private_member",         &pst_item::private_member)
576         ;
577 
578     class_<pst_x_attrib_ll>("pst_x_attrib_ll")
579         .def_readonly("mytype",                 &pst_x_attrib_ll::mytype)
580         .def_readonly("map",                    &pst_x_attrib_ll::map)
581         .def_readonly("data",                   &pst_x_attrib_ll::data)
582         .add_property("next",                   make_getter(&pst_x_attrib_ll::next, return_value_policy<reference_existing_object>()))
583         ;
584 
585     class_<pst_file>("pst_file")
586         .def_readonly("cwd",                    &pst_file::cwd)
587         .def_readonly("fname",                  &pst_file::fname)
588         .add_property("d_head",                 make_getter(&pst_file::d_head, return_value_policy<reference_existing_object>()))
589         .add_property("d_tail",                 make_getter(&pst_file::d_tail, return_value_policy<reference_existing_object>()))
590         .add_property("x_head",                 make_getter(&pst_file::x_head, return_value_policy<reference_existing_object>()))
591         .def_readonly("do_read64",              &pst_file::do_read64)
592         .def_readonly("index1",                 &pst_file::index1)
593         .def_readonly("index1_back",            &pst_file::index1_back)
594         .def_readonly("index2",                 &pst_file::index2)
595         .def_readonly("index2_back",            &pst_file::index2_back)
596         .def_readonly("size",                   &pst_file::size)
597         .def_readonly("encryption",             &pst_file::encryption)
598         .def_readonly("ind_type",               &pst_file::ind_type)
599         ;
600 
601     class_<pst>("pst", init<string,string>())
602         .def("pst_getTopOfFolders",             &pst::pst_getTopOfFolders, return_value_policy<reference_existing_object>())
603         .def("pst_attach_to_mem",               &pst::pst_attach_to_mem)
604         .def("pst_attach_to_file",              &pst::pst_attach_to_file)
605         .def("pst_attach_to_file_base64",       &pst::pst_attach_to_file_base64)
606         .def("pst_getNextDptr",                 &pst::pst_getNextDptr,     return_value_policy<reference_existing_object>())
607         .def("pst_parse_item",                  &pst::pst_parse_item,      return_value_policy<reference_existing_object>())
608         .def("pst_freeItem",                    &pst::pst_freeItem)
609         .def("pst_getID",                       &pst::pst_getID,           return_value_policy<reference_existing_object>())
610         .def("pst_ff_getIDblock_dec",           &pst::pst_ff_getIDblock_dec)
611         .def("pst_rfc2426_escape",              &pst::pst_rfc2426_escape)
612         .def("pst_rfc2425_datetime_format",     &pst::pst_rfc2425_datetime_format)
613         .def("pst_rfc2445_datetime_format",     &pst::pst_rfc2445_datetime_format)
614         .def("pst_default_charset",             &pst::pst_default_charset)
615         .def("pst_convert_utf8_null",           &pst::pst_convert_utf8_null)
616         .def("pst_convert_utf8",                &pst::pst_convert_utf8)
617         .def("ppst_open_file",                  &pst::ppst_open_file,      return_value_policy<reference_existing_object>())
618         .def("ppst_close_file",                 &pst::ppst_close_file)
619         ;
620 }
621 
622 
623