Bump version to 4.3-4
[LibreOffice.git] / lotuswordpro / source / filter / lwptools.cxx
blob8645a0525870b708036056cdc15a77adf4b04d46
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
10 * Sun Microsystems Inc., October, 2000
12 * GNU Lesser General Public License Version 2.1
13 * =============================================
14 * Copyright 2000 by Sun Microsystems, Inc.
15 * 901 San Antonio Road, Palo Alto, CA 94303, USA
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License version 2.1, as published by the Free Software Foundation.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 * MA 02111-1307 USA
32 * Sun Industry Standards Source License Version 1.1
33 * =================================================
34 * The contents of this file are subject to the Sun Industry Standards
35 * Source License Version 1.1 (the "License"); You may not use this file
36 * except in compliance with the License. You may obtain a copy of the
37 * License at http://www.openoffice.org/license.html.
39 * Software provided under this License is provided on an "AS IS" basis,
40 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43 * See the License for the specific provisions governing your rights and
44 * obligations concerning the Software.
46 * The Initial Developer of the Original Code is: IBM Corporation
48 * Copyright: 2008 by IBM Corporation
50 * All Rights Reserved.
52 * Contributor(s): _______________________________________
55 ************************************************************************/
56 /*************************************************************************
57 * @file
58 * For LWP filter architecture prototype
59 ************************************************************************/
60 /*************************************************************************
61 * Change History
62 Jan 2005 Created
63 ************************************************************************/
65 #include "lwptools.hxx"
66 #include <rtl/ustrbuf.hxx>
67 #include <osl/process.h>
68 #include <osl/thread.h>
69 #include <osl/file.hxx>
70 #include <vcl/svapp.hxx>
71 #include <vcl/settings.hxx>
72 #include <unicode/datefmt.h>
73 #include <unicode/udat.h>
74 #include <i18nlangtag/languagetagicu.hxx>
76 #ifdef SAL_UNX
77 #define SEPARATOR '/'
78 #else
79 #define SEPARATOR '\\'
80 #endif
82 using namespace ::rtl;
83 using namespace ::osl;
85 /**
86 * @descr read lwp unicode string from stream to OUString per aEncoding
88 sal_uInt16 LwpTools::QuickReadUnicode(LwpObjectStream* pObjStrm,
89 OUString& str, sal_uInt16 strlen, rtl_TextEncoding aEncoding)
90 //strlen: length of bytes
93 sal_uInt16 readLen = 0;
94 OUStringBuffer strBuf(128);
96 if( !IsUnicodePacked(pObjStrm, strlen) )
98 sal_uInt16 len = 0;
99 sal_Char buf[1024];
101 while(strlen)
103 strlen>1023?len=1023 :len=strlen;
104 len = pObjStrm->QuickRead(buf, len);
105 buf[len] = '\0';
106 strBuf.append( OUString(buf, len, aEncoding) );
107 strlen -= len;
108 readLen += len;
109 if(!len) break;
111 str = strBuf.makeStringAndClear();
112 return readLen;
114 else
116 sal_Char buf[1024];
117 sal_Unicode unibuf[1024];
118 sal_uInt8 readbyte;
119 sal_uInt16 readword;
121 bool flag = false; //switch if unicode part reached
122 sal_uInt16 sublen = 0;
124 while(readLen<strlen)
126 if(!flag) //Not unicode string
128 bool bFailure;
129 readbyte = pObjStrm->QuickReaduInt8(&bFailure);
130 if(bFailure) break;
131 readLen+=sizeof(readbyte);
133 if(readbyte == 0x00)
135 flag = true;
136 if(sublen>0) //add it to the strBuf
138 strBuf.append( OUString(buf, sublen, aEncoding) ); //try the aEncoding
139 sublen = 0;
142 else
144 buf[sublen++] = readbyte;
146 if(sublen>=1023 || readLen==strlen) //add it to the strBuf
148 strBuf.append( OUString(buf, sublen, aEncoding) ); //try the aEncoding
149 sublen = 0;
152 else //unicode string
154 bool bFailure;
155 readword = pObjStrm->QuickReaduInt16(&bFailure);
156 if(bFailure) break;
157 readLen+=sizeof(readword);
159 if(readword == 0x0000)
161 flag = false;
162 if(sublen)
164 unibuf[sublen] = '\0';
165 strBuf.append( OUString(unibuf) );
166 sublen = 0;
169 else
171 unibuf[sublen++] = readword;
173 if(sublen>=1023 || readLen==strlen)
175 unibuf[sublen] = '\0';
176 strBuf.append( OUString(unibuf) );
177 sublen = 0;
181 str = strBuf.makeStringAndClear();
182 return readLen;
187 * @descr Judge if the data (len) in object stream is lwp unicode packed
189 bool LwpTools::IsUnicodePacked(LwpObjectStream* pObjStrm, sal_uInt16 len)
191 sal_uInt8 byte;
192 sal_uInt16 oldpos = pObjStrm->GetPos();
194 for (sal_uInt16 i = 0; i < len; i++)
196 byte = pObjStrm->QuickReaduInt8();
197 if (byte == 0x00)
199 pObjStrm->Seek(oldpos);
200 return true;
203 pObjStrm->Seek(oldpos);
204 return false;
207 bool LwpTools::isFileUrl(const OString &fileName)
209 if (fileName.startsWith("file://") )
210 return true;
211 return false;
214 OUString LwpTools::convertToFileUrl(const OString &fileName)
216 if ( isFileUrl(fileName) )
218 return OStringToOUString(fileName, osl_getThreadTextEncoding());
221 OUString uUrlFileName;
222 OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
223 if ( fileName.startsWith(".") || fileName.indexOf(SEPARATOR) < 0 )
225 OUString uWorkingDir;
226 OSL_VERIFY( osl_getProcessWorkingDir(&uWorkingDir.pData) == osl_Process_E_None );
227 OSL_VERIFY( FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName) == FileBase::E_None );
228 } else
230 OSL_VERIFY( FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName) == FileBase::E_None );
233 return uUrlFileName;
236 OUString LwpTools::DateTimeToOUString(LtTm & dt)
238 OUString aResult = OUString::number(dt.tm_year) + "-" + OUString::number(dt.tm_mon) + "-" + OUString::number(dt.tm_mday) +
239 "T" + OUString::number(dt.tm_hour) + ":" + OUString::number(dt.tm_min) + ":" + OUString::number(dt.tm_sec);
241 return aResult;
245 * @descr get the system date format
247 XFDateStyle* LwpTools::GetSystemDateStyle(bool bLongFormat)
249 icu::DateFormat::EStyle style;
250 if (bLongFormat)
251 style = icu::DateFormat::FULL;//system full date format
252 else
253 style = icu::DateFormat::SHORT;//system short date format
255 //1 get locale for system
256 icu::Locale aLocale( LanguageTagIcu::getIcuLocale( Application::GetSettings().GetLanguageTag()));
257 //2 get icu format pattern by locale
258 icu::DateFormat* fmt = icu::DateFormat::createDateInstance(style,aLocale);
260 int32_t nLength = 0;
261 int32_t nLengthNeed;
262 UErrorCode status = U_ZERO_ERROR;
263 UChar* pattern = NULL;
265 nLengthNeed = udat_toPattern((void *const *)fmt,sal_False,NULL,nLength,&status);
266 if (status == U_BUFFER_OVERFLOW_ERROR)
268 status = U_ZERO_ERROR;
269 nLength = nLengthNeed +1;
270 pattern = (UChar*)malloc(sizeof(UChar)*nLength);
271 udat_toPattern((void *const *)fmt,sal_False,pattern,nLength,&status);
273 if (pattern == NULL)
274 return NULL;
275 // 3 parse pattern string,per icu date/time format syntax, there are 20 letters reserved
276 // as patter letter,each represent a element in date/time and its repeat numbers represent
277 // different format: for exampel: M produces '1',MM produces '01', MMM produces 'Jan', MMMM produces 'Januaray'
278 // letter other than these letters is regard as text in the format, for example ','in 'Jan,2005'
279 // we parse pattern string letter by letter and get the time format.
280 UChar cSymbol;
281 UChar cTmp;
282 XFDateStyle* pDateStyle = new XFDateStyle;
284 for (int32_t i=0;i<nLengthNeed;)
286 cSymbol = pattern[i];
287 int32_t j;
288 switch(cSymbol)
290 case 'G':
292 for (j=1;;j++)
294 cTmp = pattern[i+j];
295 if (cTmp != cSymbol)
297 i=i+j;
298 break;
301 pDateStyle->AddEra();
302 break;
304 case 'y':
306 for (j=1;;j++)
308 cTmp = pattern[i+j];
309 if (cTmp != cSymbol)
311 i=i+j;
312 break;
315 if (j <= 2)
316 pDateStyle->AddYear(false);
317 else
318 pDateStyle->AddYear();
319 break;
321 case 'M':
323 for (j=1;;j++)
325 cTmp = pattern[i+j];
326 if (cTmp != cSymbol)
328 i=i+j;
329 break;
332 if (j==1)
333 pDateStyle->AddMonth(false,false);
334 else if (j==2)
335 pDateStyle->AddMonth(true,false);
336 else if (j==3)
337 pDateStyle->AddMonth(false,true);
338 else
339 pDateStyle->AddMonth(true,true);
340 break;
342 case 'd':
344 for (j=1;;j++)
346 cTmp = pattern[i+j];
347 if (cTmp != cSymbol)
349 i=i+j;
350 break;
353 if (j==1)
354 pDateStyle->AddMonthDay(false);
355 else
356 pDateStyle->AddMonthDay();
357 break;
359 case 'h':
361 for (j=1;;j++)
363 cTmp = pattern[i+j];
364 if (cTmp != cSymbol)
366 i=i+j;
367 break;
370 if (j==1)
371 pDateStyle->AddHour(false);
372 else
373 pDateStyle->AddHour();
374 break;
376 case 'H':
378 for (j=1;;j++)
380 cTmp = pattern[i+j];
381 if (cTmp != cSymbol)
383 i=i+j;
384 break;
387 if (j==1)
388 pDateStyle->AddHour(false);
389 else
390 pDateStyle->AddHour();
391 break;
393 case 'm':
395 for (j=1;;j++)
397 cTmp = pattern[i+j];
398 if (cTmp != cSymbol)
400 i=i+j;
401 break;
404 if (j==1)
405 pDateStyle->AddMinute(false);
406 else
407 pDateStyle->AddMinute();
408 break;
410 case 's':
412 for (j=1;;j++)
414 cTmp = pattern[i+j];
415 if (cTmp != cSymbol)
417 i=i+j;
418 break;
421 if (j==1)
422 pDateStyle->AddSecond(false,0);
423 else
424 pDateStyle->AddSecond(true,0);
425 break;
427 case 'S':
429 for (j=1;;j++)
431 cTmp = pattern[i+j];
432 if (cTmp != cSymbol)
434 i=i+j;
435 break;
438 /*if (j==1)
439 pDateStyle->AddSecond(sal_False);
440 else
441 pDateStyle->AddSecond();*/
442 break;
444 case 'E':
446 for (j=1;;j++)
448 cTmp = pattern[i+j];
449 if (cTmp != cSymbol)
451 i=i+j;
452 break;
455 if (j<=2)
456 pDateStyle->AddWeekDay(false);
457 else
458 pDateStyle->AddWeekDay();
459 break;
461 case 'D':
463 for (j=1;;j++)
465 cTmp = pattern[i+j];
466 if (cTmp != cSymbol)
468 i=i+j;
469 break;
472 /*if (j==1)
473 pDateStyle->AddWeekDay(sal_False);
474 else
475 pDateStyle->AddWeekDay();*/
476 break;
478 case 'F':
480 for (j=1;;j++)
482 cTmp = pattern[i+j];
483 if (cTmp != cSymbol)
485 i=i+j;
486 break;
489 /*if (j==1)
490 pDateStyle->AddWeekDay(sal_False);
491 else
492 pDateStyle->AddWeekDay();*/
493 break;
495 case 'w':
497 for (j=1;;j++)
499 cTmp = pattern[i+j];
500 if (cTmp != cSymbol)
502 i=i+j;
503 break;
506 /*if (j==1)
507 pDateStyle->AddWeekDay(sal_False);
508 else
509 pDateStyle->AddWeekDay();*/
510 break;
512 case 'W':
514 for (j=1;;j++)
516 cTmp = pattern[i+j];
517 if (cTmp != cSymbol)
519 i=i+j;
520 break;
523 /*if (j==1)
524 pDateStyle->AddWeekDay(sal_False);
525 else
526 pDateStyle->AddWeekDay();*/
527 break;
529 case 'a':
531 for (j=1;;j++)
533 cTmp = pattern[i+j];
534 if (cTmp != cSymbol)
536 i=i+j;
537 break;
540 pDateStyle->AddAmPm(true);
541 break;
543 case 'k':
545 for (j=1;;j++)
547 cTmp = pattern[i+j];
548 if (cTmp != cSymbol)
550 i=i+j;
551 break;
554 break;
556 case 'K':
558 for (j=1;;j++)
560 cTmp = pattern[i+j];
561 if (cTmp != cSymbol)
563 i=i+j;
564 break;
567 if (j==1)
568 pDateStyle->AddHour(false);
569 else
570 pDateStyle->AddHour();
571 break;
573 case 'Z':
575 for (j=1;;j++)
577 cTmp = pattern[i+j];
578 if (cTmp != cSymbol)
580 i=i+j;
581 break;
584 break;
586 case '\''://'
588 for (j=1;;j++)
590 cTmp = pattern[i+j];
591 if (cTmp != cSymbol)
593 i=i+j;
594 break;
597 break;
599 case '"':
601 pDateStyle->AddText("'");
602 break;
604 default:
606 if ((cSymbol>='A' && cSymbol<='Z') || (cSymbol>='a' && cSymbol<='z') )
607 return NULL;
608 else//TEXT
610 //UChar buffer[1024];
611 sal_Unicode buffer[1024];
612 buffer[0] = cSymbol;
613 for (j=1;;j++)
615 cTmp = pattern[i+j];
616 if ((cTmp>='A' && cTmp<='Z') || (cTmp>='a' && cTmp<='z') ||
617 cTmp=='\'' || cTmp=='"' )
619 i=i+j;
620 buffer[j]= '\0';
621 break;
623 else
624 buffer[j] = cTmp;
627 pDateStyle->AddText(OUString(buffer));//keep for all parsed
629 break;
633 // udat_close(fmt);
634 return pDateStyle;
637 * @descr get the system time format
639 XFTimeStyle* LwpTools::GetSystemTimeStyle()
641 //1 get locale for system
642 icu::Locale aLocale( LanguageTagIcu::getIcuLocale( Application::GetSettings().GetLanguageTag()));
643 //2 get icu format pattern by locale
644 icu::DateFormat* fmt = icu::DateFormat::createTimeInstance(icu::DateFormat::DEFAULT,aLocale);
646 int32_t nLength = 0;
647 int32_t nLengthNeed;
648 UErrorCode status = U_ZERO_ERROR;
649 UChar* pattern = NULL;
650 nLengthNeed = udat_toPattern((void *const *)fmt,false,NULL,nLength,&status);
651 if (status == U_BUFFER_OVERFLOW_ERROR)
653 status = U_ZERO_ERROR;
654 nLength = nLengthNeed +1;
655 pattern = (UChar*)malloc(sizeof(UChar)*nLength);
656 udat_toPattern((void *const *)fmt,false,pattern,nLength,&status);
659 if (pattern == NULL)
660 return NULL;
661 // 3 parse pattern string,per icu date/time format syntax, there are 20 letters reserved
662 // as patter letter,each represent a element in date/time and its repeat numbers represent
663 // different format: for exampel: M produces '1',MM produces '01', MMM produces 'Jan', MMMM produces 'Januaray'
664 // letter other than these letters is regard as text in the format, for example ','in 'Jan,2005'
665 // we parse pattern string letter by letter and get the time format.
666 // for time format ,for there is not date info,we can only parse the letter representing time.
667 UChar cSymbol;
668 UChar cTmp;
669 XFTimeStyle* pTimeStyle = new XFTimeStyle;
671 for (int32_t i=0;i<nLengthNeed;)
673 cSymbol = pattern[i];
674 int32_t j;
675 switch(cSymbol)
677 case 'h':
679 for (j=1;;j++)
681 cTmp = pattern[i+j];
682 if (cTmp != cSymbol)
684 i=i+j;
685 break;
688 if (j==1)
689 pTimeStyle->AddHour(false);
690 else
691 pTimeStyle->AddHour();
692 break;
694 case 'H':
696 for (j=1;;j++)
698 cTmp = pattern[i+j];
699 if (cTmp != cSymbol)
701 i=i+j;
702 break;
705 if (j==1)
706 pTimeStyle->AddHour(false);
707 else
708 pTimeStyle->AddHour();
709 break;
711 case 'm':
713 for (j=1;;j++)
715 cTmp = pattern[i+j];
716 if (cTmp != cSymbol)
718 i=i+j;
719 break;
722 if (j==1)
723 pTimeStyle->AddMinute(false);
724 else
725 pTimeStyle->AddMinute();
726 break;
728 case 's':
730 for (j=1;;j++)
732 cTmp = pattern[i+j];
733 if (cTmp != cSymbol)
735 i=i+j;
736 break;
739 if (j==1)
740 pTimeStyle->AddSecond(false,0);
741 else
742 pTimeStyle->AddSecond(true,0);
743 break;
745 case 'S':
747 for (j=1;;j++)
749 cTmp = pattern[i+j];
750 if (cTmp != cSymbol)
752 i=i+j;
753 break;
756 /*if (j==1)
757 pDateStyle->AddSecond(sal_False);
758 else
759 pDateStyle->AddSecond();*/
760 break;
762 case 'a':
764 for (j=1;;j++)
766 cTmp = pattern[i+j];
767 if (cTmp != cSymbol)
769 i=i+j;
770 break;
773 pTimeStyle->SetAmPm(true);
774 break;
776 case 'k':
778 for (j=1;;j++)
780 cTmp = pattern[i+j];
781 if (cTmp != cSymbol)
783 i=i+j;
784 break;
787 break;
789 case 'K':
791 for (j=1;;j++)
793 cTmp = pattern[i+j];
794 if (cTmp != cSymbol)
796 i=i+j;
797 break;
800 if (j==1)
801 pTimeStyle->AddHour(false);
802 else
803 pTimeStyle->AddHour();
804 break;
806 case '\''://'
808 for (j=1;;j++)
810 cTmp = pattern[i+j];
811 if (cTmp != cSymbol)
813 i=i+j;
814 break;
817 break;
819 case '"':
821 pTimeStyle->AddText("'");
822 break;
824 default:
826 if ((cSymbol>='A' && cSymbol<='Z') || (cSymbol>='a' && cSymbol<='z') )
827 return NULL;
828 else//TEXT
830 sal_Unicode buffer[1024];
831 buffer[0] = cSymbol;
832 //strBuffer.append(cSymbol);
833 for (j=1;;j++)
835 cTmp = pattern[i+j];
836 if ((cTmp>='A' && cTmp<='Z') || (cTmp>='a' && cTmp<='z') ||
837 cTmp=='\'' || cTmp=='"' )
839 i=i+j;
840 buffer[j]= '\0';
841 break;
843 else
844 buffer[j] = cTmp;
846 pTimeStyle->AddText(OUString(buffer));//keep for all parsed
848 break;
852 // udat_close(fmt);
853 return pTimeStyle;
856 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */