Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / lotuswordpro / source / filter / lwptools.cxx
blobcf04d1d64d0c663da60b7cce43b6c5a47d9ad0f9
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 ************************************************************************/
61 #include "lwptools.hxx"
62 #include <rtl/ustrbuf.hxx>
63 #include <osl/process.h>
64 #include <osl/thread.h>
65 #include <osl/file.hxx>
66 #include <vcl/svapp.hxx>
67 #include <vcl/settings.hxx>
68 #include <unicode/datefmt.h>
69 #include <unicode/udat.h>
70 #include <i18nlangtag/languagetagicu.hxx>
72 #ifdef SAL_UNX
73 #define SEPARATOR '/'
74 #else
75 #define SEPARATOR '\\'
76 #endif
78 using namespace ::osl;
80 /**
81 * @descr read lwp unicode string from stream to OUString per aEncoding
83 void LwpTools::QuickReadUnicode(LwpObjectStream* pObjStrm,
84 OUString& str, sal_uInt16 strlen, rtl_TextEncoding aEncoding)
85 //strlen: length of bytes
87 OUStringBuffer strBuf(128);
89 if( !IsUnicodePacked(pObjStrm, strlen) )
91 sal_uInt16 len = 0;
92 sal_Char buf[1024];
94 while(strlen)
96 strlen>1023?len=1023 :len=strlen;
97 len = pObjStrm->QuickRead(buf, len);
98 buf[len] = '\0';
99 strBuf.append( OUString(buf, len, aEncoding) );
100 strlen -= len;
101 if(!len) break;
103 str = strBuf.makeStringAndClear();
105 else
107 sal_Char buf[1024];
108 sal_Unicode unibuf[1024];
109 sal_uInt8 readbyte;
110 sal_uInt16 readword;
112 bool flag = false; //switch if unicode part reached
113 sal_uInt16 sublen = 0;
115 sal_uInt16 readLen = 0;
116 while(readLen<strlen)
118 if(!flag) //Not unicode string
120 bool bFailure;
121 readbyte = pObjStrm->QuickReaduInt8(&bFailure);
122 if(bFailure) break;
123 readLen+=sizeof(readbyte);
125 if(readbyte == 0x00)
127 flag = true;
128 if(sublen>0) //add it to the strBuf
130 strBuf.append( OUString(buf, sublen, aEncoding) ); //try the aEncoding
131 sublen = 0;
134 else
136 buf[sublen++] = readbyte;
138 if(sublen>=1023 || readLen==strlen) //add it to the strBuf
140 strBuf.append( OUString(buf, sublen, aEncoding) ); //try the aEncoding
141 sublen = 0;
144 else //unicode string
146 bool bFailure;
147 readword = pObjStrm->QuickReaduInt16(&bFailure);
148 if(bFailure) break;
149 readLen+=sizeof(readword);
151 if(readword == 0x0000)
153 flag = false;
154 if(sublen)
156 unibuf[sublen] = '\0';
157 strBuf.append( OUString(unibuf) );
158 sublen = 0;
161 else
163 unibuf[sublen++] = readword;
165 if(sublen>=1023 || readLen==strlen)
167 unibuf[sublen] = '\0';
168 strBuf.append( OUString(unibuf) );
169 sublen = 0;
173 str = strBuf.makeStringAndClear();
178 * @descr Judge if the data (len) in object stream is lwp unicode packed
180 bool LwpTools::IsUnicodePacked(LwpObjectStream* pObjStrm, sal_uInt16 len)
182 sal_uInt8 byte;
183 sal_uInt16 oldpos = pObjStrm->GetPos();
185 for (sal_uInt16 i = 0; i < len; i++)
187 byte = pObjStrm->QuickReaduInt8();
188 if (byte == 0x00)
190 pObjStrm->Seek(oldpos);
191 return true;
194 pObjStrm->Seek(oldpos);
195 return false;
198 bool LwpTools::isFileUrl(const OString &fileName)
200 if (fileName.startsWith("file://") )
201 return true;
202 return false;
205 OUString LwpTools::convertToFileUrl(const OString &fileName)
207 if ( isFileUrl(fileName) )
209 return OStringToOUString(fileName, osl_getThreadTextEncoding());
212 OUString uUrlFileName;
213 OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
214 if ( fileName.startsWith(".") || fileName.indexOf(SEPARATOR) < 0 )
216 OUString uWorkingDir;
217 OSL_VERIFY( osl_getProcessWorkingDir(&uWorkingDir.pData) == osl_Process_E_None );
218 OSL_VERIFY( FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName) == FileBase::E_None );
219 } else
221 OSL_VERIFY( FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName) == FileBase::E_None );
224 return uUrlFileName;
227 OUString LwpTools::DateTimeToOUString(LtTm & dt)
229 OUString aResult = OUString::number(dt.tm_year) + "-" + OUString::number(dt.tm_mon) + "-" + OUString::number(dt.tm_mday) +
230 "T" + OUString::number(dt.tm_hour) + ":" + OUString::number(dt.tm_min) + ":" + OUString::number(dt.tm_sec);
232 return aResult;
236 * @descr get the system date format
238 XFDateStyle* LwpTools::GetSystemDateStyle(bool bLongFormat)
240 icu::DateFormat::EStyle style;
241 if (bLongFormat)
242 style = icu::DateFormat::FULL;//system full date format
243 else
244 style = icu::DateFormat::SHORT;//system short date format
246 //1 get locale for system
247 icu::Locale aLocale( LanguageTagIcu::getIcuLocale( Application::GetSettings().GetLanguageTag()));
248 //2 get icu format pattern by locale
249 icu::DateFormat* fmt = icu::DateFormat::createDateInstance(style,aLocale);
251 int32_t nLength = 0;
252 int32_t nLengthNeed;
253 UErrorCode status = U_ZERO_ERROR;
254 UChar* pattern = nullptr;
256 nLengthNeed = udat_toPattern(reinterpret_cast<void **>(fmt),false,nullptr,nLength,&status);
257 if (status == U_BUFFER_OVERFLOW_ERROR)
259 status = U_ZERO_ERROR;
260 nLength = nLengthNeed +1;
261 pattern = static_cast<UChar*>(malloc(sizeof(UChar)*nLength));
262 udat_toPattern(reinterpret_cast<void **>(fmt),false,pattern,nLength,&status);
264 if (pattern == nullptr)
265 return nullptr;
266 // 3 parse pattern string,per icu date/time format syntax, there are 20 letters reserved
267 // as patter letter,each represent a element in date/time and its repeat numbers represent
268 // different format: for exampel: M produces '1',MM produces '01', MMM produces 'Jan', MMMM produces 'Januaray'
269 // letter other than these letters is regard as text in the format, for example ','in 'Jan,2005'
270 // we parse pattern string letter by letter and get the time format.
271 UChar cSymbol;
272 UChar cTmp;
273 XFDateStyle* pDateStyle = new XFDateStyle;
275 for (int32_t i=0;i<nLengthNeed;)
277 cSymbol = pattern[i];
278 int32_t j;
279 switch(cSymbol)
281 case 'G':
283 for (j=1;;j++)
285 cTmp = pattern[i+j];
286 if (cTmp != cSymbol)
288 i=i+j;
289 break;
292 pDateStyle->AddEra();
293 break;
295 case 'y':
297 for (j=1;;j++)
299 cTmp = pattern[i+j];
300 if (cTmp != cSymbol)
302 i=i+j;
303 break;
306 if (j <= 2)
307 pDateStyle->AddYear(false);
308 else
309 pDateStyle->AddYear();
310 break;
312 case 'M':
314 for (j=1;;j++)
316 cTmp = pattern[i+j];
317 if (cTmp != cSymbol)
319 i=i+j;
320 break;
323 if (j==1)
324 pDateStyle->AddMonth(false);
325 else if (j==2)
326 pDateStyle->AddMonth();
327 else if (j==3)
328 pDateStyle->AddMonth(false,true);
329 else
330 pDateStyle->AddMonth(true,true);
331 break;
333 case 'd':
335 for (j=1;;j++)
337 cTmp = pattern[i+j];
338 if (cTmp != cSymbol)
340 i=i+j;
341 break;
344 if (j==1)
345 pDateStyle->AddMonthDay(false);
346 else
347 pDateStyle->AddMonthDay();
348 break;
350 case 'h':
352 for (j=1;;j++)
354 cTmp = pattern[i+j];
355 if (cTmp != cSymbol)
357 i=i+j;
358 break;
361 if (j==1)
362 pDateStyle->AddHour(false);
363 else
364 pDateStyle->AddHour();
365 break;
367 case 'H':
369 for (j=1;;j++)
371 cTmp = pattern[i+j];
372 if (cTmp != cSymbol)
374 i=i+j;
375 break;
378 if (j==1)
379 pDateStyle->AddHour(false);
380 else
381 pDateStyle->AddHour();
382 break;
384 case 'm':
386 for (j=1;;j++)
388 cTmp = pattern[i+j];
389 if (cTmp != cSymbol)
391 i=i+j;
392 break;
395 if (j==1)
396 pDateStyle->AddMinute(false);
397 else
398 pDateStyle->AddMinute();
399 break;
401 case 's':
403 for (j=1;;j++)
405 cTmp = pattern[i+j];
406 if (cTmp != cSymbol)
408 i=i+j;
409 break;
412 if (j==1)
413 pDateStyle->AddSecond(false);
414 else
415 pDateStyle->AddSecond();
416 break;
418 case 'S':
420 for (j=1;;j++)
422 cTmp = pattern[i+j];
423 if (cTmp != cSymbol)
425 i=i+j;
426 break;
429 /*if (j==1)
430 pDateStyle->AddSecond(sal_False);
431 else
432 pDateStyle->AddSecond();*/
433 break;
435 case 'E':
437 for (j=1;;j++)
439 cTmp = pattern[i+j];
440 if (cTmp != cSymbol)
442 i=i+j;
443 break;
446 if (j<=2)
447 pDateStyle->AddWeekDay(false);
448 else
449 pDateStyle->AddWeekDay();
450 break;
452 case 'D':
454 for (j=1;;j++)
456 cTmp = pattern[i+j];
457 if (cTmp != cSymbol)
459 i=i+j;
460 break;
463 /*if (j==1)
464 pDateStyle->AddWeekDay(sal_False);
465 else
466 pDateStyle->AddWeekDay();*/
467 break;
469 case 'F':
471 for (j=1;;j++)
473 cTmp = pattern[i+j];
474 if (cTmp != cSymbol)
476 i=i+j;
477 break;
480 /*if (j==1)
481 pDateStyle->AddWeekDay(sal_False);
482 else
483 pDateStyle->AddWeekDay();*/
484 break;
486 case 'w':
488 for (j=1;;j++)
490 cTmp = pattern[i+j];
491 if (cTmp != cSymbol)
493 i=i+j;
494 break;
497 /*if (j==1)
498 pDateStyle->AddWeekDay(sal_False);
499 else
500 pDateStyle->AddWeekDay();*/
501 break;
503 case 'W':
505 for (j=1;;j++)
507 cTmp = pattern[i+j];
508 if (cTmp != cSymbol)
510 i=i+j;
511 break;
514 /*if (j==1)
515 pDateStyle->AddWeekDay(sal_False);
516 else
517 pDateStyle->AddWeekDay();*/
518 break;
520 case 'a':
522 for (j=1;;j++)
524 cTmp = pattern[i+j];
525 if (cTmp != cSymbol)
527 i=i+j;
528 break;
531 pDateStyle->AddAmPm();
532 break;
534 case 'k':
536 for (j=1;;j++)
538 cTmp = pattern[i+j];
539 if (cTmp != cSymbol)
541 i=i+j;
542 break;
545 break;
547 case 'K':
549 for (j=1;;j++)
551 cTmp = pattern[i+j];
552 if (cTmp != cSymbol)
554 i=i+j;
555 break;
558 if (j==1)
559 pDateStyle->AddHour(false);
560 else
561 pDateStyle->AddHour();
562 break;
564 case 'Z':
566 for (j=1;;j++)
568 cTmp = pattern[i+j];
569 if (cTmp != cSymbol)
571 i=i+j;
572 break;
575 break;
577 case '\''://'
579 for (j=1;;j++)
581 cTmp = pattern[i+j];
582 if (cTmp != cSymbol)
584 i=i+j;
585 break;
588 break;
590 case '"':
592 pDateStyle->AddText("'");
593 break;
595 default:
597 if ((cSymbol>='A' && cSymbol<='Z') || (cSymbol>='a' && cSymbol<='z') )
599 delete pDateStyle;
600 return nullptr;
602 else//TEXT
604 //UChar buffer[1024];
605 sal_Unicode buffer[1024];
606 buffer[0] = cSymbol;
607 for (j=1;;j++)
609 cTmp = pattern[i+j];
610 if ((cTmp>='A' && cTmp<='Z') || (cTmp>='a' && cTmp<='z') ||
611 cTmp=='\'' || cTmp=='"' )
613 i=i+j;
614 buffer[j]= '\0';
615 break;
617 else
618 buffer[j] = cTmp;
621 pDateStyle->AddText(OUString(buffer));//keep for all parsed
623 break;
627 // udat_close(fmt);
628 return pDateStyle;
631 * @descr get the system time format
633 XFTimeStyle* LwpTools::GetSystemTimeStyle()
635 //1 get locale for system
636 icu::Locale aLocale( LanguageTagIcu::getIcuLocale( Application::GetSettings().GetLanguageTag()));
637 //2 get icu format pattern by locale
638 icu::DateFormat* fmt = icu::DateFormat::createTimeInstance(icu::DateFormat::DEFAULT,aLocale);
640 int32_t nLength = 0;
641 int32_t nLengthNeed;
642 UErrorCode status = U_ZERO_ERROR;
643 UChar* pattern = nullptr;
644 nLengthNeed = udat_toPattern(reinterpret_cast<void **>(fmt),false,nullptr,nLength,&status);
645 if (status == U_BUFFER_OVERFLOW_ERROR)
647 status = U_ZERO_ERROR;
648 nLength = nLengthNeed +1;
649 pattern = static_cast<UChar*>(malloc(sizeof(UChar)*nLength));
650 udat_toPattern(reinterpret_cast<void **>(fmt),false,pattern,nLength,&status);
653 if (pattern == nullptr)
654 return nullptr;
655 // 3 parse pattern string,per icu date/time format syntax, there are 20 letters reserved
656 // as patter letter,each represent a element in date/time and its repeat numbers represent
657 // different format: for exampel: M produces '1',MM produces '01', MMM produces 'Jan', MMMM produces 'Januaray'
658 // letter other than these letters is regard as text in the format, for example ','in 'Jan,2005'
659 // we parse pattern string letter by letter and get the time format.
660 // for time format ,for there is not date info,we can only parse the letter representing time.
661 UChar cSymbol;
662 UChar cTmp;
663 XFTimeStyle* pTimeStyle = new XFTimeStyle;
665 for (int32_t i=0;i<nLengthNeed;)
667 cSymbol = pattern[i];
668 int32_t j;
669 switch(cSymbol)
671 case 'h':
673 for (j=1;;j++)
675 cTmp = pattern[i+j];
676 if (cTmp != cSymbol)
678 i=i+j;
679 break;
682 if (j==1)
683 pTimeStyle->AddHour(false);
684 else
685 pTimeStyle->AddHour();
686 break;
688 case 'H':
690 for (j=1;;j++)
692 cTmp = pattern[i+j];
693 if (cTmp != cSymbol)
695 i=i+j;
696 break;
699 if (j==1)
700 pTimeStyle->AddHour(false);
701 else
702 pTimeStyle->AddHour();
703 break;
705 case 'm':
707 for (j=1;;j++)
709 cTmp = pattern[i+j];
710 if (cTmp != cSymbol)
712 i=i+j;
713 break;
716 if (j==1)
717 pTimeStyle->AddMinute(false);
718 else
719 pTimeStyle->AddMinute();
720 break;
722 case 's':
724 for (j=1;;j++)
726 cTmp = pattern[i+j];
727 if (cTmp != cSymbol)
729 i=i+j;
730 break;
733 if (j==1)
734 pTimeStyle->AddSecond(false);
735 else
736 pTimeStyle->AddSecond();
737 break;
739 case 'S':
741 for (j=1;;j++)
743 cTmp = pattern[i+j];
744 if (cTmp != cSymbol)
746 i=i+j;
747 break;
750 /*if (j==1)
751 pDateStyle->AddSecond(sal_False);
752 else
753 pDateStyle->AddSecond();*/
754 break;
756 case 'a':
758 for (j=1;;j++)
760 cTmp = pattern[i+j];
761 if (cTmp != cSymbol)
763 i=i+j;
764 break;
767 pTimeStyle->SetAmPm(true);
768 break;
770 case 'k':
772 for (j=1;;j++)
774 cTmp = pattern[i+j];
775 if (cTmp != cSymbol)
777 i=i+j;
778 break;
781 break;
783 case 'K':
785 for (j=1;;j++)
787 cTmp = pattern[i+j];
788 if (cTmp != cSymbol)
790 i=i+j;
791 break;
794 if (j==1)
795 pTimeStyle->AddHour(false);
796 else
797 pTimeStyle->AddHour();
798 break;
800 case '\''://'
802 for (j=1;;j++)
804 cTmp = pattern[i+j];
805 if (cTmp != cSymbol)
807 i=i+j;
808 break;
811 break;
813 case '"':
815 pTimeStyle->AddText("'");
816 break;
818 default:
820 if ((cSymbol>='A' && cSymbol<='Z') || (cSymbol>='a' && cSymbol<='z') )
822 delete pTimeStyle;
823 return nullptr;
825 else//TEXT
827 sal_Unicode buffer[1024];
828 buffer[0] = cSymbol;
829 //strBuffer.append(cSymbol);
830 for (j=1;;j++)
832 cTmp = pattern[i+j];
833 if ((cTmp>='A' && cTmp<='Z') || (cTmp>='a' && cTmp<='z') ||
834 cTmp=='\'' || cTmp=='"' )
836 i=i+j;
837 buffer[j]= '\0';
838 break;
840 else
841 buffer[j] = cTmp;
843 pTimeStyle->AddText(OUString(buffer));//keep for all parsed
845 break;
849 // udat_close(fmt);
850 return pTimeStyle;
853 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */