LibreOffice Module lotuswordpro (master) 1
lwptools.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*************************************************************************
3 *
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
6 *
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
9 *
10 * Sun Microsystems Inc., October, 2000
11 *
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
16 *
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.
20 *
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.
25 *
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
30 *
31 *
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.
38 *
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.
45 *
46 * The Initial Developer of the Original Code is: IBM Corporation
47 *
48 * Copyright: 2008 by IBM Corporation
49 *
50 * All Rights Reserved.
51 *
52 * Contributor(s): _______________________________________
53 *
54 *
55 ************************************************************************/
56/*************************************************************************
57 * @file
58 * For LWP filter architecture prototype
59 ************************************************************************/
60
61#include <lwptools.hxx>
62#include <rtl/ustrbuf.hxx>
63#include <o3tl/string_view.hxx>
64#include <osl/process.h>
65#include <osl/thread.h>
66#include <osl/file.hxx>
67#include <vcl/svapp.hxx>
68#include <vcl/settings.hxx>
69#include <unicode/datefmt.h>
70#include <unicode/udat.h>
72
73#ifdef SAL_UNX
74#define SEPARATOR '/'
75#else
76#define SEPARATOR '\\'
77#endif
78
79using namespace ::osl;
80
85 OUString& str, sal_uInt16 strlen, rtl_TextEncoding aEncoding)
86 //strlen: length of bytes
87{
88 OUStringBuffer strBuf(128);
89
90 if( !IsUnicodePacked(pObjStrm, strlen) )
91 {
92 sal_uInt16 len = 0;
93 char buf[1024];
94
95 while(strlen)
96 {
97 len = std::min(sal_uInt16(1023), strlen);
98 len = pObjStrm->QuickRead(buf, len);
99 buf[len] = '\0';
100 strBuf.append( OUString(buf, len, aEncoding) );
101 strlen -= len;
102 if(!len) break;
103 }
104 str = strBuf.makeStringAndClear();
105 }
106 else
107 {
108 char buf[1024];
109 sal_Unicode unibuf[1024];
110 sal_uInt8 readbyte;
111 sal_uInt16 readword;
112
113 bool flag = false; //switch if unicode part reached
114 sal_uInt16 sublen = 0;
115
116 sal_uInt16 readLen = 0;
117 while(readLen<strlen)
118 {
119 if(!flag) //Not unicode string
120 {
121 bool bFailure;
122 readbyte = pObjStrm->QuickReaduInt8(&bFailure);
123 if(bFailure) break;
124 readLen+=sizeof(readbyte);
125
126 if(readbyte == 0x00)
127 {
128 flag = true;
129 if(sublen>0) //add it to the strBuf
130 {
131 strBuf.append( OUString(buf, sublen, aEncoding) ); //try the aEncoding
132 sublen = 0;
133 }
134 }
135 else
136 {
137 buf[sublen++] = readbyte;
138 }
139 if(sublen>=1023 || readLen==strlen) //add it to the strBuf
140 {
141 strBuf.append( OUString(buf, sublen, aEncoding) ); //try the aEncoding
142 sublen = 0;
143 }
144 }
145 else //unicode string
146 {
147 bool bFailure;
148 readword = pObjStrm->QuickReaduInt16(&bFailure);
149 if(bFailure) break;
150 readLen+=sizeof(readword);
151
152 if(readword == 0x0000)
153 {
154 flag = false;
155 if(sublen)
156 {
157 unibuf[sublen] = '\0';
158 strBuf.append( unibuf );
159 sublen = 0;
160 }
161 }
162 else
163 {
164 unibuf[sublen++] = readword;
165 }
166 if(sublen>=1023 || readLen==strlen)
167 {
168 unibuf[sublen] = '\0';
169 strBuf.append( unibuf );
170 sublen = 0;
171 }
172 }
173 }
174 str = strBuf.makeStringAndClear();
175 }
176}
177
181bool LwpTools::IsUnicodePacked(LwpObjectStream* pObjStrm, sal_uInt16 len)
182{
184 sal_uInt16 oldpos = pObjStrm->GetPos();
185
186 for (sal_uInt16 i = 0; i < len; i++)
187 {
188 byte = pObjStrm->QuickReaduInt8();
189 if (byte == 0x00)
190 {
191 pObjStrm->Seek(oldpos);
192 return true;
193 }
194 }
195 pObjStrm->Seek(oldpos);
196 return false;
197}
198
199bool LwpTools::isFileUrl(std::string_view fileName)
200{
201 return o3tl::starts_with(fileName, "file://");
202}
203
204OUString LwpTools::convertToFileUrl(const OString &fileName)
205{
206 if ( isFileUrl(fileName) )
207 {
208 return OStringToOUString(fileName, osl_getThreadTextEncoding());
209 }
210
211 OUString uUrlFileName;
212 OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
213 if ( fileName.startsWith(".") || fileName.indexOf(SEPARATOR) < 0 )
214 {
215 OUString uWorkingDir;
216 OSL_VERIFY( osl_getProcessWorkingDir(&uWorkingDir.pData) == osl_Process_E_None );
217 OSL_VERIFY( FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName) == FileBase::E_None );
218 } else
219 {
220 OSL_VERIFY( FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName) == FileBase::E_None );
221 }
222
223 return uUrlFileName;
224}
225
227{
228 OUString aResult = OUString::number(dt.tm_year) + "-" + OUString::number(dt.tm_mon) + "-" + OUString::number(dt.tm_mday) +
229 "T" + OUString::number(dt.tm_hour) + ":" + OUString::number(dt.tm_min) + ":" + OUString::number(dt.tm_sec);
230
231 return aResult;
232}
233
237std::unique_ptr<XFDateStyle> LwpTools::GetSystemDateStyle(bool bLongFormat)
238{
239 icu::DateFormat::EStyle style;
240 if (bLongFormat)
241 style = icu::DateFormat::FULL;//system full date format
242 else
243 style = icu::DateFormat::SHORT;//system short date format
244
245 //1 get locale for system
246 icu::Locale aLocale( LanguageTagIcu::getIcuLocale( Application::GetSettings().GetLanguageTag()));
247 //2 get icu format pattern by locale
248 icu::DateFormat* fmt = icu::DateFormat::createDateInstance(style,aLocale);
249
250 int32_t nLength = 0;
251 int32_t nLengthNeed;
252 UErrorCode status = U_ZERO_ERROR;
253 UChar* pattern = nullptr;
254
255 nLengthNeed = udat_toPattern(reinterpret_cast<void **>(fmt),false,nullptr,nLength,&status);
256 if (status == U_BUFFER_OVERFLOW_ERROR)
257 {
258 status = U_ZERO_ERROR;
259 nLength = nLengthNeed +1;
260 pattern = static_cast<UChar*>(malloc(sizeof(UChar)*nLength));
261 udat_toPattern(reinterpret_cast<void **>(fmt),false,pattern,nLength,&status);
262 }
263 if (pattern == nullptr)
264 return nullptr;
265 // 3 parse pattern string,per icu date/time format syntax, there are 20 letters reserved
266 // as pattern letter,each represent an element in date/time and its repeat numbers represent
267 // different format: for example: M produces '1', MM produces '01', MMM produces 'Jan', MMMM produces 'January'
268 // letter other than these letters is regard as text in the format, for example ',' in 'Jan,2005'
269 // we parse pattern string letter by letter and get the time format.
270 UChar cSymbol;
271 UChar cTmp;
272 std::unique_ptr<XFDateStyle> pDateStyle(new XFDateStyle);
273
274 for (int32_t i=0;i<nLengthNeed;)
275 {
276 cSymbol = pattern[i];
277 int32_t j;
278 switch(cSymbol)
279 {
280 case 'G':
281 {
282 for (j=1;;j++)
283 {
284 cTmp = pattern[i+j];
285 if (cTmp != cSymbol)
286 {
287 i=i+j;
288 break;
289 }
290 }
291 pDateStyle->AddEra();
292 break;
293 }
294 case 'y':
295 {
296 for (j=1;;j++)
297 {
298 cTmp = pattern[i+j];
299 if (cTmp != cSymbol)
300 {
301 i=i+j;
302 break;
303 }
304 }
305 if (j <= 2)
306 pDateStyle->AddYear(false);
307 else
308 pDateStyle->AddYear();
309 break;
310 }
311 case 'M':
312 {
313 for (j=1;;j++)
314 {
315 cTmp = pattern[i+j];
316 if (cTmp != cSymbol)
317 {
318 i=i+j;
319 break;
320 }
321 }
322 if (j==1)
323 pDateStyle->AddMonth(false);
324 else if (j==2)
325 pDateStyle->AddMonth();
326 else if (j==3)
327 pDateStyle->AddMonth(false,true);
328 else
329 pDateStyle->AddMonth(true,true);
330 break;
331 }
332 case 'd':
333 {
334 for (j=1;;j++)
335 {
336 cTmp = pattern[i+j];
337 if (cTmp != cSymbol)
338 {
339 i=i+j;
340 break;
341 }
342 }
343 if (j==1)
344 pDateStyle->AddMonthDay(false);
345 else
346 pDateStyle->AddMonthDay();
347 break;
348 }
349 case 'h':
350 {
351 for (j=1;;j++)
352 {
353 cTmp = pattern[i+j];
354 if (cTmp != cSymbol)
355 {
356 i=i+j;
357 break;
358 }
359 }
360 if (j==1)
361 pDateStyle->AddHour(false);
362 else
363 pDateStyle->AddHour();
364 break;
365 }
366 case 'H':
367 {
368 for (j=1;;j++)
369 {
370 cTmp = pattern[i+j];
371 if (cTmp != cSymbol)
372 {
373 i=i+j;
374 break;
375 }
376 }
377 if (j==1)
378 pDateStyle->AddHour(false);
379 else
380 pDateStyle->AddHour();
381 break;
382 }
383 case 'm':
384 {
385 for (j=1;;j++)
386 {
387 cTmp = pattern[i+j];
388 if (cTmp != cSymbol)
389 {
390 i=i+j;
391 break;
392 }
393 }
394 if (j==1)
395 pDateStyle->AddMinute(false);
396 else
397 pDateStyle->AddMinute();
398 break;
399 }
400 case 's':
401 {
402 for (j=1;;j++)
403 {
404 cTmp = pattern[i+j];
405 if (cTmp != cSymbol)
406 {
407 i=i+j;
408 break;
409 }
410 }
411 if (j==1)
412 pDateStyle->AddSecond(false);
413 else
414 pDateStyle->AddSecond();
415 break;
416 }
417 case 'S':
418 {
419 for (j=1;;j++)
420 {
421 cTmp = pattern[i+j];
422 if (cTmp != cSymbol)
423 {
424 i=i+j;
425 break;
426 }
427 }
428 /*if (j==1)
429 pDateStyle->AddSecond(sal_False);
430 else
431 pDateStyle->AddSecond();*/
432 break;
433 }
434 case 'E':
435 {
436 for (j=1;;j++)
437 {
438 cTmp = pattern[i+j];
439 if (cTmp != cSymbol)
440 {
441 i=i+j;
442 break;
443 }
444 }
445 if (j<=2)
446 pDateStyle->AddWeekDay(false);
447 else
448 pDateStyle->AddWeekDay();
449 break;
450 }
451 case 'D':
452 {
453 for (j=1;;j++)
454 {
455 cTmp = pattern[i+j];
456 if (cTmp != cSymbol)
457 {
458 i=i+j;
459 break;
460 }
461 }
462 /*if (j==1)
463 pDateStyle->AddWeekDay(sal_False);
464 else
465 pDateStyle->AddWeekDay();*/
466 break;
467 }
468 case 'F':
469 {
470 for (j=1;;j++)
471 {
472 cTmp = pattern[i+j];
473 if (cTmp != cSymbol)
474 {
475 i=i+j;
476 break;
477 }
478 }
479 /*if (j==1)
480 pDateStyle->AddWeekDay(sal_False);
481 else
482 pDateStyle->AddWeekDay();*/
483 break;
484 }
485 case 'w':
486 {
487 for (j=1;;j++)
488 {
489 cTmp = pattern[i+j];
490 if (cTmp != cSymbol)
491 {
492 i=i+j;
493 break;
494 }
495 }
496 /*if (j==1)
497 pDateStyle->AddWeekDay(sal_False);
498 else
499 pDateStyle->AddWeekDay();*/
500 break;
501 }
502 case 'W':
503 {
504 for (j=1;;j++)
505 {
506 cTmp = pattern[i+j];
507 if (cTmp != cSymbol)
508 {
509 i=i+j;
510 break;
511 }
512 }
513 /*if (j==1)
514 pDateStyle->AddWeekDay(sal_False);
515 else
516 pDateStyle->AddWeekDay();*/
517 break;
518 }
519 case 'a':
520 {
521 for (j=1;;j++)
522 {
523 cTmp = pattern[i+j];
524 if (cTmp != cSymbol)
525 {
526 i=i+j;
527 break;
528 }
529 }
530 pDateStyle->AddAmPm();
531 break;
532 }
533 case 'k':
534 {
535 for (j=1;;j++)
536 {
537 cTmp = pattern[i+j];
538 if (cTmp != cSymbol)
539 {
540 i=i+j;
541 break;
542 }
543 }
544 break;
545 }
546 case 'K':
547 {
548 for (j=1;;j++)
549 {
550 cTmp = pattern[i+j];
551 if (cTmp != cSymbol)
552 {
553 i=i+j;
554 break;
555 }
556 }
557 if (j==1)
558 pDateStyle->AddHour(false);
559 else
560 pDateStyle->AddHour();
561 break;
562 }
563 case 'Z':
564 {
565 for (j=1;;j++)
566 {
567 cTmp = pattern[i+j];
568 if (cTmp != cSymbol)
569 {
570 i=i+j;
571 break;
572 }
573 }
574 break;
575 }
576 case '\''://'
577 {
578 for (j=1;;j++)
579 {
580 cTmp = pattern[i+j];
581 if (cTmp != cSymbol)
582 {
583 i=i+j;
584 break;
585 }
586 }
587 break;
588 }
589 case '"':
590 {
591 pDateStyle->AddText("'");
592 break;
593 }
594 default:
595 {
596 if ((cSymbol>='A' && cSymbol<='Z') || (cSymbol>='a' && cSymbol<='z') )
597 {
598 return nullptr;
599 }
600 else//TEXT
601 {
602 //UChar buffer[1024];
603 sal_Unicode buffer[1024];
604 buffer[0] = cSymbol;
605 for (j=1;;j++)
606 {
607 cTmp = pattern[i+j];
608 if ((cTmp>='A' && cTmp<='Z') || (cTmp>='a' && cTmp<='z') ||
609 cTmp=='\'' || cTmp=='"' )
610 {
611 i=i+j;
612 buffer[j]= '\0';
613 break;
614 }
615 else
616 buffer[j] = cTmp;
617 }
618
619 pDateStyle->AddText(OUString(buffer));//keep for all parsed
620 }
621 break;
622 }
623 }
624 }
625// udat_close(fmt);
626 return pDateStyle;
627}
631std::unique_ptr<XFTimeStyle> LwpTools::GetSystemTimeStyle()
632{
633 //1 get locale for system
634 icu::Locale aLocale( LanguageTagIcu::getIcuLocale( Application::GetSettings().GetLanguageTag()));
635 //2 get icu format pattern by locale
636 icu::DateFormat* fmt = icu::DateFormat::createTimeInstance(icu::DateFormat::DEFAULT,aLocale);
637
638 int32_t nLength = 0;
639 int32_t nLengthNeed;
640 UErrorCode status = U_ZERO_ERROR;
641 UChar* pattern = nullptr;
642 nLengthNeed = udat_toPattern(reinterpret_cast<void **>(fmt),false,nullptr,nLength,&status);
643 if (status == U_BUFFER_OVERFLOW_ERROR)
644 {
645 status = U_ZERO_ERROR;
646 nLength = nLengthNeed +1;
647 pattern = static_cast<UChar*>(malloc(sizeof(UChar)*nLength));
648 udat_toPattern(reinterpret_cast<void **>(fmt),false,pattern,nLength,&status);
649 }
650
651 if (pattern == nullptr)
652 return nullptr;
653 // 3 parse pattern string,per icu date/time format syntax, there are 20 letters reserved
654 // as pattern letter,each represent an element in date/time and its repeat numbers represent
655 // different format: for example: M produces '1',MM produces '01', MMM produces 'Jan', MMMM produces 'Januaray'
656 // letter other than these letters is regard as text in the format, for example ','in 'Jan,2005'
657 // we parse pattern string letter by letter and get the time format.
658 // for time format ,for there is not date info,we can only parse the letter representing time.
659 UChar cSymbol;
660 UChar cTmp;
661 std::unique_ptr<XFTimeStyle> pTimeStyle(new XFTimeStyle);
662
663 for (int32_t i=0;i<nLengthNeed;)
664 {
665 cSymbol = pattern[i];
666 int32_t j;
667 switch(cSymbol)
668 {
669 case 'h':
670 {
671 for (j=1;;j++)
672 {
673 cTmp = pattern[i+j];
674 if (cTmp != cSymbol)
675 {
676 i=i+j;
677 break;
678 }
679 }
680 if (j==1)
681 pTimeStyle->AddHour(false);
682 else
683 pTimeStyle->AddHour();
684 break;
685 }
686 case 'H':
687 {
688 for (j=1;;j++)
689 {
690 cTmp = pattern[i+j];
691 if (cTmp != cSymbol)
692 {
693 i=i+j;
694 break;
695 }
696 }
697 if (j==1)
698 pTimeStyle->AddHour(false);
699 else
700 pTimeStyle->AddHour();
701 break;
702 }
703 case 'm':
704 {
705 for (j=1;;j++)
706 {
707 cTmp = pattern[i+j];
708 if (cTmp != cSymbol)
709 {
710 i=i+j;
711 break;
712 }
713 }
714 if (j==1)
715 pTimeStyle->AddMinute(false);
716 else
717 pTimeStyle->AddMinute();
718 break;
719 }
720 case 's':
721 {
722 for (j=1;;j++)
723 {
724 cTmp = pattern[i+j];
725 if (cTmp != cSymbol)
726 {
727 i=i+j;
728 break;
729 }
730 }
731 if (j==1)
732 pTimeStyle->AddSecond(false);
733 else
734 pTimeStyle->AddSecond();
735 break;
736 }
737 case 'S':
738 {
739 for (j=1;;j++)
740 {
741 cTmp = pattern[i+j];
742 if (cTmp != cSymbol)
743 {
744 i=i+j;
745 break;
746 }
747 }
748 /*if (j==1)
749 pDateStyle->AddSecond(sal_False);
750 else
751 pDateStyle->AddSecond();*/
752 break;
753 }
754 case 'a':
755 {
756 for (j=1;;j++)
757 {
758 cTmp = pattern[i+j];
759 if (cTmp != cSymbol)
760 {
761 i=i+j;
762 break;
763 }
764 }
765 pTimeStyle->SetAmPm(true);
766 break;
767 }
768 case 'k':
769 {
770 for (j=1;;j++)
771 {
772 cTmp = pattern[i+j];
773 if (cTmp != cSymbol)
774 {
775 i=i+j;
776 break;
777 }
778 }
779 break;
780 }
781 case 'K':
782 {
783 for (j=1;;j++)
784 {
785 cTmp = pattern[i+j];
786 if (cTmp != cSymbol)
787 {
788 i=i+j;
789 break;
790 }
791 }
792 if (j==1)
793 pTimeStyle->AddHour(false);
794 else
795 pTimeStyle->AddHour();
796 break;
797 }
798 case '\''://'
799 {
800 for (j=1;;j++)
801 {
802 cTmp = pattern[i+j];
803 if (cTmp != cSymbol)
804 {
805 i=i+j;
806 break;
807 }
808 }
809 break;
810 }
811 case '"':
812 {
813 pTimeStyle->AddText("'");
814 break;
815 }
816 default:
817 {
818 if ((cSymbol>='A' && cSymbol<='Z') || (cSymbol>='a' && cSymbol<='z') )
819 {
820 return nullptr;
821 }
822 else//TEXT
823 {
824 sal_Unicode buffer[1024];
825 buffer[0] = cSymbol;
826 //strBuffer.append(cSymbol);
827 for (j=1;;j++)
828 {
829 cTmp = pattern[i+j];
830 if ((cTmp>='A' && cTmp<='Z') || (cTmp>='a' && cTmp<='z') ||
831 cTmp=='\'' || cTmp=='"' )
832 {
833 i=i+j;
834 buffer[j]= '\0';
835 break;
836 }
837 else
838 buffer[j] = cTmp;
839 }
840 pTimeStyle->AddText(OUString(buffer));//keep for all parsed
841 }
842 break;
843 }
844 }
845 }
846// udat_close(fmt);
847 return pTimeStyle;
848}
849
850/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static const AllSettings & GetSettings()
static icu::Locale getIcuLocale(const LanguageTag &rLanguageTag)
stream class for LwpObject body data provide stream like interface to read object data
Definition: lwpobjstrm.hxx:77
sal_uInt16 QuickReaduInt16(bool *pFailure=nullptr)
@descr Quick read sal_uInt32
Definition: lwpobjstrm.cxx:200
sal_uInt16 QuickRead(void *buf, sal_uInt16 len)
@descr read len bytes from object stream to buffer
Definition: lwpobjstrm.cxx:143
sal_uInt16 GetPos() const
Definition: lwpobjstrm.hxx:98
sal_uInt8 QuickReaduInt8(bool *pFailure=nullptr)
@descr Quick read sal_uInt8
Definition: lwpobjstrm.cxx:230
void Seek(sal_uInt16 pos)
@descr Seek to pos in object buffer/buffer
Definition: lwpobjstrm.cxx:169
static std::unique_ptr< XFTimeStyle > GetSystemTimeStyle()
@descr get the system time format
Definition: lwptools.cxx:631
static std::unique_ptr< XFDateStyle > GetSystemDateStyle(bool bLongFormat)
@descr get the system date format
Definition: lwptools.cxx:237
static void QuickReadUnicode(LwpObjectStream *pObjStrm, OUString &str, sal_uInt16 strlen, rtl_TextEncoding aEncoding)
@descr read lwp unicode string from stream to OUString per aEncoding
Definition: lwptools.cxx:84
static bool IsUnicodePacked(LwpObjectStream *pObjStrm, sal_uInt16 len)
@descr Judge if the data (len) in object stream is lwp unicode packed
Definition: lwptools.cxx:181
static bool isFileUrl(std::string_view fileName)
Definition: lwptools.cxx:199
static OUString DateTimeToOUString(const LtTm &dt)
Definition: lwptools.cxx:226
static OUString convertToFileUrl(const OString &fileName)
Definition: lwptools.cxx:204
unsigned char byte
#define SEPARATOR
Definition: lwptools.cxx:76
int i
constexpr bool starts_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept
tools::Long tm_mday
Definition: localtime.hxx:65
tools::Long tm_min
Definition: localtime.hxx:63
tools::Long tm_sec
Definition: localtime.hxx:62
tools::Long tm_hour
Definition: localtime.hxx:64
tools::Long tm_mon
Definition: localtime.hxx:66
tools::Long tm_year
Definition: localtime.hxx:67
unsigned char sal_uInt8
sal_uInt16 sal_Unicode
sal_Int32 nLength