summaryrefslogtreecommitdiffstats
path: root/lotuswordpro/source/filter/lwptools.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lotuswordpro/source/filter/lwptools.cxx850
1 files changed, 850 insertions, 0 deletions
diff --git a/lotuswordpro/source/filter/lwptools.cxx b/lotuswordpro/source/filter/lwptools.cxx
new file mode 100644
index 000000000..8a171fda7
--- /dev/null
+++ b/lotuswordpro/source/filter/lwptools.cxx
@@ -0,0 +1,850 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: IBM Corporation
+ *
+ * Copyright: 2008 by IBM Corporation
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+/*************************************************************************
+ * @file
+ * For LWP filter architecture prototype
+ ************************************************************************/
+
+#include <lwptools.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <o3tl/string_view.hxx>
+#include <osl/process.h>
+#include <osl/thread.h>
+#include <osl/file.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <unicode/datefmt.h>
+#include <unicode/udat.h>
+#include <i18nlangtag/languagetagicu.hxx>
+
+#ifdef SAL_UNX
+#define SEPARATOR '/'
+#else
+#define SEPARATOR '\\'
+#endif
+
+using namespace ::osl;
+
+/**
+ * @descr read lwp unicode string from stream to OUString per aEncoding
+*/
+void LwpTools::QuickReadUnicode(LwpObjectStream* pObjStrm,
+ OUString& str, sal_uInt16 strlen, rtl_TextEncoding aEncoding)
+ //strlen: length of bytes
+{
+ OUStringBuffer strBuf(128);
+
+ if( !IsUnicodePacked(pObjStrm, strlen) )
+ {
+ sal_uInt16 len = 0;
+ char buf[1024];
+
+ while(strlen)
+ {
+ len = std::min(sal_uInt16(1023), strlen);
+ len = pObjStrm->QuickRead(buf, len);
+ buf[len] = '\0';
+ strBuf.append( OUString(buf, len, aEncoding) );
+ strlen -= len;
+ if(!len) break;
+ }
+ str = strBuf.makeStringAndClear();
+ }
+ else
+ {
+ char buf[1024];
+ sal_Unicode unibuf[1024];
+ sal_uInt8 readbyte;
+ sal_uInt16 readword;
+
+ bool flag = false; //switch if unicode part reached
+ sal_uInt16 sublen = 0;
+
+ sal_uInt16 readLen = 0;
+ while(readLen<strlen)
+ {
+ if(!flag) //Not unicode string
+ {
+ bool bFailure;
+ readbyte = pObjStrm->QuickReaduInt8(&bFailure);
+ if(bFailure) break;
+ readLen+=sizeof(readbyte);
+
+ if(readbyte == 0x00)
+ {
+ flag = true;
+ if(sublen>0) //add it to the strBuf
+ {
+ strBuf.append( OUString(buf, sublen, aEncoding) ); //try the aEncoding
+ sublen = 0;
+ }
+ }
+ else
+ {
+ buf[sublen++] = readbyte;
+ }
+ if(sublen>=1023 || readLen==strlen) //add it to the strBuf
+ {
+ strBuf.append( OUString(buf, sublen, aEncoding) ); //try the aEncoding
+ sublen = 0;
+ }
+ }
+ else //unicode string
+ {
+ bool bFailure;
+ readword = pObjStrm->QuickReaduInt16(&bFailure);
+ if(bFailure) break;
+ readLen+=sizeof(readword);
+
+ if(readword == 0x0000)
+ {
+ flag = false;
+ if(sublen)
+ {
+ unibuf[sublen] = '\0';
+ strBuf.append( unibuf );
+ sublen = 0;
+ }
+ }
+ else
+ {
+ unibuf[sublen++] = readword;
+ }
+ if(sublen>=1023 || readLen==strlen)
+ {
+ unibuf[sublen] = '\0';
+ strBuf.append( unibuf );
+ sublen = 0;
+ }
+ }
+ }
+ str = strBuf.makeStringAndClear();
+ }
+}
+
+/**
+ * @descr Judge if the data (len) in object stream is lwp unicode packed
+*/
+bool LwpTools::IsUnicodePacked(LwpObjectStream* pObjStrm, sal_uInt16 len)
+{
+ sal_uInt8 byte;
+ sal_uInt16 oldpos = pObjStrm->GetPos();
+
+ for (sal_uInt16 i = 0; i < len; i++)
+ {
+ byte = pObjStrm->QuickReaduInt8();
+ if (byte == 0x00)
+ {
+ pObjStrm->Seek(oldpos);
+ return true;
+ }
+ }
+ pObjStrm->Seek(oldpos);
+ return false;
+}
+
+bool LwpTools::isFileUrl(std::string_view fileName)
+{
+ return o3tl::starts_with(fileName, "file://");
+}
+
+OUString LwpTools::convertToFileUrl(const OString &fileName)
+{
+ if ( isFileUrl(fileName) )
+ {
+ return OStringToOUString(fileName, osl_getThreadTextEncoding());
+ }
+
+ OUString uUrlFileName;
+ OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
+ if ( fileName.startsWith(".") || fileName.indexOf(SEPARATOR) < 0 )
+ {
+ OUString uWorkingDir;
+ OSL_VERIFY( osl_getProcessWorkingDir(&uWorkingDir.pData) == osl_Process_E_None );
+ OSL_VERIFY( FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName) == FileBase::E_None );
+ } else
+ {
+ OSL_VERIFY( FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName) == FileBase::E_None );
+ }
+
+ return uUrlFileName;
+}
+
+OUString LwpTools::DateTimeToOUString(const LtTm &dt)
+{
+ OUString aResult = OUString::number(dt.tm_year) + "-" + OUString::number(dt.tm_mon) + "-" + OUString::number(dt.tm_mday) +
+ "T" + OUString::number(dt.tm_hour) + ":" + OUString::number(dt.tm_min) + ":" + OUString::number(dt.tm_sec);
+
+ return aResult;
+}
+
+/**
+ * @descr get the system date format
+*/
+std::unique_ptr<XFDateStyle> LwpTools::GetSystemDateStyle(bool bLongFormat)
+{
+ icu::DateFormat::EStyle style;
+ if (bLongFormat)
+ style = icu::DateFormat::FULL;//system full date format
+ else
+ style = icu::DateFormat::SHORT;//system short date format
+
+ //1 get locale for system
+ icu::Locale aLocale( LanguageTagIcu::getIcuLocale( Application::GetSettings().GetLanguageTag()));
+ //2 get icu format pattern by locale
+ icu::DateFormat* fmt = icu::DateFormat::createDateInstance(style,aLocale);
+
+ int32_t nLength = 0;
+ int32_t nLengthNeed;
+ UErrorCode status = U_ZERO_ERROR;
+ UChar* pattern = nullptr;
+
+ nLengthNeed = udat_toPattern(reinterpret_cast<void **>(fmt),false,nullptr,nLength,&status);
+ if (status == U_BUFFER_OVERFLOW_ERROR)
+ {
+ status = U_ZERO_ERROR;
+ nLength = nLengthNeed +1;
+ pattern = static_cast<UChar*>(malloc(sizeof(UChar)*nLength));
+ udat_toPattern(reinterpret_cast<void **>(fmt),false,pattern,nLength,&status);
+ }
+ if (pattern == nullptr)
+ return nullptr;
+ // 3 parse pattern string,per icu date/time format syntax, there are 20 letters reserved
+ // as pattern letter,each represent an element in date/time and its repeat numbers represent
+ // different format: for example: M produces '1', MM produces '01', MMM produces 'Jan', MMMM produces 'January'
+ // letter other than these letters is regard as text in the format, for example ',' in 'Jan,2005'
+ // we parse pattern string letter by letter and get the time format.
+ UChar cSymbol;
+ UChar cTmp;
+ std::unique_ptr<XFDateStyle> pDateStyle(new XFDateStyle);
+
+ for (int32_t i=0;i<nLengthNeed;)
+ {
+ cSymbol = pattern[i];
+ int32_t j;
+ switch(cSymbol)
+ {
+ case 'G':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ pDateStyle->AddEra();
+ break;
+ }
+ case 'y':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ if (j <= 2)
+ pDateStyle->AddYear(false);
+ else
+ pDateStyle->AddYear();
+ break;
+ }
+ case 'M':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ if (j==1)
+ pDateStyle->AddMonth(false);
+ else if (j==2)
+ pDateStyle->AddMonth();
+ else if (j==3)
+ pDateStyle->AddMonth(false,true);
+ else
+ pDateStyle->AddMonth(true,true);
+ break;
+ }
+ case 'd':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ if (j==1)
+ pDateStyle->AddMonthDay(false);
+ else
+ pDateStyle->AddMonthDay();
+ break;
+ }
+ case 'h':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ if (j==1)
+ pDateStyle->AddHour(false);
+ else
+ pDateStyle->AddHour();
+ break;
+ }
+ case 'H':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ if (j==1)
+ pDateStyle->AddHour(false);
+ else
+ pDateStyle->AddHour();
+ break;
+ }
+ case 'm':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ if (j==1)
+ pDateStyle->AddMinute(false);
+ else
+ pDateStyle->AddMinute();
+ break;
+ }
+ case 's':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ if (j==1)
+ pDateStyle->AddSecond(false);
+ else
+ pDateStyle->AddSecond();
+ break;
+ }
+ case 'S':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ /*if (j==1)
+ pDateStyle->AddSecond(sal_False);
+ else
+ pDateStyle->AddSecond();*/
+ break;
+ }
+ case 'E':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ if (j<=2)
+ pDateStyle->AddWeekDay(false);
+ else
+ pDateStyle->AddWeekDay();
+ break;
+ }
+ case 'D':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ /*if (j==1)
+ pDateStyle->AddWeekDay(sal_False);
+ else
+ pDateStyle->AddWeekDay();*/
+ break;
+ }
+ case 'F':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ /*if (j==1)
+ pDateStyle->AddWeekDay(sal_False);
+ else
+ pDateStyle->AddWeekDay();*/
+ break;
+ }
+ case 'w':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ /*if (j==1)
+ pDateStyle->AddWeekDay(sal_False);
+ else
+ pDateStyle->AddWeekDay();*/
+ break;
+ }
+ case 'W':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ /*if (j==1)
+ pDateStyle->AddWeekDay(sal_False);
+ else
+ pDateStyle->AddWeekDay();*/
+ break;
+ }
+ case 'a':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ pDateStyle->AddAmPm();
+ break;
+ }
+ case 'k':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ break;
+ }
+ case 'K':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ if (j==1)
+ pDateStyle->AddHour(false);
+ else
+ pDateStyle->AddHour();
+ break;
+ }
+ case 'Z':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ break;
+ }
+ case '\''://'
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ break;
+ }
+ case '"':
+ {
+ pDateStyle->AddText("'");
+ break;
+ }
+ default:
+ {
+ if ((cSymbol>='A' && cSymbol<='Z') || (cSymbol>='a' && cSymbol<='z') )
+ {
+ return nullptr;
+ }
+ else//TEXT
+ {
+ //UChar buffer[1024];
+ sal_Unicode buffer[1024];
+ buffer[0] = cSymbol;
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if ((cTmp>='A' && cTmp<='Z') || (cTmp>='a' && cTmp<='z') ||
+ cTmp=='\'' || cTmp=='"' )
+ {
+ i=i+j;
+ buffer[j]= '\0';
+ break;
+ }
+ else
+ buffer[j] = cTmp;
+ }
+
+ pDateStyle->AddText(OUString(buffer));//keep for all parsed
+ }
+ break;
+ }
+ }
+ }
+// udat_close(fmt);
+ return pDateStyle;
+}
+/**
+ * @descr get the system time format
+*/
+std::unique_ptr<XFTimeStyle> LwpTools::GetSystemTimeStyle()
+{
+ //1 get locale for system
+ icu::Locale aLocale( LanguageTagIcu::getIcuLocale( Application::GetSettings().GetLanguageTag()));
+ //2 get icu format pattern by locale
+ icu::DateFormat* fmt = icu::DateFormat::createTimeInstance(icu::DateFormat::DEFAULT,aLocale);
+
+ int32_t nLength = 0;
+ int32_t nLengthNeed;
+ UErrorCode status = U_ZERO_ERROR;
+ UChar* pattern = nullptr;
+ nLengthNeed = udat_toPattern(reinterpret_cast<void **>(fmt),false,nullptr,nLength,&status);
+ if (status == U_BUFFER_OVERFLOW_ERROR)
+ {
+ status = U_ZERO_ERROR;
+ nLength = nLengthNeed +1;
+ pattern = static_cast<UChar*>(malloc(sizeof(UChar)*nLength));
+ udat_toPattern(reinterpret_cast<void **>(fmt),false,pattern,nLength,&status);
+ }
+
+ if (pattern == nullptr)
+ return nullptr;
+ // 3 parse pattern string,per icu date/time format syntax, there are 20 letters reserved
+ // as pattern letter,each represent an element in date/time and its repeat numbers represent
+ // different format: for example: M produces '1',MM produces '01', MMM produces 'Jan', MMMM produces 'Januaray'
+ // letter other than these letters is regard as text in the format, for example ','in 'Jan,2005'
+ // we parse pattern string letter by letter and get the time format.
+ // for time format ,for there is not date info,we can only parse the letter representing time.
+ UChar cSymbol;
+ UChar cTmp;
+ std::unique_ptr<XFTimeStyle> pTimeStyle(new XFTimeStyle);
+
+ for (int32_t i=0;i<nLengthNeed;)
+ {
+ cSymbol = pattern[i];
+ int32_t j;
+ switch(cSymbol)
+ {
+ case 'h':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ if (j==1)
+ pTimeStyle->AddHour(false);
+ else
+ pTimeStyle->AddHour();
+ break;
+ }
+ case 'H':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ if (j==1)
+ pTimeStyle->AddHour(false);
+ else
+ pTimeStyle->AddHour();
+ break;
+ }
+ case 'm':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ if (j==1)
+ pTimeStyle->AddMinute(false);
+ else
+ pTimeStyle->AddMinute();
+ break;
+ }
+ case 's':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ if (j==1)
+ pTimeStyle->AddSecond(false);
+ else
+ pTimeStyle->AddSecond();
+ break;
+ }
+ case 'S':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ /*if (j==1)
+ pDateStyle->AddSecond(sal_False);
+ else
+ pDateStyle->AddSecond();*/
+ break;
+ }
+ case 'a':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ pTimeStyle->SetAmPm(true);
+ break;
+ }
+ case 'k':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ break;
+ }
+ case 'K':
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ if (j==1)
+ pTimeStyle->AddHour(false);
+ else
+ pTimeStyle->AddHour();
+ break;
+ }
+ case '\''://'
+ {
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if (cTmp != cSymbol)
+ {
+ i=i+j;
+ break;
+ }
+ }
+ break;
+ }
+ case '"':
+ {
+ pTimeStyle->AddText("'");
+ break;
+ }
+ default:
+ {
+ if ((cSymbol>='A' && cSymbol<='Z') || (cSymbol>='a' && cSymbol<='z') )
+ {
+ return nullptr;
+ }
+ else//TEXT
+ {
+ sal_Unicode buffer[1024];
+ buffer[0] = cSymbol;
+ //strBuffer.append(cSymbol);
+ for (j=1;;j++)
+ {
+ cTmp = pattern[i+j];
+ if ((cTmp>='A' && cTmp<='Z') || (cTmp>='a' && cTmp<='z') ||
+ cTmp=='\'' || cTmp=='"' )
+ {
+ i=i+j;
+ buffer[j]= '\0';
+ break;
+ }
+ else
+ buffer[j] = cTmp;
+ }
+ pTimeStyle->AddText(OUString(buffer));//keep for all parsed
+ }
+ break;
+ }
+ }
+ }
+// udat_close(fmt);
+ return pTimeStyle;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */