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 )