# HG changeset patch # User Carl Byington # Date 1239647973 25200 # Node ID b65e8d0a088a979f8f4bff1c8a5d3774250aa855 # Parent 3b04745ff76da97c2bdae0489537657c4da64d16 more cleanup on external names in the shared object file diff -r 3b04745ff76d -r b65e8d0a088a ChangeLog --- a/ChangeLog Fri Apr 10 13:10:14 2009 -0700 +++ b/ChangeLog Mon Apr 13 11:39:33 2009 -0700 @@ -1,8 +1,9 @@ -LibPST 0.6.36 (2009-04-10) +LibPST 0.6.36 (2009-04-13) =============================== * spec file cleanup with multiple sub packages. * add doxygen devel-doc documentation for the shared library. * switch back to fully versioned subpackage dependencies. + * more cleanup on external names in the shared object file. LibPST 0.6.35 (2009-04-08) =============================== diff -r 3b04745ff76d -r b65e8d0a088a NEWS --- a/NEWS Fri Apr 10 13:10:14 2009 -0700 +++ b/NEWS Mon Apr 13 11:39:33 2009 -0700 @@ -1,4 +1,4 @@ -0.6.36 2009-04-10 build separate -doc and -devel-doc subpackages +0.6.36 2009-04-13 build separate -doc and -devel-doc subpackages 0.6.35 2009-04-08 properly add trailing mime boundary in all modes, build separate rpms with libpst.so shared. 0.6.34 2009-03-19 avoid putting mixed item types into the same output folder 0.6.33 2009-03-17 fix utf-7 conversions, don't produce empty attachment files in separate mode diff -r 3b04745ff76d -r b65e8d0a088a README --- a/README Fri Apr 10 13:10:14 2009 -0700 +++ b/README Mon Apr 13 11:39:33 2009 -0700 @@ -9,7 +9,7 @@ Starting with a mercurial working directory, try this: make -f *cvs - ./configure + ./configure --enable-libpst-shared (cd xml; make; make distclean) make distcheck diff -r 3b04745ff76d -r b65e8d0a088a html/Makefile.am --- a/html/Makefile.am Fri Apr 10 13:10:14 2009 -0700 +++ b/html/Makefile.am Mon Apr 13 11:39:33 2009 -0700 @@ -1,5 +1,6 @@ htmldir = ${datadir}/doc/@PACKAGE@-@VERSION@ -htmldeveldir = ${datadir}/doc/@PACKAGE@-@VERSION@-devel +htmldeveldir = ${datadir}/doc/@PACKAGE@-@VERSION@/devel html_DATA = $(wildcard *.html) $(wildcard *.pdf) htmldevel_DATA = $(wildcard devel/*) EXTRA_DIST = $(html_DATA) $(htmldevel_DATA) + diff -r 3b04745ff76d -r b65e8d0a088a libpst.spec.in --- a/libpst.spec.in Fri Apr 10 13:10:14 2009 -0700 +++ b/libpst.spec.in Mon Apr 13 11:39:33 2009 -0700 @@ -44,6 +44,7 @@ %package devel-doc Summary: Documentation for libpst.so for libpst application development Group: Documentation +Requires: %{name}-doc = %{version}-%{release} %description devel-doc The libpst-devel-doc package contains the doxygen generated @@ -101,7 +102,7 @@ %files devel-doc %defattr(-,root,root,-) -%{_datadir}/doc/%{name}-%{version}-devel/ +%{_datadir}/doc/%{name}-%{version}/devel/ %files devel @@ -113,12 +114,18 @@ %files doc %defattr(-,root,root,-) -%{_datadir}/doc/%{name}-%{version}/ - +%dir %{_datadir}/doc/%{name}-%{version}/ +%{_datadir}/doc/%{name}-%{version}/*.html +%{_datadir}/doc/%{name}-%{version}/*.pdf +%{_datadir}/doc/%{name}-%{version}/AUTHORS +%{_datadir}/doc/%{name}-%{version}/COPYING +%{_datadir}/doc/%{name}-%{version}/ChangeLog +%{_datadir}/doc/%{name}-%{version}/NEWS +%{_datadir}/doc/%{name}-%{version}/README %changelog -* Fri Apr 10 2009 Carl Byington - 0.6.36-1 +* Mon Apr 13 2009 Carl Byington - 0.6.36-1 - build separate -doc and -devel-doc subpackages. - other spec file cleanup diff -r 3b04745ff76d -r b65e8d0a088a src/common.h --- a/src/common.h Fri Apr 10 13:10:14 2009 -0700 +++ b/src/common.h Mon Apr 13 11:39:33 2009 -0700 @@ -1,6 +1,6 @@ -#ifndef __COMMON_H -#define __COMMON_H +#ifndef __PST_COMMON_H +#define __PST_COMMON_H #include @@ -24,13 +24,9 @@ #ifndef _WIN32 - typedef uint32_t DWORD; - typedef uint16_t WORD; - typedef uint8_t BYTE; - typedef uint32_t UINT32; - typedef struct { // copied from wine - DWORD dwLowDateTime; - DWORD dwHighDateTime; + typedef struct { + uint32_t dwLowDateTime; + uint32_t dwHighDateTime; } FILETIME; // According to Jan Wolter, sys/param.h is the most portable source of endian // information on UNIX systems. see http://www.unixpapa.com/incnote/byteorder.html diff -r 3b04745ff76d -r b65e8d0a088a src/libpst.c --- a/src/libpst.c Fri Apr 10 13:10:14 2009 -0700 +++ b/src/libpst.c Mon Apr 13 11:39:33 2009 -0700 @@ -1673,15 +1673,11 @@ if (table_rec.ref_type == (uint16_t)0x1f) { // there is more to do for the type 0x1f unicode strings size_t rc; - static vbuf *utf16buf = NULL; - static vbuf *utf8buf = NULL; + static pst_vbuf *utf16buf = NULL; + static pst_vbuf *utf8buf = NULL; if (!utf16buf) utf16buf = pst_vballoc((size_t)1024); if (!utf8buf) utf8buf = pst_vballoc((size_t)1024); - // splint barfed on the following lines - //VBUF_STATIC(utf16buf, 1024); - //VBUF_STATIC(utf8buf, 1024); - //need UTF-16 zero-termination pst_vbset(utf16buf, mo_ptr->elements[x]->data, mo_ptr->elements[x]->size); pst_vbappend(utf16buf, "\0\0", (size_t)2); @@ -3934,44 +3930,6 @@ } -#ifdef _WIN32 -char * pst_fileTimeToAscii(const FILETIME* filetime) { - time_t t; - DEBUG_ENT("pst_fileTimeToAscii"); - t = pst_fileTimeToUnixTime(filetime, 0); - if (t == -1) - DEBUG_WARN(("ERROR time_t varible that was produced, is -1\n")); - DEBUG_RET(); - return ctime(&t); -} - - -time_t pst_fileTimeToUnixTime(const FILETIME* filetime, DWORD *x) { - SYSTEMTIME s; - struct tm t; - DEBUG_ENT("pst_fileTimeToUnixTime"); - memset (&t, 0, sizeof(struct tm)); - FileTimeToSystemTime(filetime, &s); - t.tm_year = s.wYear-1900; // this is what is required - t.tm_mon = s.wMonth-1; // also required! It made me a bit confused - t.tm_mday = s.wDay; - t.tm_hour = s.wHour; - t.tm_min = s.wMinute; - t.tm_sec = s.wSecond; - DEBUG_RET(); - return mktime(&t); -} - - -struct tm * pst_fileTimeToStructTM (const FILETIME *filetime) { - time_t t1; - t1 = pst_fileTimeToUnixTime(filetime, 0); - return gmtime(&t1); -} - - -#endif //_WIN32 - static int pst_stricmp(char *a, char *b) { // compare strings case-insensitive. // returns -1 if a < b, 0 if a==b, 1 if a > b @@ -4215,7 +4173,7 @@ const char *charset = pst_default_charset(item); if (!strcasecmp("utf-8", charset)) return; // already utf8 DEBUG_ENT("pst_convert_utf8"); - vbuf *newer = pst_vballoc(2); + pst_vbuf *newer = pst_vballoc(2); size_t rc = pst_vb_8bit2utf8(newer, str->str, strlen(str->str) + 1, charset); if (rc == (size_t)-1) { free(newer->b); diff -r 3b04745ff76d -r b65e8d0a088a src/libpst.h --- a/src/libpst.h Fri Apr 10 13:10:14 2009 -0700 +++ b/src/libpst.h Mon Apr 13 11:39:33 2009 -0700 @@ -7,8 +7,8 @@ // LibPST - Library for Accessing Outlook .pst files // Dave Smith - davesmith@users.sourceforge.net -#ifndef LIBPST_H -#define LIBPST_H +#ifndef __PST_LIBPST_H +#define __PST_LIBPST_H #include "common.h" @@ -647,4 +647,4 @@ -#endif // defined LIBPST_H +#endif diff -r 3b04745ff76d -r b65e8d0a088a src/libstrfunc.h --- a/src/libstrfunc.h Fri Apr 10 13:10:14 2009 -0700 +++ b/src/libstrfunc.h Mon Apr 13 11:39:33 2009 -0700 @@ -1,4 +1,12 @@ + +#ifndef __PST_LIBSTRFUNC_H +#define __PST_LIBSTRFUNC_H + #include "common.h" + char *pst_base64_encode(void *data, size_t size); char *pst_base64_encode_multiple(void *data, size_t size, int *line_count); void pst_hexdump(char *hbuf, int start, int stop, int ascii); + +#endif + diff -r 3b04745ff76d -r b65e8d0a088a src/pst2dii.cpp.in --- a/src/pst2dii.cpp.in Fri Apr 10 13:10:14 2009 -0700 +++ b/src/pst2dii.cpp.in Mon Apr 13 11:39:33 2009 -0700 @@ -480,7 +480,7 @@ if (mybcc.empty()) write_simple("BCC", item->email->bcc_address.str); else write_simple("BCC", mybcc); if (item->email->sent_date) { - time_t t = pst_fileTimeToUnixTime(item->email->sent_date, NULL); + time_t t = pst_fileTimeToUnixTime(item->email->sent_date); char c_time[C_TIME_SIZE]; strftime(c_time, C_TIME_SIZE, "%F", gmtime(&t)); write_simple("DATESENT", c_time); @@ -488,7 +488,7 @@ write_simple("TIMESENT", c_time); } if (item->email->arrival_date) { - time_t t = pst_fileTimeToUnixTime(item->email->arrival_date, NULL); + time_t t = pst_fileTimeToUnixTime(item->email->arrival_date); char c_time[C_TIME_SIZE]; strftime(c_time, C_TIME_SIZE, "%F", gmtime(&t)); write_simple("DATERCVD", c_time); @@ -540,7 +540,7 @@ } if (item->email->sent_date) { - time_t em_time = pst_fileTimeToUnixTime(item->email->sent_date, 0); + time_t em_time = pst_fileTimeToUnixTime(item->email->sent_date); char c_time[C_TIME_SIZE]; strftime(c_time, C_TIME_SIZE, "%a, %d %b %Y %H:%M:%S %z", gmtime(&em_time)); snprintf(line, sizeof(line), "Date: %s\n", c_time); diff -r 3b04745ff76d -r b65e8d0a088a src/readpst.c --- a/src/readpst.c Fri Apr 10 13:10:14 2009 -0700 +++ b/src/readpst.c Mon Apr 13 11:39:33 2009 -0700 @@ -1054,7 +1054,7 @@ // and is now in utf-8. size_t rc; DEBUG_EMAIL(("Convert %s utf-8 to %s\n", mime, charset)); - vbuf *newer = pst_vballoc(2); + pst_vbuf *newer = pst_vballoc(2); rc = pst_vb_utf8to8bit(newer, body->str, strlen(body->str), charset); if (rc == (size_t)-1) { // unable to convert, change the charset to utf8 @@ -1130,7 +1130,7 @@ // convert the sent date if it exists, or set it to a fixed date if (item->email->sent_date) { - em_time = pst_fileTimeToUnixTime(item->email->sent_date, 0); + em_time = pst_fileTimeToUnixTime(item->email->sent_date); c_time = ctime(&em_time); if (c_time) c_time[strlen(c_time)-1] = '\0'; //remove end \n diff -r 3b04745ff76d -r b65e8d0a088a src/timeconv.c --- a/src/timeconv.c Fri Apr 10 13:10:14 2009 -0700 +++ b/src/timeconv.c Mon Apr 13 11:39:33 2009 -0700 @@ -1,126 +1,32 @@ -/*********************************************************************** - * - * Borrowed from WINE sources!! (http://www.winehq.com) - * Converts a Win32 FILETIME structure to a UNIX time_t value - */ - -/*** WARNING **** - * This file is not to be included in a Visual C++ Project - * It will make the whole project fail to compile - * There are functions in libpst.c to handle the dates - * Do not use this one - */ - -#ifndef _WIN32 - #include "define.h" -char * pst_fileTimeToAscii (const FILETIME *filetime) { - time_t t1; + - t1 = pst_fileTimeToUnixTime(filetime, NULL); - return ctime(&t1); +char * pst_fileTimeToAscii(const FILETIME* filetime) { + time_t t; + t = pst_fileTimeToUnixTime(filetime); + return ctime(&t); } + struct tm * pst_fileTimeToStructTM (const FILETIME *filetime) { time_t t1; - t1 = pst_fileTimeToUnixTime(filetime, NULL); + t1 = pst_fileTimeToUnixTime(filetime); return gmtime(&t1); } -/*********************************************************************** - * DOSFS_FileTimeToUnixTime - * - * Convert a FILETIME format to Unix time. - * If not NULL, 'remainder' contains the fractional part of the filetime, - * in the range of [0..9999999] (even if time_t is negative). - */ -time_t pst_fileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder ) + +time_t pst_fileTimeToUnixTime(const FILETIME *filetime) { - /* Read the comment in the function DOSFS_UnixTimeToFileTime. */ -#if USE_LONG_LONG - - long long int t = filetime->dwHighDateTime; + int64_t t = filetime->dwHighDateTime; t <<= 32; - t += (UINT32)filetime->dwLowDateTime; + t += filetime->dwLowDateTime; t -= 116444736000000000LL; - if (t < 0) - { - if (remainder) *remainder = 9999999 - (-t - 1) % 10000000; - return -1 - ((-t - 1) / 10000000); - } - else - { - if (remainder) *remainder = t % 10000000; - return t / 10000000; + if (t < 0) { + return -1 - ((-t - 1) / 10000000); } - -#else /* ISO version */ - - UINT32 a0; /* 16 bit, low bits */ - UINT32 a1; /* 16 bit, medium bits */ - UINT32 a2; /* 32 bit, high bits */ - UINT32 r; /* remainder of division */ - unsigned int carry; /* carry bit for subtraction */ - int negative; /* whether a represents a negative value */ - - /* Copy the time values to a2/a1/a0 */ - a2 = (UINT32)filetime->dwHighDateTime; - a1 = ((UINT32)filetime->dwLowDateTime ) >> 16; - a0 = ((UINT32)filetime->dwLowDateTime ) & 0xffff; - - /* Subtract the time difference */ - if (a0 >= 32768 ) a0 -= 32768 , carry = 0; - else a0 += (1 << 16) - 32768 , carry = 1; - - if (a1 >= 54590 + carry) a1 -= 54590 + carry, carry = 0; - else a1 += (1 << 16) - 54590 - carry, carry = 1; - - a2 -= 27111902 + carry; - - /* If a is negative, replace a by (-1-a) */ - negative = (a2 >= ((UINT32)1) << 31); - if (negative) - { - /* Set a to -a - 1 (a is a2/a1/a0) */ - a0 = 0xffff - a0; - a1 = 0xffff - a1; - a2 = ~a2; + else { + return t / 10000000; } - - /* Divide a by 10000000 (a = a2/a1/a0), put the rest into r. - Split the divisor into 10000 * 1000 which are both less than 0xffff. */ - a1 += (a2 % 10000) << 16; - a2 /= 10000; - a0 += (a1 % 10000) << 16; - a1 /= 10000; - r = a0 % 10000; - a0 /= 10000; - - a1 += (a2 % 1000) << 16; - a2 /= 1000; - a0 += (a1 % 1000) << 16; - a1 /= 1000; - r += (a0 % 1000) * 10000; - a0 /= 1000; - - /* If a was negative, replace a by (-1-a) and r by (9999999 - r) */ - if (negative) - { - /* Set a to -a - 1 (a is a2/a1/a0) */ - a0 = 0xffff - a0; - a1 = 0xffff - a1; - a2 = ~a2; - - r = 9999999 - r; - } - - if (remainder) *remainder = r; - - /* Do not replace this by << 32, it gives a compiler warning and it does - not work. */ - return ((((time_t)a2) << 16) << 16) + (a1 << 16) + a0; -#endif } -#endif /* !_WIN32 */ diff -r 3b04745ff76d -r b65e8d0a088a src/timeconv.h --- a/src/timeconv.h Fri Apr 10 13:10:14 2009 -0700 +++ b/src/timeconv.h Mon Apr 13 11:39:33 2009 -0700 @@ -1,14 +1,14 @@ -#ifndef __TIMECONV_H -#define __TIMECONV_H +#ifndef __PST_TIMECONV_H +#define __PST_TIMECONV_H #include "common.h" #ifdef __cplusplus extern "C" { #endif - time_t pst_fileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder ); char * pst_fileTimeToAscii (const FILETIME *filetime); struct tm * pst_fileTimeToStructTM (const FILETIME *filetime); + time_t pst_fileTimeToUnixTime( const FILETIME *filetime); #ifdef __cplusplus } #endif diff -r 3b04745ff76d -r b65e8d0a088a src/vbuf.c --- a/src/vbuf.c Fri Apr 10 13:10:14 2009 -0700 +++ b/src/vbuf.c Mon Apr 13 11:39:33 2009 -0700 @@ -1,88 +1,6 @@ #include "define.h" -static int pst_skip_nl(char *s); // returns the width of the newline at s[0] -static int pst_find_nl(vstr *vs); // find newline of type type in b - -// vbuf functions -static void pst_vbfree(vbuf *vb); -static void pst_vbclear(vbuf *vb); // ditch the data, keep the buffer -static void pst_vbresize(vbuf *vb, size_t len); -static size_t pst_vbavail(vbuf *vb); -static void pst_vbdump(vbuf *vb); -static void pst_vbskipws(vbuf *vb); -static void pst_vbskip(vbuf *vb, size_t skip); -static void pst_vboverwrite(vbuf *vbdest, vbuf *vbsrc); - -// vstr functions -static vstr *pst_vsalloc(size_t len); -static char *pst_vsb(vstr *vs); -static size_t pst_vslen(vstr *vs); //strlen -static void pst_vsfree(vstr *vs); -static void pst_vsset(vstr *vs, char *s); // Store string s in vb -static void pst_vsnset(vstr *vs, char *s, size_t n); // Store string s in vb -static void pst_vsgrow(vstr *vs, size_t len); // grow buffer by len bytes, data are preserved -static size_t pst_vsavail(vstr *vs); -static void pst_vscat(vstr *vs, char *str); -static void pst_vsncat(vstr *vs, char *str, size_t len); -static void pst_vsnprepend(vstr *vs, char *str, size_t len) ; -static void pst_vsskip(vstr *vs, size_t len); -static int pst_vscmp(vstr *vs, char *str); -static void pst_vsskipws(vstr *vs); -static void pst_vs_printf(vstr *vs, char *fmt, ...); -static void pst_vs_printfa(vstr *vs, char *fmt, ...); -static void pst_vshexdump(vstr *vs, const char *b, size_t start, size_t stop, int ascii); -static int pst_vscatprintf(vstr *vs, char *fmt, ...); -static void pst_vsvprintf(vstr *vs, char *fmt, va_list ap); -static void pst_vstrunc(vstr *vs, size_t off); // Drop chars [off..dlen] -static int pst_vslast(vstr *vs); // returns the last character stored in a vstr string -static void pst_vscharcat(vstr *vs, int ch); - -static void pst_unicode_close(); - -static int pst_vb_skipline(vbuf *vb); // in: vb->b == "stuff\nmore_stuff"; out: vb->b == "more_stuff" - - - - -#define ASSERT(x,...) { if( !(x) ) DIE(( __VA_ARGS__)); } - - -static int pst_skip_nl(char *s) -{ - if (s[0] == '\n') - return 1; - if (s[0] == '\r' && s[1] == '\n') - return 2; - if (s[0] == '\0') - return 0; - return -1; -} - - -static int pst_find_nl(vstr * vs) -{ - char *nextr, *nextn; - - nextr = memchr(vs->b, '\r', vs->dlen); - nextn = memchr(vs->b, '\n', vs->dlen); - - //case 1: UNIX, we find \n first - if (nextn && (!nextr || (nextr > nextn))) { - return nextn - vs->b; - } - //case 2: DOS, we find \r\n - if (nextr && nextn && (nextn-nextr == 1)) { - return nextr - vs->b; - } - //case 3: we find nothing - - return -1; -} - - -// UTF8 <-> UTF16 <-> ISO8859 Character set conversion functions and (ack) their globals - static int unicode_up = 0; static iconv_t i16to8; static const char *target_charset = NULL; @@ -92,18 +10,88 @@ static iconv_t target2i8 = (iconv_t)-1; -void pst_unicode_init() +#define ASSERT(x,...) { if( !(x) ) DIE(( __VA_ARGS__)); } + + +/** DESTRUCTIVELY grow or shrink buffer + */ +static void pst_vbresize(pst_vbuf *vb, size_t len); +static void pst_vbresize(pst_vbuf *vb, size_t len) { - if (unicode_up) pst_unicode_close(); - i16to8 = iconv_open("utf-8", "utf-16le"); - if (i16to8 == (iconv_t)-1) { - WARN(("Couldn't open iconv descriptor for utf-16le to utf-8.\n")); - exit(1); + vb->dlen = 0; + + if (vb->blen >= len) { + vb->b = vb->buf; + return; } - unicode_up = 1; + + vb->buf = realloc(vb->buf, len); + vb->b = vb->buf; + vb->blen = len; +} + + +static size_t pst_vbavail(pst_vbuf * vb); +static size_t pst_vbavail(pst_vbuf * vb) +{ + return vb->blen - vb->dlen - (size_t)(vb->b - vb->buf); } +static void open_targets(const char* charset); +static void open_targets(const char* charset) +{ + if (!target_charset || strcasecmp(target_charset, charset)) { + if (target_open_from) iconv_close(i8totarget); + if (target_open_to) iconv_close(target2i8); + if (target_charset) free((char *)target_charset); + target_charset = strdup(charset); + target_open_from = 1; + target_open_to = 1; + i8totarget = iconv_open(target_charset, "utf-8"); + if (i8totarget == (iconv_t)-1) { + target_open_from = 0; + WARN(("Couldn't open iconv descriptor for utf-8 to %s.\n", target_charset)); + } + target2i8 = iconv_open("utf-8", target_charset); + if (target2i8 == (iconv_t)-1) { + target_open_to = 0; + WARN(("Couldn't open iconv descriptor for %s to utf-8.\n", target_charset)); + } + } +} + + +static size_t sbcs_conversion(pst_vbuf *dest, const char *inbuf, int iblen, iconv_t conversion); +static size_t sbcs_conversion(pst_vbuf *dest, const char *inbuf, int iblen, iconv_t conversion) +{ + size_t inbytesleft = iblen; + size_t icresult = (size_t)-1; + size_t outbytesleft = 0; + char *outbuf = NULL; + int myerrno; + + pst_vbresize(dest, 2*iblen); + + do { + outbytesleft = dest->blen - dest->dlen; + outbuf = dest->b + dest->dlen; + icresult = iconv(conversion, (ICONV_CONST char**)&inbuf, &inbytesleft, &outbuf, &outbytesleft); + myerrno = errno; + dest->dlen = outbuf - dest->b; + if (inbytesleft) pst_vbgrow(dest, 2*inbytesleft); + } while ((size_t)-1 == icresult && E2BIG == myerrno); + + if (icresult == (size_t)-1) { + DEBUG_WARN(("iconv failure: %s\n", strerror(myerrno))); + pst_unicode_init(); + return (size_t)-1; + } + return (icresult) ? (size_t)-1 : 0; +} + + +static void pst_unicode_close(); static void pst_unicode_close() { iconv_close(i16to8); @@ -120,7 +108,6 @@ static int utf16_is_terminated(const char *str, int length); static int utf16_is_terminated(const char *str, int length) { - VSTR_STATIC(errbuf, 100); int len = -1; int i; for (i = 0; i < length; i += 2) { @@ -129,16 +116,99 @@ } } - if (-1 == len) { - pst_vshexdump(errbuf, str, 0, length, 1); - DEBUG_WARN(("String is not zero terminated (probably broken data from registry) %s.\n", errbuf->b)); + if (len == -1) { + DEBUG_WARN(("utf16 string is not zero terminated\n")); } - return (-1 == len) ? 0 : 1; + return (len == -1) ? 0 : 1; +} + + +pst_vbuf *pst_vballoc(size_t len) +{ + pst_vbuf *result = pst_malloc(sizeof(pst_vbuf)); + if (result) { + result->dlen = 0; + result->blen = 0; + result->buf = NULL; + pst_vbresize(result, len); + } + else DIE(("malloc() failure")); + return result; } -size_t pst_vb_utf16to8(vbuf *dest, const char *inbuf, int iblen) +/** out: vbavail(vb) >= len, data are preserved + */ +void pst_vbgrow(pst_vbuf *vb, size_t len) +{ + if (0 == len) + return; + + if (0 == vb->blen) { + pst_vbresize(vb, len); + return; + } + + if (vb->dlen + len > vb->blen) { + if (vb->dlen + len < vb->blen * 1.5) + len = vb->blen * 1.5; + char *nb = pst_malloc(vb->blen + len); + if (!nb) DIE(("malloc() failure")); + vb->blen = vb->blen + len; + memcpy(nb, vb->b, vb->dlen); + + free(vb->buf); + vb->buf = nb; + vb->b = vb->buf; + } else { + if (vb->b != vb->buf) + memcpy(vb->buf, vb->b, vb->dlen); + } + + vb->b = vb->buf; + + ASSERT(pst_vbavail(vb) >= len, "vbgrow(): I have failed in my mission."); +} + + +/** set vbuf b size=len, resize if necessary, relen = how much to over-allocate + */ +void pst_vbset(pst_vbuf * vb, void *b, size_t len) +{ + pst_vbresize(vb, len); + memcpy(vb->b, b, len); + vb->dlen = len; +} + + +/** append len bytes of b to vb, resize if necessary + */ +void pst_vbappend(pst_vbuf *vb, void *b, size_t len) +{ + if (0 == vb->dlen) { + pst_vbset(vb, b, len); + return; + } + pst_vbgrow(vb, len); + memcpy(vb->b + vb->dlen, b, len); + vb->dlen += len; +} + + +void pst_unicode_init() +{ + if (unicode_up) pst_unicode_close(); + i16to8 = iconv_open("utf-8", "utf-16le"); + if (i16to8 == (iconv_t)-1) { + WARN(("Couldn't open iconv descriptor for utf-16le to utf-8.\n")); + exit(1); + } + unicode_up = 1; +} + + +size_t pst_vb_utf16to8(pst_vbuf *dest, const char *inbuf, int iblen) { size_t inbytesleft = iblen; size_t icresult = (size_t)-1; @@ -171,60 +241,7 @@ } -static void open_targets(const char* charset); -static void open_targets(const char* charset) -{ - if (!target_charset || strcasecmp(target_charset, charset)) { - if (target_open_from) iconv_close(i8totarget); - if (target_open_to) iconv_close(target2i8); - if (target_charset) free((char *)target_charset); - target_charset = strdup(charset); - target_open_from = 1; - target_open_to = 1; - i8totarget = iconv_open(target_charset, "utf-8"); - if (i8totarget == (iconv_t)-1) { - target_open_from = 0; - WARN(("Couldn't open iconv descriptor for utf-8 to %s.\n", target_charset)); - } - target2i8 = iconv_open("utf-8", target_charset); - if (target2i8 == (iconv_t)-1) { - target_open_to = 0; - WARN(("Couldn't open iconv descriptor for %s to utf-8.\n", target_charset)); - } - } -} - - -static size_t sbcs_conversion(vbuf *dest, const char *inbuf, int iblen, iconv_t conversion); -static size_t sbcs_conversion(vbuf *dest, const char *inbuf, int iblen, iconv_t conversion) -{ - size_t inbytesleft = iblen; - size_t icresult = (size_t)-1; - size_t outbytesleft = 0; - char *outbuf = NULL; - int myerrno; - - pst_vbresize(dest, 2*iblen); - - do { - outbytesleft = dest->blen - dest->dlen; - outbuf = dest->b + dest->dlen; - icresult = iconv(conversion, (ICONV_CONST char**)&inbuf, &inbytesleft, &outbuf, &outbytesleft); - myerrno = errno; - dest->dlen = outbuf - dest->b; - if (inbytesleft) pst_vbgrow(dest, 2*inbytesleft); - } while ((size_t)-1 == icresult && E2BIG == myerrno); - - if (icresult == (size_t)-1) { - DEBUG_WARN(("iconv failure: %s\n", strerror(myerrno))); - pst_unicode_init(); - return (size_t)-1; - } - return (icresult) ? (size_t)-1 : 0; -} - - -size_t pst_vb_utf8to8bit(vbuf *dest, const char *inbuf, int iblen, const char* charset) +size_t pst_vb_utf8to8bit(pst_vbuf *dest, const char *inbuf, int iblen, const char* charset) { open_targets(charset); if (!target_open_from) return (size_t)-1; // failure to open the target @@ -232,438 +249,10 @@ } -size_t pst_vb_8bit2utf8(vbuf *dest, const char *inbuf, int iblen, const char* charset) +size_t pst_vb_8bit2utf8(pst_vbuf *dest, const char *inbuf, int iblen, const char* charset) { open_targets(charset); if (!target_open_to) return (size_t)-1; // failure to open the target return sbcs_conversion(dest, inbuf, iblen, target2i8); } - -vbuf *pst_vballoc(size_t len) -{ - vbuf *result = malloc(sizeof(vbuf)); - if (result) { - result->dlen = 0; - result->blen = 0; - result->buf = NULL; - pst_vbresize(result, len); - } - else DIE(("malloc() failure")); - return result; -} - - -static void pst_vbcheck(vbuf * vb) -{ - ASSERT(vb->b >= vb->buf, "vbcheck(): data not inside buffer"); - ASSERT((size_t)(vb->b - vb->buf) <= vb->blen, "vbcheck(): vb->b outside of buffer range."); - ASSERT(vb->dlen <= vb->blen, "vbcheck(): data length > buffer length."); - ASSERT(vb->blen < 1024 * 1024, "vbcheck(): blen is a bit large...hmmm."); -} - - -static void pst_vbfree(vbuf * vb) -{ - free(vb->buf); - free(vb); -} - - -static void pst_vbclear(vbuf *vb) // ditch the data, keep the buffer -{ - pst_vbresize(vb, 0); -} - - -static void pst_vbresize(vbuf *vb, size_t len) // DESTRUCTIVELY grow or shrink buffer -{ - vb->dlen = 0; - - if (vb->blen >= len) { - vb->b = vb->buf; - return; - } - - vb->buf = realloc(vb->buf, len); - vb->b = vb->buf; - vb->blen = len; -} - - -static size_t pst_vbavail(vbuf * vb) -{ - return vb->blen - vb->dlen - (size_t)(vb->b - vb->buf); -} - - -void pst_vbgrow(vbuf *vb, size_t len) // out: vbavail(vb) >= len, data are preserved -{ - if (0 == len) - return; - - if (0 == vb->blen) { - pst_vbresize(vb, len); - return; - } - - if (vb->dlen + len > vb->blen) { - if (vb->dlen + len < vb->blen * 1.5) - len = vb->blen * 1.5; - char *nb = pst_malloc(vb->blen + len); - if (!nb) DIE(("malloc() failure")); - vb->blen = vb->blen + len; - memcpy(nb, vb->b, vb->dlen); - - free(vb->buf); - vb->buf = nb; - vb->b = vb->buf; - } else { - if (vb->b != vb->buf) - memcpy(vb->buf, vb->b, vb->dlen); - } - - vb->b = vb->buf; - - ASSERT(pst_vbavail(vb) >= len, "vbgrow(): I have failed in my mission."); -} - - -void pst_vbset(vbuf * vb, void *b, size_t len) // set vbuf b size=len, resize if necessary, relen = how much to over-allocate -{ - pst_vbresize(vb, len); - memcpy(vb->b, b, len); - vb->dlen = len; -} - - -static void pst_vsskipws(vstr * vs) -{ - char *p = vs->b; - while ((size_t)(p - vs->b) < vs->dlen && isspace(p[0])) - p++; - - pst_vbskip((vbuf *) vs, p - vs->b); -} - - -// append len bytes of b to vbuf, resize if necessary -void pst_vbappend(vbuf *vb, void *b, size_t len) -{ - if (0 == vb->dlen) { - pst_vbset(vb, b, len); - return; - } - pst_vbgrow(vb, len); - memcpy(vb->b + vb->dlen, b, len); - vb->dlen += len; -} - - -// dumps the first skip bytes from vbuf -static void pst_vbskip(vbuf *vb, size_t skip) -{ - ASSERT(skip <= vb->dlen, "vbskip(): Attempt to seek past end of buffer."); - vb->b += skip; - vb->dlen -= skip; -} - - -// overwrite vbdest with vbsrc -static void pst_vboverwrite(vbuf *vbdest, vbuf *vbsrc) -{ - pst_vbresize(vbdest, vbsrc->blen); - memcpy(vbdest->b, vbsrc->b, vbsrc->dlen); - vbdest->blen = vbsrc->blen; - vbdest->dlen = vbsrc->dlen; -} - - -static vstr *pst_vsalloc(size_t len) -{ - vstr *result = (vstr *) pst_vballoc(len + 1); - pst_vsset(result, ""); - return result; -} - - -static char *pst_vsstr(vstr * vs); -static char *pst_vsstr(vstr * vs) -{ - return vs->b; -} - - -static size_t pst_vslen(vstr * vs) -{ - return strlen(pst_vsstr(vs)); -} - - -static void pst_vsfree(vstr * vs) -{ - pst_vbfree((vbuf *) vs); -} - - -static void pst_vscharcat(vstr * vb, int ch) -{ - pst_vbgrow((vbuf *) vb, 1); - vb->b[vb->dlen - 1] = ch; - vb->b[vb->dlen] = '\0'; - vb->dlen++; -} - - -// prependappend string str to vbuf, vbuf must already contain a valid string -static void pst_vsnprepend(vstr * vb, char *str, size_t len) -{ - ASSERT(vb->b[vb->dlen - 1] == '\0', "vsncat(): attempt to append string to non-string."); - size_t sl = strlen(str); - size_t n = (sl < len) ? sl : len; - pst_vbgrow((vbuf *) vb, n + 1); - memmove(vb->b + n, vb->b, vb->dlen - 1); - memcpy(vb->b, str, n); - vb->dlen += n; - vb->b[vb->dlen - 1] = '\0'; -} - - -// len < dlen-1 -> skip len chars, else DIE -static void pst_vsskip(vstr * vs, size_t len) -{ - ASSERT(len < vs->dlen - 1, "Attempt to skip past end of string"); - pst_vbskip((vbuf *) vs, len); -} - - -// in: vb->b == "stuff\nmore_stuff"; out: vb->b == "more_stuff" -static int pst_vsskipline(vstr * vs) -{ - int nloff = pst_find_nl(vs); - int nll = pst_skip_nl(vs->b + nloff); - - if (nloff < 0) { - //TODO: error - printf("vb_skipline(): there seems to be no newline here.\n"); - return -1; - } - if (nll < 0) { - //TODO: error - printf("vb_skipline(): there seems to be no newline here...except there should be. :P\n"); - return -1; - } - - memmove(vs->b, vs->b + nloff + nll, vs->dlen - nloff - nll); - - vs->dlen -= nloff + nll; - - return 0; -} - - -static int pst_vscatprintf(vstr * vs, char *fmt, ...) -{ - int size; - va_list ap; - - /* Guess we need no more than 100 bytes. */ - //vsresize( vb, 100 ); - if (!vs->b || vs->dlen == 0) { - pst_vsset(vs, ""); - } - - while (1) { - /* Try to print in the allocated space. */ - va_start(ap, fmt); - size = vsnprintf(vs->b + vs->dlen - 1, vs->blen - vs->dlen, fmt, ap); - va_end(ap); - - /* If that worked, return the string. */ - if ((size > -1) && ((size_t)size < vs->blen - vs->dlen)) { - vs->dlen += size; - return size; - } - /* Else try again with more space. */ - if (size >= 0) /* glibc 2.1 */ - pst_vbgrow((vbuf *) vs, size + 1); /* precisely what is needed */ - else /* glibc 2.0 */ - pst_vbgrow((vbuf *) vs, vs->blen); - } -} - - -// returns the last character stored in a vstr -static int pst_vslast(vstr * vs) -{ - if (vs->dlen < 1) - return -1; - if (vs->b[vs->dlen - 1] != '\0') - return -1; - if (vs->dlen == 1) - return '\0'; - return vs->b[vs->dlen - 2]; -} - - -// print over vb -static void pst_vs_printf(vstr * vs, char *fmt, ...) -{ - int size; - va_list ap; - - /* Guess we need no more than 100 bytes. */ - pst_vbresize((vbuf *) vs, 100); - - while (1) { - /* Try to print in the allocated space. */ - va_start(ap, fmt); - size = vsnprintf(vs->b, vs->blen, fmt, ap); - va_end(ap); - - /* If that worked, return the string. */ - if ((size > -1) && ((size_t)size < vs->blen)) { - vs->dlen = size + 1; - return; - } - /* Else try again with more space. */ - if (size >= 0) /* glibc 2.1 */ - pst_vbresize((vbuf *) vs, size + 1); /* precisely what is needed */ - else /* glibc 2.0 */ - pst_vbresize((vbuf *) vs, vs->blen * 2); - } -} - - -// printf append to vs -static void pst_vs_printfa(vstr * vs, char *fmt, ...) -{ - int size; - va_list ap; - - if (vs->blen - vs->dlen < 50) - pst_vbgrow((vbuf *) vs, 100); - - while (1) { - /* Try to print in the allocated space. */ - va_start(ap, fmt); - size = vsnprintf(vs->b + vs->dlen - 1, vs->blen - vs->dlen + 1, fmt, ap); - va_end(ap); - - /* If that worked, return the string. */ - if ((size > -1) && ((size_t)size < vs->blen)) { - vs->dlen += size; - return; - } - /* Else try again with more space. */ - if (size >= 0) /* glibc 2.1 */ - pst_vbgrow((vbuf *) vs, size + 1 - vs->dlen); /* precisely what is needed */ - else /* glibc 2.0 */ - pst_vbgrow((vbuf *) vs, size); - } -} - - -static void pst_vshexdump(vstr * vs, const char *b, size_t start, size_t stop, int ascii) -{ - char c; - int diff, i; - - while (start < stop) { - diff = stop - start; - if (diff > 16) - diff = 16; - - pst_vs_printfa(vs, ":%08X ", start); - - for (i = 0; i < diff; i++) { - if (8 == i) - pst_vs_printfa(vs, " "); - pst_vs_printfa(vs, "%02X ", (unsigned char) *(b + start + i)); - } - if (ascii) { - for (i = diff; i < 16; i++) - pst_vs_printfa(vs, " "); - for (i = 0; i < diff; i++) { - c = *(b + start + i); - pst_vs_printfa(vs, "%c", isprint(c) ? c : '.'); - } - } - pst_vs_printfa(vs, "\n"); - start += 16; - } -} - - -static void pst_vsset(vstr * vs, char *s) // Store string s in vs -{ - pst_vsnset(vs, s, strlen(s)); -} - - -static void pst_vsnset(vstr * vs, char *s, size_t n) // Store string s in vs -{ - pst_vbresize((vbuf *) vs, n + 1); - memcpy(vs->b, s, n); - vs->b[n] = '\0'; - vs->dlen = n + 1; -} - - -static void pst_vsgrow(vstr * vs, size_t len) // grow buffer by len bytes, data are preserved -{ - pst_vbgrow((vbuf *) vs, len); -} - - -static size_t pst_vsavail(vstr * vs) -{ - return pst_vbavail((vbuf *) vs); -} - - -static void pst_vsnset16(vstr * vs, char *s, size_t len) // Like vbstrnset, but for UTF16 -{ - pst_vbresize((vbuf *) vs, len + 1); - memcpy(vs->b, s, len); - - vs->b[len] = '\0'; - vs->dlen = len + 1; - vs->b[len] = '\0'; -} - - -static void pst_vscat(vstr * vs, char *str) -{ - pst_vsncat(vs, str, strlen(str)); -} - - -static int pst_vscmp(vstr * vs, char *str) -{ - return strcmp(vs->b, str); -} - - -static void pst_vsncat(vstr * vs, char *str, size_t len) // append string str to vstr, vstr must already contain a valid string -{ - ASSERT(vs->b[vs->dlen - 1] == '\0', "vsncat(): attempt to append string to non-string."); - size_t sl = strlen(str); - size_t n = (sl < len) ? sl : len; - //string append - pst_vbgrow((vbuf *) vs, n + 1); - memcpy(vs->b + vs->dlen - 1, str, n); - vs->dlen += n; - vs->b[vs->dlen - 1] = '\0'; -} - - -static void pst_vstrunc(vstr * v, size_t off) // Drop chars [off..dlen] -{ - if (off >= v->dlen - 1) - return; //nothing to do - v->b[off] = '\0'; - v->dlen = off + 1; -} - - diff -r 3b04745ff76d -r b65e8d0a088a src/vbuf.h --- a/src/vbuf.h Fri Apr 10 13:10:14 2009 -0700 +++ b/src/vbuf.h Mon Apr 13 11:39:33 2009 -0700 @@ -1,25 +1,12 @@ -/* vbuf.h - variable length buffer functions - * - * Functions that try to make dealing with buffers easier. - * - * vbuf - * - * vstr - * - should always contain a valid string - * - */ -#ifndef VBUF_H -#define VBUF_H +#ifndef __PST_VBUF_H +#define __PST_VBUF_H #include "common.h" -#define SZ_MAX 4096 -/***************************************************/ - // Variable-length buffers -struct varbuf { +struct pst_varbuf { size_t dlen; //length of data stored in buffer size_t blen; //length of buffer char *buf; //buffer @@ -27,29 +14,16 @@ }; -// The exact same thing as a varbuf but should always contain at least '\0' -struct varstr { - size_t dlen; //length of data stored in buffer - size_t blen; //length of buffer - char *buf; //buffer - char *b; //start of stored data -}; +typedef struct pst_varbuf pst_vbuf; + +pst_vbuf *pst_vballoc(size_t len); +void pst_vbgrow(pst_vbuf *vb, size_t len); // grow buffer by len bytes, data are preserved +void pst_vbset(pst_vbuf *vb, void *data, size_t len); +void pst_vbappend(pst_vbuf *vb, void *data, size_t length); +void pst_unicode_init(); +size_t pst_vb_utf16to8(pst_vbuf *dest, const char *inbuf, int iblen); +size_t pst_vb_utf8to8bit(pst_vbuf *dest, const char *inbuf, int iblen, const char* charset); +size_t pst_vb_8bit2utf8(pst_vbuf *dest, const char *inbuf, int iblen, const char* charset); -typedef struct varbuf vbuf; -typedef struct varstr vstr; - -#define VBUF_STATIC(x,y) static vbuf *x = NULL; if(!x) x = pst_vballoc(y); -#define VSTR_STATIC(x,y) static vstr *x = NULL; if(!x) x = pst_vsalloc(y); - -vbuf *pst_vballoc(size_t len); -void pst_vbgrow(vbuf *vb, size_t len); // grow buffer by len bytes, data are preserved -void pst_vbset(vbuf *vb, void *data, size_t len); -void pst_vbappend(vbuf *vb, void *data, size_t length); -void pst_unicode_init(); -size_t pst_vb_utf16to8(vbuf *dest, const char *inbuf, int iblen); -size_t pst_vb_utf8to8bit(vbuf *dest, const char *inbuf, int iblen, const char* charset); -size_t pst_vb_8bit2utf8(vbuf *dest, const char *inbuf, int iblen, const char* charset); - - -#endif // VBUF_H +#endif diff -r 3b04745ff76d -r b65e8d0a088a xml/Doxyfile --- a/xml/Doxyfile Fri Apr 10 13:10:14 2009 -0700 +++ b/xml/Doxyfile Mon Apr 13 11:39:33 2009 -0700 @@ -17,7 +17,7 @@ # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. -PROJECT_NAME = 'LibPst' +PROJECT_NAME = 'libpst' # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or @@ -114,7 +114,7 @@ # If left blank the directory from which doxygen is run is used as the # path to strip. -STRIP_FROM_PATH = ../src +STRIP_FROM_PATH = ./tmp # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells @@ -123,7 +123,7 @@ # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. -STRIP_FROM_INC_PATH = ../src +STRIP_FROM_INC_PATH = ./tmp # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems @@ -423,7 +423,7 @@ # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = ../src/common.h ../src/libpst.h ../src/libstrfunc.h ../src/timeconv.h ../src/vbuf.h +INPUT = tmp/libpst # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp @@ -924,7 +924,7 @@ # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. -MACRO_EXPANSION = YES +MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the diff -r 3b04745ff76d -r b65e8d0a088a xml/Makefile.am --- a/xml/Makefile.am Fri Apr 10 13:10:14 2009 -0700 +++ b/xml/Makefile.am Mon Apr 13 11:39:33 2009 -0700 @@ -1,3 +1,5 @@ +EXTRA_DIST = Doxyfile $(wildcard *.pdf) + all: libpst cat header.xml libpst >libpst.xml cat header.sgml libpst >libpst.sgml @@ -7,6 +9,9 @@ xmlto -o ../man man libpst.xml xmlto -o ../html xhtml libpst.xml xmlto -o ../html pdf libpst.xml - docbook2texi -o ../info libpst.sgml rm -f libpst.xml libpst.sgml + mkdir tmp + mkdir tmp/libpst + cp ../src/common.h ../src/libpst.h ../src/libstrfunc.h ../src/timeconv.h ../src/vbuf.h tmp/libpst doxygen + rm -rf tmp diff -r 3b04745ff76d -r b65e8d0a088a xml/libpst.in --- a/xml/libpst.in Fri Apr 10 13:10:14 2009 -0700 +++ b/xml/libpst.in Mon Apr 13 11:39:33 2009 -0700 @@ -481,15 +481,6 @@ - - TODO - - The binary debug log file is generally much larger than the .pst file, - so we need to switch to ftello/fseeko there also to handle files - larger than 2GB. - - - Copyright