21#include "kmime_util.h"
27#include <kcalendarsystem.h>
29#include <tqtextcodec.h>
32#include <tqdatetime.h>
43TQStrIList c_harsetCache;
44TQStrIList l_anguageCache;
46const char* cachedCharset( const TQCString &name)
48 int idx=c_harsetCache.find(name.data());
50 return c_harsetCache.at(idx);
52 c_harsetCache.append(name.upper().data());
54 return c_harsetCache.last();
57const char* cachedLanguage( const TQCString &name)
59 int idx=l_anguageCache.find(name.data());
61 return l_anguageCache.at(idx);
63 l_anguageCache.append(name.upper().data());
65 return l_anguageCache.last();
68bool isUsAscii( const TQString &s)
70 uint sLength = s.length();
71 for (uint i=0; i<sLength; i++)
72 if (s.at(i).latin1()<=0)
79const uchar specialsMap[16] = {
80 0x00, 0x00, 0x00, 0x00,
81 0x20, 0xCA, 0x00, 0x3A,
82 0x80, 0x00, 0x00, 0x1C,
83 0x00, 0x00, 0x00, 0x00
87const uchar tSpecialsMap[16] = {
88 0x00, 0x00, 0x00, 0x00,
89 0x20, 0xC9, 0x00, 0x3F,
90 0x80, 0x00, 0x00, 0x1C,
91 0x00, 0x00, 0x00, 0x00
95const uchar aTextMap[16] = {
96 0x00, 0x00, 0x00, 0x00,
97 0x5F, 0x35, 0xFF, 0xC5,
98 0x7F, 0xFF, 0xFF, 0xE3,
99 0xFF, 0xFF, 0xFF, 0xFE
103const uchar tTextMap[16] = {
104 0x00, 0x00, 0x00, 0x00,
105 0x5F, 0x36, 0xFF, 0xC0,
106 0x7F, 0xFF, 0xFF, 0xE3,
107 0xFF, 0xFF, 0xFF, 0xFE
111const uchar eTextMap[16] = {
112 0x00, 0x00, 0x00, 0x00,
113 0x40, 0x35, 0xFF, 0xC0,
114 0x7F, 0xFF, 0xFF, 0xE0,
115 0x7F, 0xFF, 0xFF, 0xE0
118#if defined(_AIX) && defined(truncate)
122TQString decodeRFC2047String( const TQCString &src, const char **usedCS,
123 const TQCString &defaultCS, bool forceCS)
125 TQCString result, str;
126 TQCString declaredCS;
127 const char *beg, *end, *mid, *pos=0;
128 char *dest, *endOfLastEncWord=0;
129 char encoding = '\0';
130 bool valid, onlySpacesSinceLastWord= false;
131 const int maxLen=400;
134 if(src.find( "=?") < 0)
137 result.truncate(src.length());
138 for (pos=src.data(), dest=result.data(); *pos; pos++)
140 if (pos[0]!= '=' || pos[1]!= '?')
143 if (onlySpacesSinceLastWord)
144 onlySpacesSinceLastWord = (pos[0]== ' ' || pos[1]== '\t');
152 for (i=2,pos+=2; i<maxLen && (*pos!= '?'&&(ispunct(*pos)||isalnum(*pos))); i++) {
156 if (*pos!= '?' || i<4 || i>=maxLen) valid = false;
160 encoding = toupper(pos[1]);
161 if (pos[2]!= '?' || (encoding!= 'Q' && encoding!= 'B'))
170 while (i<maxLen && *pos && !(*pos== '?' && *(pos+1)== '='))
176 if (i>=maxLen || !*pos) valid = false;
181 if (onlySpacesSinceLastWord)
182 dest=endOfLastEncWord;
185 str = TQCString(mid, ( int)(pos - mid + 1));
189 for (i=str.length()-1; i>=0; i--)
190 if (str[i]== '_') str[i]= ' ';
191 str = KCodecs::quotedPrintableDecode(str);
195 str = KCodecs::base64Decode(str);
198 for (i=0; str[i]; i++) {
204 endOfLastEncWord=dest;
205 onlySpacesSinceLastWord= true;
220 TQTextCodec *codec=0;
222 if (forceCS || declaredCS.isEmpty()) {
223 codec=TDEGlobal::charsets()->codecForName(defaultCS);
224 (*usedCS)=cachedCharset(defaultCS);
227 codec=TDEGlobal::charsets()->codecForName(declaredCS, ok);
229 codec=TDEGlobal::charsets()->codecForName(defaultCS);
230 (*usedCS)=cachedCharset(defaultCS);
233 (*usedCS)=cachedCharset(declaredCS);
236 return codec->toUnicode(result.data(), result.length());
239TQString decodeRFC2047String( const TQCString &src)
242 return decodeRFC2047String(src, &usedCS, "utf-8", false);
245TQCString encodeRFC2047String( const TQString &src, const char *charset,
246 bool addressHeader, bool allow8BitHeaders)
248 TQCString encoded8Bit, result, usedCS;
249 unsigned int start=0,end=0;
250 bool nonAscii= false, ok= true, useTQEncoding= false;
251 TQTextCodec *codec=0;
254 codec=TDEGlobal::charsets()->codecForName(usedCS, ok);
258 usedCS=TDEGlobal::locale()->encoding();
259 codec=TDEGlobal::charsets()->codecForName(usedCS, ok);
262 if (usedCS.find( "8859-")>=0)
265 encoded8Bit=codec->fromUnicode(src);
270 uint encoded8BitLength = encoded8Bit.length();
271 for ( unsigned int i=0; i<encoded8BitLength; i++) {
272 if (encoded8Bit[i]== ' ')
276 if ((( signed char)encoded8Bit[i]<0) || (encoded8Bit[i] == '\033') ||
277 (addressHeader && (strchr( "\"()<>@,.;:\\[]=",encoded8Bit[i])!=0))) {
285 while ((end<encoded8Bit.length())&&(encoded8Bit[end]!= ' '))
288 for ( unsigned int x=end;x<encoded8Bit.length();x++)
289 if ((( signed char)encoded8Bit[x]<0) || (encoded8Bit[x] == '\033') ||
290 (addressHeader && (strchr( "\"()<>@,.;:\\[]=",encoded8Bit[x])!=0))) {
291 end = encoded8Bit.length();
293 while ((end<encoded8Bit.length())&&(encoded8Bit[end]!= ' '))
297 result = encoded8Bit.left(start)+ "=?"+usedCS;
303 for ( unsigned int i=start;i<end;i++) {
308 if (((c>= 'a')&&(c<= 'z'))||
309 ((c>= 'A')&&(c<= 'Z'))||
310 ((c>= '0')&&(c<= '9')))
314 hexcode = ((c & 0xF0) >> 4) + 48;
315 if (hexcode >= 58) hexcode += 7;
317 hexcode = (c & 0x0F) + 48;
318 if (hexcode >= 58) hexcode += 7;
323 result += "?B?"+KCodecs::base64Encode(encoded8Bit.mid(start,end-start), false);
327 result += encoded8Bit.right(encoded8Bit.length()-end);
330 result = encoded8Bit;
335TQCString uniqueString()
337 static char chars[] = "0123456789abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
342 unsigned int timeval;
346 ran=1+(int) (1000.0*rand()/(RAND_MAX+1.0));
347 timeval=(now/ran)+getpid();
349 for( int i=0; i<10; i++){
350 pos=(int) (61.0*rand()/(RAND_MAX+1.0));
354 ret.sprintf( "%d.%s", timeval, p);
360TQCString multiPartBoundary()
363 ret= "nextPart"+uniqueString();
367TQCString extractHeader( const TQCString &src, const char *name)
369 TQCString n=TQCString(name)+ ":";
370 int pos1=-1, pos2=0, len=src.length()-1;
373 if (n.lower() == src.left(n.length()).lower()) {
377 pos1 = src.find(n.data(),0, false);
383 if ( src.at( pos1 ) == ' ' )
387 if (src[pos2]!= '\n') {
389 pos2=src.find( "\n", pos2+1);
390 if(pos2==-1 || pos2==len || ( src[pos2+1]!= ' ' && src[pos2+1]!= '\t') )
397 if(pos2<0) pos2=len+1;
400 return src.mid(pos1, pos2-pos1);
402 return (src.mid(pos1, pos2-pos1).replace(TQRegExp( "\\s*\\n\\s*"), " "));
410TQCString CRLFtoLF( const TQCString &s)
412 TQCString ret=s.copy();
413 ret.replace(TQRegExp( "\\r\\n"), "\n");
418TQCString CRLFtoLF( const char *s)
421 ret.replace(TQRegExp( "\\r\\n"), "\n");
426TQCString LFtoCRLF( const TQCString &s)
428 TQCString ret=s.copy();
429 ret.replace(TQRegExp( "\\n"), "\r\n");
434void removeQuots(TQCString &str)
437 str.replace(TQRegExp( "[\\\"]"), "");
441void removeQuots(TQString &str)
444 str.replace(TQRegExp( "[\\\"]"), "");
448void addQuotes(TQCString &str, bool forceQuotes)
450 if ( forceQuotes || TQString(str).contains( TQRegExp( TQString( "\"|\\\\|=|\\]|\\[|:|;|,|\\.|,|@|<|>|\\)|\\(" ) ) ) ) {
452 str.replace(TQRegExp( "([\\\"])"), "\\\\1");
459int DateFormatter::mDaylight = -1;
461 : mFormat( fType ), mCurrentTime( 0 )
466DateFormatter::~DateFormatter()
469DateFormatter::FormatType
483 bool shortFormat, bool includeSecs ) const
487 return fancy( otime );
490 return localized( otime, shortFormat, includeSecs, lang );
493 return cTime( otime );
507 bool shortFormat, bool includeSecs ) const
518 tmp.setTime_t(otime);
520 ret = tmp.toString( "ddd, dd MMM yyyy hh:mm:ss ").latin1();
529 if ( mCustomFormat.isEmpty() )
532 int z = mCustomFormat.find( "Z");
534 TQString ret = mCustomFormat;
538 ret.replace(z,1, zone(t));
541 ret = d.toString(ret);
549 mCustomFormat = format;
554DateFormatter::getCustomFormat() const
556 return mCustomFormat;
564#if defined(HAVE_TIMEZONE) || defined(HAVE_TM_GMTOFF)
565 struct tm *local = localtime( &otime );
568#if defined(HAVE_TIMEZONE)
571 int secs = abs(timezone);
572 int neg = (timezone>0)?1:0;
573 int hours = secs/3600;
574 int mins = (secs - hours*3600)/60;
577 if ( local->tm_isdst > 0 ) {
586 ret.sprintf( "%c%.2d%.2d",(neg)? '-': '+', hours, mins);
588#elif defined(HAVE_TM_GMTOFF)
590 int secs = abs( local->tm_gmtoff );
591 int neg = (local->tm_gmtoff<0)?1:0;
592 int hours = secs/3600;
593 int mins = (secs - hours*3600)/60;
595 if ( local->tm_isdst > 0 )
600 ret.sprintf( "%c%.2d%.2d",(neg)? '-': '+', hours, mins);
604 TQDateTime d1 = TQDateTime::fromString( asctime(gmtime(&otime)) );
605 TQDateTime d2 = TQDateTime::fromString( asctime(localtime(&otime)) );
606 int secs = d1.secsTo(d2);
607 int neg = (secs<0)?1:0;
609 int hours = secs/3600;
610 int mins = (secs - hours*3600)/60;
612 ret.sprintf( "%c%.2d%.2d",(neg)? '-': '+', hours, mins);
620DateFormatter::qdateToTimeT( const TQDateTime& dt) const
622 TQDateTime epoch( TQDate(1970, 1,1), TQTime(00,00,00) );
626 TQDateTime d1 = TQDateTime::fromString( asctime(gmtime(&otime)) );
627 TQDateTime d2 = TQDateTime::fromString( asctime(localtime(&otime)) );
628 time_t drf = epoch.secsTo( dt ) - d1.secsTo( d2 );
636 TDELocale *locale = TDEGlobal::locale();
639 return i18n( "unknown" );
641 if ( !mCurrentTime ) {
642 time( &mCurrentTime );
643 mDate.setTime_t( mCurrentTime );
647 old.setTime_t( otime );
650 if ( mCurrentTime + 60 * 60 >= otime ) {
651 time_t diff = mCurrentTime - otime;
653 if ( diff < 24 * 60 * 60 ) {
654 if ( old.date().year() == mDate.date().year() &&
655 old.date().dayOfYear() == mDate.date().dayOfYear() )
656 return i18n( "Today %1" ).arg( locale->
657 formatTime( old.time(), true ) );
659 if ( diff < 2 * 24 * 60 * 60 ) {
660 TQDateTime yesterday( mDate.addDays( -1 ) );
661 if ( old.date().year() == yesterday.date().year() &&
662 old.date().dayOfYear() == yesterday.date().dayOfYear() )
663 return i18n( "Yesterday %1" ).arg( locale->
664 formatTime( old.time(), true) );
666 for ( int i = 3; i < 7; i++ )
667 if ( diff < i * 24 * 60 * 60 ) {
668 TQDateTime weekday( mDate.addDays( -i + 1 ) );
669 if ( old.date().year() == weekday.date().year() &&
670 old.date().dayOfYear() == weekday.date().dayOfYear() )
671 return i18n( "1. weekday, 2. time", "%1 %2" ).
672 arg( locale->calendar()->weekDayName( old.date() ) ).
673 arg( locale->formatTime( old.time(), true) );
677 return locale->formatDateTime( old );
683 const TQString& localeLanguage ) const
687 TDELocale *locale = TDEGlobal::locale();
689 tmp.setTime_t( otime );
692 if ( !localeLanguage.isEmpty() ) {
693 locale= new TDELocale(localeLanguage);
694 locale->setLanguage(localeLanguage);
695 locale->setCountry(localeLanguage);
696 ret = locale->formatDateTime( tmp, shortFormat, includeSecs );
699 ret = locale->formatDateTime( tmp, shortFormat, includeSecs );
708 return TQString::fromLatin1( ctime( &otime ) ).stripWhiteSpace() ;
715 strftime( cstr, 63, "%Y-%m-%d %H:%M:%S", localtime(&otime) );
716 return TQString( cstr );
728 const TQString& data, bool shortFormat, bool includeSecs )
731 if ( t == DateFormatter::Custom ) {
734 return f. dateString( otime, data, shortFormat, includeSecs );
739 bool shortFormat, bool includeSecs )
742 if ( t == DateFormatter::Custom ) {
745 return f. dateString( time(0), data, shortFormat, includeSecs );
756DateFormatter::isDaylight()
758 if ( mDaylight == -1 ) {
759 time_t ntime = time( 0 );
760 struct tm *local = localtime( &ntime );
761 if ( local->tm_isdst > 0 ) {
768 } else if ( mDaylight != 0 )
|