summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/bootstrp/addexes/makefile.mk49
-rw-r--r--tools/bootstrp/addexes/replace.cxx79
-rw-r--r--tools/bootstrp/addexes2/makefile.mk56
-rw-r--r--tools/bootstrp/addexes2/mkfilt.cxx240
-rw-r--r--tools/bootstrp/appdef.cxx171
-rw-r--r--tools/bootstrp/command.cxx693
-rw-r--r--tools/bootstrp/cppdep.cxx249
-rw-r--r--tools/bootstrp/cppdep.hxx60
-rw-r--r--tools/bootstrp/inimgr.cxx213
-rw-r--r--tools/bootstrp/iserver.cxx154
-rw-r--r--tools/bootstrp/makefile.mk108
-rw-r--r--tools/bootstrp/md5.cxx152
-rw-r--r--tools/bootstrp/md5.hxx34
-rw-r--r--tools/bootstrp/mkcreate.cxx947
-rw-r--r--tools/bootstrp/prj.cxx1602
-rw-r--r--tools/bootstrp/rscdep.cxx301
-rw-r--r--tools/bootstrp/so_checksum.cxx58
-rw-r--r--tools/bootstrp/sspretty.cxx62
-rw-r--r--tools/bootstrp/sstring.cxx320
-rw-r--r--tools/inc/bootstrp/appdef.hxx71
-rw-r--r--tools/inc/bootstrp/command.hxx166
-rw-r--r--tools/inc/bootstrp/inimgr.hxx63
-rw-r--r--tools/inc/bootstrp/listmacr.hxx62
-rw-r--r--tools/inc/bootstrp/mkcreate.hxx298
-rw-r--r--tools/inc/bootstrp/prj.hxx334
-rw-r--r--tools/inc/bootstrp/sstring.hxx108
-rw-r--r--tools/inc/impcont.hxx150
-rw-r--r--tools/inc/impstrg.hxx57
-rw-r--r--tools/inc/makefile.mk48
-rw-r--r--tools/inc/pch/precompiled_tools.cxx31
-rw-r--r--tools/inc/pch/precompiled_tools.hxx93
-rw-r--r--tools/inc/poly.h102
-rw-r--r--tools/inc/tools/StringListResource.hxx59
-rw-r--r--tools/inc/tools/agapi.hxx69
-rw-r--r--tools/inc/tools/agitem.hxx53
-rw-r--r--tools/inc/tools/appendunixshellword.hxx62
-rw-r--r--tools/inc/tools/b3dtrans.hxx355
-rw-r--r--tools/inc/tools/bigint.hxx331
-rw-r--r--tools/inc/tools/cachestr.hxx86
-rw-r--r--tools/inc/tools/chapi.hxx71
-rw-r--r--tools/inc/tools/color.hxx240
-rw-r--r--tools/inc/tools/config.hxx104
-rw-r--r--tools/inc/tools/contnr.hxx126
-rw-r--r--tools/inc/tools/date.hxx123
-rw-r--r--tools/inc/tools/datetime.hxx114
-rw-r--r--tools/inc/tools/debug.hxx778
-rw-r--r--tools/inc/tools/diagnose_ex.h178
-rw-r--r--tools/inc/tools/download.hxx59
-rw-r--r--tools/inc/tools/dynary.hxx113
-rw-r--r--tools/inc/tools/eacopier.hxx49
-rw-r--r--tools/inc/tools/errcode.hxx324
-rw-r--r--tools/inc/tools/errinf.hxx246
-rw-r--r--tools/inc/tools/extendapplicationenvironment.hxx45
-rw-r--r--tools/inc/tools/fldunit.hxx44
-rw-r--r--tools/inc/tools/fontenum.hxx175
-rw-r--r--tools/inc/tools/fract.hxx168
-rw-r--r--tools/inc/tools/fsys.hxx571
-rw-r--r--tools/inc/tools/gen.hxx715
-rw-r--r--tools/inc/tools/geninfo.hxx232
-rw-r--r--tools/inc/tools/getprocessworkingdir.hxx51
-rw-r--r--tools/inc/tools/globname.hxx140
-rw-r--r--tools/inc/tools/inetdef.hxx119
-rw-r--r--tools/inc/tools/inetmime.hxx1447
-rw-r--r--tools/inc/tools/inetmsg.hxx621
-rw-r--r--tools/inc/tools/inetstrm.hxx277
-rw-r--r--tools/inc/tools/iparser.hxx149
-rw-r--r--tools/inc/tools/isofallback.hxx40
-rw-r--r--tools/inc/tools/line.hxx78
-rw-r--r--tools/inc/tools/link.hxx161
-rw-r--r--tools/inc/tools/list.hxx146
-rw-r--r--tools/inc/tools/mapunit.hxx44
-rw-r--r--tools/inc/tools/mempool.hxx123
-rw-r--r--tools/inc/tools/multisel.hxx219
-rw-r--r--tools/inc/tools/ownlist.hxx95
-rw-r--r--tools/inc/tools/pathutils.hxx104
-rw-r--r--tools/inc/tools/poly.hxx344
-rw-r--r--tools/inc/tools/postsys.h246
-rw-r--r--tools/inc/tools/postwin.h260
-rw-r--r--tools/inc/tools/postx.h75
-rw-r--r--tools/inc/tools/presys.h46
-rw-r--r--tools/inc/tools/prewin.h83
-rw-r--r--tools/inc/tools/prex.h80
-rw-r--r--tools/inc/tools/pstm.hxx265
-rw-r--r--tools/inc/tools/queue.hxx107
-rw-r--r--tools/inc/tools/rc.h223
-rw-r--r--tools/inc/tools/rc.hxx111
-rw-r--r--tools/inc/tools/rcid.h137
-rw-r--r--tools/inc/tools/ref.hxx457
-rw-r--r--tools/inc/tools/resary.hxx94
-rw-r--r--tools/inc/tools/resid.hxx165
-rw-r--r--tools/inc/tools/resmgr.hxx241
-rw-r--r--tools/inc/tools/rtti.hxx177
-rw-r--r--tools/inc/tools/shl.hxx117
-rw-r--r--tools/inc/tools/simplerm.hxx120
-rw-r--r--tools/inc/tools/solar.h449
-rw-r--r--tools/inc/tools/solarmutex.hxx48
-rw-r--r--tools/inc/tools/stack.hxx108
-rw-r--r--tools/inc/tools/stream.hxx857
-rw-r--r--tools/inc/tools/string.hxx698
-rw-r--r--tools/inc/tools/svborder.hxx99
-rw-r--r--tools/inc/tools/svlibrary.hxx44
-rw-r--r--tools/inc/tools/svwin.h39
-rw-r--r--tools/inc/tools/table.hxx153
-rw-r--r--tools/inc/tools/tempfile.hxx80
-rw-r--r--tools/inc/tools/tenccvt.hxx59
-rw-r--r--tools/inc/tools/testtoolloader.hxx42
-rw-r--r--tools/inc/tools/time.hxx115
-rw-r--r--tools/inc/tools/tools.h41
-rw-r--r--tools/inc/tools/toolsdllapi.h43
-rw-r--r--tools/inc/tools/unqid.hxx112
-rw-r--r--tools/inc/tools/unqidx.hxx154
-rw-r--r--tools/inc/tools/urlkeys.hxx79
-rw-r--r--tools/inc/tools/urlobj.hxx1923
-rw-r--r--tools/inc/tools/vcompat.hxx73
-rw-r--r--tools/inc/tools/vector2d.hxx122
-rw-r--r--tools/inc/tools/weakbase.h162
-rw-r--r--tools/inc/tools/weakbase.hxx185
-rw-r--r--tools/inc/tools/wintypes.hxx346
-rw-r--r--tools/inc/tools/wldcrd.hxx94
-rw-r--r--tools/inc/tools/zcodec.hxx131
-rw-r--r--tools/inc/toolsin.hxx55
-rw-r--r--tools/os2/inc/dll.hxx42
-rw-r--r--tools/os2/source/dll/makefile.mk46
-rw-r--r--tools/os2/source/dll/toolsdll.cxx46
-rw-r--r--tools/prj/build.lst30
-rw-r--r--tools/prj/d.lst125
-rw-r--r--tools/qa/makefile.mk55
-rw-r--r--tools/qa/test_pathutils.cxx84
-rw-r--r--tools/qa/version.map34
-rw-r--r--tools/source/communi/geninfo.cxx410
-rw-r--r--tools/source/communi/makefile.mk50
-rw-r--r--tools/source/communi/parser.cxx471
-rw-r--r--tools/source/datetime/datetime.cxx445
-rw-r--r--tools/source/datetime/makefile.mk50
-rw-r--r--tools/source/datetime/tdate.cxx497
-rw-r--r--tools/source/datetime/ttime.cxx448
-rw-r--r--tools/source/debug/debug.cxx1816
-rw-r--r--tools/source/debug/makefile.mk53
-rw-r--r--tools/source/debug/stcktree.cxx323
-rw-r--r--tools/source/fsys/comdep.cxx47
-rw-r--r--tools/source/fsys/comdep.hxx159
-rw-r--r--tools/source/fsys/dirent.cxx3197
-rw-r--r--tools/source/fsys/filecopy.cxx489
-rw-r--r--tools/source/fsys/fstat.cxx422
-rw-r--r--tools/source/fsys/makefile.mk67
-rw-r--r--tools/source/fsys/os2.cxx885
-rw-r--r--tools/source/fsys/os2.hxx94
-rw-r--r--tools/source/fsys/tdir.cxx769
-rw-r--r--tools/source/fsys/tempfile.cxx303
-rw-r--r--tools/source/fsys/unx.cxx663
-rw-r--r--tools/source/fsys/unx.hxx98
-rw-r--r--tools/source/fsys/urlobj.cxx5575
-rw-r--r--tools/source/fsys/wldcrd.cxx146
-rw-r--r--tools/source/fsys/wntmsc.cxx1083
-rw-r--r--tools/source/fsys/wntmsc.hxx105
-rw-r--r--tools/source/generic/b3dtrans.cxx1017
-rw-r--r--tools/source/generic/bigint.cxx1144
-rw-r--r--tools/source/generic/color.cxx510
-rw-r--r--tools/source/generic/config.cxx1306
-rw-r--r--tools/source/generic/fract.cxx737
-rw-r--r--tools/source/generic/gen.cxx664
-rw-r--r--tools/source/generic/line.cxx366
-rw-r--r--tools/source/generic/link.cxx61
-rw-r--r--tools/source/generic/makefile.mk71
-rw-r--r--tools/source/generic/poly.cxx2379
-rw-r--r--tools/source/generic/poly2.cxx894
-rw-r--r--tools/source/generic/svborder.cxx79
-rw-r--r--tools/source/generic/svlibrary.cxx132
-rw-r--r--tools/source/generic/toolsin.cxx98
-rw-r--r--tools/source/inet/inetmime.cxx4565
-rw-r--r--tools/source/inet/inetmsg.cxx1646
-rw-r--r--tools/source/inet/inetstrm.cxx1823
-rw-r--r--tools/source/inet/makefile.mk45
-rw-r--r--tools/source/makefile.mk58
-rw-r--r--tools/source/memtools/contnr.cxx1705
-rw-r--r--tools/source/memtools/makefile.mk56
-rw-r--r--tools/source/memtools/mempool.cxx84
-rw-r--r--tools/source/memtools/multisel.cxx1164
-rw-r--r--tools/source/memtools/table.cxx416
-rw-r--r--tools/source/memtools/unqidx.cxx604
-rw-r--r--tools/source/misc/appendunixshellword.cxx79
-rw-r--r--tools/source/misc/extendapplicationenvironment.cxx95
-rw-r--r--tools/source/misc/getprocessworkingdir.cxx67
-rw-r--r--tools/source/misc/makefile.mk47
-rw-r--r--tools/source/misc/pathutils.cxx222
-rw-r--r--tools/source/misc/solarmutex.cxx63
-rw-r--r--tools/source/rc/isofallback.cxx69
-rw-r--r--tools/source/rc/makefile.mk53
-rw-r--r--tools/source/rc/rc.cxx100
-rw-r--r--tools/source/rc/resary.cxx81
-rw-r--r--tools/source/rc/resmgr.cxx2076
-rw-r--r--tools/source/ref/errinf.cxx464
-rw-r--r--tools/source/ref/globname.cxx511
-rw-r--r--tools/source/ref/makefile.mk53
-rw-r--r--tools/source/ref/pstm.cxx917
-rw-r--r--tools/source/ref/ref.cxx53
-rw-r--r--tools/source/solar/makefile.mk63
-rw-r--r--tools/source/solar/solar.c565
-rw-r--r--tools/source/stream/cachestr.cxx293
-rw-r--r--tools/source/stream/makefile.mk58
-rw-r--r--tools/source/stream/stream.cxx2859
-rw-r--r--tools/source/stream/strmos2.cxx687
-rw-r--r--tools/source/stream/strmsys.cxx40
-rw-r--r--tools/source/stream/strmunx.cxx924
-rw-r--r--tools/source/stream/strmwnt.cxx691
-rw-r--r--tools/source/stream/vcompat.cxx83
-rw-r--r--tools/source/string/debugprint.cxx49
-rw-r--r--tools/source/string/makefile.mk81
-rw-r--r--tools/source/string/strascii.cxx640
-rw-r--r--tools/source/string/strcvt.cxx616
-rw-r--r--tools/source/string/strimp.cxx2118
-rw-r--r--tools/source/string/strucvt.cxx215
-rw-r--r--tools/source/string/tenccvt.cxx100
-rw-r--r--tools/source/string/tstring.cxx290
-rw-r--r--tools/source/string/tustring.cxx158
-rw-r--r--tools/source/testtoolloader/makefile.mk45
-rw-r--r--tools/source/testtoolloader/testtoolloader.cxx186
-rw-r--r--tools/source/zcodec/makefile.mk47
-rw-r--r--tools/source/zcodec/zcodec.cxx490
-rw-r--r--tools/test/export.map34
-rw-r--r--tools/test/makefile.mk64
-rw-r--r--tools/test/tests.cxx124
-rw-r--r--tools/unx/source/dll/makefile.mk48
-rw-r--r--tools/unx/source/dll/toolsdll.cxx50
-rw-r--r--tools/util/makefile.mk173
-rw-r--r--tools/util/makefile.pmk31
-rw-r--r--tools/util/tools.r17
-rw-r--r--tools/win/inc/dll.hxx62
-rw-r--r--tools/win/inc/parser.hxx51
-rw-r--r--tools/win/inc/shellex.h117
-rw-r--r--tools/win/inc/shutil.h217
-rw-r--r--tools/win/inc/toolsdll.hxx89
-rw-r--r--tools/win/inc/winshell.hxx389
-rw-r--r--tools/win/source/dll/makefile.mk56
-rw-r--r--tools/win/source/dll/toolsdll.cxx51
-rw-r--r--tools/win/source/fastfsys/makefile.mk71
-rw-r--r--tools/workben/fstest.cxx97
-rw-r--r--tools/workben/hashtbl.cxx518
-rw-r--r--tools/workben/hashtbl.hxx205
-rw-r--r--tools/workben/helloworld.c36
-rw-r--r--tools/workben/inetmimetest.cxx70
-rw-r--r--tools/workben/makefile.mk89
-rw-r--r--tools/workben/solar.c430
-rw-r--r--tools/workben/tldem.cxx85
-rw-r--r--tools/workben/urltest.cxx1910
245 files changed, 88177 insertions, 0 deletions
diff --git a/tools/bootstrp/addexes/makefile.mk b/tools/bootstrp/addexes/makefile.mk
new file mode 100644
index 000000000000..324de9479502
--- /dev/null
+++ b/tools/bootstrp/addexes/makefile.mk
@@ -0,0 +1,49 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=tools
+TARGET=addexes
+TARGETTYPE=CUI
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+CDEFS+=-D_TOOLS_STRINGLIST
+
+# --- Files --------------------------------------------------------
+
+APP1TARGET= txtrepl
+APP1OBJS= $(OBJ)$/replace.obj
+APP1STDLIBS=$(TOOLSLIB)
+
+DEPOBJFILES = $(APP1OBJS)
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/tools/bootstrp/addexes/replace.cxx b/tools/bootstrp/addexes/replace.cxx
new file mode 100644
index 000000000000..ec079ea55c8e
--- /dev/null
+++ b/tools/bootstrp/addexes/replace.cxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <stdio.h>
+#include <tools/string.hxx>
+
+
+/****************************************************************************/
+#if defined UNX
+int main( int argc, char *argv[] )
+#else
+int _cdecl main( int argc, char *argv[] )
+#endif
+/****************************************************************************/
+{
+ if ( argc < 4 )
+ {
+ fprintf( stderr, "ERROR: too few parameters. \n\n");
+ fprintf( stderr, "usage: txtrep.exe EnvironmentVariable Searchstring replacestring\n");
+ return 1;
+ }
+ ByteString aText( getenv( argv[ 1 ] ));
+ if ( aText.Len() == 0 )
+ {
+ fprintf( stderr, "ERROR: Variable not set. \n\n");
+ fprintf( stderr, "usage: txtrep.exe EnvironmentVariable Searchstring replacestring\n");
+ return 2;
+ }
+ ByteString aSearch( argv[ 2 ] );
+ ByteString aReplace( argv[ 3 ] );
+
+ ByteString aUpperText( aText );
+ aUpperText.ToUpperAscii();
+
+
+ ULONG nIndex;
+ aSearch.ToUpperAscii();
+
+ nIndex = aUpperText.Search( aSearch.GetBuffer(), 0);
+ while ( nIndex != STRING_NOTFOUND )
+ {
+ aText.Replace( nIndex, aSearch.Len(), aReplace.GetBuffer());
+ aUpperText.Replace( nIndex, aSearch.Len(), aReplace.GetBuffer());
+ nIndex = aUpperText.Search( aSearch.GetBuffer(), nIndex + aReplace.Len());
+ }
+
+ fprintf( stdout, "%s\n", aText.GetBuffer());
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/bootstrp/addexes2/makefile.mk b/tools/bootstrp/addexes2/makefile.mk
new file mode 100644
index 000000000000..ee0e79ae6b27
--- /dev/null
+++ b/tools/bootstrp/addexes2/makefile.mk
@@ -0,0 +1,56 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=tools
+TARGET=addexes2
+TARGETTYPE=CUI
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+APP1TARGET= mkunroll
+APP1OBJS= $(OBJ)$/mkfilt.obj
+APP1STDLIBS= $(SALLIB) $(TOOLSLIB)
+.IF "$(OS)"=="LINUX"
+APP1STDLIBS+=-lpthread
+.ENDIF
+.IF "$(OS)"=="NETBSD"
+APP1STDLIBS+=-lpthread
+.ENDIF
+APP1LIBS= $(LB)$/btstrp.lib $(LB)$/bootstrp2.lib
+APP1DEPN= $(LB)$/atools.lib $(LB)$/btstrp.lib $(LB)$/bootstrp2.lib
+
+
+DEPOBJFILES = $(APP1OBJS)
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/tools/bootstrp/addexes2/mkfilt.cxx b/tools/bootstrp/addexes2/mkfilt.cxx
new file mode 100644
index 000000000000..0ee927e4c693
--- /dev/null
+++ b/tools/bootstrp/addexes2/mkfilt.cxx
@@ -0,0 +1,240 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <stdio.h>
+
+#include <../../inc/tools/string.hxx>
+#include <../../inc/tools/list.hxx>
+
+class TextFilter
+{
+protected:
+ FILE *pIn, *pOut;
+ virtual void Filter();
+public:
+ TextFilter( ByteString aInFile = "stdin",
+ ByteString aOutFile = "stdout" );
+ virtual ~TextFilter();
+
+ virtual void Execute();
+};
+
+TextFilter::TextFilter( ByteString aInFile, ByteString aOutFile )
+{
+ if ( aInFile == "stdin" )
+ pIn = stdin;
+ else
+ if (( pIn = fopen( aInFile.GetBuffer(), "r" )) == NULL )
+ printf( "Can't read %s\n", aInFile.GetBuffer() );
+
+ if ( aOutFile == "stdout" )
+ pOut = stdout;
+ else
+ if (( pOut = fopen( aOutFile.GetBuffer(), "w" )) == NULL )
+ printf( "Can't write %s\n", aOutFile.GetBuffer() );
+}
+
+TextFilter::~TextFilter()
+{
+ fclose( pOut );
+ fclose( pIn );
+}
+
+void TextFilter::Execute()
+{
+ Filter();
+}
+
+void TextFilter::Filter()
+{
+ int c;
+ while ( (c = fgetc( pIn )) != EOF )
+ fputc( c, pOut );
+}
+
+#define LINE_LEN 2048
+
+class ByteStringList;
+
+class MkLine
+{
+public:
+ ByteString aLine;
+ ByteStringList* pPrivateTnrLst;
+ BOOL bOut;
+ BOOL bHier;
+
+ MkLine();
+};
+
+MkLine::MkLine()
+{
+ bOut = FALSE;
+ bHier = FALSE;
+ pPrivateTnrLst = NULL;
+}
+
+DECLARE_LIST( ByteStringList, MkLine * )
+
+class MkFilter : public TextFilter
+{
+ static ByteString aTnr;
+ ByteStringList *pLst;
+ ByteStringList *pTnrLst;
+protected:
+ virtual void Filter();
+public:
+ MkFilter( ByteString aInFile = "stdin", ByteString aOutFile = "stdout");
+ ~MkFilter();
+};
+
+MkFilter::MkFilter( ByteString aInFile, ByteString aOutFile ) :
+ TextFilter( aInFile, aOutFile )
+{
+ pLst = new ByteStringList;
+ pTnrLst = new ByteStringList;
+}
+
+MkFilter::~MkFilter()
+{
+ delete pTnrLst;
+ delete pLst;
+}
+
+ByteString MkFilter::aTnr="$(TNR)";
+
+void MkFilter::Filter()
+{
+ char aLineBuf[LINE_LEN];
+ int nState = 0;
+
+ while(( fgets(aLineBuf, LINE_LEN, pIn)) != NULL )
+ {
+ ByteString aLine( aLineBuf );
+ //fprintf(stderr, "aLine :%s\n", aLine.GetBuffer());
+ if ( aLine.Search("mkfilter1" ) != STRING_NOTFOUND )
+ {
+ // Zeilen unterdruecken
+ fprintf( stderr, "mkfilter1\n" );
+ nState = 0;
+ }
+ else if ( aLine.Search("unroll begin" ) != STRING_NOTFOUND )
+ {
+ // Zeilen raus schreiben mit ersetzen von $(TNR) nach int n
+ fprintf( stderr, "\nunroll begin\n" );
+ nState = 1;
+ }
+ ;
+
+ if ( nState == 0 )
+ {
+ fprintf( stderr, "." );
+ MkLine *pMkLine = new MkLine();
+ ByteString *pStr = new ByteString( aLineBuf );
+ pMkLine->aLine = *pStr;
+ pMkLine->bOut = FALSE;
+
+ pLst->Insert( pMkLine, LIST_APPEND );
+ }
+ else if ( nState == 1 )
+ {
+ BOOL bInTnrList = TRUE;
+ fprintf( stderr, ":" );
+ MkLine *pMkLine = new MkLine();
+ if ( aLine.Search("unroll end") != STRING_NOTFOUND )
+ {
+ fprintf( stderr, ";\nunroll end\n" );
+ MkLine *p_MkLine = new MkLine();
+ p_MkLine->bHier = TRUE;
+ ByteString *pByteString = new ByteString("# do not delete this line === mkfilter3i\n");
+ p_MkLine->aLine = *pByteString;
+ p_MkLine->bOut = FALSE;
+ p_MkLine->pPrivateTnrLst = pTnrLst;
+ pTnrLst = new ByteStringList();
+ pLst->Insert( p_MkLine, LIST_APPEND );
+ nState = 0;
+ bInTnrList = FALSE;
+ }
+ ByteString *pStr = new ByteString( aLineBuf );
+ pMkLine->aLine = *pStr;
+ pMkLine->bOut = FALSE;
+
+ if ( bInTnrList )
+ pTnrLst->Insert( pMkLine, LIST_APPEND );
+ }
+ else {
+ /* Zeilen ignorieren */;
+ }
+ } // End Of File
+ fprintf( stderr, "\n" );
+
+ // das File wieder ausgegeben
+ ULONG nLines = pLst->Count();
+ for ( ULONG j=0; j<nLines; j++ )
+ {
+ MkLine *pLine = pLst->GetObject( j );
+ if ( pLine->bHier )
+ {
+ // die List n - Mal abarbeiten
+ for ( USHORT n=1; n<11; n++)
+ {
+ ULONG nCount = pLine->pPrivateTnrLst->Count();
+ for ( ULONG i=0; i<nCount; i++ )
+ {
+ MkLine *pMkLine = pLine->pPrivateTnrLst->GetObject(i);
+ ByteString aLine = pMkLine->aLine;
+ while( aLine.SearchAndReplace( aTnr, ByteString::CreateFromInt32( n )) != (USHORT)-1 ) ;
+ fputs( aLine.GetBuffer(), pOut );
+ fprintf( stderr, "o" );
+ }
+ }
+ if ( pLine->pPrivateTnrLst != NULL )
+ delete pLine->pPrivateTnrLst;
+ pLine->pPrivateTnrLst = NULL;
+ }
+ if ( pLine->bOut )
+ fputs(pLine->aLine.GetBuffer(), pOut );
+ }
+ fprintf( stderr, "\n" );
+}
+
+int main()
+{
+ int nRet = 0;
+
+ TextFilter *pFlt = new MkFilter();
+ pFlt->Execute();
+ delete pFlt;
+
+ return nRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/bootstrp/appdef.cxx b/tools/bootstrp/appdef.cxx
new file mode 100644
index 000000000000..ebdb96e813ca
--- /dev/null
+++ b/tools/bootstrp/appdef.cxx
@@ -0,0 +1,171 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "bootstrp/appdef.hxx"
+
+const char* GetDefStandList()
+{
+ char* pRet;
+ char* pEnv = getenv("STAR_STANDLST");
+ if ( pEnv )
+ {
+ int nLen = strlen( pEnv );
+ pRet = ( char *) malloc( nLen + 1 );
+ (void) strcpy( pRet, pEnv );
+ }
+ else
+ {
+ int nLen = strlen( _DEF_STAND_LIST );
+ pRet = ( char *) malloc( nLen + 1 );
+ (void) strcpy( pRet, _DEF_STAND_LIST );
+ }
+ return pRet;
+}
+
+
+const char* GetIniRoot()
+{
+ char* pRet;
+ char* pEnv = getenv("STAR_INIROOT");
+ if ( pEnv )
+ {
+ int nLen = strlen( pEnv );
+ pRet = ( char *) malloc( nLen + 1 );
+ (void) strcpy( pRet, pEnv );
+ }
+ else
+ {
+ int nLen = strlen( _INIROOT );
+ pRet = ( char *) malloc( nLen + 1 );
+ (void) strcpy( pRet, _INIROOT );
+ }
+ return pRet;
+}
+
+const char* GetIniRootOld()
+{
+ char* pRet;
+ char* pEnv = getenv("STAR_INIROOTOLD");
+ if ( pEnv )
+ {
+ int nLen = strlen( pEnv );
+ pRet = ( char *) malloc( nLen + 1 );
+ (void) strcpy( pRet, pEnv );
+ }
+ else
+ {
+ int nLen = strlen( _INIROOT_OLD );
+ pRet = ( char *) malloc( nLen + 1 );
+ (void) strcpy( pRet, _INIROOT_OLD );
+ }
+ return pRet;
+}
+
+const char* GetSSolarIni()
+{
+ char* pRet;
+ char* pEnv = getenv("STAR_SSOLARINI");
+ if ( pEnv )
+ {
+ int nLen = strlen( pEnv );
+ pRet = ( char *) malloc( nLen + 1 );
+ (void) strcpy( pRet, pEnv );
+ }
+ else
+ {
+ int nLen = strlen( _DEF_SSOLARINI );
+ pRet = ( char *) malloc( nLen + 1 );
+ (void) strcpy( pRet, _DEF_SSOLARINI );
+ }
+ return pRet;
+}
+
+
+const char* GetSSCommon()
+{
+ char* pRet;
+ char* pEnv = getenv("STAR_SSCOMMON");
+ if ( pEnv )
+ {
+ int nLen = strlen( pEnv );
+ pRet = ( char *) malloc( nLen + 1 );
+ (void) strcpy( pRet, pEnv );
+ }
+ else
+ {
+ int nLen = strlen( _DEF_SSCOMMON );
+ pRet = ( char *) malloc( nLen + 1 );
+ (void) strcpy( pRet, _DEF_SSCOMMON );
+ }
+ return pRet;
+}
+
+
+const char* GetBServerRoot()
+{
+ char* pRet;
+ char* pEnv = getenv("STAR_BSERVERROOT");
+ if ( pEnv )
+ {
+ int nLen = strlen( pEnv );
+ pRet = ( char *) malloc( nLen + 1 );
+ (void) strcpy( pRet, pEnv );
+ }
+ else
+ {
+ int nLen = strlen( B_SERVER_ROOT );
+ pRet = ( char *) malloc( nLen + 1 );
+ (void) strcpy( pRet, B_SERVER_ROOT );
+ }
+ return pRet;
+}
+
+const char* GetEnv( const char *pVar )
+{
+ char const *pRet = getenv( pVar );
+ if ( !pRet )
+ pRet = "";
+ return pRet;
+}
+
+const char* GetEnv( const char *pVar, const char *pDefault )
+{
+ char *pRet = getenv( pVar );
+ if ( !pRet )
+ return pDefault;
+ return pRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/bootstrp/command.cxx b/tools/bootstrp/command.cxx
new file mode 100644
index 000000000000..89ee09422833
--- /dev/null
+++ b/tools/bootstrp/command.cxx
@@ -0,0 +1,693 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#ifdef SCO
+#define _IOSTREAM_H
+#endif
+
+#ifdef PRECOMPILED
+#include "first.hxx"
+#endif
+
+#include <tools/fsys.hxx>
+#include <tools/stream.hxx>
+#include "bootstrp/command.hxx"
+#include <tools/debug.hxx>
+#include "bootstrp/appdef.hxx"
+
+#ifdef _MSC_VER
+#pragma warning (push,1)
+#endif
+
+#include <iostream>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+
+//#define MH_TEST2 1 // fuers direkte Testen
+
+#if defined(WNT) || defined(OS2)
+#ifdef _MSC_VER
+#pragma warning (push,1)
+#endif
+#include <process.h> // for _SPAWN
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+#endif
+#ifdef UNX
+#include <sys/types.h>
+#include <unistd.h>
+#if ( defined NETBSD ) || defined (FREEBSD) || defined (AIX) \
+ || defined (HPUX) || defined (MACOSX) || defined (OPENBSD)
+#include <sys/wait.h>
+#else
+#include <wait.h>
+#endif
+#define P_WAIT 1 // erstmal einen dummz
+#endif
+
+#if defined WNT
+#include <tools/svwin.h>
+#endif
+
+#if defined(WNT) || defined(OS2)
+#define cPathSeperator ';'
+#endif
+#ifdef UNX
+#define cPathSeperator ':'
+#endif
+
+/*****************************************************************************/
+CommandLine::CommandLine(BOOL bWrite)
+/*****************************************************************************/
+ : bTmpWrite(bWrite)
+{
+ CommandBuffer = new char [1];
+ if (CommandBuffer == NULL) {
+ //cout << "Error: nospace" << endl;
+ exit(0);
+ }
+ CommandBuffer[0] = '\0';
+ nArgc = 0;
+ ppArgv = new char * [1];
+ ppArgv[0] = NULL;
+
+ ComShell = new char [128];
+ char* pTemp = getenv("COMMAND_SHELL");
+ if(!pTemp)
+ strcpy(ComShell,COMMAND_SHELL);
+ else
+ strcpy(ComShell,pTemp);
+
+ strcpy(&ComShell[strlen(ComShell)]," -C ");
+}
+
+/*****************************************************************************/
+CommandLine::CommandLine(const char *CommandString, BOOL bWrite)
+/*****************************************************************************/
+ : bTmpWrite(bWrite)
+{
+ CommandBuffer = new char [1];
+ if (CommandBuffer == NULL) {
+ //cout << "Error: nospace" << endl;
+ exit(0);
+ }
+ nArgc = 0;
+ ppArgv = new char * [1];
+ ppArgv[0] = NULL;
+
+ ComShell = new char [128];
+ char* pTemp = getenv("COMMAND_SHELL");
+ if(!pTemp)
+ strcpy(ComShell,COMMAND_SHELL);
+ else
+ strcpy(ComShell,pTemp);
+
+ strcpy(&ComShell[strlen(ComShell)]," -C ");
+
+ BuildCommand(CommandString);
+}
+
+/*****************************************************************************/
+CommandLine::CommandLine(const CommandLine& CCommandLine, BOOL bWrite)
+/*****************************************************************************/
+ : bTmpWrite(bWrite)
+{
+ CommandBuffer = new char [1];
+ if (CommandBuffer == NULL) {
+ //cout << "Error: nospace" << endl;
+ exit(0);
+ }
+ nArgc = 0;
+ ppArgv = new char * [1];
+ ppArgv[0] = NULL;
+
+ ComShell = new char [128];
+ char* pTemp = getenv("COMMAND_SHELL");
+ if(!pTemp)
+ strcpy(ComShell,COMMAND_SHELL);
+ else
+ strcpy(ComShell,pTemp);
+
+ strcpy(&ComShell[strlen(ComShell)]," -C ");
+
+ BuildCommand(CCommandLine.CommandBuffer);
+}
+
+/*****************************************************************************/
+CommandLine::~CommandLine()
+/*****************************************************************************/
+{
+ delete [] CommandBuffer;
+ delete [] ComShell;
+ //for (int i = 0; ppArgv[i] != '\0'; i++) {
+ for (int i = 0; ppArgv[i] != 0; i++) {
+ delete [] ppArgv[i];
+ }
+ delete [] ppArgv;
+
+}
+
+/*****************************************************************************/
+CommandLine& CommandLine::operator=(const CommandLine& CCommandLine)
+/*****************************************************************************/
+{
+ strcpy (CommandBuffer, CCommandLine.CommandBuffer);
+ for (int i = 0; i != nArgc; i++) {
+ delete [] ppArgv[i];
+ }
+ delete [] ppArgv;
+ ppArgv = new char * [1];
+ ppArgv[0] = NULL;
+ BuildCommand(CommandBuffer);
+ return *this;
+}
+
+/*****************************************************************************/
+CommandLine& CommandLine::operator=(const char *CommandString)
+/*****************************************************************************/
+{
+ strcpy (CommandBuffer, CommandString);
+ for (int i = 0; i != nArgc; i++) {
+ delete [] ppArgv[i];
+ }
+ delete [] ppArgv;
+ ppArgv = new char * [1];
+ ppArgv[0] = NULL;
+ BuildCommand(CommandBuffer);
+
+ return *this;
+}
+
+/*****************************************************************************/
+void CommandLine::Print()
+/*****************************************************************************/
+{
+ //cout << "******* start print *******" << endl;
+ //cout << "nArgc = " << nArgc << endl;
+ //cout << "CommandBuffer = " << CommandBuffer << endl;
+ for (int i = 0; ppArgv[i] != NULL; i++) {
+ //cout << "ppArgv[" << i << "] = " << ppArgv[i] << endl;
+ }
+ //cout << "******** end print ********" << endl;
+}
+
+/*****************************************************************************/
+void CommandLine::BuildCommand(const char *CommandString)
+/*****************************************************************************/
+{
+ int index = 0, pos=0;
+ char buffer[1024];
+ char WorkString[1024];
+
+ strcpy(WorkString,CommandString);
+
+ //falls LogWindow -> in tmpfile schreiben
+ if(bTmpWrite)
+ {
+ strcpy(&WorkString[strlen(WorkString)]," >&");
+ strcpy(&WorkString[strlen(WorkString)],getenv("TMP"));
+ strcpy(&WorkString[strlen(WorkString)],TMPNAME);
+ }
+
+ // delete old memory and get some new memory for CommandBuffer
+
+ delete [] CommandBuffer;
+ CommandBuffer = new char [strlen(ComShell)+strlen(WorkString)+1];
+ if (CommandBuffer == NULL) {
+ //cout << "Error: nospace" << endl;
+ exit(0);
+ }
+ strcpy (CommandBuffer, ComShell);
+ strcpy (&CommandBuffer[strlen(ComShell)], WorkString);
+
+ CommandString = CommandBuffer;
+
+ // get the number of tokens
+ Strtokens(CommandString);
+
+ // delete the space for the old CommandLine
+
+ for (int i = 0; ppArgv[i] != 0; i++) {
+ delete [] ppArgv[i];
+ }
+ delete [] ppArgv;
+
+ /* get space for the new command line */
+
+ ppArgv = (char **) new char * [nArgc+1];
+ if (ppArgv == NULL) {
+ //cout << "Error: no space" << endl;
+ exit(0);
+ }
+
+ // flush the white space
+
+ while ( isspace(*CommandString) )
+ CommandString++;
+
+ index = 0;
+
+ // start the loop to build all the individual tokens
+
+ while (*CommandString != '\0') {
+
+ pos = 0;
+
+ // copy the token until white space is found
+
+ while ( !isspace(*CommandString) && *CommandString != '\0') {
+
+ buffer[pos++] = *CommandString++;
+
+ }
+
+ buffer[pos] = '\0';
+
+ // get space for the individual tokens
+
+ ppArgv[index] = (char *) new char [strlen(buffer)+1];
+ if (ppArgv[index] == NULL) {
+ //cout << "Error: nospace" << endl;
+ exit(0);
+ }
+
+ // copy the token
+
+ strcpy (ppArgv[index++], buffer);
+
+ // flush while space
+
+ while ( isspace(*CommandString) )
+ CommandString++;
+
+ }
+
+ // finish by setting the las pointer to NULL
+ ppArgv[nArgc]= NULL;
+
+}
+
+/*****************************************************************************/
+void CommandLine::Strtokens(const char *CommandString)
+/*****************************************************************************/
+{
+ int count = 0;
+ const char *temp;
+
+ temp = CommandString;
+
+ /* bypass white space */
+
+ while (isspace(*temp)) temp++;
+
+ for (count=0; *temp != '\0'; count++) {
+
+ /* continue until white space of string terminator is found */
+
+ while ((!isspace(*temp)) && (*temp != '\0')) temp++;
+
+ /* bypass white space */
+
+ while (isspace(*temp)) temp++;
+
+ }
+ nArgc = count;
+}
+
+/*****************************************************************************/
+CCommand::CCommand( ByteString &rString )
+/*****************************************************************************/
+{
+ rString.SearchAndReplace( '\t', ' ' );
+ aCommand = rString.GetToken( 0, ' ' );
+ aCommandLine = Search( "PATH" );
+#ifndef UNX
+ aCommandLine += " /c ";
+#else
+ aCommandLine += " -c ";
+#endif
+
+ ByteString sCmd( rString.GetToken( 0, ' ' ));
+ ByteString sParam( rString.Copy( sCmd.Len()));
+
+ aCommandLine += Search( "PATH", sCmd );
+ aCommandLine += sParam;
+
+ ImplInit();
+}
+
+/*****************************************************************************/
+CCommand::CCommand( const char *pChar )
+/*****************************************************************************/
+{
+ ByteString aString = pChar;
+ aString.SearchAndReplace( '\t', ' ' );
+ aCommand = aString.GetToken( 0, ' ' );
+
+ aCommandLine = Search( "PATH" );
+#ifndef UNX
+ aCommandLine += " /c ";
+#else
+ aCommandLine += " -c ";
+#endif
+ ByteString rString( pChar );
+
+ ByteString sCmd( rString.GetToken( 0, ' ' ));
+ ByteString sParam( rString.Copy( sCmd.Len()));
+
+ aCommandLine += Search( "PATH", sCmd );
+ aCommandLine += sParam;
+
+ ImplInit();
+}
+
+/*****************************************************************************/
+void CCommand::ImplInit()
+/*****************************************************************************/
+{
+ char pTmpStr[255];
+ size_t *pPtr;
+ char *pChar;
+ int nVoid = sizeof( size_t * );
+ nArgc = aCommandLine.GetTokenCount(' ');
+ ULONG nLen = aCommandLine.Len();
+
+ ppArgv = (char **) new char[ (ULONG)(nLen + nVoid * (nArgc +2) + nArgc ) ];
+ pChar = (char *) ppArgv + ( (1+nArgc) * nVoid );
+ pPtr = (size_t *) ppArgv;
+ for ( xub_StrLen i=0; i<nArgc; i++ )
+ {
+ (void) strcpy( pTmpStr, aCommandLine.GetToken(i, ' ' ).GetBuffer() );
+ size_t nStrLen = strlen( pTmpStr ) + 1;
+ strcpy( pChar, pTmpStr );
+ *pPtr = (sal_uIntPtr) pChar;
+ pChar += nStrLen;
+ pPtr += 1;
+#ifdef UNX
+ if ( i == 1 )
+ {
+ USHORT nWo = aCommandLine.Search("csh -c ");
+ if (nWo != STRING_NOTFOUND)
+ aCommandLine.Erase(0, nWo + 7);
+ else
+ aCommandLine.Erase(0, 16);
+ i = nArgc;
+ strcpy( pChar, aCommandLine.GetBuffer() );
+ *pPtr = (sal_uIntPtr) pChar;
+ pPtr += 1;
+ }
+#endif
+ }
+ *pPtr = 0;
+}
+
+/*****************************************************************************/
+CCommand::operator int()
+/*****************************************************************************/
+{
+ int nRet;
+#if defined WNT
+ nRet = _spawnv( P_WAIT, ppArgv[0], (const char **) ppArgv );
+#elif defined OS2
+ nRet = _spawnv( P_WAIT, ppArgv[0], ppArgv );
+#elif defined UNX
+ //fprintf( stderr, "CComand : operator (int) not implemented\n");
+ // **** Unix Implementierung ***************
+ pid_t pid;
+
+ if (( pid = fork()) < 0 )
+ {
+ DBG_ASSERT( FALSE, "fork error" );
+ }
+ else if ( pid == 0 )
+ {
+ if ( execv( ppArgv[0], (char * const *) ppArgv ) < 0 )
+ {
+ DBG_ASSERT( FALSE, "execv failed" );
+ }
+ }
+ //fprintf( stderr, "parent: %s %s\n", ppArgv[0] , ppArgv[1] );
+ if ( (nRet = waitpid( pid, NULL, 0 ) < 0) )
+ {
+ DBG_ASSERT( FALSE, "wait error" );
+ }
+#endif
+
+ switch ( errno )
+ {
+ case E2BIG :
+ nError = COMMAND_TOOBIG;
+ break;
+ case EINVAL :
+ nError = COMMAND_INVALID;
+ break;
+ case ENOENT:
+ nError = COMMAND_NOTFOUND;
+ break;
+ case ENOEXEC :
+ nError = COMMAND_NOEXEC;
+ break;
+ case ENOMEM :
+ nError = COMMAND_NOMEM;
+ break;
+ default:
+ nError = COMMAND_UNKNOWN;
+ }
+
+ if ( nRet )
+ fprintf( stderr, "Program returned with errros\n");
+ return nRet;
+}
+
+/*****************************************************************************/
+ByteString CCommand::Search(ByteString aEnv, ByteString sItem)
+/*****************************************************************************/
+{
+ // default wird eine Shell im Path gesucht,
+ // wenn aber compsec gestzt ist holen wir uns die
+ // Shell von dort
+ if ( sItem.Equals( COMMAND_SHELL ))
+ {
+ ByteString aComspec = GetEnv( "COMSPEC" );
+ if ( !aComspec.Equals(""))
+ return aComspec;
+ }
+
+ DirEntry aItem( String( sItem, RTL_TEXTENCODING_ASCII_US ));
+ if ( aItem.Exists())
+ return sItem;
+
+ ByteString aEntry, sReturn;
+ ByteString sEnv( aEnv );
+ ByteString sEnvironment = GetEnv( sEnv.GetBuffer());
+ xub_StrLen nCount = sEnvironment.GetTokenCount( cPathSeperator );
+
+ BOOL bFound = FALSE;
+
+ for ( xub_StrLen i=0; i<nCount && !bFound; i++ )
+ {
+ aEntry = sEnvironment.GetToken(i, cPathSeperator );
+#ifndef UNX
+ aEntry += '\\';
+#else
+ aEntry += '/';
+#endif
+ aEntry += sItem;
+
+ String sEntry( aEntry, RTL_TEXTENCODING_ASCII_US );
+ DirEntry aDirEntry( sEntry );
+ aDirEntry.ToAbs();
+ if ( aDirEntry.Exists()) {
+ sReturn = aEntry;
+ bFound = TRUE;
+ }
+ }
+ if ( !bFound )
+ {
+ sEnv = sEnv.ToUpperAscii();
+ ByteString sEnvironment2 = GetEnv(sEnv.GetBuffer() );
+ xub_StrLen nCount2 = sEnvironment2.GetTokenCount( cPathSeperator );
+ for ( xub_StrLen i=0; i<nCount2 && !bFound; i++ )
+ {
+ aEntry = sEnvironment2.GetToken(i, cPathSeperator );
+#ifndef UNX
+ aEntry += '\\';
+#else
+ aEntry += '/';
+#endif
+ aEntry += sItem;
+
+ String sEntry( aEntry, RTL_TEXTENCODING_ASCII_US );
+ DirEntry aDirEntry( sEntry );
+ aDirEntry.ToAbs();
+ if ( aDirEntry.Exists()) {
+ sReturn = aEntry;
+ bFound = TRUE;
+ }
+ }
+ }
+
+ if ( sReturn.Equals( "" ))
+ sReturn = sItem;
+
+ return sReturn;
+}
+
+/*****************************************************************************/
+CCommandd::CCommandd( ByteString &rString, CommandBits nBits )
+/*****************************************************************************/
+ : CCommand( rString ),
+ nFlag( nBits )
+{
+}
+
+
+/*****************************************************************************/
+CCommandd::CCommandd( const char *pChar, CommandBits nBits )
+/*****************************************************************************/
+ : CCommand( pChar ),
+ nFlag( nBits )
+{
+}
+
+/*****************************************************************************/
+CCommandd::operator int()
+/*****************************************************************************/
+{
+ int nRet = 0;
+
+#ifdef WNT
+ LPCTSTR lpApplicationName = NULL;
+ LPTSTR lpCommandLine = (char *) GetCommandLine_().GetBuffer();
+ LPSECURITY_ATTRIBUTES lpProcessAttributes = NULL;
+ LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL;
+ BOOL bInheritHandles = TRUE;
+
+ // wie wuenschen wir denn gestartet zu werden ??
+ DWORD dwCreationFlags;
+
+ if ( nFlag & COMMAND_EXECUTE_START )
+ dwCreationFlags = DETACHED_PROCESS;
+ else
+ dwCreationFlags = CREATE_NEW_CONSOLE;
+
+ // wir erben vom Vaterprozess
+ LPVOID lpEnvironment = NULL;
+
+ // das exe im Pfad suchen
+ LPCTSTR lpCurrentDirectory = NULL;
+
+ // in dieser Struktur bekommen wir die erzeugte Processinfo
+ // zurueck
+ PROCESS_INFORMATION aProcessInformation;
+
+ // weiteres Startupinfo anlegen
+ STARTUPINFO aStartupInfo;
+
+ aStartupInfo.cb = sizeof( STARTUPINFO );
+ aStartupInfo.lpReserved = NULL;
+ aStartupInfo.lpDesktop = NULL;
+
+ // das Fenster bekommt den Namen des Exes
+ aStartupInfo.lpTitle = NULL;
+ aStartupInfo.dwX = 100;
+ aStartupInfo.dwY = 100;
+ //aStartupInfo.dwXSize = 400;
+ //aStartupInfo.dwYSize = 400;
+ aStartupInfo.dwXCountChars = 40;
+ aStartupInfo.dwYCountChars = 40;
+
+ // Farben setzen
+ aStartupInfo.dwFillAttribute = FOREGROUND_RED | BACKGROUND_RED |
+ BACKGROUND_BLUE | BACKGROUND_GREEN;
+
+// aStartupInfo.dwFlags = STARTF_USESTDHANDLES;
+ //aStartupInfo.wShowWindow = SW_NORMAL; //SW_SHOWDEFAULT;
+ //aStartupInfo.wShowWindow = SW_HIDE; //SW_SHOWNOACTIVATE;
+ aStartupInfo.wShowWindow = SW_SHOWNOACTIVATE;
+ aStartupInfo.cbReserved2 = NULL;
+ aStartupInfo.lpReserved2 = NULL;
+ //aStartupInfo.hStdInput = stdin;
+ //aStartupInfo.hStdOutput = stdout;
+ //aStartupInfo.hStdError = stderr;
+
+ if ( nFlag & COMMAND_EXECUTE_HIDDEN )
+ {
+ aStartupInfo.wShowWindow = SW_HIDE;
+ aStartupInfo.dwFlags = aStartupInfo.dwFlags | STARTF_USESHOWWINDOW;
+ }
+
+ bool bProcess = CreateProcess( lpApplicationName,
+ lpCommandLine, lpProcessAttributes,
+ lpThreadAttributes, bInheritHandles,
+ dwCreationFlags, lpEnvironment, lpCurrentDirectory,
+ &aStartupInfo, &aProcessInformation );
+
+ LPVOID lpMsgBuf;
+
+ if ( bProcess )
+ {
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL );
+
+ ByteString aErrorString = (char *) lpMsgBuf;
+
+ if ( nFlag & COMMAND_EXECUTE_WAIT )
+ {
+ DWORD aProcessState = STILL_ACTIVE;
+ while(aProcessState == STILL_ACTIVE)
+ {
+ GetExitCodeProcess(aProcessInformation.hProcess,&aProcessState);
+ }
+ }
+ }
+ else
+ fprintf( stderr, "Can not start Process !" );
+
+#endif
+ return nRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/bootstrp/cppdep.cxx b/tools/bootstrp/cppdep.cxx
new file mode 100644
index 000000000000..6d4596507749
--- /dev/null
+++ b/tools/bootstrp/cppdep.cxx
@@ -0,0 +1,249 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <unistd.h>
+
+#include <sys/stat.h>
+#include <tools/stream.hxx>
+#include "cppdep.hxx"
+
+//#define TEST
+
+CppDep::CppDep( ByteString aFileName )
+{
+ aSourceFile = aFileName;
+
+ pSearchPath = new ByteStringList;
+ pFileList = new ByteStringList;
+}
+
+CppDep::CppDep()
+{
+ pSources = new ByteStringList;
+ pSearchPath = new ByteStringList;
+ pFileList = new ByteStringList;
+}
+
+CppDep::~CppDep()
+{
+ delete pSources;
+ delete pSearchPath;
+ delete pFileList;
+}
+
+void CppDep::Execute()
+{
+ ULONG nCount = pSources->Count();
+ for ( ULONG n=0; n<nCount;n++)
+ {
+ ByteString *pStr = pSources->GetObject(n);
+ Search( *pStr );
+ }
+}
+
+BOOL CppDep::AddSearchPath( const char* aPath )
+{
+ ByteString *pStr = new ByteString( aPath );
+ pSearchPath->Insert( pStr, LIST_APPEND );
+ return FALSE;
+}
+
+BOOL CppDep::AddSource( const char* aSource )
+{
+ ByteString *pStr = new ByteString( aSource );
+ pSources->Insert( pStr, LIST_APPEND );
+ return FALSE;
+}
+
+BOOL CppDep::Search( ByteString aFileName )
+{
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, "SEARCH : %s\n", aFileName.GetBuffer());
+#endif
+ BOOL bRet = FALSE;
+
+ SvFileStream aFile;
+ ByteString aReadLine;
+
+ UniString suFileName( aFileName, gsl_getSystemTextEncoding());
+
+ aFile.Open( suFileName, STREAM_READ );
+ while ( aFile.ReadLine( aReadLine ))
+ {
+ USHORT nPos = aReadLine.Search( "include" );
+ if ( nPos != STRING_NOTFOUND )
+ {
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, "found : %d %s\n", nPos, aReadLine.GetBuffer() );
+#endif
+ ByteString aResult = IsIncludeStatement( aReadLine );
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, "Result : %s\n", aResult.GetBuffer() );
+#endif
+
+ ByteString aNewFile;
+ if ( aResult !="")
+ if ( (aNewFile = Exists( aResult )) != "" )
+ {
+ BOOL bFound = FALSE;
+ ULONG nCount = pFileList->Count();
+ for ( ULONG i=0; i<nCount; i++ )
+ {
+ ByteString *pStr = pFileList->GetObject(i);
+ if ( *pStr == aNewFile )
+ bFound = TRUE;
+ }
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, "not in list : %d %s\n", nPos, aReadLine.GetBuffer() );
+#endif
+ if ( !bFound )
+ {
+ pFileList->Insert( new ByteString( aNewFile ), LIST_APPEND );
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, " CppDep %s\\\n", aNewFile.GetBuffer() );
+#endif
+ Search(aNewFile);
+ }
+ }
+ }
+ }
+ aFile.Close();
+
+ return bRet;
+}
+
+ByteString CppDep::Exists( ByteString aFileName )
+{
+ char pFullName[1023];
+ ByteString aString;
+
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, "Searching %s \n", aFileName.GetBuffer() );
+#endif
+
+ ULONG nCount = pSearchPath->Count();
+ for ( ULONG n=0; n<nCount; n++)
+ {
+ struct stat aBuf;
+ ByteString *pPathName = pSearchPath->GetObject(n);
+
+ strcpy( pFullName, pPathName->GetBuffer());
+ strcat( pFullName, DIR_SEP );
+ strcat( pFullName, aFileName.GetBuffer());
+
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, "looking for %s\t ", pFullName );
+#endif
+ if ( stat( pFullName, &aBuf ) == 0 )
+ {
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, "Got Dependency ", pFullName );
+#endif
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, "%s \\\n", pFullName );
+#endif
+
+ return ByteString(pFullName);
+ }
+ }
+ return aString;
+}
+
+ByteString CppDep::IsIncludeStatement( ByteString aLine )
+{
+ ByteString aRetStr;
+ if ( aLine.Search("/*",0) != STRING_NOTFOUND )
+ {
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, "found starting C comment : %s\n", aLine.GetBuffer() );
+#endif
+ aLine.Erase(aLine.Search("/*",0), aLine.Len() - 1);
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, "cleaned string : %s\n", aLine.GetBuffer() );
+#endif
+ }
+ if ( aLine.Search("//",0) != STRING_NOTFOUND )
+ {
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, "found C++ comment : %s\n", aLine.GetBuffer() );
+#endif
+ aLine.Erase(aLine.Search("//",0), aLine.Len() - 1);
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, "cleaned string : %s\n", aLine.GetBuffer() );
+#endif
+ }
+ // WhiteSpacesfressen
+ aLine.EraseAllChars(' ');
+ aLine.EraseAllChars('\t');
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, "now : %s\n", aLine.GetBuffer() );
+#endif
+ // ist der erste Teil ein #include ?
+ ByteString aTmpStr;
+ aTmpStr = aLine.Copy( 0, 8 );
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, "is include : %s\n", aTmpStr.GetBuffer() );
+#endif
+ if ( aTmpStr.Equals("#include") )
+ {
+ aTmpStr = aLine.Erase( 0, 8 );
+ USHORT nLen = aLine.Len();
+ aLine.Erase( nLen-1, 1 );
+ aLine.Erase( 0, 1 );
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, "Gotcha : %s\n", aLine.GetBuffer() );
+#endif
+ aRetStr = aLine;
+ }
+ return aRetStr;
+}
+
+#ifdef TEST
+
+int main( int argc, char **argv )
+{
+ CppDep *pDep = new CppDep( "cppdep.cxx" );
+ pDep->AddSearchPath(".");
+ pDep->AddSearchPath("/usr/include");
+ pDep->AddSearchPath("/usr/local/include");
+ pDep->AddSearchPath("/usr/include/sys");
+ pDep->AddSearchPath("/usr/include/X11");
+ pDep->Execute();
+ delete pDep;
+ return 0;
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/bootstrp/cppdep.hxx b/tools/bootstrp/cppdep.hxx
new file mode 100644
index 000000000000..46d401f57698
--- /dev/null
+++ b/tools/bootstrp/cppdep.hxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/list.hxx>
+#include <tools/string.hxx>
+#define PATH_SEP ":"
+#define DIR_SEP "/"
+
+DECLARE_LIST( ByteStringList, ByteString * )
+
+class CppDep
+{
+ ByteString aSourceFile;
+ ByteStringList *pSearchPath;
+
+protected:
+ ByteStringList *pFileList;
+ ByteStringList *pSources;
+
+ BOOL Search( ByteString aFileName );
+ ByteString Exists( ByteString aFileName );
+
+ ByteString IsIncludeStatement( ByteString aLine );
+public:
+ CppDep( ByteString aFileName );
+ CppDep();
+ virtual ~CppDep();
+ virtual void Execute();
+
+ ByteStringList* GetDepList(){return pFileList;}
+ BOOL AddSearchPath( const char* aPath );
+ BOOL AddSource( const char * aSource );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/bootstrp/inimgr.cxx b/tools/bootstrp/inimgr.cxx
new file mode 100644
index 000000000000..410e0ac7a6e2
--- /dev/null
+++ b/tools/bootstrp/inimgr.cxx
@@ -0,0 +1,213 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#if !defined( UNX )
+#include <direct.h>
+#else
+#include <sys/stat.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+
+
+#include "bootstrp/inimgr.hxx"
+#include "bootstrp/appdef.hxx"
+
+/****************************************************************************/
+IniManager::IniManager( ByteString &rDir, ByteString &rLocalDir )
+/****************************************************************************/
+ : bUpdate( TRUE )
+{
+ sLocalPath = ByteString( getenv( "LOCALINI" ));
+ if ( !sLocalPath.Len())
+ sLocalPath = rLocalDir;
+
+ sGlobalDir = rDir;
+#if !defined( UNX ) && !defined( OS2 )
+ mkdir(( char * ) sLocalPath.GetBuffer());
+#else
+ mkdir( sLocalPath.GetBuffer() ,00777 );
+#endif
+}
+
+/****************************************************************************/
+IniManager::IniManager( ByteString &rDir )
+/****************************************************************************/
+ : bUpdate( TRUE )
+{
+ sLocalPath = GetLocalIni();
+ sGlobalDir = rDir;
+#if !defined( UNX ) && !defined( OS2 )
+ mkdir(( char * ) sLocalPath.GetBuffer());
+#else
+ mkdir( sLocalPath.GetBuffer() ,00777 );
+#endif
+}
+
+/****************************************************************************/
+IniManager::IniManager()
+/****************************************************************************/
+ : bUpdate( TRUE )
+{
+ sLocalPath = GetLocalIni();
+
+#if !defined( UNX ) && !defined( OS2 )
+ mkdir(( char * ) sLocalPath.GetBuffer());
+#else
+ mkdir( sLocalPath.GetBuffer(), 00777 );
+#endif
+
+ sGlobalDir = GetGlobalIni();
+}
+
+/****************************************************************************/
+ByteString IniManager::ToLocal( ByteString &rPath )
+/****************************************************************************/
+{
+ ByteString sTmp( rPath );
+#if !defined( UNX )
+ ByteString sUnc( _INI_UNC );
+ sUnc.ToUpperAscii();
+ ByteString sOldUnc( _INI_UNC_OLD );
+ sOldUnc.ToUpperAscii();
+ sTmp.ToUpperAscii();
+
+ sTmp.SearchAndReplace( sUnc, _INI_DRV );
+ sTmp.SearchAndReplace( sOldUnc, _INI_DRV );
+ sTmp.ToUpperAscii();
+
+ ByteString sIni( sGlobalDir );
+ sIni.ToUpperAscii();
+
+ sTmp.SearchAndReplace( sIni, sLocalPath );
+
+ while ( sTmp.SearchAndReplace( "\\\\", "\\" ) != STRING_NOTFOUND ) ;
+#else
+ sTmp.SearchAndReplace( sGlobalDir, sLocalPath );
+
+ ByteString sOldGlobalDir( GetIniRootOld() );
+ sTmp.SearchAndReplace( sOldGlobalDir, sLocalPath );
+
+ while ( sTmp.SearchAndReplace( "//", "/" ) != STRING_NOTFOUND ) ;
+#endif
+
+ return sTmp;
+}
+
+/****************************************************************************/
+ByteString IniManager::GetLocalIni()
+/****************************************************************************/
+{
+ ByteString sLocalPath = ByteString( getenv( "LOCALINI" ));
+
+ if ( !sLocalPath.Len()) {
+#ifdef UNX
+ ByteString sLocal( getenv( "HOME" ));
+ sLocal += ByteString( "/localini" );
+#else
+ ByteString sLocal( getenv( "TMP" ));
+ sLocal += ByteString( "\\localini" );
+#endif
+
+ sLocalPath = sLocal;
+ }
+
+ return sLocalPath;
+}
+
+/****************************************************************************/
+ByteString IniManager::GetGlobalIni()
+/****************************************************************************/
+{
+ ByteString sGlobalPath = ByteString( GetEnv( "GLOBALINI" ));
+
+ if ( !sGlobalPath.Len())
+ sGlobalPath = ByteString( _INIROOT );
+
+ return sGlobalPath;
+}
+
+/****************************************************************************/
+void IniManager::ForceUpdate()
+/****************************************************************************/
+{
+ UniString sUniGlobalDir( sGlobalDir, gsl_getSystemTextEncoding());
+ DirEntry aPath( UniString( sGlobalDir, gsl_getSystemTextEncoding()));
+ Dir aDir( aPath, FSYS_KIND_DIR | FSYS_KIND_FILE);
+
+#ifndef UNX
+ sLocalPath.EraseTrailingChars( '\\' );
+ sLocalPath += "\\";
+#else
+ sLocalPath.EraseTrailingChars( '/' );
+ sLocalPath += "/";
+#endif
+
+ for ( USHORT i=0; i < aDir.Count(); i++ ) {
+ ByteString sEntry( aDir[i].GetName(), gsl_getSystemTextEncoding());
+ if (( sEntry != "." ) &&
+ ( sEntry != ".." ))
+ {
+ if ( !FileStat( aDir[i] ).IsKind( FSYS_KIND_DIR )) {
+ ByteString sSrc( aDir[i].GetFull(), gsl_getSystemTextEncoding());
+ ByteString sDestination( sLocalPath );
+ sDestination += sEntry;
+
+ UniString sUniDestination( sDestination, gsl_getSystemTextEncoding());
+ DirEntry aDestEntry( sUniDestination );
+ FileStat aDestStat( aDestEntry );
+ FileStat aSrcStat( aDir[i] );
+
+ if (( !aDestEntry.Exists() ) ||
+ ( aSrcStat.IsYounger( aDestStat )))
+ {
+ FileCopier aFileCopier( aDir[ i ], aDestEntry );
+ aFileCopier.Execute();
+
+ while ( !aDestEntry.Exists())
+ aFileCopier.Execute();
+ }
+ }
+ }
+ }
+}
+
+/****************************************************************************/
+void IniManager::Update()
+/****************************************************************************/
+{
+ if ( bUpdate )
+ {
+ ForceUpdate();
+ bUpdate = FALSE;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/bootstrp/iserver.cxx b/tools/bootstrp/iserver.cxx
new file mode 100644
index 000000000000..6f24c1e274f3
--- /dev/null
+++ b/tools/bootstrp/iserver.cxx
@@ -0,0 +1,154 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <tools/iparser.hxx>
+#include <tools/geninfo.hxx>
+#include "bootstrp/appdef.hxx"
+#include <stdio.h>
+
+
+/*****************************************************************************/
+#ifdef UNX
+int main( int argc, char *argv[] )
+#else
+int _cdecl main( int argc, char *argv[] )
+#endif
+/*****************************************************************************/
+{
+ if ( argc == 1 ) {
+ fprintf( stdout, "\ni_server.exe v2.0 (c) 2000\n\n" );
+ fprintf( stdout, "Syntax: i_server -i accesspath [-l] [-d database] \n" );
+ fprintf( stdout, "Example: - i_server -i vcl364/settings/now\n" );
+ fprintf( stdout, " returns value of settings \"now\" of version \"vcl364\"\n" );
+ fprintf( stdout, " - i_server -i vcl364/settings -l\n" );
+ fprintf( stdout, " returns a list of all settings of version \"vcl364\"\n" );
+ }
+ else {
+ BOOL bError = FALSE;
+ BOOL bList = FALSE;
+ ByteString sInfo( "" );
+ ByteString sDataBase( GetDefStandList());
+
+ BOOL bGetNow = FALSE;
+
+ int nCount = 1;
+ while (( nCount < argc ) &&
+ ( !bError ))
+ {
+ if ( ByteString( argv[nCount] ).ToUpperAscii() == "-I" ) {
+ // requestet info path
+ nCount++;
+ if( nCount < argc ) {
+ sInfo = ByteString( argv[nCount] );
+ nCount++;
+ }
+ else bError = TRUE;
+ }
+ else if ( ByteString( argv[nCount] ).ToUpperAscii() == "-D" ) {
+ // requestet info path
+ nCount++;
+ if( nCount < argc ) {
+ sDataBase = ByteString( argv[nCount] );
+ nCount++;
+ }
+ else bError = TRUE;
+ }
+ else if ( ByteString( argv[nCount] ).ToUpperAscii() == "-L" ) {
+ // request list of childs
+ nCount++;
+ bList = TRUE;
+ }
+ else if ( ByteString( argv[nCount] ).ToUpperAscii() == "-N" ) {
+ // request list of childs
+ nCount++;
+ bGetNow = TRUE;
+ }
+ else {
+ bError = TRUE;
+ }
+ }
+
+ if ( !bError ) {
+ InformationParser aParser( REPLACE_VARIABLES );
+ ByteString sStandList( sDataBase );
+ String s = String( sStandList, gsl_getSystemTextEncoding());
+ GenericInformationList *pList = aParser.Execute( s );
+ if ( !pList )
+ return 1;
+
+ if ( sInfo.Len()) {
+ GenericInformation *pInfo = pList->GetInfo( sInfo, TRUE );
+
+ if ( pInfo ) {
+ ByteString sValue( pInfo->GetValue());
+ // show the info and its value
+ fprintf( stdout, "%s %s\n", pInfo->GetBuffer(), sValue.GetBuffer());
+ if ( bList ) {
+ GenericInformationList *pList = pInfo->GetSubList();
+ if ( pList ) {
+ // show whole list of childs and their values
+ for( ULONG i = 0; i < pList->Count(); i++ ) {
+ GenericInformation *pInfo = pList->GetObject( i );
+ ByteString sValue( pInfo->GetValue());
+ fprintf( stdout, " %s %s\n", pInfo->GetBuffer(), sValue.GetBuffer());
+ }
+ }
+ }
+ return 0;
+ }
+ return 1;
+ }
+ else {
+ // show whole list of childs and their values
+ for( ULONG i = 0; i < pList->Count(); i++ ) {
+ GenericInformation *pInfo = pList->GetObject( i );
+ if ( bGetNow ) {
+ ByteString sPath( "settings/now" );
+ GenericInformation *pSubInfo = pInfo->GetSubInfo( sPath, TRUE );
+ if ( pSubInfo && pSubInfo->GetValue() == "_TRUE" )
+ fprintf( stdout, "%s\n", pInfo->GetBuffer());
+ }
+ else {
+ ByteString sValue( pInfo->GetValue());
+ fprintf( stdout, " %s %s\n", pInfo->GetBuffer(), sValue.GetBuffer());
+ }
+ }
+ return 0;
+ }
+ }
+ else
+ fprintf( stderr, "%s: Fehler in der Kommandozeile!", argv[0] );
+ // command line arror !!!
+ }
+
+ return 1;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/bootstrp/makefile.mk b/tools/bootstrp/makefile.mk
new file mode 100644
index 000000000000..06162f065682
--- /dev/null
+++ b/tools/bootstrp/makefile.mk
@@ -0,0 +1,108 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=tools
+TARGET=btstrp
+TARGET1=bootstrp2
+TARGETTYPE=CUI
+LIBTARGET=NO
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+CDEFS+=-D_TOOLS_STRINGLIST
+
+.IF "$(HAVE_GETOPT)" == "YES"
+CDEFS += -DHAVE_GETOPT
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+OBJFILES= \
+ $(OBJ)$/appdef.obj \
+ $(OBJ)$/command.obj \
+ $(OBJ)$/cppdep.obj\
+ $(OBJ)$/inimgr.obj\
+ $(OBJ)$/mkcreate.obj \
+ $(OBJ)$/sstring.obj \
+ $(OBJ)$/prj.obj
+
+SLOFILES= \
+ $(SLO)$/appdef.obj \
+ $(SLO)$/command.obj \
+ $(SLO)$/cppdep.obj \
+ $(SLO)$/inimgr.obj \
+ $(SLO)$/mkcreate.obj \
+ $(SLO)$/sstring.obj \
+ $(SLO)$/prj.obj
+
+
+LIB1TARGET= $(LB)$/$(TARGET).lib
+LIB1ARCHIV= $(LB)$/lib$(TARGET).a
+LIB1OBJFILES=\
+ $(OBJ)$/appdef.obj \
+ $(OBJ)$/command.obj \
+ $(OBJ)$/cppdep.obj \
+ $(OBJ)$/inimgr.obj \
+ $(OBJ)$/mkcreate.obj \
+ $(OBJ)$/sstring.obj
+
+LIB2TARGET= $(LB)$/$(TARGET1).lib
+LIB2ARCHIV= $(LB)$/lib$(TARGET1).a
+LIB2OBJFILES=\
+ $(OBJ)$/prj.obj
+
+APP1TARGET= sspretty
+APP1OBJS= $(OBJ)$/sspretty.obj
+APP1LIBS= $(LB)$/$(TARGET).lib $(LB)$/$(TARGET1).lib
+APP1STDLIBS=$(SALLIB) $(TOOLSLIB) $(BASEGFXLIB) $(UCBHELPERLIB) $(CPPULIB) $(COMPHELPERLIB) $(CPPUHELPERLIB) $(SALHELPERLIB) $(I18NISOLANGLIB)
+
+APP2TARGET= rscdep
+APP2OBJS= $(OBJ)$/rscdep.obj
+APP2LIBS= $(LB)$/$(TARGET).lib $(LB)$/$(TARGET1).lib
+APP2STDLIBS= $(SALLIB) $(TOOLSLIB) $(BASEGFXLIB) $(UCBHELPERLIB) $(CPPULIB) $(COMPHELPERLIB) $(I18NISOLANGLIB) $(CPPUHELPERLIB) $(SALHELPERLIB)
+.IF "$(HAVE_GETOPT)" != "YES"
+.IF "$(OS)"=="WNT"
+APP2STDLIBS+=gnu_getopt.lib
+.ENDIF
+.ENDIF
+APP2RPATH= NONE
+APP2RPATH= NONE
+APP2RPATH= NONE
+
+APP3TARGET= so_checksum
+APP3OBJS= $(OBJ)$/md5.obj \
+ $(OBJ)$/so_checksum.obj
+APP3STDLIBS= $(TOOLSLIB) $(SALLIB) $(BASEGFXLIB) $(UCBHELPERLIB) $(CPPULIB) $(COMPHELPERLIB) $(I18NISOLANGLIB) $(CPPUHELPERLIB) $(SALHELPERLIB)
+
+DEPOBJFILES = $(APP1OBJS) $(APP2OBJS) $(APP3OBJS)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/tools/bootstrp/md5.cxx b/tools/bootstrp/md5.cxx
new file mode 100644
index 000000000000..d3f524393500
--- /dev/null
+++ b/tools/bootstrp/md5.cxx
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include "md5.hxx"
+
+#include <cstddef>
+#include <stdio.h>
+
+#include <tools/string.hxx>
+
+#ifdef WNT
+#define FILE_OPEN_READ "rb"
+#else
+#define FILE_OPEN_READ "r"
+#endif
+
+// Extended calc_md5_checksum to recognize Windows executables and libraries. To
+// create the same md5 checksum for a (code/data) identical file it ignores a different
+// date and header checksum. Please see crashrep/source/win32/soreport.cpp
+// where the same method is also used. The crash reporter uses the MD5
+// checksums to transfer them to the crash database. You have to make sure that both
+// methods use the same algorithm otherwise there could be problems with stack reports.
+
+void normalize_pe_image(sal_uInt8* buffer, size_t nBufferSize)
+{
+ const int OFFSET_PE_OFFSET = 0x3c;
+ const int OFFSET_COFF_TIMEDATESTAMP = 4;
+ const int PE_SIGNATURE_SIZE = 4;
+ const int COFFHEADER_SIZE = 20;
+ const int OFFSET_PE_OPTIONALHEADER_CHECKSUM = 64;
+
+ // Check the header part of the file buffer
+ if (buffer[0] == sal_uInt8('M') && buffer[1] == sal_uInt8('Z'))
+ {
+ unsigned long PEHeaderOffset = (long)buffer[OFFSET_PE_OFFSET];
+ if (PEHeaderOffset < nBufferSize-4)
+ {
+ if ( buffer[PEHeaderOffset+0] == sal_uInt8('P') &&
+ buffer[PEHeaderOffset+1] == sal_uInt8('E') &&
+ buffer[PEHeaderOffset+2] == 0 &&
+ buffer[PEHeaderOffset+3] == 0 )
+ {
+ PEHeaderOffset += PE_SIGNATURE_SIZE;
+ if (PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP < nBufferSize-4)
+ {
+ // Set timedatestamp and checksum fields to a normalized
+ // value to enforce the same MD5 checksum for identical
+ // Windows executables/libraries.
+ buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+0] = 0;
+ buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+1] = 0;
+ buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+2] = 0;
+ buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+3] = 0;
+ }
+
+ if (PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM < nBufferSize-4)
+ {
+ // Set checksum to a normalized value
+ buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM] = 0;
+ buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM+1] = 0;
+ buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM+2] = 0;
+ buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM+3] = 0;
+ }
+ }
+ }
+ }
+}
+
+rtlDigestError calc_md5_checksum( const char *filename, ByteString &aChecksum )
+{
+ const size_t BUFFER_SIZE = 0x1000;
+ const size_t MINIMAL_SIZE = 512;
+
+ sal_uInt8 checksum[RTL_DIGEST_LENGTH_MD5];
+ rtlDigestError error = rtl_Digest_E_None;
+
+ FILE *fp = fopen( filename, FILE_OPEN_READ );
+
+ if ( fp )
+ {
+ rtlDigest digest = rtl_digest_createMD5();
+
+ if ( digest )
+ {
+ size_t nBytesRead;
+ sal_uInt8 buffer[BUFFER_SIZE];
+ bool bHeader(true);
+
+ while ( rtl_Digest_E_None == error &&
+ 0 != (nBytesRead = fread( buffer, 1, sizeof(buffer), fp )) )
+ {
+ if (bHeader)
+ {
+ bHeader = false;
+ if (nBytesRead >= MINIMAL_SIZE && buffer[0] == sal_uInt8('M') && buffer[1] == sal_uInt8('Z') )
+ normalize_pe_image(buffer, nBytesRead);
+ }
+
+ error = rtl_digest_updateMD5( digest, buffer, nBytesRead );
+ }
+
+ if ( rtl_Digest_E_None == error )
+ {
+ error = rtl_digest_getMD5( digest, checksum, sizeof(checksum) );
+ }
+
+ rtl_digest_destroyMD5( digest );
+
+ for ( std::size_t i = 0; i < sizeof(checksum); i++ )
+ {
+ if ( checksum[i] < 16 )
+ aChecksum.Append( "0" );
+ aChecksum += ByteString::CreateFromInt32( checksum[i], 16 );
+ }
+ }
+
+ fclose( fp );
+ }
+ else
+ error = rtl_Digest_E_Unknown;
+
+ return error;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/bootstrp/md5.hxx b/tools/bootstrp/md5.hxx
new file mode 100644
index 000000000000..9db4a739b4f2
--- /dev/null
+++ b/tools/bootstrp/md5.hxx
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <rtl/digest.h>
+class ByteString;
+
+rtlDigestError calc_md5_checksum( const char *filename, ByteString &aChecksum );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/bootstrp/mkcreate.cxx b/tools/bootstrp/mkcreate.cxx
new file mode 100644
index 000000000000..fdc895ecc190
--- /dev/null
+++ b/tools/bootstrp/mkcreate.cxx
@@ -0,0 +1,947 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+// global includes
+#include <stdio.h>
+
+// local includes
+#include "bootstrp/mkcreate.hxx"
+#include "bootstrp/inimgr.hxx"
+#include "bootstrp/appdef.hxx"
+#include <tools/geninfo.hxx>
+#include <tools/iparser.hxx>
+#include "bootstrp/prj.hxx"
+
+char const *NoBuildProject[] = {
+ "solenv",
+ "EndOf_NoBuildProject"
+};
+
+char const *LimitedPath[] = {
+ "jurt\\com\\sun\\star",
+ "r_tools",
+ "ridljar",
+ "setup2",
+ "connectivity",
+ "EndOf_LimitedPath"
+};
+
+//
+// class SourceDirectory
+//
+
+/*****************************************************************************/
+SourceDirectory::SourceDirectory( const ByteString &rDirectoryName,
+ USHORT nOperatingSystem, SourceDirectory *pParentDirectory )
+/*****************************************************************************/
+ : ByteString( rDirectoryName ),
+ pParent( pParentDirectory ),
+ pSubDirectories( NULL ),
+ nOSType( nOperatingSystem ),
+ nDepth( 0 ),
+ pDependencies( NULL ),
+ pCodedDependencies( NULL ),
+ pCodedIdentifier( NULL )
+{
+ if ( pParent ) {
+ if ( !pParent->pSubDirectories )
+ pParent->pSubDirectories = new SourceDirectoryList();
+ pParent->pSubDirectories->InsertSorted( this );
+ nDepth = pParent->nDepth + 1;
+ }
+}
+
+/*****************************************************************************/
+SourceDirectory::~SourceDirectory()
+/*****************************************************************************/
+{
+ delete pSubDirectories;
+}
+
+/*****************************************************************************/
+CodedDependency *SourceDirectory::AddCodedDependency(
+ const ByteString &rCodedIdentifier, USHORT nOperatingSystems )
+/*****************************************************************************/
+{
+ CodedDependency *pReturn = NULL;
+
+ if ( !pCodedDependencies ) {
+ pCodedDependencies = new SByteStringList();
+ pReturn = new CodedDependency( rCodedIdentifier, nOperatingSystems );
+ pCodedDependencies->PutString(( ByteString * ) pReturn );
+ }
+ else {
+ ULONG nPos =
+ pCodedDependencies->IsString( (ByteString *) (& rCodedIdentifier) );
+ if ( nPos == NOT_THERE ) {
+ pReturn =
+ new CodedDependency( rCodedIdentifier, nOperatingSystems );
+ pCodedDependencies->PutString(( ByteString * ) pReturn );
+ }
+ else {
+ pReturn =
+ ( CodedDependency * ) pCodedDependencies->GetObject( nPos );
+ pReturn->TryToMerge( rCodedIdentifier, nOperatingSystems );
+ }
+ }
+ return pReturn;
+}
+
+/*****************************************************************************/
+CodedDependency *SourceDirectory::AddCodedIdentifier(
+ const ByteString &rCodedIdentifier, USHORT nOperatingSystems )
+/*****************************************************************************/
+{
+ CodedDependency *pReturn = NULL;
+
+ if ( !pCodedIdentifier ) {
+ pCodedIdentifier = new SByteStringList();
+ pReturn = new CodedDependency( rCodedIdentifier, nOperatingSystems );
+ pCodedIdentifier->PutString(( ByteString * ) pReturn );
+ }
+ else {
+ ULONG nPos =
+ pCodedIdentifier->IsString( ( ByteString *) (& rCodedIdentifier) );
+ if ( nPos == NOT_THERE ) {
+ pReturn =
+ new CodedDependency( rCodedIdentifier, nOperatingSystems );
+ pCodedIdentifier->PutString(( ByteString * ) pReturn );
+ }
+ else {
+ pReturn =
+ ( CodedDependency * ) pCodedIdentifier->GetObject( nPos );
+ pReturn->TryToMerge( rCodedIdentifier, nOperatingSystems );
+ }
+ }
+ if ( pParent && pParent->nDepth > 1 )
+ pParent->AddCodedIdentifier( rCodedIdentifier, nOperatingSystems );
+
+ return pReturn;
+}
+
+/*****************************************************************************/
+ByteString SourceDirectory::GetFullPath()
+/*****************************************************************************/
+{
+ ByteString sFullPath;
+ if ( pParent ) {
+ sFullPath = pParent->GetFullPath();
+ sFullPath += ByteString( PATH_SEPARATOR );
+ }
+ sFullPath += *this;
+
+ return sFullPath;
+}
+
+/*****************************************************************************/
+SourceDirectory *SourceDirectory::GetRootDirectory()
+/*****************************************************************************/
+{
+ if ( !pParent )
+ return this;
+
+ return pParent->GetRootDirectory();
+}
+
+/*****************************************************************************/
+SourceDirectory *SourceDirectory::GetSubDirectory(
+ const ByteString &rDirectoryPath, USHORT nOperatingSystem )
+/*****************************************************************************/
+{
+ ByteString sSearch;
+
+ BOOL bSubs = TRUE;
+ ULONG nIndex = 0;
+
+ while ( bSubs && ByteString( LimitedPath[ nIndex ]) != "EndOf_LimitedPath" ) {
+ SourceDirectory *pActDir = this;
+ ByteString sLimitation( LimitedPath[ nIndex ]);
+
+ BOOL bBreak = FALSE;
+ for ( ULONG i = sLimitation.GetTokenCount( '\\' ); i > 0 && !bBreak; i-- ) {
+ if (( !pActDir ) || ( *pActDir != sLimitation.GetToken(( USHORT )( i - 1 ), '\\' )))
+ bBreak = TRUE;
+ else
+ pActDir = pActDir->pParent;
+ }
+ bSubs = bBreak;
+ nIndex++;
+ }
+
+ if ( !bSubs )
+ {
+ sSearch = rDirectoryPath;
+ }
+ else
+ sSearch = rDirectoryPath.GetToken( 0, PATH_SEPARATOR );
+
+ SourceDirectory *pSubDirectory = NULL;
+
+ if ( pSubDirectories )
+ pSubDirectory = pSubDirectories->Search( sSearch );
+
+ if ( !pSubDirectory )
+ pSubDirectory = new SourceDirectory(
+ sSearch, nOperatingSystem, this );
+
+ pSubDirectory->nOSType |= nOperatingSystem;
+
+ if ( sSearch.Len() == rDirectoryPath.Len())
+ return pSubDirectory;
+
+ ByteString sPath = rDirectoryPath.Copy( sSearch.Len() + 1 );
+
+ return pSubDirectory->GetSubDirectory( sPath, nOperatingSystem );
+}
+
+/*****************************************************************************/
+SourceDirectory *SourceDirectory::GetDirectory(
+ const ByteString &rDirectoryName, USHORT nOperatingSystem )
+/*****************************************************************************/
+{
+ ByteString sDirectoryName( rDirectoryName );
+#ifdef UNX
+ sDirectoryName.SearchAndReplaceAll( "\\", "/" );
+#endif
+
+ SourceDirectory *pRoot = GetRootDirectory();
+
+ if ( sDirectoryName.Search( *pRoot ) != 0 )
+ return NULL;
+
+ if ( sDirectoryName.Len() == pRoot->Len())
+ return pRoot;
+
+ if ( sDirectoryName.GetChar( pRoot->Len()) == PATH_SEPARATOR ) {
+ ByteString sSub = sDirectoryName.Copy( pRoot->Len() + 1 );
+ return pRoot->GetSubDirectory( sSub, nOperatingSystem );
+ }
+
+ return NULL;
+}
+
+/*****************************************************************************/
+SourceDirectory *SourceDirectory::Insert( const ByteString &rDirectoryName,
+ USHORT nOperatingSystem )
+/*****************************************************************************/
+{
+ SourceDirectory *pSubDirectory = NULL;
+ if ( pSubDirectories )
+ pSubDirectory = pSubDirectories->Search( rDirectoryName );
+
+ if ( !pSubDirectory )
+ pSubDirectory = new SourceDirectory(
+ rDirectoryName, nOperatingSystem, this );
+
+ return pSubDirectory;
+}
+
+/*****************************************************************************/
+Dependency *SourceDirectory::ResolvesDependency(
+ CodedDependency *pCodedDependency )
+/*****************************************************************************/
+{
+ if ( !pCodedIdentifier )
+ return NULL;
+
+ ULONG nPos = pCodedIdentifier->IsString( pCodedDependency );
+ if ( nPos != NOT_THERE ) {
+ CodedDependency *pIdentifier =
+ ( CodedDependency * ) pCodedIdentifier->GetObject( nPos );
+ USHORT nResult =
+ pIdentifier->GetOperatingSystem() &
+ pCodedDependency->GetOperatingSystem();
+ Dependency *pReturn = new Dependency( *this, nResult );
+ nResult ^= pCodedDependency->GetOperatingSystem();
+ pCodedDependency->SetOperatingSystem( nResult );
+ return pReturn;
+ }
+ return NULL;
+}
+
+
+/*****************************************************************************/
+void SourceDirectory::ResolveDependencies()
+/*****************************************************************************/
+{
+ if ( !pSubDirectories )
+ return;
+
+ for ( ULONG i = 0; i < pSubDirectories->Count(); i++ ) {
+ SourceDirectory *pActDirectory =
+ ( SourceDirectory * ) pSubDirectories->GetObject( i );
+ if ( pActDirectory->pSubDirectories )
+ pActDirectory->ResolveDependencies();
+
+ if ( pActDirectory->pCodedDependencies ) {
+ while ( pActDirectory->pCodedDependencies->Count())
+ {
+ CodedDependency *pCodedDependency = ( CodedDependency * )
+ pActDirectory->pCodedDependencies->GetObject(( ULONG ) 0 );
+
+ for (
+ ULONG k = 0;
+ ( k < pSubDirectories->Count()) &&
+ ( pCodedDependency->GetOperatingSystem() != OS_NONE );
+ k++
+ ) {
+ Dependency *pDependency =
+ ((SourceDirectory *) pSubDirectories->GetObject( k ))->
+ ResolvesDependency( pCodedDependency );
+ if ( pDependency )
+ {
+ if ( !pActDirectory->pDependencies )
+ pActDirectory->pDependencies = new SByteStringList();
+ pActDirectory->pDependencies->PutString( pDependency );
+ }
+ }
+ if ( pCodedDependency->GetOperatingSystem()) {
+ if ( !pCodedDependencies )
+ pCodedDependencies = new SByteStringList();
+ pCodedDependencies->PutString( pCodedDependency );
+ }
+ else
+ delete pCodedDependency;
+ pActDirectory->pCodedDependencies->Remove(( ULONG ) 0 );
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+ByteString SourceDirectory::GetTarget()
+/*****************************************************************************/
+{
+ ByteString sReturn;
+
+ if ( !pDependencies )
+ return sReturn;
+
+ ULONG k = 0;
+ while ( k < pDependencies->Count()) {
+ if ( *this == *pDependencies->GetObject( k ))
+ delete pDependencies->Remove( k );
+ else
+ k++;
+ }
+
+ if ( !pDependencies->Count()) {
+ delete pDependencies;
+ pDependencies = NULL;
+ return sReturn;
+ }
+
+ BOOL bDependsOnPlatform = FALSE;
+ for ( ULONG i = 0; i < pDependencies->Count(); i++ )
+ if ((( Dependency * ) pDependencies->GetObject( i ))->
+ GetOperatingSystem() != OS_ALL )
+ bDependsOnPlatform = TRUE;
+
+ ByteString sTarget( *this );
+ sTarget.SearchAndReplaceAll( "\\", "$/" );
+ if ( !bDependsOnPlatform ) {
+ sReturn = sTarget;
+ sReturn += " :";
+ for ( ULONG i = 0; i < pDependencies->Count(); i++ ) {
+ ByteString sDependency( *pDependencies->GetObject( i ));
+ sDependency.SearchAndReplaceAll( "\\", "$/" );
+ sReturn += " ";
+ sReturn += sDependency;
+ }
+ }
+ else {
+ ByteString sUNX( ".IF \"$(GUI)\" == \"UNX\"\n" );
+ sUNX += sTarget;
+ sUNX += " :";
+ BOOL bUNX = FALSE;
+
+ ByteString sWNT( ".IF \"$(GUI)\" == \"WNT\"\n" );
+ sWNT += sTarget;
+ sWNT += " :";
+ BOOL bWNT = FALSE;
+
+ ByteString sOS2( ".IF \"$(GUI)\" == \"OS2\"\n" );
+ sOS2 += sTarget;
+ sOS2 += " :";
+ BOOL bOS2 = FALSE;
+
+ for ( ULONG i = 0; i < pDependencies->Count(); i++ ) {
+ Dependency *pDependency =
+ ( Dependency * ) pDependencies->GetObject( i );
+ ByteString sDependency( *pDependency );
+ sDependency.SearchAndReplaceAll( "\\", "$/" );
+
+ if ( pDependency->GetOperatingSystem() & OS_UNX ) {
+ sUNX += " ";
+ sUNX += sDependency;
+ bUNX = TRUE;
+ }
+ if ( pDependency->GetOperatingSystem() & OS_WIN32 ) {
+ sWNT += " ";
+ sWNT += sDependency;
+ bWNT = TRUE;
+ }
+ if ( pDependency->GetOperatingSystem() & OS_OS2 ) {
+ sOS2 += " ";
+ sOS2 += sDependency;
+ bOS2 = TRUE;
+ }
+ }
+
+ if ( bUNX ) {
+ sReturn += sUNX;
+ sReturn += "\n.ENDIF\n";
+ }
+ if ( bWNT ) {
+ sReturn += sWNT;
+ sReturn += "\n.ENDIF\n";
+ }
+ if ( bOS2 ) {
+ sReturn += sOS2;
+ sReturn += "\n.ENDIF\n";
+ }
+ }
+ sReturn.EraseTrailingChars( '\n' );
+ return sReturn;
+}
+
+/*****************************************************************************/
+ByteString SourceDirectory::GetSubDirsTarget()
+/*****************************************************************************/
+{
+ ByteString sReturn;
+
+ if ( pSubDirectories ) {
+ BOOL bDependsOnPlatform = FALSE;
+ for ( ULONG i = 0; i < pSubDirectories->Count(); i++ )
+ if ((( SourceDirectory * ) pSubDirectories->GetObject( i ))->
+ GetOperatingSystems() != OS_ALL )
+ bDependsOnPlatform = TRUE;
+
+ if ( !bDependsOnPlatform ) {
+ sReturn = "RC_SUBDIRS = ";
+
+ for ( ULONG i = 0; i < pSubDirectories->Count(); i++ ) {
+ ByteString sSubDirectory( *pSubDirectories->GetObject( i ));
+ sSubDirectory.SearchAndReplaceAll( "\\", "$/" );
+ sReturn += " \\\n\t";
+ sReturn += sSubDirectory;
+ }
+ sReturn += "\n";
+ }
+ else {
+ ByteString sUNX( ".IF \"$(GUI)\" == \"UNX\"\n" );
+ sUNX += "RC_SUBDIRS = ";
+ BOOL bUNX = FALSE;
+
+ ByteString sWNT( ".IF \"$(GUI)\" == \"WNT\"\n" );
+ sWNT += "RC_SUBDIRS = ";
+ BOOL bWNT = FALSE;
+
+ ByteString sOS2( ".IF \"$(GUI)\" == \"OS2\"\n" );
+ sOS2 += "RC_SUBDIRS = ";
+ BOOL bOS2 = FALSE;
+
+ for ( ULONG i = 0; i < pSubDirectories->Count(); i++ ) {
+ SourceDirectory *pDirectory =
+ ( SourceDirectory * ) pSubDirectories->GetObject( i );
+ ByteString sDirectory( *pDirectory );
+ sDirectory.SearchAndReplaceAll( "\\", "$/" );
+
+ if ( pDirectory->GetOperatingSystems() & OS_UNX ) {
+ sUNX += " \\\n\t";
+ sUNX += sDirectory;
+ bUNX = TRUE;
+ }
+ if ( pDirectory->GetOperatingSystems() & OS_WIN32 ) {
+ sWNT += " \\\n\t";
+ sWNT += sDirectory;
+ bWNT = TRUE;
+ }
+ if ( pDirectory->GetOperatingSystems() & OS_OS2 ) {
+ sOS2 += " \\\n\t";
+ sOS2 += sDirectory;
+ bOS2 = TRUE;
+ }
+ }
+ if ( bUNX ) {
+ sReturn += sUNX;
+ sReturn += "\n.ENDIF\n";
+ }
+ if ( bWNT ) {
+ sReturn += sWNT;
+ sReturn += "\n.ENDIF\n";
+ }
+ if ( bOS2 ) {
+ sReturn += sOS2;
+ sReturn += "\n.ENDIF\n";
+ }
+ }
+ }
+ return sReturn;
+}
+
+/*****************************************************************************/
+USHORT SourceDirectory::GetOSType( const ByteString &sDependExt )
+/*****************************************************************************/
+{
+ USHORT nOSType = 0;
+ if ( sDependExt == "" )
+ nOSType |= OS_ALL;
+ else if ( sDependExt == "N" || sDependExt == "W" )
+ nOSType |= OS_WIN32;
+ else if ( sDependExt == "U" )
+ nOSType |= OS_UNX;
+ else if ( sDependExt == "P" )
+ nOSType |= OS_OS2;
+ return nOSType;
+}
+
+/*****************************************************************************/
+SourceDirectory *SourceDirectory::CreateRootDirectory(
+ const ByteString &rRoot, const ByteString &rVersion, BOOL bAll )
+/*****************************************************************************/
+{
+ IniManager aIniManager;
+ aIniManager.Update();
+
+ ByteString sDefLst( GetDefStandList());
+ ByteString sStandLst( aIniManager.ToLocal( sDefLst ));
+ String s = String( sStandLst, gsl_getSystemTextEncoding());
+ InformationParser aParser;
+// fprintf( stderr,
+// "Reading database %s ...\n", sStandLst.GetBuffer());
+ GenericInformationList *pVerList = aParser.Execute(
+ s );
+
+/*
+ ByteString sPath( rVersion );
+#ifndef UNX
+ sPath += ByteString( "/settings/solarlist" );
+#else
+ sPath += ByteString( "/settings/unxsolarlist" );
+#endif
+ ByteString sSolarList( _SOLARLIST );
+
+ GenericInformation *pInfo = pVerList->GetInfo( sPath, TRUE );
+ if ( pInfo ) {
+ ByteString aIniRoot( GetIniRoot() );
+ DirEntry aIniEntry( String( aIniRoot, RTL_TEXTENCODING_ASCII_US ));
+ aIniEntry += DirEntry( String( pInfo->GetValue(), RTL_TEXTENCODING_ASCII_US )).GetBase( PATH_SEPARATOR );
+ sSolarList = ByteString( aIniEntry.GetFull(), RTL_TEXTENCODING_ASCII_US );
+ }
+
+ sSolarList = aIniManager.ToLocal( sSolarList );
+ fprintf( stderr,
+ "Reading directory information %s ...\n", sSolarList.GetBuffer());
+*/
+
+ ByteString sVersion( rVersion );
+ Star aStar( pVerList, sVersion, TRUE, rRoot.GetBuffer());
+// fprintf( stderr,
+// "Creating virtual directory tree ...\n" );
+
+
+ SourceDirectory *pSourceRoot = new SourceDirectory( rRoot, OS_ALL );
+
+ for ( ULONG i = 0; i < aStar.Count(); i++ ) {
+ Prj *pPrj = aStar.GetObject( i );
+
+ BOOL bBuildable = TRUE;
+ ULONG nIndex = 0;
+
+ while ( bBuildable && ByteString( NoBuildProject[ nIndex ]) != "EndOf_NoBuildProject" ) {
+ bBuildable = ( ByteString( NoBuildProject[ nIndex ]) != pPrj->GetProjectName());
+ nIndex ++;
+ }
+
+ if ( bBuildable ) {
+ SourceDirectory *pProject = pSourceRoot->Insert( pPrj->GetProjectName(), OS_ALL );
+
+ SByteStringList *pPrjDependencies = pPrj->GetDependencies( FALSE );
+ if ( pPrjDependencies )
+ for ( ULONG x = 0; x < pPrjDependencies->Count(); x++ )
+ pProject->AddCodedDependency( *pPrjDependencies->GetObject( x ), OS_ALL );
+
+ pProject->AddCodedIdentifier( pPrj->GetProjectName(), OS_ALL );
+
+ for ( ULONG j = 0; j < pPrj->Count(); j++ ) {
+ CommandData *pData = pPrj->GetObject( j );
+ if ( bAll || ( pData->GetCommandType() == COMMAND_NMAKE )) {
+ ByteString sDirPath( rRoot );
+ sDirPath += ByteString( PATH_SEPARATOR );
+ sDirPath += pData->GetPath();
+ SourceDirectory *pDirectory =
+ pSourceRoot->InsertFull( sDirPath, pData->GetOSType());
+ SByteStringList *pDependencies = pData->GetDependencies();
+ if ( pDependencies ) {
+ for ( ULONG k = 0; k < pDependencies->Count(); k++ ) {
+ ByteString sDependency(*pDependencies->GetObject( k ));
+ ByteString sDependExt(sDependency.GetToken( 1, '.' ));
+ sDependExt.ToUpperAscii();
+ pDirectory->AddCodedDependency(
+ sDependency.GetToken( 0, '.' ), GetOSType( sDependExt ));
+ }
+ }
+ ByteString sIdentifier = pData->GetLogFile();
+ ByteString sIdExt = sIdentifier.GetToken( 1, '.' );
+ sIdExt.ToUpperAscii();
+ pDirectory->AddCodedIdentifier( sIdentifier.GetToken( 0, '.' ), GetOSType( sIdExt ));
+ }
+ }
+ }
+ }
+ delete pVerList;
+ return pSourceRoot;
+}
+
+/*****************************************************************************/
+BOOL SourceDirectory::RemoveDirectoryTreeAndAllDependencies()
+/*****************************************************************************/
+{
+ if ( !pParent )
+ return FALSE;
+
+ SourceDirectoryList *pParentContent = pParent->pSubDirectories;
+ ULONG i = 0;
+ while ( i < pParentContent->Count()) {
+ SourceDirectory *pCandidate =
+ ( SourceDirectory * )pParentContent->GetObject( i );
+ if ( pCandidate == this ) {
+ pParentContent->Remove( i );
+ }
+ else {
+ if ( pCandidate->pDependencies ) {
+ ULONG nPos = pCandidate->pDependencies->IsString( this );
+ if ( nPos != NOT_THERE )
+ delete pCandidate->pDependencies->Remove( nPos );
+ }
+ i++;
+ }
+ }
+ delete this;
+ return TRUE;
+}
+
+/*****************************************************************************/
+BOOL SourceDirectory::CreateRecursiveMakefile( BOOL bAllChilds )
+/*****************************************************************************/
+{
+ if ( !pSubDirectories )
+ return TRUE;
+
+ fprintf( stdout, "%s", GetFullPath().GetBuffer());
+
+ String aTmpStr( GetFullPath(), gsl_getSystemTextEncoding());
+ DirEntry aEntry( aTmpStr );
+ if ( !aEntry.Exists()) {
+ fprintf( stdout, " ... no directory!n" );
+ return FALSE;
+ }
+
+ ULONG j = 0;
+ while( j < pSubDirectories->Count()) {
+ String sSubDirectory(
+ (( SourceDirectory * ) pSubDirectories->GetObject( j ))->
+ GetFullPath(),
+ gsl_getSystemTextEncoding()
+ );
+ DirEntry aSubDirectory( sSubDirectory );
+ if ( !aSubDirectory.Exists())
+ (( SourceDirectory * ) pSubDirectories->GetObject( j ))->
+ RemoveDirectoryTreeAndAllDependencies();
+ else
+ j++;
+ }
+
+ DirEntry aRCFile( String( "makefile.rc", gsl_getSystemTextEncoding()));
+ DirEntry aRCEntry( aEntry );
+ aRCEntry += aRCFile;
+
+ DirEntry aMKFile( String( "makefile.mk", gsl_getSystemTextEncoding()));
+ DirEntry aMKEntry( aEntry );
+ aMKEntry += aMKFile;
+
+ BOOL bMakefileMk = FALSE;
+ if ( aMKEntry.Exists()) {
+ if ( nDepth == 1 && *this == ByteString( "api" ))
+ fprintf( stdout, " ... makefile.mk exists, ignoring (hack: prj == api)!" );
+ else {
+ fprintf( stdout, " ... makefile.mk exists, including!" );
+ bMakefileMk = TRUE;
+ }
+ }
+
+ SvFileStream aMakefile( aRCEntry.GetFull(), STREAM_STD_WRITE | STREAM_TRUNC );
+ if ( !aMakefile.IsOpen()) {
+ fprintf( stdout, " ... failed!\n" );
+ return FALSE;
+ }
+
+ ByteString sHeader(
+ "#*************************************************************************\n"
+ "#\n"
+ "# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n"
+ "#\n"
+ "# Copyright 2000, 2010 Oracle and/or its affiliates.\n"
+ "#\n"
+ "# OpenOffice.org - a multi-platform office productivity suite\n"
+ "#\n"
+ "# This file is part of OpenOffice.org.\n"
+ "#\n"
+ "# OpenOffice.org is free software: you can redistribute it and/or modify\n"
+ "# it under the terms of the GNU Lesser General Public License version 3\n"
+ "# only, as published by the Free Software Foundation.\n"
+ "#\n"
+ "# OpenOffice.org is distributed in the hope that it will be useful,\n"
+ "# but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "# GNU Lesser General Public License version 3 for more details\n"
+ "# (a copy is included in the LICENSE file that accompanied this code).\n"
+ "#\n"
+ "# You should have received a copy of the GNU Lesser General Public License\n"
+ "# version 3 along with OpenOffice.org. If not, see\n"
+ "# <http://www.openoffice.org/license.html>\n"
+ "# for a copy of the LGPLv3 License.\n"
+ "#\n"
+ "#*************************************************************************\n"
+ "\n"
+ );
+ if ( !bMakefileMk ) {
+ if ( nDepth == 0 ) {
+ sHeader += ByteString(
+ "\n"
+ "# \n"
+ "# mark this makefile as a recursive one\n"
+ "# \n"
+ "\n"
+ "MAKEFILERC=yes\n"
+ "\n"
+ "# \n"
+ "# implementation of cvs checkout\n"
+ "# \n"
+ "\n"
+ ".IF \"$(checkout)\"==\"\"\n"
+ "all_target: ALLTAR\n"
+ ".ELSE\t# \"$(checkout)\"==\"\"\n"
+ ".IF \"$(checkout)\"==\"true\"\n"
+ "% : $(NULL)\n"
+ "\t_cvs co $@\n"
+ ".ELSE\t# \"$(checkout)\"==\"true\"\n"
+ "% : $(NULL)\n"
+ "\t_cvs co -r$(checkout) $@\n"
+ ".ENDIF\t# \"$(checkout)\"==\"true\"\n"
+ "all_subdirs : $(RC_SUBDIRS)\n"
+ ".ENDIF\t# \"$(checkout)\"==\"\"\n"
+ );
+ }
+ else {
+ sHeader += ByteString(
+ "\n"
+ "# \n"
+ "# mark this makefile as a recursive one\n"
+ "# \n"
+ "\n"
+ "MAKEFILERC=yes\n"
+ );
+ if ( nDepth == 1 )
+ sHeader += ByteString(
+ ".IF \"$(build_deliver)\"==\"true\"\n"
+ "all_target:\t\t\\\n"
+ "\tTG_DELIVER\t\\\n"
+ "\tALLTAR\n"
+ ".ELSE # \"$(build_deliver)\"==\"true\"\n"
+ "all_target: ALLTAR\n"
+ ".ENDIF # \"$(build_deliver)\"==\"true\"\n"
+ );
+ else
+ sHeader += ByteString(
+ "all_target: ALLTAR\n"
+ );
+ }
+ }
+ else {
+ if ( nDepth == 1 )
+ sHeader += ByteString(
+ ".IF \"$(build_deliver)\"==\"true\"\n"
+ "all_target:\t\t\\\n"
+ "\tTG_DELIVER\t\\\n"
+ "\tALLTAR\n"
+ ".ELSE # \"$(build_deliver)\"==\"true\"\n"
+ "all_target: ALLTAR\n"
+ ".ENDIF # \"$(build_deliver)\"==\"true\"\n"
+ );
+ }
+ sHeader += ByteString(
+ "\n"
+ "# \n"
+ "# macro RC_SUBDIRS handles iteration over\n"
+ "# all mandatory sub directories\n"
+ "# \n"
+ );
+
+ aMakefile.WriteLine( sHeader );
+ aMakefile.WriteLine( GetSubDirsTarget());
+
+ if ( nDepth == 0 ) {
+ ByteString sBootstrapTarget(
+ "# \n"
+ "# bootstrap target\n"
+ "# \n\n"
+ "bootstrap .PHONY :\n"
+ "\t@config_office/bootstrap\n\n"
+ );
+ aMakefile.WriteLine( sBootstrapTarget );
+ ByteString sConfigureTarget(
+ "# \n"
+ "# configure target\n"
+ "# \n\n"
+ "configure .PHONY SETDIR=config_office :\n"
+ "\t@configure\n"
+ );
+ aMakefile.WriteLine( sConfigureTarget );
+ }
+ else if ( nDepth == 1 ) {
+ ByteString sDeliverTarget(
+ "# \n"
+ "# deliver target to handle\n"
+ "# project dependencies\n"
+ "# \n\n"
+ "TG_DELIVER : $(RC_SUBDIRS)\n"
+ "\t$(DELIVER)\n"
+ );
+ aMakefile.WriteLine( sDeliverTarget );
+ }
+
+ if ( bMakefileMk ) {
+ ByteString sInclude(
+ "# \n"
+ "# local makefile\n"
+ "# \n"
+ "\n"
+ ".INCLUDE : makefile.mk\n"
+ );
+
+ if ( nDepth != 1 )
+ sInclude += ByteString(
+ "\n"
+ "all_rc_target: ALLTAR\n"
+ );
+
+ aMakefile.WriteLine( sInclude );
+ }
+
+ ByteString sComment(
+ "# \n"
+ "# single directory targets for\n"
+ "# dependency handling between directories\n"
+ "# \n"
+ );
+ aMakefile.WriteLine( sComment );
+
+ for ( ULONG i = 0; i < pSubDirectories->Count(); i++ ) {
+ ByteString sTarget(
+ (( SourceDirectory * )pSubDirectories->GetObject( i ))->
+ GetTarget()
+ );
+ if ( sTarget.Len())
+ aMakefile.WriteLine( sTarget );
+ }
+
+ ByteString sFooter(
+ "\n"
+ );
+ if ( !bMakefileMk ) {
+ sFooter += ByteString(
+ "# \n"
+ "# central target makefile\n"
+ "# \n"
+ "\n"
+ );
+ if ( nDepth != 0 ) {
+ sFooter += ByteString(
+ ".INCLUDE : target.mk\n"
+ );
+ }
+ else {
+ sFooter += ByteString(
+ ".IF \"$(checkout)\"==\"\"\n"
+ ".INCLUDE : target.mk\n"
+ ".ENDIF\t#\"$(checkout)\"==\"\"\n"
+ );
+ }
+ }
+ sFooter += ByteString(
+ "\n"
+ "#*************************************************************************\n"
+ );
+ aMakefile.WriteLine( sFooter );
+
+ aMakefile.Close();
+
+ fprintf( stdout, "\n" );
+
+ BOOL bSuccess = TRUE;
+ if ( bAllChilds )
+ for ( ULONG k = 0; k < pSubDirectories->Count(); k++ )
+ if ( !(( SourceDirectory * ) pSubDirectories->GetObject( k ))->
+ CreateRecursiveMakefile( TRUE ))
+ bSuccess = FALSE;
+
+ return bSuccess;
+}
+
+//
+// class SourceDirectoryList
+//
+
+/*****************************************************************************/
+SourceDirectoryList::~SourceDirectoryList()
+/*****************************************************************************/
+{
+ for ( ULONG i = 0; i < Count(); i++ )
+ delete GetObject( i );
+}
+
+/*****************************************************************************/
+SourceDirectory *SourceDirectoryList::Search(
+ const ByteString &rDirectoryName )
+/*****************************************************************************/
+{
+ ULONG nPos = IsString( ( ByteString * ) (&rDirectoryName) );
+ if ( nPos != LIST_ENTRY_NOTFOUND )
+ return ( SourceDirectory * ) GetObject( nPos );
+
+ return NULL;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/bootstrp/prj.cxx b/tools/bootstrp/prj.cxx
new file mode 100644
index 000000000000..5f232cd4c197
--- /dev/null
+++ b/tools/bootstrp/prj.cxx
@@ -0,0 +1,1602 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <stdlib.h>
+#include <stdio.h>
+#include "bootstrp/sstring.hxx"
+#include <osl/mutex.hxx>
+
+#include <tools/stream.hxx>
+#include <tools/geninfo.hxx>
+#include "bootstrp/prj.hxx"
+#include "bootstrp/inimgr.hxx"
+
+//#define TEST 1
+
+#if defined(WNT) || defined(OS2)
+#define LIST_DELIMETER ';'
+#define PATH_DELIMETER '\\'
+#elif defined UNX
+#define LIST_DELIMETER ':'
+#define PATH_DELIMETER '/'
+#endif
+
+Link Star::aDBNotFoundHdl;
+
+//
+// class SimpleConfig
+//
+
+/*****************************************************************************/
+SimpleConfig::SimpleConfig( String aSimpleConfigFileName )
+/*****************************************************************************/
+{
+ nLine = 0;
+ aFileName = aSimpleConfigFileName;
+ aFileStream.Open ( aFileName, STREAM_READ );
+}
+
+/*****************************************************************************/
+SimpleConfig::SimpleConfig( DirEntry& rDirEntry )
+/*****************************************************************************/
+{
+ nLine = 0;
+ aFileName = rDirEntry.GetFull();
+ aFileStream.Open ( aFileName, STREAM_READ );
+}
+
+/*****************************************************************************/
+SimpleConfig::~SimpleConfig()
+/*****************************************************************************/
+{
+ aFileStream.Close ();
+}
+
+/*****************************************************************************/
+ByteString SimpleConfig::GetNext()
+/*****************************************************************************/
+{
+ ByteString aString;
+
+ if ( aStringBuffer =="" )
+ while ((aStringBuffer = GetNextLine()) == "\t") ; //solange bis != "\t"
+ if ( aStringBuffer =="" )
+ return ByteString();
+
+ aString = aStringBuffer.GetToken(0,'\t');
+ aStringBuffer.Erase(0, aString.Len()+1);
+
+ aStringBuffer.EraseLeadingChars( '\t' );
+
+ return aString;
+}
+
+/*****************************************************************************/
+ByteString SimpleConfig::GetNextLine()
+/*****************************************************************************/
+{
+ ByteString aSecStr;
+ nLine++;
+
+ aFileStream.ReadLine ( aTmpStr );
+ if ( aTmpStr.Search( "#" ) == 0 )
+ return "\t";
+ aTmpStr = aTmpStr.EraseLeadingChars();
+ aTmpStr = aTmpStr.EraseTrailingChars();
+ while ( aTmpStr.SearchAndReplace(ByteString(' '),ByteString('\t') ) != STRING_NOTFOUND ) ;
+ int nLength = aTmpStr.Len();
+ BOOL bFound = FALSE;
+ ByteString aEraseString;
+ for ( USHORT i = 0; i<= nLength; i++)
+ {
+ if ( aTmpStr.GetChar( i ) == 0x20 && !bFound )
+ aTmpStr.SetChar( i, 0x09 );
+ }
+ return aTmpStr;
+}
+
+/*****************************************************************************/
+ByteString SimpleConfig::GetCleanedNextLine( BOOL bReadComments )
+/*****************************************************************************/
+{
+
+ aFileStream.ReadLine ( aTmpStr );
+ if ( aTmpStr.Search( "#" ) == 0 )
+ {
+ if (bReadComments )
+ return aTmpStr;
+ else
+ while ( aTmpStr.Search( "#" ) == 0 )
+ {
+ aFileStream.ReadLine ( aTmpStr );
+ }
+ }
+
+ aTmpStr = aTmpStr.EraseLeadingChars();
+ aTmpStr = aTmpStr.EraseTrailingChars();
+// while ( aTmpStr.SearchAndReplace(String(' '),String('\t') ) != (USHORT)-1 );
+ int nLength = aTmpStr.Len();
+ ByteString aEraseString;
+ BOOL bFirstTab = TRUE;
+ for ( USHORT i = 0; i<= nLength; i++)
+ {
+ if ( aTmpStr.GetChar( i ) == 0x20 )
+ aTmpStr.SetChar( i, 0x09 );
+
+ if ( aTmpStr.GetChar( i ) == 0x09 )
+ {
+ if ( bFirstTab )
+ bFirstTab = FALSE;
+ else
+ {
+ aTmpStr.SetChar( i, 0x20 );
+ }
+ }
+ else
+ bFirstTab = TRUE;
+
+ }
+ aTmpStr.EraseAllChars(' ');
+ return aTmpStr;
+
+}
+
+
+//
+// class CommandData
+//
+
+/*****************************************************************************/
+CommandData::CommandData()
+/*****************************************************************************/
+{
+ nOSType = 0;
+ nCommand = 0;
+ pDepList = 0;
+}
+
+/*****************************************************************************/
+CommandData::~CommandData()
+/*****************************************************************************/
+{
+ if ( pDepList )
+ {
+ ByteString *pString = pDepList->First();
+ while ( pString )
+ {
+ delete pString;
+ pString = pDepList->Next();
+ }
+ delete pDepList;
+
+ pDepList = NULL;
+ }
+}
+
+/*****************************************************************************/
+ByteString CommandData::GetOSTypeString()
+/*****************************************************************************/
+{
+ ByteString aRetStr;
+
+ switch (nOSType)
+ {
+ case OS_WIN16 | OS_WIN32 | OS_OS2 | OS_UNX :
+ aRetStr = "all";
+ break;
+ case OS_WIN32 | OS_WIN16 :
+ aRetStr = "w";
+ break;
+ case OS_OS2 :
+ aRetStr = "p";
+ break;
+ case OS_UNX :
+ aRetStr = "u";
+ break;
+ case OS_WIN16 :
+ aRetStr = "d";
+ break;
+ case OS_WIN32 :
+ aRetStr = "n";
+ break;
+ default :
+ aRetStr = "none";
+ }
+
+ return aRetStr;
+}
+
+/*****************************************************************************/
+ByteString CommandData::GetCommandTypeString()
+/*****************************************************************************/
+{
+ ByteString aRetStr;
+
+ switch (nCommand)
+ {
+ case COMMAND_NMAKE :
+ aRetStr = "nmake";
+ break;
+ case COMMAND_GET :
+ aRetStr = "get";
+ break;
+ default :
+ aRetStr = "usr";
+ aRetStr += ByteString::CreateFromInt64( nCommand + 1 - COMMAND_USER_START );
+
+ }
+
+ return aRetStr;
+}
+
+/*****************************************************************************/
+CommandData* Prj::GetDirectoryList ( USHORT, USHORT )
+/*****************************************************************************/
+{
+ return (CommandData *)NULL;
+}
+
+/*****************************************************************************/
+CommandData* Prj::GetDirectoryData( ByteString aLogFileName )
+/*****************************************************************************/
+{
+ CommandData *pData = NULL;
+ ULONG nObjCount = Count();
+ for ( ULONG i=0; i<nObjCount; i++ )
+ {
+ pData = GetObject(i);
+ if ( pData->GetLogFile() == aLogFileName )
+ return pData;
+ }
+ return NULL;
+}
+
+//
+// class Prj
+//
+
+/*****************************************************************************/
+Prj::Prj() :
+ bVisited( FALSE ),
+ pPrjInitialDepList(0),
+ pPrjDepList(0),
+ bHardDependencies( FALSE ),
+ bSorted( FALSE )
+/*****************************************************************************/
+{
+}
+
+/*****************************************************************************/
+Prj::Prj( ByteString aName ) :
+ bVisited( FALSE ),
+ aProjectName( aName ),
+ pPrjInitialDepList(0),
+ pPrjDepList(0),
+ bHardDependencies( FALSE ),
+ bSorted( FALSE )
+/*****************************************************************************/
+{
+}
+
+/*****************************************************************************/
+Prj::~Prj()
+/*****************************************************************************/
+{
+ if ( pPrjDepList )
+ {
+ ByteString *pString = pPrjDepList->First();
+ while ( pString )
+ {
+ delete pString;
+ pString = pPrjDepList->Next();
+ }
+ delete pPrjDepList;
+
+ pPrjDepList = NULL;
+ }
+
+ if ( pPrjInitialDepList )
+ {
+ ByteString *pString = pPrjInitialDepList->First();
+ while ( pString )
+ {
+ delete pString;
+ pString = pPrjInitialDepList->Next();
+ }
+ delete pPrjInitialDepList;
+
+ pPrjInitialDepList = NULL;
+ }
+}
+
+/*****************************************************************************/
+void Prj::AddDependencies( ByteString aStr )
+/*****************************************************************************/
+{
+
+ // needs dirty flag - not expanded
+ if ( !pPrjDepList )
+ pPrjDepList = new SByteStringList;
+
+ pPrjDepList->PutString( new ByteString(aStr) );
+
+ if ( !pPrjInitialDepList )
+ pPrjInitialDepList = new SByteStringList;
+
+ pPrjInitialDepList->PutString( new ByteString(aStr) );
+}
+
+/*****************************************************************************/
+SByteStringList* Prj::GetDependencies( BOOL bExpanded )
+/*****************************************************************************/
+{
+ if ( bExpanded )
+ return pPrjDepList;
+ else
+ return pPrjInitialDepList;
+}
+
+
+
+/*****************************************************************************/
+BOOL Prj::InsertDirectory ( ByteString aDirName, USHORT aWhat,
+ USHORT aWhatOS, ByteString aLogFileName,
+ const ByteString &rClientRestriction )
+/*****************************************************************************/
+{
+ CommandData* pData = new CommandData();
+
+ pData->SetPath( aDirName );
+ pData->SetCommandType( aWhat );
+ pData->SetOSType( aWhatOS );
+ pData->SetLogFile( aLogFileName );
+ pData->SetClientRestriction( rClientRestriction );
+
+ Insert( pData );
+
+ return FALSE;
+}
+
+/*****************************************************************************/
+//
+// removes directory and existing dependencies on it
+//
+CommandData* Prj::RemoveDirectory ( ByteString aLogFileName )
+/*****************************************************************************/
+{
+ ULONG nCountMember = Count();
+ CommandData* pData;
+ CommandData* pDataFound = NULL;
+ SByteStringList* pDataDeps;
+
+ for ( USHORT i = 0; i < nCountMember; i++ )
+ {
+ pData = GetObject( i );
+ if ( pData->GetLogFile() == aLogFileName )
+ pDataFound = pData;
+ else
+ {
+ pDataDeps = pData->GetDependencies();
+ if ( pDataDeps )
+ {
+ ByteString* pString;
+ ULONG nDataDepsCount = pDataDeps->Count();
+ for ( ULONG j = nDataDepsCount; j > 0; j-- )
+ {
+ pString = pDataDeps->GetObject( j - 1 );
+ if ( pString->GetToken( 0, '.') == aLogFileName )
+ pDataDeps->Remove( pString );
+ }
+ }
+ }
+ }
+
+ Remove( pDataFound );
+
+ return pDataFound;
+}
+
+//
+// class Star
+//
+
+/*****************************************************************************/
+Star::Star()
+/*****************************************************************************/
+{
+ // this ctor is only used by StarWriter
+}
+
+/*****************************************************************************/
+Star::Star(String aFileName, USHORT nMode )
+/*****************************************************************************/
+ : nStarMode( nMode )
+{
+ Read( aFileName );
+}
+
+/*****************************************************************************/
+Star::Star( SolarFileList *pSolarFiles )
+/*****************************************************************************/
+ : nStarMode( STAR_MODE_MULTIPLE_PARSE )
+{
+ // this ctor is used by StarBuilder to get the information for the whole workspace
+ Read( pSolarFiles );
+}
+
+/*****************************************************************************/
+Star::Star( GenericInformationList *pStandLst, ByteString &rVersion,
+ BOOL bLocal, const char *pSourceRoot )
+/*****************************************************************************/
+{
+ ByteString sPath( rVersion );
+ String sSrcRoot;
+ if ( pSourceRoot )
+ sSrcRoot = String::CreateFromAscii( pSourceRoot );
+
+#ifdef UNX
+ sPath += "/settings/UNXSOLARLIST";
+#else
+ sPath += "/settings/SOLARLIST";
+#endif
+ GenericInformation *pInfo = pStandLst->GetInfo( sPath, TRUE );
+
+ if( pInfo && pInfo->GetValue().Len()) {
+ ByteString sFile( pInfo->GetValue());
+ if ( bLocal ) {
+ IniManager aIniManager;
+ aIniManager.ToLocal( sFile );
+ }
+ String sFileName( sFile, RTL_TEXTENCODING_ASCII_US );
+ nStarMode = STAR_MODE_SINGLE_PARSE;
+ Read( sFileName );
+ }
+ else {
+ SolarFileList *pFileList = new SolarFileList();
+
+ sPath = rVersion;
+ sPath += "/drives";
+
+ GenericInformation *pInfo2 = pStandLst->GetInfo( sPath, TRUE );
+ if ( pInfo2 && pInfo2->GetSubList()) {
+ GenericInformationList *pDrives = pInfo2->GetSubList();
+ for ( ULONG i = 0; i < pDrives->Count(); i++ ) {
+ GenericInformation *pDrive = pDrives->GetObject( i );
+ if ( pDrive ) {
+ DirEntry aEntry;
+ BOOL bOk = FALSE;
+ if ( sSrcRoot.Len()) {
+ aEntry = DirEntry( sSrcRoot );
+ bOk = TRUE;
+ }
+ else {
+#ifdef UNX
+ sPath = "UnixVolume";
+ GenericInformation *pUnixVolume = pDrive->GetSubInfo( sPath );
+ if ( pUnixVolume ) {
+ String sRoot( pUnixVolume->GetValue(), RTL_TEXTENCODING_ASCII_US );
+ aEntry = DirEntry( sRoot );
+ bOk = TRUE;
+ }
+#else
+ bOk = TRUE;
+ String sRoot( *pDrive, RTL_TEXTENCODING_ASCII_US );
+ sRoot += String::CreateFromAscii( "\\" );
+ aEntry = DirEntry( sRoot );
+#endif
+ }
+ if ( bOk ) {
+ sPath = "projects";
+ GenericInformation *pProjectsKey = pDrive->GetSubInfo( sPath, TRUE );
+ if ( pProjectsKey ) {
+ if ( !sSrcRoot.Len()) {
+ sPath = rVersion;
+ sPath += "/settings/PATH";
+ GenericInformation *pPath = pStandLst->GetInfo( sPath, TRUE );
+ if( pPath ) {
+ ByteString sAddPath( pPath->GetValue());
+#ifdef UNX
+ sAddPath.SearchAndReplaceAll( "\\", "/" );
+#else
+ sAddPath.SearchAndReplaceAll( "/", "\\" );
+#endif
+ String ssAddPath( sAddPath, RTL_TEXTENCODING_ASCII_US );
+ aEntry += DirEntry( ssAddPath );
+ }
+ }
+ GenericInformationList *pProjects = pProjectsKey->GetSubList();
+ if ( pProjects ) {
+ String sPrjDir( String::CreateFromAscii( "prj" ));
+ String sSolarFile( String::CreateFromAscii( "build.lst" ));
+
+ for ( ULONG j = 0; j < pProjects->Count(); j++ ) {
+ ByteString sProject( *pProjects->GetObject( j ));
+ String ssProject( sProject, RTL_TEXTENCODING_ASCII_US );
+
+ DirEntry aPrjEntry( aEntry );
+
+ aPrjEntry += DirEntry( ssProject );
+ aPrjEntry += DirEntry( sPrjDir );
+ aPrjEntry += DirEntry( sSolarFile );
+
+ pFileList->Insert( new String( aPrjEntry.GetFull()), LIST_APPEND );
+
+ ByteString sFile( aPrjEntry.GetFull(), RTL_TEXTENCODING_ASCII_US );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ Read( pFileList );
+ }
+}
+
+/*****************************************************************************/
+Star::~Star()
+/*****************************************************************************/
+{
+}
+
+/*****************************************************************************/
+BOOL Star::NeedsUpdate()
+/*****************************************************************************/
+{
+ aMutex.acquire();
+ for ( ULONG i = 0; i < aLoadedFilesList.Count(); i++ )
+ if ( aLoadedFilesList.GetObject( i )->NeedsUpdate()) {
+ aMutex.release();
+ return TRUE;
+ }
+
+ aMutex.release();
+ return FALSE;
+}
+
+/*****************************************************************************/
+void Star::Read( String &rFileName )
+/*****************************************************************************/
+{
+ ByteString aString;
+ aFileList.Insert( new String( rFileName ));
+
+ DirEntry aEntry( rFileName );
+ aEntry.ToAbs();
+ aEntry = aEntry.GetPath().GetPath().GetPath();
+ sSourceRoot = aEntry.GetFull();
+
+ while( aFileList.Count()) {
+ StarFile *pFile = new StarFile( *aFileList.GetObject(( ULONG ) 0 ));
+ if ( pFile->Exists()) {
+ SimpleConfig aSolarConfig( *aFileList.GetObject(( ULONG ) 0 ));
+ while (( aString = aSolarConfig.GetNext()) != "" )
+ InsertToken (( char * ) aString.GetBuffer());
+ }
+ aMutex.acquire();
+ aLoadedFilesList.Insert( pFile, LIST_APPEND );
+ aMutex.release();
+ aFileList.Remove(( ULONG ) 0 );
+ }
+ // resolve all dependencies recursive
+ Expand_Impl();
+}
+
+/*****************************************************************************/
+void Star::Read( SolarFileList *pSolarFiles )
+/*****************************************************************************/
+{
+ while( pSolarFiles->Count()) {
+ ByteString aString;
+
+ StarFile *pFile = new StarFile( *pSolarFiles->GetObject(( ULONG ) 0 ));
+ if ( pFile->Exists()) {
+ SimpleConfig aSolarConfig( *pSolarFiles->GetObject(( ULONG ) 0 ));
+ while (( aString = aSolarConfig.GetNext()) != "" )
+ InsertToken (( char * ) aString.GetBuffer());
+ }
+
+ aMutex.acquire();
+ aLoadedFilesList.Insert( pFile, LIST_APPEND );
+ aMutex.release();
+ delete pSolarFiles->Remove(( ULONG ) 0 );
+ }
+ delete pSolarFiles;
+
+ Expand_Impl();
+}
+
+/*****************************************************************************/
+String Star::CreateFileName( String sProject )
+/*****************************************************************************/
+{
+ // this method is used to find solarlist parts of nabours (other projects)
+ String sPrjDir( String::CreateFromAscii( "prj" ));
+ String sSolarFile( String::CreateFromAscii( "build.lst" ));
+
+ DirEntry aEntry( sSourceRoot );
+ aEntry += DirEntry( sProject );
+ aEntry += DirEntry( sPrjDir );
+ aEntry += DirEntry( sSolarFile );
+
+ if ( !aEntry.Exists() && aDBNotFoundHdl.IsSet())
+ aDBNotFoundHdl.Call( &sProject );
+
+ return aEntry.GetFull();
+}
+
+/*****************************************************************************/
+void Star::InsertSolarList( String sProject )
+/*****************************************************************************/
+{
+ // inserts a new solarlist part of another project
+ String sFileName( CreateFileName( sProject ));
+
+ for ( ULONG i = 0; i < aFileList.Count(); i++ ) {
+ if (( *aFileList.GetObject( i )) == sFileName )
+ return;
+ }
+
+ ByteString ssProject( sProject, RTL_TEXTENCODING_ASCII_US );
+ if ( HasProject( ssProject ))
+ return;
+
+ aFileList.Insert( new String( sFileName ), LIST_APPEND );
+}
+
+/*****************************************************************************/
+void Star::ExpandPrj_Impl( Prj *pPrj, Prj *pDepPrj )
+/*****************************************************************************/
+{
+ if ( pDepPrj->bVisited )
+ return;
+
+ pDepPrj->bVisited = TRUE;
+
+ SByteStringList* pPrjLst = pPrj->GetDependencies();
+ SByteStringList* pDepLst = NULL;
+ ByteString* pDepend;
+ ByteString* pPutStr;
+ Prj *pNextPrj = NULL;
+ ULONG i, nRetPos;
+
+ if ( pPrjLst ) {
+ pDepLst = pDepPrj->GetDependencies();
+ if ( pDepLst ) {
+ for ( i = 0; i < pDepLst->Count(); i++ ) {
+ pDepend = pDepLst->GetObject( i );
+ pPutStr = new ByteString( *pDepend );
+ nRetPos = pPrjLst->PutString( pPutStr );
+ if( nRetPos == NOT_THERE )
+ delete pPutStr;
+ pNextPrj = GetPrj( *pDepend );
+ if ( pNextPrj ) {
+ ExpandPrj_Impl( pPrj, pNextPrj );
+ }
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+void Star::Expand_Impl()
+/*****************************************************************************/
+{
+ for ( ULONG i = 0; i < Count(); i++ ) {
+ for ( ULONG j = 0; j < Count(); j++ )
+ GetObject( j )->bVisited = FALSE;
+
+ Prj* pPrj = GetObject( i );
+ ExpandPrj_Impl( pPrj, pPrj );
+ }
+}
+
+/*****************************************************************************/
+void Star::InsertToken ( char *yytext )
+/*****************************************************************************/
+{
+ static int i = 0;
+ static ByteString aDirName, aWhat, aWhatOS,
+ sClientRestriction, aLogFileName, aProjectName, aPrefix, aCommandPara;
+ static BOOL bPrjDep = FALSE;
+ static BOOL bHardDep = FALSE;
+ static USHORT nCommandType, nOSType;
+ CommandData* pCmdData;
+ static SByteStringList *pStaticDepList;
+ Prj* pPrj;
+
+ switch (i)
+ {
+ case 0:
+ aPrefix = yytext;
+ pStaticDepList = 0;
+ break;
+ case 1:
+ aDirName = yytext;
+ break;
+ case 2:
+ if ( !strcmp( yytext, ":" ))
+ {
+ bPrjDep = TRUE;
+ bHardDep = FALSE;
+ i = 9;
+ }
+ else if ( !strcmp( yytext, "::" ))
+ {
+ bPrjDep = TRUE;
+ bHardDep = TRUE;
+ i = 9;
+ }
+ else
+ {
+ bPrjDep = FALSE;
+ bHardDep = FALSE;
+
+ aWhat = yytext;
+ if ( aWhat == "nmake" )
+ nCommandType = COMMAND_NMAKE;
+ else if ( aWhat == "get" )
+ nCommandType = COMMAND_GET;
+ else {
+ ULONG nOffset = aWhat.Copy( 3 ).ToInt32();
+ nCommandType = sal::static_int_cast< USHORT >(
+ COMMAND_USER_START + nOffset - 1);
+ }
+ }
+ break;
+ case 3:
+ if ( !bPrjDep )
+ {
+ aWhat = yytext;
+ if ( aWhat == "-" )
+ {
+ aCommandPara = ByteString();
+ }
+ else
+ aCommandPara = aWhat;
+ }
+ break;
+ case 4:
+ if ( !bPrjDep )
+ {
+ aWhatOS = yytext;
+ if ( aWhatOS.GetTokenCount( ',' ) > 1 ) {
+ sClientRestriction = aWhatOS.Copy( aWhatOS.GetToken( 0, ',' ).Len() + 1 );
+ aWhatOS = aWhatOS.GetToken( 0, ',' );
+ }
+ if ( aWhatOS == "all" )
+ nOSType = ( OS_WIN16 | OS_WIN32 | OS_OS2 | OS_UNX );
+ else if ( aWhatOS == "w" )
+ nOSType = ( OS_WIN16 | OS_WIN32 );
+ else if ( aWhatOS == "p" )
+ nOSType = OS_OS2;
+ else if ( aWhatOS == "u" )
+ nOSType = OS_UNX;
+ else if ( aWhatOS == "d" )
+ nOSType = OS_WIN16;
+ else if ( aWhatOS == "n" )
+ nOSType = OS_WIN32;
+ else
+ nOSType = OS_NONE;
+ }
+ break;
+ case 5:
+ if ( !bPrjDep )
+ {
+ aLogFileName = yytext;
+ }
+ break;
+ default:
+ if ( !bPrjDep )
+ {
+ ByteString aItem = yytext;
+ if ( aItem == "NULL" )
+ {
+ // Liste zu Ende
+ i = -1;
+ }
+ else
+ {
+ // ggfs. Dependency liste anlegen und ergaenzen
+ if ( !pStaticDepList )
+ pStaticDepList = new SByteStringList;
+ pStaticDepList->PutString( new ByteString( aItem ));
+ }
+ }
+ else
+ {
+ ByteString aItem = yytext;
+ if ( aItem == "NULL" )
+ {
+ // Liste zu Ende
+ i = -1;
+ bPrjDep= FALSE;
+ }
+ else
+ {
+ aProjectName = aDirName.GetToken ( 0, '\\');
+ if ( HasProject( aProjectName ))
+ {
+ pPrj = GetPrj( aProjectName );
+ // Projekt exist. schon, neue Eintraege anhaengen
+ }
+ else
+ {
+ // neues Project anlegen
+ pPrj = new Prj ( aProjectName );
+ pPrj->SetPreFix( aPrefix );
+ Insert(pPrj,LIST_APPEND);
+ }
+ pPrj->AddDependencies( aItem );
+ pPrj->HasHardDependencies( bHardDep );
+
+ if ( nStarMode == STAR_MODE_RECURSIVE_PARSE ) {
+ String sItem( aItem, RTL_TEXTENCODING_ASCII_US );
+ InsertSolarList( sItem );
+ }
+ }
+ }
+ break;
+ }
+ /* Wenn dieses Project noch nicht vertreten ist, in die Liste
+ der Solar-Projekte einfuegen */
+ if ( i == -1 )
+ {
+ aProjectName = aDirName.GetToken ( 0, '\\');
+ if ( HasProject( aProjectName ))
+ {
+ pPrj = GetPrj( aProjectName );
+ // Projekt exist. schon, neue Eintraege anhaengen
+ }
+ else
+ {
+ // neues Project anlegen
+ pPrj = new Prj ( aProjectName );
+ pPrj->SetPreFix( aPrefix );
+ Insert(pPrj,LIST_APPEND);
+ }
+
+ pCmdData = new CommandData;
+ pCmdData->SetPath( aDirName );
+ pCmdData->SetCommandType( nCommandType );
+ pCmdData->SetCommandPara( aCommandPara );
+ pCmdData->SetOSType( nOSType );
+ pCmdData->SetLogFile( aLogFileName );
+ pCmdData->SetClientRestriction( sClientRestriction );
+ if ( pStaticDepList )
+ pCmdData->SetDependencies( pStaticDepList );
+
+ pStaticDepList = 0;
+ pPrj->Insert ( pCmdData, LIST_APPEND );
+ aDirName ="";
+ aWhat ="";
+ aWhatOS = "";
+ sClientRestriction = "";
+ aLogFileName = "";
+ nCommandType = 0;
+ nOSType = 0;
+ }
+ i++;
+
+ // und wer raeumt die depLst wieder ab ?
+}
+
+/*****************************************************************************/
+BOOL Star::HasProject ( ByteString aProjectName )
+/*****************************************************************************/
+{
+ Prj *pPrj;
+ int nCountMember;
+
+ nCountMember = Count();
+
+ for ( int i=0; i<nCountMember; i++)
+ {
+ pPrj = GetObject(i);
+ if ( pPrj->GetProjectName().EqualsIgnoreCaseAscii(aProjectName) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*****************************************************************************/
+Prj* Star::GetPrj ( ByteString aProjectName )
+/*****************************************************************************/
+{
+ Prj* pPrj;
+ int nCountMember = Count();
+ for ( int i=0;i<nCountMember;i++)
+ {
+ pPrj = GetObject(i);
+ if ( pPrj->GetProjectName().EqualsIgnoreCaseAscii(aProjectName) )
+ return pPrj;
+ }
+// return (Prj*)NULL;
+ return 0L ;
+}
+
+/*****************************************************************************/
+ByteString Star::GetPrjName( DirEntry &aPath )
+/*****************************************************************************/
+{
+ ByteString aRetPrj, aDirName;
+ ByteString aFullPathName = ByteString( aPath.GetFull(), gsl_getSystemTextEncoding());
+
+ xub_StrLen nToken = aFullPathName.GetTokenCount(PATH_DELIMETER);
+ for ( xub_StrLen i=0; i< nToken; i++ )
+ {
+ aDirName = aFullPathName.GetToken( i, PATH_DELIMETER );
+ if ( HasProject( aDirName ))
+ {
+ aRetPrj = aDirName;
+ break;
+ }
+ }
+
+ return aRetPrj;
+}
+
+
+//
+// class StarWriter
+//
+
+/*****************************************************************************/
+StarWriter::StarWriter( String aFileName, BOOL bReadComments, USHORT nMode )
+/*****************************************************************************/
+{
+ Read ( aFileName, bReadComments, nMode );
+}
+
+/*****************************************************************************/
+StarWriter::StarWriter( SolarFileList *pSolarFiles, BOOL bReadComments )
+/*****************************************************************************/
+{
+ Read( pSolarFiles, bReadComments );
+}
+
+/*****************************************************************************/
+StarWriter::StarWriter( GenericInformationList *pStandLst, ByteString &rVersion,
+ BOOL bLocal, const char *pSourceRoot )
+/*****************************************************************************/
+{
+ ByteString sPath( rVersion );
+ String sSrcRoot;
+ if ( pSourceRoot )
+ sSrcRoot = String::CreateFromAscii( pSourceRoot );
+
+#ifdef UNX
+ sPath += "/settings/UNXSOLARLIST";
+#else
+ sPath += "/settings/SOLARLIST";
+#endif
+ GenericInformation *pInfo = pStandLst->GetInfo( sPath, TRUE );
+
+ if( pInfo && pInfo->GetValue().Len()) {
+ ByteString sFile( pInfo->GetValue());
+ if ( bLocal ) {
+ IniManager aIniManager;
+ aIniManager.ToLocal( sFile );
+ }
+ String sFileName( sFile, RTL_TEXTENCODING_ASCII_US );
+ nStarMode = STAR_MODE_SINGLE_PARSE;
+ Read( sFileName );
+ }
+ else {
+ SolarFileList *pFileList = new SolarFileList();
+
+ sPath = rVersion;
+ sPath += "/drives";
+
+ GenericInformation *pInfo2 = pStandLst->GetInfo( sPath, TRUE );
+ if ( pInfo2 && pInfo2->GetSubList()) {
+ GenericInformationList *pDrives = pInfo2->GetSubList();
+ for ( ULONG i = 0; i < pDrives->Count(); i++ ) {
+ GenericInformation *pDrive = pDrives->GetObject( i );
+ if ( pDrive ) {
+ DirEntry aEntry;
+ BOOL bOk = FALSE;
+ if ( sSrcRoot.Len()) {
+ aEntry = DirEntry( sSrcRoot );
+ bOk = TRUE;
+ }
+ else {
+#ifdef UNX
+ sPath = "UnixVolume";
+ GenericInformation *pUnixVolume = pDrive->GetSubInfo( sPath );
+ if ( pUnixVolume ) {
+ String sRoot( pUnixVolume->GetValue(), RTL_TEXTENCODING_ASCII_US );
+ aEntry = DirEntry( sRoot );
+ bOk = TRUE;
+ }
+#else
+ bOk = TRUE;
+ String sRoot( *pDrive, RTL_TEXTENCODING_ASCII_US );
+ sRoot += String::CreateFromAscii( "\\" );
+ aEntry = DirEntry( sRoot );
+#endif
+ }
+ if ( bOk ) {
+ sPath = "projects";
+ GenericInformation *pProjectsKey = pDrive->GetSubInfo( sPath, TRUE );
+ if ( pProjectsKey ) {
+ if ( !sSrcRoot.Len()) {
+ sPath = rVersion;
+ sPath += "/settings/PATH";
+ GenericInformation *pPath = pStandLst->GetInfo( sPath, TRUE );
+ if( pPath ) {
+ ByteString sAddPath( pPath->GetValue());
+#ifdef UNX
+ sAddPath.SearchAndReplaceAll( "\\", "/" );
+#else
+ sAddPath.SearchAndReplaceAll( "/", "\\" );
+#endif
+ String ssAddPath( sAddPath, RTL_TEXTENCODING_ASCII_US );
+ aEntry += DirEntry( ssAddPath );
+ }
+ }
+ GenericInformationList *pProjects = pProjectsKey->GetSubList();
+ if ( pProjects ) {
+ String sPrjDir( String::CreateFromAscii( "prj" ));
+ String sSolarFile( String::CreateFromAscii( "build.lst" ));
+
+ for ( ULONG j = 0; j < pProjects->Count(); j++ ) {
+ ByteString sProject( *pProjects->GetObject( j ));
+ String ssProject( sProject, RTL_TEXTENCODING_ASCII_US );
+
+ DirEntry aPrjEntry( aEntry );
+
+ aPrjEntry += DirEntry( ssProject );
+ aPrjEntry += DirEntry( sPrjDir );
+ aPrjEntry += DirEntry( sSolarFile );
+
+ pFileList->Insert( new String( aPrjEntry.GetFull()), LIST_APPEND );
+
+ ByteString sFile( aPrjEntry.GetFull(), RTL_TEXTENCODING_ASCII_US );
+ fprintf( stdout, "%s\n", sFile.GetBuffer());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ Read( pFileList );
+ }
+}
+
+/*****************************************************************************/
+void StarWriter::CleanUp()
+/*****************************************************************************/
+{
+ Expand_Impl();
+}
+
+/*****************************************************************************/
+USHORT StarWriter::Read( String aFileName, BOOL bReadComments, USHORT nMode )
+/*****************************************************************************/
+{
+ nStarMode = nMode;
+
+ ByteString aString;
+ aFileList.Insert( new String( aFileName ));
+
+ DirEntry aEntry( aFileName );
+ aEntry.ToAbs();
+ aEntry = aEntry.GetPath().GetPath().GetPath();
+ sSourceRoot = aEntry.GetFull();
+
+ while( aFileList.Count()) {
+
+ StarFile *pFile = new StarFile( *aFileList.GetObject(( ULONG ) 0 ));
+ if ( pFile->Exists()) {
+ SimpleConfig aSolarConfig( *aFileList.GetObject(( ULONG ) 0 ));
+ while (( aString = aSolarConfig.GetCleanedNextLine( bReadComments )) != "" )
+ InsertTokenLine ( aString );
+ }
+
+ aMutex.acquire();
+ aLoadedFilesList.Insert( pFile, LIST_APPEND );
+ aMutex.release();
+ delete aFileList.Remove(( ULONG ) 0 );
+ }
+ // resolve all dependencies recursive
+ Expand_Impl();
+
+ // Die gefundenen Abhaengigkeiten rekursiv aufloesen
+ Expand_Impl();
+ return 0;
+}
+
+/*****************************************************************************/
+USHORT StarWriter::Read( SolarFileList *pSolarFiles, BOOL bReadComments )
+/*****************************************************************************/
+{
+ nStarMode = STAR_MODE_MULTIPLE_PARSE;
+
+ // this ctor is used by StarBuilder to get the information for the whole workspace
+ while( pSolarFiles->Count()) {
+ ByteString aString;
+
+ StarFile *pFile = new StarFile( *pSolarFiles->GetObject(( ULONG ) 0 ));
+ if ( pFile->Exists()) {
+ SimpleConfig aSolarConfig( *pSolarFiles->GetObject(( ULONG ) 0 ));
+ while (( aString = aSolarConfig.GetCleanedNextLine( bReadComments )) != "" )
+ InsertTokenLine ( aString );
+ }
+
+ aMutex.acquire();
+ aLoadedFilesList.Insert( pFile, LIST_APPEND );
+ aMutex.release();
+ delete pSolarFiles->Remove(( ULONG ) 0 );
+ }
+ delete pSolarFiles;
+
+ Expand_Impl();
+ return 0;
+}
+
+/*****************************************************************************/
+USHORT StarWriter::WritePrj( Prj *pPrj, SvFileStream& rStream )
+/*****************************************************************************/
+{
+ ByteString aDataString;
+ ByteString aTab('\t');
+ ByteString aSpace(' ');
+ ByteString aEmptyString("");
+ SByteStringList* pCmdDepList;
+
+ CommandData* pCmdData = NULL;
+ if ( pPrj->Count() > 0 )
+ {
+ pCmdData = pPrj->First();
+ SByteStringList* pPrjDepList = pPrj->GetDependencies( FALSE );
+ if ( pPrjDepList != 0 )
+ {
+ aDataString = pPrj->GetPreFix();
+ aDataString += aTab;
+ aDataString += pPrj->GetProjectName();
+ aDataString += aTab;
+ if ( pPrj->HasHardDependencies())
+ aDataString+= ByteString("::");
+ else
+ aDataString+= ByteString(":");
+ aDataString += aTab;
+ for ( USHORT i = 0; i< pPrjDepList->Count(); i++ ) {
+ aDataString += *pPrjDepList->GetObject( i );
+ aDataString += aSpace;
+ }
+ aDataString+= "NULL";
+
+ rStream.WriteLine( aDataString );
+
+ pCmdData = pPrj->Next();
+ }
+ if ( pCmdData ) {
+ do
+ {
+ if (( aDataString = pCmdData->GetComment()) == aEmptyString )
+ {
+ aDataString = pPrj->GetPreFix();
+ aDataString += aTab;
+
+ aDataString+= pCmdData->GetPath();
+ aDataString += aTab;
+ USHORT nPathLen = pCmdData->GetPath().Len();
+ if ( nPathLen < 40 )
+ for ( int i = 0; i < 9 - pCmdData->GetPath().Len() / 4 ; i++ )
+ aDataString += aTab;
+ else
+ for ( int i = 0; i < 12 - pCmdData->GetPath().Len() / 4 ; i++ )
+ aDataString += aTab;
+ aDataString += pCmdData->GetCommandTypeString();
+ aDataString += aTab;
+ if ( pCmdData->GetCommandType() == COMMAND_GET )
+ aDataString += aTab;
+ if ( pCmdData->GetCommandPara() == aEmptyString )
+ aDataString+= ByteString("-");
+ else
+ aDataString+= pCmdData->GetCommandPara();
+ aDataString += aTab;
+ aDataString+= pCmdData->GetOSTypeString();
+ if ( pCmdData->GetClientRestriction().Len()) {
+ aDataString += ByteString( "," );
+ aDataString += pCmdData->GetClientRestriction();
+ }
+ aDataString += aTab;
+ aDataString += pCmdData->GetLogFile();
+ aDataString += aSpace;
+
+ pCmdDepList = pCmdData->GetDependencies();
+ if ( pCmdDepList )
+ for ( USHORT i = 0; i< pCmdDepList->Count(); i++ ) {
+ aDataString += *pCmdDepList->GetObject( i );
+ aDataString += aSpace;
+ }
+ aDataString += "NULL";
+ }
+
+ rStream.WriteLine( aDataString );
+
+ pCmdData = pPrj->Next();
+ } while ( pCmdData );
+ }
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+USHORT StarWriter::Write( String aFileName )
+/*****************************************************************************/
+{
+ SvFileStream aFileStream;
+
+ aFileStream.Open( aFileName, STREAM_WRITE | STREAM_TRUNC);
+
+ if ( Count() > 0 )
+ {
+ Prj* pPrj = First();
+ do
+ {
+ WritePrj( pPrj, aFileStream );
+ pPrj = Next();
+ } while ( pPrj );
+ }
+
+ aFileStream.Close();
+
+ return 0;
+}
+
+/*****************************************************************************/
+USHORT StarWriter::WriteMultiple( String rSourceRoot )
+/*****************************************************************************/
+{
+ if ( Count() > 0 )
+ {
+ String sPrjDir( String::CreateFromAscii( "prj" ));
+ String sSolarFile( String::CreateFromAscii( "build.lst" ));
+
+ Prj* pPrj = First();
+ do
+ {
+ String sName( pPrj->GetProjectName(), RTL_TEXTENCODING_ASCII_US );
+
+ DirEntry aEntry( rSourceRoot );
+ aEntry += DirEntry( sName );
+ aEntry += DirEntry( sPrjDir );
+ aEntry += DirEntry( sSolarFile );
+
+ SvFileStream aFileStream;
+ aFileStream.Open( aEntry.GetFull(), STREAM_WRITE | STREAM_TRUNC);
+
+ WritePrj( pPrj, aFileStream );
+
+ aFileStream.Close();
+
+ pPrj = Next();
+ } while ( pPrj );
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+void StarWriter::InsertTokenLine ( ByteString& rString )
+/*****************************************************************************/
+{
+ int i = 0;
+ ByteString aWhat, aWhatOS,
+ sClientRestriction, aLogFileName, aProjectName, aPrefix, aCommandPara;
+ static ByteString aDirName;
+ BOOL bPrjDep = FALSE;
+ BOOL bHardDep = FALSE;
+ USHORT nCommandType = 0;
+ USHORT nOSType = 0;
+ CommandData* pCmdData;
+ SByteStringList *pDepList2 = NULL;
+ Prj* pPrj;
+
+ ByteString aEmptyString;
+ ByteString aToken = rString.GetToken( 0, '\t' );
+ ByteString aCommentString;
+
+ const char* yytext = aToken.GetBuffer();
+
+ while ( !( aToken == aEmptyString ) )
+ {
+ switch (i)
+ {
+ case 0:
+ if ( rString.Search( "#" ) == 0 )
+ {
+ i = -1;
+ aCommentString = rString;
+ rString = aEmptyString;
+ if ( Count() == 0 )
+ aDirName = "null_entry" ; //comments at begin of file
+ break;
+ }
+ aPrefix = yytext;
+ pDepList2 = NULL;
+ break;
+ case 1:
+ aDirName = yytext;
+ break;
+ case 2:
+ if ( !strcmp( yytext, ":" ))
+ {
+ bPrjDep = TRUE;
+ bHardDep = FALSE;
+ i = 9;
+ }
+ else if ( !strcmp( yytext, "::" ))
+ {
+ bPrjDep = TRUE;
+ bHardDep = TRUE;
+ i = 9;
+ }
+ else
+ {
+ bPrjDep = FALSE;
+ bHardDep = FALSE;
+
+ aWhat = yytext;
+ if ( aWhat == "nmake" )
+ nCommandType = COMMAND_NMAKE;
+ else if ( aWhat == "get" )
+ nCommandType = COMMAND_GET;
+ else {
+ ULONG nOffset = aWhat.Copy( 3 ).ToInt32();
+ nCommandType = sal::static_int_cast< USHORT >(
+ COMMAND_USER_START + nOffset - 1);
+ }
+ }
+ break;
+ case 3:
+ if ( !bPrjDep )
+ {
+ aWhat = yytext;
+ if ( aWhat == "-" )
+ {
+ aCommandPara = ByteString();
+ }
+ else
+ aCommandPara = aWhat;
+ }
+ break;
+ case 4:
+ if ( !bPrjDep )
+ {
+ aWhatOS = yytext;
+ if ( aWhatOS.GetTokenCount( ',' ) > 1 ) {
+ sClientRestriction = aWhatOS.Copy( aWhatOS.GetToken( 0, ',' ).Len() + 1 );
+ aWhatOS = aWhatOS.GetToken( 0, ',' );
+ }
+ aWhatOS = aWhatOS.GetToken( 0, ',' );
+ if ( aWhatOS == "all" )
+ nOSType = ( OS_WIN16 | OS_WIN32 | OS_OS2 | OS_UNX );
+ else if ( aWhatOS == "w" )
+ nOSType = ( OS_WIN16 | OS_WIN32 );
+ else if ( aWhatOS == "p" )
+ nOSType = OS_OS2;
+ else if ( aWhatOS == "u" )
+ nOSType = OS_UNX;
+ else if ( aWhatOS == "d" )
+ nOSType = OS_WIN16;
+ else if ( aWhatOS == "n" )
+ nOSType = OS_WIN32;
+ else
+ nOSType = OS_NONE;
+ }
+ break;
+ case 5:
+ if ( !bPrjDep )
+ {
+ aLogFileName = yytext;
+ }
+ break;
+ default:
+ if ( !bPrjDep )
+ {
+ ByteString aItem = yytext;
+ if ( aItem == "NULL" )
+ {
+ // Liste zu Ende
+ i = -1;
+ }
+ else
+ {
+ // ggfs. Dependency liste anlegen und ergaenzen
+ if ( !pDepList2 )
+ pDepList2 = new SByteStringList;
+ pDepList2->PutString( new ByteString( aItem ));
+ }
+ }
+ else
+ {
+ ByteString aItem = yytext;
+ if ( aItem == "NULL" )
+ {
+ // Liste zu Ende
+ i = -1;
+ bPrjDep= FALSE;
+ }
+ else
+ {
+ aProjectName = aDirName.GetToken ( 0, '\\');
+ if ( HasProject( aProjectName ))
+ {
+ pPrj = GetPrj( aProjectName );
+ // Projekt exist. schon, neue Eintraege anhaengen
+ }
+ else
+ {
+ // neues Project anlegen
+ pPrj = new Prj ( aProjectName );
+ pPrj->SetPreFix( aPrefix );
+ Insert(pPrj,LIST_APPEND);
+ }
+ pPrj->AddDependencies( aItem );
+ pPrj->HasHardDependencies( bHardDep );
+
+ if ( nStarMode == STAR_MODE_RECURSIVE_PARSE ) {
+ String sItem( aItem, RTL_TEXTENCODING_ASCII_US );
+ InsertSolarList( sItem );
+ }
+ }
+
+ }
+ break;
+ }
+ /* Wenn dieses Project noch nicht vertreten ist, in die Liste
+ der Solar-Projekte einfuegen */
+ if ( i == -1 )
+ {
+ aProjectName = aDirName.GetToken ( 0, '\\');
+ if ( HasProject( aProjectName ))
+ {
+ pPrj = GetPrj( aProjectName );
+ // Projekt exist. schon, neue Eintraege anhaengen
+ }
+ else
+ {
+ // neues Project anlegen
+ pPrj = new Prj ( aProjectName );
+ pPrj->SetPreFix( aPrefix );
+ Insert(pPrj,LIST_APPEND);
+ }
+
+ pCmdData = new CommandData;
+ pCmdData->SetPath( aDirName );
+ pCmdData->SetCommandType( nCommandType );
+ pCmdData->SetCommandPara( aCommandPara );
+ pCmdData->SetOSType( nOSType );
+ pCmdData->SetLogFile( aLogFileName );
+ pCmdData->SetComment( aCommentString );
+ pCmdData->SetClientRestriction( sClientRestriction );
+ if ( pDepList2 )
+ pCmdData->SetDependencies( pDepList2 );
+
+ pPrj->Insert ( pCmdData, LIST_APPEND );
+
+ }
+ i++;
+
+ rString.Erase(0, aToken.Len()+1);
+ aToken = rString.GetToken( 0, '\t' );
+ yytext = aToken.GetBuffer();
+
+ }
+ // und wer raeumt die depLst wieder ab ?
+}
+
+/*****************************************************************************/
+BOOL StarWriter::InsertProject ( Prj* )
+/*****************************************************************************/
+{
+ return FALSE;
+}
+
+/*****************************************************************************/
+Prj* StarWriter::RemoveProject ( ByteString aProjectName )
+/*****************************************************************************/
+{
+ ULONG nCountMember = Count();
+ Prj* pPrj;
+ Prj* pPrjFound = NULL;
+ SByteStringList* pPrjDeps;
+
+ for ( USHORT i = 0; i < nCountMember; i++ )
+ {
+ pPrj = GetObject( i );
+ if ( pPrj->GetProjectName() == aProjectName )
+ pPrjFound = pPrj;
+ else
+ {
+ pPrjDeps = pPrj->GetDependencies( FALSE );
+ if ( pPrjDeps )
+ {
+ ByteString* pString;
+ ULONG nPrjDepsCount = pPrjDeps->Count();
+ for ( ULONG j = nPrjDepsCount; j > 0; j-- )
+ {
+ pString = pPrjDeps->GetObject( j - 1 );
+ if ( pString->GetToken( 0, '.') == aProjectName )
+ pPrjDeps->Remove( pString );
+ }
+ }
+ }
+ }
+
+ Remove( pPrjFound );
+
+ return pPrjFound;
+}
+
+//
+// class StarFile
+//
+
+/*****************************************************************************/
+StarFile::StarFile( const String &rFile )
+/*****************************************************************************/
+ : aFileName( rFile )
+{
+ DirEntry aEntry( aFileName );
+ if ( aEntry.Exists()) {
+ bExists = TRUE;
+ FileStat aStat( aEntry );
+ aDate = aStat.DateModified();
+ aTime = aStat.TimeModified();
+ }
+ else
+ bExists = FALSE;
+}
+
+/*****************************************************************************/
+BOOL StarFile::NeedsUpdate()
+/*****************************************************************************/
+{
+ DirEntry aEntry( aFileName );
+ if ( aEntry.Exists()) {
+ if ( !bExists ) {
+ bExists = TRUE;
+ return TRUE;
+ }
+ FileStat aStat( aEntry );
+ if (( aStat.DateModified() > aDate ) ||
+ (( aStat.DateModified() == aDate ) && ( aStat.TimeModified() > aTime )))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/bootstrp/rscdep.cxx b/tools/bootstrp/rscdep.cxx
new file mode 100644
index 000000000000..b7cc7b25bac8
--- /dev/null
+++ b/tools/bootstrp/rscdep.cxx
@@ -0,0 +1,301 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#ifdef UNX
+#include <unistd.h>
+#endif
+
+#include <sys/stat.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "bootstrp/prj.hxx"
+#include "sal/main.h"
+
+#include <tools/string.hxx>
+#include <tools/list.hxx>
+#include <tools/fsys.hxx>
+#include <tools/stream.hxx>
+
+#include "cppdep.hxx"
+
+#if defined WNT
+#if !defined HAVE_GETOPT
+#define __STDC__ 1
+#define __GNU_LIBRARY__
+#include <external/glibc/getopt.h>
+#else
+#include <getopt.h>
+#endif
+#endif
+
+class RscHrcDep : public CppDep
+{
+public:
+ RscHrcDep();
+ virtual ~RscHrcDep();
+
+ virtual void Execute();
+};
+
+RscHrcDep::RscHrcDep() :
+ CppDep()
+{
+}
+
+RscHrcDep::~RscHrcDep()
+{
+}
+
+void RscHrcDep::Execute()
+{
+ CppDep::Execute();
+}
+
+//static String aDelim;
+
+SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv )
+{
+ int c;
+ char aBuf[255];
+ char pFileNamePrefix[255];
+ char pOutputFileName[255];
+ char pSrsFileName[255];
+ String aSrsBaseName;
+ BOOL bSource = FALSE;
+ ByteString aRespArg;
+// who needs anything but '/' ?
+// String aDelim = String(DirEntry::GetAccessDelimiter());
+ String aDelim = '/';
+
+ RscHrcDep *pDep = new RscHrcDep;
+
+ pOutputFileName[0] = 0;
+ pSrsFileName[0] = 0;
+
+ for ( int i=1; i<argc; i++)
+ {
+ strcpy( aBuf, (const char *)argv[i] );
+ if ( aBuf[0] == '-' && aBuf[1] == 'p' && aBuf[2] == '=' )
+ {
+ strcpy(pFileNamePrefix, &aBuf[3]);
+ //break;
+ }
+ if ( aBuf[0] == '-' && aBuf[1] == 'f' && aBuf[2] == 'o' && aBuf[3] == '=' )
+ {
+ strcpy(pOutputFileName, &aBuf[4]);
+ //break;
+ }
+ if ( aBuf[0] == '-' && aBuf[1] == 'f' && aBuf[2] == 'p' && aBuf[3] == '=' )
+ {
+ strcpy(pSrsFileName, &aBuf[4]);
+ String aName( pSrsFileName, gsl_getSystemTextEncoding());
+ DirEntry aDest( aName );
+ aSrsBaseName = aDest.GetBase();
+ //break;
+ }
+ if (aBuf[0] == '-' && aBuf[1] == 'i' )
+ {
+ //printf("Include : %s\n", &aBuf[2] );
+ pDep->AddSearchPath( &aBuf[2] );
+ }
+ if (aBuf[0] == '-' && aBuf[1] == 'I' )
+ {
+ //printf("Include : %s\n", &aBuf[2] );
+ pDep->AddSearchPath( &aBuf[2] );
+ }
+ if (aBuf[0] == '@' )
+ {
+ ByteString aToken;
+ String aRespName( &aBuf[1], gsl_getSystemTextEncoding());
+ SimpleConfig aConfig( aRespName );
+ while ( (aToken = aConfig.GetNext()) != "")
+ {
+ char aBuf2[255];
+ (void) strcpy( aBuf2, aToken.GetBuffer());
+ if ( aBuf[0] == '-' && aBuf[1] == 'p' && aBuf[2] == '=' )
+ {
+ strcpy(pFileNamePrefix, &aBuf[3]);
+ //break;
+ }
+ if ( aBuf2[0] == '-' && aBuf2[1] == 'f' && aBuf2[2] == 'o' )
+ {
+ strcpy(pOutputFileName, &aBuf2[3]);
+ //break;
+ }
+ if ( aBuf2[0] == '-' && aBuf2[1] == 'f' && aBuf2[2] == 'p' )
+ {
+ strcpy(pSrsFileName, &aBuf2[3]);
+ String aName( pSrsFileName, gsl_getSystemTextEncoding());
+ DirEntry aDest( aName );
+ aSrsBaseName = aDest.GetBase();
+ //break;
+ }
+ if (aBuf2[0] == '-' && aBuf2[1] == 'i' )
+ {
+ //printf("Include : %s\n", &aBuf[2] );
+ pDep->AddSearchPath( &aBuf2[2] );
+ }
+ if (aBuf2[0] == '-' && aBuf2[1] == 'I' )
+ {
+ //printf("Include : %s\n", &aBuf[2] );
+ pDep->AddSearchPath( &aBuf2[2] );
+ }
+ if (( aBuf2[0] != '-' ) && ( aBuf2[0] != '@' ))
+ {
+ pDep->AddSource( &aBuf2[0] );
+ aRespArg += " ";
+ aRespArg += &aBuf2[0];
+ bSource = TRUE;
+ }
+ }
+ }
+ }
+
+ while( 1 )
+ {
+ c = getopt( argc, argv,
+ "_abcdefghi:jklmnopqrstuvwxyzABCDEFGHI:JKLMNOPQRSTUVWXYZ1234567890/-+=.\\()\"");
+ if ( c == -1 )
+ break;
+
+ switch( c )
+ {
+ case 0:
+ break;
+ case 'a' :
+#ifdef DEBUG_VERBOSE
+ printf("option a\n");
+#endif
+ break;
+
+ case 'l' :
+#ifdef DEBUG_VERBOSE
+ printf("option l with Value %s\n", optarg );
+#endif
+ pDep->AddSource( optarg );
+ break;
+
+ case 'h' :
+ case 'H' :
+ case '?' :
+ printf("RscDep 1.0 (c)2000 StarOffice\n");
+ break;
+
+ default:
+#ifdef DEBUG_VERBOSE
+ printf("Unknown getopt error\n");
+#endif
+ ;
+ }
+ }
+
+
+ DirEntry aEntry(".");
+ aEntry.ToAbs();
+// String aCwd = aEntry.GetName();
+ String aCwd(pFileNamePrefix, gsl_getSystemTextEncoding());
+/* USHORT nPos;
+#ifndef UNX
+ while ( (nPos = aCwd.Search('\\') != STRING_NOTFOUND ))
+#else
+ while ( (nPos = aCwd.Search('/') != STRING_NOTFOUND ))
+#endif
+ {
+ String attt = aCwd.Copy( 0, nPos );
+ aCwd.Erase( 0, nPos );
+ } */
+ SvFileStream aOutStream;
+ String aOutputFileName( pOutputFileName, gsl_getSystemTextEncoding());
+ DirEntry aOutEntry( aOutputFileName );
+ String aOutPath = aOutEntry.GetPath().GetFull();
+
+ String aFileName( aOutPath );
+ aFileName += aDelim;
+ aFileName += aCwd;
+ aFileName += String(".", gsl_getSystemTextEncoding());
+ aFileName += aSrsBaseName;
+ aFileName += String(".dprr", gsl_getSystemTextEncoding());
+ //fprintf( stderr, "OutFileName : %s \n",aFileName.GetStr());
+ aOutStream.Open( aFileName, STREAM_WRITE );
+
+ ByteString aString;
+ if ( optind < argc )
+ {
+#ifdef DEBUG_VERBOSE
+ printf("further arguments : ");
+#endif
+ aString = ByteString( pSrsFileName );
+ aString.SearchAndReplaceAll('\\', ByteString( aDelim, RTL_TEXTENCODING_ASCII_US ));
+ aString += ByteString(" : " );
+
+ while ( optind < argc )
+ {
+ if (!bSource )
+ {
+ aString += ByteString(" " );
+ aString += ByteString( argv[optind]);
+ pDep->AddSource( argv[optind++]);
+ }
+ else
+ {
+ optind++;
+ }
+ }
+ }
+ aString += aRespArg;
+ pDep->Execute();
+ ByteStringList *pLst = pDep->GetDepList();
+ ULONG nCount = pLst->Count();
+ if ( nCount == 0 )
+ {
+ aOutStream.WriteLine( aString );
+ }
+ else
+ {
+ aString += ByteString( "\\" );
+ aOutStream.WriteLine( aString );
+ }
+
+ for ( ULONG j=0; j<nCount; j++ )
+ {
+ ByteString *pStr = pLst->GetObject(j);
+ pStr->SearchAndReplaceAll('\\', ByteString( aDelim, RTL_TEXTENCODING_ASCII_US ));
+ if ( j != (nCount-1) )
+ *pStr += ByteString( "\\" );
+ aOutStream.WriteLine( *pStr );
+ }
+ delete pDep;
+ aOutStream.Close();
+
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/bootstrp/so_checksum.cxx b/tools/bootstrp/so_checksum.cxx
new file mode 100644
index 000000000000..0b2268924c07
--- /dev/null
+++ b/tools/bootstrp/so_checksum.cxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include "md5.hxx"
+
+#include <stdio.h>
+
+#include <tools/string.hxx>
+
+int main( int argc, char * argv[] )
+{
+ for ( int n = 1; n < argc; n++ )
+ {
+ ByteString aChecksum;
+ rtlDigestError error = calc_md5_checksum( argv[n], aChecksum );
+
+ if ( rtl_Digest_E_None == error )
+ {
+ printf( "%s %s\n", aChecksum.GetBuffer(), argv[n] );
+ }
+ else
+ printf( "ERROR: Unable to calculate MD5 checksum for %s\n", argv[n] );
+ }
+
+ return 0;
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/bootstrp/sspretty.cxx b/tools/bootstrp/sspretty.cxx
new file mode 100644
index 000000000000..5a27cf7d2306
--- /dev/null
+++ b/tools/bootstrp/sspretty.cxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <tools/iparser.hxx>
+#include <tools/geninfo.hxx>
+#include <stdio.h>
+
+
+/*****************************************************************************/
+#ifdef UNX
+int main( int argc, char *argv[] )
+#else
+int _cdecl main( int argc, char *argv[] )
+#endif
+/*****************************************************************************/
+{
+ if ( argc != 2 ) {
+ fprintf( stdout, "\nsspretty.exe v1.0 (c) 2001\n\n" );
+ fprintf( stdout, "Syntax: sspretty filename\n" );
+ }
+ else {
+ String aFileName( argv[ 1 ], RTL_TEXTENCODING_ASCII_US );
+ InformationParser aParser;
+ GenericInformationList *pList = aParser.Execute( aFileName );
+ if ( pList )
+ aParser.Save( aFileName, pList );
+ else {
+ fprintf( stderr, "Error reading input file!\n" );
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/bootstrp/sstring.cxx b/tools/bootstrp/sstring.cxx
new file mode 100644
index 000000000000..5224b2ca85e5
--- /dev/null
+++ b/tools/bootstrp/sstring.cxx
@@ -0,0 +1,320 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#ifndef _TOOLS_STRINGLIST
+# define _TOOLS_STRINGLIST
+#endif
+
+#define ENABLE_BYTESTRING_STREAM_OPERATORS
+#include <tools/stream.hxx>
+#include "bootstrp/sstring.hxx"
+
+SByteStringList::SByteStringList()
+{
+}
+
+SByteStringList::~SByteStringList()
+{
+}
+
+ULONG SByteStringList::IsString( ByteString* pStr )
+{
+ ULONG nRet = NOT_THERE;
+ if ( (nRet = GetPrevString( pStr )) != 0 )
+ {
+ ByteString* pString = GetObject( nRet );
+ if ( *pString == *pStr )
+ return nRet;
+ else
+ return NOT_THERE;
+ }
+ else
+ {
+ ByteString* pString = GetObject( 0 );
+ if ( pString && (*pString == *pStr) )
+ return 0;
+ else
+ return NOT_THERE;
+ }
+}
+
+ULONG SByteStringList::GetPrevString( ByteString* pStr )
+{
+ ULONG nRet = 0;
+ BOOL bFound = FALSE;
+ ULONG nCountMember = Count();
+ ULONG nUpper = nCountMember;
+ ULONG nLower = 0;
+ ULONG nCurrent = nUpper / 2;
+ ULONG nRem = 0;
+ ByteString* pString;
+
+ do
+ {
+ if ( (nCurrent == nLower) || (nCurrent == nUpper) )
+ return nLower;
+ pString = GetObject( nCurrent );
+ StringCompare nResult = pStr->CompareTo( *pString );
+ if ( nResult == COMPARE_LESS )
+ {
+ nUpper = nCurrent;
+ nCurrent = (nCurrent + nLower) /2;
+ }
+ else if ( nResult == COMPARE_GREATER )
+ {
+ nLower = nCurrent;
+ nCurrent = (nUpper + nCurrent) /2;
+ }
+ else if ( nResult == COMPARE_EQUAL )
+ return nCurrent;
+ if ( nRem == nCurrent )
+ return nCurrent;
+ nRem = nCurrent;
+ }
+ while ( !bFound );
+ return nRet;
+}
+
+/**************************************************************************
+*
+* Sortiert einen ByteString in die Liste ein und gibt die Position,
+* an der einsortiert wurde, zurueck
+*
+**************************************************************************/
+
+ULONG SByteStringList::PutString( ByteString* pStr )
+{
+ ULONG nPos = GetPrevString ( pStr );
+ if ( Count() )
+ {
+ {
+ ByteString* pString = GetObject( 0 );
+ if ( pString->CompareTo( *pStr ) == COMPARE_GREATER )
+ {
+ Insert( pStr, (ULONG)0 );
+ return (ULONG)0;
+ }
+ }
+ ByteString* pString = GetObject( nPos );
+ if ( *pStr != *pString )
+ {
+ Insert( pStr, nPos+1 );
+ return ( nPos +1 );
+ }
+ }
+ else
+ {
+ Insert( pStr );
+ return (ULONG)0;
+ }
+
+ return NOT_THERE;
+}
+
+ByteString* SByteStringList::RemoveString( const ByteString& rName )
+{
+ ULONG i;
+ ByteString* pReturn;
+
+ for( i = 0 ; i < Count(); i++ )
+ {
+ if ( rName == *GetObject( i ) )
+ {
+ pReturn = GetObject(i);
+ Remove(i);
+ return pReturn;
+ }
+ }
+
+ return NULL;
+}
+
+void SByteStringList::CleanUp()
+{
+ ByteString* pByteString = First();
+ while (pByteString) {
+ delete pByteString;
+ pByteString = Next();
+ }
+ Clear();
+}
+
+SByteStringList& SByteStringList::operator<< ( SvStream& rStream )
+{
+ sal_uInt32 nListCount;
+ rStream >> nListCount;
+ for ( USHORT i = 0; i < nListCount; i++ ) {
+ ByteString* pByteString = new ByteString();
+ rStream >> *pByteString;
+ Insert (pByteString, LIST_APPEND);
+ }
+ return *this;
+}
+
+SByteStringList& SByteStringList::operator>> ( SvStream& rStream )
+{
+ sal_uInt32 nListCount = Count();
+ rStream << nListCount;
+ ByteString* pByteString = First();
+ while (pByteString) {
+ rStream << *pByteString;
+ pByteString = Next();
+ }
+ return *this;
+}
+
+
+
+
+
+
+
+SUniStringList::SUniStringList()
+{
+}
+
+SUniStringList::~SUniStringList()
+{
+}
+
+ULONG SUniStringList::IsString( UniString* pStr )
+{
+ ULONG nRet = NOT_THERE;
+ if ( (nRet = GetPrevString( pStr )) != 0 )
+ {
+ UniString* pString = GetObject( nRet );
+ if ( *pString == *pStr )
+ return nRet;
+ else
+ return NOT_THERE;
+ }
+ else
+ {
+ UniString* pString = GetObject( 0 );
+ if ( pString && (*pString == *pStr) )
+ return 0;
+ else
+ return NOT_THERE;
+ }
+}
+
+ULONG SUniStringList::GetPrevString( UniString* pStr )
+{
+ ULONG nRet = 0;
+ BOOL bFound = FALSE;
+ ULONG nCountMember = Count();
+ ULONG nUpper = nCountMember;
+ ULONG nLower = 0;
+ ULONG nCurrent = nUpper / 2;
+ ULONG nRem = 0;
+ UniString* pString;
+
+ do
+ {
+ if ( (nCurrent == nLower) || (nCurrent == nUpper) )
+ return nLower;
+ pString = GetObject( nCurrent );
+ StringCompare nResult = pStr->CompareTo( *pString );
+ if ( nResult == COMPARE_LESS )
+ {
+ nUpper = nCurrent;
+ nCurrent = (nCurrent + nLower) /2;
+ }
+ else if ( nResult == COMPARE_GREATER )
+ {
+ nLower = nCurrent;
+ nCurrent = (nUpper + nCurrent) /2;
+ }
+ else if ( nResult == COMPARE_EQUAL )
+ return nCurrent;
+ if ( nRem == nCurrent )
+ return nCurrent;
+ nRem = nCurrent;
+ }
+ while ( !bFound );
+ return nRet;
+}
+
+/**************************************************************************
+*
+* Sortiert einen UniString in die Liste ein und gibt die Position,
+* an der einsortiert wurde, zurueck
+*
+**************************************************************************/
+
+ULONG SUniStringList::PutString( UniString* pStr )
+{
+ ULONG nPos = GetPrevString ( pStr );
+ if ( Count() )
+ {
+ {
+ UniString* pString = GetObject( 0 );
+ if ( pString->CompareTo( *pStr ) == COMPARE_GREATER )
+ {
+ Insert( pStr, (ULONG)0);
+ return (ULONG)0;
+ }
+ }
+ UniString* pString = GetObject( nPos );
+ if ( *pStr != *pString )
+ {
+ Insert( pStr, nPos+1 );
+ return ( nPos +1 );
+ }
+ }
+ else
+ {
+ Insert( pStr );
+ return (ULONG)0;
+ }
+
+ return NOT_THERE;
+}
+
+UniString* SUniStringList::RemoveString( const UniString& rName )
+{
+ ULONG i;
+ UniString* pReturn;
+
+ for( i = 0 ; i < Count(); i++ )
+ {
+ if ( rName == *GetObject( i ) )
+ {
+ pReturn = GetObject(i);
+ Remove(i);
+ return pReturn;
+ }
+ }
+
+ return NULL;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/bootstrp/appdef.hxx b/tools/inc/bootstrp/appdef.hxx
new file mode 100644
index 000000000000..df012c491388
--- /dev/null
+++ b/tools/inc/bootstrp/appdef.hxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _MHAPPDEF_HXX
+#define _MHAPPDEF_HXX
+
+
+#ifdef UNX
+#define DEFAULT_INI_ROOT "/so/env"
+#define DEFAULT_BS_ROOT "/so/env/b_server"
+#define PATH_SEPARATOR '/'
+#define S_PATH_SEPARATOR "/"
+#else
+#define DEFAULT_INI_ROOT "r:"
+#define DEFAULT_BS_ROOT "n:"
+#define PATH_SEPARATOR '\\'
+#define S_PATH_SEPARATOR "\\"
+#endif
+
+#define _INI_DRV DEFAULT_INI_ROOT
+#define B_SERVER_ROOT DEFAULT_BS_ROOT
+#define _SOLARLIST B_SERVER_ROOT S_PATH_SEPARATOR "config" S_PATH_SEPARATOR "solar.lst"
+#define _DEF_STAND_LIST B_SERVER_ROOT S_PATH_SEPARATOR "config" S_PATH_SEPARATOR "stand.lst"
+#define _DEF_SSOLARINI B_SERVER_ROOT S_PATH_SEPARATOR "config" S_PATH_SEPARATOR "ssolar.ini"
+#define _DEF_SSCOMMON B_SERVER_ROOT S_PATH_SEPARATOR "config" S_PATH_SEPARATOR "ssolar.cmn"
+#define _INIROOT B_SERVER_ROOT S_PATH_SEPARATOR "config"
+#define _INIROOT_OLD B_SERVER_ROOT S_PATH_SEPARATOR "config"
+#define _INI_UNC "\\\\jumbo2.germany.sun.com\\R-Laufwerk"
+#define _INI_UNC_OLD "\\\\jumbo2.germany.sun.com\\R-Laufwerk"
+
+
+// path conversion
+const char* GetDefStandList();
+const char* GetIniRoot();
+const char* GetIniRootOld();
+const char* GetSSolarIni();
+const char* GetSSCommon();
+const char* GetBServerRoot();
+
+const char* GetEnv( const char *pVar );
+const char* GetEnv( const char *pVar, const char *pDefault );
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/bootstrp/command.hxx b/tools/inc/bootstrp/command.hxx
new file mode 100644
index 000000000000..fea483dca97d
--- /dev/null
+++ b/tools/inc/bootstrp/command.hxx
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef COMMAND_HXX
+#define COMMAND_HXX
+
+#include <iostream>
+
+#include <tools/stream.hxx>
+#define STRLEN 100
+#ifndef UNX
+#define TMPNAME "\\command.tmp"
+#else
+#define TMPNAME "/tmp/command.tmp"
+#endif
+
+/** Different types of spawnable programs
+*/
+enum ExeType
+{
+ EXE, /// programm is a native executable
+ BAT, /// programm is a DOS-Batch
+ BTM /// programm is a 4DOS-Batch
+};
+
+#define COMMAND_NOTFOUND 0x0001
+#define COMMAND_TOOBIG 0x0002
+#define COMMAND_INVALID 0x0004
+#define COMMAND_NOEXEC 0x0008
+#define COMMAND_NOMEM 0x0010
+#define COMMAND_UNKNOWN 0x0020
+
+#ifdef WNT
+#define COMMAND_SHELL "4nt.exe"
+#endif
+#ifdef OS2
+#define COMMAND_SHELL "4os2.exe"
+#endif
+#ifdef UNX
+#define COMMAND_SHELL "csh"
+#endif
+
+class CommandLine;
+class LogWindow;
+
+class CommandLine
+{
+friend class ChildProcess;
+private:
+ char *CommandBuffer;
+ char *ComShell;
+ char **ppArgv;
+ BOOL bTmpWrite;
+
+public:
+ CommandLine(BOOL bTmpWrite = FALSE);
+ CommandLine(const char *, BOOL bTmpWrite = FALSE);
+ CommandLine(const CommandLine&, BOOL bTmpWrite = FALSE);
+ virtual ~CommandLine();
+
+ int nArgc;
+
+ CommandLine& operator=(const CommandLine&);
+ CommandLine& operator=(const char *);
+ void BuildCommand(const char *);
+ char** GetCommand(void) { return ppArgv; }
+ void Strtokens(const char *);
+ void Print();
+};
+
+/** Declares and spawns a child process.
+ The spawned programm could be a native executable or a schell script.
+*/
+class CCommand
+{
+private:
+ ByteString aCommandLine;
+ ByteString aCommand;
+ char *pArgv;
+ char **ppArgv;
+ ULONG nArgc;
+ int nError;
+
+protected:
+ void ImplInit();
+ void Initpp( ULONG nCount, ByteString &rStr );
+
+public:
+ /** Creates the process specified without spawning it
+ @param rString specifies the programm or shell scrip
+ */
+ CCommand( ByteString &rString );
+
+ /** Creates the process specified without spawning it
+ @param pChar specifies the programm or shell scrip
+ */
+ CCommand( const char *pChar );
+
+ /** Try to find the given programm in specified path
+ @param sEnv specifies the current search path, defaulted by environment
+ @param sItem specifies the system shell
+ @return the Location (when programm was found)
+ */
+ static ByteString Search( ByteString sEnv,
+ ByteString sItem = COMMAND_SHELL );
+
+ /** Spawns the Process
+ @return 0 when spawned without errors, otherwise a error code
+ */
+ operator int();
+
+ ByteString GetCommandLine_() { return aCommandLine; }
+ ByteString GetCommand() { return aCommand; }
+
+ char** GetCommandStr() { return ppArgv; }
+};
+
+#define COMMAND_EXECUTE_WINDOW 0x0000001
+#define COMMAND_EXECUTE_CONSOLE 0x0000002
+#define COMMAND_EXECUTE_HIDDEN 0x0000004
+#define COMMAND_EXECUTE_START 0x0000008
+#define COMMAND_EXECUTE_WAIT 0x0000010
+#define COMMAND_EXECUTE_REMOTE 0x1000000
+
+typedef ULONG CommandBits;
+
+/** Allowes to spawn programms hidden, waiting etc.
+ @see CCommand
+*/
+class CCommandd : public CCommand
+{
+ CommandBits nFlag;
+public:
+ CCommandd( ByteString &rString, CommandBits nBits );
+ CCommandd( const char *pChar, CommandBits nBits );
+ operator int();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/bootstrp/inimgr.hxx b/tools/inc/bootstrp/inimgr.hxx
new file mode 100644
index 000000000000..dc5a65222768
--- /dev/null
+++ b/tools/inc/bootstrp/inimgr.hxx
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _INIMGR_HXX
+#define _INIMGR_HXX
+
+#include <tools/fsys.hxx>
+#include <tools/string.hxx>
+
+/*****************************************************************************
+Purpose: Allows to work on a local set of initialisation files
+If Update is used, the user must ensure that only one set of
+Source and Destination Dir is used. Otherwise ForceUpdate has to be used
+*****************************************************************************/
+
+class IniManager
+{
+private:
+ BOOL bUpdate;
+
+ ByteString sGlobalDir; /// holds the org. ini dir
+ ByteString sLocalPath; /// holds path of local ini dir
+
+public:
+ IniManager( ByteString &rDir, ByteString &rLocalDir );
+ IniManager( ByteString &rDir );
+ IniManager();
+
+ ByteString ToLocal( ByteString &rPath );
+ void Update(); /// Call ForceUpdate the First Time called
+ void ForceUpdate();
+
+ static ByteString GetLocalIni();
+ static ByteString GetGlobalIni();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/bootstrp/listmacr.hxx b/tools/inc/bootstrp/listmacr.hxx
new file mode 100644
index 000000000000..1aed769b2983
--- /dev/null
+++ b/tools/inc/bootstrp/listmacr.hxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _LISTMACR_HXX
+#define _LISTMACR_HXX
+
+#define DECL_DEST_LIST( TmpListType, ListType, PointerType ) \
+DECLARE_LIST(TmpListType, PointerType) \
+class ListType : public TmpListType \
+{ \
+public: \
+ void ClearAndDelete() \
+ { \
+ while ( Count()) { \
+ PointerType pTmp = GetObject(( ULONG ) 0 ); \
+ delete pTmp; \
+ Remove(( ULONG ) 0 ); \
+ } \
+ } \
+ ~ListType() \
+ { \
+ ClearAndDelete(); \
+ } \
+}; \
+
+#endif
+
+
+
+
+
+
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/bootstrp/mkcreate.hxx b/tools/inc/bootstrp/mkcreate.hxx
new file mode 100644
index 000000000000..ee89c008c133
--- /dev/null
+++ b/tools/inc/bootstrp/mkcreate.hxx
@@ -0,0 +1,298 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _MK_CREATE_HXX
+#define _MK_CREATE_HXX
+
+#include <tools/string.hxx>
+#include "bootstrp/sstring.hxx"
+
+#include <tools/list.hxx>
+#include "bootstrp/prj.hxx"
+
+class SvStream;
+class SourceDirectoryList;
+
+//
+// class SourceDirectoryDependency
+//
+
+class CodedDependency : public ByteString
+{
+private:
+ USHORT nOSType; // operating systems where dependeny exists
+
+public:
+ /* create a dependency instance with given coded directory name
+ */
+ CodedDependency(
+ const ByteString &rCodedIdentifier, // the coded name of the directory
+ USHORT nOperatingSystems // the operating systems where this dependency exists
+ ) :
+ ByteString( rCodedIdentifier ),
+ nOSType( nOperatingSystems )
+ {
+ }
+
+ /* returns the operating system
+ */
+ USHORT GetOperatingSystem()
+ {
+ return nOSType;
+ }
+
+ /* set operating system
+ */
+ void SetOperatingSystem( USHORT nOperatingSystems )
+ {
+ nOSType = nOperatingSystems;
+ }
+
+ /* add operating systems if same dependency
+ */
+ BOOL TryToMerge(
+ const ByteString &rCodedIdentifier, // the coded name of the directory
+ USHORT nOperatingSystems // the operating systems where this dependency exists
+ )
+ {
+ if ( rCodedIdentifier != *this )
+ return FALSE;
+ nOSType |= nOperatingSystems;
+ return TRUE;
+ }
+};
+
+//
+// class Dependecy
+//
+
+class Dependency : public ByteString
+{
+private:
+ USHORT nOSType; // operating systems where dependecy exists
+
+public:
+ /* create a dependency instance with given directory name
+ */
+ Dependency(
+ const ByteString &rDirectoryName, // the coded name of the directory
+ USHORT nOperatingSystems // the operating systems where this dependency exists
+ ) :
+ ByteString( rDirectoryName ),
+ nOSType( nOperatingSystems )
+ {
+ }
+
+ /* returns the operating system
+ */
+ USHORT GetOperatingSystem()
+ {
+ return nOSType;
+ }
+};
+
+//
+// class SourceDirectory
+//
+
+class SourceDirectory : public ByteString
+{
+private:
+ SourceDirectory *pParent; // the parent directory
+ SourceDirectoryList *pSubDirectories; // list of sub directories
+ USHORT nOSType; // operating systems where this directory is used
+ USHORT nDepth; // depth of directory structure (root is 0)
+
+ SByteStringList *pDependencies; // dependencies on other directories in this depth
+
+ SByteStringList *pCodedDependencies; // dependencies on other directories in different depth
+ SByteStringList *pCodedIdentifier; // symbolic identifier to resolve dependencies
+
+ /* try to resolve a single dependency
+ */
+ Dependency *ResolvesDependency(
+ CodedDependency *pCodedDependency // the dependency
+ );
+
+ /* returns the operating systems of a coded dependency
+ */
+ static USHORT GetOSType(
+ const ByteString &sDependExt // the corresponding dependency extension (see also prj.hxx)
+ );
+
+ /* removes this and all sub directories with all dependencies
+ */
+ BOOL RemoveDirectoryTreeAndAllDependencies();
+
+public:
+
+ /* create a directory instance with given parent and name, no parent means this is the root
+ * (not the file system root but the root of the source tree, e.g. o:\569)
+ */
+ SourceDirectory(
+ const ByteString &rDirectoryName, // name without parent
+ USHORT nOperatingSystem, // the operating systems where this directory is used
+ SourceDirectory *pParentDirectory = NULL // parent (if not root)
+ );
+ ~SourceDirectory();
+
+ /* returns the full absolute path of this directory
+ */
+ ByteString GetFullPath();
+
+ /* returns a list of all sub directories
+ */
+ SourceDirectoryList *GetSubDirectories() { return pSubDirectories; }
+
+ /* returns the Operating systems where this directory is used
+ */
+ USHORT GetOperatingSystems() { return nOSType; }
+
+ /* returns the given directory
+ */
+ SourceDirectory *GetDirectory(
+ const ByteString &rDirectoryName, // full path
+ USHORT nOperatingSystem // the operating systems where this directory is used
+ );
+
+ /* create the directory and all mandatory parents
+ */
+ SourceDirectory *InsertFull(
+ const ByteString &rDirectoryName, // full path
+ USHORT nOperatingSystem // the operating systems where this directory is used
+ )
+ {
+ return GetDirectory( rDirectoryName, nOperatingSystem );
+ }
+
+ /* create the directory as sub directory of this directory
+ */
+ SourceDirectory *Insert(
+ const ByteString &rDirectoryName, // name without parent
+ USHORT nOperatingSystem // the operating systems where this directory is used
+ );
+
+ /* get the root directory
+ */
+ SourceDirectory *GetRootDirectory();
+
+ /* get sub directory if exists
+ */
+ SourceDirectory *GetSubDirectory(
+ const ByteString &rDirectoryPath, // full sub path
+ USHORT nOperatingSystem // the operating systems where this directory is used
+ );
+
+ /* add a dependency for several platforms
+ */
+ CodedDependency *AddCodedDependency(
+ const ByteString &rCodedIdentifier, // the coded name of the directory
+ USHORT nOperatingSystems // the operating systems where this dependency exists
+ );
+
+ /* returns the dependency list
+ */
+ SByteStringList *GetCodedDependencies()
+ {
+ return pCodedDependencies;
+ }
+
+ /* add symbolic identifier to resolve dependencies (to this directory and all parents)
+ */
+ CodedDependency *AddCodedIdentifier(
+ const ByteString &rCodedIdentifier, // the coded name of the directory
+ USHORT nOperatingSystems // the operating systems where this dependency exists
+ );
+
+ /* returns the identifier list
+ */
+ SByteStringList *GetCodedIdentifier()
+ {
+ return pCodedIdentifier;
+ }
+
+ /* create dependencies on other directory, coded dependecies are used
+ */
+ void ResolveDependencies();
+
+ /* returns the target definition for this directory (if dependencies exist)
+ */
+ ByteString GetTarget();
+
+ /* returns the target definition for all sub directory
+ */
+ ByteString GetSubDirsTarget();
+
+ /* create the full directory tree (only virtual, not in file system)
+ */
+ static SourceDirectory *CreateRootDirectory(
+ const ByteString &rRoot, // the root directory in file system
+ const ByteString &rVersion, // the solar verion (r.g. SRC590, SRC591 etc.)
+ BOOL bAll = FALSE // add all directories or only buildable ones
+ );
+
+ /* create the makefile.rc in file system
+ */
+ BOOL CreateRecursiveMakefile(
+ BOOL bAllChilds = FALSE // create rcursive for all sub directories
+ );
+};
+
+//
+// class SourceDirectoryList
+//
+
+class SourceDirectoryList : public SByteStringList
+{
+public:
+ /* create a empty directory list
+ */
+ SourceDirectoryList()
+ {
+ }
+ ~SourceDirectoryList();
+
+ /* search for a directory by directory name
+ */
+ SourceDirectory *Search(
+ const ByteString &rDirectoryName // name without parent
+ );
+
+ /* insert a new directory
+ */
+ ULONG InsertSorted(
+ SourceDirectory *pDirectory // directory
+ )
+ {
+ return PutString(( ByteString * ) pDirectory );
+ }
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/bootstrp/prj.hxx b/tools/inc/bootstrp/prj.hxx
new file mode 100644
index 000000000000..5b620afe7fe0
--- /dev/null
+++ b/tools/inc/bootstrp/prj.hxx
@@ -0,0 +1,334 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _PRJ_HXX
+#define _PRJ_HXX
+
+#include <tools/fsys.hxx>
+#include <tools/stream.hxx>
+#include "bootstrp/listmacr.hxx"
+#include <osl/mutex.hxx>
+
+#define OS_NONE 0x0000
+#define OS_WIN16 0x0001
+#define OS_WIN32 0x0002
+#define OS_OS2 0x0004
+#define OS_UNX 0x0008
+#define OS_ALL ( OS_WIN16 | OS_WIN32 | OS_OS2 | OS_UNX )
+
+#define COMMAND_PROJECTROOT 0x0000
+#define COMMAND_NMAKE 0x0001
+#define COMMAND_GET 0x0002
+#define COMMAND_USER_START 0x0003
+#define COMMAND_USER_END 0xFFFE
+#define COMMAND_ALLDIRS 0xFFFF
+
+class SByteStringList;
+class GenericInformationList;
+
+/*
+// Pfade auf Konfigurationsdateien des Build-Servers
+
+#define REQUEST_DIR \\src\data4\source\b_server\server\newjob
+*/
+/*********************************************************************
+*
+* Die Klasse CommandData haelte alle Informationen, die fuer die
+* Abarbeitung eines Kommandos (nmake, get) noetig sind
+*
+*********************************************************************/
+
+class CommandData
+{
+ ByteString aPrj;
+ ByteString aLogFileName;
+ ByteString aInpath;
+ ByteString aUpd;
+ ByteString aUpdMinor;
+ ByteString aProduct;
+ ByteString aCommand;
+ ByteString aPath;
+ ByteString aPrePath;
+ ByteString aPreFix;
+ ByteString aCommandPara;
+ ByteString aComment;
+ ByteString sClientRestriction;
+ SByteStringList *pDepList;
+ USHORT nOSType;
+ USHORT nCommand;
+
+ ULONG nDepth; // Tiefe der Abhaenigkeit
+
+public:
+ CommandData();
+ ~CommandData();
+ ByteString GetProjectName(){return aPrj;}
+ void SetProjectName( ByteString aName ){aPrj = aName;}
+ ByteString GetLogFile(){return aLogFileName;}
+ void SetLogFile( ByteString aName ){aLogFileName = aName;}
+ ByteString GetInpath(){return aInpath;}
+ void SetInpath( ByteString aName ){aInpath = aName;}
+ ByteString GetUpd(){return aUpd;}
+ void SetUpd( ByteString aName ){aUpd = aName;}
+ ByteString GetUpdMinor(){return aUpdMinor;}
+ void SetUpdMinor( ByteString aName ){aUpdMinor = aName;}
+ ByteString GetProduct(){return aProduct;}
+ void SetProduct( ByteString aName ){aProduct = aName;}
+ ByteString GetCommand(){return aCommand;}
+ void SetCommand ( ByteString aName ){aCommand = aName;}
+ ByteString GetCommandPara(){return aCommandPara;}
+ void SetCommandPara ( ByteString aName ){aCommandPara = aName;}
+ ByteString GetComment(){return aComment;}
+ void SetComment ( ByteString aCommentString ){aComment = aCommentString;}
+ ByteString GetPath(){return aPath;}
+ void SetPath( ByteString aName ){aPath = aName;}
+ ByteString GetPrePath(){return aPrePath;}
+ void SetPrePath( ByteString aName ){aPrePath = aName;}
+ USHORT GetOSType(){return nOSType;}
+ ByteString GetOSTypeString();
+ void SetOSType( USHORT nType ){nOSType = nType;}
+ USHORT GetCommandType(){return nCommand;}
+ ByteString GetCommandTypeString();
+ void SetCommandType( USHORT nCommandType ){nCommand = nCommandType;}
+ SByteStringList* GetDependencies(){return pDepList;}
+ void SetDependencies( SByteStringList *pList ){pDepList = pList;}
+ ByteString GetClientRestriction() { return sClientRestriction; }
+ void SetClientRestriction( ByteString sRestriction ) { sClientRestriction = sRestriction; }
+
+ void AddDepth(){nDepth++;}
+ ULONG GetDepth(){return nDepth;}
+};
+
+/*********************************************************************
+*
+* Die Klasse SimpleConfig kann benutzt werden, um aus einer Textdatei
+* alle Tokens zu lesen
+*
+*********************************************************************/
+
+class SimpleConfig
+{
+ long nLine;
+ String aFileName;
+ SvFileStream aFileStream;
+ ByteString aTmpStr;
+ ByteString aStringBuffer;
+
+ ByteString GetNextLine();
+public:
+ SimpleConfig(String aSimpleConfigFileName);
+ SimpleConfig(DirEntry& rDirEntry);
+ ~SimpleConfig();
+ ByteString GetNext();
+ ByteString GetCleanedNextLine( BOOL bReadComments = FALSE );
+};
+
+#define ENV_GUI 0x00000000
+#define ENV_OS 0x00000001
+#define ENV_UPD 0x00000002
+#define ENV_UPDMIN 0x00000004
+#define ENV_INPATH 0x00000008
+#define ENV_OUTPATH 0x00000010
+#define ENV_GUIBASE 0x00000020
+#define ENV_CVER 0x00000040
+#define ENV_GVER 0x00000080
+#define ENV_GUIENV 0x00000100
+#define ENV_CPU 0x00000200
+#define ENV_CPUNAME 0x00000400
+#define ENV_DLLSUFF 0x00000800
+#define ENV_COMEX 0x00001000
+#define ENV_COMPATH 0x00002000
+#define ENV_INCLUDE 0x00004000
+#define ENV_LIB 0x00008000
+#define ENV_PATH 0x00010000
+#define ENV_SOLVER 0x00020000
+#define ENV_SOLENV 0x00040000
+#define ENV_SOLROOT 0x00080000
+#define ENV_DEVROOT 0x00100000
+#define ENV_EMERG 0x00200000
+#define ENV_STAND 0x00400000
+
+/*********************************************************************
+*
+* class Prj
+* alle Daten eines Projektes werden hier gehalten
+*
+*********************************************************************/
+
+DECL_DEST_LIST ( PrjList_tmp, PrjList, CommandData * )
+
+class Star;
+class Prj : public PrjList
+{
+friend class Star;
+private:
+ BOOL bVisited;
+
+ ByteString aPrjPath;
+ ByteString aProjectName;
+ ByteString aProjectPrefix; // max. 2-buchstabige Abk.
+ SByteStringList* pPrjInitialDepList;
+ SByteStringList* pPrjDepList;
+ BOOL bHardDependencies;
+ BOOL bSorted;
+
+public:
+ Prj();
+ Prj( ByteString aName );
+ ~Prj();
+ void SetPreFix( ByteString aPre ){aProjectPrefix = aPre;}
+ ByteString GetPreFix(){return aProjectPrefix;}
+ ByteString GetProjectName()
+ {return aProjectName;}
+ void SetProjectName(ByteString aName)
+ {aProjectName = aName;}
+ BOOL InsertDirectory( ByteString aDirName , USHORT aWhat,
+ USHORT aWhatOS, ByteString aLogFileName,
+ const ByteString &rClientRestriction );
+ CommandData* RemoveDirectory( ByteString aLogFileName );
+ CommandData* GetDirectoryList ( USHORT nWhatOs, USHORT nCommand );
+ CommandData* GetDirectoryData( ByteString aLogFileName );
+ inline CommandData* GetData( ByteString aLogFileName )
+ { return GetDirectoryData( aLogFileName ); };
+
+ SByteStringList* GetDependencies( BOOL bExpanded = TRUE );
+ void AddDependencies( ByteString aStr );
+ void HasHardDependencies( BOOL bHard ) { bHardDependencies = bHard; }
+ BOOL HasHardDependencies() { return bHardDependencies; }
+};
+
+/*********************************************************************
+*
+* class Star
+* Diese Klasse liest die Projectstruktur aller StarDivision Projekte
+* aus \\dev\data1\upenv\data\config\solar.lst aus
+*
+*********************************************************************/
+
+DECL_DEST_LIST ( StarList_tmp, StarList, Prj* )
+DECLARE_LIST ( SolarFileList, String* )
+
+class StarFile
+{
+private:
+ String aFileName;
+ Date aDate;
+ Time aTime;
+
+ BOOL bExists;
+
+public:
+ StarFile( const String &rFile );
+ const String &GetName() { return aFileName; }
+ Date GetDate() { return aDate; }
+ Time GetTime() { return aTime; }
+
+ BOOL NeedsUpdate();
+ BOOL Exists() { return bExists; }
+};
+
+DECLARE_LIST( StarFileList, StarFile * )
+
+#define STAR_MODE_SINGLE_PARSE 0x0000
+#define STAR_MODE_RECURSIVE_PARSE 0x0001
+#define STAR_MODE_MULTIPLE_PARSE 0x0002
+
+class Star : public StarList
+{
+private:
+ ByteString aStarName;
+
+ static Link aDBNotFoundHdl;
+protected:
+ osl::Mutex aMutex;
+
+ USHORT nStarMode;
+ SolarFileList aFileList;
+ StarFileList aLoadedFilesList;
+ String sSourceRoot;
+
+ void InsertSolarList( String sProject );
+ String CreateFileName( String sProject );
+
+ void Expand_Impl();
+ void ExpandPrj_Impl( Prj *pPrj, Prj *pDepPrj );
+
+private:
+ void Read( String &rFileName );
+ void Read( SolarFileList *pSOlarFiles );
+
+public:
+ Star();
+ Star( String aFileName, USHORT nMode = STAR_MODE_SINGLE_PARSE );
+ Star( SolarFileList *pSolarFiles );
+ Star( GenericInformationList *pStandLst, ByteString &rVersion, BOOL bLocal = FALSE,
+ const char *pSourceRoot = NULL );
+
+ ~Star();
+
+ static void SetDBNotFoundHdl( const Link &rLink ) { aDBNotFoundHdl = rLink; }
+
+ ByteString GetName(){ return aStarName; };
+
+ BOOL HasProject( ByteString aProjectName );
+ Prj* GetPrj( ByteString aProjectName );
+ ByteString GetPrjName( DirEntry &rPath );
+
+ void InsertToken( char *pChar );
+ BOOL NeedsUpdate();
+
+ USHORT GetMode() { return nStarMode; }
+};
+
+class StarWriter : public Star
+{
+private:
+ USHORT WritePrj( Prj *pPrj, SvFileStream& rStream );
+
+public:
+ StarWriter( String aFileName, BOOL bReadComments = FALSE, USHORT nMode = STAR_MODE_SINGLE_PARSE );
+ StarWriter( SolarFileList *pSolarFiles, BOOL bReadComments = FALSE );
+ StarWriter( GenericInformationList *pStandLst, ByteString &rVersion, BOOL bLocal = FALSE,
+ const char *pSourceRoot = NULL );
+
+ void CleanUp();
+
+ BOOL InsertProject ( Prj* pNewPrj );
+ Prj* RemoveProject ( ByteString aProjectName );
+
+ USHORT Read( String aFileName, BOOL bReadComments = FALSE, USHORT nMode = STAR_MODE_SINGLE_PARSE );
+ USHORT Read( SolarFileList *pSolarFiles, BOOL bReadComments = FALSE );
+ USHORT Write( String aFileName );
+ USHORT WriteMultiple( String rSourceRoot );
+
+ void InsertTokenLine( ByteString& rString );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/bootstrp/sstring.hxx b/tools/inc/bootstrp/sstring.hxx
new file mode 100644
index 000000000000..8e21af030870
--- /dev/null
+++ b/tools/inc/bootstrp/sstring.hxx
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SSTRING_HXX
+#define _SSTRING_HXX
+
+#include <tools/string.hxx>
+#include <tools/list.hxx>
+
+#define NOT_THERE LIST_ENTRY_NOTFOUND
+
+#define SStringList SUniStringList
+#define StringList UniStringList
+
+DECLARE_LIST( ByteStringList, ByteString* )
+DECLARE_LIST( UniStringList, UniString* )
+
+class SvStream;
+
+// ---------------------
+// - class SStringList -
+// ---------------------
+
+class SByteStringList : public ByteStringList
+{
+public:
+ SByteStringList();
+ ~SByteStringList();
+
+ // neuen ByteString in Liste einfuegen
+ ULONG PutString( ByteString* );
+ ByteString* RemoveString( const ByteString& rName );
+
+ // Position des ByteString in Liste, wenn nicht enthalten, dann
+ // return = NOT_THERE
+ ULONG IsString( ByteString* );
+
+ // Vorgaenger ermitteln ( auch wenn selbst noch nicht in
+ // Liste enthalten
+ ULONG GetPrevString( ByteString* );
+ void CleanUp();
+
+ SByteStringList& operator<< ( SvStream& rStream );
+ SByteStringList& operator>> ( SvStream& rStream );
+};
+
+// ---------------------
+// - class SUniStringList -
+// ---------------------
+
+class SUniStringList : public UniStringList
+{
+public:
+ SUniStringList();
+ ~SUniStringList();
+
+ // neuen UniString in Liste einfuegen
+ ULONG PutString( UniString* );
+ UniString* RemoveString( const UniString& rName );
+
+ // Position des UniString in Liste, wenn nicht enthalten, dann
+ // return = NOT_THERE
+ ULONG IsString( UniString* );
+
+ // Vorgaenger ermitteln ( auch wenn selbst noch nicht in
+ // Liste enthalten
+ ULONG GetPrevString( UniString* );
+};
+
+class Text
+{
+protected:
+ String aString;
+
+public:
+ Text( char* pChar );
+ Text( String &rStr ) { aString = rStr; }
+ void Stderr();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/impcont.hxx b/tools/inc/impcont.hxx
new file mode 100644
index 000000000000..ef5a34893e6d
--- /dev/null
+++ b/tools/inc/impcont.hxx
@@ -0,0 +1,150 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _IMPCONT_HXX
+#define _IMPCONT_HXX
+
+#include <tools/tools.h>
+#include <tools/contnr.hxx>
+
+typedef void* PVOID;
+
+// ----------
+// - CBlock -
+// ----------
+
+class CBlock
+{
+private:
+ CBlock* pPrev; // Vorheriger Block
+ CBlock* pNext; // Naechster Block
+ USHORT nSize; // Groesse des Blocks
+ USHORT nCount; // Anzahl Pointer
+ void** pNodes; // Pointer auf die Daten
+
+#if defined DBG_UTIL
+ static char const * DbgCheckCBlock(void const *);
+#endif
+
+public:
+ // Fuer List-Container
+ CBlock( USHORT nSize, CBlock* pPrev, CBlock* pNext );
+ // Fuer Array-Container
+ CBlock( USHORT nSize, CBlock* pPrev );
+ // Copy-Ctor
+ CBlock( const CBlock& r, CBlock* pPrev );
+ ~CBlock();
+
+ void Insert( void* p, USHORT nIndex, USHORT nReSize );
+ CBlock* Split( void* p, USHORT nIndex, USHORT nReSize );
+ void* Remove( USHORT nIndex, USHORT nReSize );
+ void* Replace( void* pNew, USHORT nIndex );
+
+ void** GetNodes() const { return pNodes; }
+ void** GetObjectPtr( USHORT nIndex );
+ void* GetObject( USHORT nIndex ) const;
+
+ void SetSize( USHORT nNewSize );
+
+ USHORT GetSize() const { return nCount; }
+ USHORT Count() const { return nCount; }
+ void SetPrevBlock( CBlock* p ) { pPrev = p; }
+ void SetNextBlock( CBlock* p ) { pNext = p; }
+ CBlock* GetPrevBlock() const { return pPrev; }
+ CBlock* GetNextBlock() const { return pNext; }
+ void Reset() { nCount = 0; }
+
+private:
+ CBlock( const CBlock& r );
+
+ friend class Container;
+};
+
+/*************************************************************************
+|*
+|* CBlock::GetObject()
+|*
+|* Beschreibung Gibt einen Pointer aus dem Block zurueck
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+inline void* CBlock::GetObject( USHORT nIndex ) const
+{
+ return pNodes[nIndex];
+}
+
+/*************************************************************************
+|*
+|* Container::ImpGetObject()
+|*
+|* Beschreibung Wir gehen davon aus, das Pointer in der Regel
+|* sich im ersten Block befindet und schalten
+|* deshalb eine Inline-Methode davor
+|* Ersterstellung TH 02.07.93
+|* Letzte Aenderung TH 02.07.93
+|*
+*************************************************************************/
+
+inline void* Container::ImpGetObject( ULONG nIndex ) const
+{
+ if ( pFirstBlock && (nIndex < pFirstBlock->Count()) )
+ // Item innerhalb des gefundenen Blocks zurueckgeben
+ return pFirstBlock->GetObject( (USHORT)nIndex );
+ else
+ return GetObject( nIndex );
+}
+
+/*************************************************************************
+|*
+|* Container::ImpGetOnlyNodes()
+|*
+|* Beschreibung Wenn es nur einen Block gibt, wird davon
+|* das Daten-Array zurueckgegeben
+|* Ersterstellung TH 24.01.96
+|* Letzte Aenderung TH 24.01.96
+|*
+*************************************************************************/
+
+// #i70651#: Prevent warnings on Mac OS X
+#ifdef MACOSX
+#pragma GCC system_header
+#endif
+
+inline void** Container::ImpGetOnlyNodes() const
+{
+ if ( (pFirstBlock == pLastBlock) && pFirstBlock )
+ return pFirstBlock->GetNodes();
+ else
+ return NULL;
+}
+
+#endif // _IMPCONT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/impstrg.hxx b/tools/inc/impstrg.hxx
new file mode 100644
index 000000000000..5a7843653714
--- /dev/null
+++ b/tools/inc/impstrg.hxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _IMPSTRG_HXX
+#define _IMPSTRG_HXX
+
+#include <tools/tools.h>
+#include <tools/string.hxx>
+
+// ------------------------------
+// - Debug-Methoden fuer String -
+// ------------------------------
+
+const char* DbgCheckByteString( const void* pString );
+const char* DbgCheckUniString( const void* pString );
+
+// -------------------------------
+// - Hilfsfunktionen fuer String -
+// -------------------------------
+
+xub_StrLen ImplStringLen( const sal_Char* pStr );
+xub_StrLen ImplStringLen( const sal_Unicode* pStr );
+
+// ------------------------------------
+// - Zugriff fuer International class -
+// ------------------------------------
+
+sal_Unicode* ImplGet1ByteUnicodeTab( rtl_TextEncoding eTextEncoding );
+
+#endif // _IMPSTRG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/makefile.mk b/tools/inc/makefile.mk
new file mode 100644
index 000000000000..a3a76dc94a11
--- /dev/null
+++ b/tools/inc/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..
+
+PRJNAME=tools
+TARGET=inc
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.IF "$(ENABLE_PCH)"!=""
+ALLTAR : \
+ $(SLO)$/precompiled.pch \
+ $(SLO)$/precompiled_ex.pch
+
+.ENDIF # "$(ENABLE_PCH)"!=""
+
diff --git a/tools/inc/pch/precompiled_tools.cxx b/tools/inc/pch/precompiled_tools.cxx
new file mode 100644
index 000000000000..a214b36bcddf
--- /dev/null
+++ b/tools/inc/pch/precompiled_tools.cxx
@@ -0,0 +1,31 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_tools.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/pch/precompiled_tools.hxx b/tools/inc/pch/precompiled_tools.hxx
new file mode 100644
index 000000000000..dfed2ac7d4f6
--- /dev/null
+++ b/tools/inc/pch/precompiled_tools.hxx
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): Generated on 2006-09-01 17:50:15.029610
+
+#ifdef PRECOMPILED_HEADERS
+//---MARKER---
+#include "sal/config.h"
+#include "sal/types.h"
+
+#include "basegfx/point/b2dpoint.hxx"
+#include "basegfx/polygon/b2dpolygon.hxx"
+#include "basegfx/polygon/b2dpolygontools.hxx"
+#include "basegfx/polygon/b2dpolypolygon.hxx"
+#include "basegfx/polygon/b2dpolypolygontools.hxx"
+#include "basegfx/vector/b2dvector.hxx"
+
+#include "boost/static_assert.hpp"
+
+#include "com/sun/star/lang/Locale.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/util/XStringWidth.hpp"
+
+#include "comphelper/fileformat.h"
+
+#include "cppuhelper/implbase1.hxx"
+
+#include "i18npool/lang.h"
+#include "i18npool/mslangid.hxx"
+
+#include "osl/diagnose.h"
+#include "osl/endian.h"
+#include "osl/file.hxx"
+#include "osl/interlck.h"
+#include "osl/module.h"
+#include "osl/module.hxx"
+#include "osl/mutex.hxx"
+#include "osl/process.h"
+#include "osl/security.h"
+#include "osl/signal.h"
+#include "osl/thread.h"
+
+#include "rtl/alloc.h"
+#include "rtl/crc.h"
+#include "rtl/digest.h"
+#include "rtl/instance.hxx"
+#include "rtl/logfile.hxx"
+#include "rtl/math.hxx"
+#include "rtl/memory.h"
+#include "rtl/string.h"
+#include "rtl/string.hxx"
+#include "rtl/tencinfo.h"
+#include "rtl/textcvt.h"
+#include "rtl/textenc.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+
+#include "salhelper/timer.hxx"
+
+#include "sys/stat.h"
+#include "sys/types.h"
+
+//---MARKER---
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/poly.h b/tools/inc/poly.h
new file mode 100644
index 000000000000..92b3c883c84e
--- /dev/null
+++ b/tools/inc/poly.h
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _POLY_H
+#define _POLY_H
+
+#include <tools/gen.hxx>
+
+#define MAX_64KPOINTS ((((USHORT)0xFFFF)-32)/sizeof(Point))
+
+// -------------------
+// - ImplPolygonData -
+// -------------------
+
+class ImplPolygonData
+{
+public:
+#ifdef WIN
+ Point huge* mpPointAry;
+ BYTE* mpFlagAry;
+ GLOBALHANDLE mhPoints;
+#else
+ Point* mpPointAry;
+ BYTE* mpFlagAry;
+#endif
+
+ USHORT mnPoints;
+ ULONG mnRefCount;
+};
+
+// ---------------
+// - ImplPolygon -
+// ---------------
+
+class ImplPolygon : public ImplPolygonData
+{
+public:
+ ImplPolygon( USHORT nInitSize, BOOL bFlags = FALSE );
+ ImplPolygon( USHORT nPoints, const Point* pPtAry, const BYTE* pInitFlags = NULL );
+ ImplPolygon( const ImplPolygon& rImplPoly );
+ ~ImplPolygon();
+
+ void ImplSetSize( USHORT nSize, BOOL bResize = TRUE );
+ void ImplCreateFlagArray();
+ void ImplSplit( USHORT nPos, USHORT nSpace, ImplPolygon* pInitPoly = NULL );
+ void ImplRemove( USHORT nPos, USHORT nCount );
+};
+
+// -------------------
+// - ImplPolyPolygon -
+// -------------------
+
+#define MAX_POLYGONS ((USHORT)0x3FF0)
+
+class Polygon;
+typedef Polygon* SVPPOLYGON;
+
+class ImplPolyPolygon
+{
+public:
+ SVPPOLYGON* mpPolyAry;
+ ULONG mnRefCount;
+ USHORT mnCount;
+ USHORT mnSize;
+ USHORT mnResize;
+
+ ImplPolyPolygon( USHORT nInitSize, USHORT nResize )
+ { mpPolyAry = NULL; mnCount = 0; mnRefCount = 1;
+ mnSize = nInitSize; mnResize = nResize; }
+ ImplPolyPolygon( USHORT nInitSize );
+ ImplPolyPolygon( const ImplPolyPolygon& rImplPolyPoly );
+ ~ImplPolyPolygon();
+};
+
+#endif // _SV_POLY_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/StringListResource.hxx b/tools/inc/tools/StringListResource.hxx
new file mode 100644
index 000000000000..2e5f65dec981
--- /dev/null
+++ b/tools/inc/tools/StringListResource.hxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef TOOLS_STRINGLISTRESOURCE_HXX
+#define TOOLS_STRINGLISTRESOURCE_HXX
+
+#include <vector>
+#include <tools/resid.hxx>
+#include <tools/rcid.h>
+#include <tools/rc.hxx>
+
+namespace tools
+{
+ class StringListResource : public Resource
+ {
+ public:
+ StringListResource(const ResId& _aResId,::std::vector< ::rtl::OUString>& _rToFill ) : Resource(_aResId)
+ {
+ USHORT i = 1;
+ while( IsAvailableRes(ResId(i,*m_pResMgr).SetRT(RSC_STRING)) )
+ {
+ String sStr = String(ResId(i,*m_pResMgr));
+ _rToFill.push_back(sStr);
+ ++i;
+ }
+ }
+ ~StringListResource()
+ {
+ FreeResource();
+ }
+ };
+} // namespace tools
+#endif // TOOLS_STRINGLISTRESOURCE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/agapi.hxx b/tools/inc/tools/agapi.hxx
new file mode 100644
index 000000000000..bfd33a555775
--- /dev/null
+++ b/tools/inc/tools/agapi.hxx
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _AGAPI_HXX
+#define _AGAPI_HXX
+
+#include <tools/solar.h>
+
+class INetURLObject;
+class ChannelList;
+class AgentItem;
+class String;
+
+class AgentApi
+{
+protected:
+ friend class ChannelList;
+
+ AgentItem* pChannelAgent;
+ virtual BOOL StartAgent() = 0;
+
+ AgentApi(AgentItem* pAgent) { pChannelAgent = pAgent; }
+
+public:
+ virtual ~AgentApi() {}
+
+ virtual void InitAgent() = 0;
+ virtual void ShutDownAgent() = 0;
+
+ virtual BOOL NewDataPermission(const String& rChannelName) = 0;
+ virtual void NewData(const String& rChannelName,
+ const INetURLObject& rURL) = 0;
+ virtual void NotifyChannelObjFile(const INetURLObject& rURL,
+ const String& rFileName) = 0;
+ virtual void NotifyChannelObjData(const INetURLObject& rURL,
+ void* pBuffer, long nOffset, long nLen, long nTotalLen) = 0;
+
+ virtual void RegisterChannels() = 0;
+ virtual void RegisterUpdateTransmitter() = 0;
+};
+
+#endif //_AGAPI_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/agitem.hxx b/tools/inc/tools/agitem.hxx
new file mode 100644
index 000000000000..19d33fc830bf
--- /dev/null
+++ b/tools/inc/tools/agitem.hxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _AGITEM_HXX
+#define _AGITEM_HXX
+
+#include <tools/solar.h>
+
+class String;
+class INetURLObject;
+class AgentApi;
+class ChApi;
+
+class AgentItem
+{
+public:
+ virtual const String& GetChAgentName() const = 0;
+ virtual const INetURLObject& GetLocation() const = 0;
+ virtual AgentApi* GetApi() const = 0;
+ virtual ChApi* GetChApi() const = 0;
+
+ virtual void SetIsActive(BOOL bNew) = 0;
+ virtual BOOL IsActive() const = 0;
+};
+
+#endif //_AGITEM_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/appendunixshellword.hxx b/tools/inc/tools/appendunixshellword.hxx
new file mode 100644
index 000000000000..91bf77cce9ec
--- /dev/null
+++ b/tools/inc/tools/appendunixshellword.hxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TOOLS_APPENDUNIXSHELLWORD_HXX
+#define INCLUDED_TOOLS_APPENDUNIXSHELLWORD_HXX
+
+#include "sal/config.h"
+
+#if defined UNX
+
+#include "tools/toolsdllapi.h"
+
+namespace rtl {
+ class OString;
+ class OStringBuffer;
+}
+
+namespace tools {
+
+// append arbitrary bytes as a properly quoted Unix-style shell word
+//
+// @param accumulator
+// the string buffer to which the word is appended (without any surrounding
+// whitespace); must not be null
+//
+// @param text
+// the text to add
+TOOLS_DLLPUBLIC void appendUnixShellWord(
+ rtl::OStringBuffer * accumulator, rtl::OString const & text);
+
+}
+
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/b3dtrans.hxx b/tools/inc/tools/b3dtrans.hxx
new file mode 100644
index 000000000000..e7a7d7a40b00
--- /dev/null
+++ b/tools/inc/tools/b3dtrans.hxx
@@ -0,0 +1,355 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _B3D_B3DTRANS_HXX
+#define _B3D_B3DTRANS_HXX
+
+// Zu verwendender DephRange des Z-Buffers
+#define ZBUFFER_DEPTH_RANGE ((double)(256L * 256L * 256L))
+
+#include <basegfx/matrix/b3dhommatrix.hxx>
+#include <basegfx/range/b3drange.hxx>
+#include <tools/gen.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+#include <tools/toolsdllapi.h>
+
+// Vorausdeklarationen
+
+/*************************************************************************
+|*
+|* Unterstuetzte Methoden, um das Seitenverhaeltnis einzuhalten
+|*
+\************************************************************************/
+
+enum Base3DRatio
+{
+ Base3DRatioGrow = 1,
+ Base3DRatioShrink,
+ Base3DRatioMiddle
+};
+
+/*************************************************************************
+|*
+|* Typ der Projektion
+|*
+\************************************************************************/
+
+enum Base3DProjectionType
+{
+ Base3DProjectionTypeParallel = 1,
+ Base3DProjectionTypePerspective
+};
+
+/*************************************************************************
+|*
+|* Transformationen fuer alle 3D Ausgaben
+|*
+\************************************************************************/
+
+class TOOLS_DLLPUBLIC B3dTransformationSet
+{
+private:
+ // Object Matrix Object -> World
+ basegfx::B3DHomMatrix maObjectTrans;
+ basegfx::B3DHomMatrix maInvObjectTrans;
+
+ // Orientation Matrix
+ basegfx::B3DHomMatrix maOrientation;
+ basegfx::B3DHomMatrix maInvOrientation;
+
+ // Projection Matrix
+ basegfx::B3DHomMatrix maProjection;
+ basegfx::B3DHomMatrix maInvProjection;
+
+ // Texture Matrices
+ basegfx::B2DHomMatrix maTexture;
+
+ // Speziell zum Umwandeln von Punkten Objekt -> Device
+ basegfx::B3DHomMatrix maObjectToDevice;
+
+ // Transponierte Inverse fuer Vectortransformationen
+ basegfx::B3DHomMatrix maInvTransObjectToEye;
+
+ // Transformation World->View
+ basegfx::B3DHomMatrix maMatFromWorldToView;
+ basegfx::B3DHomMatrix maInvMatFromWorldToView;
+
+ // Parameters for ViewportTransformation
+ basegfx::B3DVector maScale;
+ basegfx::B3DVector maTranslate;
+
+ // ViewPlane DeviceRectangle (vom Benutzer gesetzt)
+ double mfLeftBound;
+ double mfRightBound;
+ double mfBottomBound;
+ double mfTopBound;
+
+ // Near and far clipping planes
+ double mfNearBound;
+ double mfFarBound;
+
+ // Seitenverhaeltnis der 3D Abbildung (Y / X)
+ // default ist 1:1 -> 1.0
+ // Deaktivieren mit 0.0 als Wert
+ double mfRatio;
+
+ // Der gesetzte Ausgabebereich (in logischen Koordinaten)
+ // und der dazugehoerige sichtbare Bereich
+ Rectangle maViewportRectangle;
+ Rectangle maVisibleRectangle;
+
+ // Die tatsaechlich von CalcViewport gesetzten Abmessungen
+ // des sichtbaren Bereichs (in logischen Koordinaten)
+ Rectangle maSetBound;
+
+ // Methode zur Aufrechterhaltung des Seitenverhaeltnisses
+ // default ist Base3DRatioGrow
+ Base3DRatio meRatio;
+
+ // Flags
+ unsigned mbPerspective : 1;
+ unsigned mbWorldToViewValid : 1;
+ unsigned mbInvTransObjectToEyeValid : 1;
+ unsigned mbObjectToDeviceValid : 1;
+ unsigned mbProjectionValid : 1;
+
+public:
+ B3dTransformationSet();
+ virtual ~B3dTransformationSet();
+
+ // Zurueck auf Standard
+ void Reset();
+
+ // ObjectTrans
+ void SetObjectTrans(const basegfx::B3DHomMatrix& rObj);
+ const basegfx::B3DHomMatrix& GetObjectTrans() { return maObjectTrans; }
+ const basegfx::B3DHomMatrix& GetInvObjectTrans() { return maInvObjectTrans; }
+
+ // Orientation
+ void SetOrientation(
+ basegfx::B3DPoint aVRP = basegfx::B3DPoint(0.0,0.0,1.0),
+ basegfx::B3DVector aVPN = basegfx::B3DVector(0.0,0.0,1.0),
+ basegfx::B3DVector aVUP = basegfx::B3DVector(0.0,1.0,0.0));
+ void SetOrientation(basegfx::B3DHomMatrix& mOrient);
+ const basegfx::B3DHomMatrix& GetOrientation() { return maOrientation; }
+ const basegfx::B3DHomMatrix& GetInvOrientation() { return maInvOrientation; }
+
+ // Projection
+ void SetProjection(const basegfx::B3DHomMatrix& mProject);
+ const basegfx::B3DHomMatrix& GetProjection();
+ const basegfx::B3DHomMatrix& GetInvProjection();
+
+ // Texture
+ void SetTexture(const basegfx::B2DHomMatrix& rTxt);
+ const basegfx::B2DHomMatrix& GetTexture() { return maTexture; }
+
+ // Seitenverhaeltnis und Modus zu dessen Aufrechterhaltung
+ double GetRatio() { return mfRatio; }
+ void SetRatio(double fNew=1.0);
+ Base3DRatio GetRatioMode() { return meRatio; }
+ void SetRatioMode(Base3DRatio eNew=Base3DRatioGrow);
+
+ // Parameter der ViewportTransformation
+ void SetDeviceRectangle(double fL=-1.0, double fR=1.0, double fB=-1.0, double fT=1.0, sal_Bool bBroadCastChange=sal_True);
+ void SetDeviceVolume(const basegfx::B3DRange& rVol, sal_Bool bBroadCastChange=sal_True);
+ void GetDeviceRectangle(double &fL, double &fR, double& fB, double& fT);
+ basegfx::B3DRange GetDeviceVolume();
+ double GetDeviceRectangleWidth() const { return mfRightBound - mfLeftBound; }
+ double GetDeviceRectangleHeight() const { return mfTopBound - mfBottomBound; }
+ void SetFrontClippingPlane(double fF=0.0);
+ double GetFrontClippingPlane() { return mfNearBound; }
+ void SetBackClippingPlane(double fB=1.0);
+ double GetBackClippingPlane() { return mfFarBound; }
+ void SetPerspective(sal_Bool bNew);
+ sal_Bool GetPerspective() { return mbPerspective; }
+ void SetViewportRectangle(Rectangle& rRect, Rectangle& rVisible);
+ void SetViewportRectangle(Rectangle& rRect) { SetViewportRectangle(rRect, rRect); }
+ const Rectangle& GetViewportRectangle() { return maViewportRectangle; }
+ void CalcViewport();
+
+ // Spezielle Matritzen anfordern
+ basegfx::B3DHomMatrix GetMatFromObjectToView();
+
+ // Transponierte Inverse fuer Vectortransformationen
+ const basegfx::B3DHomMatrix& GetInvTransObjectToEye();
+
+ // Speziell zum Umwandeln von Punkten Objekt -> Device
+ const basegfx::B3DHomMatrix& GetObjectToDevice();
+
+ // Speziell zum Umwandeln von Punkten World -> View
+ const basegfx::B3DHomMatrix& GetMatFromWorldToView();
+ const basegfx::B3DHomMatrix& GetInvMatFromWorldToView();
+
+ // Bounds des Viewports lesen
+ const Rectangle& GetLogicalViewportBounds();
+ const basegfx::B3DVector& GetScale();
+ const basegfx::B3DVector& GetTranslate();
+
+ // Direkter Zugriff auf verschiedene Transformationen
+ const basegfx::B3DPoint WorldToEyeCoor(const basegfx::B3DPoint& rVec);
+ const basegfx::B3DPoint EyeToWorldCoor(const basegfx::B3DPoint& rVec);
+ const basegfx::B3DPoint EyeToViewCoor(const basegfx::B3DPoint& rVec);
+ const basegfx::B3DPoint ViewToEyeCoor(const basegfx::B3DPoint& rVec);
+ const basegfx::B3DPoint WorldToViewCoor(const basegfx::B3DPoint& rVec);
+ const basegfx::B3DPoint ViewToWorldCoor(const basegfx::B3DPoint& rVec);
+ const basegfx::B3DPoint DeviceToViewCoor(const basegfx::B3DPoint& rVec);
+ const basegfx::B3DPoint ViewToDeviceCoor(const basegfx::B3DPoint& rVec);
+ const basegfx::B3DPoint ObjectToWorldCoor(const basegfx::B3DPoint& rVec);
+ const basegfx::B3DPoint WorldToObjectCoor(const basegfx::B3DPoint& rVec);
+ const basegfx::B3DPoint ObjectToViewCoor(const basegfx::B3DPoint& rVec);
+ const basegfx::B3DPoint ViewToObjectCoor(const basegfx::B3DPoint& rVec);
+ const basegfx::B3DPoint ObjectToEyeCoor(const basegfx::B3DPoint& rVec);
+ const basegfx::B3DPoint EyeToObjectCoor(const basegfx::B3DPoint& rVec);
+ const basegfx::B3DPoint DeviceToEyeCoor(const basegfx::B3DPoint& rVec);
+ const basegfx::B3DPoint EyeToDeviceCoor(const basegfx::B3DPoint& rVec);
+
+ const basegfx::B3DPoint InvTransObjectToEye(const basegfx::B3DPoint& rVec);
+ const basegfx::B2DPoint TransTextureCoor(const basegfx::B2DPoint& rVec);
+
+ static void Frustum(
+ basegfx::B3DHomMatrix& rTarget,
+ double fLeft = -1.0, double fRight = 1.0,
+ double fBottom = -1.0, double fTop = 1.0,
+ double fNear = 0.001, double fFar = 1.0);
+ static void Ortho(
+ basegfx::B3DHomMatrix& rTarget,
+ double fLeft = -1.0, double fRight = 1.0,
+ double fBottom = -1.0, double fTop = 1.0,
+ double fNear = 0.0, double fFar = 1.0);
+ static void Orientation(
+ basegfx::B3DHomMatrix& rTarget,
+ basegfx::B3DPoint aVRP = basegfx::B3DPoint(0.0,0.0,1.0),
+ basegfx::B3DVector aVPN = basegfx::B3DVector(0.0,0.0,1.0),
+ basegfx::B3DVector aVUP = basegfx::B3DVector(0.0,1.0,0.0));
+
+protected:
+ void PostSetObjectTrans();
+ void PostSetOrientation();
+ void PostSetProjection();
+ void PostSetTexture();
+ void PostSetViewport();
+
+ void CalcMatObjectToDevice();
+ void CalcMatFromWorldToView();
+ void CalcMatInvTransObjectToEye();
+
+ virtual void DeviceRectangleChange();
+};
+
+/*************************************************************************
+|*
+|* Viewport fuer B3D
+|*
+|* Verwendet wird hier ein vereinfachtes System, bei dem der abzubildende
+|* Punkt durch VRP repraesentiert wird
+|*
+\************************************************************************/
+
+class TOOLS_DLLPUBLIC B3dViewport : public B3dTransformationSet
+{
+private:
+ basegfx::B3DPoint aVRP; // View Reference Point
+ basegfx::B3DVector aVPN; // View Plane Normal
+ basegfx::B3DVector aVUV; // View Up Vector
+
+public:
+ B3dViewport();
+ virtual ~B3dViewport();
+
+ void SetVRP(const basegfx::B3DPoint& rNewVRP);
+ void SetVPN(const basegfx::B3DVector& rNewVPN);
+ void SetVUV(const basegfx::B3DVector& rNewVUV);
+ void SetViewportValues(
+ const basegfx::B3DPoint& rNewVRP,
+ const basegfx::B3DVector& rNewVPN,
+ const basegfx::B3DVector& rNewVUV);
+
+ const basegfx::B3DPoint& GetVRP() const { return aVRP; }
+ const basegfx::B3DVector& GetVPN() const { return aVPN; }
+ const basegfx::B3DVector& GetVUV() const { return aVUV; }
+
+protected:
+ void CalcOrientation();
+};
+
+/*************************************************************************
+|*
+|* Kamera fuer B3D
+|*
+\************************************************************************/
+
+class TOOLS_DLLPUBLIC B3dCamera : public B3dViewport
+{
+private:
+ basegfx::B3DPoint aPosition;
+ basegfx::B3DPoint aCorrectedPosition;
+ basegfx::B3DVector aLookAt;
+ double fFocalLength;
+ double fBankAngle;
+
+ unsigned bUseFocalLength : 1;
+
+public:
+ B3dCamera(
+ const basegfx::B3DPoint& rPos = basegfx::B3DPoint(0.0, 0.0, 1.0),
+ const basegfx::B3DVector& rLkAt = basegfx::B3DVector(0.0, 0.0, 0.0),
+ double fFocLen = 35.0, double fBnkAng = 0.0,
+ sal_Bool bUseFocLen = sal_False);
+ virtual ~B3dCamera();
+
+ // Positionen
+ void SetPosition(const basegfx::B3DPoint& rNewPos);
+ const basegfx::B3DPoint& GetPosition() const { return aPosition; }
+ void SetLookAt(const basegfx::B3DVector& rNewLookAt);
+ const basegfx::B3DVector& GetLookAt() const { return aLookAt; }
+ void SetPositionAndLookAt(const basegfx::B3DPoint& rNewPos, const basegfx::B3DVector& rNewLookAt);
+
+ // Brennweite in mm
+ void SetFocalLength(double fLen);
+ double GetFocalLength() const { return fFocalLength; }
+
+ // Neigung links/rechts
+ void SetBankAngle(double fAngle);
+ double GetBankAngle() const { return fBankAngle; }
+
+ // FocalLength Flag
+ void SetUseFocalLength(sal_Bool bNew);
+ sal_Bool GetUseFocalLength() const { return (sal_Bool)bUseFocalLength; }
+
+protected:
+ void CalcNewViewportValues();
+ sal_Bool CalcFocalLength();
+
+ virtual void DeviceRectangleChange();
+};
+
+
+#endif // _B3D_B3DTRANS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/bigint.hxx b/tools/inc/tools/bigint.hxx
new file mode 100644
index 000000000000..5c4f170a7c24
--- /dev/null
+++ b/tools/inc/tools/bigint.hxx
@@ -0,0 +1,331 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _BIGINT_HXX
+#define _BIGINT_HXX
+
+#include <climits>
+#include "tools/toolsdllapi.h"
+#include <tools/solar.h>
+#include <tools/string.hxx>
+
+class SvStream;
+#ifdef _TLBIGINT_INT64
+struct SbxINT64;
+struct SbxUINT64;
+namespace binfilter { class SbxINT64Converter; }
+#endif
+
+// ----------
+// - BigInt -
+// ----------
+
+#define MAX_DIGITS 8
+
+class Fraction;
+
+class TOOLS_DLLPUBLIC BigInt
+{
+#ifdef _TLBIGINT_INT64
+ friend class ::binfilter::SbxINT64Converter;
+#endif
+
+private:
+ long nVal;
+ unsigned short nNum[MAX_DIGITS];
+ sal_uInt8 nLen : 5; // Aktuelle Laenge
+ sal_Bool bIsNeg : 1, // Is Sign negative
+ bIsBig : 1, // sal_True == BigInt
+ bIsSet : 1; // Not "Null" (not not 0)
+
+ TOOLS_DLLPRIVATE void MakeBigInt(BigInt const &);
+ TOOLS_DLLPRIVATE void Normalize();
+ TOOLS_DLLPRIVATE void Mult(BigInt const &, sal_uInt16);
+ TOOLS_DLLPRIVATE void Div(sal_uInt16, sal_uInt16 &);
+ TOOLS_DLLPRIVATE sal_Bool IsLess(BigInt const &) const;
+ TOOLS_DLLPRIVATE void AddLong(BigInt &, BigInt &);
+ TOOLS_DLLPRIVATE void SubLong(BigInt &, BigInt &);
+ TOOLS_DLLPRIVATE void MultLong(BigInt const &, BigInt &) const;
+ TOOLS_DLLPRIVATE void DivLong(BigInt const &, BigInt &) const;
+ TOOLS_DLLPRIVATE void ModLong(BigInt const &, BigInt &) const;
+ TOOLS_DLLPRIVATE sal_Bool ABS_IsLess(BigInt const &) const;
+
+public:
+ BigInt();
+ BigInt( short nVal );
+ BigInt( long nVal );
+ BigInt( int nVal );
+ BigInt( double nVal );
+ BigInt( sal_uInt16 nVal );
+ BigInt( sal_uInt32 nVal );
+ BigInt( const BigInt& rBigInt );
+ BigInt( const ByteString& rString );
+ BigInt( const UniString& rString );
+#ifdef _TLBIGINT_INT64
+ BigInt( const SbxINT64 &r );
+ BigInt( const SbxUINT64 &r );
+#endif
+
+ operator short() const;
+ operator long() const;
+ operator int() const;
+ operator double() const;
+ operator USHORT() const;
+ operator ULONG() const;
+
+ void Set( sal_Bool bSet ) { bIsSet = bSet; }
+ ByteString GetByteString() const;
+ UniString GetString() const;
+
+ sal_Bool IsSet() const { return bIsSet; }
+ sal_Bool IsNeg() const;
+ sal_Bool IsZero() const;
+ sal_Bool IsOne() const;
+ sal_Bool IsLong() const { return !bIsBig; }
+ void Abs();
+ void DivMod( const BigInt &rDivisor, BigInt &rMod );
+#ifdef _TLBIGINT_INT64
+ sal_Bool INT64 ( SbxINT64 *p ) const;
+ sal_Bool UINT64( SbxUINT64 *p ) const;
+#endif
+
+ BigInt& operator =( const BigInt& rVal );
+ BigInt& operator +=( const BigInt& rVal );
+ BigInt& operator -=( const BigInt& rVal );
+ BigInt& operator *=( const BigInt& rVal );
+ BigInt& operator /=( const BigInt& rVal );
+ BigInt& operator %=( const BigInt& rVal );
+
+ BigInt& operator =( const short nValue );
+ BigInt& operator =( const long nValue );
+ BigInt& operator =( const int nValue );
+ BigInt& operator =( const sal_uInt16 nValue );
+
+ friend inline BigInt operator +( const BigInt& rVal1, const BigInt& rVal2 );
+ friend inline BigInt operator -( const BigInt& rVal1, const BigInt& rVal2 );
+ friend inline BigInt operator *( const BigInt& rVal1, const BigInt& rVal2 );
+ friend inline BigInt operator /( const BigInt& rVal1, const BigInt& rVal2 );
+ friend inline BigInt operator %( const BigInt& rVal1, const BigInt& rVal2 );
+
+ TOOLS_DLLPUBLIC friend sal_Bool operator==( const BigInt& rVal1, const BigInt& rVal2 );
+ friend inline sal_Bool operator!=( const BigInt& rVal1, const BigInt& rVal2 );
+ TOOLS_DLLPUBLIC friend sal_Bool operator< ( const BigInt& rVal1, const BigInt& rVal2 );
+ TOOLS_DLLPUBLIC friend sal_Bool operator> ( const BigInt& rVal1, const BigInt& rVal2 );
+ friend inline sal_Bool operator<=( const BigInt& rVal1, const BigInt& rVal2 );
+ friend inline sal_Bool operator>=( const BigInt& rVal1, const BigInt& rVal2 );
+
+ friend class Fraction;
+};
+
+inline BigInt::BigInt()
+{
+ bIsSet = sal_False;
+ bIsBig = sal_False;
+ nVal = 0;
+}
+
+inline BigInt::BigInt( short nValue )
+{
+ bIsSet = sal_True;
+ bIsBig = sal_False;
+ nVal = nValue;
+}
+
+inline BigInt::BigInt( long nValue )
+{
+ bIsSet = sal_True;
+ bIsBig = sal_False;
+ nVal = nValue;
+}
+
+inline BigInt::BigInt( int nValue )
+{
+ bIsSet = sal_True;
+ bIsBig = sal_False;
+ nVal = nValue;
+}
+
+inline BigInt::BigInt( sal_uInt16 nValue )
+{
+ bIsSet = sal_True;
+ bIsBig = sal_False;
+ nVal = nValue;
+}
+
+inline BigInt::operator short() const
+{
+ if ( !bIsBig && nVal >= SHRT_MIN && nVal <= SHRT_MAX )
+ return (short)nVal;
+ else
+ return 0;
+}
+
+inline BigInt::operator long() const
+{
+ if ( !bIsBig )
+ return nVal;
+ else
+ return 0;
+}
+
+inline BigInt::operator int() const
+{
+ if ( !bIsBig && (nVal == (long)(int)nVal) )
+ return (int)nVal;
+ else
+ return 0;
+}
+
+inline BigInt::operator USHORT() const
+{
+ if ( !bIsBig && nVal >= 0 && nVal <= USHRT_MAX )
+ return (USHORT)nVal;
+ else
+ return 0;
+}
+
+inline BigInt& BigInt::operator =( const short nValue )
+{
+ bIsSet = sal_True;
+ bIsBig = sal_False;
+ nVal = nValue;
+
+ return *this;
+}
+
+inline BigInt& BigInt::operator =( const long nValue )
+{
+ bIsSet = sal_True;
+ bIsBig = sal_False;
+ nVal = nValue;
+
+ return *this;
+}
+
+inline BigInt& BigInt::operator =( const int nValue )
+{
+ bIsSet = sal_True;
+ bIsBig = sal_False;
+ nVal = nValue;
+
+ return *this;
+}
+
+inline BigInt& BigInt::operator =( const sal_uInt16 nValue )
+{
+ bIsSet = sal_True;
+ bIsBig = sal_False;
+ nVal = nValue;
+
+ return *this;
+}
+
+inline sal_Bool BigInt::IsNeg() const
+{
+ if ( !bIsBig )
+ return (nVal < 0);
+ else
+ return (sal_Bool)bIsNeg;
+}
+
+inline sal_Bool BigInt::IsZero() const
+{
+ if ( bIsBig )
+ return sal_False;
+ else
+ return (nVal == 0);
+}
+
+inline sal_Bool BigInt::IsOne() const
+{
+ if ( bIsBig )
+ return sal_False;
+ else
+ return (nVal == 1);
+}
+
+inline void BigInt::Abs()
+{
+ if ( bIsBig )
+ bIsNeg = sal_False;
+ else if ( nVal < 0 )
+ nVal = -nVal;
+}
+
+inline BigInt operator+( const BigInt &rVal1, const BigInt &rVal2 )
+{
+ BigInt aErg( rVal1 );
+ aErg += rVal2;
+ return aErg;
+}
+
+inline BigInt operator-( const BigInt &rVal1, const BigInt &rVal2 )
+{
+ BigInt aErg( rVal1 );
+ aErg -= rVal2;
+ return aErg;
+}
+
+inline BigInt operator*( const BigInt &rVal1, const BigInt &rVal2 )
+{
+ BigInt aErg( rVal1 );
+ aErg *= rVal2;
+ return aErg;
+}
+
+inline BigInt operator/( const BigInt &rVal1, const BigInt &rVal2 )
+{
+ BigInt aErg( rVal1 );
+ aErg /= rVal2;
+ return aErg;
+}
+
+inline BigInt operator%( const BigInt &rVal1, const BigInt &rVal2 )
+{
+ BigInt aErg( rVal1 );
+ aErg %= rVal2;
+ return aErg;
+}
+
+inline sal_Bool operator!=( const BigInt& rVal1, const BigInt& rVal2 )
+{
+ return !(rVal1 == rVal2);
+}
+
+inline sal_Bool operator<=( const BigInt& rVal1, const BigInt& rVal2 )
+{
+ return !( rVal1 > rVal2);
+}
+
+inline sal_Bool operator>=( const BigInt& rVal1, const BigInt& rVal2 )
+{
+ return !(rVal1 < rVal2);
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/cachestr.hxx b/tools/inc/tools/cachestr.hxx
new file mode 100644
index 000000000000..c3d9328b7835
--- /dev/null
+++ b/tools/inc/tools/cachestr.hxx
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CACHESTR_HXX
+#define _CACHESTR_HXX
+
+#include <tools/stream.hxx>
+#include <tools/string.hxx>
+#include <tools/link.hxx>
+#include "tools/toolsdllapi.h"
+
+// -----------------
+// - SvCacheStream -
+// -----------------
+
+class TempFile;
+class TOOLS_DLLPUBLIC SvCacheStream : public SvStream
+{
+private:
+ String aFileName;
+ ULONG nMaxSize;
+ int bPersistent;
+
+ SvStream* pSwapStream;
+ SvStream* pCurrentStream;
+ TempFile* pTempFile;
+
+ Link aFilenameLinkHdl;
+
+ TOOLS_DLLPRIVATE virtual ULONG GetData( void* pData, ULONG nSize );
+ TOOLS_DLLPRIVATE virtual ULONG PutData( const void* pData, ULONG nSize );
+ TOOLS_DLLPRIVATE virtual ULONG SeekPos( ULONG nPos );
+ TOOLS_DLLPRIVATE virtual void FlushData();
+ TOOLS_DLLPRIVATE virtual void SetSize( ULONG nSize );
+
+public:
+ SvCacheStream( ULONG nMaxMemSize = 0 );
+ SvCacheStream( const String &rFileName,
+ ULONG nExpectedSize = 0,
+ ULONG nMaxMemSize = 0 );
+ ~SvCacheStream();
+
+ void SetFilenameHdl( const Link& rLink);
+ const Link& GetFilenameHdl() const;
+ void SetFilename( const String& rFN )
+ { aFileName = rFN; } // darf nur vom FilenameHdl gerufen werden!
+ const String& GetFilename() const { return aFileName; }
+
+ void SwapOut();
+ const void* GetBuffer();
+ ULONG GetSize();
+
+ BOOL IsPersistent() { return bPersistent != 0; }
+ void SetPersistence( BOOL b = TRUE ) { bPersistent = b; }
+ void SetSwapStream( SvStream *p )
+ { pSwapStream = p; } // darf nur vom FilenameHdl gerufen werden!
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/chapi.hxx b/tools/inc/tools/chapi.hxx
new file mode 100644
index 000000000000..4d7e60e86f1d
--- /dev/null
+++ b/tools/inc/tools/chapi.hxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CHAPI_HXX
+#define _CHAPI_HXX
+
+#include <tools/solar.h>
+
+class ChannelAgentItem;
+class INetURLObject;
+class String;
+
+enum RequestType {
+ REQTYP_LOCAL_FILE = 1,
+ REQTYP_MEMORY = 2
+};
+
+class ChApi
+{
+public:
+ virtual ~ChApi() {}
+
+ virtual void ShutDownAgent() = 0;
+ virtual void SetLastSuccUpd() = 0;
+
+ virtual void GetChannelObject( const INetURLObject& rURL, RequestType eStreamType,
+ const String& rFileName ) = 0;
+ virtual void AddChannelItem( const String& aChName, const INetURLObject& aTransmitter,
+ const String& aChannel, USHORT nUpdPeriode,
+ const String& rChAgentName ) = 0;
+ virtual void DelChannelItem( const String& aChName ) = 0;
+ virtual void SetChTransmitter( const String& aChName, const String& rNewVal ) = 0;
+ virtual void SetChannel( const String& aChName, const String& rNewVal ) = 0;
+ virtual void SetChannelName( const String& aChName, const String& rNewVal ) = 0;
+ virtual void SetChUpdPeriode( const String& aChName, USHORT nUpdPeriode ) = 0;
+ virtual void SetChannelAgentName( const String& aChName, const String& rNewVal ) = 0;
+
+ virtual void SetUpdateTransmitter(ChannelAgentItem* pAgent, const INetURLObject& rTransmitter) = 0;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+
+#endif //_CHAPI_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/color.hxx b/tools/inc/tools/color.hxx
new file mode 100644
index 000000000000..bc59d89d5a05
--- /dev/null
+++ b/tools/inc/tools/color.hxx
@@ -0,0 +1,240 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _TOOLS_COLOR_HXX
+#define _TOOLS_COLOR_HXX
+
+#include "tools/toolsdllapi.h"
+
+class SvStream;
+class ResId;
+#include <tools/solar.h>
+
+#include <basegfx/color/bcolor.hxx>
+
+// --------------------
+// - ColorCount-Types -
+// --------------------
+
+#define COLCOUNT_MONOCHROM ((ULONG)2)
+#define COLCOUNT_16 ((ULONG)16)
+#define COLCOUNT_256 ((ULONG)256)
+#define COLCOUNT_HICOLOR1 (((ULONG)0x00007FFF)+1)
+#define COLCOUNT_HICOLOR2 (((ULONG)0x0000FFFF)+1)
+#define COLCOUNT_TRUECOLOR (((ULONG)0x00FFFFFF)+1)
+
+// ---------------
+// - Color-Types -
+// ---------------
+
+typedef UINT32 ColorData;
+#define RGB_COLORDATA( r,g,b ) ((ColorData)(((UINT32)((UINT8)(b))))|(((UINT32)((UINT8)(g)))<<8)|(((UINT32)((UINT8)(r)))<<16))
+#define TRGB_COLORDATA( t,r,g,b ) ((ColorData)(((UINT32)((UINT8)(b))))|(((UINT32)((UINT8)(g)))<<8)|(((UINT32)((UINT8)(r)))<<16)|(((UINT32)((UINT8)(t)))<<24))
+#define COLORDATA_RED( n ) ((UINT8)((n)>>16))
+#define COLORDATA_GREEN( n ) ((UINT8)(((UINT16)(n)) >> 8))
+#define COLORDATA_BLUE( n ) ((UINT8)(n))
+#define COLORDATA_TRANSPARENCY( n ) ((UINT8)((n)>>24))
+#define COLORDATA_RGB( n ) ((ColorData)((n) & 0x00FFFFFF))
+
+#define COL_BLACK RGB_COLORDATA( 0x00, 0x00, 0x00 )
+#define COL_BLUE RGB_COLORDATA( 0x00, 0x00, 0x80 )
+#define COL_GREEN RGB_COLORDATA( 0x00, 0x80, 0x00 )
+#define COL_CYAN RGB_COLORDATA( 0x00, 0x80, 0x80 )
+#define COL_RED RGB_COLORDATA( 0x80, 0x00, 0x00 )
+#define COL_MAGENTA RGB_COLORDATA( 0x80, 0x00, 0x80 )
+#define COL_BROWN RGB_COLORDATA( 0x80, 0x80, 0x00 )
+#define COL_GRAY RGB_COLORDATA( 0x80, 0x80, 0x80 )
+#define COL_LIGHTGRAY RGB_COLORDATA( 0xC0, 0xC0, 0xC0 )
+#define COL_LIGHTBLUE RGB_COLORDATA( 0x00, 0x00, 0xFF )
+#define COL_LIGHTGREEN RGB_COLORDATA( 0x00, 0xFF, 0x00 )
+#define COL_LIGHTCYAN RGB_COLORDATA( 0x00, 0xFF, 0xFF )
+#define COL_LIGHTRED RGB_COLORDATA( 0xFF, 0x00, 0x00 )
+#define COL_LIGHTMAGENTA RGB_COLORDATA( 0xFF, 0x00, 0xFF )
+#define COL_YELLOW RGB_COLORDATA( 0xFF, 0xFF, 0x00 )
+#define COL_WHITE RGB_COLORDATA( 0xFF, 0xFF, 0xFF )
+#define COL_TRANSPARENT TRGB_COLORDATA( 0xFF, 0xFF, 0xFF, 0xFF )
+#define COL_AUTO (ColorData)0xFFFFFFFF
+#define COL_AUTHOR1_DARK RGB_COLORDATA(198, 146, 0)
+#define COL_AUTHOR1_NORMAL RGB_COLORDATA(255, 255, 158)
+#define COL_AUTHOR1_LIGHT RGB_COLORDATA(255, 255, 195)
+#define COL_AUTHOR2_DARK RGB_COLORDATA(6, 70, 162)
+#define COL_AUTHOR2_NORMAL RGB_COLORDATA(216, 232, 255)
+#define COL_AUTHOR2_LIGHT RGB_COLORDATA(233, 242, 255)
+#define COL_AUTHOR3_DARK RGB_COLORDATA(87, 157, 28)
+#define COL_AUTHOR3_NORMAL RGB_COLORDATA(218, 248, 193)
+#define COL_AUTHOR3_LIGHT RGB_COLORDATA(226, 250, 207)
+#define COL_AUTHOR4_DARK RGB_COLORDATA(105, 43, 157)
+#define COL_AUTHOR4_NORMAL RGB_COLORDATA(228, 210, 245)
+#define COL_AUTHOR4_LIGHT RGB_COLORDATA(239, 228, 248)
+#define COL_AUTHOR5_DARK RGB_COLORDATA(197, 0, 11)
+#define COL_AUTHOR5_NORMAL RGB_COLORDATA(254, 205, 208)
+#define COL_AUTHOR5_LIGHT RGB_COLORDATA(255, 227, 229)
+#define COL_AUTHOR6_DARK RGB_COLORDATA(0, 128, 128)
+#define COL_AUTHOR6_NORMAL RGB_COLORDATA(210, 246, 246)
+#define COL_AUTHOR6_LIGHT RGB_COLORDATA(230, 250, 250)
+#define COL_AUTHOR7_DARK RGB_COLORDATA(140, 132, 0)
+#define COL_AUTHOR7_NORMAL RGB_COLORDATA(237, 252, 163)
+#define COL_AUTHOR7_LIGHT RGB_COLORDATA(242, 254, 181)
+#define COL_AUTHOR8_DARK RGB_COLORDATA(53, 85, 107)
+#define COL_AUTHOR8_NORMAL RGB_COLORDATA(211, 222, 232)
+#define COL_AUTHOR8_LIGHT RGB_COLORDATA(226, 234, 241)
+#define COL_AUTHOR9_DARK RGB_COLORDATA(209, 118, 0)
+#define COL_AUTHOR9_NORMAL RGB_COLORDATA(255, 226, 185)
+#define COL_AUTHOR9_LIGHT RGB_COLORDATA(255, 231, 199)
+
+#define COLOR_CHANNEL_MERGE( _def_cDst, _def_cSrc, _def_cSrcTrans ) \
+ ((BYTE)((((long)(_def_cDst)-(_def_cSrc))*(_def_cSrcTrans)+(((_def_cSrc)<<8L)|(_def_cDst)))>>8L))
+
+// ---------
+// - Color -
+// ---------
+
+class TOOLS_DLLPUBLIC Color
+{
+protected:
+ ColorData mnColor;
+
+public:
+ Color() { mnColor = COL_BLACK; }
+ Color( ColorData nColor ) { mnColor = nColor; }
+ Color( UINT8 nRed, UINT8 nGreen, UINT8 nBlue )
+ { mnColor = RGB_COLORDATA( nRed, nGreen, nBlue ); }
+ Color( UINT8 nTransparency, UINT8 nRed, UINT8 nGreen, UINT8 nBlue )
+ { mnColor = TRGB_COLORDATA( nTransparency, nRed, nGreen, nBlue ); }
+ Color( const ResId& rResId );
+ // This ctor is defined in svtools, not tools!
+
+ // constructor to create a tools-Color from ::basegfx::BColor
+ explicit Color(const ::basegfx::BColor& rBColor)
+ {
+ mnColor = RGB_COLORDATA(
+ UINT8((rBColor.getRed() * 255.0) + 0.5),
+ UINT8((rBColor.getGreen() * 255.0) + 0.5),
+ UINT8((rBColor.getBlue() * 255.0) + 0.5));
+ }
+
+ void SetRed( UINT8 nRed );
+ UINT8 GetRed() const { return COLORDATA_RED( mnColor ); }
+ void SetGreen( UINT8 nGreen );
+ UINT8 GetGreen() const { return COLORDATA_GREEN( mnColor ); }
+ void SetBlue( UINT8 nBlue );
+ UINT8 GetBlue() const { return COLORDATA_BLUE( mnColor ); }
+ void SetTransparency( UINT8 nTransparency );
+ UINT8 GetTransparency() const { return COLORDATA_TRANSPARENCY( mnColor ); }
+
+ void SetColor( ColorData nColor ) { mnColor = nColor; }
+ ColorData GetColor() const { return mnColor; }
+ ColorData GetRGBColor() const { return COLORDATA_RGB( mnColor ); }
+
+ UINT8 GetColorError( const Color& rCompareColor ) const;
+
+ UINT8 GetLuminance() const;
+ void IncreaseLuminance( UINT8 cLumInc );
+ void DecreaseLuminance( UINT8 cLumDec );
+
+ void IncreaseContrast( UINT8 cContInc );
+ void DecreaseContrast( UINT8 cContDec );
+
+ void Invert();
+
+ void Merge( const Color& rMergeColor, BYTE cTransparency );
+
+ BOOL IsRGBEqual( const Color& rColor ) const;
+
+ // comparison with luminance thresholds
+ BOOL IsDark() const;
+ BOOL IsBright() const;
+
+ // color space conversion tools
+ // the range for h/s/b is:
+ // Hue: 0-360 degree
+ // Saturation: 0-100 %
+ // Brightness: 0-100 %
+ static ColorData HSBtoRGB( USHORT nHue, USHORT nSat, USHORT nBri );
+ void RGBtoHSB( USHORT& nHue, USHORT& nSat, USHORT& nBri ) const;
+
+ BOOL operator==( const Color& rColor ) const
+ { return (mnColor == rColor.mnColor); }
+ BOOL operator!=( const Color& rColor ) const
+ { return !(Color::operator==( rColor )); }
+
+ SvStream& Read( SvStream& rIStm, BOOL bNewFormat = TRUE );
+ SvStream& Write( SvStream& rOStm, BOOL bNewFormat = TRUE );
+
+ TOOLS_DLLPUBLIC friend SvStream& operator>>( SvStream& rIStream, Color& rColor );
+ TOOLS_DLLPUBLIC friend SvStream& operator<<( SvStream& rOStream, const Color& rColor );
+
+ // get ::basegfx::BColor from this color
+ ::basegfx::BColor getBColor() const { return ::basegfx::BColor(GetRed() / 255.0, GetGreen() / 255.0, GetBlue() / 255.0); }
+};
+
+inline void Color::SetRed( UINT8 nRed )
+{
+ mnColor &= 0xFF00FFFF;
+ mnColor |= ((UINT32)nRed)<<16;
+}
+
+inline void Color::SetGreen( UINT8 nGreen )
+{
+ mnColor &= 0xFFFF00FF;
+ mnColor |= ((UINT16)nGreen)<<8;
+}
+
+inline void Color::SetBlue( UINT8 nBlue )
+{
+ mnColor &= 0xFFFFFF00;
+ mnColor |= nBlue;
+}
+
+inline void Color::SetTransparency( UINT8 nTransparency )
+{
+ mnColor &= 0x00FFFFFF;
+ mnColor |= ((UINT32)nTransparency)<<24;
+}
+
+inline BOOL Color::IsRGBEqual( const Color& rColor ) const
+{
+ return (COLORDATA_RGB( mnColor ) == COLORDATA_RGB( rColor.mnColor ));
+}
+
+inline UINT8 Color::GetLuminance() const
+{
+ return( (UINT8) ( ( COLORDATA_BLUE( mnColor ) * 28UL +
+ COLORDATA_GREEN( mnColor ) * 151UL +
+ COLORDATA_RED( mnColor ) * 77UL ) >> 8UL ) );
+}
+
+inline void Color::Merge( const Color& rMergeColor, BYTE cTransparency )
+{
+ SetRed( COLOR_CHANNEL_MERGE( COLORDATA_RED( mnColor ), COLORDATA_RED( rMergeColor.mnColor ), cTransparency ) );
+ SetGreen( COLOR_CHANNEL_MERGE( COLORDATA_GREEN( mnColor ), COLORDATA_GREEN( rMergeColor.mnColor ), cTransparency ) );
+ SetBlue( COLOR_CHANNEL_MERGE( COLORDATA_BLUE( mnColor ), COLORDATA_BLUE( rMergeColor.mnColor ), cTransparency ) );
+}
+
+#endif // _TOOLS_COLOR_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/config.hxx b/tools/inc/tools/config.hxx
new file mode 100644
index 000000000000..e8fa0eab1254
--- /dev/null
+++ b/tools/inc/tools/config.hxx
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _CONFIG_HXX
+#define _CONFIG_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/string.hxx>
+
+struct ImplConfigData;
+struct ImplGroupData;
+
+// ----------
+// - Config -
+// ----------
+
+class TOOLS_DLLPUBLIC Config
+{
+private:
+ XubString maFileName;
+ ByteString maGroupName;
+ ImplConfigData* mpData;
+ ImplGroupData* mpActGroup;
+ ULONG mnDataUpdateId;
+ USHORT mnLockCount;
+ BOOL mbPersistence;
+ BOOL mbDummy1;
+
+#ifdef _CONFIG_CXX
+ TOOLS_DLLPRIVATE BOOL ImplUpdateConfig() const;
+ TOOLS_DLLPRIVATE ImplGroupData* ImplGetGroup() const;
+#endif
+
+public:
+ Config();
+ Config( const XubString& rFileName );
+ ~Config();
+
+ const XubString& GetPathName() const { return maFileName; }
+ static XubString GetDefDirectory();
+ static XubString GetConfigName( const XubString& rPath, const XubString& rBaseName );
+
+ void SetGroup( const ByteString& rGroup );
+ const ByteString& GetGroup() const { return maGroupName; }
+ void DeleteGroup( const ByteString& rGroup );
+ ByteString GetGroupName( USHORT nGroup ) const;
+ USHORT GetGroupCount() const;
+ BOOL HasGroup( const ByteString& rGroup ) const;
+
+ ByteString ReadKey( const ByteString& rKey ) const;
+ UniString ReadKey( const ByteString& rKey, rtl_TextEncoding eEncoding ) const;
+ ByteString ReadKey( const ByteString& rKey, const ByteString& rDefault ) const;
+ void WriteKey( const ByteString& rKey, const ByteString& rValue );
+ void WriteKey( const ByteString& rKey, const UniString& rValue, rtl_TextEncoding eEncoding );
+ void DeleteKey( const ByteString& rKey );
+ ByteString GetKeyName( USHORT nKey ) const;
+ ByteString ReadKey( USHORT nKey ) const;
+ USHORT GetKeyCount() const;
+
+ void EnterLock();
+ void LeaveLock();
+ BOOL IsLocked() const { return (mnLockCount != 0); }
+ BOOL Update();
+ void Flush();
+
+ void EnablePersistence( BOOL bPersistence = TRUE )
+ { mbPersistence = bPersistence; }
+ BOOL IsPersistenceEnabled() const { return mbPersistence; }
+
+ void SetLineEnd( LineEnd eLineEnd );
+ LineEnd GetLineEnd() const;
+
+private:
+ TOOLS_DLLPRIVATE Config( const Config& rConfig );
+ TOOLS_DLLPRIVATE Config& operator = ( const Config& rConfig );
+};
+
+#endif // _SV_CONFIG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/contnr.hxx b/tools/inc/tools/contnr.hxx
new file mode 100644
index 000000000000..3995d6012dae
--- /dev/null
+++ b/tools/inc/tools/contnr.hxx
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _CONTNR_HXX
+#define _CONTNR_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/solar.h>
+
+#include <limits.h>
+
+class CBlock;
+
+// -------------
+// - Container -
+// -------------
+
+// Maximale Blockgroesse
+#define CONTAINER_MAXBLOCKSIZE ((USHORT)0x3FF0)
+
+#define CONTAINER_APPEND ULONG_MAX
+#define CONTAINER_ENTRY_NOTFOUND ULONG_MAX
+
+class TOOLS_DLLPUBLIC Container
+{
+private:
+ CBlock* pFirstBlock;
+ CBlock* pCurBlock;
+ CBlock* pLastBlock;
+ USHORT nCurIndex;
+ USHORT nBlockSize;
+ USHORT nInitSize;
+ USHORT nReSize;
+ ULONG nCount;
+
+ TOOLS_DLLPRIVATE void ImpCopyContainer(Container const *);
+#if defined DBG_UTIL
+ TOOLS_DLLPRIVATE static char const * DbgCheckContainer(void const *);
+#endif
+
+protected:
+#ifdef _IMPCONT_HXX
+ void ImpInsert( void* p, CBlock* pBlock, USHORT nIndex );
+ void* ImpRemove( CBlock* pBlock, USHORT nIndex );
+ void* ImpGetObject( ULONG nIndex ) const;
+ void** ImpGetOnlyNodes() const;
+#endif
+ void** GetObjectPtr( ULONG nIndex );
+
+public:
+ Container( USHORT nBlockSize,
+ USHORT nInitSize,
+ USHORT nReSize );
+ Container( ULONG nSize );
+ Container( const Container& rContainer );
+ ~Container();
+
+ void Insert( void* p );
+ void Insert( void* p, ULONG nIndex );
+ void Insert( void* pNew, void* pOld );
+
+ void* Remove();
+ void* Remove( ULONG nIndex );
+ void* Remove( void* p )
+ { return Remove( GetPos( p ) ); }
+
+ void* Replace( void* p );
+ void* Replace( void* p, ULONG nIndex );
+ void* Replace( void* pNew, void* pOld )
+ { return Replace( pNew, GetPos( pOld ) ); }
+
+ void SetSize( ULONG nNewSize );
+ ULONG GetSize() const { return nCount; }
+
+ ULONG Count() const { return nCount; }
+ void Clear();
+
+ void* GetCurObject() const;
+ ULONG GetCurPos() const;
+ void* GetObject( ULONG nIndex ) const;
+ ULONG GetPos( const void* p ) const;
+ ULONG GetPos( const void* p, ULONG nStartIndex,
+ BOOL bForward = TRUE ) const;
+
+ void* Seek( ULONG nIndex );
+ void* Seek( void* p ) { return Seek( GetPos( p ) ); }
+
+ void* First();
+ void* Last();
+ void* Next();
+ void* Prev();
+
+ Container& operator =( const Container& rContainer );
+
+ BOOL operator ==( const Container& rContainer ) const;
+ BOOL operator !=( const Container& rContainer ) const
+ { return !(Container::operator==( rContainer )); }
+};
+
+#endif // _CONTNR_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/date.hxx b/tools/inc/tools/date.hxx
new file mode 100644
index 000000000000..f39698f4a69f
--- /dev/null
+++ b/tools/inc/tools/date.hxx
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _DATE_HXX
+#define _DATE_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/solar.h>
+
+class ResId;
+
+// --------------
+// - Date-Types -
+// --------------
+
+enum DayOfWeek { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,
+ SATURDAY, SUNDAY };
+
+// --------
+// - Date -
+// --------
+
+class TOOLS_DLLPUBLIC Date
+{
+private:
+ sal_uInt32 nDate;
+
+public:
+ Date();
+ Date( const ResId & rResId );
+ Date( sal_uInt32 _nDate ) { Date::nDate = _nDate; }
+ Date( const Date& rDate )
+ { nDate = rDate.nDate; }
+ Date( USHORT nDay, USHORT nMonth, USHORT nYear )
+ { nDate = ( sal_uInt32( nDay % 100 ) ) +
+ ( ( sal_uInt32( nMonth % 100 ) ) * 100 ) +
+ ( ( sal_uInt32( nYear % 10000 ) ) * 10000); }
+
+ void SetDate( sal_uInt32 nNewDate ) { nDate = nNewDate; }
+ sal_uInt32 GetDate() const { return nDate; }
+
+ void SetDay( USHORT nNewDay );
+ void SetMonth( USHORT nNewMonth );
+ void SetYear( USHORT nNewYear );
+ USHORT GetDay() const { return (USHORT)(nDate % 100); }
+ USHORT GetMonth() const { return (USHORT)((nDate / 100) % 100); }
+ USHORT GetYear() const { return (USHORT)(nDate / 10000); }
+
+ DayOfWeek GetDayOfWeek() const;
+ USHORT GetDayOfYear() const;
+ /** nMinimumNumberOfDaysInWeek: how many days of a week must reside in the
+ first week of a year. */
+ USHORT GetWeekOfYear( DayOfWeek eStartDay = MONDAY,
+ sal_Int16 nMinimumNumberOfDaysInWeek = 4 ) const;
+
+ USHORT GetDaysInMonth() const;
+ USHORT GetDaysInYear() const { return (IsLeapYear()) ? 366 : 365; }
+ BOOL IsLeapYear() const;
+ BOOL IsValid() const;
+
+ BOOL IsBetween( const Date& rFrom, const Date& rTo ) const
+ { return ((nDate >= rFrom.nDate) &&
+ (nDate <= rTo.nDate)); }
+
+ BOOL operator ==( const Date& rDate ) const
+ { return (nDate == rDate.nDate); }
+ BOOL operator !=( const Date& rDate ) const
+ { return (nDate != rDate.nDate); }
+ BOOL operator >( const Date& rDate ) const
+ { return (nDate > rDate.nDate); }
+ BOOL operator <( const Date& rDate ) const
+ { return (nDate < rDate.nDate); }
+ BOOL operator >=( const Date& rDate ) const
+ { return (nDate >= rDate.nDate); }
+ BOOL operator <=( const Date& rDate ) const
+ { return (nDate <= rDate.nDate); }
+
+ Date& operator =( const Date& rDate )
+ { nDate = rDate.nDate; return *this; }
+ Date& operator +=( long nDays );
+ Date& operator -=( long nDays );
+ Date& operator ++();
+ Date& operator --();
+#ifndef MPW33
+ Date operator ++( int );
+ Date operator --( int );
+#endif
+
+ TOOLS_DLLPUBLIC friend Date operator +( const Date& rDate, long nDays );
+ TOOLS_DLLPUBLIC friend Date operator -( const Date& rDate, long nDays );
+ TOOLS_DLLPUBLIC friend long operator -( const Date& rDate1, const Date& rDate2 );
+
+ static long DateToDays( USHORT nDay, USHORT nMonth, USHORT nYear );
+
+};
+
+#endif // _DATE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/datetime.hxx b/tools/inc/tools/datetime.hxx
new file mode 100644
index 000000000000..efc8a3ef5743
--- /dev/null
+++ b/tools/inc/tools/datetime.hxx
@@ -0,0 +1,114 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _DATETIME_HXX
+#define _DATETIME_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/solar.h>
+#include <tools/date.hxx>
+#include <tools/time.hxx>
+
+// ------------
+// - DateTime -
+// ------------
+
+class TOOLS_DLLPUBLIC DateTime : public Date, public Time
+{
+public:
+ DateTime() : Date(), Time() {}
+ DateTime( const DateTime& rDateTime ) :
+ Date( rDateTime ), Time( rDateTime ) {}
+ DateTime( const Date& rDate ) : Date( rDate ), Time(0) {}
+ DateTime( const Time& rTime ) : Date(0), Time( rTime ) {}
+ DateTime( const Date& rDate, const Time& rTime ) :
+ Date( rDate ), Time( rTime ) {}
+
+ BOOL IsBetween( const DateTime& rFrom,
+ const DateTime& rTo ) const;
+
+ BOOL IsEqualIgnore100Sec( const DateTime& rDateTime ) const
+ {
+ if ( Date::operator!=( rDateTime ) )
+ return FALSE;
+ return Time::IsEqualIgnore100Sec( rDateTime );
+ }
+
+ BOOL operator ==( const DateTime& rDateTime ) const
+ { return (Date::operator==( rDateTime ) &&
+ Time::operator==( rDateTime )); }
+ BOOL operator !=( const DateTime& rDateTime ) const
+ { return (Date::operator!=( rDateTime ) ||
+ Time::operator!=( rDateTime )); }
+ BOOL operator >( const DateTime& rDateTime ) const;
+ BOOL operator <( const DateTime& rDateTime ) const;
+ BOOL operator >=( const DateTime& rDateTime ) const;
+ BOOL operator <=( const DateTime& rDateTime ) const;
+
+ long GetSecFromDateTime( const Date& rDate ) const;
+ void MakeDateTimeFromSec( const Date& rDate, ULONG nSec );
+
+ void ConvertToUTC() { *this -= Time::GetUTCOffset(); }
+ void ConvertToLocalTime() { *this += Time::GetUTCOffset(); }
+
+ DateTime& operator +=( long nDays )
+ { Date::operator+=( nDays ); return *this; }
+ DateTime& operator -=( long nDays )
+ { Date::operator-=( nDays ); return *this; }
+ DateTime& operator +=( double fTimeInDays );
+ DateTime& operator -=( double fTimeInDays )
+ { return operator+=( -fTimeInDays ); }
+ DateTime& operator +=( const Time& rTime );
+ DateTime& operator -=( const Time& rTime );
+
+ TOOLS_DLLPUBLIC friend DateTime operator +( const DateTime& rDateTime, long nDays );
+ TOOLS_DLLPUBLIC friend DateTime operator -( const DateTime& rDateTime, long nDays );
+ TOOLS_DLLPUBLIC friend DateTime operator +( const DateTime& rDateTime, double fTimeInDays );
+ TOOLS_DLLPUBLIC friend DateTime operator -( const DateTime& rDateTime, double fTimeInDays )
+ { return operator+( rDateTime, -fTimeInDays ); }
+ TOOLS_DLLPUBLIC friend DateTime operator +( const DateTime& rDateTime, const Time& rTime );
+ TOOLS_DLLPUBLIC friend DateTime operator -( const DateTime& rDateTime, const Time& rTime );
+ TOOLS_DLLPUBLIC friend double operator -( const DateTime& rDateTime1, const DateTime& rDateTime2 );
+ TOOLS_DLLPUBLIC friend long operator -( const DateTime& rDateTime, const Date& rDate )
+ { return (const Date&) rDateTime - rDate; }
+
+ DateTime& operator =( const DateTime& rDateTime );
+
+ void GetWin32FileDateTime( sal_uInt32 & rLower, sal_uInt32 & rUpper );
+ static DateTime CreateFromWin32FileDateTime( const sal_uInt32 & rLower, const sal_uInt32 & rUpper );
+};
+
+inline DateTime& DateTime::operator =( const DateTime& rDateTime )
+{
+ Date::operator=( rDateTime );
+ Time::operator=( rDateTime );
+ return *this;
+}
+
+#endif // _DATETIME_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/debug.hxx b/tools/inc/tools/debug.hxx
new file mode 100644
index 000000000000..3b3c753e5473
--- /dev/null
+++ b/tools/inc/tools/debug.hxx
@@ -0,0 +1,778 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _TOOLS_DEBUG_HXX
+#define _TOOLS_DEBUG_HXX
+
+#include "tools/toolsdllapi.h"
+
+#include <sal/types.h>
+#include <tools/solar.h>
+
+// ------------
+// - DBG_UITL -
+// ------------
+
+#ifdef DBG_UTIL
+
+// --- Dbg-Daten ---
+
+typedef void (*DbgPrintLine)( const sal_Char* pLine );
+typedef const sal_Char* (*DbgUsr)(const void* pThis );
+typedef void (*DbgTestSolarMutexProc)();
+
+#define DBG_BUF_MAXLEN 16384
+
+#define DBG_TEST_XTOR (0x00000FFF)
+#define DBG_TEST_XTOR_THIS (0x00000001)
+#define DBG_TEST_XTOR_FUNC (0x00000002)
+#define DBG_TEST_XTOR_EXIT (0x00000004)
+#define DBG_TEST_XTOR_REPORT (0x00000008)
+#define DBG_TEST_XTOR_TRACE (0x00000010)
+
+#define DBG_TEST_MEM (0x00FFF000)
+#define DBG_TEST_MEM_INIT (0x00001000)
+#define DBG_TEST_MEM_OVERWRITE (0x00002000)
+#define DBG_TEST_MEM_OVERWRITEFREE (0x00004000)
+#define DBG_TEST_MEM_POINTER (0x00008000)
+#define DBG_TEST_MEM_REPORT (0x00010000)
+#define DBG_TEST_MEM_TRACE (0x00020000)
+#define DBG_TEST_MEM_NEWDEL (0x00040000)
+#define DBG_TEST_MEM_XTOR (0x00080000)
+#define DBG_TEST_MEM_SYSALLOC (0x00100000)
+#define DBG_TEST_MEM_LEAKREPORT (0x00200000)
+
+#define DBG_TEST_PROFILING (0x01000000)
+#define DBG_TEST_RESOURCE (0x02000000)
+#define DBG_TEST_DIALOG (0x04000000)
+#define DBG_TEST_BOLDAPPFONT (0x08000000)
+
+#define DBG_OUT_NULL 0
+#define DBG_OUT_FILE 1
+#define DBG_OUT_WINDOW 2
+#define DBG_OUT_SHELL 3
+#define DBG_OUT_MSGBOX 4
+#define DBG_OUT_TESTTOOL 5
+#define DBG_OUT_DEBUGGER 6
+#define DBG_OUT_COREDUMP 7
+
+#define DBG_OUT_COUNT 8
+
+// user (runtime) defined output channels
+#define DBG_OUT_USER_CHANNEL_0 100
+
+#define DBGGUI_RESTORE 0
+#define DBGGUI_MINIMIZE 1
+#define DBGGUI_MAXIMIZE 2
+
+struct DbgData
+{
+ ULONG nTestFlags;
+ ULONG bOverwrite;
+ ULONG nTraceOut;
+ ULONG nWarningOut;
+ ULONG nErrorOut;
+ ULONG bHookOSLAssert;
+ BYTE bMemInit;
+ BYTE bMemBound;
+ BYTE bMemFree;
+ sal_Char aDebugName[260];
+ sal_Char aInclFilter[512];
+ sal_Char aExclFilter[512];
+ sal_Char aInclClassFilter[512];
+ sal_Char aExclClassFilter[512];
+ sal_Char aDbgWinState[50]; // DbgGUIData for VCL
+};
+
+struct DbgDataType
+{
+ void* pData;
+ sal_Char const * pName;
+};
+
+// --- Dbg-Prototypen ---
+
+#define DBG_FUNC_DEBUGSTART 1
+#define DBG_FUNC_DEBUGEND 2
+#define DBG_FUNC_GLOBALDEBUGEND 3
+#define DBG_FUNC_GETDATA 4
+#define DBG_FUNC_SAVEDATA 5
+#define DBG_FUNC_SETPRINTMSGBOX 6
+#define DBG_FUNC_SETPRINTWINDOW 7
+#define DBG_FUNC_SETPRINTTESTTOOL 8
+#define DBG_FUNC_MEMTEST 9
+#define DBG_FUNC_XTORINFO 10
+#define DBG_FUNC_MEMINFO 11
+#define DBG_FUNC_COREDUMP 12
+#define DBG_FUNC_ALLERROROUT 13
+#define DBG_FUNC_SETTESTSOLARMUTEX 14
+#define DBG_FUNC_TESTSOLARMUTEX 15
+#define DBG_FUNC_PRINTFILE 16
+#define DBG_FUNC_GETPRINTMSGBOX 17
+#define DBG_FUNC_FILTERMESSAGE 18 // new for #i38967
+#define DBG_FUNC_UPDATEOSLHOOK 19
+
+TOOLS_DLLPUBLIC void* DbgFunc( USHORT nAction, void* pData = NULL );
+
+inline void DbgUpdateOslHook( DbgData* pData )
+{
+ DbgFunc( DBG_FUNC_UPDATEOSLHOOK, pData );
+}
+
+inline void DbgDebugStart()
+{
+ DbgFunc( DBG_FUNC_DEBUGSTART );
+}
+
+inline void DbgDebugEnd()
+{
+ DbgFunc( DBG_FUNC_DEBUGEND );
+}
+
+inline void DbgGlobalDebugEnd()
+{
+ DbgFunc( DBG_FUNC_GLOBALDEBUGEND );
+}
+
+inline void DbgSetPrintMsgBox( DbgPrintLine pProc )
+{
+ DbgFunc( DBG_FUNC_SETPRINTMSGBOX, (void*)(long)pProc );
+}
+
+inline DbgPrintLine DbgGetPrintMsgBox()
+{
+ return (DbgPrintLine)(long)DbgFunc( DBG_FUNC_GETPRINTMSGBOX );
+}
+
+inline void DbgSetPrintWindow( DbgPrintLine pProc )
+{
+ DbgFunc( DBG_FUNC_SETPRINTWINDOW, (void*)(long)pProc );
+}
+
+inline void DbgSetPrintTestTool( DbgPrintLine pProc )
+{
+ DbgFunc( DBG_FUNC_SETPRINTTESTTOOL, (void*)(long)pProc );
+}
+
+typedef USHORT DbgChannelId;
+/** registers a user-defined channel for emitting the diagnostic messages
+
+ Note that such a user-defined channel cannot be revoked during the lifetime
+ of the process. Thus, it's the caller's responsibility to ensure that the
+ procedure to which ->pProc points remains valid.
+
+ @param pProc
+ the function for emitting the diagnostic messages
+ @return
+ a unique number for this channel, which can be used for ->DbgData::nErrorOut,
+ ->DbgData::nWarningOut and ->DbgData::nTraceOut
+ @see DBG_OUT_USER_CHANNEL_0
+
+ (In theory, this function could replace the other hard-coded channels. Well, at least
+ the ones for MsgBox, Window, Shell, TestTool. Perhaps in the next life ...)
+*/
+TOOLS_DLLPUBLIC DbgChannelId DbgRegisterUserChannel( DbgPrintLine pProc );
+
+inline BOOL DbgFilterMessage( const char* pMsg )
+{
+ return (BOOL)(long) DbgFunc( DBG_FUNC_FILTERMESSAGE, (void*)pMsg );
+}
+
+inline int DbgIsAllErrorOut()
+{
+ return (DbgFunc( DBG_FUNC_ALLERROROUT ) != 0);
+}
+
+inline DbgData* DbgGetData()
+{
+ return (DbgData*)DbgFunc( DBG_FUNC_GETDATA );
+}
+
+inline void DbgSaveData( const DbgData& rData )
+{
+ DbgFunc( DBG_FUNC_SAVEDATA, (void*)&rData );
+}
+
+inline ULONG DbgIsTraceOut()
+{
+ DbgData* pData = DbgGetData();
+ if ( pData )
+ return (pData->nTraceOut != DBG_OUT_NULL);
+ else
+ return FALSE;
+}
+
+inline ULONG DbgIsWarningOut()
+{
+ DbgData* pData = DbgGetData();
+ if ( pData )
+ return (pData->nWarningOut != DBG_OUT_NULL);
+ else
+ return FALSE;
+}
+
+inline ULONG DbgIsErrorOut()
+{
+ DbgData* pData = DbgGetData();
+ if ( pData )
+ return (pData->nErrorOut != DBG_OUT_NULL);
+ else
+ return FALSE;
+}
+
+inline ULONG DbgGetErrorOut() // Testtool: test wether to collect OSL_ASSERTions as well
+{
+ DbgData* pData = DbgGetData();
+ if ( pData )
+ return pData->nErrorOut;
+ else
+ return DBG_OUT_NULL;
+}
+
+inline ULONG DbgIsAssertWarning()
+{
+ return DbgIsWarningOut();
+}
+
+inline ULONG DbgIsAssert()
+{
+ return DbgIsErrorOut();
+}
+
+inline ULONG DbgIsResource()
+{
+ DbgData* pData = DbgGetData();
+ if ( pData )
+ return pData->nTestFlags & DBG_TEST_RESOURCE;
+ else
+ return FALSE;
+}
+
+inline ULONG DbgIsDialog()
+{
+ DbgData* pData = DbgGetData();
+ if ( pData )
+ return pData->nTestFlags & DBG_TEST_DIALOG;
+ else
+ return FALSE;
+}
+
+inline ULONG DbgIsBoldAppFont()
+{
+ DbgData* pData = DbgGetData();
+ if ( pData )
+ return pData->nTestFlags & DBG_TEST_BOLDAPPFONT;
+ else
+ return FALSE;
+}
+
+inline void DbgXtorInfo( sal_Char* pBuf )
+{
+ DbgFunc( DBG_FUNC_XTORINFO, (void*)pBuf );
+}
+
+inline void DbgMemInfo( sal_Char* pBuf )
+{
+ DbgFunc( DBG_FUNC_MEMINFO, (void*)pBuf );
+}
+
+inline void DbgCoreDump()
+{
+ DbgFunc( DBG_FUNC_COREDUMP );
+}
+
+inline void DbgSetTestSolarMutex( DbgTestSolarMutexProc pProc )
+{
+ DbgFunc( DBG_FUNC_SETTESTSOLARMUTEX, (void*)(long)pProc );
+}
+
+inline void DbgTestSolarMutex()
+{
+ DbgFunc( DBG_FUNC_TESTSOLARMUTEX );
+}
+
+inline void DbgPrintFile( const sal_Char* pLine )
+{
+ DbgFunc( DBG_FUNC_PRINTFILE, (void*)(sal_Char*)pLine );
+}
+
+// --- Dbg-StackTree-Functions ---
+
+TOOLS_DLLPUBLIC void DbgStartStackTree();
+TOOLS_DLLPUBLIC void DbgEndStackTree();
+void* DbgGetStackTree( ULONG nAlloc = 0 );
+void DbgFreeStackTree( void* p, ULONG nAlloc = 0 );
+void DbgPrintStackTree( void* p );
+
+// --- Dbg-Output ---
+
+#define DBG_OUT_TRACE 1
+#define DBG_OUT_WARNING 2
+#define DBG_OUT_ERROR 3
+
+TOOLS_DLLPUBLIC void DbgOut( const sal_Char* pMsg, USHORT nOutType = DBG_OUT_TRACE,
+ const sal_Char* pFile = NULL, USHORT nLine = 0 );
+TOOLS_DLLPUBLIC void DbgPrintShell(char const * message);
+TOOLS_DLLPUBLIC void DbgOutTypef( USHORT nOutType, const sal_Char* pFStr, ... );
+TOOLS_DLLPUBLIC void DbgOutf( const sal_Char* pFStr, ... );
+TOOLS_DLLPUBLIC void ImpDbgOutfBuf( sal_Char* pBuf, const sal_Char* pFStr, ... );
+
+inline void DbgTrace( const sal_Char* pMsg,
+ const sal_Char* pFile = NULL, USHORT nLine = 0 )
+{
+ DbgOut( pMsg, DBG_OUT_TRACE, pFile, nLine );
+}
+
+inline void DbgWarning( const sal_Char* pMsg,
+ const sal_Char* pFile = NULL, USHORT nLine = 0 )
+{
+ DbgOut( pMsg, DBG_OUT_WARNING, pFile, nLine );
+}
+
+inline void DbgError( const sal_Char* pMsg,
+ const sal_Char* pFile = NULL, USHORT nLine = 0 )
+{
+ DbgOut( pMsg, DBG_OUT_ERROR, pFile, nLine );
+}
+
+// --- Dbg-Test-Functions ---
+
+inline void DbgMemTest( void* p = NULL )
+{
+ DbgFunc( DBG_FUNC_MEMTEST, p );
+}
+
+#define DBG_PROF_START 1
+#define DBG_PROF_STOP 2
+#define DBG_PROF_CONTINUE 3
+#define DBG_PROF_PAUSE 4
+
+TOOLS_DLLPUBLIC void DbgProf( USHORT nAction, DbgDataType* );
+
+#define DBG_XTOR_CTOR 1
+#define DBG_XTOR_DTOR 2
+#define DBG_XTOR_CHKTHIS 3
+#define DBG_XTOR_CHKOBJ 4
+#define DBG_XTOR_DTOROBJ 0x8000
+
+TOOLS_DLLPUBLIC void DbgXtor( DbgDataType* pDbgData,
+ USHORT nAction, const void* pThis, DbgUsr fDbgUsr );
+
+class DbgXtorObj
+{
+private:
+ DbgDataType* pDbgData;
+ const void* pThis;
+ DbgUsr fDbgUsr;
+ USHORT nAction;
+
+public:
+ DbgXtorObj( DbgDataType* pData,
+ USHORT nAct, const void* pThs, DbgUsr fUsr )
+ {
+ DbgXtor( pData, nAct, pThs, fUsr );
+ pDbgData = pData;
+ nAction = nAct;
+ pThis = pThs;
+ fDbgUsr = fUsr;
+ }
+
+ ~DbgXtorObj()
+ {
+ DbgXtor( pDbgData, nAction | DBG_XTOR_DTOROBJ,
+ pThis, fDbgUsr );
+ }
+};
+
+// --- Dbg-Defines (intern) ---
+
+#define DBG_FUNC( aName ) DbgName_##aName()
+#define DBG_NAME( aName ) static DbgDataType aImpDbgData_##aName = { 0, #aName }; \
+ DbgDataType* DBG_FUNC( aName ) { return &aImpDbgData_##aName; }
+#define DBG_NAMEEX_VISIBILITY( aName, vis ) vis DbgDataType* DBG_FUNC( aName );
+#define DBG_NAMEEX( aName ) DBG_NAMEEX_VISIBILITY( aName, )
+
+// --- Dbg-Defines (extern) ---
+
+#define DBG_DEBUGSTART() DbgDebugStart()
+#define DBG_DEBUGEND() DbgDebugEnd()
+#define DBG_GLOBALDEBUGEND() DbgGlobalDebugEnd()
+
+#define DBG_STARTAPPEXECUTE() DbgStartStackTree()
+#define DBG_ENDAPPEXECUTE() DbgEndStackTree()
+
+#define DBG_MEMTEST() DbgMemTest()
+#define DBG_MEMTEST_PTR( p ) DbgMemTest( (void*)p )
+
+#define DBG_PROFSTART( aName ) \
+ DbgProf( DBG_PROF_START, DBG_FUNC( aName ) )
+
+#define DBG_PROFSTOP( aName ) \
+ DbgProf( DBG_PROF_STOP, DBG_FUNC( aName ) )
+
+#define DBG_PROFCONTINUE( aName ) \
+ DbgProf( DBG_PROF_CONTINUE, DBG_FUNC( aName ) )
+
+#define DBG_PROFPAUSE( aName ) \
+ DbgProf( DBG_PROF_PAUSE, DBG_FUNC( aName ) )
+
+#define DBG_CTOR( aName, fTest ) \
+ DbgXtorObj aDbgXtorObj( DBG_FUNC( aName ), \
+ DBG_XTOR_CTOR, \
+ (const void*)this, \
+ fTest )
+
+#define DBG_DTOR( aName, fTest ) \
+ DbgXtorObj aDbgXtorObj( DBG_FUNC( aName ), \
+ DBG_XTOR_DTOR, \
+ (const void*)this, \
+ fTest )
+
+#define DBG_CHKTHIS( aName, fTest ) \
+ DbgXtorObj aDbgXtorObj( DBG_FUNC( aName ), \
+ DBG_XTOR_CHKTHIS, \
+ (const void*)this, \
+ fTest )
+
+#define DBG_CHKOBJ( pObj, aName, fTest ) \
+ DbgXtor( DBG_FUNC( aName ), DBG_XTOR_CHKOBJ, \
+ (const void*)pObj, (DbgUsr)fTest )
+
+#define DBG_ASSERTWARNING( sCon, aWarning ) \
+do \
+{ \
+ if ( DbgIsAssertWarning() ) \
+ { \
+ if ( !( sCon ) ) \
+ { \
+ DbgWarning( aWarning, __FILE__, \
+ __LINE__ ); \
+ } \
+ } \
+} while(0)
+
+#define DBG_ASSERT( sCon, aError ) \
+do \
+{ \
+ if ( DbgIsAssert() ) \
+ { \
+ if ( !( sCon ) ) \
+ { \
+ DbgError( aError, \
+ __FILE__, __LINE__ ); \
+ } \
+ } \
+} while(0)
+
+#ifdef DBG_BINFILTER
+#define DBG_BF_ASSERT( sCon, aError ) \
+do \
+{ \
+ if ( !( sCon ) ) \
+ { \
+ DbgError( aError, \
+ __FILE__, __LINE__ ); \
+ } \
+} while(0)
+#else
+#define DBG_BF_ASSERT( sCon, aError ) ((void)0)
+#endif
+
+#define DBG_TRACE( aTrace ) \
+do \
+{ \
+ if ( DbgIsTraceOut() ) \
+ DbgTrace( aTrace ); \
+} while(0)
+#define DBG_TRACE1( aTrace, x1 ) \
+do \
+{ \
+ if ( DbgIsTraceOut() ) \
+ { \
+ DbgOutTypef( DBG_OUT_TRACE, aTrace, \
+ x1 ); \
+ } \
+} while(0)
+#define DBG_TRACE2( aTrace, x1, x2 ) \
+do \
+{ \
+ if ( DbgIsTraceOut() ) \
+ { \
+ DbgOutTypef( DBG_OUT_TRACE, aTrace, \
+ x1, x2 ); \
+ } \
+} while(0)
+#define DBG_TRACE3( aTrace, x1, x2, x3 ) \
+do \
+{ \
+ if ( DbgIsTraceOut() ) \
+ { \
+ DbgOutTypef( DBG_OUT_TRACE, aTrace, \
+ x1, x2, x3 ); \
+ } \
+} while(0)
+#define DBG_TRACE4( aTrace, x1, x2, x3, x4 ) \
+do \
+{ \
+ if ( DbgIsTraceOut() ) \
+ { \
+ DbgOutTypef( DBG_OUT_TRACE, aTrace, \
+ x1, x2, x3, x4 ); \
+ } \
+} while(0)
+#define DBG_TRACE5( aTrace, x1, x2, x3, x4, x5 ) \
+do \
+{ \
+ if ( DbgIsTraceOut() ) \
+ { \
+ DbgOutTypef( DBG_OUT_TRACE, aTrace, \
+ x1, x2, x3, x4, x5 ); \
+ } \
+} while(0)
+#define DBG_TRACEFILE( aTrace ) \
+do \
+{ \
+ if ( DbgIsTraceOut() ) \
+ DbgTrace( aTrace, __FILE__, __LINE__ ); \
+} while(0)
+
+#define DBG_WARNING( aWarning ) \
+do \
+{ \
+ if ( DbgIsWarningOut() ) \
+ DbgWarning( aWarning ); \
+} while(0)
+#define DBG_WARNING1( aWarning, x1 ) \
+do \
+{ \
+ if ( DbgIsWarningOut() ) \
+ { \
+ DbgOutTypef( DBG_OUT_WARNING, aWarning, \
+ x1 ); \
+ } \
+} while(0)
+#define DBG_WARNING2( aWarning, x1, x2 ) \
+do \
+{ \
+ if ( DbgIsWarningOut() ) \
+ { \
+ DbgOutTypef( DBG_OUT_WARNING, aWarning, \
+ x1, x2 ); \
+ } \
+} while(0)
+#define DBG_WARNING3( aWarning, x1, x2, x3 ) \
+do \
+{ \
+ if ( DbgIsWarningOut() ) \
+ { \
+ DbgOutTypef( DBG_OUT_WARNING, aWarning, \
+ x1, x2, x3 ); \
+ } \
+} while(0)
+#define DBG_WARNING4( aWarning, x1, x2, x3, x4 ) \
+do \
+{ \
+ if ( DbgIsWarningOut() ) \
+ { \
+ DbgOutTypef( DBG_OUT_WARNING, aWarning, \
+ x1, x2, x3, x4 ); \
+ } \
+} while(0)
+#define DBG_WARNING5( aWarning, x1, x2, x3, x4, x5 )\
+do \
+{ \
+ if ( DbgIsWarningOut() ) \
+ { \
+ DbgOutTypef( DBG_OUT_WARNING, aWarning, \
+ x1, x2, x3, x4, x5 ); \
+ } \
+} while(0)
+#define DBG_WARNINGFILE( aWarning ) \
+do \
+{ \
+ if ( DbgIsWarningOut() ) \
+ DbgWarning( aWarning, __FILE__, __LINE__ ); \
+} while(0)
+
+#define DBG_ERROR( aError ) \
+do \
+{ \
+ if ( DbgIsErrorOut() ) \
+ DbgError( aError ); \
+} while(0)
+#define DBG_ERROR1( aError, x1 ) \
+do \
+{ \
+ if ( DbgIsErrorOut() ) \
+ { \
+ DbgOutTypef( DBG_OUT_ERROR, aError, \
+ x1 ); \
+ } \
+} while(0)
+#define DBG_ERROR2( aError, x1, x2 ) \
+do \
+{ \
+ if ( DbgIsErrorOut() ) \
+ { \
+ DbgOutTypef( DBG_OUT_ERROR, aError, \
+ x1, x2 ); \
+ } \
+} while(0)
+#define DBG_ERROR3( aError, x1, x2, x3 ) \
+do \
+{ \
+ if ( DbgIsErrorOut() ) \
+ { \
+ DbgOutTypef( DBG_OUT_ERROR, aError, \
+ x1, x2, x3 ); \
+ } \
+} while(0)
+#define DBG_ERROR4( aError, x1, x2, x3, x4 ) \
+do \
+{ \
+ if ( DbgIsErrorOut() ) \
+ { \
+ DbgOutTypef( DBG_OUT_ERROR, aError, \
+ x1, x2, x3, x4 ); \
+ } \
+} while(0)
+#define DBG_ERROR5( aError, x1, x2, x3, x4, x5 ) \
+do \
+{ \
+ if ( DbgIsErrorOut() ) \
+ { \
+ DbgOutTypef( DBG_OUT_ERROR, aError, \
+ x1, x2, x3, x4, x5 ); \
+ } \
+} while(0)
+#define DBG_ERRORFILE( aError ) \
+do \
+{ \
+ if ( DbgIsErrorOut() ) \
+ DbgError( aError, __FILE__, __LINE__ ); \
+} while(0)
+
+#define DBG_TESTSOLARMUTEX() \
+do \
+{ \
+ DbgTestSolarMutex(); \
+} while(0)
+
+// --- Dbg-Defines (An/Ausschlaten) ---
+
+#define DBG_INSTOUTTRACE( nOut ) \
+do \
+{ \
+ DbgGetData()->nTraceOut = nOut; \
+} while(0)
+
+#define DBG_INSTOUTWARNING( nOut ) \
+do \
+{ \
+ DbgGetData()->nWarningOut = nOut; \
+} while(0)
+
+#define DBG_INSTOUTERROR( nOut ) \
+do \
+{ \
+ DbgGetData()->nErrorOut = nOut; \
+} while(0)
+
+#else
+
+// ---------------
+// - NO DBG_UITL -
+// ---------------
+
+struct DbgData;
+struct DbgGUIData;
+struct DbgDataType;
+
+typedef void (*DbgPrintLine)( const sal_Char* pLine );
+typedef const sal_Char* (*DbgUsr)(const void* pThis );
+
+#define DBG_DEBUGSTART() ((void)0)
+#define DBG_DEBUGEND() ((void)0)
+#define DBG_GLOBALDEBUGEND() ((void)0)
+
+#define DBG_STARTAPPEXECUTE() ((void)0)
+#define DBG_ENDAPPEXECUTE() ((void)0)
+
+#define DBG_MEMTEST() ((void)0)
+#define DBG_MEMTEST_PTR( p ) ((void)0)
+
+#define DBG_NAME( aName )
+#define DBG_NAMEEX( aName )
+#define DBG_NAMEEX_VISIBILITY( aName, vis )
+
+#define DBG_PROFSTART( aName ) ((void)0)
+#define DBG_PROFSTOP( aName ) ((void)0)
+#define DBG_PROFCONTINUE( aName ) ((void)0)
+#define DBG_PROFPAUSE( aName ) ((void)0)
+
+#define DBG_CTOR( aName, fTest ) ((void)0)
+#define DBG_DTOR( aName, fTest ) ((void)0)
+#define DBG_CHKTHIS( aName, fTest ) ((void)0)
+#define DBG_CHKOBJ( pObj, aName, fTest ) ((void)0)
+
+#define DBG_ASSERTWARNING( sCon, aWarning ) ((void)0)
+#define DBG_ASSERT( sCon, aError ) ((void)0)
+#define DBG_BF_ASSERT( sCon, aError ) ((void)0)
+#define DBG_TRACE( aTrace ) ((void)0)
+#define DBG_TRACE1( aTrace, x1 ) ((void)0)
+#define DBG_TRACE2( aTrace, x1, x2 ) ((void)0)
+#define DBG_TRACE3( aTrace, x1, x2, x3 ) ((void)0)
+#define DBG_TRACE4( aTrace, x1, x2, x3, x4 ) ((void)0)
+#define DBG_TRACE5( aTrace, x1, x2, x3, x4, x5 ) ((void)0)
+#define DBG_TRACEFILE( aTrace ) ((void)0)
+#define DBG_WARNING( aWarning ) ((void)0)
+#define DBG_WARNING1( aWarning, x1 ) ((void)0)
+#define DBG_WARNING2( aWarning, x1, x2 ) ((void)0)
+#define DBG_WARNING3( aWarning, x1, x2, x3 ) ((void)0)
+#define DBG_WARNING4( aWarning, x1, x2, x3, x4 ) ((void)0)
+#define DBG_WARNING5( aWarning, x1, x2, x3, x4, x5 ) ((void)0)
+#define DBG_WARNINGFILE( aWarning ) ((void)0)
+#define DBG_ERROR( aError ) ((void)0)
+#define DBG_ERROR1( aError, x1 ) ((void)0)
+#define DBG_ERROR2( aError, x1, x2 ) ((void)0)
+#define DBG_ERROR3( aError, x1, x2, x3 ) ((void)0)
+#define DBG_ERROR4( aError, x1, x2, x3, x4 ) ((void)0)
+#define DBG_ERROR5( aError, x1, x2, x3, x4, x5 ) ((void)0)
+#define DBG_ERRORFILE( aError ) ((void)0)
+
+#define DBG_TESTSOLARMUTEX() ((void)0)
+
+#define DBG_INSTOUTTRACE( nOut ) ((void)0)
+#define DBG_INSTOUTWARNING( nOut ) ((void)0)
+#define DBG_INSTOUTERROR( nOut ) ((void)0)
+
+#endif
+
+#endif // _TOOLS_DEBUG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/diagnose_ex.h b/tools/inc/tools/diagnose_ex.h
new file mode 100644
index 000000000000..e20884022bee
--- /dev/null
+++ b/tools/inc/tools/diagnose_ex.h
@@ -0,0 +1,178 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef TOOLS_DIAGNOSE_EX_H
+#define TOOLS_DIAGNOSE_EX_H
+
+#include <osl/diagnose.h>
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+#include <boost/current_function.hpp>
+
+
+#define OSL_UNUSED( expression ) \
+ (void)(expression)
+
+#if OSL_DEBUG_LEVEL > 0
+
+ #include <cppuhelper/exc_hlp.hxx>
+ #include <osl/diagnose.h>
+ #include <osl/thread.h>
+ #include <boost/current_function.hpp>
+ #include <typeinfo>
+
+ /** reports a caught UNO exception via OSL diagnostics
+
+ Note that whenever you use this, it might be an indicator that your error
+ handling is not correct ....
+ */
+ #define DBG_UNHANDLED_EXCEPTION() \
+ ::com::sun::star::uno::Any caught( ::cppu::getCaughtException() ); \
+ ::rtl::OString sMessage( "caught an exception!" ); \
+ sMessage += "\nin function:"; \
+ sMessage += BOOST_CURRENT_FUNCTION; \
+ sMessage += "\ntype: "; \
+ sMessage += ::rtl::OString( caught.getValueTypeName().getStr(), caught.getValueTypeName().getLength(), osl_getThreadTextEncoding() ); \
+ ::com::sun::star::uno::Exception exception; \
+ caught >>= exception; \
+ if ( exception.Message.getLength() ) \
+ { \
+ sMessage += "\nmessage: "; \
+ sMessage += ::rtl::OString( exception.Message.getStr(), exception.Message.getLength(), osl_getThreadTextEncoding() ); \
+ } \
+ if ( exception.Context.is() ) \
+ { \
+ const char* pContext = typeid( *exception.Context.get() ).name(); \
+ sMessage += "\ncontext: "; \
+ sMessage += pContext; \
+ } \
+ sMessage += "\n"; \
+ OSL_ENSURE( false, sMessage )
+
+#else // OSL_DEBUG_LEVEL
+
+ #define DBG_UNHANDLED_EXCEPTION()
+
+#endif // OSL_DEBUG_LEVEL
+
+
+/** This macro asserts the given condition (in debug mode), and throws
+ an IllegalArgumentException afterwards.
+ */
+#define ENSURE_ARG_OR_THROW(c, m) if( !(c) ) { \
+ OSL_ENSURE(c, m); \
+ throw ::com::sun::star::lang::IllegalArgumentException( \
+ ::rtl::OUString::createFromAscii(BOOST_CURRENT_FUNCTION) + \
+ ::rtl::OUString::createFromAscii(",\n"m), \
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >(), \
+ 0 ); }
+#define ENSURE_ARG_OR_THROW2(c, m, ifc, arg) if( !(c) ) { \
+ OSL_ENSURE(c, m); \
+ throw ::com::sun::star::lang::IllegalArgumentException( \
+ ::rtl::OUString::createFromAscii(BOOST_CURRENT_FUNCTION) + \
+ ::rtl::OUString::createFromAscii(",\n"m), \
+ ifc, \
+ arg ); }
+
+/** This macro asserts the given condition (in debug mode), and throws
+ an RuntimeException afterwards.
+ */
+#define ENSURE_OR_THROW(c, m) if( !(c) ) { \
+ OSL_ENSURE(c, m); \
+ throw ::com::sun::star::uno::RuntimeException( \
+ ::rtl::OUString::createFromAscii(BOOST_CURRENT_FUNCTION) + \
+ ::rtl::OUString::createFromAscii(",\n"m), \
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() ); }
+#define ENSURE_OR_THROW2(c, m, ifc) if( !(c) ) { \
+ OSL_ENSURE(c, m); \
+ throw ::com::sun::star::uno::RuntimeException( \
+ ::rtl::OUString::createFromAscii(BOOST_CURRENT_FUNCTION) + \
+ ::rtl::OUString::createFromAscii(",\n"m), \
+ ifc ); }
+
+/** This macro asserts the given condition (in debug mode), and
+ returns the given value afterwards.
+ */
+#define ENSURE_OR_RETURN(c, m, r) if( !(c) ) { \
+ OSL_ENSURE(c, m); \
+ return r; }
+
+/** This macro asserts the given condition (in debug mode), and
+ returns false afterwards.
+ */
+#define ENSURE_OR_RETURN_FALSE(c, m) \
+ ENSURE_OR_RETURN(c, m, false)
+
+/** This macro asserts the given condition (in debug mode), and
+ returns afterwards, without return value "void".
+ */
+#define ENSURE_OR_RETURN_VOID( c, m ) \
+ if( !(c) ) \
+ { \
+ OSL_ENSURE( c, m ); \
+ return; \
+ }
+
+
+
+/** This macro asserts the given condition (in debug mode), and
+ returns afterwards, without return value "void".
+ */
+#define ENSURE_OR_RETURN_VOID( c, m ) \
+ if( !(c) ) \
+ { \
+ OSL_ENSURE( c, m ); \
+ return; \
+ }
+
+/** asserts a given condition (in debug mode), and continues the most-inner
+ loop if the condition is not met
+*/
+#define ENSURE_OR_CONTINUE( c, m ) \
+ if ( !(c) ) \
+ { \
+ OSL_ENSURE( false, m ); \
+ continue; \
+ }
+
+/** asserts a given condition (in debug mode), and continues the most-inner
+ loop if the condition is not met
+*/
+#define ENSURE_OR_BREAK( c, m ) \
+ if ( !(c) ) \
+ { \
+ OSL_ENSURE( false, m ); \
+ break; \
+ }
+
+#endif // TOOLS_DIAGNOSE_EX_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/download.hxx b/tools/inc/tools/download.hxx
new file mode 100644
index 000000000000..758e71c75491
--- /dev/null
+++ b/tools/inc/tools/download.hxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DOWNLOAD_HXX
+#define _DOWNLOAD_HXX
+
+// Forward declarations
+class String;
+class Link;
+
+#define DOWNLOAD_SUCCESS 0
+#define DOWNLOAD_CONNECT 1
+#define DOWNLOAD_LOCATION 2
+#define DOWNLOAD_ABORT 3
+#define DOWNLOAD_FILEACCESS 4
+#define DOWNLOAD_INSTALL 5
+#define DOWNLOAD_ERROR 6
+
+class Downloader
+/* ***************************************************************************
+Purpose: Abstract base class for a file downloader
+*************************************************************************** */
+{
+public:
+ Downloader() {};
+
+ virtual void Download(const String &rDestLocation,
+ const String &rSourceLocation,
+ const Link &rFinishedLink) = 0;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/dynary.hxx b/tools/inc/tools/dynary.hxx
new file mode 100644
index 000000000000..85a2cac7a917
--- /dev/null
+++ b/tools/inc/tools/dynary.hxx
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DYNARY_HXX
+#define _DYNARY_HXX
+
+#include <tools/solar.h>
+#include <tools/contnr.hxx>
+
+// ------------
+// - DynArray -
+// ------------
+
+#define DYNARRAY_ENTRY_NOTFOUND CONTAINER_ENTRY_NOTFOUND
+
+class DynArray : private Container
+{
+public:
+ using Container::SetSize;
+ using Container::GetSize;
+ using Container::Clear;
+
+ DynArray( ULONG nSize = 16 ) : Container( nSize ) {}
+ DynArray( const DynArray& rAry ) : Container( rAry ) {}
+
+ void* Put( ULONG nIndex, void* p )
+ { return Container::Replace( p, nIndex ); }
+ void* Get( ULONG nIndex ) const
+ { return Container::GetObject( nIndex ); }
+
+ ULONG GetIndex( const void* p ) const
+ { return Container::GetPos( p ); }
+ ULONG GetIndex( const void* p, ULONG nStartIndex,
+ BOOL bForward = TRUE ) const
+ { return Container::GetPos( p, nStartIndex, bForward ); }
+
+ DynArray& operator =( const DynArray& rAry )
+ { Container::operator =( rAry ); return *this; }
+
+ BOOL operator ==( const DynArray& rAry ) const
+ { return Container::operator ==( rAry ); }
+ BOOL operator !=( const DynArray& rAry ) const
+ { return Container::operator !=( rAry ); }
+};
+
+// --------------------
+// - DECLARE_DYNARRAY -
+// --------------------
+
+#define DECLARE_DYNARRAY( ClassName, Type ) \
+class ClassName : private DynArray \
+{ \
+public: \
+ using DynArray::SetSize; \
+ using DynArray::GetSize; \
+ using DynArray::Clear; \
+ \
+ ClassName( ULONG nSize = 16 ) : \
+ DynArray( nSize ) {} \
+ ClassName( const ClassName& rClassName ) : \
+ DynArray( rClassName ) {} \
+ \
+ Type Put( ULONG nIndex, Type p ) \
+ { return (Type)DynArray::Put( nIndex, (void*)p ); } \
+ Type Get( ULONG nIndex ) const \
+ { return (Type)DynArray::Get( nIndex ); } \
+ \
+ ULONG GetIndex( const Type p ) const \
+ { return DynArray::GetIndex( (const void*)p ); } \
+ ULONG GetIndex( const Type p, ULONG nStartIndex, \
+ BOOL bForward = TRUE ) const \
+ { return DynArray::GetIndex( (const void*)p, \
+ nStartIndex, \
+ bForward ); } \
+ \
+ ClassName& operator =( const ClassName& rClassName ) \
+ { DynArray::operator =( rClassName ); \
+ return *this; } \
+ \
+ BOOL operator ==( const ClassName& rAry ) const \
+ { return DynArray::operator ==( rAry ); } \
+ BOOL operator !=( const ClassName& rAry ) const \
+ { return DynArray::operator !=( rAry ); } \
+};
+
+#endif // _DYNARY_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/eacopier.hxx b/tools/inc/tools/eacopier.hxx
new file mode 100644
index 000000000000..c2b0e7fb5161
--- /dev/null
+++ b/tools/inc/tools/eacopier.hxx
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _EACOPIER_HXX
+#define _EACOPIER_HXX
+
+#include <tools/solar.h>
+
+class SvFileStream;
+
+class EA_Copier
+{
+ static EA_Copier* _pCopier;
+
+public:
+ static void Register( EA_Copier* pCopier );
+ static EA_Copier* Get();
+
+ virtual ~EA_Copier();
+ virtual BOOL Copy( const SvFileStream& rFrom, const SvFileStream& rTo ) const = 0;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/errcode.hxx b/tools/inc/tools/errcode.hxx
new file mode 100644
index 000000000000..aa78bc2e2157
--- /dev/null
+++ b/tools/inc/tools/errcode.hxx
@@ -0,0 +1,324 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _ERRCODE_HXX
+#define _ERRCODE_HXX
+
+#ifndef __RSC
+#include <tools/solar.h>
+#endif
+
+/*
+
+01234567012345670123456701234567
+|| || ||| || |
+Warning || || |
+ | || || || |
+ Dynamic || || |
+ | || || |
+ Subsystembereiche | |
+ | || |
+ | || |
+ | || |
+ Class |
+ | |
+ | |
+ | |
+ Code
+*/
+
+#define ERRCODE_BUTTON_OK 0x01
+#define ERRCODE_BUTTON_CANCEL 0x02
+#define ERRCODE_BUTTON_RETRY 0x04
+#define ERRCODE_BUTTON_OK_CANCEL 0x03
+#define ERRCODE_BUTTON_OK_RETRY_CANCEL 0x07
+#define ERRCODE_BUTTON_NO 0x08
+#define ERRCODE_BUTTON_YES 0x10
+#define ERRCODE_BUTTON_YES_NO 0x18
+#define ERRCODE_BUTTON_YES_NO_CANCEL 0x1a
+
+#define ERRCODE_BUTTON_DEF_OK 0x100
+#define ERRCODE_BUTTON_DEF_CANCEL 0x200
+#define ERRCODE_BUTTON_DEF_YES 0x300
+#define ERRCODE_BUTTON_DEF_NO 0x400
+
+#define ERRCODE_MSG_ERROR 0x1000
+#define ERRCODE_MSG_WARNING 0x2000
+#define ERRCODE_MSG_INFO 0x3000
+#define ERRCODE_MSG_QUERY 0x4000
+
+#define ERRCODE_ERROR_MASK 0x3fffffffUL
+#define ERRCODE_WARNING_MASK 0x80000000UL
+#define ERRCODE_RES_MASK 0x7fff
+
+#define ERRCODE_CLASS_SHIFT 8
+#define ERRCODE_AREA_SHIFT 13
+#define ERRCODE_DYNAMIC_SHIFT 26
+
+#define ERRCODE_CLASS_MASK (31UL <<ERRCODE_CLASS_SHIFT)
+
+#define ERRCODE_DYNAMIC_START (1UL <<ERRCODE_DYNAMIC_SHIFT)
+#define ERRCODE_DYNAMIC_COUNT 31UL
+#define ERRCODE_DYNAMIC_MASK (31UL <<ERRCODE_DYNAMIC_SHIFT)
+
+#ifdef __RSC
+
+#define ERRCODE_TOERRID(x) (x & ~ERRCODE_DYNAMIC_MASK)
+#define ERRCODE_TOERROR(x) \
+ ((x & ERRCODE_WARNING_MASK) ? 0 : (x & ERRCODE_ERROR_MASK))
+
+#else
+
+typedef ULONG ErrCode;
+
+inline ULONG ERRCODE_TOERRID( ULONG x )
+{
+ return x & ~ERRCODE_DYNAMIC_MASK;
+}
+
+inline ULONG ERRCODE_TOERROR( ULONG x )
+{
+ return ((x & ERRCODE_WARNING_MASK) ? 0 : (x & ERRCODE_ERROR_MASK));
+}
+
+#endif
+
+#define ERRCODE_AREA_TOOLS (0UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_SV (1UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_SFX (2UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_INET (3UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_IO ERRCODE_AREA_TOOLS
+
+#define ERRCODE_AREA_LIB1 (8UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_SVX ERRCODE_AREA_LIB1
+#define ERRCODE_AREA_SVX_END (ERRCODE_AREA_SO-1)
+#define ERRCODE_AREA_SO (9UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_SO_END (ERRCODE_AREA_SBX-1)
+#define ERRCODE_AREA_SBX (10UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_SBX_END ((11UL << ERRCODE_AREA_SHIFT) - 1)
+#define ERRCODE_AREA_DB (11UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_DB_END ((12UL << ERRCODE_AREA_SHIFT) - 1)
+#define ERRCODE_AREA_JAVA (12UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_JAVA_END ((13UL << ERRCODE_AREA_SHIFT) - 1)
+#define ERRCODE_AREA_UUI (13UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_UUI_END ((14UL << ERRCODE_AREA_SHIFT) - 1)
+#define ERRCODE_AREA_LIB2 (14UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_LIB2_END ((15UL << ERRCODE_AREA_SHIFT) - 1)
+#define ERRCODE_AREA_CHAOS (15UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_CHAOS_END ((16UL << ERRCODE_AREA_SHIFT) - 1)
+
+#define ERRCODE_AREA_APP1 (32UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_APP2 (40UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_APP3 (48UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_APP4 (56UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_APP5 (64UL << ERRCODE_AREA_SHIFT)
+#define ERRCODE_AREA_APP6 (72UL << ERRCODE_AREA_SHIFT)
+
+#define ERRCODE_AREA_SC ERRCODE_AREA_APP1
+#define ERRCODE_AREA_SC_END (ERRCODE_AREA_APP2-1)
+
+#define ERRCODE_AREA_SD ERRCODE_AREA_APP2
+#define ERRCODE_AREA_SD_END (ERRCODE_AREA_APP3-1)
+
+#define ERRCODE_AREA_SW ERRCODE_AREA_APP4
+#define ERRCODE_AREA_SW_END (ERRCODE_AREA_APP5-1)
+
+#define ERRCODE_AREA_OFA ERRCODE_AREA_APP5
+#define ERRCODE_AREA_OFA_END (ERRCODE_AREA_APP6-1)
+
+#define ERRCODE_CLASS_NONE (0UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_ABORT (1UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_GENERAL (2UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_NOTEXISTS (3UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_ALREADYEXISTS (4UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_ACCESS (5UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_PATH (6UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_LOCKING (7UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_PARAMETER (8UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_SPACE (9UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_NOTSUPPORTED (10UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_READ (11UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_WRITE (12UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_UNKNOWN (13UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_VERSION (14UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_FORMAT (15UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_CREATE (16UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_IMPORT (17UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_EXPORT (18UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_FILTER (19UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_SO (20UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_SBX (21UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_RUNTIME (22UL << ERRCODE_CLASS_SHIFT)
+#define ERRCODE_CLASS_COMPILER (23UL << ERRCODE_CLASS_SHIFT)
+
+#define ERRCODE_NONE (0UL)
+#define ERRCODE_ABORT ERRCODE_IO_ABORT
+
+#define ERRCODE_IO_MISPLACEDCHAR (1UL |ERRCODE_CLASS_PARAMETER|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_NOTEXISTS (2UL |ERRCODE_CLASS_NOTEXISTS|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_ALREADYEXISTS (3UL |ERRCODE_CLASS_ALREADYEXISTS|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_NOTADIRECTORY (4UL |ERRCODE_CLASS_PARAMETER|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_NOTAFILE (5UL |ERRCODE_CLASS_PARAMETER|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_INVALIDDEVICE (6UL |ERRCODE_CLASS_PATH|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_ACCESSDENIED (7UL |ERRCODE_CLASS_ACCESS|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_LOCKVIOLATION (8UL |ERRCODE_CLASS_LOCKING|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_OUTOFSPACE (9UL |ERRCODE_CLASS_SPACE|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_ISWILDCARD (11UL|ERRCODE_CLASS_PARAMETER|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_NOTSUPPORTED (12UL|ERRCODE_CLASS_NOTSUPPORTED|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_GENERAL (13UL|ERRCODE_CLASS_GENERAL|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_TOOMANYOPENFILES (14UL|ERRCODE_CLASS_SPACE|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_CANTREAD (15UL|ERRCODE_CLASS_READ|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_CANTWRITE (16UL|ERRCODE_CLASS_WRITE|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_OUTOFMEMORY (17UL|ERRCODE_CLASS_SPACE|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_CANTSEEK (18UL|ERRCODE_CLASS_GENERAL|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_CANTTELL (19UL|ERRCODE_CLASS_GENERAL|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_WRONGVERSION (20UL|ERRCODE_CLASS_VERSION|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_WRONGFORMAT (21UL|ERRCODE_CLASS_FORMAT|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_INVALIDCHAR (22UL|ERRCODE_CLASS_PARAMETER|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_UNKNOWN (23UL|ERRCODE_CLASS_UNKNOWN|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_INVALIDACCESS (24UL|ERRCODE_CLASS_ACCESS|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_CANTCREATE (25UL|ERRCODE_CLASS_CREATE|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_INVALIDPARAMETER (26UL|ERRCODE_CLASS_PARAMETER|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_ABORT (27UL|ERRCODE_CLASS_ABORT|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_NOTEXISTSPATH (28UL |ERRCODE_CLASS_NOTEXISTS|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_PENDING (29UL |ERRCODE_CLASS_NOTEXISTS|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_RECURSIVE (30UL |ERRCODE_CLASS_PARAMETER|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_NAMETOOLONG (31UL |ERRCODE_CLASS_PARAMETER|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_INVALIDLENGTH (32UL |ERRCODE_CLASS_PARAMETER|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_CURRENTDIR (33UL |ERRCODE_CLASS_PARAMETER|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_NOTSAMEDEVICE (34UL |ERRCODE_CLASS_PARAMETER|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_DEVICENOTREADY (35UL |ERRCODE_CLASS_READ|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_BADCRC (36UL |ERRCODE_CLASS_READ|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_WRITEPROTECTED (37UL |ERRCODE_CLASS_ACCESS|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_BROKENPACKAGE (38UL |ERRCODE_CLASS_FORMAT|\
+ ERRCODE_AREA_IO)
+#define ERRCODE_IO_NOTSTORABLEINBINARYFORMAT (39UL |ERRCODE_CLASS_FORMAT|\
+ ERRCODE_AREA_IO)
+
+// FsysErrorCodes
+
+#define FSYS_ERR_OK ERRCODE_NONE
+#define FSYS_ERR_MISPLACEDCHAR ERRCODE_IO_MISPLACEDCHAR
+#define FSYS_ERR_INVALIDCHAR ERRCODE_IO_INVALIDCHAR
+#define FSYS_ERR_NOTEXISTS ERRCODE_IO_NOTEXISTS
+#define FSYS_ERR_ALREADYEXISTS ERRCODE_IO_ALREADYEXISTS
+#define FSYS_ERR_NOTADIRECTORY ERRCODE_IO_NOTADIRECTORY
+#define FSYS_ERR_NOTAFILE ERRCODE_IO_NOTAFILE
+#define FSYS_ERR_INVALIDDEVICE ERRCODE_IO_INVALIDDEVICE
+#define FSYS_ERR_ACCESSDENIED ERRCODE_IO_ACCESSDENIED
+#define FSYS_ERR_LOCKVIOLATION ERRCODE_IO_LOCKVIOLATION
+#define FSYS_ERR_VOLUMEFULL ERRCODE_IO_OUTOFSPACE
+#define FSYS_ERR_ISWILDCARD ERRCODE_IO_ISWILDCARD
+#define FSYS_ERR_NOTSUPPORTED ERRCODE_IO_NOTSUPPORTED
+#define FSYS_ERR_UNKNOWN ERRCODE_IO_UNKNOWN
+
+// StreamErrorCodes
+
+#define SVSTREAM_OK ERRCODE_NONE
+
+#define SVSTREAM_GENERALERROR ERRCODE_IO_GENERAL
+#define SVSTREAM_FILE_NOT_FOUND ERRCODE_IO_NOTEXISTS
+#define SVSTREAM_PATH_NOT_FOUND ERRCODE_IO_NOTEXISTSPATH
+#define SVSTREAM_TOO_MANY_OPEN_FILES ERRCODE_IO_TOOMANYOPENFILES
+#define SVSTREAM_ACCESS_DENIED ERRCODE_IO_ACCESSDENIED
+#define SVSTREAM_SHARING_VIOLATION ERRCODE_IO_LOCKVIOLATION
+#define SVSTREAM_LOCKING_VIOLATION ERRCODE_IO_LOCKVIOLATION
+#define SVSTREAM_SHARE_BUFF_EXCEEDED ERRCODE_IO_LOCKVIOLATION
+
+#define SVSTREAM_INVALID_ACCESS ERRCODE_IO_INVALIDACCESS
+#define SVSTREAM_INVALID_HANDLE ERRCODE_IO_GENERAL
+#define SVSTREAM_CANNOT_MAKE ERRCODE_IO_CANTCREATE
+#define SVSTREAM_INVALID_PARAMETER ERRCODE_IO_INVALIDPARAMETER
+
+#define SVSTREAM_READ_ERROR ERRCODE_IO_CANTREAD
+#define SVSTREAM_WRITE_ERROR ERRCODE_IO_CANTWRITE
+#define SVSTREAM_SEEK_ERROR ERRCODE_IO_CANTSEEK
+#define SVSTREAM_TELL_ERROR ERRCODE_IO_CANTTELL
+
+#define SVSTREAM_OUTOFMEMORY ERRCODE_IO_OUTOFMEMORY
+
+#define SVSTREAM_FILEFORMAT_ERROR ERRCODE_IO_WRONGFORMAT
+#define SVSTREAM_WRONGVERSION ERRCODE_IO_WRONGVERSION
+
+#define SVSTREAM_DISK_FULL ERRCODE_IO_OUTOFSPACE
+
+// Fuer die EditEngine:
+#define SVSTREAM_ERRBASE_USER ERRCODE_AREA_LIB1
+
+#define PRINTER_OK ERRCODE_NONE
+#define PRINTER_ABORT ERRCODE_IO_ABORT
+#define PRINTER_OUTOFMEMORY ERRCODE_IO_OUTOFMEMORY
+#define PRINTER_GENERALERROR ERRCODE_IO_GENERAL
+#define PRINTER_ACCESSDENIED ERRCODE_IO_ACCESSDENIED
+
+#define ERRCODE_INET_NAME_RESOLVE (ERRCODE_AREA_INET | ERRCODE_CLASS_READ | 1)
+#define ERRCODE_INET_CONNECT (ERRCODE_AREA_INET | ERRCODE_CLASS_READ | 2)
+#define ERRCODE_INET_READ (ERRCODE_AREA_INET | ERRCODE_CLASS_READ | 3)
+#define ERRCODE_INET_WRITE (ERRCODE_AREA_INET | ERRCODE_CLASS_WRITE| 4)
+#define ERRCODE_INET_GENERAL (ERRCODE_AREA_INET | ERRCODE_CLASS_WRITE |5)
+#define ERRCODE_INET_OFFLINE (ERRCODE_AREA_INET | ERRCODE_CLASS_READ |6)
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/errinf.hxx b/tools/inc/tools/errinf.hxx
new file mode 100644
index 000000000000..2a0afba0884c
--- /dev/null
+++ b/tools/inc/tools/errinf.hxx
@@ -0,0 +1,246 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __RSC
+
+#ifndef _EINF_HXX
+#define _EINF_HXX
+
+#include <limits.h>
+#include <tools/rtti.hxx>
+#include <tools/errcode.hxx>
+#include <tools/string.hxx>
+#include "tools/toolsdllapi.h"
+
+class EDcr_Impl;
+class ErrHdl_Impl;
+class Window;
+
+// -------------
+// - ErrorInfo -
+// -------------
+
+class ErrorInfo
+{
+private:
+ ULONG lUserId;
+
+public:
+ TYPEINFO();
+
+ ErrorInfo( ULONG lArgUserId ) :
+ lUserId( lArgUserId ){}
+ virtual ~ErrorInfo(){}
+
+ ULONG GetErrorCode() const { return lUserId; }
+
+ static ErrorInfo* GetErrorInfo(ULONG);
+};
+
+
+// --------------------
+// - DynamicErrorInfo -
+// --------------------
+
+class TOOLS_DLLPUBLIC DynamicErrorInfo : public ErrorInfo
+{
+ friend class EDcr_Impl;
+
+private:
+ EDcr_Impl* pImpl;
+
+public:
+ TYPEINFO();
+
+ DynamicErrorInfo(ULONG lUserId, USHORT nMask);
+ virtual ~DynamicErrorInfo();
+
+ operator ULONG() const;
+ USHORT GetDialogMask() const;
+};
+
+
+// ---------------------
+// - StandardErrorInfo -
+// ---------------------
+
+class StandardErrorInfo : public DynamicErrorInfo
+{
+private:
+ ULONG lExtId;
+
+public:
+ TYPEINFO();
+
+ StandardErrorInfo( ULONG lUserId, ULONG lExtId,
+ USHORT nFlags = 0);
+ ULONG GetExtendedErrorCode() const { return lExtId; }
+
+};
+
+
+// -------------------
+// - StringErrorInfo -
+// -------------------
+
+class TOOLS_DLLPUBLIC StringErrorInfo : public DynamicErrorInfo
+{
+private:
+ String aString;
+
+public:
+ TYPEINFO();
+
+ StringErrorInfo( ULONG lUserId,
+ const String& aStringP,
+ USHORT nFlags = 0);
+ const String& GetErrorString() const { return aString; }
+};
+
+//=============================================================================
+class TOOLS_DLLPUBLIC TwoStringErrorInfo: public DynamicErrorInfo
+{
+private:
+ String aArg1;
+ String aArg2;
+
+public:
+ TYPEINFO();
+
+ TwoStringErrorInfo(ULONG nUserID, const String & rTheArg1,
+ const String & rTheArg2, USHORT nFlags = 0):
+ DynamicErrorInfo(nUserID, nFlags), aArg1(rTheArg1), aArg2(rTheArg2) {}
+ virtual ~TwoStringErrorInfo() {}
+
+ String GetArg1() const { return aArg1; }
+ String GetArg2() const { return aArg2; }
+};
+
+// -------------------
+// - MessageInfo -
+// -------------------
+
+class TOOLS_DLLPUBLIC MessageInfo : public DynamicErrorInfo
+{
+ public:
+
+ TYPEINFO();
+ MessageInfo(ULONG UserId, USHORT nFlags = 0) :
+ DynamicErrorInfo(UserId, nFlags){}
+ MessageInfo(ULONG UserId, const String &rArg,
+ USHORT nFlags = 0 ) :
+ DynamicErrorInfo(UserId, nFlags), aArg(rArg) {}
+ const String& GetMessageArg() const { return aArg; }
+
+ private:
+
+ String aArg;
+};
+
+
+// ----------------
+// - ErrorContext -
+// ----------------
+
+class TOOLS_DLLPUBLIC ErrorContext
+{
+ friend class ErrorHandler;
+
+private:
+ ErrorContext* pNext;
+ Window* pWin;
+
+public:
+ ErrorContext(Window *pWin=0);
+ virtual ~ErrorContext();
+
+ virtual BOOL GetString( ULONG nErrId, String& rCtxStr ) = 0;
+ Window* GetParent() { return pWin; }
+
+ static ErrorContext* GetContext();
+};
+
+
+// ----------------
+// - ErrorHandler -
+// ----------------
+
+typedef USHORT WindowDisplayErrorFunc(
+ Window *, USHORT nMask, const String &rErr, const String &rAction);
+
+typedef void BasicDisplayErrorFunc(
+ const String &rErr, const String &rAction);
+
+class TOOLS_DLLPUBLIC ErrorHandler
+{
+ friend class ErrHdl_Impl;
+
+private:
+ ErrHdl_Impl* pImpl;
+
+ static USHORT HandleError_Impl( ULONG lId,
+ USHORT nFlags,
+ BOOL bJustCreateString,
+ String & rError);
+protected:
+ virtual BOOL CreateString( const ErrorInfo *,
+ String &, USHORT& nMask ) const = 0;
+ BOOL ForwCreateString( const ErrorInfo*,
+ String&, USHORT& nMask ) const;
+
+public:
+ ErrorHandler();
+ virtual ~ErrorHandler();
+
+ static USHORT HandleError ( ULONG lId, USHORT nMask = USHRT_MAX );
+ static BOOL GetErrorString( ULONG lId, String& rStr );
+
+ static void RegisterDisplay( BasicDisplayErrorFunc* );
+ static void RegisterDisplay( WindowDisplayErrorFunc* );
+};
+
+
+// ----------------------
+// - SimpleErrorHandler -
+// ----------------------
+
+class TOOLS_DLLPUBLIC SimpleErrorHandler : private ErrorHandler
+{
+protected:
+ virtual BOOL CreateString( const ErrorInfo*, String &,
+ USHORT &nMask ) const;
+
+public:
+ SimpleErrorHandler();
+
+};
+
+#endif
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/extendapplicationenvironment.hxx b/tools/inc/tools/extendapplicationenvironment.hxx
new file mode 100644
index 000000000000..91d57e08fbbb
--- /dev/null
+++ b/tools/inc/tools/extendapplicationenvironment.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TOOLS_EXTENDAPPLICATIONENVIRONMENT_HXX
+#define INCLUDED_TOOLS_EXTENDAPPLICATIONENVIRONMENT_HXX
+
+#include "sal/config.h"
+#include "tools/toolsdllapi.h"
+
+namespace tools {
+
+// Extend the environment of the process in a platform specifc way as necessary
+// for OOo-related applications; must be called first thing in main:
+TOOLS_DLLPUBLIC void extendApplicationEnvironment();
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/fldunit.hxx b/tools/inc/tools/fldunit.hxx
new file mode 100644
index 000000000000..8df08b979405
--- /dev/null
+++ b/tools/inc/tools/fldunit.hxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _TOOLS_FLDUNIT_HXX
+#define _TOOLS_FLDUNIT_HXX
+
+// --------------
+// - FieldTypes -
+// --------------
+
+// By changes you must also change: rsc/vclrsc.hxx
+enum FieldUnit { FUNIT_NONE, FUNIT_MM, FUNIT_CM, FUNIT_M, FUNIT_KM,
+ FUNIT_TWIP, FUNIT_POINT, FUNIT_PICA,
+ FUNIT_INCH, FUNIT_FOOT, FUNIT_MILE, FUNIT_CHAR, FUNIT_LINE, FUNIT_CUSTOM,
+ FUNIT_PERCENT, FUNIT_100TH_MM };
+
+#endif // _TOOLS_FLDUNIT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/fontenum.hxx b/tools/inc/tools/fontenum.hxx
new file mode 100644
index 000000000000..185e3ec95d00
--- /dev/null
+++ b/tools/inc/tools/fontenum.hxx
@@ -0,0 +1,175 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _TOOLS_FONTENUM_HXX
+#define _TOOLS_FONTENUM_HXX
+
+#include <sal/types.h>
+#include <tools/solar.h>
+
+#ifndef ENUM_FONTFAMILY_DECLARED
+#define ENUM_FONTFAMILY_DECLARED
+
+enum FontFamily { FAMILY_DONTKNOW, FAMILY_DECORATIVE, FAMILY_MODERN,
+ FAMILY_ROMAN, FAMILY_SCRIPT, FAMILY_SWISS, FAMILY_SYSTEM, FontFamily_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+#endif
+
+// ------------------------------------------------------------
+
+#ifndef ENUM_FONTPITCH_DECLARED
+#define ENUM_FONTPITCH_DECLARED
+
+enum FontPitch { PITCH_DONTKNOW, PITCH_FIXED, PITCH_VARIABLE, FontPitch_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+#endif
+
+// ------------------------------------------------------------
+
+#ifndef ENUM_TEXTALIGN_DECLARED
+#define ENUM_TEXTALIGN_DECLARED
+
+enum TextAlign { ALIGN_TOP, ALIGN_BASELINE, ALIGN_BOTTOM, TextAlign_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+#endif
+
+// ------------------------------------------------------------
+
+#ifndef ENUM_FONTWEIGHT_DECLARED
+#define ENUM_FONTWEIGHT_DECLARED
+
+enum FontWeight { WEIGHT_DONTKNOW, WEIGHT_THIN, WEIGHT_ULTRALIGHT,
+ WEIGHT_LIGHT, WEIGHT_SEMILIGHT, WEIGHT_NORMAL,
+ WEIGHT_MEDIUM, WEIGHT_SEMIBOLD, WEIGHT_BOLD,
+ WEIGHT_ULTRABOLD, WEIGHT_BLACK, FontWeight_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+#endif
+
+// ------------------------------------------------------------
+
+#ifndef ENUM_FONTWIDTH_DECLARED
+#define ENUM_FONTWIDTH_DECLARED
+
+enum FontWidth { WIDTH_DONTKNOW, WIDTH_ULTRA_CONDENSED, WIDTH_EXTRA_CONDENSED,
+ WIDTH_CONDENSED, WIDTH_SEMI_CONDENSED, WIDTH_NORMAL,
+ WIDTH_SEMI_EXPANDED, WIDTH_EXPANDED, WIDTH_EXTRA_EXPANDED,
+ WIDTH_ULTRA_EXPANDED,
+ FontWidth_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+#endif
+
+// ------------------------------------------------------------
+
+#ifndef ENUM_FONTITALIC_DECLARED
+#define ENUM_FONTITALIC_DECLARED
+
+enum FontItalic { ITALIC_NONE, ITALIC_OBLIQUE, ITALIC_NORMAL, ITALIC_DONTKNOW, FontItalic_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+#endif
+
+// ------------------------------------------------------------
+
+#ifndef ENUM_FONTUNDERLINE_DECLARED
+#define ENUM_FONTUNDERLINE_DECLARED
+
+enum FontUnderline { UNDERLINE_NONE, UNDERLINE_SINGLE, UNDERLINE_DOUBLE,
+ UNDERLINE_DOTTED, UNDERLINE_DONTKNOW,
+ UNDERLINE_DASH, UNDERLINE_LONGDASH,
+ UNDERLINE_DASHDOT, UNDERLINE_DASHDOTDOT,
+ UNDERLINE_SMALLWAVE,
+ UNDERLINE_WAVE, UNDERLINE_DOUBLEWAVE,
+ UNDERLINE_BOLD, UNDERLINE_BOLDDOTTED,
+ UNDERLINE_BOLDDASH, UNDERLINE_BOLDLONGDASH,
+ UNDERLINE_BOLDDASHDOT, UNDERLINE_BOLDDASHDOTDOT,
+ UNDERLINE_BOLDWAVE,
+ FontUnderline_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+#endif
+
+// ------------------------------------------------------------
+
+#ifndef ENUM_FONTSTRIKEOUT_DECLARED
+#define ENUM_FONTSTRIKEOUT_DECLARED
+
+enum FontStrikeout { STRIKEOUT_NONE, STRIKEOUT_SINGLE, STRIKEOUT_DOUBLE,
+ STRIKEOUT_DONTKNOW, STRIKEOUT_BOLD,
+ STRIKEOUT_SLASH, STRIKEOUT_X,
+ FontStrikeout_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+#endif
+
+// ------------------------------------------------------------
+
+#ifndef ENUM_FONTEMPHASISMARK_DECLARED
+#define ENUM_FONTEMPHASISMARK_DECLARED
+
+typedef USHORT FontEmphasisMark;
+#define EMPHASISMARK_NONE ((FontEmphasisMark)0x0000)
+#define EMPHASISMARK_DOT ((FontEmphasisMark)0x0001)
+#define EMPHASISMARK_CIRCLE ((FontEmphasisMark)0x0002)
+#define EMPHASISMARK_DISC ((FontEmphasisMark)0x0003)
+#define EMPHASISMARK_ACCENT ((FontEmphasisMark)0x0004)
+#define EMPHASISMARK_STYLE ((FontEmphasisMark)0x00FF)
+#define EMPHASISMARK_POS_ABOVE ((FontEmphasisMark)0x1000)
+#define EMPHASISMARK_POS_BELOW ((FontEmphasisMark)0x2000)
+
+// Only for kompability
+#define EMPHASISMARK_DOTS_ABOVE (EMPHASISMARK_DOT | EMPHASISMARK_POS_ABOVE)
+#define EMPHASISMARK_DOTS_BELOW (EMPHASISMARK_DOT | EMPHASISMARK_POS_BELOW)
+#define EMPHASISMARK_SIDE_DOTS (EMPHASISMARK_ACCENT | EMPHASISMARK_POS_ABOVE)
+#define EMPHASISMARK_CIRCLE_ABOVE (EMPHASISMARK_CIRCLE | EMPHASISMARK_POS_ABOVE)
+
+#endif
+
+// ------------------------------------------------------------
+
+#ifndef ENUM_FONTTYPE_DECLARED
+#define ENUM_FONTTYPE_DECLARED
+
+enum FontType { TYPE_DONTKNOW, TYPE_RASTER, TYPE_VECTOR, TYPE_SCALABLE,
+ FontType_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+#endif
+
+#ifndef ENUM_FONTEMBEDDEDBITMAP_DECLARED
+#define ENUM_FONTEMBEDDEDBITMAP_DECLARED
+
+enum FontEmbeddedBitmap { EMBEDDEDBITMAP_DONTKNOW, EMBEDDEDBITMAP_FALSE, EMBEDDEDBITMAP_TRUE };
+
+#endif
+
+#ifndef ENUM_FONTANTIALIAS_DECLARED
+#define ENUM_FONTANTIALIAS_DECLARED
+
+enum FontAntiAlias { ANTIALIAS_DONTKNOW, ANTIALIAS_FALSE, ANTIALIAS_TRUE };
+
+#endif
+
+#endif // _TOOLS_FONTENUM_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/fract.hxx b/tools/inc/tools/fract.hxx
new file mode 100644
index 000000000000..41fe89add7ac
--- /dev/null
+++ b/tools/inc/tools/fract.hxx
@@ -0,0 +1,168 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _FRACT_HXX
+#define _FRACT_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/solar.h>
+
+class SvStream;
+// ------------
+// - Fraction -
+// ------------
+
+class TOOLS_DLLPUBLIC Fraction
+{
+private:
+ long nNumerator;
+ long nDenominator;
+
+public:
+ Fraction() { nNumerator = 0; nDenominator = 1; }
+ Fraction( const Fraction & rFrac );
+ Fraction( long nNum, long nDen=1 );
+ Fraction( long nN1, long nN2, long nD1, long nD2 );
+ Fraction( double dVal );
+
+ BOOL IsValid() const;
+
+ long GetNumerator() const { return nNumerator; }
+ long GetDenominator() const { return nDenominator; }
+
+ operator long() const;
+ operator double() const;
+
+ Fraction& operator=( const Fraction& rfrFrac );
+
+ Fraction& operator+=( const Fraction& rfrFrac );
+ Fraction& operator-=( const Fraction& rfrFrac );
+ Fraction& operator*=( const Fraction& rfrFrac );
+ Fraction& operator/=( const Fraction& rfrFrac );
+
+ void ReduceInaccurate( unsigned nSignificantBits );
+#ifdef __BORLANDC__
+ friend Fraction operator+( const Fraction& rVal1, const Fraction& rVal2 );
+ friend Fraction operator-( const Fraction& rVal1, const Fraction& rVal2 );
+ friend Fraction operator*( const Fraction& rVal1, const Fraction& rVal2 );
+ friend Fraction operator/( const Fraction& rVal1, const Fraction& rVal2 );
+
+ friend BOOL operator==( const Fraction& rVal1, const Fraction& rVal2 );
+ friend BOOL operator!=( const Fraction& rVal1, const Fraction& rVal2 );
+ friend BOOL operator< ( const Fraction& rVal1, const Fraction& rVal2 );
+ friend BOOL operator> ( const Fraction& rVal1, const Fraction& rVal2 );
+ friend BOOL operator<=( const Fraction& rVal1, const Fraction& rVal2 );
+ friend BOOL operator>=( const Fraction& rVal1, const Fraction& rVal2 );
+#else
+ friend inline Fraction operator+( const Fraction& rVal1, const Fraction& rVal2 );
+ friend inline Fraction operator-( const Fraction& rVal1, const Fraction& rVal2 );
+ friend inline Fraction operator*( const Fraction& rVal1, const Fraction& rVal2 );
+ friend inline Fraction operator/( const Fraction& rVal1, const Fraction& rVal2 );
+
+ TOOLS_DLLPUBLIC friend BOOL operator==( const Fraction& rVal1, const Fraction& rVal2 );
+ friend inline BOOL operator!=( const Fraction& rVal1, const Fraction& rVal2 );
+ TOOLS_DLLPUBLIC friend BOOL operator< ( const Fraction& rVal1, const Fraction& rVal2 );
+ TOOLS_DLLPUBLIC friend BOOL operator> ( const Fraction& rVal1, const Fraction& rVal2 );
+ friend inline BOOL operator<=( const Fraction& rVal1, const Fraction& rVal2 );
+ friend inline BOOL operator>=( const Fraction& rVal1, const Fraction& rVal2 );
+#endif
+ TOOLS_DLLPUBLIC friend SvStream& operator>>( SvStream& rIStream, Fraction& rFract );
+ TOOLS_DLLPUBLIC friend SvStream& operator<<( SvStream& rOStream, const Fraction& rFract );
+};
+
+inline Fraction::Fraction( const Fraction& rFrac )
+{
+ nNumerator = rFrac.nNumerator;
+ nDenominator = rFrac.nDenominator;
+}
+
+inline Fraction& Fraction::operator=( const Fraction& rFrac )
+{
+ nNumerator = rFrac.nNumerator;
+ nDenominator = rFrac.nDenominator;
+ return *this;
+}
+
+inline BOOL Fraction::IsValid() const
+{
+ return (nDenominator > 0);
+}
+
+inline Fraction::operator long() const
+{
+ if ( nDenominator > 0 )
+ return (nNumerator / nDenominator);
+ else
+ return 0;
+}
+
+inline Fraction operator+( const Fraction& rVal1, const Fraction& rVal2 )
+{
+ Fraction aErg( rVal1 );
+ aErg += rVal2;
+ return aErg;
+}
+
+inline Fraction operator-( const Fraction& rVal1, const Fraction& rVal2 )
+{
+ Fraction aErg( rVal1 );
+ aErg -= rVal2;
+ return aErg;
+}
+
+inline Fraction operator*( const Fraction& rVal1, const Fraction& rVal2 )
+{
+ Fraction aErg( rVal1 );
+ aErg *= rVal2;
+ return aErg;
+}
+
+inline Fraction operator/( const Fraction& rVal1, const Fraction& rVal2 )
+{
+ Fraction aErg( rVal1 );
+ aErg /= rVal2;
+ return aErg;
+}
+
+inline BOOL operator !=( const Fraction& rVal1, const Fraction& rVal2 )
+{
+ return !(rVal1 == rVal2);
+}
+
+inline BOOL operator <=( const Fraction& rVal1, const Fraction& rVal2 )
+{
+ return !(rVal1 > rVal2);
+}
+
+inline BOOL operator >=( const Fraction& rVal1, const Fraction& rVal2 )
+{
+ return !(rVal1 < rVal2);
+}
+
+#endif // _FRACT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/fsys.hxx b/tools/inc/tools/fsys.hxx
new file mode 100644
index 000000000000..2f252216018a
--- /dev/null
+++ b/tools/inc/tools/fsys.hxx
@@ -0,0 +1,571 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _FSYS_HXX
+#define _FSYS_HXX
+
+#include <tools/solar.h>
+#include <tools/datetime.hxx>
+#include <tools/string.hxx>
+#include <tools/link.hxx>
+#include <tools/wldcrd.hxx>
+#include <tools/errcode.hxx>
+#include "tools/toolsdllapi.h"
+
+#include <cstdarg>
+
+#define FEAT_FSYS_DOUBLESPEED
+
+// --------------
+// - FSys-Types -
+// --------------
+
+class DirEntry;
+class DirEntryList;
+class FSysSortList;
+class FileStatList;
+struct FileCopier_Impl;
+class SvFileStream;
+class BigInt;
+
+#define FSYS_BUFSIZE 1024
+#define FSYS_SHORTNAME_DELIMITER '@'
+
+// FSysAccess
+typedef int FSysAccess;
+#define FSYS_ACCESS_FORCED 1
+#define FSYS_ACCESS_FLOPPY FSYS_ACCESS_FORCED
+#define FSYS_ACCESS_CACHED 2
+
+// DirEntryKind
+typedef int DirEntryKind;
+#define FSYS_KIND_NONE ((DirEntryKind) 0)
+#define FSYS_KIND_UNKNOWN FSYS_KIND_NONE
+#define FSYS_KIND_FILE ((DirEntryKind) 1)
+#define FSYS_KIND_DIR ((DirEntryKind) 2)
+#define FSYS_KIND_DEV ((DirEntryKind) 4)
+#define FSYS_KIND_BLOCK ((DirEntryKind) 8)
+#define FSYS_KIND_CHAR ((DirEntryKind) 16)
+#define FSYS_KIND_WILD ((DirEntryKind) 32)
+#define FSYS_KIND_BLOCK_REMOTE ((DirEntryKind) 64) //TPF: fuer RFS
+#define FSYS_KIND_REMOVEABLE ((DirEntryKind) 128)
+#define FSYS_KIND_FIXED ((DirEntryKind) 256)
+#define FSYS_KIND_REMOTE ((DirEntryKind) 512)
+#define FSYS_KIND_RAM ((DirEntryKind) 1024)
+#define FSYS_KIND_CDROM ((DirEntryKind) 2048)
+#define FSYS_KIND_ALL ((DirEntryKind) 4095)
+#define FSYS_KIND_VISIBLE ((DirEntryKind) 4096)
+
+// FSysSort
+typedef int FSysSort;
+#define FSYS_SORT_NONE ((FSysSort) 0)
+#define FSYS_SORT_SIZE ((FSysSort) 1)
+#define FSYS_SORT_CREATED ((FSysSort) 2)
+#define FSYS_SORT_MODIFYED ((FSysSort) 4)
+#define FSYS_SORT_ACCESSED ((FSysSort) 8)
+#define FSYS_SORT_ASCENDING ((FSysSort) 16)
+#define FSYS_SORT_DESCENDING ((FSysSort) 32)
+#define FSYS_SORT_EXT ((FSysSort) 64)
+#define FSYS_SORT_NAME ((FSysSort) 128)
+#define FSYS_SORT_KIND ((FSysSort) 256)
+#define FSYS_SORT_CREATOR ((FSysSort) 512)
+#define FSYS_SORT_END ((FSysSort)1024)
+
+// DirEntryFlag
+enum DirEntryFlag
+{
+ FSYS_FLAG_NORMAL,
+ FSYS_FLAG_VOLUME, // Dir( FSYS_FLAG_VOLUME ) und GetDevice()
+ FSYS_FLAG_ABSROOT, // z.B. "a:\" oder "\"
+ FSYS_FLAG_RELROOT, // z.B. "a:", "a:." oder "."
+ FSYS_FLAG_CURRENT = FSYS_FLAG_RELROOT, // Synonym fuer FSYS_FLAG_RELROOT
+ FSYS_FLAG_PARENT, // z.B. ".."
+ FSYS_FLAG_INVALID
+};
+
+// FSysPathStyle
+enum FSysPathStyle
+{
+ FSYS_STYLE_HOST,
+ FSYS_STYLE_FAT,
+ FSYS_STYLE_MSDOS = FSYS_STYLE_FAT,
+ FSYS_STYLE_VFAT,
+ FSYS_STYLE_WIN95 = FSYS_STYLE_VFAT,
+ FSYS_STYLE_HPFS,
+ FSYS_STYLE_OS2 = FSYS_STYLE_HPFS,
+ FSYS_STYLE_NTFS,
+ FSYS_STYLE_NWFS,
+ FSYS_STYLE_SYSV,
+ FSYS_STYLE_BSD,
+ FSYS_STYLE_UNX = FSYS_STYLE_BSD,
+ FSYS_STYLE_MAC,
+ FSYS_STYLE_DETECT,
+ FSYS_STYLE_UNKNOWN,
+ FSYS_STYLE_URL
+};
+
+// FSysAction
+typedef int FSysAction;
+#define FSYS_ACTION_COPYFILE 0x01 // not only create hardlink
+#define FSYS_ACTION_RECURSIVE 0x02 // deep through dircetory structure
+#define FSYS_ACTION_USERECYCLEBIN 0x04 // move to recycle bin
+#define FSYS_ACTION_MOVE 0x08 // delete after copy (=> move)
+#define FSYS_ACTION_CONTINUE 0x10 // continue on error
+#define FSYS_ACTION_KEEP_EXISTING 0x20 // do not overwrite objects in
+ // target folder in case of name
+ // clashes
+#define FSYS_ACTION_STANDARD 0
+
+// Fuer RFS
+#define RFS_IDENTIFIER "-rfs-"
+#define RFS_LOWER "-rfs-"
+#define RFS_UPPER "-RFS-"
+
+typedef ULONG FSysError;
+
+// FSysExact
+enum FSysExact
+{
+ FSYS_NOTEXACT,
+ FSYS_EXACT
+};
+
+// ------------
+// - Char-Set -
+// ------------
+
+#if defined(WIN) || defined(W30)
+
+// MS-Windows has different char-sets for file-system and user-interface
+String Gui2FSys( const String& rStr );
+String FSys2Gui( const String& rStr );
+#define GUI2FSYS(s) Gui2FSys( s )
+#define FSYS2GUI(s) FSys2Gui( s )
+
+#else
+
+// all other OS have the same char-set for both
+#define GUI2FSYS(s) s
+#define FSYS2GUI(s) s
+
+#endif
+
+// ------------
+// - FileStat -
+// ------------
+
+struct dirent;
+class TOOLS_DLLPUBLIC FileStat
+{
+ friend class CORmFSys;
+ friend class Dir;
+ friend struct DirReader_Impl;
+ friend void ImpInitFileStat( FileStat&, dirent* );
+
+ ULONG nError;
+ DirEntryKind nKindFlags;
+ ULONG nSize;
+ String aCreator;
+ String aType;
+ Date aDateCreated;
+ Time aTimeCreated;
+ Date aDateModified;
+ Time aTimeModified;
+ Date aDateAccessed;
+ Time aTimeAccessed;
+private:
+ TOOLS_DLLPRIVATE void ImpInit( void* );
+
+protected:
+ // Implementation
+ FileStat( const void *pInfo, // CInfoPBRec
+ const void *pVolInfo ); // ParamBlockRec
+
+public:
+ FileStat();
+ FileStat( const DirEntry& rDirEntry,
+ FSysAccess nAccess = FSYS_ACCESS_FLOPPY );
+ BOOL Update( const DirEntry& rDirEntry,
+ BOOL bForceAccess = TRUE );
+
+ ULONG GetError() const { return ERRCODE_TOERROR(nError); }
+ ULONG GetErrorCode() const { return nError; }
+
+ ULONG GetSize() const { return nSize; }
+
+ DirEntryKind GetKind() const { return nKindFlags; }
+ BOOL IsKind( DirEntryKind nKind ) const;
+
+ String GetType() const { return aType; }
+ String GetCreator() const { return aCreator; }
+
+ Date DateCreated() const { return aDateCreated; }
+ Time TimeCreated() const { return aTimeCreated; }
+ Date DateModified() const { return aDateModified; }
+ Time TimeModified() const { return aTimeModified; }
+ Date DateAccessed() const { return aDateAccessed; }
+ Time TimeAccessed() const { return aTimeAccessed; }
+ BOOL IsYounger( const FileStat& rIsOlder ) const;
+
+#define TF_FSYS_READONLY_FLAG
+ static ULONG SetReadOnlyFlag( const DirEntry &rEntry, BOOL bRO = TRUE );
+ static BOOL GetReadOnlyFlag( const DirEntry &rEntry );
+ static BOOL HasReadOnlyFlag();
+
+ static ErrCode QueryDiskSpace( const String &rPath,
+ BigInt &rFreeBytes, BigInt &rTotalBytes );
+
+ static void SetDateTime( const String& rFileName,
+ const DateTime& rNewDateTime );
+};
+
+// ------------
+// - DirEntry -
+// ------------
+
+class DirEntryStack;
+
+const char* ImpCheckDirEntry( const void* p );
+
+class TOOLS_DLLPUBLIC DirEntry
+{
+friend struct DirReader_Impl;
+friend class FileCopier;
+
+#ifdef FEAT_FSYS_DOUBLESPEED
+ FileStat* pStat; // optional
+#endif
+ ByteString aName;
+ DirEntry* pParent;
+ ULONG nError;
+ DirEntryFlag eFlag;
+
+private:
+ TOOLS_DLLPRIVATE DirEntry( const ByteString& rInitName,
+ DirEntryFlag aDirFlag,
+ FSysPathStyle eStyle );
+
+ friend class Dir;
+ friend class FileStat;
+ friend const char* ImpCheckDirEntry( const void* p );
+
+ TOOLS_DLLPRIVATE FSysError ImpParseName( const ByteString& rIntiName,
+ FSysPathStyle eParser );
+ TOOLS_DLLPRIVATE FSysError ImpParseOs2Name( const ByteString& rPfad,
+ FSysPathStyle eStyle );
+ TOOLS_DLLPRIVATE FSysError ImpParseUnixName( const ByteString& rPfad,
+ FSysPathStyle eStyle );
+ TOOLS_DLLPRIVATE USHORT ImpTryUrl( DirEntryStack& rStack, const String& rPfad, FSysPathStyle eStyle );
+ TOOLS_DLLPRIVATE const DirEntry* ImpGetTopPtr() const;
+ TOOLS_DLLPRIVATE DirEntry* ImpGetTopPtr();
+ TOOLS_DLLPRIVATE DirEntry* ImpGetPreTopPtr();
+ TOOLS_DLLPRIVATE BOOL ImpToRel( String aStart );
+
+protected:
+ void ImpTrim( FSysPathStyle eStyle );
+ const ByteString& ImpTheName() const;
+ DirEntryFlag ImpTheFlag() const { return eFlag; };
+ DirEntry* ImpChangeParent( DirEntry* pNewParent, BOOL bNormalize = TRUE );
+ DirEntry* ImpGetParent() { return pParent; }
+#ifdef FEAT_FSYS_DOUBLESPEED
+ FileStat* ImpGetStat() const { return pStat; }
+ void ImpSetStat( FileStat *p ) { pStat = p; }
+#endif
+
+protected:
+ void SetError( ULONG nErr ) { nError = nErr; }
+ DirEntry* GetParent() { return pParent; }
+public:
+ DirEntry( DirEntryFlag aDirFlag = FSYS_FLAG_CURRENT );
+ DirEntry( const DirEntry& rEntry );
+ DirEntry( const ByteString& rInitName,
+ FSysPathStyle eParser = FSYS_STYLE_HOST );
+ DirEntry( const String& rInitName,
+ FSysPathStyle eParser = FSYS_STYLE_HOST );
+ ~DirEntry();
+
+ BOOL IsLongNameOnFAT() const;
+ BOOL IsCaseSensitive (FSysPathStyle eFormatter = FSYS_STYLE_HOST) const;
+
+ ULONG GetError() const { return nError; }
+ BOOL IsValid() const;
+ DirEntryFlag GetFlag() const { return eFlag; };
+
+ void SetExtension( const String& rExt, char cSep = '.' );
+ String GetExtension( char cSep = '.' ) const;
+ String CutExtension( char cSep = '.' );
+ void SetName( const String& rName, FSysPathStyle eFormatter = FSYS_STYLE_HOST );
+ inline const String GetNameDirect() const { return String(aName, osl_getThreadTextEncoding()); }
+ String GetName( FSysPathStyle eFormatter = FSYS_STYLE_HOST ) const;
+ String CutName( FSysPathStyle eFormatter = FSYS_STYLE_HOST );
+ void SetBase( const String& rBase, char cSep = '.' );
+ String GetBase(char cSep = '.' ) const;
+ DirEntry GetPath() const;
+ DirEntry GetDevice() const;
+ String GetVolume() const;
+ String GetFull( FSysPathStyle eFormatter = FSYS_STYLE_HOST,
+ BOOL bWithDelimiter = FALSE,
+ USHORT nMaxChars = STRING_MAXLEN ) const;
+
+ DirEntry TempName( DirEntryKind = FSYS_KIND_NONE ) const;
+ static const DirEntry& SetTempNameBase( const String &rBaseName );
+ BOOL MakeShortName( const String& rLongName,
+ DirEntryKind eCreateKind = FSYS_KIND_NONE,
+ BOOL bUseTilde = TRUE,
+ FSysPathStyle eStyle = FSYS_STYLE_DETECT );
+
+ bool IsAbs() const;
+ BOOL ToAbs();
+ BOOL Find( const String& rPfad, char cDelim = 0 );
+ BOOL ToRel();
+ BOOL ToRel( const DirEntry& rRefDir );
+ USHORT CutRelParents();
+
+ BOOL SetCWD( BOOL bSloppy = FALSE ) const;
+ BOOL MakeDir( BOOL bSloppy = FALSE ) const;
+ BOOL Exists( FSysAccess nAccess = FSYS_ACCESS_FLOPPY ) const;
+ BOOL First();
+
+ USHORT Level() const;
+ const DirEntry& operator []( USHORT nParentLevel ) const;
+ BOOL Contains( const DirEntry &rSubEntry ) const;
+
+ FSysError CopyTo( const DirEntry& rDestDir,
+ FSysAction nActions = FSYS_ACTION_STANDARD ) const;
+ FSysError MoveTo( const DirEntry& rDestDir ) const;
+ FSysError Kill( FSysAction nActions = FSYS_ACTION_STANDARD ) const;
+
+ DirEntry& operator =( const DirEntry& rOrigDir );
+ DirEntry operator +( const DirEntry& rSubDir ) const;
+ DirEntry& operator +=( const DirEntry& rSubDir );
+ BOOL operator ==( const DirEntry& rAnotherDir ) const;
+ BOOL operator !=( const DirEntry& rAnotherDir ) const
+ { return !(DirEntry::operator==( rAnotherDir )); }
+
+ StringCompare NameCompare( const DirEntry &rWith ) const;
+ inline StringCompare NameCompareDirect( const DirEntry &rWith ) const
+ {
+#ifdef UNX
+ return rWith.aName.CompareTo( aName );
+#else
+ return rWith.aName.CompareIgnoreCaseToAscii( aName );
+#endif
+ }
+
+ static String GetAccessDelimiter( FSysPathStyle eFormatter = FSYS_STYLE_HOST );
+ static String GetSearchDelimiter( FSysPathStyle eFormatter = FSYS_STYLE_HOST );
+ static USHORT GetMaxNameLen( FSysPathStyle eFormatter = FSYS_STYLE_HOST );
+ static FSysPathStyle GetPathStyle( const String &rDevice );
+ static String ConvertNameToSystem( const String & rName );
+ static String ConvertSystemToName( const String & rName );
+ static BOOL IsRFSAvailable();
+};
+
+// --------------
+// - FileCopier -
+// --------------
+
+class TOOLS_DLLPUBLIC FileCopier
+{
+ DirEntry aSource;
+ DirEntry aTarget;
+ ULONG nBytesTotal;
+ ULONG nBytesCopied;
+ Link aProgressLink;
+ USHORT nBlockSize;
+ FileCopier_Impl* pImp;
+
+private:
+ TOOLS_DLLPRIVATE FSysError DoCopy_Impl(
+ const DirEntry &rSource, const DirEntry &rTarget );
+
+protected:
+ virtual BOOL Progress();
+ virtual ErrCode Error( ErrCode eErr,
+ const DirEntry *pSource, const DirEntry *pTarget );
+
+public:
+ FileCopier();
+ FileCopier( const DirEntry &rSource,
+ const DirEntry &rTarget );
+ FileCopier( const FileCopier &rCopier );
+ virtual ~FileCopier();
+
+ FileCopier& operator = ( const FileCopier &rCopier );
+
+ void SetBlockSize( USHORT nBytes ) { nBlockSize = nBytes; }
+ USHORT GetBlockSize() const { return nBlockSize; }
+
+ ULONG GetBytesTotal() const { return nBytesTotal; }
+ ULONG GetBytesCopied() const { return nBytesCopied; }
+
+ void SetSource( const DirEntry &rSource ) { aSource = rSource; }
+ void SetTarget( const DirEntry &rTarget ) { aTarget = rTarget; }
+ const DirEntry& GetSource() const { return aSource; }
+ const DirEntry& GetTarget() const { return aTarget; }
+
+ FSysError Execute( FSysAction nActions = FSYS_ACTION_STANDARD );
+ FSysError ExecuteExact( FSysAction nActions = FSYS_ACTION_STANDARD,
+ FSysExact eExact = FSYS_NOTEXACT);
+
+ const DirEntry* GetErrorSource() const;
+ const DirEntry* GetErrorTarget() const;
+ ErrCode GetError() const;
+
+ void SetProgressHdl( const Link& rLink ) { aProgressLink = rLink; }
+ const Link& GetProgressHdl() const { return aProgressLink; }
+ void SetErrorHdl( const Link& rLink );
+ const Link& GetErrorHdl() const;
+};
+
+// -------
+// - Dir -
+// -------
+
+struct DirReader_Impl;
+class TOOLS_DLLPUBLIC Dir : public DirEntry
+{
+friend struct DirReader_Impl;
+friend class CORmFSys;
+
+ DirReader_Impl* pReader; // systemabhaengig
+ DirEntryList* pLst;
+ FSysSortList* pSortLst; // NULL, wenn kein Sort gefordert
+ FileStatList* pStatLst; // NULL, wenn keine Stat's benoetigt
+ WildCard aNameMask;
+ DirEntryKind eAttrMask;
+
+private:
+ TOOLS_DLLPRIVATE Dir( const Dir& ); // not allowed
+ TOOLS_DLLPRIVATE Dir& operator=( const Dir& ); // not allowed
+
+#ifdef _DIR_CXX
+ TOOLS_DLLPRIVATE FSysError ImpSetSort( std::va_list pArgs, FSysSort nSort );
+ TOOLS_DLLPRIVATE void Construct( DirEntryKind nKind = FSYS_KIND_DIR|FSYS_KIND_FILE );
+#endif
+
+#ifndef _TOOLS_HXX
+protected:
+ BOOL ImpInsertPointReached( const DirEntry& rIsSmaller,
+ const FileStat& rNewStat,
+ ULONG nCurPos,
+ ULONG nSortIndex ) const;
+ void ImpSortedInsert( const DirEntry *pNewEntry,
+ const FileStat *pNewStat );
+#endif
+
+public:
+ Dir();
+ Dir( const DirEntry& rDirEntry,
+ DirEntryKind nKind = FSYS_KIND_ALL );
+ Dir( const DirEntry& rDirEntry,
+ DirEntryKind nKind,
+ FSysSort nSort, ... );
+ ~Dir();
+
+ const WildCard& GetNameMask() const { return aNameMask; }
+
+ FSysError SetSort( FSysSort nSort, ... );
+
+ void Reset();
+ USHORT Scan( USHORT nCount = 5 );
+ USHORT Count( BOOL bUpdated = TRUE ) const;
+ BOOL Update();
+
+ Dir& operator +=( const Dir& rDir );
+ DirEntry& operator []( USHORT nIndex ) const;
+};
+
+// we don't need this stuff for bootstraping
+#ifndef BOOTSTRAP
+
+//========================================================================
+
+/** FSysRedirector is an abstract base class for a hook to redirect
+ mirrored directory trees.
+
+ <P>One instance of a subclass can be instanciated and registered
+ using the method FSysRedirector::Register(FSysRedirector*).
+ */
+
+class FSysRedirector
+{
+ static FSysRedirector* _pRedirector;
+ static BOOL _bEnabled;
+
+public:
+ /** This method must called with the one and only instance of the
+ subclass which implements the redirection.
+
+ <P>It must be called with 0 when the instance is destroyed.
+ */
+ static void Register( FSysRedirector *pRedirector );
+
+ //-----------------------------------------------------------------------
+ /** This method returns the currently registererd instance of
+ a subclass which implements the redirection.
+
+ <P>If no redirector is registered, it returns 0.
+ */
+ static FSysRedirector* Redirector();
+
+ //-----------------------------------------------------------------------
+ /** This method is to be used to redirect a file system path.
+
+ <P>It will not redirect while redirection is disabled.
+
+ <P>It may block while another thread is accessing the redirector
+ or another thread has disabled redirections.
+
+ @param String &rPath<BR>
+ This inout-argument accepts a file:-URL even as a native
+ file system path name to redirect in 'rPath'. It returns the
+ redirected (modified) path too, which can be of both formats
+ too.
+
+ @return BOOL<BR>
+ TRUE, if the path is redirected
+ FALSE, if the path is not redirected (unchanged)
+ */
+ static void DoRedirect( String &rPath );
+};
+
+#endif // BOOTSTRP
+
+//========================================================================
+
+void FSysEnableSysErrorBox( BOOL bEnable );
+
+//========================================================================
+
+#if defined(DBG_UTIL)
+void FSysTest();
+#endif
+
+#endif // #ifndef _FSYS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/gen.hxx b/tools/inc/tools/gen.hxx
new file mode 100644
index 000000000000..304f9e689dff
--- /dev/null
+++ b/tools/inc/tools/gen.hxx
@@ -0,0 +1,715 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _SV_GEN_HXX
+#define _SV_GEN_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/solar.h>
+
+#include <limits.h>
+
+class SvStream;
+
+// --------------------
+// - Helper functions -
+// --------------------
+
+inline long MinMax( long nVal, long nMin, long nMax );
+inline long AlignedWidth4Bytes( long nWidthBits );
+inline long FRound( double fVal );
+
+// ---------------
+// - Inlines -
+// ---------------
+
+inline long MinMax( long nVal, long nMin, long nMax )
+{
+ return( nVal >= nMin ? ( nVal <= nMax ? nVal : nMax ) : nMin );
+}
+
+// ------------------------------------------------------------------
+
+inline long AlignedWidth4Bytes( long nWidthBits )
+{
+ return( ( ( nWidthBits + 31 ) >> 5 ) << 2 );
+}
+
+// ------------------------------------------------------------------
+
+inline long FRound( double fVal )
+{
+ return( fVal > 0.0 ? (long) ( fVal + 0.5 ) : -(long) ( -fVal + 0.5 ) );
+}
+
+// --------
+// - Pair -
+// --------
+
+class Pair
+{
+public:
+ long nA;
+ long nB;
+
+ Pair();
+ Pair( long nA, long nB );
+
+ long A() const { return nA; }
+ long B() const { return nB; }
+
+ long& A() { return nA; }
+ long& B() { return nB; }
+
+ BOOL operator == ( const Pair& rPair ) const;
+ BOOL operator != ( const Pair& rPair ) const;
+
+ TOOLS_DLLPUBLIC friend SvStream& operator>>( SvStream& rIStream, Pair& rPair );
+ TOOLS_DLLPUBLIC friend SvStream& operator<<( SvStream& rOStream, const Pair& rPair );
+};
+
+inline Pair::Pair()
+{
+ nA = nB = 0;
+}
+
+inline Pair::Pair( long _nA, long _nB )
+{
+ Pair::nA = _nA;
+ Pair::nB = _nB;
+}
+
+inline BOOL Pair::operator == ( const Pair& rPair ) const
+{
+ return ((nA == rPair.nA) && (nB == rPair.nB));
+}
+
+inline BOOL Pair::operator != ( const Pair& rPair ) const
+{
+ return ((nA != rPair.nA) || (nB != rPair.nB));
+}
+
+// ---------
+// - Point -
+// ---------
+
+class Point : public Pair
+{
+public:
+ Point();
+ Point( long nX, long nY );
+
+ long X() const { return nA; }
+ long Y() const { return nB; }
+
+ long& X() { return nA; }
+ long& Y() { return nB; }
+
+ void Move( long nHorzMove, long nVertMove );
+ BOOL IsAbove( const Point& rPoint ) const;
+ BOOL IsBelow( const Point& rPoint ) const;
+ BOOL IsLeft( const Point& rPoint ) const;
+ BOOL IsRight( const Point& rPoint ) const;
+
+ Point& operator += ( const Point& rPoint );
+ Point& operator -= ( const Point& rPoint );
+ Point& operator *= ( const long nVal );
+ Point& operator /= ( const long nVal );
+
+#ifdef __BORLANDC__
+ friend Point operator+( const Point &rVal1, const Point &rVal2 );
+ friend Point operator-( const Point &rVal1, const Point &rVal2 );
+ friend Point operator*( const Point &rVal1, const long nVal2 );
+ friend Point operator/( const Point &rVal1, const long nVal2 );
+#else
+ friend inline Point operator+( const Point &rVal1, const Point &rVal2 );
+ friend inline Point operator-( const Point &rVal1, const Point &rVal2 );
+ friend inline Point operator*( const Point &rVal1, const long nVal2 );
+ friend inline Point operator/( const Point &rVal1, const long nVal2 );
+#endif
+
+ long getX() const { return X(); }
+ long getY() const { return Y(); }
+ void setX(long nX) { X() = nX; }
+ void setY(long nY) { Y() = nY; }
+};
+
+inline Point::Point()
+{
+}
+
+inline Point::Point( long nX, long nY ) : Pair( nX, nY )
+{
+}
+
+inline void Point::Move( long nHorzMove, long nVertMove )
+{
+ nA += nHorzMove;
+ nB += nVertMove;
+}
+
+inline BOOL Point::IsAbove( const Point& rPoint ) const
+{
+ return (nB > rPoint.nB);
+}
+
+inline BOOL Point::IsBelow( const Point& rPoint ) const
+{
+ return (nB < rPoint.nB);
+}
+
+inline BOOL Point::IsLeft( const Point& rPoint ) const
+{
+ return (nA < rPoint.nA);
+}
+
+inline BOOL Point::IsRight( const Point& rPoint ) const
+{
+ return (nA > rPoint.nA);
+}
+
+inline Point& Point::operator += ( const Point& rPoint )
+{
+ nA += rPoint.nA;
+ nB += rPoint.nB;
+ return *this;
+}
+
+inline Point& Point::operator -= ( const Point& rPoint )
+{
+ nA -= rPoint.nA;
+ nB -= rPoint.nB;
+ return *this;
+}
+
+inline Point& Point::operator *= ( const long nVal )
+{
+ nA *= nVal;
+ nB *= nVal;
+ return *this;
+}
+
+inline Point& Point::operator /= ( const long nVal )
+{
+ nA /= nVal;
+ nB /= nVal;
+ return *this;
+}
+
+inline Point operator+( const Point &rVal1, const Point &rVal2 )
+{
+ return Point( rVal1.nA+rVal2.nA, rVal1.nB+rVal2.nB );
+}
+
+inline Point operator-( const Point &rVal1, const Point &rVal2 )
+{
+ return Point( rVal1.nA-rVal2.nA, rVal1.nB-rVal2.nB );
+}
+
+inline Point operator*( const Point &rVal1, const long nVal2 )
+{
+ return Point( rVal1.nA*nVal2, rVal1.nB*nVal2 );
+}
+
+inline Point operator/( const Point &rVal1, const long nVal2 )
+{
+ return Point( rVal1.nA/nVal2, rVal1.nB/nVal2 );
+}
+
+// --------
+// - Size -
+// --------
+
+class Size : public Pair
+{
+public:
+ Size();
+ Size( long nWidth, long nHeight );
+
+ long Width() const { return nA; }
+ long Height() const { return nB; }
+
+ long& Width() { return nA; }
+ long& Height() { return nB; }
+
+ long getWidth() const { return Width(); }
+ long getHeight() const { return Height(); }
+ void setWidth(long nWidth) { Width() = nWidth; }
+ void setHeight(long nHeight) { Height() = nHeight; }
+};
+
+inline Size::Size()
+{
+}
+
+inline Size::Size( long nWidth, long nHeight ) :
+ Pair( nWidth, nHeight )
+{
+}
+
+// ---------
+// - Range -
+// ---------
+
+#define RANGE_MIN LONG_MIN
+#define RANGE_MAX LONG_MAX
+
+class Range : public Pair
+{
+public:
+ Range();
+ Range( long nMin, long nMax );
+
+ long Min() const { return nA; }
+ long Max() const { return nB; }
+ long Len() const { return nB - nA + 1; }
+
+ long& Min() { return nA; }
+ long& Max() { return nB; }
+
+ BOOL IsInside( long nIs ) const;
+
+ void Justify();
+};
+
+inline Range::Range()
+{
+}
+
+inline Range::Range( long nMin, long nMax ) : Pair( nMin, nMax )
+{
+}
+
+inline BOOL Range::IsInside( long nIs ) const
+{
+ return ((nA <= nIs) && (nIs <= nB ));
+}
+
+inline void Range::Justify()
+{
+ if ( nA > nB )
+ {
+ long nHelp = nA;
+ nA = nB;
+ nB = nHelp;
+ }
+}
+
+// -------------
+// - Selection -
+// -------------
+
+#define SELECTION_MIN LONG_MIN
+#define SELECTION_MAX LONG_MAX
+
+class Selection : public Pair
+{
+public:
+ Selection();
+ Selection( long nPos );
+ Selection( long nMin, long nMax );
+
+ long Min() const { return nA; }
+ long Max() const { return nB; }
+ long Len() const { return nB - nA; }
+
+ long& Min() { return nA; }
+ long& Max() { return nB; }
+
+ BOOL IsInside( long nIs ) const;
+
+ void Justify();
+
+ BOOL operator !() const { return !Len(); }
+
+ long getMin() const { return Min(); }
+ long getMax() const { return Max(); }
+ void setMin(long nMin) { Min() = nMin; }
+ void setMax(long nMax) { Max() = nMax; }
+};
+
+inline Selection::Selection()
+{
+}
+
+inline Selection::Selection( long nPos ) : Pair( nPos, nPos )
+{
+}
+
+inline Selection::Selection( long nMin, long nMax ) :
+ Pair( nMin, nMax )
+{
+}
+
+inline BOOL Selection::IsInside( long nIs ) const
+{
+ return ((nA <= nIs) && (nIs < nB ));
+}
+
+inline void Selection::Justify()
+{
+ if ( nA > nB )
+ {
+ long nHelp = nA;
+ nA = nB;
+ nB = nHelp;
+ }
+}
+
+// -------------
+// - Rectangle -
+// -------------
+
+#define RECT_EMPTY ((short)-32767)
+
+class TOOLS_DLLPUBLIC Rectangle
+{
+public:
+ long nLeft;
+ long nTop;
+ long nRight;
+ long nBottom;
+
+ Rectangle();
+ Rectangle( const Point& rLT, const Point& rRB );
+ Rectangle( long nLeft, long nTop,
+ long nRight, long nBottom );
+ Rectangle( const Point& rLT, const Size& rSize );
+
+ long Left() const { return nLeft; }
+ long Right() const { return nRight; }
+ long Top() const { return nTop; }
+ long Bottom() const { return nBottom; }
+
+ long& Left() { return nLeft; }
+ long& Right() { return nRight; }
+ long& Top() { return nTop; }
+ long& Bottom() { return nBottom; }
+
+ inline Point TopLeft() const;
+ Point TopRight() const;
+ Point TopCenter() const;
+ Point BottomLeft() const;
+ Point BottomRight() const;
+ Point BottomCenter() const;
+ Point LeftCenter() const;
+ Point RightCenter() const;
+ Point Center() const;
+
+ void Move( long nHorzMove, long nVertMove );
+ inline void Transpose();
+ inline void SetPos( const Point& rPoint );
+ void SetSize( const Size& rSize );
+ inline Size GetSize() const;
+
+ long GetWidth() const;
+ long GetHeight() const;
+
+ Rectangle& Union( const Rectangle& rRect );
+ Rectangle& Intersection( const Rectangle& rRect );
+ Rectangle GetUnion( const Rectangle& rRect ) const;
+ Rectangle GetIntersection( const Rectangle& rRect ) const;
+
+ void Justify();
+
+ BOOL IsInside( const Point& rPOINT ) const;
+ BOOL IsInside( const Rectangle& rRect ) const;
+ BOOL IsOver( const Rectangle& rRect ) const;
+
+ void SetEmpty() { nRight = nBottom = RECT_EMPTY; }
+ BOOL IsEmpty() const;
+
+ BOOL operator == ( const Rectangle& rRect ) const;
+ BOOL operator != ( const Rectangle& rRect ) const;
+
+ Rectangle& operator += ( const Point& rPt );
+ Rectangle& operator -= ( const Point& rPt );
+
+#ifdef __BORLANDC__
+ friend Rectangle operator + ( const Rectangle& rRect, const Point& rPt );
+ friend Rectangle operator - ( const Rectangle& rRect, const Point& rPt );
+#else
+ friend inline Rectangle operator + ( const Rectangle& rRect, const Point& rPt );
+ friend inline Rectangle operator - ( const Rectangle& rRect, const Point& rPt );
+#endif
+
+ TOOLS_DLLPUBLIC friend SvStream& operator>>( SvStream& rIStream, Rectangle& rRect );
+ TOOLS_DLLPUBLIC friend SvStream& operator<<( SvStream& rOStream, const Rectangle& rRect );
+
+ // ONE
+ long getX() const { return nLeft; }
+ long getY() const { return nTop; }
+ long getWidth() const { return nRight - nLeft; }
+ long getHeight() const { return nBottom - nTop; }
+ void setX( long n ) { nRight += n-nLeft; nLeft = n; }
+ void setY( long n ) { nBottom += n-nTop; nTop = n; }
+ void setWidth( long n ) { nRight = nLeft + n; }
+ void setHeight( long n ) { nBottom = nTop + n; }
+};
+
+inline Rectangle::Rectangle()
+{
+ nLeft = nTop = 0;
+ nRight = nBottom = RECT_EMPTY;
+}
+
+inline Rectangle::Rectangle( const Point& rLT, const Point& rRB )
+{
+ nLeft = rLT.X();
+ nTop = rLT.Y();
+ nRight = rRB.X();
+ nBottom = rRB.Y();
+}
+
+inline Rectangle::Rectangle( long _nLeft, long _nTop,
+ long _nRight, long _nBottom )
+{
+ nLeft = _nLeft;
+ nTop = _nTop;
+ nRight = _nRight;
+ nBottom = _nBottom;
+}
+
+inline Rectangle::Rectangle( const Point& rLT, const Size& rSize )
+{
+ nLeft = rLT.X();
+ nTop = rLT.Y();
+ nRight = rSize.Width() ? nLeft+rSize.Width()-1 : RECT_EMPTY;
+ nBottom = rSize.Height() ? nTop+rSize.Height()-1 : RECT_EMPTY;
+}
+
+inline BOOL Rectangle::IsEmpty() const
+{
+ return ((nRight == RECT_EMPTY) || (nBottom == RECT_EMPTY));
+}
+
+inline Point Rectangle::TopLeft() const
+{
+ return Point( nLeft, nTop );
+}
+
+inline Point Rectangle::TopRight() const
+{
+ return Point( (nRight == RECT_EMPTY) ? nLeft : nRight, nTop );
+}
+
+inline Point Rectangle::BottomLeft() const
+{
+ return Point( nLeft, (nBottom == RECT_EMPTY) ? nTop : nBottom );
+}
+
+inline Point Rectangle::BottomRight() const
+{
+ return Point( (nRight == RECT_EMPTY) ? nLeft : nRight,
+ (nBottom == RECT_EMPTY) ? nTop : nBottom );
+}
+
+inline Point Rectangle::TopCenter() const
+{
+ if ( IsEmpty() )
+ return Point( nLeft, nTop );
+ else
+ return Point( Min( nLeft, nRight ) + Abs( (nRight - nLeft)/2 ),
+ Min( nTop, nBottom) );
+}
+
+inline Point Rectangle::BottomCenter() const
+{
+ if ( IsEmpty() )
+ return Point( nLeft, nTop );
+ else
+ return Point( Min( nLeft, nRight ) + Abs( (nRight - nLeft)/2 ),
+ Max( nTop, nBottom) );
+}
+
+inline Point Rectangle::LeftCenter() const
+{
+ if ( IsEmpty() )
+ return Point( nLeft, nTop );
+ else
+ return Point( Min( nLeft, nRight ), nTop + (nBottom - nTop)/2 );
+}
+
+inline Point Rectangle::RightCenter() const
+{
+ if ( IsEmpty() )
+ return Point( nLeft, nTop );
+ else
+ return Point( Max( nLeft, nRight ), nTop + (nBottom - nTop)/2 );
+}
+
+inline Point Rectangle::Center() const
+{
+ if ( IsEmpty() )
+ return Point( nLeft, nTop );
+ else
+ return Point( nLeft+(nRight-nLeft)/2 , nTop+(nBottom-nTop)/2 );
+}
+
+inline void Rectangle::Move( long nHorzMove, long nVertMove )
+{
+ nLeft += nHorzMove;
+ nTop += nVertMove;
+ if ( nRight != RECT_EMPTY )
+ nRight += nHorzMove;
+ if ( nBottom != RECT_EMPTY )
+ nBottom += nVertMove;
+}
+
+void Rectangle::Transpose()
+{
+ if ( !IsEmpty() )
+ {
+ long swap( nLeft );
+ nLeft = nTop;
+ nTop = swap;
+
+ swap = nRight;
+ nRight = nBottom;
+ nBottom = swap;
+ }
+}
+
+inline void Rectangle::SetPos( const Point& rPoint )
+{
+ if ( nRight != RECT_EMPTY )
+ nRight += rPoint.X() - nLeft;
+ if ( nBottom != RECT_EMPTY )
+ nBottom += rPoint.Y() - nTop;
+ nLeft = rPoint.X();
+ nTop = rPoint.Y();
+}
+
+inline long Rectangle::GetWidth() const
+{
+ long n;
+ if ( nRight == RECT_EMPTY )
+ n = 0;
+ else
+ {
+ n = nRight - nLeft;
+ if( n < 0 )
+ n--;
+ else
+ n++;
+ }
+
+ return n;
+}
+
+inline long Rectangle::GetHeight() const
+{
+ long n;
+ if ( nBottom == RECT_EMPTY )
+ n = 0;
+ else
+ {
+ n = nBottom - nTop;
+ if ( n < 0 )
+ n--;
+ else
+ n++;
+ }
+
+ return n;
+}
+
+inline Size Rectangle::GetSize() const
+{
+ return Size( GetWidth(), GetHeight() );
+}
+
+inline Rectangle Rectangle::GetUnion( const Rectangle& rRect ) const
+{
+ Rectangle aTmpRect( *this );
+ return aTmpRect.Union( rRect );
+}
+
+inline Rectangle Rectangle::GetIntersection( const Rectangle& rRect ) const
+{
+ Rectangle aTmpRect( *this );
+ return aTmpRect.Intersection( rRect );
+}
+
+inline BOOL Rectangle::operator == ( const Rectangle& rRect ) const
+{
+ return ((nLeft == rRect.nLeft ) &&
+ (nTop == rRect.nTop ) &&
+ (nRight == rRect.nRight ) &&
+ (nBottom == rRect.nBottom ));
+}
+
+inline BOOL Rectangle::operator != ( const Rectangle& rRect ) const
+{
+ return ((nLeft != rRect.nLeft ) ||
+ (nTop != rRect.nTop ) ||
+ (nRight != rRect.nRight ) ||
+ (nBottom != rRect.nBottom ));
+}
+
+inline Rectangle& Rectangle::operator +=( const Point& rPt )
+{
+ nLeft += rPt.X();
+ nTop += rPt.Y();
+ if ( nRight != RECT_EMPTY )
+ nRight += rPt.X();
+ if ( nBottom != RECT_EMPTY )
+ nBottom += rPt.Y();
+ return *this;
+}
+
+inline Rectangle& Rectangle::operator -= ( const Point& rPt )
+{
+ nLeft -= rPt.X();
+ nTop -= rPt.Y();
+ if ( nRight != RECT_EMPTY )
+ nRight -= rPt.X();
+ if ( nBottom != RECT_EMPTY )
+ nBottom -= rPt.Y();
+ return *this;
+}
+
+inline Rectangle operator + ( const Rectangle& rRect, const Point& rPt )
+{
+ Rectangle aRect( rRect.nLeft + rPt.X(), rRect.nTop + rPt.Y(),
+ (rRect.nRight == RECT_EMPTY) ? RECT_EMPTY : rRect.nRight + rPt.X(),
+ (rRect.nBottom == RECT_EMPTY) ? RECT_EMPTY : rRect.nBottom + rPt.Y() );
+ return aRect;
+}
+
+inline Rectangle operator - ( const Rectangle& rRect, const Point& rPt )
+{
+ Rectangle aRect( rRect.nLeft - rPt.X(),
+ rRect.nTop - rPt.Y(),
+ (rRect.nRight == RECT_EMPTY) ? RECT_EMPTY : rRect.nRight - rPt.X(),
+ (rRect.nBottom == RECT_EMPTY) ? RECT_EMPTY : rRect.nBottom - rPt.Y() );
+ return aRect;
+}
+
+#endif // _GEN_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/geninfo.hxx b/tools/inc/tools/geninfo.hxx
new file mode 100644
index 000000000000..feab81485e2b
--- /dev/null
+++ b/tools/inc/tools/geninfo.hxx
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _BOOTSTRP_GENINFO_HXX
+#define _BOOTSTRP_GENINFO_HXX
+
+#include "tools/toolsdllapi.h"
+
+#include <tools/string.hxx>
+#include <tools/list.hxx>
+
+// forwards
+class GenericInformationList;
+
+//
+// class GenericInformation
+//
+
+/******************************************************************************
+Purpose: holds generic informations and subinformations in a simple format
+******************************************************************************/
+
+class TOOLS_DLLPUBLIC GenericInformation : public ByteString // the key is stored in base class
+{
+friend class GenericInformationList; // can be child or/and parent
+private:
+ ByteString sValue; // holds value of data
+ ByteString sComment;
+
+ GenericInformationList *pInfoList; // holds subinformations
+ GenericInformationList *pParent; // holds a pointer to parent list
+
+ // methods
+ void ListDeleted() { pParent = NULL; } // allowed to be accessed
+ // from friend class
+ // GenericInformationList
+
+public:
+ GenericInformation( const ByteString &rKey, const ByteString &rValue,
+ GenericInformationList *pParentList = NULL,
+ GenericInformationList *pSubInfos = NULL );
+ GenericInformation( const GenericInformation& rInf, BOOL bCopySubs = TRUE);
+
+ ~GenericInformation();
+
+ ByteString &GetValue() { return sValue; }
+ void SetValue( const ByteString &rValue ) { sValue = rValue; }
+
+ ByteString &GetComment() { return sComment; }
+ void SetComment( const ByteString &rComment ) { sComment = rComment; }
+
+ // this methods used to handle sub informations
+ BOOL InsertSubInfo( GenericInformation *pInfo );
+ // siehe GenericInformationList
+ BOOL InsertSubInfo( const ByteString &rPathKey, const ByteString &rValue,
+ BOOL bSearchByPath = FALSE, BOOL bNewPath = FALSE);
+ void RemoveSubInfo( GenericInformation *pInfo, BOOL bDelete = FALSE );
+ // void RemoveSelf( BOOL bDelete = FALSE ); // loescht sich selbst aus der Parentliste
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // bei bDelete = TRUE werden auch alle Sublisten UND DIE INFO SELBST geloescht.
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ GenericInformation *GetSubInfo( ByteString &rKey, BOOL bSearchByPath = FALSE,
+ BOOL bCreatePath = FALSE );
+ // path can be something like this: src370/drives/o:
+
+ void SetSubList( GenericInformationList *pSubList )
+ { pInfoList = pSubList; }
+ GenericInformationList *GetSubList() { return pInfoList; }
+};
+
+/* diese Klasse bietet einen SemaphoreLock zum lesen (und nicht Schreiben)
+ * oder schreiben (und nicht lesen)
+ */
+class GenericLockInformation : public GenericInformation
+{
+public:
+GenericLockInformation( const ByteString &rKey, const ByteString &rValue,
+ GenericInformationList *pParentList = NULL,
+ GenericInformationList *pSubInfos = NULL )
+ : GenericInformation( rKey, rValue, pParentList, pSubInfos),
+ aLockState( read ), nLockKey( 0 ) {};
+ //~GenericLockInformation();
+
+ /* bietet einen Lockmechanismus fuer exclusive Zugriffe
+ *
+ * -"writeonly" wird angesprochen, wenn von der Wurzel ausgehend
+ * ein Item veraendert werden soll. In der Zeit kann die Liste nicht
+ * gelesen werden, womit keine Inconsistenzen entstehen koennen.
+ *
+ * -"read" wird zum Normalen lesen der Infos benutzt, 90% der Betriebszeit.
+ * waerenddessen kann nicht geschrieben werden -> writeonly Lock.
+ * Ist fuer den atomaren(nicht unterbrochenen) Lesezugriff gedacht
+ *
+ * -"readonly" wird zum niederschreiben des Teilbaums benutzt, was schon mal
+ * 10 Minuten dauern kann. In der Zeit kann kein Writeonlylock gesetzt
+ * werden, aber ein rescedule. Damit koennen andere Aktionen asynchron ausgefuert
+ * werden, aber die Datensicherheit bleibt gewahrt
+ *
+ * Zustandsaenderung: writeonly <-> read <-> readonly
+ *
+ * nLockKey ist zum verschluesseln des LockZugriffs mit einem 32bit Wort vorgesehen.
+ * ist der Schluessel nicht null, so kann nur mit dem Schluessel in
+ * die Baumstruktur geschrieben werden.
+ * ist der Schluessel nLockKey Null, dann kann jeder Schreiben und die Locks loesen
+ */
+ enum LockState{ writeonly, read, readonly };
+
+ /* der Schreibschutz darf nur aktiviert werden, wenn
+ * der Status auf Lesen steht
+ */
+ BOOL SetWriteLock(UINT32 nKey = 0) { return ((read==aLockState) &&
+ (aLockState=writeonly, nLockKey=nKey, TRUE)); }
+ /* Schreibschutz darf nur geloest werden, wenn
+ * der Schreibschutz drin ist, und
+ * entweder der LockKey Null ist(Generalschluessel) oder der Key zum LockKey passt
+ */
+ BOOL ReleaseWriteLock(UINT32 nKey = 0) { return ((writeonly==aLockState) &&
+ (!nLockKey||nKey==nLockKey) &&
+ (aLockState=read, nLockKey=0, TRUE)); } // setzt den zustand auf "read"
+ BOOL SetReadLock(UINT32 nKey = 0) { return ((read==aLockState) &&
+ (aLockState=readonly, nLockKey=nKey, TRUE)); }
+ BOOL ReleaseReadLock(UINT32 nKey = 0) { return ((readonly==aLockState) &&
+ (!nLockKey||nKey==nLockKey) &&
+ (aLockState=read, nLockKey=0, TRUE)); } // setzt den zustand auf "read"
+
+ LockState GetLockState() const { return aLockState; }
+ BOOL IsWriteLocked() const { return (writeonly==aLockState); }
+ BOOL IsReadLocked() const { return (readonly==aLockState); }
+ BOOL IsNotLocked() const { return (read==aLockState); }
+ BOOL IsLocker( UINT32 nKey ) { return (nKey==nLockKey || !nLockKey); }
+
+ /* wenn der Schreibschutz aktiviert wurde,
+ * und bei vorhandenem Schreibschutz die Keys stimmen
+ * rufe die Parentmethode auf */
+ BOOL InsertSubInfo( GenericInformation *pInfo, UINT32 nKey = 0 ) {
+ return ((writeonly==aLockState) &&
+ (!nLockKey || nKey==nLockKey) &&
+ (GenericInformation::InsertSubInfo( pInfo ), TRUE)); }
+
+ BOOL InsertSubInfo( const ByteString &rPathKey, const ByteString &rValue, UINT32 nKey = 0,
+ BOOL bSearchByPath = FALSE, BOOL bNewPath = FALSE) {
+ return ((writeonly==aLockState) &&
+ (!nLockKey || nKey==nLockKey) &&
+ (GenericInformation::InsertSubInfo( rPathKey, rValue, bSearchByPath, bNewPath ), TRUE)); }
+ /* 29.jan.98: erweiterung um lesemoeglichkeit vom Lockclienten */
+ GenericInformation *GetSubInfo( ByteString &rKey, BOOL bSearchByPath = FALSE,
+ BOOL bCreatePath = FALSE, UINT32 nKey = 0 ) {
+ if (writeonly==aLockState && nLockKey && nKey!=nLockKey )
+ return NULL;
+ return GenericInformation::GetSubInfo(rKey, bSearchByPath, bCreatePath); }
+
+ // TYPEINFO();
+private:
+
+ LockState aLockState;
+ UINT32 nLockKey;
+};
+
+//
+// class GenericInformationList
+//
+
+/******************************************************************************
+Purpose: holds set of generic informations in a sorted list
+******************************************************************************/
+
+DECLARE_LIST( GenericInformationList_Impl, GenericInformation * )
+
+class TOOLS_DLLPUBLIC GenericInformationList : public GenericInformationList_Impl
+{
+private:
+ GenericInformation *pOwner; // holds parent of this list
+
+protected:
+ // methods
+ ULONG InsertSorted( GenericInformation *pInfo, BOOL bOverwrite,
+ ULONG nStart, ULONG nEnd );
+ GenericInformation *Search( ULONG &rPos, ByteString sKey,
+ ULONG nStart, ULONG nEnd );
+
+public:
+ GenericInformationList( GenericInformation *pParent = NULL );
+ GenericInformationList(const GenericInformationList& rList, GenericInformation *pParent = NULL);
+ ~GenericInformationList();
+
+ // this methods used to handle the informations using binary search
+ GenericInformation *GetInfo( ByteString &rKey, BOOL bSearchByPath = FALSE,
+ BOOL bCreatePath = FALSE );
+ /* path can be something like this: src370/drives/o:
+ * bCreatePath will create the neccecary paths to the GI */
+
+ BOOL InsertInfo( GenericInformation *pInfo, BOOL bOverwrite = TRUE );
+ /* legt eine GenericInformation im Baum an mit Key-Value
+ * wenn bNewPath gesetzt, wird der nichtexistente Teil des Pfades neu kreiert
+ * wenn bNewPath nicht gesetzt ist und ein Teil des Pfades nicht vorhanden ist,
+ * gibt die Methode FALSE zurueck.*/
+ BOOL InsertInfo( const ByteString &rPathKey, const ByteString &rValue,
+ BOOL bSearchByPath = FALSE, BOOL bNewPath = FALSE);
+ void RemoveInfo( GenericInformation *pInfo, BOOL bDelete = FALSE );
+
+ GenericInformation* SetOwner( GenericInformation *pNewOwner );
+
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/getprocessworkingdir.hxx b/tools/inc/tools/getprocessworkingdir.hxx
new file mode 100644
index 000000000000..b27e40e1027f
--- /dev/null
+++ b/tools/inc/tools/getprocessworkingdir.hxx
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TOOLS_GETPROCESSWORKINGDIR_HXX
+#define INCLUDED_TOOLS_GETPROCESSWORKINGDIR_HXX
+
+#include "sal/config.h"
+
+#include "tools/toolsdllapi.h"
+
+namespace rtl { class OUString; }
+
+namespace tools {
+
+// get the process's current working directory, taking OOO_CWD into account
+//
+// @param url
+// a non-null pointer that receives the directory URL (with or without a final
+// slash) upon successful return, and the empty string upon unsuccessful return
+TOOLS_DLLPUBLIC bool getProcessWorkingDir(rtl::OUString * url);
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/globname.hxx b/tools/inc/tools/globname.hxx
new file mode 100644
index 000000000000..950b529673ae
--- /dev/null
+++ b/tools/inc/tools/globname.hxx
@@ -0,0 +1,140 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _GLOBNAME_HXX
+#define _GLOBNAME_HXX
+
+#include "tools/toolsdllapi.h"
+#include <com/sun/star/uno/Sequence.hxx>
+#include <tools/string.hxx>
+#include <tools/list.hxx>
+
+/*************************************************************************
+*************************************************************************/
+struct ImpSvGlobalName
+{
+ BYTE szData[ 16 ];
+ USHORT nRefCount;
+
+ ImpSvGlobalName()
+ {
+ nRefCount = 0;
+ }
+ ImpSvGlobalName( const ImpSvGlobalName & rObj );
+ ImpSvGlobalName( int );
+
+ BOOL operator == ( const ImpSvGlobalName & rObj ) const;
+};
+
+#ifdef WNT
+struct _GUID;
+typedef struct _GUID GUID;
+#else
+struct GUID;
+#endif
+typedef GUID CLSID;
+class SvStream;
+class SvGlobalNameList;
+class TOOLS_DLLPUBLIC SvGlobalName
+{
+friend class SvGlobalNameList;
+ ImpSvGlobalName * pImp;
+ void NewImp();
+public:
+ SvGlobalName();
+ SvGlobalName( const SvGlobalName & rObj )
+ {
+ pImp = rObj.pImp;
+ pImp->nRefCount++;
+ }
+ SvGlobalName( ImpSvGlobalName * pImpP )
+ {
+ pImp = pImpP;
+ pImp->nRefCount++;
+ }
+ SvGlobalName( UINT32 n1, USHORT n2, USHORT n3,
+ BYTE b8, BYTE b9, BYTE b10, BYTE b11,
+ BYTE b12, BYTE b13, BYTE b14, BYTE b15 );
+
+ // create SvGlobalName from a platform independent representation
+ SvGlobalName( const ::com::sun::star::uno::Sequence< sal_Int8 >& aSeq );
+
+ SvGlobalName & operator = ( const SvGlobalName & rObj );
+ ~SvGlobalName();
+
+ TOOLS_DLLPUBLIC friend SvStream & operator >> ( SvStream &, SvGlobalName & );
+ TOOLS_DLLPUBLIC friend SvStream & operator << ( SvStream &, const SvGlobalName & );
+
+ BOOL operator < ( const SvGlobalName & rObj ) const;
+ SvGlobalName & operator += ( UINT32 );
+ SvGlobalName & operator ++ () { return operator += ( 1 ); }
+
+ BOOL operator == ( const SvGlobalName & rObj ) const;
+ BOOL operator != ( const SvGlobalName & rObj ) const
+ { return !(*this == rObj); }
+
+ void MakeFromMemory( void * pData );
+ BOOL MakeId( const String & rId );
+ String GetctorName() const;
+ String GetHexName() const;
+ String GetRegDbName() const
+ {
+ String a = '{';
+ a += GetHexName();
+ a += '}';
+ return a;
+ }
+
+ SvGlobalName( const CLSID & rId );
+ const CLSID & GetCLSID() const { return *(CLSID *)pImp->szData; }
+ const BYTE* GetBytes() const { return pImp->szData; }
+
+ // platform independent representation of a "GlobalName"
+ // maybe transported remotely
+ com::sun::star::uno::Sequence < sal_Int8 > GetByteSequence() const;
+};
+
+class SvGlobalNameList
+{
+ List aList;
+public:
+ SvGlobalNameList();
+ ~SvGlobalNameList();
+
+ void Append( const SvGlobalName & );
+ SvGlobalName GetObject( ULONG );
+ BOOL IsEntry( const SvGlobalName & rName );
+ ULONG Count() const { return aList.Count(); }
+private:
+ // nicht erlaubt
+ SvGlobalNameList( const SvGlobalNameList & );
+ SvGlobalNameList & operator = ( const SvGlobalNameList & );
+};
+
+#endif // _GLOBNAME_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/inetdef.hxx b/tools/inc/tools/inetdef.hxx
new file mode 100644
index 000000000000..ac2f8bc3e56e
--- /dev/null
+++ b/tools/inc/tools/inetdef.hxx
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _TOOLS_INETDEF_HXX
+#define _TOOLS_INETDEF_HXX
+
+//============================================================================
+#if defined WNT
+#define TOOLS_INETDEF_OS "Win32"
+#elif defined OS2
+#define TOOLS_INETDEF_OS "OS/2"
+#elif defined UNX
+#if defined AIX
+#define TOOLS_INETDEF_OS "AIX"
+#elif defined HPUX
+#define TOOLS_INETDEF_OS "HP/UX"
+#elif defined SOLARIS && defined SPARC
+#define TOOLS_INETDEF_OS "Solaris Sparc"
+#elif defined SOLARIS && defined INTEL
+#define TOOLS_INETDEF_OS "Solaris x86"
+#elif defined SCO
+#define TOOLS_INETDEF_OS "SCO"
+#elif defined NETBSD && defined X86
+#define TOOLS_INETDEF_OS "NetBSD/i386"
+#elif defined NETBSD && defined X86_64
+#define TOOLS_INETDEF_OS "NetBSD/amd64"
+#elif defined NETBSD && defined ARM32
+#define TOOLS_INETDEF_OS "NetBSD/arm"
+#elif defined NETBSD && defined SPARC
+#define TOOLS_INETDEF_OS "NetBSD/sparc"
+#elif defined LINUX && defined X86
+#define TOOLS_INETDEF_OS "Linux"
+#elif defined FREEBSD && defined X86
+#define TOOLS_INETDEF_OS "FreeBSD/i386"
+#elif defined FREEBSD && defined X86_64
+#define TOOLS_INETDEF_OS "FreeBSD/amd64"
+#elif defined OPENBSD && defined X86
+#define TOOLS_INETDEF_OS "OpenBSD/i386"
+#elif defined OPENBSD && defined X86_64
+#define TOOLS_INETDEF_OS "OpenBSD/amd64"
+#elif defined SINIX
+#define TOOLS_INETDEF_OS "SINIX"
+#else // AIX, HPUX, SOLARIS, ...
+#define TOOLS_INETDEF_OS "Unix"
+#endif // AIX, HPUX, SOLARIS, ...
+#else // WNT, ...
+#define TOOLS_INETDEF_OS "unknown OS"
+#endif // WN, ...
+
+#define TOOLS_INETDEF_PRODUCT "StarOffice/5.2"
+#define TOOLS_INETDEF_MOZILLA "Mozilla/3.0"
+
+#define INET_PRODUCTNAME TOOLS_INETDEF_PRODUCT " (" TOOLS_INETDEF_OS ")"
+#define INET_DEF_CALLERNAME TOOLS_INETDEF_MOZILLA " (compatible; " \
+ TOOLS_INETDEF_PRODUCT "; " TOOLS_INETDEF_OS ")"
+
+//============================================================================
+// The following definitions seem obsolete and might get removed in future.
+
+#define INET_PERS_CERT_HOMEPAGE "http://www.stardivision.de/certs.html"
+#define INET_PERS_CERT_HOMEPAGE_INT \
+ "http://www.stardivision.de/certs/certs##.html"
+ // the above definitions are only used in svx/source/options/optinet2.cxx
+
+#if defined __RSC
+#define INET_UNDEFINED 0
+#define INET_NAME_RESOLVE_START 1
+#define INET_NAME_RESOLVE_ERROR 2
+#define INET_NAME_RESOLVE_SUCCESS 3
+#define INET_CONNECT_START 4
+#define INET_CONNECT_ERROR 5
+#define INET_CONNECT_SUCCESS 6
+#define INET_WRITE_START 7
+#define INET_WRITE_STATUS 8
+#define INET_WRITE_ERROR 9
+#define INET_WRITE_SUCCESS 10
+#define INET_READ_START 11
+#define INET_READ_STATUS 12
+#define INET_READ_ERROR 13
+#define INET_READ_SUCCESS 14
+#define INET_CLOSING_CONNECTION 15
+#define INET_CONNECTION_CLOSED 16
+#define INET_REQUEST_CANCELED 17
+#define INET_CONNECTION_CANCELED 18
+#define INET_SESSION_CANCELED 19
+#define INET_AUTHENTICATION 20
+#define INET_OFFLINE_ERROR 21
+#define INET_PROXY_AUTHENTICATION 22
+#endif // __RSC
+ // the above definitions are only used in sfx2/source/doc/doc.src
+
+#endif // _TOOLS_INETDEF_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/inetmime.hxx b/tools/inc/tools/inetmime.hxx
new file mode 100644
index 000000000000..7ca43f08921b
--- /dev/null
+++ b/tools/inc/tools/inetmime.hxx
@@ -0,0 +1,1447 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef TOOLS_INETMIME_HXX
+#define TOOLS_INETMIME_HXX
+
+#include "tools/toolsdllapi.h"
+#include <rtl/alloc.h>
+#include <rtl/string.h>
+#include "rtl/tencinfo.h"
+#include <tools/debug.hxx>
+#include <tools/errcode.hxx>
+#include <tools/list.hxx>
+#include <tools/string.hxx>
+
+class DateTime;
+class INetContentTypeParameterList;
+class INetMIMECharsetList_Impl;
+class INetMIMEOutputSink;
+
+//============================================================================
+class TOOLS_DLLPUBLIC INetMIME
+{
+public:
+ enum { SOFT_LINE_LENGTH_LIMIT = 76,
+ HARD_LINE_LENGTH_LIMIT = 998 };
+
+ /** The various types of message header field bodies, with respect to
+ encoding and decoding them.
+
+ @descr At the moment, five different types of header fields suffice
+ to describe how to encoded and decode any known message header field
+ body, but need for more types may arise in the future as new header
+ fields are introduced.
+
+ @descr The following is an exhaustive list of all the header fields
+ currently known to our implementation. For every header field, it
+ includes a 'canonic' (with regard to capitalization) name, a grammar
+ rule for the body (using RFC 822 and RFC 2234 conventions), a list of
+ relevant sources of information, and the HeaderFieldType value to use
+ with that header field. The list is based on RFC 2076 and draft-
+ palme-mailext-headers-02.txt (see also <http://www.dsv.su.se/~jpalme/
+ ietf/jp-ietf-home.html#anchor1003783>).
+
+ Approved: address ;RFC 1036; HEADER_FIELD_ADDRESS
+ bcc: #address ;RFCs 822, 2047; HEADER_FIELD_ADDRESS
+ cc: 1#address ;RFCs 822, 2047; HEADER_FIELD_ADDRESS
+ Comments: *text ;RFCs 822, RFC 2047; HEADER_FIELD_TEXT
+ Content-Base: absoluteURI ;RFC 2110; HEADER_FIELD_TEXT
+ Content-Description: *text ;RFC 2045, RFC 2047; HEADER_FIELD_TEXT
+ Content-Disposition: disposition-type *(";" disposition-parm)
+ ;RFC 1806; HEADER_FIELD_STRUCTURED
+ Content-ID: msg-id ;RFC 2045, RFC 2047; HEADER_FIELD_MESSAGE_ID
+ Content-Location: absoluteURI / relativeURI ;RFC 2110;
+ HEADER_FIELD_TEXT
+ Content-Transfer-Encoding: mechanism ;RFC 2045, RFC 2047;
+ HEADER_FIELD_STRUCTURED
+ Content-Type: type "/" subtype *(";" parameter) ;RFC 2045, RFC 2047;
+ HEADER_FIELD_STRUCTURED
+ Control: *text ;RFC 1036; HEADER_FIELD_TEXT
+ Date: date-time ;RFC 822, RFC 1123, RFC 2047; HEADER_FIELD_STRUCTURED
+ Distribution: 1#atom ;RFC 1036; HEADER_FIELD_STRUCTURED
+ Encrypted: 1#2word ;RFC 822, RFC 2047; HEADER_FIELD_STRUCTURED
+ Expires: date-time ;RFC 1036; HEADER_FIELD_STRUCTURED
+ Followup-To: 1#(atom *("." atom)) ;RFC 1036; HEADER_FIELD_STRUCTURED
+ From: mailbox / 1#mailbox ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
+ In-Reply-To: *(phrase / msg-id) ;RFC 822, RFC 2047;
+ HEADER_FIELD_ADDRESS
+ Keywords: #phrase ;RFC 822, RFC 2047; HEADER_FIELD_PHRASE
+ MIME-Version: 1*DIGIT "." 1*DIGIT ;RFC 2045, RFC 2047;
+ HEADER_FIELD_STRUCTURED
+ Message-ID: msg-id ;RFC 822, RFC 2047; HEADER_FIELD_MESSAGE_ID
+ Newsgroups: 1#(atom *("." atom)) ;RFC 1036, RFC 2047;
+ HEADER_FIELD_STRUCTURED
+ Organization: *text ;RFC 1036; HEADER_FIELD_TEXT
+ Received: ["from" domain] ["by" domain] ["via" atom] *("with" atom)
+ ["id" msg-id] ["for" addr-spec] ";" date-time ;RFC 822, RFC 1123,
+ RFC 2047; HEADER_FIELD_STRUCTURED
+ References: *(phrase / msg-id) ;RFC 822, RFC 2047;
+ HEADER_FIELD_ADDRESS
+ Reply-To: 1#address ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
+ Resent-Date: date-time ;RFC 822, RFC 1123, RFC 2047;
+ HEADER_FIELD_STRUCTURED
+ Resent-From: mailbox / 1#mailbox ;RFC 822, RFC 2047;
+ HEADER_FIELD_ADDRESS
+ Resent-Message-ID: msg-id ;RFC 822, RFC 2047; HEADER_FIELD_MESSAGE_ID
+ Resent-Reply-To: 1#address ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
+ Resent-Sender: mailbox ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
+ Resent-To: 1#address ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
+ Resent-bcc: #address ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
+ Resent-cc: 1#address ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
+ Return-path: route-addr / ("<" ">") ;RFC 822, RFC 1123, RFC 2047;
+ HEADER_FIELD_STRUCTURED
+ Return-Receipt-To: address ;Not Internet standard;
+ HEADER_FIELD_ADDRES
+ Sender: mailbox ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
+ Subject: *text ;RFC 822, RFC 2047; HEADER_FIELD_TEXT
+ Summary: *text ;RFC 1036; HEADER_FIELD_TEXT
+ To: 1#address ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
+ X-CHAOS-Marked: "YES" / "NO" ;local; HEADER_FIELD_STRUCTURED
+ X-CHAOS-Read: "YES" / "NO" ;local; HEADER_FIELD_STRUCTURED
+ X-CHAOS-Recipients: #*("<" atom word ">") ;local;
+ HEADER_FIELD_STRUCTURED
+ X-CHAOS-Size: 1*DIGIT ;local; HEADER_FIELD_STRUCTURED
+ X-Mailer: *text ;Not Internet standard; HEADER_FIELD_TEXT
+ X-Mozilla-Status: 4HEXDIG ;Mozilla; HEADER_FIELD_STRUCTURED
+ X-Newsreader: *text ;Not Internet standard; HEADER_FIELD_TEXT
+ X-Priority: "1" / "2" / "3" / "4" / "5" ;Not Internet standard;
+ HEADER_FIELD_STRUCTURED
+ Xref: sub-domain
+ 1*((atom / string) *("." (atom / string)) ":" msg-number)
+ ;RFCs 1036, 2047, local; HEADER_FIELD_STRUCTURED
+ */
+ enum HeaderFieldType
+ {
+ HEADER_FIELD_TEXT,
+ HEADER_FIELD_STRUCTURED,
+ HEADER_FIELD_PHRASE,
+ HEADER_FIELD_MESSAGE_ID,
+ HEADER_FIELD_ADDRESS
+ };
+
+ /** Check for US-ASCII character.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is a US-ASCII character (0x00--0x7F).
+ */
+ static inline bool isUSASCII(sal_uInt32 nChar);
+
+ /** Check for ISO 8859-1 character.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is a ISO 8859-1 character (0x00--0xFF).
+ */
+ static inline bool isISO88591(sal_uInt32 nChar);
+
+ /** Check for US-ASCII control character.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is a US-ASCII control character (US-ASCII
+ 0x00--0x1F or 0x7F).
+ */
+ static inline bool isControl(sal_uInt32 nChar);
+
+ /** Check for US-ASCII white space character.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is a US-ASCII white space character (US-ASCII
+ 0x09 or 0x20).
+ */
+ static inline bool isWhiteSpace(sal_uInt32 nChar);
+
+ /** Check for US-ASCII visible character.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is a US-ASCII visible character (US-ASCII
+ 0x21--0x7E).
+ */
+ static inline bool isVisible(sal_uInt32 nChar);
+
+ /** Check for US-ASCII digit character.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is a US-ASCII (decimal) digit character (US-
+ ASCII '0'--'9').
+ */
+ static inline bool isDigit(sal_uInt32 nChar);
+
+ /** Check for US-ASCII canonic hexadecimal digit character.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is a US-ASCII canonic (i.e., upper case)
+ hexadecimal digit character (US-ASCII '0'--'9' or 'A'--'F').
+ */
+ static inline bool isCanonicHexDigit(sal_uInt32 nChar);
+
+ /** Check for US-ASCII hexadecimal digit character.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is a US-ASCII hexadecimal digit character (US-
+ ASCII '0'--'9', 'A'--'F', 'a'--'f').
+ */
+ static inline bool isHexDigit(sal_uInt32 nChar);
+
+ /** Check for US-ASCII upper case character.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is a US-ASCII upper case alphabetic character
+ (US-ASCII 'A'--'Z').
+ */
+ static inline bool isUpperCase(sal_uInt32 nChar);
+
+ /** Check for US-ASCII lower case character.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is a US-ASCII lower case alphabetic character
+ (US-ASCII 'a'--'z').
+ */
+ static inline bool isLowerCase(sal_uInt32 nChar);
+
+ /** Check for US-ASCII alphabetic character.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is a US-ASCII alphabetic character (US-ASCII
+ 'A'--'Z' or 'a'--'z').
+ */
+ static inline bool isAlpha(sal_uInt32 nChar);
+
+ /** Check for US-ASCII alphanumeric character.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is a US-ASCII alphanumeric character (US-ASCII
+ '0'--'9', 'A'--'Z' or 'a'--'z').
+ */
+ static inline bool isAlphanumeric(sal_uInt32 nChar);
+
+ /** Check for US-ASCII Base 64 digit character.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is a US-ASCII Base 64 digit character (US-ASCII
+ 'A'--'Z', 'a'--'z', '0'--'9', '+', or '/').
+ */
+ static inline bool isBase64Digit(sal_uInt32 nChar);
+
+ /** Check whether some character is valid within an RFC 822 <atom>.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is valid within an RFC 822 <atom> (US-ASCII
+ 'A'--'Z', 'a'--'z', '0'--'9', '!', '#', '$', '%', '&', ''', '*', '+',
+ '-', '/', '=', '?', '^', '_', '`', '{', '|', '}', or '~').
+ */
+ static bool isAtomChar(sal_uInt32 nChar);
+
+ /** Check whether some character is valid within an RFC 2045 <token>.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is valid within an RFC 2047 <token> (US-ASCII
+ 'A'--'Z', 'a'--'z', '0'--'9', '!', '#', '$', '%', '&', ''', '*', '+',
+ '-', '.', '^', '_', '`', '{', '|', '}', or '~').
+ */
+ static bool isTokenChar(sal_uInt32 nChar);
+
+ /** Check whether some character is valid within an RFC 2047 <token>.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is valid within an RFC 2047 <token> (US-ASCII
+ 'A'--'Z', 'a'--'z', '0'--'9', '!', '#', '$', '%', '&', ''', '*', '+',
+ '-', '^', '_', '`', '{', '|', '}', or '~').
+ */
+ static bool isEncodedWordTokenChar(sal_uInt32 nChar);
+
+ /** Check whether some character is valid within an RFC 2060 <atom>.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is valid within an RFC 2060 <atom> (US-ASCII
+ 'A'--'Z', 'a'--'z', '0'--'9', '!', '#', '$', '&', ''', '+', ',', '-',
+ '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', ']', '^', '_', '`',
+ '|', '}', or '~').
+ */
+ static bool isIMAPAtomChar(sal_uInt32 nChar);
+
+ /** Translate an US-ASCII character to upper case.
+
+ @param nChar Some UCS-4 character.
+
+ @return If nChar is a US-ASCII upper case character (US-ASCII
+ 'A'--'Z'), return the corresponding US-ASCII lower case character (US-
+ ASCII 'a'--'z'); otherwise, return nChar unchanged.
+ */
+ static inline sal_uInt32 toUpperCase(sal_uInt32 nChar);
+
+ /** Translate an US-ASCII character to lower case.
+
+ @param nChar Some UCS-4 character.
+
+ @return If nChar is a US-ASCII lower case character (US-ASCII
+ 'a'--'z'), return the corresponding US-ASCII upper case character (US-
+ ASCII 'A'--'Z'); otherwise, return nChar unchanged.
+ */
+ static inline sal_uInt32 toLowerCase(sal_uInt32 nChar);
+
+ /** Get the digit weight of a US-ASCII character.
+
+ @param nChar Some UCS-4 character.
+
+ @return If nChar is a US-ASCII (decimal) digit character (US-ASCII
+ '0'--'9'), return the corresponding weight (0--9); otherwise,
+ return -1.
+ */
+ static inline int getWeight(sal_uInt32 nChar);
+
+ /** Get the hexadecimal digit weight of a US-ASCII character.
+
+ @param nChar Some UCS-4 character.
+
+ @return If nChar is a US-ASCII hexadecimal digit character (US-ASCII
+ '0'--'9', 'A'--'F', or 'a'--'f'), return the corresponding weight
+ (0--15); otherwise, return -1.
+ */
+ static inline int getHexWeight(sal_uInt32 nChar);
+
+ /** Get the Base 64 digit weight of a US-ASCII character.
+
+ @param nChar Some UCS-4 character.
+
+ @return If nChar is a US-ASCII Base 64 digit character (US-ASCII
+ 'A'--'F', or 'a'--'f', '0'--'9', '+', or '/'), return the
+ corresponding weight (0--63); if nChar is the US-ASCII Base 64 padding
+ character (US-ASCII '='), return -1; otherwise, return -2.
+ */
+ static inline int getBase64Weight(sal_uInt32 nChar);
+
+ /** Get a decimal digit encoded as US-ASCII.
+
+ @param nWeight Must be in the range 0--9, inclusive.
+
+ @return The decimal digit corresponding to nWeight (US-ASCII
+ '0'--'9').
+ */
+ static sal_uInt32 getDigit(int nWeight);
+
+ /** Get a hexadecimal digit encoded as US-ASCII.
+
+ @param nWeight Must be in the range 0--15, inclusive.
+
+ @return The canonic (i.e., upper case) hexadecimal digit
+ corresponding to nWeight (US-ASCII '0'--'9' or 'A'--'F').
+ */
+ static sal_uInt32 getHexDigit(int nWeight);
+
+ /** Get a Base 64 digit encoded as US-ASCII.
+
+ @param nWeight Must be in the range 0--63, inclusive.
+
+ @return The Base 64 digit corresponding to nWeight (US-ASCII 'A'--
+ 'Z', 'a'--'z', '0'--'9', '+' or '/').
+ */
+ static sal_uInt32 getBase64Digit(int nWeight);
+
+ static inline bool isHighSurrogate(sal_uInt32 nUTF16);
+
+ static inline bool isLowSurrogate(sal_uInt32 nUTF16);
+
+ static inline sal_uInt32 toUTF32(sal_Unicode cHighSurrogate,
+ sal_Unicode cLowSurrogate);
+
+ /** Check two US-ASCII strings for equality, ignoring case.
+
+ @param pBegin1 Points to the start of the first string, must not be
+ null.
+
+ @param pEnd1 Points past the end of the first string, must be >=
+ pBegin1.
+
+ @param pBegin2 Points to the start of the second string, must not be
+ null.
+
+ @param pEnd2 Points past the end of the second string, must be >=
+ pBegin2.
+
+ @return True if the two strings are equal, ignoring the case of US-
+ ASCII alphabetic characters (US-ASCII 'A'--'Z' and 'a'--'z').
+ */
+ static bool equalIgnoreCase(const sal_Char * pBegin1,
+ const sal_Char * pEnd1,
+ const sal_Char * pBegin2,
+ const sal_Char * pEnd2);
+
+ /** Check two US-ASCII strings for equality, ignoring case.
+
+ @param pBegin1 Points to the start of the first string, must not be
+ null.
+
+ @param pEnd1 Points past the end of the first string, must be >=
+ pBegin1.
+
+ @param pString2 Points to the start of the null terminated second
+ string, must not be null.
+
+ @return True if the two strings are equal, ignoring the case of US-
+ ASCII alphabetic characters (US-ASCII 'A'--'Z' and 'a'--'z').
+ */
+ static bool equalIgnoreCase(const sal_Char * pBegin1,
+ const sal_Char * pEnd1,
+ const sal_Char * pString2);
+
+ /** Check two US-ASCII strings for equality, ignoring case.
+
+ @param pBegin1 Points to the start of the first string, must not be
+ null.
+
+ @param pEnd1 Points past the end of the first string, must be >=
+ pBegin1.
+
+ @param pString2 Points to the start of the null terminated second
+ string, must not be null.
+
+ @return True if the two strings are equal, ignoring the case of US-
+ ASCII alphabetic characters (US-ASCII 'A'--'Z' and 'a'--'z').
+ */
+ static bool equalIgnoreCase(const sal_Unicode * pBegin1,
+ const sal_Unicode * pEnd1,
+ const sal_Char * pString2);
+
+ /** Check two US-ASCII strings for equality, ignoring case.
+
+ @param rString1 The first string.
+
+ @param sString2 Points to the start of the null terminated second
+ string, must not be null.
+
+ @return True if the two strings are equal, ignoring the case of US-
+ ASCII alphabetic characters (US-ASCII 'A'--'Z' and 'a'--'z').
+ */
+ static inline bool equalIgnoreCase(const ByteString & rString1,
+ const sal_Char * pString2);
+
+ static inline bool startsWithLineBreak(const sal_Char * pBegin,
+ const sal_Char * pEnd);
+
+ static inline bool startsWithLineBreak(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd);
+
+ static inline bool startsWithLineFolding(const sal_Char * pBegin,
+ const sal_Char * pEnd);
+
+ static inline bool startsWithLineFolding(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd);
+
+ static bool startsWithLinearWhiteSpace(const sal_Char * pBegin,
+ const sal_Char * pEnd);
+
+ static const sal_Char * skipLinearWhiteSpace(const sal_Char * pBegin,
+ const sal_Char * pEnd);
+
+ static const sal_Unicode * skipLinearWhiteSpace(const sal_Unicode *
+ pBegin,
+ const sal_Unicode * pEnd);
+
+ static const sal_Char * skipComment(const sal_Char * pBegin,
+ const sal_Char * pEnd);
+
+ static const sal_Unicode * skipComment(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd);
+
+ static const sal_Char * skipLinearWhiteSpaceComment(const sal_Char *
+ pBegin,
+ const sal_Char *
+ pEnd);
+
+ static const sal_Unicode * skipLinearWhiteSpaceComment(const sal_Unicode *
+ pBegin,
+ const sal_Unicode *
+ pEnd);
+
+ static inline bool needsQuotedStringEscape(sal_uInt32 nChar);
+
+ static const sal_Char * skipQuotedString(const sal_Char * pBegin,
+ const sal_Char * pEnd);
+
+ static const sal_Unicode * skipQuotedString(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd);
+
+ static const sal_Char * scanAtom(const sal_Char * pBegin,
+ const sal_Char * pEnd);
+
+ static const sal_Unicode * scanAtom(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd);
+
+ static bool scanUnsigned(const sal_Char *& rBegin, const sal_Char * pEnd,
+ bool bLeadingZeroes, sal_uInt32 & rValue);
+
+ static bool scanUnsigned(const sal_Unicode *& rBegin,
+ const sal_Unicode * pEnd, bool bLeadingZeroes,
+ sal_uInt32 & rValue);
+
+ static bool scanUnsignedHex(const sal_Char *& rBegin,
+ const sal_Char * pEnd, bool bLeadingZeroes,
+ sal_uInt32 & rValue);
+
+ static bool scanUnsignedHex(const sal_Unicode *& rBegin,
+ const sal_Unicode * pEnd, bool bLeadingZeroes,
+ sal_uInt32 & rValue);
+
+ static const sal_Char * scanQuotedBlock(const sal_Char * pBegin,
+ const sal_Char * pEnd,
+ sal_uInt32 nOpening,
+ sal_uInt32 nClosing,
+ sal_Size & rLength,
+ bool & rModify);
+
+ static const sal_Unicode * scanQuotedBlock(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd,
+ sal_uInt32 nOpening,
+ sal_uInt32 nClosing,
+ sal_Size & rLength,
+ bool & rModify);
+
+ static sal_Char const * scanParameters(sal_Char const * pBegin,
+ sal_Char const * pEnd,
+ INetContentTypeParameterList *
+ pParameters);
+
+ static sal_Unicode const * scanParameters(sal_Unicode const * pBegin,
+ sal_Unicode const * pEnd,
+ INetContentTypeParameterList *
+ pParameters);
+
+ static inline rtl_TextEncoding translateToMIME(rtl_TextEncoding
+ eEncoding);
+
+ static inline rtl_TextEncoding translateFromMIME(rtl_TextEncoding
+ eEncoding);
+
+ static const sal_Char * getCharsetName(rtl_TextEncoding eEncoding);
+
+ static rtl_TextEncoding getCharsetEncoding(const sal_Char * pBegin,
+ const sal_Char * pEnd);
+
+ static rtl_TextEncoding getCharsetEncoding(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd);
+
+ static inline bool isMIMECharsetEncoding(rtl_TextEncoding eEncoding);
+
+ static INetMIMECharsetList_Impl *
+ createPreferredCharsetList(rtl_TextEncoding eEncoding);
+
+ static sal_Unicode * convertToUnicode(const sal_Char * pBegin,
+ const sal_Char * pEnd,
+ rtl_TextEncoding eEncoding,
+ sal_Size & rSize);
+
+ static sal_Char * convertFromUnicode(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd,
+ rtl_TextEncoding eEncoding,
+ sal_Size & rSize);
+
+ /** Get the number of octets required to encode an UCS-4 character using
+ UTF-8 encoding.
+
+ @param nChar Some UCS-4 character.
+
+ @return The number of octets required (in the range 1--6, inclusive).
+ */
+ static inline int getUTF8OctetCount(sal_uInt32 nChar);
+
+ static inline void writeEscapeSequence(INetMIMEOutputSink & rSink,
+ sal_uInt32 nChar);
+
+ static void writeUTF8(INetMIMEOutputSink & rSink, sal_uInt32 nChar);
+
+ static void writeUnsigned(INetMIMEOutputSink & rSink, sal_uInt32 nValue,
+ int nMinDigits = 1);
+
+ static void writeDateTime(INetMIMEOutputSink & rSink,
+ const DateTime & rUTC);
+
+ static void writeHeaderFieldBody(INetMIMEOutputSink & rSink,
+ HeaderFieldType eType,
+ const ByteString & rBody,
+ rtl_TextEncoding ePreferredEncoding,
+ bool bInitialSpace = true);
+
+ static void writeHeaderFieldBody(INetMIMEOutputSink & rSink,
+ HeaderFieldType eType,
+ const UniString & rBody,
+ rtl_TextEncoding ePreferredEncoding,
+ bool bInitialSpace = true);
+
+ static bool translateUTF8Char(const sal_Char *& rBegin,
+ const sal_Char * pEnd,
+ rtl_TextEncoding eEncoding,
+ sal_uInt32 & rCharacter);
+
+ static ByteString decodeUTF8(const ByteString & rText,
+ rtl_TextEncoding eEncoding);
+
+ static UniString decodeHeaderFieldBody(HeaderFieldType eType,
+ const ByteString & rBody);
+
+// #i70651#: Prevent warnings on Mac OS X.
+#ifdef MACOSX
+#pragma GCC system_header
+#endif
+
+ /** Get the UTF-32 character at the head of a UTF-16 encoded string.
+
+ @param rBegin Points to the start of the UTF-16 encoded string, must
+ not be null. On exit, it points past the first UTF-32 character's
+ encoding.
+
+ @param pEnd Points past the end of the UTF-16 encoded string, must be
+ strictly greater than rBegin.
+
+ @return The UCS-4 character at the head of the UTF-16 encoded string.
+ If the string does not start with the UTF-16 encoding of a UCS-32
+ character, the first UTF-16 value is returned.
+ */
+ static inline sal_uInt32 getUTF32Character(const sal_Unicode *& rBegin,
+ const sal_Unicode * pEnd);
+
+ /** Put the UTF-16 encoding of a UTF-32 character into a buffer.
+
+ @param pBuffer Points to a buffer, must not be null.
+
+ @param nUTF32 An UTF-32 character, must be in the range 0..0x10FFFF.
+
+ @return A pointer past the UTF-16 characters put into the buffer
+ (i.e., pBuffer + 1 or pBuffer + 2).
+ */
+ static inline sal_Unicode * putUTF32Character(sal_Unicode * pBuffer,
+ sal_uInt32 nUTF32);
+};
+
+// static
+inline bool INetMIME::isUSASCII(sal_uInt32 nChar)
+{
+ return nChar <= 0x7F;
+}
+
+// static
+inline bool INetMIME::isISO88591(sal_uInt32 nChar)
+{
+ return nChar <= 0xFF;
+}
+
+// static
+inline bool INetMIME::isControl(sal_uInt32 nChar)
+{
+ return nChar <= 0x1F || nChar == 0x7F;
+}
+
+// static
+inline bool INetMIME::isWhiteSpace(sal_uInt32 nChar)
+{
+ return nChar == '\t' || nChar == ' ';
+}
+
+// static
+inline bool INetMIME::isVisible(sal_uInt32 nChar)
+{
+ return nChar >= '!' && nChar <= '~';
+}
+
+// static
+inline bool INetMIME::isDigit(sal_uInt32 nChar)
+{
+ return nChar >= '0' && nChar <= '9';
+}
+
+// static
+inline bool INetMIME::isCanonicHexDigit(sal_uInt32 nChar)
+{
+ return isDigit(nChar) || (nChar >= 'A' && nChar <= 'F');
+}
+
+// static
+inline bool INetMIME::isHexDigit(sal_uInt32 nChar)
+{
+ return isCanonicHexDigit(nChar) || (nChar >= 'a' && nChar <= 'f');
+}
+
+// static
+inline bool INetMIME::isUpperCase(sal_uInt32 nChar)
+{
+ return nChar >= 'A' && nChar <= 'Z';
+}
+
+// static
+inline bool INetMIME::isLowerCase(sal_uInt32 nChar)
+{
+ return nChar >= 'a' && nChar <= 'z';
+}
+
+// static
+inline bool INetMIME::isAlpha(sal_uInt32 nChar)
+{
+ return isUpperCase(nChar) || isLowerCase(nChar);
+}
+
+// static
+inline bool INetMIME::isAlphanumeric(sal_uInt32 nChar)
+{
+ return isAlpha(nChar) || isDigit(nChar);
+}
+
+// static
+inline bool INetMIME::isBase64Digit(sal_uInt32 nChar)
+{
+ return isUpperCase(nChar) || isLowerCase(nChar) || isDigit(nChar)
+ || nChar == '+' || nChar == '/';
+}
+
+// static
+inline sal_uInt32 INetMIME::toUpperCase(sal_uInt32 nChar)
+{
+ return isLowerCase(nChar) ? nChar - ('a' - 'A') : nChar;
+}
+
+// static
+inline sal_uInt32 INetMIME::toLowerCase(sal_uInt32 nChar)
+{
+ return isUpperCase(nChar) ? nChar + ('a' - 'A') : nChar;
+}
+
+// static
+inline int INetMIME::getWeight(sal_uInt32 nChar)
+{
+ return isDigit(nChar) ? int(nChar - '0') : -1;
+}
+
+// static
+inline int INetMIME::getHexWeight(sal_uInt32 nChar)
+{
+ return isDigit(nChar) ? int(nChar - '0') :
+ nChar >= 'A' && nChar <= 'F' ? int(nChar - 'A' + 10) :
+ nChar >= 'a' && nChar <= 'f' ? int(nChar - 'a' + 10) : -1;
+}
+
+// static
+inline int INetMIME::getBase64Weight(sal_uInt32 nChar)
+{
+ return isUpperCase(nChar) ? int(nChar - 'A') :
+ isLowerCase(nChar) ? int(nChar - 'a' + 26) :
+ isDigit(nChar) ? int(nChar - '0' + 52) :
+ nChar == '+' ? 62 :
+ nChar == '/' ? 63 :
+ nChar == '=' ? -1 : -2;
+}
+
+// static
+inline bool INetMIME::isHighSurrogate(sal_uInt32 nUTF16)
+{
+ return nUTF16 >= 0xD800 && nUTF16 <= 0xDBFF;
+}
+
+// static
+inline bool INetMIME::isLowSurrogate(sal_uInt32 nUTF16)
+{
+ return nUTF16 >= 0xDC00 && nUTF16 <= 0xDFFF;
+}
+
+// static
+inline sal_uInt32 INetMIME::toUTF32(sal_Unicode cHighSurrogate,
+ sal_Unicode cLowSurrogate)
+{
+ DBG_ASSERT(isHighSurrogate(cHighSurrogate)
+ && isLowSurrogate(cLowSurrogate),
+ "INetMIME::toUTF32(): Bad chars");
+ return ((sal_uInt32(cHighSurrogate) & 0x3FF) << 10)
+ | (sal_uInt32(cLowSurrogate) & 0x3FF);
+}
+
+// static
+inline bool INetMIME::equalIgnoreCase(const ByteString & rString1,
+ const sal_Char * pString2)
+{
+ return equalIgnoreCase(rString1.GetBuffer(),
+ rString1.GetBuffer() + rString1.Len(), pString2);
+}
+
+// static
+inline bool INetMIME::startsWithLineBreak(const sal_Char * pBegin,
+ const sal_Char * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIME::startsWithLineBreak(): Bad sequence");
+
+ return pEnd - pBegin >= 2 && pBegin[0] == 0x0D && pBegin[1] == 0x0A;
+ // CR, LF
+}
+
+// static
+inline bool INetMIME::startsWithLineBreak(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIME::startsWithLineBreak(): Bad sequence");
+
+ return pEnd - pBegin >= 2 && pBegin[0] == 0x0D && pBegin[1] == 0x0A;
+ // CR, LF
+}
+
+// static
+inline bool INetMIME::startsWithLineFolding(const sal_Char * pBegin,
+ const sal_Char * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIME::startsWithLineFolding(): Bad sequence");
+
+ return pEnd - pBegin >= 3 && pBegin[0] == 0x0D && pBegin[1] == 0x0A
+ && isWhiteSpace(pBegin[2]); // CR, LF
+}
+
+// static
+inline bool INetMIME::startsWithLineFolding(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIME::startsWithLineFolding(): Bad sequence");
+
+ return pEnd - pBegin >= 3 && pBegin[0] == 0x0D && pBegin[1] == 0x0A
+ && isWhiteSpace(pBegin[2]); // CR, LF
+}
+
+// static
+inline bool INetMIME::startsWithLinearWhiteSpace(const sal_Char * pBegin,
+ const sal_Char * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIME::startsWithLinearWhiteSpace(): Bad sequence");
+
+ return pBegin != pEnd
+ && (isWhiteSpace(*pBegin) || startsWithLineFolding(pBegin, pEnd));
+}
+
+// static
+inline bool INetMIME::needsQuotedStringEscape(sal_uInt32 nChar)
+{
+ return nChar == '"' || nChar == '\\';
+}
+
+// static
+inline rtl_TextEncoding INetMIME::translateToMIME(rtl_TextEncoding eEncoding)
+{
+#if defined WNT
+ return eEncoding == RTL_TEXTENCODING_MS_1252 ?
+ RTL_TEXTENCODING_ISO_8859_1 : eEncoding;
+#else // WNT
+ return eEncoding;
+#endif // WNT
+}
+
+// static
+inline rtl_TextEncoding INetMIME::translateFromMIME(rtl_TextEncoding
+ eEncoding)
+{
+#if defined WNT
+ return eEncoding == RTL_TEXTENCODING_ISO_8859_1 ?
+ RTL_TEXTENCODING_MS_1252 : eEncoding;
+#else // WNT
+ return eEncoding;
+#endif // WNT
+}
+
+// static
+inline bool INetMIME::isMIMECharsetEncoding(rtl_TextEncoding eEncoding)
+{
+ return ( rtl_isOctetTextEncoding(eEncoding) == sal_True );
+}
+
+// static
+inline int INetMIME::getUTF8OctetCount(sal_uInt32 nChar)
+{
+ DBG_ASSERT(nChar < 0x80000000, "INetMIME::getUTF8OctetCount(): Bad char");
+
+ return nChar < 0x80 ? 1 :
+ nChar < 0x800 ? 2 :
+ nChar <= 0x10000 ? 3 :
+ nChar <= 0x200000 ? 4 :
+ nChar <= 0x4000000 ? 5 : 6;
+}
+
+// static
+inline sal_uInt32 INetMIME::getUTF32Character(const sal_Unicode *& rBegin,
+ const sal_Unicode * pEnd)
+{
+ DBG_ASSERT(rBegin && rBegin < pEnd,
+ "INetMIME::getUTF32Character(): Bad sequence");
+ if (rBegin + 1 < pEnd && rBegin[0] >= 0xD800 && rBegin[0] <= 0xDBFF
+ && rBegin[1] >= 0xDC00 && rBegin[1] <= 0xDFFF)
+ {
+ sal_uInt32 nUTF32 = sal_uInt32(*rBegin++ & 0x3FF) << 10;
+ return (nUTF32 | (*rBegin++ & 0x3FF)) + 0x10000;
+ }
+ else
+ return *rBegin++;
+}
+
+// static
+inline sal_Unicode * INetMIME::putUTF32Character(sal_Unicode * pBuffer,
+ sal_uInt32 nUTF32)
+{
+ DBG_ASSERT(nUTF32 <= 0x10FFFF, "INetMIME::putUTF32Character(): Bad char");
+ if (nUTF32 < 0x10000)
+ *pBuffer++ = sal_Unicode(nUTF32);
+ else
+ {
+ nUTF32 -= 0x10000;
+ *pBuffer++ = sal_Unicode(0xD800 | (nUTF32 >> 10));
+ *pBuffer++ = sal_Unicode(0xDC00 | (nUTF32 & 0x3FF));
+ }
+ return pBuffer;
+}
+
+//============================================================================
+class INetMIMEOutputSink
+{
+public:
+ static sal_uInt32 const NO_LINE_LENGTH_LIMIT = SAL_MAX_UINT32;
+
+private:
+ sal_uInt32 m_nColumn;
+ sal_uInt32 m_nLineLengthLimit;
+
+protected:
+ /** Write a sequence of octets.
+
+ @param pBegin Points to the start of the sequence, must not be null.
+
+ @param pEnd Points past the end of the sequence, must be >= pBegin.
+ */
+ virtual void writeSequence(const sal_Char * pBegin,
+ const sal_Char * pEnd) = 0;
+
+ /** Write a null terminated sequence of octets (without the terminating
+ null).
+
+ @param pOctets A null terminated sequence of octets, must not be
+ null.
+
+ @return The length of pOctets (without the terminating null).
+ */
+ virtual sal_Size writeSequence(const sal_Char * pSequence);
+
+ /** Write a sequence of octets.
+
+ @descr The supplied sequence of UCS-4 characters is interpreted as a
+ sequence of octets. It is an error if any of the elements of the
+ sequence has a numerical value greater than 255.
+
+ @param pBegin Points to the start of the sequence, must not be null.
+
+ @param pEnd Points past the end of the sequence, must be >= pBegin.
+ */
+ virtual void writeSequence(const sal_uInt32 * pBegin,
+ const sal_uInt32 * pEnd);
+
+ /** Write a sequence of octets.
+
+ @descr The supplied sequence of Unicode characters is interpreted as
+ a sequence of octets. It is an error if any of the elements of the
+ sequence has a numerical value greater than 255.
+
+ @param pBegin Points to the start of the sequence, must not be null.
+
+ @param pEnd Points past the end of the sequence, must be >= pBegin.
+ */
+ virtual void writeSequence(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd);
+
+public:
+ INetMIMEOutputSink(sal_uInt32 nTheColumn = 0,
+ sal_uInt32 nTheLineLengthLimit
+ = INetMIME::SOFT_LINE_LENGTH_LIMIT):
+ m_nColumn(nTheColumn), m_nLineLengthLimit(nTheLineLengthLimit) {}
+
+ virtual ~INetMIMEOutputSink() {}
+
+ /** Get the current column.
+
+ @return The current column (starting from zero).
+ */
+ sal_uInt32 getColumn() const { return m_nColumn; }
+
+ sal_uInt32 getLineLengthLimit() const { return m_nLineLengthLimit; }
+
+ void setLineLengthLimit(sal_uInt32 nTheLineLengthLimit)
+ { m_nLineLengthLimit = nTheLineLengthLimit; }
+
+ virtual ErrCode getError() const;
+
+ /** Write a sequence of octets.
+
+ @param pBegin Points to the start of the sequence, must not be null.
+
+ @param pEnd Points past the end of the sequence, must be >= pBegin.
+ */
+ inline void write(const sal_Char * pBegin, const sal_Char * pEnd);
+
+ /** Write a sequence of octets.
+
+ @param pBegin Points to the start of the sequence, must not be null.
+
+ @param nLength The length of the sequence.
+ */
+ void write(const sal_Char * pBegin, sal_Size nLength)
+ { write(pBegin, pBegin + nLength); }
+
+ /** Write a sequence of octets.
+
+ @descr The supplied sequence of UCS-4 characters is interpreted as a
+ sequence of octets. It is an error if any of the elements of the
+ sequence has a numerical value greater than 255.
+
+ @param pBegin Points to the start of the sequence, must not be null.
+
+ @param pEnd Points past the end of the sequence, must be >= pBegin.
+ */
+ inline void write(const sal_uInt32 * pBegin, const sal_uInt32 * pEnd);
+
+ /** Write a sequence of octets.
+
+ @descr The supplied sequence of Unicode characters is interpreted as
+ a sequence of octets. It is an error if any of the elements of the
+ sequence has a numerical value greater than 255.
+
+ @param pBegin Points to the start of the sequence, must not be null.
+
+ @param pEnd Points past the end of the sequence, must be >= pBegin.
+ */
+ inline void write(const sal_Unicode * pBegin, const sal_Unicode * pEnd);
+
+ /** Write a sequence of octets.
+
+ @param rOctets A ByteString, interpreted as a sequence of octets.
+
+ @param nBegin The offset of the first character to write.
+
+ @param nEnd The offset past the last character to write.
+ */
+ inline void write(const ByteString & rString, xub_StrLen nBegin,
+ xub_StrLen nEnd);
+
+ /** Write a single octet.
+
+ @param nOctet Some octet.
+
+ @return This instance.
+ */
+ inline INetMIMEOutputSink & operator <<(sal_Char nOctet);
+
+ /** Write a null terminated sequence of octets (without the terminating
+ null).
+
+ @param pOctets A null terminated sequence of octets, must not be
+ null.
+
+ @return This instance.
+ */
+ inline INetMIMEOutputSink & operator <<(const sal_Char * pOctets);
+
+ /** Write a sequence of octets.
+
+ @param rOctets A ByteString, interpreted as a sequence of octets.
+
+ @return This instance.
+ */
+ inline INetMIMEOutputSink & operator <<(const ByteString & rOctets);
+
+ /** Call a manipulator function.
+
+ @param pManipulator A manipulator function.
+
+ @return Whatever the manipulator function returns.
+ */
+ INetMIMEOutputSink &
+ operator <<(INetMIMEOutputSink & (* pManipulator)(INetMIMEOutputSink &))
+ { return pManipulator(*this); }
+
+ /** Write a line end (CR LF).
+ */
+ void writeLineEnd();
+
+ /** A manipulator function that writes a line end (CR LF).
+
+ @param rSink Some sink.
+
+ @return The sink rSink.
+ */
+ static inline INetMIMEOutputSink & endl(INetMIMEOutputSink & rSink);
+};
+
+inline void INetMIMEOutputSink::write(const sal_Char * pBegin,
+ const sal_Char * pEnd)
+{
+ writeSequence(pBegin, pEnd);
+ m_nColumn += pEnd - pBegin;
+}
+
+inline void INetMIMEOutputSink::write(const sal_uInt32 * pBegin,
+ const sal_uInt32 * pEnd)
+{
+ writeSequence(pBegin, pEnd);
+ m_nColumn += pEnd - pBegin;
+}
+
+inline void INetMIMEOutputSink::write(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd)
+{
+ writeSequence(pBegin, pEnd);
+ m_nColumn += pEnd - pBegin;
+}
+
+inline void INetMIMEOutputSink::write(const ByteString & rOctets,
+ xub_StrLen nBegin, xub_StrLen nEnd)
+{
+ writeSequence(rOctets.GetBuffer() + nBegin, rOctets.GetBuffer() + nEnd);
+ m_nColumn += nEnd - nBegin;
+}
+
+inline INetMIMEOutputSink & INetMIMEOutputSink::operator <<(sal_Char nOctet)
+{
+ writeSequence(&nOctet, &nOctet + 1);
+ ++m_nColumn;
+ return *this;
+}
+
+inline INetMIMEOutputSink & INetMIMEOutputSink::operator <<(const sal_Char *
+ pOctets)
+{
+ m_nColumn += writeSequence(pOctets);
+ return *this;
+}
+
+inline INetMIMEOutputSink & INetMIMEOutputSink::operator <<(const ByteString &
+ rOctets)
+{
+ writeSequence(rOctets.GetBuffer(), rOctets.GetBuffer() + rOctets.Len());
+ m_nColumn += rOctets.Len();
+ return *this;
+}
+
+// static
+inline INetMIMEOutputSink & INetMIMEOutputSink::endl(INetMIMEOutputSink &
+ rSink)
+{
+ rSink.writeLineEnd();
+ return rSink;
+}
+
+// static
+inline void INetMIME::writeEscapeSequence(INetMIMEOutputSink & rSink,
+ sal_uInt32 nChar)
+{
+ DBG_ASSERT(nChar <= 0xFF, "INetMIME::writeEscapeSequence(): Bad char");
+ rSink << '=' << sal_uInt8(getHexDigit(nChar >> 4))
+ << sal_uInt8(getHexDigit(nChar & 15));
+}
+
+//============================================================================
+class INetMIMEStringOutputSink: public INetMIMEOutputSink
+{
+ ByteString m_aBuffer;
+ bool m_bOverflow;
+
+ using INetMIMEOutputSink::writeSequence;
+
+ virtual void writeSequence(const sal_Char * pBegin,
+ const sal_Char * pEnd);
+
+public:
+ inline INetMIMEStringOutputSink(sal_uInt32 nColumn = 0,
+ sal_uInt32 nLineLengthLimit
+ = INetMIME::SOFT_LINE_LENGTH_LIMIT):
+ INetMIMEOutputSink(nColumn, nLineLengthLimit), m_bOverflow(false) {}
+
+ virtual ErrCode getError() const;
+
+ inline ByteString takeBuffer();
+};
+
+inline ByteString INetMIMEStringOutputSink::takeBuffer()
+{
+ ByteString aTheBuffer = m_aBuffer;
+ m_aBuffer.Erase();
+ m_bOverflow = false;
+ return aTheBuffer;
+}
+
+//============================================================================
+class INetMIMEUnicodeOutputSink: public INetMIMEOutputSink
+{
+ UniString m_aBuffer;
+ bool m_bOverflow;
+
+ using INetMIMEOutputSink::writeSequence;
+
+ virtual void writeSequence(const sal_Char * pBegin,
+ const sal_Char * pEnd);
+
+ virtual void writeSequence(const sal_uInt32 * pBegin,
+ const sal_uInt32 * pEnd);
+
+ virtual void writeSequence(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd);
+
+public:
+ inline INetMIMEUnicodeOutputSink(sal_uInt32 nColumn = 0,
+ sal_uInt32 nLineLengthLimit
+ = INetMIME::SOFT_LINE_LENGTH_LIMIT):
+ INetMIMEOutputSink(nColumn, nLineLengthLimit), m_bOverflow(false) {}
+
+ virtual ErrCode getError() const;
+
+ inline UniString takeBuffer();
+};
+
+inline UniString INetMIMEUnicodeOutputSink::takeBuffer()
+{
+ UniString aTheBuffer = m_aBuffer;
+ m_aBuffer.Erase();
+ m_bOverflow = false;
+ return aTheBuffer;
+}
+
+//============================================================================
+class INetMIMEEncodedWordOutputSink
+{
+public:
+ enum Context { CONTEXT_TEXT = 1,
+ CONTEXT_COMMENT = 2,
+ CONTEXT_PHRASE = 4 };
+
+ enum Space { SPACE_NO, SPACE_ENCODED, SPACE_ALWAYS };
+
+private:
+ enum { BUFFER_SIZE = 256 };
+
+ enum Coding { CODING_NONE, CODING_QUOTED, CODING_ENCODED,
+ CODING_ENCODED_TERMINATED };
+
+ enum EncodedWordState { STATE_INITIAL, STATE_FIRST_EQUALS,
+ STATE_FIRST_QUESTION, STATE_CHARSET,
+ STATE_SECOND_QUESTION, STATE_ENCODING,
+ STATE_THIRD_QUESTION, STATE_ENCODED_TEXT,
+ STATE_FOURTH_QUESTION, STATE_SECOND_EQUALS,
+ STATE_BAD };
+
+ INetMIMEOutputSink & m_rSink;
+ Context m_eContext;
+ Space m_eInitialSpace;
+ sal_uInt32 m_nExtraSpaces;
+ INetMIMECharsetList_Impl * m_pEncodingList;
+ sal_Unicode * m_pBuffer;
+ sal_uInt32 m_nBufferSize;
+ sal_Unicode * m_pBufferEnd;
+ Coding m_ePrevCoding;
+ rtl_TextEncoding m_ePrevMIMEEncoding;
+ Coding m_eCoding;
+ sal_uInt32 m_nQuotedEscaped;
+ EncodedWordState m_eEncodedWordState;
+
+ inline bool needsEncodedWordEscape(sal_uInt32 nChar) const;
+
+ void finish(bool bWriteTrailer);
+
+public:
+ inline INetMIMEEncodedWordOutputSink(INetMIMEOutputSink & rTheSink,
+ Context eTheContext,
+ Space eTheInitialSpace,
+ rtl_TextEncoding ePreferredEncoding);
+
+ ~INetMIMEEncodedWordOutputSink();
+
+ INetMIMEEncodedWordOutputSink & operator <<(sal_uInt32 nChar);
+
+ inline void write(const sal_Char * pBegin, const sal_Char * pEnd);
+
+ inline void write(const sal_Unicode * pBegin, const sal_Unicode * pEnd);
+
+ inline bool flush();
+};
+
+inline INetMIMEEncodedWordOutputSink::INetMIMEEncodedWordOutputSink(
+ INetMIMEOutputSink & rTheSink, Context eTheContext,
+ Space eTheInitialSpace, rtl_TextEncoding ePreferredEncoding):
+ m_rSink(rTheSink),
+ m_eContext(eTheContext),
+ m_eInitialSpace(eTheInitialSpace),
+ m_nExtraSpaces(0),
+ m_pEncodingList(INetMIME::createPreferredCharsetList(ePreferredEncoding)),
+ m_ePrevCoding(CODING_NONE),
+ m_eCoding(CODING_NONE),
+ m_nQuotedEscaped(0),
+ m_eEncodedWordState(STATE_INITIAL)
+{
+ m_nBufferSize = BUFFER_SIZE;
+ m_pBuffer = static_cast< sal_Unicode * >(rtl_allocateMemory(
+ m_nBufferSize
+ * sizeof (sal_Unicode)));
+ m_pBufferEnd = m_pBuffer;
+}
+
+inline void INetMIMEEncodedWordOutputSink::write(const sal_Char * pBegin,
+ const sal_Char * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIMEEncodedWordOutputSink::write(): Bad sequence");
+
+ while (pBegin != pEnd)
+ operator <<(*pBegin++);
+}
+
+inline void INetMIMEEncodedWordOutputSink::write(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIMEEncodedWordOutputSink::write(): Bad sequence");
+
+ while (pBegin != pEnd)
+ operator <<(*pBegin++);
+}
+
+inline bool INetMIMEEncodedWordOutputSink::flush()
+{
+ finish(true);
+ return m_ePrevCoding != CODING_NONE;
+}
+
+//============================================================================
+struct INetContentTypeParameter
+{
+ /** The name of the attribute, in US-ASCII encoding and converted to lower
+ case. If a parameter value is split as described in RFC 2231, there
+ will only be one item for the complete parameter, with the attribute
+ name lacking any section suffix.
+ */
+ const ByteString m_sAttribute;
+
+ /** The optional character set specification (see RFC 2231), in US-ASCII
+ encoding and converted to lower case.
+ */
+ const ByteString m_sCharset;
+
+ /** The optional language specification (see RFC 2231), in US-ASCII
+ encoding and converted to lower case.
+ */
+ const ByteString m_sLanguage;
+
+ /** The attribute value. If the value is a quoted-string, it is
+ 'unpacked.' If a character set is specified, and the value can be
+ converted to Unicode, this is done. Also, if no character set is
+ specified, it is first tried to convert the value from UTF-8 encoding
+ to Unicode, and if that doesn't work (because the value is not in
+ UTF-8 encoding), it is converted from ISO-8859-1 encoding to Unicode
+ (which will always work). But if a character set is specified and the
+ value cannot be converted from that character set to Unicode, special
+ action is taken to produce a value that can possibly be transformed
+ back into its original form: Any 8-bit character from a non-encoded
+ part of the original value is directly converted to Unicode
+ (effectively handling it as if it was ISO-8859-1 encoded), and any
+ 8-bit character from an encoded part of the original value is mapped
+ to the range U+F800..U+F8FF at the top of the Corporate Use Subarea
+ within Unicode's Private Use Area (effectively adding 0xF800 to the
+ character's numeric value).
+ */
+ const UniString m_sValue;
+
+ /** This is true if the value is successfuly converted to Unicode, and
+ false if the value is a special mixture of ISO-LATIN-1 characters and
+ characters from Unicode's Private Use Area.
+ */
+ const bool m_bConverted;
+
+ inline INetContentTypeParameter(const ByteString & rTheAttribute,
+ const ByteString & rTheCharset,
+ const ByteString & rTheLanguage,
+ const UniString & rTheValue,
+ bool bTheConverted);
+};
+
+inline INetContentTypeParameter::INetContentTypeParameter(const ByteString &
+ rTheAttribute,
+ const ByteString &
+ rTheCharset,
+ const ByteString &
+ rTheLanguage,
+ const UniString &
+ rTheValue,
+ bool bTheConverted):
+ m_sAttribute(rTheAttribute),
+ m_sCharset(rTheCharset),
+ m_sLanguage(rTheLanguage),
+ m_sValue(rTheValue),
+ m_bConverted(bTheConverted)
+{}
+
+//============================================================================
+class TOOLS_DLLPUBLIC INetContentTypeParameterList: private List
+{
+public:
+ ~INetContentTypeParameterList() { Clear(); }
+
+ using List::Count;
+
+ void Clear();
+
+ void Insert(INetContentTypeParameter * pParameter, ULONG nIndex)
+ { List::Insert(pParameter, nIndex); }
+
+ inline const INetContentTypeParameter * GetObject(ULONG nIndex) const;
+
+ const INetContentTypeParameter * find(const ByteString & rAttribute)
+ const;
+};
+
+inline const INetContentTypeParameter *
+INetContentTypeParameterList::GetObject(ULONG nIndex) const
+{
+ return static_cast< INetContentTypeParameter * >(List::GetObject(nIndex));
+}
+
+#endif // TOOLS_INETMIME_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/inetmsg.hxx b/tools/inc/tools/inetmsg.hxx
new file mode 100644
index 000000000000..24705abe85fd
--- /dev/null
+++ b/tools/inc/tools/inetmsg.hxx
@@ -0,0 +1,621 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _TOOLS_INETMSG_HXX
+#define _TOOLS_INETMSG_HXX
+
+#include "tools/toolsdllapi.h"
+#include <sal/types.h>
+
+#include <rtl/textenc.h>
+
+#include <tools/inetmime.hxx>
+#include <tools/list.hxx>
+#include <tools/stream.hxx>
+#include <tools/string.hxx>
+
+class DateTime;
+
+/*=======================================================================
+ *
+ * INetMessageHeader Interface.
+ *
+ *=====================================================================*/
+class INetMessageHeader
+{
+ ByteString m_aName;
+ ByteString m_aValue;
+
+public:
+ INetMessageHeader (void)
+ {}
+
+ INetMessageHeader (
+ const ByteString& rName, const ByteString& rValue)
+ : m_aName (rName), m_aValue (rValue)
+ {}
+
+ INetMessageHeader (
+ const INetMessageHeader& rHdr)
+ : m_aName (rHdr.m_aName), m_aValue (rHdr.m_aValue)
+ {}
+
+ ~INetMessageHeader (void)
+ {}
+
+ INetMessageHeader& operator= (const INetMessageHeader& rHdr)
+ {
+ m_aName = rHdr.m_aName;
+ m_aValue = rHdr.m_aValue;
+ return *this;
+ }
+
+ const ByteString& GetName (void) const { return m_aName; }
+ const ByteString& GetValue (void) const { return m_aValue; }
+
+ friend SvStream& operator<< (
+ SvStream& rStrm, const INetMessageHeader& rHdr)
+ {
+#ifdef ENABLE_BYTESTRING_STREAM_OPERATORS
+ rStrm << rHdr.m_aName;
+ rStrm << rHdr.m_aValue;
+#else
+ rStrm.WriteByteString (rHdr.m_aName);
+ rStrm.WriteByteString (rHdr.m_aValue);
+#endif
+ return rStrm;
+ }
+
+ friend SvStream& operator>> (
+ SvStream& rStrm, INetMessageHeader& rHdr)
+ {
+#ifdef ENABLE_BYTESTRING_STREAM_OPERATORS
+ rStrm >> rHdr.m_aName;
+ rStrm >> rHdr.m_aValue;
+#else
+ rStrm.ReadByteString (rHdr.m_aName);
+ rStrm.ReadByteString (rHdr.m_aValue);
+#endif
+ return rStrm;
+ }
+};
+
+/*=======================================================================
+ *
+ * INetMessage Interface.
+ *
+ *=====================================================================*/
+class INetMessage
+{
+ List m_aHeaderList;
+
+ ULONG m_nDocSize;
+ UniString m_aDocName;
+ SvLockBytesRef m_xDocLB;
+
+ void ListCleanup_Impl (void);
+ void ListCopy (const INetMessage& rMsg);
+
+protected:
+ UniString GetHeaderName_Impl (
+ ULONG nIndex, rtl_TextEncoding eEncoding) const
+ {
+ INetMessageHeader *p =
+ (INetMessageHeader*)(m_aHeaderList.GetObject(nIndex));
+ if (p)
+ return UniString(p->GetName(), eEncoding);
+ else
+ return UniString();
+ }
+
+ UniString GetHeaderValue_Impl (
+ ULONG nIndex, INetMIME::HeaderFieldType eType) const
+ {
+ INetMessageHeader *p =
+ (INetMessageHeader*)(m_aHeaderList.GetObject(nIndex));
+ if (p)
+ return INetMIME::decodeHeaderFieldBody (eType, p->GetValue());
+ else
+ return UniString();
+ }
+
+ void SetHeaderField_Impl (
+ const INetMessageHeader &rHeader, ULONG &rnIndex)
+ {
+ INetMessageHeader *p = new INetMessageHeader (rHeader);
+ if (m_aHeaderList.Count() <= rnIndex)
+ {
+ m_aHeaderList.Insert (p, LIST_APPEND);
+ rnIndex = m_aHeaderList.Count() - 1;
+ }
+ else
+ {
+ p = (INetMessageHeader*)(m_aHeaderList.Replace(p, rnIndex));
+ delete p;
+ }
+ }
+
+ void SetHeaderField_Impl (
+ INetMIME::HeaderFieldType eType,
+ const ByteString &rName,
+ const UniString &rValue,
+ ULONG &rnIndex);
+
+ virtual SvStream& operator<< (SvStream& rStrm) const;
+ virtual SvStream& operator>> (SvStream& rStrm);
+
+public:
+ INetMessage (void) : m_nDocSize(0) {}
+ virtual ~INetMessage (void);
+
+ INetMessage (const INetMessage& rMsg)
+ : m_nDocSize (rMsg.m_nDocSize),
+ m_aDocName (rMsg.m_aDocName),
+ m_xDocLB (rMsg.m_xDocLB)
+ {
+ ListCopy (rMsg);
+ }
+
+ INetMessage& operator= (const INetMessage& rMsg)
+ {
+ m_nDocSize = rMsg.m_nDocSize;
+ m_aDocName = rMsg.m_aDocName;
+ m_xDocLB = rMsg.m_xDocLB;
+ ListCopy (rMsg);
+ return *this;
+ }
+
+ ULONG GetHeaderCount (void) const { return m_aHeaderList.Count(); }
+
+ UniString GetHeaderName (ULONG nIndex) const
+ {
+ return GetHeaderName_Impl (nIndex, RTL_TEXTENCODING_ASCII_US);
+ }
+
+ UniString GetHeaderValue (ULONG nIndex) const
+ {
+ return GetHeaderValue_Impl (nIndex, INetMIME::HEADER_FIELD_TEXT);
+ }
+
+ INetMessageHeader GetHeaderField (ULONG nIndex) const
+ {
+ INetMessageHeader *p =
+ (INetMessageHeader*)(m_aHeaderList.GetObject(nIndex));
+ if (p)
+ return INetMessageHeader(*p);
+ else
+ return INetMessageHeader();
+ }
+
+ ULONG SetHeaderField (
+ const UniString& rName,
+ const UniString& rValue,
+ ULONG nIndex = LIST_APPEND);
+
+ virtual ULONG SetHeaderField (
+ const INetMessageHeader &rField, ULONG nIndex = LIST_APPEND);
+
+ ULONG GetDocumentSize (void) const { return m_nDocSize; }
+ void SetDocumentSize (ULONG nSize) { m_nDocSize = nSize; }
+
+ const UniString& GetDocumentName (void) const { return m_aDocName; }
+ void SetDocumentName (const UniString& rName) { m_aDocName = rName; }
+
+ SvLockBytes* GetDocumentLB (void) const { return m_xDocLB; }
+ void SetDocumentLB (SvLockBytes *pDocLB) { m_xDocLB = pDocLB; }
+
+ friend SvStream& operator<< (
+ SvStream& rStrm, const INetMessage& rMsg)
+ {
+ return rMsg.operator<< (rStrm);
+ }
+
+ friend SvStream& operator>> (
+ SvStream& rStrm, INetMessage& rMsg)
+ {
+ return rMsg.operator>> (rStrm);
+ }
+};
+
+/*=======================================================================
+ *
+ * INetMessageHeaderIterator Interface.
+ *
+ *=====================================================================*/
+class INetMessageHeaderIterator
+{
+ ULONG nValueCount;
+ List aValueList;
+ UniString aEmptyString;
+
+public:
+ INetMessageHeaderIterator (
+ const INetMessage& rMsg, const UniString& rHdrName);
+ virtual ~INetMessageHeaderIterator (void);
+
+ ULONG GetValueCount (void) const { return nValueCount; }
+ const UniString& GetValue (ULONG nIndex) const
+ {
+ if (nIndex < nValueCount)
+ {
+ return *((UniString*)(aValueList.GetObject(nIndex)));
+ }
+ else
+ {
+ return aEmptyString;
+ }
+ }
+};
+
+/*=======================================================================
+ *
+ * INetRFC822Message Interface.
+ *
+ *=====================================================================*/
+#define INETMSG_RFC822_BCC 0
+#define INETMSG_RFC822_CC 1
+#define INETMSG_RFC822_COMMENTS 2
+#define INETMSG_RFC822_DATE 3
+#define INETMSG_RFC822_FROM 4
+#define INETMSG_RFC822_IN_REPLY_TO 5
+#define INETMSG_RFC822_KEYWORDS 6
+#define INETMSG_RFC822_MESSAGE_ID 7
+#define INETMSG_RFC822_REFERENCES 8
+#define INETMSG_RFC822_REPLY_TO 9
+#define INETMSG_RFC822_RETURN_PATH 10
+#define INETMSG_RFC822_SENDER 11
+#define INETMSG_RFC822_SUBJECT 12
+#define INETMSG_RFC822_TO 13
+
+#define INETMSG_RFC822_X_MAILER 14
+#define INETMSG_RFC822_RETURN_RECEIPT_TO 15
+
+#define INETMSG_RFC822_NUMHDR 16
+
+class TOOLS_DLLPUBLIC INetRFC822Message : public INetMessage
+{
+ ULONG m_nIndex[INETMSG_RFC822_NUMHDR];
+
+protected:
+ virtual SvStream& operator<< (SvStream& rStrm) const;
+ virtual SvStream& operator>> (SvStream& rStrm);
+
+public:
+ INetRFC822Message (void);
+ INetRFC822Message (const INetRFC822Message& rMsg);
+ virtual ~INetRFC822Message (void);
+
+ INetRFC822Message& operator= (const INetRFC822Message& rMsg);
+
+ static BOOL GenerateDateField (
+ const DateTime& rDateTime, UniString& rDateField);
+ static BOOL ParseDateField (
+ const UniString& rDateField, DateTime& rDateTime);
+
+ using INetMessage::SetHeaderField;
+ virtual ULONG SetHeaderField (
+ const INetMessageHeader &rHeader, ULONG nIndex = LIST_APPEND);
+
+ /** Header fields.
+ */
+ void SetBCC (const UniString& rBCC);
+ UniString GetBCC (void) const
+ {
+ return GetHeaderValue_Impl (
+ m_nIndex[INETMSG_RFC822_BCC],
+ INetMIME::HEADER_FIELD_ADDRESS);
+ }
+
+ void SetCC (const UniString& rCC);
+ UniString GetCC (void) const
+ {
+ return GetHeaderValue_Impl (
+ m_nIndex[INETMSG_RFC822_CC],
+ INetMIME::HEADER_FIELD_ADDRESS);
+ }
+
+ void SetComments (const UniString& rComments);
+ UniString GetComments (void) const
+ {
+ return GetHeaderValue_Impl (
+ m_nIndex[INETMSG_RFC822_COMMENTS],
+ INetMIME::HEADER_FIELD_TEXT);
+ }
+
+ void SetDate (const UniString& rDate);
+ UniString GetDate (void) const
+ {
+ return GetHeaderValue_Impl (
+ m_nIndex[INETMSG_RFC822_DATE],
+ INetMIME::HEADER_FIELD_STRUCTURED);
+ }
+
+ void SetFrom (const UniString& rFrom);
+ UniString GetFrom (void) const
+ {
+ return GetHeaderValue_Impl (
+ m_nIndex[INETMSG_RFC822_FROM],
+ INetMIME::HEADER_FIELD_ADDRESS);
+ }
+
+ void SetInReplyTo (const UniString& rInReplyTo);
+ UniString GetInReplyTo (void) const
+ {
+ return GetHeaderValue_Impl (
+ m_nIndex[INETMSG_RFC822_IN_REPLY_TO],
+ INetMIME::HEADER_FIELD_ADDRESS); // ??? MESSAGE_ID ???
+ }
+
+ void SetKeywords (const UniString& rKeywords);
+ UniString GetKeywords (void) const
+ {
+ return GetHeaderValue_Impl (
+ m_nIndex[INETMSG_RFC822_KEYWORDS],
+ INetMIME::HEADER_FIELD_PHRASE);
+ }
+
+ void SetMessageID (const UniString& rMessageID);
+ UniString GetMessageID (void) const
+ {
+ return GetHeaderValue_Impl (
+ m_nIndex[INETMSG_RFC822_MESSAGE_ID],
+ INetMIME::HEADER_FIELD_MESSAGE_ID);
+ }
+
+ void SetReferences (const UniString& rReferences);
+ UniString GetReferences (void) const
+ {
+ return GetHeaderValue_Impl (
+ m_nIndex[INETMSG_RFC822_REFERENCES],
+ INetMIME::HEADER_FIELD_ADDRESS);
+ }
+
+ void SetReplyTo (const UniString& rReplyTo);
+ UniString GetReplyTo (void) const
+ {
+ return GetHeaderValue_Impl (
+ m_nIndex[INETMSG_RFC822_REPLY_TO],
+ INetMIME::HEADER_FIELD_ADDRESS);
+ }
+
+ void SetReturnPath (const UniString& rReturnPath);
+ UniString GetReturnPath (void) const
+ {
+ return GetHeaderValue_Impl (
+ m_nIndex[INETMSG_RFC822_RETURN_PATH],
+ INetMIME::HEADER_FIELD_ADDRESS);
+ }
+
+ void SetReturnReceiptTo (const UniString& rReturnReceiptTo);
+ UniString GetReturnReceiptTo (void) const
+ {
+ return GetHeaderValue_Impl (
+ m_nIndex[INETMSG_RFC822_RETURN_RECEIPT_TO],
+ INetMIME::HEADER_FIELD_ADDRESS);
+ }
+
+ void SetSender (const UniString& rSender);
+ UniString GetSender (void) const
+ {
+ return GetHeaderValue_Impl (
+ m_nIndex[INETMSG_RFC822_SENDER],
+ INetMIME::HEADER_FIELD_ADDRESS);
+ }
+
+ void SetSubject (const UniString& rSubject);
+ UniString GetSubject (void) const
+ {
+ return GetHeaderValue_Impl (
+ m_nIndex[INETMSG_RFC822_SUBJECT],
+ INetMIME::HEADER_FIELD_TEXT);
+ }
+
+ void SetTo (const UniString& rTo);
+ UniString GetTo (void) const
+ {
+ return GetHeaderValue_Impl (
+ m_nIndex[INETMSG_RFC822_TO],
+ INetMIME::HEADER_FIELD_TEXT);
+ }
+
+ void SetXMailer (const UniString& rXMailer);
+ UniString GetXMailer (void) const
+ {
+ return GetHeaderValue_Impl (
+ m_nIndex[INETMSG_RFC822_X_MAILER],
+ INetMIME::HEADER_FIELD_TEXT);
+ }
+
+ /** Stream operators.
+ */
+ friend SvStream& operator<< (
+ SvStream& rStrm, const INetRFC822Message& rMsg)
+ {
+ return rMsg.operator<< (rStrm);
+ }
+
+ friend SvStream& operator>> (
+ SvStream& rStrm, INetRFC822Message& rMsg)
+ {
+ return rMsg.operator>> (rStrm);
+ }
+};
+
+/*=======================================================================
+ *
+ * INetMIMEMessage Interface.
+ *
+ *=====================================================================*/
+#define INETMSG_MIME_VERSION 0
+#define INETMSG_MIME_CONTENT_DESCRIPTION 1
+#define INETMSG_MIME_CONTENT_DISPOSITION 2
+#define INETMSG_MIME_CONTENT_ID 3
+#define INETMSG_MIME_CONTENT_TYPE 4
+#define INETMSG_MIME_CONTENT_TRANSFER_ENCODING 5
+
+#define INETMSG_MIME_NUMHDR 6
+
+enum INetMessageContainerType
+{
+ INETMSG_MESSAGE_RFC822,
+ INETMSG_MULTIPART_MIXED,
+ INETMSG_MULTIPART_ALTERNATIVE,
+ INETMSG_MULTIPART_DIGEST,
+ INETMSG_MULTIPART_PARALLEL,
+ INETMSG_MULTIPART_RELATED,
+ INETMSG_MULTIPART_FORM_DATA
+};
+
+class TOOLS_DLLPUBLIC INetMIMEMessage : public INetRFC822Message
+{
+ ULONG m_nIndex[INETMSG_MIME_NUMHDR];
+
+ INetMIMEMessage *pParent;
+ ULONG nNumChildren;
+ List aChildren;
+ ByteString m_aBoundary;
+ BOOL bHeaderParsed;
+
+ friend class INetMIMEMessageStream;
+
+ void SetChildCount (ULONG nCount) { nNumChildren = nCount; }
+ const ByteString& GetMultipartBoundary (void) const { return m_aBoundary; }
+ void SetMultipartBoundary (const ByteString& rBnd) { m_aBoundary = rBnd; }
+
+ void CleanupImp (void);
+ void CopyImp (const INetMIMEMessage& rMsg);
+ void SetHeaderParsed() { bHeaderParsed = TRUE; }
+
+protected:
+ virtual SvStream& operator<< (SvStream& rStrm) const;
+ virtual SvStream& operator>> (SvStream& rStrm);
+
+public:
+ INetMIMEMessage (void);
+ INetMIMEMessage (const INetMIMEMessage& rMsg);
+ virtual ~INetMIMEMessage (void);
+
+ INetMIMEMessage& operator= (const INetMIMEMessage& rMsg);
+
+ BOOL HeaderParsed() const { return bHeaderParsed; }
+
+ virtual INetMIMEMessage* CreateMessage (
+ const INetMIMEMessage& rMsg) const;
+
+ using INetRFC822Message::SetHeaderField;
+ virtual ULONG SetHeaderField (
+ const INetMessageHeader &rHeader, ULONG nIndex = LIST_APPEND);
+
+ /** Header fields.
+ */
+ void SetMIMEVersion (const UniString& rVersion);
+ UniString GetMIMEVersion (void) const
+ {
+ return GetHeaderValue (m_nIndex[INETMSG_MIME_VERSION]);
+ }
+
+ void SetContentDescription (const UniString& rDescription);
+ UniString GetContentDescription (void) const
+ {
+ return GetHeaderValue (m_nIndex[INETMSG_MIME_CONTENT_DESCRIPTION]);
+ }
+
+ void SetContentDisposition (const UniString& rDisposition);
+ UniString GetContentDisposition (void) const
+ {
+ return GetHeaderValue (m_nIndex[INETMSG_MIME_CONTENT_DISPOSITION]);
+ }
+
+ void SetContentID (const UniString& rID);
+ UniString GetContentID (void) const
+ {
+ return GetHeaderValue (m_nIndex[INETMSG_MIME_CONTENT_ID]);
+ }
+
+ void SetContentType (const UniString& rType);
+ UniString GetContentType (void) const
+ {
+ return GetHeaderValue (m_nIndex[INETMSG_MIME_CONTENT_TYPE]);
+ }
+
+ void SetContentTransferEncoding (const UniString& rEncoding);
+ UniString GetContentTransferEncoding (void) const
+ {
+ return GetHeaderValue (m_nIndex[INETMSG_MIME_CONTENT_TRANSFER_ENCODING]);
+ }
+
+ virtual void GetDefaultContentType (UniString& rContentType);
+
+ /** Message container methods.
+ */
+ BOOL IsContainer (void) const
+ {
+ return (IsMessage() || IsMultipart());
+ }
+ BOOL IsMessage (void) const
+ {
+ UniString aType (GetContentType());
+ return (aType.CompareIgnoreCaseToAscii("message/", 8) == 0);
+ }
+ BOOL IsMultipart (void) const
+ {
+ UniString aType (GetContentType());
+ return (aType.CompareIgnoreCaseToAscii("multipart/", 10) == 0);
+ }
+
+ ULONG GetChildCount (void) const { return nNumChildren; }
+ INetMIMEMessage* GetChild (ULONG nIndex) const
+ {
+ return ((INetMIMEMessage *)(aChildren.GetObject (nIndex)));
+ }
+ INetMIMEMessage* GetParent (void) const { return pParent; }
+
+ BOOL EnableAttachChild (
+ INetMessageContainerType eType = INETMSG_MULTIPART_MIXED);
+ BOOL AttachChild (
+ INetMIMEMessage& rChildMsg, BOOL bOwner = TRUE);
+ BOOL DetachChild (
+ ULONG nIndex, INetMIMEMessage& rChildMsg) const;
+
+ /** Stream operators.
+ */
+ friend SvStream& operator<< (
+ SvStream& rStrm, const INetMIMEMessage& rMsg)
+ {
+ return rMsg.operator<< (rStrm);
+ }
+
+ friend SvStream& operator>> (
+ SvStream& rStrm, INetMIMEMessage& rMsg)
+ {
+ return rMsg.operator>> (rStrm);
+ }
+};
+
+#endif /* !_TOOLS_INETMSG_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/inetstrm.hxx b/tools/inc/tools/inetstrm.hxx
new file mode 100644
index 000000000000..cf2912d92f7e
--- /dev/null
+++ b/tools/inc/tools/inetstrm.hxx
@@ -0,0 +1,277 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _TOOLS_INETSTRM_HXX
+#define _TOOLS_INETSTRM_HXX
+
+#include "tools/toolsdllapi.h"
+#include <sal/types.h>
+#include <tools/string.hxx>
+
+class INetMessage;
+class INetMIMEMessage;
+class INetHTTPMessage;
+class SvMemoryStream;
+class SvStream;
+
+/*=========================================================================
+ *
+ * INetStream Interface.
+ *
+ *=======================================================================*/
+enum INetStreamStatus
+{
+ INETSTREAM_STATUS_LOADED = -4,
+ INETSTREAM_STATUS_WOULDBLOCK = -3,
+ INETSTREAM_STATUS_OK = -2,
+ INETSTREAM_STATUS_ERROR = -1
+};
+
+/*
+ * INetIStream.
+ */
+class TOOLS_DLLPUBLIC INetIStream
+{
+ // Not implemented.
+ INetIStream (const INetIStream& rStrm);
+ INetIStream& operator= (const INetIStream& rStrm);
+
+protected:
+ virtual int GetData (sal_Char *pData, ULONG nSize) = 0;
+
+public:
+ INetIStream ();
+ virtual ~INetIStream (void);
+
+ int Read (sal_Char *pData, ULONG nSize);
+
+ static void Decode64 (SvStream& rIn, SvStream& rOut);
+ static void Encode64 (SvStream& rIn, SvStream& rOut);
+};
+
+/*
+ * INetOStream.
+ */
+class INetOStream
+{
+ // Not implemented.
+ INetOStream (const INetOStream& rStrm);
+ INetOStream& operator= (const INetOStream& rStrm);
+
+protected:
+ virtual int PutData (
+ const sal_Char *pData, ULONG nSize) = 0;
+
+public:
+ INetOStream ();
+ virtual ~INetOStream (void);
+
+ int Write (const sal_Char *pData, ULONG nSize);
+};
+
+/*
+ * INetIOStream.
+ */
+class INetIOStream : public INetIStream, public INetOStream
+{
+ // Not implemented.
+ INetIOStream (const INetIOStream& rStrm);
+ INetIOStream& operator= (const INetIOStream& rStrm);
+
+public:
+ INetIOStream (ULONG nIBufferSize = 0, ULONG nOBufferSize = 0);
+ virtual ~INetIOStream (void);
+};
+
+/*=========================================================================
+ *
+ * INetMessageStream Interface.
+ *
+ *=======================================================================*/
+enum INetMessageStreamState
+{
+ INETMSG_EOL_BEGIN,
+ INETMSG_EOL_DONE,
+ INETMSG_EOL_SCR,
+ INETMSG_EOL_FCR,
+ INETMSG_EOL_FLF,
+ INETMSG_EOL_FSP,
+ INETMSG_EOL_FESC
+};
+
+/*
+ * INetMessageIStream (Message Generator) Interface.
+ */
+class INetMessageIStream : public INetIStream
+{
+ INetMessage *pSourceMsg;
+ BOOL bHeaderGenerated;
+
+ ULONG nBufSiz;
+ sal_Char *pBuffer;
+ sal_Char *pRead;
+ sal_Char *pWrite;
+
+ SvStream *pMsgStrm;
+ SvMemoryStream *pMsgBuffer;
+ sal_Char *pMsgRead;
+ sal_Char *pMsgWrite;
+
+ virtual int GetData (sal_Char *pData, ULONG nSize);
+
+ // Not implemented.
+ INetMessageIStream (const INetMessageIStream& rStrm);
+ INetMessageIStream& operator= (const INetMessageIStream& rStrm);
+
+protected:
+ virtual int GetMsgLine (sal_Char *pData, ULONG nSize);
+
+public:
+ INetMessageIStream (ULONG nBufferSize = 2048);
+ virtual ~INetMessageIStream (void);
+
+ INetMessage *GetSourceMessage (void) const { return pSourceMsg; }
+ void SetSourceMessage (INetMessage *pMsg) { pSourceMsg = pMsg; }
+
+ void GenerateHeader (BOOL bGen = TRUE) { bHeaderGenerated = !bGen; }
+ BOOL IsHeaderGenerated (void) const { return bHeaderGenerated; }
+};
+
+/*
+ * INetMessageOStream (Message Parser) Interface.
+ */
+class INetMessageOStream : public INetOStream
+{
+ INetMessage *pTargetMsg;
+ BOOL bHeaderParsed;
+
+ INetMessageStreamState eOState;
+
+ SvMemoryStream *pMsgBuffer;
+
+ virtual int PutData (const sal_Char *pData, ULONG nSize);
+
+ // Not implemented.
+ INetMessageOStream (const INetMessageOStream& rStrm);
+ INetMessageOStream& operator= (const INetMessageOStream& rStrm);
+
+protected:
+ virtual int PutMsgLine (const sal_Char *pData, ULONG nSize);
+
+public:
+ INetMessageOStream (void);
+ virtual ~INetMessageOStream (void);
+
+ INetMessage *GetTargetMessage (void) const { return pTargetMsg; }
+ void SetTargetMessage (INetMessage *pMsg) { pTargetMsg = pMsg; }
+
+ void ParseHeader (BOOL bParse = TRUE) { bHeaderParsed = !bParse; }
+ BOOL IsHeaderParsed (void) const { return bHeaderParsed; }
+};
+
+/*
+ * INetMessageIOStream Interface.
+ */
+class INetMessageIOStream
+ : public INetMessageIStream,
+ public INetMessageOStream
+{
+ // Not implemented.
+ INetMessageIOStream (const INetMessageIOStream& rStrm);
+ INetMessageIOStream& operator= (const INetMessageIOStream& rStrm);
+
+public:
+ INetMessageIOStream (ULONG nBufferSize = 2048);
+ virtual ~INetMessageIOStream (void);
+};
+
+/*=========================================================================
+ *
+ * INetMIMEMessageStream Interface.
+ *
+ *=======================================================================*/
+enum INetMessageEncoding
+{
+ INETMSG_ENCODING_7BIT,
+ INETMSG_ENCODING_8BIT,
+ INETMSG_ENCODING_BINARY,
+ INETMSG_ENCODING_QUOTED,
+ INETMSG_ENCODING_BASE64
+};
+
+class TOOLS_DLLPUBLIC INetMIMEMessageStream : public INetMessageIOStream
+{
+ int eState;
+
+ ULONG nChildIndex;
+ INetMIMEMessageStream *pChildStrm;
+
+ INetMessageEncoding eEncoding;
+ INetMessageIStream *pEncodeStrm;
+ INetMessageOStream *pDecodeStrm;
+
+ SvMemoryStream *pMsgBuffer;
+
+ static INetMessageEncoding GetMsgEncoding (
+ const String& rContentType);
+
+ // Not implemented.
+ INetMIMEMessageStream (const INetMIMEMessageStream& rStrm);
+ INetMIMEMessageStream& operator= (const INetMIMEMessageStream& rStrm);
+
+protected:
+ virtual int GetMsgLine (sal_Char *pData, ULONG nSize);
+ virtual int PutMsgLine (const sal_Char *pData, ULONG nSize);
+
+public:
+ INetMIMEMessageStream (ULONG nBufferSize = 2048);
+ virtual ~INetMIMEMessageStream (void);
+
+ using INetMessageIStream::SetSourceMessage;
+ void SetSourceMessage (INetMIMEMessage *pMsg)
+ {
+ INetMessageIStream::SetSourceMessage ((INetMessage *)pMsg);
+ }
+ INetMIMEMessage *GetSourceMessage (void) const
+ {
+ return ((INetMIMEMessage *)INetMessageIStream::GetSourceMessage());
+ }
+
+ using INetMessageOStream::SetTargetMessage;
+ void SetTargetMessage (INetMIMEMessage *pMsg)
+ {
+ INetMessageOStream::SetTargetMessage ((INetMessage *)pMsg);
+ }
+ INetMIMEMessage *GetTargetMessage (void) const
+ {
+ return ((INetMIMEMessage *)INetMessageOStream::GetTargetMessage());
+ }
+};
+
+#endif /* !_TOOLS_INETSTRM_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/iparser.hxx b/tools/inc/tools/iparser.hxx
new file mode 100644
index 000000000000..b9c0e7af2152
--- /dev/null
+++ b/tools/inc/tools/iparser.hxx
@@ -0,0 +1,149 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef IPARSER_HXX
+#define IPARSER_HXX
+
+#include <tools/string.hxx>
+#include <tools/link.hxx>
+#include <tools/stream.hxx>
+#include "tools/toolsdllapi.h"
+
+// forwards
+class Dir;
+class GenericInformation;
+class GenericInformationList;
+
+//
+// class InformationParser
+//
+
+/******************************************************************************
+Purpose: reads generic information files into a simple structure in memory
+******************************************************************************/
+
+// information files used by this parser have following format:
+
+/*
+
+key [value]
+{
+ key [value]
+ key [value]
+ {
+ key [value]
+ ...
+ ...
+ }
+}
+key [value]
+...
+...
+
+*/
+
+#define DEF_STAND_LST "\\\\dev4\\data1\\b_server\\config\\stand.lst"
+
+// error codes:
+
+#define IP_NO_ERROR 0x0000
+#define IP_UNEXPECTED_EOF 0x0001
+
+#define REPLACE_VARIABLES TRUE
+
+class TOOLS_DLLPUBLIC InformationParser
+{
+private:
+ BOOL bRecover;
+ ByteString sOldLine;
+
+ ByteString sCurrentComment;
+
+ BOOL bReplaceVariables; // meaning %UPD and %VERSION
+ USHORT nLevel;
+ ByteString sUPD;
+ ByteString sVersion;
+
+ Link aStatusLink;
+ SvStream *pActStream;
+ UniString sStreamName;
+
+ USHORT nErrorCode;
+ ULONG nErrorLine;
+ ByteString sErrorText;
+ ULONG nActLine;
+
+ // methods
+ TOOLS_DLLPRIVATE ByteString &ReadLine();
+ TOOLS_DLLPRIVATE GenericInformation *ReadKey( GenericInformationList *pExistingList );
+ inline void Recover();
+
+protected:
+ BOOL Save( SvStream &rOutStream,
+ const GenericInformationList *pSaveList, USHORT nLevel, BOOL bStripped );
+ GenericInformationList *Execute( SvStream &rSourceStream,
+ GenericInformationList *pExistingList );
+ virtual void PrintStatus( ByteString &rStatus )
+ { if ( aStatusLink.IsSet()) aStatusLink.Call( &rStatus ); }
+
+public:
+ InformationParser( BOOL bReplace = FALSE );
+ virtual ~InformationParser();
+
+ // the following methods return NULL if any errors are detected
+
+ // reads a information file and stores the data in a
+ // GenericInformationList
+ GenericInformationList *Execute( SvMemoryStream &rSourceStream,
+ GenericInformationList *pExistingList = NULL );
+ GenericInformationList *Execute( SvFileStream &rSourceStream,
+ GenericInformationList *pExistingList = NULL );
+ GenericInformationList *Execute( UniString &rSourceFile,
+ GenericInformationList *pExistingList = NULL );
+ // reads all information files in the dir and stores the data in a
+ // GenericInformationList => first key is the filename
+ GenericInformationList *Execute( Dir &rDir,
+ GenericInformationList *pExistingList = NULL );
+
+ // save the InfrormationList to rSourceFile
+ // returns FALSE on error
+ BOOL Save( SvFileStream &rSourceStream,
+ const GenericInformationList *pSaveList );
+ BOOL Save( SvMemoryStream &rSourceStream,
+ const GenericInformationList *pSaveList );
+ BOOL Save( const UniString &rSourceFile,
+ const GenericInformationList *pSaveList );
+
+ USHORT GetErrorCode();
+ ByteString &GetErrorText();
+
+ void SetStatusHdl( const Link &rHdl ) { aStatusLink = rHdl; }
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/isofallback.hxx b/tools/inc/tools/isofallback.hxx
new file mode 100644
index 000000000000..c014e3d70b64
--- /dev/null
+++ b/tools/inc/tools/isofallback.hxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _ISOFALLBACK_HXX
+#define _ISOFALLBACK_HXX
+
+#include <tools/string.hxx>
+#include "tools/toolsdllapi.h"
+
+// Return true if valid fallback found
+TOOLS_DLLPUBLIC sal_Bool GetIsoFallback( ByteString& rLanguage );
+
+#endif //_ISOFALLBACK_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/line.hxx b/tools/inc/tools/line.hxx
new file mode 100644
index 000000000000..500787434587
--- /dev/null
+++ b/tools/inc/tools/line.hxx
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _LINE_HXX
+#define _LINE_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/gen.hxx>
+
+class Link;
+
+// --------
+// - Line -
+// --------
+
+class TOOLS_DLLPUBLIC Line
+{
+private:
+
+ Point maStart;
+ Point maEnd;
+
+public:
+ Line() {};
+ Line( const Point& rStartPt, const Point& rEndPt ) : maStart( rStartPt ), maEnd( rEndPt ) {}
+
+ void SetStart( const Point& rStartPt ) { maStart = rStartPt; }
+ const Point& GetStart() const { return maStart; }
+
+ void SetEnd( const Point& rEndPt ) { maEnd = rEndPt; }
+ const Point& GetEnd() const { return maEnd; }
+
+ long Left() const { return ( maStart.X() < maEnd.X() ) ? maStart.X() : maEnd.X(); }
+ long Top() const { return ( maStart.Y() < maEnd.Y() ) ? maStart.Y() : maEnd.Y(); }
+ long Right() const { return ( maStart.X() > maEnd.X() ) ? maStart.X() : maEnd.X(); }
+ long Bottom() const { return ( maStart.Y() > maEnd.Y() ) ? maStart.Y() : maEnd.Y(); }
+
+ double GetLength() const;
+
+ BOOL Intersection( const Line& rLine, double& rIntersectionX, double& rIntersectionY ) const;
+ BOOL Intersection( const Line& rLine, Point& rIntersection ) const;
+ BOOL Intersection( const Rectangle& rRect, Line& rIntersection ) const;
+
+ double GetDistance( const double& rPtX, const double& rPtY ) const;
+ double GetDistance( const Point& rPoint ) const { return( GetDistance( rPoint.X(), rPoint.Y() ) ); }
+
+ Point NearestPoint( const Point& rPoint ) const;
+
+ void Enum( const Link& rEnumLink );
+};
+
+#endif // _SV_LINE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/link.hxx b/tools/inc/tools/link.hxx
new file mode 100644
index 000000000000..e2f80a18c87b
--- /dev/null
+++ b/tools/inc/tools/link.hxx
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _LINK_HXX
+#define _LINK_HXX
+
+#include "tools/toolsdllapi.h"
+#include "sal/config.h"
+#include "sal/types.h"
+#include <tools/solar.h>
+
+// ---------------
+// - Link-Makros -
+// ---------------
+
+typedef long (*PSTUB)( void*, void* );
+
+#define DECL_LINK( Method, ArgType ) \
+ long Method( ArgType ); \
+ static long LinkStub##Method( void* pThis, void* )
+
+#define DECL_STATIC_LINK( Class, Method, ArgType ) \
+ static long Method( Class*, ArgType )
+
+#define DECL_DLLPRIVATE_LINK(Method, ArgType) \
+ SAL_DLLPRIVATE long Method(ArgType); \
+ SAL_DLLPRIVATE static long LinkStub##Method(void * pThis, void *)
+
+#define DECL_DLLPRIVATE_STATIC_LINK(Class, Method, ArgType) \
+ SAL_DLLPRIVATE static long Method(Class *, ArgType)
+
+#define IMPL_METHOD( Class, Method, ArgType, ArgName ) \
+ long Class::Method( ArgType ArgName )
+
+#define IMPL_STUB(Class, Method, ArgType) \
+ long __EXPORT Class::LinkStub##Method( void* pThis, void* pCaller) \
+ { \
+ return ((Class*)pThis )->Method( (ArgType)pCaller ); \
+ }
+
+#define IMPL_STATIC_LINK( Class, Method, ArgType, ArgName ) \
+ long __EXPORT Class::Method( Class* pThis, ArgType ArgName )
+
+#define IMPL_STATIC_LINK_NOINSTANCE( Class, Method, ArgType, ArgName ) \
+ long __EXPORT Class::Method( Class*, ArgType ArgName )
+
+#define LINK( Inst, Class, Member ) \
+ Link( (Class*)Inst, (PSTUB)&Class::LinkStub##Member )
+
+#define STATIC_LINK( Inst, Class, Member ) \
+ Link( (Class*)Inst, (PSTUB)&Class::Member )
+
+#define IMPL_LINK( Class, Method, ArgType, ArgName ) \
+ IMPL_STUB( Class, Method, ArgType ) \
+ long Class::Method( ArgType ArgName )
+
+#if defined GCC && defined NO_OPTIMIZE
+#define IMPL_LINK_INLINE_START( Class, Method, ArgType, ArgName ) \
+ IMPL_LINK( Class, Method, ArgType, ArgName )
+
+#define IMPL_LINK_INLINE_END( Class, Method, ArgType, ArgName )
+#else
+#define IMPL_LINK_INLINE_START( Class, Method, ArgType, ArgName ) \
+ inline long Class::Method( ArgType ArgName )
+
+#define IMPL_LINK_INLINE_END( Class, Method, ArgType, ArgName ) \
+ IMPL_STUB( Class, Method, ArgType )
+#endif
+
+#define IMPL_LINK_INLINE( Class, Method, ArgType, ArgName, Body ) \
+ long Class::Method( ArgType ArgName ) \
+ Body \
+ IMPL_STUB( Class, Method, ArgType )
+
+#define EMPTYARG
+
+// --------
+// - Link -
+// --------
+
+class TOOLS_DLLPUBLIC Link
+{
+ void* pInst;
+ PSTUB pFunc;
+
+public:
+ Link();
+ Link( void* pLinkHdl, PSTUB pMemFunc );
+
+ long Call( void* pCaller ) const;
+
+ BOOL IsSet() const;
+ BOOL operator !() const;
+
+ BOOL operator==( const Link& rLink ) const;
+ BOOL operator!=( const Link& rLink ) const
+ { return !(Link::operator==( rLink )); }
+ BOOL operator<( const Link& rLink ) const
+ { return ((ULONG)rLink.pFunc < (ULONG)pFunc); }
+};
+
+inline Link::Link()
+{
+ pInst = 0;
+ pFunc = 0;
+}
+
+inline Link::Link( void* pLinkHdl, PSTUB pMemFunc )
+{
+ pInst = pLinkHdl;
+ pFunc = pMemFunc;
+}
+
+inline long Link::Call(void *pCaller) const
+{
+ return pFunc ? (*pFunc)(pInst, pCaller) : 0;
+}
+
+inline BOOL Link::IsSet() const
+{
+ if ( pFunc )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+inline BOOL Link::operator !() const
+{
+ if ( !pFunc )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+#endif // _LINK_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/list.hxx b/tools/inc/tools/list.hxx
new file mode 100644
index 000000000000..1874d31de156
--- /dev/null
+++ b/tools/inc/tools/list.hxx
@@ -0,0 +1,146 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _LIST_HXX
+#define _LIST_HXX
+
+#include <tools/solar.h>
+#include <tools/contnr.hxx>
+
+// --------
+// - List -
+// --------
+
+#define LIST_APPEND CONTAINER_APPEND
+#define LIST_ENTRY_NOTFOUND CONTAINER_ENTRY_NOTFOUND
+
+class List : private Container
+{
+public:
+ using Container::Insert;
+ using Container::Remove;
+ using Container::Replace;
+ using Container::Clear;
+ using Container::Count;
+ using Container::GetCurObject;
+ using Container::GetCurPos;
+ using Container::GetObject;
+ using Container::GetPos;
+ using Container::Seek;
+ using Container::First;
+ using Container::Last;
+ using Container::Next;
+ using Container::Prev;
+
+ List( USHORT _nInitSize = 16, USHORT _nReSize = 16 ) :
+ Container( 1024, _nInitSize, _nReSize ) {}
+ List( USHORT _nBlockSize, USHORT _nInitSize, USHORT _nReSize ) :
+ Container( _nBlockSize, _nInitSize, _nReSize ) {}
+ List( const List& rList ) : Container( rList ) {}
+
+ List& operator =( const List& rList )
+ { Container::operator =( rList ); return *this; }
+
+ BOOL operator ==( const List& rList ) const
+ { return Container::operator ==( rList ); }
+ BOOL operator !=( const List& rList ) const
+ { return Container::operator !=( rList ); }
+};
+
+// ----------------
+// - DECLARE_LIST -
+// ----------------
+
+#define DECLARE_LIST( ClassName, Type ) \
+class ClassName : private List \
+{ \
+public: \
+ using List::Clear; \
+ using List::Count; \
+ using List::GetCurPos; \
+ \
+ ClassName( USHORT _nInitSize = 16, \
+ USHORT _nReSize = 16 ) : \
+ List( _nInitSize, _nReSize ) {} \
+ ClassName( USHORT _nBlockSize, USHORT _nInitSize, \
+ USHORT _nReSize ) : \
+ List( _nBlockSize, _nInitSize, _nReSize ) {} \
+ ClassName( const ClassName& rClassName ) : \
+ List( rClassName ) {} \
+ \
+ void Insert( Type p, ULONG nIndex ) \
+ { List::Insert( (void*)p, nIndex ); } \
+ void Insert( Type p ) \
+ { List::Insert( (void*)p ); } \
+ void Insert( Type pNew, Type pOld ) \
+ { List::Insert( (void*)pNew, (void*)pOld ); } \
+ Type Remove() \
+ { return (Type)List::Remove(); } \
+ Type Remove( ULONG nIndex ) \
+ { return (Type)List::Remove( nIndex ); } \
+ Type Remove( Type p ) \
+ { return (Type)List::Remove( (void*)p ); } \
+ Type Replace( Type p ) \
+ { return (Type)List::Replace( (void*)p ); } \
+ Type Replace( Type p, ULONG nIndex ) \
+ { return (Type)List::Replace( (void*)p, nIndex ); } \
+ Type Replace( Type pNew, Type pOld ) \
+ { return (Type)List::Replace( (void*)pNew, \
+ (void*)pOld ); } \
+ \
+ Type GetCurObject() const \
+ { return (Type)List::GetCurObject(); } \
+ Type GetObject( ULONG nIndex ) const \
+ { return (Type)List::GetObject( nIndex ); } \
+ ULONG GetPos( const Type p ) const \
+ { return List::GetPos( (const void*)p ); } \
+ ULONG GetPos( const Type p, ULONG nStartIndex, \
+ BOOL bForward = TRUE ) const \
+ { return List::GetPos( (const void*)p, nStartIndex, \
+ bForward ); } \
+ \
+ Type Seek( ULONG nIndex ) \
+ { return (Type)List::Seek( nIndex ); } \
+ Type Seek( void* p ) { return (Type)List::Seek( p ); } \
+ Type First() { return (Type)List::First(); } \
+ Type Last() { return (Type)List::Last(); } \
+ Type Next() { return (Type)List::Next(); } \
+ Type Prev() { return (Type)List::Prev(); } \
+ \
+ ClassName& operator =( const ClassName& rClassName ) \
+ { List::operator =( rClassName ); return *this; } \
+ \
+ BOOL operator ==( const ClassName& rList ) const \
+ { return List::operator ==( rList ); } \
+ BOOL operator !=( const ClassName& rList ) const \
+ { return List::operator !=( rList ); } \
+};
+
+#endif // _LIST_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/mapunit.hxx b/tools/inc/tools/mapunit.hxx
new file mode 100644
index 000000000000..5ff01f287618
--- /dev/null
+++ b/tools/inc/tools/mapunit.hxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _TOOLS_MAPUNIT_HXX
+#define _TOOLS_MAPUNIT_HXX
+
+// -----------------
+// - MapMode-Types -
+// -----------------
+
+// By changes you must also change: rsc/vclrsc.hxx
+enum MapUnit { MAP_100TH_MM, MAP_10TH_MM, MAP_MM, MAP_CM,
+ MAP_1000TH_INCH, MAP_100TH_INCH, MAP_10TH_INCH, MAP_INCH,
+ MAP_POINT, MAP_TWIP, MAP_PIXEL, MAP_SYSFONT, MAP_APPFONT,
+ MAP_RELATIVE, MAP_REALAPPFONT, MAP_LASTENUMDUMMY };
+
+#endif // _TOOLS_MAPUNIT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/mempool.hxx b/tools/inc/tools/mempool.hxx
new file mode 100644
index 000000000000..626177e0a323
--- /dev/null
+++ b/tools/inc/tools/mempool.hxx
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _SVMEMPOOL_HXX
+#define _SVMEMPOOL_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/solar.h>
+
+// ----------------
+// - FixedMemPool -
+// ----------------
+
+struct FixedMemPool_Impl;
+
+class TOOLS_DLLPUBLIC FixedMemPool
+{
+ FixedMemPool_Impl * m_pImpl;
+
+public:
+ FixedMemPool( USHORT nTypeSize,
+ USHORT nInitSize = 512,
+ USHORT nGrowSize = 256 );
+ ~FixedMemPool();
+
+ void* Alloc();
+ void Free( void* p );
+};
+
+// ----------------------------
+// - DECL_FIXEDMEMPOOL_NEWDEL -
+// ----------------------------
+
+#define DECL_FIXEDMEMPOOL_NEW_DECL() \
+static void * operator new( size_t n )
+
+#define DECL_FIXEDMEMPOOL_NEW_IMPL( Class ) \
+void * Class::operator new( size_t n )
+
+#define IMPL_FIXEDMEMPOOL_NEW_BODY( Class, aPool ) \
+{ \
+ if ( n == sizeof( Class ) ) \
+ return (aPool).Alloc(); \
+ else \
+ return ::operator new(n); \
+}
+
+#define DECL_FIXEDMEMPOOL_NEW_INLINE( Class, aPool ) \
+DECL_FIXEDMEMPOOL_NEW_DECL() \
+IMPL_FIXEDMEMPOOL_NEW_BODY( Class, aPool )
+
+#define DECL_FIXEDMEMPOOL_DEL_DECL() \
+static void operator delete( void * p, size_t n )
+
+#define DECL_FIXEDMEMPOOL_DEL_IMPL( Class ) \
+void Class::operator delete( void * p, size_t n )
+
+#define IMPL_FIXEDMEMPOOL_DEL_BODY( Class, aPool ) \
+{ \
+ if ( n == sizeof( Class ) ) \
+ (aPool).Free(p); \
+ else \
+ ::operator delete(p); \
+}
+
+#define DECL_FIXEDMEMPOOL_DEL_INLINE( Class, aPool ) \
+DECL_FIXEDMEMPOOL_DEL_DECL() \
+IMPL_FIXEDMEMPOOL_DEL_BODY( Class, aPool )
+
+#define DECL_FIXEDMEMPOOL_NEWDEL( Class ) \
+ private: \
+ static FixedMemPool aPool; \
+ public: \
+ DECL_FIXEDMEMPOOL_NEW_INLINE( Class, aPool ) \
+ DECL_FIXEDMEMPOOL_DEL_INLINE( Class, aPool )
+
+#define IMPL_FIXEDMEMPOOL_NEWDEL( Class, InitSize, GrowSize) \
+ FixedMemPool Class::aPool( sizeof( Class ), (InitSize), (GrowSize) );
+
+#define DECL_FIXEDMEMPOOL_NEWDEL_DLL( Class ) \
+ private: \
+ static FixedMemPool aPool; \
+ public: \
+ DECL_FIXEDMEMPOOL_NEW_DECL(); \
+ DECL_FIXEDMEMPOOL_DEL_DECL();
+
+#define IMPL_FIXEDMEMPOOL_NEWDEL_DLL( Class, InitSize, GrowSize) \
+ FixedMemPool Class::aPool( sizeof( Class ), (InitSize), (GrowSize) ); \
+ DECL_FIXEDMEMPOOL_NEW_IMPL( Class ) \
+ IMPL_FIXEDMEMPOOL_NEW_BODY( Class, aPool ) \
+ DECL_FIXEDMEMPOOL_DEL_IMPL( Class ) \
+ IMPL_FIXEDMEMPOOL_DEL_BODY( Class, aPool )
+
+#define INIT_FIXEDMEMPOOL_NEWDEL_DLL( class, aPool, InitSize, GrowSize ) \
+ aPool( sizeof( class ), InitSize, GrowSize )
+
+#endif // _SVMEMPOOL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/multisel.hxx b/tools/inc/tools/multisel.hxx
new file mode 100644
index 000000000000..de5f55487459
--- /dev/null
+++ b/tools/inc/tools/multisel.hxx
@@ -0,0 +1,219 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _SV_MULTISEL_HXX
+#define _SV_MULTISEL_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/gen.hxx>
+#include <tools/list.hxx>
+#include <tools/string.hxx>
+
+#include <vector>
+#include <set>
+
+//------------------------------------------------------------------
+
+#ifdef _SV_MULTISEL_CXX
+DECLARE_LIST( ImpSelList, Range* )
+#else
+#define ImpSelList List
+#endif
+
+#define SFX_ENDOFSELECTION CONTAINER_ENTRY_NOTFOUND
+
+//------------------------------------------------------------------
+
+// ------------------
+// - MultiSelection -
+// ------------------
+
+class TOOLS_DLLPUBLIC MultiSelection
+{
+private:
+ ImpSelList aSels; // array of SV-selections
+ Range aTotRange; // total range of indexes
+ ULONG nCurSubSel; // index in aSels of current selected index
+ long nCurIndex; // current selected entry
+ ULONG nSelCount; // number of selected indexes
+ BOOL bInverseCur;// inverse cursor
+ BOOL bCurValid; // are nCurIndex and nCurSubSel valid
+ BOOL bSelectNew; // auto-select newly inserted indexes
+
+#ifdef _SV_MULTISEL_CXX
+ TOOLS_DLLPRIVATE void ImplClear();
+ TOOLS_DLLPRIVATE ULONG ImplFindSubSelection( long nIndex ) const;
+ TOOLS_DLLPRIVATE BOOL ImplMergeSubSelections( ULONG nPos1, ULONG nPos2 );
+ TOOLS_DLLPRIVATE long ImplFwdUnselected();
+ TOOLS_DLLPRIVATE long ImplBwdUnselected();
+#endif
+
+public:
+ MultiSelection();
+ MultiSelection( const MultiSelection& rOrig );
+ MultiSelection( const Range& rRange );
+ MultiSelection( const UniString& rString,
+ sal_Unicode cRange = '-',
+ sal_Unicode cSep = ';' );
+ ~MultiSelection();
+
+ MultiSelection& operator= ( const MultiSelection& rOrig );
+ BOOL operator== ( MultiSelection& rOrig );
+ BOOL operator!= ( MultiSelection& rOrig )
+ { return !operator==( rOrig ); }
+ BOOL operator !() const
+ { return nSelCount == 0; }
+
+ void SelectAll( BOOL bSelect = TRUE );
+ BOOL Select( long nIndex, BOOL bSelect = TRUE );
+ void Select( const Range& rIndexRange, BOOL bSelect = TRUE );
+ BOOL IsSelected( long nIndex ) const;
+ BOOL IsAllSelected() const
+ { return nSelCount == ULONG(aTotRange.Len()); }
+ long GetSelectCount() const { return nSelCount; }
+
+ void SetTotalRange( const Range& rTotRange );
+ void Insert( long nIndex, long nCount = 1 );
+ void Remove( long nIndex );
+ void Append( long nCount = 1 );
+
+ const Range& GetTotalRange() const { return aTotRange; }
+ BOOL IsCurValid() const { return bCurValid; }
+ long GetCurSelected() const { return nCurIndex; }
+ long FirstSelected( BOOL bInverse = FALSE );
+ long LastSelected();
+ long NextSelected();
+ long PrevSelected();
+
+ ULONG GetRangeCount() const { return aSels.Count(); }
+ const Range& GetRange( ULONG nRange ) const { return *(const Range*)aSels.GetObject(nRange); }
+};
+
+class TOOLS_DLLPUBLIC StringRangeEnumerator
+{
+ struct Range
+ {
+ sal_Int32 nFirst;
+ sal_Int32 nLast;
+
+ Range() : nFirst( -1 ), nLast( -1 ) {}
+ Range( sal_Int32 i_nFirst, sal_Int32 i_nLast ) : nFirst( i_nFirst ), nLast( i_nLast ) {}
+ };
+ std::vector< StringRangeEnumerator::Range > maSequence;
+ sal_Int32 mnCount;
+ sal_Int32 mnMin;
+ sal_Int32 mnMax;
+ sal_Int32 mnOffset;
+
+ bool insertRange( sal_Int32 nFirst, sal_Int32 nLast, bool bSequence, bool bMayAdjust );
+ bool checkValue( sal_Int32, const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const;
+public:
+ class TOOLS_DLLPUBLIC Iterator
+ {
+ const StringRangeEnumerator* pEnumerator;
+ const std::set< sal_Int32 >* pPossibleValues;
+ sal_Int32 nRangeIndex;
+ sal_Int32 nCurrent;
+
+ friend class StringRangeEnumerator;
+ Iterator( const StringRangeEnumerator* i_pEnum,
+ const std::set< sal_Int32 >* i_pPossibleValues,
+ sal_Int32 i_nRange,
+ sal_Int32 i_nCurrent )
+ : pEnumerator( i_pEnum ), pPossibleValues( i_pPossibleValues )
+ , nRangeIndex( i_nRange ), nCurrent( i_nCurrent ) {}
+ public:
+ Iterator() : pEnumerator( NULL ), pPossibleValues( NULL ), nRangeIndex( -1 ), nCurrent( -1 ) {}
+ Iterator& operator++();
+ sal_Int32 operator*() const;
+ bool operator==(const Iterator&) const;
+ bool operator!=(const Iterator& i_rComp) const
+ { return ! (*this == i_rComp); }
+ };
+
+ friend class StringRangeEnumerator::Iterator;
+
+ StringRangeEnumerator() : mnCount( 0 ), mnMin( -1 ), mnMax( -1 ), mnOffset( -1 ) {}
+ StringRangeEnumerator( const rtl::OUString& i_rInput,
+ sal_Int32 i_nMinNumber = -1,
+ sal_Int32 i_nMaxNumber = -1,
+ sal_Int32 i_nLogicalOffset = -1
+ );
+
+ size_t size() const { return size_t(mnCount); }
+ Iterator begin( const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const;
+ Iterator end( const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const;
+
+ sal_Int32 getMin() const { return mnMin; }
+ void setMin( sal_Int32 i_nMinValue ) { mnMin = i_nMinValue; }
+ sal_Int32 getMax() const { return mnMax; }
+ void setMax( sal_Int32 i_nMaxValue ) { mnMax = i_nMaxValue; }
+ sal_Int32 getLogicalOffset() const { return mnOffset; }
+ void setLogicalOffset( sal_Int32 i_nOffset ) { mnOffset = i_nOffset; }
+
+ bool setRange( const rtl::OUString& i_rNewRange, bool i_bStrict = false );
+ bool hasValue( sal_Int32 nValue, const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const;
+
+
+ /**
+ i_rPageRange: the string to be changed into a sequence of numbers
+ valid format example "5-3,9,9,7-8" ; instead of ',' ';' or ' ' are allowed as well
+ o_rPageVector: the output sequence of numbers
+ i_nLogicalOffset: an offset to be applied to each number in the string before inserting it in the resulting sequence
+ example: a user enters page numbers from 1 to n (since that is logical)
+ of course usable page numbers in code would start from 0 and end at n-1
+ so the logical offset would be -1
+ i_nMinNumber: the minimum allowed number, a negative number means no minimum check
+ i_nMaxNumber: the maximum allowed number, a negative number means no maximum check
+
+ @returns: true if the input string was valid, o_rPageVector will contain the resulting sequence
+ false if the input string was invalid, o_rPageVector will be unchanged
+
+ behavior:
+ - only non-negative sequence numbers are allowed
+ - only non-negative values in the input string are allowed
+ - the string "-3" will be either
+ * an error if no minimum is given
+ * or result in the sequence i_nMinNumber to 3
+ - the string "3-" will be either
+ * an error if no maximum is given
+ * or result in the seqeuence 3 to i_nMaxNumber
+ - an empty string as input is valid and will result in the range [min,max] if given
+ or an empty vector, if not
+ */
+ static bool getRangesFromString( const rtl::OUString& i_rPageRange,
+ std::vector< sal_Int32 >& o_rPageVector,
+ sal_Int32 i_nMinNumber = -1,
+ sal_Int32 i_nMaxNumber = -1,
+ sal_Int32 i_nLogicalOffset = -1,
+ std::set< sal_Int32 >* i_pPossibleValues = NULL
+ );
+};
+
+#endif // _SV_MULTISEL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/ownlist.hxx b/tools/inc/tools/ownlist.hxx
new file mode 100644
index 000000000000..59d2a8a4a9a7
--- /dev/null
+++ b/tools/inc/tools/ownlist.hxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _TOOLS_OWNLIST_HXX
+#define _TOOLS_OWNLIST_HXX
+
+#include <tools/list.hxx>
+/*************************************************************************
+*************************************************************************/
+
+#define PRV_SV_DECL_OWNER_LIST(ClassName,Type) \
+ List aTypes; \
+public: \
+ ClassName( USHORT nInitSize = 16, \
+ USHORT nReSize = 16 ) \
+ : aTypes( nInitSize, nReSize ) {} \
+ ClassName( const ClassName & rObj ) \
+ { *this = rObj; } \
+ ClassName & operator = ( const ClassName & ); \
+ ~ClassName() \
+ { Clear(); } \
+ void Clear(); \
+ void Remove() \
+ { delete (Type *)aTypes.Remove(); } \
+ void Remove( Type * pObj ) \
+ { delete (Type *)aTypes.Remove( pObj ); } \
+ void Remove( ULONG nPos ) \
+ { delete (Type *)aTypes.Remove( nPos ); } \
+ Type & Insert( const Type &, ULONG nPos ); \
+ Type & Insert( const Type & rType ) \
+ { return Insert( rType, aTypes.GetCurPos() ); } \
+ Type & Append( const Type & rType ) \
+ { return Insert( rType, LIST_APPEND ); } \
+ Type & GetObject( ULONG nPos ) const \
+ { return *(Type *)aTypes.GetObject( nPos ); } \
+ Type & operator []( ULONG nPos ) const \
+ { return *(Type *)aTypes.GetObject( nPos ); } \
+ ULONG Count() const { return aTypes.Count(); }
+
+#define PRV_SV_IMPL_OWNER_LIST(ClassName,Type) \
+ClassName & ClassName::operator = ( const ClassName & rObj ) \
+{ \
+ if( this != &rObj ) \
+ { \
+ Clear(); \
+ for( ULONG i = 0; i < rObj.Count(); i++ ) \
+ Append( rObj.GetObject( i ) ); \
+ } \
+ return *this; \
+} \
+void ClassName::Clear() \
+{ \
+ Type * p = (Type *)aTypes.First(); \
+ while( p ) \
+ { \
+ delete p; \
+ p = (Type *)aTypes.Next(); \
+ } \
+ aTypes.Clear(); \
+} \
+Type & ClassName::Insert( const Type & rType, ULONG nPos ) \
+{ \
+ Type * pType = new Type( rType ); \
+ aTypes.Insert( pType, nPos ); \
+ return *pType; \
+}
+
+#endif // _TOOLS_OWNLIST_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/pathutils.hxx b/tools/inc/tools/pathutils.hxx
new file mode 100644
index 000000000000..96c5cafee3ad
--- /dev/null
+++ b/tools/inc/tools/pathutils.hxx
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TOOLS_PATHUTILS_HXX
+#define INCLUDED_TOOLS_PATHUTILS_HXX
+
+#include "sal/config.h"
+
+#if defined WNT
+
+#include <cstddef>
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+// The compiled code is not part of the tl dynamic library, but is delivered as
+// pathutils-obj and pathutils-slo objects (it is linked into special
+// executables and dynamic libraries that do not link against OOo libraries):
+
+namespace tools {
+
+// Determine the filename part of a path.
+//
+// @param path
+// A non-NULL pointer to a null-terminated path.
+//
+// @return
+// A pointer to the trailing filename part of the given path.
+WCHAR * filename(WCHAR * path);
+
+// Concatenate two paths.
+//
+// Either the first path is empty and the second path is an absolute path. Or
+// the first path is an absolute path that ends in a backslash and the second
+// path is a relative path. In the latter case, to avoid paths that grow too
+// long, leading .. segments of the second path are removed together with
+// trailing segments from the first path. This should not cause problems as
+// long as there are no symbolic links on Windows (as with symbolic links,
+// x\y\.. and x might denote different directories).
+//
+// @param path
+// An output paremeter taking the resulting path; must point at a valid range of
+// memory of size at least MAX_PATH. If NULL is returned, the content is
+// unspecified.
+//
+// @param frontBegin, frontEnd
+// Forms a valid range [frontBegin .. frontEnd) of less than MAX_PATH size.
+//
+// @param backBegin, backLength
+// Forms a valid range [backBeghin .. backBegin + backLength) of less than
+// MAX_PATH size.
+//
+// @return
+// A pointer to the terminating null character of the concatenation, or NULL if
+// a failure occurred.
+WCHAR * buildPath(
+ WCHAR * path, WCHAR const * frontBegin, WCHAR const * frontEnd,
+ WCHAR const * backBegin, std::size_t backLength);
+
+// Resolve a link file.
+//
+// @param path
+// An input/output parameter taking the path; must point at a valid range of
+// memory of size at least MAX_PATH. On input, contains the null-terminated
+// full path of the link file. On output, contains the null-terminated full
+// path of the resolved link; if NULL is returned, the content is unspecified.
+//
+// @return
+// A pointer to the terminating null character of path, or NULL if a failure
+// occurred.
+WCHAR * resolveLink(WCHAR * path);
+
+}
+
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/poly.hxx b/tools/inc/tools/poly.hxx
new file mode 100644
index 000000000000..e7dc14b519dc
--- /dev/null
+++ b/tools/inc/tools/poly.hxx
@@ -0,0 +1,344 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _TL_POLY_HXX
+#define _TL_POLY_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/gen.hxx>
+#include <tools/debug.hxx>
+
+#include <vector>
+
+// -----------
+// - Defines -
+// -----------
+
+#define POLY_APPEND (0xFFFF)
+#define POLYPOLY_APPEND (0xFFFF)
+
+// ------------------------------------------------------------------------
+
+#define POLY_OPTIMIZE_NONE 0x00000000UL
+#define POLY_OPTIMIZE_OPEN 0x00000001UL
+#define POLY_OPTIMIZE_CLOSE 0x00000002UL
+#define POLY_OPTIMIZE_NO_SAME 0x00000004UL
+#define POLY_OPTIMIZE_REDUCE 0x00000008UL
+#define POLY_OPTIMIZE_EDGES 0x00000010UL
+
+// -------------
+// - PolyStyle -
+// -------------
+
+enum PolyStyle
+{
+ POLY_ARC = 1,
+ POLY_PIE = 2,
+ POLY_CHORD = 3
+};
+
+// -------------
+// - PolyFlags -
+// -------------
+
+#ifndef ENUM_POLYFLAGS_DECLARED
+#define ENUM_POLYFLAGS_DECLARED
+enum PolyFlags
+{
+ POLY_NORMAL,
+ POLY_SMOOTH,
+ POLY_CONTROL,
+ POLY_SYMMTR
+};
+#endif
+
+// ----------------
+// - PolyOptimize -
+// ----------------
+
+class PolyOptimizeData
+{
+private:
+
+ enum DataType { DATA_NONE = 0, DATA_ABSOLUT = 1, DATA_PERCENT = 2 };
+ DataType eType;
+ union { ULONG mnAbsolut; USHORT mnPercent; };
+
+public:
+
+ PolyOptimizeData() : eType( DATA_NONE ) {}
+ PolyOptimizeData( ULONG nAbsolut ) : eType( DATA_ABSOLUT ), mnAbsolut( nAbsolut ) {}
+ PolyOptimizeData( USHORT nPercent ) : eType( DATA_PERCENT ), mnPercent( nPercent ) {}
+
+ ULONG GetAbsValue() const { DBG_ASSERT( eType == DATA_ABSOLUT, "Wrong data type" ); return mnAbsolut; }
+ USHORT GetPercentValue() const { DBG_ASSERT( eType == DATA_PERCENT, "Wrong data type" ); return mnPercent; }
+};
+
+// -----------
+// - Polygon -
+// -----------
+
+class SvStream;
+class ImplPolygon;
+class ImplPolyPolygon;
+class PolyPolygon;
+
+namespace basegfx
+{
+ class B2DPolygon;
+ class B2DPolyPolygon;
+} // end of namespace basegfx
+
+class TOOLS_DLLPUBLIC Polygon
+{
+private:
+
+ ImplPolygon* mpImplPolygon;
+
+ TOOLS_DLLPRIVATE inline void ImplMakeUnique();
+
+public:
+
+ Point* ImplGetPointAry();
+ BYTE* ImplGetFlagAry();
+
+ static void ImplReduceEdges( Polygon& rPoly, const double& rArea, USHORT nPercent );
+ void ImplRead( SvStream& rIStream );
+ void ImplWrite( SvStream& rOStream ) const;
+
+public:
+ Polygon();
+ Polygon( USHORT nSize );
+ Polygon( USHORT nPoints, const Point* pPtAry,
+ const BYTE* pFlagAry = NULL );
+ Polygon( const Rectangle& rRect );
+ Polygon( const Rectangle& rRect,
+ ULONG nHorzRound, ULONG nVertRound );
+ Polygon( const Point& rCenter,
+ long nRadX, long nRadY,
+ USHORT nPoints = 0 );
+ Polygon( const Rectangle& rBound,
+ const Point& rStart, const Point& rEnd,
+ PolyStyle ePolyStyle = POLY_ARC );
+ Polygon( const Point& rBezPt1, const Point& rCtrlPt1,
+ const Point& rBezPt2, const Point& rCtrlPt2,
+ USHORT nPoints = 0 );
+
+ Polygon( const Polygon& rPoly );
+ ~Polygon();
+
+ void SetPoint( const Point& rPt, USHORT nPos );
+ const Point& GetPoint( USHORT nPos ) const;
+
+ void SetFlags( USHORT nPos, PolyFlags eFlags );
+ PolyFlags GetFlags( USHORT nPos ) const;
+ sal_Bool HasFlags() const;
+
+ BOOL IsControl( USHORT nPos ) const;
+ BOOL IsSmooth( USHORT nPos ) const;
+ BOOL IsRect() const;
+
+ void SetSize( USHORT nNewSize );
+ USHORT GetSize() const;
+
+ void Clear();
+
+ Rectangle GetBoundRect() const;
+ double GetArea() const;
+ double GetSignedArea() const;
+ BOOL IsInside( const Point& rPt ) const;
+ BOOL IsRightOrientated() const;
+ double CalcDistance( USHORT nPt1, USHORT nPt2 );
+ void Clip( const Rectangle& rRect, BOOL bPolygon = TRUE );
+ void Optimize( ULONG nOptimizeFlags, const PolyOptimizeData* pData = NULL );
+
+ /** Adaptive subdivision of polygons with curves
+
+ This method adaptively subdivides bezier arcs within the
+ polygon to straight line segments and returns the resulting
+ polygon.
+
+ @param rResult
+ The resulting subdivided polygon
+
+ @param d
+ This parameter controls the amount of subdivision. The
+ original curve is guaranteed to not differ by more than this
+ amount per bezier segment from the subdivided
+ lines. Concretely, if the polygon is in device coordinates and
+ d equals 1.0, then the difference between the subdivided and
+ the original polygon is guaranteed to be smaller than one
+ pixel.
+ */
+ void AdaptiveSubdivide( Polygon& rResult, const double d = 1.0 ) const;
+
+ void GetIntersection( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
+ void GetUnion( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
+ void GetDifference( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
+ void GetXOR( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
+
+ void Move( long nHorzMove, long nVertMove );
+ void Translate( const Point& rTrans );
+ void Scale( double fScaleX, double fScaleY );
+ void Rotate( const Point& rCenter, double fSin, double fCos );
+ void Rotate( const Point& rCenter, USHORT nAngle10 );
+ void SlantX( long nYRef, double fSin, double fCos );
+ void SlantY( long nXRef, double fSin, double fCos );
+ void Distort( const Rectangle& rRefRect, const Polygon& rDistortedRect );
+
+ void Insert( USHORT nPos, const Point& rPt, PolyFlags eFlags = POLY_NORMAL );
+ void Insert( USHORT nPos, const Polygon& rPoly );
+ void Remove( USHORT nPos, USHORT nCount );
+
+ const Point& operator[]( USHORT nPos ) const { return GetPoint( nPos ); }
+ Point& operator[]( USHORT nPos );
+
+ Polygon& operator=( const Polygon& rPoly );
+ BOOL operator==( const Polygon& rPoly ) const;
+ BOOL operator!=( const Polygon& rPoly ) const
+ { return !(Polygon::operator==( rPoly )); }
+ sal_Bool IsEqual( const Polygon& rPoly ) const;
+
+ // streaming a Polygon does ignore PolyFlags, so use the Write Or Read
+ // method to take care of PolyFlags
+ TOOLS_DLLPUBLIC friend SvStream& operator>>( SvStream& rIStream, Polygon& rPoly );
+ TOOLS_DLLPUBLIC friend SvStream& operator<<( SvStream& rOStream, const Polygon& rPoly );
+
+ void Read( SvStream& rIStream );
+ void Write( SvStream& rOStream ) const;
+
+ const Point* GetConstPointAry() const;
+ const BYTE* GetConstFlagAry() const;
+
+ // convert to ::basegfx::B2DPolygon and return
+ ::basegfx::B2DPolygon getB2DPolygon() const;
+
+ // constructor to convert from ::basegfx::B2DPolygon
+ // #i76339# made explicit
+ explicit Polygon(const ::basegfx::B2DPolygon& rPolygon);
+};
+
+// ---------------
+// - PolyPolygon -
+// ---------------
+
+class TOOLS_DLLPUBLIC PolyPolygon
+{
+private:
+
+ ImplPolyPolygon* mpImplPolyPolygon;
+
+ TOOLS_DLLPRIVATE void ImplDoOperation( const PolyPolygon& rPolyPoly, PolyPolygon& rResult, ULONG nOperation ) const;
+ TOOLS_DLLPRIVATE void *ImplCreateArtVpath() const;
+ TOOLS_DLLPRIVATE void ImplSetFromArtVpath( void *pVpath );
+
+public:
+
+ PolyPolygon( USHORT nInitSize = 16, USHORT nResize = 16 );
+ PolyPolygon( const Polygon& rPoly );
+ PolyPolygon( USHORT nPoly, const USHORT* pPointCountAry,
+ const Point* pPtAry );
+ PolyPolygon( const PolyPolygon& rPolyPoly );
+ ~PolyPolygon();
+
+ void Insert( const Polygon& rPoly, USHORT nPos = POLYPOLY_APPEND );
+ void Remove( USHORT nPos );
+ void Replace( const Polygon& rPoly, USHORT nPos );
+ const Polygon& GetObject( USHORT nPos ) const;
+
+ BOOL IsRect() const;
+
+ void Clear();
+
+ USHORT Count() const;
+ Rectangle GetBoundRect() const;
+ void Clip( const Rectangle& rRect );
+ void Optimize( ULONG nOptimizeFlags, const PolyOptimizeData* pData = NULL );
+
+ /** Adaptive subdivision of polygons with curves
+
+ This method adaptively subdivides bezier arcs within the
+ polygon to straight line segments and returns the resulting
+ polygon.
+
+ @param rResult
+ The resulting subdivided polygon
+
+ @param d
+ This parameter controls the amount of subdivision. The
+ original curve is guaranteed to not differ by more than this
+ amount per bezier segment from the subdivided
+ lines. Concretely, if the polygon is in device coordinates and
+ d equals 1.0, then the difference between the subdivided and
+ the original polygon is guaranteed to be smaller than one
+ pixel.
+ */
+ void AdaptiveSubdivide( PolyPolygon& rResult, const double d = 1.0 ) const;
+
+ void GetIntersection( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
+ void GetUnion( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
+ void GetDifference( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
+ void GetXOR( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
+
+ void Move( long nHorzMove, long nVertMove );
+ void Translate( const Point& rTrans );
+ void Scale( double fScaleX, double fScaleY );
+ void Rotate( const Point& rCenter, double fSin, double fCos );
+ void Rotate( const Point& rCenter, USHORT nAngle10 );
+ void SlantX( long nYRef, double fSin, double fCos );
+ void SlantY( long nXRef, double fSin, double fCos );
+ void Distort( const Rectangle& rRefRect, const Polygon& rDistortedRect );
+
+ const Polygon& operator[]( USHORT nPos ) const { return GetObject( nPos ); }
+ Polygon& operator[]( USHORT nPos );
+
+ PolyPolygon& operator=( const PolyPolygon& rPolyPoly );
+ BOOL operator==( const PolyPolygon& rPolyPoly ) const;
+ BOOL operator!=( const PolyPolygon& rPolyPoly ) const
+ { return !(PolyPolygon::operator==( rPolyPoly )); }
+
+ sal_Bool IsEqual( const PolyPolygon& rPolyPoly ) const;
+
+ TOOLS_DLLPUBLIC friend SvStream& operator>>( SvStream& rIStream, PolyPolygon& rPolyPoly );
+ TOOLS_DLLPUBLIC friend SvStream& operator<<( SvStream& rOStream, const PolyPolygon& rPolyPoly );
+
+ void Read( SvStream& rIStream );
+ void Write( SvStream& rOStream ) const;
+
+ // convert to ::basegfx::B2DPolyPolygon and return
+ ::basegfx::B2DPolyPolygon getB2DPolyPolygon() const;
+
+ // constructor to convert from ::basegfx::B2DPolyPolygon
+ // #i76339# made explicit
+ explicit PolyPolygon(const ::basegfx::B2DPolyPolygon& rPolyPolygon);
+};
+
+typedef std::vector< PolyPolygon > PolyPolyVector;
+
+#endif // _SV_POLY_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/postsys.h b/tools/inc/tools/postsys.h
new file mode 100644
index 000000000000..68711b38a0b0
--- /dev/null
+++ b/tools/inc/tools/postsys.h
@@ -0,0 +1,246 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/* nicht geschuetz, muss als gegenstueck zu prestl.h includet werden */
+
+#if defined WNT
+
+#undef Region
+#undef PolyPolygon
+#undef Polygon
+#undef Rectangle
+#undef BYTE
+#undef BOOL
+#undef DELETE
+
+/* Hilfe-Ids umbenennen */
+#define WIN_HELP_INDEX 0x0003
+#define WIN_HELP_HELPONHELP 0x0004
+#undef HELP_INDEX
+#undef HELP_HELPONHELP
+
+#define WIN_MOUSE_MOVED 0x0001
+#undef MOUSE_MOVED
+
+#define WIN_WB_LEFT 0
+#define WIN_WB_RIGHT 1
+#undef WB_LEFT
+#undef WB_RIGHT
+
+#ifdef GetObject
+#undef GetObject
+#ifdef UNICODE
+#define WIN_GetObject GetObjectW
+#else
+#define WIN_GetObject GetObjectA
+#endif
+#else
+#define WIN_GetObject GetObject
+#endif
+
+#ifdef SetPrinter
+#undef SetPrinter
+#ifdef UNICODE
+#define WIN_SetPrinter SetPrinterW
+#else
+#define WIN_SetPrinter SetPrinterA
+#endif
+#else
+#define WIN_SetPrinter SetPrinter
+#endif
+
+#ifdef GetPrinter
+#undef GetPrinter
+#ifdef UNICODE
+#define WIN_GetPrinter GetPrinterW
+#else
+#define WIN_GetPrinter GetPrinterA
+#endif
+#else
+#define WIN_GetPrinter GetPrinter
+#endif
+
+#ifdef DrawText
+#undef DrawText
+#ifdef UNICODE
+#define WIN_DrawText DrawTextW
+#else
+#define WIN_DrawText DrawTextA
+#endif
+#else
+#define WIN_DrawText DrawText
+#endif
+
+#ifdef mciSetCommand
+#undef mciSetCommand
+#ifdef UNICODE
+#define WIN_mciSetCommand mciSetCommandW
+#else
+#define WIN_mciSetCommand mciSetCommandA
+#endif
+#else
+#define mciSetCommand mciSetCommand
+#endif
+
+#ifdef SetPort
+#undef SetPort
+#ifdef UNICODE
+#define WIN_SetPort SetPortW
+#else
+#define WIN_SetPort SetPortA
+#endif
+#else
+#define WIN_SetPort SetPort
+#endif
+
+#ifdef CopyFile
+#undef CopyFile
+#ifdef UNICODE
+#define WIN_CopyFile CopyFileW
+#else
+#define WIN_CopyFile CopyFileA
+#endif
+#else
+#define WIN_CopyFile CopyFile
+#endif
+
+#ifdef GetUserName
+#undef GetUserName
+#ifdef UNICODE
+#define WIN_GetUserName GetUserNameW
+#else
+#define WIN_GetUserName GetUserNameA
+#endif
+#else
+#define WIN_GetUserName GetUserName
+#endif
+
+#ifdef GetClassName
+#undef GetClassName
+#ifdef UNICODE
+#define WIN_GetClassName GetClassNameW
+#else
+#define WIN_GetClassName GetClassNameA
+#endif
+#else
+#define WIN_GetClassName GetClassName
+#endif
+
+#ifdef GetCharWidth
+#undef GetCharWidth
+#ifdef UNICODE
+#define WIN_GetCharWidth GetCharWidthW
+#else
+#define WIN_GetCharWidth GetCharWidthA
+#endif
+#else
+#define WIN_GetCharWidth GetCharWidth
+#endif
+
+#ifdef GetMetaFile
+#undef GetMetaFile
+#ifdef UNICODE
+#define WIN_GetMetaFile GetMetaFileW
+#else
+#define WIN_GetMetaFile GetMetaFileA
+#endif
+#else
+#define WIN_GetMetaFile GetMetaFile
+#endif
+
+#ifdef GetNumberFormat
+#undef GetNumberFormat
+#ifdef UNICODE
+#define WIN_GetNumberFormat GetNumberFormatW
+#else
+#define WIN_GetNumberFormat GetNumberFormatA
+#endif
+#else
+#define WIN_GetNumberFormat GetNumberFormat
+#endif
+
+#ifdef GetGlyphOutline
+#undef GetGlyphOutline
+#ifdef UNICODE
+#define WIN_GetGlyphOutline GetGlyphOutlineW
+#else
+#define WIN_GetGlyphOutline GetGlyphOutlineA
+#endif
+#else
+#define WIN_GetGlyphOutline GetGlyphOutline
+#endif
+
+#ifdef GetKerningPairs
+#undef GetKerningPairs
+#ifdef UNICODE
+#define WIN_GetKerningPairs GetKerningPairsW
+#else
+#define WIN_GetKerningPairs GetKerningPairsA
+#endif
+#else
+#define WIN_GetKerningPairs GetKerningPairs
+#endif
+
+#ifdef FindWindow
+#undef FindWindow
+#ifdef UNICODE
+#define WIN_FindWindow FindWindowW
+#else
+#define WIN_FindWindow FindWindowA
+#endif
+#else
+#define WIN_FindWindow FindWindow
+#endif
+
+// keine Yield-Definition
+#undef Yield
+
+/* new StretchBlt() Modes (simpler names) */
+#ifndef STRETCH_ANDSCANS
+#define STRETCH_ANDSCANS 1
+#endif
+#ifndef STRETCH_ORSCANS
+#define STRETCH_ORSCANS 2
+#endif
+#ifndef STRETCH_DELETESCANS
+#define STRETCH_DELETESCANS 3
+#endif
+
+extern "C"
+{
+WIN_BOOL WINAPI WIN_Rectangle( HDC hDC, int X1, int Y1, int X2, int Y2 );
+WIN_BOOL WINAPI WIN_Polygon( HDC hDC, CONST POINT * ppt, int ncnt );
+WIN_BOOL WINAPI WIN_PolyPolygon( HDC hDC, CONST POINT * ppt, LPINT npcnt, int ncnt );
+}
+
+#endif
+
+// Konfl�kt mit den Tools-Pair vermeiden
+#undef Pair
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/postwin.h b/tools/inc/tools/postwin.h
new file mode 100644
index 000000000000..40a11c175fde
--- /dev/null
+++ b/tools/inc/tools/postwin.h
@@ -0,0 +1,260 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/* nicht geschuetz, muss als gegenstueck zu prewin.h includet werden */
+
+#ifdef WNT
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#undef Region
+#undef PolyPolygon
+#undef Polygon
+#undef Rectangle
+#undef BYTE
+#undef BOOL
+#undef DELETE
+
+#ifndef VCL_NEED_BASETSD
+#undef INT64
+#undef UINT64
+#undef INT32
+#undef UINT32
+#endif
+#undef Folder
+#undef GradientStyle_RECT
+
+/* Hilfe-Ids umbenennen */
+#define WIN_HELP_INDEX 0x0003
+#define WIN_HELP_HELPONHELP 0x0004
+#undef HELP_INDEX
+#undef HELP_HELPONHELP
+
+#define WIN_MOUSE_MOVED 0x0001
+#undef MOUSE_MOVED
+
+#define WIN_WB_LEFT 0
+#define WIN_WB_RIGHT 1
+#undef WB_LEFT
+#undef WB_RIGHT
+
+#ifdef GetObject
+#undef GetObject
+#ifdef UNICODE
+#define WIN_GetObject GetObjectW
+#else
+#define WIN_GetObject GetObjectA
+#endif
+#else
+#define WIN_GetObject GetObject
+#endif
+
+#ifdef SetPrinter
+#undef SetPrinter
+#ifdef UNICODE
+#define WIN_SetPrinter SetPrinterW
+#else
+#define WIN_SetPrinter SetPrinterA
+#endif
+#else
+#define WIN_SetPrinter SetPrinter
+#endif
+
+#ifdef GetPrinter
+#undef GetPrinter
+#ifdef UNICODE
+#define WIN_GetPrinter GetPrinterW
+#else
+#define WIN_GetPrinter GetPrinterA
+#endif
+#else
+#define WIN_GetPrinter GetPrinter
+#endif
+
+#ifdef DrawText
+#undef DrawText
+#ifdef UNICODE
+#define WIN_DrawText DrawTextW
+#else
+#define WIN_DrawText DrawTextA
+#endif
+#else
+#define WIN_DrawText DrawText
+#endif
+
+#ifdef mciSetCommand
+#undef mciSetCommand
+#ifdef UNICODE
+#define WIN_mciSetCommand mciSetCommandW
+#else
+#define WIN_mciSetCommand mciSetCommandA
+#endif
+#else
+#define mciSetCommand mciSetCommand
+#endif
+
+#ifdef SetPort
+#undef SetPort
+#ifdef UNICODE
+#define WIN_SetPort SetPortW
+#else
+#define WIN_SetPort SetPortA
+#endif
+#else
+#define WIN_SetPort SetPort
+#endif
+
+#ifdef CopyFile
+#undef CopyFile
+#ifdef UNICODE
+#define WIN_CopyFile CopyFileW
+#else
+#define WIN_CopyFile CopyFileA
+#endif
+#else
+#define WIN_CopyFile CopyFile
+#endif
+
+
+#ifdef GetUserName
+#undef GetUserName
+#ifdef UNICODE
+#define WIN_GetUserName GetUserNameW
+#else
+#define WIN_GetUserName GetUserNameA
+#endif
+#else
+#define WIN_GetUserName GetUserName
+#endif
+
+#ifdef GetClassName
+#undef GetClassName
+#ifdef UNICODE
+#define WIN_GetClassName GetClassNameW
+#else
+#define WIN_GetClassName GetClassNameA
+#endif
+#else
+#define WIN_GetClassName GetClassName
+#endif
+
+#ifdef GetCharWidth
+#undef GetCharWidth
+#ifdef UNICODE
+#define WIN_GetCharWidth GetCharWidthW
+#else
+#define WIN_GetCharWidth GetCharWidthA
+#endif
+#else
+#define WIN_GetCharWidth GetCharWidth
+#endif
+
+#ifdef GetMetaFile
+#undef GetMetaFile
+#ifdef UNICODE
+#define WIN_GetMetaFile GetMetaFileW
+#else
+#define WIN_GetMetaFile GetMetaFileA
+#endif
+#else
+#define WIN_GetMetaFile GetMetaFile
+#endif
+
+#ifdef GetNumberFormat
+#undef GetNumberFormat
+#ifdef UNICODE
+#define WIN_GetNumberFormat GetNumberFormatW
+#else
+#define WIN_GetNumberFormat GetNumberFormatA
+#endif
+#else
+#define WIN_GetNumberFormat GetNumberFormat
+#endif
+
+#ifdef GetGlyphOutline
+#undef GetGlyphOutline
+#ifdef UNICODE
+#define WIN_GetGlyphOutline GetGlyphOutlineW
+#else
+#define WIN_GetGlyphOutline GetGlyphOutlineA
+#endif
+#else
+#define WIN_GetGlyphOutline GetGlyphOutline
+#endif
+
+#ifdef GetKerningPairs
+#undef GetKerningPairs
+#ifdef UNICODE
+#define WIN_GetKerningPairs GetKerningPairsW
+#else
+#define WIN_GetKerningPairs GetKerningPairsA
+#endif
+#else
+#define WIN_GetKerningPairs GetKerningPairs
+#endif
+
+#ifdef FindWindow
+#undef FindWindow
+#ifdef UNICODE
+#define WIN_FindWindow FindWindowW
+#else
+#define WIN_FindWindow FindWindowA
+#endif
+#else
+#define WIN_FindWindow FindWindow
+#endif
+
+// keine Yield-Definition
+#undef Yield
+
+/* new StretchBlt() Modes (simpler names) */
+#ifndef STRETCH_ANDSCANS
+#define STRETCH_ANDSCANS 1
+#endif
+#ifndef STRETCH_ORSCANS
+#define STRETCH_ORSCANS 2
+#endif
+#ifndef STRETCH_DELETESCANS
+#define STRETCH_DELETESCANS 3
+#endif
+
+#ifdef WNT
+extern "C"
+{
+WIN_BOOL WINAPI WIN_Rectangle( HDC hDC, int X1, int Y1, int X2, int Y2 );
+WIN_BOOL WINAPI WIN_Polygon( HDC hDC, CONST POINT * ppt, int ncnt );
+WIN_BOOL WINAPI WIN_PolyPolygon( HDC hDC, CONST POINT * ppt, LPINT npcnt, int ncnt );
+}
+#endif
+
+// svwin.h nicht mehr includen
+#define _SVWIN_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/postx.h b/tools/inc/tools/postx.h
new file mode 100644
index 000000000000..c7199876fc02
--- /dev/null
+++ b/tools/inc/tools/postx.h
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _POSTX_H
+#define _POSTX_H
+
+#if defined __cplusplus
+}
+#endif
+
+/* X-Types */
+#undef Window
+#undef BYTE
+#undef INT8
+#undef INT64
+#undef BOOL
+#undef Font
+#undef Cursor
+#undef String
+#undef KeyCode
+#undef Region
+#undef Icon
+#undef Time
+#undef Boolean
+
+#undef Min
+#undef Max
+#undef DestroyAll
+#undef Success
+
+#undef Printer
+/* #undef FontInfo */
+#undef Orientation
+
+#undef GetToken
+#undef ReleaseToken
+#undef InitializeToken
+#undef NextRequest
+
+#ifdef KeyPress
+#if KeyPress != 2
+Error KeyPress must be Equal 2
+#endif
+#undef KeyPress
+#endif
+#define XLIB_KeyPress 2
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/presys.h b/tools/inc/tools/presys.h
new file mode 100644
index 000000000000..8d27515fb83f
--- /dev/null
+++ b/tools/inc/tools/presys.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/* nicht geschuetzt, darf nur einmal includet werden */
+
+// Konflíkt mit den Tools-Pair vermeiden
+#define Pair StlPair
+
+#if defined WNT
+
+#define BOOL WIN_BOOL
+#define BYTE WIN_BYTE
+
+#define Rectangle BLA_Rectangle
+#define Polygon BLA_Polygon
+#define PolyPolygon BLA_PolyPolygon
+#define Region WIN_Region
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/prewin.h b/tools/inc/tools/prewin.h
new file mode 100644
index 000000000000..b73e93fa3342
--- /dev/null
+++ b/tools/inc/tools/prewin.h
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/* nicht geschuetzt, darf nur einmal includet werden */
+
+#if defined WNT
+
+#define BOOL WIN_BOOL
+#define BYTE WIN_BYTE
+#ifndef VCL_NEED_BASETSD
+#define INT64 WIN_INT64
+#define UINT64 WIN_UINT64
+#define INT32 WIN_INT32
+#define UINT32 WIN_UINT32
+#endif
+
+#define Rectangle BLA_Rectangle
+#define Polygon BLA_Polygon
+#define PolyPolygon BLA_PolyPolygon
+#define Region WIN_Region
+#define Folder WIN_Folder
+#define GradientStyle_RECT WIN_GradientStyle_RECT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define STRICT
+#ifdef _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+#include <shellapi.h>
+#include <commdlg.h>
+#include <dlgs.h>
+#ifdef USE_TOOLHELP
+#include <tlhelp32.h>
+#endif
+#ifdef USE_IMAGEHLP
+#include <imagehlp.h>
+#endif
+#ifdef INCLUDE_MMSYSTEM
+#include <mmsystem.h>
+#endif
+#ifdef _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <commctrl.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/prex.h b/tools/inc/tools/prex.h
new file mode 100644
index 000000000000..3cc8f32ae09d
--- /dev/null
+++ b/tools/inc/tools/prex.h
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _PREX_H
+#define _PREX_H
+
+#define Window XLIB_Window
+#define BYTE XLIB_BYTE
+#define INT8 XLIB_INT8
+#define INT64 XLIB_INT64
+#define BOOL XLIB_BOOL
+#define Font XLIB_Font
+#define Cursor XLIB_Cursor
+#define String XLIB_String
+#define KeyCode XLIB_KeyCode
+#define Region XLIB_Region
+#define Icon XLIB_Icon
+#define Time XLIB_Time
+#define Region XLIB_Region
+#define Boolean XLIB_Boolean
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+#if defined(LINUX) || defined(FREEBSD) || defined(MACOSX) || defined(NETBSD) || defined(OPENBSD) // should really check for xfree86 or for X11R6.1 and higher
+#define __XKeyboardExtension__ 1
+#else
+#define __XKeyboardExtension__ 0
+#endif
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/StringDefs.h>
+#include <X11/extensions/Xrender.h>
+#if __XKeyboardExtension__
+#include <X11/XKBlib.h>
+#endif
+typedef unsigned long Pixel;
+
+#undef DestroyAll
+#define DestroyAll XLIB_DestroyAll
+#define XLIB_DestroyAll 0
+#undef String
+#define String XLIB_String
+
+#undef KeyCode
+#define KeyCode XLIB_KeyCode //undef in intrinsics
+
+#define __Ol_OlXlibExt_h__
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/pstm.hxx b/tools/inc/tools/pstm.hxx
new file mode 100644
index 000000000000..1530474170cc
--- /dev/null
+++ b/tools/inc/tools/pstm.hxx
@@ -0,0 +1,265 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _PSTM_HXX
+#define _PSTM_HXX
+
+#include <hash_map>
+#include "tools/toolsdllapi.h"
+
+#include <tools/table.hxx>
+
+#include <tools/unqidx.hxx>
+#include <tools/ref.hxx>
+#include <tools/rtti.hxx>
+#include <tools/stream.hxx>
+
+#define ERRCODE_IO_NOFACTORY ERRCODE_IO_WRONGFORMAT
+
+/*************************************************************************
+*************************************************************************/
+class SvPersistBase;
+typedef void * (*SvCreateInstancePersist)( SvPersistBase ** );
+#define SV_CLASS_REGISTER( Class ) \
+ Register( Class::StaticClassId(), Class::CreateInstance )
+
+class TOOLS_DLLPUBLIC SvClassManager
+{
+ typedef std::hash_map< USHORT, SvCreateInstancePersist > Map;
+ Map aAssocTable;
+public:
+ void Register( USHORT nClassId, SvCreateInstancePersist pFunc );
+ SvCreateInstancePersist Get( USHORT nClassId );
+};
+
+/************************** S v R t t i B a s e **************************/
+/*
+#if defined (DOS) && defined (STC)
+#ifdef WIN
+#error Fuer Win muss der Kram virtual sein (MM/MH)
+#endif
+class SvRttiBase : public SvRefBase
+#else
+class SvRttiBase : virtual public SvRefBase
+#endif
+*/
+class TOOLS_DLLPUBLIC SvRttiBase : public SvRefBase
+{
+public:
+ TYPEINFO();
+};
+SV_DECL_IMPL_REF(SvRttiBase)
+
+/*************************************************************************/
+#define SV_DECL_PERSIST( Class, CLASS_ID ) \
+ TYPEINFO(); \
+ static USHORT StaticClassId() { return CLASS_ID; } \
+ static void * CreateInstance( SvPersistBase ** ppBase ); \
+ friend SvPersistStream& operator >> ( SvPersistStream & rStm, \
+ Class *& rpObj); \
+ virtual USHORT GetClassId() const; \
+ virtual void Load( SvPersistStream & ); \
+ virtual void Save( SvPersistStream & );
+
+#define SV_DECL_PERSIST1( Class, Super1, CLASS_ID ) \
+ SV_DECL_PERSIST( Class, CLASS_ID )
+
+#define PRV_SV_IMPL_PERSIST( Class ) \
+ void * Class::CreateInstance( SvPersistBase ** ppBase )\
+ { \
+ Class * p = new Class(); \
+ *ppBase = p; \
+ return p; \
+ } \
+ USHORT Class::GetClassId() const \
+ { return StaticClassId(); } \
+ SvPersistStream& operator >> (SvPersistStream & rStm, Class *& rpObj)\
+ { \
+ SvPersistBase * pObj; \
+ rStm >> pObj; \
+ rpObj = PTR_CAST( Class, pObj ); \
+ return rStm; \
+ }
+
+#define SV_IMPL_PERSIST( Class ) \
+ TYPEINIT0( Class ) \
+ PRV_SV_IMPL_PERSIST( Class )
+
+#define SV_IMPL_PERSIST1( Class, Super1 ) \
+ TYPEINIT1( Class, Super1 ) \
+ PRV_SV_IMPL_PERSIST( Class )
+
+/*************************************************************************/
+class SvPersistStream;
+class SvPersistBase : public SvRttiBase
+{
+public:
+ virtual USHORT GetClassId() const = 0;
+ virtual void Load( SvPersistStream & ) = 0;
+ virtual void Save( SvPersistStream & ) = 0;
+ TOOLS_DLLPUBLIC friend SvPersistStream& operator >> ( SvPersistStream & rStm,
+ SvPersistBase *& rpObj );
+};
+SV_DECL_IMPL_REF(SvPersistBase)
+
+/*************************************************************************/
+// Damit die Liste, anders benannt wird
+typedef SvPersistBase SuperSvPersistBase;
+SV_DECL_REF_LIST_VISIBILITY(SuperSvPersistBase,SuperSvPersistBase*,TOOLS_DLLPUBLIC)
+SV_IMPL_REF_LIST(SuperSvPersistBase,SuperSvPersistBase*)
+
+class TOOLS_DLLPUBLIC SvPersistBaseMemberList : public SuperSvPersistBaseMemberList
+{
+public:
+ SvPersistBaseMemberList();
+ SvPersistBaseMemberList(USHORT nInitSz, USHORT nResize );
+
+ void WriteObjects( SvPersistStream &, BOOL bOnlyStreamedObj = FALSE ) const;
+ TOOLS_DLLPUBLIC friend SvPersistStream& operator << (SvPersistStream &, const SvPersistBaseMemberList &);
+ TOOLS_DLLPUBLIC friend SvPersistStream& operator >> (SvPersistStream &, SvPersistBaseMemberList &);
+};
+
+/*************************************************************************/
+#define SV_DECL_PERSIST_LIST(ClassName,EntryName)\
+class ClassName##MemberList : public SvPersistBaseMemberList\
+{\
+public:\
+ PRV_SV_DECL_MEMBER_LIST(ClassName,EntryName)\
+};
+
+#define SV_IMPL_PERSIST_LIST(ClassName,EntryName)\
+ PRV_SV_IMPL_MEMBER_LIST(ClassName,EntryName,SvPersistBaseMemberList)
+
+#define SV_DECL_IMPL_PERSIST_LIST(ClassName,EntryName)\
+SV_DECL_PERSIST_LIST(ClassName,EntryName)\
+SV_IMPL_PERSIST_LIST(ClassName,EntryName)
+
+DECLARE_UNIQUEINDEX( SvPersistUIdx,SvPersistBase *)
+
+//=========================================================================
+class SvStream;
+class TOOLS_DLLPUBLIC SvPersistStream : public SvStream
+/* [Beschreibung]
+
+ Mit dieser Klasse k"onnen Laufzeit Objektstrukturen gespeichert
+ und geladen werden. Es m"ussen immer alle beteiligten Objekte
+ gespeichert oder geladen werden. Um die Objekte automatisch
+ laden zu k"onnen, wird eine Factory f"ur jede Klasse von Objekten,
+ die im Stream vorkommen k"onnen, ben"otigt. Die Liste aller Klassen
+ wird in einem <SvClassManager> Objekt gespeichert und dem
+ SvPersistStream "ubergeben, wenn er erzeugt wird.
+ Weiterhin wird die M"oglichkeit geboten UINT32 Werte komprimiert
+ zu schreiben und zu lesen (<SvPersistStream::WriteCompressed>,
+ <SvPersistStream::ReadCompressed>).
+ Es gibt auch die drei Hilfsmethoden <SvPersistStream::WriteDummyLen>,
+ <SvPersistStream::WriteLen> und <SvPersistStream::ReadLen> um eine
+ L"ange vor das Objekt zu schreiben.
+
+ [Beispiel]
+
+ Ein konkretes Beispiel ist im Konstruktor beschrieben.
+ Objekt A verweist auf B, dieses auf C und das wieder auf A.
+ C verweist auf D.
+
+ Die Reihenfolge beim Speichern und Laden ist egal, sie muss nur
+ gleich sein:
+ Speichern: Laden:
+ A,B,C,D A,B,C,D richtig
+ B,A,C,D B,A,C,D richtig
+ C,A,B,D A,B,C,D falsch
+ A,B,C,D A,B,C falsch
+
+ [Anmerkung]
+
+ Das Dateiformat zwischen DBG_UTIL und !DBG_UTIL ist unterschiedlich,
+ kann aber von beiden Versionen gelesen werden.
+*/
+{
+ SvClassManager & rClassMgr;
+ SvStream * pStm;
+ Table aPTable; // Pointer und Key gedreht
+ SvPersistUIdx aPUIdx;
+ ULONG nStartIdx;
+ const SvPersistStream * pRefStm;
+ UINT32 nFlags;
+
+ virtual ULONG GetData( void* pData, ULONG nSize );
+ virtual ULONG PutData( const void* pData, ULONG nSize );
+ virtual ULONG SeekPos( ULONG nPos );
+ virtual void FlushData();
+protected:
+ ULONG GetCurMaxIndex( const SvPersistUIdx & ) const;
+ ULONG GetCurMaxIndex() const
+ { return GetCurMaxIndex( aPUIdx ); }
+
+ void WriteObj( BYTE nHdr, SvPersistBase * pObj );
+ UINT32 ReadObj( SvPersistBase * & rpObj,
+ BOOL bRegister );
+public:
+ BOOL IsStreamed( SvPersistBase * pObj ) const
+ { return 0 != GetIndex( pObj ); }
+ virtual void ResetError();
+
+ SvPersistStream( SvClassManager &, SvStream * pStream,
+ UINT32 nStartIdx = 1 );
+ SvPersistStream( SvClassManager &, SvStream * pStream,
+ const SvPersistStream & rPersStm );
+ ~SvPersistStream();
+
+ void SetStream( SvStream * pStream );
+ SvStream * GetStream() const { return pStm; }
+ virtual USHORT IsA() const;
+
+ SvPersistBase * GetObject( ULONG nIdx ) const;
+ ULONG GetIndex( SvPersistBase * ) const;
+
+ void SetContextFlags( UINT32 n ) { nFlags = n; }
+ UINT32 GetContextFlags() const { return nFlags; }
+
+ static void WriteCompressed( SvStream & rStm, UINT32 nVal );
+ static UINT32 ReadCompressed( SvStream & rStm );
+
+ UINT32 WriteDummyLen();
+ void WriteLen( UINT32 nLenPos );
+ UINT32 ReadLen( UINT32 * pTestPos );
+
+ SvPersistStream& WritePointer( SvPersistBase * pObj );
+ SvPersistStream& ReadPointer( SvPersistBase * & rpObj );
+ TOOLS_DLLPUBLIC friend SvPersistStream& operator << (SvPersistStream &, SvPersistBase *);
+ TOOLS_DLLPUBLIC friend SvPersistStream& operator >> (SvPersistStream &, SvPersistBase * &);
+
+ // Objekte halten ihre Id's w"ahrend geladen und
+ // gespeichert werden.
+ friend SvStream& operator >> ( SvStream &, SvPersistStream & );
+ friend SvStream& operator << ( SvStream &, SvPersistStream & );
+ ULONG InsertObj( SvPersistBase * );
+ ULONG RemoveObj( SvPersistBase * );
+};
+
+#endif // _PSTM_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/queue.hxx b/tools/inc/tools/queue.hxx
new file mode 100644
index 000000000000..d5a6ff15730f
--- /dev/null
+++ b/tools/inc/tools/queue.hxx
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _QUEUE_HXX
+#define _QUEUE_HXX
+
+#include <tools/solar.h>
+#include <tools/contnr.hxx>
+
+// ---------
+// - Queue -
+// ---------
+
+#define QUEUE_ENTRY_NOTFOUND CONTAINER_ENTRY_NOTFOUND
+
+class Queue : private Container
+{
+public:
+ using Container::Clear;
+ using Container::Count;
+ using Container::GetObject;
+ using Container::GetPos;
+
+ Queue( USHORT _nInitSize = 16, USHORT _nReSize = 16 ) :
+ Container( _nReSize, _nInitSize, _nReSize ) {}
+ Queue( const Queue& rQueue ) : Container( rQueue ) {}
+
+ void Put( void* p ) { Container::Insert( p, CONTAINER_APPEND ); }
+ void* Get() { return Container::Remove( (ULONG)0 ); }
+
+ Queue& operator =( const Queue& rQueue )
+ { Container::operator =( rQueue ); return *this; }
+
+ BOOL operator ==( const Queue& rQueue ) const
+ { return Container::operator ==( rQueue ); }
+ BOOL operator !=( const Queue& rQueue ) const
+ { return Container::operator !=( rQueue ); }
+};
+
+// -----------------
+// - DECLARE_QUEUE -
+// -----------------
+
+#define DECLARE_QUEUE( ClassName, Type ) \
+class ClassName : private Queue \
+{ \
+public: \
+ using Queue::Clear; \
+ using Queue::Count; \
+ \
+ ClassName( USHORT _nInitSize = 16, \
+ USHORT _nReSize = 16 ) : \
+ Queue( _nInitSize, _nReSize ) {} \
+ ClassName( const ClassName& rClassName ) : \
+ Queue( rClassName ) {} \
+ \
+ void Put( Type p ) { Queue::Put( (void*)p ); } \
+ Type Get() { return (Type)Queue::Get(); } \
+ \
+ Type GetObject( ULONG nIndex ) const \
+ { return (Type)Queue::GetObject( nIndex ); } \
+ ULONG GetPos( const Type p ) const \
+ { return Queue::GetPos( (const void*)p ); } \
+ ULONG GetPos( const Type p, ULONG nStartIndex, \
+ BOOL bForward = TRUE ) const \
+ { return Queue::GetPos( (const void*)p, \
+ nStartIndex, \
+ bForward ); } \
+ \
+ ClassName& operator =( const ClassName& rClassName ) \
+ { Queue::operator =( rClassName ); \
+ return *this; } \
+ \
+ BOOL operator ==( const Queue& rQueue ) const \
+ { return Queue::operator ==( rQueue ); } \
+ BOOL operator !=( const Queue& rQueue ) const \
+ { return Queue::operator !=( rQueue ); } \
+};
+
+#endif // _QUEUE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/rc.h b/tools/inc/tools/rc.h
new file mode 100644
index 000000000000..de7d4f81b735
--- /dev/null
+++ b/tools/inc/tools/rc.h
@@ -0,0 +1,223 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _TOOLS_RC_H
+#define _TOOLS_RC_H
+
+#include <tools/rcid.h>
+
+// Definition der Struktur die alle "Window"-Resourcen haben
+// Hier sind die Fensterstyles definiert die nicht in WinBits sind
+#define RSC_EXTRAMAPUNIT 0xFFFF //Wert nicht veraendern!!!
+
+typedef short RSWND_STYLE;
+#define RSWND_DISABLED 0x01
+#define RSWND_CLIENTSIZE 0x02
+
+#define WINDOW_XYMAPMODE 0x0001
+#define WINDOW_X 0x0002
+#define WINDOW_Y 0x0004
+#define WINDOW_WHMAPMODE 0x0008
+#define WINDOW_WIDTH 0x0010
+#define WINDOW_HEIGHT 0x0020
+#define WINDOW_TEXT 0x0080
+#define WINDOW_HELPTEXT 0x0100
+#define WINDOW_QUICKTEXT 0x0200
+#define WINDOW_EXTRALONG 0x0800
+#define WINDOW_UNIQUEID 0x1000
+#define WINDOW_BORDER_STYLE 0x2000
+
+// Definition der Struktur die alle "WorkWindow"-Resourcen haben
+#define WORKWIN_SHOWNORMAL 0
+#define WORKWIN_SHOWMINIMIZED 1
+#define WORKWIN_SHOWMAXIMIZED 2
+
+// Definition der Struktur der FixedBitmap-Resource.
+#define RSC_FIXEDBITMAP_BITMAP 0x0001
+
+// Definition der Struktur der FixedImage-Resource.
+#define RSC_FIXEDIMAGE_IMAGE 0x0001
+
+// Definition der Struktur des MenuButtons
+#define RSCMENUBUTTON_MENU 0x01
+
+// Definition der Struktur die alle Menu-Resourcen haben
+#define RSC_MENU_ITEMS 0x01
+#define RSC_MENU_TEXT 0x02
+#define RSC_MENU_DEFAULTITEMID 0x04
+
+// Hier sind die MenuItem-Resourceoptionen definiert
+#define RSC_MENUITEM_SEPARATOR 0x001
+#define RSC_MENUITEM_ID 0x002
+#define RSC_MENUITEM_STATUS 0x004
+#define RSC_MENUITEM_TEXT 0x008
+#define RSC_MENUITEM_BITMAP 0x010
+#define RSC_MENUITEM_HELPTEXT 0x020
+#define RSC_MENUITEM_HELPID 0x040
+#define RSC_MENUITEM_KEYCODE 0x080
+#define RSC_MENUITEM_MENU 0x100
+#define RSC_MENUITEM_CHECKED 0x200
+#define RSC_MENUITEM_DISABLE 0x400
+#define RSC_MENUITEM_COMMAND 0x800
+
+// Hier sind die AccelKey-Resourceoptionen definiert
+#define ACCELITEM_ACCEL 0x01
+#define ACCELITEM_KEY 0x02
+
+// Definition der Struktur die alle "Field"-Resourcen haben
+#define PATTERNFORMATTER_STRICTFORMAT 0x01
+#define PATTERNFORMATTER_EDITMASK 0x02
+#define PATTERNFORMATTER_LITTERALMASK 0x04
+
+#define NUMERICFORMATTER_MIN 0x01
+#define NUMERICFORMATTER_MAX 0x02
+#define NUMERICFORMATTER_STRICTFORMAT 0x04
+//#define NUMERICFORMATTER_I12 0x08 // erAck: got rid of class International (2005-06-17)
+#define NUMERICFORMATTER_DECIMALDIGITS 0x10
+#define NUMERICFORMATTER_VALUE 0x20
+#define NUMERICFORMATTER_NOTHOUSANDSEP 0x40
+
+#define METRICFORMATTER_UNIT 0x01
+#define METRICFORMATTER_CUSTOMUNITTEXT 0x02
+
+#define DATEFORMATTER_MIN 0x01
+#define DATEFORMATTER_MAX 0x02
+#define DATEFORMATTER_LONGFORMAT 0x04
+#define DATEFORMATTER_STRICTFORMAT 0x08
+//#define DATEFORMATTER_I12 0x10 // erAck: got rid of class International (2005-06-17)
+#define DATEFORMATTER_VALUE 0x20
+
+#define TIMEFORMATTER_MIN 0x01
+#define TIMEFORMATTER_MAX 0x02
+#define TIMEFORMATTER_TIMEFIELDFORMAT 0x04
+#define TIMEFORMATTER_DURATION 0x08
+#define TIMEFORMATTER_STRICTFORMAT 0x10
+//#define TIMEFORMATTER_I12 0x20 // erAck: got rid of class International (2005-06-17)
+#define TIMEFORMATTER_VALUE 0x40
+
+#define NUMERICFIELD_FIRST 0x01
+#define NUMERICFIELD_LAST 0x02
+#define NUMERICFIELD_SPINSIZE 0x04
+
+#define METRICFIELD_FIRST 0x01
+#define METRICFIELD_LAST 0x02
+#define METRICFIELD_SPINSIZE 0x04
+
+#define CURRENCYFIELD_FIRST 0x01
+#define CURRENCYFIELD_LAST 0x02
+#define CURRENCYFIELD_SPINSIZE 0x04
+
+#define DATEFIELD_FIRST 0x01
+#define DATEFIELD_LAST 0x02
+
+#define TIMEFIELD_FIRST 0x01
+#define TIMEFIELD_LAST 0x02
+
+// Definition der Struktur die alle "ToolBoxItem"-Resourcen haben
+#define RSC_TOOLBOXITEM_ID 0x0001
+#define RSC_TOOLBOXITEM_TYPE 0x0002
+#define RSC_TOOLBOXITEM_STATUS 0x0004
+#define RSC_TOOLBOXITEM_HELPID 0x0008
+#define RSC_TOOLBOXITEM_TEXT 0x0010
+#define RSC_TOOLBOXITEM_HELPTEXT 0x0020
+#define RSC_TOOLBOXITEM_BITMAP 0x0040
+#define RSC_TOOLBOXITEM_IMAGE 0x0080
+#define RSC_TOOLBOXITEM_DISABLE 0x0100
+#define RSC_TOOLBOXITEM_STATE 0x0200
+#define RSC_TOOLBOXITEM_HIDE 0x0400
+#define RSC_TOOLBOXITEM_COMMAND 0x0800
+#define RSC_TOOLBOXITEM_MENUSTRINGS 0x1000
+
+// Definition der Struktur die alle ToolBox-Resourcen haben
+#define RSC_TOOLBOX_BUTTONTYPE 0x01
+#define RSC_TOOLBOX_ALIGN 0x02
+#define RSC_TOOLBOX_LINECOUNT 0x04
+#define RSC_TOOLBOX_FLOATLINES 0x08
+#define RSC_TOOLBOX_CUSTOMIZE 0x10
+#define RSC_TOOLBOX_MENUSTRINGS 0x20
+#define RSC_TOOLBOX_ITEMIMAGELIST 0x40
+#define RSC_TOOLBOX_ITEMLIST 0x80
+
+// Definition der Struktur die alle MoreButton-Resourcen haben
+#define RSC_MOREBUTTON_STATE 0x01
+#define RSC_MOREBUTTON_MAPUNIT 0x02
+#define RSC_MOREBUTTON_DELTA 0x04
+
+// Definition der Struktur die alle FloatingWindow-Resourcen haben
+#define RSC_FLOATINGWINDOW_WHMAPMODE 0x01
+#define RSC_FLOATINGWINDOW_WIDTH 0x02
+#define RSC_FLOATINGWINDOW_HEIGHT 0x04
+#define RSC_FLOATINGWINDOW_ZOOMIN 0x08
+
+// Definition der Struktur die alle DockingWindow-Resourcen haben
+#define RSC_DOCKINGWINDOW_XYMAPMODE 0x01
+#define RSC_DOCKINGWINDOW_X 0x02
+#define RSC_DOCKINGWINDOW_Y 0x04
+#define RSC_DOCKINGWINDOW_FLOATING 0x08
+
+// Definition der Struktur die alle "TabControlItem"-Resourcen haben
+#define RSC_TABCONTROLITEM_ID 0x0001
+#define RSC_TABCONTROLITEM_TEXT 0x0002
+#define RSC_TABCONTROLITEM_PAGERESID 0x0008
+
+// Definition der Struktur die alle TabControl-Resourcen haben
+#define RSC_TABCONTROL_ITEMLIST 0x01
+
+// Definition der Struktur des ImageButtons
+#define RSC_IMAGEBUTTON_IMAGE 0x01
+#define RSC_IMAGEBUTTON_SYMBOL 0x02
+#define RSC_IMAGEBUTTON_STATE 0x04
+
+// Definition der Struktur des ImageRadioButtons
+#define RSC_IMAGERADIOBUTTON_IMAGE 0x01
+
+// Definition der Struktur des Image
+#define RSC_IMAGE_IMAGEBITMAP 0x01
+#define RSC_IMAGE_MASKBITMAP 0x02
+#define RSC_IMAGE_MASKCOLOR 0x04
+
+// Definition der Struktur des Image
+#define RSC_IMAGELIST_IMAGEBITMAP 0x01
+#define RSC_IMAGELIST_MASKBITMAP 0x02
+#define RSC_IMAGELIST_MASKCOLOR 0x04
+#define RSC_IMAGELIST_IDLIST 0x08
+#define RSC_IMAGELIST_IDCOUNT 0x10
+
+// obsolete, should be removed by MM
+#define RSC_COLOR (RSC_NOTYPE + 0x16)
+#define TIME_HOUR 0x01
+#define TIME_MINUTE 0x02
+#define TIME_SECOND 0x04
+#define TIME_SEC100 0x08
+#define DATE_YEAR 0x01
+#define DATE_MONTH 0x02
+#define DATE_DAY 0x04
+
+#endif // _TOOLS_RC_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/rc.hxx b/tools/inc/tools/rc.hxx
new file mode 100644
index 000000000000..9a6afceedf6c
--- /dev/null
+++ b/tools/inc/tools/rc.hxx
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _TOOLS_RC_HXX
+#define _TOOLS_RC_HXX
+
+#include "tools/toolsdllapi.h"
+#include <i18npool/lang.h>
+#include <tools/string.hxx>
+#include <tools/resmgr.hxx>
+
+// ------------
+// - Resource -
+// ------------
+
+class TOOLS_DLLPUBLIC Resource
+{
+ protected:
+ ResMgr* m_pResMgr;
+
+ // check availability of Resource
+ BOOL IsAvailableRes( const ResId& rId ) const
+ { return m_pResMgr->IsAvailable( rId, this ); }
+
+ // Load a Resource
+ void GetRes( const ResId& rResId );
+
+ // check Resource state
+ void TestRes();
+
+ // Get a pointer to the Resource's data
+ void* GetClassRes()
+ { return m_pResMgr->GetClass(); }
+
+ // read a string from the resource
+ static sal_uInt32 GetStringRes( UniString& rStr, const BYTE* pStr )
+ { return ResMgr::GetString( rStr, pStr ); }
+
+ // increase the memory pointer gotten by GetClassRes()
+ void* IncrementRes( sal_uInt32 nBytes )
+ { return m_pResMgr->Increment( nBytes ); }
+
+ // return the memory size of a Resource data block
+ static sal_uInt32 GetObjSizeRes( RSHEADER_TYPE * pHT )
+ { return ResMgr::GetObjSize( pHT ); }
+
+ // return the remaining size of this Resource's data
+ sal_uInt32 GetRemainSizeRes()
+ { return m_pResMgr->GetRemainSize(); }
+
+ // get a 32bit value from Resource data
+ static sal_Int32 GetLongRes( void * pLong )
+ { return ResMgr::GetLong( pLong ); }
+ // get a 16bit value from Resource data
+ static sal_Int16 GetShortRes( void * pShort )
+ { return ResMgr::GetShort( pShort ); }
+
+ // read a 32bit value from resource data and increment pointer
+ sal_Int32 ReadLongRes()
+ { return m_pResMgr->ReadLong(); }
+ // read a 16bit value from resource data and increment pointer
+ sal_Int16 ReadShortRes()
+ { return m_pResMgr->ReadShort(); }
+ // read a string from resource data and increment pointer
+ UniString ReadStringRes()
+ { return m_pResMgr->ReadString(); }
+
+ // Gibt die Resource frei (this-Zeiger fuer Fehlerueberpruefung)
+ // free the resource from m_pResMgr's stack (pass this ptr for validation)
+ void FreeResource()
+ { m_pResMgr->PopContext( this ); }
+
+ // constructors
+ Resource() : m_pResMgr( NULL ) {}
+ Resource( const ResId& rResId );
+
+ public:
+ #ifdef DBG_UTIL
+ ~Resource() { TestRes(); }
+ #else
+ ~Resource() {}
+ #endif
+};
+
+#endif // _SV_RC_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/rcid.h b/tools/inc/tools/rcid.h
new file mode 100644
index 000000000000..d34315d810b2
--- /dev/null
+++ b/tools/inc/tools/rcid.h
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _TOOLS_RCID_H
+#define _TOOLS_RCID_H
+
+#include <tools/resid.hxx>
+
+// Definition der Versionsnummer
+#define RSCVERSION_ID 200U
+// Definition eines ungueltige Identifiers.
+#define RC_NO_ID (sal_uInt32(0xFFFFFFFF))
+
+// Dies sind die Resourcetypen
+// Mindestens 0x100 wegen MS-Windows Resourcetypen
+//#define RSC_NOTYPE 0x100
+//RSC_NOTYPE wird in resid.hxx definiert
+#define RSC_BYNAME (RSC_NOTYPE + 0x01)
+#define RSC_VERSIONCONTROL (RSC_NOTYPE + 0x02) // Versionskontrolle
+
+#define RSC_RESOURCE (RSC_NOTYPE + 0x10)
+#define RSC_STRING (RSC_NOTYPE + 0x11)
+#define RSC_BITMAP (RSC_NOTYPE + 0x13)
+#define RSC_ACCEL (RSC_NOTYPE + 0x1a)
+#define RSC_ACCELITEM (RSC_NOTYPE + 0x1b)// nur intern
+#define RSC_MENU (RSC_NOTYPE + 0x1c)
+#define RSC_MENUITEM (RSC_NOTYPE + 0x1d)// nur intern
+#define RSC_KEYCODE (RSC_NOTYPE + 0x1f)
+#define RSC_TIME (RSC_NOTYPE + 0x20)
+#define RSC_DATE (RSC_NOTYPE + 0x21)
+//#define RSC_INTERNATIONAL (RSC_NOTYPE + 0x22) // erAck: got rid of class International (2005-06-17)
+#define RSC_IMAGE (RSC_NOTYPE + 0x23)
+#define RSC_IMAGELIST (RSC_NOTYPE + 0x24)
+
+#define RSC_MESSBOX (RSC_NOTYPE + 0x30)
+#define RSC_INFOBOX (RSC_NOTYPE + 0x31)
+#define RSC_WARNINGBOX (RSC_NOTYPE + 0x32)
+#define RSC_ERRORBOX (RSC_NOTYPE + 0x33)
+#define RSC_QUERYBOX (RSC_NOTYPE + 0x34)
+#define RSC_WINDOW (RSC_NOTYPE + 0x35)
+#define RSC_SYSWINDOW (RSC_NOTYPE + 0x36)
+#define RSC_WORKWIN (RSC_NOTYPE + 0x37)
+#define RSC_MDIWINDOW (RSC_NOTYPE + 0x38)
+#define RSC_FLOATINGWINDOW (RSC_NOTYPE + 0x39)
+#define RSC_DIALOG (RSC_NOTYPE + 0x3a)
+#define RSC_MODELESSDIALOG (RSC_NOTYPE + 0x3b)
+#define RSC_MODALDIALOG (RSC_NOTYPE + 0x3c)
+#define RSC_CONTROL (RSC_NOTYPE + 0x44)
+#define RSC_BUTTON (RSC_NOTYPE + 0x45)
+#define RSC_PUSHBUTTON (RSC_NOTYPE + 0x46)
+#define RSC_OKBUTTON (RSC_NOTYPE + 0x47)
+#define RSC_CANCELBUTTON (RSC_NOTYPE + 0x48)
+#define RSC_HELPBUTTON (RSC_NOTYPE + 0x49)
+#define RSC_IMAGEBUTTON (RSC_NOTYPE + 0x4a)
+#define RSC_MENUBUTTON (RSC_NOTYPE + 0x4b)
+#define RSC_MOREBUTTON (RSC_NOTYPE + 0x4c)
+#define RSC_SPINBUTTON (RSC_NOTYPE + 0x4d)
+#define RSC_RADIOBUTTON (RSC_NOTYPE + 0x4e)
+#define RSC_IMAGERADIOBUTTON (RSC_NOTYPE + 0x4f)
+#define RSC_CHECKBOX (RSC_NOTYPE + 0x50)
+#define RSC_TRISTATEBOX (RSC_NOTYPE + 0x51)
+#define RSC_EDIT (RSC_NOTYPE + 0x52)
+#define RSC_MULTILINEEDIT (RSC_NOTYPE + 0x53)
+#define RSC_COMBOBOX (RSC_NOTYPE + 0x54)
+#define RSC_LISTBOX (RSC_NOTYPE + 0x55)
+#define RSC_MULTILISTBOX (RSC_NOTYPE + 0x56)
+#define RSC_TEXT (RSC_NOTYPE + 0x57)
+#define RSC_FIXEDLINE (RSC_NOTYPE + 0x58)
+#define RSC_FIXEDBITMAP (RSC_NOTYPE + 0x59)
+#define RSC_FIXEDIMAGE (RSC_NOTYPE + 0x5a)
+#define RSC_GROUPBOX (RSC_NOTYPE + 0x5c)
+#define RSC_SCROLLBAR (RSC_NOTYPE + 0x5d)
+#define RSC_SCROLLBARBOX (RSC_NOTYPE + 0x5e)
+#define RSC_SPLITTER (RSC_NOTYPE + 0x5f)
+#define RSC_SPLITWINDOW (RSC_NOTYPE + 0x60)
+#define RSC_SPINFIELD (RSC_NOTYPE + 0x61)
+#define RSC_PATTERNFIELD (RSC_NOTYPE + 0x62)
+#define RSC_NUMERICFIELD (RSC_NOTYPE + 0x63)
+#define RSC_METRICFIELD (RSC_NOTYPE + 0x64)
+#define RSC_CURRENCYFIELD (RSC_NOTYPE + 0x65)
+#define RSC_DATEFIELD (RSC_NOTYPE + 0x66)
+#define RSC_TIMEFIELD (RSC_NOTYPE + 0x67)
+#define RSC_PATTERNBOX (RSC_NOTYPE + 0x68)
+#define RSC_NUMERICBOX (RSC_NOTYPE + 0x69)
+#define RSC_METRICBOX (RSC_NOTYPE + 0x6a)
+#define RSC_CURRENCYBOX (RSC_NOTYPE + 0x6b)
+#define RSC_DATEBOX (RSC_NOTYPE + 0x6c)
+#define RSC_TIMEBOX (RSC_NOTYPE + 0x6d)
+#define RSC_LONGCURRENCYFIELD (RSC_NOTYPE + 0x6e)
+#define RSC_LONGCURRENCYBOX (RSC_NOTYPE + 0x6f)
+#define RSC_TOOLBOXITEM (RSC_NOTYPE + 0x70)
+#define RSC_TOOLBOX (RSC_NOTYPE + 0x71)
+#define RSC_DOCKINGWINDOW (RSC_NOTYPE + 0x72)
+#define RSC_STATUSBAR (RSC_NOTYPE + 0x73)
+#define RSC_TABPAGE (RSC_NOTYPE + 0x74)
+#define RSC_TABCONTROL (RSC_NOTYPE + 0x75)
+#define RSC_TABDIALOG (RSC_NOTYPE + 0x76)
+#define RSC_TABCONTROLITEM (RSC_NOTYPE + 0x77)
+#define RSC_TREELISTBOX (RSC_NOTYPE + 0x78)
+#define RSC_STRINGARRAY (RSC_NOTYPE + 0x79)
+
+// (RSC_NOTYPE + 0x200) - (RSC_NOTYPE + 0x300) fuer Sfx reserviert
+
+#define RT_SYS_BITMAP (RSC_NOTYPE + 0xf2)
+#define RT_SYS_STRING (RSC_NOTYPE + 0xf3) // Sonderbehandlung
+#define RT_SYS_FILE (RSC_NOTYPE + 0xf4) // nicht implementiert
+
+// (RSC_NOTYPE + 0x200) - (RSC_NOTYPE + 0x300) fuer Sfx reserviert
+
+#endif // _RCID_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/ref.hxx b/tools/inc/tools/ref.hxx
new file mode 100644
index 000000000000..cf7dc26fdb25
--- /dev/null
+++ b/tools/inc/tools/ref.hxx
@@ -0,0 +1,457 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _REF_HXX
+#define _REF_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/list.hxx>
+#include <tools/link.hxx>
+
+//=========================================================================
+
+#define PRV_SV_DECL_REF_SIGNATURE( ClassName, Ref ) \
+ inline ClassName##Ref() { pObj = 0; } \
+ inline ClassName##Ref( const ClassName##Ref & rObj ); \
+ inline ClassName##Ref( ClassName * pObjP ); \
+ inline void Clear(); \
+ inline ~ClassName##Ref(); \
+ inline ClassName##Ref & operator = ( const ClassName##Ref & rObj ); \
+ inline ClassName##Ref & operator = ( ClassName * pObj ); \
+ inline BOOL Is() const { return pObj != NULL; } \
+ inline ClassName * operator & () const { return pObj; } \
+ inline ClassName * operator -> () const { return pObj; } \
+ inline ClassName & operator * () const { return *pObj; } \
+ inline operator ClassName * () const { return pObj; }
+
+#define PRV_SV_IMPL_REF_COUNTERS( ClassName, Ref, AddRef, AddNextRef, ReleaseRef, Init, pRefbase ) \
+inline ClassName##Ref::ClassName##Ref( const ClassName##Ref & rObj ) \
+ { pObj = rObj.pObj; if( pObj ) { Init pRefbase->AddNextRef; } } \
+inline ClassName##Ref::ClassName##Ref( ClassName * pObjP ) \
+{ pObj = pObjP; if( pObj ) { Init pRefbase->AddRef; } } \
+inline void ClassName##Ref::Clear() \
+{ \
+ if( pObj ) \
+ { \
+ ClassName* const pRefObj = pRefbase; \
+ pObj = 0; \
+ pRefObj->ReleaseRef; \
+ } \
+} \
+inline ClassName##Ref::~ClassName##Ref() \
+{ if( pObj ) { pRefbase->ReleaseRef; } } \
+inline ClassName##Ref & ClassName##Ref:: \
+ operator = ( const ClassName##Ref & rObj ) \
+{ \
+ if( rObj.pObj ) rObj.pRefbase->AddNextRef; \
+ ClassName* const pRefObj = pRefbase; \
+ pObj = rObj.pObj; \
+ Init if( pRefObj ) { pRefObj->ReleaseRef; } \
+ return *this; \
+} \
+inline ClassName##Ref & ClassName##Ref::operator = ( ClassName * pObjP ) \
+{ return *this = ClassName##Ref( pObjP ); }
+
+#define PRV_SV_DECL_REF_LOCK(ClassName, Ref) \
+protected: \
+ ClassName * pObj; \
+public: \
+PRV_SV_DECL_REF_SIGNATURE(ClassName, Ref)
+
+#define PRV_SV_DECL_REF( ClassName ) \
+PRV_SV_DECL_REF_LOCK( ClassName, Ref )
+
+#define PRV_SV_DECL_LOCK( ClassName ) \
+PRV_SV_DECL_REF_LOCK( ClassName, Lock )
+
+#define SV_DECL_REF( ClassName ) \
+class ClassName; \
+class ClassName##Ref \
+{ \
+ PRV_SV_DECL_REF( ClassName ) \
+};
+
+#define SV_DECL_LOCK( ClassName ) \
+class ClassName; \
+class ClassName##Lock \
+{ \
+ PRV_SV_DECL_LOCK( ClassName ) \
+};
+
+#define SV_IMPL_REF( ClassName ) \
+PRV_SV_IMPL_REF_COUNTERS( ClassName, Ref, AddRef(), AddNextRef(),\
+ ReleaseReference(), EMPTYARG, pObj )
+
+#define SV_IMPL_LOCK( ClassName ) \
+PRV_SV_IMPL_REF_COUNTERS( ClassName, Lock, OwnerLock( TRUE ), \
+ OwnerLock( TRUE ), OwnerLock( FALSE ), \
+ EMPTYARG, pObj )
+
+#define SV_DECL_IMPL_REF(ClassName) \
+ SV_DECL_REF(ClassName) \
+ SV_IMPL_REF(ClassName)
+
+#define SV_DECL_IMPL_LOCK( ClassName ) \
+ SV_DECL_LOCK(ClassName) \
+ SV_IMPL_LOCK(ClassName)
+
+
+/************************** S v R e f L i s t ****************************/
+#define PRV_SV_DECL_REF_LIST(CN,EN,vis) \
+DECLARE_LIST(CN##List,EN)\
+class vis CN##MemberList : public CN##List\
+{\
+public:\
+inline CN##MemberList();\
+inline CN##MemberList(USHORT nInitSz, USHORT nResize );\
+inline CN##MemberList( const CN##MemberList & rRef );\
+inline ~CN##MemberList();\
+inline CN##MemberList & operator =\
+ ( const CN##MemberList & rRef );\
+inline void Clear();\
+inline void Insert( EN p )\
+{ CN##List::Insert( p ); p->AddRef();}\
+inline void Insert( EN p, ULONG nIndex )\
+{ CN##List::Insert( p, nIndex ); p->AddRef();}\
+inline void Insert( EN p, EN pOld )\
+{ CN##List::Insert( p, pOld ); p->AddRef();}\
+inline void Append( EN p )\
+{ Insert( p, LIST_APPEND );}\
+inline EN Remove();\
+inline EN Remove( ULONG nIndex );\
+inline EN Remove( EN p );\
+inline EN Replace( EN p );\
+inline EN Replace( EN p, ULONG nIndex );\
+inline EN Replace( EN pNew, EN pOld );\
+inline void Append( const CN##MemberList & );\
+};
+
+#define SV_DECL_REF_LIST(CN,EN) \
+PRV_SV_DECL_REF_LIST(CN,EN,/* empty */)
+#define SV_DECL_REF_LIST_VISIBILITY(CN,EN,vis) \
+PRV_SV_DECL_REF_LIST(CN,EN,vis)
+
+/************************** S v R e f L i s t ****************************/
+#define SV_IMPL_REF_LIST( CN, EN ) \
+inline CN##MemberList::CN##MemberList(){}\
+inline CN##MemberList::CN##MemberList(USHORT nInitSz, USHORT nResize )\
+ : CN##List( nInitSz, nResize ){}\
+inline CN##MemberList::CN##MemberList( const CN##MemberList & rRef ) \
+ : CN##List( rRef ) \
+{\
+ ULONG nOldCount = Count(); \
+ EN pEntry = First(); \
+ while( pEntry ) \
+ { pEntry->AddRef(); pEntry = Next(); } \
+ Seek( nOldCount ); /* auch Curser gleich */ \
+}\
+inline CN##MemberList::~CN##MemberList() { Clear(); } \
+inline CN##MemberList & CN##MemberList::operator = \
+ ( const CN##MemberList & rRef ) \
+{\
+ CN##MemberList & rList = (CN##MemberList &)rRef; \
+ ULONG nOldCount = rList.Count(); \
+ /* Count der Objekte erhoehen */ \
+ EN pEntry = rList.First(); \
+ while( pEntry ) \
+ { pEntry->AddRef(); pEntry = rList.Next(); } \
+ rList.Seek( nOldCount ); /* Curser zurueck */ \
+ /* Liste kopieren */ \
+ Clear(); \
+ CN##List::operator = ( rRef ); \
+ return *this; \
+}\
+inline void CN##MemberList::Clear() \
+{\
+ EN pEntry = Last();\
+ while( NULL != pEntry )\
+ pEntry = Remove();\
+}\
+inline EN CN##MemberList::Remove() \
+{\
+ EN p = CN##List::Remove(); \
+ if( p ) p->ReleaseReference(); return p; \
+}\
+inline EN CN##MemberList::Remove( ULONG nIndex ) \
+{\
+ EN p = CN##List::Remove( nIndex ); \
+ if( p ) p->ReleaseReference(); return p; \
+}\
+inline EN CN##MemberList::Remove( EN p ) \
+{\
+ p = CN##List::Remove( p ); \
+ if( p ) p->ReleaseReference(); return p; \
+}\
+inline EN CN##MemberList::Replace( EN p ) \
+{\
+ p->AddRef(); p = CN##List::Replace( p ); \
+ if( p ) p->ReleaseReference(); return p; \
+}\
+inline EN CN##MemberList::Replace( EN p, ULONG nIndex ) \
+{\
+ p->AddRef(); p = CN##List::Replace( p, nIndex ); \
+ if( p ) p->ReleaseReference(); return p; \
+}\
+inline EN CN##MemberList::Replace( EN pNew, EN pOld ) \
+{\
+ pNew->AddRef(); CN##List::Replace( pNew, pOld ); \
+ if( pOld ) pOld->ReleaseReference(); return pOld; \
+}\
+inline void CN##MemberList::Append( const CN##MemberList & rList )\
+{\
+ for( ULONG i = 0; i < rList.Count(); i++ )\
+ Append( rList.GetObject( i ) );\
+}
+
+/************************** S V _ D E C L _ R E F _ L I S T **************/
+#define SV_DECL_IMPL_REF_LIST(ClassName,EntryName) \
+ SV_DECL_REF_LIST(ClassName,EntryName) \
+ SV_IMPL_REF_LIST(ClassName,EntryName)
+
+/************************** S v M e m b e r L i s t **********************/
+#define PRV_SV_DECL_MEMBER_LIST(Class,EntryName) \
+ Class##MemberList() {} \
+inline Class##MemberList(USHORT nInitSz,USHORT nResize);\
+inline void Insert( EntryName p ); \
+inline void Insert( EntryName p, ULONG nIndex ); \
+inline void Insert( EntryName p, EntryName pOld ); \
+inline void Append( EntryName p ); \
+inline EntryName Remove(); \
+inline EntryName Remove( ULONG nIndex ); \
+inline EntryName Remove( EntryName p ); \
+inline EntryName Replace( EntryName p ); \
+inline EntryName Replace( EntryName p, ULONG nIndex );\
+inline EntryName Replace( EntryName pNew, EntryName pOld );\
+inline EntryName GetCurObject() const;\
+inline EntryName GetObject( ULONG nIndex ) const;\
+inline ULONG GetPos( const EntryName ) const;\
+inline ULONG GetPos( const EntryName, ULONG nStartIndex,\
+ BOOL bForward = TRUE ) const;\
+inline EntryName Seek( ULONG nIndex );\
+inline EntryName Seek( EntryName p );\
+inline EntryName First();\
+inline EntryName Last();\
+inline EntryName Next();\
+inline EntryName Prev();\
+inline void Append( const Class##MemberList & rList );
+
+#define PRV_SV_IMPL_MEMBER_LIST(ClassName,EntryName,BaseList)\
+inline ClassName##MemberList::ClassName##MemberList\
+ (USHORT nInitSz,USHORT nResize)\
+ : BaseList( nInitSz, nResize ){}\
+inline void ClassName##MemberList::Insert( EntryName p )\
+ {BaseList::Insert(p);}\
+inline void ClassName##MemberList::Insert( EntryName p, ULONG nIdx )\
+ {BaseList::Insert(p,nIdx);}\
+inline void ClassName##MemberList::Insert( EntryName p, EntryName pOld )\
+ {BaseList::Insert(p,pOld);}\
+inline void ClassName##MemberList::Append( EntryName p )\
+ {BaseList::Append(p);}\
+inline EntryName ClassName##MemberList::Remove()\
+ {return (EntryName)BaseList::Remove();}\
+inline EntryName ClassName##MemberList::Remove( ULONG nIdx )\
+ {return (EntryName)BaseList::Remove(nIdx);}\
+inline EntryName ClassName##MemberList::Remove( EntryName p )\
+ {return (EntryName)BaseList::Remove(p);}\
+inline EntryName ClassName##MemberList::Replace( EntryName p )\
+ {return (EntryName)BaseList::Replace(p);}\
+inline EntryName ClassName##MemberList::Replace( EntryName p, ULONG nIdx )\
+ {return (EntryName)BaseList::Replace(p,nIdx);}\
+inline EntryName ClassName##MemberList::Replace( EntryName p, EntryName pOld )\
+ {return (EntryName)BaseList::Replace(p,pOld);}\
+inline EntryName ClassName##MemberList::GetCurObject() const\
+ {return (EntryName)BaseList::GetCurObject();}\
+inline EntryName ClassName##MemberList::GetObject( ULONG nIdx ) const\
+ {return (EntryName)BaseList::GetObject( nIdx );}\
+inline EntryName ClassName##MemberList::Seek( ULONG nIdx )\
+ {return (EntryName)BaseList::Seek( nIdx );}\
+inline EntryName ClassName##MemberList::Seek( EntryName p )\
+ {return (EntryName)BaseList::Seek( p );}\
+inline EntryName ClassName##MemberList::First()\
+ {return (EntryName)BaseList::First();}\
+inline EntryName ClassName##MemberList::Last()\
+ {return (EntryName)BaseList::Last();}\
+inline EntryName ClassName##MemberList::Next()\
+ {return (EntryName)BaseList::Next();}\
+inline EntryName ClassName##MemberList::Prev()\
+ {return (EntryName)BaseList::Prev();}\
+inline void ClassName##MemberList::Append( const ClassName##MemberList & rList )\
+ {BaseList::Append(rList);}\
+inline ULONG ClassName##MemberList::GetPos( const EntryName p) const\
+ {return BaseList::GetPos( p );}\
+inline ULONG ClassName##MemberList::GetPos\
+ ( const EntryName p, ULONG nStart, BOOL bForward ) const\
+ {return BaseList::GetPos( p, nStart, bForward );}
+
+#define SV_DECL_MEMBER_LIST(ClassName,EntryName)\
+class ClassName##MemberList : public SvRefBaseMemberList\
+{\
+public:\
+ PRV_SV_DECL_MEMBER_LIST(ClassName,EntryName)\
+};
+
+#define SV_IMPL_MEMBER_LIST(ClassName,EntryName)\
+ PRV_SV_IMPL_MEMBER_LIST(ClassName,EntryName,SvRefBaseMemberList)
+
+#define SV_DECL_IMPL_MEMBER_LIST(ClassName,EntryName)\
+SV_DECL_MEMBER_LIST(ClassName,EntryName)\
+SV_IMPL_MEMBER_LIST(ClassName,EntryName)
+
+/************************** S v R e f B a s e ****************************/
+#define SV_NO_DELETE_REFCOUNT 0x80000000
+class TOOLS_DLLPUBLIC SvRefBase
+{
+ UINT32 nRefCount;
+#if defined (GCC) && (defined (C281) || defined (C290) || defined (C291))
+public:
+#else
+protected:
+#endif
+ virtual ~SvRefBase();
+ virtual void QueryDelete();
+public:
+ SvRefBase() { nRefCount = SV_NO_DELETE_REFCOUNT; }
+ SvRefBase( const SvRefBase & /* rObj */ )
+ { nRefCount = SV_NO_DELETE_REFCOUNT; }
+ SvRefBase & operator = ( const SvRefBase & ) { return *this; }
+
+ void RestoreNoDelete()
+ {
+ if( nRefCount < SV_NO_DELETE_REFCOUNT )
+ nRefCount += SV_NO_DELETE_REFCOUNT;
+ }
+ UINT32 AddMulRef( UINT32 n ) { return nRefCount += n; }
+ UINT32 AddNextRef() { return ++nRefCount; }
+ UINT32 AddRef()
+ {
+ if( nRefCount >= SV_NO_DELETE_REFCOUNT )
+ nRefCount -= SV_NO_DELETE_REFCOUNT;
+ return ++nRefCount;
+ }
+ void ReleaseReference()
+ {
+ if( !--nRefCount )
+ QueryDelete();
+ }
+ UINT32 ReleaseRef()
+ {
+ UINT32 n = --nRefCount;
+ if( !n )
+ QueryDelete();
+ return n;
+ }
+ UINT32 GetRefCount() const { return nRefCount; }
+};
+
+#ifndef EMPTYARG
+#define EMPTYARG
+#endif
+
+SV_DECL_IMPL_REF(SvRefBase)
+
+SV_DECL_REF_LIST(SvRefBase,SvRefBase*)
+
+class SvWeakBase;
+class SvWeakHdl : public SvRefBase
+{
+ friend class SvWeakBase;
+ SvWeakBase* _pObj;
+public:
+ void ResetWeakBase( ) { _pObj = 0; }
+private:
+ SvWeakHdl( SvWeakBase* pObj ) : _pObj( pObj ) {}
+public:
+ SvWeakBase* GetObj() { return _pObj; }
+};
+
+SV_DECL_IMPL_REF( SvWeakHdl )
+
+class SvCompatWeakHdl : public SvRefBase
+{
+ friend class SvCompatWeakBase;
+ void* _pObj;
+ SvCompatWeakHdl( void* pObj ) : _pObj( pObj ) {}
+public:
+ void ResetWeakBase( ) { _pObj = 0; }
+ void* GetObj() { return _pObj; }
+};
+
+SV_DECL_IMPL_REF( SvCompatWeakHdl )
+
+class SvWeakBase
+{
+ SvWeakHdlRef _xHdl;
+public:
+ SvWeakHdl* GetHdl() { return _xHdl; }
+
+ // Wg CompilerWarnung nicht ueber Initializer
+ SvWeakBase() { _xHdl = new SvWeakHdl( this ); }
+ ~SvWeakBase() { _xHdl->ResetWeakBase(); }
+};
+
+class SvCompatWeakBase
+{
+ SvCompatWeakHdlRef _xHdl;
+public:
+ SvCompatWeakHdl* GetHdl() { return _xHdl; }
+
+ // Wg CompilerWarnung nicht ueber Initializer
+ SvCompatWeakBase( void* pObj ) { _xHdl = new SvCompatWeakHdl( pObj ); }
+ ~SvCompatWeakBase() { _xHdl->ResetWeakBase(); }
+};
+
+#define SV_DECL_WEAK_IMPL( ClassName, HdlName ) \
+class ClassName##Weak \
+{ \
+ HdlName _xHdl; \
+public: \
+ inline ClassName##Weak( ) {} \
+ inline ClassName##Weak( ClassName* pObj ) { \
+ if( pObj ) _xHdl = pObj->GetHdl(); } \
+ inline void Clear() { _xHdl.Clear(); } \
+ inline ClassName##Weak& operator = ( ClassName * pObj ) { \
+ _xHdl = pObj ? pObj->GetHdl() : 0; return *this; } \
+ inline BOOL Is() const { \
+ return _xHdl.Is() && _xHdl->GetObj(); } \
+ inline ClassName * operator & () const { \
+ return (ClassName*) ( _xHdl.Is() ? _xHdl->GetObj() : 0 ); } \
+ inline ClassName * operator -> () const { \
+ return (ClassName*) ( _xHdl.Is() ? _xHdl->GetObj() : 0 ); } \
+ inline ClassName & operator * () const { \
+ return *(ClassName*) _xHdl->GetObj(); } \
+ inline operator ClassName * () const { \
+ return (ClassName*) (_xHdl.Is() ? _xHdl->GetObj() : 0 ); } \
+};
+
+#define SV_DECL_WEAK( ClassName ) SV_DECL_WEAK_IMPL( ClassName, SvWeakHdlRef )
+#define SV_DECL_COMPAT_WEAK( ClassName ) SV_DECL_WEAK_IMPL( ClassName, SvCompatWeakHdlRef )
+
+SV_DECL_WEAK( SvWeakBase )
+
+#endif // _Weak_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/resary.hxx b/tools/inc/tools/resary.hxx
new file mode 100644
index 000000000000..63c4859c66b7
--- /dev/null
+++ b/tools/inc/tools/resary.hxx
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _TOOLS_RESARY_HXX
+#define _TOOLS_RESARY_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/resid.hxx>
+#include <tools/rc.hxx>
+
+// ---------------------
+// - ImplResStringItem -
+// ---------------------
+
+struct ImplResStringItem
+{
+ XubString maStr;
+ long mnValue;
+
+#ifdef _TOOLS_RESARY_CXX
+ ImplResStringItem( const XubString& rStr ) :
+ maStr( rStr ) {}
+#endif
+};
+
+// ------------------
+// - ResStringArray -
+// ------------------
+
+#define RESARRAY_INDEX_NOTFOUND (0xffffffff)
+
+class TOOLS_DLLPUBLIC ResStringArray
+{
+ private:
+ // ---------------------
+ // - ImplResStringItem -
+ // ---------------------
+ struct ImplResStringItem
+ {
+ XubString m_aStr;
+ long m_nValue;
+
+ ImplResStringItem( const XubString& rStr, long nValue = 0 ) :
+ m_aStr( rStr ),
+ m_nValue( nValue )
+ {}
+ };
+
+ std::vector< ImplResStringItem > m_aStrings;
+
+ public:
+ ResStringArray( const ResId& rResId );
+ ~ResStringArray();
+
+ const XubString& GetString( sal_uInt32 nIndex ) const
+ { return (nIndex < m_aStrings.size()) ? m_aStrings[nIndex].m_aStr : String::EmptyString(); }
+ long GetValue( sal_uInt32 nIndex ) const
+ { return (nIndex < m_aStrings.size()) ? m_aStrings[nIndex].m_nValue : -1; }
+ sal_uInt32 Count() const { return sal_uInt32(m_aStrings.size()); }
+
+ sal_uInt32 FindIndex( long nValue ) const;
+
+ private:
+ ResStringArray( const ResStringArray& );
+ ResStringArray& operator=( const ResStringArray& );
+};
+
+#endif // _TOOLS_RESARY_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/resid.hxx b/tools/inc/tools/resid.hxx
new file mode 100644
index 000000000000..2b5cb21c2690
--- /dev/null
+++ b/tools/inc/tools/resid.hxx
@@ -0,0 +1,165 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _TOOLS_RESID_HXX
+#define _TOOLS_RESID_HXX
+
+#include <tools/solar.h>
+#include <osl/diagnose.h>
+
+struct RSHEADER_TYPE;
+typedef sal_uInt32 RESOURCE_TYPE;
+#define RSC_NOTYPE 0x100
+#define RSC_DONTRELEASE (sal_uInt32(1 << 31))
+
+class ResMgr;
+
+//---------
+//- ResId -
+//---------
+
+class ResId
+{
+ /*
+ consider two cases: either m_pResource is valid and points
+ two a resource data buffer; then m_nResId and m_pResMgr are
+ not used and may be 0 resp. NULL
+ or m_pResource is NULL, the m_nResId and m_pResMgr must be valid.
+ In this case the highest bit if set decides whether to
+ not to release the Resource context after loading this id
+ */
+ RSHEADER_TYPE* m_pResource;
+
+ mutable sal_uInt32 m_nResId; // Resource Identifier
+ mutable RESOURCE_TYPE m_nRT; // type for loading (mutable to be set later)
+ mutable ResMgr * m_pResMgr; // load from this ResMgr (mutable for setting on demand)
+ mutable RESOURCE_TYPE m_nRT2; // type for loading (supercedes m_nRT)
+ mutable sal_uInt32 m_nWinBits; // container for original style bits on a window in a resource
+
+ void ImplInit( sal_uInt32 nId, ResMgr& rMgr, RSHEADER_TYPE* pRes )
+ {
+ m_pResource = pRes; m_nResId = nId; m_nRT = RSC_NOTYPE; m_pResMgr = &rMgr; m_nRT2 = RSC_NOTYPE; m_nWinBits = 0;
+ OSL_ENSURE( m_pResMgr != NULL, "ResId without ResMgr created" );
+ }
+ public:
+ ResId( RSHEADER_TYPE * pRc, ResMgr& rMgr )
+ {
+ ImplInit( 0, rMgr, pRc );
+ }
+ ResId( sal_uInt32 nId, ResMgr& rMgr )
+ {
+ ImplInit( nId, rMgr, NULL );
+ }
+ // backwards compatibility; avoid ambiguities
+ ResId( USHORT nId, ResMgr& rMgr )
+ {
+ ImplInit( sal_uInt32(nId), rMgr, NULL );
+ }
+ ResId( int nId, ResMgr& rMgr )
+ {
+ ImplInit( sal_uInt32(nId), rMgr, NULL );
+ }
+ ResId( long nId, ResMgr& rMgr )
+ {
+ ImplInit( sal_uInt32(nId), rMgr, NULL );
+ }
+
+ sal_uInt32 GetWinBits() const
+ { return m_nWinBits; }
+ void SetWinBits( sal_uInt32 nBits ) const
+ { m_nWinBits = nBits; }
+
+ RESOURCE_TYPE GetRT() const { return( m_nRT ); }
+ const ResId & SetRT( RESOURCE_TYPE nType ) const
+ /*
+ Set the type if not already set. Ask for tye with GetRT()
+
+ [Example]
+ ResId aId( 1000 );
+ aId.SetRT( RSC_WINDOW ); // settype window Window
+ aId.SetRT( RSC_BUTTON ); // will not set type Button
+ //aId.GetRT() == RSC_WINDOW is true
+
+ @see
+ ResId::GetRT2(), ResId::GetRT()
+ */
+ {
+ if( RSC_NOTYPE == m_nRT )
+ m_nRT = nType;
+ return *this;
+ }
+ RESOURCE_TYPE GetRT2() const
+ /*
+ Get the effective type (m_nRT2 or m_nRT1)
+
+ A second resource type is used to supercede settings
+ of the base class ( e.g. Window )
+ */
+ {
+ return (RSC_NOTYPE == m_nRT2) ? m_nRT : m_nRT2;
+ }
+ const ResId & SetRT2( RESOURCE_TYPE nTyp ) const
+ /*
+ Set the superceding type. Ask spcifically for it with GetRT2()
+
+ SetRT2() may only be called if no derived class calls SetRT in its
+ Resource constructor.
+ */
+ {
+ if( RSC_NOTYPE == m_nRT2 )
+ m_nRT2 = nTyp;
+ return *this;
+ }
+
+ ResMgr * GetResMgr() const { return m_pResMgr; }
+ const ResId & SetResMgr( ResMgr * pMgr ) const
+ {
+ m_pResMgr = pMgr;
+ OSL_ENSURE( m_pResMgr != NULL, "invalid ResMgr set on ResId" );
+ return *this;
+ }
+
+ const ResId & SetAutoRelease(BOOL bRelease) const
+ {
+ if( bRelease )
+ m_nResId &= ~RSC_DONTRELEASE;
+ else
+ m_nResId |= RSC_DONTRELEASE;
+ return *this;
+ }
+
+ BOOL IsAutoRelease() const
+ { return !(m_nResId & RSC_DONTRELEASE); }
+
+ sal_uInt32 GetId() const { return m_nResId & ~RSC_DONTRELEASE; }
+ RSHEADER_TYPE* GetpResource() const { return m_pResource; }
+};
+
+#endif // _RESID_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/resmgr.hxx b/tools/inc/tools/resmgr.hxx
new file mode 100644
index 000000000000..e14a8679c788
--- /dev/null
+++ b/tools/inc/tools/resmgr.hxx
@@ -0,0 +1,241 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _TOOLS_RESMGR_HXX
+#define _TOOLS_RESMGR_HXX
+
+#include "tools/toolsdllapi.h"
+#include <i18npool/lang.h>
+#include <tools/string.hxx>
+#include <tools/ref.hxx>
+#include <tools/resid.hxx>
+#include <com/sun/star/lang/Locale.hpp>
+
+#define CREATEVERSIONRESMGR_NAME( Name ) #Name
+#define CREATEVERSIONRESMGR( Name ) ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( Name ) )
+
+#define LOCALE_MAX_FALLBACK 6
+
+#include <vector>
+
+class SvStream;
+class InternalResMgr;
+
+// -----------------
+// - RSHEADER_TYPE -
+// -----------------
+
+// Definition der Struktur, aus denen die Resource aufgebaut ist
+struct RSHEADER_TYPE
+{
+private:
+ sal_uInt32 nId; // Identifier der Resource
+ RESOURCE_TYPE nRT; // Resource Typ
+ sal_uInt32 nGlobOff; // Globaler Offset
+ sal_uInt32 nLocalOff; // Lokaler Offset
+
+public:
+ inline sal_uInt32 GetId(); // Identifier der Resource
+ inline RESOURCE_TYPE GetRT(); // Resource Typ
+ inline sal_uInt32 GetGlobOff(); // Globaler Offset
+ inline sal_uInt32 GetLocalOff(); // Lokaler Offset
+};
+
+// ----------
+// - ResMgr -
+// ----------
+
+typedef void (*ResHookProc)( UniString& rStr );
+
+// ----------
+// - ResMgr -
+// ----------
+
+// Initialisierung
+#define RC_NOTYPE 0x00
+// Globale Resource
+#define RC_GLOBAL 0x01
+#define RC_AUTORELEASE 0x02
+#define RC_NOTFOUND 0x04
+#define RC_FALLBACK_DOWN 0x08
+#define RC_FALLBACK_UP 0x10
+
+class Resource;
+class ResMgr;
+struct ImpRCStack
+{
+ // pResource and pClassRes equal NULL: resource was not loaded
+ RSHEADER_TYPE * pResource; // pointer to resource
+ void * pClassRes; // pointer to class specified init data
+ short Flags; // resource status
+ void * aResHandle; // Resource-Identifier from InternalResMgr
+ const Resource* pResObj; // pointer to Resource object
+ sal_uInt32 nId; // ResId used for error message
+ ResMgr* pResMgr; // ResMgr for Resource pResObj
+
+ void Clear();
+ void Init( ResMgr * pMgr, const Resource * pObj, sal_uInt32 nId );
+};
+
+class TOOLS_DLLPUBLIC ResMgr
+{
+private:
+ InternalResMgr* pImpRes;
+ std::vector< ImpRCStack > aStack; // resource context stack
+ int nCurStack;
+ ResMgr* pFallbackResMgr; // fallback ResMgr in case the Resource
+ // was not contained in this ResMgr
+ ResMgr* pOriginalResMgr; // the res mgr that fell back to this
+ // stack level
+
+ TOOLS_DLLPRIVATE void incStack();
+ TOOLS_DLLPRIVATE void decStack();
+
+ TOOLS_DLLPRIVATE const ImpRCStack * StackTop( sal_uInt32 nOff = 0 ) const
+ {
+ return (((int)nOff >= nCurStack) ? NULL : &aStack[nCurStack-nOff]);
+ }
+ TOOLS_DLLPRIVATE void Init( const rtl::OUString& rFileName );
+
+ TOOLS_DLLPRIVATE ResMgr( InternalResMgr * pImp );
+
+ #ifdef DBG_UTIL
+ TOOLS_DLLPRIVATE static void RscError_Impl( const sal_Char* pMessage, ResMgr* pResMgr,
+ RESOURCE_TYPE nRT, sal_uInt32 nId,
+ std::vector< ImpRCStack >& rResStack, int nDepth );
+ #endif
+
+ // called from within GetResource() if a resource could not be found
+ TOOLS_DLLPRIVATE ResMgr* CreateFallbackResMgr( const ResId& rId, const Resource* pResource );
+ // creates a 1k sized buffer set to zero for unfound resources
+ // used in case RC_NOTFOUND
+ static void* pEmptyBuffer;
+ TOOLS_DLLPRIVATE static void* getEmptyBuffer();
+
+ // the next two methods are needed to prevent the string hook called
+ // with the res mgr mutex locked
+ // like GetString, but doesn't call the string hook
+ TOOLS_DLLPRIVATE static sal_uInt32 GetStringWithoutHook( UniString& rStr, const BYTE* pStr );
+ // like ReadString but doesn't call the string hook
+ TOOLS_DLLPRIVATE UniString ReadStringWithoutHook();
+
+ static ResMgr* ImplCreateResMgr( InternalResMgr* pImpl ) { return new ResMgr( pImpl ); }
+
+ //No copying
+ ResMgr(const ResMgr&);
+ ResMgr& operator=(const ResMgr&);
+public:
+ static void DestroyAllResMgr(); // Wird gerufen, wenn App beendet wird
+
+ ~ResMgr();
+
+ // Sprachabhaengige Ressource Library
+ static const sal_Char* GetLang( LanguageType& eLanguage, USHORT nPrio = 0 ); //depricated! see "tools/source/rc/resmgr.cxx"
+ static ResMgr* SearchCreateResMgr( const sal_Char* pPrefixName,
+ com::sun::star::lang::Locale& rLocale );
+ static ResMgr* CreateResMgr( const sal_Char* pPrefixName,
+ com::sun::star::lang::Locale aLocale = com::sun::star::lang::Locale( rtl::OUString(),
+ rtl::OUString(),
+ rtl::OUString()));
+
+ // Testet ob Resource noch da ist
+ void TestStack( const Resource * );
+
+ // ist Resource verfuegbar
+ BOOL IsAvailable( const ResId& rId,
+ const Resource* = NULL) const;
+
+ // Resource suchen und laden
+ BOOL GetResource( const ResId& rId, const Resource * = NULL );
+ static void * GetResourceSkipHeader( const ResId& rResId, ResMgr ** ppResMgr );
+ // Kontext freigeben
+ void PopContext( const Resource* = NULL );
+
+ // Resourcezeiger erhoehen
+ void* Increment( sal_uInt32 nSize );
+
+ // Groesse ein Objektes in der Resource
+ static sal_uInt32 GetObjSize( RSHEADER_TYPE* pHT )
+ { return( pHT->GetGlobOff() ); }
+
+ // Liefert einen String aus der Resource
+ static sal_uInt32 GetString( UniString& rStr, const BYTE* pStr );
+
+ // Groesse eines Strings in der Resource
+ static sal_uInt32 GetStringSize( sal_uInt32 nLen )
+ { nLen++; return (nLen + nLen%2); }
+ static sal_uInt32 GetStringSize( const BYTE* pStr );
+
+ // return a int64
+ static sal_uInt64 GetUInt64( void* pDatum );
+ // Gibt einen long zurueck
+ static INT32 GetLong( void * pLong );
+ // return a short
+ static INT16 GetShort( void * pShort );
+
+ // Gibt einen Zeiger auf die Resource zurueck
+ void * GetClass();
+
+ RSHEADER_TYPE * CreateBlock( const ResId & rId );
+
+ // Gibt die verbleibende Groesse zurueck
+ sal_uInt32 GetRemainSize();
+
+ const rtl::OUString&GetFileName() const;
+
+ INT16 ReadShort();
+ INT32 ReadLong();
+ UniString ReadString();
+
+ // generate auto help id for current resource stack
+ ULONG GetAutoHelpId();
+
+ static void SetReadStringHook( ResHookProc pProc );
+ static ResHookProc GetReadStringHook();
+ static void SetDefaultLocale( const com::sun::star::lang::Locale& rLocale );
+};
+
+inline sal_uInt32 RSHEADER_TYPE::GetId()
+{
+ return (sal_uInt32)ResMgr::GetLong( &nId );
+}
+inline RESOURCE_TYPE RSHEADER_TYPE::GetRT()
+{
+ return (RESOURCE_TYPE)ResMgr::GetLong( &nRT );
+}
+inline sal_uInt32 RSHEADER_TYPE::GetGlobOff()
+{
+ return (sal_uInt32)ResMgr::GetLong( &nGlobOff );
+}
+inline sal_uInt32 RSHEADER_TYPE::GetLocalOff()
+{
+ return (sal_uInt32)ResMgr::GetLong( &nLocalOff );
+}
+
+#endif // _SV_RESMGR_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/rtti.hxx b/tools/inc/tools/rtti.hxx
new file mode 100644
index 000000000000..4a165e3c99ed
--- /dev/null
+++ b/tools/inc/tools/rtti.hxx
@@ -0,0 +1,177 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _RTTI_HXX
+#define _RTTI_HXX
+
+#include <string.h>
+#include <tools/solar.h>
+
+typedef void* (*TypeId)();
+
+//-------------------------------------------------------------------------
+
+#define TYPEINFO() \
+ static void* CreateType(); \
+ static TypeId StaticType(); \
+ static BOOL IsOf( TypeId aSameOrSuperType ); \
+ virtual TypeId Type() const; \
+ virtual BOOL IsA( TypeId aSameOrSuperType ) const
+
+#define TYPEINFO_VISIBILITY(visibility) \
+ visibility static void* CreateType(); \
+ visibility static TypeId StaticType(); \
+ visibility static BOOL IsOf( TypeId aSameOrSuperType ); \
+ visibility virtual TypeId Type() const; \
+ visibility virtual BOOL IsA( TypeId aSameOrSuperType ) const
+
+#define TYPEINIT_FACTORY(sType, Factory ) \
+ void* sType::CreateType() { return Factory; } \
+ TypeId sType::StaticType() { return &CreateType; } \
+ TypeId sType::Type() const { return &CreateType; } \
+ BOOL sType::IsOf( TypeId aSameOrSuperType ) \
+ { \
+ if ( aSameOrSuperType == StaticType() ) \
+ return TRUE
+
+#define STATICTYPE(sType) (sType::StaticType())
+
+//-------------------------------------------------------------------------
+
+#define TYPEINIT_AUTOFACTORY(sType) TYPEINIT_FACTORY(sType, new sType)
+#define TYPEINIT(sType) TYPEINIT_FACTORY(sType, 0)
+
+#define SUPERTYPE(sSuper) \
+ if ( sSuper::IsOf(aSameOrSuperType ) ) \
+ return TRUE
+
+#define TYPEINIT_END(sType) \
+ return FALSE; \
+ } \
+ BOOL sType::IsA( TypeId aSameOrSuperType ) const \
+ { return IsOf( aSameOrSuperType ); }
+
+#define TYPEINIT0_FACTORY(sType, Factory) \
+ TYPEINIT_FACTORY(sType, Factory); \
+ TYPEINIT_END(sType)
+#define TYPEINIT0_AUTOFACTORY(sType) TYPEINIT0_FACTORY(sType, new sType)
+#define TYPEINIT0(sType) TYPEINIT0_FACTORY(sType, 0)
+
+#define TYPEINIT1_FACTORY(sType, sSuper, Factory) \
+ TYPEINIT_FACTORY(sType, Factory); \
+ SUPERTYPE(sSuper); \
+ TYPEINIT_END(sType)
+#define TYPEINIT1_AUTOFACTORY(sType, sSuper) \
+ TYPEINIT1_FACTORY(sType, sSuper, new sType)
+#define TYPEINIT1(sType, sSuper) \
+ TYPEINIT1_FACTORY(sType, sSuper, 0)
+
+#define TYPEINIT2_FACTORY(sType, sSuper1, sSuper2, Factory) \
+ TYPEINIT_FACTORY(sType, Factory); \
+ SUPERTYPE(sSuper1); \
+ SUPERTYPE(sSuper2); \
+ TYPEINIT_END(sType)
+#define TYPEINIT2_AUTOFACTORY(sType, sSuper1, sSuper2) \
+ TYPEINIT2_FACTORY(sType, sSuper1, sSuper2, new sType)
+#define TYPEINIT2(sType, sSuper1, sSuper2) \
+ TYPEINIT2_FACTORY(sType, sSuper1, sSuper2, 0)
+
+#define TYPEINIT3_FACTORY(sType, sSuper1, sSuper2, sSuper3, Factory) \
+ TYPEINIT_FACTORY(sType, Factory); \
+ SUPERTYPE(sSuper1); \
+ SUPERTYPE(sSuper2); \
+ SUPERTYPE(sSuper3); \
+ TYPEINIT_END(sType)
+#define TYPEINIT3_AUTOFACTORY(sType, sSuper1, sSuper2, sSuper3) \
+ TYPEINIT3_FACTORY(sType, sSuper1, sSuper2, sSuper3, new sType)
+#define TYPEINIT3(sType, sSuper1, sSuper2, sSuper3) \
+ TYPEINIT3_FACTORY(sType, sSuper1, sSuper2, sSuper3, 0)
+
+#define TYPE(sType) (sType::StaticType())
+#define ISA(sType) IsA(sType::StaticType())
+#define ISOF(sType) IsOf(sType::StaticType())
+#define CREATE(TypeId) (TypeId())
+
+//-------------------------------------------------------------------------
+// On-Demand-faehige persistent-TypeId Version
+
+#define TYPEINFO_ID(id) \
+ static TypeId StaticType() { return (TypeId) ( id | 0xF000000L ); } \
+ static BOOL IsOf( TypeId aSameOrSuperType ); \
+ virtual TypeId Type() const; \
+ virtual BOOL IsA( TypeId aSameOrSuperType ) const
+
+#define TYPEINIT_ID(sType) \
+ TypeId sType::Type() const { return StaticType(); } \
+ BOOL sType::IsOf( TypeId aSameOrSuperType ) \
+ { \
+ if ( aSameOrSuperType == StaticType() ) \
+ return TRUE
+
+#define TYPEINIT0_ID(sType) \
+ TYPEINIT_ID(sType); \
+ TYPEINIT_END(sType)
+
+#define TYPEINIT1_ID(sType, sSuper) \
+ TYPEINIT_ID(sType); \
+ SUPERTYPE(sSuper); \
+ TYPEINIT_END(sType)
+
+#define TYPEINIT2_ID(sType, sSuper1, sSuper2) \
+ TYPEINIT_ID(sType); \
+ SUPERTYPE(sSuper1); \
+ SUPERTYPE(sSuper2); \
+ TYPEINIT_END(sType)
+
+//-------------------------------------------------------------------------
+
+// Die (exemplarischen) Makros fuer die Anwendung ( hier fuer
+// Pointer, kann aber nach dem gleichen Strickmuster fuer
+// Referenzen erweitert werden.
+// PTR_CAST: sicheres Casten eines Pointers auf einen Pointer
+// einer abgeleiteten Klasse. Liefert im Fehlerfall einen
+// Nullpointer (wahrscheinlich die haeufigste Anwendung)
+//
+// T: Typ, auf den gecastet werden soll
+// p: Pointer, der gecastet werden soll
+#define PTR_CAST( T, pObj ) \
+ ( pObj && (pObj)->IsA( TYPE(T) ) ? (T*)(pObj) : 0 )
+
+// Abfrage, ob ein Objekt eine bestimmte Klasse als
+// Basisklasse hat (oder genau von dieser Klasse ist)
+#define HAS_BASE( T, pObj ) \
+ ( pObj && (pObj)->IsA( TYPE(T) ) )
+
+// Abfrage, ob ein Pointer auf ein Objekt eines bestimmten
+// Typs zeigt
+#define IS_TYPE(T,pObj) \
+ ( pObj && (pObj)->Type() == TYPE(T) )
+
+#endif // _RTTI_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/shl.hxx b/tools/inc/tools/shl.hxx
new file mode 100644
index 000000000000..c02dde3114ee
--- /dev/null
+++ b/tools/inc/tools/shl.hxx
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SHL_HXX
+#define _SHL_HXX
+
+#include <tools/solar.h>
+#include "tools/toolsdllapi.h"
+
+// ----------------
+// - GetAppData() -
+// ----------------
+
+#define SHL_SHL1 0
+#define SHL_SHL2 1
+#define SHL_SHL3 2
+#define SHL_APP1 3
+#define SHL_APP2 4
+#define SHL_APP3 5
+#define SHL_TOOLS 6
+#define SHL_SV 7
+#define SHL_SVT 8
+#define SHL_SVDDE 9
+#define SHL_ERR 10
+#define SHL_IPC 11
+#define SHL_SVX 12
+#define SHL_ITEM 13
+#define SHL_SVD 14
+#define SHL_SI 15
+#define SHL_SFC 16
+#define SHL_SFX 17
+//#define SHL_SO2 18
+#define SHL_IDL 19
+#define SHL_IDE 20
+#define SHL_EDIT 21
+#define SHL_VCED 22
+#define SHL_BASIC 23
+#define SHL_HELP 24
+#define SHL_LNKCCH 25
+#define SHL_CHANNEL 26
+#define SHL_SBX 27
+#define SHL_SBC 28
+#define SHL_SDB 29
+#define SHL_SBA 30
+#define SHL_SBA2 31
+#define SHL_SCH 32
+#define SHL_SIM 33
+#define SHL_SM 34
+#define SHL_SGA 35
+#define SHL_DOCMGR 36
+// 37 removed
+#define SHL_MAIL 38
+#define SHL_NEWS 39
+#define SHL_OFFAPP 40
+#define SHL_INET 41
+#define SHL_CHAOS 42
+#define SHL_HISTORY 43
+#define SHL_SJ 44
+#define SHL_CALC 45
+#define SHL_DRAW 46
+#define SHL_WRITER 47
+#define SHL_MONEY 48
+#define SHL_HBCI 49
+#define SHL_BASE3D 50
+#define SHL_BRUSHITEM 51
+#define SHL_SFONTITEM 52
+
+// #110743#
+// #define SHL_COUNT 53
+// the following added for binary filter project
+// Sice an array is created for that values, it is necessary to
+// put them directly behind the defined ones. Else, some space is
+// wasted.
+#define BF_SHL_SVX 53
+#define BF_SHL_ITEM 54
+#define BF_SHL_SVD 55
+#define BF_SHL_EDIT 56
+#define BF_SHL_SCH 57
+#define BF_SHL_SM 58
+#define BF_SHL_CALC 59
+#define BF_SHL_DRAW 60
+#define BF_SHL_WRITER 61
+#define BF_SHL_SVT 62
+#define BF_SHL_SVDDE 63
+
+#define SHL_COUNT 64
+
+TOOLS_DLLPUBLIC void** GetAppData( USHORT nSharedLib );
+
+#endif // _SHL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/simplerm.hxx b/tools/inc/tools/simplerm.hxx
new file mode 100644
index 000000000000..2665b3294203
--- /dev/null
+++ b/tools/inc/tools/simplerm.hxx
@@ -0,0 +1,120 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// ----------------
+// - SimpleResMgr -
+// ----------------
+
+// a simple resource manager : no stacks, no sharing of the impl class, only loading of strings and blobs
+// but thread-safety !! :)
+
+#ifndef _TOOLS_SIMPLERESMGR_HXX_
+#define _TOOLS_SIMPLERESMGR_HXX_
+
+#include <osl/mutex.hxx>
+#include <tools/resid.hxx>
+#include <i18npool/lang.h>
+#include <tools/string.hxx>
+#include <com/sun/star/lang/Locale.hpp>
+#include "tools/toolsdllapi.h"
+
+class InternalResMgr;
+class TOOLS_DLLPUBLIC SimpleResMgr
+{
+protected:
+ osl::Mutex m_aAccessSafety;
+ InternalResMgr* m_pResImpl;
+
+public:
+ /** creates a new SimpleResManager
+ @param pPrefixName
+ denotes the prefix of the resource file name, in ThreadTextEncoding
+ @param rLocale
+ denotes the locale of the resource file to load. If empty, a default locale
+ will be used.
+ */
+ SimpleResMgr( const sal_Char* pPrefixName,
+ const ::com::sun::star::lang::Locale& _rLocale);
+
+ /** creates a new SimpleResManager
+ @param _rPrefixName
+ denotes the prefix of the resource file name
+ @param _inout_Locale
+ denotes the locale of the resource file to load. If empty, no default handling
+ (like in the other constructor) will happen, instead an unlocalized version will be
+ attempted to be loaded.
+ Upon return, the variable will contain the actual locale of the loaded resource file.
+ For instance, if "en-US" is requested, but only "en" exists, the latter will be loaded
+ and returned. Furthermore, if an unlocalized resource file with only the base name exists,
+ this one will be loaded as final fallback.
+ */
+ SimpleResMgr( const ::rtl::OUString& _rPrefixName, ::com::sun::star::lang::Locale& _inout_Locale );
+ virtual ~SimpleResMgr();
+
+ static SimpleResMgr* Create( const sal_Char* pPrefixName,
+ ::com::sun::star::lang::Locale aLocale = ::com::sun::star::lang::Locale( rtl::OUString(),
+ rtl::OUString(),
+ rtl::OUString()));// nur in VCL
+
+ bool IsValid() const { return m_pResImpl != NULL; }
+
+ /** retrieves the locale of the resource file represented by this instance
+ @precond
+ IsValid returns <TRUE/>
+ */
+ const ::com::sun::star::lang::Locale&
+ GetLocale() const;
+
+ /** reads the string with the given resource id
+ @param nId
+ the resource id of the string to read
+ @return
+ the string with the given resource id, or an empty string if the id does not denote
+ an existent string
+ @seealso IsAvailable
+ */
+ UniString ReadString( sal_uInt32 nId );
+
+ /** checks whether a certain resource is availble
+ @param _resourceType
+ the type of the resource to check. Currently, only RSC_STRING (strings) and RSC_RESOURCE (blobs)
+ are supported, for every other type, <FALSE/> will be returned.
+ @param _resourceId
+ the id of the resource to lookup.
+ @return
+ <TRUE/> if and only if a resource of the given type, with the given id, is available.
+ */
+ bool IsAvailable( RESOURCE_TYPE _resourceType, sal_uInt32 _resourceId );
+
+ sal_uInt32 ReadBlob( sal_uInt32 nId, void** pBuffer );
+ void FreeBlob( void* pBuffer );
+};
+
+#endif // _TOOLS_SIMPLERESMGR_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/solar.h b/tools/inc/tools/solar.h
new file mode 100644
index 000000000000..3a819188f66a
--- /dev/null
+++ b/tools/inc/tools/solar.h
@@ -0,0 +1,449 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SOLAR_H
+#define _SOLAR_H
+
+#include <sal/types.h>
+#include <osl/endian.h>
+#include <comphelper/fileformat.h>
+
+/*** common solar defines ***********************************/
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifdef _SOLAR__PRIVATE
+#undef _SOLAR__PRIVATE
+#endif
+#define _SOLAR__PRIVATE 1
+#define __REFERENCED 0
+
+/*** common solar types ********************************************/
+/* NOTE: these types are deprecated, or soon will be. They should */
+/* not be used in new code, and should be replaced with their */
+/* corresponding types from sal/types.h in old code when possible. */
+/* Previous typedefs from before sal convergence are in comments */
+/* to the right of the new types. */
+
+typedef sal_Bool BOOL; /* typedef unsigned char BOOL; */
+typedef sal_uInt8 BYTE; /* typedef unsigned char BYTE; */
+typedef sal_uInt16 USHORT; /* typedef unsigned short USHORT; */
+typedef sal_uIntPtr ULONG; /* typedef unsigned long ULONG; */
+typedef int FASTBOOL;
+
+#if !defined(VCL_NEED_BASETSD) || defined(__MINGW32__)
+#ifndef _SOLAR_NOUINT
+typedef sal_Int16 INT16; /* typedef short INT16; */
+typedef sal_uInt16 UINT16; /* typedef unsigned short UINT16; */
+#if defined(SAL_W32)
+typedef sal_sChar INT8;
+#else
+typedef sal_Char INT8; /* typedef char INT8; */
+#endif
+typedef sal_uInt8 UINT8; /* typedef unsigned char UINT8; */
+#endif /* _SOLAR_NOUINT */
+#endif
+
+#ifndef VCL_NEED_BASETSD
+#ifndef _SOLAR_NOUINT
+/* types with exact defined size (not just the minimum size) */
+typedef sal_Int64 INT64; /* typedef long INT64; previously "void" on Windows */
+typedef sal_uInt64 UINT64; /* typedef unsigned long UINT64; previously "void" on Windows */
+typedef sal_Int32 INT32; /* typedef int INT32; previously "long" on Windows */
+typedef sal_uInt32 UINT32; /* typedef unsigned int UINT32; previously "unsigned long" on Windows */
+#endif /* _SOLAR_NOUINT */
+#endif
+
+/*** misc. macros to leverage platform and compiler differences ********/
+
+#define DELETEZ( p ) ( delete p,p = 0 )
+
+#define __FAR_DATA
+#define __READONLY_DATA const
+#define __EXPORT
+
+#ifdef WNT
+#if defined (_MSC_VER) && ( _MSC_VER < 1200 )
+#define __LOADONCALLAPI _cdecl
+#else
+#define __LOADONCALLAPI __cdecl
+#endif
+#else
+#define __LOADONCALLAPI
+#endif
+
+#if defined UNX
+#define ILLEGAL_POINTER ((void*)1)
+#else
+#define ILLEGAL_POINTER NULL
+#endif
+
+/*** solar binary types **********************************************/
+
+#ifndef _SOLAR_NOSVBT
+/* Solar (portable) Binary (exchange) Type; OSI 6 subset
+ always little endian;
+ not necessarily aligned */
+
+typedef BYTE SVBT8[1];
+typedef BYTE SVBT16[2];
+typedef BYTE SVBT32[4];
+typedef BYTE SVBT64[8];
+
+#ifdef __cplusplus
+
+inline BYTE SVBT8ToByte ( const SVBT8 p ) { return p[0]; }
+inline USHORT SVBT16ToShort( const SVBT16 p ) { return (USHORT)p[0]
+ + ((USHORT)p[1] << 8); }
+inline sal_uInt32 SVBT32ToUInt32 ( const SVBT32 p ) { return (sal_uInt32)p[0]
+ + ((sal_uInt32)p[1] << 8)
+ + ((sal_uInt32)p[2] << 16)
+ + ((sal_uInt32)p[3] << 24); }
+#if defined OSL_LITENDIAN
+inline double SVBT64ToDouble( const SVBT64 p ) { double n;
+ ((BYTE*)&n)[0] = p[0];
+ ((BYTE*)&n)[1] = p[1];
+ ((BYTE*)&n)[2] = p[2];
+ ((BYTE*)&n)[3] = p[3];
+ ((BYTE*)&n)[4] = p[4];
+ ((BYTE*)&n)[5] = p[5];
+ ((BYTE*)&n)[6] = p[6];
+ ((BYTE*)&n)[7] = p[7];
+ return n; }
+#else
+inline double SVBT64ToDouble( const SVBT64 p ) { double n;
+ ((BYTE*)&n)[0] = p[7];
+ ((BYTE*)&n)[1] = p[6];
+ ((BYTE*)&n)[2] = p[5];
+ ((BYTE*)&n)[3] = p[4];
+ ((BYTE*)&n)[4] = p[3];
+ ((BYTE*)&n)[5] = p[2];
+ ((BYTE*)&n)[6] = p[1];
+ ((BYTE*)&n)[7] = p[0];
+ return n; }
+#endif
+
+inline void ByteToSVBT8 ( BYTE n, SVBT8 p ) { p[0] = n; }
+inline void ShortToSVBT16( USHORT n, SVBT16 p ) { p[0] = (BYTE) n;
+ p[1] = (BYTE)(n >> 8); }
+inline void UInt32ToSVBT32 ( sal_uInt32 n, SVBT32 p ) { p[0] = (BYTE) n;
+ p[1] = (BYTE)(n >> 8);
+ p[2] = (BYTE)(n >> 16);
+ p[3] = (BYTE)(n >> 24); }
+#if defined OSL_LITENDIAN
+inline void DoubleToSVBT64( double n, SVBT64 p ) { p[0] = ((BYTE*)&n)[0];
+ p[1] = ((BYTE*)&n)[1];
+ p[2] = ((BYTE*)&n)[2];
+ p[3] = ((BYTE*)&n)[3];
+ p[4] = ((BYTE*)&n)[4];
+ p[5] = ((BYTE*)&n)[5];
+ p[6] = ((BYTE*)&n)[6];
+ p[7] = ((BYTE*)&n)[7]; }
+#else
+inline void DoubleToSVBT64( double n, SVBT64 p ) { p[0] = ((BYTE*)&n)[7];
+ p[1] = ((BYTE*)&n)[6];
+ p[2] = ((BYTE*)&n)[5];
+ p[3] = ((BYTE*)&n)[4];
+ p[4] = ((BYTE*)&n)[3];
+ p[5] = ((BYTE*)&n)[2];
+ p[6] = ((BYTE*)&n)[1];
+ p[7] = ((BYTE*)&n)[0]; }
+#endif
+#endif
+#endif
+
+
+/*** standard floating point definitions *******************************/
+
+#ifndef F_PI
+#define F_PI 3.14159265358979323846
+#endif
+#ifndef F_PI2
+#define F_PI2 1.57079632679489661923
+#endif
+#ifndef F_PI4
+#define F_PI4 0.785398163397448309616
+#endif
+#ifndef F_PI180
+#define F_PI180 0.01745329251994
+#endif
+#ifndef F_PI1800
+#define F_PI1800 0.001745329251994
+#endif
+#ifndef F_PI18000
+#define F_PI18000 0.0001745329251994
+#endif
+#ifndef F_2PI
+#define F_2PI 6.28318530717958647694
+#endif
+
+
+/*** standard macros *****************************************/
+
+#define SWAPSHORT(x) ((((x) >> 8) & 0x00FF) | (((x) & 0x00FF) << 8))
+#define SWAPLONG(x) ((((x) >> 24) & 0x000000FF) | (((x) & 0x00FF0000) >> 8) | \
+ (((x) & 0x0000FF00) << 8) | (((x) & 0x000000FF) << 24))
+
+#ifndef __cplusplus
+#ifndef min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+#endif
+
+
+
+/*** standard inline functions *****************************************/
+
+#ifdef __cplusplus
+template<typename T> inline T Min(T a, T b) { return (a<b?a:b); }
+template<typename T> inline T Max(T a, T b) { return (a>b?a:b); }
+template<typename T> inline T Abs(T a) { return (a>=0?a:-a); }
+#endif
+
+
+/*** C / C++ - macros **************************************************/
+
+#ifdef __cplusplus
+#define BEGIN_C extern "C" {
+#define END_C }
+#define EXTERN_C extern "C"
+#else
+#define BEGIN_C
+#define END_C
+#define EXTERN_C
+#endif
+
+
+/*** macros ************************************************************/
+
+#ifdef NOHACKS
+#define HACK( comment ) #error hack: comment
+#else
+#define HACK( comment )
+#endif
+
+#define _MAKE_NUMSTR( n ) # n
+#define MAKE_NUMSTR( n ) _MAKE_NUMSTR( n )
+
+#define _LF ((char)0x0A)
+#define _CR ((char)0x0D)
+
+
+/*** pragmas ************************************************************/
+
+#if defined _MSC_VER
+/* deletion of pointer to incomplete type '...'; no destructor called
+ serious error, memory deleted without call of dtor */
+#pragma warning( error: 4150 )
+// warning C4002: too many actual parameters for macro
+// warning C4003: not enough actual parameters for macro
+#pragma warning(error : 4002 4003)
+#endif
+
+
+/* dll file extensions *******************************************************/
+
+/* many of these platforms are historic */
+#define SYSTEM_WINMSCI 1
+#define SYSTEM_WNTMSCI 2
+#define SYSTEM_WNTMSCA 3
+#define SYSTEM_WNTMSCP 4
+#define SYSTEM_WNTMSCM 5
+#define SYSTEM_OS2BLCI 6
+#define SYSTEM_OS2ICCI 7
+#define SYSTEM_OS2ICCI3 8
+#define SYSTEM_UNXLNXI 9
+#define SYSTEM_UNXSOLS 10
+#define SYSTEM_UNXBSDI 11
+#define SYSTEM_UNXBSDA 12
+#define SYSTEM_UNXSCOI 13
+#define SYSTEM_UNXAIXP 14
+#define SYSTEM_UNXHPXR 15
+#define SYSTEM_UNXSNIM 16
+#define SYSTEM_UNXMVSG 17
+#define SYSTEM_UNXIRXM 18
+// #define SYSTEM_MACOSP 19
+#define SYSTEM_UNXFBSDI 20
+#define SYSTEM_UNXSOLI 21
+#define SYSTEM_WINBLCI 22
+#define SYSTEM_UNXMACXP 23
+#define SYSTEM_UNXLNXP 24
+#define SYSTEM_UNXBSDS 25
+#define SYSTEM_UNXLNXR 26
+#define SYSTEM_UNXLNX3 28
+#define SYSTEM_UNXLNXS 29
+#define SYSTEM_UNXLNXX 30
+#define SYSTEM_UNXSOGS 31
+#define SYSTEM_UNXSOGI 32
+#define SYSTEM_UNXMACXI 33
+#define SYSTEM_OS2GCCI 34
+#define SYSTEM_UNXBSDX 35
+#define SYSTEM_UNXOBSD 36
+#define SYSTEM_WNTGCCI 99
+
+#if defined WNT
+#if defined(__MINGW32__)
+ #define __DLLEXTENSION "gi"
+#else
+ #define __DLLEXTENSION "mi"
+#endif
+#elif defined OS2
+ #define __DLLEXTENSION "go"
+#elif defined UNX
+#ifdef AIX
+ #define __DLLEXTENSION "ap.so"
+#elif defined HPUX
+ #define __DLLEXTENSION "hr.sl"
+#elif defined SOLARIS && defined SPARC && defined IS_LP64
+ #define __DLLEXTENSION "su.so"
+#elif defined SOLARIS && defined SPARC && !defined __GNUC__
+ #define __DLLEXTENSION "ss.so"
+#elif defined SOLARIS && defined SPARC && defined __GNUC__
+ #define __DLLEXTENSION "sogs.so"
+#elif defined SOLARIS && defined INTEL && !defined __GNUC__
+ #define __DLLEXTENSION "si.so"
+#elif defined SOLARIS && defined INTEL && defined __GNUC__
+ #define __DLLEXTENSION "sogi.so"
+#elif defined SCO
+ #define __DLLEXTENSION "ci.so"
+#elif defined NETBSD && defined X86
+ #define __DLLEXTENSION "bi.so"
+#elif defined NETBSD && defined X86_64
+ #define __DLLEXTENSION "bx.so"
+#elif defined NETBSD && defined ARM32
+ #define __DLLEXTENSION "ba.so"
+#elif defined NETBSD && defined SPARC
+ #define __DLLEXTENSION "bs.so"
+#elif defined NETBSD && defined POWERPC
+ #define __DLLEXTENSION "bp.so"
+#elif defined LINUX && defined X86
+ #define __DLLEXTENSION "li.so"
+#elif defined LINUX && defined POWERPC
+ #define __DLLEXTENSION "lp.so"
+#elif defined LINUX && defined S390
+ #define __DLLEXTENSION "l3.so"
+#elif defined LINUX && defined ARM32
+ #define __DLLEXTENSION "lr.so"
+#elif defined LINUX && defined SPARC
+ #define __DLLEXTENSION "ls.so"
+#elif defined LINUX && defined __x86_64__
+ #define __DLLEXTENSION "lx.so"
+#elif defined LINUX && defined MIPS
+ #define __DLLEXTENSION "lm.so"
+#elif defined LINUX && defined IA64
+ #define __DLLEXTENSION "la.so"
+#elif defined LINUX && defined M68K
+ #define __DLLEXTENSION "lm.so"
+#elif defined LINUX && defined HPPA
+ #define __DLLEXTENSION "lh.so"
+#elif defined LINUX && defined AXP
+ #define __DLLEXTENSION "ll.so"
+#elif defined LINUX
+ #error unknown plattform
+#elif defined FREEBSD && defined X86
+ #define __DLLEXTENSION "fi.so"
+#elif defined FREEBSD && defined X86_64
+ #define __DLLEXTENSION "fx.so"
+#elif defined MACOSX && defined POWERPC
+ #define __DLLEXTENSION "mxp.dylib"
+#elif defined MACOSX && defined X86
+ #define __DLLEXTENSION "mxi.dylib"
+#elif defined OPENBSD
+ #define __DLLEXTENSION "ob.so"
+#else
+ #define __DLLEXTENSION ".so"
+#endif
+#endif
+
+// -----------------------------------------------------------------------
+
+#define NOOLDSTRING
+#ifndef NOREPLACESTRING
+#define UniString String
+#define XubString String
+#else
+#define XubString UniString
+#endif
+#define xub_Unicode sal_Unicode
+#define xub_uUnicode sal_Unicode
+#ifdef STRING32
+#define xub_StrLen sal_uInt32
+#else
+#define xub_StrLen USHORT
+#endif
+
+// -- moved here from libcall.hxx ----------------------------------------
+
+#define LIBRARY_STR(s) # s
+#define LIBRARY_STRING(s) LIBRARY_STR(s)
+
+#define GETFUNCTION( s ) GetFunction( s )
+#define LIBRARY_CONCAT3( s1, s2, s3 ) \
+ s1 s2 s3
+#define LIBRARY_CONCAT4( s1, s2, s3, s4 ) \
+ s1 s2 s3 s4
+
+#if defined WIN || defined WNT || defined OS2
+#define SVLIBRARY( Base ) \
+ LIBRARY_CONCAT3( Base, __DLLEXTENSION, ".DLL" )
+#define SVLIBRARYLANG( Base, Lang ) \
+ LIBRARY_CONCAT3( Base, Lang, ".DLL" )
+#elif defined UNX
+#define SVLIBRARY( Base ) \
+ LIBRARY_CONCAT3( "lib", Base, __DLLEXTENSION )
+#define SVLIBRARYLANG( Base, Lang ) \
+ LIBRARY_CONCAT3( "lib", Base, Lang )
+#else
+#define SVLIBRARY( Base ) \
+ LIBRARY_CONCAT2( Base, __DLLEXTENSION )
+#define SVLIBRARYLANG( Base, Lang ) \
+ LIBRARY_CONCAT2( Base, Lang )
+#endif
+
+#if defined MACOSX
+#define SV_LIBFILENAME(str) \
+ LIBRARYFILENAME_CONCAT2( str, __DLLEXTENSION )
+#elif defined UNX
+#define SV_LIBFILENAME(str) \
+ LIBRARYFILENAME_CONCAT2( str, __DLLEXTENSION )
+#else
+#define SV_LIBFILENAME(str) \
+ LIBRARYFILENAME_CONCAT3( str, __DLLEXTENSION, ".dll" )
+#endif
+
+#endif /* _SOLAR_H */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/solarmutex.hxx b/tools/inc/tools/solarmutex.hxx
new file mode 100644
index 000000000000..af96e317ea0c
--- /dev/null
+++ b/tools/inc/tools/solarmutex.hxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _TOOLS_SOLARMUTEX_HXX
+#define _TOOLS_SOLARMUTEX_HXX
+
+#include "tools/toolsdllapi.h"
+#include <osl/mutex.hxx>
+
+namespace tools
+{
+ class TOOLS_DLLPUBLIC SolarMutex
+ {
+ public:
+ static ::osl::SolarMutex* GetSolarMutex();
+ static void SetSolarMutex( ::osl::SolarMutex* pMutex );
+ static bool Acquire();
+ static void Release();
+ };
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/stack.hxx b/tools/inc/tools/stack.hxx
new file mode 100644
index 000000000000..009339df18d9
--- /dev/null
+++ b/tools/inc/tools/stack.hxx
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _STACK_HXX
+#define _STACK_HXX
+
+#include <tools/contnr.hxx>
+
+// ---------
+// - Stack -
+// ---------
+
+#define STACK_ENTRY_NOTFOUND CONTAINER_ENTRY_NOTFOUND
+
+class Stack : private Container
+{
+public:
+ using Container::Clear;
+ using Container::Count;
+ using Container::GetObject;
+ using Container::GetPos;
+
+ Stack( USHORT _nInitSize = 16, USHORT _nReSize = 16 ) :
+ Container( CONTAINER_MAXBLOCKSIZE, _nInitSize, _nReSize ) {}
+ Stack( const Stack& rStack ) : Container( rStack ) {}
+
+ void Push( void* p ) { Container::Insert( p, CONTAINER_APPEND ); }
+ void* Pop() { return Container::Remove( Count()-1 ); }
+ void* Top() const { return Container::GetObject( Count()-1 ); }
+
+ Stack& operator =( const Stack& rStack )
+ { Container::operator =( rStack ); return *this; }
+
+ BOOL operator ==( const Stack& rStack ) const
+ { return Container::operator ==( rStack ); }
+ BOOL operator !=( const Stack& rStack ) const
+ { return Container::operator !=( rStack ); }
+};
+
+// -----------------
+// - DECLARE_STACK -
+// -----------------
+
+#define DECLARE_STACK( ClassName, Type ) \
+class ClassName : private Stack \
+{ \
+public: \
+ using Stack::Clear; \
+ using Stack::Count; \
+ \
+ ClassName( USHORT _nInitSize = 16, \
+ USHORT _nReSize = 16 ) : \
+ Stack( _nInitSize, _nReSize ) {} \
+ ClassName( const ClassName& rClassName ) : \
+ Stack( rClassName ) {} \
+ \
+ void Push( Type p ) { Stack::Push( (void*)p ); } \
+ Type Pop() { return (Type)Stack::Pop(); } \
+ Type Top() const { return (Type)Stack::Top(); } \
+ \
+ Type GetObject( ULONG nIndex ) const \
+ { return (Type)Stack::GetObject( nIndex ); } \
+ ULONG GetPos( const Type p ) const \
+ { return Stack::GetPos( (const void*)p ); } \
+ ULONG GetPos( const Type p, ULONG nStartIndex, \
+ BOOL bForward = TRUE ) const \
+ { return Stack::GetPos( (const void*)p, \
+ nStartIndex, \
+ bForward ); } \
+ \
+ ClassName& operator =( const ClassName& rClassName ) \
+ { Stack::operator =( rClassName ); \
+ return *this; } \
+ \
+ BOOL operator ==( const ClassName& rStack ) const \
+ { return Stack::operator ==( rStack ); } \
+ BOOL operator !=( const ClassName& rStack ) const \
+ { return Stack::operator !=( rStack ); } \
+};
+
+#endif // _STACK_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/stream.hxx b/tools/inc/tools/stream.hxx
new file mode 100644
index 000000000000..a50138913e45
--- /dev/null
+++ b/tools/inc/tools/stream.hxx
@@ -0,0 +1,857 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _STREAM_HXX
+#define _STREAM_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/solar.h>
+#include <tools/string.hxx>
+#include <tools/errinf.hxx>
+#include <tools/ref.hxx>
+#include <tools/rtti.hxx>
+
+class FileCopier;
+class StreamData;
+
+// ------------------------
+// - FileFormat-Functions -
+// ------------------------
+
+inline rtl_TextEncoding GetStoreCharSet( rtl_TextEncoding eEncoding )
+{
+ if ( eEncoding == RTL_TEXTENCODING_ISO_8859_1 )
+ return RTL_TEXTENCODING_MS_1252;
+ else
+ return eEncoding;
+}
+
+// ---------------
+// - StreamTypes -
+// ---------------
+
+typedef sal_uInt16 StreamMode;
+
+// read, write, create,... options
+#define STREAM_READ 0x0001 // allow read accesses
+#define STREAM_WRITE 0x0002 // allow write accesses
+// file i/o
+#define STREAM_NOCREATE 0x0004 // 1 == Dont create file
+#define STREAM_TRUNC 0x0008 // Truncate _existing_ file to zero length
+#define STREAM_COPY_ON_SYMLINK 0x0010 // copy-on-write for symlinks (UNX)
+
+#define STREAM_READWRITEBITS (STREAM_READ | STREAM_WRITE | \
+ STREAM_NOCREATE | STREAM_TRUNC)
+
+// sharing options
+#define STREAM_SHARE_DENYNONE 0x0100
+#define STREAM_SHARE_DENYREAD 0x0200 // overrides denynone
+#define STREAM_SHARE_DENYWRITE 0x0400 // overrides denynone
+#define STREAM_SHARE_DENYALL 0x0800 // overrides denyread,write,none
+
+#define STREAM_SHAREBITS (STREAM_SHARE_DENYNONE | STREAM_SHARE_DENYREAD |\
+ STREAM_SHARE_DENYWRITE | STREAM_SHARE_DENYALL)
+
+#define STREAM_READWRITE (STREAM_READ | STREAM_WRITE)
+#define STREAM_SHARE_DENYREADWRITE (STREAM_SHARE_DENYREAD | STREAM_SHARE_DENYWRITE)
+
+#define STREAM_STD_READ (STREAM_READ | STREAM_SHARE_DENYNONE | STREAM_NOCREATE)
+#define STREAM_STD_WRITE (STREAM_WRITE | STREAM_SHARE_DENYALL)
+#define STREAM_STD_READWRITE (STREAM_READWRITE | STREAM_SHARE_DENYALL)
+
+#define STREAM_SEEK_TO_BEGIN 0L
+#define STREAM_SEEK_TO_END ULONG_MAX
+
+#define NUMBERFORMAT_INT_BIGENDIAN (sal_uInt16)0x0000
+#define NUMBERFORMAT_INT_LITTLEENDIAN (sal_uInt16)0xFFFF
+
+#define COMPRESSMODE_FULL (sal_uInt16)0xFFFF
+#define COMPRESSMODE_NONE (sal_uInt16)0x0000
+#define COMPRESSMODE_ZBITMAP (sal_uInt16)0x0001
+#define COMPRESSMODE_NATIVE (sal_uInt16)0x0010
+
+#define JUSTIFY_RIGHT 0x00
+#define JUSTIFY_LEFT 0x01
+
+#define STREAM_IO_DONTKNOW 0
+#define STREAM_IO_READ 1
+#define STREAM_IO_WRITE 2
+
+#define ID_STREAM 1
+#define ID_FILESTREAM 2
+#define ID_MEMORYSTREAM 3
+#define ID_SHAREDMEMORYSTREAM 4
+#define ID_STORAGESTREAM 5
+#define ID_PERSISTSTREAM 6
+
+class SvStream;
+typedef SvStream& (*SvStrPtr)( SvStream& );
+
+// forward declaration with internal linkage
+inline SvStream& operator<<( SvStream& rStr, SvStrPtr f );
+
+// ---------------
+// - SvLockBytes -
+// ---------------
+
+enum LockType {};
+
+struct SvLockBytesStat
+{
+ sal_Size nSize;
+
+ SvLockBytesStat(): nSize(0) {}
+};
+
+enum SvLockBytesStatFlag { SVSTATFLAG_DEFAULT };
+
+class TOOLS_DLLPUBLIC SvLockBytes: public virtual SvRefBase
+{
+ SvStream * m_pStream;
+ sal_Bool m_bOwner;
+ sal_Bool m_bSync;
+
+protected:
+ void close();
+
+public:
+ TYPEINFO();
+
+ SvLockBytes(): m_pStream(0), m_bOwner(FALSE), m_bSync(FALSE) {}
+
+ SvLockBytes(SvStream * pTheStream, sal_Bool bTheOwner = FALSE):
+ m_pStream(pTheStream), m_bOwner(bTheOwner), m_bSync(FALSE) {}
+
+ virtual ~SvLockBytes() { close(); }
+
+ virtual const SvStream * GetStream() const { return m_pStream; }
+
+ virtual void SetSynchronMode(sal_Bool bTheSync = TRUE) { m_bSync = bTheSync; }
+
+ virtual sal_Bool IsSynchronMode() const { return m_bSync; }
+
+ virtual ErrCode ReadAt(sal_Size nPos, void * pBuffer, sal_Size nCount,
+ sal_Size * pRead) const;
+
+ virtual ErrCode WriteAt(sal_Size nPos, const void * pBuffer, sal_Size nCount,
+ sal_Size * pWritten);
+
+ virtual ErrCode Flush() const;
+
+ virtual ErrCode SetSize(sal_Size nSize);
+
+ virtual ErrCode LockRegion(sal_Size, sal_Size, LockType);
+
+ virtual ErrCode UnlockRegion(sal_Size, sal_Size, LockType);
+
+ virtual ErrCode Stat(SvLockBytesStat * pStat, SvLockBytesStatFlag) const;
+};
+
+SV_DECL_IMPL_REF(SvLockBytes);
+
+// -------------------
+// - SvOpenLockBytes -
+// -------------------
+
+class TOOLS_DLLPUBLIC SvOpenLockBytes: public SvLockBytes
+{
+public:
+ TYPEINFO();
+
+ SvOpenLockBytes(): SvLockBytes(0, FALSE) {}
+
+ SvOpenLockBytes(SvStream * pStream, sal_Bool bOwner):
+ SvLockBytes(pStream, bOwner) {}
+
+ virtual ErrCode FillAppend(const void * pBuffer, sal_Size nCount,
+ sal_Size * pWritten) = 0;
+
+ virtual sal_Size Tell() const = 0;
+
+ virtual sal_Size Seek(sal_Size nPos) = 0;
+
+ virtual void Terminate() = 0;
+};
+
+SV_DECL_IMPL_REF(SvOpenLockBytes);
+
+// --------------------
+// - SvAsyncLockBytes -
+// --------------------
+
+class SvAsyncLockBytes: public SvOpenLockBytes
+{
+ sal_Size m_nSize;
+ sal_Bool m_bTerminated;
+
+public:
+ TYPEINFO();
+
+ SvAsyncLockBytes(SvStream * pStream, sal_Bool bOwner):
+ SvOpenLockBytes(pStream, bOwner), m_nSize(0), m_bTerminated(FALSE) {}
+
+ virtual ErrCode ReadAt(sal_Size nPos, void * pBuffer, sal_Size nCount,
+ sal_Size * pRead) const;
+
+ virtual ErrCode WriteAt(sal_Size nPos, const void * pBuffer, sal_Size nCount,
+ sal_Size * pWritten);
+
+ virtual ErrCode FillAppend(const void * pBuffer, sal_Size nCount,
+ sal_Size * pWritten);
+
+ virtual sal_Size Tell() const { return m_nSize; }
+
+ virtual sal_Size Seek(sal_Size nPos);
+
+ virtual void Terminate() { m_bTerminated = TRUE; }
+};
+
+SV_DECL_IMPL_REF(SvAsyncLockBytes);
+
+// ----------
+// - Stream -
+// ----------
+
+class TOOLS_DLLPUBLIC SvStream
+{
+private:
+ // LockBytes Interface
+ void* pImp; // unused
+ SvLockBytesRef xLockBytes; // Default Implmentierung
+ sal_Size nActPos; //
+
+ // Puffer-Verwaltung
+ sal_uInt8* pRWBuf; // Zeigt auf Read/Write-Puffer
+ sal_uInt8* pBufPos; // pRWBuf + nBufActualPos
+ sal_uInt16 nBufSize; // Allozierte Groesse des Puffers
+ sal_uInt16 nBufActualLen; // Laenge des beschriebenen Teils des Puffers
+ // Entspricht nBufSize, wenn EOF nicht
+ // ueberschritten wurde
+ sal_uInt16 nBufActualPos; // aktuelle Position im Puffer (0..nBufSize-1)
+ sal_uInt16 nBufFree; // freier Platz im Puffer fuer IO vom Typ eIOMode
+ unsigned int eIOMode:2; // STREAM_IO_*
+
+ // Error-Codes, Konvertierung, Komprimierung, ...
+ int bIsDirty:1; // TRUE: Stream != Pufferinhalt
+ int bIsConsistent:1;// FALSE: Buffer enthaelt Daten, die NICHT
+ // per PutData in den abgeleiteten Stream
+ // geschrieben werden duerfen (siehe PutBack)
+ int bSwap:1;
+ int bIsEof:1;
+ sal_uInt32 nError;
+ sal_uInt16 nNumberFormatInt;
+ sal_uInt16 nCompressMode;
+ LineEnd eLineDelimiter;
+ CharSet eStreamCharSet;
+// CharSet eTargetCharSet;
+
+ // Verschluesselung
+ ByteString aKey; // aKey.Len != 0 -> Verschluesselung
+ unsigned char nCryptMask;
+
+ // Formatierung von Strings
+ char cFiller;
+ sal_uInt8 nRadix;
+ sal_uInt8 nPrecision;
+ sal_uInt8 nWidth;
+ sal_uInt8 nPrintfParams;
+ sal_uInt8 nJustification;
+ ByteString aFormatString;
+
+ // Userdata
+ long nVersion; // for external use
+
+ // Hilfsmethoden
+ void CreateFormatString();
+ TOOLS_DLLPRIVATE void ImpInit();
+
+ SvStream ( const SvStream& rStream ); // not implemented
+ SvStream& operator=( const SvStream& rStream ); // not implemented
+
+protected:
+ sal_Size nBufFilePos; // Fileposition von pBuf[0]
+ sal_uInt16 eStreamMode;
+ sal_Bool bIsWritable;
+
+ virtual sal_Size GetData( void* pData, sal_Size nSize );
+ virtual sal_Size PutData( const void* pData, sal_Size nSize );
+ virtual sal_Size SeekPos( sal_Size nPos );
+ virtual void FlushData();
+ virtual void SetSize( sal_Size nSize );
+
+ void ClearError();
+ void ClearBuffer();
+
+ // verschluesselt & schreibt blockweise
+ sal_Size CryptAndWriteBuffer( const void* pStart, sal_Size nLen );
+ sal_Bool EncryptBuffer( void* pStart, sal_Size nLen );
+
+ void SyncSvStream( sal_Size nNewStreamPos ); // SvStream <- Medium
+ void SyncSysStream(); // SvStream -> Medium
+
+public:
+ SvStream();
+ SvStream( SvLockBytes *pLockBytes);
+ virtual ~SvStream();
+
+ ErrCode SetLockBytes( SvLockBytesRef& rBytes );
+ SvLockBytes* GetLockBytes() const { return xLockBytes; }
+
+ sal_uInt32 GetError() const { return ERRCODE_TOERROR(nError); }
+ sal_uInt32 GetErrorCode() const { return nError; }
+
+ void SetError( sal_uInt32 nErrorCode );
+ virtual void ResetError();
+
+ void SetNumberFormatInt( sal_uInt16 nNewFormat );
+ sal_uInt16 GetNumberFormatInt() const { return nNumberFormatInt; }
+ /// Enable/disable swapping of endians, may be needed for Unicode import/export
+ inline void SetEndianSwap( sal_Bool bVal );
+ // returns status of endian swap flag
+ sal_Bool IsEndianSwap() const { return 0 != bSwap; }
+
+ void SetCompressMode( sal_uInt16 nNewMode )
+ { nCompressMode = nNewMode; }
+ sal_uInt16 GetCompressMode() const { return nCompressMode; }
+
+ void SetKey( const ByteString& rKey );
+ const ByteString& GetKey() const { return aKey; }
+
+ void SetStreamCharSet( CharSet eCharSet )
+ { eStreamCharSet = eCharSet; }
+ CharSet GetStreamCharSet() const { return eStreamCharSet; }
+// void SetTargetCharSet( CharSet eCharSet )
+// { eTargetCharSet = eCharSet; }
+// CharSet GetTargetCharSet() const { return eTargetCharSet; }
+
+ void SetLineDelimiter( LineEnd eLineEnd )
+ { eLineDelimiter = eLineEnd; }
+ LineEnd GetLineDelimiter() const { return eLineDelimiter; }
+
+ SvStream& operator>>( sal_uInt16& rUInt16 );
+ SvStream& operator>>( sal_uInt32& rUInt32 );
+ SvStream& operator>>( long& rLong );
+ SvStream& operator>>( short& rShort );
+ SvStream& operator>>( int& rInt );
+ SvStream& operator>>( signed char& rChar );
+ SvStream& operator>>( char& rChar );
+ SvStream& operator>>( unsigned char& rChar );
+ SvStream& operator>>( float& rFloat );
+ SvStream& operator>>( double& rDouble );
+#ifdef ENABLE_BYTESTRING_STREAM_OPERATORS
+ SvStream& operator>>( ByteString& rString ) { return ReadByteString(rString); }
+#endif
+#ifdef ENABLE_STRING_STREAM_OPERATORS
+ SvStream& operator>>( UniString& rString ) { return ReadByteString(rString); }
+#endif
+ SvStream& operator>>( SvStream& rStream );
+
+ SvStream& operator<<( sal_uInt16 nUInt16 );
+ SvStream& operator<<( sal_uInt32 nUInt32 );
+ SvStream& operator<<( long nLong );
+ SvStream& operator<<( short nShort );
+ SvStream& operator<<( int nInt );
+ SvStream& operator<<( signed char nChar );
+ SvStream& operator<<( char nChar );
+ SvStream& operator<<( unsigned char nChar );
+ SvStream& operator<<( float nFloat );
+ SvStream& operator<<( const double& rDouble );
+ SvStream& operator<<( const char* pBuf );
+ SvStream& operator<<( const unsigned char* pBuf );
+#ifdef ENABLE_BYTESTRING_STREAM_OPERATORS
+ SvStream& operator<<( const ByteString& rString ) { return WriteByteString( rString ); }
+#endif
+#ifdef ENABLE_STRING_STREAM_OPERATORS
+ SvStream& operator<<( const UniString& rString ) { return WriteByteString(rString); }
+#endif
+ SvStream& operator<<( SvStream& rStream );
+
+ SvStream& ReadByteString( UniString& rStr, rtl_TextEncoding eSrcCharSet );
+ SvStream& ReadByteString( UniString& rStr ) { return ReadByteString( rStr, GetStreamCharSet() ); }
+ SvStream& ReadByteString( ByteString& rStr );
+ SvStream& WriteByteString( const UniString& rStr, rtl_TextEncoding eDestCharSet );
+ SvStream& WriteByteString( const UniString& rStr ) { return WriteByteString( rStr, GetStreamCharSet() ); }
+ SvStream& WriteByteString( const ByteString& rStr );
+
+ void SetRadix( sal_uInt8 nRad )
+ { nRadix = nRad; CreateFormatString(); }
+ sal_uInt8 GetRadix() const { return nRadix; }
+ void SetPrecision( sal_uInt8 nPrec )
+ { nPrecision = nPrec; CreateFormatString(); }
+ sal_uInt8 GetPrecision() const { return nPrecision; }
+ void SetWidth( sal_uInt8 nWid)
+ { nWidth = nWid; CreateFormatString(); }
+ sal_uInt8 GetWidth() const { return nWidth; }
+ void SetFiller( char cFil )
+ { cFiller = cFil; CreateFormatString(); }
+ char GetFiller() const { return cFiller; }
+ void SetJustification( sal_uInt8 nJus )
+ { nJustification = nJus; CreateFormatString(); }
+ sal_uInt8 GetJustification() const { return nJustification; }
+
+ SvStream& ReadNumber( short& rShort );
+ SvStream& ReadNumber( sal_uInt16& rUInt16 );
+ SvStream& ReadNumber( long& rLong );
+ SvStream& ReadNumber( sal_uInt32& rUInt32 );
+ SvStream& ReadNumber( int& rInt );
+ SvStream& ReadNumber( float& rFloat );
+ SvStream& ReadNumber( double& rDouble );
+
+ SvStream& WriteNumber( short nShort );
+ SvStream& WriteNumber( sal_uInt16 nUInt16 );
+ SvStream& WriteNumber( long nLong );
+ SvStream& WriteNumber( sal_uInt32 nUInt32 );
+ SvStream& WriteNumber( int nInt );
+ SvStream& WriteNumber( float nFloat );
+ SvStream& WriteNumber( const double& rDouble );
+
+ sal_Size Read( void* pData, sal_Size nSize );
+ sal_Size Write( const void* pData, sal_Size nSize );
+ sal_Size Seek( sal_Size nPos );
+ sal_Size SeekRel( sal_sSize nPos );
+ sal_Size Tell() const { return nBufFilePos+nBufActualPos; }
+ void Flush();
+ sal_Bool IsEof() const { return bIsEof; }
+ // next Tell() <= nSize
+ sal_Bool SetStreamSize( sal_Size nSize );
+
+ /// Read in the stream to a zero character and put all
+ /// read chracters in the Bytestring. The String interface
+ /// convert the BytString with the given encoding to a String
+ sal_Bool ReadCString( ByteString& rStr );
+ sal_Bool ReadCString( String& rStr, rtl_TextEncoding eToEncode );
+ sal_Bool ReadCString( String& rStr ) { return ReadCString( rStr, GetStreamCharSet()); }
+
+ sal_Bool ReadLine( ByteString& rStr );
+ sal_Bool WriteLine( const ByteString& rStr );
+ sal_Bool WriteLines( const ByteString& rStr );
+
+ sal_Bool ReadByteStringLine( String& rStr, rtl_TextEncoding eSrcCharSet );
+ sal_Bool ReadByteStringLine( String& rStr ) { return ReadByteStringLine( rStr, GetStreamCharSet()); }
+ sal_Bool WriteByteStringLine( const String& rStr, rtl_TextEncoding eDestCharSet );
+ sal_Bool WriteByteStringLine( const String& rStr ) { return WriteByteStringLine( rStr, GetStreamCharSet()); }
+ sal_Bool WriteByteStringLines( const String& rStr, rtl_TextEncoding eDestCharSet );
+ sal_Bool WriteByteStringLines( const String& rStr ) { return WriteByteStringLine( rStr, GetStreamCharSet()); }
+
+ /// Switch to no endian swapping and write 0xfeff
+ sal_Bool StartWritingUnicodeText();
+ /// Read 16bit, if 0xfeff do nothing, if 0xfffe switch
+ /// endian swapping, if none of them put back
+ sal_Bool StartReadingUnicodeText();
+
+ /// Read a line of Unicode
+ sal_Bool ReadUniStringLine( String& rStr );
+ /// Read a line of Unicode if eSrcCharSet==RTL_TEXTENCODING_UNICODE,
+ /// otherwise read a line of Bytecode and convert from eSrcCharSet
+ sal_Bool ReadUniOrByteStringLine( String& rStr, rtl_TextEncoding eSrcCharSet );
+ sal_Bool ReadUniOrByteStringLine( String& rStr )
+ { return ReadUniOrByteStringLine( rStr, GetStreamCharSet() ); }
+ /// Write a sequence of Unicode characters
+ sal_Bool WriteUnicodeText( const String& rStr );
+ /// Write a sequence of Unicode characters if eDestCharSet==RTL_TEXTENCODING_UNICODE,
+ /// otherwise write a sequence of Bytecodes converted to eDestCharSet
+ sal_Bool WriteUnicodeOrByteText( const String& rStr, rtl_TextEncoding eDestCharSet );
+ sal_Bool WriteUnicodeOrByteText( const String& rStr )
+ { return WriteUnicodeOrByteText( rStr, GetStreamCharSet() ); }
+ /// Write a line of Unicode and append line end (endlu())
+ sal_Bool WriteUniStringLine( const String& rStr );
+ /// Write multiple lines of Unicode (with CovertLineEnd) and append line end (endlu())
+ sal_Bool WriteUniStringLines( const String& rStr );
+ /// Write a line of Unicode if eDestCharSet==RTL_TEXTENCODING_UNICODE,
+ /// otherwise write a line of Bytecode converted to eDestCharSet
+ sal_Bool WriteUniOrByteStringLine( const String& rStr, rtl_TextEncoding eDestCharSet );
+ sal_Bool WriteUniOrByteStringLine( const String& rStr )
+ { return WriteUniOrByteStringLine( rStr, GetStreamCharSet() ); }
+ /// Write multiple lines of Unicode if eDestCharSet==RTL_TEXTENCODING_UNICODE,
+ /// otherwise write multiple lines of Bytecode converted to eDestCharSet,
+ /// CovertLineEnd is applied.
+ sal_Bool WriteUniOrByteStringLines( const String& rStr, rtl_TextEncoding eDestCharSet );
+ sal_Bool WriteUniOrByteStringLines( const String& rStr )
+ { return WriteUniOrByteStringLines( rStr, GetStreamCharSet() ); }
+ /// Write a Unicode character if eDestCharSet==RTL_TEXTENCODING_UNICODE,
+ /// otherwise write as Bytecode converted to eDestCharSet.
+ /// This may result in more than one byte being written
+ /// if a multi byte encoding (e.g. UTF7, UTF8) is chosen.
+ sal_Bool WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet );
+ sal_Bool WriteUniOrByteChar( sal_Unicode ch )
+ { return WriteUniOrByteChar( ch, GetStreamCharSet() ); }
+
+ /** Read a CSV (comma separated values) data line using
+ ReadUniOrByteStringLine().
+
+ @param bEmbeddedLineBreak
+ If sal_True and a line-break occurs inside a field of data,
+ a line feed LF '\n' and the next line are appended. Repeats
+ until a line-break is not in a field. A field is determined
+ by delimiting rFieldSeparators and optionally surrounded by
+ a pair of cFieldQuote characters. For a line-break to be
+ within a field, the field content MUST be surrounded by
+ cFieldQuote characters, and the opening cFieldQuote MUST be
+ at the very start of a line or follow right behind a field
+ separator with no extra characters in between. Anything,
+ including field separators and escaped quotes (by doubling
+ them, or preceding them with a backslash if
+ bAllowBackslashEscape==sal_True) may appear in a quoted
+ field.
+
+ If bEmbeddedLineBreak==sal_False, nothing is parsed and the
+ string returned is simply one ReadUniOrByteStringLine().
+
+ @param rFieldSeparators
+ A list of characters that each may act as a field separator.
+
+ @param cFieldQuote
+ The quote character used.
+
+ @param bAllowBackslashEscape
+ If sal_True, an embedded quote character inside a quoted
+ field may also be escaped with a preceding backslash.
+ Normally, quotes are escaped by doubling them.
+
+ @return
+ sal_True if no stream error.
+
+ @ATTENTION
+ Note that the string returned may be truncated even inside
+ a quoted field if STRING_MAXLEN was reached. There
+ currently is no way to exactly determine the conditions,
+ whether this was at a line end, or whether open quotes
+ would have closed the field before the line end, as even a
+ ReadUniOrByteStringLine() may return prematurely but the
+ stream was positioned ahead until the real end of line.
+ Additionally, due to character encoding conversions, string
+ length and bytes read don't necessarily match, and
+ resyncing to a previous position matching the string's
+ length isn't always possible. As a result, a logical line
+ with embedded line breaks and more than STRING_MAXLEN
+ characters will be spoiled, and a subsequent ReadCsvLine()
+ may start under false preconditions.
+ */
+ sal_Bool ReadCsvLine( String& rStr, sal_Bool bEmbeddedLineBreak,
+ const String& rFieldSeparators, sal_Unicode cFieldQuote,
+ sal_Bool bAllowBackslashEscape = sal_False);
+
+ void SetBufferSize( sal_uInt16 nBufSize );
+ sal_uInt16 GetBufferSize() const { return nBufSize; }
+
+ void RefreshBuffer();
+ SvStream& PutBack( char aCh );
+ void EatWhite();
+
+ sal_Bool IsWritable() const { return bIsWritable; }
+ StreamMode GetStreamMode() const { return eStreamMode; }
+ virtual sal_uInt16 IsA() const;
+
+ long GetVersion() { return nVersion; }
+ void SetVersion( long n ) { nVersion = n; }
+
+ /** Add a mark to indicate to which position in the stream you want to be
+ able to seek back.
+
+ @descr If you set a mark at nPos, you indicate to the stream that you
+ won't issue seek operations to any position 'before' nPos. This can
+ be exploited by 'transient streams' that do not permanently store
+ their data; they can discard any buffered data up to nPos.
+
+ @descr However, if the stream is already positioned past nPos, this
+ method is not guaranteed to have the desired effect. A 'transient
+ stream' may have already discarded the buffered data at nPos, so that
+ a seek operation to nPos will fail nonetheless.
+
+ @descr There can be more than one mark for a stream, indicating that
+ you want to be able to seek back in the stream as far as the 'lowest'
+ off all the marks. There can even be multiple marks at the same
+ position (and they must all be individually removed with
+ RemoveMark()).
+
+ @param nPos The position in the stream at which to add a mark.
+ */
+ virtual void AddMark(sal_Size nPos);
+
+ /** Remove a mark introduced with AddMark().
+
+ @descr If you no longer need to seek back to some position for which
+ you added a mark, you should remove that mark. (And a 'transient
+ stream' that does not permanently store its data can then potentially
+ discard some of its buffered data.)
+
+ @descr Removing one mark does not have any effects on any other
+ marks. Especially, if you have multiple marks at the same position,
+ you must call this method multiple times to effectively 'unmark' that
+ position.
+
+ @descr If you specify a position for which there is no mark, this
+ method simply has no effect.
+
+ @param nPos The position in the stream at which to remove the mark.
+ */
+ virtual void RemoveMark(sal_Size nPos);
+
+ friend SvStream& operator<<( SvStream& rStr, SvStrPtr f ); // fuer Manips
+};
+
+inline SvStream& operator<<( SvStream& rStr, SvStrPtr f )
+{
+ (*f)(rStr);
+ return rStr;
+}
+
+inline SvStream& SvStream::ReadNumber( short& rShort )
+{
+ long nTmp;
+ ReadNumber( nTmp );
+ rShort = (short)nTmp;
+ return *this;
+}
+
+inline SvStream& SvStream::ReadNumber( sal_uInt16& rUShort )
+{
+ sal_uInt32 nTmp;
+ ReadNumber( nTmp );
+ rUShort = (sal_uInt16)nTmp;
+ return *this;
+}
+
+inline SvStream& SvStream::ReadNumber( int& rInt )
+{
+ long nTmp;
+ ReadNumber( nTmp );
+ rInt = (int)nTmp;
+ return *this;
+}
+
+/*
+inline SvStream& SvStream::ReadNumber( unsigned int& rUInt )
+{
+ ULONG nTmp;
+ ReadNumber( nTmp );
+ rUInt = (unsigned int)nTmp;
+ return *this;
+}
+*/
+
+inline SvStream& SvStream::ReadNumber( float& rFloat )
+{
+ double nTmp;
+ ReadNumber( nTmp );
+ rFloat = (float)nTmp;
+ return *this;
+}
+
+inline SvStream& SvStream::WriteNumber( short nShort )
+{
+ WriteNumber( (long)nShort );
+ return *this;
+}
+
+inline SvStream& SvStream::WriteNumber( sal_uInt16 nUShort )
+{
+ WriteNumber( (sal_uInt32)nUShort );
+ return *this;
+}
+
+inline SvStream& SvStream::WriteNumber( int nInt )
+{
+ WriteNumber( (long)nInt );
+ return *this;
+}
+
+/*
+inline SvStream& SvStream::WriteNumber( unsigned int nUInt )
+{
+ WriteNumber( (ULONG)nUInt );
+ return *this;
+}
+*/
+
+inline SvStream& SvStream::WriteNumber( float nFloat )
+{
+ double nTemp = nFloat;
+ WriteNumber( nTemp );
+ return *this;
+}
+
+inline void SvStream::SetEndianSwap( sal_Bool bVal )
+{
+#ifdef OSL_BIGENDIAN
+ SetNumberFormatInt( bVal ? NUMBERFORMAT_INT_LITTLEENDIAN : NUMBERFORMAT_INT_BIGENDIAN );
+#else
+ SetNumberFormatInt( bVal ? NUMBERFORMAT_INT_BIGENDIAN : NUMBERFORMAT_INT_LITTLEENDIAN );
+#endif
+}
+
+TOOLS_DLLPUBLIC SvStream& endl( SvStream& rStr );
+/// same as endl() but Unicode
+TOOLS_DLLPUBLIC SvStream& endlu( SvStream& rStr );
+/// call endlu() if eStreamCharSet==RTL_TEXTECODING_UNICODE otherwise endl()
+TOOLS_DLLPUBLIC SvStream& endlub( SvStream& rStr );
+
+// --------------
+// - FileStream -
+// --------------
+
+class TOOLS_DLLPUBLIC SvFileStream : public SvStream
+{
+ friend class ImpEaMgr;
+ friend class CORmFileStream;
+ friend class FileCopier;
+
+private:
+ StreamData* pInstanceData;
+ String aFilename;
+ sal_uInt16 nLockCounter;
+ sal_Bool bIsOpen;
+ sal_uInt32 GetFileHandle() const;
+
+ // Forbidden and not implemented.
+ SvFileStream (const SvFileStream&);
+ SvFileStream & operator= (const SvFileStream&);
+
+protected:
+
+ virtual sal_Size GetData( void* pData, sal_Size nSize );
+ virtual sal_Size PutData( const void* pData, sal_Size nSize );
+ virtual sal_Size SeekPos( sal_Size nPos );
+ virtual void SetSize( sal_Size nSize );
+ virtual void FlushData();
+
+public:
+ // Schaltet bei fehlgeschlagenem Schreiboeffnen auf Lesen zurueck
+ SvFileStream( const String& rFileName, StreamMode eOpenMode );
+ SvFileStream();
+ ~SvFileStream();
+
+ virtual void ResetError();
+
+ sal_Bool LockRange( sal_Size nByteOffset, sal_Size nBytes );
+ sal_Bool UnlockRange( sal_Size nByteOffset, sal_Size nBytes );
+ sal_Bool LockFile();
+ sal_Bool UnlockFile();
+
+ void Open( const String& rFileName, StreamMode eOpenMode );
+ void Close();
+ void ReOpen(); // Aufruf nach Close, FilePointer == 0
+ sal_Bool IsOpen() const { return bIsOpen; }
+ sal_Bool IsLocked() const { return ( nLockCounter!=0 ); }
+ virtual sal_uInt16 IsA() const;
+
+ const String& GetFileName() const { return aFilename; }
+};
+
+// ----------------
+// - MemoryStream -
+// ----------------
+
+class TOOLS_DLLPUBLIC SvMemoryStream : public SvStream
+{
+ // Forbidden and not implemented.
+ SvMemoryStream (const SvMemoryStream&);
+ SvMemoryStream & operator= (const SvMemoryStream&);
+
+ friend class SvCacheStream;
+ sal_Size GetSize() const { return nSize; }
+
+protected:
+ sal_Size nSize;
+ sal_Size nResize;
+ sal_Size nPos;
+ sal_Size nEndOfData;
+ sal_uInt8* pBuf;
+ sal_Bool bOwnsData;
+
+ virtual sal_Size GetData( void* pData, sal_Size nSize );
+ virtual sal_Size PutData( const void* pData, sal_Size nSize );
+ virtual sal_Size SeekPos( sal_Size nPos );
+ virtual void SetSize( sal_Size nSize );
+ virtual void FlushData();
+
+ // AllocateMemory muss folgende Variable mitpflegen:
+ // - pBuf: Adresse des neuen Blocks
+ virtual sal_Bool AllocateMemory( sal_Size nSize );
+
+ // ReAllocateMemory muss folgende Variablen mitpflegen:
+ // - pBuf: Adresse des neuen Blocks
+ // - nEndOfData: Muss auf nNewSize-1L gesetzt werden, wenn ausserhalb des Blocks
+ // Muss auf 0 gesetzt werden, wenn neuer Block 0 Byte gross
+ // - nSize: Neue Groesse des Blocks
+ // - nPos: Muss auf 0 gesetzt werden, wenn ausserhalb des Blocks
+ virtual sal_Bool ReAllocateMemory( long nDiff );
+
+ // wird aufgerufen, wenn dem Stream der Speicher gehoert oder wenn
+ // der Speicher in der Groesse veraendert wird.
+ // FreeMemory muss folgende Variablen mitpflegen:
+ // - in abgeleiteten Klassen muessen ggf. Handles genullt werden
+ virtual void FreeMemory();
+
+ SvMemoryStream(void*) { } // Fuer unsere Subklassen
+
+public:
+ SvMemoryStream( void* pBuf, sal_Size nSize, StreamMode eMode);
+ SvMemoryStream( sal_Size nInitSize=512, sal_Size nResize=64 );
+ ~SvMemoryStream();
+
+ virtual void ResetError();
+
+ sal_Size GetEndOfData() const { return nEndOfData; }
+ const void* GetData() { Flush(); return pBuf; }
+ operator const void*() { Flush(); return pBuf; }
+ virtual sal_uInt16 IsA() const;
+
+ void* SwitchBuffer( sal_Size nInitSize=512, sal_Size nResize=64 );
+ void* SetBuffer( void* pBuf, sal_Size nSize,
+ sal_Bool bOwnsData=TRUE, sal_Size nEOF=0 );
+
+ void ObjectOwnsMemory( sal_Bool bOwn ) { bOwnsData = bOwn; }
+ sal_Bool IsObjectMemoryOwner() { return bOwnsData; }
+ void SetResizeOffset( sal_Size nNewResize ) { nResize = nNewResize; }
+ sal_Size GetResizeOffset() const { return nResize; }
+};
+
+// --------------------
+// - SvDataCopyStream -
+// --------------------
+
+// AB 10.5.1996: Diese Klasse bildet die Basis fuer Klassen, die mittels
+// SvData (SO2\DTRANS.HXX/CXX) transportiert werden sollen, z.B. Graphik
+// Die abgeleiteten Klassen muessen die virtuellen Funktionen ueberladen.
+
+class TOOLS_DLLPUBLIC SvDataCopyStream
+{
+public:
+ /*-----------------MM 30.04.96 11:01-----------------
+ mehrfaches Aufrufen von Load und Assign erlaubt
+ --------------------------------------------------*/
+ TYPEINFO();
+ virtual ~SvDataCopyStream(){}
+ virtual void Load( SvStream & ) = 0;
+ virtual void Save( SvStream & ) = 0;
+ virtual void Assign( const SvDataCopyStream & );
+};
+
+#endif // _STREAM_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/string.hxx b/tools/inc/tools/string.hxx
new file mode 100644
index 000000000000..cb6b455ade11
--- /dev/null
+++ b/tools/inc/tools/string.hxx
@@ -0,0 +1,698 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _STRING_HXX
+#define _STRING_HXX
+
+#include <tools/solar.h>
+#include <osl/thread.h>
+#include <rtl/textenc.h>
+#include <rtl/textcvt.h>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+#include "tools/toolsdllapi.h"
+
+/*******************************************************************************
+ *
+ * THIS CODE IS DEPRECATED. DO NOT USE IT IN ANY NEW CODE.
+ *
+ * Use the string classes in rtl/ustring.hxx and rtl/ustrbuf.hxx (and
+ * rtl/string.hxx and rtl/strbuf.hxx for byte-sized strings) instead. If you
+ * feel functionality missing from those string classes, please request
+ * improvements on discuss@openoffice.org.
+ *
+ * There will not be any fixes to the code here.
+ ******************************************************************************/
+
+// -----------------------------------------------------------------------
+
+class ResId;
+class String;
+class ByteString;
+class UniString;
+
+// -----------------------------------------------------------------------
+
+#define BYTESTRING_TO_UNISTRING_CVTFLAGS (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MAPTOPRIVATE |\
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |\
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT)
+#define UNISTRING_TO_BYTESTRING_CVTFLAGS (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT |\
+ RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT |\
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE |\
+ RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 |\
+ RTL_UNICODETOTEXT_FLAGS_NOCOMPOSITE)
+
+// -----------------------------------------------------------------------
+
+// -----------
+// - CharSet -
+// -----------
+
+#ifndef ENUM_CHARSET_DECLARED
+#define ENUM_CHARSET_DECLARED
+
+typedef rtl_TextEncoding CharSet;
+
+#endif // ENUM_CHARSET_DECLARED
+
+inline rtl_TextEncoding gsl_getSystemTextEncoding()
+{
+ return osl_getThreadTextEncoding();
+}
+
+// -----------------------------------------------------------------------
+
+// -----------
+// - LineEnd -
+// -----------
+
+enum LineEnd { LINEEND_CR, LINEEND_LF, LINEEND_CRLF };
+
+inline LineEnd GetSystemLineEnd()
+{
+#if defined UNX
+ return LINEEND_LF;
+#else
+ return LINEEND_CRLF;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+// ----------------
+// - String-Types -
+// ----------------
+
+#ifdef STRING32
+#define STRING_NOTFOUND ((xub_StrLen)0x7FFFFFFF)
+#define STRING_MATCH ((xub_StrLen)0x7FFFFFFF)
+#define STRING_LEN ((xub_StrLen)0x7FFFFFFF)
+#define STRING_MAXLEN ((xub_StrLen)0x7FFFFFFF)
+#else
+#define STRING_NOTFOUND ((xub_StrLen)0xFFFF)
+#define STRING_MATCH ((xub_StrLen)0xFFFF)
+#define STRING_LEN ((xub_StrLen)0xFFFF)
+#define STRING_MAXLEN ((xub_StrLen)0xFFFF)
+#endif
+
+enum StringCompare { COMPARE_LESS = -1, COMPARE_EQUAL = 0, COMPARE_GREATER = 1 };
+
+// -----------------------------------------------------------------------
+
+// ------------------------
+// - Interne String-Daten -
+// ------------------------
+
+// Daten vom String, mit denen der String verwaltet wird
+// Nur fuer Debug-Zwecke (darf nie direkt einem String zugewiesen werden)
+
+#ifdef SAL_W32
+#pragma pack(push, 8)
+#elif defined(SAL_OS2)
+#pragma pack(1)
+#endif
+
+typedef struct _ByteStringData
+{
+ sal_Int32 mnRefCount; // Referenz counter
+ sal_Int32 mnLen; // Length of the String
+ sal_Char maStr[1]; // CharArray (String)
+} ByteStringData;
+
+#ifdef SAL_W32
+#pragma pack(pop)
+#elif defined(SAL_OS2)
+#pragma pack()
+#endif
+
+// --------------
+// - ByteString -
+// --------------
+
+class TOOLS_DLLPUBLIC ByteString
+{
+ friend class UniString;
+
+ TOOLS_DLLPRIVATE void InitStringRes( const UniString& rStr );
+
+private:
+ ByteStringData* mpData;
+
+ TOOLS_DLLPRIVATE inline void ImplCopyData();
+ TOOLS_DLLPRIVATE inline char * ImplCopyStringData(char *);
+ TOOLS_DLLPRIVATE void ImplUpdateStringFromUniString(
+ sal_Unicode const *, sal_Size, rtl_TextEncoding, sal_uInt32);
+ TOOLS_DLLPRIVATE void ImplStringConvert(
+ rtl_TextEncoding, rtl_TextEncoding, BOOL);
+
+ ByteString( const int* pDummy ); // not implemented: to prevent ByteString( NULL )
+ ByteString(int); // not implemented; to detect misuses
+ // of ByteString(sal_Char);
+ void Assign(int); // not implemented; to detect misuses of
+ // Assign(sal_Char)
+ void operator =(int); // not implemented; to detect misuses
+ // of operator =(sal_Char)
+ void Append(int); // not implemented; to detect misuses of
+ // Append(char)
+ void operator +=(int); // not implemented; to detect misuses
+ // of operator +=(sal_Char)
+
+public:
+ ByteString();
+ ByteString( const ByteString& rStr );
+ ByteString( const ByteString& rStr, xub_StrLen nPos, xub_StrLen nLen );
+ ByteString( const rtl::OString& rStr );
+ ByteString( const sal_Char* pCharStr );
+ ByteString( const sal_Char* pCharStr, xub_StrLen nLen );
+ ByteString( sal_Char c );
+ ByteString( const UniString& rUniStr,
+ rtl_TextEncoding eTextEncoding,
+ sal_uInt32 nCvtFlags = UNISTRING_TO_BYTESTRING_CVTFLAGS );
+ ByteString( const UniString& rUniStr, xub_StrLen nPos, xub_StrLen nLen,
+ rtl_TextEncoding eTextEncoding,
+ sal_uInt32 nCvtFlags = UNISTRING_TO_BYTESTRING_CVTFLAGS );
+ ByteString( const sal_Unicode* pUniStr,
+ rtl_TextEncoding eTextEncoding,
+ sal_uInt32 nCvtFlags = UNISTRING_TO_BYTESTRING_CVTFLAGS );
+ ByteString( const sal_Unicode* pUniStr, xub_StrLen nLen,
+ rtl_TextEncoding eTextEncoding,
+ sal_uInt32 nCvtFlags = UNISTRING_TO_BYTESTRING_CVTFLAGS );
+ ~ByteString();
+
+ operator rtl::OString () const
+ {
+ return rtl::OString (reinterpret_cast<rtl_String*>(mpData));
+ }
+
+ static ByteString CreateFromInt32( sal_Int32 n, sal_Int16 nRadix = 10 );
+ static ByteString CreateFromInt64( sal_Int64 n, sal_Int16 nRadix = 10 );
+ static ByteString CreateFromFloat( float f );
+ static ByteString CreateFromDouble( double d );
+ static const ByteString& EmptyString();
+ sal_Int32 ToInt32() const;
+ sal_Int64 ToInt64() const;
+ float ToFloat() const;
+ double ToDouble() const;
+
+ ByteString& Assign( const ByteString& rStr );
+ ByteString& Assign( const rtl::OString& rStr );
+ ByteString& Assign( const sal_Char* pCharStr );
+ ByteString& Assign( const sal_Char* pCharStr, xub_StrLen nLen );
+ ByteString& Assign( sal_Char c );
+ ByteString& operator =( const ByteString& rStr )
+ { return Assign( rStr ); }
+ ByteString& operator =( const rtl::OString& rStr )
+ { return Assign( rStr ); }
+ ByteString& operator =( const sal_Char* pCharStr )
+ { return Assign( pCharStr ); }
+ ByteString& operator =( const sal_Char c )
+ { return Assign( c ); }
+
+ ByteString& Append( const ByteString& rStr );
+ ByteString& Append( const sal_Char* pCharStr );
+ ByteString& Append( const sal_Char* pCharStr, xub_StrLen nLen );
+ ByteString& Append( char c );
+ ByteString& operator +=( const ByteString& rStr )
+ { return Append( rStr ); }
+ ByteString& operator +=( const sal_Char* pCharStr )
+ { return Append( pCharStr ); }
+ ByteString& operator +=( sal_Char c )
+ { return Append( c ); }
+
+ void SetChar( xub_StrLen nIndex, sal_Char c );
+ sal_Char GetChar( xub_StrLen nIndex ) const
+ { return mpData->maStr[nIndex]; }
+
+ xub_StrLen Len() const { return (xub_StrLen)mpData->mnLen; }
+
+ ByteString& Insert( const ByteString& rStr, xub_StrLen nIndex = STRING_LEN );
+ ByteString& Insert( const ByteString& rStr, xub_StrLen nPos, xub_StrLen nLen,
+ xub_StrLen nIndex = STRING_LEN );
+ ByteString& Insert( const sal_Char* pCharStr, xub_StrLen nIndex = STRING_LEN );
+ ByteString& Insert( sal_Char c, xub_StrLen nIndex = STRING_LEN );
+ ByteString& Replace( xub_StrLen nIndex, xub_StrLen nCount, const ByteString& rStr );
+ ByteString& Erase( xub_StrLen nIndex = 0, xub_StrLen nCount = STRING_LEN );
+ ByteString Copy( xub_StrLen nIndex = 0, xub_StrLen nCount = STRING_LEN ) const;
+
+ ByteString& Fill( xub_StrLen nCount, sal_Char cFillChar = ' ' );
+ ByteString& Expand( xub_StrLen nCount, sal_Char cExpandChar = ' ' );
+
+ ByteString& EraseLeadingChars( sal_Char c = ' ' );
+ ByteString& EraseTrailingChars( sal_Char c = ' ' );
+ ByteString& EraseLeadingAndTrailingChars( sal_Char c = ' ' );
+ ByteString& EraseAllChars( sal_Char c = ' ' );
+ ByteString& Reverse();
+
+ ByteString& Convert( rtl_TextEncoding eSource,
+ rtl_TextEncoding eTarget,
+ BOOL bReplace = TRUE );
+ static sal_Char Convert( sal_Char c, rtl_TextEncoding eSource,
+ rtl_TextEncoding eTarget,
+ BOOL bReplace = TRUE );
+ static sal_Unicode ConvertToUnicode( sal_Char c,
+ rtl_TextEncoding eTextEncoding );
+ static sal_Char ConvertFromUnicode( sal_Unicode c,
+ rtl_TextEncoding eTextEncoding,
+ BOOL bReplace = TRUE );
+ static sal_Unicode ConvertToUnicode( const sal_Char* pChar, sal_Size* pLen,
+ rtl_TextEncoding eTextEncoding );
+ static sal_Size ConvertFromUnicode( sal_Unicode c, sal_Char* pBuf, sal_Size nBufLen,
+ rtl_TextEncoding eTextEncoding,
+ BOOL bReplace = TRUE );
+ ByteString& ConvertLineEnd( LineEnd eLineEnd );
+ ByteString& ConvertLineEnd()
+ { return ConvertLineEnd( GetSystemLineEnd() ); }
+
+ BOOL IsLowerAscii() const;
+ BOOL IsUpperAscii() const;
+ BOOL IsAlphaAscii() const;
+ BOOL IsNumericAscii() const;
+ BOOL IsAlphaNumericAscii() const;
+
+ ByteString& ToLowerAscii();
+ ByteString& ToUpperAscii();
+
+ StringCompare CompareTo( const ByteString& rStr,
+ xub_StrLen nLen = STRING_LEN ) const;
+ StringCompare CompareTo( const sal_Char* pCharStr,
+ xub_StrLen nLen = STRING_LEN ) const;
+ StringCompare CompareIgnoreCaseToAscii( const ByteString& rStr,
+ xub_StrLen nLen = STRING_LEN ) const;
+ StringCompare CompareIgnoreCaseToAscii( const sal_Char* pCharStr,
+ xub_StrLen nLen = STRING_LEN ) const;
+ BOOL Equals( const ByteString& rStr ) const;
+ BOOL Equals( const sal_Char* pCharStr ) const;
+ BOOL EqualsIgnoreCaseAscii( const ByteString& rStr ) const;
+ BOOL EqualsIgnoreCaseAscii( const sal_Char* pCharStr ) const;
+ BOOL Equals( const ByteString& rStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+ BOOL Equals( const sal_Char* pCharStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+ BOOL EqualsIgnoreCaseAscii( const ByteString& rStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+ BOOL EqualsIgnoreCaseAscii( const sal_Char* pCharStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+
+ xub_StrLen Match( const ByteString& rStr ) const;
+ xub_StrLen Match( const sal_Char* pCharStr ) const;
+
+ xub_StrLen Search( sal_Char c, xub_StrLen nIndex = 0 ) const;
+ xub_StrLen Search( const ByteString& rStr, xub_StrLen nIndex = 0 ) const;
+ xub_StrLen Search( const sal_Char* pCharStr, xub_StrLen nIndex = 0 ) const;
+ xub_StrLen SearchBackward( sal_Char c, xub_StrLen nIndex = STRING_LEN ) const;
+ xub_StrLen SearchChar( const sal_Char* pChars, xub_StrLen nIndex = 0 ) const;
+ xub_StrLen SearchCharBackward( const sal_Char* pChars, xub_StrLen nIndex = STRING_LEN ) const;
+
+ xub_StrLen SearchAndReplace( sal_Char c, sal_Char cRep, xub_StrLen nIndex = 0 );
+ xub_StrLen SearchAndReplace( const ByteString& rStr, const ByteString& rRepStr,
+ xub_StrLen nIndex = 0 );
+ xub_StrLen SearchAndReplace( const sal_Char* pCharStr, const ByteString& rRepStr,
+ xub_StrLen nIndex = 0 );
+ void SearchAndReplaceAll( sal_Char c, sal_Char cRep );
+ void SearchAndReplaceAll( const ByteString& rStr, const ByteString& rRepStr );
+ void SearchAndReplaceAll( const sal_Char* pCharStr, const ByteString& rRepStr );
+
+ xub_StrLen GetTokenCount( sal_Char cTok = ';' ) const;
+ void SetToken( xub_StrLen nToken, sal_Char cTok, const ByteString& rStr,
+ xub_StrLen nIndex = 0 );
+ ByteString GetToken( xub_StrLen nToken, sal_Char cTok, xub_StrLen& rIndex ) const;
+ ByteString GetToken( xub_StrLen nToken, sal_Char cTok = ';' ) const;
+
+ xub_StrLen GetQuotedTokenCount( const ByteString& rQuotedPairs, sal_Char cTok = ';' ) const;
+ ByteString GetQuotedToken( xub_StrLen nToken, const ByteString& rQuotedPairs,
+ sal_Char cTok, xub_StrLen& rIndex ) const;
+ ByteString GetQuotedToken( xub_StrLen nToken, const ByteString& rQuotedPairs,
+ sal_Char cTok = ';' ) const;
+
+ const sal_Char* GetBuffer() const { return mpData->maStr; }
+ sal_Char* GetBufferAccess();
+ void ReleaseBufferAccess( xub_StrLen nLen = STRING_LEN );
+ sal_Char* AllocBuffer( xub_StrLen nLen );
+
+ friend BOOL operator == ( const ByteString& rStr1, const ByteString& rStr2 )
+ { return rStr1.Equals( rStr2 ); }
+ friend BOOL operator == ( const ByteString& rStr, const sal_Char* pCharStr )
+ { return rStr.Equals( pCharStr ); }
+ friend BOOL operator == ( const sal_Char* pCharStr, const ByteString& rStr )
+ { return rStr.Equals( pCharStr ); }
+ friend BOOL operator != ( const ByteString& rStr1, const ByteString& rStr2 )
+ { return !(operator == ( rStr1, rStr2 )); }
+ friend BOOL operator != ( const ByteString& rStr, const sal_Char* pCharStr )
+ { return !(operator == ( rStr, pCharStr )); }
+ friend BOOL operator != ( const sal_Char* pCharStr, const ByteString& rStr )
+ { return !(operator == ( pCharStr, rStr )); }
+ friend BOOL operator < ( const ByteString& rStr1, const ByteString& rStr2 )
+ { return (rStr1.CompareTo( rStr2 ) == COMPARE_LESS); }
+ friend BOOL operator < ( const ByteString& rStr, const sal_Char* pCharStr )
+ { return (rStr.CompareTo( pCharStr ) == COMPARE_LESS); }
+ friend BOOL operator < ( const sal_Char* pCharStr, const ByteString& rStr )
+ { return (rStr.CompareTo( pCharStr ) >= COMPARE_EQUAL); }
+ friend BOOL operator > ( const ByteString& rStr1, const ByteString& rStr2 )
+ { return (rStr1.CompareTo( rStr2 ) == COMPARE_GREATER); }
+ friend BOOL operator > ( const ByteString& rStr, const sal_Char* pCharStr )
+ { return (rStr.CompareTo( pCharStr ) == COMPARE_GREATER); }
+ friend BOOL operator > ( const sal_Char* pCharStr, const ByteString& rStr )
+ { return (rStr.CompareTo( pCharStr ) <= COMPARE_EQUAL); }
+ friend BOOL operator <= ( const ByteString& rStr1, const ByteString& rStr2 )
+ { return !(operator > ( rStr1, rStr2 )); }
+ friend BOOL operator <= ( const ByteString& rStr, const sal_Char* pCharStr )
+ { return !(operator > ( rStr, pCharStr )); }
+ friend BOOL operator <= ( const sal_Char* pCharStr, const ByteString& rStr )
+ { return !(operator > ( pCharStr, rStr )); }
+ friend BOOL operator >= ( const ByteString& rStr1, const ByteString& rStr2 )
+ { return !(operator < ( rStr1, rStr2 )); }
+ friend BOOL operator >= ( const ByteString& rStr, const sal_Char* pCharStr )
+ { return !(operator < ( rStr, pCharStr )); }
+ friend BOOL operator >= ( const sal_Char* pCharStr, const ByteString& rStr )
+ { return !(operator < ( pCharStr, rStr )); }
+};
+
+inline ByteString ByteString::Copy( xub_StrLen nIndex, xub_StrLen nCount ) const
+{
+ return ByteString( *this, nIndex, nCount );
+}
+
+inline ByteString ByteString::GetToken( xub_StrLen nToken, sal_Char cTok ) const
+{
+ xub_StrLen nTempPos = 0;
+ return GetToken( nToken, cTok, nTempPos );
+}
+
+inline ByteString ByteString::GetQuotedToken( xub_StrLen nToken, const ByteString& rQuotedPairs,
+ sal_Char cTok ) const
+{
+ xub_StrLen nTempPos = 0;
+ return GetQuotedToken( nToken, rQuotedPairs, cTok, nTempPos );
+}
+
+// -----------------------------------------------------------------------
+
+// ------------------------
+// - Interne String-Daten -
+// ------------------------
+
+// Daten vom String, mit denen der String verwaltet wird
+// Nur fuer Debug-Zwecke (darf nie direkt einem String zugewiesen werden)
+
+#ifdef SAL_W32
+#pragma pack(push, 4)
+#elif defined(SAL_OS2)
+#pragma pack(1)
+#endif
+
+typedef struct _UniStringData
+{
+ sal_Int32 mnRefCount; // Referenz counter
+ sal_Int32 mnLen; // Length of the String
+ sal_Unicode maStr[1]; // CharArray (String)
+} UniStringData;
+
+#ifdef SAL_W32
+#pragma pack(pop)
+#elif defined(SAL_OS2)
+#pragma pack()
+#endif
+
+// -------------------
+// - UniString-Types -
+// -------------------
+
+#ifndef NOOLDSTRING
+#define WSTRING_MAXLEN STRING_MAXLEN
+#endif
+
+// -------------
+// - UniString -
+// -------------
+
+class TOOLS_DLLPUBLIC UniString
+{
+ friend class ByteString;
+
+ TOOLS_DLLPRIVATE void InitStringRes( const sal_Char* pUTF8Str, sal_Int32 nLen );
+
+private:
+ UniStringData* mpData;
+
+ TOOLS_DLLPRIVATE inline void ImplCopyData();
+ TOOLS_DLLPRIVATE inline sal_Unicode * ImplCopyStringData(sal_Unicode *);
+
+ UniString( const int* pDummy ); // not implemented: to prevent UniString( NULL )
+ UniString(int); // not implemented; to detect misuses of
+ // UniString(sal_Unicode)
+ void Assign(int); // not implemented; to detect misuses of
+ // Assign(sal_Unicode)
+ void operator =(int); // not implemented; to detect misuses
+ // of operator =(sal_Unicode)
+ void Append(int); // not implemented; to detect misuses of
+ // Append(sal_Unicode)
+ void operator +=(int); // not implemented; to detect misuses
+ // of operator +=(sal_Unicode)
+
+public:
+ UniString();
+ UniString( const ResId& rResId );
+ UniString( const UniString& rStr );
+ UniString( const UniString& rStr, xub_StrLen nPos, xub_StrLen nLen );
+ UniString( const rtl::OUString& rStr );
+ UniString( const sal_Unicode* pCharStr );
+ UniString( const sal_Unicode* pCharStr, xub_StrLen nLen );
+ UniString( sal_Unicode c );
+ UniString(char c); // ...but allow "UniString('a')"
+ UniString( const ByteString& rByteStr,
+ rtl_TextEncoding eTextEncoding,
+ sal_uInt32 nCvtFlags = BYTESTRING_TO_UNISTRING_CVTFLAGS );
+ UniString( const ByteString& rByteStr, xub_StrLen nPos, xub_StrLen nLen,
+ rtl_TextEncoding eTextEncoding,
+ sal_uInt32 nCvtFlags = BYTESTRING_TO_UNISTRING_CVTFLAGS );
+ UniString( const sal_Char* pByteStr,
+ rtl_TextEncoding eTextEncoding,
+ sal_uInt32 nCvtFlags = BYTESTRING_TO_UNISTRING_CVTFLAGS );
+ UniString( const sal_Char* pByteStr, xub_StrLen nLen,
+ rtl_TextEncoding eTextEncoding,
+ sal_uInt32 nCvtFlags = BYTESTRING_TO_UNISTRING_CVTFLAGS );
+ ~UniString();
+
+ operator rtl::OUString () const
+ {
+ return rtl::OUString (reinterpret_cast<rtl_uString*>(mpData));
+ }
+
+ UniString intern() const;
+
+ static UniString CreateFromAscii( const sal_Char* pAsciiStr );
+ static UniString CreateFromAscii( const sal_Char* pAsciiStr, xub_StrLen nLen );
+
+ static UniString CreateFromInt32( sal_Int32 n, sal_Int16 nRadix = 10 );
+ static UniString CreateFromInt64( sal_Int64 n, sal_Int16 nRadix = 10 );
+ static UniString CreateFromFloat( float f );
+ static UniString CreateFromDouble( double d );
+ static const UniString& EmptyString();
+ sal_Int32 ToInt32() const;
+ sal_Int64 ToInt64() const;
+ float ToFloat() const;
+ double ToDouble() const;
+
+ UniString& Assign( const UniString& rStr );
+ UniString& Assign( const rtl::OUString& rStr );
+ UniString& Assign( const sal_Unicode* pCharStr );
+ UniString& Assign( const sal_Unicode* pCharStr, xub_StrLen nLen );
+ UniString& Assign( sal_Unicode c );
+ inline UniString & Assign(char c) // ...but allow "Assign('a')"
+ { return Assign(static_cast< sal_Unicode >(c)); }
+ UniString& AssignAscii( const sal_Char* pAsciiStr );
+ UniString& AssignAscii( const sal_Char* pAsciiStr, xub_StrLen nLen );
+ UniString& operator =( const UniString& rStr )
+ { return Assign( rStr ); }
+ UniString& operator =( const rtl::OUString& rStr )
+ { return Assign( rStr ); }
+ UniString& operator =( const sal_Unicode* pCharStr )
+ { return Assign( pCharStr ); }
+ UniString& operator =( sal_Unicode c )
+ { return Assign( c ); }
+ inline UniString & operator =(char c) // ...but allow "= 'a'"
+ { return operator =(static_cast< sal_Unicode >(c)); }
+
+ UniString& Append( const UniString& rStr );
+ UniString& Append( const sal_Unicode* pCharStr );
+ UniString& Append( const sal_Unicode* pCharStr, xub_StrLen nLen );
+ UniString& Append( sal_Unicode c );
+ inline UniString & Append(char c) // ...but allow "Append('a')"
+ { return Append(static_cast< sal_Unicode >(c)); }
+ UniString& AppendAscii( const sal_Char* pAsciiStr );
+ UniString& AppendAscii( const sal_Char* pAsciiStr, xub_StrLen nLen );
+ UniString& operator +=( const UniString& rStr )
+ { return Append( rStr ); }
+ UniString& operator +=( const sal_Unicode* pCharStr )
+ { return Append( pCharStr ); }
+ UniString& operator +=( sal_Unicode c )
+ { return Append( c ); }
+ inline UniString & operator +=(char c) // ...but allow "+= 'a'"
+ { return operator +=(static_cast< sal_Unicode >(c)); }
+
+ void SetChar( xub_StrLen nIndex, sal_Unicode c );
+ sal_Unicode GetChar( xub_StrLen nIndex ) const
+ { return mpData->maStr[nIndex]; }
+
+ xub_StrLen Len() const { return (xub_StrLen)mpData->mnLen; }
+
+ UniString& Insert( const UniString& rStr, xub_StrLen nIndex = STRING_LEN );
+ UniString& Insert( const UniString& rStr, xub_StrLen nPos, xub_StrLen nLen,
+ xub_StrLen nIndex = STRING_LEN );
+ UniString& Insert( const sal_Unicode* pCharStr, xub_StrLen nIndex = STRING_LEN );
+ UniString& Insert( sal_Unicode c, xub_StrLen nIndex = STRING_LEN );
+ UniString& InsertAscii( const sal_Char* pAsciiStr, xub_StrLen nIndex = STRING_LEN );
+ UniString& Replace( xub_StrLen nIndex, xub_StrLen nLen, const UniString& rStr );
+ UniString& ReplaceAscii( xub_StrLen nIndex, xub_StrLen nLen,
+ const sal_Char* pAsciiStr, xub_StrLen nStrLen = STRING_LEN );
+ UniString& Erase( xub_StrLen nIndex = 0, xub_StrLen nCount = STRING_LEN );
+ UniString Copy( xub_StrLen nIndex = 0, xub_StrLen nCount = STRING_LEN ) const;
+
+ UniString& Fill( xub_StrLen nCount, sal_Unicode cFillChar = ' ' );
+ UniString& Expand( xub_StrLen nCount, sal_Unicode cExpandChar = ' ' );
+
+ UniString& EraseLeadingChars( sal_Unicode c = ' ' );
+ UniString& EraseTrailingChars( sal_Unicode c = ' ' );
+ UniString& EraseLeadingAndTrailingChars( sal_Unicode c = ' ' );
+ UniString& EraseAllChars( sal_Unicode c = ' ' );
+ UniString& Reverse();
+
+ UniString& ConvertLineEnd( LineEnd eLineEnd );
+ UniString& ConvertLineEnd()
+ { return ConvertLineEnd( GetSystemLineEnd() ); }
+
+ UniString& ToLowerAscii();
+ UniString& ToUpperAscii();
+
+ StringCompare CompareTo( const UniString& rStr,
+ xub_StrLen nLen = STRING_LEN ) const;
+ StringCompare CompareTo( const sal_Unicode* pCharStr,
+ xub_StrLen nLen = STRING_LEN ) const;
+ StringCompare CompareToAscii( const sal_Char* pAsciiStr,
+ xub_StrLen nLen = STRING_LEN ) const;
+ StringCompare CompareIgnoreCaseToAscii( const UniString& rStr,
+ xub_StrLen nLen = STRING_LEN ) const;
+ StringCompare CompareIgnoreCaseToAscii( const sal_Unicode* pCharStr,
+ xub_StrLen nLen = STRING_LEN ) const;
+ StringCompare CompareIgnoreCaseToAscii( const sal_Char* pAsciiStr,
+ xub_StrLen nLen = STRING_LEN ) const;
+ BOOL Equals( const UniString& rStr ) const;
+ BOOL Equals( const sal_Unicode* pCharStr ) const;
+ BOOL EqualsAscii( const sal_Char* pAsciiStr ) const;
+ BOOL EqualsIgnoreCaseAscii( const UniString& rStr ) const;
+ BOOL EqualsIgnoreCaseAscii( const sal_Unicode* pCharStr ) const;
+ BOOL EqualsIgnoreCaseAscii( const sal_Char* pAsciiStr ) const;
+ BOOL Equals( const UniString& rStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+ BOOL Equals( const sal_Unicode* pCharStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+ BOOL EqualsAscii( const sal_Char* pAsciiStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+ BOOL EqualsIgnoreCaseAscii( const UniString& rStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+ BOOL EqualsIgnoreCaseAscii( const sal_Unicode* pCharStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+ BOOL EqualsIgnoreCaseAscii( const sal_Char* pAsciiStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+
+ xub_StrLen Match( const UniString& rStr ) const;
+ xub_StrLen Match( const sal_Unicode* pCharStr ) const;
+
+ xub_StrLen Search( sal_Unicode c, xub_StrLen nIndex = 0 ) const;
+ xub_StrLen Search( const UniString& rStr, xub_StrLen nIndex = 0 ) const;
+ xub_StrLen Search( const sal_Unicode* pCharStr, xub_StrLen nIndex = 0 ) const;
+ xub_StrLen SearchAscii( const sal_Char* pAsciiStr, xub_StrLen nIndex = 0 ) const;
+ xub_StrLen SearchBackward( sal_Unicode c, xub_StrLen nIndex = STRING_LEN ) const;
+ xub_StrLen SearchChar( const sal_Unicode* pChars, xub_StrLen nIndex = 0 ) const;
+ xub_StrLen SearchCharBackward( const sal_Unicode* pChars, xub_StrLen nIndex = STRING_LEN ) const;
+
+ xub_StrLen SearchAndReplace( sal_Unicode c, sal_Unicode cRep,
+ xub_StrLen nIndex = 0 );
+ xub_StrLen SearchAndReplace( const UniString& rStr, const UniString& rRepStr,
+ xub_StrLen nIndex = 0 );
+ xub_StrLen SearchAndReplace( const sal_Unicode* pCharStr, const UniString& rRepStr,
+ xub_StrLen nIndex = 0 );
+ xub_StrLen SearchAndReplaceAscii( const sal_Char* pAsciiStr, const UniString& rRepStr,
+ xub_StrLen nIndex = 0 );
+ void SearchAndReplaceAll( sal_Unicode c, sal_Unicode cRep );
+ void SearchAndReplaceAll( const UniString& rStr, const UniString& rRepStr );
+ void SearchAndReplaceAll( const sal_Unicode* pCharStr, const UniString& rRepStr );
+ void SearchAndReplaceAllAscii( const sal_Char* pAsciiStr, const UniString& rRepStr );
+
+ xub_StrLen GetTokenCount( sal_Unicode cTok = ';' ) const;
+ void SetToken( xub_StrLen nToken, sal_Unicode cTok, const UniString& rStr,
+ xub_StrLen nIndex = 0 );
+ UniString GetToken( xub_StrLen nToken, sal_Unicode cTok, xub_StrLen& rIndex ) const;
+ UniString GetToken( xub_StrLen nToken, sal_Unicode cTok = ';' ) const;
+
+ xub_StrLen GetQuotedTokenCount( const UniString& rQuotedPairs, sal_Unicode cTok = ';' ) const;
+ UniString GetQuotedToken( xub_StrLen nToken, const UniString& rQuotedPairs,
+ sal_Unicode cTok, xub_StrLen& rIndex ) const;
+ UniString GetQuotedToken( xub_StrLen nToken, const UniString& rQuotedPairs,
+ sal_Unicode cTok = ';' ) const;
+
+ const sal_Unicode* GetBuffer() const { return mpData->maStr; }
+ sal_Unicode* GetBufferAccess();
+ void ReleaseBufferAccess( xub_StrLen nLen = STRING_LEN );
+ sal_Unicode* AllocBuffer( xub_StrLen nLen );
+
+ friend BOOL operator == ( const UniString& rStr1, const UniString& rStr2 )
+ { return rStr1.Equals( rStr2 ); }
+ friend BOOL operator != ( const UniString& rStr1, const UniString& rStr2 )
+ { return !(operator == ( rStr1, rStr2 )); }
+ friend BOOL operator < ( const UniString& rStr1, const UniString& rStr2 )
+ { return (rStr1.CompareTo( rStr2 ) == COMPARE_LESS); }
+ friend BOOL operator > ( const UniString& rStr1, const UniString& rStr2 )
+ { return (rStr1.CompareTo( rStr2 ) == COMPARE_GREATER); }
+ friend BOOL operator <= ( const UniString& rStr1, const UniString& rStr2 )
+ { return !(operator > ( rStr1, rStr2 )); }
+ friend BOOL operator >= ( const UniString& rStr1, const UniString& rStr2 )
+ { return !(operator < ( rStr1, rStr2 )); }
+};
+
+inline UniString UniString::Copy( xub_StrLen nIndex, xub_StrLen nCount ) const
+{
+ return UniString( *this, nIndex, nCount );
+}
+
+inline UniString UniString::GetToken( xub_StrLen nToken, sal_Unicode cTok ) const
+{
+ xub_StrLen nTempPos = 0;
+ return GetToken( nToken, cTok, nTempPos );
+}
+
+inline UniString UniString::GetQuotedToken( xub_StrLen nToken, const UniString& rQuotedPairs,
+ sal_Unicode cTok ) const
+{
+ xub_StrLen nTempPos = 0;
+ return GetQuotedToken( nToken, rQuotedPairs, cTok, nTempPos );
+}
+
+#endif // _STRING_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/svborder.hxx b/tools/inc/tools/svborder.hxx
new file mode 100644
index 000000000000..1b2a87044696
--- /dev/null
+++ b/tools/inc/tools/svborder.hxx
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVBORDER_HXX
+#define _SVBORDER_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/gen.hxx>
+
+class TOOLS_DLLPUBLIC SvBorder
+{
+ long nTop, nRight, nBottom, nLeft;
+public:
+ SvBorder()
+ { nTop = nRight = nBottom = nLeft = 0; }
+ SvBorder( const Size & rSz )
+ { nTop = nBottom = rSz.Height(); nRight = nLeft = rSz.Width(); }
+ SvBorder( const Rectangle & rOuter, const Rectangle & rInner );
+ SvBorder( long nLeftP, long nTopP, long nRightP, long nBottomP )
+ { nLeft = nLeftP; nTop = nTopP; nRight = nRightP; nBottom = nBottomP; }
+ BOOL operator == ( const SvBorder & rObj ) const
+ {
+ return nTop == rObj.nTop && nRight == rObj.nRight &&
+ nBottom == rObj.nBottom && nLeft == rObj.nLeft;
+ }
+ BOOL operator != ( const SvBorder & rObj ) const
+ { return !(*this == rObj); }
+ SvBorder & operator = ( const SvBorder & rBorder )
+ {
+ Left() = rBorder.Left();
+ Top() = rBorder.Top();
+ Right() = rBorder.Right();
+ Bottom() = rBorder.Bottom();
+ return *this;
+ }
+ SvBorder & operator += ( const SvBorder & rBorder )
+ {
+ Left() += rBorder.Left();
+ Top() += rBorder.Top();
+ Right() += rBorder.Right();
+ Bottom() += rBorder.Bottom();
+ return *this;
+ }
+ SvBorder & operator -= ( const SvBorder & rBorder )
+ {
+ Left() -= rBorder.Left();
+ Top() -= rBorder.Top();
+ Right() -= rBorder.Right();
+ Bottom() -= rBorder.Bottom();
+ return *this;
+ }
+ BOOL IsInside( const SvBorder & rInside )
+ {
+ return nTop >= rInside.nTop && nRight >= rInside.nRight &&
+ nBottom >= rInside.nBottom && nLeft >= rInside.nLeft;
+ }
+ long & Top() { return nTop; }
+ long & Right() { return nRight; }
+ long & Bottom() { return nBottom; }
+ long & Left() { return nLeft; }
+ long Top() const { return nTop; }
+ long Right() const { return nRight; }
+ long Bottom() const { return nBottom; }
+ long Left() const { return nLeft; }
+};
+
+TOOLS_DLLPUBLIC Rectangle & operator += ( Rectangle & rRect, const SvBorder & rBorder );
+TOOLS_DLLPUBLIC Rectangle & operator -= ( Rectangle & rRect, const SvBorder & rBorder );
+
+//=========================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/svlibrary.hxx b/tools/inc/tools/svlibrary.hxx
new file mode 100644
index 000000000000..e58e1a9c0e37
--- /dev/null
+++ b/tools/inc/tools/svlibrary.hxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _SVLIBRARY_HXX
+#define _SVLIBRARY_HXX
+
+#include "tools/toolsdllapi.h"
+
+#include <osl/module.hxx>
+#include <rtl/ustring.hxx>
+
+class TOOLS_DLLPUBLIC SvLibrary
+{
+public:
+ static bool LoadModule( osl::Module&, const rtl::OUString& rLibName, ::oslGenericFunction baseModule, ::sal_Int32 mode = SAL_LOADMODULE_DEFAULT );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/svwin.h b/tools/inc/tools/svwin.h
new file mode 100644
index 000000000000..cddcdf3a57b8
--- /dev/null
+++ b/tools/inc/tools/svwin.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVWIN_H
+#define _SVWIN_H
+
+#if defined WNT
+#include <tools/prewin.h>
+#include <tools/postwin.h>
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/table.hxx b/tools/inc/tools/table.hxx
new file mode 100644
index 000000000000..75cb338dfd7d
--- /dev/null
+++ b/tools/inc/tools/table.hxx
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _TOOLS_TABLE_HXX
+#define _TOOLS_TABLE_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/solar.h>
+#include <tools/contnr.hxx>
+
+// ---------
+// - Table -
+// ---------
+
+#define TABLE_ENTRY_NOTFOUND CONTAINER_ENTRY_NOTFOUND
+
+class TOOLS_DLLPUBLIC Table : private Container
+{
+private:
+ ULONG nCount;
+ TOOLS_DLLPRIVATE ULONG ImplGetIndex( ULONG nKey, ULONG* pIndex = NULL ) const;
+public:
+ Table( USHORT nInitSize = 16, USHORT nReSize = 16 );
+ Table( const Table& rTable ) : Container( rTable )
+ { nCount = rTable.nCount; }
+
+ BOOL Insert( ULONG nKey, void* p );
+ void* Remove( ULONG nKey );
+ void* Replace( ULONG nKey, void* p );
+ void* Get( ULONG nKey ) const;
+
+ void Clear() { Container::Clear(); nCount = 0; }
+ ULONG Count() const { return( nCount ); }
+
+ void* GetCurObject() const;
+ ULONG GetCurKey() const { return (ULONG)Container::GetCurObject(); }
+ ULONG GetKey( const void* p ) const;
+ BOOL IsKeyValid( ULONG nKey ) const;
+
+ void* GetObject( ULONG nPos ) const
+ { return Container::GetObject( (nPos*2)+1 ); }
+ ULONG GetObjectKey( ULONG nPos ) const
+ { return (ULONG)Container::GetObject( nPos*2 ); }
+ ULONG GetUniqueKey( ULONG nStartKey = 1 ) const;
+ ULONG SearchKey( ULONG nKey, ULONG* pPos = NULL ) const;
+
+ void* Seek( ULONG nKey );
+ void* Seek( void* p );
+ void* First();
+ void* Last();
+ void* Next();
+ void* Prev();
+
+ Table& operator =( const Table& rTable );
+
+ BOOL operator ==( const Table& rTable ) const
+ { return Container::operator ==( rTable ); }
+ BOOL operator !=( const Table& rTable ) const
+ { return Container::operator !=( rTable ); }
+};
+
+inline Table& Table::operator =( const Table& r )
+{
+ Container::operator =( r );
+ nCount = r.nCount;
+ return *this;
+}
+
+// -----------------
+// - DECLARE_TABLE -
+// -----------------
+
+#define DECLARE_TABLE( ClassName, Type ) \
+class ClassName : private Table \
+{ \
+public: \
+ using Table::Clear; \
+ using Table::Count; \
+ using Table::GetCurKey; \
+ using Table::GetObjectKey; \
+ using Table::GetUniqueKey; \
+ using Table::SearchKey; \
+ using Table::IsKeyValid; \
+ \
+ ClassName( USHORT _nInitSize = 16, \
+ USHORT _nReSize = 16 ) : \
+ Table( _nInitSize, _nReSize ) {} \
+ ClassName( const ClassName& rClassName ) : \
+ Table( rClassName ) {} \
+ \
+ BOOL Insert( ULONG nKey, Type p ) \
+ { return Table::Insert( nKey, (void*)p ); } \
+ Type Remove( ULONG nKey ) \
+ { return (Type)Table::Remove( nKey ); } \
+ Type Replace( ULONG nKey, Type p ) \
+ { return (Type)Table::Replace( nKey, (void*)p ); } \
+ Type Get( ULONG nKey ) const \
+ { return (Type)Table::Get( nKey ); } \
+ \
+ Type GetCurObject() const \
+ { return (Type)Table::GetCurObject(); } \
+ ULONG GetKey( const Type p ) const \
+ { return Table::GetKey( (const void*)p ); } \
+ \
+ Type GetObject( ULONG nPos ) const \
+ { return (Type)Table::GetObject( nPos ); } \
+ \
+ Type Seek( ULONG nKey ) \
+ { return (Type)Table::Seek( nKey ); } \
+ Type Seek( Type p ) \
+ { return (Type)Table::Seek( (void*)p ); } \
+ Type First() { return (Type)Table::First(); } \
+ Type Last() { return (Type)Table::Last(); } \
+ Type Next() { return (Type)Table::Next(); } \
+ Type Prev() { return (Type)Table::Prev(); } \
+ \
+ ClassName& operator =( const ClassName& rClassName ) \
+ { Table::operator =( rClassName ); \
+ return *this; } \
+ \
+ BOOL operator ==( const ClassName& rTable ) const \
+ { return Table::operator ==( rTable ); } \
+ BOOL operator !=( const ClassName& rTable ) const \
+ { return Table::operator !=( rTable ); } \
+};
+
+#endif // _TOOLS_TABLE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/tempfile.hxx b/tools/inc/tools/tempfile.hxx
new file mode 100644
index 000000000000..da8a18b8b342
--- /dev/null
+++ b/tools/inc/tools/tempfile.hxx
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _TOOLS_TEMPFILE_HXX
+#define _TOOLS_TEMPFILE_HXX
+
+#include <tools/string.hxx>
+#include "tools/toolsdllapi.h"
+
+struct TempFile_Impl;
+class TOOLS_DLLPUBLIC TempFile
+{
+ TempFile_Impl* pImp;
+ sal_Bool bKillingFileEnabled;
+
+public:
+ // Create a temporary file or directory in a given folder or the default tempfile folder
+ TempFile( const String* pParent=NULL, sal_Bool bDirectory=sal_False );
+
+ // Create a temporary file or directory in a given folder or the default tempfile folder; its name starts
+ // with some given characters followed by a counter ( example: rLeadingChars="abc" means "abc0","abc1"
+ // and so on, depending on existing files in that folder ).
+ // The extension string may be f.e. ".txt" or "", if no extension string is given, ".tmp" is used
+ TempFile( const String& rLeadingChars, const String* pExtension=NULL, const String* pParent=NULL, sal_Bool bDirectory=sal_False );
+
+ // TempFile will be removed from disk in dtor if EnableKillingTempFile was called before.
+ // TempDirs will be removed recursively in that case.
+ ~TempFile();
+
+ sal_Bool IsValid() const;
+
+ // Returns the real name of the tempfile in file URL scheme.
+ String GetName() const;
+
+ // If enabled the file will be removed from disk when the dtor is called ( default is not enabled )
+ void EnableKillingFile( sal_Bool bEnable=sal_True )
+ { bKillingFileEnabled = bEnable; }
+
+ sal_Bool IsKillingFileEnabled() const
+ { return bKillingFileEnabled; }
+
+ // Only create a name for a temporary file that would be valid at that moment.
+ static String CreateTempName( const String* pParent=NULL );
+
+ // The TempNameBase is a folder in the default ( system ) tempfile folder.
+ // This subfolder will be used if a TempFile or TempName is created without a parent name.
+ // The caller of the SetTempNameBase is responsible for deleting this folder and all temporary files in it.
+ // The argument must be a simple name, not a complete URL.
+ // The return value of both methods is the complete URL of the tempname base folder.
+ static String SetTempNameBaseDirectory( const String &rBaseName );
+ static String GetTempNameBaseDirectory();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/tenccvt.hxx b/tools/inc/tools/tenccvt.hxx
new file mode 100644
index 000000000000..c38f00d56c88
--- /dev/null
+++ b/tools/inc/tools/tenccvt.hxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _TOOLS_TENCCVT_HXX
+#define _TOOLS_TENCCVT_HXX
+
+#include <rtl/textenc.h>
+#include <tools/solar.h>
+#include "tools/toolsdllapi.h"
+
+// ----------------------------------------
+// - Functions for handling Import/Export -
+// ----------------------------------------
+
+// return an encoding which has more defined Characters as the given
+// encoding, but have the same definition for the defined characters
+// e.g.: windows-1252 for iso-8859-1 or windows-1254 for iso-8859-9
+TOOLS_DLLPUBLIC rtl_TextEncoding GetExtendedCompatibilityTextEncoding( rtl_TextEncoding eEncoding );
+
+// return an encoding which has more defined Characters as the given
+// encoding. The encodings could be different.
+// e.g.: windows-1251 for iso-8859-5
+TOOLS_DLLPUBLIC rtl_TextEncoding GetExtendedTextEncoding( rtl_TextEncoding eEncoding );
+
+// if the given encoding is an multi-byte encoding (which allows more than
+// one byte per char, e.g. UTF-8 or Shift-JIS), a one-byte encoding
+// is returned (normally windows-1252).
+TOOLS_DLLPUBLIC rtl_TextEncoding GetOneByteTextEncoding( rtl_TextEncoding eEncoding );
+
+TOOLS_DLLPUBLIC rtl_TextEncoding GetSOLoadTextEncoding( rtl_TextEncoding eEncoding, USHORT nVersion = SOFFICE_FILEFORMAT_50 );
+TOOLS_DLLPUBLIC rtl_TextEncoding GetSOStoreTextEncoding( rtl_TextEncoding eEncoding, USHORT nVersion = SOFFICE_FILEFORMAT_50 );
+
+#endif // _TOOLS_TENCCVT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/testtoolloader.hxx b/tools/inc/tools/testtoolloader.hxx
new file mode 100644
index 000000000000..f4a4f3dd23de
--- /dev/null
+++ b/tools/inc/tools/testtoolloader.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _TOOLS_TESTTOOLLOADER_HXX_
+#define _TOOLS_TESTTOOLLOADER_HXX_
+
+#include "tools/toolsdllapi.h"
+
+namespace tools
+{
+ TOOLS_DLLPUBLIC void InitTestToolLib();
+ TOOLS_DLLPUBLIC void DeInitTestToolLib();
+}
+
+#endif // _TOOLS_TESTTOOLLOADER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/time.hxx b/tools/inc/tools/time.hxx
new file mode 100644
index 000000000000..a72fe7c587e8
--- /dev/null
+++ b/tools/inc/tools/time.hxx
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _TOOLS_TIME_HXX
+#define _TOOLS_TIME_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/solar.h>
+
+class ResId;
+
+// --------
+// - Time -
+// --------
+
+class TOOLS_DLLPUBLIC Time
+{
+private:
+ sal_Int32 nTime;
+
+public:
+ Time();
+ Time( const ResId & rResId );
+ Time( sal_Int32 _nTime ) { Time::nTime = _nTime; }
+ Time( const Time& rTime );
+ Time( ULONG nHour, ULONG nMin,
+ ULONG nSec = 0, ULONG n100Sec = 0 );
+
+ void SetTime( sal_Int32 nNewTime ) { nTime = nNewTime; }
+ sal_Int32 GetTime() const { return nTime; }
+
+ void SetHour( USHORT nNewHour );
+ void SetMin( USHORT nNewMin );
+ void SetSec( USHORT nNewSec );
+ void Set100Sec( USHORT nNew100Sec );
+ USHORT GetHour() const
+ { ULONG nTempTime = (nTime >= 0) ? nTime : nTime*-1;
+ return (USHORT)(nTempTime / 1000000); }
+ USHORT GetMin() const
+ { ULONG nTempTime = (nTime >= 0) ? nTime : nTime*-1;
+ return (USHORT)((nTempTime / 10000) % 100); }
+ USHORT GetSec() const
+ { ULONG nTempTime = (nTime >= 0) ? nTime : nTime*-1;
+ return (USHORT)((nTempTime / 100) % 100); }
+ USHORT Get100Sec() const
+ { ULONG nTempTime = (nTime >= 0) ? nTime : nTime*-1;
+ return (USHORT)(nTempTime % 100); }
+
+ sal_Int32 GetMSFromTime() const;
+ void MakeTimeFromMS( sal_Int32 nMS );
+
+ /// 12 hours == 0.5 days
+ double GetTimeInDays() const;
+
+ BOOL IsBetween( const Time& rFrom, const Time& rTo ) const
+ { return ((nTime >= rFrom.nTime) && (nTime <= rTo.nTime)); }
+
+ BOOL IsEqualIgnore100Sec( const Time& rTime ) const;
+
+ BOOL operator ==( const Time& rTime ) const
+ { return (nTime == rTime.nTime); }
+ BOOL operator !=( const Time& rTime ) const
+ { return (nTime != rTime.nTime); }
+ BOOL operator >( const Time& rTime ) const
+ { return (nTime > rTime.nTime); }
+ BOOL operator <( const Time& rTime ) const
+ { return (nTime < rTime.nTime); }
+ BOOL operator >=( const Time& rTime ) const
+ { return (nTime >= rTime.nTime); }
+ BOOL operator <=( const Time& rTime ) const
+ { return (nTime <= rTime.nTime); }
+
+ static Time GetUTCOffset();
+ static ULONG GetSystemTicks(); // Elapsed time
+ static ULONG GetProcessTicks(); // CPU time
+
+ void ConvertToUTC() { *this -= Time::GetUTCOffset(); }
+ void ConvertToLocalTime() { *this += Time::GetUTCOffset(); }
+
+ Time& operator =( const Time& rTime );
+ Time operator -() const
+ { return Time( nTime * -1 ); }
+ Time& operator +=( const Time& rTime );
+ Time& operator -=( const Time& rTime );
+ TOOLS_DLLPUBLIC friend Time operator +( const Time& rTime1, const Time& rTime2 );
+ TOOLS_DLLPUBLIC friend Time operator -( const Time& rTime1, const Time& rTime2 );
+};
+
+#endif // _TOOLS_TIME_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/tools.h b/tools/inc/tools/tools.h
new file mode 100644
index 000000000000..3a186d22c27a
--- /dev/null
+++ b/tools/inc/tools/tools.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _TOOLS_H
+#define _TOOLS_H
+
+#include "tools/toolsdllapi.h"
+#include <tools/solar.h>
+
+// Methoden, die von VCL gerufen werden muessen
+TOOLS_DLLPUBLIC void InitTools();
+TOOLS_DLLPUBLIC void DeInitTools();
+TOOLS_DLLPUBLIC void GlobalDeInitTools();
+
+#endif // _TOOLS_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/toolsdllapi.h b/tools/inc/tools/toolsdllapi.h
new file mode 100644
index 000000000000..8e654168f71e
--- /dev/null
+++ b/tools/inc/tools/toolsdllapi.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TOOLSDLLAPI_H
+#define INCLUDED_TOOLSDLLAPI_H
+
+#include "sal/types.h"
+
+#if defined(TOOLS_DLLIMPLEMENTATION)
+#define TOOLS_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
+#else
+#define TOOLS_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
+#endif
+#define TOOLS_DLLPRIVATE SAL_DLLPRIVATE
+
+#endif /* INCLUDED_TOOLSDLLAPI_H */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/unqid.hxx b/tools/inc/tools/unqid.hxx
new file mode 100644
index 000000000000..20c223892c19
--- /dev/null
+++ b/tools/inc/tools/unqid.hxx
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _UNQID_HXX
+#define _UNQID_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/unqidx.hxx>
+
+// ---------------
+// - ImpUniqueId -
+// ---------------
+
+struct ImpUniqueId
+{
+ ULONG nId;
+ USHORT nRefCount;
+ void Release()
+ {
+ nRefCount--;
+ if( 0 == nRefCount )
+ delete this;
+ }
+};
+
+// ------------
+// - UniqueId -
+// ------------
+
+class UniqueIdContainer;
+class UniqueItemId
+{
+ friend class UniqueIdContainer;
+ ImpUniqueId* pId;
+
+ UniqueItemId( ImpUniqueId * pIdP )
+ { pId = pIdP; pId->nRefCount++; }
+public:
+ UniqueItemId() { pId = NULL; }
+ UniqueItemId( const UniqueItemId & rId )
+ { pId = rId.pId; if( pId ) pId->nRefCount++; }
+ ~UniqueItemId()
+ { if( pId ) pId->Release(); }
+ UniqueItemId& operator = ( const UniqueItemId & rId )
+ {
+ if( rId.pId ) rId.pId->nRefCount++;
+ if( pId ) pId->Release();
+ pId = rId.pId;
+ return *this;
+ }
+ ULONG GetId() const { return pId ? pId->nId : 0; }
+};
+
+// ---------------------
+// - UniqueIdContainer -
+// ---------------------
+
+class TOOLS_DLLPUBLIC UniqueIdContainer : private UniqueIndex
+{
+ USHORT nCollectCount;
+
+public: // Irgend etwas mit protected falsch
+ void Clear( BOOL bAll );
+ UniqueItemId CreateIdProt( ULONG nId );
+
+public:
+ UniqueIdContainer( ULONG _nStartIndex,
+ ULONG _nInitSize = 16,
+ ULONG _nReSize = 16 )
+ : UniqueIndex( _nStartIndex, _nInitSize, _nReSize )
+ , nCollectCount( 0 )
+ {}
+ UniqueIdContainer( const UniqueIdContainer& );
+
+ ~UniqueIdContainer()
+ { Clear( TRUE ); }
+ UniqueIdContainer& operator = ( const UniqueIdContainer & );
+
+ BOOL IsIndexValid( ULONG nIndex ) const
+ { return UniqueIndex::IsIndexValid( nIndex ); }
+
+ UniqueItemId CreateId();
+ static UniqueItemId CreateFreeId( ULONG nId ); // freies Id
+};
+
+#endif // _UNQID_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/unqidx.hxx b/tools/inc/tools/unqidx.hxx
new file mode 100644
index 000000000000..371b7ff6c28c
--- /dev/null
+++ b/tools/inc/tools/unqidx.hxx
@@ -0,0 +1,154 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _UNQIDX_HXX
+#define _UNQIDX_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/solar.h>
+#include <tools/contnr.hxx>
+
+// ---------------
+// - UniqueIndex -
+// ---------------
+
+#define UNIQUEINDEX_ENTRY_NOTFOUND CONTAINER_ENTRY_NOTFOUND
+
+class TOOLS_DLLPUBLIC UniqueIndex : private Container
+{
+private:
+ ULONG nReSize;
+ ULONG nStartIndex;
+ ULONG nUniqIndex;
+ ULONG nCount;
+
+public:
+ using Container::GetCurObject;
+
+ UniqueIndex( ULONG nStartIndex = 0,
+ ULONG nInitSize = 16,
+ ULONG nReSize = 16 );
+ UniqueIndex( const UniqueIndex& rIdx );
+
+ ULONG Insert( ULONG nIndex, void* p );
+ ULONG Insert( void* p );
+ void* Remove( ULONG nIndex );
+ void* Replace( ULONG nIndex, void* p );
+ void* Get( ULONG nIndex ) const;
+
+ void Clear();
+ ULONG Count() const { return nCount; }
+
+ ULONG GetCurIndex() const;
+ ULONG GetIndex( const void* p ) const;
+ BOOL IsIndexValid( ULONG nIndex ) const;
+
+ void* Seek( ULONG nIndex );
+ void* Seek( void* p );
+ void* First();
+ void* Last();
+ void* Next();
+ void* Prev();
+
+ ULONG GetStartIndex() const { return nStartIndex; }
+ ULONG GetCurMaxIndex() const
+ { return (nStartIndex + Container::GetSize()); }
+
+ UniqueIndex& operator =( const UniqueIndex& rIdx );
+
+ BOOL operator ==( const UniqueIndex& rIdx ) const;
+ BOOL operator !=( const UniqueIndex& rIdx ) const
+ { return !(UniqueIndex::operator==( rIdx )); }
+};
+
+inline void UniqueIndex::Clear()
+{
+ Container::Clear();
+ nCount = 0;
+ nUniqIndex = 0;
+}
+
+// -----------------------
+// - DECLARE_UNIQUEINDEX -
+// -----------------------
+
+#define DECLARE_UNIQUEINDEX( ClassName, Type ) \
+class ClassName : private UniqueIndex \
+{ \
+public: \
+ using UniqueIndex::Clear; \
+ using UniqueIndex::Count; \
+ using UniqueIndex::GetCurIndex; \
+ using UniqueIndex::IsIndexValid; \
+ using UniqueIndex::GetStartIndex; \
+ using UniqueIndex::GetCurMaxIndex; \
+ \
+ ClassName( ULONG _nStartIndex = 0, \
+ ULONG _nInitSize = 16, ULONG _nReSize = 16 ):\
+ UniqueIndex( _nStartIndex, _nInitSize, _nReSize ) {}\
+ ClassName( const ClassName& rClassName ) : \
+ UniqueIndex( rClassName ) {} \
+ \
+ ULONG Insert( ULONG nIndex, Type p ) \
+ { return UniqueIndex::Insert( nIndex, (void*)p ); } \
+ ULONG Insert( Type p ) \
+ { return UniqueIndex::Insert( (void*)p ); } \
+ Type Remove( ULONG nIndex ) \
+ { return (Type)UniqueIndex::Remove( nIndex ); } \
+ Type Replace( ULONG nIndex, Type p ) \
+ { return (Type)UniqueIndex::Replace( nIndex, \
+ (void*)p ); } \
+ Type Get( ULONG nIndex ) const \
+ { return (Type)UniqueIndex::Get( nIndex ); } \
+ \
+ Type GetCurObject() const \
+ { return (Type)UniqueIndex::GetCurObject(); } \
+ ULONG GetIndex( const Type p ) const \
+ { return UniqueIndex::GetIndex( (const void*)p ); } \
+ \
+ Type Seek( ULONG nKey ) \
+ { return (Type)UniqueIndex::Seek( nKey ); } \
+ Type Seek( Type p ) \
+ { return (Type)UniqueIndex::Seek( (void*)p ); } \
+ Type First() { return (Type)UniqueIndex::First(); } \
+ Type Last() { return (Type)UniqueIndex::Last(); } \
+ Type Next() { return (Type)UniqueIndex::Next(); } \
+ Type Prev() { return (Type)UniqueIndex::Prev(); } \
+ \
+ ClassName& operator =( const ClassName& rClassName ) \
+ { UniqueIndex::operator =( rClassName ); \
+ return *this; } \
+ \
+ BOOL operator ==( const ClassName& rIdx ) const \
+ { return UniqueIndex::operator ==( rIdx ); } \
+ BOOL operator !=( const ClassName& rIdx ) const \
+ { return UniqueIndex::operator !=( rIdx ); } \
+};
+
+#endif // _UNQIDX_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/urlkeys.hxx b/tools/inc/tools/urlkeys.hxx
new file mode 100644
index 000000000000..68b1b2052ac0
--- /dev/null
+++ b/tools/inc/tools/urlkeys.hxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __URLKEYS_HXX
+#define __URLKEYS_HXX
+
+// Defines for common keys in URL files
+
+// ANSI version
+
+#define A_URLSECTION_SHORTCUT "InternetShortcut"
+#define A_URLKEY_URL "URL"
+#define A_URLKEY_TITLE "Title"
+#define A_URLKEY_TARGET "Target"
+#define A_URLKEY_FRAME "Frame"
+#define A_URLKEY_OPENAS "OpenAs"
+#define A_URLKEY_SOICON "SOIcon"
+#define A_URLKEY_WIN_ICONFILE "IconFile"
+#define A_URLKEY_WIN_ICONINDEX "IconIndex"
+#define A_URLKEY_WORKDIR "WorkingDirectory"
+#define A_URLKEY_ARGUMENTS "Arguments"
+#define A_URLKEY_INTERN_ORIGURL "[URL]"
+
+// Unicode version
+
+#define U_URLSECTION_SHORTCUT L"InternetShortcut"
+#define U_URLKEY_URL L"URL"
+#define U_URLKEY_TITLE L"Title"
+#define U_URLKEY_TARGET L"Target"
+#define U_URLKEY_FRAME L"Frame"
+#define U_URLKEY_OPENAS L"OpenAs"
+#define U_URLKEY_SOICON L"SOIcon"
+#define U_URLKEY_WIN_ICONFILE L"IconFile"
+#define U_URLKEY_WIN_ICONINDEX L"IconIndex"
+#define U_URLKEY_WORKDIR L"WorkingDirectory"
+#define U_URLKEY_ARGUMENTS L"Arguments"
+#define U_URLKEY_INTERN_ORIGURL L"[URL]"
+
+# define URLSECTION_SHORTCUT U_URLSECTION_SHORTCUT
+# define URLKEY_URL U_URLKEY_URL
+# define URLKEY_TITLE U_URLKEY_TITLE
+# define URLKEY_TARGET U_URLKEY_TARGET
+# define URLKEY_FRAME U_URLKEY_FRAME
+# define URLKEY_OPENAS U_URLKEY_OPENAS
+# define URLKEY_SOICON U_URLKEY_SOICON
+# define URLKEY_WIN_ICONFILE U_URLKEY_WIN_ICONFILE
+# define URLKEY_WIN_ICONINDEX U_URLKEY_WIN_ICONINDEX
+# define URLKEY_WORKDIR U_URLKEY_WORKDIR
+# define URLKEY_ARGUMENTS U_URLKEY_ARGUMENTS
+# define URLKEY_INTERN_ORIGURL U_URLKEY_INTERN_ORIGURL
+
+#endif // __URLKEYS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/urlobj.hxx b/tools/inc/tools/urlobj.hxx
new file mode 100644
index 000000000000..a4f2a07af762
--- /dev/null
+++ b/tools/inc/tools/urlobj.hxx
@@ -0,0 +1,1923 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _URLOBJ_HXX
+#define _URLOBJ_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/string.hxx>
+#include "com/sun/star/uno/Reference.hxx"
+#include "rtl/string.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/textenc.h"
+#include "sal/types.h"
+
+namespace com { namespace sun { namespace star { namespace util {
+ class XStringWidth;
+} } } }
+
+//============================================================================
+// Special tokens:
+#define INET_PASS_TOKEN '@'
+#define INET_DELIM_TOKEN ':'
+#define INET_DELIM_IMAPID ';'
+#define INET_ENC_DELIM_TOKEN '|'
+#define INET_DELIM_HOST_TOKEN '.'
+#define INET_PATH_TOKEN '/'
+#define INET_DOSPATH_TOKEN '\\'
+#define INET_MARK_TOKEN '#'
+#define INET_PARAM_TOKEN '?'
+#define INET_HEX_ESCAPE '%'
+
+//============================================================================
+// Common URL prefixes for various schemes:
+#define INET_FTP_SCHEME "ftp://"
+#define INET_HTTP_SCHEME "http://"
+#define INET_HTTPS_SCHEME "https://"
+#define INET_FILE_SCHEME "file://"
+#define INET_GOPHER_SCHEME "gopher://"
+#define INET_MAILTO_SCHEME "mailto:"
+#define INET_CID_SCHEME "cid:"
+#define INET_NEWS_SCHEME "news:"
+#define INET_POP3_SCHEME "pop3://"
+#define INET_LDAP_SCHEME "ldap://"
+#define INET_PRIVATE_SCHEME "private:"
+#define INET_BUGDOC_SCHEME "bugdoc:"
+#define INET_SLOT_SCHEME "slot:"
+#define INET_MACRO_SCHEME "macro:"
+#define INET_JAVASCRIPT_SCHEME "javascript:"
+#define INET_IMAP_SCHEME "imap://"
+#define INET_DOWNPASS_SCHEME ".."
+#define INET_DATA_SCHEME "data:"
+#define INET_OUT_SCHEME "out://"
+#define INET_FIF_SCHEME "fif://"
+#define INET_CEPT_SCHEME "cept://"
+#define INET_VIM_SCHEME "vim://"
+#define INET_UNO_SCHEME ".uno:"
+#define INET_COMPONENT_SCHEME ".component:"
+#define INET_DB_SCHEME "db:"
+#define INET_BUGID_SCHEME "bugid:"
+#define INET_TELNET_SCHEME "telnet://"
+
+#define URL_PREFIX_PRIV_SOFFICE "private:"
+enum
+{
+ URL_PREFIX_PRIV_SOFFICE_LEN
+ = RTL_CONSTASCII_LENGTH(URL_PREFIX_PRIV_SOFFICE)
+};
+
+#define URL_PREFIX_PRIV_OBSOLETE URL_PREFIX_PRIV_SOFFICE
+enum
+{
+ URL_PREFIX_PRIV_OBSOLETE_LEN
+ = RTL_CONSTASCII_LENGTH(URL_PREFIX_PRIV_OBSOLETE)
+};
+
+#define URL_PREFIX_PRIV_EXTERN "staroffice:"
+enum
+{
+ URL_PREFIX_PRIV_EXTERN_LEN = RTL_CONSTASCII_LENGTH(URL_PREFIX_PRIV_EXTERN)
+};
+
+//============================================================================
+// Schemes:
+enum INetProtocol
+{
+ INET_PROT_NOT_VALID = 0,
+ INET_PROT_FTP = 1,
+ INET_PROT_HTTP = 2,
+ INET_PROT_FILE = 3,
+ INET_PROT_MAILTO = 4,
+ INET_PROT_VND_SUN_STAR_WEBDAV = 5,
+ INET_PROT_NEWS = 6,
+ INET_PROT_PRIV_SOFFICE = 7,
+ INET_PROT_PRIVATE = INET_PROT_PRIV_SOFFICE, // obsolete
+ INET_PROT_VND_SUN_STAR_HELP = 8,
+ INET_PROT_HTTPS = 9,
+ INET_PROT_SLOT = 10,
+ INET_PROT_MACRO = 11,
+ INET_PROT_JAVASCRIPT = 12,
+ INET_PROT_IMAP = 13,
+ INET_PROT_POP3 = 14,
+ INET_PROT_DATA = 15,
+ INET_PROT_CID = 16,
+ INET_PROT_OUT = 17,
+ INET_PROT_VND_SUN_STAR_HIER = 18,
+ INET_PROT_VIM = 19,
+ INET_PROT_UNO = 20,
+ INET_PROT_COMPONENT = 21,
+ INET_PROT_VND_SUN_STAR_PKG = 22,
+ INET_PROT_LDAP = 23,
+ INET_PROT_DB = 24,
+ INET_PROT_VND_SUN_STAR_CMD = 25,
+ INET_PROT_VND_SUN_STAR_ODMA = 26,
+ INET_PROT_TELNET = 27,
+ INET_PROT_VND_SUN_STAR_EXPAND = 28,
+ INET_PROT_VND_SUN_STAR_TDOC = 29,
+ INET_PROT_GENERIC = 30,
+ INET_PROT_SMB = 31,
+ INET_PROT_END = 32
+};
+
+//============================================================================
+class TOOLS_DLLPUBLIC INetURLObject
+{
+public:
+ //========================================================================
+ // Get- and Set-Methods:
+
+ /** The way input strings that represent (parts of) URIs are interpreted
+ in set-methods.
+
+ @descr Most set-methods accept either a ByteString or a rtl::OUString
+ as input. Using a ByteString, octets in the range 0x80--0xFF are
+ replaced by single escape sequences. Using a rtl::OUString , UTF-32
+ characters in the range 0x80--0x10FFFF are replaced by sequences of
+ escape sequences, representing the UTF-8 coded characters.
+
+ @descr Along with an EncodeMechanism parameter, the set-methods all
+ take an rtl_TextEncoding parameter, which is ignored unless the
+ EncodeMechanism is WAS_ENCODED.
+ */
+ enum EncodeMechanism
+ {
+ /** All escape sequences that are already present are ignored, and are
+ interpreted as literal sequences of three characters.
+ */
+ ENCODE_ALL,
+
+ /** Sequences of escape sequences, that represent characters from the
+ specified character set and that can be converted to UTF-32
+ characters, are first decoded. If they have to be encoded, they
+ are converted to UTF-8 characters and are than translated into
+ (sequences of) escape sequences. Other escape sequences are
+ copied verbatim (but using upper case hex digits).
+ */
+ WAS_ENCODED,
+
+ /** All escape sequences that are already present are copied verbatim
+ (but using upper case hex digits).
+ */
+ NOT_CANONIC
+ };
+
+ /** The way strings that represent (parts of) URIs are returned from get-
+ methods.
+
+ @descr Along with a DecodeMechanism parameter, the get-methods all
+ take an rtl_TextEncoding parameter, which is ignored unless the
+ DecodeMechanism is DECODE_WITH_CHARSET or DECODE_UNAMBIGUOUS.
+ */
+ enum DecodeMechanism
+ {
+ /** The (part of the) URI is returned unchanged. Since URIs are
+ written using a subset of US-ASCII, the returned string is
+ guaranteed to contain only US-ASCII characters.
+ */
+ NO_DECODE,
+
+ /** All sequences of escape sequences that represent UTF-8 coded
+ UTF-32 characters with a numerical value greater than 0x7F, are
+ replaced by the respective UTF-16 characters. All other escape
+ sequences are not decoded.
+ */
+ DECODE_TO_IURI,
+
+ /** All (sequences of) escape sequences that represent characters from
+ the specified character set, and that can be converted to UTF-32,
+ are replaced by the respective UTF-16 characters. All other
+ escape sequences are not decoded.
+ */
+ DECODE_WITH_CHARSET,
+
+ /** All (sequences of) escape sequences that represent characters from
+ the specified character set, that can be converted to UTF-32, and
+ that (in the case of ASCII characters) can safely be decoded
+ without altering the meaning of the (part of the) URI, are
+ replaced by the respective UTF-16 characters. All other escape
+ sequences are not decoded.
+ */
+ DECODE_UNAMBIGUOUS
+ };
+
+ //========================================================================
+ // General Structure:
+
+ inline INetURLObject():
+ m_eScheme(INET_PROT_NOT_VALID), m_eSmartScheme(INET_PROT_HTTP) {}
+
+ inline bool HasError() const { return m_eScheme == INET_PROT_NOT_VALID; }
+
+ inline rtl::OUString GetMainURL(DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const
+ { return decode(m_aAbsURIRef, getEscapePrefix(), eMechanism, eCharset); }
+
+ rtl::OUString GetURLNoPass(DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ const;
+
+ rtl::OUString GetURLNoMark(DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ const;
+
+ rtl::OUString
+ getAbbreviated(com::sun::star::uno::Reference<
+ com::sun::star::util::XStringWidth > const &
+ rStringWidth,
+ sal_Int32 nWidth,
+ DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ const;
+
+ bool operator ==(INetURLObject const & rObject) const;
+
+ inline bool operator !=(INetURLObject const & rObject) const
+ { return !(*this == rObject); }
+
+ bool operator <(INetURLObject const & rObject) const;
+
+ inline bool operator >(INetURLObject const & rObject) const
+ { return rObject < *this; }
+
+ //========================================================================
+ // Strict Parsing:
+
+ inline INetURLObject(ByteString const & rTheAbsURIRef,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ inline INetURLObject(rtl::OUString const & rTheAbsURIRef,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ inline bool SetURL(ByteString const & rTheAbsURIRef,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ inline bool SetURL(rtl::OUString const & rTheAbsURIRef,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ bool ConcatData(INetProtocol eTheScheme, rtl::OUString const & rTheUser,
+ rtl::OUString const & rThePassword,
+ rtl::OUString const & rTheHost, sal_uInt32 nThePort,
+ rtl::OUString const & rThePath,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ //========================================================================
+ // Smart Parsing:
+
+ /** The supported notations for file system paths.
+ */
+ enum FSysStyle
+ {
+ /** VOS notation (e.g., "//server/dir/file").
+ */
+ FSYS_VOS = 0x1,
+
+ /** Unix notation (e.g., "/dir/file").
+ */
+ FSYS_UNX = 0x2,
+
+ /** DOS notation (e.g., "a:\dir\file" and "\\server\dir\file").
+ */
+ FSYS_DOS = 0x4,
+
+ /** Mac notation (e.g., "dir:file").
+ */
+ FSYS_MAC = 0x8,
+
+ /** Detect the used notation.
+
+ @descr For the following descriptions, please note that
+ whereas FSYS_DEFAULT includes all style bits, combinations of only
+ a few style bits are also possible, and are also described.
+
+ @descr When used to translate a file system path to a file URL,
+ the subset of the following productions for which the appropriate
+ style bit is set are checked in order (using the conventions of
+ RFC 2234, RFC 2396, and RFC 2732; UCS4 stands for any UCS4
+ character):
+
+ Production T1 (VOS local; FSYS_VOS only):
+ "//." ["/" *UCS4]
+ becomes
+ "file:///" *UCS4
+
+ Production T2 (VOS host; FSYS_VOS only):
+ "//" [host] ["/" *UCS4]
+ becomes
+ "file://" host "/" *UCS4
+
+ Production T3 (UNC; FSYS_DOS only):
+ "\\" [host] ["\" *UCS4]
+ becomes
+ "file://" host "/" *UCS4
+ replacing "\" by "/" within <*UCS4>
+
+ Production T4 (Unix-like DOS; FSYS_DOS only):
+ ALPHA ":" ["/" *UCS4]
+ becomes
+ "file:///" ALPHA ":/" *UCS4
+ replacing "\" by "/" within <*UCS4>
+
+ Production T5 (DOS; FSYS_DOS only):
+ ALPHA ":" ["\" *UCS4]
+ becomes
+ "file:///" ALPHA ":/" *UCS4
+ replacing "\" by "/" within <*UCS4>
+
+ Production T6 (any):
+ *UCS4
+ becomes
+ "file:///" *UCS4
+ replacing the delimiter by "/" within <*UCS4>. The delimiter is
+ that character from the set { "/", "\", ":" } which appears most
+ often in <*UCS4> (if FSYS_UNX is not among the style bits, "/"
+ is removed from the set; if FSYS_DOS is not among the style
+ bits, "\" is removed from the set; if FSYS_MAC is not among the
+ style bits, ":" is removed from the set). If two or more
+ characters appear the same number of times, the character
+ mentioned first in that set is chosen. If the first character
+ of <*UCS4> is the delimiter, that character is not copied.
+
+ @descr When used to translate a file URL to a file system path,
+ the following productions are checked in order (using the
+ conventions of RFC 2234, RFC 2396, and RFC 2732):
+
+ Production F1 (VOS; FSYS_VOS):
+ "file://" host "/" fpath ["#" fragment]
+ becomes
+ "//" host "/" fpath
+
+ Production F2 (DOS; FSYS_DOS):
+ "file:///" ALPHA ":" ["/" fpath] ["#" fragment]
+ becomes
+ ALPHA ":" ["\" fpath]
+ replacing "/" by "\" in <fpath>
+
+ Production F3 (Unix; FSYS_UNX):
+ "file:///" fpath ["#" fragment]
+ becomes
+ "/" fpath
+ */
+ FSYS_DETECT = FSYS_VOS | FSYS_UNX | FSYS_DOS
+ };
+
+ inline INetURLObject(rtl::OUString const & rTheAbsURIRef,
+ INetProtocol eTheSmartScheme,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
+ FSysStyle eStyle = FSYS_DETECT);
+
+ inline void SetSmartProtocol(INetProtocol eTheSmartScheme)
+ { m_eSmartScheme = eTheSmartScheme; }
+
+ inline bool
+ SetSmartURL(ByteString const & rTheAbsURIRef,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
+ FSysStyle eStyle = FSYS_DETECT);
+
+ inline bool
+ SetSmartURL(rtl::OUString const & rTheAbsURIRef,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
+ FSysStyle eStyle = FSYS_DETECT);
+
+ inline INetURLObject
+ smartRel2Abs(ByteString const & rTheRelURIRef,
+ bool & rWasAbsolute,
+ bool bIgnoreFragment = false,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
+ bool bRelativeNonURIs = false,
+ FSysStyle eStyle = FSYS_DETECT) const;
+
+ inline INetURLObject
+ smartRel2Abs(rtl::OUString const & rTheRelURIRef,
+ bool & rWasAbsolute,
+ bool bIgnoreFragment = false,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
+ bool bRelativeNonURIs = false,
+ FSysStyle eStyle = FSYS_DETECT) const;
+
+ //========================================================================
+ // Relative URLs:
+
+ inline bool
+ GetNewAbsURL(ByteString const & rTheRelURIRef,
+ INetURLObject * pTheAbsURIRef,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
+ FSysStyle eStyle = FSYS_DETECT, bool bIgnoreFragment = false)
+ const;
+
+ inline bool
+ GetNewAbsURL(rtl::OUString const & rTheRelURIRef,
+ INetURLObject * pTheAbsURIRef,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
+ FSysStyle eStyle = FSYS_DETECT, bool bIgnoreFragment = false)
+ const;
+
+ /** @descr If rTheRelURIRef cannot be converted to an absolute URL
+ (because of syntactic reasons), either rTheRelURIRef or an empty
+ string is returned: If all of the parameters eEncodeMechanism,
+ eDecodeMechanism and eCharset have their respective default values,
+ then rTheRelURIRef is returned unmodified; otherwise, an empty string
+ is returned.
+ */
+ static rtl::OUString
+ GetAbsURL(rtl::OUString const & rTheBaseURIRef,
+ rtl::OUString const & rTheRelURIRef,
+ bool bIgnoreFragment = false,
+ EncodeMechanism eEncodeMechanism = WAS_ENCODED,
+ DecodeMechanism eDecodeMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
+ FSysStyle eStyle = FSYS_DETECT);
+
+ static inline rtl::OUString
+ GetRelURL(ByteString const & rTheBaseURIRef,
+ ByteString const & rTheAbsURIRef,
+ EncodeMechanism eEncodeMechanism = WAS_ENCODED,
+ DecodeMechanism eDecodeMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
+ FSysStyle eStyle = FSYS_DETECT);
+
+ static inline rtl::OUString
+ GetRelURL(rtl::OUString const & rTheBaseURIRef,
+ rtl::OUString const & rTheAbsURIRef,
+ EncodeMechanism eEncodeMechanism = WAS_ENCODED,
+ DecodeMechanism eDecodeMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
+ FSysStyle eStyle = FSYS_DETECT);
+
+ //========================================================================
+ // External URLs:
+
+ rtl::OUString getExternalURL(DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const;
+
+ static inline bool translateToExternal(ByteString const & rTheIntURIRef,
+ rtl::OUString & rTheExtURIRef,
+ DecodeMechanism eDecodeMechanism
+ = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8);
+
+ static inline bool translateToExternal(rtl::OUString const & rTheIntURIRef,
+ rtl::OUString & rTheExtURIRef,
+ DecodeMechanism eDecodeMechanism
+ = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8);
+
+ static inline bool translateToInternal(ByteString const & rTheExtURIRef,
+ rtl::OUString & rTheIntURIRef,
+ DecodeMechanism eDecodeMechanism
+ = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8);
+
+ static inline bool translateToInternal(rtl::OUString const & rTheExtURIRef,
+ rtl::OUString & rTheIntURIRef,
+ DecodeMechanism eDecodeMechanism
+ = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8);
+
+ //========================================================================
+ // Scheme:
+
+ struct SchemeInfo;
+
+ inline INetProtocol GetProtocol() const { return m_eScheme; }
+
+ /** Return the URL 'prefix' for a given scheme.
+
+ @param eTheScheme One of the supported URL schemes.
+
+ @return The 'prefix' of URLs of the given scheme.
+ */
+ static rtl::OUString GetScheme(INetProtocol eTheScheme);
+
+ static inline INetProtocol CompareProtocolScheme(ByteString const &
+ rTheAbsURIRef)
+ { return CompareProtocolScheme(extend(rTheAbsURIRef)); }
+
+ static INetProtocol CompareProtocolScheme(rtl::OUString const &
+ rTheAbsURIRef);
+
+ //========================================================================
+ // User Info:
+
+ inline bool HasUserData() const { return m_aUser.isPresent(); }
+
+ inline bool IsEmptyUser() const
+ { return m_aUser.isPresent() && m_aUser.isEmpty(); }
+
+ bool hasPassword() const;
+
+ inline bool IsEmptyPass() const
+ { return hasPassword() && m_aAuth.isEmpty(); }
+
+ inline rtl::OUString GetUser(DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const
+ { return decode(m_aUser, getEscapePrefix(), eMechanism, eCharset); }
+
+ inline rtl::OUString GetPass(DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const
+ { return decode(m_aAuth, getEscapePrefix(), eMechanism, eCharset); }
+
+ inline bool SetUser(ByteString const & rTheUser,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ { return setUser(extend(rTheUser), true, eMechanism, eCharset); }
+
+ inline bool SetUser(rtl::OUString const & rTheUser,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ { return setUser(rTheUser, false, eMechanism, eCharset); }
+
+ void makeAuthCanonic();
+
+ inline bool SetPass(ByteString const & rThePassword,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ inline bool SetPass(rtl::OUString const & rThePassword,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ inline bool SetUserAndPass(ByteString const & rTheUser,
+ ByteString const & rThePassword,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8);
+
+ inline bool SetUserAndPass(rtl::OUString const & rTheUser,
+ rtl::OUString const & rThePassword,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8);
+
+ //========================================================================
+ // Host and Port:
+
+ inline bool HasPort() const { return m_aPort.isPresent(); }
+
+ inline rtl::OUString GetHost(DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const
+ { return decode(m_aHost, getEscapePrefix(), eMechanism, eCharset); }
+
+ rtl::OUString GetHostPort(DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ sal_uInt32 GetPort() const;
+
+ inline bool SetHost(ByteString const & rTheHost,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ { return setHost(extend(rTheHost), true, eMechanism, eCharset); }
+
+ inline bool SetHost(rtl::OUString const & rTheHost,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ { return setHost(rTheHost, false, eMechanism, eCharset); }
+
+ bool SetPort(sal_uInt32 nThePort);
+
+ void makePortCanonic();
+
+ /** Encode the <hostport> part of a URL.
+
+ @ATT Obsolete, because at the moment the <hostport> part of a URL may
+ not contain any escape sequences anyway, and because this method does
+ not inform the caller whether the given <hostport> part is legal.
+
+ @param rTheHostPort The <hostport> part of a URL (for its
+ interpretation, see the general discussion for set-methods).
+
+ @param eMechanism See the general discussion for set-methods.
+
+ @param eCharset See the general discussion for set-methods.
+
+ @return The <hostport> part, encoded according to the given mechanism
+ and charset ('forbidden' characters replaced by escape sequences).
+ */
+ static inline rtl::OUString encodeHostPort(ByteString const & rTheHostPort,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8);
+
+ /** Encode the <hostport> part of a URL.
+
+ @ATT Obsolete, because at the moment the <hostport> part of a URL may
+ not contain any escape sequences anyway, and because this method does
+ not inform the caller whether the given <hostport> part is legal.
+
+ @param rTheHostPort The <hostport> part of a URL (for its
+ interpretation, see the general discussion for set-methods).
+
+ @param eMechanism See the general discussion for set-methods.
+
+ @param eCharset See the general discussion for set-methods.
+
+ @return The <hostport> part, encoded according to the given mechanism
+ and charset ('forbidden' characters replaced by escape sequences).
+ */
+ static inline rtl::OUString encodeHostPort(rtl::OUString const & rTheHostPort,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8)
+ { return encodeHostPort(rTheHostPort, false, eMechanism, eCharset); }
+
+ //========================================================================
+ // Path:
+
+ inline bool HasURLPath() const { return !m_aPath.isEmpty(); }
+
+ inline rtl::OUString GetURLPath(DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const
+ { return decode(m_aPath, getEscapePrefix(), eMechanism, eCharset); }
+
+ inline bool SetURLPath(ByteString const & rThePath,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ { return setPath(extend(rThePath), true, eMechanism, eCharset); }
+
+ inline bool SetURLPath(rtl::OUString const & rThePath,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ { return setPath(rThePath, false, eMechanism, eCharset); }
+
+ //========================================================================
+ // Hierarchical Path:
+
+ /** A constant to address the last segment in various methods dealing with
+ hierarchical paths.
+
+ @descr It is often more efficient to address the last segment using
+ this constant, than to determine its ordinal value using
+ getSegmentCount().
+ */
+ enum { LAST_SEGMENT = -1 };
+
+ /** The number of segments in the hierarchical path.
+
+ @descr Using RFC 2396 and RFC 2234, a hierarchical path is of the
+ form
+
+ hierarchical-path = 1*("/" segment)
+
+ segment = name *(";" param)
+
+ name = [base ["." extension]]
+
+ base = 1*pchar
+
+ extension = *<any pchar except ".">
+
+ param = *pchar
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @return The number of segments in the hierarchical path. If the path
+ is not hierarchical, 0 is returned.
+ */
+ sal_Int32 getSegmentCount(bool bIgnoreFinalSlash = true) const;
+
+ /** Remove a segment from the hierarchical path.
+
+ @param nIndex The non-negative index of the segment, or LAST_SEGMENT
+ if addressing the last segment.
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @return True if the segment has successfully been removed (and the
+ resulting URI is still valid). If the path is not hierarchical, or
+ the specified segment does not exist, false is returned. If false is
+ returned, the object is not modified.
+ */
+ bool removeSegment(sal_Int32 nIndex = LAST_SEGMENT,
+ bool bIgnoreFinalSlash = true);
+
+ /** Insert a new segment into the hierarchical path.
+
+ @param rTheName The name part of the new segment. The new segment
+ will contain no parameters.
+
+ @param bAppendFinalSlash If the new segment is appended at the end of
+ the hierarchical path, this parameter specifies whether to add a final
+ slash after it or not.
+
+ @param nIndex The non-negative index of the segment before which
+ to insert the new segment. LAST_SEGMENT or an nIndex that equals
+ getSegmentCount() inserts the new segment at the end of the
+ hierarchical path.
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @param eMechanism See the general discussion for set-methods.
+
+ @param eCharset See the general discussion for set-methods.
+
+ @return True if the segment has successfully been inserted (and the
+ resulting URI is still valid). If the path is not hierarchical, or
+ the specified place to insert the new segment does not exist, false is
+ returned. If false is returned, the object is not modified.
+ */
+ inline bool insertName(rtl::OUString const & rTheName,
+ bool bAppendFinalSlash = false,
+ sal_Int32 nIndex = LAST_SEGMENT,
+ bool bIgnoreFinalSlash = true,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ /** Get the name of a segment of the hierarchical path.
+
+ @param nIndex The non-negative index of the segment, or LAST_SEGMENT
+ if addressing the last segment.
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @param eMechanism See the general discussion for get-methods.
+
+ @param eCharset See the general discussion for get-methods.
+
+ @return The name part of the specified segment. If the path is not
+ hierarchical, or the specified segment does not exits, an empty string
+ is returned.
+ */
+ rtl::OUString getName(sal_Int32 nIndex = LAST_SEGMENT,
+ bool bIgnoreFinalSlash = true,
+ DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ const;
+
+ /** Set the name of a segment (preserving any parameters and any query or
+ fragment part).
+
+ @param rTheName The new name.
+
+ @param nIndex The non-negative index of the segment, or LAST_SEGMENT
+ if addressing the last segment.
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @param eMechanism See the general discussion for set-methods.
+
+ @param eCharset See the general discussion for set-methods.
+
+ @return True if the name has successfully been modified (and the
+ resulting URI is still valid). If the path is not hierarchical, or
+ the specified segment does not exist, false is returned. If false is
+ returned, the object is not modified.
+ */
+ bool setName(rtl::OUString const & rTheName,
+ sal_Int32 nIndex = LAST_SEGMENT,
+ bool bIgnoreFinalSlash = true,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ /** Get the base of the name of a segment.
+
+ @param nIndex The non-negative index of the segment, or LAST_SEGMENT
+ if addressing the last segment.
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @param eMechanism See the general discussion for get-methods.
+
+ @param eCharset See the general discussion for get-methods.
+
+ @return The base part of the specified segment. If the path is
+ not hierarchical, or the specified segment does not exits, an empty
+ string is returned.
+ */
+ rtl::OUString getBase(sal_Int32 nIndex = LAST_SEGMENT,
+ bool bIgnoreFinalSlash = true,
+ DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ const;
+
+ /** Set the base of the name of a segment (preserving the extension).
+
+ @param rTheBase The new base.
+
+ @param nIndex The non-negative index of the segment, or LAST_SEGMENT
+ if addressing the last segment.
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @param eMechanism See the general discussion for set-methods.
+
+ @param eCharset See the general discussion for set-methods.
+
+ @return True if the base has successfully been modified (and the
+ resulting URI is still valid). If the path is not hierarchical, or
+ the specified segment does not exist, false is returned. If false is
+ returned, the object is not modified.
+ */
+ bool setBase(rtl::OUString const & rTheBase,
+ sal_Int32 nIndex = LAST_SEGMENT,
+ bool bIgnoreFinalSlash = true,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ /** Determine whether the name of a segment has an extension.
+
+ @param nIndex The non-negative index of the segment, or LAST_SEGMENT
+ if addressing the last segment.
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @return True if the name of the specified segment has an extension.
+ If the path is not hierarchical, or the specified segment does not
+ exist, false is returned.
+ */
+ bool hasExtension(sal_Int32 nIndex = LAST_SEGMENT,
+ bool bIgnoreFinalSlash = true) const;
+
+ /** Get the extension of the name of a segment.
+
+ @param nIndex The non-negative index of the segment, or LAST_SEGMENT
+ if addressing the last segment.
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @param eMechanism See the general discussion for get-methods.
+
+ @param eCharset See the general discussion for get-methods.
+
+ @return The extension part of the specified segment. If the path is
+ not hierarchical, or the specified segment does not exits, an empty
+ string is returned.
+ */
+ rtl::OUString getExtension(sal_Int32 nIndex = LAST_SEGMENT,
+ bool bIgnoreFinalSlash = true,
+ DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ const;
+
+ /** Set the extension of the name of a segment (replacing an already
+ existing extension).
+
+ @param rTheExtension The new extension.
+
+ @param nIndex The non-negative index of the segment, or LAST_SEGMENT
+ if addressing the last segment.
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @param eMechanism See the general discussion for set-methods.
+
+ @param eCharset See the general discussion for set-methods.
+
+ @return True if the extension has successfully been modified (and the
+ resulting URI is still valid). If the path is not hierarchical, or
+ the specified segment does not exist, false is returned. If false is
+ returned, the object is not modified.
+ */
+ bool setExtension(rtl::OUString const & rTheExtension,
+ sal_Int32 nIndex = LAST_SEGMENT,
+ bool bIgnoreFinalSlash = true,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ /** Remove the extension of the name of a segment.
+
+ @param nIndex The non-negative index of the segment, or LAST_SEGMENT
+ if addressing the last segment.
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @return True if the extension has successfully been removed (and the
+ resulting URI is still valid), or if the name did not have an
+ extension. If the path is not hierarchical, or the specified segment
+ does not exist, false is returned. If false is returned, the object
+ is not modified.
+ */
+ bool removeExtension(sal_Int32 nIndex = LAST_SEGMENT,
+ bool bIgnoreFinalSlash = true);
+
+ /** Determine whether the hierarchical path ends in a final slash.
+
+ @return True if the hierarchical path ends in a final slash. If the
+ path is not hierarchical, false is returned.
+ */
+ bool hasFinalSlash() const;
+
+ /** Make the hierarchical path end in a final slash (if it does not
+ already do so).
+
+ @return True if a final slash has successfully been appended (and the
+ resulting URI is still valid), or if the hierarchical path already
+ ended in a final slash. If the path is not hierarchical, false is
+ returned. If false is returned, the object is not modified.
+ */
+ bool setFinalSlash();
+
+ /** Remove a final slash from the hierarchical path.
+
+ @return True if a final slash has successfully been removed (and the
+ resulting URI is still valid), or if the hierarchical path already did
+ not end in a final slash. If the path is not hierarchical, false is
+ returned. If false is returned, the object is not modified.
+ */
+ bool removeFinalSlash();
+
+ //========================================================================
+ // Query:
+
+ inline bool HasParam() const { return m_aQuery.isPresent(); }
+
+ inline rtl::OUString GetParam(DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const
+ { return decode(m_aQuery, getEscapePrefix(), eMechanism, eCharset); }
+
+ inline bool SetParam(ByteString const & rTheQuery,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ inline bool SetParam(rtl::OUString const & rTheQuery,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ //========================================================================
+ // Fragment:
+
+ inline bool HasMark() const { return m_aFragment.isPresent(); }
+
+ inline rtl::OUString GetMark(DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const
+ { return decode(m_aFragment, getEscapePrefix(), eMechanism, eCharset); }
+
+ inline bool SetMark(ByteString const & rTheFragment,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ inline bool SetMark(rtl::OUString const & rTheFragment,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ static rtl::OUString createFragment(rtl::OUString const & rText);
+
+ //========================================================================
+ // File URLs:
+
+ /** Create an INetURLObject from a file system path.
+
+ @param rFSysPath A file system path. An URL is not allowed here!
+
+ @param eStyle The notation of rFSysPath.
+ */
+ inline INetURLObject(rtl::OUString const & rFSysPath, FSysStyle eStyle);
+
+ /** Set this INetURLObject to a file URL constructed from a file system
+ path.
+
+ @param rFSysPath A file system path. An URL is not allowed here!
+
+ @param eStyle The notation of rFSysPath.
+
+ @return True if this INetURLObject has successfully been changed. If
+ false is returned, this INetURLObject has not been modified.
+ */
+ bool setFSysPath(rtl::OUString const & rFSysPath, FSysStyle eStyle);
+
+ /** Return the file system path represented by a file URL (ignoring any
+ fragment part).
+
+ @param eStyle The notation of the returned file system path.
+
+ @param pDelimiter Upon successful return, this parameter can return
+ the character that is the 'main' delimiter within the returned file
+ system path (e.g., "/" for Unix, "\" for DOS, ":" for Mac). This is
+ especially useful for routines that later try to shorten the returned
+ file system path at a 'good' position, e.g. to fit it into some
+ limited display space.
+
+ @return The file system path represented by this file URL. If this
+ file URL does not represent a file system path according to the
+ specified notation, or if this is not a file URL at all, an empty
+ string is returned.
+ */
+ rtl::OUString getFSysPath(FSysStyle eStyle, sal_Unicode * pDelimiter = 0)
+ const;
+
+ //========================================================================
+ // POP3 and URLs:
+
+ bool HasMsgId() const;
+
+ rtl::OUString GetMsgId(DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ const;
+
+ //========================================================================
+ // Coding:
+
+ enum Part
+ {
+ PART_OBSOLETE_NORMAL = 0x001, // Obsolete, do not use!
+ PART_OBSOLETE_FILE = 0x002, // Obsolete, do not use!
+ PART_OBSOLETE_PARAM = 0x004, // Obsolete, do not use!
+ PART_USER_PASSWORD = 0x008,
+ PART_IMAP_ACHAR = 0x010,
+ PART_VIM = 0x020,
+ PART_HOST_EXTRA = 0x040,
+ PART_FPATH = 0x080,
+ PART_AUTHORITY = 0x100,
+ PART_PATH_SEGMENTS_EXTRA = 0x200,
+ PART_REL_SEGMENT_EXTRA = 0x400,
+ PART_URIC = 0x800,
+ PART_HTTP_PATH = 0x1000,
+ PART_FILE_SEGMENT_EXTRA = 0x2000, // Obsolete, do not use!
+ PART_MESSAGE_ID = 0x4000,
+ PART_MESSAGE_ID_PATH = 0x8000,
+ PART_MAILTO = 0x10000,
+ PART_PATH_BEFORE_QUERY = 0x20000,
+ PART_PCHAR = 0x40000,
+ PART_FRAGMENT = 0x80000, // Obsolete, do not use!
+ PART_VISIBLE = 0x100000,
+ PART_VISIBLE_NONSPECIAL = 0x200000,
+ PART_CREATEFRAGMENT = 0x400000,
+ PART_UNO_PARAM_VALUE = 0x800000,
+ PART_UNAMBIGUOUS = 0x1000000,
+ PART_URIC_NO_SLASH = 0x2000000,
+ PART_HTTP_QUERY = 0x4000000, //TODO! unused?
+ PART_NEWS_ARTICLE_LOCALPART = 0x8000000,
+ max_part = 0x80000000
+ // Do not use! Only there to allow compatible changes in the
+ // future.
+ };
+
+ enum EscapeType
+ {
+ ESCAPE_NO,
+ ESCAPE_OCTET,
+ ESCAPE_UTF32
+ };
+
+ /** Encode some text as part of a URI.
+
+ @param rText Some text (for its interpretation, see the general
+ discussion for set-methods).
+
+ @param ePart The part says which characters are 'forbidden' and must
+ be encoded (replaced by escape sequences). Characters outside the US-
+ ASCII range are always 'forbidden.'
+
+ @param cEscapePrefix The first character in an escape sequence
+ (normally '%').
+
+ @param eMechanism See the general discussion for set-methods.
+
+ @param eCharset See the general discussion for set-methods.
+
+ @return The encoded representation of the text ('forbidden'
+ characters replaced by escape sequences).
+ */
+ static inline rtl::OUString encode(ByteString const & rText, Part ePart,
+ sal_Char cEscapePrefix,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8);
+
+ /** Encode some text as part of a URI.
+
+ @param rText Some text (for its interpretation, see the general
+ discussion for set-methods).
+
+ @param ePart The part says which characters are 'forbidden' and must
+ be encoded (replaced by escape sequences). Characters outside the US-
+ ASCII range are always 'forbidden.'
+
+ @param cEscapePrefix The first character in an escape sequence
+ (normally '%').
+
+ @param eMechanism See the general discussion for set-methods.
+
+ @param eCharset See the general discussion for set-methods.
+
+ @return The text, encoded according to the given mechanism and
+ charset ('forbidden' characters replaced by escape sequences).
+ */
+ static inline rtl::OUString encode(rtl::OUString const & rText, Part ePart,
+ sal_Char cEscapePrefix,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8);
+
+ /** Decode some text.
+
+ @param rText Some (encoded) text.
+
+ @param cEscapePrefix The first character in an escape sequence
+ (normally '%').
+
+ @param eMechanism See the general discussion for get-methods.
+
+ @param eCharset See the general discussion for get-methods.
+
+ @return The text, decoded according to the given mechanism and
+ charset (escape sequences replaced by 'raw' characters).
+ */
+ static inline rtl::OUString decode(rtl::OUString const & rText,
+ sal_Char cEscapePrefix,
+ DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8);
+
+ static inline rtl::OUString decode(rtl::OUStringBuffer const & rText,
+ sal_Char cEscapePrefix,
+ DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8);
+
+ static void appendUCS4Escape(rtl::OUStringBuffer & rTheText,
+ sal_Char cEscapePrefix,
+ sal_uInt32 nUCS4);
+
+ static void appendUCS4(rtl::OUStringBuffer & rTheText, sal_uInt32 nUCS4,
+ EscapeType eEscapeType, bool bOctets, Part ePart,
+ sal_Char cEscapePrefix, rtl_TextEncoding eCharset,
+ bool bKeepVisibleEscapes);
+
+ static sal_uInt32 getUTF32(sal_Unicode const *& rBegin,
+ sal_Unicode const * pEnd, bool bOctets,
+ sal_Char cEscapePrefix,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ EscapeType & rEscapeType);
+
+ //========================================================================
+ // Specialized helpers:
+
+ static sal_uInt32 scanDomain(sal_Unicode const *& rBegin,
+ sal_Unicode const * pEnd,
+ bool bEager = true);
+
+ //========================================================================
+ // OBSOLETE Hierarchical Path:
+
+ rtl::OUString GetPartBeforeLastName(DecodeMechanism eMechanism
+ = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const;
+
+ /** Get the last segment in the path.
+
+ @param eMechanism See the general discussion for get-methods.
+
+ @param eCharset See the general discussion for get-methods.
+
+ @return For a hierarchical URL, the last segment (everything after
+ the last unencoded '/'). Not that this last segment may be empty. If
+ the URL is not hierarchical, an empty string is returned.
+ */
+ rtl::OUString GetLastName(DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ const;
+
+ /** Get the 'extension' of the last segment in the path.
+
+ @param eMechanism See the general discussion for get-methods.
+
+ @param eCharset See the general discussion for get-methods.
+
+ @return For a hierarchical URL, everything after the first unencoded
+ '.' in the last segment of the path. Note that this 'extension' may
+ be empty. If the URL is not hierarchical, or if the last segment does
+ not contain an unencoded '.', an empty string is returned.
+ */
+ rtl::OUString GetFileExtension(DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const;
+
+ inline bool Append(ByteString const & rTheSegment,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ { return appendSegment(extend(rTheSegment), true, eMechanism, eCharset); }
+
+ inline bool Append(rtl::OUString const & rTheSegment,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ { return appendSegment(rTheSegment, false, eMechanism, eCharset); }
+
+ bool CutLastName();
+
+ //========================================================================
+ // OBSOLETE File URLs:
+
+ rtl::OUString PathToFileName() const;
+
+ rtl::OUString GetFull() const;
+
+ rtl::OUString GetPath() const;
+
+ void SetBase(rtl::OUString const & rTheBase);
+
+ rtl::OUString GetBase() const;
+
+ void SetName(rtl::OUString const & rTheName,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ inline rtl::OUString GetName(DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const
+ { return GetLastName(eMechanism, eCharset); }
+
+ rtl::OUString CutName(DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ void SetExtension(rtl::OUString const & rTheExtension,
+ EncodeMechanism eMechanism = WAS_ENCODED,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ inline rtl::OUString GetExtension(
+ DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const
+ { return GetFileExtension(eMechanism, eCharset); }
+
+ rtl::OUString CutExtension(DecodeMechanism eMechanism = DECODE_TO_IURI,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ bool IsCaseSensitive() const;
+
+ //========================================================================
+
+private:
+ // General Structure:
+
+ class SubString
+ {
+ sal_Int32 m_nBegin;
+ sal_Int32 m_nLength;
+
+ public:
+ explicit inline SubString(sal_Int32 nTheBegin = -1,
+ sal_Int32 nTheLength = 0):
+ m_nBegin(nTheBegin), m_nLength(nTheLength) {}
+
+ inline bool isPresent() const { return m_nBegin != -1; }
+
+ inline bool isEmpty() const { return m_nLength == 0; }
+
+ inline sal_Int32 getBegin() const { return m_nBegin; }
+
+ inline sal_Int32 getLength() const { return m_nLength; }
+
+ inline sal_Int32 getEnd() const { return m_nBegin + m_nLength; }
+
+ inline sal_Int32 clear();
+
+ inline sal_Int32 set(rtl::OUStringBuffer & rString,
+ rtl::OUString const & rSubString,
+ sal_Int32 nTheBegin);
+
+ inline sal_Int32 set(rtl::OUString & rString,
+ rtl::OUString const & rSubString);
+
+ inline sal_Int32 set(rtl::OUStringBuffer & rString,
+ rtl::OUString const & rSubString);
+
+ inline void operator +=(sal_Int32 nDelta);
+
+ int compare(SubString const & rOther,
+ rtl::OUStringBuffer const & rThisString,
+ rtl::OUStringBuffer const & rOtherString) const;
+ };
+
+ rtl::OUStringBuffer m_aAbsURIRef;
+ SubString m_aScheme;
+ SubString m_aUser;
+ SubString m_aAuth;
+ SubString m_aHost;
+ SubString m_aPort;
+ SubString m_aPath;
+ SubString m_aQuery;
+ SubString m_aFragment;
+ INetProtocol m_eScheme;
+ INetProtocol m_eSmartScheme;
+
+ TOOLS_DLLPRIVATE void setInvalid();
+
+ bool setAbsURIRef(
+ rtl::OUString const & rTheAbsURIRef, bool bOctets,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset, bool bSmart,
+ FSysStyle eStyle);
+
+ // Relative URLs:
+
+ bool convertRelToAbs(
+ rtl::OUString const & rTheRelURIRef, bool bOctets,
+ INetURLObject & rTheAbsURIRef, bool & rWasAbsolute,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset,
+ bool bIgnoreFragment, bool bSmart, bool bRelativeNonURIs,
+ FSysStyle eStyle) const;
+
+ bool convertAbsToRel(
+ rtl::OUString const & rTheAbsURIRef, bool bOctets,
+ rtl::OUString & rTheRelURIRef, EncodeMechanism eEncodeMechanism,
+ DecodeMechanism eDecodeMechanism, rtl_TextEncoding eCharset,
+ FSysStyle eStyle) const;
+
+ // External URLs:
+
+ static bool convertIntToExt(
+ rtl::OUString const & rTheIntURIRef, bool bOctets,
+ rtl::OUString & rTheExtURIRef, DecodeMechanism eDecodeMechanism,
+ rtl_TextEncoding eCharset);
+
+ static bool convertExtToInt(
+ rtl::OUString const & rTheExtURIRef, bool bOctets,
+ rtl::OUString & rTheIntURIRef, DecodeMechanism eDecodeMechanism,
+ rtl_TextEncoding eCharset);
+
+ // Scheme:
+
+ struct PrefixInfo;
+
+ TOOLS_DLLPRIVATE static inline SchemeInfo const & getSchemeInfo(
+ INetProtocol eTheScheme);
+
+ TOOLS_DLLPRIVATE inline SchemeInfo const & getSchemeInfo() const;
+
+ TOOLS_DLLPRIVATE static PrefixInfo const * getPrefix(
+ sal_Unicode const *& rBegin, sal_Unicode const * pEnd);
+
+ // Authority:
+
+ TOOLS_DLLPRIVATE sal_Int32 getAuthorityBegin() const;
+
+ TOOLS_DLLPRIVATE SubString getAuthority() const;
+
+ // User Info:
+
+ bool setUser(
+ rtl::OUString const & rTheUser, bool bOctets,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
+
+ bool clearPassword();
+
+ bool setPassword(
+ rtl::OUString const & rThePassword, bool bOctets,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
+
+ // Host and Port:
+
+ TOOLS_DLLPRIVATE static bool parseHost(
+ sal_Unicode const *& rBegin, sal_Unicode const * pEnd,
+ rtl::OUString & rCanonic);
+
+ TOOLS_DLLPRIVATE static bool parseHostOrNetBiosName(
+ sal_Unicode const * pBegin, sal_Unicode const * pEnd, bool bOctets,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset,
+ bool bNetBiosName, rtl::OUStringBuffer* pCanonic);
+
+ static rtl::OUString encodeHostPort(
+ rtl::OUString const & rTheHostPort, bool bOctets,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
+
+ bool setHost(
+ rtl::OUString const & rTheHost, bool bOctets,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
+
+ // Path:
+
+ TOOLS_DLLPRIVATE static bool parsePath(
+ INetProtocol eScheme, sal_Unicode const ** pBegin,
+ sal_Unicode const * pEnd, bool bOctets, EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset, bool bSkippedInitialSlash,
+ sal_uInt32 nSegmentDelimiter, sal_uInt32 nAltSegmentDelimiter,
+ sal_uInt32 nQueryDelimiter, sal_uInt32 nFragmentDelimiter,
+ rtl::OUStringBuffer &rSynPath);
+
+ bool setPath(
+ rtl::OUString const & rThePath, bool bOctets,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
+
+ // Hierarchical Path:
+
+ TOOLS_DLLPRIVATE bool checkHierarchical() const;
+
+ bool appendSegment(
+ rtl::OUString const & rTheSegment, bool bOctets,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
+
+ TOOLS_DLLPRIVATE SubString getSegment(
+ sal_Int32 nIndex, bool bIgnoreFinalSlash) const;
+
+ bool insertName(
+ rtl::OUString const & rTheName, bool bOctets, bool bAppendFinalSlash,
+ sal_Int32 nIndex, bool bIgnoreFinalSlash, EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset);
+
+ // Query:
+
+ bool clearQuery();
+
+ bool setQuery(
+ rtl::OUString const & rTheQuery, bool bOctets,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
+
+ // Fragment:
+
+ bool clearFragment();
+
+ bool setFragment(
+ rtl::OUString const & rTheMark, bool bOctets,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
+
+ // FTP URLs:
+
+ enum FTPType { FTP_TYPE_NONE, FTP_TYPE_A, FTP_TYPE_I, FTP_TYPE_D };
+
+ TOOLS_DLLPRIVATE FTPType getFTPType() const;
+
+ // FILE URLs:
+
+ TOOLS_DLLPRIVATE bool hasDosVolume(FSysStyle eStyle) const;
+
+ // IMAP URLs:
+
+ TOOLS_DLLPRIVATE sal_uInt32 getIMAPUID() const;
+
+ // Coding:
+
+ static inline rtl::OUString extend(ByteString const & rOctets)
+ {
+ return rtl::OUString(rOctets.GetBuffer(), rOctets.Len(),
+ RTL_TEXTENCODING_ISO_8859_1);
+ }
+
+ static inline sal_Char getEscapePrefix(INetProtocol eTheScheme)
+ { return eTheScheme == INET_PROT_VIM ? '=' : '%'; }
+
+ inline sal_Char getEscapePrefix() const
+ { return getEscapePrefix(m_eScheme); }
+
+ TOOLS_DLLPRIVATE static inline void appendEscape(
+ rtl::OUStringBuffer & rTheText, sal_Char cEscapePrefix,
+ sal_uInt32 nOctet);
+
+ static rtl::OUString encodeText(
+ sal_Unicode const * pBegin, sal_Unicode const * pEnd, bool bOctets,
+ Part ePart, sal_Char cEscapePrefix, EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset, bool bKeepVisibleEscapes);
+
+ static inline rtl::OUString encodeText(
+ rtl::OUString const & rTheText, bool bOctets, Part ePart,
+ sal_Char cEscapePrefix, EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset, bool bKeepVisibleEscapes);
+
+ static rtl::OUString decode(
+ sal_Unicode const * pBegin, sal_Unicode const * pEnd,
+ sal_Char cEscapePrefix, DecodeMechanism, rtl_TextEncoding eCharset);
+
+ inline rtl::OUString decode(
+ SubString const & rSubString, sal_Char cEscapePrefix,
+ DecodeMechanism eMechanism, rtl_TextEncoding eCharset) const;
+
+ // Specialized helpers:
+
+ TOOLS_DLLPRIVATE static bool scanIPv6reference(
+ sal_Unicode const *& rBegin, sal_Unicode const * pEnd);
+};
+
+// static
+inline rtl::OUString INetURLObject::encodeText(rtl::OUString const & rTheText,
+ bool bOctets, Part ePart,
+ sal_Char cEscapePrefix,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ bool bKeepVisibleEscapes)
+{
+ return encodeText(rTheText.getStr(),
+ rTheText.getStr() + rTheText.getLength(), bOctets, ePart,
+ cEscapePrefix, eMechanism, eCharset,
+ bKeepVisibleEscapes);
+}
+
+inline rtl::OUString INetURLObject::decode(SubString const & rSubString,
+ sal_Char cEscapePrefix,
+ DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset) const
+{
+ return rSubString.isPresent() ?
+ decode(m_aAbsURIRef.getStr() + rSubString.getBegin(),
+ m_aAbsURIRef.getStr() + rSubString.getEnd(),
+ cEscapePrefix, eMechanism, eCharset) :
+ rtl::OUString();
+}
+
+inline INetURLObject::INetURLObject(ByteString const & rTheAbsURIRef,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset):
+ m_eScheme(INET_PROT_NOT_VALID), m_eSmartScheme(INET_PROT_HTTP)
+{
+ setAbsURIRef(extend(rTheAbsURIRef), true, eMechanism, eCharset, false,
+ FSysStyle(0));
+}
+
+inline INetURLObject::INetURLObject(rtl::OUString const & rTheAbsURIRef,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset):
+ m_eScheme(INET_PROT_NOT_VALID), m_eSmartScheme(INET_PROT_HTTP)
+{
+ setAbsURIRef(rTheAbsURIRef, false, eMechanism, eCharset, false,
+ FSysStyle(0));
+}
+
+inline bool INetURLObject::SetURL(ByteString const & rTheAbsURIRef,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return setAbsURIRef(extend(rTheAbsURIRef), true, eMechanism, eCharset,
+ false, FSysStyle(0));
+}
+
+inline bool INetURLObject::SetURL(rtl::OUString const & rTheAbsURIRef,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return setAbsURIRef(rTheAbsURIRef, false, eMechanism, eCharset, false,
+ FSysStyle(0));
+}
+
+inline INetURLObject::INetURLObject(rtl::OUString const & rTheAbsURIRef,
+ INetProtocol eTheSmartScheme,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ FSysStyle eStyle):
+ m_eScheme(INET_PROT_NOT_VALID), m_eSmartScheme(eTheSmartScheme)
+{
+ setAbsURIRef(rTheAbsURIRef, false, eMechanism, eCharset, true, eStyle);
+}
+
+inline bool INetURLObject::SetSmartURL(ByteString const & rTheAbsURIRef,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ FSysStyle eStyle)
+{
+ return setAbsURIRef(extend(rTheAbsURIRef), true, eMechanism, eCharset,
+ true, eStyle);
+}
+
+inline bool INetURLObject::SetSmartURL(rtl::OUString const & rTheAbsURIRef,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ FSysStyle eStyle)
+{
+ return setAbsURIRef(rTheAbsURIRef, false, eMechanism, eCharset, true,
+ eStyle);
+}
+
+inline INetURLObject
+INetURLObject::smartRel2Abs(ByteString const & rTheRelURIRef,
+ bool & rWasAbsolute,
+ bool bIgnoreFragment,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ bool bRelativeNonURIs,
+ FSysStyle eStyle) const
+{
+ INetURLObject aTheAbsURIRef;
+ convertRelToAbs(extend(rTheRelURIRef), true, aTheAbsURIRef, rWasAbsolute,
+ eMechanism, eCharset, bIgnoreFragment, true,
+ bRelativeNonURIs, eStyle);
+ return aTheAbsURIRef;
+}
+
+inline INetURLObject
+INetURLObject::smartRel2Abs(rtl::OUString const & rTheRelURIRef,
+ bool & rWasAbsolute,
+ bool bIgnoreFragment,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ bool bRelativeNonURIs,
+ FSysStyle eStyle) const
+{
+ INetURLObject aTheAbsURIRef;
+ convertRelToAbs(rTheRelURIRef, false, aTheAbsURIRef, rWasAbsolute,
+ eMechanism, eCharset, bIgnoreFragment, true,
+ bRelativeNonURIs, eStyle);
+ return aTheAbsURIRef;
+}
+
+inline bool INetURLObject::GetNewAbsURL(ByteString const & rTheRelURIRef,
+ INetURLObject * pTheAbsURIRef,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ FSysStyle eStyle, bool bIgnoreFragment)
+ const
+{
+ INetURLObject aTheAbsURIRef;
+ bool bWasAbsolute;
+ if (!convertRelToAbs(extend(rTheRelURIRef), true, aTheAbsURIRef,
+ bWasAbsolute, eMechanism, eCharset, bIgnoreFragment,
+ false, false, eStyle))
+ return false;
+ if (pTheAbsURIRef)
+ *pTheAbsURIRef = aTheAbsURIRef;
+ return true;
+}
+
+inline bool INetURLObject::GetNewAbsURL(rtl::OUString const & rTheRelURIRef,
+ INetURLObject * pTheAbsURIRef,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ FSysStyle eStyle, bool bIgnoreFragment)
+ const
+{
+ INetURLObject aTheAbsURIRef;
+ bool bWasAbsolute;
+ if (!convertRelToAbs(rTheRelURIRef, false, aTheAbsURIRef, bWasAbsolute,
+ eMechanism, eCharset, bIgnoreFragment, false, false,
+ eStyle))
+ return false;
+ if (pTheAbsURIRef)
+ *pTheAbsURIRef = aTheAbsURIRef;
+ return true;
+}
+
+// static
+inline rtl::OUString INetURLObject::GetRelURL(ByteString const & rTheBaseURIRef,
+ ByteString const & rTheAbsURIRef,
+ EncodeMechanism eEncodeMechanism,
+ DecodeMechanism eDecodeMechanism,
+ rtl_TextEncoding eCharset,
+ FSysStyle eStyle)
+{
+ rtl::OUString aTheRelURIRef;
+ INetURLObject(rTheBaseURIRef, eEncodeMechanism, eCharset).
+ convertAbsToRel(extend(rTheAbsURIRef), true, aTheRelURIRef,
+ eEncodeMechanism, eDecodeMechanism, eCharset, eStyle);
+ return aTheRelURIRef;
+}
+
+// static
+inline rtl::OUString INetURLObject::GetRelURL(rtl::OUString const & rTheBaseURIRef,
+ rtl::OUString const & rTheAbsURIRef,
+ EncodeMechanism eEncodeMechanism,
+ DecodeMechanism eDecodeMechanism,
+ rtl_TextEncoding eCharset,
+ FSysStyle eStyle)
+{
+ rtl::OUString aTheRelURIRef;
+ INetURLObject(rTheBaseURIRef, eEncodeMechanism, eCharset).
+ convertAbsToRel(rTheAbsURIRef, false, aTheRelURIRef, eEncodeMechanism,
+ eDecodeMechanism, eCharset, eStyle);
+ return aTheRelURIRef;
+}
+
+// static
+inline bool INetURLObject::translateToExternal(ByteString const &
+ rTheIntURIRef,
+ rtl::OUString & rTheExtURIRef,
+ DecodeMechanism
+ eDecodeMechanism,
+ rtl_TextEncoding eCharset)
+{
+ rtl::OUString aTheExtURIRef;
+ bool bRet = convertIntToExt(extend(rTheIntURIRef), true, aTheExtURIRef,
+ eDecodeMechanism, eCharset);
+ rTheExtURIRef = aTheExtURIRef;
+ return bRet;
+}
+
+// static
+inline bool INetURLObject::translateToExternal(rtl::OUString const &
+ rTheIntURIRef,
+ rtl::OUString & rTheExtURIRef,
+ DecodeMechanism
+ eDecodeMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return convertIntToExt(rTheIntURIRef, false, rTheExtURIRef,
+ eDecodeMechanism, eCharset);
+}
+
+// static
+inline bool INetURLObject::translateToInternal(ByteString const &
+ rTheExtURIRef,
+ rtl::OUString & rTheIntURIRef,
+ DecodeMechanism
+ eDecodeMechanism,
+ rtl_TextEncoding eCharset)
+{
+ rtl::OUString aTheIntURIRef;
+ bool bRet = convertExtToInt(extend(rTheExtURIRef), true, aTheIntURIRef,
+ eDecodeMechanism, eCharset);
+ rTheIntURIRef = aTheIntURIRef;
+ return bRet;
+}
+
+// static
+inline bool INetURLObject::translateToInternal(rtl::OUString const &
+ rTheExtURIRef,
+ rtl::OUString & rTheIntURIRef,
+ DecodeMechanism
+ eDecodeMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return convertExtToInt(rTheExtURIRef, false, rTheIntURIRef,
+ eDecodeMechanism, eCharset);
+}
+
+inline bool INetURLObject::SetPass(ByteString const & rThePassword,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return rThePassword.Len() == 0 ?
+ clearPassword() :
+ setPassword(extend(rThePassword), true, eMechanism, eCharset);
+}
+
+inline bool INetURLObject::SetPass(rtl::OUString const & rThePassword,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return rThePassword.getLength() == 0 ?
+ clearPassword() :
+ setPassword(rThePassword, false, eMechanism, eCharset);
+}
+
+inline bool INetURLObject::SetUserAndPass(ByteString const & rTheUser,
+ ByteString const & rThePassword,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return setUser(extend(rTheUser), true, eMechanism, eCharset)
+ && (rThePassword.Len() == 0 ?
+ clearPassword() :
+ setPassword(extend(rThePassword), true, eMechanism,
+ eCharset));
+}
+
+inline bool INetURLObject::SetUserAndPass(rtl::OUString const & rTheUser,
+ rtl::OUString const & rThePassword,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return setUser(rTheUser, false, eMechanism, eCharset)
+ && (rThePassword.getLength() == 0 ?
+ clearPassword() :
+ setPassword(rThePassword, false, eMechanism, eCharset));
+}
+
+// static
+inline rtl::OUString INetURLObject::encodeHostPort(ByteString const &
+ rTheHostPort,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return encodeHostPort(extend(rTheHostPort), true, eMechanism, eCharset);
+}
+
+inline bool INetURLObject::insertName(rtl::OUString const & rTheName,
+ bool bAppendFinalSlash,
+ sal_Int32 nIndex,
+ bool bIgnoreFinalSlash,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return insertName(rTheName, false, bAppendFinalSlash, nIndex,
+ bIgnoreFinalSlash, eMechanism, eCharset);
+}
+
+inline bool INetURLObject::SetParam(ByteString const & rTheQuery,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return rTheQuery.Len() == 0 ?
+ clearQuery() :
+ setQuery(extend(rTheQuery), true, eMechanism, eCharset);
+}
+
+inline bool INetURLObject::SetParam(rtl::OUString const & rTheQuery,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return rTheQuery.getLength() == 0 ?
+ clearQuery() :
+ setQuery(rTheQuery, false, eMechanism, eCharset);
+}
+
+inline bool INetURLObject::SetMark(ByteString const & rTheFragment,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return rTheFragment.Len() == 0 ?
+ clearFragment() :
+ setFragment(extend(rTheFragment), true, eMechanism, eCharset);
+}
+
+inline bool INetURLObject::SetMark(rtl::OUString const & rTheFragment,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return rTheFragment.getLength() == 0 ?
+ clearFragment() :
+ setFragment(rTheFragment, false, eMechanism, eCharset);
+}
+
+inline INetURLObject::INetURLObject(rtl::OUString const & rFSysPath,
+ FSysStyle eStyle):
+ m_eScheme(INET_PROT_NOT_VALID), m_eSmartScheme(INET_PROT_HTTP)
+{
+ setFSysPath(rFSysPath, eStyle);
+}
+
+// static
+inline rtl::OUString INetURLObject::encode(ByteString const & rText, Part ePart,
+ sal_Char cEscapePrefix,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return encodeText(extend(rText), true, ePart, cEscapePrefix, eMechanism,
+ eCharset, false);
+}
+
+// static
+inline rtl::OUString INetURLObject::encode(rtl::OUString const & rText, Part ePart,
+ sal_Char cEscapePrefix,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return encodeText(rText, false, ePart, cEscapePrefix, eMechanism,
+ eCharset, false);
+}
+
+// static
+inline rtl::OUString INetURLObject::decode(rtl::OUString const & rText,
+ sal_Char cEscapePrefix,
+ DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return decode(rText.getStr(), rText.getStr() + rText.getLength(),
+ cEscapePrefix, eMechanism, eCharset);
+}
+
+inline rtl::OUString INetURLObject::decode(rtl::OUStringBuffer const & rText,
+ sal_Char cEscapePrefix,
+ DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return decode(rText.getStr(), rText.getStr() + rText.getLength(),
+ cEscapePrefix, eMechanism, eCharset);
+}
+
+#endif // _URLOBJ_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/vcompat.hxx b/tools/inc/tools/vcompat.hxx
new file mode 100644
index 000000000000..78dbe57f90e4
--- /dev/null
+++ b/tools/inc/tools/vcompat.hxx
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _VCOMPAT_HXX
+#define _VCOMPAT_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/solar.h>
+
+// -----------
+// - Defines -
+// -----------
+
+#define COMPAT_FORMAT( char1, char2, char3, char4 ) \
+ ((UINT32)((((UINT32)(char)(char1)))| \
+ (((UINT32)(char)(char2))<<8UL)| \
+ (((UINT32)(char)(char3))<<16UL)| \
+ ((UINT32)(char)(char4))<<24UL))
+
+// --------------
+// - ImplCompat -
+// --------------
+
+class SvStream;
+
+class TOOLS_DLLPUBLIC VersionCompat
+{
+ SvStream* mpRWStm;
+ UINT32 mnCompatPos;
+ UINT32 mnTotalSize;
+ UINT16 mnStmMode;
+ UINT16 mnVersion;
+
+ VersionCompat() {}
+ VersionCompat( const VersionCompat& ) {}
+ VersionCompat& operator=( const VersionCompat& ) { return *this; }
+ BOOL operator==( const VersionCompat& ) { return FALSE; }
+
+public:
+
+ VersionCompat( SvStream& rStm, USHORT nStreamMode, UINT16 nVersion = 1 );
+ ~VersionCompat();
+
+ UINT16 GetVersion() const { return mnVersion; }
+};
+
+#endif // _VCOMPAT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/vector2d.hxx b/tools/inc/tools/vector2d.hxx
new file mode 100644
index 000000000000..6a27342f9976
--- /dev/null
+++ b/tools/inc/tools/vector2d.hxx
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _VECTOR2D_HXX
+#define _VECTOR2D_HXX
+
+#include <math.h>
+#include <tools/gen.hxx>
+
+// ------------
+// - Vector2D -
+// ------------
+
+class Vector2D
+{
+private:
+ double mfX;
+ double mfY;
+
+public:
+ inline Vector2D() : mfX( 0.0 ), mfY( 0.0 ) {}
+ inline Vector2D( double fX, double fY ) : mfX( fX ), mfY( fY ) {}
+ inline Vector2D( const Vector2D& rVec ) : mfX( rVec.mfX ), mfY( rVec.mfY ) {}
+ inline Vector2D( const Pair& rPair ) : mfX( rPair.nA ), mfY( rPair.nB ) {};
+ inline ~Vector2D() {}
+
+ inline const double& X() const { return mfX; }
+ inline const double& Y() const { return mfY; }
+ inline double& X() { return mfX; }
+ inline double& Y() { return mfY; }
+ inline const double& operator[] (int nPos) const { return (nPos ? mfY : mfX); }
+ inline double& operator[] (int nPos) { return (nPos ? mfY : mfX); }
+
+ inline double GetLength() const { return hypot( mfX, mfY ); }
+ inline Vector2D& Normalize();
+
+ inline void Min(const Vector2D& rVec) { if(rVec.mfX < mfX) mfX = rVec.mfX; if(rVec.mfY < mfY) mfY = rVec.mfY; }
+ inline void Max(const Vector2D& rVec) { if(rVec.mfX > mfX) mfX = rVec.mfX; if(rVec.mfY > mfY) mfY = rVec.mfY; }
+ inline void Abs() { if(mfX < 0.0) mfX = -mfX; if(mfY < 0.0) mfY = -mfY; }
+
+ inline void CalcInBetween(Vector2D& rOld1, Vector2D& rOld2, double t)
+ { mfX = ((rOld2.mfX - rOld1.mfX) + t) + rOld1.mfX; mfY = ((rOld2.mfY - rOld1.mfY) + t) + rOld1.mfY; }
+ inline void CalcMiddle(Vector2D& rOld1, Vector2D& rOld2)
+ { mfX = (rOld1.mfX + rOld2.mfX) / 2.0; mfY = (rOld1.mfY + rOld2.mfY) / 2.0; }
+ inline void CalcMiddle(Vector2D& rOld1, Vector2D& rOld2, Vector2D& rOld3)
+ { mfX = (rOld1.mfX + rOld2.mfX + rOld3.mfX) / 3.0; mfY = (rOld1.mfY + rOld2.mfY + rOld3.mfY) / 3.0; }
+
+ inline Vector2D& operator+=( const Vector2D& rVec ) { mfX += rVec.mfX, mfY += rVec.mfY; return *this; }
+ inline Vector2D& operator-=( const Vector2D& rVec ) { mfX -= rVec.mfX, mfY -= rVec.mfY; return *this; }
+ inline Vector2D operator+(const Vector2D& rVec) const { Vector2D aSum(*this); aSum += rVec; return aSum; }
+ inline Vector2D operator-(const Vector2D& rVec) const { Vector2D aSub(*this); aSub -= rVec; return aSub; }
+ inline Vector2D operator-(void) const { return Vector2D(-mfX, -mfY); }
+
+ inline double Scalar( const Vector2D& rVec ) const { return( mfX * rVec.mfX + mfY * rVec.mfY ); }
+
+ inline Vector2D& operator/=( const Vector2D& rVec ) { mfX /= rVec.mfX, mfY /= rVec.mfY; return *this; }
+ inline Vector2D& operator*=( const Vector2D& rVec ) { mfX *= rVec.mfX, mfY *= rVec.mfY; return *this; }
+ inline Vector2D operator/(const Vector2D& rVec) const { Vector2D aDiv(*this); aDiv /= rVec; return aDiv; }
+ inline Vector2D operator*(const Vector2D& rVec) const { Vector2D aMul(*this); aMul *= rVec; return aMul; }
+
+ inline Vector2D& operator*=(double t) { mfX *= t; mfY *= t; return *this; }
+ inline Vector2D operator*(double t) const { Vector2D aNew(*this); aNew *= t; return aNew; }
+ inline Vector2D& operator/=(double t) { mfX /= t; mfY /= t; return *this; }
+ inline Vector2D operator/(double t) const { Vector2D aNew(*this); aNew /= t; return aNew; }
+
+ inline BOOL operator==( const Vector2D& rVec ) const { return( mfX == rVec.mfX && mfY == rVec.mfY ); }
+ inline BOOL operator!=( const Vector2D& rVec ) const { return !( *this == rVec ); }
+
+ inline Vector2D& operator=( const Vector2D& rVec ) { mfX = rVec.mfX, mfY = rVec.mfY; return *this; }
+ inline Vector2D& operator=( const Pair& rPair ) { mfX = rPair.nA, mfY = rPair.nB; return *this; }
+ inline Vector2D& operator-=( const Pair& rPair ) { mfX -= rPair.nA, mfY -= rPair.nB; return *this; }
+ inline Vector2D& operator+=( const Pair& rPair ) { mfX += rPair.nA, mfY += rPair.nB; return *this; }
+ inline Vector2D& operator*=( const Pair& rPair ) { mfX *= rPair.nA, mfY *= rPair.nB; return *this; }
+ inline Vector2D& operator/=( const Pair& rPair ) { mfX /= rPair.nA, mfY /= rPair.nB; return *this; }
+
+ inline BOOL operator==( const Pair& rPair ) const { return( mfX == rPair.nA && mfY == rPair.nB ); }
+ inline BOOL operator!=( const Pair& rPair ) const { return !( *this == rPair ); }
+
+ inline BOOL IsPositive( Vector2D& rVec ) const { return( ( mfX * rVec.mfY - mfY * rVec.mfX ) >= 0.0 ); }
+ inline BOOL IsNegative( Vector2D& rVec ) const { return !IsPositive( rVec ); }
+};
+
+// -----------------------------------------------------------------------------
+
+inline Vector2D& Vector2D::Normalize()
+{
+ double fLen = Scalar( *this );
+
+ if( ( fLen != 0.0 ) && ( fLen != 1.0 ) && ( ( fLen = sqrt( fLen ) ) != 0.0 ) )
+ mfX /= fLen, mfY /= fLen;
+
+ return *this;
+}
+
+#endif // _SV_VECTOR2D_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/weakbase.h b/tools/inc/tools/weakbase.h
new file mode 100644
index 000000000000..49e03a724c0e
--- /dev/null
+++ b/tools/inc/tools/weakbase.h
@@ -0,0 +1,162 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _TOOLS_WEAKBASE_H_
+#define _TOOLS_WEAKBASE_H_
+
+#include <sal/types.h>
+#include <osl/diagnose.h>
+
+/** the template classes in this header are helper to implement weak references
+ to implementation objects that are not refcounted.
+
+ THIS IS NOT THREADSAFE
+
+ Use this only to have 'safe' pointers to implementation objects that you
+ don't own but that you reference with a pointer.
+
+ Example:
+
+ class ImplClass : public tools::WeakBase< ImplClass >
+ {
+ ~ImplClass() { clearWeek(); } // not needed but safer, see method description
+ ...
+ };
+
+ class UserClass
+ {
+ tools::WeakReference< ImplClass > mxWeakRef;
+
+ UserClass( ImplClass* pOjbect ) : mxWeakRef( pObject ) {}
+
+ DoSomething()
+ {
+ if( mxWeakRef.is() )
+ mxWeakRef->DoSomethingMore();
+ }
+ };
+*/
+namespace tools
+{
+
+// --------------------------------------------------------------------
+
+/** private connection helper, do not use directly */
+template <class reference_type>
+struct WeakConnection
+{
+ sal_Int32 mnRefCount;
+ reference_type* mpReference;
+
+ WeakConnection( reference_type* pReference ) : mnRefCount( 0 ), mpReference( pReference ) {};
+ void acquire() { mnRefCount++; }
+ void release() { mnRefCount--; if( mnRefCount == 0 ) delete this; }
+};
+
+// --------------------------------------------------------------------
+
+/** template implementation to hold a weak reference to an instance of type reference_type */
+template <class reference_type>
+class WeakReference
+{
+public:
+ /** constructs an empty reference */
+ inline WeakReference();
+
+ /** constructs a reference with a pointer to a class derived from WeakBase */
+ inline WeakReference( reference_type* pReference );
+
+ /** constructs a reference with another reference */
+ inline WeakReference( const WeakReference< reference_type >& rWeakRef );
+
+ inline ~WeakReference();
+
+ /** returns true if the reference object is not null and still alive */
+ inline bool is() const;
+
+ /** returns the pointer to the reference object or null */
+ inline reference_type * get() const;
+
+ /** sets this reference to the given object or null */
+ inline void reset( reference_type* pReference );
+
+ /** returns the pointer to the reference object or null */
+ inline reference_type * operator->() const;
+
+ /** returns true if this instance references pReferenceObject */
+ inline sal_Bool operator== (const reference_type * pReferenceObject) const;
+
+ /** returns true if this instance and the given weakref reference the same object */
+ inline sal_Bool operator== (const WeakReference<reference_type> & handle) const;
+
+ /** only needed for using this class with stl containers */
+ inline sal_Bool operator!= (const WeakReference<reference_type> & handle) const;
+
+ /** only needed for using this class with stl containers */
+ inline sal_Bool operator< (const WeakReference<reference_type> & handle) const;
+
+ /** only needed for using this class with stl containers */
+ inline sal_Bool operator> (const WeakReference<reference_type> & handle) const;
+
+ /** the assignment operator */
+ inline WeakReference<reference_type>& operator= (const WeakReference<reference_type> & handle);
+
+private:
+ WeakConnection< reference_type >* mpWeakConnection;
+};
+
+// --------------------------------------------------------------------
+
+/** derive your implementation classes from this class if you want them to support weak references */
+template <class reference_type>
+class WeakBase
+{
+ friend class WeakReference<reference_type>;
+
+public:
+ inline WeakBase();
+
+ inline ~WeakBase();
+ /** clears the reference pointer in all living weak references for this instance.
+ Further created weak references will also be invalid.
+ You should call this method in the d'tor of your derived classes for an early
+ invalidate of all living weak references while youre object is already inside
+ it d'tor.
+ */
+ inline void clearWeak();
+
+private:
+ inline WeakConnection< reference_type >* getWeakConnection();
+ WeakConnection< reference_type >* mpWeakConnection;
+};
+
+}
+
+#endif // _TOOLS_WEAKBASE_H_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/weakbase.hxx b/tools/inc/tools/weakbase.hxx
new file mode 100644
index 000000000000..8c4c164987ca
--- /dev/null
+++ b/tools/inc/tools/weakbase.hxx
@@ -0,0 +1,185 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _TOOLS_WEAKBASE_HXX_
+#define _TOOLS_WEAKBASE_HXX_
+
+#include <tools/weakbase.h>
+
+/// see weakbase.h for documentation
+
+namespace tools
+{
+
+template< class reference_type >
+inline WeakReference< reference_type >::WeakReference()
+{
+ mpWeakConnection = new WeakConnection<reference_type>( 0 );
+ mpWeakConnection->acquire();
+}
+
+template< class reference_type >
+inline WeakReference< reference_type >::WeakReference( reference_type* pReference )
+{
+ if( pReference )
+ mpWeakConnection = pReference->getWeakConnection();
+ else
+ mpWeakConnection = new WeakConnection<reference_type>( 0 );
+
+ mpWeakConnection->acquire();
+}
+
+template< class reference_type >
+inline WeakReference< reference_type >::WeakReference( const WeakReference< reference_type >& rWeakRef )
+{
+ mpWeakConnection = rWeakRef.mpWeakConnection;
+ mpWeakConnection->acquire();
+}
+
+template< class reference_type >
+inline WeakReference< reference_type >::~WeakReference()
+{
+ mpWeakConnection->release();
+}
+
+template< class reference_type >
+inline bool WeakReference< reference_type >::is() const
+{
+ return mpWeakConnection->mpReference != 0;
+}
+
+template< class reference_type >
+inline reference_type * WeakReference< reference_type >::get() const
+{
+ return mpWeakConnection->mpReference;
+}
+
+template< class reference_type >
+inline void WeakReference< reference_type >::reset( reference_type* pReference )
+{
+ mpWeakConnection->release();
+
+ if( pReference )
+ mpWeakConnection = pReference->getWeakConnection();
+ else
+ mpWeakConnection = new WeakConnection<reference_type>( 0 );
+
+ mpWeakConnection->acquire();
+}
+
+template< class reference_type >
+inline reference_type * WeakReference< reference_type >::operator->() const
+{
+ OSL_PRECOND(mpWeakConnection, "tools::WeakReference::operator->() : null body");
+ return mpWeakConnection->mpReference;
+}
+
+template< class reference_type >
+inline sal_Bool WeakReference< reference_type >::operator==(const reference_type * pReferenceObject) const
+{
+ return mpWeakConnection->mpReference == pReferenceObject;
+}
+
+template< class reference_type >
+inline sal_Bool WeakReference< reference_type >::operator==(const WeakReference<reference_type> & handle) const
+{
+ return mpWeakConnection == handle.mpWeakConnection;
+}
+
+template< class reference_type >
+inline sal_Bool WeakReference< reference_type >::operator!=(const WeakReference<reference_type> & handle) const
+{
+ return mpWeakConnection != handle.mpWeakConnection;
+}
+
+template< class reference_type >
+inline sal_Bool WeakReference< reference_type >::operator<(const WeakReference<reference_type> & handle) const
+{
+ return mpWeakConnection->mpReference < handle.mpWeakConnection->mpReference;
+}
+
+template< class reference_type >
+inline sal_Bool WeakReference< reference_type >::operator>(const WeakReference<reference_type> & handle) const
+{
+ return mpWeakConnection->mpReference > handle.mpWeakConnection->mpReference;
+}
+
+template< class reference_type >
+inline WeakReference<reference_type>& WeakReference<reference_type>::operator= (
+ const WeakReference<reference_type>& rReference)
+{
+ if (&rReference != this)
+ {
+ mpWeakConnection->release();
+
+ mpWeakConnection = rReference.mpWeakConnection;
+ mpWeakConnection->acquire();
+ }
+ return *this;
+}
+
+template< class reference_type >
+inline WeakBase< reference_type >::WeakBase()
+{
+ mpWeakConnection = 0;
+}
+
+template< class reference_type >
+inline WeakBase< reference_type >::~WeakBase()
+{
+ if( mpWeakConnection )
+ {
+ mpWeakConnection->mpReference = 0;
+ mpWeakConnection->release();
+ mpWeakConnection = 0;
+ }
+}
+
+template< class reference_type >
+inline void WeakBase< reference_type >::clearWeak()
+{
+ if( mpWeakConnection )
+ mpWeakConnection->mpReference = 0;
+}
+
+template< class reference_type >
+inline WeakConnection< reference_type >* WeakBase< reference_type >::getWeakConnection()
+{
+ if( !mpWeakConnection )
+ {
+ mpWeakConnection = new WeakConnection< reference_type >( static_cast< reference_type* >( this ) );
+ mpWeakConnection->acquire();
+ }
+ return mpWeakConnection;
+}
+
+}
+
+#endif // _TOOLS_WEAKBASE_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/wintypes.hxx b/tools/inc/tools/wintypes.hxx
new file mode 100644
index 000000000000..a280d334cdc3
--- /dev/null
+++ b/tools/inc/tools/wintypes.hxx
@@ -0,0 +1,346 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _TOOLS_WINTYPES_HXX
+#define _TOOLS_WINTYPES_HXX
+
+#include <tools/solar.h>
+#include <sal/types.h>
+
+// ----------------
+// - Window-Types -
+// ----------------
+
+typedef USHORT WindowType;
+#define WINDOW_BASE 0x0100
+#define WINDOW_FIRST (WINDOW_BASE + 0x30)
+#define WINDOW_MESSBOX (WINDOW_FIRST)
+#define WINDOW_INFOBOX (WINDOW_FIRST + 0x01)
+#define WINDOW_WARNINGBOX (WINDOW_FIRST + 0x02)
+#define WINDOW_ERRORBOX (WINDOW_FIRST + 0x03)
+#define WINDOW_QUERYBOX (WINDOW_FIRST + 0x04)
+#define WINDOW_WINDOW (WINDOW_FIRST + 0x05)
+#define WINDOW_SYSWINDOW (WINDOW_FIRST + 0x06)
+#define WINDOW_WORKWINDOW (WINDOW_FIRST + 0x07)
+// #define WINDOW_MDIWINDOW (WINDOW_FIRST + 0x08)
+#define WINDOW_FLOATINGWINDOW (WINDOW_FIRST + 0x09)
+#define WINDOW_DIALOG (WINDOW_FIRST + 0x0a)
+#define WINDOW_MODELESSDIALOG (WINDOW_FIRST + 0x0b)
+#define WINDOW_MODALDIALOG (WINDOW_FIRST + 0x0c)
+#define WINDOW_SYSTEMDIALOG (WINDOW_FIRST + 0x0d)
+#define WINDOW_PATHDIALOG (WINDOW_FIRST + 0x0e)
+#define WINDOW_FILEDIALOG (WINDOW_FIRST + 0x0f)
+#define WINDOW_PRINTERSETUPDIALOG (WINDOW_FIRST + 0x10)
+#define WINDOW_PRINTDIALOG (WINDOW_FIRST + 0x11)
+#define WINDOW_COLORDIALOG (WINDOW_FIRST + 0x12)
+#define WINDOW_FONTDIALOG (WINDOW_FIRST + 0x13)
+#define WINDOW_CONTROL (WINDOW_FIRST + 0x14)
+#define WINDOW_BUTTON (WINDOW_FIRST + 0x15)
+#define WINDOW_PUSHBUTTON (WINDOW_FIRST + 0x16)
+#define WINDOW_OKBUTTON (WINDOW_FIRST + 0x17)
+#define WINDOW_CANCELBUTTON (WINDOW_FIRST + 0x18)
+#define WINDOW_HELPBUTTON (WINDOW_FIRST + 0x19)
+#define WINDOW_IMAGEBUTTON (WINDOW_FIRST + 0x1a)
+#define WINDOW_MENUBUTTON (WINDOW_FIRST + 0x1b)
+#define WINDOW_MOREBUTTON (WINDOW_FIRST + 0x1c)
+#define WINDOW_SPINBUTTON (WINDOW_FIRST + 0x1d)
+#define WINDOW_RADIOBUTTON (WINDOW_FIRST + 0x1e)
+#define WINDOW_IMAGERADIOBUTTON (WINDOW_FIRST + 0x1f)
+#define WINDOW_CHECKBOX (WINDOW_FIRST + 0x20)
+#define WINDOW_TRISTATEBOX (WINDOW_FIRST + 0x21)
+#define WINDOW_EDIT (WINDOW_FIRST + 0x22)
+#define WINDOW_MULTILINEEDIT (WINDOW_FIRST + 0x23)
+#define WINDOW_COMBOBOX (WINDOW_FIRST + 0x24)
+#define WINDOW_LISTBOX (WINDOW_FIRST + 0x25)
+#define WINDOW_MULTILISTBOX (WINDOW_FIRST + 0x26)
+#define WINDOW_FIXEDTEXT (WINDOW_FIRST + 0x27)
+#define WINDOW_FIXEDLINE (WINDOW_FIRST + 0x28)
+#define WINDOW_FIXEDBITMAP (WINDOW_FIRST + 0x29)
+#define WINDOW_FIXEDIMAGE (WINDOW_FIRST + 0x2a)
+#define WINDOW_GROUPBOX (WINDOW_FIRST + 0x2c)
+#define WINDOW_SCROLLBAR (WINDOW_FIRST + 0x2d)
+#define WINDOW_SCROLLBARBOX (WINDOW_FIRST + 0x2e)
+#define WINDOW_SPLITTER (WINDOW_FIRST + 0x2f)
+#define WINDOW_SPLITWINDOW (WINDOW_FIRST + 0x30)
+#define WINDOW_SPINFIELD (WINDOW_FIRST + 0x31)
+#define WINDOW_PATTERNFIELD (WINDOW_FIRST + 0x32)
+#define WINDOW_NUMERICFIELD (WINDOW_FIRST + 0x33)
+#define WINDOW_METRICFIELD (WINDOW_FIRST + 0x34)
+#define WINDOW_CURRENCYFIELD (WINDOW_FIRST + 0x35)
+#define WINDOW_DATEFIELD (WINDOW_FIRST + 0x36)
+#define WINDOW_TIMEFIELD (WINDOW_FIRST + 0x37)
+#define WINDOW_PATTERNBOX (WINDOW_FIRST + 0x38)
+#define WINDOW_NUMERICBOX (WINDOW_FIRST + 0x39)
+#define WINDOW_METRICBOX (WINDOW_FIRST + 0x3a)
+#define WINDOW_CURRENCYBOX (WINDOW_FIRST + 0x3b)
+#define WINDOW_DATEBOX (WINDOW_FIRST + 0x3c)
+#define WINDOW_TIMEBOX (WINDOW_FIRST + 0x3d)
+#define WINDOW_LONGCURRENCYFIELD (WINDOW_FIRST + 0x3e)
+#define WINDOW_LONGCURRENCYBOX (WINDOW_FIRST + 0x3f)
+#define WINDOW_TOOLBOX (WINDOW_FIRST + 0x41)
+#define WINDOW_DOCKINGWINDOW (WINDOW_FIRST + 0x42)
+#define WINDOW_STATUSBAR (WINDOW_FIRST + 0x43)
+#define WINDOW_TABPAGE (WINDOW_FIRST + 0x44)
+#define WINDOW_TABCONTROL (WINDOW_FIRST + 0x45)
+#define WINDOW_TABDIALOG (WINDOW_FIRST + 0x46)
+#define WINDOW_BORDERWINDOW (WINDOW_FIRST + 0x47)
+#define WINDOW_BUTTONDIALOG (WINDOW_FIRST + 0x48)
+#define WINDOW_SYSTEMCHILDWINDOW (WINDOW_FIRST + 0x49)
+#define WINDOW_FIXEDBORDER (WINDOW_FIRST + 0x4a)
+#define WINDOW_SLIDER (WINDOW_FIRST + 0x4b)
+#define WINDOW_MENUBARWINDOW (WINDOW_FIRST + 0x4c)
+#define WINDOW_TREELISTBOX (WINDOW_FIRST + 0x4d)
+#define WINDOW_HELPTEXTWINDOW (WINDOW_FIRST + 0x4e)
+#define WINDOW_INTROWINDOW (WINDOW_FIRST + 0x4f)
+#define WINDOW_LISTBOXWINDOW (WINDOW_FIRST + 0x50)
+#define WINDOW_DOCKINGAREA (WINDOW_FIRST + 0x51)
+#define WINDOW_LAST (WINDOW_DOCKINGAREA)
+
+
+// ---------------
+// - Window-Bits -
+// ---------------
+
+// By changes you must also change: rsc/vclrsc.hxx
+typedef sal_Int64 WinBits;
+
+// Window-Bits fuer Window
+#define WB_CLIPCHILDREN ((WinBits)0x00000001)
+#define WB_DIALOGCONTROL ((WinBits)0x00000002)
+#define WB_NODIALOGCONTROL ((WinBits)0x00000004)
+#define WB_BORDER ((WinBits)0x00000008)
+#define WB_NOBORDER ((WinBits)0x00000010)
+#define WB_SIZEABLE ((WinBits)0x00000020)
+#define WB_3DLOOK ((WinBits)0x00000040)
+#define WB_AUTOSIZE ((WinBits)0x00000080)
+
+// Window-Bits fuer SystemWindows
+#define WB_MOVEABLE ((WinBits)0x00000100)
+#define WB_ROLLABLE ((WinBits)0x00000200)
+#define WB_CLOSEABLE ((WinBits)0x00000400)
+#define WB_STANDALONE ((WinBits)0x00000800)
+#define WB_APP ((WinBits)0x00001000)
+#define WB_PINABLE ((WinBits)0x00002000)
+#define WB_SYSTEMWINDOW ((WinBits)SAL_CONST_INT64(0x40000000))
+// warning: do not confuse WB_SYSTEMCHILDWINDOW with the SystemChildWindow class
+
+// the SystemChildWindow class was there first and is a very specialized
+// sytem child window type for plugged applications. The SystemChildWindow class
+// explicitly should never use the WB_SYSTEMCHILDWINDOW WinBit
+
+// WB_SYSTEMCHILDWINDOW on the other hand is to be used on system windows
+// which should be created as system child windows with (more or less)
+// normal event handling
+#define WB_SYSTEMCHILDWINDOW ((WinBits)SAL_CONST_INT64(0x8000000000))
+#define WB_SIZEMOVE (WB_SIZEABLE | WB_MOVEABLE)
+
+// Standard-Window-Bits fuer ChildWindows
+#define WB_TABSTOP ((WinBits)0x00000100)
+#define WB_NOTABSTOP ((WinBits)0x00000200)
+#define WB_GROUP ((WinBits)0x00000400)
+#define WB_NOGROUP ((WinBits)0x00000800)
+#define WB_HORZ ((WinBits)0x00001000)
+#define WB_VERT ((WinBits)0x00002000)
+#define WB_LEFT ((WinBits)0x00004000)
+#define WB_CENTER ((WinBits)0x00008000)
+#define WB_RIGHT ((WinBits)0x00010000)
+#define WB_TOP ((WinBits)0x00020000)
+#define WB_VCENTER ((WinBits)0x00040000)
+#define WB_BOTTOM ((WinBits)0x00080000)
+#define WB_DRAG ((WinBits)0x00100000)
+#define WB_SPIN ((WinBits)0x00200000)
+#define WB_REPEAT ((WinBits)0x00400000)
+#define WB_NOPOINTERFOCUS ((WinBits)0x00800000)
+#define WB_WORDBREAK ((WinBits)0x01000000)
+#define WB_NOLABEL ((WinBits)0x02000000)
+#define WB_SORT ((WinBits)0x04000000)
+#define WB_DROPDOWN ((WinBits)0x08000000)
+#define WB_HIDE ((WinBits)SAL_CONST_INT64(0x80000000))
+#define WB_AUTOHSCROLL ((WinBits)SAL_CONST_INT64(0x10000000))
+#define WB_DOCKABLE ((WinBits)SAL_CONST_INT64(0x20000000))
+#define WB_AUTOVSCROLL ((WinBits)SAL_CONST_INT64(0x40000000))
+#define WB_HYPHENATION (((WinBits)SAL_CONST_INT64(0x800000000)) | WB_WORDBREAK)
+#define WB_CHILDDLGCTRL ((WinBits)SAL_CONST_INT64(0x100000000000))
+
+// system floating window
+#define WB_SYSTEMFLOATWIN ((WinBits)SAL_CONST_INT64(0x100000000))
+#define WB_INTROWIN ((WinBits)SAL_CONST_INT64(0x200000000))
+#define WB_NOSHADOW ((WinBits)SAL_CONST_INT64(0x400000000))
+#define WB_TOOLTIPWIN ((WinBits)SAL_CONST_INT64(0x800000000))
+#define WB_OWNERDRAWDECORATION ((WinBits)SAL_CONST_INT64(0x2000000000))
+#define WB_DEFAULTWIN ((WinBits)SAL_CONST_INT64(0x4000000000))
+#define WB_NEEDSFOCUS ((WinBits)SAL_CONST_INT64(0x1000000000))
+#define WB_POPUP ((WinBits)SAL_CONST_INT64(0x20000000))
+
+#define WB_HSCROLL WB_HORZ
+#define WB_VSCROLL WB_VERT
+#define WB_TOPIMAGE WB_TOP
+
+// Window-Bits for PushButtons
+#define WB_DEFBUTTON ((WinBits)0x10000000)
+#define WB_NOLIGHTBORDER ((WinBits)0x20000000)
+#define WB_RECTSTYLE ((WinBits)0x08000000)
+#define WB_SMALLSTYLE ((WinBits)0x04000000)
+#define WB_TOGGLE ((WinBits)SAL_CONST_INT64(0x1000000000))
+#define WB_BEVELBUTTON ((WinBits)SAL_CONST_INT64(0x2000000000))
+#define WB_FLATBUTTON ((WinBits)SAL_CONST_INT64(0x4000000000))
+
+// Window-Bits for FixedText
+#define WB_PATHELLIPSIS ((WinBits)0x00100000)
+#define WB_EXTRAOFFSET ((WinBits)0x02000000)
+#define WB_NOMULTILINE ((WinBits)0x10000000)
+#define WB_INFO ((WinBits)0x20000000)
+
+// Window-Bits for CheckBox
+#define WB_CBLINESTYLE ((WinBits)SAL_CONST_INT64(0x2000000000))
+#define WB_EARLYTOGGLE ((WinBits)SAL_CONST_INT64(0x4000000000))
+
+// Window-Bits for Edit
+#define WB_PASSWORD ((WinBits)0x01000000)
+#define WB_READONLY ((WinBits)0x02000000)
+#define WB_NOHIDESELECTION ((WinBits)SAL_CONST_INT64(0x1000000000))
+#define WB_FORCECTRLBACKGROUND ((WinBits)0x80000000)
+
+// Window-Bits for MultiLineEdit
+#define WB_IGNORETAB ((WinBits)0x20000000)
+
+// Window-Bits for ListBox and MultiListBox
+#define WB_SIMPLEMODE ((WinBits)0x20000000)
+
+// Window-Bits for FixedBitmap
+#define WB_FAST ((WinBits)0x04000000)
+#define WB_SCALE ((WinBits)0x08000000)
+#define WB_TOPLEFTVISIBLE ((WinBits)0x10000000)
+
+// Window-Bits for ToolBox
+#define WB_LINESPACING ((WinBits)0x01000000)
+#define WB_SCROLL ((WinBits)0x02000000)
+#define WB_FORCETABCYCLE ((WinBits)0x04000000)
+
+// Window-Bits for TabControl
+#define WB_SINGLELINE ((WinBits)0x02000000)
+
+// Window-Bits for DockingWindows
+#define WB_DOCKBORDER ((WinBits)0x00001000)
+
+// Window-Bits for SplitWindow
+#define WB_NOSPLITDRAW ((WinBits)0x01000000)
+#define WB_FLATSPLITDRAW ((WinBits)0x02000000)
+
+// Window-Bits for MessageBoxen
+#define WB_OK ((WinBits)0x00100000)
+#define WB_OK_CANCEL ((WinBits)0x00200000)
+#define WB_YES_NO ((WinBits)0x00400000)
+#define WB_YES_NO_CANCEL ((WinBits)0x00800000)
+#define WB_RETRY_CANCEL ((WinBits)0x01000000)
+#define WB_DEF_OK ((WinBits)0x02000000)
+#define WB_DEF_CANCEL ((WinBits)0x04000000)
+#define WB_DEF_RETRY ((WinBits)0x08000000)
+#define WB_DEF_YES ((WinBits)SAL_CONST_INT64(0x10000000))
+#define WB_DEF_NO ((WinBits)SAL_CONST_INT64(0x20000000))
+#define WB_ABORT_RETRY_IGNORE ((WinBits)SAL_CONST_INT64(0x1000000000))
+#define WB_DEF_IGNORE ((WinBits)SAL_CONST_INT64(0x2000000000))
+
+// Standard-WinBits
+#define WB_STDWORK (WB_SIZEMOVE | WB_CLOSEABLE)
+#define WB_STDDOCKWIN (WB_DOCKABLE | WB_MOVEABLE | WB_CLOSEABLE)
+#define WB_STDFLOATWIN (WB_SIZEMOVE | WB_CLOSEABLE | WB_ROLLABLE)
+#define WB_STDDIALOG (WB_MOVEABLE | WB_CLOSEABLE)
+#define WB_STDMODELESS (WB_STDDIALOG)
+#define WB_STDMODAL (WB_STDDIALOG)
+#define WB_STDTABDIALOG (WB_STDDIALOG)
+#define WB_STDTABCONTROL 0
+#define WB_STDPOPUP (WB_BORDER | WB_POPUP | WB_SYSTEMWINDOW | WB_3DLOOK | WB_DIALOGCONTROL)
+
+// For TreeListBox
+#define WB_HASBUTTONS ((WinBits)0x00800000)
+#define WB_HASLINES ((WinBits)0x01000000)
+#define WB_HASLINESATROOT ((WinBits)0x02000000)
+
+// For FileOpen Dialog
+#define WB_PATH ((WinBits)0x00100000)
+#define WB_OPEN ((WinBits)0x00200000)
+#define WB_SAVEAS ((WinBits)0x00400000)
+
+// For Slider
+// Window-Bits for TabControl
+#define WB_SLIDERSET ((WinBits)0x02000000)
+
+
+// --------------------
+// - extended WinBits -
+// --------------------
+#define WB_EXT_DOCUMENT ((WinBits)0x00000001)
+#define WB_EXT_DOCMODIFIED ((WinBits)0x00000002)
+
+// ---------------
+// - WindowAlign -
+// ---------------
+
+// By changes you must also change: rsc/vclrsc.hxx
+enum WindowAlign { WINDOWALIGN_LEFT, WINDOWALIGN_TOP, WINDOWALIGN_RIGHT, WINDOWALIGN_BOTTOM };
+enum ImageAlign { IMAGEALIGN_LEFT, IMAGEALIGN_TOP, IMAGEALIGN_RIGHT, IMAGEALIGN_BOTTOM,
+ IMAGEALIGN_LEFT_TOP, IMAGEALIGN_LEFT_BOTTOM, IMAGEALIGN_TOP_LEFT,
+ IMAGEALIGN_TOP_RIGHT, IMAGEALIGN_RIGHT_TOP, IMAGEALIGN_RIGHT_BOTTOM,
+ IMAGEALIGN_BOTTOM_LEFT, IMAGEALIGN_BOTTOM_RIGHT, IMAGEALIGN_CENTER };
+enum SymbolAlign { SYMBOLALIGN_LEFT, SYMBOLALIGN_RIGHT };
+
+// ------------
+// - TriState -
+// ------------
+
+// By changes you must also change: rsc/vclrsc.hxx
+enum TriState { STATE_NOCHECK, STATE_CHECK, STATE_DONTKNOW };
+
+
+// ----------------------
+// - ButtonDialog-Types -
+// ----------------------
+
+typedef USHORT StandardButtonType;
+#define BUTTON_OK ((StandardButtonType)0)
+#define BUTTON_CANCEL ((StandardButtonType)1)
+#define BUTTON_YES ((StandardButtonType)2)
+#define BUTTON_NO ((StandardButtonType)3)
+#define BUTTON_RETRY ((StandardButtonType)4)
+#define BUTTON_HELP ((StandardButtonType)5)
+#define BUTTON_CLOSE ((StandardButtonType)6)
+#define BUTTON_MORE ((StandardButtonType)7)
+#define BUTTON_IGNORE ((StandardButtonType)8)
+#define BUTTON_ABORT ((StandardButtonType)9)
+#define BUTTON_LESS ((StandardButtonType)10)
+#define BUTTON_COUNT 11
+
+// --------------------------------------------
+// - prominent place for ListBox window types -
+// --------------------------------------------
+
+enum ProminentEntry { PROMINENT_TOP, PROMINENT_MIDDLE };
+
+#endif // _TOOLS_WINTYPES_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/wldcrd.hxx b/tools/inc/tools/wldcrd.hxx
new file mode 100644
index 000000000000..84c692c2bc2d
--- /dev/null
+++ b/tools/inc/tools/wldcrd.hxx
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _WLDCRD_HXX
+#define _WLDCRD_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/solar.h>
+#include <tools/string.hxx>
+#include <osl/thread.h>
+
+// ------------
+// - WildCard -
+// ------------
+
+class TOOLS_DLLPUBLIC WildCard
+{
+private:
+ ByteString aWildString;
+ char cSepSymbol;
+
+ USHORT ImpMatch( const char *pWild, const char *pStr ) const;
+
+public:
+ WildCard();
+ WildCard( const String& rWildCards,
+ const char cSeparator = '\0' );
+
+ const String GetWildCard() const { return UniString( aWildString, osl_getThreadTextEncoding()); }
+ const String operator ()() const { return UniString( aWildString, osl_getThreadTextEncoding()); }
+
+ BOOL Matches( const String& rStr ) const;
+
+ BOOL operator ==( const String& rString ) const
+ { return Matches( rString ); }
+ BOOL operator !=( const String& rString ) const
+ { return !( Matches( rString ) ); }
+
+ WildCard& operator =( const String& rString );
+ WildCard& operator =( const WildCard& rWildCard );
+};
+
+inline WildCard::WildCard() :
+ aWildString( '*' )
+{
+ cSepSymbol = '\0';
+}
+
+inline WildCard::WildCard( const String& rWildCard, const char cSeparator ) :
+ aWildString( rWildCard, osl_getThreadTextEncoding())
+{
+ cSepSymbol = cSeparator;
+}
+
+inline WildCard& WildCard::operator=( const String& rString )
+{
+ aWildString = ByteString(rString, osl_getThreadTextEncoding());
+ return *this;
+}
+
+inline WildCard& WildCard::operator=( const WildCard& rWildCard )
+{
+ aWildString = rWildCard.aWildString;
+ cSepSymbol = rWildCard.cSepSymbol;
+ return *this;
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/tools/zcodec.hxx b/tools/inc/tools/zcodec.hxx
new file mode 100644
index 000000000000..ec3021b3ac59
--- /dev/null
+++ b/tools/inc/tools/zcodec.hxx
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _ZCODEC_HXX
+#define _ZCODEC_HXX
+
+#include "tools/toolsdllapi.h"
+#include <tools/solar.h>
+
+// -----------
+// - Defines -
+// -----------
+
+#define DEFAULT_IN_BUFSIZE (0x00008000UL)
+#define DEFAULT_OUT_BUFSIZE (0x00008000UL)
+
+#define MAX_MEM_USAGE 8
+
+//
+// memory requirement using compress:
+// [ INBUFFER ] + [ OUTBUFFER ] + 128KB + 1 << (MEM_USAGE+9)
+//
+// memory requirement using decompress:
+// [ INBUFFER ] + [ OUTBUFFER ] + 32KB
+//
+
+#define ZCODEC_NO_COMPRESSION (0x00000000UL)
+#define ZCODEC_BEST_SPEED (0x00000001UL)
+#define ZCODEC_DEFAULT_COMPRESSION (0x00000006UL)
+#define ZCODEC_BEST_COMPRESSION (0x00000009UL)
+
+#define ZCODEC_DEFAULT_STRATEGY (0x00000000UL)
+#define ZCODEC_ZFILTERED (0x00000100UL)
+#define ZCODEC_ZHUFFMAN_ONLY (0x00000200UL)
+
+#define ZCODEC_UPDATE_CRC (0x00010000UL)
+#define ZCODEC_GZ_LIB (0x00020000UL)
+
+#define ZCODEC_PNG_DEFAULT ( ZCODEC_NO_COMPRESSION | ZCODEC_DEFAULT_STRATEGY | ZCODEC_UPDATE_CRC )
+#define ZCODEC_DEFAULT ( ZCODEC_DEFAULT_COMPRESSION | ZCODEC_DEFAULT_STRATEGY )
+
+// ----------
+// - ZCodec -
+// ----------
+
+class SvStream;
+
+class TOOLS_DLLPUBLIC ZCodec
+{
+private:
+
+ ULONG mbInit;
+ BOOL mbStatus;
+ BOOL mbFinish;
+ ULONG mnMemUsage;
+ SvStream* mpIStm;
+ BYTE* mpInBuf;
+ ULONG mnInBufSize;
+ ULONG mnInToRead;
+ SvStream* mpOStm;
+ BYTE* mpOutBuf;
+ ULONG mnOutBufSize;
+
+ ULONG mnCRC;
+ ULONG mnCompressMethod;
+ void* mpsC_Stream;
+
+ void ImplInitBuf( BOOL nIOFlag );
+ void ImplWriteBack( void );
+
+public:
+ ZCodec( ULONG nInBuf, ULONG nOutBuf, ULONG nMemUsage = MAX_MEM_USAGE );
+ ZCodec( void );
+ virtual ~ZCodec();
+
+ virtual void BeginCompression( ULONG nCompressMethod = ZCODEC_DEFAULT );
+ virtual long EndCompression();
+ BOOL IsFinished () const { return mbFinish; }
+
+ long Compress( SvStream& rIStm, SvStream& rOStm );
+ long Decompress( SvStream& rIStm, SvStream& rOStm );
+
+ long Write( SvStream& rOStm, const BYTE* pData, ULONG nSize );
+ long Read( SvStream& rIStm, BYTE* pData, ULONG nSize );
+ long ReadAsynchron( SvStream& rIStm, BYTE* pData, ULONG nSize );
+
+ void SetBreak( ULONG );
+ ULONG GetBreak( void );
+ void SetCRC( ULONG nCurrentCRC );
+ ULONG UpdateCRC( ULONG nLatestCRC, ULONG nSource );
+ ULONG UpdateCRC( ULONG nLatestCRC, BYTE* pSource, long nDatSize );
+ ULONG GetCRC();
+};
+
+class GZCodec : public ZCodec
+{
+
+public:
+ GZCodec(){};
+ ~GZCodec(){};
+ virtual void BeginCompression( ULONG nCompressMethod = ZCODEC_DEFAULT );
+};
+
+#endif // _ZCODEC_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/inc/toolsin.hxx b/tools/inc/toolsin.hxx
new file mode 100644
index 000000000000..aa77bdc83523
--- /dev/null
+++ b/tools/inc/toolsin.hxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _TOOLSIN_HXX
+#define _TOOLSIN_HXX
+
+#include <tools/tools.h>
+
+struct ImplRegisterLanguageData;
+struct ImplRegisterFormatData;
+struct Impl1ByteUnicodeTabData;
+struct Impl1ByteConvertTabData;
+
+// --------------
+// - TOOLSNDATA -
+// --------------
+
+struct TOOLSINDATA
+{
+ ImplRegisterLanguageData* mpFirstLangData;
+ ImplRegisterFormatData* mpFirstFormatData;
+ Impl1ByteUnicodeTabData* mpFirstUniTabData;
+ Impl1ByteConvertTabData* mpFirstConvertTabData;
+};
+
+TOOLSINDATA* ImplGetToolsInData();
+
+#endif // _TOOLSIN_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/os2/inc/dll.hxx b/tools/os2/inc/dll.hxx
new file mode 100644
index 000000000000..297b136240d7
--- /dev/null
+++ b/tools/os2/inc/dll.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DLL_HXX
+#define _DLL_HXX
+
+// MultiThread-Sicherung aktivieren
+void EnterMultiThread( int bEnter );
+int IsMultiThread();
+
+// Um Resourcen wieder freizugeben
+//YD void ImpDeInitOS2Tools();
+inline void ImpDeInitOS2Tools() {}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/os2/source/dll/makefile.mk b/tools/os2/source/dll/makefile.mk
new file mode 100644
index 000000000000..97cff795defb
--- /dev/null
+++ b/tools/os2/source/dll/makefile.mk
@@ -0,0 +1,46 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=TOOLS
+TARGET=dll
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES= toolsdll.cxx
+
+SLOFILES= $(SLO)$/toolsdll.obj
+
+OBJFILES= $(OBJ)$/toolsdll.obj
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/tools/os2/source/dll/toolsdll.cxx b/tools/os2/source/dll/toolsdll.cxx
new file mode 100644
index 000000000000..977061195295
--- /dev/null
+++ b/tools/os2/source/dll/toolsdll.cxx
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/shl.hxx>
+
+#include <dll.hxx>
+
+// =======================================================================
+
+static void* aAppData[SHL_COUNT];
+
+// -----------------------------------------------------------------------
+
+void** GetAppData( USHORT nSharedLib )
+{
+ return &(aAppData[nSharedLib]);
+}
+
+// =======================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/prj/build.lst b/tools/prj/build.lst
new file mode 100644
index 000000000000..f28d3a346aea
--- /dev/null
+++ b/tools/prj/build.lst
@@ -0,0 +1,30 @@
+tl tools : cppu external offuh ZLIB:zlib EXPAT:expat basegfx comphelper i18npool NULL
+tl tools usr1 - all tl_mkout NULL
+tl tools\bootstrp\isdll get - all tl_bsisdll NULL
+tl tools\bootstrp\addexes get - all tl_bsexes NULL
+tl tools\inc nmake - all tl_inc NULL
+tl tools\prj get - all tl_prj NULL
+tl tools\prj usr7 - all tl_deliver NULL
+tl tools\prj usr42 - all tl_zn NULL
+tl tools\workben get - all tl_wben NULL
+tl tools\source\testtoolloader nmake - all tl_ttloader tl_inc NULL
+tl tools\source\generic nmake - all tl_gen tl_fsys tl_inc NULL
+tl tools\source\memtools nmake - all tl_mem tl_fsys tl_inc NULL
+tl tools\source\debug nmake - all tl_deb tl_fsys tl_inc NULL
+tl tools\source\datetime nmake - all tl_dat tl_fsys tl_inc NULL
+tl tools\source\stream nmake - all tl_str tl_fsys tl_inc NULL
+tl tools\source\rc nmake - all tl_rc tl_fsys tl_inc NULL
+tl tools\source\ref nmake - all tl_ref tl_fsys tl_inc NULL
+tl tools\source\fsys nmake - all tl_fsys tl_inc NULL
+tl tools\source\zcodec nmake - all tl_zco tl_fsys tl_inc NULL
+tl tools\source\communi nmake - all tl_com tl_fsys tl_inc NULL
+tl tools\source\inet nmake - all tl_inet tl_fsys tl_inc NULL
+tl tools\source\string nmake - all tl_string tl_fsys tl_inc NULL
+tl tools\source\misc nmake - all tl_misc tl_inc NULL
+tl tools\win\source\dll nmake - w tl_dllw tl_inc NULL
+tl tools\os2\source\dll nmake - p tl_dllp tl_inc NULL
+tl tools\unx\source\dll nmake - u tl_dllu tl_inc NULL
+tl tools\util nmake - all tl_utl tl_com tl_dat tl_deb tl_dllu.u tl_dllp.p tl_dllw.w tl_fsys tl_gen tl_inet tl_mem tl_rc tl_ref tl_str tl_string tl_misc tl_zco tl_ttloader NULL
+tl tools\bootstrp nmake - all tl_bstrp tl_utl tl_inc NULL
+tl tools\bootstrp\addexes2 nmake - all tl_bsexes2 tl_bstrp tl_inc NULL
+tl tools\qa nmake - all tl_qa tl_utl NULL
diff --git a/tools/prj/d.lst b/tools/prj/d.lst
new file mode 100644
index 000000000000..4a705025a89e
--- /dev/null
+++ b/tools/prj/d.lst
@@ -0,0 +1,125 @@
+mkdir: %_DEST%\inc%_EXT%\bootstrp
+
+..\%__SRC%\misc\_ooo_st_btstrp.pdb %_DEST%\lib%_EXT%\_ooo_st_btstrp.pdb
+..\%__SRC%\bin\mkunroll* %_DEST%\bin%_EXT%
+..\%__SRC%\bin\tl?????.dll %_DEST%\bin%_EXT%\tl?????.dll
+..\%__SRC%\bin\tl?????.sym %_DEST%\bin%_EXT%\tl?????.sym
+..\%__SRC%\lib\atools.lib %_DEST%\lib%_EXT%\atools.lib
+..\%__SRC%\lib\btstrp.lib %_DEST%\lib%_EXT%\btstrp.lib
+..\%__SRC%\lib\bootstrp2.lib %_DEST%\lib%_EXT%\bootstrp2.lib
+..\%__SRC%\lib\itools.lib %_DEST%\lib%_EXT%\itools.lib
+..\%__SRC%\lib\lib*.a %_DEST%\lib%_EXT%\lib*.a
+..\%__SRC%\lib\lib*.sl %_DEST%\lib%_EXT%\lib*.sl
+..\%__SRC%\lib\lib*.so %_DEST%\lib%_EXT%\lib*.so
+..\%__SRC%\lib\lib*.so.* %_DEST%\lib%_EXT%\lib*.so.*
+..\%__SRC%\lib\lib*.dylib %_DEST%\lib%_EXT%\lib*.dylib
+..\%__SRC%\lib\stdstrm.lib %_DEST%\lib%_EXT%\stdstrm.lib
+..\%__SRC%\misc\tl?????.map %_DEST%\bin%_EXT%\tl?????.map
+..\%__SRC%\slb\btstrpsh.lib %_DEST%\lib%_EXT%\btstrpsh.lib
+
+..\inc\bootstrp\command.hxx %_DEST%\inc%_EXT%\bootstrp\command.hxx
+..\inc\bootstrp\inimgr.hxx %_DEST%\inc%_EXT%\bootstrp\inimgr.hxx
+..\inc\bootstrp\listmacr.hxx %_DEST%\inc%_EXT%\bootstrp\listmacr.hxx
+..\inc\bootstrp\mkcreate.hxx %_DEST%\inc%_EXT%\bootstrp\mkcreate.hxx
+..\inc\bootstrp\prj.hxx %_DEST%\inc%_EXT%\bootstrp\prj.hxx
+..\inc\bootstrp\sstring.hxx %_DEST%\inc%_EXT%\bootstrp\sstring.hxx
+
+..\inc\tools\toolsdllapi.h %_DEST%\inc%_EXT%\tools\toolsdllapi.h
+..\inc\tools\weakbase.hxx %_DEST%\inc%_EXT%\tools\weakbase.hxx
+..\inc\tools\weakbase.h %_DEST%\inc%_EXT%\tools\weakbase.h
+
+..\inc\tools\postwin.h %_DEST%\inc%_EXT%\tools\postwin.h
+..\inc\tools\prewin.h %_DEST%\inc%_EXT%\tools\prewin.h
+
+..\inc\tools\postx.h %_DEST%\inc%_EXT%\tools\postx.h
+..\inc\tools\prex.h %_DEST%\inc%_EXT%\tools\prex.h
+
+..\inc\tools\svlibrary.hxx %_DEST%\inc%_EXT%\tools\svlibrary.hxx
+..\inc\tools\solarmutex.hxx %_DEST%\inc%_EXT%\tools\solarmutex.hxx
+..\inc\tools\wintypes.hxx %_DEST%\inc%_EXT%\tools\wintypes.hxx
+..\inc\tools\mapunit.hxx %_DEST%\inc%_EXT%\tools\mapunit.hxx
+..\inc\tools\fldunit.hxx %_DEST%\inc%_EXT%\tools\fldunit.hxx
+..\inc\tools\fontenum.hxx %_DEST%\inc%_EXT%\tools\fontenum.hxx
+..\inc\tools\agapi.hxx %_DEST%\inc%_EXT%\tools\agapi.hxx
+..\inc\tools\agitem.hxx %_DEST%\inc%_EXT%\tools\agitem.hxx
+..\inc\tools\appendunixshellword.hxx %_DEST%\inc%_EXT%\tools\appendunixshellword.hxx
+..\inc\tools\bigint.hxx %_DEST%\inc%_EXT%\tools\bigint.hxx
+..\inc\tools\cachestr.hxx %_DEST%\inc%_EXT%\tools\cachestr.hxx
+..\inc\tools\chapi.hxx %_DEST%\inc%_EXT%\tools\chapi.hxx
+..\inc\tools\color.hxx %_DEST%\inc%_EXT%\tools\color.hxx
+..\inc\tools\contnr.hxx %_DEST%\inc%_EXT%\tools\contnr.hxx
+..\inc\tools\date.hxx %_DEST%\inc%_EXT%\tools\date.hxx
+..\inc\tools\datetime.hxx %_DEST%\inc%_EXT%\tools\datetime.hxx
+..\inc\tools\debug.hxx %_DEST%\inc%_EXT%\tools\debug.hxx
+..\inc\tools\diagnose_ex.h %_DEST%\inc%_EXT%\tools\diagnose_ex.h
+..\inc\tools\download.hxx %_DEST%\inc%_EXT%\tools\download.hxx
+..\inc\tools\dynary.hxx %_DEST%\inc%_EXT%\tools\dynary.hxx
+..\inc\tools\errcode.hxx %_DEST%\inc%_EXT%\tools\errcode.hxx
+..\inc\tools\errinf.hxx %_DEST%\inc%_EXT%\tools\errinf.hxx
+..\inc\tools\extendapplicationenvironment.hxx %_DEST%\inc%_EXT%\tools\extendapplicationenvironment.hxx
+..\inc\tools\fract.hxx %_DEST%\inc%_EXT%\tools\fract.hxx
+..\inc\tools\fsys.hxx %_DEST%\inc%_EXT%\tools\fsys.hxx
+..\inc\tools\eacopier.hxx %_DEST%\inc%_EXT%\tools\eacopier.hxx
+..\inc\tools\gen.hxx %_DEST%\inc%_EXT%\tools\gen.hxx
+..\inc\tools\globname.hxx %_DEST%\inc%_EXT%\tools\globname.hxx
+..\inc\tools\inetdef.hxx %_DEST%\inc%_EXT%\tools\inetdef.hxx
+..\inc\tools\inetmime.hxx %_DEST%\inc%_EXT%\tools\inetmime.hxx
+..\inc\tools\inetmsg.hxx %_DEST%\inc%_EXT%\tools\inetmsg.hxx
+..\inc\tools\inetstrm.hxx %_DEST%\inc%_EXT%\tools\inetstrm.hxx
+..\inc\tools\link.hxx %_DEST%\inc%_EXT%\tools\link.hxx
+..\inc\tools\list.hxx %_DEST%\inc%_EXT%\tools\list.hxx
+..\inc\tools\mempool.hxx %_DEST%\inc%_EXT%\tools\mempool.hxx
+..\inc\tools\multisel.hxx %_DEST%\inc%_EXT%\tools\multisel.hxx
+..\inc\tools\ownlist.hxx %_DEST%\inc%_EXT%\tools\ownlist.hxx
+..\inc\tools\postsys.h %_DEST%\inc%_EXT%\tools\postsys.h
+..\inc\tools\presys.h %_DEST%\inc%_EXT%\tools\presys.h
+..\inc\tools\pstm.hxx %_DEST%\inc%_EXT%\tools\pstm.hxx
+..\inc\tools\queue.hxx %_DEST%\inc%_EXT%\tools\queue.hxx
+..\inc\tools\rc.h %_DEST%\inc%_EXT%\tools\rc.h
+..\inc\tools\rc.hxx %_DEST%\inc%_EXT%\tools\rc.hxx
+..\inc\tools\rcid.h %_DEST%\inc%_EXT%\tools\rcid.h
+..\inc\tools\ref.hxx %_DEST%\inc%_EXT%\tools\ref.hxx
+..\inc\tools\resid.hxx %_DEST%\inc%_EXT%\tools\resid.hxx
+..\inc\tools\resmgr.hxx %_DEST%\inc%_EXT%\tools\resmgr.hxx
+..\inc\tools\StringListResource.hxx %_DEST%\inc%_EXT%\tools\StringListResource.hxx
+..\inc\tools\isofallback.hxx %_DEST%\inc%_EXT%\tools\isofallback.hxx
+..\inc\tools\rtti.hxx %_DEST%\inc%_EXT%\tools\rtti.hxx
+..\inc\tools\shl.hxx %_DEST%\inc%_EXT%\tools\shl.hxx
+..\inc\tools\simplerm.hxx %_DEST%\inc%_EXT%\tools\simplerm.hxx
+..\inc\tools\solar.h %_DEST%\inc%_EXT%\tools\solar.h
+..\inc\tools\stack.hxx %_DEST%\inc%_EXT%\tools\stack.hxx
+..\inc\tools\stream.hxx %_DEST%\inc%_EXT%\tools\stream.hxx
+..\inc\tools\string.hxx %_DEST%\inc%_EXT%\tools\string.hxx
+..\inc\tools\svwin.h %_DEST%\inc%_EXT%\tools\svwin.h
+..\inc\tools\table.hxx %_DEST%\inc%_EXT%\tools\table.hxx
+..\inc\tools\tenccvt.hxx %_DEST%\inc%_EXT%\tools\tenccvt.hxx
+..\inc\tools\time.hxx %_DEST%\inc%_EXT%\tools\time.hxx
+..\inc\tools\tools.h %_DEST%\inc%_EXT%\tools\tools.h
+..\inc\tools\unqid.hxx %_DEST%\inc%_EXT%\tools\unqid.hxx
+..\inc\tools\unqidx.hxx %_DEST%\inc%_EXT%\tools\unqidx.hxx
+..\inc\tools\urlkeys.hxx %_DEST%\inc%_EXT%\tools\urlkeys.hxx
+..\inc\tools\urlobj.hxx %_DEST%\inc%_EXT%\tools\urlobj.hxx
+..\inc\tools\vcompat.hxx %_DEST%\inc%_EXT%\tools\vcompat.hxx
+..\inc\tools\wldcrd.hxx %_DEST%\inc%_EXT%\tools\wldcrd.hxx
+..\inc\tools\zcodec.hxx %_DEST%\inc%_EXT%\tools\zcodec.hxx
+..\inc\tools\tempfile.hxx %_DEST%\inc%_EXT%\tools\tempfile.hxx
+..\inc\tools\geninfo.hxx %_DEST%\inc%_EXT%\tools\geninfo.hxx
+..\inc\tools\iparser.hxx %_DEST%\inc%_EXT%\tools\iparser.hxx
+..\inc\tools\config.hxx %_DEST%\inc%_EXT%\tools\config.hxx
+..\inc\tools\resary.hxx %_DEST%\inc%_EXT%\tools\resary.hxx
+..\inc\tools\poly.hxx %_DEST%\inc%_EXT%\tools\poly.hxx
+..\inc\tools\line.hxx %_DEST%\inc%_EXT%\tools\line.hxx
+..\inc\tools\vector2d.hxx %_DEST%\inc%_EXT%\tools\vector2d.hxx
+..\inc\tools\testtoolloader.hxx %_DEST%\inc%_EXT%\tools\testtoolloader.hxx
+..\inc\tools\svborder.hxx %_DEST%\inc%_EXT%\tools\svborder.hxx
+..\inc\tools\getprocessworkingdir.hxx %_DEST%\inc%_EXT%\tools\getprocessworkingdir.hxx
+..\inc\tools\b3dtrans.hxx %_DEST%\inc%_EXT%\tools\b3dtrans.hxx
+
+..\%__SRC%\bin\rscdep.exe %_DEST%\bin%_EXT%\rscdep.exe
+..\%__SRC%\bin\rscdep %_DEST%\bin%_EXT%\rscdep
+..\%__SRC%\bin\so_checksum.exe %_DEST%\bin%_EXT%\so_checksum.exe
+..\%__SRC%\bin\so_checksum %_DEST%\bin%_EXT%\so_checksum
+
+..\inc\tools\pathutils.hxx %_DEST%\inc%_EXT%\tools\pathutils.hxx
+..\%__SRC%\obj\pathutils.obj %_DEST%\lib%_EXT%\pathutils-obj.obj
+..\%__SRC%\slo\pathutils.obj %_DEST%\lib%_EXT%\pathutils-slo.obj
diff --git a/tools/qa/makefile.mk b/tools/qa/makefile.mk
new file mode 100644
index 000000000000..7e8720efef71
--- /dev/null
+++ b/tools/qa/makefile.mk
@@ -0,0 +1,55 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..
+PRJNAME = tools
+TARGET = qa
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE: settings.mk
+
+#building with stlport, but cppunit was not built with stlport
+.IF "$(USE_SYSTEM_STL)"!="YES"
+.IF "$(SYSTEM_CPPUNIT)"=="YES"
+CFLAGSCXX+=-DADAPT_EXT_STL
+.ENDIF
+.ENDIF
+
+CFLAGSCXX += $(CPPUNIT_CFLAGS)
+DLLPRE = # no leading "lib" on .so files
+
+SHL1TARGET = test_pathutils
+SHL1OBJS = $(SLO)$/test_pathutils.obj $(SLO)$/pathutils.obj
+SHL1STDLIBS = $(TOOLSLIB) $(CPPUNITLIB) $(SALLIB)
+SHL1VERSIONMAP = version.map
+SHL1IMPLIB = i$(SHL1TARGET)
+DEF1NAME = $(SHL1TARGET)
+
+SLOFILES = $(SHL1OBJS)
+
+.INCLUDE: target.mk
+.INCLUDE: _cppunit.mk
diff --git a/tools/qa/test_pathutils.cxx b/tools/qa/test_pathutils.cxx
new file mode 100644
index 000000000000..aa9a24e44457
--- /dev/null
+++ b/tools/qa/test_pathutils.cxx
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_tools.hxx"
+#include "sal/config.h"
+
+#include <cwchar>
+
+#include "preextstl.h"
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+#include "postextstl.h"
+
+#include "tools/pathutils.hxx"
+
+namespace {
+
+void buildPath(
+ wchar_t const * front, wchar_t const * back, wchar_t const * path)
+{
+#if defined WNT
+ wchar_t p[MAX_PATH];
+ wchar_t * e = tools::buildPath(
+ p, front, front + std::wcslen(front), back, std::wcslen(back));
+ CPPUNIT_ASSERT_EQUAL(p + std::wcslen(path), e);
+ CPPUNIT_ASSERT_EQUAL(0, std::wcscmp(path, p));
+#else
+ (void) front;
+ (void) back;
+ (void) path;
+#endif
+}
+
+class Test: public CppUnit::TestFixture {
+public:
+ void testBuildPath();
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(testBuildPath);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void Test::testBuildPath() {
+ buildPath(L"a:\\b\\", L"..", L"a:\\");
+ buildPath(L"a:\\b\\", L"..\\", L"a:\\");
+ buildPath(L"a:\\b\\c\\", L"..\\..\\..\\d", L"a:\\..\\d");
+ buildPath(L"\\\\a\\b\\", L"..\\..\\..\\c", L"\\\\..\\c");
+ buildPath(L"\\", L"..\\a", L"\\..\\a");
+ buildPath(L"", L"..\\a", L"..\\a");
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/qa/version.map b/tools/qa/version.map
new file mode 100644
index 000000000000..0dbbcc5a7372
--- /dev/null
+++ b/tools/qa/version.map
@@ -0,0 +1,34 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+UDK_3_0_0 {
+ global:
+ cppunitTestPlugIn;
+
+ local:
+ *;
+};
diff --git a/tools/source/communi/geninfo.cxx b/tools/source/communi/geninfo.cxx
new file mode 100644
index 000000000000..d6c70de3c467
--- /dev/null
+++ b/tools/source/communi/geninfo.cxx
@@ -0,0 +1,410 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include "tools/geninfo.hxx"
+#include <stdio.h>
+
+//
+// class GenericInformation
+//
+
+/*****************************************************************************/
+GenericInformation::GenericInformation( const ByteString &rKey,
+ const ByteString &rValue,
+ GenericInformationList *pParentList,
+ GenericInformationList *pSubInfos )
+/*****************************************************************************/
+ : ByteString( rKey ),
+ sValue( rValue ),
+ pInfoList( pSubInfos ),
+ pParent( pParentList )
+{
+ // if a ParentList exists, insert this object into it
+ if ( pParent )
+ pParent->InsertInfo( this );
+ // make myself owner of pInfoList
+ if ( pInfoList )
+ pInfoList->SetOwner( this );
+}
+
+/*****************************************************************************/
+GenericInformation::GenericInformation( const GenericInformation& rInf,
+ BOOL bCopySubs)
+/*****************************************************************************/
+ : ByteString( rInf ),
+ sValue( rInf.sValue ),
+ pInfoList( 0L ),
+ pParent(NULL)
+{
+ if(bCopySubs && rInf.pInfoList)
+ pInfoList = new GenericInformationList(*rInf.pInfoList, this);
+}
+
+/*****************************************************************************/
+GenericInformation::~GenericInformation()
+/*****************************************************************************/
+{
+ // remove pInfoList and all childs out of memory
+ delete pInfoList;
+ pInfoList = 0;
+
+ // remove this Info out of ParentList
+ if ( pParent )
+ pParent->RemoveInfo( this );
+}
+
+/*****************************************************************************/
+BOOL GenericInformation::InsertSubInfo( GenericInformation *pInfo )
+/*****************************************************************************/
+{
+ return ( pInfoList && pInfoList->InsertInfo( pInfo ));
+}
+
+/*****************************************************************************/
+BOOL GenericInformation::InsertSubInfo( const ByteString &rPathKey, const ByteString &rValue,
+ BOOL bSearchByPath, BOOL bNewPath )
+/*****************************************************************************/
+{
+ return (pInfoList && pInfoList->InsertInfo( rPathKey, rValue, bSearchByPath, bNewPath ));
+}
+
+/*****************************************************************************/
+void GenericInformation::RemoveSubInfo( GenericInformation *pInfo,
+ BOOL bDelete )
+/*****************************************************************************/
+{
+ pInfoList->RemoveInfo( pInfo, bDelete );
+}
+
+/*****************************************************************************/
+//void GenericInformation::RemoveSelf( BOOL bDelete )
+/*****************************************************************************/
+/*{
+ if ( pParent )
+ pParent->RemoveInfo( this, bDelete ); // loescht sich aus der Liste vom Parent und
+ // bei Bedarf auch mit obiger Methode alle Sublisten
+
+ // loescht sich bei Bedarf auch selbst
+ if ( bDelete )
+ delete this;
+}
+*/
+
+/*****************************************************************************/
+GenericInformation *GenericInformation::GetSubInfo( ByteString &rKey,
+ BOOL bSearchByPath,
+ BOOL bCreatePath )
+/*****************************************************************************/
+{
+ if ( !pInfoList && bCreatePath )
+ pInfoList = new GenericInformationList( this );
+ if ( pInfoList )
+ return pInfoList->GetInfo( rKey, bSearchByPath, bCreatePath );
+ return NULL;
+}
+
+
+//
+// class GenericInformationList
+//
+
+/*****************************************************************************/
+GenericInformationList::GenericInformationList( GenericInformation *pParent )
+/*****************************************************************************/
+ : pOwner( pParent )
+{
+}
+
+/*****************************************************************************/
+GenericInformationList::GenericInformationList(const GenericInformationList& rList,
+ GenericInformation *pParent)
+/*****************************************************************************/
+ : GenericInformationList_Impl()
+{
+ USHORT i;
+ GenericInformation* pTemp,*pWork;
+
+ pOwner = pParent;
+
+ for(i=0;i<rList.Count();i++)
+ {
+ pTemp = rList.GetObject(i);
+ pWork = new GenericInformation(*pTemp,TRUE);
+
+ Insert(pWork,LIST_APPEND);
+ }
+}
+
+/*****************************************************************************/
+GenericInformationList::~GenericInformationList()
+/*****************************************************************************/
+{
+ // delete all Informations stored in this List
+ // ### GH: Hier werden dann wohl etwa die H�lfte der Eintr�ge gel�scht
+/* for ( ULONG i = 0; i < Count(); i++ ) {
+ GetObject( i )->ListDeleted();
+ delete GetObject( i );
+ Remove( i );*/
+ // Neue Variante:
+ while ( Count() ) {
+ GetObject( 0 )->ListDeleted();
+ delete GetObject( 0 );
+ Remove( (ULONG)0 );
+ }
+}
+
+/*****************************************************************************/
+GenericInformation *GenericInformationList::Search( ULONG &rPos, ByteString sKey,
+ ULONG nStart, ULONG nEnd )
+/*****************************************************************************/
+{
+ if ( Count() == 0 ) {
+ rPos = 0;
+ return NULL;
+ }
+
+ if ( nStart == nEnd ) {
+ rPos = nStart;
+ ByteString sCandidate = ByteString( *GetObject( nStart ));
+ if ( sCandidate.ToUpperAscii() == sKey.ToUpperAscii()) {
+ return GetObject( nStart ); // found !!!
+ }
+ else {
+ // requested key not found
+ return NULL;
+ }
+ }
+
+ // search binary in existing list
+ ULONG nActPos = nStart + (( nEnd - nStart ) / 2 );
+ rPos = nActPos;
+ ByteString sCandidate = ByteString( *GetObject( nActPos ));
+
+ if ( sCandidate.ToUpperAscii() == sKey.ToUpperAscii())
+ return GetObject( nActPos ); // found !!!
+
+ // split the list at ActPos
+ if ( sCandidate < sKey )
+ return Search( rPos, sKey, nActPos + 1, nEnd );
+ else
+ return Search( rPos, sKey, nStart, nActPos );
+}
+
+/*****************************************************************************/
+GenericInformation *GenericInformationList::GetInfo( ByteString &rKey,
+ BOOL bSearchByPath,
+ BOOL bCreatePath )
+/*****************************************************************************/
+{
+
+ rKey.EraseLeadingChars( '/' );
+ rKey.EraseTrailingChars( '/' );
+
+ ByteString sKey;
+ if ( bSearchByPath )
+ sKey = rKey.GetToken( 0, '/' );
+ else
+ sKey = rKey;
+
+ ULONG nPos = 0;
+ GenericInformation *pReturnInfo = Search( nPos, sKey, 0, Count() - 1 );
+ /* wenn kein Searchpath gesetzt und kein Returninfo vorhanden,
+ * gib NULL zurueck
+ * wenn Searchpath gesetzt und returninfo vorhanden,
+ * suche weiter nach unten
+ * wenn searchpath gesetzt kein returninfo vorhanden und newpath gesetzt,
+ * mache neues Verzeichniss
+ */
+ USHORT nTokenCount = rKey.GetTokenCount('/');
+ // search for next key of path in next level of tree
+ if ( bSearchByPath && (nTokenCount > 1)) {
+ ByteString sPath = ByteString(rKey.Copy( sKey.Len() + 1 ));
+ if ( !pReturnInfo ) { // wenn kein Return, dann muss man es anlegen
+ if ( !bCreatePath ) // wenn aber kein Create, dann nicht anlegen
+ return NULL;
+ pReturnInfo = new GenericInformation( sKey, "", this, NULL);
+ pReturnInfo->SetSubList( new GenericInformationList( pReturnInfo ));
+ }
+ return pReturnInfo->GetSubInfo( sPath, TRUE, bCreatePath );
+ }
+ if ( !pReturnInfo && bCreatePath ) {
+ pReturnInfo = new GenericInformation ( sKey, "", this, NULL);
+ }
+
+ return pReturnInfo; // kann durchaus NULL sein.
+}
+
+/*****************************************************************************/
+ULONG GenericInformationList::InsertSorted( GenericInformation *pInfo,
+ BOOL bOverwrite,
+ ULONG nStart, ULONG nEnd )
+/*****************************************************************************/
+{
+ if ( Count() == 0 ) {
+ // empty list, so insert at first pos
+ Insert( pInfo, LIST_APPEND );
+ return 0;
+ }
+
+ ByteString sKey( pInfo->GetBuffer());
+ sKey.ToUpperAscii();
+
+ // Check to sppeed up reading a (partially) sorted list
+ if ( nStart == 0 && Count()-1 == nEnd )
+ {
+ ByteString sCandidate( *GetObject( nEnd ));
+ if ( sCandidate.ToUpperAscii() < sKey )
+ {
+ Insert( pInfo, LIST_APPEND );
+ return nEnd+1;
+ }
+ }
+
+// ### GH: dieser Block schein �berfl�ssig zu sein
+ if ( Count() == 1 ) {
+ ByteString sCandidate( *GetObject( 0 ));
+ if ( sCandidate.ToUpperAscii() == sKey ) {
+ // key allready exists in list
+ if ( bOverwrite )
+ Replace( pInfo, ULONG(0)); // ### Laut NF scheint hier ein Memory Leak zu sein
+ return 0;
+ }
+ else if ( sCandidate > sKey ) {
+ Insert( pInfo, ULONG(0));
+ return 0;
+ }
+ else {
+ Insert( pInfo, LIST_APPEND );
+ return 1;
+ }
+ }
+// ### GH: /ENDE/ dieser Block schein �berfl�ssig zu sein
+
+ ULONG nActPos = nStart + (( nEnd - nStart ) / 2 );
+ ByteString sCandidate = ByteString( *GetObject( nActPos ));
+
+ if ( sCandidate.ToUpperAscii() == sKey ) {
+ // key allready exists in list
+ if ( bOverwrite )
+ Replace( pInfo, nActPos ); // ### Laut NF scheint hier ein Memory Leak zu sein
+ return nActPos;
+ }
+
+ if ( nStart == nEnd ) {
+ // now more ways to search for key -> insert here
+ if ( sCandidate > sKey ) {
+ Insert( pInfo, nStart );
+ return nStart;
+ }
+ else {
+ Insert( pInfo, nStart + 1 );
+ return ( nStart + 1 );
+ }
+ }
+
+ if ( nActPos == Count() - 1 ) {
+ // reached end of list -> insert here
+ Insert( pInfo, LIST_APPEND );
+ return ( nActPos + 1 );
+ }
+
+ ByteString sSecondCand = ByteString( *GetObject( nActPos + 1 ));
+ if (( sCandidate < sKey ) && ( sSecondCand.ToUpperAscii() > sKey )) {
+ // optimal position to insert object
+ Insert( pInfo, nActPos + 1 );
+ return ( nActPos + 1 );
+ }
+
+ if ( sCandidate < sKey )
+ return InsertSorted( pInfo, bOverwrite, nActPos + 1, nEnd );
+ else
+ return InsertSorted( pInfo, bOverwrite, nStart, nActPos );
+}
+
+/*****************************************************************************/
+BOOL GenericInformationList::InsertInfo( GenericInformation *pInfo,
+ BOOL bOverwrite )
+/*****************************************************************************/
+{
+ if ( !pInfo->Len())
+ return FALSE;
+
+ InsertSorted( pInfo, bOverwrite, 0, Count() - 1 );
+ return TRUE;
+}
+
+
+/*****************************************************************************/
+BOOL GenericInformationList::InsertInfo( const ByteString &rPathKey, const ByteString &rValue,
+ BOOL bSearchByPath, BOOL bNewPath )
+/*****************************************************************************/
+{
+ GenericInformation *pInfo;
+ ByteString sPathKey ( rPathKey );
+ sPathKey.EraseLeadingChars( '/' );
+ sPathKey.EraseTrailingChars( '/' );
+
+ pInfo = GetInfo( sPathKey, bSearchByPath, bNewPath );
+
+ if ( pInfo ) {
+ pInfo->SetValue( rValue );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*****************************************************************************/
+void GenericInformationList::RemoveInfo( GenericInformation *pInfo,
+ BOOL bDelete )
+/*****************************************************************************/
+{
+ Remove( pInfo );
+ if ( bDelete )
+ delete pInfo;
+/* if ( Count() == 0 && pOwner ) // Leere Listen entfernen;
+ {
+ SetOwner( NULL );
+ delete this;
+ } Rausgepatched by GH */
+}
+
+GenericInformation* GenericInformationList::SetOwner( GenericInformation *pNewOwner )
+{
+ GenericInformation *pOldOwner = pOwner;
+ if ( pOwner ) // bei parent austragen;
+ pOwner->SetSubList( NULL );
+ if ( pNewOwner )
+ pNewOwner->SetSubList( this );
+ pOwner = pNewOwner;
+ return pOldOwner;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/communi/makefile.mk b/tools/source/communi/makefile.mk
new file mode 100644
index 000000000000..1795081a9ec5
--- /dev/null
+++ b/tools/source/communi/makefile.mk
@@ -0,0 +1,50 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=TOOLS
+TARGET=communi
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+OBJFILES= \
+ $(OBJ)$/parser.obj \
+ $(OBJ)$/geninfo.obj \
+
+SLOFILES= \
+ $(SLO)$/parser.obj \
+ $(SLO)$/geninfo.obj \
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/tools/source/communi/parser.cxx b/tools/source/communi/parser.cxx
new file mode 100644
index 000000000000..2ca53475d88b
--- /dev/null
+++ b/tools/source/communi/parser.cxx
@@ -0,0 +1,471 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <stdio.h>
+#include <tools/stream.hxx>
+#include <tools/fsys.hxx>
+
+#include "tools/iparser.hxx"
+#include "tools/geninfo.hxx"
+
+
+
+//
+// class InformationParser
+//
+
+#define cKeyLevelChar '\t'
+
+/*****************************************************************************/
+InformationParser::InformationParser( BOOL bReplace )
+/*****************************************************************************/
+ : bRecover( FALSE ),
+ sOldLine( "" ),
+ bReplaceVariables( bReplace ),
+ nLevel( 0 ),
+ sUPD( "" ),
+ sVersion( "" ),
+ pActStream( NULL ),
+ nErrorCode( 0 ),
+ nErrorLine( 0 ),
+ sErrorText( "" ),
+ nActLine( 0 )
+{
+}
+
+/*****************************************************************************/
+InformationParser::~InformationParser()
+/*****************************************************************************/
+{
+}
+
+/*****************************************************************************/
+ByteString &InformationParser::ReadLine()
+/*****************************************************************************/
+{
+ ByteString sLine;
+
+ if ( bRecover ) {
+ bRecover = FALSE;
+ }
+ else {
+ if ( !pActStream->IsEof()) {
+ pActStream->ReadLine( sLine );
+ xub_StrLen nStart = 0;
+ xub_StrLen nEnd = sLine.Len();
+ BOOL bCopy = FALSE;
+ while ( nStart < nEnd && ( sLine.GetChar( nStart ) == ' ' || sLine.GetChar( nStart ) == 0x09 ) )
+ {
+ nStart++;
+ bCopy = TRUE;
+ }
+
+ while ( nStart < nEnd && ( sLine.GetChar( nEnd-1 ) == ' ' || sLine.GetChar( nEnd-1 ) == 0x09 ) )
+ {
+ nEnd--;
+ bCopy = TRUE;
+ }
+
+ if ( bCopy )
+ sLine = sLine.Copy( nStart, nEnd - nStart );
+
+ if (( sLine.GetChar( 0 ) == '#' ) || ( !sLine.Len())) {
+ if ( sCurrentComment.Len())
+ sCurrentComment += "\n";
+ sCurrentComment += sLine;
+ return ReadLine();
+ }
+ else {
+ if ( bReplaceVariables ) {
+ sLine.SearchAndReplaceAll( "%UPD", sUPD );
+ sLine.SearchAndReplaceAll( "%VERSION", sVersion );
+ }
+ }
+ }
+ else {
+ if ( nLevel ) {
+ sLine = "}";
+ fprintf( stdout, "Reached EOF parsing %s. Suplying extra '}'\n",ByteString( sStreamName, gsl_getSystemTextEncoding()).GetBuffer() );
+ // nErrorCode = IP_UNEXPECTED_EOF;
+ // nErrorLine = nActLine;
+ }
+ else
+ sLine = "";
+ }
+
+ sOldLine = sLine;
+ nActLine++;
+ }
+
+ return sOldLine;
+}
+
+/*****************************************************************************/
+GenericInformation *InformationParser::ReadKey(
+ GenericInformationList *pExistingList )
+/*****************************************************************************/
+{
+ // this method has no error handling yet, but it works very fast.
+ // it is used to create whole informations and sub informations in
+ // a simple data format in memory, readed in a configuration file with
+ // following format:
+
+ /*
+
+ key [value]
+ {
+ key [value]
+ key [value]
+ {
+ key [value]
+ ...
+ ...
+ }
+ }
+ key [value]
+ ...
+ ...
+
+ */
+
+ GenericInformation *pInfo = NULL;
+
+ ByteString sLine( ReadLine());
+ ByteString sKey;
+ ByteString sValue;
+ ByteString sComment( sCurrentComment );
+ sCurrentComment = "";
+
+ // key separated from value by tab?
+ USHORT nWSPos = sLine.Search( ' ' );
+ if ( sLine.Search( '\t' ) < nWSPos ) {
+ nWSPos = sLine.Search( '\t' );
+ sLine.SearchAndReplace( "\t", " " );
+ }
+
+ if ( sLine.GetTokenCount( ' ' ) > 1 ) {
+ sKey = sLine.GetToken( 0, ' ' );
+ sValue = sLine.Copy( sKey.Len() + 1 );
+ while (( sValue.Search( ' ' ) == 0 ) || ( sValue.Search( '\t' ) == 0 )) {
+ sValue.Erase( 0, 1 );
+ }
+ }
+ else
+ sKey=sLine;
+
+ if ( bReplaceVariables && !nLevel ) {
+ sUPD = sKey.Copy( sKey.Len() - 3 );
+ sVersion = sKey;
+ }
+
+ if ( ReadLine() == "{" ) {
+ nLevel++;
+ GenericInformationList *pSubList = new GenericInformationList();
+ while ( ReadLine() != "}" ) {
+ Recover();
+ ReadKey( pSubList );
+ }
+ nLevel--;
+ pInfo = new GenericInformation( sKey, sValue,
+ pExistingList, pSubList );
+ pInfo->SetComment( sComment );
+ }
+ else {
+ Recover();
+ if ( !sKey.Equals( "}" ) && !sKey.Equals( "{" ) )
+ {
+ pInfo = new GenericInformation( sKey, sValue, pExistingList );
+ pInfo->SetComment( sComment );
+ }
+ }
+
+ return pInfo;
+}
+
+/*****************************************************************************/
+void InformationParser::Recover()
+/*****************************************************************************/
+{
+ bRecover = TRUE;
+}
+
+/*****************************************************************************/
+BOOL InformationParser::Save( SvStream &rOutStream,
+ const GenericInformationList *pSaveList,
+ USHORT level, BOOL bStripped )
+/*****************************************************************************/
+{
+ USHORT i;
+ ULONG nInfoListCount;
+ ByteString sTmpStr;
+ GenericInformation *pGenericInfo;
+ GenericInformationList *pGenericInfoList;
+
+ static ByteString aKeyLevel;
+ aKeyLevel.Expand( level, cKeyLevelChar );
+
+ for ( nInfoListCount = 0; nInfoListCount < pSaveList->Count(); nInfoListCount++) {
+ // Key-Value Paare schreiben
+ pGenericInfo = pSaveList->GetObject( nInfoListCount );
+ sTmpStr = "";
+ if ( !bStripped && level )
+ sTmpStr.Append( aKeyLevel.GetBuffer(), level );
+
+ if ( !bStripped )
+ for ( i = 0; i < pGenericInfo->GetComment().GetTokenCount( '\n' ); i++ ) {
+ sTmpStr += pGenericInfo->GetComment().GetToken( i, '\n' );
+ sTmpStr += "\n";
+ if ( level )
+ sTmpStr.Append( aKeyLevel.GetBuffer(), level );
+ }
+
+ sTmpStr += pGenericInfo->GetBuffer();
+ sTmpStr += ' ';
+ sTmpStr += pGenericInfo->GetValue();
+ if ( !rOutStream.WriteLine( sTmpStr ) )
+ return FALSE;
+
+ // wenn vorhanden, bearbeite recursive die Sublisten
+ if (( pGenericInfoList = pGenericInfo->GetSubList() ) != NULL ) {
+ // oeffnende Klammer
+ sTmpStr = "";
+ if ( !bStripped && level )
+ sTmpStr.Append( aKeyLevel.GetBuffer(), level );
+ sTmpStr += '{';
+ if ( !rOutStream.WriteLine( sTmpStr ) )
+ return FALSE;
+ // recursiv die sublist abarbeiten
+ if ( !Save( rOutStream, pGenericInfoList, level+1, bStripped ) )
+ return FALSE;
+ // schliessende Klammer
+ sTmpStr = "";
+ if ( !bStripped && level )
+ sTmpStr.Append( aKeyLevel.GetBuffer(), level );
+ sTmpStr += '}';
+ if ( !rOutStream.WriteLine( sTmpStr ) )
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/*****************************************************************************/
+GenericInformationList *InformationParser::Execute(
+ SvStream &rSourceStream,
+ GenericInformationList *pExistingList )
+/*****************************************************************************/
+{
+ GenericInformationList *pList;
+ if ( pExistingList )
+ pList = pExistingList;
+ else
+ pList = new GenericInformationList();
+
+ pActStream = &rSourceStream;
+
+ // read all infos out of current file
+ while( !rSourceStream.IsEof()) {
+ nLevel = 0;
+ ReadKey( pList );
+ }
+
+ return pList;
+}
+
+/*****************************************************************************/
+GenericInformationList *InformationParser::Execute( SvMemoryStream &rSourceStream,
+ GenericInformationList *pExistingList )
+/*****************************************************************************/
+{
+ sStreamName = UniString( "Memory", gsl_getSystemTextEncoding());
+ return Execute( (SvStream &)rSourceStream, pExistingList );
+}
+
+/*****************************************************************************/
+GenericInformationList *InformationParser::Execute(
+ SvFileStream &rSourceStream,
+ GenericInformationList *pExistingList )
+/*****************************************************************************/
+{
+ if ( !rSourceStream.IsOpen())
+ return NULL;
+ sStreamName = rSourceStream.GetFileName();
+ return Execute( (SvStream &)rSourceStream, pExistingList );
+}
+
+/*****************************************************************************/
+GenericInformationList *InformationParser::Execute( UniString &rSourceFile,
+ GenericInformationList *pExistingList )
+/*****************************************************************************/
+{
+ DirEntry aDirEntry( rSourceFile );
+ if ( !aDirEntry.Exists())
+ return NULL;
+
+ GenericInformationList *pList;
+ if ( pExistingList )
+ pList = pExistingList;
+ else
+ pList = new GenericInformationList();
+
+ // reset status
+ nErrorCode = 0;
+ nErrorLine = 0;
+ nActLine = 0;
+
+ SvFileStream aActStream;
+ aActStream.Open( rSourceFile, STREAM_READ );
+ if( aActStream.GetError())
+ return NULL;
+
+ pActStream = &aActStream;
+ if ( !Execute( aActStream, pList )) {
+ delete pList;
+ pList = NULL;
+ }
+
+ // close the stream
+ aActStream.Close();
+ pActStream = NULL;
+
+ if ( !nErrorCode )
+ return pList;
+
+ return NULL;
+}
+
+/*****************************************************************************/
+GenericInformationList *InformationParser::Execute( Dir &rDir,
+ GenericInformationList *pExistingList )
+/*****************************************************************************/
+{
+ GenericInformationList *pList;
+
+ if ( pExistingList )
+ pList = pExistingList;
+ else
+ pList = new GenericInformationList();
+
+ for ( USHORT i = 0; i < rDir.Count(); i++ ) {
+
+ // execute this dir
+ UniString sNextFile( rDir[i].GetFull());
+ GenericInformationList *pSubList = Execute( sNextFile );
+
+ if ( !pSubList ) {
+ // any errors ?
+ delete pList;
+ return NULL;
+ }
+
+ // create new info and insert it into list
+ ByteString sFileKey( rDir[i].GetName(), RTL_TEXTENCODING_UTF8 );
+ new GenericInformation(
+ sFileKey,
+ ByteString( "" ),
+ pList, pSubList );
+ }
+
+ return pList;
+}
+
+/*****************************************************************************/
+BOOL InformationParser::Save( SvFileStream &rSourceStream,
+ const GenericInformationList *pSaveList )
+/*****************************************************************************/
+{
+ if ( !rSourceStream.IsOpen() || !Save( (SvStream &)rSourceStream, pSaveList, 0, FALSE ))
+ {
+ printf( "ERROR saving file \"%s\"\n",ByteString( rSourceStream.GetFileName(), gsl_getSystemTextEncoding()).GetBuffer() );
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************/
+BOOL InformationParser::Save( SvMemoryStream &rSourceStream,
+ const GenericInformationList *pSaveList )
+/*****************************************************************************/
+{
+ Time a;
+ BOOL bRet = Save( (SvStream &)rSourceStream, pSaveList, 0, TRUE );
+ Time b;
+ b = b - a;
+ return bRet;
+}
+
+/*****************************************************************************/
+BOOL InformationParser::Save( const UniString &rSourceFile,
+ const GenericInformationList *pSaveList )
+/*****************************************************************************/
+{
+ SvFileStream *pOutFile = new SvFileStream( rSourceFile, STREAM_STD_WRITE | STREAM_TRUNC );
+
+ if ( !Save( *pOutFile, pSaveList )) {
+ delete pOutFile;
+ return FALSE;
+ }
+ delete pOutFile;
+ return TRUE;
+}
+
+/*****************************************************************************/
+USHORT InformationParser::GetErrorCode()
+/*****************************************************************************/
+{
+ return nErrorCode;
+}
+
+/*****************************************************************************/
+ByteString &InformationParser::GetErrorText()
+/*****************************************************************************/
+{
+ // sErrorText = pActStream->GetFileName();
+ sErrorText = ByteString( sStreamName, gsl_getSystemTextEncoding());
+ sErrorText += ByteString( " (" );
+ sErrorText += ByteString::CreateFromInt64(nErrorLine);
+ sErrorText += ByteString( "): " );
+
+ switch ( nErrorCode ) {
+ case IP_NO_ERROR:
+ sErrorText += ByteString( "Keine Fehler aufgetereten" );
+ break;
+ case IP_UNEXPECTED_EOF:
+ sErrorText += ByteString( "Ungültiges Dateiende!" );
+ break;
+ }
+
+ return sErrorText;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/datetime/datetime.cxx b/tools/source/datetime/datetime.cxx
new file mode 100644
index 000000000000..05f03ab10f77
--- /dev/null
+++ b/tools/source/datetime/datetime.cxx
@@ -0,0 +1,445 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <tools/datetime.hxx>
+#include <rtl/math.hxx>
+
+/*************************************************************************
+|*
+|* DateTime::IsBetween()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 18.05.92
+|* Letzte Aenderung TH 18.05.92
+|*
+*************************************************************************/
+
+BOOL DateTime::IsBetween( const DateTime& rFrom,
+ const DateTime& rTo ) const
+{
+ if ( (*this >= rFrom) && (*this <= rTo) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator >()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 18.05.92
+|* Letzte Aenderung TH 18.05.92
+|*
+*************************************************************************/
+
+BOOL DateTime::operator >( const DateTime& rDateTime ) const
+{
+ if ( (Date::operator>( rDateTime )) ||
+ (Date::operator==( rDateTime ) && Time::operator>( rDateTime )) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator <()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 18.05.92
+|* Letzte Aenderung TH 18.05.92
+|*
+*************************************************************************/
+
+BOOL DateTime::operator <( const DateTime& rDateTime ) const
+{
+ if ( (Date::operator<( rDateTime )) ||
+ (Date::operator==( rDateTime ) && Time::operator<( rDateTime )) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator >=()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 18.05.92
+|* Letzte Aenderung TH 18.05.92
+|*
+*************************************************************************/
+
+BOOL DateTime::operator >=( const DateTime& rDateTime ) const
+{
+ if ( (Date::operator>( rDateTime )) ||
+ (Date::operator==( rDateTime ) && Time::operator>=( rDateTime )) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator <=()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 18.05.92
+|* Letzte Aenderung TH 18.05.92
+|*
+*************************************************************************/
+
+BOOL DateTime::operator <=( const DateTime& rDateTime ) const
+{
+ if ( (Date::operator<( rDateTime )) ||
+ (Date::operator==( rDateTime ) && Time::operator<=( rDateTime )) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* DateTime::GetSecFromDateTime()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 02.10.96
+|* Letzte Aenderung TH 02.10.96
+|*
+*************************************************************************/
+
+long DateTime::GetSecFromDateTime( const Date& rDate ) const
+{
+ if ( Date::operator<( rDate ) )
+ return 0;
+ else
+ {
+ long nSec = Date( *this ) - rDate;
+ nSec *= 24UL*60*60;
+ long nHour = GetHour();
+ long nMin = GetMin();
+ nSec += (nHour*3600)+(nMin*60)+GetSec();
+ return nSec;
+ }
+}
+
+/*************************************************************************
+|*
+|* DateTime::GetSecFromDateTime()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 02.10.96
+|* Letzte Aenderung TH 02.10.96
+|*
+*************************************************************************/
+
+void DateTime::MakeDateTimeFromSec( const Date& rDate, ULONG nSec )
+{
+ long nDays = nSec / (24UL*60*60);
+ ((Date*)this)->operator=( rDate );
+ nSec -= nDays * (24UL*60*60);
+ USHORT nMin = (USHORT)(nSec / 60);
+ nSec -= nMin * 60;
+ ((Time*)this)->operator=( Time( 0, nMin, (USHORT)nSec ) );
+ operator+=( nDays );
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator +=()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 02.10.96
+|* Letzte Aenderung TH 02.10.96
+|*
+*************************************************************************/
+
+DateTime& DateTime::operator +=( const Time& rTime )
+{
+ Time aTime = *this;
+ aTime += rTime;
+ USHORT nHours = aTime.GetHour();
+ if ( aTime.GetTime() > 0 )
+ {
+ while ( nHours >= 24 )
+ {
+ Date::operator++();
+ nHours -= 24;
+ }
+ aTime.SetHour( nHours );
+ }
+ else if ( aTime.GetTime() != 0 )
+ {
+ while ( nHours >= 24 )
+ {
+ Date::operator--();
+ nHours -= 24;
+ }
+ Date::operator--();
+ aTime = Time( 24, 0, 0 )+aTime;
+ }
+ Time::operator=( aTime );
+
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator -=()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 02.10.96
+|* Letzte Aenderung TH 02.10.96
+|*
+*************************************************************************/
+
+DateTime& DateTime::operator -=( const Time& rTime )
+{
+ Time aTime = *this;
+ aTime -= rTime;
+ USHORT nHours = aTime.GetHour();
+ if ( aTime.GetTime() > 0 )
+ {
+ while ( nHours >= 24 )
+ {
+ Date::operator++();
+ nHours -= 24;
+ }
+ aTime.SetHour( nHours );
+ }
+ else if ( aTime.GetTime() != 0 )
+ {
+ while ( nHours >= 24 )
+ {
+ Date::operator--();
+ nHours -= 24;
+ }
+ Date::operator--();
+ aTime = Time( 24, 0, 0 )+aTime;
+ }
+ Time::operator=( aTime );
+
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator+()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 02.10.96
+|* Letzte Aenderung TH 02.10.96
+|*
+*************************************************************************/
+
+DateTime operator +( const DateTime& rDateTime, long nDays )
+{
+ DateTime aDateTime( rDateTime );
+ aDateTime += nDays;
+ return aDateTime;
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator-()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 02.10.96
+|* Letzte Aenderung TH 02.10.96
+|*
+*************************************************************************/
+
+DateTime operator -( const DateTime& rDateTime, long nDays )
+{
+ DateTime aDateTime( rDateTime );
+ aDateTime -= nDays;
+ return aDateTime;
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator+()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 02.10.96
+|* Letzte Aenderung TH 02.10.96
+|*
+*************************************************************************/
+
+DateTime operator +( const DateTime& rDateTime, const Time& rTime )
+{
+ DateTime aDateTime( rDateTime );
+ aDateTime += rTime;
+ return aDateTime;
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator-()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 02.10.96
+|* Letzte Aenderung TH 02.10.96
+|*
+*************************************************************************/
+
+DateTime operator -( const DateTime& rDateTime, const Time& rTime )
+{
+ DateTime aDateTime( rDateTime );
+ aDateTime -= rTime;
+ return aDateTime;
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator +=( double )
+|*
+*************************************************************************/
+
+DateTime& DateTime::operator +=( double fTimeInDays )
+{
+ double fInt, fFrac;
+ if ( fTimeInDays < 0.0 )
+ {
+ fInt = ::rtl::math::approxCeil( fTimeInDays );
+ fFrac = fInt <= fTimeInDays ? 0.0 : fTimeInDays - fInt;
+ }
+ else
+ {
+ fInt = ::rtl::math::approxFloor( fTimeInDays );
+ fFrac = fInt >= fTimeInDays ? 0.0 : fTimeInDays - fInt;
+ }
+ Date::operator+=( long(fInt) ); // full days
+ if ( fFrac )
+ {
+ Time aTime(0); // default ctor calls system time, we don't need that
+ fFrac *= 24UL * 60 * 60 * 1000; // time expressed in milliseconds
+ aTime.MakeTimeFromMS( long(fFrac) ); // method handles negative ms
+ operator+=( aTime );
+ }
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator +( double )
+|*
+*************************************************************************/
+
+DateTime operator +( const DateTime& rDateTime, double fTimeInDays )
+{
+ DateTime aDateTime( rDateTime );
+ aDateTime += fTimeInDays;
+ return aDateTime;
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator -()
+|*
+*************************************************************************/
+
+double operator -( const DateTime& rDateTime1, const DateTime& rDateTime2 )
+{
+ long nDays = (const Date&) rDateTime1 - (const Date&) rDateTime2;
+ long nTime = rDateTime1.GetMSFromTime() - rDateTime2.GetMSFromTime();
+ if ( nTime )
+ {
+ double fTime = double(nTime);
+ fTime /= 24UL * 60 * 60 * 1000; // convert from milliseconds to fraction
+ if ( nDays < 0 && fTime > 0.0 )
+ fTime = 1.0 - fTime;
+ return double(nDays) + fTime;
+ }
+ return double(nDays);
+}
+
+void DateTime::GetWin32FileDateTime( sal_uInt32 & rLower, sal_uInt32 & rUpper )
+{
+ const sal_Int64 a100nPerSecond = SAL_CONST_INT64( 10000000 );
+ const sal_Int64 a100nPerDay = a100nPerSecond * sal_Int64( 60 * 60 * 24 );
+
+ sal_Int64 nYears = GetYear() - 1601;
+ sal_Int64 nDays =
+ nYears * 365 +
+ nYears / 4 - nYears / 100 + nYears / 400 +
+ GetDayOfYear() - 1;
+
+ sal_Int64 aTime =
+ a100nPerDay * nDays +
+ a100nPerSecond * (
+ sal_Int64( GetSec() ) +
+ 60 * sal_Int64( GetMin() ) +
+ 60 * 60 * sal_Int64( GetHour() ) );
+
+ rLower = sal_uInt32( aTime % SAL_CONST_UINT64( 0x100000000 ) );
+ rUpper = sal_uInt32( aTime / SAL_CONST_UINT64( 0x100000000 ) );
+}
+
+DateTime DateTime::CreateFromWin32FileDateTime( const sal_uInt32 & rLower, const sal_uInt32 & rUpper )
+{
+ const sal_Int64 a100nPerSecond = SAL_CONST_INT64( 10000000 );
+ const sal_Int64 a100nPerDay = a100nPerSecond * sal_Int64( 60 * 60 * 24 );
+
+ sal_Int64 aTime = sal_Int64(
+ sal_uInt64( rUpper ) * SAL_CONST_UINT64( 0x100000000 ) +
+ sal_uInt64( rLower ) );
+
+ sal_Int64 nDays = aTime / a100nPerDay;
+ sal_Int64 nYears =
+ ( nDays -
+ ( nDays / ( 4 * 365 ) ) +
+ ( nDays / ( 100 * 365 ) ) -
+ ( nDays / ( 400 * 365 ) ) ) / 365;
+ nDays -= nYears * 365 + nYears / 4 - nYears / 100 + nYears / 400;
+
+ USHORT nMonths = 0;
+ for( sal_Int64 nDaysCount = nDays; nDaysCount >= 0; )
+ {
+ nDays = nDaysCount;
+ nMonths ++;
+ nDaysCount -= Date(
+ 1, nMonths, sal::static_int_cast< USHORT >(1601 + nYears) ).
+ GetDaysInMonth();
+ }
+
+ Date _aDate(
+ (USHORT)( nDays + 1 ), nMonths,
+ sal::static_int_cast< USHORT >(nYears + 1601) );
+ Time _aTime( ULONG( ( aTime / ( a100nPerSecond * 60 * 60 ) ) % sal_Int64( 24 ) ),
+ ULONG( ( aTime / ( a100nPerSecond * 60 ) ) % sal_Int64( 60 ) ),
+ ULONG( ( aTime / ( a100nPerSecond ) ) % sal_Int64( 60 ) ) );
+
+ return DateTime( _aDate, _aTime );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/datetime/makefile.mk b/tools/source/datetime/makefile.mk
new file mode 100644
index 000000000000..3d46cc6ce1b0
--- /dev/null
+++ b/tools/source/datetime/makefile.mk
@@ -0,0 +1,50 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=tools
+TARGET=datetime
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/tdate.obj \
+ $(SLO)$/ttime.obj \
+ $(SLO)$/datetime.obj
+
+OBJFILES= $(OBJ)$/tdate.obj \
+ $(OBJ)$/ttime.obj \
+ $(OBJ)$/datetime.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/tools/source/datetime/tdate.cxx b/tools/source/datetime/tdate.cxx
new file mode 100644
index 000000000000..2dcff7d30bd4
--- /dev/null
+++ b/tools/source/datetime/tdate.cxx
@@ -0,0 +1,497 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#if defined( OS2 )
+#define INCL_DOSDATETIME
+#include <svpm.h>
+#elif defined( WNT )
+#ifdef _MSC_VER
+#pragma warning (push,1)
+#endif
+#include <tools/svwin.h>
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+#else
+#include <time.h>
+#endif
+
+#include <tools/debug.hxx>
+#include <tools/date.hxx>
+#ifdef MACOSX
+extern "C" {
+struct tm *localtime_r(const time_t *timep, struct tm *buffer);
+}
+#endif
+
+// =======================================================================
+
+static USHORT aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30,
+ 31, 31, 30, 31, 30, 31 };
+
+#define MAX_DAYS 3636532
+
+// =======================================================================
+
+inline BOOL ImpIsLeapYear( USHORT nYear )
+{
+ return (
+ ( ((nYear % 4) == 0) && ((nYear % 100) != 0) ) ||
+ ( (nYear % 400) == 0 )
+ );
+}
+
+// -----------------------------------------------------------------------
+
+inline USHORT DaysInMonth( USHORT nMonth, USHORT nYear )
+{
+ if ( nMonth != 2 )
+ return aDaysInMonth[nMonth-1];
+ else
+ {
+ if (ImpIsLeapYear(nYear))
+ return aDaysInMonth[nMonth-1] + 1;
+ else
+ return aDaysInMonth[nMonth-1];
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long Date::DateToDays( USHORT nDay, USHORT nMonth, USHORT nYear )
+{
+ long nDays;
+
+ nDays = ((ULONG)nYear-1) * 365;
+ nDays += ((nYear-1) / 4) - ((nYear-1) / 100) + ((nYear-1) / 400);
+ for( USHORT i = 1; i < nMonth; i++ )
+ nDays += DaysInMonth(i,nYear);
+ nDays += nDay;
+ return nDays;
+}
+
+// -----------------------------------------------------------------------
+
+static void DaysToDate( long nDays,
+ USHORT& rDay, USHORT& rMonth, USHORT& rYear )
+{
+ long nTempDays;
+ long i = 0;
+ BOOL bCalc;
+
+ do
+ {
+ nTempDays = (long)nDays;
+ rYear = (USHORT)((nTempDays / 365) - i);
+ nTempDays -= ((ULONG)rYear-1) * 365;
+ nTempDays -= ((rYear-1) / 4) - ((rYear-1) / 100) + ((rYear-1) / 400);
+ bCalc = FALSE;
+ if ( nTempDays < 1 )
+ {
+ i++;
+ bCalc = TRUE;
+ }
+ else
+ {
+ if ( nTempDays > 365 )
+ {
+ if ( (nTempDays != 366) || !ImpIsLeapYear( rYear ) )
+ {
+ i--;
+ bCalc = TRUE;
+ }
+ }
+ }
+ }
+ while ( bCalc );
+
+ rMonth = 1;
+ while ( (ULONG)nTempDays > DaysInMonth( rMonth, rYear ) )
+ {
+ nTempDays -= DaysInMonth( rMonth, rYear );
+ rMonth++;
+ }
+ rDay = (USHORT)nTempDays;
+}
+
+// =======================================================================
+
+Date::Date()
+{
+#if defined( OS2 )
+ DATETIME aDateTime;
+ DosGetDateTime( &aDateTime );
+
+ // Datum zusammenbauen
+ nDate = ((ULONG)aDateTime.day) +
+ (((ULONG)aDateTime.month)*100) +
+ (((ULONG)aDateTime.year)*10000);
+#elif defined WNT
+ SYSTEMTIME aDateTime;
+ GetLocalTime( &aDateTime );
+
+ // Datum zusammenbauen
+ nDate = ((ULONG)aDateTime.wDay) +
+ (((ULONG)aDateTime.wMonth)*100) +
+ (((ULONG)aDateTime.wYear)*10000);
+#else
+ time_t nTmpTime;
+ struct tm aTime;
+
+ // Zeit ermitteln
+ nTmpTime = time( 0 );
+
+ // Datum zusammenbauen
+ if ( localtime_r( &nTmpTime, &aTime ) )
+ {
+ nDate = ((ULONG)aTime.tm_mday) +
+ (((ULONG)(aTime.tm_mon+1))*100) +
+ (((ULONG)(aTime.tm_year+1900))*10000);
+ }
+ else
+ nDate = 1 + 100 + (((ULONG)1900)*10000);
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Date::SetDay( USHORT nNewDay )
+{
+ ULONG nMonth = GetMonth();
+ ULONG nYear = GetYear();
+
+ nDate = ((ULONG)(nNewDay%100)) + (nMonth*100) + (nYear*10000);
+}
+
+// -----------------------------------------------------------------------
+
+void Date::SetMonth( USHORT nNewMonth )
+{
+ ULONG nDay = GetDay();
+ ULONG nYear = GetYear();
+
+ nDate = nDay + (((ULONG)(nNewMonth%100))*100) + (nYear*10000);
+}
+
+// -----------------------------------------------------------------------
+
+void Date::SetYear( USHORT nNewYear )
+{
+ ULONG nDay = GetDay();
+ ULONG nMonth = GetMonth();
+
+ nDate = nDay + (nMonth*100) + (((ULONG)(nNewYear%10000))*10000);
+}
+
+// -----------------------------------------------------------------------
+
+DayOfWeek Date::GetDayOfWeek() const
+{
+ return (DayOfWeek)((ULONG)(DateToDays( GetDay(), GetMonth(), GetYear() )-1) % 7);
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Date::GetDayOfYear() const
+{
+ USHORT nDay = GetDay();
+ for( USHORT i = 1; i < GetMonth(); i++ )
+ nDay = nDay + ::DaysInMonth( i, GetYear() ); // += yields a warning on MSVC, so don't use it
+ return nDay;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Date::GetWeekOfYear( DayOfWeek eStartDay,
+ sal_Int16 nMinimumNumberOfDaysInWeek ) const
+{
+ short nWeek;
+ short n1WDay = (short)Date( 1, 1, GetYear() ).GetDayOfWeek();
+ short nDayOfYear = (short)GetDayOfYear();
+
+ // Wochentage beginnen bei 0, deshalb einen abziehen
+ nDayOfYear--;
+ // StartDay beruecksichtigen
+ n1WDay = (n1WDay+(7-(short)eStartDay)) % 7;
+
+ if (nMinimumNumberOfDaysInWeek < 1 || 7 < nMinimumNumberOfDaysInWeek)
+ {
+ DBG_ERRORFILE("Date::GetWeekOfYear: invalid nMinimumNumberOfDaysInWeek");
+ nMinimumNumberOfDaysInWeek = 4;
+ }
+
+ if ( nMinimumNumberOfDaysInWeek == 1 )
+ {
+ nWeek = ((n1WDay+nDayOfYear)/7) + 1;
+ // 53te-Woche nur dann, wenn wir nicht schon in der ersten
+ // Woche des neuen Jahres liegen
+ if ( nWeek == 54 )
+ nWeek = 1;
+ else if ( nWeek == 53 )
+ {
+ short nDaysInYear = (short)GetDaysInYear();
+ short nDaysNextYear = (short)Date( 1, 1, GetYear()+1 ).GetDayOfWeek();
+ nDaysNextYear = (nDaysNextYear+(7-(short)eStartDay)) % 7;
+ if ( nDayOfYear > (nDaysInYear-nDaysNextYear-1) )
+ nWeek = 1;
+ }
+ }
+ else if ( nMinimumNumberOfDaysInWeek == 7 )
+ {
+ nWeek = ((n1WDay+nDayOfYear)/7);
+ // Erste Woche eines Jahres entspricht der letzen Woche des
+ // vorherigen Jahres
+ if ( nWeek == 0 )
+ {
+ Date aLastDatePrevYear( 31, 12, GetYear()-1 );
+ nWeek = aLastDatePrevYear.GetWeekOfYear( eStartDay, nMinimumNumberOfDaysInWeek );
+ }
+ }
+ else // ( nMinimumNumberOfDaysInWeek == somehing_else, commentary examples for 4 )
+ {
+ // x_monday - thursday
+ if ( n1WDay < nMinimumNumberOfDaysInWeek )
+ nWeek = 1;
+ // friday
+ else if ( n1WDay == nMinimumNumberOfDaysInWeek )
+ nWeek = 53;
+ // saturday
+ else if ( n1WDay == nMinimumNumberOfDaysInWeek + 1 )
+ {
+ // Jahr nach Schaltjahr
+ if ( Date( 1, 1, GetYear()-1 ).IsLeapYear() )
+ nWeek = 53;
+ else
+ nWeek = 52;
+ }
+ // sunday
+ else
+ nWeek = 52;
+
+ if ( (nWeek == 1) || (nDayOfYear + n1WDay > 6) )
+ {
+ if ( nWeek == 1 )
+ nWeek += (nDayOfYear + n1WDay) / 7;
+ else
+ nWeek = (nDayOfYear + n1WDay) / 7;
+ if ( nWeek == 53 )
+ {
+ // naechster x_Sonntag == erster x_Sonntag im neuen Jahr
+ // == noch gleiche Woche
+ long nTempDays = DateToDays( GetDay(), GetMonth(), GetYear() );
+ nTempDays += 6 - (GetDayOfWeek()+(7-(short)eStartDay)) % 7;
+ USHORT nDay;
+ USHORT nMonth;
+ USHORT nYear;
+ DaysToDate( nTempDays, nDay, nMonth, nYear );
+ nWeek = Date( nDay, nMonth, nYear ).GetWeekOfYear( eStartDay, nMinimumNumberOfDaysInWeek );
+ }
+ }
+ }
+
+ return (USHORT)nWeek;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Date::GetDaysInMonth() const
+{
+ return DaysInMonth( GetMonth(), GetYear() );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Date::IsLeapYear() const
+{
+ USHORT nYear = GetYear();
+ return ImpIsLeapYear( nYear );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Date::IsValid() const
+{
+ USHORT nDay = GetDay();
+ USHORT nMonth = GetMonth();
+ USHORT nYear = GetYear();
+
+ if ( !nMonth || (nMonth > 12) )
+ return FALSE;
+ if ( !nDay || (nDay > DaysInMonth( nMonth, nYear )) )
+ return FALSE;
+ else if ( nYear <= 1582 )
+ {
+ if ( nYear < 1582 )
+ return FALSE;
+ else if ( nMonth < 10 )
+ return FALSE;
+ else if ( (nMonth == 10) && (nDay < 15) )
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+Date& Date::operator +=( long nDays )
+{
+ USHORT nDay;
+ USHORT nMonth;
+ USHORT nYear;
+ long nTempDays = DateToDays( GetDay(), GetMonth(), GetYear() );
+
+ nTempDays += nDays;
+ if ( nTempDays > MAX_DAYS )
+ nDate = 31 + (12*100) + (((ULONG)9999)*10000);
+ else if ( nTempDays <= 0 )
+ nDate = 1 + 100;
+ else
+ {
+ DaysToDate( nTempDays, nDay, nMonth, nYear );
+ nDate = ((ULONG)nDay) + (((ULONG)nMonth)*100) + (((ULONG)nYear)*10000);
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+Date& Date::operator -=( long nDays )
+{
+ USHORT nDay;
+ USHORT nMonth;
+ USHORT nYear;
+ long nTempDays = DateToDays( GetDay(), GetMonth(), GetYear() );
+
+ nTempDays -= nDays;
+ if ( nTempDays > MAX_DAYS )
+ nDate = 31 + (12*100) + (((ULONG)9999)*10000);
+ else if ( nTempDays <= 0 )
+ nDate = 1 + 100;
+ else
+ {
+ DaysToDate( nTempDays, nDay, nMonth, nYear );
+ nDate = ((ULONG)nDay) + (((ULONG)nMonth)*100) + (((ULONG)nYear)*10000);
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+Date& Date::operator ++()
+{
+ USHORT nDay;
+ USHORT nMonth;
+ USHORT nYear;
+ long nTempDays = DateToDays( GetDay(), GetMonth(), GetYear() );
+
+ if ( nTempDays < MAX_DAYS )
+ {
+ nTempDays++;
+ DaysToDate( nTempDays, nDay, nMonth, nYear );
+ nDate = ((ULONG)nDay) + (((ULONG)nMonth)*100) + (((ULONG)nYear)*10000);
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+Date& Date::operator --()
+{
+ USHORT nDay;
+ USHORT nMonth;
+ USHORT nYear;
+ long nTempDays = DateToDays( GetDay(), GetMonth(), GetYear() );
+
+ if ( nTempDays > 1 )
+ {
+ nTempDays--;
+ DaysToDate( nTempDays, nDay, nMonth, nYear );
+ nDate = ((ULONG)nDay) + (((ULONG)nMonth)*100) + (((ULONG)nYear)*10000);
+ }
+ return *this;
+}
+
+#ifndef MPW33
+
+// -----------------------------------------------------------------------
+
+Date Date::operator ++( int )
+{
+ Date aOldDate = *this;
+ Date::operator++();
+ return aOldDate;
+}
+
+// -----------------------------------------------------------------------
+
+Date Date::operator --( int )
+{
+ Date aOldDate = *this;
+ Date::operator--();
+ return aOldDate;
+}
+
+#endif
+
+// -----------------------------------------------------------------------
+
+Date operator +( const Date& rDate, long nDays )
+{
+ Date aDate( rDate );
+ aDate += nDays;
+ return aDate;
+}
+
+// -----------------------------------------------------------------------
+
+Date operator -( const Date& rDate, long nDays )
+{
+ Date aDate( rDate );
+ aDate -= nDays;
+ return aDate;
+}
+
+// -----------------------------------------------------------------------
+
+long operator -( const Date& rDate1, const Date& rDate2 )
+{
+ ULONG nTempDays1 = Date::DateToDays( rDate1.GetDay(), rDate1.GetMonth(),
+ rDate1.GetYear() );
+ ULONG nTempDays2 = Date::DateToDays( rDate2.GetDay(), rDate2.GetMonth(),
+ rDate2.GetYear() );
+ return nTempDays1 - nTempDays2;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/datetime/ttime.cxx b/tools/source/datetime/ttime.cxx
new file mode 100644
index 000000000000..5a5cb33d08bb
--- /dev/null
+++ b/tools/source/datetime/ttime.cxx
@@ -0,0 +1,448 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#define _TOOLS_TIME_CXX
+
+#if defined( OS2 )
+#define INCL_DOSMISC
+#define INCL_DOSDATETIME
+#include <svpm.h>
+#elif defined( WNT )
+#ifdef _MSC_VER
+#pragma warning (push,1)
+#endif
+#include <tools/svwin.h>
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+#elif defined UNX
+#include <unistd.h>
+#include <limits.h>
+#include <math.h>
+#include <sys/time.h>
+#endif
+
+#include <time.h>
+#include <tools/time.hxx>
+
+#if defined(SOLARIS) && defined(__GNUC__)
+extern long altzone;
+#endif
+
+// =======================================================================
+
+static sal_Int32 TimeToSec100( const Time& rTime )
+{
+ short nSign = (rTime.GetTime() >= 0) ? +1 : -1;
+ sal_Int32 nHour = rTime.GetHour();
+ sal_Int32 nMin = rTime.GetMin();
+ sal_Int32 nSec = rTime.GetSec();
+ sal_Int32 n100Sec = rTime.Get100Sec();
+
+// Wegen Interal Compiler Error bei MSC, etwas komplizierter
+// return (n100Sec + (nSec*100) + (nMin*60*100) + (nHour*60*60*100) * nSign);
+
+ sal_Int32 nRet = n100Sec;
+ nRet += nSec*100;
+ nRet += nMin*60*100;
+ nRet += nHour*60*60*100;
+
+ return (nRet * nSign);
+}
+
+// -----------------------------------------------------------------------
+
+static Time Sec100ToTime( sal_Int32 nSec100 )
+{
+ short nSign;
+ if ( nSec100 < 0 )
+ {
+ nSec100 *= -1;
+ nSign = -1;
+ }
+ else
+ nSign = 1;
+
+ Time aTime( 0, 0, 0, nSec100 );
+ aTime.SetTime( aTime.GetTime() * nSign );
+ return aTime;
+}
+
+// =======================================================================
+
+Time::Time()
+{
+#if defined( OS2 )
+ DATETIME aDateTime;
+ DosGetDateTime( &aDateTime );
+
+ // Zeit zusammenbauen
+ nTime = (((sal_Int32)aDateTime.hours)*1000000) +
+ (((sal_Int32)aDateTime.minutes)*10000) +
+ (((sal_Int32)aDateTime.seconds)*100) +
+ ((sal_Int32)aDateTime.hundredths);
+#elif defined( WNT )
+ SYSTEMTIME aDateTime;
+ GetLocalTime( &aDateTime );
+
+ // Zeit zusammenbauen
+ nTime = (((sal_Int32)aDateTime.wHour)*1000000) +
+ (((sal_Int32)aDateTime.wMinute)*10000) +
+ (((sal_Int32)aDateTime.wSecond)*100) +
+ ((sal_Int32)aDateTime.wMilliseconds/10);
+#else
+ time_t nTmpTime;
+ struct tm aTime;
+
+ // Zeit ermitteln
+ nTmpTime = time( 0 );
+
+ // Zeit zusammenbauen
+ if ( localtime_r( &nTmpTime, &aTime ) )
+ {
+ nTime = (((sal_Int32)aTime.tm_hour)*1000000) +
+ (((sal_Int32)aTime.tm_min)*10000) +
+ (((sal_Int32)aTime.tm_sec)*100);
+ }
+ else
+ nTime = 0;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+Time::Time( const Time& rTime )
+{
+ nTime = rTime.nTime;
+}
+
+// -----------------------------------------------------------------------
+
+Time::Time( ULONG nHour, ULONG nMin, ULONG nSec, ULONG n100Sec )
+{
+ // Zeit normalisieren
+ nSec += n100Sec / 100;
+ n100Sec = n100Sec % 100;
+ nMin += nSec / 60;
+ nSec = nSec % 60;
+ nHour += nMin / 60;
+ nMin = nMin % 60;
+
+ // Zeit zusammenbauen
+ nTime = (sal_Int32)(n100Sec + (nSec*100) + (nMin*10000) + (nHour*1000000));
+}
+
+// -----------------------------------------------------------------------
+
+void Time::SetHour( USHORT nNewHour )
+{
+ short nSign = (nTime >= 0) ? +1 : -1;
+ sal_Int32 nMin = GetMin();
+ sal_Int32 nSec = GetSec();
+ sal_Int32 n100Sec = Get100Sec();
+
+ nTime = (n100Sec + (nSec*100) + (nMin*10000) +
+ (((sal_Int32)nNewHour)*1000000)) * nSign;
+}
+
+// -----------------------------------------------------------------------
+
+void Time::SetMin( USHORT nNewMin )
+{
+ short nSign = (nTime >= 0) ? +1 : -1;
+ sal_Int32 nHour = GetHour();
+ sal_Int32 nSec = GetSec();
+ sal_Int32 n100Sec = Get100Sec();
+
+ // kein Ueberlauf
+ nNewMin = nNewMin % 60;
+
+ nTime = (n100Sec + (nSec*100) + (((sal_Int32)nNewMin)*10000) +
+ (nHour*1000000)) * nSign;
+}
+
+// -----------------------------------------------------------------------
+
+void Time::SetSec( USHORT nNewSec )
+{
+ short nSign = (nTime >= 0) ? +1 : -1;
+ sal_Int32 nHour = GetHour();
+ sal_Int32 nMin = GetMin();
+ sal_Int32 n100Sec = Get100Sec();
+
+ // kein Ueberlauf
+ nNewSec = nNewSec % 60;
+
+ nTime = (n100Sec + (((sal_Int32)nNewSec)*100) + (nMin*10000) +
+ (nHour*1000000)) * nSign;
+}
+
+// -----------------------------------------------------------------------
+
+void Time::Set100Sec( USHORT nNew100Sec )
+{
+ short nSign = (nTime >= 0) ? +1 : -1;
+ sal_Int32 nHour = GetHour();
+ sal_Int32 nMin = GetMin();
+ sal_Int32 nSec = GetSec();
+
+ // kein Ueberlauf
+ nNew100Sec = nNew100Sec % 100;
+
+ nTime = (((sal_Int32)nNew100Sec) + (nSec*100) + (nMin*10000) +
+ (nHour*1000000)) * nSign;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int32 Time::GetMSFromTime() const
+{
+ short nSign = (nTime >= 0) ? +1 : -1;
+ sal_Int32 nHour = GetHour();
+ sal_Int32 nMin = GetMin();
+ sal_Int32 nSec = GetSec();
+ sal_Int32 n100Sec = Get100Sec();
+
+ return (((nHour*3600000)+(nMin*60000)+(nSec*1000)+(n100Sec*10))*nSign);
+}
+
+// -----------------------------------------------------------------------
+
+void Time::MakeTimeFromMS( sal_Int32 nMS )
+{
+ short nSign;
+ if ( nMS < 0 )
+ {
+ nMS *= -1;
+ nSign = -1;
+ }
+ else
+ nSign = 1;
+
+ Time aTime( 0, 0, 0, nMS/10 );
+ SetTime( aTime.GetTime() * nSign );
+}
+
+// -----------------------------------------------------------------------
+
+double Time::GetTimeInDays() const
+{
+ short nSign = (nTime >= 0) ? +1 : -1;
+ double nHour = GetHour();
+ double nMin = GetMin();
+ double nSec = GetSec();
+ double n100Sec = Get100Sec();
+
+ return (nHour+(nMin/60)+(nSec/(60*60))+(n100Sec/(60*60*100))) / 24 * nSign;
+}
+
+// -----------------------------------------------------------------------
+
+Time& Time::operator =( const Time& rTime )
+{
+ nTime = rTime.nTime;
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+Time& Time::operator +=( const Time& rTime )
+{
+ nTime = Sec100ToTime( TimeToSec100( *this ) +
+ TimeToSec100( rTime ) ).GetTime();
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+Time& Time::operator -=( const Time& rTime )
+{
+ nTime = Sec100ToTime( TimeToSec100( *this ) -
+ TimeToSec100( rTime ) ).GetTime();
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+Time operator +( const Time& rTime1, const Time& rTime2 )
+{
+ return Sec100ToTime( TimeToSec100( rTime1 ) +
+ TimeToSec100( rTime2 ) );
+}
+
+// -----------------------------------------------------------------------
+
+Time operator -( const Time& rTime1, const Time& rTime2 )
+{
+ return Sec100ToTime( TimeToSec100( rTime1 ) -
+ TimeToSec100( rTime2 ) );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Time::IsEqualIgnore100Sec( const Time& rTime ) const
+{
+ sal_Int32 n1 = (nTime < 0 ? -Get100Sec() : Get100Sec() );
+ sal_Int32 n2 = (rTime.nTime < 0 ? -rTime.Get100Sec() : rTime.Get100Sec() );
+ return (nTime - n1) == (rTime.nTime - n2);
+}
+
+// -----------------------------------------------------------------------
+
+Time Time::GetUTCOffset()
+{
+#if defined( OS2 )
+#undef timezone
+ DATETIME aDateTime;
+ DosGetDateTime( &aDateTime );
+
+ // Zeit zusammenbauen
+ if ( aDateTime.timezone != -1 )
+ {
+ short nTempTime = (short)Abs( aDateTime.timezone );
+ Time aTime( 0, (USHORT)nTempTime );
+ if ( aDateTime.timezone > 0 )
+ aTime = -aTime;
+ return aTime;
+ }
+ else
+ return Time( 0 );
+#elif defined( WNT )
+ TIME_ZONE_INFORMATION aTimeZone;
+ aTimeZone.Bias = 0;
+ DWORD nTimeZoneRet = GetTimeZoneInformation( &aTimeZone );
+ sal_Int32 nTempTime = aTimeZone.Bias;
+ if ( nTimeZoneRet == TIME_ZONE_ID_STANDARD )
+ nTempTime += aTimeZone.StandardBias;
+ else if ( nTimeZoneRet == TIME_ZONE_ID_DAYLIGHT )
+ nTempTime += aTimeZone.DaylightBias;
+ Time aTime( 0, (USHORT)Abs( nTempTime ) );
+ if ( nTempTime > 0 )
+ aTime = -aTime;
+ return aTime;
+#else
+ static ULONG nCacheTicks = 0;
+ static sal_Int32 nCacheSecOffset = -1;
+ ULONG nTicks = Time::GetSystemTicks();
+ time_t nTime;
+ tm aTM;
+ sal_Int32 nLocalTime;
+ sal_Int32 nUTC;
+ short nTempTime;
+
+ // Evt. Wert neu ermitteln
+ if ( (nCacheSecOffset == -1) ||
+ ((nTicks - nCacheTicks) > 360000) ||
+ ( nTicks < nCacheTicks ) // handle overflow
+ )
+ {
+ nTime = time( 0 );
+ localtime_r( &nTime, &aTM );
+ nLocalTime = mktime( &aTM );
+#if defined( SOLARIS )
+ // Solaris gmtime_r() seems not to handle daylight saving time
+ // flags correctly
+ nUTC = nLocalTime + ( aTM.tm_isdst == 0 ? timezone : altzone );
+#elif defined( LINUX )
+ // Linux mktime() seems not to handle tm_isdst correctly
+ nUTC = nLocalTime - aTM.tm_gmtoff;
+#else
+ gmtime_r( &nTime, &aTM );
+ nUTC = mktime( &aTM );
+#endif
+ nCacheTicks = nTicks;
+ nCacheSecOffset = (nLocalTime-nUTC) / 60;
+ }
+
+ nTempTime = (short)Abs( nCacheSecOffset );
+ Time aTime( 0, (USHORT)nTempTime );
+ if ( nCacheSecOffset < 0 )
+ aTime = -aTime;
+ return aTime;
+#endif
+}
+
+
+// -----------------------------------------------------------------------
+
+ULONG Time::GetSystemTicks()
+{
+#if defined WNT
+ return (ULONG)GetTickCount();
+#elif defined( OS2 )
+ ULONG nClock;
+ DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &nClock, sizeof( nClock ) );
+ return (ULONG)nClock;
+#else
+ timeval tv;
+ gettimeofday (&tv, 0);
+
+ double fTicks = tv.tv_sec;
+ fTicks *= 1000;
+ fTicks += ((tv.tv_usec + 500) / 1000);
+
+ fTicks = fmod (fTicks, double(ULONG_MAX));
+ return ULONG(fTicks);
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Time::GetProcessTicks()
+{
+#if defined WNT
+ return (ULONG)GetTickCount();
+#elif defined( OS2 )
+ ULONG nClock;
+ DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &nClock, sizeof( nClock ) );
+ return (ULONG)nClock;
+#else
+ static ULONG nImplTicksPerSecond = 0;
+ static double dImplTicksPerSecond;
+ static double dImplTicksULONGMAX;
+ ULONG nTicks = (ULONG)clock();
+
+ if ( !nImplTicksPerSecond )
+ {
+ nImplTicksPerSecond = CLOCKS_PER_SEC;
+ dImplTicksPerSecond = nImplTicksPerSecond;
+ dImplTicksULONGMAX = (double)(ULONG)ULONG_MAX;
+ }
+
+ double fTicks = nTicks;
+ fTicks *= 1000;
+ fTicks /= dImplTicksPerSecond;
+ fTicks = fmod (fTicks, dImplTicksULONGMAX);
+ return (ULONG)fTicks;
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/debug/debug.cxx b/tools/source/debug/debug.cxx
new file mode 100644
index 000000000000..c8234b4973d6
--- /dev/null
+++ b/tools/source/debug/debug.cxx
@@ -0,0 +1,1816 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#define _TOOLS_DEBUG_CXX
+
+#if defined (UNX) || defined (GCC)
+#include <unistd.h>
+#else
+#include <direct.h>
+#endif
+
+#include <time.h>
+#include <cstdarg> // combinations
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifdef OS2
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSMISC
+#define INCL_WINDIALOGS
+#define INCL_WINSHELLDATA
+#include <svpm.h>
+#endif
+
+#if defined ( WNT )
+#ifdef _MSC_VER
+#pragma warning (push,1)
+#endif
+#include <tools/svwin.h>
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+#endif
+
+#include <tools/debug.hxx>
+#include <rtl/string.h>
+#include <sal/macros.h>
+
+#include <vector>
+
+#include <osl/diagnose.h>
+
+// =======================================================================
+
+#ifdef DBG_UTIL
+
+// --- DbgErrors ---
+
+static sal_Char const DbgError_ProfEnd1[] = "DBG_PROF...() without DBG_PROFSTART(): ";
+static sal_Char const DbgError_Xtor1[] = "DBG_DTOR() or DBG_CHKTHIS() without DBG_CTOR(): ";
+
+static sal_Char const DbgError_CtorDtor1[] = "this == NULL in class ";
+static sal_Char const DbgError_CtorDtor2[] = "invalid this-Pointer %p in class ";
+static sal_Char const DbgError_CtorDtor3[] = "Error-Msg from Object %p in class ";
+
+static sal_Char const DbgTrace_EnterCtor[] = "Enter Ctor from class ";
+static sal_Char const DbgTrace_LeaveCtor[] = "Leave Ctor from class ";
+static sal_Char const DbgTrace_EnterDtor[] = "Enter Dtor from class ";
+static sal_Char const DbgTrace_LeaveDtor[] = "Leave Dtor from class ";
+static sal_Char const DbgTrace_EnterMeth[] = "Enter method from class ";
+static sal_Char const DbgTrace_LeaveMeth[] = "Leave method from class ";
+
+// --- PointerList ---
+
+#define PBLOCKCOUNT 1024
+
+struct PBlock
+{
+ void* aData[PBLOCKCOUNT];
+ USHORT nCount;
+ PBlock* pPrev;
+ PBlock* pNext;
+};
+
+class PointerList
+{
+private:
+ PBlock* pFirst;
+ PBlock* pLast;
+ ULONG nCount;
+
+public:
+ PointerList() { pFirst = NULL; pLast = NULL; nCount = 0; }
+ ~PointerList();
+
+ void Add( const void* p );
+ BOOL Remove( const void* p );
+
+ const void* Get( ULONG nPos ) const;
+ BOOL IsIn( const void* p ) const;
+ ULONG Count() const { return nCount; }
+};
+
+// --- Datentypen ---
+
+#define DBG_MAXNAME 28
+
+struct ProfType
+{
+ ULONG nCount;
+ ULONG nTime;
+ ULONG nMinTime;
+ ULONG nMaxTime;
+ ULONG nStart;
+ ULONG nContinueTime;
+ ULONG nContinueStart;
+ sal_Char aName[DBG_MAXNAME+1];
+};
+
+struct XtorType
+{
+ ULONG nCtorCalls;
+ ULONG nDtorCalls;
+ ULONG nMaxCount;
+ ULONG nStatics;
+ sal_Char aName[DBG_MAXNAME+1];
+ BOOL bTest;
+ PointerList aThisList;
+};
+
+struct DebugData
+{
+ DbgData aDbgData;
+ USHORT bInit;
+ DbgPrintLine pDbgPrintMsgBox;
+ DbgPrintLine pDbgPrintWindow;
+ DbgPrintLine pDbgPrintTestTool;
+ ::std::vector< DbgPrintLine >
+ aDbgPrintUserChannels;
+ PointerList* pProfList;
+ PointerList* pXtorList;
+ DbgTestSolarMutexProc pDbgTestSolarMutex;
+ pfunc_osl_printDetailedDebugMessage
+ pOldDebugMessageFunc;
+ bool bOslIsHooked;
+
+ DebugData()
+ :bInit( FALSE )
+ ,pDbgPrintMsgBox( FALSE )
+ ,pDbgPrintWindow( NULL )
+ ,pDbgPrintTestTool( NULL )
+ ,pProfList( NULL )
+ ,pXtorList( NULL )
+ ,pDbgTestSolarMutex( NULL )
+ ,pOldDebugMessageFunc( NULL )
+ ,bOslIsHooked( false )
+ {
+ aDbgData.nTestFlags = DBG_TEST_RESOURCE | DBG_TEST_MEM_INIT;
+ aDbgData.bOverwrite = TRUE;
+ aDbgData.nTraceOut = DBG_OUT_NULL;
+ aDbgData.nWarningOut = DBG_OUT_NULL;
+#ifdef UNX
+ aDbgData.nErrorOut = DBG_OUT_SHELL;
+#else
+ aDbgData.nErrorOut = DBG_OUT_MSGBOX;
+#endif
+ aDbgData.bMemInit = 0x77;
+ aDbgData.bMemBound = 0x55;
+ aDbgData.bMemFree = 0x33;
+ aDbgData.bHookOSLAssert = TRUE;
+ aDbgData.aDebugName[0] = 0;
+ aDbgData.aInclFilter[0] = 0;
+ aDbgData.aExclFilter[0] = 0;
+ aDbgData.aInclClassFilter[0] = 0;
+ aDbgData.aExclClassFilter[0] = 0;
+ aDbgData.aDbgWinState[0] = 0;
+ }
+};
+
+#define DBG_TEST_XTOR_EXTRA (DBG_TEST_XTOR_THIS | DBG_TEST_XTOR_FUNC | \
+ DBG_TEST_XTOR_EXIT | DBG_TEST_XTOR_REPORT )
+
+// ------------------------------
+// - statische Verwaltungsdaten -
+// ------------------------------
+
+static DebugData aDebugData;
+
+static sal_Char aCurPath[260];
+
+static int bDbgImplInMain = FALSE;
+
+// =======================================================================
+
+#if defined( WNT )
+static CRITICAL_SECTION aImplCritDbgSection;
+#elif defined( OS2 )
+static HMTX hImplCritDbgSection = 0;
+#endif
+static BOOL bImplCritDbgSectionInit = FALSE;
+
+// -----------------------------------------------------------------------
+
+void ImplDbgInitLock()
+{
+#if defined( WNT )
+ InitializeCriticalSection( &aImplCritDbgSection );
+#elif defined( OS2 )
+ DosCreateMutexSem( NULL, &hImplCritDbgSection, 0, FALSE );
+#endif
+ bImplCritDbgSectionInit = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDbgDeInitLock()
+{
+#if defined( WNT )
+ DeleteCriticalSection( &aImplCritDbgSection );
+#elif defined( OS2 )
+ DosCloseMutexSem( hImplCritDbgSection );
+#endif
+ bImplCritDbgSectionInit = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDbgLock()
+{
+ if ( !bImplCritDbgSectionInit )
+ return;
+
+#if defined( WNT )
+ EnterCriticalSection( &aImplCritDbgSection );
+#elif defined( OS2 )
+ DosRequestMutexSem( hImplCritDbgSection, SEM_INDEFINITE_WAIT );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDbgUnlock()
+{
+ if ( !bImplCritDbgSectionInit )
+ return;
+
+#if defined( WNT )
+ LeaveCriticalSection( &aImplCritDbgSection );
+#elif defined( OS2 )
+ DosReleaseMutexSem( hImplCritDbgSection );
+#endif
+}
+
+// =======================================================================
+
+#if (defined WNT || defined OS2) && !defined SVX_LIGHT
+//#define SV_MEMMGR //
+#endif
+#ifdef SV_MEMMGR
+void DbgImpCheckMemory( void* p = NULL );
+void DbgImpCheckMemoryDeInit();
+void DbgImpMemoryInfo( sal_Char* pBuf );
+#endif
+
+#define FILE_LINEEND "\n"
+
+// =======================================================================
+
+static BOOL ImplActivateDebugger( const sal_Char* pMsg )
+{
+#if defined( WNT )
+ static sal_Char aImplDbgOutBuf[DBG_BUF_MAXLEN];
+ strcpy( aImplDbgOutBuf, pMsg );
+ strcat( aImplDbgOutBuf, "\r\n" );
+ OutputDebugString( aImplDbgOutBuf );
+ DebugBreak();
+ return TRUE;
+#else
+ (void) pMsg; // avoid warning about unused parameter
+ return FALSE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplCoreDump()
+{
+#if defined( WNT )
+ DebugBreak();
+#else
+ long* pTemp = 0;
+ *pTemp = 0xCCCC;
+#endif
+ return TRUE;
+}
+
+// =======================================================================
+
+static ULONG ImplGetPerfTime()
+{
+#if defined( WNT )
+ return (ULONG)GetTickCount();
+#elif defined( OS2 )
+ ULONG nClock;
+ DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &nClock, sizeof( nClock ) );
+ return (ULONG)nClock;
+#else
+ static ULONG nImplTicksPerSecond = 0;
+ static double dImplTicksPerSecond;
+ ULONG nTicks = (ULONG)clock();
+
+ if ( !nImplTicksPerSecond )
+ {
+ nImplTicksPerSecond = CLOCKS_PER_SEC;
+ dImplTicksPerSecond = nImplTicksPerSecond;
+ }
+
+ double fTicks = nTicks;
+ fTicks *= 1000;
+ fTicks /= dImplTicksPerSecond;
+ return (ULONG)fTicks;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+typedef FILE* FILETYPE;
+#define FileOpen fopen
+#define FileRead fread
+#define FileWrite fwrite
+#define FilePrintF fprintf
+#define FileClose fclose
+
+// =======================================================================
+
+namespace
+{
+ enum ConfigSection
+ {
+ eOutput,
+ eMemory,
+ eGUI,
+ eObjects,
+ eTest,
+
+ eUnknown
+ };
+
+ void lcl_lineFeed( FILETYPE _pFile )
+ {
+ FilePrintF( _pFile, "%s", FILE_LINEEND );
+ }
+
+ const sal_Char* lcl_getSectionName( ConfigSection _eSection )
+ {
+ const sal_Char* pSectionName = NULL;
+ switch ( _eSection )
+ {
+ case eOutput : pSectionName = "output"; break;
+ case eMemory : pSectionName = "memory"; break;
+ case eGUI : pSectionName = "gui"; break;
+ case eObjects : pSectionName = "objects"; break;
+ case eTest : pSectionName = "test"; break;
+ case eUnknown:
+ OSL_ASSERT(false);
+ break;
+ }
+ return pSectionName;
+ }
+
+ ConfigSection lcl_getSectionFromName( const sal_Char* _pSectionName, size_t _nSectionNameLength )
+ {
+ if ( strncmp( _pSectionName, "output", _nSectionNameLength < 6 ? _nSectionNameLength : 6 ) == 0 )
+ return eOutput;
+ if ( strncmp( _pSectionName, "memory", _nSectionNameLength < 6 ? _nSectionNameLength : 6 ) == 0 )
+ return eMemory;
+ if ( strncmp( _pSectionName, "gui", _nSectionNameLength < 3 ? _nSectionNameLength : 3 ) == 0 )
+ return eGUI;
+ if ( strncmp( _pSectionName, "objects", _nSectionNameLength < 7 ? _nSectionNameLength : 7 ) == 0 )
+ return eObjects;
+ if ( strncmp( _pSectionName, "test", _nSectionNameLength < 4 ? _nSectionNameLength : 4 ) == 0 )
+ return eTest;
+ return eUnknown;
+ }
+
+ void lcl_startSection( FILETYPE _pFile, ConfigSection _eSection )
+ {
+ FilePrintF( _pFile, "[%s]%s", lcl_getSectionName( _eSection ), FILE_LINEEND );
+ }
+
+ void lcl_writeConfigString( FILETYPE _pFile, const sal_Char* _pKeyName, const sal_Char* _pValue )
+ {
+ FilePrintF( _pFile, "%s=%s%s", _pKeyName, _pValue, FILE_LINEEND );
+ }
+
+ void lcl_writeConfigBoolean( FILETYPE _pFile, const sal_Char* _pKeyName, bool _bValue )
+ {
+ lcl_writeConfigString( _pFile, _pKeyName, _bValue ? "1" : "0" );
+ }
+
+ void lcl_writeConfigFlag( FILETYPE _pFile, const sal_Char* _pKeyName, ULONG _nAllFlags, ULONG _nCheckFlag )
+ {
+ lcl_writeConfigBoolean( _pFile, _pKeyName, ( _nAllFlags & _nCheckFlag ) != 0 );
+ }
+
+ void lcl_writeConfigOutChannel( FILETYPE _pFile, const sal_Char* _pKeyName, ULONG _nValue )
+ {
+ const sal_Char* names[ DBG_OUT_COUNT ] =
+ {
+ "dev/null", "file", "window", "shell", "messagebox", "testtool", "debugger", "coredump"
+ };
+ lcl_writeConfigString( _pFile, _pKeyName, names[ _nValue ] );
+ }
+ void lcl_writeHexByte( FILETYPE _pFile, const sal_Char* _pKeyName, BYTE _nValue )
+ {
+ sal_Char buf[RTL_STR_MAX_VALUEOFINT32];
+ rtl_String* stringData = NULL;
+ rtl_string_newFromStr_WithLength( &stringData, buf, rtl_str_valueOfInt32( buf, _nValue, 16 ) );
+
+ lcl_writeConfigString( _pFile, _pKeyName, stringData->buffer );
+
+ rtl_string_release( stringData );
+ }
+ bool lcl_isConfigSection( const sal_Char* _pLine, size_t _nLineLen )
+ {
+ if ( _nLineLen < 2 )
+ // not even enough space for '[' and ']'
+ return false;
+ if ( ( _pLine[0] == '[' ) && ( _pLine[ _nLineLen - 1 ] == ']' ) )
+ return true;
+ return false;
+ }
+ bool lcl_isConfigKey( const sal_Char* _pLine, size_t _nLineLen, const sal_Char* _pKeyName )
+ {
+ size_t nKeyLength = strlen( _pKeyName );
+ if ( nKeyLength + 1 >= _nLineLen )
+ // not even long enough for the key name plus "=" plus a one-character value
+ return false;
+ if ( ( strncmp( _pLine, _pKeyName, nKeyLength ) == 0 ) && ( _pLine[ nKeyLength ] == '=' ) )
+ return true;
+ return false;
+ }
+ sal_Int32 lcl_tryReadConfigString( const sal_Char* _pLine, size_t _nLineLen, const sal_Char* _pKeyName, sal_Char* _pValue, size_t _nValueLen )
+ {
+ if ( !lcl_isConfigKey( _pLine, _nLineLen, _pKeyName ) )
+ return 0;
+ size_t nValuePos = strlen( _pKeyName ) + 1;
+ size_t nValueLen = _nLineLen - nValuePos;
+ const sal_Char* pValue = _pLine + nValuePos;
+ strncpy( _pValue, pValue, ( _nValueLen > nValueLen ) ? nValueLen : _nValueLen );
+ _pValue[ ( _nValueLen > nValueLen ) ? nValueLen : _nValueLen - 1 ] = 0;
+ return strlen( _pValue );
+ }
+ void lcl_tryReadConfigBoolean( const sal_Char* _pLine, size_t _nLineLen, const sal_Char* _pKeyName, ULONG* _out_pnValue )
+ {
+ sal_Char aBuf[2];
+ size_t nValueLen = lcl_tryReadConfigString( _pLine, _nLineLen, _pKeyName, aBuf, sizeof( aBuf ) );
+ if ( nValueLen )
+ *_out_pnValue = strcmp( aBuf, "1" ) == 0 ? TRUE : FALSE;
+ }
+ void lcl_tryReadOutputChannel( const sal_Char* _pLine, size_t _nLineLen, const sal_Char* _pKeyName, ULONG* _out_pnValue )
+ {
+ const sal_Char* names[ DBG_OUT_COUNT ] =
+ {
+ "dev/null", "file", "window", "shell", "messagebox", "testtool", "debugger", "coredump"
+ };
+ sal_Char aBuf[20];
+ size_t nValueLen = lcl_tryReadConfigString( _pLine, _nLineLen, _pKeyName, aBuf, sizeof( aBuf ) );
+ if ( nValueLen )
+ {
+ for ( ULONG name = 0; name < SAL_N_ELEMENTS( names ); ++name )
+ {
+ if ( strcmp( aBuf, names[ name ] ) == 0 )
+ {
+ *_out_pnValue = name;
+ return;
+ }
+ }
+ }
+ }
+ void lcl_tryReadConfigFlag( const sal_Char* _pLine, size_t _nLineLen, const sal_Char* _pKeyName, ULONG* _out_pnAllFlags, ULONG _nCheckFlag )
+ {
+ sal_Char aBuf[2];
+ size_t nValueLen = lcl_tryReadConfigString( _pLine, _nLineLen, _pKeyName, aBuf, sizeof( aBuf ) );
+ if ( nValueLen )
+ if ( strcmp( aBuf, "1" ) == 0 )
+ *_out_pnAllFlags |= _nCheckFlag;
+ else
+ *_out_pnAllFlags &= ~_nCheckFlag;
+ }
+ void lcl_tryReadHexByte( const sal_Char* _pLine, size_t _nLineLen, const sal_Char* _pKeyName, BYTE* _out_pnValue )
+ {
+ sal_Char aBuf[3];
+ size_t nValueLen = lcl_tryReadConfigString( _pLine, _nLineLen, _pKeyName, aBuf, sizeof( aBuf ) );
+ if ( nValueLen )
+ *_out_pnValue = (BYTE)rtl_str_toInt32( aBuf, 16 );
+ }
+}
+
+// =======================================================================
+
+PointerList::~PointerList()
+{
+ PBlock* pBlock = pFirst;
+ while ( pBlock )
+ {
+ PBlock* pNextBlock = pBlock->pNext;
+ delete pBlock;
+ pBlock = pNextBlock;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PointerList::Add( const void* p )
+{
+ if ( !pFirst )
+ {
+ pFirst = new PBlock;
+ memset( pFirst->aData, 0, PBLOCKCOUNT * sizeof( void* ) );
+ pFirst->nCount = 0;
+ pFirst->pPrev = NULL;
+ pFirst->pNext = NULL;
+ pLast = pFirst;
+ }
+
+ PBlock* pBlock = pFirst;
+ while ( pBlock && (pBlock->nCount == PBLOCKCOUNT) )
+ pBlock = pBlock->pNext;
+
+ if ( !pBlock )
+ {
+ pBlock = new PBlock;
+ memset( pBlock->aData, 0, PBLOCKCOUNT * sizeof( void* ) );
+ pBlock->nCount = 0;
+ pBlock->pPrev = pLast;
+ pBlock->pNext = NULL;
+ pLast->pNext = pBlock;
+ pLast = pBlock;
+ }
+
+ USHORT i = 0;
+ while ( pBlock->aData[i] )
+ i++;
+
+ pBlock->aData[i] = (void*)p;
+ pBlock->nCount++;
+ nCount++;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL PointerList::Remove( const void* p )
+{
+ if ( !p )
+ return FALSE;
+
+ PBlock* pBlock = pFirst;
+ while ( pBlock )
+ {
+ USHORT i = 0;
+ while ( i < PBLOCKCOUNT )
+ {
+ if ( ((ULONG)p) == ((ULONG)pBlock->aData[i]) )
+ {
+ pBlock->aData[i] = NULL;
+ pBlock->nCount--;
+ nCount--;
+
+ if ( !pBlock->nCount )
+ {
+ if ( pBlock->pPrev )
+ pBlock->pPrev->pNext = pBlock->pNext;
+ if ( pBlock->pNext )
+ pBlock->pNext->pPrev = pBlock->pPrev;
+ if ( pBlock == pFirst )
+ pFirst = pBlock->pNext;
+ if ( pBlock == pLast )
+ pLast = pBlock->pPrev;
+ delete pBlock;
+ }
+
+ return TRUE;
+ }
+ i++;
+ }
+
+ pBlock = pBlock->pNext;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+const void* PointerList::Get( ULONG nPos ) const
+{
+ if ( nCount <= nPos )
+ return NULL;
+
+ PBlock* pBlock = pFirst;
+ ULONG nStart = 0;
+ while ( pBlock )
+ {
+ USHORT i = 0;
+ while ( i < PBLOCKCOUNT )
+ {
+ if ( pBlock->aData[i] )
+ {
+ nStart++;
+ if ( (nStart-1) == nPos )
+ return pBlock->aData[i];
+ }
+
+ i++;
+ }
+
+ pBlock = pBlock->pNext;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL PointerList::IsIn( const void* p ) const
+{
+ if ( !p )
+ return FALSE;
+
+ PBlock* pBlock = pFirst;
+ while ( pBlock )
+ {
+ USHORT i = 0;
+ while ( i < PBLOCKCOUNT )
+ {
+ if ( ((ULONG)p) == ((ULONG)pBlock->aData[i]) )
+ return TRUE;
+ i++;
+ }
+
+ pBlock = pBlock->pNext;
+ }
+
+ return FALSE;
+}
+
+
+// =======================================================================
+
+static void DbgGetDbgFileName( sal_Char* pStr, sal_Int32 nMaxLen )
+{
+#if defined( UNX )
+ const sal_Char* pName = getenv("DBGSV_INIT");
+ if ( !pName )
+ pName = ".dbgsv.init";
+ strncpy( pStr, pName, nMaxLen );
+#elif defined( WNT )
+ const sal_Char* pName = getenv("DBGSV_INIT");
+ if ( pName )
+ strncpy( pStr, pName, nMaxLen );
+ else
+ GetProfileStringA( "sv", "dbgsv", "dbgsv.ini", pStr, nMaxLen );
+#elif defined( OS2 )
+ PrfQueryProfileString( HINI_PROFILE, (PSZ)"SV", (PSZ)"DBGSV",
+ "dbgsv.ini", (PSZ)pStr, nMaxLen );
+#else
+ strncpy( pStr, "dbgsv.ini", nMaxLen );
+#endif
+ pStr[ nMaxLen - 1 ] = 0;
+}
+
+// -----------------------------------------------------------------------
+
+static void DbgGetLogFileName( sal_Char* pStr )
+{
+#if defined( UNX )
+ const sal_Char* pName = getenv("DBGSV_LOG");
+ if ( !pName )
+ pName = "dbgsv.log";
+ strcpy( pStr, pName );
+#elif defined( WNT )
+ const sal_Char* pName = getenv("DBGSV_LOG");
+ if ( pName )
+ strcpy( pStr, pName );
+ else
+ GetProfileStringA( "sv", "dbgsvlog", "dbgsv.log", pStr, 200 );
+#elif defined( OS2 )
+ PrfQueryProfileString( HINI_PROFILE, (PSZ)"SV", (PSZ)"DBGSVLOG",
+ "dbgsv.log", (PSZ)pStr, 200 );
+#else
+ strcpy( pStr, "dbgsv.log" );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static void DbgDebugBeep()
+{
+#if defined( WNT )
+ MessageBeep( MB_ICONHAND );
+#elif defined( OS2 )
+ WinAlarm( HWND_DESKTOP, WA_ERROR );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static DebugData* GetDebugData()
+{
+ if ( !aDebugData.bInit )
+ {
+ aDebugData.bInit = TRUE;
+
+ // Default Debug-Namen setzen
+ DbgGetLogFileName( aDebugData.aDbgData.aDebugName );
+
+ // DEBUG.INI-File
+ sal_Char aBuf[ 4096 ];
+ DbgGetDbgFileName( aBuf, sizeof( aBuf ) );
+ FILETYPE pIniFile = FileOpen( aBuf, "r" );
+ if ( pIniFile != NULL )
+ {
+ ConfigSection eCurrentSection = eUnknown;
+
+ // no sophisticated algorithm here, assume that the whole file fits into aBuf ...
+ ULONG nReallyRead = FileRead( aBuf, 1, sizeof( aBuf ) / sizeof( sal_Char ) - 1, pIniFile );
+ aBuf[ nReallyRead ] = 0;
+ const sal_Char* pLine = aBuf;
+ while ( const sal_Char* pNextLine = strstr( pLine, FILE_LINEEND ) )
+ {
+ size_t nLineLength = pNextLine - pLine;
+
+ if ( lcl_isConfigSection( pLine, nLineLength ) )
+ eCurrentSection = lcl_getSectionFromName( pLine + 1, nLineLength - 2 );
+
+ // elements of the [output] section
+ if ( eCurrentSection == eOutput )
+ {
+ lcl_tryReadConfigString( pLine, nLineLength, "log_file", aDebugData.aDbgData.aDebugName, sizeof( aDebugData.aDbgData.aDebugName ) );
+ lcl_tryReadConfigBoolean( pLine, nLineLength, "overwrite", &aDebugData.aDbgData.bOverwrite );
+ lcl_tryReadConfigString( pLine, nLineLength, "include", aDebugData.aDbgData.aInclFilter, sizeof( aDebugData.aDbgData.aInclFilter ) );
+ lcl_tryReadConfigString( pLine, nLineLength, "exclude", aDebugData.aDbgData.aExclFilter, sizeof( aDebugData.aDbgData.aExclFilter ) );
+ lcl_tryReadConfigString( pLine, nLineLength, "include_class", aDebugData.aDbgData.aInclClassFilter, sizeof( aDebugData.aDbgData.aInclClassFilter ) );
+ lcl_tryReadConfigString( pLine, nLineLength, "exclude_class", aDebugData.aDbgData.aExclClassFilter, sizeof( aDebugData.aDbgData.aExclClassFilter ) );
+ lcl_tryReadOutputChannel( pLine, nLineLength, "trace", &aDebugData.aDbgData.nTraceOut );
+ lcl_tryReadOutputChannel( pLine, nLineLength, "warning", &aDebugData.aDbgData.nWarningOut );
+ lcl_tryReadOutputChannel( pLine, nLineLength, "error", &aDebugData.aDbgData.nErrorOut );
+ lcl_tryReadConfigBoolean( pLine, nLineLength, "oslhook", &aDebugData.aDbgData.bHookOSLAssert );
+ }
+
+ // elements of the [memory] section
+ if ( eCurrentSection == eMemory )
+ {
+ lcl_tryReadConfigFlag( pLine, nLineLength, "initialize", &aDebugData.aDbgData.nTestFlags, DBG_TEST_MEM_INIT );
+ lcl_tryReadConfigFlag( pLine, nLineLength, "overwrite", &aDebugData.aDbgData.nTestFlags, DBG_TEST_MEM_OVERWRITE );
+ lcl_tryReadConfigFlag( pLine, nLineLength, "overwrite_free", &aDebugData.aDbgData.nTestFlags, DBG_TEST_MEM_OVERWRITEFREE );
+ lcl_tryReadConfigFlag( pLine, nLineLength, "pointer", &aDebugData.aDbgData.nTestFlags, DBG_TEST_MEM_POINTER );
+ lcl_tryReadConfigFlag( pLine, nLineLength, "report", &aDebugData.aDbgData.nTestFlags, DBG_TEST_MEM_REPORT );
+ lcl_tryReadConfigFlag( pLine, nLineLength, "trace", &aDebugData.aDbgData.nTestFlags, DBG_TEST_MEM_TRACE );
+ lcl_tryReadConfigFlag( pLine, nLineLength, "new_and_delete", &aDebugData.aDbgData.nTestFlags, DBG_TEST_MEM_NEWDEL );
+ lcl_tryReadConfigFlag( pLine, nLineLength, "object_test", &aDebugData.aDbgData.nTestFlags, DBG_TEST_MEM_XTOR );
+ lcl_tryReadConfigFlag( pLine, nLineLength, "sys_alloc", &aDebugData.aDbgData.nTestFlags, DBG_TEST_MEM_SYSALLOC );
+ lcl_tryReadConfigFlag( pLine, nLineLength, "leak_report", &aDebugData.aDbgData.nTestFlags, DBG_TEST_MEM_LEAKREPORT );
+
+ lcl_tryReadHexByte( pLine, nLineLength, "init_byte", &aDebugData.aDbgData.bMemInit );
+ lcl_tryReadHexByte( pLine, nLineLength, "bound_byte", &aDebugData.aDbgData.bMemBound );
+ lcl_tryReadHexByte( pLine, nLineLength, "free_byte", &aDebugData.aDbgData.bMemFree );
+ }
+
+ // elements of the [gui] section
+ if ( eCurrentSection == eGUI )
+ {
+ lcl_tryReadConfigString( pLine, nLineLength, "debug_window_state", aDebugData.aDbgData.aDbgWinState, sizeof( aDebugData.aDbgData.aDbgWinState ) );
+ }
+
+ // elements of the [objects] section
+ if ( eCurrentSection == eObjects )
+ {
+ lcl_tryReadConfigFlag( pLine, nLineLength, "check_this", &aDebugData.aDbgData.nTestFlags, DBG_TEST_XTOR_THIS );
+ lcl_tryReadConfigFlag( pLine, nLineLength, "check_function", &aDebugData.aDbgData.nTestFlags, DBG_TEST_XTOR_FUNC );
+ lcl_tryReadConfigFlag( pLine, nLineLength, "check_exit", &aDebugData.aDbgData.nTestFlags, DBG_TEST_XTOR_EXIT );
+ lcl_tryReadConfigFlag( pLine, nLineLength, "generate_report", &aDebugData.aDbgData.nTestFlags, DBG_TEST_XTOR_REPORT );
+ lcl_tryReadConfigFlag( pLine, nLineLength, "trace", &aDebugData.aDbgData.nTestFlags, DBG_TEST_XTOR_TRACE );
+ }
+
+ // elements of the [test] section
+ if ( eCurrentSection == eTest )
+ {
+ lcl_tryReadConfigFlag( pLine, nLineLength, "profiling", &aDebugData.aDbgData.nTestFlags, DBG_TEST_PROFILING );
+ lcl_tryReadConfigFlag( pLine, nLineLength, "resources", &aDebugData.aDbgData.nTestFlags, DBG_TEST_RESOURCE );
+ lcl_tryReadConfigFlag( pLine, nLineLength, "dialog", &aDebugData.aDbgData.nTestFlags, DBG_TEST_DIALOG );
+ lcl_tryReadConfigFlag( pLine, nLineLength, "bold_app_font", &aDebugData.aDbgData.nTestFlags, DBG_TEST_BOLDAPPFONT );
+ }
+
+ pLine = pNextLine + strlen( FILE_LINEEND );
+ }
+
+ FileClose( pIniFile );
+ }
+
+ getcwd( aCurPath, sizeof( aCurPath ) );
+
+ // Daten initialisieren
+ if ( aDebugData.aDbgData.nTestFlags & DBG_TEST_XTOR )
+ aDebugData.pXtorList = new PointerList;
+ if ( aDebugData.aDbgData.nTestFlags & DBG_TEST_PROFILING )
+ aDebugData.pProfList = new PointerList;
+ }
+
+ return &aDebugData;
+}
+
+// -----------------------------------------------------------------------
+
+inline DebugData* ImplGetDebugData()
+{
+ if ( !aDebugData.bInit )
+ return GetDebugData();
+ else
+ return &aDebugData;
+}
+
+// -----------------------------------------------------------------------
+
+static FILETYPE ImplDbgInitFile()
+{
+ static BOOL bFileInit = FALSE;
+
+ sal_Char aBuf[4096];
+ getcwd( aBuf, sizeof( aBuf ) );
+ chdir( aCurPath );
+
+ DebugData* pData = GetDebugData();
+ FILETYPE pDebugFile;
+
+ if ( !bFileInit )
+ {
+ bFileInit = TRUE;
+
+ if ( pData->aDbgData.bOverwrite )
+ pDebugFile = FileOpen( pData->aDbgData.aDebugName, "w" );
+ else
+ pDebugFile = FileOpen( pData->aDbgData.aDebugName, "a" );
+
+ if ( pDebugFile )
+ {
+ time_t nTime = time( 0 );
+ tm* pTime;
+#ifdef UNX
+ tm aTime;
+ pTime = localtime_r( &nTime, &aTime );
+#else
+ pTime = localtime( &nTime );
+#endif
+
+ // Header ausgeben
+ FilePrintF( pDebugFile, "******************************************************************************%s", FILE_LINEEND );
+ FilePrintF( pDebugFile, "%s%s", pData->aDbgData.aDebugName, FILE_LINEEND );
+ if ( pTime )
+ FilePrintF( pDebugFile, "%s%s", asctime( pTime ), FILE_LINEEND );
+ }
+ }
+ else
+ pDebugFile = FileOpen( pData->aDbgData.aDebugName, "a" );
+
+ chdir( aBuf );
+
+ return pDebugFile;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDbgPrintFile( const sal_Char* pLine )
+{
+ FILETYPE pDebugFile = ImplDbgInitFile();
+
+ if ( pDebugFile )
+ {
+ FilePrintF( pDebugFile, "%s%s", pLine, FILE_LINEEND );
+ FileClose( pDebugFile );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static int ImplStrSearch( const sal_Char* pSearchStr, int nSearchLen,
+ const sal_Char* pStr, int nLen )
+{
+ int nPos = 0;
+ while ( nPos+nSearchLen <= nLen )
+ {
+ if ( strncmp( pStr+nPos, pSearchStr, nSearchLen ) == 0 )
+ return 1;
+ nPos++;
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static int ImplDbgFilter( const sal_Char* pFilter, const sal_Char* pMsg,
+ int bEmpty )
+{
+ int nStrLen = strlen( pFilter );
+ if ( !nStrLen )
+ return bEmpty;
+
+ int nMsgLen = strlen( pMsg );
+ const sal_Char* pTok = pFilter;
+ int nTok = 0;
+ while ( pTok[nTok] )
+ {
+ if ( pTok[nTok] == ';' )
+ {
+ if ( nTok && ImplStrSearch( pTok, nTok, pMsg, nMsgLen ) )
+ return TRUE;
+
+ pTok += nTok+1;
+ nTok = 0;
+ }
+
+ nTok++;
+ }
+
+ if ( nTok && ImplStrSearch( pTok, nTok, pMsg, nMsgLen ) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+extern "C"
+void SAL_CALL dbg_printOslDebugMessage( const sal_Char * pszFileName, sal_Int32 nLine, const sal_Char * pszMessage )
+{
+ DbgOut( pszMessage ? pszMessage : "assertion failed!", DBG_OUT_ERROR, pszFileName, (USHORT)nLine );
+}
+
+// -----------------------------------------------------------------------
+
+static void DebugInit()
+{
+ bDbgImplInMain = TRUE;
+ ImplDbgInitLock();
+
+ DebugData* pData = GetDebugData();
+ if( pData->aDbgData.bHookOSLAssert && ! pData->bOslIsHooked )
+ {
+ pData->pOldDebugMessageFunc = osl_setDetailedDebugMessageFunc( &dbg_printOslDebugMessage );
+ pData->bOslIsHooked = true;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void DebugDeInit()
+{
+ DebugData* pData = GetDebugData();
+ ULONG i;
+ ULONG nCount;
+ ULONG nOldOut;
+
+ if( pData->bOslIsHooked )
+ {
+ osl_setDetailedDebugMessageFunc( pData->pOldDebugMessageFunc );
+ pData->bOslIsHooked = FALSE;
+ }
+
+ // Statistik-Ausgaben immer in File
+ nOldOut = pData->aDbgData.nTraceOut;
+ pData->aDbgData.nTraceOut = DBG_OUT_FILE;
+
+ // Xtor-Liste ausgeben
+ if ( pData->pXtorList && pData->pXtorList->Count() &&
+ (pData->aDbgData.nTestFlags & DBG_TEST_XTOR_REPORT) )
+ {
+ DbgOutf( "------------------------------------------------------------------------------" );
+ DbgOutf( "Object Report" );
+ DbgOutf( "------------------------------------------------------------------------------" );
+ DbgOutf( "%-27s : %-9s : %-9s : %-7s : %-3s : %-6s :",
+ "XTor-List", "Ctor", "Dtor", "MaxInst", "St.", "Diff." );
+ DbgOutf( "----------------------------:-----------:-----------:---------:----:---------:" );
+ for( i = 0, nCount = pData->pXtorList->Count(); i < nCount; i++ )
+ {
+ XtorType* pXtorData = (XtorType*)pData->pXtorList->Get( i );
+ if ( pXtorData->bTest )
+ {
+ // Static-Objekte dazurechnen
+ pXtorData->nDtorCalls += pXtorData->nStatics;
+ if ( pXtorData->nStatics && (pXtorData->nDtorCalls > pXtorData->nCtorCalls) )
+ pXtorData->nDtorCalls = pXtorData->nCtorCalls;
+ DbgOutf( "%-27s : %9lu : %9lu : %7lu : %3lu : %4lu %-1s :",
+ pXtorData->aName, pXtorData->nCtorCalls, pXtorData->nDtorCalls,
+ pXtorData->nMaxCount, pXtorData->nStatics,
+ pXtorData->nCtorCalls - pXtorData->nDtorCalls,
+ (pXtorData->nCtorCalls - pXtorData->nDtorCalls) ? "!" : " " );
+ }
+ }
+ DbgOutf( "==============================================================================" );
+ }
+
+ // Aufraeumen
+ if ( pData->pXtorList )
+ {
+ for( i = 0, nCount = pData->pXtorList->Count(); i < nCount; i++ )
+ {
+ XtorType* pXtorData = (XtorType*)pData->pXtorList->Get( i );
+ delete pXtorData;
+ }
+ delete pData->pXtorList;
+ pData->pXtorList = NULL;
+ }
+
+ // Alles auf FALSE setzen, damit globale Variablen nicht das
+ // System zum Abstuerzen bringt. Dabei muessen aber die
+ // Memory-Flags erhalten bleiben, da sonst new/delete in globalen
+ // Variablen abstuerzen, da die Pointeranpassung dann nicht mehr richtig
+ // funktioniert
+ pData->aDbgData.nTraceOut = nOldOut;
+ pData->aDbgData.nTestFlags &= (DBG_TEST_MEM | DBG_TEST_PROFILING);
+ pData->aDbgPrintUserChannels.clear();
+ pData->pDbgPrintTestTool = NULL;
+ pData->pDbgPrintWindow = NULL;
+ pData->pOldDebugMessageFunc = NULL;
+ ImplDbgDeInitLock();
+}
+
+// -----------------------------------------------------------------------
+
+static void DebugGlobalDeInit()
+{
+ DebugData* pData = GetDebugData();
+ ULONG i;
+ ULONG nCount;
+ ULONG nOldOut;
+
+ // Statistik-Ausgaben immer in File
+ nOldOut = pData->aDbgData.nTraceOut;
+ pData->aDbgData.nTraceOut = DBG_OUT_FILE;
+
+ // Profileliste ausgeben
+ if ( pData->pProfList && pData->pProfList->Count() )
+ {
+ DbgOutf( "------------------------------------------------------------------------------" );
+ DbgOutf( "Profiling Report" );
+ DbgOutf( "------------------------------------------------------------------------------" );
+ DbgOutf( "%-25s : %-9s : %-6s : %-6s : %-6s : %-9s :",
+ "Prof-List (ms)", "Time", "Min", "Max", "Ave", "Count" );
+ DbgOutf( "--------------------------:-----------:--------:--------:--------:-----------:" );
+ for( i = 0, nCount = pData->pProfList->Count(); i < nCount; i++ )
+ {
+ ProfType* pProfData = (ProfType*)pData->pProfList->Get( i );
+ ULONG nAve = pProfData->nTime / pProfData->nCount;
+ DbgOutf( "%-25s : %9lu : %6lu : %6lu : %6lu : %9lu :",
+ pProfData->aName, pProfData->nTime,
+ pProfData->nMinTime, pProfData->nMaxTime, nAve,
+ pProfData->nCount );
+ }
+ DbgOutf( "==============================================================================" );
+ }
+
+ // Aufraeumen
+ if ( pData->pProfList )
+ {
+ for( i = 0, nCount = pData->pProfList->Count(); i < nCount; i++ )
+ {
+ ProfType* pProfData = (ProfType*)pData->pProfList->Get( i );
+ delete pProfData;
+ }
+ delete pData->pProfList;
+ pData->pProfList = NULL;
+ }
+
+#ifdef SV_MEMMGR
+ DbgImpCheckMemoryDeInit();
+#endif
+
+ // Profiling-Flags ausschalten
+ pData->aDbgData.nTraceOut = nOldOut;
+ pData->aDbgData.nTestFlags &= ~DBG_TEST_PROFILING;
+}
+
+// -----------------------------------------------------------------------
+
+void ImpDbgOutfBuf( sal_Char* pBuf, const sal_Char* pFStr, ... )
+{
+ va_list pList;
+
+ va_start( pList, pFStr );
+ sal_Char aBuf[DBG_BUF_MAXLEN];
+ vsprintf( aBuf, pFStr, pList );
+ va_end( pList );
+
+ strcat( pBuf, aBuf );
+ strcat( pBuf, "\n" );
+}
+
+// -----------------------------------------------------------------------
+
+static void DebugXTorInfo( sal_Char* pBuf )
+{
+ DebugData* pData = GetDebugData();
+ ULONG i;
+ ULONG nCount;
+
+ // Xtor-Liste ausgeben
+ if ( pData->pXtorList && pData->pXtorList->Count() &&
+ (pData->aDbgData.nTestFlags & DBG_TEST_XTOR_REPORT) )
+ {
+ ImpDbgOutfBuf( pBuf, "------------------------------------------------------------------------------" );
+ ImpDbgOutfBuf( pBuf, "Object Report" );
+ ImpDbgOutfBuf( pBuf, "------------------------------------------------------------------------------" );
+ ImpDbgOutfBuf( pBuf, "%-27s : %-9s : %-9s : %-7s : %-3s : %-6s :",
+ "XTor-List", "Ctor", "Dtor", "MaxInst", "St.", "Diff." );
+ ImpDbgOutfBuf( pBuf, "----------------------------:-----------:-----------:---------:----:---------:" );
+ for( i = 0, nCount = pData->pXtorList->Count(); i < nCount; i++ )
+ {
+ XtorType* pXtorData = (XtorType*)pData->pXtorList->Get( i );
+ if ( pXtorData->bTest )
+ {
+ ImpDbgOutfBuf( pBuf, "%-27s : %9lu : %9lu : %7lu : %3lu : %6lu :",
+ pXtorData->aName, pXtorData->nCtorCalls, pXtorData->nDtorCalls,
+ pXtorData->nMaxCount, pXtorData->nStatics,
+ pXtorData->nCtorCalls - pXtorData->nDtorCalls );
+ }
+ }
+ ImpDbgOutfBuf( pBuf, "==============================================================================" );
+ ImpDbgOutfBuf( pBuf, "" );
+ }
+}
+
+// -----------------------------------------------------------------------
+BOOL ImplDbgFilterMessage( const sal_Char* pMsg )
+{
+ DebugData* pData = GetDebugData();
+ if ( !ImplDbgFilter( pData->aDbgData.aInclFilter, pMsg, TRUE ) )
+ return TRUE;
+ if ( ImplDbgFilter( pData->aDbgData.aExclFilter, pMsg, FALSE ) )
+ return TRUE;
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void* DbgFunc( USHORT nAction, void* pParam )
+{
+ DebugData* pDebugData = ImplGetDebugData();
+
+ if ( nAction == DBG_FUNC_GETDATA )
+ return (void*)&(pDebugData->aDbgData);
+ else if ( nAction == DBG_FUNC_GETPRINTMSGBOX )
+ return (void*)(long)(pDebugData->pDbgPrintMsgBox);
+ else if ( nAction == DBG_FUNC_FILTERMESSAGE )
+ if ( ImplDbgFilterMessage( (const sal_Char*) pParam ) )
+ return (void*) -1;
+ else
+ return (void*) 0; // aka NULL
+ else
+
+ {
+ switch ( nAction )
+ {
+ case DBG_FUNC_DEBUGSTART:
+ DebugInit();
+ break;
+
+ case DBG_FUNC_DEBUGEND:
+ DebugDeInit();
+ break;
+
+ case DBG_FUNC_GLOBALDEBUGEND:
+ DebugGlobalDeInit();
+ break;
+
+ case DBG_FUNC_SETPRINTMSGBOX:
+ pDebugData->pDbgPrintMsgBox = (DbgPrintLine)(long)pParam;
+ break;
+
+ case DBG_FUNC_SETPRINTWINDOW:
+ pDebugData->pDbgPrintWindow = (DbgPrintLine)(long)pParam;
+ break;
+
+ case DBG_FUNC_SETPRINTTESTTOOL:
+ pDebugData->pDbgPrintTestTool = (DbgPrintLine)(long)pParam;
+ break;
+
+ case DBG_FUNC_SAVEDATA:
+ {
+ const DbgData* pData = static_cast< const DbgData* >( pParam );
+
+ sal_Char aBuf[ 4096 ];
+ DbgGetDbgFileName( aBuf, sizeof( aBuf ) );
+ FILETYPE pIniFile = FileOpen( aBuf, "w" );
+ if ( pIniFile == NULL )
+ break;
+
+ lcl_startSection( pIniFile, eOutput );
+ lcl_writeConfigString( pIniFile, "log_file", pData->aDebugName );
+ lcl_writeConfigBoolean( pIniFile, "overwrite", pData->bOverwrite );
+ lcl_writeConfigString( pIniFile, "include", pData->aInclFilter );
+ lcl_writeConfigString( pIniFile, "exclude", pData->aExclFilter );
+ lcl_writeConfigString( pIniFile, "include_class", pData->aInclClassFilter );
+ lcl_writeConfigString( pIniFile, "exclude_class", pData->aExclClassFilter );
+ lcl_writeConfigOutChannel( pIniFile, "trace", pData->nTraceOut );
+ lcl_writeConfigOutChannel( pIniFile, "warning", pData->nWarningOut );
+ lcl_writeConfigOutChannel( pIniFile, "error", pData->nErrorOut );
+ lcl_writeConfigBoolean( pIniFile, "oslhook", pData->bHookOSLAssert );
+
+ lcl_lineFeed( pIniFile );
+ lcl_startSection( pIniFile, eMemory );
+ lcl_writeConfigFlag( pIniFile, "initialize", pData->nTestFlags, DBG_TEST_MEM_INIT );
+ lcl_writeConfigFlag( pIniFile, "overwrite", pData->nTestFlags, DBG_TEST_MEM_OVERWRITE );
+ lcl_writeConfigFlag( pIniFile, "overwrite_free", pData->nTestFlags, DBG_TEST_MEM_OVERWRITEFREE );
+ lcl_writeConfigFlag( pIniFile, "pointer", pData->nTestFlags, DBG_TEST_MEM_POINTER );
+ lcl_writeConfigFlag( pIniFile, "report", pData->nTestFlags, DBG_TEST_MEM_REPORT );
+ lcl_writeConfigFlag( pIniFile, "trace", pData->nTestFlags, DBG_TEST_MEM_TRACE );
+ lcl_writeConfigFlag( pIniFile, "new_and_delete", pData->nTestFlags, DBG_TEST_MEM_NEWDEL );
+ lcl_writeConfigFlag( pIniFile, "object_test", pData->nTestFlags, DBG_TEST_MEM_XTOR );
+ lcl_writeConfigFlag( pIniFile, "sys_alloc", pData->nTestFlags, DBG_TEST_MEM_SYSALLOC );
+ lcl_writeConfigFlag( pIniFile, "leak_report", pData->nTestFlags, DBG_TEST_MEM_LEAKREPORT );
+
+ lcl_lineFeed( pIniFile );
+ lcl_writeHexByte( pIniFile, "init_byte", pData->bMemInit );
+ lcl_writeHexByte( pIniFile, "bound_byte", pData->bMemBound );
+ lcl_writeHexByte( pIniFile, "free_byte", pData->bMemFree );
+
+ lcl_lineFeed( pIniFile );
+ lcl_startSection( pIniFile, eGUI );
+ lcl_writeConfigString( pIniFile, "debug_window_state", pData->aDbgWinState );
+
+ lcl_lineFeed( pIniFile );
+ lcl_startSection( pIniFile, eObjects );
+ lcl_writeConfigFlag( pIniFile, "check_this", pData->nTestFlags, DBG_TEST_XTOR_THIS );
+ lcl_writeConfigFlag( pIniFile, "check_function", pData->nTestFlags, DBG_TEST_XTOR_FUNC );
+ lcl_writeConfigFlag( pIniFile, "check_exit", pData->nTestFlags, DBG_TEST_XTOR_EXIT );
+ lcl_writeConfigFlag( pIniFile, "generate_report", pData->nTestFlags, DBG_TEST_XTOR_REPORT );
+ lcl_writeConfigFlag( pIniFile, "trace", pData->nTestFlags, DBG_TEST_XTOR_TRACE );
+
+ lcl_lineFeed( pIniFile );
+ lcl_startSection( pIniFile, eTest );
+ lcl_writeConfigFlag( pIniFile, "profiling", pData->nTestFlags, DBG_TEST_PROFILING );
+ lcl_writeConfigFlag( pIniFile, "resources", pData->nTestFlags, DBG_TEST_RESOURCE );
+ lcl_writeConfigFlag( pIniFile, "dialog", pData->nTestFlags, DBG_TEST_DIALOG );
+ lcl_writeConfigFlag( pIniFile, "bold_app_font", pData->nTestFlags, DBG_TEST_BOLDAPPFONT );
+
+ FileClose( pIniFile );
+ }
+ break;
+
+ case DBG_FUNC_MEMTEST:
+#ifdef SV_MEMMGR
+ DbgImpCheckMemory( pParam );
+#endif
+ break;
+
+ case DBG_FUNC_XTORINFO:
+ DebugXTorInfo( (sal_Char*)pParam );
+ break;
+
+ case DBG_FUNC_MEMINFO:
+#ifdef SV_MEMMGR
+ DbgImpMemoryInfo( (sal_Char*)pParam );
+#endif
+ break;
+
+ case DBG_FUNC_COREDUMP:
+ ImplCoreDump();
+ break;
+
+ case DBG_FUNC_ALLERROROUT:
+ return (void*)(ULONG)TRUE;
+
+ case DBG_FUNC_SETTESTSOLARMUTEX:
+ pDebugData->pDbgTestSolarMutex = (DbgTestSolarMutexProc)(long)pParam;
+ break;
+
+ case DBG_FUNC_TESTSOLARMUTEX:
+ if ( pDebugData->pDbgTestSolarMutex )
+ pDebugData->pDbgTestSolarMutex();
+ break;
+
+ case DBG_FUNC_PRINTFILE:
+ ImplDbgPrintFile( (const sal_Char*)pParam );
+ break;
+ case DBG_FUNC_UPDATEOSLHOOK:
+ {
+ const DbgData* pData = static_cast< const DbgData* >( pParam );
+ pDebugData->aDbgData.bHookOSLAssert = pData->bHookOSLAssert;
+ if( pDebugData->bOslIsHooked && ! pData->bHookOSLAssert )
+ {
+ osl_setDetailedDebugMessageFunc( pDebugData->pOldDebugMessageFunc );
+ pDebugData->bOslIsHooked = FALSE;
+ }
+ else if( ! pDebugData->bOslIsHooked && pData->bHookOSLAssert )
+ {
+ pDebugData->pOldDebugMessageFunc = osl_setDetailedDebugMessageFunc( &dbg_printOslDebugMessage );
+ pDebugData->bOslIsHooked = TRUE;
+ }
+ }
+ break;
+ }
+
+ return NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+DbgChannelId DbgRegisterUserChannel( DbgPrintLine pProc )
+{
+ DebugData* pData = ImplGetDebugData();
+ pData->aDbgPrintUserChannels.push_back( pProc );
+ return (DbgChannelId)( pData->aDbgPrintUserChannels.size() - 1 + DBG_OUT_USER_CHANNEL_0 );
+}
+
+// -----------------------------------------------------------------------
+
+void DbgProf( USHORT nAction, DbgDataType* pDbgData )
+{
+ // Ueberhaupt Profiling-Test an
+ DebugData* pData = ImplGetDebugData();
+
+ if ( !(pData->aDbgData.nTestFlags & DBG_TEST_PROFILING) )
+ return;
+
+ sal_Char aBuf[DBG_BUF_MAXLEN];
+ ProfType* pProfData = (ProfType*)pDbgData->pData;
+ ULONG nTime;
+ if ( (nAction != DBG_PROF_START) && !pProfData )
+ {
+ strcpy( aBuf, DbgError_ProfEnd1 );
+ strcat( aBuf, pDbgData->pName );
+ DbgError( aBuf );
+ return;
+ }
+
+ switch ( nAction )
+ {
+ case DBG_PROF_START:
+ if ( !pDbgData->pData )
+ {
+ pDbgData->pData = (void*)new ProfType;
+ pProfData = (ProfType*)pDbgData->pData;
+ strncpy( pProfData->aName, pDbgData->pName, DBG_MAXNAME );
+ pProfData->aName[DBG_MAXNAME] = '\0';
+ pProfData->nCount = 0;
+ pProfData->nTime = 0;
+ pProfData->nMinTime = 0xFFFFFFFF;
+ pProfData->nMaxTime = 0;
+ pProfData->nStart = 0xFFFFFFFF;
+ pProfData->nContinueTime = 0;
+ pProfData->nContinueStart = 0xFFFFFFFF;
+ pData->pProfList->Add( (void*)pProfData );
+ }
+
+ if ( pProfData->nStart == 0xFFFFFFFF )
+ {
+ pProfData->nStart = ImplGetPerfTime();
+ pProfData->nCount++;
+ }
+ break;
+
+ case DBG_PROF_STOP:
+ nTime = ImplGetPerfTime();
+
+ if ( pProfData->nStart == 0xFFFFFFFF )
+ {
+ DbgError( DbgError_ProfEnd1 );
+ return;
+ }
+
+ if ( pProfData->nContinueStart != 0xFFFFFFFF )
+ {
+ pProfData->nContinueTime += ImplGetPerfTime() - pProfData->nContinueStart;
+ pProfData->nContinueStart = 0xFFFFFFFF;
+ }
+
+ nTime -= pProfData->nStart;
+ nTime -= pProfData->nContinueTime;
+
+ if ( nTime < pProfData->nMinTime )
+ pProfData->nMinTime = nTime;
+
+ if ( nTime > pProfData->nMaxTime )
+ pProfData->nMaxTime = nTime;
+
+ pProfData->nTime += nTime;
+
+ pProfData->nStart = 0xFFFFFFFF;
+ pProfData->nContinueTime = 0;
+ pProfData->nContinueStart = 0xFFFFFFFF;
+ break;
+
+ case DBG_PROF_CONTINUE:
+ if ( pProfData->nContinueStart != 0xFFFFFFFF )
+ {
+ pProfData->nContinueTime += ImplGetPerfTime() - pProfData->nContinueStart;
+ pProfData->nContinueStart = 0xFFFFFFFF;
+ }
+ break;
+
+ case DBG_PROF_PAUSE:
+ if ( pProfData->nContinueStart == 0xFFFFFFFF )
+ pProfData->nContinueStart = ImplGetPerfTime();
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void DbgXtor( DbgDataType* pDbgData, USHORT nAction, const void* pThis,
+ DbgUsr fDbgUsr )
+{
+ DebugData* pData = ImplGetDebugData();
+
+ // Verbindung zu Debug-Memory-Manager testen
+#ifdef SV_MEMMGR
+ if ( pData->aDbgData.nTestFlags & DBG_TEST_MEM_XTOR )
+ DbgImpCheckMemory();
+#endif
+
+ // Schnell-Test
+ if ( !(pData->aDbgData.nTestFlags & DBG_TEST_XTOR) )
+ return;
+
+ XtorType* pXtorData = (XtorType*)pDbgData->pData;
+ if ( !pXtorData )
+ {
+ pDbgData->pData = (void*)new XtorType;
+ pXtorData = (XtorType*)pDbgData->pData;
+ strncpy( pXtorData->aName, pDbgData->pName, DBG_MAXNAME );
+ pXtorData->aName[DBG_MAXNAME] = '\0';
+ pXtorData->nCtorCalls = 0;
+ pXtorData->nDtorCalls = 0;
+ pXtorData->nMaxCount = 0;
+ pXtorData->nStatics = 0;
+ pXtorData->bTest = TRUE;
+ pData->pXtorList->Add( (void*)pXtorData );
+
+ if ( !ImplDbgFilter( pData->aDbgData.aInclClassFilter, pXtorData->aName, TRUE ) )
+ pXtorData->bTest = FALSE;
+ if ( ImplDbgFilter( pData->aDbgData.aExclClassFilter, pXtorData->aName, FALSE ) )
+ pXtorData->bTest = FALSE;
+ }
+ if ( !pXtorData->bTest )
+ return;
+
+ sal_Char aBuf[DBG_BUF_MAXLEN];
+ USHORT nAct = nAction & ~DBG_XTOR_DTOROBJ;
+
+ // Trace (Enter)
+ if ( (pData->aDbgData.nTestFlags & DBG_TEST_XTOR_TRACE) &&
+ !(nAction & DBG_XTOR_DTOROBJ) )
+ {
+ if ( nAct != DBG_XTOR_CHKOBJ )
+ {
+ if ( nAct == DBG_XTOR_CTOR )
+ strcpy( aBuf, DbgTrace_EnterCtor );
+ else if ( nAct == DBG_XTOR_DTOR )
+ strcpy( aBuf, DbgTrace_EnterDtor );
+ else
+ strcpy( aBuf, DbgTrace_EnterMeth );
+ strcat( aBuf, pDbgData->pName );
+ DbgTrace( aBuf );
+ }
+ }
+
+ // Sind noch Xtor-Tests als Trace an
+ if ( pData->aDbgData.nTestFlags & DBG_TEST_XTOR_EXTRA )
+ {
+ // DBG_CTOR-Aufruf vor allen anderen DBG_XTOR-Aufrufen
+ if ( ((nAction & ~DBG_XTOR_DTOROBJ) != DBG_XTOR_CTOR) && !pDbgData->pData )
+ {
+ strcpy( aBuf, DbgError_Xtor1 );
+ strcat( aBuf, pDbgData->pName );
+ DbgError( aBuf );
+ return;
+ }
+
+ // Testen, ob This-Pointer gueltig
+ if ( pData->aDbgData.nTestFlags & DBG_TEST_XTOR_THIS )
+ {
+ if ( (pData->aDbgData.nTestFlags & DBG_TEST_XTOR_EXIT) ||
+ !(nAction & DBG_XTOR_DTOROBJ) )
+ {
+ // This-Pointer == NULL
+ if ( !pThis )
+ {
+ strcpy( aBuf, DbgError_CtorDtor1 );
+ strcat( aBuf, pDbgData->pName );
+ DbgError( aBuf );
+ return;
+ }
+
+ if ( (nAction & ~DBG_XTOR_DTOROBJ) != DBG_XTOR_CTOR )
+ {
+ if ( !pXtorData->aThisList.IsIn( pThis ) )
+ {
+ sprintf( aBuf, DbgError_CtorDtor2, pThis );
+ strcat( aBuf, pDbgData->pName );
+ DbgError( aBuf );
+ }
+ }
+ }
+ }
+
+ // Function-Test durchfuehren und Verwaltungsdaten updaten
+ const sal_Char* pMsg = NULL;
+ switch ( nAction & ~DBG_XTOR_DTOROBJ )
+ {
+ case DBG_XTOR_CTOR:
+ if ( nAction & DBG_XTOR_DTOROBJ )
+ {
+ if ( fDbgUsr &&
+ (pData->aDbgData.nTestFlags & DBG_TEST_XTOR_EXIT) &&
+ (pData->aDbgData.nTestFlags & DBG_TEST_XTOR_FUNC) )
+ pMsg = fDbgUsr( pThis );
+ }
+ else
+ {
+ pXtorData->nCtorCalls++;
+ if ( !bDbgImplInMain )
+ pXtorData->nStatics++;
+ if ( (pXtorData->nCtorCalls-pXtorData->nDtorCalls) > pXtorData->nMaxCount )
+ pXtorData->nMaxCount = pXtorData->nCtorCalls - pXtorData->nDtorCalls;
+
+ if ( pData->aDbgData.nTestFlags & DBG_TEST_XTOR_THIS )
+ pXtorData->aThisList.Add( pThis );
+ }
+ break;
+
+ case DBG_XTOR_DTOR:
+ if ( nAction & DBG_XTOR_DTOROBJ )
+ {
+ pXtorData->nDtorCalls++;
+ if ( pData->aDbgData.nTestFlags & DBG_TEST_XTOR_THIS )
+ pXtorData->aThisList.Remove( pThis );
+ }
+ else
+ {
+ if ( fDbgUsr &&
+ (pData->aDbgData.nTestFlags & DBG_TEST_XTOR_FUNC) )
+ pMsg = fDbgUsr( pThis );
+ }
+ break;
+
+ case DBG_XTOR_CHKTHIS:
+ case DBG_XTOR_CHKOBJ:
+ if ( nAction & DBG_XTOR_DTOROBJ )
+ {
+ if ( fDbgUsr &&
+ (pData->aDbgData.nTestFlags & DBG_TEST_XTOR_EXIT) &&
+ (pData->aDbgData.nTestFlags & DBG_TEST_XTOR_FUNC) )
+ pMsg = fDbgUsr( pThis );
+ }
+ else
+ {
+ if ( fDbgUsr &&
+ (pData->aDbgData.nTestFlags & DBG_TEST_XTOR_FUNC) )
+ pMsg = fDbgUsr( pThis );
+ }
+ break;
+ }
+
+ // Gegebenenfalls Fehlermeldung ausgeben
+ if ( pMsg )
+ {
+ sprintf( aBuf, DbgError_CtorDtor3, pThis );
+ strcat( aBuf, pDbgData->pName );
+ strcat( aBuf, ": \n" );
+ strcat( aBuf, pMsg );
+ DbgError( aBuf );
+ }
+ }
+
+ // Trace (Leave)
+ if ( (pData->aDbgData.nTestFlags & DBG_TEST_XTOR_TRACE) &&
+ (nAction & DBG_XTOR_DTOROBJ) )
+ {
+ if ( nAct != DBG_XTOR_CHKOBJ )
+ {
+ if ( nAct == DBG_XTOR_CTOR )
+ strcpy( aBuf, DbgTrace_LeaveCtor );
+ else if ( nAct == DBG_XTOR_DTOR )
+ strcpy( aBuf, DbgTrace_LeaveDtor );
+ else
+ strcpy( aBuf, DbgTrace_LeaveMeth );
+ strcat( aBuf, pDbgData->pName );
+ DbgTrace( aBuf );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void DbgOut( const sal_Char* pMsg, USHORT nDbgOut, const sal_Char* pFile, USHORT nLine )
+{
+ static BOOL bIn = FALSE;
+ if ( bIn )
+ return;
+ bIn = TRUE;
+
+ DebugData* pData = GetDebugData();
+ sal_Char const * pStr;
+ ULONG nOut;
+ int nBufLen = 0;
+
+ if ( nDbgOut == DBG_OUT_ERROR )
+ {
+ nOut = pData->aDbgData.nErrorOut;
+ pStr = "Error: ";
+ if ( pData->aDbgData.nErrorOut == DBG_OUT_FILE )
+ DbgDebugBeep();
+ }
+ else if ( nDbgOut == DBG_OUT_WARNING )
+ {
+ nOut = pData->aDbgData.nWarningOut;
+ pStr = "Warning: ";
+ }
+ else
+ {
+ nOut = pData->aDbgData.nTraceOut;
+ pStr = NULL;
+ }
+
+ if ( nOut == DBG_OUT_NULL )
+ {
+ bIn = FALSE;
+ return;
+ }
+
+ if ( ImplDbgFilterMessage( pMsg ) )
+ {
+ bIn = FALSE;
+ return;
+ }
+
+ ImplDbgLock();
+
+ sal_Char aBufOut[DBG_BUF_MAXLEN];
+ if ( pStr )
+ {
+ strcpy( aBufOut, pStr );
+ nBufLen = strlen( pStr );
+ }
+ else
+ aBufOut[0] = '\0';
+
+ int nMsgLen = strlen( pMsg );
+ if ( nBufLen+nMsgLen > DBG_BUF_MAXLEN )
+ {
+ int nCopyLen = DBG_BUF_MAXLEN-nBufLen-3;
+ strncpy( &(aBufOut[nBufLen]), pMsg, nCopyLen );
+ strcpy( &(aBufOut[nBufLen+nCopyLen]), "..." );
+ }
+ else
+ strcpy( &(aBufOut[nBufLen]), pMsg );
+
+ if ( pFile && nLine && (nBufLen+nMsgLen < DBG_BUF_MAXLEN) )
+ {
+ if ( nOut == DBG_OUT_MSGBOX )
+ strcat( aBufOut, "\n" );
+ else
+ strcat( aBufOut, " " );
+ strcat( aBufOut, "From File " );
+ strcat( aBufOut, pFile );
+ strcat( aBufOut, " at Line " );
+
+ // Line in String umwandeln und dranhaengen
+ sal_Char aLine[9];
+ sal_Char* pLine = &aLine[7];
+ USHORT i;
+ memset( aLine, 0, sizeof( aLine ) );
+ do
+ {
+ i = nLine % 10;
+ pLine--;
+ *(pLine) = (sal_Char)i + 48;
+ nLine /= 10;
+ }
+ while ( nLine );
+ strcat( aBufOut, pLine );
+ }
+
+ if ( ( nOut >= DBG_OUT_USER_CHANNEL_0 ) && ( nOut - DBG_OUT_USER_CHANNEL_0 < pData->aDbgPrintUserChannels.size() ) )
+ {
+ DbgPrintLine pPrinter = pData->aDbgPrintUserChannels[ nOut - DBG_OUT_USER_CHANNEL_0 ];
+ if ( pPrinter )
+ pPrinter( aBufOut );
+ else
+ nOut = DBG_OUT_DEBUGGER;
+ }
+
+ if ( nOut == DBG_OUT_COREDUMP )
+ {
+ if ( !ImplCoreDump() )
+ nOut = DBG_OUT_DEBUGGER;
+ }
+
+ if ( nOut == DBG_OUT_DEBUGGER )
+ {
+ if ( !ImplActivateDebugger( aBufOut ) )
+ nOut = DBG_OUT_TESTTOOL;
+ }
+
+ if ( nOut == DBG_OUT_TESTTOOL )
+ {
+ if ( pData->pDbgPrintTestTool )
+ pData->pDbgPrintTestTool( aBufOut );
+ else
+ nOut = DBG_OUT_MSGBOX;
+ }
+
+ if ( nOut == DBG_OUT_MSGBOX )
+ {
+ if ( pData->pDbgPrintMsgBox )
+ pData->pDbgPrintMsgBox( aBufOut );
+ else
+ nOut = DBG_OUT_WINDOW;
+ }
+
+ if ( nOut == DBG_OUT_WINDOW )
+ {
+ if ( pData->pDbgPrintWindow )
+ pData->pDbgPrintWindow( aBufOut );
+ else
+ nOut = DBG_OUT_FILE;
+ }
+
+ switch ( nOut )
+ {
+ case DBG_OUT_SHELL:
+ DbgPrintShell( aBufOut );
+ break;
+ case DBG_OUT_FILE:
+ ImplDbgPrintFile( aBufOut );
+ break;
+ }
+
+ ImplDbgUnlock();
+
+ bIn = FALSE;
+}
+
+void DbgPrintShell(char const * message) {
+ fprintf(stderr, "%s\n", message);
+#if defined WNT
+ OutputDebugStringA(message);
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void DbgOutTypef( USHORT nDbgOut, const sal_Char* pFStr, ... )
+{
+ va_list pList;
+
+ va_start( pList, pFStr );
+ sal_Char aBuf[DBG_BUF_MAXLEN];
+ vsprintf( aBuf, pFStr, pList );
+ va_end( pList );
+
+ DbgOut( aBuf, nDbgOut );
+}
+
+// -----------------------------------------------------------------------
+
+void DbgOutf( const sal_Char* pFStr, ... )
+{
+ va_list pList;
+
+ va_start( pList, pFStr );
+ sal_Char aBuf[DBG_BUF_MAXLEN];
+ vsprintf( aBuf, pFStr, pList );
+ va_end( pList );
+
+ DbgOut( aBuf );
+}
+
+// =======================================================================
+
+#else
+
+void* DbgFunc( USHORT, void* ) { return NULL; }
+
+void DbgProf( USHORT, DbgDataType* ) {}
+void DbgXtor( DbgDataType*, USHORT, const void*, DbgUsr ) {}
+
+void DbgOut( const sal_Char*, USHORT, const sal_Char*, USHORT ) {}
+void DbgOutTypef( USHORT, const sal_Char*, ... ) {}
+void DbgOutf( const sal_Char*, ... ) {}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/debug/makefile.mk b/tools/source/debug/makefile.mk
new file mode 100644
index 000000000000..925ae90f333d
--- /dev/null
+++ b/tools/source/debug/makefile.mk
@@ -0,0 +1,53 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=tools
+TARGET=debug
+
+ENABLE_EXCEPTIONS := TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES= debug.cxx \
+ stcktree.cxx
+
+SLOFILES= $(SLO)$/debug.obj \
+ $(SLO)$/stcktree.obj
+
+OBJFILES= $(OBJ)$/debug.obj \
+ $(OBJ)$/stcktree.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/tools/source/debug/stcktree.cxx b/tools/source/debug/stcktree.cxx
new file mode 100644
index 000000000000..93e4bde49a2a
--- /dev/null
+++ b/tools/source/debug/stcktree.cxx
@@ -0,0 +1,323 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <string.h>
+
+#include <tools/debug.hxx>
+
+// -----------------------------------------------------------------------
+
+#if defined( DBG_UTIL ) && defined( WNT ) && defined( INTEL )
+
+struct ImpDbgStackTree
+{
+ ImpDbgStackTree* pLeft_;
+ ImpDbgStackTree* pRight_;
+ ImpDbgStackTree* pCaller_;
+ ImpDbgStackTree* pSub_;
+ ULONG nIP_;
+ ULONG nBytesLeak_;
+ ULONG nBytesPeak_;
+ ULONG nBytes_;
+ ULONG nCountLeak_;
+ ULONG nCountPeak_;
+ ULONG nCount_;
+ ULONG nMax_;
+ ULONG nMin_;
+
+ ImpDbgStackTree( ImpDbgStackTree* pSub, ULONG nIP );
+ ~ImpDbgStackTree();
+
+ ImpDbgStackTree* Add( ULONG nAlloc, ULONG* pBP, ULONG nIP );
+ void Print( int nLevel, ULONG nCount, ULONG nCountLeak );
+ void Print( int nLevel );
+};
+
+static ImpDbgStackTree* pImpDbgStackTreeRoot = NULL;
+static ULONG* pImpDbgStackTreeBP = NULL;
+static ULONG nImpDbgStackTreeMain = 0;
+static int nImpDbgStackTreeSem = 0;
+
+// -----------------------------------------------------------------------
+
+ImpDbgStackTree::ImpDbgStackTree( ImpDbgStackTree* pSub, ULONG nIP )
+{
+ pSub_ = pSub;
+ nIP_ = nIP;
+ pLeft_ = pRight_ = pCaller_ = NULL;
+ nBytesLeak_ = nBytesPeak_ = nBytes_ = 0;
+ nCountLeak_ = nCountPeak_ = nCount_ = 0;
+}
+
+// -----------------------------------------------------------------------
+
+ImpDbgStackTree::~ImpDbgStackTree()
+{
+ if ( pLeft_ )
+ delete pLeft_;
+ if ( pRight_ )
+ delete pRight_;
+ if ( pCaller_ )
+ delete pCaller_;
+}
+
+// -----------------------------------------------------------------------
+
+void ImpDbgStackTree::Print( int nLevel, ULONG nCount, ULONG nCountLeak )
+{
+ if ( pLeft_ )
+ pLeft_->Print( nLevel, nCount, nCountLeak );
+
+ if ( nCount_ >= nCount && nCountLeak_ >= nCountLeak )
+ {
+ if ( nMax_ == nMin_ )
+ {
+ ULONG nTemp = nCountLeak_ * nMin_;
+ DbgOutf( "%*c%08lx Count=%lu/%lu/%lu Bytes=%lu/%lu/%lu Size=%lu",
+ nLevel, ' ', nIP_,
+ nCount_, nCountPeak_, nCountLeak_,
+ nBytes_, nBytesPeak_, nTemp,
+ nMin_ );
+ }
+ else
+ {
+ DbgOutf( "%*c%08lx Count=%lu/%lu/%lu Bytes=%lu/%lu/%lu Size=%lu-%lu",
+ nLevel, ' ', nIP_,
+ nCount_, nCountPeak_, nCountLeak_,
+ nBytes_, nBytesPeak_, nBytesLeak_,
+ nMin_, nMax_ );
+ }
+
+ if ( pCaller_ )
+ if( nLevel > 3 && nCountLeak )
+ pCaller_->Print( nLevel + 1, nCount, 1 );
+ else
+ pCaller_->Print( nLevel + 1, nCount, nCountLeak );
+ }
+
+ if ( pRight_ )
+ pRight_->Print( nLevel, nCount, nCountLeak );
+}
+
+// -----------------------------------------------------------------------
+
+void ImpDbgStackTree::Print( int nLevel )
+{
+ if ( pSub_ )
+ pSub_->Print( nLevel + 1 );
+ DbgOutf( "%*c%08lx", nLevel, ' ',nIP_ );
+}
+
+// -----------------------------------------------------------------------
+
+ImpDbgStackTree* ImpDbgStackTree::Add( ULONG nAlloc, ULONG *pBP, ULONG nIP )
+{
+ if ( nIP < nIP_ )
+ {
+ if ( !pLeft_ )
+ pLeft_ = new ImpDbgStackTree( pSub_, nIP );
+ return pLeft_->Add( nAlloc, pBP, nIP );
+ }
+ if ( nIP > nIP_ )
+ {
+ if ( !pRight_ )
+ pRight_ = new ImpDbgStackTree( pSub_, nIP );
+ return pRight_->Add( nAlloc, pBP, nIP );
+ }
+
+ nCount_++;
+ nCountLeak_++;
+ if ( nCountLeak_ > nCountPeak_ )
+ nCountPeak_ = nCountLeak_;
+ nBytes_ += nAlloc;
+ nBytesLeak_ += nAlloc;
+ if ( nBytesLeak_ > nBytesPeak_ )
+ nBytesPeak_ = nBytesLeak_;
+ if ( nCount_ == 1 )
+ nMax_ = nMin_ = nAlloc;
+ else if ( nMax_ < nAlloc )
+ nMax_ = nAlloc;
+ else if ( nMin_ > nAlloc )
+ nMin_ = nAlloc;
+
+ if ( !(pBP[0] & 3) && (ULONG)pBP < pBP[0] && pBP[0] < (ULONG)pImpDbgStackTreeBP )
+ {
+ pBP = (ULONG*)pBP[0];
+ nIP = pBP[1];
+ if ( 0x01100000 <= nIP && nIP < 0x20000000 && nIP != nImpDbgStackTreeMain )
+ {
+ if ( !pCaller_ )
+ pCaller_ = new ImpDbgStackTree( this, nIP );
+ return pCaller_->Add( nAlloc, pBP, nIP );
+ }
+ else
+ return this;
+ }
+
+ return this;
+}
+
+// -----------------------------------------------------------------------
+
+void DbgStartStackTree()
+{
+ if ( !nImpDbgStackTreeMain )
+ {
+ ULONG* pBP;
+ __asm mov pBP, ebp;
+
+ pImpDbgStackTreeBP = (ULONG*)pBP[0];
+ nImpDbgStackTreeMain = pImpDbgStackTreeBP[1];
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void DbgEndStackTree()
+{
+ if ( nImpDbgStackTreeMain )
+ {
+ nImpDbgStackTreeMain = 0;
+ if ( pImpDbgStackTreeRoot )
+ {
+ // Ausgaben ins File umleiten
+ DbgData* pData = DbgGetData();
+ ULONG nOldOut = pData->nTraceOut;
+ pData->nTraceOut = DBG_OUT_FILE;
+
+ DbgOutf( "Leak-Report" );
+ DbgOutf( "===========" );
+ DbgOutf( "Mem-StackTree:" );
+ DbgOutf( "{" );
+ pImpDbgStackTreeRoot->Print( 1, 1, 2 );
+ DbgOutf( "}" );
+
+ DbgOutf( "Alloc-Report" );
+ DbgOutf( "===========" );
+ DbgOutf( "Mem-StackTree:" );
+ DbgOutf( "{" );
+ pImpDbgStackTreeRoot->Print( 1, 1000, 0 ); // ???
+ DbgOutf( "}" );
+
+ pData->nTraceOut = nOldOut;
+
+ nImpDbgStackTreeSem++;
+ delete pImpDbgStackTreeRoot;
+ pImpDbgStackTreeRoot = NULL;
+ nImpDbgStackTreeSem--;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void* DbgGetStackTree( ULONG nAlloc )
+{
+ ImpDbgStackTree* pReturn = NULL;
+
+ if ( nImpDbgStackTreeMain && !nImpDbgStackTreeSem )
+ {
+ nImpDbgStackTreeSem++;
+
+ ULONG* pBP;
+ __asm mov pBP, ebp;
+
+ ULONG nIP = pBP[1];
+ if ( !pImpDbgStackTreeRoot )
+ pImpDbgStackTreeRoot = new ImpDbgStackTree( NULL, nIP );
+ pReturn = pImpDbgStackTreeRoot->Add( nAlloc, pBP, nIP );
+ nImpDbgStackTreeSem--;
+ }
+
+ return pReturn;
+}
+
+// -----------------------------------------------------------------------
+
+void DbgFreeStackTree( void* pVoid, ULONG nAlloc )
+{
+ ImpDbgStackTree* p = (ImpDbgStackTree*)pVoid;
+
+ if ( p && nImpDbgStackTreeMain && !nImpDbgStackTreeSem )
+ {
+ if ( nAlloc < p->nMin_ )
+ nAlloc = p->nMin_;
+
+ p->nCountLeak_--;
+ p->nBytesLeak_ -= nAlloc;
+
+ if ( p->nMax_ && 0xFFFFFFFF / p->nMax_ > p->nCountLeak_ )
+ {
+ if ( p->nBytesLeak_ > p->nMax_ * p->nCountLeak_ )
+ {
+ nAlloc += p->nBytesLeak_ - p->nMax_ * p->nCountLeak_;
+ p->nBytesLeak_ = p->nMax_ * p->nCountLeak_;
+ }
+ }
+
+ if ( p->pSub_ )
+ DbgFreeStackTree( (void*)(p->pSub_), nAlloc );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void DbgPrintStackTree( void* pVoid )
+{
+ ImpDbgStackTree* p = (ImpDbgStackTree*)pVoid;
+
+ if ( p && nImpDbgStackTreeMain && !nImpDbgStackTreeSem )
+ {
+ // Ausgaben ins File umleiten
+ DbgData* pData = DbgGetData();
+ ULONG nOldOut = pData->nTraceOut;
+ pData->nTraceOut = DBG_OUT_FILE;
+
+ DbgOutf( "Mem-StackTree:" );
+ DbgOutf( "{" );
+ p->Print( 1 );
+ DbgOutf( "}" );
+
+ pData->nTraceOut = nOldOut;
+ }
+}
+
+#else
+
+void DbgStartStackTree() {}
+void DbgEndStackTree() {}
+void* DbgGetStackTree( ULONG ) { return NULL; }
+void DbgFreeStackTree( void*, ULONG ) {}
+void DbgPrintStackTree( void* ) {}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/comdep.cxx b/tools/source/fsys/comdep.cxx
new file mode 100644
index 000000000000..2278e8dd1357
--- /dev/null
+++ b/tools/source/fsys/comdep.cxx
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include "comdep.hxx"
+#include <tools/debug.hxx>
+#include <tools/list.hxx>
+#include <tools/fsys.hxx>
+
+DBG_NAMEEX( DirEntry )
+
+#if defined UNX
+#include "unx.cxx"
+#elif defined WNT
+#include "wntmsc.cxx"
+#elif defined OS2
+#include "os2.cxx"
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/comdep.hxx b/tools/source/fsys/comdep.hxx
new file mode 100644
index 000000000000..286557167ae7
--- /dev/null
+++ b/tools/source/fsys/comdep.hxx
@@ -0,0 +1,159 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _COMDEP_HXX
+#define _COMDEP_HXX
+
+#include <tools/fsys.hxx>
+
+#define ACCESSDELIM(e) ( (e == FSYS_STYLE_MAC) ? ":" : \
+ ( ( e == FSYS_STYLE_VFAT || e == FSYS_STYLE_HPFS || \
+ e == FSYS_STYLE_FAT ) || e == FSYS_STYLE_NTFS ) \
+ ? "\\" : "/" )
+#define ACCESSDELIM_C(e)(char)\
+ ( (e == FSYS_STYLE_MAC) ? ':' : \
+ ( ( e == FSYS_STYLE_VFAT || e == FSYS_STYLE_HPFS || \
+ e == FSYS_STYLE_FAT ) || e == FSYS_STYLE_NTFS ) \
+ ? '\\' : '/' )
+#define SEARCHDELIM(e) ( (e == FSYS_STYLE_SYSV || e == FSYS_STYLE_BSD) ? ":" \
+ : ";" )
+#define SEARCHDELIM_C(e)(char)\
+ ( (e == FSYS_STYLE_SYSV || e == FSYS_STYLE_BSD) ? ':' \
+ : ';' )
+#define ACTPARENT(e) ( (e == FSYS_STYLE_MAC) ? ":" : ".." )
+#define ACTCURRENT(e) ( (e == FSYS_STYLE_MAC) ? "" : "." )
+
+#if defined UNX
+#include "unx.hxx"
+#elif defined WNT
+#include "wntmsc.hxx"
+#elif defined OS2
+#include "os2.hxx"
+#endif
+
+//--------------------------------------------------------------------
+
+#ifndef LINUX
+DIR *opendir( const char* pPfad );
+dirent *readdir( DIR *pDir );
+int closedir( DIR *pDir );
+char *volumeid( const char* pPfad );
+#endif
+
+//--------------------------------------------------------------------
+
+struct DirReader_Impl
+{
+ Dir* pDir;
+ DIR* pDosDir;
+ dirent* pDosEntry;
+ DirEntry* pParent;
+ String aPath;
+ ByteString aBypass;
+ BOOL bReady;
+ BOOL bInUse;
+
+ DirReader_Impl( Dir &rDir )
+ : pDir( &rDir ),
+ pDosEntry( 0 ),
+ pParent( 0 ),
+ aPath( GUI2FSYS(rDir.GetFull()) ),
+ bReady ( FALSE ),
+ bInUse( FALSE )
+ {
+#ifndef BOOTSTRAP
+ // Redirection
+ FSysRedirector::DoRedirect( aPath );
+#endif
+
+ // nur den String der Memer-Var nehmen!
+
+#if defined(UNX) || defined(OS2) //for further exlpanation see DirReader_Impl::Read() in unx.cxx
+ pDosDir = NULL;
+#else
+ aBypass = ByteString(aPath, osl_getThreadTextEncoding());
+ pDosDir = opendir( (char*) aBypass.GetBuffer() );
+#endif
+
+ // Parent f"ur die neuen DirEntries ermitteln
+ pParent = pDir->GetFlag() == FSYS_FLAG_NORMAL ||
+ pDir->GetFlag() == FSYS_FLAG_ABSROOT
+ ? pDir
+ : pDir->GetParent();
+
+ }
+
+ ~DirReader_Impl()
+ { if( pDosDir ) closedir( pDosDir ); }
+
+ // die folgenden sind systemabh"angig implementiert
+ USHORT Init(); // initialisiert, liest ggf. devices
+ USHORT Read(); // liest 1 Eintrag, F2ugt ein falls ok
+};
+
+//--------------------------------------------------------------------
+
+struct FileCopier_Impl
+{
+ FSysAction nActions; // was zu tun ist (Copy/Move/recur)
+ Link aErrorLink; // bei Fehlern zu rufen
+ ErrCode eErr; // aktueller Fehlercode im Error-Handler
+ const DirEntry* pErrSource; // fuer Error-Handler falls Source-Fehler
+ const DirEntry* pErrTarget; // fuer Error-Handler falls Target-Fehler
+
+ FileCopier_Impl()
+ : nActions( 0 ), eErr( 0 ),
+ pErrSource( 0 ), pErrTarget( 0 )
+ {}
+ FileCopier_Impl( const FileCopier_Impl &rOrig )
+ : nActions( rOrig.nActions ), eErr( 0 ),
+ pErrSource( 0 ), pErrTarget( 0 )
+ {}
+
+ FileCopier_Impl& operator=( const FileCopier_Impl &rOrig )
+ {
+ nActions = rOrig.nActions;
+ eErr = 0; pErrSource = 0; pErrTarget = 0;
+ return *this;
+ }
+};
+
+//--------------------------------------------------------------------
+
+#if defined WNT || defined OS2
+BOOL IsRedirectable_Impl( const ByteString &rPath );
+#else
+#define IsRedirectable_Impl( rPath ) TRUE
+#endif
+
+//--------------------------------------------------------------------
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/dirent.cxx b/tools/source/fsys/dirent.cxx
new file mode 100644
index 000000000000..debb0fa44ad5
--- /dev/null
+++ b/tools/source/fsys/dirent.cxx
@@ -0,0 +1,3197 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+
+#if !defined UNX
+#include <io.h>
+#include <process.h>
+#endif
+
+#if defined(UNX) || defined(OS2)
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <tools/debug.hxx>
+#include <tools/list.hxx>
+#include "comdep.hxx"
+#include <tools/fsys.hxx>
+#define _TOOLS_HXX
+#include <tools/urlobj.hxx>
+
+#ifdef UNX
+#define _MAX_PATH 260
+#endif
+#include <tools/stream.hxx>
+
+#include <osl/mutex.hxx>
+
+#include <osl/file.hxx>
+#include <rtl/instance.hxx>
+
+
+using namespace osl;
+using namespace rtl;
+
+int ApiRet2ToSolarError_Impl( int nApiRet );
+
+//--------------------------------------------------------------------
+int Sys2SolarError_Impl( int nSysErr )
+{
+ switch ( nSysErr )
+ {
+#ifdef WNT
+ case NO_ERROR: return ERRCODE_NONE;
+ case ERROR_INVALID_FUNCTION: return ERRCODE_IO_GENERAL;
+ case ERROR_FILE_NOT_FOUND: return ERRCODE_IO_NOTEXISTS;
+ case ERROR_PATH_NOT_FOUND: return ERRCODE_IO_NOTEXISTSPATH;
+ case ERROR_TOO_MANY_OPEN_FILES: return ERRCODE_IO_TOOMANYOPENFILES;
+ case ERROR_ACCESS_DENIED: return ERRCODE_IO_ACCESSDENIED;
+ case ERROR_INVALID_HANDLE: return ERRCODE_IO_GENERAL;
+ case ERROR_NOT_ENOUGH_MEMORY: return ERRCODE_IO_OUTOFMEMORY;
+ case ERROR_INVALID_BLOCK: return ERRCODE_IO_GENERAL;
+// case ERROR_BAD_ENVIRONMENT: return ERRCODE_IO_;
+ case ERROR_BAD_FORMAT: return ERRCODE_IO_WRONGFORMAT;
+ case ERROR_INVALID_ACCESS: return ERRCODE_IO_ACCESSDENIED;
+// case ERROR_INVALID_DATA: return ERRCODE_IO_;
+ case ERROR_INVALID_DRIVE: return ERRCODE_IO_INVALIDDEVICE;
+ case ERROR_CURRENT_DIRECTORY: return ERRCODE_IO_CURRENTDIR;
+ case ERROR_NOT_SAME_DEVICE: return ERRCODE_IO_NOTSAMEDEVICE;
+// case ERROR_NO_MORE_FILES: return ERRCODE_IO_;
+ case ERROR_WRITE_PROTECT: return ERRCODE_IO_CANTWRITE;
+ case ERROR_BAD_UNIT: return ERRCODE_IO_INVALIDDEVICE;
+ case ERROR_NOT_READY: return ERRCODE_IO_DEVICENOTREADY;
+ case ERROR_BAD_COMMAND: return ERRCODE_IO_GENERAL;
+ case ERROR_CRC: return ERRCODE_IO_BADCRC;
+ case ERROR_BAD_LENGTH: return ERRCODE_IO_INVALIDLENGTH;
+ case ERROR_SEEK: return ERRCODE_IO_CANTSEEK;
+ case ERROR_NOT_DOS_DISK: return ERRCODE_IO_WRONGFORMAT;
+ case ERROR_SECTOR_NOT_FOUND: return ERRCODE_IO_GENERAL;
+ case ERROR_WRITE_FAULT: return ERRCODE_IO_CANTWRITE;
+ case ERROR_READ_FAULT: return ERRCODE_IO_CANTREAD;
+ case ERROR_GEN_FAILURE: return ERRCODE_IO_GENERAL;
+ case ERROR_SHARING_VIOLATION: return ERRCODE_IO_LOCKVIOLATION;
+ case ERROR_LOCK_VIOLATION: return ERRCODE_IO_LOCKVIOLATION;
+ case ERROR_WRONG_DISK: return ERRCODE_IO_INVALIDDEVICE;
+ case ERROR_NOT_SUPPORTED: return ERRCODE_IO_NOTSUPPORTED;
+#else
+ case 0: return ERRCODE_NONE;
+ case ENOENT: return ERRCODE_IO_NOTEXISTS;
+ case EACCES: return ERRCODE_IO_ACCESSDENIED;
+ case EEXIST: return ERRCODE_IO_ALREADYEXISTS;
+ case EINVAL: return ERRCODE_IO_INVALIDPARAMETER;
+ case EMFILE: return ERRCODE_IO_TOOMANYOPENFILES;
+ case ENOMEM: return ERRCODE_IO_OUTOFMEMORY;
+ case ENOSPC: return ERRCODE_IO_OUTOFSPACE;
+#endif
+ }
+
+ DBG_TRACE1( "FSys: unknown system error %d occured", nSysErr );
+ return FSYS_ERR_UNKNOWN;
+}
+
+//--------------------------------------------------------------------
+
+#ifndef BOOTSTRAP
+
+FSysRedirector* FSysRedirector::_pRedirector = 0;
+BOOL FSysRedirector::_bEnabled = TRUE;
+#ifdef UNX
+BOOL bInRedirection = TRUE;
+#else
+BOOL bInRedirection = FALSE;
+#endif
+static osl::Mutex* pRedirectMutex = 0;
+
+//------------------------------------------------------------------------
+void FSysRedirector::Register( FSysRedirector *pRedirector )
+{
+ if ( pRedirector )
+ pRedirectMutex = new osl::Mutex;
+ else
+ DELETEZ( pRedirectMutex );
+ _pRedirector = pRedirector;
+}
+
+//------------------------------------------------------------------------
+
+void FSysRedirector::DoRedirect( String &rPath )
+{
+ String aURL(rPath);
+
+ // if redirection is disabled or not even registered do nothing
+ if ( !_bEnabled || !pRedirectMutex )
+ return;
+
+ // redirect only removable or remote volumes
+ if ( !IsRedirectable_Impl( ByteString( aURL, osl_getThreadTextEncoding() ) ) )
+ return;
+
+ // Redirection is acessible only by one thread per time
+ // dont move the guard behind the bInRedirection check!!!
+ // think of nested calls (when called from callback)
+ osl::MutexGuard aGuard( pRedirectMutex );
+
+ // if already in redirection, dont redirect
+ if ( bInRedirection )
+ return;
+
+ // dont redirect on nested calls
+ bInRedirection = TRUE;
+
+ // convert to URL
+#ifndef UNX
+ for ( sal_Unicode *p = (sal_Unicode*)aURL.GetBuffer(); *p; ++p )
+ if ( '\\' == *p ) *p = '/';
+ else if ( ':' == *p ) *p = '|';
+#endif
+
+ aURL.Insert( String("file:///", osl_getThreadTextEncoding()), 0 );
+
+ // do redirection
+ Redirector();
+
+ bInRedirection = FALSE;
+ return;
+}
+
+//------------------------------------------------------------------------
+
+FSysRedirector* FSysRedirector::Redirector()
+{
+ if ( !_pRedirector )
+ Register( new FSysRedirector );
+ return _pRedirector;
+}
+
+#endif // BOOTSTRAP
+
+//--------------------------------------------------------------------
+
+class DirEntryStack: public List
+{
+public:
+ DirEntryStack() {};
+ ~DirEntryStack();
+
+ inline void Push( DirEntry *pEntry );
+ inline DirEntry* Pop();
+ inline DirEntry* Top();
+ inline DirEntry* Bottom();
+};
+
+inline void DirEntryStack::Push( DirEntry *pEntry )
+{
+ List::Insert( pEntry, LIST_APPEND );
+}
+
+inline DirEntry* DirEntryStack::Pop()
+{
+ return (DirEntry*) List::Remove( Count() - 1 );
+}
+
+inline DirEntry* DirEntryStack::Top()
+{
+ return (DirEntry*) List::GetObject( Count() - 1 );
+}
+
+inline DirEntry* DirEntryStack::Bottom()
+{
+ return (DirEntry*) List::GetObject( 0 );
+}
+
+//--------------------------------------------------------------------
+
+DBG_NAME( DirEntry );
+
+/*************************************************************************
+|*
+|* DirEntry::~DirEntryStack()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MI 04.07.91
+|*
+*************************************************************************/
+
+DirEntryStack::~DirEntryStack()
+{
+ while ( Count() )
+ delete Pop();
+}
+
+/*************************************************************************
+|*
+|* ImpCheckDirEntry()
+|*
+|* Beschreibung Pruefung eines DirEntry fuer DBG_UTIL
+|* Parameter void* p Zeiger auf den DirEntry
+|* Return-Wert char* Fehlermeldungs-TExtension oder NULL
+|* Ersterstellung MI 16.07.91
+|* Letzte Aenderung MI 26.05.93
+|*
+*************************************************************************/
+
+#ifdef DBG_UTIL
+const char* ImpCheckDirEntry( const void* p )
+{
+ DirEntry* p0 = (DirEntry*)p;
+
+ if ( p0->pParent )
+ DBG_CHKOBJ( p0->pParent, DirEntry, ImpCheckDirEntry );
+
+ return NULL;
+}
+#endif
+
+/*************************************************************************
+|*
+|* ImplCutPath()
+|*
+|* Beschreibung Fuegt ... ein, damit maximal nMaxChars lang
+|* Ersterstellung MI 06.04.94
+|* Letzte Aenderung DV 24.06.96
+|*
+*************************************************************************/
+
+ByteString ImplCutPath( const ByteString& rStr, USHORT nMax, char cAccDel )
+{
+ USHORT nMaxPathLen = nMax;
+ ByteString aCutPath( rStr );
+ BOOL bInsertPrefix = FALSE;
+ USHORT nBegin = aCutPath.Search( cAccDel );
+
+ if( nBegin == STRING_NOTFOUND )
+ nBegin = 0;
+ else
+ nMaxPathLen += 2; // fuer Prefix <Laufwerk>:
+
+ while( aCutPath.Len() > nMaxPathLen )
+ {
+ USHORT nEnd = aCutPath.Search( cAccDel, nBegin + 1 );
+ USHORT nCount;
+
+ if ( nEnd != STRING_NOTFOUND )
+ {
+ nCount = nEnd - nBegin;
+ aCutPath.Erase( nBegin, nCount );
+ bInsertPrefix = TRUE;
+ }
+ else
+ break;
+ }
+
+ if ( aCutPath.Len() > nMaxPathLen )
+ {
+ for ( USHORT n = nMaxPathLen; n > nMaxPathLen/2; --n )
+ if ( !ByteString(aCutPath.GetChar(n)).IsAlphaNumericAscii() )
+ {
+ aCutPath.Erase( n );
+ aCutPath += "...";
+ break;
+ }
+ }
+
+ if ( bInsertPrefix )
+ {
+ ByteString aIns( cAccDel );
+ aIns += "...";
+ aCutPath.Insert( aIns, nBegin );
+ }
+
+ return aCutPath;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::ImpParseOs2Name()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MI 23.06.95
+|*
+*************************************************************************/
+
+FSysError DirEntry::ImpParseOs2Name( const ByteString& rPfad, FSysPathStyle eStyle )
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ // die einzelnen Namen auf einen Stack packen
+ String aPfad( rPfad, osl_getThreadTextEncoding() );
+ DirEntryStack aStack;
+
+ do
+ {
+ // den Namen vor dem ersten "\\" abspalten,
+ // falls '\\' am Anfang, ist der Name '\\',
+ // der Rest immer ohne die fuehrenden '\\'.
+ // ein ":" trennt ebenfalls, gehoert aber zum Namen
+ // den ersten '\\', '/' oder ':' suchen
+ USHORT nPos;
+ for ( nPos = 0;
+ nPos < aPfad.Len() && //?O
+ aPfad.GetChar(nPos) != '\\' && aPfad.GetChar(nPos) != '/' && //?O
+ aPfad.GetChar(nPos) != ':'; //?O
+ nPos++ )
+ /* do nothing */;
+
+ // ist der Name ein UNC Pathname?
+ if ( nPos == 0 && aPfad.Len() > 1 &&
+ ( ( aPfad.GetChar(0) == '\\' && aPfad.GetChar(1) == '\\' ) ||
+ ( aPfad.GetChar(0) == '/' && aPfad.GetChar(1) == '/' ) ) )
+ {
+ for ( nPos = 2; aPfad.Len() > nPos; ++nPos )
+ if ( aPfad.GetChar(nPos) == '\\' || aPfad.GetChar(nPos) == '/' )
+ break;
+ aName = ByteString( aPfad.Copy( 2, nPos-2 ), osl_getThreadTextEncoding() );
+ aStack.Push( new DirEntry( aName, FSYS_FLAG_ABSROOT, eStyle ) );
+ }
+ // ist der Name die Root des aktuellen Drives?
+ else if ( nPos == 0 && aPfad.Len() > 0 &&
+ ( aPfad.GetChar(0) == '\\' || aPfad.GetChar(0) == '/' ) )
+ {
+ // Root-Directory des aktuellen Drives
+ aStack.Push( new DirEntry( FSYS_FLAG_ABSROOT ) );
+ }
+ else
+ {
+ // ist der Name ein Drive?
+ if ( nPos < aPfad.Len() && aPfad.GetChar(nPos) == ':' )
+ {
+ aName = ByteString( aPfad.Copy( 0, nPos + 1 ), osl_getThreadTextEncoding() );
+
+ // ist der Name die Root des Drives
+ if ( (nPos + 1) < aPfad.Len() &&
+ ( aPfad.GetChar(nPos+1) == '\\' || aPfad.GetChar(nPos+1) == '/' ) )
+ {
+ // schon was auf dem Stack?
+ // oder Novell-Format? (not supported wegen URLs)
+ if ( aStack.Count() || aName.Len() > 2 )
+ {
+ aName = rPfad;
+ return FSYS_ERR_MISPLACEDCHAR;
+ }
+ // Root-Directory des Drive
+ aStack.Push( new DirEntry( aName, FSYS_FLAG_ABSROOT, eStyle ) );
+ }
+ else
+ {
+ // liegt ein anderes Drive auf dem Stack?
+ if ( aStack.Count() &&
+ COMPARE_EQUAL != aStack.Bottom()->aName.CompareIgnoreCaseToAscii(aName) )
+ aStack.Clear();
+
+ // liegt jetzt nichts mehr auf dem Stack?
+ if ( !aStack.Count() )
+ aStack.Push( new DirEntry( aName, FSYS_FLAG_RELROOT, eStyle ) );
+ }
+ }
+
+ // es ist kein Drive
+ else
+ {
+ // den Namen ohne Trenner abspalten
+ aName = ByteString( aPfad.Copy( 0, nPos ), osl_getThreadTextEncoding() );
+
+ // stellt der Name die aktuelle Directory dar?
+ if ( aName == "." )
+ /* do nothing */;
+
+ // stellt der Name die Parent-Directory dar?
+ else if ( aName == ".." )
+ {
+ // ist nichts, ein Parent oder eine relative Root
+ // auf dem Stack?
+ if ( ( aStack.Count() == 0 ) ||
+ ( aStack.Top()->eFlag == FSYS_FLAG_PARENT ) ||
+ ( aStack.Top()->eFlag == FSYS_FLAG_RELROOT ) )
+ // fuehrende Parents kommen auf den Stack
+ aStack.Push( new DirEntry( FSYS_FLAG_PARENT ) );
+
+ // ist es eine absolute Root
+ else if ( aStack.Top()->eFlag == FSYS_FLAG_ABSROOT )
+ {
+ // die hat keine Parent-Directory
+ aName = rPfad;
+ return FSYS_ERR_NOTEXISTS;
+ }
+ else
+ // sonst hebt der Parent den TOS auf
+ delete aStack.Pop();
+ }
+
+ else
+ {
+ if ( eStyle == FSYS_STYLE_FAT )
+ {
+ // ist der Name grundsaetzlich ungueltig?
+ int nPunkte = 0;
+ const char *pChar;
+ for ( pChar = aName.GetBuffer();
+ nPunkte < 2 && *pChar != 0;
+ pChar++ )
+ {
+ if ( *pChar == ';' )
+ nPunkte = 0;
+ else
+ nPunkte += ( *pChar == '.' ) ? 1 : 0;
+ }
+ if ( nPunkte > 1 )
+ {
+ aName = rPfad;
+ return FSYS_ERR_MISPLACEDCHAR;
+ }
+ }
+
+ // normalen Entries kommen auf den Stack
+ DirEntry *pNew = new DirEntry( aName, FSYS_FLAG_NORMAL, eStyle );
+ if ( !pNew->IsValid() )
+ {
+ aName = rPfad;
+ ErrCode eErr = pNew->GetError();
+ delete pNew;
+ return eErr;
+ }
+ aStack.Push( pNew );
+ }
+ }
+ }
+
+ // den Restpfad bestimmen
+ aPfad.Erase( 0, nPos + 1 );
+ while ( aPfad.Len() && ( aPfad.GetChar(0) == '\\' || aPfad.GetChar(0) == '/' ) )
+ aPfad.Erase( 0, 1 );
+ }
+ while ( aPfad.Len() );
+
+ ULONG nErr = ERRCODE_NONE;
+ // Haupt-Entry (selbst) zuweisen
+ if ( aStack.Count() == 0 )
+ {
+ eFlag = FSYS_FLAG_CURRENT;
+ aName.Erase();
+ }
+ else
+ {
+ eFlag = aStack.Top()->eFlag;
+ aName = aStack.Top()->aName;
+ nErr = aStack.Top()->nError;
+ delete aStack.Pop();
+ }
+
+ // die Parent-Entries vom Stack holen
+ DirEntry** pTemp = &pParent; // Zeiger auf den Member pParent setzen
+ while ( aStack.Count() )
+ {
+ *pTemp = aStack.Pop();
+
+ // Zeiger auf den Member pParent des eigenen Parent setzen
+ pTemp = &( (*pTemp)->pParent );
+ }
+
+ // wird damit ein Volume beschrieben?
+ if ( !pParent && eFlag == FSYS_FLAG_RELROOT && aName.Len() )
+ eFlag = FSYS_FLAG_VOLUME;
+
+ // bei gesetztem ErrorCode den Namen komplett "ubernehmen
+ if ( nErr )
+ aName = rPfad;
+ return nErr;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::ImpParseName()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.08.91
+|* Letzte Aenderung MI 26.05.93
+|*
+*************************************************************************/
+
+FSysError DirEntry::ImpParseName( const ByteString& rbInitName,
+ FSysPathStyle eStyle )
+{
+ String rInitName( rbInitName, osl_getThreadTextEncoding() );
+ if ( eStyle == FSYS_STYLE_HOST )
+ eStyle = DEFSTYLE;
+
+ // KI-Division of FSys
+ if ( eStyle == FSYS_STYLE_DETECT )
+ {
+ sal_Unicode cFirst = rInitName.GetChar(0);
+ if ( rInitName.Len() == 2 && rInitName.GetChar(1) == ':' &&
+ ((cFirst >= 'A' && cFirst <= 'Z') ||
+ (cFirst >= 'a' && cFirst <= 'z')))
+ eStyle = FSYS_STYLE_HPFS;
+ else if ( rInitName.Len() > 2 && rInitName.GetChar(1) == ':' )
+ {
+ if ( rInitName.Search( ':', 2 ) == STRING_NOTFOUND )
+ eStyle = FSYS_STYLE_HPFS;
+ else
+ eStyle = FSYS_STYLE_MAC;
+ }
+ else if ( rInitName.Search( '/' ) != STRING_NOTFOUND )
+ eStyle = FSYS_STYLE_BSD;
+ else if ( rInitName.Search( '\\' ) != STRING_NOTFOUND )
+ eStyle = FSYS_STYLE_HPFS;
+ else if ( rInitName.Search( ':' ) != STRING_NOTFOUND )
+ eStyle = FSYS_STYLE_MAC;
+ else
+ eStyle = FSYS_STYLE_HPFS;
+ }
+
+ switch ( eStyle )
+ {
+ case FSYS_STYLE_FAT:
+ case FSYS_STYLE_VFAT:
+ case FSYS_STYLE_HPFS:
+ case FSYS_STYLE_NTFS:
+ case FSYS_STYLE_NWFS:
+ return ImpParseOs2Name( rbInitName, eStyle );
+
+ case FSYS_STYLE_BSD:
+ case FSYS_STYLE_SYSV:
+ return ImpParseUnixName( rbInitName, eStyle );
+
+ case FSYS_STYLE_MAC:
+ return FSYS_ERR_OK;
+
+ default:
+ return FSYS_ERR_UNKNOWN;
+ }
+}
+
+/*************************************************************************
+|*
+|* GetStyle()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 15.11.91
+|* Letzte Aenderung MI 15.11.91
+|*
+*************************************************************************/
+
+static FSysPathStyle GetStyle( FSysPathStyle eStyle )
+{
+ if ( eStyle == FSYS_STYLE_HOST || eStyle == FSYS_STYLE_DETECT )
+ return DEFSTYLE;
+ else
+ return eStyle;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::ImpTrim()
+|*
+|* Beschreibung bringt den Namen auf Betriebssystem-Norm
+|* z.B. 8.3 lower beim MS-DOS Formatter
+|* wirkt nicht rekursiv
+|* Ersterstellung MI 12.08.91
+|* Letzte Aenderung MI 21.05.92
+|*
+*************************************************************************/
+
+void DirEntry::ImpTrim( FSysPathStyle eStyle )
+{
+ // Wildcards werden nicht geclipt
+ if ( ( aName.Search( '*' ) != STRING_NOTFOUND ) ||
+ ( aName.Search( '?' ) != STRING_NOTFOUND ) ||
+ ( aName.Search( ';' ) != STRING_NOTFOUND ) )
+ return;
+
+ switch ( eStyle )
+ {
+ case FSYS_STYLE_FAT:
+ {
+ USHORT nPunktPos = aName.Search( '.' );
+ if ( nPunktPos == STRING_NOTFOUND )
+ {
+ if ( aName.Len() > 8 )
+ {
+ nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
+ aName.Erase( 8 );
+ }
+ }
+ else
+ {
+ if ( nPunktPos > 8 )
+ {
+ nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
+ aName.Erase( 8, nPunktPos - 8 );
+ nPunktPos = 8;
+ }
+ if ( aName.Len() > nPunktPos + 3 )
+ {
+ if ( aName.Len() - nPunktPos > 4 )
+ {
+ nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
+ aName.Erase( nPunktPos + 4 );
+ }
+ }
+ }
+ aName.ToLowerAscii();
+ break;
+ }
+
+ case FSYS_STYLE_VFAT:
+ case FSYS_STYLE_HPFS:
+ case FSYS_STYLE_NTFS:
+ case FSYS_STYLE_NWFS:
+ if ( aName.Len() > 254 )
+ {
+ nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
+ aName.Erase( 254 );
+ }
+
+ if ( eStyle == FSYS_STYLE_HPFS &&
+ ( eFlag == FSYS_FLAG_ABSROOT || eFlag == FSYS_FLAG_RELROOT ) )
+ aName.ToUpperAscii();
+ break;
+
+ case FSYS_STYLE_SYSV:
+ if ( aName.Len() > 14 )
+ {
+ nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
+ aName.Erase( 14 );
+ }
+ break;
+
+ case FSYS_STYLE_BSD:
+ if ( aName.Len() > 250 )
+ {
+ nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
+ aName.Erase( 250 );
+ }
+ break;
+
+ case FSYS_STYLE_MAC:
+ if ( eFlag & ( FSYS_FLAG_ABSROOT | FSYS_FLAG_VOLUME ) )
+ {
+ if ( aName.Len() > 27 )
+ {
+ nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
+ aName.Erase( 27 );
+ }
+ }
+ else
+ {
+ if ( aName.Len() > 31 )
+ {
+ nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
+ aName.Erase( 31 );
+ }
+ }
+ break;
+
+ default:
+ /* kann nicht sein */;
+ }
+}
+
+/*************************************************************************
+|*
+|* DirEntry::DirEntry()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+DirEntry::DirEntry( const ByteString& rName, DirEntryFlag eDirFlag,
+ FSysPathStyle eStyle ) :
+#ifdef FEAT_FSYS_DOUBLESPEED
+ pStat( 0 ),
+#endif
+ aName( rName )
+{
+ DBG_CTOR( DirEntry, ImpCheckDirEntry );
+
+ pParent = NULL;
+ eFlag = eDirFlag;
+ nError = FSYS_ERR_OK;
+
+ ImpTrim( eStyle );
+}
+
+/*************************************************************************
+|*
+|* DirEntry::DirEntry()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+DirEntry::DirEntry( const DirEntry& rOrig ) :
+#ifdef FEAT_FSYS_DOUBLESPEED
+ pStat( rOrig.pStat ? new FileStat(*rOrig.pStat) : 0 ),
+#endif
+ aName( rOrig.aName )
+{
+ DBG_CTOR( DirEntry, ImpCheckDirEntry );
+
+ eFlag = rOrig.eFlag;
+ nError = rOrig.nError;
+
+ if ( rOrig.pParent )
+ {
+ pParent = new DirEntry( *rOrig.pParent );
+ }
+ else
+ {
+ pParent = NULL;
+ }
+}
+
+/*************************************************************************
+|*
+|* DirEntry::DirEntry()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+DirEntry::DirEntry( const String& rInitName, FSysPathStyle eStyle )
+#ifdef FEAT_FSYS_DOUBLESPEED
+ : pStat( 0 )
+#endif
+{
+ DBG_CTOR( DirEntry, ImpCheckDirEntry );
+
+ pParent = NULL;
+
+ // schnelle Loesung fuer Leerstring
+ if ( !rInitName.Len())
+ {
+ eFlag = FSYS_FLAG_CURRENT;
+ nError = FSYS_ERR_OK;
+ return;
+ }
+
+ ByteString aTmpName(rInitName, osl_getThreadTextEncoding());
+ if( eStyle == FSYS_STYLE_URL || aTmpName.CompareIgnoreCaseToAscii("file:",5 ) == COMPARE_EQUAL )
+ {
+#ifndef BOOTSTRAP
+ DBG_WARNING( "File URLs are not permitted but accepted" );
+ aTmpName = ByteString(String(INetURLObject( rInitName ).PathToFileName()), osl_getThreadTextEncoding());
+ eStyle = FSYS_STYLE_HOST;
+#endif // BOOTSTRAP
+ }
+ else
+ {
+ ::rtl::OUString aTmp;
+ ::rtl::OUString aOInitName;
+ if ( FileBase::getFileURLFromSystemPath( OUString( rInitName ), aTmp ) == FileBase::E_None )
+ {
+ aOInitName = OUString( rInitName );
+ aTmpName = ByteString( String(aOInitName), osl_getThreadTextEncoding() );
+ }
+
+#ifdef DBG_UTIL
+ // ASF nur bei Default eStyle, nicht z.B. aus MakeShortName()
+ if( eStyle == FSYS_STYLE_HOST &&
+ aTmpName.Search( "://" ) != STRING_NOTFOUND )
+ {
+ ByteString aErr = "DirEntries akzeptieren nur File URLS: ";
+ aErr += aTmpName;
+ DBG_WARNING( aErr.GetBuffer() );
+ }
+#endif
+ }
+
+ nError = ImpParseName( aTmpName, eStyle );
+
+ if ( nError != FSYS_ERR_OK )
+ eFlag = FSYS_FLAG_INVALID;
+}
+
+/*************************************************************************/
+
+DirEntry::DirEntry( const ByteString& rInitName, FSysPathStyle eStyle )
+#ifdef FEAT_FSYS_DOUBLESPEED
+ : pStat( 0 )
+#endif
+{
+ DBG_CTOR( DirEntry, ImpCheckDirEntry );
+
+ pParent = NULL;
+
+ // schnelle Loesung fuer Leerstring
+ if ( !rInitName.Len() )
+ {
+ eFlag = FSYS_FLAG_CURRENT;
+ nError = FSYS_ERR_OK;
+ return;
+ }
+
+ ByteString aTmpName( rInitName );
+ if( eStyle == FSYS_STYLE_URL || rInitName.CompareIgnoreCaseToAscii("file:",5 ) == COMPARE_EQUAL )
+ {
+#ifndef BOOTSTRAP
+ DBG_WARNING( "File URLs are not permitted but accepted" );
+ aTmpName = ByteString(String(INetURLObject( rInitName ).PathToFileName()), osl_getThreadTextEncoding());
+ eStyle = FSYS_STYLE_HOST;
+#endif
+ }
+#ifdef DBG_UTIL
+ else
+ // ASF nur bei Default eStyle, nicht z.B. aus MakeShortName()
+ if( eStyle == FSYS_STYLE_HOST &&
+ rInitName.Search( "://" ) != STRING_NOTFOUND )
+ {
+ ByteString aErr = "DirEntries akzeptieren nur File URLS: ";
+ aErr += rInitName;
+ DBG_WARNING( aErr.GetBuffer() );
+ }
+#endif
+
+ nError = ImpParseName( aTmpName, eStyle );
+
+ if ( nError != FSYS_ERR_OK )
+ eFlag = FSYS_FLAG_INVALID;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::DirEntry()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+DirEntry::DirEntry( DirEntryFlag eDirFlag )
+#ifdef FEAT_FSYS_DOUBLESPEED
+ : pStat( 0 )
+#endif
+{
+ DBG_CTOR( DirEntry, ImpCheckDirEntry );
+
+ eFlag = eDirFlag;
+ nError = ( eFlag == FSYS_FLAG_INVALID ) ? FSYS_ERR_UNKNOWN : FSYS_ERR_OK;
+ pParent = NULL;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::~DirEntry()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+DirEntry::~DirEntry()
+{
+ DBG_DTOR( DirEntry, ImpCheckDirEntry );
+
+ delete pParent;
+#ifdef FEAT_FSYS_DOUBLESPEED
+ delete pStat;
+#endif
+
+}
+
+/*************************************************************************
+|*
+|* DirEntry::ImpGetTopPtr() const
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+const DirEntry* DirEntry::ImpGetTopPtr() const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ const DirEntry *pTemp = this;
+ while ( pTemp->pParent )
+ pTemp = pTemp->pParent;
+
+ return pTemp;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::ImpGetTopPtr()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 13.11.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+DirEntry* DirEntry::ImpGetTopPtr()
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ DirEntry *pTemp = this;
+ while ( pTemp->pParent )
+ pTemp = pTemp->pParent;
+
+ return pTemp;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::ImpGetPreTopPtr()
+|*
+|* Beschreibung liefert einen Pointer auf den vorletzten Entry
+|* Ersterstellung MI 01.11.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+DirEntry* DirEntry::ImpGetPreTopPtr()
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ DirEntry *pTemp = this;
+ if ( pTemp->pParent )
+ {
+ while ( pTemp->pParent->pParent )
+ pTemp = pTemp->pParent;
+ }
+
+ return pTemp;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::ImpChangeParent()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MI 21.05.92
+|*
+*************************************************************************/
+
+DirEntry* DirEntry::ImpChangeParent( DirEntry* pNewParent, BOOL bNormalize )
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ DirEntry *pTemp = pParent;
+ if ( bNormalize && pNewParent &&
+ pNewParent->eFlag == FSYS_FLAG_RELROOT && !pNewParent->aName.Len() )
+ {
+ pParent = 0;
+ delete pNewParent;
+ }
+ else
+ pParent = pNewParent;
+
+ return pTemp;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::Exists()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MI 24.09.91
+|*
+*************************************************************************/
+
+BOOL DirEntry::Exists( FSysAccess nAccess ) const
+{
+#ifndef BOOTSTRAP
+ static osl::Mutex aLocalMutex;
+ osl::MutexGuard aGuard( aLocalMutex );
+#endif
+ if ( !IsValid() )
+ return FALSE;
+
+#if defined WNT || defined OS2
+ // spezielle Filenamen sind vom System da
+ if ( ( aName.CompareIgnoreCaseToAscii("CLOCK$") == COMPARE_EQUAL ||
+ aName.CompareIgnoreCaseToAscii("CON") == COMPARE_EQUAL ||
+ aName.CompareIgnoreCaseToAscii("AUX") == COMPARE_EQUAL ||
+ aName.CompareIgnoreCaseToAscii("COM1") == COMPARE_EQUAL ||
+ aName.CompareIgnoreCaseToAscii("COM2") == COMPARE_EQUAL ||
+ aName.CompareIgnoreCaseToAscii("COM3") == COMPARE_EQUAL ||
+ aName.CompareIgnoreCaseToAscii("COM4") == COMPARE_EQUAL ||
+ aName.CompareIgnoreCaseToAscii("LPT1") == COMPARE_EQUAL ||
+ aName.CompareIgnoreCaseToAscii("LPT2") == COMPARE_EQUAL ||
+ aName.CompareIgnoreCaseToAscii("LPT3") == COMPARE_EQUAL ||
+ aName.CompareIgnoreCaseToAscii("NUL") == COMPARE_EQUAL ||
+ aName.CompareIgnoreCaseToAscii("PRN") == COMPARE_EQUAL ) )
+ return TRUE;
+#endif
+
+ FSysFailOnErrorImpl();
+ DirEntryKind eKind = FileStat( *this, nAccess ).GetKind();
+ if ( eKind & ( FSYS_KIND_FILE | FSYS_KIND_DIR ) )
+ {
+ return TRUE;
+ }
+
+#if defined WNT || defined OS2
+ if ( 0 != ( eKind & FSYS_KIND_DEV ) )
+ {
+ return DRIVE_EXISTS( ImpGetTopPtr()->aName.GetChar(0) );
+ }
+#endif
+
+ return 0 != ( eKind & ( FSYS_KIND_FILE | FSYS_KIND_DIR ) );
+}
+
+/*************************************************************************
+|*
+|* DirEntry::First()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 15.01.92
+|*
+*************************************************************************/
+
+BOOL DirEntry::First()
+{
+ FSysFailOnErrorImpl();
+
+ String aUniPathName( GetPath().GetFull() );
+#ifndef BOOTSTRAP
+ FSysRedirector::DoRedirect( aUniPathName );
+ ByteString aPathName(aUniPathName, osl_getThreadTextEncoding());
+#else
+ ByteString aPathName(aUniPathName, gsl_getSystemTextEncoding());
+#endif
+ aPathName = GUI2FSYS( aPathName );
+
+ DIR *pDir = opendir( (char*) aPathName.GetBuffer() );
+ if ( pDir )
+ {
+#ifndef BOOTSTRAP
+ WildCard aWildeKarte( String(CMP_LOWER( aName ), osl_getThreadTextEncoding()) );
+#else
+ WildCard aWildeKarte( String(CMP_LOWER( aName ), gsl_getSystemTextEncoding()) );
+#endif
+ for ( dirent* pEntry = readdir( pDir );
+ pEntry;
+ pEntry = readdir( pDir ) )
+ {
+ ByteString aFound( FSYS2GUI( ByteString( pEntry->d_name ) ) );
+ if ( aWildeKarte.Matches( String(CMP_LOWER( aFound ), osl_getThreadTextEncoding())))
+ {
+ aName = aFound;
+ closedir( pDir );
+ return TRUE;
+ }
+ }
+ closedir( pDir );
+ }
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::GetFull()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+String DirEntry::GetFull( FSysPathStyle eStyle, BOOL bWithDelimiter,
+ USHORT nMaxChars ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ ByteString aRet;
+ eStyle = GetStyle( eStyle );
+ if ( pParent )
+ {
+ if ( ( pParent->eFlag == FSYS_FLAG_ABSROOT ||
+ pParent->eFlag == FSYS_FLAG_RELROOT ||
+ pParent->eFlag == FSYS_FLAG_VOLUME ) )
+ {
+ aRet = ByteString(pParent->GetName( eStyle ), osl_getThreadTextEncoding());
+ aRet += ByteString(GetName( eStyle ), osl_getThreadTextEncoding());
+ }
+ else
+ {
+ aRet = ByteString(pParent->GetFull( eStyle ), osl_getThreadTextEncoding());
+ aRet += ACCESSDELIM_C(eStyle);
+ aRet += ByteString(GetName( eStyle ), osl_getThreadTextEncoding());
+ }
+ }
+ else
+ {
+ aRet = ByteString(GetName( eStyle ), osl_getThreadTextEncoding());
+ }
+
+ if ( ( eStyle == FSYS_STYLE_MAC ) &&
+ ( ImpGetTopPtr()->eFlag != FSYS_FLAG_VOLUME ) &&
+ ( ImpGetTopPtr()->eFlag != FSYS_FLAG_ABSROOT ) &&
+ ( aRet.GetChar(0) != ':' ) )
+ aRet.Insert( ACCESSDELIM_C(eStyle), 0 );
+
+ //! Hack
+ if ( bWithDelimiter )
+ if ( aRet.GetChar( aRet.Len()-1 ) != ACCESSDELIM_C(eStyle) )
+ aRet += ACCESSDELIM_C(eStyle);
+
+ //! noch ein Hack
+ if ( nMaxChars < STRING_MAXLEN )
+ aRet = ImplCutPath( aRet, nMaxChars, ACCESSDELIM_C(eStyle) );
+
+ return String(aRet, osl_getThreadTextEncoding());
+}
+
+/*************************************************************************
+|*
+|* DirEntry::GetPath()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+DirEntry DirEntry::GetPath() const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ if ( pParent )
+ return DirEntry( *pParent );
+
+ return DirEntry();
+}
+
+/*************************************************************************
+|*
+|* DirEntry::GetExtension()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+String DirEntry::GetExtension( char cSep ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ const char *p0 = ( aName.GetBuffer() );
+ const char *p1 = p0 + aName.Len() - 1;
+ while ( p1 >= p0 && *p1 != cSep )
+ p1--;
+
+ if ( p1 >= p0 )
+ // es wurde ein cSep an der Position p1 gefunden
+ return String(
+ aName.Copy( static_cast< xub_StrLen >(p1 - p0 + 1) ),
+ osl_getThreadTextEncoding());
+ return String();
+}
+
+/*************************************************************************
+|*
+|* DirEntry::GetBase()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+String DirEntry::GetBase( char cSep ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ const char *p0 = ( aName.GetBuffer() );
+ const char *p1 = p0 + aName.Len() - 1;
+ while ( p1 >= p0 && *p1 != cSep )
+ p1--;
+
+ if ( p1 >= p0 )
+ // es wurde ein cSep an der Position p1 gefunden
+ return String(
+ aName.Copy( 0, static_cast< xub_StrLen >(p1 - p0) ),
+ osl_getThreadTextEncoding());
+
+ else
+ // es wurde kein cSep gefunden
+ return String(aName, osl_getThreadTextEncoding());
+}
+
+/*************************************************************************
+|*
+|* DirEntry::GetName()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91 13:47
+|*
+*************************************************************************/
+
+String DirEntry::GetName( FSysPathStyle eStyle ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ ByteString aRet;
+ eStyle = GetStyle( eStyle );
+
+ switch( eFlag )
+ {
+ case FSYS_FLAG_PARENT:
+ aRet = ACTPARENT(eStyle);
+ break;
+
+ case FSYS_FLAG_ABSROOT:
+ {
+ if ( eStyle == FSYS_STYLE_URL )
+ {
+ aRet = "file:///";
+ aRet += aName;
+
+#ifndef UNX
+ if ( aName.Len())
+ {
+ if ( aName.GetChar(aName.Len()-1) == ':' )
+ {
+ aRet.SetChar(aRet.Len()-1, '|');
+ }
+ else
+ {
+ aRet.Insert( '/', 5 );
+ }
+ aRet += "/";
+ }
+#endif
+ }
+ else if ( eStyle != FSYS_STYLE_MAC &&
+ aName.Len() > 1 && aName.GetChar( 1 ) != ':' )
+ {
+ // UNC-Pathname
+ aRet = ACCESSDELIM_C(eStyle);
+ aRet += ACCESSDELIM_C(eStyle);
+ aRet += aName ;
+ aRet += ACCESSDELIM_C(eStyle);
+ }
+ else
+ {
+ aRet = aName;
+ aRet += ACCESSDELIM_C(eStyle);
+ }
+ break;
+ }
+
+ case FSYS_FLAG_INVALID:
+ case FSYS_FLAG_VOLUME:
+ {
+ if ( eStyle == FSYS_STYLE_URL )
+ {
+ aRet = "file:///";
+ aRet += aName;
+#ifndef UNX
+ if ( aName.Len() && aName.GetChar(aName.Len()-1) == ':' )
+ {
+ aRet.SetChar(aRet.Len()-1, '|');
+ }
+#endif
+ }
+ else
+ {
+ aRet = aName;
+ }
+
+ break;
+ }
+
+ case FSYS_FLAG_RELROOT:
+ if ( !aName.Len() )
+ {
+ aRet = ACTCURRENT(eStyle);
+ break;
+ }
+
+ default:
+ aRet = aName;
+ }
+
+ return String(aRet, osl_getThreadTextEncoding());
+}
+
+/*************************************************************************
+|*
+|* DirEntry::IsAbs()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+bool DirEntry::IsAbs() const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+#ifdef UNX
+ return ( pParent ? pParent->IsAbs() : eFlag == FSYS_FLAG_ABSROOT );
+#else
+ return ( pParent ? pParent->IsAbs() : eFlag == FSYS_FLAG_ABSROOT && aName.Len() > 0 );
+#endif
+}
+
+/*************************************************************************
+|*
+|* DirEntry::CutName()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+String DirEntry::CutName( FSysPathStyle eStyle )
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ eStyle = GetStyle( eStyle );
+
+ String aOldName( GetName( eStyle ) );
+
+ if ( pParent )
+ {
+ DirEntry *pOldParent = pParent;
+ if ( pOldParent )
+ {
+ pParent = pOldParent->pParent;
+ eFlag = pOldParent->eFlag;
+ aName = pOldParent->aName;
+ pOldParent->pParent = NULL;
+ delete pOldParent;
+ }
+ else
+ {
+ eFlag = FSYS_FLAG_CURRENT;
+ aName.Erase();
+ }
+ }
+ else
+ {
+ eFlag = FSYS_FLAG_CURRENT;
+ aName.Erase();
+ delete pParent;
+ pParent = NULL;
+ }
+
+ return aOldName;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::NameCompare
+|*
+|* Beschreibung Vergleich nur die Namen (ohne Pfad, aber mit Gross/Klein)
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+StringCompare DirEntry::NameCompare( const DirEntry &rWith ) const
+{
+ ByteString aThisName;
+ ByteString aParameterName;
+
+#ifdef UNX
+ aThisName = aName;
+ aParameterName = rWith.aName;
+#else
+ aThisName = ByteString(aName).ToLowerAscii();
+ aParameterName = ByteString(rWith.aName).ToLowerAscii();
+#endif
+
+ return aThisName.CompareTo( aParameterName );
+}
+
+
+/*************************************************************************
+|*
+|* DirEntry::operator==()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+BOOL DirEntry::operator==( const DirEntry& rEntry ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ // test wheather the contents are textual the same
+
+ if ( nError && ( nError == rEntry.nError ) )
+ return TRUE;
+ if ( nError || rEntry.nError ||
+ ( eFlag == FSYS_FLAG_INVALID ) ||
+ ( rEntry.eFlag == FSYS_FLAG_INVALID ) )
+ return FALSE;
+
+#ifndef OS2
+ const
+#endif
+ DirEntry *pThis = (DirEntry *)this;
+#ifndef OS2
+ const
+#endif
+ DirEntry *pWith = (DirEntry *)&rEntry;
+ while( pThis && pWith && (pThis->eFlag == pWith->eFlag) )
+ {
+ if ( CMP_LOWER(pThis->aName) != CMP_LOWER(pWith->aName) )
+ break;
+ pThis = pThis->pParent;
+ pWith = pWith->pParent;
+ }
+
+ return ( !pThis && !pWith );
+}
+
+/*************************************************************************
+|*
+|* DirEntry::operator=()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+DirEntry& DirEntry::operator=( const DirEntry& rEntry )
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ if ( this == &rEntry )
+ return *this;
+ if ( rEntry.nError != FSYS_ERR_OK ) {
+ DBG_ERROR("Zuweisung mit invalidem DirEntry");
+ nError = rEntry.nError;
+ return *this;
+ }
+
+ // Name und Typ uebernehmen, Refs beibehalten
+ aName = rEntry.aName;
+ eFlag = rEntry.eFlag;
+ nError = FSYS_ERR_OK;
+
+ DirEntry *pOldParent = pParent;
+ if ( rEntry.pParent )
+ pParent = new DirEntry( *rEntry.pParent );
+ else
+ pParent = NULL;
+
+ if ( pOldParent )
+ delete pOldParent;
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::operator+()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+DirEntry DirEntry::operator+( const DirEntry& rEntry ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+#ifdef DBG_UTIL
+ static BOOL bTested = FALSE;
+ if ( !bTested )
+ {
+ bTested = TRUE;
+ FSysTest();
+ }
+#endif
+
+ const DirEntry *pEntryTop = rEntry.ImpGetTopPtr();
+ const DirEntry *pThisTop = ImpGetTopPtr();
+
+ // "." + irgendwas oder irgendwas + "d:irgendwas"
+/* TPF:org
+ if ( ( eFlag == FSYS_FLAG_RELROOT && !aName ) ||
+ ( pEntryTop->aName.Len() &&
+ ( pEntryTop->eFlag == FSYS_FLAG_ABSROOT ||
+ pEntryTop->eFlag == FSYS_FLAG_RELROOT ||
+ pEntryTop->eFlag == FSYS_FLAG_VOLUME ) ) )
+ return rEntry;
+*/
+
+ if (
+ (eFlag == FSYS_FLAG_RELROOT && !aName.Len()) ||
+ (
+ (pEntryTop->aName.Len() ||
+ ((rEntry.Level()>1)?(rEntry[rEntry.Level()-2].aName.CompareIgnoreCaseToAscii(RFS_IDENTIFIER)==COMPARE_EQUAL):FALSE))
+ &&
+ (pEntryTop->eFlag == FSYS_FLAG_ABSROOT ||
+ pEntryTop->eFlag == FSYS_FLAG_RELROOT ||
+ pEntryTop->eFlag == FSYS_FLAG_VOLUME)
+ )
+ )
+ {
+ return rEntry;
+ }
+
+ // irgendwas + "." (=> pEntryTop == &rEntry)
+ if ( pEntryTop->eFlag == FSYS_FLAG_RELROOT && !pEntryTop->aName.Len() )
+ {
+ DBG_ASSERT( pEntryTop == &rEntry, "DirEntry::op+ buggy" );
+ return *this;
+ }
+
+ // root += ".." (=> unmoeglich)
+ if ( pEntryTop->eFlag == FSYS_FLAG_PARENT && pThisTop == this &&
+ ( eFlag == FSYS_FLAG_ABSROOT ) )
+ return DirEntry( FSYS_FLAG_INVALID );
+
+ // irgendwas += abs (=> nur Device uebernehmen falls vorhanden)
+ if ( pEntryTop->eFlag == FSYS_FLAG_ABSROOT )
+ {
+ ByteString aDevice;
+ if ( pThisTop->eFlag == FSYS_FLAG_ABSROOT )
+ aDevice = pThisTop->aName;
+ DirEntry aRet = rEntry;
+ if ( aDevice.Len() )
+ aRet.ImpGetTopPtr()->aName = aDevice;
+ return aRet;
+ }
+
+ // irgendwas += ".." (=> aufloesen)
+ if ( eFlag == FSYS_FLAG_NORMAL && pEntryTop->eFlag == FSYS_FLAG_PARENT )
+ {
+ String aConcated( GetFull() );
+ aConcated += ACCESSDELIM_C(FSYS_STYLE_HOST);
+ aConcated += rEntry.GetFull();
+ return DirEntry( aConcated );
+ }
+
+ // sonst einfach hintereinander haengen
+ DirEntry aRet( rEntry );
+ DirEntry *pTop = aRet.ImpGetTopPtr();
+ pTop->pParent = new DirEntry( *this );
+
+ return aRet;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::operator+=()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+DirEntry &DirEntry::operator+=( const DirEntry& rEntry )
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ return *this = *this + rEntry;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::GetAccessDelimiter()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 27.05.93
+|* Letzte Aenderung MI 10.06.93
+|*
+*************************************************************************/
+
+String DirEntry::GetAccessDelimiter( FSysPathStyle eFormatter )
+{
+ return String( ACCESSDELIM_C( GetStyle( eFormatter ) ) );
+}
+
+/*************************************************************************
+|*
+|* DirEntry::SetExtension()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 02.08.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+void DirEntry::SetExtension( const String& rExtension, char cSep )
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ // do not set extensions for drives
+ if(eFlag == FSYS_FLAG_ABSROOT)
+ {
+ nError = FSYS_ERR_NOTSUPPORTED;
+ return;
+ }
+
+ // cSep im Namen suchen
+ const char *p0 = ( aName.GetBuffer() );
+ const char *p1 = p0 + aName.Len() - 1;
+ while ( p1 >= p0 && *p1 != cSep )
+ p1--;
+ if ( p1 >= p0 )
+ {
+ // es wurde ein cSep an der Position p1 gefunden
+ aName.Erase(
+ static_cast< xub_StrLen >(
+ p1 - p0 + 1 - ( rExtension.Len() ? 0 : 1 )) );
+ aName += ByteString(rExtension, osl_getThreadTextEncoding());
+ }
+ else if ( rExtension.Len() )
+ {
+ // es wurde kein cSep gefunden
+ aName += cSep;
+ aName += ByteString(rExtension, osl_getThreadTextEncoding());
+ }
+}
+
+/*************************************************************************
+|*
+|* DirEntry::CutExtension()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 23.07.93
+|* Letzte Aenderung MI 23.07.93
+|*
+*************************************************************************/
+
+String DirEntry::CutExtension( char cSep )
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ const char *p0 = ( aName.GetBuffer() );
+ const char *p1 = p0 + aName.Len() - 1;
+ while ( p1 >= p0 && *p1 != cSep )
+ p1--;
+
+ if ( p1 >= p0 )
+ {
+ // es wurde ein cSep an der Position p1 gefunden
+ aName.Erase( static_cast< xub_StrLen >(p1-p0) );
+ return String(p1 + 1, osl_getThreadTextEncoding());
+ }
+
+ return String();
+}
+
+/*************************************************************************
+|*
+|* DirEntry::SetName()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 04.09.93
+|* Letzte Aenderung MI 04.09.93
+|*
+*************************************************************************/
+
+void DirEntry::SetName( const String& rName, FSysPathStyle eFormatter )
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ if ( eFormatter == FSYS_STYLE_HOST || eFormatter == FSYS_STYLE_DETECT )
+ eFormatter = DEFSTYLE;
+ ByteString aAccDelim( ACCESSDELIM_C( eFormatter ) );
+
+ if ( (eFlag != FSYS_FLAG_NORMAL) ||
+ (aName.Search( ':' ) != STRING_NOTFOUND) ||
+ (aName.Search( aAccDelim ) != STRING_NOTFOUND) ||
+ (eFormatter == FSYS_STYLE_FAT && (aName.GetTokenCount( '.' ) > 2) ) )
+ {
+ eFlag = FSYS_FLAG_INVALID;
+ }
+ else
+ {
+ aName = ByteString(rName, osl_getThreadTextEncoding());
+ }
+}
+
+/*************************************************************************
+|*
+|* DirEntry::Find()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+BOOL DirEntry::Find( const String& rPfad, char cDelim )
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ if ( ImpGetTopPtr()->eFlag == FSYS_FLAG_ABSROOT )
+ return TRUE;
+
+ BOOL bWild = aName.Search( '*' ) != STRING_NOTFOUND ||
+ aName.Search( '?' ) != STRING_NOTFOUND;
+ if ( !cDelim )
+ cDelim = SEARCHDELIM(DEFSTYLE)[0];
+
+ USHORT nTokenCount = rPfad.GetTokenCount( cDelim );
+ USHORT nIndex = 0;
+ ByteString aThis = ACCESSDELIM(DEFSTYLE);
+ aThis += ByteString(GetFull(), osl_getThreadTextEncoding());
+ for ( USHORT nToken = 0; nToken < nTokenCount; ++nToken )
+ {
+ ByteString aPath = ByteString(rPfad, osl_getThreadTextEncoding()).GetToken( 0, cDelim, nIndex );
+
+ if ( aPath.Len() )
+ {
+ if (aPath.GetChar(aPath.Len()-1)== ACCESSDELIM(DEFSTYLE)[0])
+ aPath.Erase(aPath.Len()-1);
+ aPath += aThis;
+ DirEntry aEntry( String(aPath, osl_getThreadTextEncoding()));
+ if ( aEntry.ToAbs() &&
+ ( ( !bWild && aEntry.Exists() ) || ( bWild && aEntry.First() ) ) )
+ {
+ (*this) = aEntry;
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::ImpToRel()
+|*
+|* Beschreibung
+|* Ersterstellung MI 17.06.93
+|* Letzte Aenderung MI 17.06.93
+|*
+*************************************************************************/
+
+BOOL DirEntry::ImpToRel( String aCurStr )
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ DirEntry aThis(*this);
+ aThis.ToAbs();
+ String aThisStr( aThis.GetFull( FSYS_STYLE_HPFS ) );
+
+ // #109512 preserve case of path even if caseinsensitive
+ String aThisCompareStr( aThisStr ), aCurCompareStr( aCurStr );
+ if ( ! IsCaseSensitive() )
+ {
+ aThisCompareStr.ToLowerAscii();
+ aCurCompareStr.ToLowerAscii();
+ }
+
+ // "Ubereinstimmung pr"ufen
+ USHORT nPos = aThisCompareStr.Match( aCurCompareStr );
+ if ( nPos == STRING_MATCH && aThisStr.Len() != aCurStr.Len() )
+ nPos = Min( aThisStr.Len(), aCurStr.Len() );
+
+ // Sonderfall, die DirEntries sind identisch
+ if ( nPos == STRING_MATCH )
+ {
+ // dann ist der relative Pfad das aktuelle Verzeichnis
+ *this = DirEntry();
+ return TRUE;
+ }
+
+ // Sonderfall, die DirEntries sind total verschieden
+ if ( nPos == 0 )
+ {
+ // dann ist der relativste Pfad absolut
+ *this = aThis;
+ return FALSE;
+ }
+
+ // sonst nehmen wir die identischen Einzelteile vorne weg
+ while ( nPos > 0 && aThisStr.GetChar(nPos) != '\\' )
+ --nPos;
+ aThisStr.Erase( 0, nPos + ( ( aThisStr.GetChar(nPos) == '\\' ) ? 1 : 0 ) );
+ aCurStr.Erase( 0, nPos + ( ( aCurStr.GetChar(nPos) == '\\' ) ? 1 : 0 ) );
+
+ // und fuellen mit dem Level der Directories auf
+ for ( nPos = 0; nPos < aCurStr.Len(); ++nPos )
+ if ( aCurStr.GetChar(nPos) == '\\' )
+ aThisStr.Insert( String( "..\\", osl_getThreadTextEncoding() ), 0 );
+
+ // das ist dann unser relativer Pfad
+ *this = DirEntry( aThisStr, FSYS_STYLE_HPFS );
+ return TRUE;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::CutRelParents()
+|*
+|* Beschreibung
+|* Ersterstellung MI 01.08.95
+|* Letzte Aenderung MI 01.08.95
+|*
+*************************************************************************/
+
+USHORT DirEntry::CutRelParents()
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ // erstes '..' finden
+ DirEntry *pDir = 0;
+ DirEntry *pPar;
+
+ for ( pPar = this;
+ pPar && pPar->eFlag != FSYS_FLAG_PARENT;
+ pPar = pPar->pParent )
+ pDir = pPar;
+
+ // '..' zaehlen
+ USHORT nParCount = 0;
+ while ( pPar && pPar->eFlag == FSYS_FLAG_PARENT )
+ {
+ ++nParCount;
+ pPar = pPar->pParent;
+ }
+
+ // cutten
+ if ( pDir )
+ DELETEZ(pDir->pParent);
+ else
+ eFlag = FSYS_FLAG_CURRENT;
+
+ return nParCount;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::ToRel()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.06.93
+|* Letzte Aenderung MI 17.06.93
+|*
+*************************************************************************/
+
+BOOL DirEntry::ToRel()
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ DirEntry aCur;
+ aCur.ToAbs();
+ return ImpToRel( aCur.GetFull( FSYS_STYLE_HPFS ) );
+}
+
+/*************************************************************************
+|*
+|* DirEntry::ToRel()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+BOOL DirEntry::ToRel( const DirEntry& rStart )
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ DirEntry aStart( rStart );
+ aStart.ToAbs();
+ return ImpToRel( aStart.GetFull( FSYS_STYLE_HPFS ) );
+}
+
+/*************************************************************************
+|*
+|* DirEntry::GetDevice()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+#ifndef UNX
+
+DirEntry DirEntry::GetDevice() const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ const DirEntry *pTop = ImpGetTopPtr();
+
+ if ( ( pTop->eFlag == FSYS_FLAG_ABSROOT || pTop->eFlag == FSYS_FLAG_RELROOT ) &&
+ pTop->aName.Len() )
+ return DirEntry( pTop->aName, FSYS_FLAG_VOLUME, FSYS_STYLE_HOST );
+ else
+ return DirEntry( ByteString(), FSYS_FLAG_INVALID, FSYS_STYLE_HOST );
+}
+
+#endif
+
+/*************************************************************************
+|*
+|* DirEntry::SetBase()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 23.10.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+void DirEntry::SetBase( const String& rBase, char cSep )
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ const char *p0 = ( aName.GetBuffer() );
+ const char *p1 = p0 + aName.Len() - 1;
+ while ( p1 >= p0 && *p1 != cSep )
+ p1--;
+
+ if ( p1 >= p0 )
+ {
+ // es wurde ein cSep an der Position p1 gefunden
+ aName.Erase( 0, static_cast< xub_StrLen >(p1 - p0) );
+ aName.Insert( ByteString(rBase, osl_getThreadTextEncoding()), 0 );
+ }
+ else
+ aName = ByteString(rBase, osl_getThreadTextEncoding());
+}
+
+/*************************************************************************
+|*
+|* DirEntry::GetSearchDelimiter()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 10.06.93
+|* Letzte Aenderung MI 10.06.93
+|*
+*************************************************************************/
+
+String DirEntry::GetSearchDelimiter( FSysPathStyle eFormatter )
+{
+ return String( ByteString(SEARCHDELIM( GetStyle( eFormatter ) ) ), osl_getThreadTextEncoding());
+}
+
+/*************************************************************************
+|*
+|* DirEntry::GetMaxNameLen()
+|*
+|* Beschreibung Liefert die maximale Anzahl von Zeichen in
+|* einzelnen Namensteile. Bei FileSystmen mit
+|* fester Extension (FAT) zaehlt diese nicht mit.
+|* Bei unbekannten FileSytemen und FSYS_STYLE_URL
+|* wird USHRT_MAX zurueckgegeben.
+|* Ersterstellung MI 17.06.97
+|* Letzte Aenderung MI 17.06.97
+|*
+*************************************************************************/
+
+USHORT DirEntry::GetMaxNameLen( FSysPathStyle eFormatter )
+{
+ eFormatter = GetStyle( eFormatter );
+ switch ( eFormatter )
+ {
+ case FSYS_STYLE_MAC: return 31;
+
+ case FSYS_STYLE_FAT: return 8;
+
+ case FSYS_STYLE_VFAT:
+ case FSYS_STYLE_NTFS:
+ case FSYS_STYLE_NWFS:
+ case FSYS_STYLE_HPFS: return 255;
+
+
+ case FSYS_STYLE_SYSV: return 14;
+
+ case FSYS_STYLE_BSD: return 250;
+
+ default:
+ return USHRT_MAX;
+ }
+}
+
+/*************************************************************************
+|*
+|* DirEntry::TempName()
+|*
+|* Beschreibung FSYS.SDW - Aha, wo?
+|* Ersterstellung VB 06.09.93 (im SWG)
+|* Letzte Aenderung MI 06.02.98
+|*
+*************************************************************************/
+namespace { struct TempNameBase_Impl : public rtl::Static< DirEntry, TempNameBase_Impl > {}; }
+
+const DirEntry& DirEntry::SetTempNameBase( const String &rBase )
+{
+ DirEntry aTempDir = DirEntry().TempName().GetPath();
+ aTempDir += DirEntry( rBase );
+#ifdef UNX
+ ByteString aName( aTempDir.GetFull(), osl_getThreadTextEncoding());
+ if ( access( aName.GetBuffer(), W_OK | X_OK | R_OK ) )
+ {
+ // Create the directory and only on success give all rights to
+ // everyone. Use mkdir instead of DirEntry::MakeDir because
+ // this returns TRUE even if directory already exists.
+
+ if ( !mkdir( aName.GetBuffer(), S_IRWXU | S_IRWXG | S_IRWXO ) )
+ chmod( aName.GetBuffer(), S_IRWXU | S_IRWXG | S_IRWXO );
+
+ // This will not create a directory but perhaps FileStat called
+ // there modifies the DirEntry
+
+ aTempDir.MakeDir();
+ }
+#else
+ aTempDir.MakeDir();
+#endif
+ DirEntry &rEntry = TempNameBase_Impl::get();
+ rEntry = aTempDir.TempName( FSYS_KIND_DIR );
+ return rEntry;
+}
+
+DirEntry DirEntry::TempName( DirEntryKind eKind ) const
+{
+ // ggf. Base-Temp-Dir verwenden (macht Remote keinen Sinn => vorher)
+ const DirEntry &rEntry = TempNameBase_Impl::get();
+ if ( !pParent && FSYS_FLAG_CURRENT != rEntry.eFlag && FSYS_FLAG_ABSROOT != eFlag )
+
+ {
+ DirEntry aFactory( rEntry );
+ aFactory += GetName();
+ return aFactory.TempName();
+ }
+
+ ByteString aDirName; // hiermit hatte MPW C++ Probleme - immmer noch??
+ char *ret_val;
+ size_t i;
+
+ // dertermine Directory, Prefix and Extension
+ char pfx[6];
+ char ext[5];
+ const char *dir;
+ const char *pWild = strchr( aName.GetBuffer(), '*' );
+ if ( !pWild )
+ pWild = strchr( aName.GetBuffer(), '?' );
+
+ if ( pWild )
+ {
+ if ( pParent )
+ aDirName = ByteString(pParent->GetFull(), osl_getThreadTextEncoding());
+ strncpy( pfx, aName.GetBuffer(), Min( (int)5, (int)(pWild-aName.GetBuffer()) ) );
+ pfx[ pWild-aName.GetBuffer() ] = 0;
+ const char *pExt = strchr( pWild, '.' );
+ if ( pExt )
+ {
+ strncpy( ext, pExt, 4 );
+ ext[4] = 0;
+ }
+ else
+ strcpy( ext, ".tmp" );
+ }
+ else
+ {
+ aDirName = ByteString(GetFull(), osl_getThreadTextEncoding());
+ strcpy( pfx, "sv" );
+ strcpy( ext, ".tmp" );
+ }
+ dir = aDirName.GetBuffer();
+
+ // wurde kein Dir angegeben, dann nehmen wir ein passendes TEMP-Verz.
+ char sBuf[_MAX_PATH];
+ if ( eFlag == FSYS_FLAG_CURRENT || ( !pParent && pWild ) )
+ dir = TempDirImpl(sBuf);
+
+ // ab hier leicht modifizierter Code von VB
+ DirEntry aRet(FSYS_FLAG_INVALID);
+ i = strlen(dir);
+ // need to add ?\\? + prefix + number + pid + .ext + '\0'
+# define TMPNAME_SIZE ( 1 + 5 + 5 + 10 + 4 + 1 )
+ ret_val = new char[i + TMPNAME_SIZE ];
+ if (ret_val)
+ {
+ strcpy(ret_val,dir);
+
+ /* Make sure directory ends with a separator */
+#if defined(WNT) || defined(OS2)
+ if ( i>0 && ret_val[i-1] != '\\' && ret_val[i-1] != '/' &&
+ ret_val[i-1] != ':')
+ ret_val[i++] = '\\';
+#elif defined UNX
+ if (i>0 && ret_val[i-1] != '/')
+ ret_val[i++] = '/';
+#else
+#error unknown operating system
+#endif
+
+ strncpy(ret_val + i, pfx, 5);
+ ret_val[i + 5] = '\0'; /* strncpy doesn't put a 0 if more */
+ i = strlen(ret_val); /* than 'n' chars. */
+
+ /* Prefix can have 5 chars, leaving 3 for numbers. 26 ** 3 == 17576
+ * Welcome to the 21st century, we can have longer filenames now ;)
+ * New format: pfx + "5 char milli/micro second res" + "current pid" + ".tmp"
+ */
+#if (defined MSC || defined __MINGW32__) && defined WNT
+ /* Milliseconds !! */
+ static unsigned long u = GetTickCount();
+ unsigned long mypid = static_cast<unsigned long>(_getpid());
+#else
+ /* Microseconds !! */
+ static unsigned long u = clock();
+ unsigned long mypid = static_cast<unsigned long>(getpid());
+#endif
+ for ( unsigned long nOld = u; ++u != nOld; ) /* Hae??? */
+ {
+ u %= 100000; /* on *NIX repeats every 100ms, maybe less if CLOCKS_PER_SEC > 10^6 */
+ snprintf(ret_val+i, TMPNAME_SIZE, "%05lu%lu", u, mypid);
+
+ strcat(ret_val,ext);
+
+ if ( FSYS_KIND_FILE == eKind )
+ {
+ SvFileStream aStream( String( ret_val, osl_getThreadTextEncoding()),
+ STREAM_WRITE|STREAM_SHARE_DENYALL );
+ if ( aStream.IsOpen() )
+ {
+ aStream.Seek( STREAM_SEEK_TO_END );
+ if ( 0 == aStream.Tell() )
+ {
+ aRet = DirEntry( String( ret_val, osl_getThreadTextEncoding()));
+ break;
+ }
+ aStream.Close();
+ }
+ }
+ else
+ {
+ // Redirect
+ String aRetVal(ret_val, osl_getThreadTextEncoding());
+ String aRedirected (aRetVal);
+#ifndef BOOTSTRAP
+ FSysRedirector::DoRedirect( aRedirected );
+#endif
+ if ( FSYS_KIND_DIR == eKind )
+ {
+ if ( 0 == _mkdir( ByteString(aRedirected.GetBuffer(), osl_getThreadTextEncoding()).GetBuffer() ) )
+ {
+ aRet = DirEntry( aRetVal );
+ break;
+ }
+ }
+ else
+ {
+#if defined(UNX) || defined(OS2)
+ if( access( ByteString(aRedirected, osl_getThreadTextEncoding()).GetBuffer(), F_OK ) )
+ {
+ aRet = DirEntry( aRetVal );
+ break;
+ }
+#else
+ struct stat aStat;
+ if ( stat( ByteString(aRedirected, osl_getThreadTextEncoding()).GetBuffer(), &aStat ) )
+ {
+ aRet = DirEntry( aRetVal );
+ break;
+ }
+#endif
+ }
+ }
+ }
+
+ delete[] ret_val;
+ ret_val = 0;
+ }
+
+ return aRet;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::operator[]()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 03.03.92
+|* Letzte Aenderung MI 03.03.92
+|*
+*************************************************************************/
+
+const DirEntry &DirEntry::operator[]( USHORT nParentLevel ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ //TPF: maybe to be implemented (FastFSys)
+
+ const DirEntry *pRes = this;
+ while ( pRes && nParentLevel-- )
+ pRes = pRes->pParent;
+
+ return *pRes;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::ImpParseUnixName()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MI 26.05.93
+|*
+*************************************************************************/
+
+FSysError DirEntry::ImpParseUnixName( const ByteString& rPfad, FSysPathStyle eStyle )
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ // die einzelnen Namen auf einen Stack packen
+ DirEntryStack aStack;
+ ByteString aPfad( rPfad );
+ do
+ {
+ // den Namen vor dem ersten "/" abspalten,
+ // falls '/' am Anfang, ist der Name '/',
+ // der Rest immer ohne die fuehrenden '/'.
+ // den ersten '/' suchen
+ USHORT nPos;
+ for ( nPos = 0;
+ nPos < aPfad.Len() && aPfad.GetChar(nPos) != '/';
+ nPos++ )
+ /* do nothing */;
+
+ // ist der Name die Root des aktuellen Drives?
+ if ( nPos == 0 && aPfad.Len() > 0 && ( aPfad.GetChar(0) == '/' ) )
+ {
+ // Root-Directory des aktuellen Drives
+ aStack.Push( new DirEntry( FSYS_FLAG_ABSROOT ) );
+ }
+ else
+ {
+ // den Namen ohne Trenner abspalten
+ aName = aPfad.Copy( 0, nPos );
+
+ // stellt der Name die aktuelle Directory dar?
+ if ( aName == "." )
+ /* do nothing */;
+
+#ifdef UNX
+ // stellt der Name das User-Dir dar?
+ else if ( aName == "~" )
+ {
+ DirEntry aHome( String( (const char *) getenv( "HOME" ), osl_getThreadTextEncoding()) );
+ for ( USHORT n = aHome.Level(); n; --n )
+ aStack.Push( new DirEntry( aHome[ (USHORT) n-1 ] ) );
+ }
+#endif
+
+ // stellt der Name die Parent-Directory dar?
+ else if ( aName == ".." )
+ {
+ // ist nichts, ein Parent oder eine relative Root
+ // auf dem Stack?
+ if ( ( aStack.Count() == 0 ) ||
+ ( aStack.Top()->eFlag == FSYS_FLAG_PARENT ) )
+ // fuehrende Parents kommen auf den Stack
+ aStack.Push( new DirEntry( ByteString(), FSYS_FLAG_PARENT, eStyle ) );
+
+ // ist es eine absolute Root
+ else if ( aStack.Top()->eFlag == FSYS_FLAG_ABSROOT ) {
+ // die hat keine Parent-Directory
+ return FSYS_ERR_NOTEXISTS;
+ }
+ else
+ // sonst hebt der Parent den TOS auf
+ delete aStack.Pop();
+ }
+ else
+ {
+ DirEntry *pNew = NULL;
+ // normalen Entries kommen auf den Stack
+ pNew = new DirEntry( aName, FSYS_FLAG_NORMAL, eStyle );
+ if ( !pNew->IsValid() )
+ {
+ aName = rPfad;
+ ErrCode eErr = pNew->GetError();
+ delete pNew;
+ return eErr;
+ }
+ aStack.Push( pNew );
+ }
+ }
+
+ // den Restpfad bestimmen
+ aPfad.Erase( 0, nPos + 1 );
+ while ( aPfad.Len() && ( aPfad.GetChar(0) == '/' ) )
+ aPfad.Erase( 0, 1 );
+ }
+ while ( aPfad.Len() );
+
+ // Haupt-Entry (selbst) zuweisen
+ if ( aStack.Count() == 0 )
+ {
+ eFlag = FSYS_FLAG_CURRENT;
+ aName.Erase();
+ }
+ else
+ {
+ eFlag = aStack.Top()->eFlag;
+ aName = aStack.Top()->aName;
+ delete aStack.Pop();
+ }
+
+ // die Parent-Entries vom Stack holen
+ DirEntry** pTemp = &pParent;
+ while ( aStack.Count() )
+ {
+ *pTemp = aStack.Pop();
+ pTemp = &( (*pTemp)->pParent );
+ }
+
+ return FSYS_ERR_OK;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::MakeShortName()
+|*
+|* Beschreibung
+|* Ersterstellung TLX
+|* Letzte Aenderung PB 21.08.97 (in CreateEntry_Impl())
+|*
+*************************************************************************/
+
+ErrCode CreateEntry_Impl( const DirEntry &rPath, DirEntryKind eKind )
+{
+ // versuchen, anzulegen (ausser bei FSYS_KIND_ALL)
+ ErrCode eErr = ERRCODE_NONE;
+ if ( FSYS_KIND_FILE == eKind )
+ {
+ SvFileStream aStream( rPath.GetFull(), STREAM_STD_WRITE );
+ aStream.WriteLine( "" );
+ eErr = aStream.GetError();
+ }
+ else if ( FSYS_KIND_ALL != eKind )
+ eErr = rPath.MakeDir() ? ERRCODE_NONE : ERRCODE_IO_UNKNOWN;
+
+ // erfolgreich?
+ if ( !rPath.Exists() )
+ eErr = ERRCODE_IO_UNKNOWN; // Doch was schiefgegangen ?
+
+ // ggf. wieder l"oschen
+ if ( FSYS_KIND_NONE == eKind )
+ rPath.Kill();
+
+ // Fehlercode zur?ckliefern
+ return eErr;
+}
+
+BOOL IsValidEntry_Impl( const DirEntry &rPath,
+ const String &rLongName,
+ DirEntryKind eKind,
+ BOOL bIsShortened,
+ BOOL bUseDelim )
+{
+ // Parameter-Pr"uefung
+ DBG_ASSERT( eKind == FSYS_KIND_NONE || eKind == FSYS_KIND_ALL ||
+ eKind == FSYS_KIND_FILE || eKind == FSYS_KIND_DIR,
+ "invalid entry-kind" );
+
+ // Alle von MSDOS erreichbaren FSYS_STYLES muessen den
+ // MSDOS Filenamenanforderungen genuegen. Sonst wird probiert,
+ // ob sich eine Datei des gewuenschten Names anlegen laesst.
+ FSysPathStyle eStyle = DirEntry::GetPathStyle( rPath.GetDevice().GetName() );
+ DirEntry aPath(rPath);
+ DirEntry aName(rLongName, eStyle);
+ if ( !aName.IsValid() || aName.Level() != 1 )
+ return FALSE;
+ aPath += aName;
+ if ( 1 == aPath.Level() )
+ return FALSE;
+ if ( eStyle == FSYS_STYLE_FAT || eStyle == FSYS_STYLE_NWFS ||
+ eStyle == FSYS_STYLE_UNKNOWN )
+ {
+ DirEntry aDosEntry( rLongName, FSYS_STYLE_FAT );
+ if ( !aDosEntry.IsValid() )
+ return FALSE;
+ }
+
+ // Pfad-Trenner sind nicht erlaubt (bei ungek"urzten auch nicht FSYS_SHORTNAME_DELIMITER)
+ char cDelim = bUseDelim == 2 ? FSYS_SHORTNAME_DELIMITER : char(0);
+ if (
+ rLongName.Search(DirEntry::GetAccessDelimiter()) != STRING_NOTFOUND ||
+ (!bIsShortened && rLongName.Search(cDelim) != STRING_NOTFOUND)
+ )
+ {
+ return FALSE;
+ }
+
+ // MI: Abfrage nach 'CON:' etc. wird jetzt in Exists() mitgemacht
+ if ( aPath.Exists() )
+ return FALSE;
+
+ return (ERRCODE_NONE == CreateEntry_Impl( aPath, eKind ));
+}
+
+//-------------------------------------------------------------------------
+
+#define MAX_EXT_FAT 3
+#define MAX_LEN_FAT 8
+#define INVALID_CHARS_FAT "\\/\"':|^<>[]?* "
+
+#define MAX_EXT_MAC 16 // nur wegen sinnvoller Namensk"rzung
+#define MAX_LEN_MAC 31
+#define INVALID_CHARS_MAC "\":"
+
+#define MAX_EXT_MAX 250
+#define MAX_LEN_MAX 255
+#define INVALID_CHARS_DEF "\\/\"':|^<>?*"
+
+BOOL DirEntry::MakeShortName( const String& rLongName, DirEntryKind eKind,
+ BOOL bUseDelim, FSysPathStyle eStyle )
+{
+ String aLongName(rLongName);
+
+ // Alle '#' aus den Dateinamen entfernen, weil das INetURLObject
+ // damit Probleme hat. Siehe auch #51246#
+ aLongName.EraseAllChars( '#' );
+ ByteString bLongName(aLongName, osl_getThreadTextEncoding());
+
+ // Auf Novell-Servern (wegen der rottigen Clients) nur 7bit ASCII
+
+ // bei FSYS_KIND_ALL den alten Namen merken und abh"angen (rename)
+ ByteString aOldName;
+ if ( FSYS_KIND_ALL == eKind )
+ {
+ aOldName = ByteString(CutName(), osl_getThreadTextEncoding());
+ aOldName = CMP_LOWER(aOldName);
+ }
+
+ // ist der Langname direkt verwendbar?
+ if ( IsValidEntry_Impl( *this, aLongName, eKind, FALSE, bUseDelim ) )
+ {
+ operator+=( DirEntry(aLongName) );
+ return TRUE;
+ }
+
+ // max L"angen feststellen
+ USHORT nMaxExt, nMaxLen;
+ if ( FSYS_STYLE_DETECT == eStyle )
+ eStyle = DirEntry::GetPathStyle( GetDevice().GetName() );
+ ByteString aInvalidChars;
+ switch ( eStyle )
+ {
+ case FSYS_STYLE_FAT:
+ nMaxExt = MAX_EXT_FAT;
+ nMaxLen = MAX_LEN_FAT;
+ aInvalidChars = INVALID_CHARS_FAT;
+ break;
+
+ case FSYS_STYLE_MAC:
+ nMaxExt = MAX_EXT_MAC;
+ nMaxLen = MAX_LEN_MAC;
+ aInvalidChars = INVALID_CHARS_MAC;
+ break;
+
+ default:
+ nMaxExt = MAX_EXT_MAX;
+ nMaxLen = MAX_LEN_MAX;
+ aInvalidChars = INVALID_CHARS_DEF;
+ }
+
+ // Extension abschneiden und kuerzen
+ ByteString aExt;
+ ByteString aFName = bLongName;
+ if ( FSYS_STYLE_MAC != eStyle )
+ {
+ DirEntry aUnparsed;
+ aUnparsed.aName = bLongName;
+ aExt = ByteString(aUnparsed.CutExtension(), osl_getThreadTextEncoding());
+ aFName = aUnparsed.aName;
+ if ( aExt.Len() > nMaxExt )
+ {
+ char c = aExt.GetChar( aExt.Len() - 1 );
+ aExt.Erase(nMaxExt-1);
+ aExt += c;
+ }
+ }
+
+ if ( FSYS_STYLE_FAT != eStyle )
+ {
+ // ausser auf einem FAT-System geh"ort die Extension zur
+ // Maxl"ange. Muss also vorher mit dem Punkt abgezogen werden.
+ nMaxLen -= ( aExt.Len() + 1 );
+ }
+
+ // Name k"urzen
+ ByteString aSName;
+ for ( const char *pc = aFName.GetBuffer(); aSName.Len() < nMaxLen && *pc; ++pc )
+ {
+ if ( STRING_NOTFOUND == aInvalidChars.Search( *pc ) &&
+ (unsigned char) *pc >= (unsigned char) 32 &&
+ ( !aSName.Len() || *pc != ' ' || aSName.GetChar(aSName.Len()-1) != ' ' ) )
+ aSName += *pc;
+ }
+ aSName.EraseTrailingChars();
+
+ // HRO: #74246# Also cut leading spaces
+ aSName.EraseLeadingChars();
+
+ if ( !aSName.Len() )
+ aSName = "noname";
+
+ // kommt dabei der alte Name raus?
+ ByteString aNewName = aSName;
+ if ( aExt.Len() )
+ ( aNewName += '.' ) += aExt;
+ operator+=( DirEntry(String(aNewName, osl_getThreadTextEncoding())) );
+ if ( FSYS_KIND_ALL == eKind && CMP_LOWER(aName) == aOldName )
+ if ( FSYS_KIND_ALL == eKind && CMP_LOWER(ByteString(GetName(), osl_getThreadTextEncoding())) == aOldName )
+ return TRUE;
+
+ // kann der gek"urzte Name direkt verwendet werden?
+ if ( !Exists() && (ERRCODE_NONE == CreateEntry_Impl( *this, eKind )) )
+ return TRUE;
+
+ // darf '?##' verwendet werden, um eindeutigen Name zu erzeugen?
+ if ( bUseDelim )
+ {
+ // eindeutigen Namen per '?##' erzeugen
+ aSName.Erase( nMaxLen-3 );
+ if ( bUseDelim != 2 )
+ aSName += FSYS_SHORTNAME_DELIMITER;
+ for ( int n = 1; n < 99; ++n )
+ {
+ // Name zusammensetzen
+ ByteString aTmpStr( aSName );
+ aTmpStr += ByteString::CreateFromInt32(n);
+ if ( aExt.Len() )
+ ( aTmpStr += '.' ) += aExt;
+
+ // noch nicht vorhanden?
+ SetName( String(aTmpStr, osl_getThreadTextEncoding()) );
+
+ if ( !Exists() )
+ {
+ // Fehler setzen !!!
+ nError = CreateEntry_Impl( *this, eKind );
+ return (ERRCODE_NONE == nError);
+ }
+ }
+ }
+
+ // keine ## mehr frei / ?## soll nicht verwendet werden
+ nError = ERRCODE_IO_ALREADYEXISTS;
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::CreatePath()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+BOOL DirEntry::MakeDir( BOOL bSloppy ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ // Schnellpruefung, ob vorhanden
+ if ( FileStat( *this ).IsKind( FSYS_KIND_DIR ) )
+ return TRUE;
+ if ( bSloppy && pParent )
+ if ( FileStat( *pParent ).IsKind( FSYS_KIND_DIR ) )
+ return TRUE;
+
+ const DirEntry *pNewDir = bSloppy ? pParent : this;
+ if ( pNewDir )
+ {
+ // den Path zum Dir erzeugen
+ if ( pNewDir->pParent && !pNewDir->pParent->MakeDir(FALSE) )
+ return FALSE;
+
+ // das Dir selbst erzeugen
+ if ( pNewDir->eFlag == FSYS_FLAG_ABSROOT ||
+ pNewDir->eFlag == FSYS_FLAG_ABSROOT ||
+ pNewDir->eFlag == FSYS_FLAG_VOLUME )
+ return TRUE;
+ else
+ {
+ //? nError = ???
+ if ( FileStat( *pNewDir ).IsKind( FSYS_KIND_DIR ) )
+ return TRUE;
+ else
+ {
+ FSysFailOnErrorImpl();
+ String aDirName(pNewDir->GetFull());
+#ifndef BOOTSTRAP
+ FSysRedirector::DoRedirect( aDirName );
+#endif
+ ByteString bDirName( aDirName, osl_getThreadTextEncoding() );
+ bDirName = GUI2FSYS( bDirName );
+
+#ifdef WIN32
+ SetLastError(0);
+#endif
+ BOOL bResult = (0 == _mkdir( (char*) bDirName.GetBuffer() ));
+ if ( !bResult )
+ {
+ // Wer hat diese Methode const gemacht ?
+#ifdef WIN32
+ ((DirEntry *)this)->SetError( Sys2SolarError_Impl( GetLastError() ) );
+#else
+ ((DirEntry *)this)->SetError( Sys2SolarError_Impl( errno ) );
+#endif
+ }
+
+ return bResult;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::CopyTo()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MI 07.08.96
+|*
+*************************************************************************/
+
+FSysError DirEntry::CopyTo( const DirEntry& rDest, FSysAction nActions ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ if ( FSYS_ACTION_COPYFILE != (nActions & FSYS_ACTION_COPYFILE) )
+#ifdef UNX
+ {
+ // Hardlink anlegen
+ HACK(redirection missing)
+ ByteString aThis(GUI2FSYS(GetFull()), osl_getThreadTextEncoding());
+ ByteString aDest(GUI2FSYS(rDest.GetFull()), osl_getThreadTextEncoding());
+ if (link( aThis.GetBuffer(), aDest.GetBuffer() ) == -1)
+ return Sys2SolarError_Impl( errno );
+ else
+ return FSYS_ERR_OK;
+ }
+#else
+ return FSYS_ERR_NOTSUPPORTED;
+#endif
+
+ FileCopier fc(*this, rDest);
+ return fc.Execute(nActions);
+}
+
+/*************************************************************************
+|*
+|* DirEntry::MoveTo()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung HRO 24.03.99
+|*
+*************************************************************************/
+
+#if defined WNT || defined UNX || defined OS2
+
+FSysError DirEntry::MoveTo( const DirEntry& rNewName ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+/*
+ FileStat aSourceStat(*this);
+ if ( !aSourceStat.IsKind(FSYS_KIND_FILE) )
+ return FSYS_ERR_NOTAFILE;
+*/
+
+ DirEntry aDest(rNewName);
+ FileStat aDestStat(rNewName);
+ if ( aDestStat.IsKind(FSYS_KIND_DIR ) )
+ {
+ aDest += String(aName, osl_getThreadTextEncoding());
+ }
+ if ( aDest.Exists() )
+ {
+ return FSYS_ERR_ALREADYEXISTS;
+ }
+
+#if defined(OS2)
+ if ( FileStat(*this).IsKind(FSYS_KIND_DIR) && aDest.GetPath() != GetPath() )
+ {
+ return FSYS_ERR_NOTSUPPORTED;
+ }
+#endif
+
+ FSysFailOnErrorImpl();
+ String aFrom( GetFull() );
+
+#ifndef BOOTSTRAP
+ FSysRedirector::DoRedirect(aFrom);
+#endif
+
+ String aTo( aDest.GetFull() );
+
+#ifndef BOOTSTRAP
+ FSysRedirector::DoRedirect(aTo);
+#endif
+
+ ByteString bFrom(aFrom, osl_getThreadTextEncoding());
+ ByteString bTo(aTo, osl_getThreadTextEncoding());
+ bFrom = GUI2FSYS(bFrom);
+ bTo = GUI2FSYS(bTo);
+
+#ifdef WNT
+ // MoveTo nun atomar
+ SetLastError(0);
+
+ DirEntry aFromDevice(String(bFrom, osl_getThreadTextEncoding()));
+ DirEntry aToDevice(String(bTo,osl_getThreadTextEncoding()));
+ aFromDevice.ToAbs();
+ aToDevice.ToAbs();
+ aFromDevice=aFromDevice.GetDevice();
+ aToDevice=aToDevice.GetDevice();
+
+ //Quelle und Ziel auf gleichem device?
+ if (aFromDevice==aToDevice)
+ {
+ // ja, also intra-device-move mit MoveFile
+ MoveFile( bFrom.GetBuffer(), bTo.GetBuffer() );
+ // MoveFile ist buggy bei cross-device operationen.
+ // Der R?ckgabewert ist auch dann TRUE, wenn nur ein Teil der Operation geklappt hat.
+ // Zudem zeigt MoveFile unterschiedliches Verhalten bei unterschiedlichen NT-Versionen.
+ return Sys2SolarError_Impl( GetLastError() );
+ }
+ else
+ {
+ //nein, also inter-device-move mit copy/delete
+ FSysError nCopyError = CopyTo(rNewName, FSYS_ACTION_COPYFILE);
+
+ DirEntry aKill(String(bTo, osl_getThreadTextEncoding()));
+ FileStat aKillStat(String(bTo, osl_getThreadTextEncoding()));
+ if ( aKillStat.IsKind(FSYS_KIND_DIR ) )
+ {
+ aKill += String(aName, osl_getThreadTextEncoding());
+ }
+
+ if (nCopyError==FSYS_ERR_OK)
+ {
+ if (Kill()==FSYS_ERR_OK)
+ {
+ return FSYS_ERR_OK;
+ }
+ else
+ {
+ aKill.Kill();
+ return FSYS_ERR_ACCESSDENIED;
+ }
+ }
+ else
+ {
+ aKill.Kill();
+ return nCopyError;
+ }
+ }
+#else
+ // #68639#
+ // on some nfs connections rename with from == to
+ // leads to destruction of file
+ if ( ( aFrom != aTo ) && ( 0 != rename( bFrom.GetBuffer(), bTo.GetBuffer() ) ) )
+#if !defined(UNX) && !defined(OS2)
+ return Sys2SolarError_Impl( GetLastError() );
+#else
+ {
+ if( errno == EXDEV )
+// cross device geht latuernich nicht mit rename
+ {
+ FILE *fpIN = fopen( bFrom.GetBuffer(), "r" );
+ FILE *fpOUT = fopen( bTo.GetBuffer(), "w" );
+ if( fpIN && fpOUT )
+ {
+ char pBuf[ 16384 ];
+ int nBytes, nWritten, nErr = 0;
+ errno = 0;
+ while( ( nBytes = fread( pBuf, 1, sizeof(pBuf), fpIN ) ) && ! nErr )
+ {
+ nWritten = fwrite( pBuf, 1, nBytes, fpOUT );
+ // Fehler im fwrite ?
+ if( nWritten < nBytes )
+ {
+ nErr = errno;
+ break;
+ }
+ }
+ fclose( fpIN );
+ fclose( fpOUT );
+ if ( nErr )
+ {
+ unlink( bTo.GetBuffer() );
+ return Sys2SolarError_Impl( nErr );
+ }
+ else
+ {
+ unlink( bFrom.GetBuffer() );
+ }
+ }
+ else
+ {
+ return Sys2SolarError_Impl( EXDEV );
+ }
+ }
+ else
+ {
+ return Sys2SolarError_Impl( errno );
+ }
+ }
+#endif
+#endif
+ return ERRCODE_NONE;
+}
+
+#endif
+
+/*************************************************************************
+|*
+|* DirEntry::Kill()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MI 07.08.96
+|*
+*************************************************************************/
+
+FSysError DirEntry::Kill( FSysAction nActions ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ FSysError eError = FSYS_ERR_OK;
+ FSysFailOnErrorImpl();
+
+ // Name als doppelt 0-terminierter String
+ String aTmpName( GetFull() );
+#ifndef BOOTSTRAP
+ FSysRedirector::DoRedirect( aTmpName );
+#endif
+ ByteString bTmpName( aTmpName, osl_getThreadTextEncoding());
+ bTmpName = GUI2FSYS(bTmpName);
+
+ char *pName = new char[bTmpName.Len()+2];
+ strcpy( pName, bTmpName.GetBuffer() );
+ pName[bTmpName.Len()+1] = (char) 0;
+
+ //read-only files sollen auch geloescht werden koennen
+ BOOL isReadOnly = FileStat::GetReadOnlyFlag(*this);
+ if (isReadOnly)
+ {
+ FileStat::SetReadOnlyFlag(*this, FALSE);
+ }
+
+ // directory?
+ if ( FileStat( *this ).IsKind(FSYS_KIND_DIR) )
+ {
+ // Inhalte recursiv loeschen?
+ if ( FSYS_ACTION_RECURSIVE == (nActions & FSYS_ACTION_RECURSIVE) )
+ {
+ Dir aDir( *this, FSYS_KIND_DIR|FSYS_KIND_FILE );
+ for ( USHORT n = 0; eError == FSYS_ERR_OK && n < aDir.Count(); ++n )
+ {
+ const DirEntry &rSubDir = aDir[n];
+ DirEntryFlag flag = rSubDir.GetFlag();
+ if ( flag != FSYS_FLAG_CURRENT && flag != FSYS_FLAG_PARENT )
+ eError = rSubDir.Kill(nActions);
+ }
+ }
+
+ // das Dir selbst loeschen
+#ifdef WIN32
+ SetLastError(0);
+#endif
+ if ( eError == FSYS_ERR_OK && 0 != _rmdir( (char*) pName ) )
+ //
+ {
+ // falls L"oschen nicht ging, CWD umsetzen
+#ifdef WIN32
+ eError = Sys2SolarError_Impl( GetLastError() );
+#else
+ eError = Sys2SolarError_Impl( errno );
+#endif
+ if ( eError )
+ {
+ GetPath().SetCWD();
+#ifdef WIN32
+ SetLastError(0);
+#endif
+ if (_rmdir( (char*) pName) != 0)
+ {
+#ifdef WIN32
+ eError = Sys2SolarError_Impl( GetLastError() );
+#else
+ eError = Sys2SolarError_Impl( errno );
+#endif
+ }
+ else
+ {
+ eError = FSYS_ERR_OK;
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( FSYS_ACTION_USERECYCLEBIN == (nActions & FSYS_ACTION_USERECYCLEBIN) )
+ {
+#ifdef OS2
+ eError = ApiRet2ToSolarError_Impl( DosDelete( (PSZ) pName ) );
+#elif defined(WNT)
+ SHFILEOPSTRUCT aOp;
+ aOp.hwnd = 0;
+ aOp.wFunc = FO_DELETE;
+ aOp.pFrom = pName;
+ aOp.pTo = 0;
+ aOp.fFlags = FOF_ALLOWUNDO|FOF_SILENT|FOF_NOCONFIRMATION;
+ aOp.hNameMappings = 0;
+ aOp.lpszProgressTitle = 0;
+ eError = Sys2SolarError_Impl( SHFileOperation( &aOp ) );
+#else
+ eError = ERRCODE_IO_NOTSUPPORTED;
+#endif
+ }
+ else
+ {
+#ifdef WIN32
+ SetLastError(0);
+#endif
+ if ( 0 != _unlink( (char*) pName ) )
+ {
+#ifdef WIN32
+ eError = Sys2SolarError_Impl( GetLastError() );
+#else
+ eError = Sys2SolarError_Impl( errno );
+#endif
+ }
+ else
+ {
+ eError = ERRCODE_NONE;
+ }
+ }
+ }
+
+ //falls Fehler, originales read-only flag wieder herstellen
+ if ( isReadOnly && (eError!=ERRCODE_NONE) )
+ {
+ FileStat::SetReadOnlyFlag(*this, isReadOnly);
+ }
+
+ delete[] pName;
+ return eError;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::Contains()
+|*
+|* Beschreibung ob rSubEntry direkt oder indirect in *this liegt
+|* Ersterstellung MI 20.03.97
+|* Letzte Aenderung MI 20.03.97
+|*
+*************************************************************************/
+
+BOOL DirEntry::Contains( const DirEntry &rSubEntry ) const
+{
+ DBG_ASSERT( IsAbs() && rSubEntry.IsAbs(), "must be absolute entries" );
+
+ USHORT nThisLevel = Level();
+ USHORT nSubLevel = rSubEntry.Level();
+ if ( nThisLevel < nSubLevel )
+ {
+ for ( ; nThisLevel; --nThisLevel, --nSubLevel )
+ if ( (*this)[nThisLevel-1] != rSubEntry[nSubLevel-1] )
+ return FALSE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::Level()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 03.03.92
+|* Letzte Aenderung MI 03.03.92
+|*
+*************************************************************************/
+
+USHORT DirEntry::Level() const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ USHORT nLevel = 0;
+ const DirEntry *pRes = this;
+ while ( pRes )
+ {
+ pRes = pRes->pParent;
+ nLevel++;
+ }
+
+ return nLevel;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::ConvertNameToSystem()
+|*
+|* Beschreibung
+|* Ersterstellung DV 29.03.96
+|* Letzte Aenderung DV 29.03.96
+|*
+*************************************************************************/
+
+String DirEntry::ConvertNameToSystem( const String &rName )
+{
+ return rName;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::ConvertSystemToName()
+|*
+|* Beschreibung
+|* Ersterstellung DV 29.03.96
+|* Letzte Aenderung DV 29.03.96
+|*
+*************************************************************************/
+
+String DirEntry::ConvertSystemToName( const String &rName )
+{
+ return rName;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::IsValid()
+|*
+|* Beschreibung
+|* Ersterstellung MI 18.09.93
+|* Letzte Aenderung TPF 18.09.98
+|*
+*************************************************************************/
+
+BOOL DirEntry::IsValid() const
+{
+ return (nError == FSYS_ERR_OK);
+}
+
+/*************************************************************************
+|*
+|* DirEntry::IsRFSAvailable()
+|*
+|* Beschreibung
+|* Ersterstellung TPF 21.10.98
+|* Letzte Aenderung TPF 21.10.98
+|*
+*************************************************************************/
+
+BOOL DirEntry::IsRFSAvailable()
+{
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* IsLongNameOnFAT()
+|*
+|* Beschreibung ?berpr?ft , ob das DirEntry einen langen
+|* Filenamen auf einer FAT-Partition enth?lt (EAs).
+|* (eigentlich nur f?r OS2 interessant)
+|* Ersterstellung TPF 02.10.98
+|* Letzte Aenderung TPF 01.03.1999
+|*
+*************************************************************************/
+
+BOOL DirEntry::IsLongNameOnFAT() const
+{
+ // FAT-System?
+ DirEntry aTempDirEntry(*this);
+ aTempDirEntry.ToAbs();
+ if (DirEntry::GetPathStyle(aTempDirEntry.GetDevice().GetName().GetChar(0)) != FSYS_STYLE_FAT)
+ {
+ return FALSE; // nein, also false
+ }
+
+ // DirEntry-Kette auf lange Dateinamen pr?fen
+ for( USHORT iLevel = this->Level(); iLevel > 0; iLevel-- )
+ {
+ const DirEntry& rEntry = (const DirEntry&) (*this)[iLevel-1];
+ String aBase( rEntry.GetBase() );
+ String aExtension( rEntry.GetExtension() );
+
+ if (aBase.Len()>8) // Name > 8?
+ {
+ return TRUE;
+ }
+
+ if (aExtension.Len()>3) // Extension > 3?
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+//========================================================================
+
+#if defined(DBG_UTIL)
+
+void FSysTest()
+{
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/filecopy.cxx b/tools/source/fsys/filecopy.cxx
new file mode 100644
index 000000000000..826ffeab31f5
--- /dev/null
+++ b/tools/source/fsys/filecopy.cxx
@@ -0,0 +1,489 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#if defined WNT
+#ifndef _SVWIN_H
+#include <io.h>
+#include <tools/svwin.h>
+#endif
+
+#elif defined(OS2)
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <share.h>
+#include <io.h>
+
+#elif defined UNX
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <stdio.h>
+#include "comdep.hxx"
+#include <tools/fsys.hxx>
+#include <tools/stream.hxx>
+#include <osl/file.hxx>
+
+using namespace ::osl;
+
+/*************************************************************************
+|*
+|* FileCopier::FileCopier()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 13.04.94
+|* Letzte Aenderung MI 13.04.94
+|*
+*************************************************************************/
+
+FileCopier::FileCopier() :
+
+ nBytesTotal ( 0 ),
+ nBytesCopied( 0 ),
+ nBlockSize ( 4096 ),
+ pImp ( new FileCopier_Impl )
+
+{
+}
+
+// -----------------------------------------------------------------------
+
+FileCopier::FileCopier( const DirEntry& rSource, const DirEntry& rTarget ) :
+
+ aSource ( rSource ),
+ aTarget ( rTarget ),
+ nBytesTotal ( 0 ),
+ nBytesCopied( 0 ),
+ nBlockSize ( 4096 ),
+ pImp ( new FileCopier_Impl )
+
+{
+}
+
+// -----------------------------------------------------------------------
+
+FileCopier::FileCopier( const FileCopier& rCopier ) :
+
+ aSource ( rCopier.aSource ),
+ aTarget ( rCopier.aTarget ),
+ nBytesTotal ( 0 ),
+ nBytesCopied ( 0 ),
+ aProgressLink ( rCopier.aProgressLink ),
+ nBlockSize ( 4096 ),
+ pImp ( new FileCopier_Impl )
+
+{
+}
+
+/*************************************************************************
+|*
+|* FileCopier::~FileCopier()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 13.04.94
+|* Letzte Aenderung MI 13.04.94
+|*
+*************************************************************************/
+
+FileCopier::~FileCopier()
+{
+ delete pImp;
+}
+
+/*************************************************************************
+|*
+|* FileCopier::operator =()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 13.04.94
+|* Letzte Aenderung MI 13.04.94
+|*
+*************************************************************************/
+
+FileCopier& FileCopier::operator = ( const FileCopier &rCopier )
+{
+ aSource = rCopier.aSource;
+ aTarget = rCopier.aTarget;
+ nBytesTotal = rCopier.nBytesTotal;
+ nBytesCopied = rCopier.nBytesCopied;
+ nBytesCopied = rCopier.nBytesCopied;
+ nBlockSize = rCopier.nBlockSize;
+ aProgressLink = rCopier.aProgressLink;
+ *pImp = *(rCopier.pImp);
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* FileCopier::Progress()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 13.04.94
+|* Letzte Aenderung MI 13.04.94
+|*
+*************************************************************************/
+
+BOOL FileCopier::Progress()
+{
+ if ( !aProgressLink )
+ return TRUE;
+ else
+ {
+ if ( aProgressLink.Call( this ) )
+ return TRUE;
+ return ( 0 == Error( ERRCODE_ABORT, 0, 0 ) );
+ }
+}
+
+//---------------------------------------------------------------------------
+
+ErrCode FileCopier::Error( ErrCode eErr, const DirEntry* pSource, const DirEntry* pTarget )
+{
+ // kein Fehler oder kein ErrorHandler?
+ if ( !eErr || !pImp->aErrorLink )
+ // => Error beibehalten
+ return eErr;
+
+ // sonst gesetzten ErrorHandler fragen
+ pImp->pErrSource = pSource;
+ pImp->pErrTarget = pTarget;
+ pImp->eErr = eErr;
+ ErrCode eRet = (ErrCode) pImp->aErrorLink.Call( this );
+ pImp->pErrSource = 0;
+ pImp->pErrTarget = 0;
+ return eRet;
+}
+
+//---------------------------------------------------------------------------
+
+const DirEntry* FileCopier::GetErrorSource() const
+{
+ return pImp->pErrSource;
+}
+
+//---------------------------------------------------------------------------
+
+const DirEntry* FileCopier::GetErrorTarget() const
+{
+ return pImp->pErrTarget;
+}
+
+//---------------------------------------------------------------------------
+
+ErrCode FileCopier::GetError() const
+{
+ return pImp->eErr;
+}
+
+//---------------------------------------------------------------------------
+
+void FileCopier::SetErrorHdl( const Link &rLink )
+{
+ pImp->aErrorLink = rLink;
+}
+
+//---------------------------------------------------------------------------
+
+const Link& FileCopier::GetErrorHdl() const
+{
+ return pImp->aErrorLink ;
+}
+
+/*************************************************************************
+|*
+|* FileCopier::Execute()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 13.04.94
+|* Letzte Aenderung PB 16.06.00
+|*
+*************************************************************************/
+
+FSysError FileCopier::DoCopy_Impl(
+ const DirEntry &rSource, const DirEntry &rTarget )
+{
+ FSysError eRet = FSYS_ERR_OK;
+ ErrCode eWarn = FSYS_ERR_OK;
+
+ // HPFS->FAT?
+ FSysPathStyle eSourceStyle = DirEntry::GetPathStyle( rSource.ImpGetTopPtr()->GetName() );
+ FSysPathStyle eTargetStyle = DirEntry::GetPathStyle( rTarget.ImpGetTopPtr()->GetName() );
+ BOOL bMakeShortNames = ( eSourceStyle == FSYS_STYLE_HPFS && eTargetStyle == FSYS_STYLE_FAT );
+
+ // Zieldateiname ggf. kuerzen
+ DirEntry aTgt;
+ if ( bMakeShortNames )
+ {
+ aTgt = rTarget.GetPath();
+ aTgt.MakeShortName( rTarget.GetName() );
+ }
+ else
+ aTgt = rTarget;
+
+ // kein Move wenn Namen gekuerzt werden muessten
+ if ( bMakeShortNames && FSYS_ACTION_MOVE == ( pImp->nActions & FSYS_ACTION_MOVE ) && aTgt != rTarget )
+ return ERRCODE_IO_NAMETOOLONG;
+
+ // source is directory?
+ FileStat aSourceFileStat( rSource );
+ if ( aSourceFileStat.IsKind( FSYS_KIND_DIR ) )
+ {
+#ifdef OS2
+ CHAR szSource[CCHMAXPATHCOMP];
+ HOBJECT hSourceObject;
+
+ strcpy(szSource, ByteString(rSource.GetFull(), osl_getThreadTextEncoding()).GetBuffer());
+ hSourceObject = WinQueryObject(szSource);
+
+ if ( hSourceObject )
+ {
+ PSZ pszSourceName;
+ PSZ pszTargetName;
+ CHAR szTarget[CCHMAXPATHCOMP];
+ HOBJECT hTargetObject;
+ HOBJECT hReturn = NULLHANDLE;
+
+ strcpy(szTarget, ByteString(rTarget.GetFull(), osl_getThreadTextEncoding()).GetBuffer());
+ pszTargetName = strrchr(szTarget, '\\');
+ pszSourceName = strrchr(szSource, '\\');
+
+ hTargetObject = WinQueryObject(szTarget);
+
+ if ( hTargetObject )
+ WinDestroyObject(hTargetObject);
+
+ if ( pszTargetName && pszSourceName )
+ {
+ *pszTargetName = '\0';
+ pszSourceName++;
+ pszTargetName++;
+
+ if(strcmp(pszSourceName, pszTargetName) == 0)
+ {
+ hTargetObject = WinQueryObject(szTarget);
+
+ if(pImp->nActions & FSYS_ACTION_MOVE)
+ {
+ hReturn = WinMoveObject(hSourceObject, hTargetObject, 0);
+ }
+ else
+ {
+ hReturn = WinCopyObject(hSourceObject, hTargetObject, 0);
+ }
+ if ( bMakeShortNames && aTarget.Exists() )
+ aTarget.Kill();
+ return hReturn ? FSYS_ERR_OK : FSYS_ERR_UNKNOWN;
+ }
+ }
+ }
+#endif
+ // recursive copy
+ eRet = Error( aTgt.MakeDir() ? FSYS_ERR_OK : FSYS_ERR_UNKNOWN, 0, &aTgt );
+ Dir aSourceDir( rSource, FSYS_KIND_DIR|FSYS_KIND_FILE );
+ for ( USHORT n = 0; ERRCODE_TOERROR(eRet) == FSYS_ERR_OK && n < aSourceDir.Count(); ++n )
+ {
+ const DirEntry &rSubSource = aSourceDir[n];
+ DirEntryFlag eFlag = rSubSource.GetFlag();
+ if ( eFlag != FSYS_FLAG_CURRENT && eFlag != FSYS_FLAG_PARENT )
+ {
+ DirEntry aSubTarget( aTgt );
+ aSubTarget += rSubSource.GetName();
+ eRet = DoCopy_Impl( rSubSource, aSubTarget );
+ if ( eRet && !eWarn )
+ eWarn = eRet;
+ }
+ }
+ }
+ else if ( aSourceFileStat.IsKind(FSYS_KIND_FILE) )
+ {
+ if ( ( FSYS_ACTION_KEEP_EXISTING == ( pImp->nActions & FSYS_ACTION_KEEP_EXISTING ) ) &&
+ aTgt.Exists() )
+ {
+ // Do not overwrite existing file in target folder.
+ return ERRCODE_NONE;
+ }
+
+ // copy file
+ nBytesCopied = 0;
+ nBytesTotal = FileStat( rSource ).GetSize();
+
+ ::rtl::OUString aFileName;
+ FileBase::getFileURLFromSystemPath( ::rtl::OUString(rSource.GetFull()), aFileName );
+ SvFileStream aSrc( aFileName, STREAM_READ|STREAM_NOCREATE|STREAM_SHARE_DENYNONE );
+
+ if ( !aSrc.GetError() )
+ {
+#ifdef UNX
+ struct stat buf;
+ if ( fstat( aSrc.GetFileHandle(), &buf ) == -1 )
+ eRet = Error( FSYS_ERR_ACCESSDENIED, 0, &aTgt );
+#endif
+ ::rtl::OUString aTargetFileName;
+ FileBase::getFileURLFromSystemPath( ::rtl::OUString(aTgt.GetFull()), aTargetFileName );
+
+ SvFileStream aTargetStream( aTargetFileName, STREAM_WRITE | STREAM_TRUNC | STREAM_SHARE_DENYWRITE );
+ if ( !aTargetStream.GetError() )
+ {
+#ifdef UNX
+ if ( fchmod( aTargetStream.GetFileHandle(), buf.st_mode ) == -1 )
+ eRet = Error( FSYS_ERR_ACCESSDENIED, 0, &aTgt );
+#endif
+ size_t nAllocSize = 0, nSize = 0;
+ char *pBuf = 0;
+ while ( Progress() && nSize == nAllocSize && eRet == FSYS_ERR_OK )
+ {
+ // adjust the block-size
+ if ( nBlockSize > nAllocSize )
+ {
+ delete[] pBuf;
+ nAllocSize = nBlockSize;
+ pBuf = new char[nAllocSize];
+ }
+
+ // copy one block
+ nSize = aSrc.Read( pBuf, nBlockSize );
+ aTargetStream.Write( pBuf, nSize );
+ if ( aTargetStream.GetError() )
+ eRet = Error( aTargetStream.GetError(), 0, &aTgt );
+
+ // adjust counters
+ nBytesCopied += nSize;
+ if ( nBytesCopied > nBytesTotal )
+ nBytesTotal = nBytesCopied;
+ }
+ delete[] pBuf;
+ }
+ else
+ eRet = Error( aTargetStream.GetError(), 0, &aTgt );
+
+ // unvollstaendiges File wieder loeschen
+ aTargetStream.Close();
+
+ if ( nBytesCopied != nBytesTotal )
+ {
+ aTgt.Kill();
+ }
+ }
+ else
+ eRet = Error( aSrc.GetError(), &rSource, 0 );
+ }
+ else if ( aSourceFileStat.IsKind(FSYS_KIND_NONE) )
+ eRet = Error( ERRCODE_IO_NOTEXISTS, &rSource, 0 );
+ else
+ eRet = Error( ERRCODE_IO_NOTSUPPORTED, &rSource, 0 );
+
+#ifdef WNT
+ // Set LastWriteTime and Attributes of the target identical with the source
+
+ if ( FSYS_ERR_OK == ERRCODE_TOERROR(eRet) )
+ {
+ WIN32_FIND_DATA fdSource;
+ ByteString aFullSource(aSource.GetFull(), osl_getThreadTextEncoding());
+ ByteString aFullTarget(aTgt.GetFull(), osl_getThreadTextEncoding());
+ HANDLE hFind = FindFirstFile( aFullSource.GetBuffer() , &fdSource );
+ if ( hFind != INVALID_HANDLE_VALUE )
+ {
+ FindClose( hFind );
+
+ HANDLE hFile = CreateFile( aFullTarget.GetBuffer(), GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+
+ if ( hFile != INVALID_HANDLE_VALUE )
+ {
+ SetFileTime( hFile, NULL, NULL, &fdSource.ftLastWriteTime );
+ CloseHandle( hFile );
+ }
+
+ SetFileAttributes( aFullTarget.GetBuffer(), fdSource.dwFileAttributes );
+ }
+ }
+#endif
+ // bei Move ggf. das File/Dir loeschen
+ if ( FSYS_ERR_OK == ERRCODE_TOERROR(eRet) && ( pImp->nActions & FSYS_ACTION_MOVE ) )
+ {
+ ErrCode eKillErr = Error( rSource.Kill() | ERRCODE_WARNING_MASK, &rSource, 0 );
+ if ( eKillErr != ERRCODE_WARNING_MASK )
+ {
+ if ( rSource.Exists() )
+ // loeschen ging nicht => dann die Kopie wieder loeschen
+ aTgt.Kill( pImp->nActions );
+ if ( !eWarn )
+ eWarn = eKillErr;
+ }
+ }
+
+ return !eRet ? eWarn : eRet;
+}
+
+// -----------------------------------------------------------------------
+
+FSysError FileCopier::Execute( FSysAction nActions )
+{
+ return ExecuteExact( nActions );
+}
+
+// -----------------------------------------------------------------------
+
+FSysError FileCopier::ExecuteExact( FSysAction nActions, FSysExact eExact )
+{
+ DirEntry aAbsSource = DirEntry( aSource);
+ DirEntry aAbsTarget = DirEntry( aTarget );
+ pImp->nActions = nActions;
+
+ // check if both pathes are accessible and source and target are different
+ if ( !aAbsTarget.ToAbs() || !aAbsSource.ToAbs() || aAbsTarget == aAbsSource )
+ return FSYS_ERR_ACCESSDENIED;
+
+ // check if copy would be endless recursive into itself
+ if ( FSYS_ACTION_RECURSIVE == ( nActions & FSYS_ACTION_RECURSIVE ) &&
+ aAbsSource.Contains( aAbsTarget ) )
+ return ERRCODE_IO_RECURSIVE;
+
+ // target is directory?
+ if ( eExact == FSYS_NOTEXACT &&
+ FileStat( aAbsTarget ).IsKind(FSYS_KIND_DIR) && FileStat( aAbsSource ).IsKind(FSYS_KIND_FILE) )
+ // append name of source
+ aAbsTarget += aSource.GetName();
+
+ // recursive copy
+ return DoCopy_Impl( aAbsSource, aAbsTarget );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/fstat.cxx b/tools/source/fsys/fstat.cxx
new file mode 100644
index 000000000000..468fdb6082ea
--- /dev/null
+++ b/tools/source/fsys/fstat.cxx
@@ -0,0 +1,422 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#if defined( WIN)
+#include <stdio.h>
+#include <dos.h>
+#endif
+
+#ifdef UNX
+#include <errno.h>
+#endif
+
+#include <limits.h>
+#include <string.h>
+
+#include "comdep.hxx"
+#include <tools/fsys.hxx>
+
+/*************************************************************************
+|*
+|* FileStat::FileStat()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 11.06.91
+|* Letzte Aenderung MI 11.06.91
+|*
+*************************************************************************/
+
+FileStat::FileStat()
+: // don't use Default-Ctors!
+ aDateCreated( ULONG(0) ),
+ aTimeCreated( ULONG(0) ),
+ aDateModified( ULONG(0) ),
+ aTimeModified( ULONG(0) ),
+ aDateAccessed( ULONG(0) ),
+ aTimeAccessed( ULONG(0) )
+{
+ nSize = 0;
+ nKindFlags = FSYS_KIND_UNKNOWN;
+ nError = FSYS_ERR_OK;
+}
+
+/*************************************************************************
+|*
+|* FileStat::FileStat()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 11.06.91
+|* Letzte Aenderung MI 11.06.91
+|*
+*************************************************************************/
+
+FileStat::FileStat( const DirEntry& rDirEntry, FSysAccess nAccess )
+: // don't use Default-Ctors!
+ aDateCreated( ULONG(0) ),
+ aTimeCreated( ULONG(0) ),
+ aDateModified( ULONG(0) ),
+ aTimeModified( ULONG(0) ),
+ aDateAccessed( ULONG(0) ),
+ aTimeAccessed( ULONG(0) )
+{
+ BOOL bCached = FSYS_ACCESS_CACHED == (nAccess & FSYS_ACCESS_CACHED);
+ BOOL bFloppy = FSYS_ACCESS_FLOPPY == (nAccess & FSYS_ACCESS_FLOPPY);
+
+#ifdef FEAT_FSYS_DOUBLESPEED
+ const FileStat *pStatFromDir = bCached ? rDirEntry.ImpGetStat() : 0;
+ if ( pStatFromDir )
+ {
+ nError = pStatFromDir->nError;
+ nKindFlags = pStatFromDir->nKindFlags;
+ nSize = pStatFromDir->nSize;
+ aCreator = pStatFromDir->aCreator;
+ aType = pStatFromDir->aType;
+ aDateCreated = pStatFromDir->aDateCreated;
+ aTimeCreated = pStatFromDir->aTimeCreated;
+ aDateModified = pStatFromDir->aDateModified;
+ aTimeModified = pStatFromDir->aTimeModified;
+ aDateAccessed = pStatFromDir->aDateAccessed;
+ aTimeAccessed = pStatFromDir->aTimeAccessed;
+ }
+ else
+#endif
+ Update( rDirEntry, bFloppy );
+}
+
+/*************************************************************************
+|*
+|* FileStat::IsYounger()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MA 11.11.91
+|* Letzte Aenderung MA 11.11.91
+|*
+*************************************************************************/
+
+// TRUE wenn die Instanz j"unger als rIsOlder ist.
+// FALSE wenn die Instanz "alter oder gleich alt wie rIsOlder ist.
+
+BOOL FileStat::IsYounger( const FileStat& rIsOlder ) const
+{
+ if ( aDateModified > rIsOlder.aDateModified )
+ return TRUE;
+ if ( ( aDateModified == rIsOlder.aDateModified ) &&
+ ( aTimeModified > rIsOlder.aTimeModified ) )
+ return TRUE;
+
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* FileStat::IsKind()
+|*
+|* Ersterstellung MA 11.11.91 (?)
+|* Letzte Aenderung KH 16.01.95
+|*
+*************************************************************************/
+
+BOOL FileStat::IsKind( DirEntryKind nKind ) const
+{
+ BOOL bRet = ( ( nKind == FSYS_KIND_UNKNOWN ) &&
+ ( nKindFlags == FSYS_KIND_UNKNOWN ) ) ||
+ ( ( nKindFlags & nKind ) == nKind );
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|* FileStat::HasReadOnlyFlag()
+|*
+|* Ersterstellung MI 06.03.97
+|* Letzte Aenderung UT 01.07.98
+|*
+*************************************************************************/
+
+BOOL FileStat::HasReadOnlyFlag()
+{
+#if defined WNT || defined UNX || defined OS2
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+/*************************************************************************
+|*
+|* FileStat::GetReadOnlyFlag()
+|*
+|* Ersterstellung MI 06.03.97
+|* Letzte Aenderung UT 02.07.98
+|*
+*************************************************************************/
+
+BOOL FileStat::GetReadOnlyFlag( const DirEntry &rEntry )
+{
+
+ ByteString aFPath(rEntry.GetFull(), osl_getThreadTextEncoding());
+#if defined WNT
+ DWORD nRes = GetFileAttributes( (LPCTSTR) aFPath.GetBuffer() );
+ return ULONG_MAX != nRes &&
+ ( FILE_ATTRIBUTE_READONLY & nRes ) == FILE_ATTRIBUTE_READONLY;
+#elif defined OS2
+ FILESTATUS3 aFileStat;
+ APIRET nRet = DosQueryPathInfo( (PSZ)aFPath.GetBuffer(), 1, &aFileStat, sizeof(aFileStat) );
+ switch ( nRet )
+ {
+ case NO_ERROR:
+ return FILE_READONLY == ( aFileStat.attrFile & FILE_READONLY );
+ default:
+ return FALSE;
+ }
+#elif defined UNX
+ /* could we stat the object? */
+ struct stat aBuf;
+ if (stat(aFPath.GetBuffer(), &aBuf))
+ return FALSE;
+ /* jupp, is writable for user? */
+ return((aBuf.st_mode & S_IWUSR) != S_IWUSR);
+#else
+ return FALSE;
+#endif
+}
+
+/*************************************************************************
+|*
+|* FileStat::SetReadOnlyFlag()
+|*
+|* Ersterstellung MI 06.03.97
+|* Letzte Aenderung UT 01.07.98
+|*
+*************************************************************************/
+
+ULONG FileStat::SetReadOnlyFlag( const DirEntry &rEntry, BOOL bRO )
+{
+
+ ByteString aFPath(rEntry.GetFull(), osl_getThreadTextEncoding());
+
+#if defined WNT
+ DWORD nRes = GetFileAttributes( (LPCTSTR) aFPath.GetBuffer() );
+ if ( ULONG_MAX != nRes )
+ nRes = SetFileAttributes( (LPCTSTR) aFPath.GetBuffer(),
+ ( nRes & ~FILE_ATTRIBUTE_READONLY ) |
+ ( bRO ? FILE_ATTRIBUTE_READONLY : 0 ) );
+ return ( ULONG_MAX == nRes ) ? ERRCODE_IO_UNKNOWN : 0;
+#elif defined OS2
+ FILESTATUS3 aFileStat;
+ APIRET nRet = DosQueryPathInfo( (PSZ)aFPath.GetBuffer(), 1, &aFileStat, sizeof(aFileStat) );
+ if ( !nRet )
+ {
+ aFileStat.attrFile = ( aFileStat.attrFile & ~FILE_READONLY ) |
+ ( bRO ? FILE_READONLY : 0 );
+ nRet = DosSetPathInfo( (PSZ)aFPath.GetBuffer(), 1, &aFileStat, sizeof(aFileStat), 0 );
+ }
+ switch ( nRet )
+ {
+ case NO_ERROR:
+ return ERRCODE_NONE;
+
+ case ERROR_SHARING_VIOLATION:
+ return ERRCODE_IO_LOCKVIOLATION;
+
+ default:
+ return ERRCODE_IO_NOTEXISTS;
+ }
+#elif defined UNX
+ /* first, stat the object to get permissions */
+ struct stat aBuf;
+ if (stat(aFPath.GetBuffer(), &aBuf))
+ return ERRCODE_IO_NOTEXISTS;
+ /* set or clear write bit for user */
+ mode_t nMode;
+ if (bRO)
+ {
+ nMode = aBuf.st_mode & ~S_IWUSR;
+ nMode = aBuf.st_mode & ~S_IWGRP;
+ nMode = aBuf.st_mode & ~S_IWOTH;
+ }
+ else
+ nMode = aBuf.st_mode | S_IWUSR;
+ /* change it on fs */
+ if (chmod(aFPath.GetBuffer(), nMode))
+ {
+ switch (errno)
+ {
+ case EPERM :
+ case EROFS :
+ return ERRCODE_IO_ACCESSDENIED;
+ default :
+ return ERRCODE_IO_NOTEXISTS;
+ }
+ }
+ else
+ return ERRCODE_NONE;
+#else
+ return ERRCODE_IO_NOTSUPPORTED;
+#endif
+}
+
+/*************************************************************************
+|*
+|* FileStat::SetDateTime
+|*
+|* Ersterstellung PB 27.06.97
+|* Letzte Aenderung
+|*
+*************************************************************************/
+#if defined WNT || defined OS2
+
+void FileStat::SetDateTime( const String& rFileName,
+ const DateTime& rNewDateTime )
+{
+ ByteString aFileName(rFileName, osl_getThreadTextEncoding());
+
+ Date aNewDate = rNewDateTime;
+ Time aNewTime = rNewDateTime;
+
+#if defined WNT
+ TIME_ZONE_INFORMATION aTZI;
+ DWORD dwTZI = GetTimeZoneInformation( &aTZI );
+
+ if ( dwTZI != (DWORD)-1 && dwTZI != TIME_ZONE_ID_UNKNOWN )
+ {
+ // 1. Korrektur der Zeitzone
+ LONG nDiff = aTZI.Bias;
+ Time aOldTime = aNewTime; // alte Zeit merken
+
+ // 2. evt. Korrektur Sommer-/Winterzeit
+ if ( dwTZI == TIME_ZONE_ID_DAYLIGHT )
+ nDiff += aTZI.DaylightBias;
+
+ Time aDiff( abs( nDiff / 60 /*Min -> Std*/ ), 0 );
+
+ if ( nDiff > 0 )
+ {
+ aNewTime += aDiff; // Stundenkorrektur
+
+ // bei "Uberlauf korrigieren
+ if ( aNewTime >= Time( 24, 0 ) )
+ aNewTime -= Time( 24, 0 );
+
+ // Tages"uberlauf?
+ if ( aOldTime == Time( 0, 0 ) || // 00:00 -> 01:00
+ aNewTime < aOldTime ) // 23:00 -> 00:00 | 01:00 ...
+ aNewDate++;
+ }
+ else if ( nDiff < 0 )
+ {
+ aNewTime -= aDiff; // Stundenkorrektur
+
+ // negative Zeit (-1:00) korrigieren: 23:00
+ if (aNewTime < Time( 0, 0 ) )
+ aNewTime += Time( 24, 0 );
+
+ // Tagesunterlauf ?
+ if ( aOldTime == Time( 0, 0 ) || // 00:00 -> 23:00
+ aNewTime > aOldTime ) // 01:00 -> 23:00 | 22:00 ...
+ aNewDate--;
+ }
+ }
+
+
+ SYSTEMTIME aTime;
+ aTime.wYear = aNewDate.GetYear();
+ aTime.wMonth = aNewDate.GetMonth();
+ aTime.wDayOfWeek = 0;
+ aTime.wDay = aNewDate.GetDay();
+ aTime.wHour = aNewTime.GetHour();
+ aTime.wMinute = aNewTime.GetMin();
+ aTime.wSecond = aNewTime.GetSec();
+ aTime.wMilliseconds = 0;
+ FILETIME aFileTime;
+ SystemTimeToFileTime( &aTime, &aFileTime );
+
+ HANDLE hFile = CreateFile( aFileName.GetBuffer(), GENERIC_WRITE, 0, 0,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
+
+ if ( hFile != INVALID_HANDLE_VALUE )
+ {
+ SetFileTime( hFile, &aFileTime, &aFileTime, &aFileTime );
+ CloseHandle( hFile );
+ }
+#elif defined OS2
+
+ // open file
+ ULONG nAction = FILE_EXISTED;
+ HFILE hFile = 0;
+ ULONG nFlags = OPEN_FLAGS_WRITE_THROUGH |
+ OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE |
+ OPEN_FLAGS_RANDOM | OPEN_FLAGS_NOINHERIT |
+ OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE;
+
+ APIRET nRet = DosOpen((PSZ)aFileName.GetBuffer(), &hFile, (PULONG)&nAction,
+ 0/*size*/, FILE_NORMAL,
+ OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
+ nFlags, 0/*ea*/);
+
+ if ( nRet == 0 )
+ {
+ FILESTATUS3 FileInfoBuffer;
+
+ nRet = DosQueryFileInfo(
+ hFile, 1, &FileInfoBuffer, sizeof(FileInfoBuffer));
+
+ if ( nRet == 0 )
+ {
+ FDATE aNewDate;
+ FTIME aNewTime;
+
+ // create date and time words
+ aNewDate.day = rNewDateTime.GetDay();
+ aNewDate.month = rNewDateTime.GetMonth();
+ aNewDate.year = rNewDateTime.GetYear() - 1980;
+ aNewTime.twosecs = rNewDateTime.GetSec() / 2;
+ aNewTime.minutes = rNewDateTime.GetMin();
+ aNewTime.hours = rNewDateTime.GetHour();
+
+ // set file date and time
+ FileInfoBuffer.fdateCreation = aNewDate;
+ FileInfoBuffer.ftimeCreation = aNewTime;
+ FileInfoBuffer.fdateLastAccess = aNewDate;
+ FileInfoBuffer.ftimeLastAccess = aNewTime;
+ FileInfoBuffer.fdateLastWrite = aNewDate;
+ FileInfoBuffer.ftimeLastWrite = aNewTime;
+
+ DosSetFileInfo(hFile, 1, &FileInfoBuffer, sizeof(FileInfoBuffer));
+ }
+ DosClose(hFile);
+ }
+#endif
+
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/makefile.mk b/tools/source/fsys/makefile.mk
new file mode 100644
index 000000000000..b1d34d6347f3
--- /dev/null
+++ b/tools/source/fsys/makefile.mk
@@ -0,0 +1,67 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=tools
+TARGET=fsys
+ENABLE_EXCEPTIONS=true
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+.IF "$(COM)"=="GCC"
+CFLAGSCXX+=-fexceptions
+.ENDIF
+
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/tempfile.obj \
+ $(SLO)$/wldcrd.obj \
+ $(SLO)$/fstat.obj \
+ $(SLO)$/comdep.obj \
+ $(SLO)$/filecopy.obj \
+ $(SLO)$/dirent.obj \
+ $(SLO)$/tdir.obj \
+ $(SLO)$/urlobj.obj
+
+OBJFILES= $(OBJ)$/wldcrd.obj \
+ $(OBJ)$/fstat.obj \
+ $(OBJ)$/comdep.obj \
+ $(OBJ)$/filecopy.obj \
+ $(OBJ)$/dirent.obj \
+ $(OBJ)$/tdir.obj \
+ $(OBJ)$/urlobj.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/tools/source/fsys/os2.cxx b/tools/source/fsys/os2.cxx
new file mode 100644
index 000000000000..ca57f7dd9ca9
--- /dev/null
+++ b/tools/source/fsys/os2.cxx
@@ -0,0 +1,885 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define INCL_DOSEXCEPTIONS
+
+#include <stdlib.h>
+
+#ifdef __BORLANDC__
+#include <alloc.h>
+#else
+#include <malloc.h>
+#endif
+#include <tools/debug.hxx>
+#include <tools/list.hxx>
+#include <tools/bigint.hxx>
+#include <tools/fsys.hxx>
+#include "comdep.hxx"
+
+#ifdef OS2
+#include <osl/mutex.hxx>
+#endif
+
+int Sys2SolarError_Impl( int nSysErr );
+
+DECLARE_LIST( DirEntryList, DirEntry* );
+DECLARE_LIST( FSysSortList, FSysSort* );
+DECLARE_LIST( FileStatList, FileStat* );
+
+static char sCaseMap[256];
+static BOOL bCaseMap = FALSE;
+static BOOL bDriveMap = FALSE;
+
+struct DriveMapItem
+{
+ DirEntryKind nKind;
+ char cName;
+ FSysPathStyle nStyle;
+};
+
+void CreateCaseMapImpl();
+void CreateDriveMapImpl();
+
+static DriveMapItem aDriveMap[26];
+
+static BOOL bLastCaseSensitive = FALSE;
+
+//====================================================================
+
+int ApiRet2ToSolarError_Impl( int nApiRet )
+{
+ switch ( nApiRet )
+ {
+ case NO_ERROR: return ERRCODE_NONE;
+ case ERROR_FILE_NOT_FOUND: return ERRCODE_IO_NOTEXISTS;
+ case ERROR_PATH_NOT_FOUND: return ERRCODE_IO_NOTEXISTSPATH;
+ case ERROR_TOO_MANY_OPEN_FILES: return ERRCODE_IO_TOOMANYOPENFILES;
+ case ERROR_ACCESS_DENIED: return ERRCODE_IO_ACCESSDENIED;
+ case ERROR_NOT_ENOUGH_MEMORY: return ERRCODE_IO_OUTOFMEMORY;
+ case ERROR_BAD_FORMAT: return ERRCODE_IO_WRONGFORMAT;
+ case ERROR_NOT_SAME_DEVICE: return ERRCODE_IO_INVALIDDEVICE;
+ case ERROR_WRITE_PROTECT: return ERRCODE_IO_INVALIDDEVICE;
+ case ERROR_BAD_UNIT: return ERRCODE_IO_INVALIDDEVICE;
+ case ERROR_CRC: return ERRCODE_IO_INVALIDDEVICE;
+ case ERROR_NOT_DOS_DISK: return ERRCODE_IO_INVALIDDEVICE;
+ case ERROR_WRITE_FAULT: return ERRCODE_IO_CANTWRITE;
+ case ERROR_READ_FAULT: return ERRCODE_IO_CANTREAD;
+ case ERROR_SHARING_VIOLATION: return ERRCODE_IO_LOCKVIOLATION;
+ case ERROR_LOCK_VIOLATION: return ERRCODE_IO_LOCKVIOLATION;
+ case ERROR_WRONG_DISK: return ERRCODE_IO_LOCKVIOLATION;
+ case ERROR_HANDLE_DISK_FULL: return ERRCODE_IO_OUTOFSPACE;
+ case ERROR_NOT_SUPPORTED: return ERRCODE_IO_NOTSUPPORTED;
+ case ERROR_DUP_NAME: return ERRCODE_IO_ALREADYEXISTS;
+ case ERROR_BAD_NETPATH: return ERRCODE_IO_NOTEXISTSPATH;
+ case ERROR_DEV_NOT_EXIST: return ERRCODE_IO_NOTEXISTS;
+ case ERROR_NETWORK_ACCESS_DENIED: return ERRCODE_IO_ACCESSDENIED;
+ case ERROR_INVALID_PARAMETER: return ERRCODE_IO_INVALIDPARAMETER;
+ case ERROR_NET_WRITE_FAULT: return ERRCODE_IO_CANTWRITE;
+ case ERROR_DEVICE_IN_USE: return ERRCODE_IO_INVALIDPARAMETER;
+ case ERROR_DISK_FULL: return ERRCODE_IO_OUTOFSPACE;
+ case ERROR_BAD_ARGUMENTS: return ERRCODE_IO_INVALIDPARAMETER;
+ case ERROR_BAD_PATHNAME: return ERRCODE_IO_NOTEXISTSPATH;
+ case ERROR_LOCK_FAILED: return ERRCODE_IO_LOCKVIOLATION;
+ case ERROR_LOCKED: return ERRCODE_IO_LOCKVIOLATION;
+ case ERROR_DUPLICATE_NAME: return ERRCODE_IO_ALREADYEXISTS;
+ case ERROR_DIRECTORY_IN_CDS: return ERRCODE_IO_LOCKVIOLATION;
+ case ERROR_CURRENT_DIRECTORY: return ERRCODE_IO_LOCKVIOLATION;
+ case ERROR_FILENAME_EXCED_RANGE: return ERRCODE_IO_NAMETOOLONG;
+ }
+
+ DBG_TRACE1( "FSys: unknown apiret error %d occured", nApiRet );
+ return FSYS_ERR_UNKNOWN;
+}
+
+//--------------------------------------------------------------------
+
+char* volumeid( const char* pPfad )
+{
+ static FSINFO aFSInfoBuf;
+ ULONG ulFSInfoLevel = FSIL_VOLSER;
+ ULONG nDriveNumber;
+
+ nDriveNumber = toupper(*pPfad) - 'A' + 1;
+
+ if ( nDriveNumber >= 3 )
+ {
+ APIRET rc = DosQueryFSInfo(
+ nDriveNumber, ulFSInfoLevel, &aFSInfoBuf, sizeof(FSINFO) );
+ if ( rc )
+ return 0;
+ return (char*) aFSInfoBuf.vol.szVolLabel;
+ }
+ return 0;
+}
+
+//--------------------------------------------------------------------
+
+/*************************************************************************
+|*
+|* DirEntry::ToAbs()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91 13:30
+|*
+*************************************************************************/
+
+BOOL DirEntry::ToAbs()
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ if ( FSYS_FLAG_VOLUME == eFlag )
+ {
+ eFlag = FSYS_FLAG_ABSROOT;
+ return TRUE;
+ }
+
+ if ( IsAbs() )
+ return TRUE;
+
+ char sBuf[_MAX_PATH + 1];
+ *this = DirEntry( String( getcwd( sBuf, _MAX_PATH ), osl_getThreadTextEncoding() ) ) + *this;
+
+ return IsAbs();
+}
+
+/*************************************************************************
+|*
+|* DirEntry::GetVolume()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 04.03.92
+|* Letzte Aenderung MI 04.03.92
+|*
+*************************************************************************/
+
+String DirEntry::GetVolume() const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ String aRet;
+ const DirEntry *pTop = ImpGetTopPtr();
+ ByteString aName = ByteString( pTop->aName ).ToLowerAscii();
+
+ if ( ( pTop->eFlag == FSYS_FLAG_ABSROOT ||
+ pTop->eFlag == FSYS_FLAG_RELROOT ||
+ pTop->eFlag == FSYS_FLAG_VOLUME )
+ && aName != "a:" && aName != "b:" && Exists() )
+ {
+ const char *pVol;
+ pVol = volumeid( (char*) pTop->aName.GetBuffer() );
+ if (pVol)
+ aRet = String( pVol, osl_getThreadTextEncoding());
+ }
+
+ return aRet;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::SetCWD()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MI 21.05.92
+|*
+*************************************************************************/
+
+BOOL DirEntry::SetCWD( BOOL bSloppy ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ if ( eFlag == FSYS_FLAG_CURRENT && !aName.Len() )
+ return TRUE;
+
+ if ( !chdir(ByteString(GetFull(), osl_getThreadTextEncoding()).GetBuffer()) )
+ {
+ //nError = FSYS_ERR_OK;
+ return TRUE;
+ }
+
+ if ( bSloppy && pParent &&
+ !chdir(ByteString(pParent->GetFull(), osl_getThreadTextEncoding()).GetBuffer()) )
+ {
+ //nError = FSYS_ERR_OK;
+ return TRUE;
+ }
+
+ //nError = FSYS_ERR_NOTADIRECTORY;
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::MoveTo()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91 14:07
+|*
+*************************************************************************/
+
+
+//-------------------------------------------------------------------------
+
+USHORT DirReader_Impl::Init()
+{
+ // Block-Devices auflisten?
+ if ( pDir->eAttrMask & FSYS_KIND_BLOCK )
+ {
+ CreateDriveMapImpl();
+ // CWD merken
+ DirEntry aCurrentDir;
+ aCurrentDir.ToAbs();
+
+ // einzeln auf Existenz und Masken-konformit"at pr"ufen
+ USHORT nRead = 0;
+ char sDrive[3] = { '?', ':', 0 };
+ char sRoot[4] = { '?', ':', '\\', 0 };
+ for ( char c = 'a'; c <= 'z'; c++ )
+ {
+ sDrive[0] = c;
+ sRoot[0] = c;
+ DirEntry* pDrive = new DirEntry( sDrive, FSYS_FLAG_VOLUME, FSYS_STYLE_HOST );
+ if ( pDir->aNameMask.Matches( String( ByteString(sDrive), osl_getThreadTextEncoding()))
+ && aDriveMap[c-'a'].nKind != FSYS_KIND_UNKNOWN )
+ {
+ if ( pDir->pStatLst ) //Status fuer Sort gewuenscht?
+ {
+ FileStat *pNewStat = new FileStat( *pDrive );
+ pDir->ImpSortedInsert( pDrive, pNewStat );
+ }
+ else
+ pDir->ImpSortedInsert( pDrive, NULL );
+ ++nRead;
+ }
+ else
+ delete pDrive;
+ }
+
+ // CWD restaurieren
+ aCurrentDir.SetCWD();
+ return nRead;
+ }
+
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+USHORT DirReader_Impl::Read()
+{
+ if (!pDosDir)
+ {
+ pDosDir = opendir( (char*) ByteString(aPath, osl_getThreadTextEncoding()).GetBuffer() );
+ }
+
+ if (!pDosDir)
+ {
+ bReady = TRUE;
+ return 0;
+ }
+
+ // Directories und Files auflisten?
+ if ( ( pDir->eAttrMask & FSYS_KIND_DIR || pDir->eAttrMask & FSYS_KIND_FILE ) &&
+ ( ( pDosEntry = readdir( pDosDir ) ) != NULL ) )
+ {
+ String aD_Name(pDosEntry->d_name, osl_getThreadTextEncoding());
+ if ( pDir->aNameMask.Matches( aD_Name ) )
+ {
+ DirEntryFlag eFlag =
+ 0 == strcmp( pDosEntry->d_name, "." ) ? FSYS_FLAG_CURRENT
+ : 0 == strcmp( pDosEntry->d_name, ".." ) ? FSYS_FLAG_PARENT
+ : FSYS_FLAG_NORMAL;
+ DirEntry *pTemp = new DirEntry( ByteString(pDosEntry->d_name), eFlag, FSYS_STYLE_UNX );
+ if ( pParent )
+ pTemp->ImpChangeParent( new DirEntry( *pParent ), FALSE);
+ FileStat aStat( *pTemp );
+ if ( ( ( ( pDir->eAttrMask & FSYS_KIND_DIR ) &&
+ ( aStat.IsKind( FSYS_KIND_DIR ) ) ) ||
+ ( ( pDir->eAttrMask & FSYS_KIND_FILE ) &&
+ !( aStat.IsKind( FSYS_KIND_DIR ) ) ) ) &&
+ !( pDir->eAttrMask & FSYS_KIND_VISIBLE &&
+ pDosEntry->d_name[0] == '.' ) )
+ {
+ if ( pDir->pStatLst ) //Status fuer Sort gewuenscht?
+ pDir->ImpSortedInsert( pTemp, new FileStat( aStat ) );
+ else
+ pDir->ImpSortedInsert( pTemp, NULL );;
+ return 1;
+ }
+ else
+ delete pTemp;
+ }
+ }
+ else
+ bReady = TRUE;
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* FileStat::FileStat()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MA 05.11.91
+|* Letzte Aenderung MA 07.11.91
+|*
+*************************************************************************/
+
+FileStat::FileStat( const void *pInfo, // struct dirent
+ const void * ): // dummy
+ aDateCreated(0),
+ aTimeCreated(0),
+ aDateModified(0),
+ aTimeModified(0),
+ aDateAccessed(0),
+ aTimeAccessed(0)
+{
+ struct dirent *pDirent = (struct dirent*) pInfo;
+
+ nSize = pDirent->d_size;
+
+ aDateCreated = MsDos2Date( (FDATE*) &pDirent->d_date );
+ aTimeCreated = MsDos2Time( (FTIME*) &pDirent->d_time );
+ aDateModified = aDateModified;
+ aTimeModified = aTimeModified;
+ aDateAccessed = aDateModified;
+ aTimeAccessed = aTimeModified;
+
+ nKindFlags = FSYS_KIND_FILE;
+ if ( pDirent->d_type & DOS_DIRECT )
+ nKindFlags = FSYS_KIND_DIR;
+}
+
+/*************************************************************************
+|*
+|* FileStat::Update()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 11.06.91
+|* Letzte Aenderung MA 07.11.91
+|*
+*************************************************************************/
+
+struct _FSYS_FSQBUFFER
+{
+ FSQBUFFER2 aBuf;
+ UCHAR sBuf[256];
+};
+
+BOOL FileStat::Update( const DirEntry& rDirEntry, BOOL bAccessRemovableDevice )
+{
+ nSize = 0;
+ FSysPathStyle eStyle = FSYS_STYLE_UNKNOWN;
+ aCreator.Erase();
+ aType.Erase();
+ aDateCreated = Date(0);
+ aTimeCreated = Time(0);
+ aDateModified = Date(0);
+ aTimeModified = Time(0);
+ aDateAccessed = Date(0);
+ aTimeAccessed = Time(0);
+
+ if ( !rDirEntry.IsValid() )
+ {
+ nError = FSYS_ERR_NOTEXISTS;
+ return FALSE;
+ }
+
+ // Sonderbehandlung falls es sich um eine Root ohne Laufwerk handelt
+ if ( !rDirEntry.aName.Len() && rDirEntry.eFlag == FSYS_FLAG_ABSROOT )
+ {
+ nKindFlags = FSYS_KIND_DIR;
+ nError = FSYS_ERR_OK;
+ return TRUE;
+ }
+
+ // Sonderbehandlung falls es sich um eine Wildcard handelt
+ ByteString aTempName( rDirEntry.GetName(), osl_getThreadTextEncoding() );
+ if ( strchr( aTempName.GetBuffer(), '?' ) ||
+ strchr( aTempName.GetBuffer(), '*' ) ||
+ strchr( aTempName.GetBuffer(), ';' ) )
+ {
+ nKindFlags = FSYS_KIND_WILD;
+ nError = FSYS_ERR_OK;
+ return TRUE;
+ }
+
+ // Sonderbehandlung falls es sich um eine Root handelt
+ if ( rDirEntry.eFlag == FSYS_FLAG_VOLUME ||
+ rDirEntry.eFlag == FSYS_FLAG_ABSROOT )
+ {
+ if ( rDirEntry.eFlag == FSYS_FLAG_VOLUME )
+ nKindFlags = FSYS_KIND_DEV;
+ else
+ nKindFlags = FSYS_KIND_DIR;
+
+ if ( rDirEntry.aName.Len() == 2 )
+ {
+ if ( !bDriveMap )
+ CreateDriveMapImpl();
+
+ ByteString rDirEntryUpperCase = ByteString( rDirEntry.aName ).ToUpperAscii();
+ DriveMapItem &rItem = aDriveMap[rDirEntryUpperCase.GetChar(0) - 'A'];
+ if ( !rItem.nKind )
+ {
+ nError = ERRCODE_IO_INVALIDDEVICE;
+ nKindFlags = FSYS_KIND_UNKNOWN;
+ return FALSE;
+ }
+ else
+ {
+ if ( rDirEntry.eFlag == FSYS_FLAG_VOLUME )
+ nKindFlags |= FSYS_KIND_BLOCK | rItem.nKind;
+ eStyle = rItem.nStyle;
+ }
+ }
+
+ nError = FSYS_ERR_OK;
+ return TRUE;
+ }
+
+ // disable error-boxes for hard-errors
+ DosError(FERR_DISABLEHARDERR);
+
+ // Statusinformation vom Betriebssystem holen
+ DirEntry aTempDirEntry( rDirEntry );
+ char* p;
+
+ aTempDirEntry.ToAbs();
+ ByteString aFullName( aTempDirEntry.GetFull(), osl_getThreadTextEncoding() );
+
+ p = (char *) aFullName.GetBuffer();
+
+ FILESTATUS3 filestat;
+ memset( &filestat, 0, sizeof( filestat ) );
+ if( DosQueryPathInfo( (PSZ)p, 1, &filestat, sizeof( filestat ) ) )
+ {
+ nError = FSYS_ERR_NOTEXISTS;
+ nKindFlags = FSYS_KIND_UNKNOWN;
+ return FALSE;
+ }
+
+ nError = FSYS_ERR_OK;
+ nSize = filestat.cbFile;
+
+ nKindFlags = FSYS_KIND_UNKNOWN;
+ if( filestat.attrFile & FILE_DIRECTORY )
+ nKindFlags |= FSYS_KIND_DIR;
+ if ( nKindFlags == FSYS_KIND_UNKNOWN )
+ nKindFlags = nKindFlags | FSYS_KIND_FILE;
+
+ aDateModified = Date( filestat.fdateLastWrite.day,
+ filestat.fdateLastWrite.month,
+ filestat.fdateLastWrite.year + 1980 );
+
+ aTimeModified = Time( filestat.ftimeLastWrite.hours,
+ filestat.ftimeLastWrite.minutes,
+ filestat.ftimeLastWrite.twosecs*2 );
+
+ if ( filestat.fdateCreation.day )
+ {
+ aDateCreated = Date( filestat.fdateCreation.day,
+ filestat.fdateCreation.month,
+ filestat.fdateCreation.year + 1980 );
+
+ aTimeCreated = Time( filestat.ftimeCreation.hours,
+ filestat.ftimeCreation.minutes,
+ filestat.ftimeCreation.twosecs*2 );
+ }
+ else
+ {
+ aDateCreated = aDateModified;
+ aTimeCreated = aTimeModified;
+ }
+
+ if ( filestat.fdateLastAccess.day > 0 )
+ {
+ aDateAccessed = Date( filestat.fdateLastAccess.day,
+ filestat.fdateLastAccess.month,
+ filestat.fdateLastAccess.year + 1980 );
+
+ aTimeAccessed = Time( filestat.ftimeLastAccess.hours,
+ filestat.ftimeLastAccess.minutes,
+ filestat.ftimeLastAccess.twosecs*2 );
+ }
+ else
+ {
+ aDateAccessed = aDateModified;
+ aTimeAccessed = aTimeModified;
+ }
+
+ return TRUE;
+}
+
+BOOL IsRedirectable_Impl( const ByteString &rPath )
+{
+ if ( rPath.Len() >= 3 && ':' == rPath.GetBuffer()[1] )
+ {
+ ByteString aVolume = rPath.Copy( 0, 3 );
+ DriveMapItem &rItem = aDriveMap[toupper(aVolume.GetChar(0)) - 'A'];
+ return FSYS_KIND_FIXED != rItem.nKind;
+ }
+ return FALSE;
+}
+
+
+/*************************************************************************
+|*
+|* TempDirImpl()
+|*
+|* Beschreibung liefert den Namens des Directories fuer temporaere
+|* Dateien
+|* Ersterstellung MI 16.03.94
+|* Letzte Aenderung MI 16.03.94
+|*
+*************************************************************************/
+
+const char* TempDirImpl( char *pBuf )
+{
+ PSZ pVar;
+ USHORT nRet;
+ BOOL bAppendTemp = FALSE; // mu\s noch \\temp angeh"angt werden
+
+ // Erstmal sehen, ob TEMP oder TMP gesetzt sind
+ nRet = DosScanEnv( (PSZ)"TEMP", &pVar );
+ if( nRet )
+ nRet = DosScanEnv( (PSZ)"temp", &pVar );
+ if( nRet )
+ nRet = DosScanEnv( (PSZ)"TMP", &pVar );
+ if( nRet )
+ nRet = DosScanEnv( (PSZ)"tmp", &pVar );
+ if( nRet )
+ nRet = DosScanEnv( (PSZ)"TMPDIR", &pVar );
+
+ // falls das geklappt hat, und ein Backslash dranhaengt,
+ // oder falls es bisher nicht geklappt hat,
+ // muessen wir nachher einen Backslash entfernen
+ BOOL bRemoveBS = nRet || *(pVar+strlen(pVar)-1) == '\\';
+
+ // Keine temp-Variable gefunden, dann gehen wir mal auf die Suche
+ // nach dem System-Laufwerk
+ if( nRet )
+ {
+ nRet = DosScanEnv( (PSZ)"USER_INI",&pVar );
+ bAppendTemp = (0 == nRet);
+ }
+ if( nRet )
+ {
+ nRet = DosScanEnv( (PSZ)"SYSTEM_INI", &pVar );
+ bAppendTemp = (0 == nRet);
+ }
+ if( nRet )
+ // Wenn das immer noch nicht reicht nehmen wir eben die Root von C:
+#ifdef __BORLANDC__
+ pVar = (PSZ)"c:\\temp\\";
+#else
+ pVar = (PCSZ)"c:\\temp\\";
+#endif
+ strcpy( pBuf, (const char*)pVar );
+
+ // jetzt haengt ggf. ein Backlash dran, den wir abschneiden,
+ // ggf. inklusive dahinter haengendem Dateinamen
+ if ( bRemoveBS )
+ {
+ char *pTail = pBuf + strlen(pBuf) - 1;
+ for ( char cLast = *pTail; cLast != '\\'; cLast = *(--pTail) )
+ *pTail = 0;
+ }
+
+ if ( bAppendTemp )
+ strcat( pBuf, "\\temp" );
+ DirEntry( pBuf ).MakeDir();
+
+ return pBuf;
+}
+
+#define CURRENT_COUNTRY 0
+#define NLS_CODEPAGE 850
+
+/*====================================================================
+ * CreateDriveMapImpl()
+ * creates a map of drive-infos like FileSystem (style) and Kind (remote)
+ *--------------------------------------------------------------------*/
+typedef struct _FSQBUFFER_
+{
+ FSQBUFFER2 aBuf;
+ UCHAR sBuf[64];
+} FSQBUFFER_;
+
+void CreateDriveMapImpl()
+{
+#ifdef POWERPC
+ // !!!!! Hack, da der untere Teil mit Beta 2 noch abstuertzt !!!!!
+ BYTE nFloppies = 1;
+ for ( USHORT nDrive = 0; nDrive < 26; ++nDrive )
+ {
+ if ( nDrive < nFloppies )
+ {
+ aDriveMap[nDrive].nKind = FSYS_KIND_REMOVEABLE;
+ aDriveMap[nDrive].nStyle = FSYS_STYLE_FAT;
+ }
+ else
+ {
+ aDriveMap[nDrive].nKind = FSYS_KIND_UNKNOWN;
+ aDriveMap[nDrive].nStyle = FSYS_STYLE_UNKNOWN;
+ }
+ }
+
+ aDriveMap[2].nKind = FSYS_KIND_FIXED;
+ aDriveMap[2].nStyle = FSYS_STYLE_FAT;
+#else
+ FSQBUFFER_ aBuf;
+ ULONG nBufLen;
+ APIRET nRet;
+ USHORT nDrive;
+
+ // disable error-boxes for hard-errors
+ DosError(FERR_DISABLEHARDERR);
+
+ // determine number of floppy-drives
+ BYTE nFloppies;
+ nRet = DosDevConfig( (void*) &nFloppies, DEVINFO_FLOPPY );
+
+ // reset the map
+ for ( nDrive = 0; nDrive < 26; ++nDrive )
+ {
+ if ( nDrive < nFloppies )
+ {
+ aDriveMap[nDrive].nKind = FSYS_KIND_REMOVEABLE;
+ aDriveMap[nDrive].nStyle = FSYS_STYLE_FAT;
+ }
+ else
+ {
+ aDriveMap[nDrive].nKind = FSYS_KIND_UNKNOWN;
+ aDriveMap[nDrive].nStyle = FSYS_STYLE_UNKNOWN;
+ }
+ }
+
+ // determine file-system via DosOpen/DocDevIOCtrl
+ for ( nDrive = 2; nDrive < 26; ++nDrive )
+ {
+ // open drive
+ BOOL bFixed;
+ HFILE nDevHandle;
+ char pDriveName[3] = "#:";
+ pDriveName[0] = nDrive+'a';
+ ULONG nAction;
+ nRet = DosOpen( (PSZ) pDriveName, &nDevHandle,
+ &nAction, 0, 0, OPEN_ACTION_OPEN_IF_EXISTS,
+ OPEN_FLAGS_DASD|OPEN_SHARE_DENYNONE|OPEN_ACCESS_READONLY,
+ 0 );
+
+ // exists?
+ if ( !nRet )
+ {
+ // removeable?
+ BYTE nDriveId = nDrive;
+ ULONG nParaOutLen, nDataOutLen;
+ nRet = DosDevIOCtl(nDevHandle, 8, 0x20,
+ &nDriveId, sizeof(nDriveId), &nParaOutLen,
+ &bFixed, sizeof(bFixed), &nDataOutLen );
+
+ // prepare the drive-map
+ if ( !nRet && !bFixed )
+ aDriveMap[nDrive].nKind = FSYS_KIND_REMOVEABLE;
+
+ // close drive
+ DosClose(nDevHandle);
+ }
+ else if ( nRet == ERROR_NOT_READY )
+ aDriveMap[nDrive].nKind = FSYS_KIND_REMOVEABLE | FSYS_KIND_CDROM;
+ }
+
+ // determine file-system via FSAttach
+ nRet = 0;
+ for ( USHORT n = 3; nRet != ERROR_NO_MORE_ITEMS; ++n )
+ {
+ nBufLen = sizeof( aBuf );
+ nRet = DosQueryFSAttach( 0, n, FSAIL_DRVNUMBER,
+ (_FSQBUFFER2*) &aBuf, &nBufLen );
+ if ( !nRet )
+ {
+ nDrive = toupper(aBuf.aBuf.szName[0]) - 'A';
+
+ if ( aDriveMap[nDrive].nKind == FSYS_KIND_UNKNOWN )
+ aDriveMap[nDrive].nKind =
+ aBuf.aBuf.iType == 3 ? FSYS_KIND_FIXED :
+ aBuf.aBuf.iType == 4 ? FSYS_KIND_REMOTE :
+ FSYS_KIND_UNKNOWN;
+
+ char *pType = (char*)(aBuf.aBuf.szName + aBuf.aBuf.cbName + 1);
+ aDriveMap[nDrive].nStyle =
+ strcmp( pType, "FAT" ) == 0 ? FSYS_STYLE_FAT :
+ strcmp( pType, "FAT32" ) == 0 ? FSYS_STYLE_VFAT :
+ strcmp( pType, "NTFS" ) == 0 ? FSYS_STYLE_NTFS :
+ strcmp( pType, "HPFS" ) == 0 ? FSYS_STYLE_HPFS :
+ strcmp( pType, "JFS" ) == 0 ? FSYS_STYLE_HPFS :
+ strcmp( pType, "RAMFS" ) == 0 ? FSYS_STYLE_HPFS :
+ strcmp( pType, "NDFS32" ) == 0 ? FSYS_STYLE_HPFS :
+ strcmp( pType, "NWFS" ) == 0 ? FSYS_STYLE_NWFS :
+ strcmp( pType, "EXT2" ) == 0 ? FSYS_STYLE_UNX :
+ strcmp( pType, "NFS" ) == 0 ? FSYS_STYLE_UNX :
+ FSYS_STYLE_UNKNOWN;
+ if ( strcmp( pType, "CDFS" ) == 0 )
+ aDriveMap[nDrive].nKind = FSYS_KIND_CDROM|FSYS_KIND_REMOVEABLE;
+ }
+ }
+#endif
+
+ bDriveMap = TRUE;
+}
+
+Time MsDos2Time( const time_t *pTimeT )
+{
+ tm *pTm = localtime( pTimeT );
+ if ( pTm )
+ return Time( pTm->tm_hour, pTm->tm_min, pTm->tm_sec );
+ else
+ return Time(0);
+}
+
+Date MsDos2Date( const time_t *pTimeT )
+{
+ tm *pTm = localtime( pTimeT );
+ if ( pTm )
+ return Date( pTm->tm_mday, pTm->tm_mon + 1, pTm->tm_year );
+ else
+ return Date(0);
+}
+
+/*************************************************************************
+|*
+|* DirEntry::GetPathStyle() const
+|*
+|* Beschreibung
+|* Ersterstellung MI 11.05.95
+|* Letzte Aenderung MI 11.05.95
+|*
+*************************************************************************/
+
+FSysPathStyle DirEntry::GetPathStyle( const String &rDevice )
+{
+ ByteString aRootDir(rDevice, osl_getThreadTextEncoding());
+ // UNC-Pathname?
+ if ( aRootDir.Len()==0 || ( aRootDir.Len() > 1 && aRootDir.GetChar(1) != ':' ) )
+ return FSYS_STYLE_UNKNOWN;
+
+ if ( !bDriveMap )
+ CreateDriveMapImpl();
+ return aDriveMap[toupper(aRootDir.GetChar(0)) - 'A'].nStyle;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::IsCaseSensitive() const
+|*
+|* Beschreibung
+|* Ersterstellung TPF 26.02.1999
+|* Letzte Aenderung
+|*
+*************************************************************************/
+
+BOOL DirEntry::IsCaseSensitive( FSysPathStyle eFormatter ) const
+{
+ if (eFormatter==FSYS_STYLE_HOST)
+ {
+ if (GetPathStyle(GetDevice().GetName()) == FSYS_STYLE_UNX)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ BOOL isCaseSensitive = FALSE; // ich bin unter OS2, also ist der default im Zweifelsfall case insensitiv
+ switch ( eFormatter )
+ {
+ case FSYS_STYLE_MAC:
+ case FSYS_STYLE_FAT:
+ case FSYS_STYLE_VFAT:
+ case FSYS_STYLE_NTFS:
+ case FSYS_STYLE_NWFS:
+ case FSYS_STYLE_HPFS:
+ case FSYS_STYLE_DETECT:
+ {
+ isCaseSensitive = FALSE;
+ break;
+ }
+ case FSYS_STYLE_SYSV:
+ case FSYS_STYLE_BSD:
+ {
+ isCaseSensitive = TRUE;
+ break;
+ }
+ default:
+ {
+ isCaseSensitive = FALSE; // ich bin unter OS2, also ist der default im Zweifelsfall case insensitiv
+ break;
+ }
+ }
+ return isCaseSensitive;
+ }
+}
+
+
+
+
+//=========================================================================
+
+ErrCode FileStat::QueryDiskSpace( const String &rPath,
+ BigInt &rFreeBytes, BigInt &rTotalBytes )
+{
+ FSALLOCATE aFSInfoBuf;
+ ByteString aVol( DirEntry(rPath).ImpGetTopPtr()->GetName(), osl_getThreadTextEncoding());
+ ULONG nDriveNumber = toupper( aVol.GetChar(0) ) - 'A' + 1;
+
+ APIRET rc = DosQueryFSInfo( nDriveNumber, FSIL_ALLOC,
+ &aFSInfoBuf, sizeof(aFSInfoBuf) );
+ if ( rc )
+ return Sys2SolarError_Impl( rc );
+
+ BigInt aBytesPerCluster( BigInt(aFSInfoBuf.cbSector) *
+ BigInt(aFSInfoBuf.cSectorUnit) );
+ rFreeBytes = aBytesPerCluster * BigInt(aFSInfoBuf.cUnitAvail);
+ rTotalBytes = aBytesPerCluster * BigInt(aFSInfoBuf.cUnit);
+ return 0;
+}
+
+//=========================================================================
+
+void FSysEnableSysErrorBox( BOOL bEnable )
+{
+ DosError( bEnable ? 0 : FERR_DISABLEHARDERR );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/os2.hxx b/tools/source/fsys/os2.hxx
new file mode 100644
index 000000000000..be74befe36b5
--- /dev/null
+++ b/tools/source/fsys/os2.hxx
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _os2_hxx
+#define _os2_hxx
+
+
+#define INCL_DOSEXCEPTIONS
+#define INCL_DOSFILEMGR
+#define INCL_DOSPROCESS
+#define INCL_DOSDEVICES
+#define INCL_DOSERRORS
+#define INCL_DOSMISC
+#define INCL_DOSNLS /* National Language Support values */
+#include <svpm.h>
+
+#include <dirent.h>
+#include <string.h>
+
+#include <sys\types.h>
+#include <sys\stat.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <emx/syscalls.h>
+
+#define FSYS_UNIX FALSE
+
+#define DOS_DIRECT _A_SUBDIR
+#define DOS_VOLUMEID _A_VOLID
+
+#define _mkdir(p) mkdir(p, 0777)
+
+const char* TempDirImpl( char *pBuf );
+String ToLowerImpl( const String& );
+
+#define DEFSTYLE FSYS_STYLE_OS2
+#define MKDIR( p ) mkdir( (unsigned char*) p )
+#define CMP_LOWER(s) ( s.ToLowerAscii() )
+
+#define START_DRV 'a'
+
+inline BOOL DRIVE_EXISTS( char c )
+{
+ ULONG nCur, nMap;
+ APIRET nRet = DosQueryCurrentDisk( &nCur, &nMap );
+ return ( nMap & 1 << (c - 'a') ) != 0;
+}
+
+#include <time.h>
+
+inline Time MsDos2Time( FTIME* aTime )
+{
+ return Time( aTime->hours, aTime->minutes, 2*aTime->twosecs );
+}
+
+inline Date MsDos2Date( FDATE* aDate )
+{
+ return Date( aDate->day, aDate->month, aDate->year );
+}
+
+Time MsDos2Time( const time_t *pTimeT );
+
+Date MsDos2Date( const time_t *pTimeT );
+
+#define FSysFailOnErrorImpl()
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/tdir.cxx b/tools/source/fsys/tdir.cxx
new file mode 100644
index 000000000000..93b67d9c7b2d
--- /dev/null
+++ b/tools/source/fsys/tdir.cxx
@@ -0,0 +1,769 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#define _DIR_CXX
+
+#include <stdlib.h>
+#include <cstdarg>
+#include <limits.h>
+#include <tools/debug.hxx>
+#include <tools/list.hxx>
+
+#include "comdep.hxx"
+#include <tools/fsys.hxx>
+
+
+DBG_NAME( Dir )
+
+DECLARE_LIST( DirEntryList, DirEntry* )
+DECLARE_LIST( FSysSortList, FSysSort* )
+DECLARE_LIST( FileStatList, FileStat* )
+
+#define APPEND (USHORT) 65535
+
+/*************************************************************************
+|*
+|* Dir::InsertPointReached()
+|*
+|* Beschreibung stellt fest, ob eingefuegt werden musz
+|* Ersterstellung MA 05.11.91
+|* Letzte Aenderung MI 05.02.92
+|*
+*************************************************************************/
+
+BOOL Dir::ImpInsertPointReached( const DirEntry& rNewEntry,
+ const FileStat& rNewStat,
+ ULONG nCurPos, ULONG nSortIndex ) const
+{
+#define VALUE( nKindFlags ) \
+ ( ( FSYS_KIND_FILE | FSYS_KIND_DIR | FSYS_KIND_DEV | \
+ FSYS_KIND_CHAR | FSYS_KIND_BLOCK ) & nKindFlags )
+
+ // einfache Dinge erfordern einfache Loesungen
+ if ( !pLst->Count() )
+ return TRUE;
+
+ FSysSort nSort = *( pSortLst->GetObject( nSortIndex ) );
+ FileStat *pOldStat = NULL;
+ DirEntry *pCurLstObj = pLst->GetObject( nCurPos );
+ if ( pStatLst )
+ pOldStat = pStatLst->GetObject( nCurPos );
+
+ switch( nSort )
+ {
+ case FSYS_SORT_NAME:
+ case (FSYS_SORT_NAME | FSYS_SORT_ASCENDING):
+ if ( pCurLstObj->aName > rNewEntry.aName )
+ return TRUE;
+ if ( !(pCurLstObj->aName == rNewEntry.aName) )
+ return FALSE;
+ break;
+ case (FSYS_SORT_NAME | FSYS_SORT_DESCENDING):
+ if ( pCurLstObj->aName < rNewEntry.aName )
+ return TRUE;
+ if ( !(pCurLstObj->aName == rNewEntry.aName) )
+ return FALSE;
+ break;
+
+ case FSYS_SORT_EXT:
+ case (FSYS_SORT_EXT | FSYS_SORT_ASCENDING):
+ {
+ if ( pCurLstObj->GetExtension() > rNewEntry.GetExtension() )
+ return TRUE;
+ if ( !(pCurLstObj->GetExtension() == rNewEntry.GetExtension()) )
+ return FALSE;
+ break;
+ }
+ case (FSYS_SORT_EXT | FSYS_SORT_DESCENDING):
+ {
+ if ( pCurLstObj->GetExtension() < rNewEntry.GetExtension() )
+ return TRUE;
+ if ( !(pCurLstObj->GetExtension() == rNewEntry.GetExtension()) )
+ return FALSE;
+ break;
+ }
+
+ case FSYS_SORT_KIND:
+ case (FSYS_SORT_KIND | FSYS_SORT_ASCENDING ):
+ if ( VALUE(pOldStat->nKindFlags) > VALUE(rNewStat.nKindFlags) )
+ return TRUE;
+ if ( !(VALUE(pOldStat->nKindFlags) == VALUE(rNewStat.nKindFlags)) )
+ return FALSE;
+ break;
+ case (FSYS_SORT_KIND | FSYS_SORT_DESCENDING):
+ if ( VALUE(pOldStat->nKindFlags) < VALUE(rNewStat.nKindFlags) )
+ return TRUE;
+ if ( !(VALUE(pOldStat->nKindFlags) == VALUE(rNewStat.nKindFlags)) )
+ return FALSE;
+ break;
+
+ case FSYS_SORT_SIZE:
+ case (FSYS_SORT_SIZE | FSYS_SORT_ASCENDING):
+ if ( pOldStat->nSize > rNewStat.nSize )
+ return TRUE;
+ if ( !(pOldStat->nSize == rNewStat.nSize) )
+ return FALSE;
+ break;
+ case (FSYS_SORT_SIZE | FSYS_SORT_DESCENDING):
+ if ( pOldStat->nSize < rNewStat.nSize )
+ return TRUE;
+ if ( !(pOldStat->nSize == rNewStat.nSize) )
+ return FALSE;
+ break;
+
+ case FSYS_SORT_MODIFYED:
+ case (FSYS_SORT_MODIFYED | FSYS_SORT_ASCENDING):
+ if ( (pOldStat->aDateModified >= rNewStat.aDateModified) &&
+ (pOldStat->aTimeModified > rNewStat.aTimeModified) )
+ return TRUE;
+ if ( !((pOldStat->aDateModified == rNewStat.aDateModified) &&
+ (pOldStat->aTimeModified == rNewStat.aTimeModified)) )
+ return FALSE;
+ break;
+ case (FSYS_SORT_MODIFYED | FSYS_SORT_DESCENDING):
+ if ( (pOldStat->aDateModified <= rNewStat.aDateModified) &&
+ (pOldStat->aTimeModified < rNewStat.aTimeModified) )
+ return TRUE;
+ if ( !((pOldStat->aDateModified == rNewStat.aDateModified) &&
+ (pOldStat->aTimeModified == rNewStat.aTimeModified)) )
+ return FALSE;
+ break;
+
+ case FSYS_SORT_CREATED:
+ case (FSYS_SORT_CREATED | FSYS_SORT_ASCENDING):
+ if ( (pOldStat->aDateCreated >= rNewStat.aDateCreated) &&
+ (pOldStat->aTimeCreated > rNewStat.aTimeCreated) )
+ return TRUE;
+ if ( !((pOldStat->aDateCreated == rNewStat.aDateCreated) &&
+ (pOldStat->aTimeCreated == rNewStat.aTimeCreated)) )
+ return FALSE;
+ break;
+ case (FSYS_SORT_CREATED | FSYS_SORT_DESCENDING):
+ if ( (pOldStat->aDateCreated <= rNewStat.aDateCreated) &&
+ (pOldStat->aTimeCreated < rNewStat.aTimeCreated) )
+ return TRUE;
+ if ( !((pOldStat->aDateCreated == rNewStat.aDateCreated) &&
+ (pOldStat->aTimeCreated == rNewStat.aTimeCreated)) )
+ return FALSE;
+ break;
+
+ case FSYS_SORT_ACCESSED:
+ case (FSYS_SORT_ACCESSED | FSYS_SORT_ASCENDING):
+ if ( (pOldStat->aDateAccessed >= rNewStat.aDateAccessed) &&
+ (pOldStat->aTimeAccessed > rNewStat.aTimeAccessed) )
+ return TRUE;
+ if ( !((pOldStat->aDateAccessed == rNewStat.aDateAccessed) &&
+ (pOldStat->aTimeAccessed == rNewStat.aTimeAccessed)) )
+ return FALSE;
+ break;
+ case (FSYS_SORT_ACCESSED | FSYS_SORT_DESCENDING):
+ if ( (pOldStat->aDateAccessed <= rNewStat.aDateAccessed) &&
+ (pOldStat->aTimeAccessed < rNewStat.aTimeAccessed) )
+ return TRUE;
+ if ( !((pOldStat->aDateAccessed == rNewStat.aDateAccessed) &&
+ (pOldStat->aTimeAccessed == rNewStat.aTimeAccessed)) )
+ return FALSE;
+ break;
+ default: /* Kann nicht sein */;
+ }
+
+ if ( nSortIndex == ( pSortLst->Count() - 1 ) )
+ return TRUE;
+ else
+ //Rekursion
+ return ImpInsertPointReached( rNewEntry, rNewStat,
+ nCurPos, nSortIndex + 1 );
+#undef VALUE
+}
+
+/*************************************************************************
+|*
+|* Dir::ImpSortedInsert()
+|*
+|* Beschreibung fuegt sortiert ein
+|* Ersterstellung MA 05.11.91
+|* Letzte Aenderung MA 03.12.91
+|*
+*************************************************************************/
+
+void Dir::ImpSortedInsert( const DirEntry *pNewEntry, const FileStat *pNewStat )
+{
+ //Sonderfall, keine Sortierung gewuenscht.
+ if ( !pSortLst ) {
+ pLst->Insert( (DirEntry*)pNewEntry, APPEND );
+ return;
+ }
+
+ pLst->First();
+ do {
+ if ( ImpInsertPointReached( *pNewEntry, *pNewStat, pLst->GetCurPos(),
+ (ULONG)0 ) )
+ {
+ if ( pStatLst )
+ pStatLst->Insert( (FileStat*)pNewStat, pLst->GetCurPos() );
+ pLst->Insert( (DirEntry*)pNewEntry );
+ return;
+ }
+ } while( pLst->Next() );
+
+ if ( pStatLst )
+ pStatLst->Insert( (FileStat*)pNewStat, APPEND );
+ pLst->Insert( (DirEntry*)pNewEntry, APPEND );
+}
+
+/*************************************************************************
+|*
+|* Dir::Construct()
+|*
+|* Beschreibung gemeinsame Implementation der Ctoren
+|* Ersterstellung MI 02.06.93
+|* Letzte Aenderung MI 02.06.93
+|*
+*************************************************************************/
+
+void Dir::Construct( DirEntryKind nKindFlags )
+{
+ pLst = NULL;
+ pSortLst = NULL;
+ pStatLst = NULL;
+ eAttrMask = nKindFlags;
+ ByteString aTempName( GetName(), osl_getThreadTextEncoding() );
+ if ( aTempName.Search( "*" ) != STRING_NOTFOUND ||
+ aTempName.Search( "?" ) != STRING_NOTFOUND )
+#if defined( WNT ) && !defined( WTC )
+ {
+ ByteString aTStr(CutName(), osl_getThreadTextEncoding());
+ char* pBuffer = new char[aTStr.Len()+1];
+ strcpy( pBuffer, aTStr.GetBuffer() );
+ CharLowerBuff( pBuffer, aTStr.Len() );
+ aNameMask = WildCard( String(pBuffer, osl_getThreadTextEncoding()), ';' );
+ delete [] pBuffer;
+ }
+#else
+ aNameMask = WildCard( CutName(), ';' );
+#endif
+ else
+ aNameMask = String("*", osl_getThreadTextEncoding());
+}
+
+/*************************************************************************
+|*
+|* Dir::Update()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 16.05.91
+|* Letzte Aenderung MI 19.09.96
+|*
+*************************************************************************/
+
+BOOL Dir::Update()
+{
+ Reset();
+ return Scan( USHRT_MAX ) > 0;
+}
+
+/*************************************************************************
+|*
+|* Dir::Reset()
+|*
+|* Beschreibung
+|* Ersterstellung MI 22.10.96
+|* Letzte Aenderung MI 22.10.96
+|*
+*************************************************************************/
+
+void Dir::Reset()
+{
+ // ggf. alten Reader l"oschen
+ if ( pReader && pReader->bInUse )
+ DELETEZ(pReader);
+
+ // alle DirEntries aus der Liste entfernen und deren Speicher freigeben
+ if ( pLst )
+ {
+ DirEntry* pEntry = pLst->First();
+ while (pEntry)
+ {
+ DirEntry* pNext = pLst->Next();
+ delete pEntry;
+ pEntry = pNext;
+ }
+ pLst->Clear();
+ }
+ else
+ pLst = new DirEntryList();
+
+ // Alte File-Stat's Loeschen
+ if ( pStatLst )
+ {
+ //Erstmal die alten Loeschen
+ FileStat* pEntry = pStatLst->First();
+ while (pEntry)
+ {
+ FileStat* pNext = pStatLst->Next();
+ delete pEntry;
+ pEntry = pNext;
+ }
+ pStatLst->Clear();
+ delete pStatLst;
+ }
+
+ // Verlangen die Sortierkriterien FileStat's?
+ if ( pSortLst )
+ {
+ pSortLst->First();
+ do
+ {
+ if ( *( pSortLst->GetCurObject() ) &
+ ( FSYS_SORT_KIND | FSYS_SORT_SIZE |
+ FSYS_SORT_CREATED | FSYS_SORT_MODIFYED | FSYS_SORT_ACCESSED ) )
+ pStatLst = new FileStatList();
+ } while ( !pStatLst && pSortLst->Next() );
+ }
+
+#ifndef BOOTSTRAP
+ // ggf. einen neuen Reader aufsetzen
+ if ( !pReader )
+ pReader = new DirReader_Impl( *this );
+#endif
+
+ // gibt es das zu oeffnende Verzeichnis ueberhaupt?
+#if !defined(UNX) && !defined(OS2) //explanation: see DirReader_Impl::Read() in unx.cxx
+ if( !pReader->pDosDir )
+ {
+ nError = FSYS_ERR_NOTADIRECTORY;
+ DELETEZ( pReader );
+ return;
+ }
+#endif
+}
+
+/*************************************************************************
+|*
+|* Dir::Scan()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 18.09.96
+|* Letzte Aenderung MI 19.09.96
+|*
+*************************************************************************/
+
+USHORT Dir::Scan( USHORT nCount )
+{
+
+ USHORT nRead = 0; // Anzahl in dieser Runde gelesener Eintr"age
+ FSysFailOnErrorImpl();
+
+ // noch nicht fertig gewesen
+ if ( pReader )
+ {
+ // frischer Reader?
+ if ( !pLst->Count() )
+ {
+ // dann ggf. Laufwerke scannen
+ pReader->bInUse = TRUE;
+ nRead = pReader->Init();
+ }
+
+ // weiterlesen...
+ while ( nRead <= nCount && !pReader->bReady )
+ nRead = nRead + pReader->Read();
+
+ // fertig?
+ if ( pReader && pReader->bReady )
+ DELETEZ( pReader );
+ }
+
+ // Anzahl der gelesenen zur"uckgeben
+ return nRead;
+}
+
+/*************************************************************************
+|*
+|* Dir::Dir()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 16.05.91
+|* Letzte Aenderung MI 04.03.92
+|*
+*************************************************************************/
+
+Dir::Dir( const DirEntry& rDirEntry, DirEntryKind nKindFlags, FSysSort nSort, ... ):
+ DirEntry( rDirEntry ),
+ pReader( 0 )
+{
+ DBG_CTOR( Dir, NULL );
+
+ Construct( nKindFlags );
+
+ std::va_list pArgs;
+ va_start( pArgs, nSort );
+ ImpSetSort( pArgs, nSort );
+
+ Reset();
+}
+
+/*************************************************************************
+|*
+|* Dir::Dir()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 02.06.93
+|* Letzte Aenderung MI 02.06.93
+|*
+*************************************************************************/
+
+Dir::Dir( const DirEntry& rDirEntry, DirEntryKind nKindFlags ):
+ DirEntry( rDirEntry ),
+ pReader( 0 )
+{
+ DBG_CTOR( Dir, NULL );
+
+ Construct( nKindFlags );
+ Reset();
+}
+
+/*************************************************************************
+|*
+|* Dir::Dir()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 16.05.91
+|* Letzte Aenderung MA 04.11.91
+|*
+*************************************************************************/
+
+Dir::Dir():
+ pReader( 0 )
+{
+ DBG_CTOR( Dir, NULL );
+
+ pLst = NULL;
+ pSortLst = NULL;
+ pStatLst = NULL;
+ eAttrMask = FSYS_KIND_ALL;
+ aNameMask = String("*", osl_getThreadTextEncoding());
+}
+
+/*************************************************************************
+|*
+|* Dir::~Dir()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 16.05.91
+|* Letzte Aenderung MA 04.11.91
+|*
+*************************************************************************/
+
+Dir::~Dir()
+{
+ DBG_DTOR( Dir, NULL );
+
+ // alle DirEntries aus der Liste entfernen und deren Speicher freigeben
+ if ( pLst )
+ {
+ DirEntry* pEntry = pLst->First();
+ while (pEntry)
+ {
+ DirEntry* pNext = pLst->Next();
+ delete pEntry;
+ pEntry = pNext;
+ }
+ pLst->Clear();
+
+ delete pLst;
+ }
+
+ // alle Sorts aus der Liste entfernen und deren Speicher freigeben
+ if ( pSortLst )
+ {
+ FSysSort* pEntry = pSortLst->First();
+ while (pEntry)
+ {
+ FSysSort* pNext = pSortLst->Next();
+ delete pEntry;
+ pEntry = pNext;
+ }
+ pSortLst->Clear();
+
+ delete pSortLst;
+ }
+
+ // alle FileStat's aus der Liste entfernen und deren Speicher freigeben
+ if ( pStatLst )
+ {
+ FileStat* pEntry = pStatLst->First();
+ while (pEntry)
+ {
+ FileStat* pNext = pStatLst->Next();
+ delete pEntry;
+ pEntry = pNext;
+ }
+ pStatLst->Clear();
+ delete pStatLst;
+ }
+
+ // ggf. laufenden Reader freigeben
+ delete pReader;
+}
+
+/*************************************************************************
+|*
+|* Dir::ImpSetSort()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MA 04.11.91
+|* Letzte Aenderung MI 05.02.92
+|*
+*************************************************************************/
+
+FSysError Dir::ImpSetSort( std::va_list pArgs, int nFirstSort )
+{
+ BOOL bLast;
+ FSysSort *pSort;
+ FSysSortList *pNewSortLst = new FSysSortList;
+
+ *( pSort = new FSysSort ) = nFirstSort;
+ do
+ {
+ // letztes Kriterium?
+ bLast = FSYS_SORT_END == (*pSort & FSYS_SORT_END);
+ *pSort &= ~FSYS_SORT_END;
+
+ FSysSort nSort = *pSort & ~(USHORT)FSYS_SORT_ASCENDING
+ & ~(USHORT)FSYS_SORT_DESCENDING;
+
+ // g"utliges Sortierkriterium?
+ if ( ( nSort == FSYS_SORT_NAME ) ||
+ ( nSort == FSYS_SORT_SIZE ) ||
+ ( nSort == FSYS_SORT_EXT ) ||
+ ( nSort == FSYS_SORT_CREATED ) ||
+ ( nSort == FSYS_SORT_MODIFYED ) ||
+ ( nSort == FSYS_SORT_ACCESSED ) ||
+ ( nSort == FSYS_SORT_KIND ) )
+ {
+ pNewSortLst->Insert( pSort, APPEND );
+ *(pSort = new FSysSort) = va_arg( pArgs, FSysSort );
+ }
+ else
+ { // ungueltiger Sort oder FSYS_SORT_NONE
+ FSysSort* pEntry = pNewSortLst->First();
+ while (pEntry)
+ {
+ FSysSort* pNext = pNewSortLst->Next();
+ delete pEntry;
+ pEntry = pNext;
+ }
+ pNewSortLst->Clear();
+ delete pNewSortLst;
+ if ( *pSort == FSYS_SORT_NONE )
+ {
+ delete pSort;
+ if ( pSortLst )
+ delete pSortLst;
+ return FSYS_ERR_OK;
+ }
+ else
+ {
+ delete pSort;
+ return FSYS_ERR_NOTSUPPORTED;
+ }
+ }
+ } while ( !bLast );
+
+ va_end( pArgs );
+ delete pSort; // JP:6.3.00 - delete the initial pointer
+
+ //Enfernen der alten Sort-Elemente
+ if ( pSortLst )
+ {
+ FSysSort* pEntry = pSortLst->First();
+ while (pEntry)
+ {
+ FSysSort* pNext = pSortLst->Next();
+ delete pEntry;
+ pEntry = pNext;
+ }
+ pSortLst->Clear();
+ delete pSortLst;
+ }
+ pSortLst = pNewSortLst;
+
+ //Jetzt noch neu Sortieren...
+
+ //Wenn keine FileStats da sind, aber nun welche gebraucht werden,
+ //ist der Aufruf von Update() die einfachste Moeglichkeit
+ if ( !pStatLst && pSortLst )
+ {
+ pSortLst->First();
+ do
+ {
+ if ( *(pSortLst->GetCurObject()) &
+ ( FSYS_SORT_CREATED | FSYS_SORT_MODIFYED | FSYS_SORT_SIZE |
+ FSYS_SORT_ACCESSED | FSYS_SORT_KIND ) )
+ {
+ Update();
+ return FSYS_ERR_OK;
+ }
+ } while ( !pStatLst && pSortLst->Next() );
+ }
+
+ if ( pLst ) { //Keine DirEntry's, kein Sort.
+ DirEntryList *pOldLst = pLst; //alte Liste merken
+ pLst = new DirEntryList(); //neue Liste (zu Sortieren)
+
+ FileStatList *pOldStatLst = NULL; //alte StatListe merken
+ if ( pStatLst ) {
+ pOldStatLst = pStatLst;
+ pStatLst = new FileStatList(); //neue StatListe (zu Sortieren)
+ }
+ pOldLst->First();
+ do
+ {
+ //Sortiertes Einfuegen der Elemente aus den gemerkten Listen
+ //in die 'richtigen' Listen
+ if ( pOldStatLst )
+ ImpSortedInsert( pOldLst->GetCurObject(),
+ pOldStatLst->GetObject( pOldLst->GetCurPos() ) );
+ else
+ ImpSortedInsert( pOldLst->GetCurObject(), NULL );
+ } while( pOldLst->Next() );
+
+ delete pOldLst;
+ if ( pOldStatLst )
+ delete pOldStatLst;
+ }
+ return FSYS_ERR_OK;
+}
+
+/*************************************************************************
+|*
+|* Dir::SetSort()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MA 04.11.91
+|* Letzte Aenderung MI 05.02.92
+|*
+*************************************************************************/
+
+FSysError Dir::SetSort( FSysSort nSort, ... )
+{
+ std::va_list pArgs;
+ va_start( pArgs, nSort );
+ return ImpSetSort( pArgs, nSort );
+}
+
+/*************************************************************************
+|*
+|* Dir::operator[]()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 16.05.91
+|* Letzte Aenderung MI 16.05.91
+|*
+*************************************************************************/
+
+DirEntry& Dir::operator[] ( USHORT nIndex ) const
+{
+ DBG_ASSERT( nIndex < Count(), "Dir::operator[] : nIndex > Count()" );
+
+ DirEntry *pEntry = pLst->GetObject( nIndex );
+ return *pEntry;
+}
+
+/*************************************************************************
+|*
+|* Dir::operator+= ()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 16.05.91
+|* Letzte Aenderung MI 16.05.91
+|*
+*************************************************************************/
+
+Dir& Dir::operator+=( const Dir& rDir )
+{
+ // ggf. erst den Rest lesen
+ if ( pReader )
+ Scan( USHRT_MAX );
+ DBG_ASSERT( !rDir.pReader, "Dir::+= with incomplete Dir" );
+
+ // ggf. initiale Liste erzeugen
+ if ( !pLst )
+ pLst = new DirEntryList();
+
+ //Verlangen die Sortierkriterien FileStat's?
+ BOOL bStat = FALSE;
+ if ( pSortLst ) {
+ pSortLst->First();
+ do {
+ if ( *(pSortLst->GetCurObject()) &
+ ( FSYS_SORT_CREATED | FSYS_SORT_MODIFYED | FSYS_SORT_SIZE |
+ FSYS_SORT_ACCESSED | FSYS_SORT_KIND ) )
+ bStat = TRUE;
+ } while ( !bStat && pSortLst->Next() );
+ }
+ FileStat * stat = NULL;
+ for ( USHORT nNr = 0; nNr < rDir.Count(); nNr++ )
+ {
+ if ( bStat )
+ {
+ if ( rDir.pStatLst )
+ stat = new FileStat( *rDir.pStatLst->GetObject(nNr) );
+ else
+ stat = new FileStat( rDir[nNr] );
+ }
+ ImpSortedInsert( new DirEntry( rDir[nNr] ), stat );
+ }
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* Dir::Count()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 16.05.91
+|* Letzte Aenderung MI 18.09.96
+|*
+*************************************************************************/
+
+
+USHORT Dir::Count( BOOL bUpdated ) const
+{
+ // ggf. erst den Rest lesen
+ if ( bUpdated && pReader )
+ ((Dir*)this)->Scan( USHRT_MAX );
+
+ return pLst == NULL ? 0 : (USHORT) pLst->Count();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/tempfile.cxx b/tools/source/fsys/tempfile.cxx
new file mode 100644
index 000000000000..36e06b05bf17
--- /dev/null
+++ b/tools/source/fsys/tempfile.cxx
@@ -0,0 +1,303 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <tools/tempfile.hxx>
+#include "comdep.hxx"
+
+#include <rtl/ustring.hxx>
+#include <osl/file.hxx>
+#include <rtl/instance.hxx>
+#include <tools/time.hxx>
+#include <tools/debug.hxx>
+#include <stdio.h>
+
+#ifdef UNX
+#define _MAX_PATH 260
+#endif
+
+using namespace osl;
+
+namespace { struct TempNameBase_Impl : public rtl::Static< ::rtl::OUString, TempNameBase_Impl > {}; }
+
+struct TempFile_Impl
+{
+ String aName;
+ sal_Bool bIsDirectory;
+};
+
+String GetSystemTempDir_Impl()
+{
+ char sBuf[_MAX_PATH];
+ const char *pDir = TempDirImpl(sBuf);
+
+ ::rtl::OString aTmpA( pDir );
+ ::rtl::OUString aTmp = ::rtl::OStringToOUString( aTmpA, osl_getThreadTextEncoding() );
+ rtl::OUString aRet;
+ FileBase::getFileURLFromSystemPath( aTmp, aRet );
+ String aName = aRet;
+ if( aName.GetChar(aName.Len()-1) != '/' )
+ aName += '/';
+ return aName;
+}
+
+#define TMPNAME_SIZE ( 1 + 5 + 5 + 4 + 1 )
+String ConstructTempDir_Impl( const String* pParent )
+{
+ String aName;
+ if ( pParent && pParent->Len() )
+ {
+ // if parent given try to use it
+ rtl::OUString aTmp( *pParent );
+ rtl::OUString aRet;
+
+ // test for valid filename
+ {
+ ::osl::DirectoryItem aItem;
+ sal_Int32 i = aRet.getLength();
+ if ( aRet[i-1] == '/' )
+ i--;
+
+ if ( DirectoryItem::get( ::rtl::OUString( aRet, i ), aItem ) == FileBase::E_None )
+ aName = aRet;
+ }
+ }
+
+ if ( !aName.Len() )
+ {
+ // if no parent or invalid parent : use system directory
+ ::rtl::OUString& rTempNameBase_Impl = TempNameBase_Impl::get();
+ if ( !rTempNameBase_Impl.getLength() )
+ rTempNameBase_Impl = GetSystemTempDir_Impl();
+ aName = rTempNameBase_Impl;
+ }
+
+ // Make sure that directory ends with a separator
+ xub_StrLen i = aName.Len();
+ if( i>0 && aName.GetChar(i-1) != '/' )
+ aName += '/';
+
+ return aName;
+}
+
+void CreateTempName_Impl( String& rName, sal_Bool bKeep, sal_Bool bDir = sal_True )
+{
+ // add a suitable tempname
+ // Prefix can have 5 chars, leaving 3 for numbers. 26 ** 3 == 17576
+ // ER 13.07.00 why not radix 36 [0-9A-Z] ?!?
+ const unsigned nRadix = 26;
+ String aName( rName );
+ aName += String::CreateFromAscii( "sv" );
+
+ rName.Erase();
+ static unsigned long u = Time::GetSystemTicks();
+ for ( unsigned long nOld = u; ++u != nOld; )
+ {
+ u %= (nRadix*nRadix*nRadix);
+ String aTmp( aName );
+ aTmp += String::CreateFromInt32( (sal_Int32) (unsigned) u, nRadix );
+ aTmp += String::CreateFromAscii( ".tmp" );
+
+ if ( bDir )
+ {
+ FileBase::RC err = Directory::create( aTmp );
+ if ( err == FileBase::E_None )
+ {
+ // !bKeep: only for creating a name, not a file or directory
+ if ( bKeep || Directory::remove( aTmp ) == FileBase::E_None )
+ rName = aTmp;
+ break;
+ }
+ else if ( err != FileBase::E_EXIST )
+ {
+ // if f.e. name contains invalid chars stop trying to create dirs
+ break;
+ }
+ }
+ else
+ {
+ DBG_ASSERT( bKeep, "Too expensive, use directory for creating name!" );
+ File aFile( aTmp );
+ FileBase::RC err = aFile.open(osl_File_OpenFlag_Create);
+ if ( err == FileBase::E_None )
+ {
+ rName = aTmp;
+ aFile.close();
+ break;
+ }
+ else if ( err != FileBase::E_EXIST )
+ {
+ // if f.e. name contains invalid chars stop trying to create files
+ break;
+ }
+ }
+ }
+}
+
+String TempFile::CreateTempName( const String* pParent )
+{
+ // get correct directory
+ String aName = ConstructTempDir_Impl( pParent );
+
+ // get TempFile name with default naming scheme
+ CreateTempName_Impl( aName, sal_False );
+
+ // convert to file URL
+ rtl::OUString aTmp;
+ if ( aName.Len() )
+ aTmp = aName;
+ return aTmp;
+}
+
+TempFile::TempFile( const String* pParent, sal_Bool bDirectory )
+ : pImp( new TempFile_Impl )
+ , bKillingFileEnabled( sal_False )
+{
+ pImp->bIsDirectory = bDirectory;
+
+ // get correct directory
+ pImp->aName = ConstructTempDir_Impl( pParent );
+
+ // get TempFile with default naming scheme
+ CreateTempName_Impl( pImp->aName, sal_True, bDirectory );
+}
+
+TempFile::TempFile( const String& rLeadingChars, const String* pExtension, const String* pParent, sal_Bool bDirectory )
+ : pImp( new TempFile_Impl )
+ , bKillingFileEnabled( sal_False )
+{
+ pImp->bIsDirectory = bDirectory;
+
+ // get correct directory
+ String aName = ConstructTempDir_Impl( pParent );
+
+ // now use special naming scheme ( name takes leading chars and an index counting up from zero
+ aName += rLeadingChars;
+ for ( sal_Int32 i=0;; i++ )
+ {
+ String aTmp( aName );
+ aTmp += String::CreateFromInt32( i );
+ if ( pExtension )
+ aTmp += *pExtension;
+ else
+ aTmp += String::CreateFromAscii( ".tmp" );
+ if ( bDirectory )
+ {
+ FileBase::RC err = Directory::create( aTmp );
+ if ( err == FileBase::E_None )
+ {
+ pImp->aName = aTmp;
+ break;
+ }
+ else if ( err != FileBase::E_EXIST )
+ // if f.e. name contains invalid chars stop trying to create dirs
+ break;
+ }
+ else
+ {
+ File aFile( aTmp );
+ FileBase::RC err = aFile.open(osl_File_OpenFlag_Create);
+ if ( err == FileBase::E_None )
+ {
+ pImp->aName = aTmp;
+ aFile.close();
+ break;
+ }
+ else if ( err != FileBase::E_EXIST )
+ // if f.e. name contains invalid chars stop trying to create dirs
+ break;
+ }
+ }
+}
+
+TempFile::~TempFile()
+{
+ if ( bKillingFileEnabled )
+ {
+ if ( pImp->bIsDirectory )
+ {
+ // at the moment no recursiv algorithm present
+ Directory::remove( pImp->aName );
+ }
+ else
+ {
+ File::remove( pImp->aName );
+ }
+ }
+
+ delete pImp;
+}
+
+sal_Bool TempFile::IsValid() const
+{
+ return pImp->aName.Len() != 0;
+}
+
+String TempFile::GetName() const
+{
+ rtl::OUString aTmp;
+ aTmp = pImp->aName;
+ return aTmp;
+}
+
+String TempFile::SetTempNameBaseDirectory( const String &rBaseName )
+{
+ String aName( rBaseName );
+
+ ::rtl::OUString& rTempNameBase_Impl = TempNameBase_Impl::get();
+
+ FileBase::RC err= Directory::create( aName );
+ if ( err == FileBase::E_None || err == FileBase::E_EXIST )
+ {
+ rTempNameBase_Impl = aName;
+ rTempNameBase_Impl += String( '/' );
+
+ TempFile aBase( NULL, sal_True );
+ if ( aBase.IsValid() )
+ rTempNameBase_Impl = aBase.pImp->aName;
+ }
+
+ rtl::OUString aTmp;
+ aTmp = rTempNameBase_Impl;
+ return aTmp;
+}
+
+String TempFile::GetTempNameBaseDirectory()
+{
+ ::rtl::OUString& rTempNameBase_Impl = TempNameBase_Impl::get();
+ if ( !rTempNameBase_Impl.getLength() )
+ rTempNameBase_Impl = GetSystemTempDir_Impl();
+
+ rtl::OUString aTmp;
+ aTmp = rTempNameBase_Impl;
+ return aTmp;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/unx.cxx b/tools/source/fsys/unx.cxx
new file mode 100644
index 000000000000..b1abae49d8b0
--- /dev/null
+++ b/tools/source/fsys/unx.cxx
@@ -0,0 +1,663 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <utime.h>
+#if defined HPUX || defined LINUX
+#include <mntent.h>
+#define mnttab mntent
+#elif defined SCO
+#include <mnttab.h>
+#elif defined AIX
+#include <sys/mntctl.h>
+#include <sys/vmount.h>
+extern "C" int mntctl( int cmd, size_t size, char* buf );
+#elif defined(NETBSD)
+#include <sys/mount.h>
+#elif defined(FREEBSD) || defined(MACOSX) || defined(OPENBSD)
+#elif defined DECUNIX
+struct mnttab
+{
+ char *mnt_dir;
+ char *mnt_fsname;
+};
+#else
+#include <sys/mnttab.h>
+#endif
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+
+#include <tools/debug.hxx>
+#include <tools/list.hxx>
+#include <tools/fsys.hxx>
+#include "comdep.hxx"
+#include <rtl/instance.hxx>
+
+DECLARE_LIST( DirEntryList, DirEntry* )
+DECLARE_LIST( FSysSortList, FSysSort* )
+DECLARE_LIST( FileStatList, FileStat* )
+
+#if defined SOLARIS || defined SINIX
+#define MOUNTSPECIAL mnt_special
+#define MOUNTPOINT mnt_mountp
+#define MOUNTOPTS mnt_mntopts
+#define MOUNTFS mnt_fstype
+#elif defined SCO
+#define MNTTAB "/etc/mnttab"
+#define MOUNTSPECIAL mt_dev
+#define MOUNTPOINT mt_filsys
+#else
+#define MOUNTSPECIAL mnt_fsname
+#define MOUNTPOINT mnt_dir
+#define MOUNTFS mnt_type
+#endif
+
+struct mymnttab
+{
+ dev_t mountdevice;
+ ByteString mountspecial;
+ ByteString mountpoint;
+ ByteString mymnttab_filesystem;
+ mymnttab() { mountdevice = (dev_t) -1; }
+};
+
+
+#if defined(NETBSD) || defined(FREEBSD) || defined(MACOSX) || \
+ defined(OPENBSD)
+BOOL GetMountEntry(dev_t /* dev */, struct mymnttab * /* mytab */ )
+{
+ DBG_WARNING( "Sorry, not implemented: GetMountEntry" );
+ return FALSE;
+}
+
+#elif defined AIX
+BOOL GetMountEntry(dev_t dev, struct mymnttab *mytab)
+{
+ int bufsize;
+ if (mntctl (MCTL_QUERY, sizeof bufsize, (char*) &bufsize))
+ return FALSE;
+
+ char* buffer = (char *)malloc( bufsize * sizeof(char) );
+ if (mntctl (MCTL_QUERY, bufsize, buffer) != -1)
+ for ( char* vmt = buffer;
+ vmt < buffer + bufsize;
+ vmt += ((struct vmount*)vmt)->vmt_length)
+ {
+ struct stat buf;
+ char *mountp = vmt2dataptr((struct vmount*)vmt, VMT_STUB);
+ if ((stat (mountp, &buf) != -1) && (buf.st_dev == dev))
+ {
+ mytab->mountpoint = mountp;
+ mytab->mountspecial
+ = vmt2dataptr((struct vmount*)vmt, VMT_HOSTNAME);
+ if (mytab->mountspecial.Len())
+ mytab->mountspecial += ':';
+ mytab->mountspecial
+ += vmt2dataptr((struct vmount*)vmt, VMT_OBJECT);
+ mytab->mountdevice = dev;
+ free( buffer );
+ return TRUE;
+ }
+ }
+ free( buffer );
+ return FALSE;
+}
+
+#else
+
+
+static BOOL GetMountEntry(dev_t dev, struct mymnttab *mytab)
+{
+#if defined SOLARIS || defined SINIX
+ FILE *fp = fopen (MNTTAB, "r");
+ if (! fp)
+ return FALSE;
+ struct mnttab mnt[1];
+ while (getmntent (fp, mnt) != -1)
+#elif defined SCO
+ FILE *fp = fopen (MNTTAB, "r");
+ if (! fp)
+ return FALSE;
+ struct mnttab mnt[1];
+ while (fread (&mnt, sizeof mnt, 1, fp) > 0)
+#elif defined DECUNIX || defined AIX
+ FILE *fp = NULL;
+ if (! fp)
+ return FALSE;
+ struct mnttab mnt[1];
+ while ( 0 )
+#else
+ FILE *fp = setmntent (MOUNTED, "r");
+ if (! fp)
+ return FALSE;
+ struct mnttab *mnt;
+ while ((mnt = getmntent (fp)) != NULL)
+#endif
+ {
+#ifdef SOLARIS
+ char *devopt = NULL;
+ if ( mnt->MOUNTOPTS != NULL )
+ devopt = strstr (mnt->MOUNTOPTS, "dev=");
+ if (devopt)
+ {
+ if (dev != (dev_t) strtoul (devopt+4, NULL, 16))
+ continue;
+ }
+ else
+#endif
+ {
+ struct stat buf;
+ if ((stat (mnt->MOUNTPOINT, &buf) == -1) || (buf.st_dev != dev))
+ continue;
+ }
+# ifdef LINUX
+ /* #61624# File mit setmntent oeffnen und mit fclose schliessen stoesst
+ bei der glibc-2.1 auf wenig Gegenliebe */
+ endmntent( fp );
+# else
+ fclose (fp);
+# endif
+ mytab->mountspecial = mnt->MOUNTSPECIAL;
+ mytab->mountpoint = mnt->MOUNTPOINT;
+ mytab->mountdevice = dev;
+#ifndef SCO
+ mytab->mymnttab_filesystem = mnt->MOUNTFS;
+#else
+ mytab->mymnttab_filesystem = "ext2"; //default ist case sensitiv unter unix
+#endif
+ return TRUE;
+ }
+# ifdef LINUX
+ /* #61624# dito */
+ endmntent( fp );
+# else
+ fclose (fp);
+# endif
+ return FALSE;
+}
+
+#endif
+
+/************************************************************************
+|*
+|* DirEntry::IsCaseSensitive()
+|*
+|* Beschreibung
+|* Ersterstellung TPF 25.02.1999
+|* Letzte Aenderung TPF 25.02.1999
+|*
+*************************************************************************/
+
+BOOL DirEntry::IsCaseSensitive( FSysPathStyle eFormatter ) const
+{
+
+ if (eFormatter==FSYS_STYLE_HOST)
+ {
+#ifdef NETBSD
+ return TRUE;
+#else
+ struct stat buf;
+ DirEntry aPath(*this);
+ aPath.ToAbs();
+
+ while (stat (ByteString(aPath.GetFull(), osl_getThreadTextEncoding()).GetBuffer(), &buf))
+ {
+ if (aPath.Level() == 1)
+ {
+ return TRUE; // ich bin unter UNIX, also ist der default im Zweifelsfall case sensitiv
+ }
+ aPath = aPath [1];
+ }
+
+ struct mymnttab fsmnt;
+ GetMountEntry(buf.st_dev, &fsmnt);
+ if ((fsmnt.mymnttab_filesystem.CompareTo("msdos")==COMPARE_EQUAL) ||
+ (fsmnt.mymnttab_filesystem.CompareTo("umsdos")==COMPARE_EQUAL) ||
+ (fsmnt.mymnttab_filesystem.CompareTo("vfat")==COMPARE_EQUAL) ||
+ (fsmnt.mymnttab_filesystem.CompareTo("hpfs")==COMPARE_EQUAL) ||
+ (fsmnt.mymnttab_filesystem.CompareTo("smb") ==COMPARE_EQUAL) ||
+ (fsmnt.mymnttab_filesystem.CompareTo("ncpfs")==COMPARE_EQUAL))
+ {
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+#endif
+ }
+ else
+ {
+ BOOL isCaseSensitive = TRUE; // ich bin unter UNIX, also ist der default im Zweifelsfall case sensitiv
+ switch ( eFormatter )
+ {
+ case FSYS_STYLE_MAC:
+ case FSYS_STYLE_FAT:
+ case FSYS_STYLE_VFAT:
+ case FSYS_STYLE_NTFS:
+ case FSYS_STYLE_NWFS:
+ case FSYS_STYLE_HPFS:
+ {
+ isCaseSensitive = FALSE;
+ break;
+ }
+ case FSYS_STYLE_SYSV:
+ case FSYS_STYLE_BSD:
+ case FSYS_STYLE_DETECT:
+ {
+ isCaseSensitive = TRUE;
+ break;
+ }
+ default:
+ {
+ isCaseSensitive = TRUE; // ich bin unter UNIX, also ist der default im Zweifelsfall case sensitiv
+ break;
+ }
+ }
+ return isCaseSensitive;
+ }
+}
+
+/************************************************************************
+|*
+|* DirEntry::ToAbs()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91 13:30
+|*
+*************************************************************************/
+
+BOOL DirEntry::ToAbs()
+{
+ if ( FSYS_FLAG_VOLUME == eFlag )
+ {
+ eFlag = FSYS_FLAG_ABSROOT;
+ return TRUE;
+ }
+
+ if ( IsAbs() )
+ return TRUE;
+
+ char sBuf[MAXPATHLEN + 1];
+ *this = DirEntry( String( getcwd( sBuf, MAXPATHLEN ), osl_getThreadTextEncoding() ) ) + *this;
+ return IsAbs();
+}
+
+/*************************************************************************
+|*
+|* DirEntry::GetVolume()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 04.03.92
+|* Letzte Aenderung
+|*
+*************************************************************************/
+
+namespace { struct mymnt : public rtl::Static< mymnttab, mymnt > {}; }
+
+String DirEntry::GetVolume() const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ DirEntry aPath( *this );
+ aPath.ToAbs();
+
+ struct stat buf;
+ while (stat (ByteString(aPath.GetFull(), osl_getThreadTextEncoding()).GetBuffer(), &buf))
+ {
+ if (aPath.Level() <= 1)
+ return String();
+ aPath = aPath [1];
+ }
+ mymnttab &rMnt = mymnt::get();
+ return ((buf.st_dev == rMnt.mountdevice ||
+ GetMountEntry(buf.st_dev, &rMnt)) ?
+ String(rMnt.mountspecial, osl_getThreadTextEncoding()) :
+ String());
+}
+
+DirEntry DirEntry::GetDevice() const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ DirEntry aPath( *this );
+ aPath.ToAbs();
+
+ struct stat buf;
+ while (stat (ByteString(aPath.GetFull(), osl_getThreadTextEncoding()).GetBuffer(), &buf))
+ {
+ if (aPath.Level() <= 1)
+ return String();
+ aPath = aPath [1];
+ }
+ mymnttab &rMnt = mymnt::get();
+ return ((buf.st_dev == rMnt.mountdevice ||
+ GetMountEntry(buf.st_dev, &rMnt)) ?
+ String( rMnt.mountpoint, osl_getThreadTextEncoding()) :
+ String());
+}
+
+/*************************************************************************
+|*
+|* DirEntry::SetCWD()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung DV 04.11.92
+|*
+*************************************************************************/
+
+BOOL DirEntry::SetCWD( BOOL bSloppy ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+
+ ByteString aPath( GetFull(), osl_getThreadTextEncoding());
+ if ( !chdir( aPath.GetBuffer() ) )
+ {
+ return TRUE;
+ }
+ else
+ {
+ if ( bSloppy && !chdir(aPath.GetBuffer()) )
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+
+USHORT DirReader_Impl::Init()
+{
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+USHORT DirReader_Impl::Read()
+{
+ if (!pDosDir)
+ {
+ pDosDir = opendir( (char*) ByteString(aPath, osl_getThreadTextEncoding()).GetBuffer() );
+ }
+
+ if (!pDosDir)
+ {
+ bReady = TRUE;
+ return 0;
+ }
+
+ // Directories und Files auflisten?
+ if ( ( pDir->eAttrMask & FSYS_KIND_DIR || pDir->eAttrMask & FSYS_KIND_FILE ) &&
+ ( ( pDosEntry = readdir( pDosDir ) ) != NULL ) )
+ {
+ String aD_Name(pDosEntry->d_name, osl_getThreadTextEncoding());
+ if ( pDir->aNameMask.Matches( aD_Name ) )
+ {
+ DirEntryFlag eFlag =
+ 0 == strcmp( pDosEntry->d_name, "." ) ? FSYS_FLAG_CURRENT
+ : 0 == strcmp( pDosEntry->d_name, ".." ) ? FSYS_FLAG_PARENT
+ : FSYS_FLAG_NORMAL;
+ DirEntry *pTemp = new DirEntry( ByteString(pDosEntry->d_name), eFlag, FSYS_STYLE_UNX );
+ if ( pParent )
+ pTemp->ImpChangeParent( new DirEntry( *pParent ), FALSE);
+ FileStat aStat( *pTemp );
+ if ( ( ( ( pDir->eAttrMask & FSYS_KIND_DIR ) &&
+ ( aStat.IsKind( FSYS_KIND_DIR ) ) ) ||
+ ( ( pDir->eAttrMask & FSYS_KIND_FILE ) &&
+ !( aStat.IsKind( FSYS_KIND_DIR ) ) ) ) &&
+ !( pDir->eAttrMask & FSYS_KIND_VISIBLE &&
+ pDosEntry->d_name[0] == '.' ) )
+ {
+ if ( pDir->pStatLst ) //Status fuer Sort gewuenscht?
+ pDir->ImpSortedInsert( pTemp, new FileStat( aStat ) );
+ else
+ pDir->ImpSortedInsert( pTemp, NULL );;
+ return 1;
+ }
+ else
+ delete pTemp;
+ }
+ }
+ else
+ bReady = TRUE;
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* FileStat::FileStat()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MA 05.11.91
+|* Letzte Aenderung MA 07.11.91
+|*
+*************************************************************************/
+
+FileStat::FileStat( const void *, const void * ):
+ aDateCreated(0),
+ aTimeCreated(0),
+ aDateModified(0),
+ aTimeModified(0),
+ aDateAccessed(0),
+ aTimeAccessed(0)
+{
+}
+
+/*************************************************************************
+|*
+|* FileStat::Update()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 11.06.91
+|* Letzte Aenderung MA 07.11.91
+|*
+*************************************************************************/
+BOOL FileStat::Update( const DirEntry& rDirEntry, BOOL )
+{
+
+ nSize = 0;
+ nKindFlags = 0;
+ aCreator.Erase();
+ aType.Erase();
+ aDateCreated = Date(0);
+ aTimeCreated = Time(0);
+ aDateModified = Date(0);
+ aTimeModified = Time(0);
+ aDateAccessed = Date(0);
+ aTimeAccessed = Time(0);
+
+ if ( !rDirEntry.IsValid() )
+ {
+ nError = FSYS_ERR_NOTEXISTS;
+ return FALSE;
+ }
+
+ // Sonderbehandlung falls es sich um eine Root handelt
+ if ( rDirEntry.eFlag == FSYS_FLAG_ABSROOT )
+ {
+ nKindFlags = FSYS_KIND_DIR;
+ nError = FSYS_ERR_OK;
+ return TRUE;
+ }
+
+ struct stat aStat;
+ ByteString aPath( rDirEntry.GetFull(), osl_getThreadTextEncoding() );
+ if ( stat( (char*) aPath.GetBuffer(), &aStat ) )
+ {
+ // pl: #67851#
+ // do this here, because an existing filename containing "wildcards"
+ // should be handled as a file, not a wildcard
+ // note that this is not a solution, since filenames containing special characters
+ // are handled badly across the whole Office
+
+ // Sonderbehandlung falls es sich um eine Wildcard handelt
+ ByteString aTempName( rDirEntry.GetName(), osl_getThreadTextEncoding() );
+ if ( strchr( (char*) aTempName.GetBuffer(), '?' ) ||
+ strchr( (char*) aTempName.GetBuffer(), '*' ) ||
+ strchr( (char*) aTempName.GetBuffer(), ';' ) )
+ {
+ nKindFlags = FSYS_KIND_WILD;
+ nError = FSYS_ERR_OK;
+ return TRUE;
+ }
+
+ nError = FSYS_ERR_NOTEXISTS;
+ return FALSE;
+ }
+
+ nError = FSYS_ERR_OK;
+ nSize = aStat.st_size;
+
+ nKindFlags = FSYS_KIND_UNKNOWN;
+ if ( ( aStat.st_mode & S_IFDIR ) == S_IFDIR )
+ nKindFlags = nKindFlags | FSYS_KIND_DIR;
+ if ( ( aStat.st_mode & S_IFREG ) == S_IFREG )
+ nKindFlags = nKindFlags | FSYS_KIND_FILE;
+ if ( ( aStat.st_mode & S_IFCHR ) == S_IFCHR )
+ nKindFlags = nKindFlags | FSYS_KIND_DEV | FSYS_KIND_CHAR;
+ if ( ( aStat.st_mode & S_IFBLK ) == S_IFBLK )
+ nKindFlags = nKindFlags | FSYS_KIND_DEV | FSYS_KIND_BLOCK;
+ if ( nKindFlags == FSYS_KIND_UNKNOWN )
+ nKindFlags = nKindFlags | FSYS_KIND_FILE;
+
+ Unx2DateAndTime( aStat.st_ctime, aTimeCreated, aDateCreated );
+ Unx2DateAndTime( aStat.st_mtime, aTimeModified, aDateModified );
+ Unx2DateAndTime( aStat.st_atime, aTimeAccessed, aDateAccessed );
+
+ return TRUE;
+}
+
+//====================================================================
+
+const char *TempDirImpl( char *pBuf )
+{
+#ifdef MACOSX
+ // P_tmpdir is /var/tmp on Mac OS X, and it is not cleaned up on system
+ // startup
+ strcpy( pBuf, "/tmp" );
+#else
+ const char *pValue = getenv( "TEMP" );
+ if ( !pValue )
+ pValue = getenv( "TMP" );
+ if ( pValue )
+ strcpy( pBuf, pValue );
+ else
+ // auf Solaris und Linux ist P_tmpdir vorgesehen
+ strcpy( pBuf, P_tmpdir );
+ // hart auf "/tmp" sollte wohl nur im Notfall verwendet werden
+ //strcpy( pBuf, "/tmp" );
+#endif /* MACOSX */
+
+ return pBuf;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::GetPathStyle() const
+|*
+|* Beschreibung
+|* Ersterstellung MI 11.05.95
+|* Letzte Aenderung MI 11.05.95
+|*
+*************************************************************************/
+
+FSysPathStyle DirEntry::GetPathStyle( const String & )
+{
+ return FSYS_STYLE_UNX;
+}
+
+/*************************************************************************
+|*
+|* FileStat::SetDateTime
+|*
+|* Ersterstellung PB 27.06.97
+|* Letzte Aenderung
+|*
+*************************************************************************/
+
+void FileStat::SetDateTime( const String& rFileName,
+ const DateTime& rNewDateTime )
+{
+ tm times;
+
+ times.tm_year = rNewDateTime.GetYear() - 1900; // 1997 -> 97
+ times.tm_mon = rNewDateTime.GetMonth() - 1; // 0 == Januar!
+ times.tm_mday = rNewDateTime.GetDay();
+
+ times.tm_hour = rNewDateTime.GetHour();
+ times.tm_min = rNewDateTime.GetMin();
+ times.tm_sec = rNewDateTime.GetSec();
+
+ times.tm_wday = 0;
+ times.tm_yday = 0;
+#ifdef SOLARIS
+ times.tm_isdst = -1;
+#else
+ times.tm_isdst = 0;
+#endif
+
+ time_t time = mktime (&times);
+
+ if (time != (time_t) -1)
+ {
+ struct utimbuf u_time;
+ u_time.actime = time;
+ u_time.modtime = time;
+ utime (ByteString(rFileName, osl_getThreadTextEncoding()).GetBuffer(), &u_time);
+ }
+}
+
+//=========================================================================
+
+ErrCode FileStat::QueryDiskSpace( const String &, BigInt &, BigInt & )
+{
+ return ERRCODE_IO_NOTSUPPORTED;
+}
+
+//=========================================================================
+
+void FSysEnableSysErrorBox( BOOL )
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/unx.hxx b/tools/source/fsys/unx.hxx
new file mode 100644
index 000000000000..0436c9284006
--- /dev/null
+++ b/tools/source/fsys/unx.hxx
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _unx_hxx
+#define _unx_hxx
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <dirent.h>
+#include <unistd.h>
+/* #include <sysent.h> */
+
+#define FSYS_UNIX TRUE
+#define DRIVE_EXISTS(c) ( TRUE )
+
+#define _mkdir(p) mkdir(p, 0777)
+#define _rmdir rmdir
+#define _chdir chdir
+#define _unlink unlink
+#define _getcwd getcwd
+#define _access access
+
+#ifdef SYSV3
+#define DEFSTYLE FSYS_STYLE_SYSV
+#else
+#define DEFSTYLE FSYS_STYLE_BSD
+#endif
+
+#define CMP_LOWER(s) (s)
+#define TEMPNAME() tmpnam(0)
+#define LOWER(aString) (aString.Lower())
+
+#include <time.h>
+#include <tools/datetime.hxx>
+
+inline Time Unx2Time( time_t nTime )
+{
+ tm atm;
+ tm *pTime;
+ pTime = localtime_r( &nTime, &atm );
+ return Time( pTime->tm_hour,
+ pTime->tm_min,
+ pTime->tm_sec );
+}
+
+inline Date Unx2Date( time_t nDate )
+{
+ tm atm;
+ tm *pTime;
+ pTime = localtime_r( &nDate, &atm );
+ return Date( pTime->tm_mday,
+ pTime->tm_mon + 1,
+ pTime->tm_year + 1900 );
+}
+
+inline void Unx2DateAndTime( time_t nDate, Time& rTime, Date& rDate )
+{
+ tm atm;
+ tm *pTime;
+ pTime = localtime_r( &nDate, &atm );
+ rTime = Time( pTime->tm_hour, pTime->tm_min, pTime->tm_sec );
+ rDate = Date( pTime->tm_mday, pTime->tm_mon + 1, pTime->tm_year + 1900 );
+}
+
+const char* TempDirImpl( char *pBuf );
+
+#define FSysFailOnErrorImpl()
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/urlobj.cxx b/tools/source/fsys/urlobj.cxx
new file mode 100644
index 000000000000..1f4b67518afe
--- /dev/null
+++ b/tools/source/fsys/urlobj.cxx
@@ -0,0 +1,5575 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <tools/urlobj.hxx>
+#include <tools/debug.hxx>
+#include <tools/inetmime.hxx>
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/util/XStringWidth.hpp"
+#include "osl/diagnose.h"
+#include "osl/file.hxx"
+#include "rtl/string.h"
+#include "rtl/textenc.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+#ifndef INCLUDED_ALGORITHM
+#include <algorithm>
+#define INCLUDED_ALGORITHM
+#endif
+#ifndef INCLUDED_LIMITS
+#include <limits>
+#define INCLUDED_LIMITS
+#endif
+
+#include <string.h>
+
+namespace unnamed_tools_urlobj {} using namespace unnamed_tools_urlobj;
+ // unnamed namespaces don't work well yet...
+
+using namespace com::sun;
+
+//============================================================================
+//
+// INetURLObject
+//
+//============================================================================
+
+/* The URI grammar (using RFC 2234 conventions).
+
+ Constructs of the form
+ {reference <rule1> using rule2}
+ stand for a rule matching the given rule1 specified in the given reference,
+ encoded to URI syntax using rule2 (as specified in this URI grammar).
+
+
+ ; RFC 1738, RFC 2396, RFC 2732, private
+ login = [user [":" password] "@"] hostport
+ user = *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ";" / "=" / "_" / "~")
+ password = *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ";" / "=" / "_" / "~")
+ hostport = host [":" port]
+ host = incomplete-hostname / hostname / IPv4address / IPv6reference
+ incomplete-hostname = *(domainlabel ".") domainlabel
+ hostname = *(domainlabel ".") toplabel ["."]
+ domainlabel = alphanum [*(alphanum / "-") alphanum]
+ toplabel = ALPHA [*(alphanum / "-") alphanum]
+ IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
+ IPv6reference = "[" hexpart [":" IPv4address] "]"
+ hexpart = (hexseq ["::" [hexseq]]) / ("::" [hexseq])
+ hexseq = hex4 *(":" hex4)
+ hex4 = 1*4HEXDIG
+ port = *DIGIT
+ escaped = "%" HEXDIG HEXDIG
+ reserved = "$" / "&" / "+" / "," / "/" / ":" / ";" / "=" / "?" / "@" / "[" / "]"
+ mark = "!" / "'" / "(" / ")" / "*" / "-" / "." / "_" / "~"
+ alphanum = ALPHA / DIGIT
+ unreserved = alphanum / mark
+ uric = escaped / reserved / unreserved
+ pchar = escaped / unreserved / "$" / "&" / "+" / "," / ":" / "=" / "@"
+
+
+ ; RFC 1738, RFC 2396
+ ftp-url = "FTP://" login ["/" segment *("/" segment) [";TYPE=" ("A" / "D" / "I")]]
+ segment = *pchar
+
+
+ ; RFC 1738, RFC 2396
+ http-url = "HTTP://" hostport ["/" segment *("/" segment) ["?" *uric]]
+ segment = *(pchar / ";")
+
+
+ ; RFC 1738, RFC 2396, <http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q188997&>
+ file-url = "FILE://" [host / "LOCALHOST" / netbios-name] ["/" segment *("/" segment)]
+ segment = *pchar
+ netbios-name = 1*{<alphanum / "!" / "#" / "$" / "%" / "&" / "'" / "(" / ")" / "-" / "." / "@" / "^" / "_" / "{" / "}" / "~"> using (escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "-" / "." / "@" / "_" / "~")}
+
+
+ ; RFC 2368, RFC 2396
+ mailto-url = "MAILTO:" [to] [headers]
+ to = {RFC 822 <#mailbox> using *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "@" / "_" / "~")}
+ headers = "?" header *("&" header)
+ header = hname "=" hvalue
+ hname = {RFC 822 <field-name> using *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "@" / "_" / "~")} / "BODY"
+ hvalue = {RFC 822 <field-body> using *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "@" / "_" / "~")}
+
+
+ ; private (see RFC 1738, RFC 2396)
+ vnd-sun-star-webdav-url = "VND.SUN.STAR.WEBDAV://" hostport ["/" segment *("/" segment) ["?" *uric]]
+ segment = *(pchar / ";")
+
+
+ ; RFC 1738, RFC 2396, RFC 2732
+ news-url = "NEWS:" grouppart
+ grouppart = "*" / group / article
+ group = alpha *(alphanum / "+" / "-" / "." / "_")
+ article = 1*(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "=" / "?" / "_" / "~") "@" host
+
+
+ ; private
+ private-url = "PRIVATE:" path ["?" *uric]
+ path = *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")
+
+
+ ; private
+ vnd-sun-star-help-url = "VND.SUN.STAR.HELP://" name *("/" segment) ["?" *uric]
+ name = *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ":" / ";" / "=" / "@" / "_" / "~")
+ segment = *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ":" / ";" / "=" / "@" / "_" / "~")
+
+
+ ; private
+ https-url = "HTTPS://" hostport ["/" segment *("/" segment) ["?" *uric]]
+ segment = *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ":" / ";" / "=" / "@" / "_" / "~")
+
+
+ ; private
+ slot-url = "SLOT:" path ["?" *uric]
+ path = *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")
+
+
+ ; private
+ macro-url = "MACRO:" path ["?" *uric]
+ path = *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")
+
+
+ ; private
+ javascript-url = "JAVASCRIPT:" *uric
+
+
+ ; private (see RFC 2192)
+ imap-url = "IMAP://" user [";AUTH=" auth] "@" hostport "/" segment *("/" segment) ["/;UID=" nz_number]
+ user = 1*{RFC 2060 <CHAR8> using (escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "=" / "_" / "~")}
+ auth = {RFC 2060 <atom> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "+" / "," / "-" / "." / "=" / "_" / "~")}
+ segment = *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ":" / "=" / "@" / "_" / "~")
+ nz_number = {RFC 2060 <nz_number> using *DIGIT}
+
+
+ ; private
+ pop3-url = "POP3://" login ["/" ["<" *uric ">"]]
+
+
+ ; RFC 2397
+ data-url = "DATA:" [mediatype] [";BASE64"] "," *uric
+ mediatype = [type "/" subtype] *(";" attribute "=" value)
+ type = {RFC 2045 <type> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "-" / "." / ":" / "?" / "@" / "_" / "~")}
+ subtype = {RFC 2045 <subtype> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "-" / "." / ":" / "?" / "@" / "_" / "~")}
+ attribute = {RFC 2045 <subtype> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "-" / "." / ":" / "?" / "@" / "_" / "~")}
+ value = {RFC 2045 <subtype> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "-" / "." / ":" / "?" / "@" / "_" / "~")}
+
+
+ ; RFC 2392, RFC 2396
+ cid-url = "CID:" {RFC 822 <addr-spec> using *uric}
+
+
+ ; private
+ out-url = "OUT:///~" name ["/" *uric]
+ name = *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ":" / ";" / "=" / "?" / "@" / "_" / "~"
+
+
+ ; private
+ vnd-sun-star-hier-url = "VND.SUN.STAR.HIER:" ["//"reg_name] *("/" *pchar)
+ reg_name = 1*(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ":" / ";" / "=" / "@" / "_" / "~")
+
+ ; private
+ vim-url = "VIM://" +vimc [":" *vimc] ["/" [("INBOX" message) / ("NEWSGROUPS" ["/" [+vimc message]])]]
+ message = ["/" [+vimc [":" +DIGIT "." +DIGIT "." +DIGIT]]]
+ vimc = ("=" HEXDIG HEXDIG) / alphanum
+
+
+ ; private
+ uno-url = ".UNO:" path ["?" *uric]
+ path = *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")
+
+
+ ; private
+ component-url = ".COMPONENT:" path ["?" *uric]
+ path = *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")
+
+
+ ; private
+ vnd-sun-star-pkg-url = "VND.SUN.STAR.PKG://" reg_name *("/" *pchar) ["?" *uric]
+ reg_name = 1*(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ":" / ";" / "=" / "@" / "_" / "~")
+
+
+ ; RFC 2255
+ ldap-url = "LDAP://" [hostport] ["/" [dn ["?" [attrdesct *("," attrdesc)] ["?" ["base" / "one" / "sub"] ["?" [filter] ["?" extension *("," extension)]]]]]]
+ dn = {RFC 2253 <distinguishedName> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")}
+ attrdesc = {RFC 2251 <AttributeDescription> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")}
+ filter = {RFC 2254 <filter> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")}
+ extension = ["!"] ["X-"] extoken ["=" exvalue]
+ extoken = {RFC 2252 <oid> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "-" / "." / "/" / ":" / ";" / "@" / "_" / "~")}
+ exvalue = {RFC 2251 <LDAPString> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")}
+
+
+ ; private
+ db-url = "DB:" *uric
+
+
+ ; private
+ vnd-sun-star-cmd-url = "VND.SUN.STAR.CMD:" opaque_part
+ opaque_part = uric_no_slash *uric
+ uric_no_slash = unreserved / escaped / ";" / "?" / ":" / "@" / "&" / "=" / "+" / "$" / ","
+
+
+ ; private
+ vnd-sun-star-url = "VND.SUN.STAR.ODMA:" ["/" *uric_no_slash]
+ uric_no_slash = unreserved / escaped / ";" / "?" / ":" / "@" / "&" / "=" / "+" / "$" / ","
+
+
+ ; RFC 1738
+ telnet-url = "TELNET://" login ["/"]
+
+
+ ; private
+ vnd-sun-star-expand-url = "VND.SUN.STAR.EXPAND:" opaque_part
+ opaque_part = uric_no_slash *uric
+ uric_no_slash = unreserved / escaped / ";" / "?" / ":" / "@" / "&" / "=" / "+" / "$" / ","
+
+
+ ; private
+ vnd-sun-star-tdoc-url = "VND.SUN.STAR.TDOC:/" segment *("/" segment)
+ segment = *pchar
+
+
+ ; private
+ unknown-url = scheme ":" 1*uric
+ scheme = ALPHA *(alphanum / "+" / "-" / ".")
+
+
+ ; private (http://ubiqx.org/cifs/Appendix-D.html):
+ smb-url = "SMB://" login ["/" segment *("/" segment) ["?" *uric]]
+ segment = *(pchar / ";")
+ */
+
+//============================================================================
+inline sal_Int32 INetURLObject::SubString::clear()
+{
+ sal_Int32 nDelta = -m_nLength;
+ m_nBegin = -1;
+ m_nLength = 0;
+ return nDelta;
+}
+
+inline sal_Int32 INetURLObject::SubString::set(rtl::OUStringBuffer & rString,
+ rtl::OUString const & rSubString)
+{
+ rtl::OUString sTemp(rString.makeStringAndClear());
+ sal_Int32 nDelta = set(sTemp, rSubString);
+ rString.append(sTemp);
+ return nDelta;
+}
+
+inline sal_Int32 INetURLObject::SubString::set(rtl::OUString & rString,
+ rtl::OUString const & rSubString)
+{
+ sal_Int32 nDelta = rSubString.getLength() - m_nLength;
+
+ rString = rString.replaceAt(m_nBegin, m_nLength, rSubString);
+
+ m_nLength = rSubString.getLength();
+ return nDelta;
+}
+
+inline sal_Int32 INetURLObject::SubString::set(rtl::OUStringBuffer & rString,
+ rtl::OUString const & rSubString,
+ sal_Int32 nTheBegin)
+{
+ m_nBegin = nTheBegin;
+ return set(rString, rSubString);
+}
+
+//============================================================================
+inline void INetURLObject::SubString::operator +=(sal_Int32 nDelta)
+{
+ if (isPresent())
+ m_nBegin = m_nBegin + nDelta;
+}
+
+//============================================================================
+int INetURLObject::SubString::compare(SubString const & rOther,
+ rtl::OUStringBuffer const & rThisString,
+ rtl::OUStringBuffer const & rOtherString) const
+{
+ sal_Int32 len = std::min(m_nLength, rOther.m_nLength);
+ sal_Unicode const * p1 = rThisString.getStr() + m_nBegin;
+ sal_Unicode const * end = p1 + len;
+ sal_Unicode const * p2 = rOtherString.getStr() + rOther.m_nBegin;
+ while (p1 != end) {
+ if (*p1 < *p2) {
+ return -1;
+ } else if (*p1 > *p2) {
+ return 1;
+ }
+ ++p1;
+ ++p2;
+ }
+ return m_nLength < rOther.m_nLength ? -1
+ : m_nLength > rOther.m_nLength ? 1
+ : 0;
+}
+
+//============================================================================
+struct INetURLObject::SchemeInfo
+{
+ sal_Char const * m_pScheme;
+ sal_Char const * m_pPrefix;
+ sal_uInt16 m_nDefaultPort;
+ bool m_bAuthority;
+ bool m_bUser;
+ bool m_bAuth;
+ bool m_bPassword;
+ bool m_bHost;
+ bool m_bPort;
+ bool m_bHierarchical;
+ bool m_bQuery;
+};
+
+//============================================================================
+struct INetURLObject::PrefixInfo
+{
+ enum Kind { OFFICIAL, INTERNAL, EXTERNAL, ALIAS }; // order is important!
+
+ sal_Char const * m_pPrefix;
+ sal_Char const * m_pTranslatedPrefix;
+ INetProtocol m_eScheme;
+ Kind m_eKind;
+};
+
+//============================================================================
+static INetURLObject::SchemeInfo const aSchemeInfoMap[INET_PROT_END]
+ = { { "", "", 0, false, false, false, false, false, false, false,
+ false },
+ { "ftp", "ftp://", 21, true, true, false, true, true, true, true,
+ false },
+ { "http", "http://", 80, true, false, false, false, true, true,
+ true, true },
+ { "file", "file://", 0, true, false, false, false, true, false,
+ true, false },
+ { "mailto", "mailto:", 0, false, false, false, false, false,
+ false, false, true },
+ { "vnd.sun.star.webdav", "vnd.sun.star.webdav://", 80, true, false,
+ false, false, true, true, true, true },
+ { "news", "news:", 0, false, false, false, false, false, false, false,
+ false },
+ { "private", "private:", 0, false, false, false, false, false,
+ false, false, true },
+ { "vnd.sun.star.help", "vnd.sun.star.help://", 0, true, false, false,
+ false, false, false, true, true },
+ { "https", "https://", 443, true, false, false, false, true, true,
+ true, true },
+ { "slot", "slot:", 0, false, false, false, false, false, false,
+ false, true },
+ { "macro", "macro:", 0, false, false, false, false, false, false,
+ false, true },
+ { "javascript", "javascript:", 0, false, false, false, false,
+ false, false, false, false },
+ { "imap", "imap://", 143, true, true, true, false, true, true,
+ true, false },
+ { "pop3", "pop3://", 110, true, true, false, true, true, true,
+ false, false },
+ { "data", "data:", 0, false, false, false, false, false, false,
+ false, false },
+ { "cid", "cid:", 0, false, false, false, false, false, false,
+ false, false },
+ { "out", "out://", 0, true, false, false, false, false, false,
+ false, false },
+ { "vnd.sun.star.hier", "vnd.sun.star.hier:", 0, true, false, false,
+ false, false, false, true, false },
+ { "vim", "vim://", 0, true, true, false, true, false, false, true,
+ false },
+ { ".uno", ".uno:", 0, false, false, false, false, false, false,
+ false, true },
+ { ".component", ".component:", 0, false, false, false, false,
+ false, false, false, true },
+ { "vnd.sun.star.pkg", "vnd.sun.star.pkg://", 0, true, false, false,
+ false, false, false, true, true },
+ { "ldap", "ldap://", 389, true, false, false, false, true, true,
+ false, true },
+ { "db", "db:", 0, false, false, false, false, false, false, false,
+ false },
+ { "vnd.sun.star.cmd", "vnd.sun.star.cmd:", 0, false, false, false,
+ false, false, false, false, false },
+ { "vnd.sun.star.odma", "vnd.sun.star.odma:", 0, false, false, false,
+ false, false, false, true, false },
+ { "telnet", "telnet://", 23, true, true, false, true, true, true, true,
+ false },
+ { "vnd.sun.star.expand", "vnd.sun.star.expand:", 0, false, false, false,
+ false, false, false, false, false },
+ { "vnd.sun.star.tdoc", "vnd.sun.star.tdoc:", 0, false, false, false,
+ false, false, false, true, false },
+ { "", "", 0, false, false, false, false, true, true, true, false },
+ { "smb", "smb://", 139, true, true, false, true, true, true, true,
+ true } };
+
+// static
+inline INetURLObject::SchemeInfo const &
+INetURLObject::getSchemeInfo(INetProtocol eTheScheme)
+{
+ return aSchemeInfoMap[eTheScheme];
+};
+
+//============================================================================
+inline INetURLObject::SchemeInfo const & INetURLObject::getSchemeInfo() const
+{
+ return getSchemeInfo(m_eScheme);
+}
+
+//============================================================================
+// static
+inline void INetURLObject::appendEscape(rtl::OUStringBuffer & rTheText,
+ sal_Char cEscapePrefix,
+ sal_uInt32 nOctet)
+{
+ rTheText.append(sal_Unicode(cEscapePrefix));
+ rTheText.append(sal_Unicode(INetMIME::getHexDigit(int(nOctet >> 4))));
+ rTheText.append(sal_Unicode(INetMIME::getHexDigit(int(nOctet & 15))));
+}
+
+//============================================================================
+namespace unnamed_tools_urlobj {
+
+enum
+{
+ PA = INetURLObject::PART_OBSOLETE_NORMAL,
+ PB = INetURLObject::PART_OBSOLETE_FILE,
+ PC = INetURLObject::PART_OBSOLETE_PARAM,
+ PD = INetURLObject::PART_USER_PASSWORD,
+ PE = INetURLObject::PART_IMAP_ACHAR,
+ PF = INetURLObject::PART_VIM,
+ PG = INetURLObject::PART_HOST_EXTRA,
+ PH = INetURLObject::PART_FPATH,
+ PI = INetURLObject::PART_AUTHORITY,
+ PJ = INetURLObject::PART_PATH_SEGMENTS_EXTRA,
+ PK = INetURLObject::PART_REL_SEGMENT_EXTRA,
+ PL = INetURLObject::PART_URIC,
+ PM = INetURLObject::PART_HTTP_PATH,
+ PN = INetURLObject::PART_FILE_SEGMENT_EXTRA,
+ PO = INetURLObject::PART_MESSAGE_ID,
+ PP = INetURLObject::PART_MESSAGE_ID_PATH,
+ PQ = INetURLObject::PART_MAILTO,
+ PR = INetURLObject::PART_PATH_BEFORE_QUERY,
+ PS = INetURLObject::PART_PCHAR,
+ PT = INetURLObject::PART_FRAGMENT,
+ PU = INetURLObject::PART_VISIBLE,
+ PV = INetURLObject::PART_VISIBLE_NONSPECIAL,
+ PW = INetURLObject::PART_CREATEFRAGMENT,
+ PX = INetURLObject::PART_UNO_PARAM_VALUE,
+ PY = INetURLObject::PART_UNAMBIGUOUS,
+ PZ = INetURLObject::PART_URIC_NO_SLASH,
+ P1 = INetURLObject::PART_HTTP_QUERY,
+ P2 = INetURLObject::PART_NEWS_ARTICLE_LOCALPART
+};
+
+static sal_uInt32 const aMustEncodeMap[128]
+ = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* */ PY,
+/* ! */ PC+PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* " */ PU+PV +PY,
+/* # */ PU,
+/* $ */ PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* % */ PU,
+/* & */ PA+PB+PC+PD+PE +PH+PI+PJ+PK+PL+PM+PN+PO+PP +PR+PS+PT+PU+PV+PW+PX +PZ+P1+P2,
+/* ' */ PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* ( */ PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* ) */ PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* * */ PA+PB+PC+PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* + */ PA+PB+PC+PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX +PZ+P1+P2,
+/* , */ PA+PB+PC+PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW +PZ+P1+P2,
+/* - */ PA+PB+PC+PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* . */ PA+PB+PC+PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* / */ PA+PB+PC +PH +PJ +PL+PM +PP+PQ+PR +PT+PU+PV +PX +P2,
+/* 0 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* 1 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* 2 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* 3 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* 4 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* 5 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* 6 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* 7 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* 8 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* 9 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* : */ PB+PC +PH+PI+PJ +PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX +PZ+P1+P2,
+/* ; */ PC+PD +PI+PJ+PK+PL+PM +PO+PP+PQ+PR +PT+PU +PW +PZ+P1+P2,
+/* < */ PC +PO+PP +PU+PV +PY,
+/* = */ PA+PB+PC+PD+PE +PH+PI+PJ+PK+PL+PM+PN +PR+PS+PT+PU+PV+PW +PZ+P1+P2,
+/* > */ PC +PO+PP +PU+PV +PY,
+/* ? */ PC +PL +PT+PU +PW+PX +PZ +P2,
+/* @ */ PC +PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1,
+/* A */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* B */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* C */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* D */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* E */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* F */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* G */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* H */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* I */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* J */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* K */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* L */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* M */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* N */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* O */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* P */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* Q */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* R */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* S */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* T */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* U */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* V */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* W */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* X */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* Y */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* Z */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* [ */ PL +PU+PV +PX,
+/* \ */ PB +PU+PV +PY,
+/* ] */ PL +PU+PV +PX,
+/* ^ */ PU+PV +PY,
+/* _ */ PA+PB+PC+PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* ` */ PU+PV +PY,
+/* a */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* b */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* c */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* d */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* e */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* f */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* g */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* h */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* i */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* j */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* k */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* l */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* m */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* n */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* o */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* p */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* q */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* r */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* s */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* t */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* u */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* v */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* w */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* x */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* y */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* z */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
+/* { */ PU+PV +PY,
+/* | */ PB+PC +PN +PT+PU+PV +PY,
+/* } */ PU+PV +PY,
+/* ~ */ PA+PB+PC+PD+PE +PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ +P2,
+ 0 };
+
+inline bool mustEncode(sal_uInt32 nUTF32, INetURLObject::Part ePart)
+{
+ return !INetMIME::isUSASCII(nUTF32) || !(aMustEncodeMap[nUTF32] & ePart);
+}
+
+}
+
+//============================================================================
+void INetURLObject::setInvalid()
+{
+ m_aAbsURIRef.setLength(0);
+ m_eScheme = INET_PROT_NOT_VALID;
+ m_aScheme.clear();
+ m_aUser.clear();
+ m_aAuth.clear();
+ m_aHost.clear();
+ m_aPort.clear();
+ m_aPath.clear();
+ m_aQuery.clear();
+ m_aFragment.clear();
+}
+
+//============================================================================
+
+namespace unnamed_tools_urlobj {
+
+INetURLObject::FSysStyle
+guessFSysStyleByCounting(sal_Unicode const * pBegin,
+ sal_Unicode const * pEnd,
+ INetURLObject::FSysStyle eStyle)
+{
+ DBG_ASSERT(eStyle
+ & (INetURLObject::FSYS_UNX
+ | INetURLObject::FSYS_DOS
+ | INetURLObject::FSYS_MAC),
+ "guessFSysStyleByCounting(): Bad style");
+ DBG_ASSERT(std::numeric_limits< sal_Int32 >::min() < pBegin - pEnd
+ && pEnd - pBegin <= std::numeric_limits< sal_Int32 >::max(),
+ "guessFSysStyleByCounting(): Too big");
+ sal_Int32 nSlashCount
+ = eStyle & INetURLObject::FSYS_UNX ?
+ 0 : std::numeric_limits< sal_Int32 >::min();
+ sal_Int32 nBackslashCount
+ = eStyle & INetURLObject::FSYS_DOS ?
+ 0 : std::numeric_limits< sal_Int32 >::min();
+ sal_Int32 nColonCount
+ = eStyle & INetURLObject::FSYS_MAC ?
+ 0 : std::numeric_limits< sal_Int32 >::min();
+ while (pBegin != pEnd)
+ switch (*pBegin++)
+ {
+ case '/':
+ ++nSlashCount;
+ break;
+
+ case '\\':
+ ++nBackslashCount;
+ break;
+
+ case ':':
+ ++nColonCount;
+ break;
+ }
+ return nSlashCount >= nBackslashCount ?
+ nSlashCount >= nColonCount ?
+ INetURLObject::FSYS_UNX : INetURLObject::FSYS_MAC :
+ nBackslashCount >= nColonCount ?
+ INetURLObject::FSYS_DOS : INetURLObject::FSYS_MAC;
+}
+
+rtl::OUString parseScheme(
+ sal_Unicode const ** begin, sal_Unicode const * end,
+ sal_uInt32 fragmentDelimiter)
+{
+ sal_Unicode const * p = *begin;
+ if (p != end && INetMIME::isAlpha(*p)) {
+ do {
+ ++p;
+ } while (p != end
+ && (INetMIME::isAlphanumeric(*p) || *p == '+' || *p == '-'
+ || *p == '.'));
+ // #i34835# To avoid problems with Windows file paths like "C:\foo",
+ // do not accept generic schemes that are only one character long:
+ if (end - p > 1 && p[0] == ':' && p[1] != fragmentDelimiter
+ && p - *begin >= 2)
+ {
+ rtl::OUString scheme(
+ rtl::OUString(*begin, p - *begin).toAsciiLowerCase());
+ *begin = p + 1;
+ return scheme;
+ }
+ }
+ return rtl::OUString();
+}
+
+}
+
+bool INetURLObject::setAbsURIRef(rtl::OUString const & rTheAbsURIRef,
+ bool bOctets,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ bool bSmart,
+ FSysStyle eStyle)
+{
+ sal_Unicode const * pPos = rTheAbsURIRef.getStr();
+ sal_Unicode const * pEnd = pPos + rTheAbsURIRef.getLength();
+
+ setInvalid();
+
+ sal_uInt32 nFragmentDelimiter = '#';
+
+ rtl::OUStringBuffer aSynAbsURIRef;
+
+ // Parse <scheme>:
+ sal_Unicode const * p = pPos;
+ PrefixInfo const * pPrefix = getPrefix(p, pEnd);
+ if (pPrefix)
+ {
+ pPos = p;
+ m_eScheme = pPrefix->m_eScheme;
+
+ rtl::OUString sTemp(rtl::OUString::createFromAscii(pPrefix->m_eKind
+ >= PrefixInfo::EXTERNAL ?
+ pPrefix->m_pTranslatedPrefix :
+ pPrefix->m_pPrefix));
+ aSynAbsURIRef.append(sTemp);
+ m_aScheme = SubString( 0, sTemp.indexOf(static_cast< sal_Unicode >(':')) );
+ }
+ else
+ {
+ if (bSmart)
+ {
+ // For scheme detection, the first (if any) of the following
+ // productions that matches the input string (and for which the
+ // appropriate style bit is set in eStyle, if applicable)
+ // determines the scheme. The productions use the auxiliary rules
+ //
+ // domain = label *("." label)
+ // label = alphanum [*(alphanum / "-") alphanum]
+ // alphanum = ALPHA / DIGIT
+ // IPv6reference = "[" IPv6address "]"
+ // IPv6address = hexpart [":" IPv4address]
+ // IPv4address = 1*3DIGIT 3("." 1*3DIGIT)
+ // hexpart = (hexseq ["::" [hexseq]]) / ("::" [hexseq])
+ // hexseq = hex4 *(":" hex4)
+ // hex4 = 1*4HEXDIG
+ // UCS4 = <any UCS4 character>
+ //
+ // 1st Production (known scheme):
+ // <one of the known schemes, ignoring case> ":" *UCS4
+ //
+ // 2nd Production (mailto):
+ // domain "@" domain
+ //
+ // 3rd Production (ftp):
+ // "FTP" 2*("." label) ["/" *UCS4]
+ //
+ // 4th Production (http):
+ // label 2*("." label) ["/" *UCS4]
+ //
+ // 5th Production (file):
+ // "//" (domain / IPv6reference) ["/" *UCS4]
+ //
+ // 6th Production (Unix file):
+ // "/" *UCS4
+ //
+ // 7th Production (UNC file; FSYS_DOS only):
+ // "\\" domain ["\" *UCS4]
+ //
+ // 8th Production (Unix-like DOS file; FSYS_DOS only):
+ // ALPHA ":" ["/" *UCS4]
+ //
+ // 9th Production (DOS file; FSYS_DOS only):
+ // ALPHA ":" ["\" *UCS4]
+ //
+ // For the 'non URL' file productions 6--9, the interpretation of
+ // the input as a (degenerate) URI is turned off, i.e., escape
+ // sequences and fragments are never detected as such, but are
+ // taken as literal characters.
+
+ sal_Unicode const * p1 = pPos;
+ if (eStyle & FSYS_DOS
+ && pEnd - p1 >= 2
+ && INetMIME::isAlpha(p1[0])
+ && p1[1] == ':'
+ && (pEnd - p1 == 2 || p1[2] == '/' || p1[2] == '\\'))
+ {
+ m_eScheme = INET_PROT_FILE; // 8th, 9th
+ eMechanism = ENCODE_ALL;
+ nFragmentDelimiter = 0x80000000;
+ }
+ else if (pEnd - p1 >= 2 && p1[0] == '/' && p1[1] == '/')
+ {
+ p1 += 2;
+ if ((scanDomain(p1, pEnd) > 0 || scanIPv6reference(p1, pEnd))
+ && (p1 == pEnd || *p1 == '/'))
+ m_eScheme = INET_PROT_FILE; // 5th
+ }
+ else if (p1 != pEnd && *p1 == '/')
+ {
+ m_eScheme = INET_PROT_FILE; // 6th
+ eMechanism = ENCODE_ALL;
+ nFragmentDelimiter = 0x80000000;
+ }
+ else if (eStyle & FSYS_DOS
+ && pEnd - p1 >= 2
+ && p1[0] == '\\'
+ && p1[1] == '\\')
+ {
+ p1 += 2;
+ sal_Int32 n = rtl_ustr_indexOfChar_WithLength(
+ p1, pEnd - p1, '\\');
+ sal_Unicode const * pe = n == -1 ? pEnd : p1 + n;
+ if (
+ parseHostOrNetBiosName(
+ p1, pe, bOctets, ENCODE_ALL, RTL_TEXTENCODING_DONTKNOW,
+ true, NULL) ||
+ (scanDomain(p1, pe) > 0 && p1 == pe)
+ )
+ {
+ m_eScheme = INET_PROT_FILE; // 7th
+ eMechanism = ENCODE_ALL;
+ nFragmentDelimiter = 0x80000000;
+ }
+ }
+ else
+ {
+ sal_Unicode const * pDomainEnd = p1;
+ sal_uInt32 nLabels = scanDomain(pDomainEnd, pEnd);
+ if (nLabels > 0 && pDomainEnd != pEnd && *pDomainEnd == '@')
+ {
+ ++pDomainEnd;
+ if (scanDomain(pDomainEnd, pEnd) > 0
+ && pDomainEnd == pEnd)
+ m_eScheme = INET_PROT_MAILTO; // 2nd
+ }
+ else if (nLabels >= 3
+ && (pDomainEnd == pEnd || *pDomainEnd == '/'))
+ m_eScheme
+ = pDomainEnd - p1 >= 4
+ && (p1[0] == 'f' || p1[0] == 'F')
+ && (p1[1] == 't' || p1[1] == 'T')
+ && (p1[2] == 'p' || p1[2] == 'P')
+ && p1[3] == '.' ?
+ INET_PROT_FTP : INET_PROT_HTTP; // 3rd, 4th
+ }
+ }
+
+ rtl::OUString aSynScheme;
+ if (m_eScheme == INET_PROT_NOT_VALID) {
+ sal_Unicode const * p1 = pPos;
+ aSynScheme = parseScheme(&p1, pEnd, nFragmentDelimiter);
+ if (aSynScheme.getLength() > 0)
+ {
+ m_eScheme = INET_PROT_GENERIC;
+ pPos = p1;
+ }
+ }
+
+ if (bSmart && m_eScheme == INET_PROT_NOT_VALID && pPos != pEnd
+ && *pPos != nFragmentDelimiter)
+ {
+ m_eScheme = m_eSmartScheme;
+ }
+
+ if (m_eScheme == INET_PROT_NOT_VALID)
+ {
+ setInvalid();
+ return false;
+ }
+
+ if (m_eScheme != INET_PROT_GENERIC) {
+ aSynScheme = rtl::OUString::createFromAscii(getSchemeInfo().m_pScheme);
+ }
+ m_aScheme.set(aSynAbsURIRef, aSynScheme, aSynAbsURIRef.getLength());
+ aSynAbsURIRef.append(sal_Unicode(':'));
+ }
+
+ sal_Char cEscapePrefix = getEscapePrefix();
+ sal_uInt32 nSegmentDelimiter = '/';
+ sal_uInt32 nAltSegmentDelimiter = 0x80000000;
+ bool bSkippedInitialSlash = false;
+
+ // Parse //<user>;AUTH=<auth>@<host>:<port> or
+ // //<user>:<password>@<host>:<port> or
+ // //<reg_name>
+ if (getSchemeInfo().m_bAuthority)
+ {
+ sal_Unicode const * pUserInfoBegin = 0;
+ sal_Unicode const * pUserInfoEnd = 0;
+ sal_Unicode const * pHostPortBegin = 0;
+ sal_Unicode const * pHostPortEnd = 0;
+
+ switch (m_eScheme)
+ {
+ case INET_PROT_VND_SUN_STAR_HELP:
+ {
+ if (pEnd - pPos < 2 || *pPos++ != '/' || *pPos++ != '/')
+ {
+ setInvalid();
+ return false;
+ }
+ aSynAbsURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ rtl::OUStringBuffer aSynAuthority;
+ while (pPos < pEnd
+ && *pPos != '/' && *pPos != '?'
+ && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+ cEscapePrefix, eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aSynAuthority, nUTF32, eEscapeType, bOctets,
+ PART_AUTHORITY, cEscapePrefix, eCharset,
+ false);
+ }
+ m_aHost.set(aSynAbsURIRef,
+ aSynAuthority.makeStringAndClear(),
+ aSynAbsURIRef.getLength());
+ // misusing m_aHost to store the authority
+ break;
+ }
+
+ case INET_PROT_VND_SUN_STAR_HIER:
+ {
+ if (pEnd - pPos >= 2 && pPos[0] == '/' && pPos[1] == '/')
+ {
+ pPos += 2;
+ aSynAbsURIRef.
+ appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ rtl::OUStringBuffer aSynAuthority;
+ while (pPos < pEnd
+ && *pPos != '/' && *pPos != '?'
+ && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos,
+ pEnd,
+ bOctets,
+ cEscapePrefix,
+ eMechanism,
+ eCharset,
+ eEscapeType);
+ appendUCS4(aSynAuthority,
+ nUTF32,
+ eEscapeType,
+ bOctets,
+ PART_AUTHORITY,
+ cEscapePrefix,
+ eCharset,
+ false);
+ }
+ if (aSynAuthority.getLength() == 0)
+ {
+ setInvalid();
+ return false;
+ }
+ m_aHost.set(aSynAbsURIRef,
+ aSynAuthority.makeStringAndClear(),
+ aSynAbsURIRef.getLength());
+ // misusing m_aHost to store the authority
+ }
+ break;
+ }
+
+ case INET_PROT_VND_SUN_STAR_PKG:
+ {
+ if (pEnd - pPos < 2 || *pPos++ != '/' || *pPos++ != '/')
+ {
+ setInvalid();
+ return false;
+ }
+ aSynAbsURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ rtl::OUStringBuffer aSynAuthority;
+ while (pPos < pEnd
+ && *pPos != '/' && *pPos != '?'
+ && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+ cEscapePrefix, eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aSynAuthority, nUTF32, eEscapeType, bOctets,
+ PART_AUTHORITY, cEscapePrefix, eCharset,
+ false);
+ }
+ if (aSynAuthority.getLength() == 0)
+ {
+ setInvalid();
+ return false;
+ }
+ m_aHost.set(aSynAbsURIRef,
+ aSynAuthority.makeStringAndClear(),
+ aSynAbsURIRef.getLength());
+ // misusing m_aHost to store the authority
+ break;
+ }
+
+ case INET_PROT_FILE:
+ if (bSmart)
+ {
+ // The first of the following seven productions that
+ // matches the rest of the input string (and for which the
+ // appropriate style bit is set in eStyle, if applicable)
+ // determines the used notation. The productions use the
+ // auxiliary rules
+ //
+ // domain = label *("." label)
+ // label = alphanum [*(alphanum / "-") alphanum]
+ // alphanum = ALPHA / DIGIT
+ // IPv6reference = "[" IPv6address "]"
+ // IPv6address = hexpart [":" IPv4address]
+ // IPv4address = 1*3DIGIT 3("." 1*3DIGIT)
+ // hexpart = (hexseq ["::" [hexseq]]) / ("::" [hexseq])
+ // hexseq = hex4 *(":" hex4)
+ // hex4 = 1*4HEXDIG
+ // path = <any UCS4 character except "#">
+ // UCS4 = <any UCS4 character>
+
+ // 1st Production (URL):
+ // "//" [domain / IPv6reference] ["/" *path]
+ // ["#" *UCS4]
+ // becomes
+ // "file://" domain "/" *path ["#" *UCS4]
+ if (pEnd - pPos >= 2 && pPos[0] == '/' && pPos[1] == '/')
+ {
+ sal_Unicode const * p1 = pPos + 2;
+ while (p1 != pEnd && *p1 != '/' &&
+ *p1 != nFragmentDelimiter)
+ {
+ ++p1;
+ }
+ if (parseHostOrNetBiosName(
+ pPos + 2, p1, bOctets, ENCODE_ALL,
+ RTL_TEXTENCODING_DONTKNOW, true, NULL))
+ {
+ aSynAbsURIRef.
+ appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ pHostPortBegin = pPos + 2;
+ pHostPortEnd = p1;
+ pPos = p1;
+ break;
+ }
+ }
+
+ // 2nd Production (MS IE generated 1; FSYS_DOS only):
+ // "//" ALPHA ":" ["/" *path] ["#" *UCS4]
+ // becomes
+ // "file:///" ALPHA ":" ["/" *path] ["#" *UCS4]
+ // replacing "\" by "/" within <*path>
+ //
+ // 3rd Production (MS IE generated 2; FSYS_DOS only):
+ // "//" ALPHA ":" ["\" *path] ["#" *UCS4]
+ // becomes
+ // "file:///" ALPHA ":" ["/" *path] ["#" *UCS4]
+ // replacing "\" by "/" within <*path>
+ //
+ // 4th Production (misscounted slashes):
+ // "//" *path ["#" *UCS4]
+ // becomes
+ // "file:///" *path ["#" *UCS4]
+ if (pEnd - pPos >= 2 && pPos[0] == '/' && pPos[1] == '/')
+ {
+ aSynAbsURIRef.
+ appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ pPos += 2;
+ bSkippedInitialSlash = true;
+ if ((eStyle & FSYS_DOS) != 0
+ && pEnd - pPos >= 2
+ && INetMIME::isAlpha(pPos[0])
+ && pPos[1] == ':'
+ && (pEnd - pPos == 2
+ || pPos[2] == '/' || pPos[2] == '\\'))
+ nAltSegmentDelimiter = '\\';
+ break;
+ }
+
+ // 5th Production (Unix):
+ // "/" *path ["#" *UCS4]
+ // becomes
+ // "file:///" *path ["#" *UCS4]
+ if (pPos < pEnd && *pPos == '/')
+ {
+ aSynAbsURIRef.
+ appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ break;
+ }
+
+ // 6th Production (UNC; FSYS_DOS only):
+ // "\\" domain ["\" *path] ["#" *UCS4]
+ // becomes
+ // "file://" domain "/" *path ["#" *UCS4]
+ // replacing "\" by "/" within <*path>
+ if (eStyle & FSYS_DOS
+ && pEnd - pPos >= 2
+ && pPos[0] == '\\'
+ && pPos[1] == '\\')
+ {
+ sal_Unicode const * p1 = pPos + 2;
+ sal_Unicode const * pe = p1;
+ while (pe < pEnd && *pe != '\\' &&
+ *pe != nFragmentDelimiter)
+ {
+ ++pe;
+ }
+ if (
+ parseHostOrNetBiosName(
+ p1, pe, bOctets, ENCODE_ALL,
+ RTL_TEXTENCODING_DONTKNOW, true, NULL) ||
+ (scanDomain(p1, pe) > 0 && p1 == pe)
+ )
+ {
+ aSynAbsURIRef.
+ appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ pHostPortBegin = pPos + 2;
+ pHostPortEnd = pe;
+ pPos = pe;
+ nSegmentDelimiter = '\\';
+ break;
+ }
+ }
+
+ // 7th Production (Unix-like DOS; FSYS_DOS only):
+ // ALPHA ":" ["/" *path] ["#" *UCS4]
+ // becomes
+ // "file:///" ALPHA ":" ["/" *path] ["#" *UCS4]
+ // replacing "\" by "/" within <*path>
+ //
+ // 8th Production (DOS; FSYS_DOS only):
+ // ALPHA ":" ["\" *path] ["#" *UCS4]
+ // becomes
+ // "file:///" ALPHA ":" ["/" *path] ["#" *UCS4]
+ // replacing "\" by "/" within <*path>
+ if (eStyle & FSYS_DOS
+ && pEnd - pPos >= 2
+ && INetMIME::isAlpha(pPos[0])
+ && pPos[1] == ':'
+ && (pEnd - pPos == 2
+ || pPos[2] == '/'
+ || pPos[2] == '\\'))
+ {
+ aSynAbsURIRef.
+ appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ nAltSegmentDelimiter = '\\';
+ bSkippedInitialSlash = true;
+ break;
+ }
+
+ // 9th Production (any):
+ // *path ["#" *UCS4]
+ // becomes
+ // "file:///" *path ["#" *UCS4]
+ // replacing the delimiter by "/" within <*path>. The
+ // delimiter is that character from the set { "/", "\",
+ // ":" } which appears most often in <*path> (if FSYS_UNX
+ // is not among the style bits, "/" is removed from the
+ // set; if FSYS_DOS is not among the style bits, "\" is
+ // removed from the set; if FSYS_MAC is not among the
+ // style bits, ":" is removed from the set). If two or
+ // more characters appear the same number of times, the
+ // character mentioned first in that set is chosen. If
+ // the first character of <*path> is the delimiter, that
+ // character is not copied.
+ if (eStyle & (FSYS_UNX | FSYS_DOS | FSYS_MAC))
+ {
+ aSynAbsURIRef.
+ appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ switch (guessFSysStyleByCounting(pPos, pEnd, eStyle))
+ {
+ case FSYS_UNX:
+ nSegmentDelimiter = '/';
+ break;
+
+ case FSYS_DOS:
+ nSegmentDelimiter = '\\';
+ break;
+
+ case FSYS_MAC:
+ nSegmentDelimiter = ':';
+ break;
+
+ default:
+ DBG_ERROR(
+ "INetURLObject::setAbsURIRef():"
+ " Bad guessFSysStyleByCounting");
+ break;
+ }
+ bSkippedInitialSlash
+ = pPos != pEnd && *pPos != nSegmentDelimiter;
+ break;
+ }
+ }
+ default:
+ {
+ // For INET_PROT_FILE, allow an empty authority ("//") to be
+ // missing if the following path starts with an explicit "/"
+ // (Java is notorious in generating such file URLs, so be
+ // liberal here):
+ if (pEnd - pPos >= 2 && pPos[0] == '/' && pPos[1] == '/')
+ pPos += 2;
+ else if (!bSmart
+ && !(m_eScheme == INET_PROT_FILE
+ && pPos != pEnd && *pPos == '/'))
+ {
+ setInvalid();
+ return false;
+ }
+ aSynAbsURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+
+ sal_Unicode const * pAuthority = pPos;
+ sal_uInt32 c = getSchemeInfo().m_bQuery ? '?' : 0x80000000;
+ while (pPos < pEnd && *pPos != '/' && *pPos != c
+ && *pPos != nFragmentDelimiter)
+ ++pPos;
+ if (getSchemeInfo().m_bUser)
+ if (getSchemeInfo().m_bHost)
+ {
+ sal_Unicode const * p1 = pAuthority;
+ while (p1 < pPos && *p1 != '@')
+ ++p1;
+ if (p1 == pPos)
+ {
+ pHostPortBegin = pAuthority;
+ pHostPortEnd = pPos;
+ }
+ else
+ {
+ pUserInfoBegin = pAuthority;
+ pUserInfoEnd = p1;
+ pHostPortBegin = p1 + 1;
+ pHostPortEnd = pPos;
+ }
+ }
+ else
+ {
+ pUserInfoBegin = pAuthority;
+ pUserInfoEnd = pPos;
+ }
+ else if (getSchemeInfo().m_bHost)
+ {
+ pHostPortBegin = pAuthority;
+ pHostPortEnd = pPos;
+ }
+ else if (pPos != pAuthority)
+ {
+ setInvalid();
+ return false;
+ }
+ break;
+ }
+ }
+
+ if (pUserInfoBegin)
+ {
+ Part ePart = m_eScheme == INET_PROT_IMAP ?
+ PART_IMAP_ACHAR :
+ m_eScheme == INET_PROT_VIM ?
+ PART_VIM :
+ PART_USER_PASSWORD;
+ bool bSupportsPassword = getSchemeInfo().m_bPassword;
+ bool bSupportsAuth
+ = !bSupportsPassword && getSchemeInfo().m_bAuth;
+ bool bHasAuth = false;
+ rtl::OUStringBuffer aSynUser;
+ sal_Unicode const * p1 = pUserInfoBegin;
+ while (p1 < pUserInfoEnd)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(p1, pUserInfoEnd, bOctets,
+ cEscapePrefix, eMechanism,
+ eCharset, eEscapeType);
+ if (eEscapeType == ESCAPE_NO)
+ {
+ if (nUTF32 == ':' && bSupportsPassword)
+ {
+ bHasAuth = true;
+ break;
+ }
+ else if (nUTF32 == ';' && bSupportsAuth
+ && pUserInfoEnd - p1
+ > RTL_CONSTASCII_LENGTH("auth=")
+ && INetMIME::equalIgnoreCase(
+ p1,
+ p1 + RTL_CONSTASCII_LENGTH("auth="),
+ "auth="))
+ {
+ p1 += RTL_CONSTASCII_LENGTH("auth=");
+ bHasAuth = true;
+ break;
+ }
+ }
+ appendUCS4(aSynUser, nUTF32, eEscapeType, bOctets, ePart,
+ cEscapePrefix, eCharset, false);
+ }
+ m_aUser.set(aSynAbsURIRef, aSynUser.makeStringAndClear(),
+ aSynAbsURIRef.getLength());
+ if (bHasAuth)
+ {
+ if (bSupportsPassword)
+ {
+ aSynAbsURIRef.append(sal_Unicode(':'));
+ rtl::OUStringBuffer aSynAuth;
+ while (p1 < pUserInfoEnd)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(p1, pUserInfoEnd, bOctets,
+ cEscapePrefix,
+ eMechanism, eCharset,
+ eEscapeType);
+ appendUCS4(aSynAuth, nUTF32, eEscapeType, bOctets,
+ ePart, cEscapePrefix, eCharset, false);
+ }
+ m_aAuth.set(aSynAbsURIRef, aSynAuth.makeStringAndClear(),
+ aSynAbsURIRef.getLength());
+ }
+ else
+ {
+ aSynAbsURIRef.
+ appendAscii(RTL_CONSTASCII_STRINGPARAM(";AUTH="));
+ rtl::OUStringBuffer aSynAuth;
+ while (p1 < pUserInfoEnd)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(p1, pUserInfoEnd, bOctets,
+ cEscapePrefix,
+ eMechanism, eCharset,
+ eEscapeType);
+ if (!INetMIME::isIMAPAtomChar(nUTF32))
+ {
+ setInvalid();
+ return false;
+ }
+ appendUCS4(aSynAuth, nUTF32, eEscapeType, bOctets,
+ ePart, cEscapePrefix, eCharset, false);
+ }
+ m_aAuth.set(aSynAbsURIRef, aSynAuth.makeStringAndClear(),
+ aSynAbsURIRef.getLength());
+ }
+ }
+ if (pHostPortBegin)
+ aSynAbsURIRef.append(sal_Unicode('@'));
+ }
+
+ if (pHostPortBegin)
+ {
+ sal_Unicode const * pPort = pHostPortEnd;
+ if ( getSchemeInfo().m_bPort && pHostPortBegin < pHostPortEnd )
+ {
+ sal_Unicode const * p1 = pHostPortEnd - 1;
+ while (p1 > pHostPortBegin && INetMIME::isDigit(*p1))
+ --p1;
+ if (*p1 == ':')
+ pPort = p1;
+ }
+ bool bNetBiosName = false;
+ switch (m_eScheme)
+ {
+ case INET_PROT_FILE:
+ // If the host equals "LOCALHOST" (unencoded and ignoring
+ // case), turn it into an empty host:
+ if (INetMIME::equalIgnoreCase(pHostPortBegin, pPort,
+ "localhost"))
+ pHostPortBegin = pPort;
+ bNetBiosName = true;
+ break;
+
+ case INET_PROT_LDAP:
+ case INET_PROT_SMB:
+ if (pHostPortBegin == pPort && pPort != pHostPortEnd)
+ {
+ setInvalid();
+ return false;
+ }
+ break;
+ default:
+ if (pHostPortBegin == pPort)
+ {
+ setInvalid();
+ return false;
+ }
+ break;
+ }
+ rtl::OUStringBuffer aSynHost;
+ if (!parseHostOrNetBiosName(
+ pHostPortBegin, pPort, bOctets, eMechanism, eCharset,
+ bNetBiosName, &aSynHost))
+ {
+ setInvalid();
+ return false;
+ }
+ m_aHost.set(aSynAbsURIRef, aSynHost.makeStringAndClear(),
+ aSynAbsURIRef.getLength());
+ if (pPort != pHostPortEnd)
+ {
+ aSynAbsURIRef.append(sal_Unicode(':'));
+ m_aPort.set(aSynAbsURIRef,
+ rtl::OUString(pPort + 1, pHostPortEnd - (pPort + 1)),
+ aSynAbsURIRef.getLength());
+ }
+ }
+ }
+
+ // Parse <path>
+ rtl::OUStringBuffer aSynPath;
+ if (!parsePath(m_eScheme, &pPos, pEnd, bOctets, eMechanism, eCharset,
+ bSkippedInitialSlash, nSegmentDelimiter,
+ nAltSegmentDelimiter,
+ getSchemeInfo().m_bQuery ? '?' : 0x80000000,
+ nFragmentDelimiter, aSynPath))
+ {
+ setInvalid();
+ return false;
+ }
+ m_aPath.set(aSynAbsURIRef, aSynPath.makeStringAndClear(),
+ aSynAbsURIRef.getLength());
+
+ // Parse ?<query>
+ if (getSchemeInfo().m_bQuery && pPos < pEnd && *pPos == '?')
+ {
+ aSynAbsURIRef.append(sal_Unicode('?'));
+ rtl::OUStringBuffer aSynQuery;
+ for (++pPos; pPos < pEnd && *pPos != nFragmentDelimiter;)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets, cEscapePrefix,
+ eMechanism, eCharset, eEscapeType);
+ appendUCS4(aSynQuery, nUTF32, eEscapeType, bOctets,
+ PART_URIC, cEscapePrefix, eCharset, true);
+ }
+ m_aQuery.set(aSynAbsURIRef, aSynQuery.makeStringAndClear(),
+ aSynAbsURIRef.getLength());
+ }
+
+ // Parse #<fragment>
+ if (pPos < pEnd && *pPos == nFragmentDelimiter)
+ {
+ aSynAbsURIRef.append(sal_Unicode(nFragmentDelimiter));
+ rtl::OUStringBuffer aSynFragment;
+ for (++pPos; pPos < pEnd;)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets, cEscapePrefix,
+ eMechanism, eCharset, eEscapeType);
+ appendUCS4(aSynFragment, nUTF32, eEscapeType, bOctets, PART_URIC,
+ cEscapePrefix, eCharset, true);
+ }
+ m_aFragment.set(aSynAbsURIRef, aSynFragment.makeStringAndClear(),
+ aSynAbsURIRef.getLength());
+ }
+
+ if (pPos != pEnd)
+ {
+ setInvalid();
+ return false;
+ }
+
+ m_aAbsURIRef = aSynAbsURIRef;
+
+ return true;
+}
+
+//============================================================================
+bool INetURLObject::convertRelToAbs(rtl::OUString const & rTheRelURIRef,
+ bool bOctets,
+ INetURLObject & rTheAbsURIRef,
+ bool & rWasAbsolute,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ bool bIgnoreFragment, bool bSmart,
+ bool bRelativeNonURIs, FSysStyle eStyle)
+ const
+{
+ sal_Unicode const * p = rTheRelURIRef.getStr();
+ sal_Unicode const * pEnd = p + rTheRelURIRef.getLength();
+
+ sal_Unicode const * pPrefixBegin = p;
+ PrefixInfo const * pPrefix = getPrefix(pPrefixBegin, pEnd);
+ bool hasScheme = pPrefix != 0;
+ if (!hasScheme) {
+ pPrefixBegin = p;
+ hasScheme = parseScheme(&pPrefixBegin, pEnd, '#').getLength() > 0;
+ }
+
+ sal_uInt32 nSegmentDelimiter = '/';
+ sal_uInt32 nQueryDelimiter
+ = !bSmart || getSchemeInfo().m_bQuery ? '?' : 0x80000000;
+ sal_uInt32 nFragmentDelimiter = '#';
+ Part ePart = PART_VISIBLE;
+
+ if (!hasScheme && bSmart)
+ {
+ // If the input matches any of the following productions (for which
+ // the appropriate style bit is set in eStyle), it is assumed to be an
+ // absolute file system path, rather than a relative URI reference.
+ // (This is only a subset of the productions used for scheme detection
+ // in INetURLObject::setAbsURIRef(), because most of those productions
+ // interfere with the syntax of relative URI references.) The
+ // productions use the auxiliary rules
+ //
+ // domain = label *("." label)
+ // label = alphanum [*(alphanum / "-") alphanum]
+ // alphanum = ALPHA / DIGIT
+ // UCS4 = <any UCS4 character>
+ //
+ // 1st Production (UNC file; FSYS_DOS only):
+ // "\\" domain ["\" *UCS4]
+ //
+ // 2nd Production (Unix-like DOS file; FSYS_DOS only):
+ // ALPHA ":" ["/" *UCS4]
+ //
+ // 3rd Production (DOS file; FSYS_DOS only):
+ // ALPHA ":" ["\" *UCS4]
+ if (eStyle & FSYS_DOS)
+ {
+ bool bFSys = false;
+ sal_Unicode const * q = p;
+ if (pEnd - q >= 2
+ && INetMIME::isAlpha(q[0])
+ && q[1] == ':'
+ && (pEnd - q == 2 || q[2] == '/' || q[2] == '\\'))
+ bFSys = true; // 2nd, 3rd
+ else if (pEnd - q >= 2 && q[0] == '\\' && q[1] == '\\')
+ {
+ q += 2;
+ sal_Int32 n = rtl_ustr_indexOfChar_WithLength(
+ q, pEnd - q, '\\');
+ sal_Unicode const * qe = n == -1 ? pEnd : q + n;
+ if (parseHostOrNetBiosName(
+ q, qe, bOctets, ENCODE_ALL, RTL_TEXTENCODING_DONTKNOW,
+ true, NULL))
+ {
+ bFSys = true; // 1st
+ }
+ }
+ if (bFSys)
+ {
+ INetURLObject aNewURI;
+ aNewURI.setAbsURIRef(rTheRelURIRef, bOctets, eMechanism,
+ eCharset, true, eStyle);
+ if (!aNewURI.HasError())
+ {
+ rTheAbsURIRef = aNewURI;
+ rWasAbsolute = true;
+ return true;
+ }
+ }
+ }
+
+ // When the base URL is a file URL, accept relative file system paths
+ // using "\" or ":" as delimiter (and ignoring URI conventions for "%"
+ // and "#"), as well as relative URIs using "/" as delimiter:
+ if (m_eScheme == INET_PROT_FILE)
+ switch (guessFSysStyleByCounting(p, pEnd, eStyle))
+ {
+ case FSYS_UNX:
+ nSegmentDelimiter = '/';
+ break;
+
+ case FSYS_DOS:
+ nSegmentDelimiter = '\\';
+ bRelativeNonURIs = true;
+ break;
+
+ case FSYS_MAC:
+ nSegmentDelimiter = ':';
+ bRelativeNonURIs = true;
+ break;
+
+ default:
+ DBG_ERROR("INetURLObject::convertRelToAbs():"
+ " Bad guessFSysStyleByCounting");
+ break;
+ }
+
+ if (bRelativeNonURIs)
+ {
+ eMechanism = ENCODE_ALL;
+ nQueryDelimiter = 0x80000000;
+ nFragmentDelimiter = 0x80000000;
+ ePart = PART_VISIBLE_NONSPECIAL;
+ }
+ }
+
+ // If the relative URI has the same scheme as the base URI, and that
+ // scheme is hierarchical, then ignore its presence in the relative
+ // URI in order to be backward compatible (cf. RFC 2396 section 5.2
+ // step 3):
+ if (pPrefix && pPrefix->m_eScheme == m_eScheme
+ && getSchemeInfo().m_bHierarchical)
+ {
+ hasScheme = false;
+ while (p != pEnd && *p++ != ':') ;
+ }
+ rWasAbsolute = hasScheme;
+
+ // Fast solution for non-relative URIs:
+ if (hasScheme)
+ {
+ INetURLObject aNewURI(rTheRelURIRef, eMechanism, eCharset);
+ if (aNewURI.HasError())
+ {
+ rWasAbsolute = false;
+ return false;
+ }
+
+ if (bIgnoreFragment)
+ aNewURI.clearFragment();
+ rTheAbsURIRef = aNewURI;
+ return true;
+ }
+
+ enum State { STATE_AUTH, STATE_ABS_PATH, STATE_REL_PATH, STATE_FRAGMENT,
+ STATE_DONE };
+
+ rtl::OUStringBuffer aSynAbsURIRef;
+ // make sure that the scheme is copied for generic schemes: getSchemeInfo().m_pScheme
+ // is empty ("") in that case, so take the scheme from m_aAbsURIRef
+ if (m_eScheme != INET_PROT_GENERIC)
+ {
+ aSynAbsURIRef.appendAscii(getSchemeInfo().m_pScheme);
+ }
+ else
+ {
+ sal_Unicode const * pSchemeBegin
+ = m_aAbsURIRef.getStr();
+ sal_Unicode const * pSchemeEnd = pSchemeBegin;
+ while (pSchemeEnd[0] != ':')
+ {
+ ++pSchemeEnd;
+ }
+ aSynAbsURIRef.append(pSchemeBegin, pSchemeEnd - pSchemeBegin);
+ }
+ aSynAbsURIRef.append(sal_Unicode(':'));
+
+ sal_Char cEscapePrefix = getEscapePrefix();
+
+ State eState = STATE_AUTH;
+ bool bSameDoc = true;
+
+ if (getSchemeInfo().m_bAuthority)
+ {
+ if (pEnd - p >= 2 && p[0] == '/' && p[1] == '/')
+ {
+ aSynAbsURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ p += 2;
+ eState = STATE_ABS_PATH;
+ bSameDoc = false;
+ while (p != pEnd)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32
+ = getUTF32(p, pEnd, bOctets, cEscapePrefix, eMechanism,
+ eCharset, eEscapeType);
+ if (eEscapeType == ESCAPE_NO)
+ {
+ if (nUTF32 == nSegmentDelimiter)
+ break;
+ else if (nUTF32 == nFragmentDelimiter)
+ {
+ eState = STATE_FRAGMENT;
+ break;
+ }
+ }
+ appendUCS4(aSynAbsURIRef, nUTF32, eEscapeType, bOctets,
+ PART_VISIBLE, cEscapePrefix, eCharset, true);
+ }
+ }
+ else
+ {
+ SubString aAuthority(getAuthority());
+ aSynAbsURIRef.append(m_aAbsURIRef.getStr()
+ + aAuthority.getBegin(),
+ aAuthority.getLength());
+ }
+ }
+
+ if (eState == STATE_AUTH)
+ {
+ if (p == pEnd)
+ eState = STATE_DONE;
+ else if (*p == nFragmentDelimiter)
+ {
+ ++p;
+ eState = STATE_FRAGMENT;
+ }
+ else if (*p == nSegmentDelimiter)
+ {
+ ++p;
+ eState = STATE_ABS_PATH;
+ bSameDoc = false;
+ }
+ else
+ {
+ eState = STATE_REL_PATH;
+ bSameDoc = false;
+ }
+ }
+
+ if (eState == STATE_ABS_PATH)
+ {
+ aSynAbsURIRef.append(sal_Unicode('/'));
+ eState = STATE_DONE;
+ while (p != pEnd)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32
+ = getUTF32(p, pEnd, bOctets, cEscapePrefix, eMechanism,
+ eCharset, eEscapeType);
+ if (eEscapeType == ESCAPE_NO)
+ {
+ if (nUTF32 == nFragmentDelimiter)
+ {
+ eState = STATE_FRAGMENT;
+ break;
+ }
+ else if (nUTF32 == nSegmentDelimiter)
+ nUTF32 = '/';
+ }
+ appendUCS4(aSynAbsURIRef, nUTF32, eEscapeType, bOctets, ePart,
+ cEscapePrefix, eCharset, true);
+ }
+ }
+ else if (eState == STATE_REL_PATH)
+ {
+ if (!getSchemeInfo().m_bHierarchical)
+ {
+ // Detect cases where a relative input could not be made absolute
+ // because the given base URL is broken (most probably because it is
+ // empty):
+ OSL_ASSERT(!HasError());
+ rWasAbsolute = false;
+ return false;
+ }
+
+ sal_Unicode const * pBasePathBegin
+ = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ sal_Unicode const * pBasePathEnd
+ = pBasePathBegin + m_aPath.getLength();
+ while (pBasePathEnd != pBasePathBegin)
+ if (*(--pBasePathEnd) == '/')
+ {
+ ++pBasePathEnd;
+ break;
+ }
+
+ sal_Int32 nPathBegin = aSynAbsURIRef.getLength();
+ aSynAbsURIRef.append(pBasePathBegin, pBasePathEnd - pBasePathBegin);
+ DBG_ASSERT(aSynAbsURIRef.getLength() > nPathBegin
+ && aSynAbsURIRef.charAt(aSynAbsURIRef.getLength() - 1) == '/',
+ "INetURLObject::convertRelToAbs(): Bad base path");
+
+ while (p != pEnd && *p != nQueryDelimiter && *p != nFragmentDelimiter)
+ {
+ if (*p == '.')
+ {
+ if (pEnd - p == 1
+ || p[1] == nSegmentDelimiter
+ || p[1] == nQueryDelimiter
+ || p[1] == nFragmentDelimiter)
+ {
+ ++p;
+ if (p != pEnd && *p == nSegmentDelimiter)
+ ++p;
+ continue;
+ }
+ else if (pEnd - p >= 2
+ && p[1] == '.'
+ && (pEnd - p == 2
+ || p[2] == nSegmentDelimiter
+ || p[2] == nQueryDelimiter
+ || p[2] == nFragmentDelimiter)
+ && aSynAbsURIRef.getLength() - nPathBegin > 1)
+ {
+ p += 2;
+ if (p != pEnd && *p == nSegmentDelimiter)
+ ++p;
+
+ sal_Int32 i = aSynAbsURIRef.getLength() - 2;
+ while (i > nPathBegin && aSynAbsURIRef.charAt(i) != '/')
+ --i;
+ aSynAbsURIRef.setLength(i + 1);
+ DBG_ASSERT(
+ aSynAbsURIRef.getLength() > nPathBegin
+ && aSynAbsURIRef.charAt(aSynAbsURIRef.getLength() - 1)
+ == '/',
+ "INetURLObject::convertRelToAbs(): Bad base path");
+ continue;
+ }
+ }
+
+ while (p != pEnd
+ && *p != nSegmentDelimiter
+ && *p != nQueryDelimiter
+ && *p != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32
+ = getUTF32(p, pEnd, bOctets, cEscapePrefix, eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aSynAbsURIRef, nUTF32, eEscapeType, bOctets, ePart,
+ cEscapePrefix, eCharset, true);
+ }
+ if (p != pEnd && *p == nSegmentDelimiter)
+ {
+ aSynAbsURIRef.append(sal_Unicode('/'));
+ ++p;
+ }
+ }
+
+ while (p != pEnd && *p != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32
+ = getUTF32(p, pEnd, bOctets, cEscapePrefix, eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aSynAbsURIRef, nUTF32, eEscapeType, bOctets, ePart,
+ cEscapePrefix, eCharset, true);
+ }
+
+ if (p == pEnd)
+ eState = STATE_DONE;
+ else
+ {
+ ++p;
+ eState = STATE_FRAGMENT;
+ }
+ }
+ else if (bSameDoc)
+ {
+ aSynAbsURIRef.append(m_aAbsURIRef.getStr() + m_aPath.getBegin(),
+ m_aPath.getLength());
+ if (m_aQuery.isPresent())
+ aSynAbsURIRef.append(m_aAbsURIRef.getStr()
+ + m_aQuery.getBegin() - 1,
+ m_aQuery.getLength() + 1);
+ }
+
+ if (eState == STATE_FRAGMENT && !bIgnoreFragment)
+ {
+ aSynAbsURIRef.append(sal_Unicode('#'));
+ while (p != pEnd)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32
+ = getUTF32(p, pEnd, bOctets, cEscapePrefix, eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aSynAbsURIRef, nUTF32, eEscapeType, bOctets,
+ PART_VISIBLE, cEscapePrefix, eCharset, true);
+ }
+ }
+
+ INetURLObject aNewURI(aSynAbsURIRef.makeStringAndClear());
+ if (aNewURI.HasError())
+ {
+ // Detect cases where a relative input could not be made absolute
+ // because the given base URL is broken (most probably because it is
+ // empty):
+ OSL_ASSERT(!HasError());
+ rWasAbsolute = false;
+ return false;
+ }
+
+ rTheAbsURIRef = aNewURI;
+ return true;
+}
+
+//============================================================================
+bool INetURLObject::convertAbsToRel(rtl::OUString const & rTheAbsURIRef,
+ bool bOctets, rtl::OUString & rTheRelURIRef,
+ EncodeMechanism eEncodeMechanism,
+ DecodeMechanism eDecodeMechanism,
+ rtl_TextEncoding eCharset,
+ FSysStyle eStyle) const
+{
+ // Check for hierarchical base URL:
+ if (!getSchemeInfo().m_bHierarchical)
+ {
+ rTheRelURIRef
+ = decode(rTheAbsURIRef,
+ getEscapePrefix(CompareProtocolScheme(rTheAbsURIRef)),
+ eDecodeMechanism, eCharset);
+ return false;
+ }
+
+ // Convert the input (absolute or relative URI ref) to an absolute URI
+ // ref:
+ INetURLObject aSubject;
+ bool bWasAbsolute;
+ if (!convertRelToAbs(rTheAbsURIRef, bOctets, aSubject, bWasAbsolute,
+ eEncodeMechanism, eCharset, false, false, false,
+ eStyle))
+ {
+ rTheRelURIRef
+ = decode(rTheAbsURIRef,
+ getEscapePrefix(CompareProtocolScheme(rTheAbsURIRef)),
+ eDecodeMechanism, eCharset);
+ return false;
+ }
+
+ // Check for differing scheme or authority parts:
+ if ((m_aScheme.compare(
+ aSubject.m_aScheme, m_aAbsURIRef, aSubject.m_aAbsURIRef)
+ != 0)
+ || (m_aUser.compare(
+ aSubject.m_aUser, m_aAbsURIRef, aSubject.m_aAbsURIRef)
+ != 0)
+ || (m_aAuth.compare(
+ aSubject.m_aAuth, m_aAbsURIRef, aSubject.m_aAbsURIRef)
+ != 0)
+ || (m_aHost.compare(
+ aSubject.m_aHost, m_aAbsURIRef, aSubject.m_aAbsURIRef)
+ != 0)
+ || (m_aPort.compare(
+ aSubject.m_aPort, m_aAbsURIRef, aSubject.m_aAbsURIRef)
+ != 0))
+ {
+ rTheRelURIRef = aSubject.GetMainURL(eDecodeMechanism, eCharset);
+ return false;
+ }
+
+ sal_Unicode const * pBasePathBegin
+ = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ sal_Unicode const * pBasePathEnd = pBasePathBegin + m_aPath.getLength();
+ sal_Unicode const * pSubjectPathBegin
+ = aSubject.m_aAbsURIRef.getStr() + aSubject.m_aPath.getBegin();
+ sal_Unicode const * pSubjectPathEnd
+ = pSubjectPathBegin + aSubject.m_aPath.getLength();
+
+ // Make nMatch point past the last matching slash, or past the end of the
+ // paths, in case they are equal:
+ sal_Unicode const * pSlash = 0;
+ sal_Unicode const * p1 = pBasePathBegin;
+ sal_Unicode const * p2 = pSubjectPathBegin;
+ for (;;)
+ {
+ if (p1 == pBasePathEnd || p2 == pSubjectPathEnd)
+ {
+ if (p1 == pBasePathEnd && p2 == pSubjectPathEnd)
+ pSlash = p1;
+ break;
+ }
+
+ sal_Unicode c = *p1++;
+ if (c != *p2++)
+ break;
+ if (c == '/')
+ pSlash = p1;
+ }
+ if (!pSlash)
+ {
+ // One of the paths does not start with '/':
+ rTheRelURIRef = aSubject.GetMainURL(eDecodeMechanism, eCharset);
+ return false;
+ }
+ sal_Int32 nMatch = pSlash - pBasePathBegin;
+
+ // If the two URLs are DOS file URLs starting with different volumes
+ // (e.g., file:///a:/... and file:///b:/...), the subject is not made
+ // relative (it could be, but some people do not like that):
+ if (m_eScheme == INET_PROT_FILE
+ && nMatch <= 1
+ && hasDosVolume(eStyle)
+ && aSubject.hasDosVolume(eStyle)) //TODO! ok to use eStyle for these?
+ {
+ rTheRelURIRef = aSubject.GetMainURL(eDecodeMechanism, eCharset);
+ return false;
+ }
+
+ // For every slash in the base path after nMatch, a prefix of "../" is
+ // added to the new relative URL (if the common prefix of the two paths is
+ // only "/"---but see handling of file URLs above---, the complete subject
+ // path could go into the new relative URL instead, but some people don't
+ // like that):
+ rtl::OUStringBuffer aSynRelURIRef;
+// if (nMatch <= 1) nMatch = 0; else // see comment above
+ for (sal_Unicode const * p = pBasePathBegin + nMatch; p != pBasePathEnd;
+ ++p)
+ {
+ if (*p == '/')
+ aSynRelURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("../"));
+ }
+
+ // If the new relative URL would start with "//" (i.e., it would be
+ // mistaken for a relative URL starting with an authority part), or if the
+ // new relative URL would neither be empty nor start with <"/"> nor start
+ // with <1*rseg> (i.e., it could be mistaken for an absolute URL starting
+ // with a scheme part), then the new relative URL is prefixed with "./":
+ if (aSynRelURIRef.getLength() == 0)
+ {
+ if (pSubjectPathEnd - pSubjectPathBegin >= nMatch + 2
+ && pSubjectPathBegin[nMatch] == '/'
+ && pSubjectPathBegin[nMatch + 1] == '/')
+ {
+ aSynRelURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("./"));
+ }
+ else
+ {
+ for (sal_Unicode const * p = pSubjectPathBegin + nMatch;
+ p != pSubjectPathEnd && *p != '/'; ++p)
+ {
+ if (mustEncode(*p, PART_REL_SEGMENT_EXTRA))
+ {
+ aSynRelURIRef.
+ appendAscii(RTL_CONSTASCII_STRINGPARAM("./"));
+ break;
+ }
+ }
+ }
+ }
+
+ // The remainder of the subject path, starting at nMatch, is appended to
+ // the new relative URL:
+ sal_Char cEscapePrefix = getEscapePrefix();
+ aSynRelURIRef.append(decode(pSubjectPathBegin + nMatch, pSubjectPathEnd,
+ cEscapePrefix, eDecodeMechanism, eCharset));
+
+ // If the subject has defined query or fragment parts, they are appended
+ // to the new relative URL:
+ if (aSubject.m_aQuery.isPresent())
+ {
+ aSynRelURIRef.append(sal_Unicode('?'));
+ aSynRelURIRef.append(aSubject.decode(aSubject.m_aQuery, cEscapePrefix,
+ eDecodeMechanism, eCharset));
+ }
+ if (aSubject.m_aFragment.isPresent())
+ {
+ aSynRelURIRef.append(sal_Unicode('#'));
+ aSynRelURIRef.append(aSubject.decode(aSubject.m_aFragment,
+ cEscapePrefix, eDecodeMechanism, eCharset));
+ }
+
+ rTheRelURIRef = aSynRelURIRef.makeStringAndClear();
+ return true;
+}
+
+//============================================================================
+// static
+bool INetURLObject::convertIntToExt(rtl::OUString const & rTheIntURIRef,
+ bool bOctets, rtl::OUString & rTheExtURIRef,
+ DecodeMechanism eDecodeMechanism,
+ rtl_TextEncoding eCharset)
+{
+ sal_Char cEscapePrefix
+ = getEscapePrefix(CompareProtocolScheme(rTheIntURIRef));
+ rtl::OUString aSynExtURIRef(encodeText(rTheIntURIRef, bOctets, PART_VISIBLE,
+ cEscapePrefix, NOT_CANONIC, eCharset,
+ true));
+ sal_Unicode const * pBegin = aSynExtURIRef.getStr();
+ sal_Unicode const * pEnd = pBegin + aSynExtURIRef.getLength();
+ sal_Unicode const * p = pBegin;
+ PrefixInfo const * pPrefix = getPrefix(p, pEnd);
+ bool bConvert = pPrefix && pPrefix->m_eKind == PrefixInfo::INTERNAL;
+ if (bConvert)
+ {
+ aSynExtURIRef =
+ aSynExtURIRef.replaceAt(0, p - pBegin,
+ rtl::OUString::createFromAscii(pPrefix->m_pTranslatedPrefix));
+ }
+ rTheExtURIRef = decode(aSynExtURIRef, cEscapePrefix, eDecodeMechanism,
+ eCharset);
+ return bConvert;
+}
+
+//============================================================================
+// static
+bool INetURLObject::convertExtToInt(rtl::OUString const & rTheExtURIRef,
+ bool bOctets, rtl::OUString & rTheIntURIRef,
+ DecodeMechanism eDecodeMechanism,
+ rtl_TextEncoding eCharset)
+{
+ sal_Char cEscapePrefix
+ = getEscapePrefix(CompareProtocolScheme(rTheExtURIRef));
+ rtl::OUString aSynIntURIRef(encodeText(rTheExtURIRef, bOctets, PART_VISIBLE,
+ cEscapePrefix, NOT_CANONIC, eCharset,
+ true));
+ sal_Unicode const * pBegin = aSynIntURIRef.getStr();
+ sal_Unicode const * pEnd = pBegin + aSynIntURIRef.getLength();
+ sal_Unicode const * p = pBegin;
+ PrefixInfo const * pPrefix = getPrefix(p, pEnd);
+ bool bConvert = pPrefix && pPrefix->m_eKind == PrefixInfo::EXTERNAL;
+ if (bConvert)
+ {
+ aSynIntURIRef =
+ aSynIntURIRef.replaceAt(0, p - pBegin,
+ rtl::OUString::createFromAscii(pPrefix->m_pTranslatedPrefix));
+ }
+ rTheIntURIRef = decode(aSynIntURIRef, cEscapePrefix, eDecodeMechanism,
+ eCharset);
+ return bConvert;
+}
+
+//============================================================================
+// static
+INetURLObject::PrefixInfo const *
+INetURLObject::getPrefix(sal_Unicode const *& rBegin,
+ sal_Unicode const * pEnd)
+{
+ static PrefixInfo const aMap[]
+ = { // dummy entry at front needed, because pLast may point here:
+ { 0, 0, INET_PROT_NOT_VALID, PrefixInfo::INTERNAL },
+ { ".component:", "staroffice.component:", INET_PROT_COMPONENT,
+ PrefixInfo::INTERNAL },
+ { ".uno:", "staroffice.uno:", INET_PROT_UNO,
+ PrefixInfo::INTERNAL },
+ { "cid:", 0, INET_PROT_CID, PrefixInfo::OFFICIAL },
+ { "data:", 0, INET_PROT_DATA, PrefixInfo::OFFICIAL },
+ { "db:", "staroffice.db:", INET_PROT_DB, PrefixInfo::INTERNAL },
+ { "file:", 0, INET_PROT_FILE, PrefixInfo::OFFICIAL },
+ { "ftp:", 0, INET_PROT_FTP, PrefixInfo::OFFICIAL },
+ { "http:", 0, INET_PROT_HTTP, PrefixInfo::OFFICIAL },
+ { "https:", 0, INET_PROT_HTTPS, PrefixInfo::OFFICIAL },
+ { "imap:", 0, INET_PROT_IMAP, PrefixInfo::OFFICIAL },
+ { "javascript:", 0, INET_PROT_JAVASCRIPT, PrefixInfo::OFFICIAL },
+ { "ldap:", 0, INET_PROT_LDAP, PrefixInfo::OFFICIAL },
+ { "macro:", "staroffice.macro:", INET_PROT_MACRO,
+ PrefixInfo::INTERNAL },
+ { "mailto:", 0, INET_PROT_MAILTO, PrefixInfo::OFFICIAL },
+ { "news:", 0, INET_PROT_NEWS, PrefixInfo::OFFICIAL },
+ { "out:", "staroffice.out:", INET_PROT_OUT,
+ PrefixInfo::INTERNAL },
+ { "pop3:", "staroffice.pop3:", INET_PROT_POP3,
+ PrefixInfo::INTERNAL },
+ { "private:", "staroffice.private:", INET_PROT_PRIV_SOFFICE,
+ PrefixInfo::INTERNAL },
+ { "private:factory/", "staroffice.factory:",
+ INET_PROT_PRIV_SOFFICE, PrefixInfo::INTERNAL },
+ { "private:helpid/", "staroffice.helpid:", INET_PROT_PRIV_SOFFICE,
+ PrefixInfo::INTERNAL },
+ { "private:java/", "staroffice.java:", INET_PROT_PRIV_SOFFICE,
+ PrefixInfo::INTERNAL },
+ { "private:searchfolder:", "staroffice.searchfolder:",
+ INET_PROT_PRIV_SOFFICE, PrefixInfo::INTERNAL },
+ { "private:trashcan:", "staroffice.trashcan:",
+ INET_PROT_PRIV_SOFFICE, PrefixInfo::INTERNAL },
+ { "slot:", "staroffice.slot:", INET_PROT_SLOT,
+ PrefixInfo::INTERNAL },
+ { "smb:", 0, INET_PROT_SMB, PrefixInfo::OFFICIAL },
+ { "staroffice.component:", ".component:", INET_PROT_COMPONENT,
+ PrefixInfo::EXTERNAL },
+ { "staroffice.db:", "db:", INET_PROT_DB, PrefixInfo::EXTERNAL },
+ { "staroffice.factory:", "private:factory/",
+ INET_PROT_PRIV_SOFFICE, PrefixInfo::EXTERNAL },
+ { "staroffice.helpid:", "private:helpid/", INET_PROT_PRIV_SOFFICE,
+ PrefixInfo::EXTERNAL },
+ { "staroffice.java:", "private:java/", INET_PROT_PRIV_SOFFICE,
+ PrefixInfo::EXTERNAL },
+ { "staroffice.macro:", "macro:", INET_PROT_MACRO,
+ PrefixInfo::EXTERNAL },
+ { "staroffice.out:", "out:", INET_PROT_OUT,
+ PrefixInfo::EXTERNAL },
+ { "staroffice.pop3:", "pop3:", INET_PROT_POP3,
+ PrefixInfo::EXTERNAL },
+ { "staroffice.private:", "private:", INET_PROT_PRIV_SOFFICE,
+ PrefixInfo::EXTERNAL },
+ { "staroffice.searchfolder:", "private:searchfolder:",
+ INET_PROT_PRIV_SOFFICE, PrefixInfo::EXTERNAL },
+ { "staroffice.slot:", "slot:", INET_PROT_SLOT,
+ PrefixInfo::EXTERNAL },
+ { "staroffice.trashcan:", "private:trashcan:",
+ INET_PROT_PRIV_SOFFICE, PrefixInfo::EXTERNAL },
+ { "staroffice.uno:", ".uno:", INET_PROT_UNO,
+ PrefixInfo::EXTERNAL },
+ { "staroffice.vim:", "vim:", INET_PROT_VIM,
+ PrefixInfo::EXTERNAL },
+ { "staroffice:", "private:", INET_PROT_PRIV_SOFFICE,
+ PrefixInfo::EXTERNAL },
+ { "telnet:", 0, INET_PROT_TELNET, PrefixInfo::OFFICIAL },
+ { "vim:", "staroffice.vim:", INET_PROT_VIM,
+ PrefixInfo::INTERNAL },
+ { "vnd.sun.star.cmd:", 0, INET_PROT_VND_SUN_STAR_CMD,
+ PrefixInfo::OFFICIAL },
+ { "vnd.sun.star.expand:", 0, INET_PROT_VND_SUN_STAR_EXPAND,
+ PrefixInfo::OFFICIAL },
+ { "vnd.sun.star.help:", 0, INET_PROT_VND_SUN_STAR_HELP,
+ PrefixInfo::OFFICIAL },
+ { "vnd.sun.star.hier:", 0, INET_PROT_VND_SUN_STAR_HIER,
+ PrefixInfo::OFFICIAL },
+ { "vnd.sun.star.odma:", 0, INET_PROT_VND_SUN_STAR_ODMA,
+ PrefixInfo::OFFICIAL },
+ { "vnd.sun.star.pkg:", 0, INET_PROT_VND_SUN_STAR_PKG,
+ PrefixInfo::OFFICIAL },
+ { "vnd.sun.star.tdoc:", 0, INET_PROT_VND_SUN_STAR_TDOC,
+ PrefixInfo::OFFICIAL },
+ { "vnd.sun.star.webdav:", 0, INET_PROT_VND_SUN_STAR_WEBDAV,
+ PrefixInfo::OFFICIAL } };
+ PrefixInfo const * pFirst = aMap + 1;
+ PrefixInfo const * pLast = aMap + sizeof aMap / sizeof (PrefixInfo) - 1;
+ PrefixInfo const * pMatch = 0;
+ sal_Unicode const * pMatched = rBegin;
+ sal_Unicode const * p = rBegin;
+ sal_Int32 i = 0;
+ for (; pFirst < pLast; ++i)
+ {
+ if (pFirst->m_pPrefix[i] == '\0')
+ {
+ pMatch = pFirst++;
+ pMatched = p;
+ }
+ if (p >= pEnd)
+ break;
+ sal_uInt32 nChar = INetMIME::toLowerCase(*p++);
+ while (pFirst <= pLast && sal_uChar(pFirst->m_pPrefix[i]) < nChar)
+ ++pFirst;
+ while (pFirst <= pLast && sal_uChar(pLast->m_pPrefix[i]) > nChar)
+ --pLast;
+ }
+ if (pFirst == pLast)
+ {
+ sal_Char const * q = pFirst->m_pPrefix + i;
+ while (p < pEnd && *q != '\0'
+ && INetMIME::toLowerCase(*p) == sal_uChar(*q))
+ {
+ ++p;
+ ++q;
+ }
+ if (*q == '\0')
+ {
+ rBegin = p;
+ return pFirst;
+ }
+ }
+ rBegin = pMatched;
+ return pMatch;
+}
+
+//============================================================================
+sal_Int32 INetURLObject::getAuthorityBegin() const
+{
+ DBG_ASSERT(getSchemeInfo().m_bAuthority,
+ "INetURLObject::getAuthority(): Bad scheme");
+ sal_Int32 nBegin;
+ if (m_aUser.isPresent())
+ nBegin = m_aUser.getBegin();
+ else if (m_aHost.isPresent())
+ nBegin = m_aHost.getBegin();
+ else
+ nBegin = m_aPath.getBegin();
+ nBegin -= RTL_CONSTASCII_LENGTH("//");
+ DBG_ASSERT(m_aAbsURIRef.charAt(nBegin) == '/'
+ && m_aAbsURIRef.charAt(nBegin + 1) == '/',
+ "INetURLObject::getAuthority(): Bad authority");
+ return nBegin;
+}
+
+//============================================================================
+INetURLObject::SubString INetURLObject::getAuthority() const
+{
+ sal_Int32 nBegin = getAuthorityBegin();
+ sal_Int32 nEnd = m_aPort.isPresent() ? m_aPort.getEnd() :
+ m_aHost.isPresent() ? m_aHost.getEnd() :
+ m_aAuth.isPresent() ? m_aAuth.getEnd() :
+ m_aUser.isPresent() ? m_aUser.getEnd() :
+ nBegin + RTL_CONSTASCII_LENGTH("//");
+ return SubString(nBegin, nEnd - nBegin);
+}
+
+//============================================================================
+bool INetURLObject::setUser(rtl::OUString const & rTheUser,
+ bool bOctets, EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ if (
+ !getSchemeInfo().m_bUser ||
+ (m_eScheme == INET_PROT_IMAP && rTheUser.getLength() == 0)
+ )
+ {
+ return false;
+ }
+
+ rtl::OUString aNewUser(encodeText(rTheUser, bOctets,
+ m_eScheme == INET_PROT_IMAP ?
+ PART_IMAP_ACHAR :
+ m_eScheme == INET_PROT_VIM ?
+ PART_VIM :
+ PART_USER_PASSWORD,
+ getEscapePrefix(), eMechanism, eCharset,
+ false));
+ sal_Int32 nDelta;
+ if (m_aUser.isPresent())
+ nDelta = m_aUser.set(m_aAbsURIRef, aNewUser);
+ else if (m_aHost.isPresent())
+ {
+ m_aAbsURIRef.insert(m_aHost.getBegin(), sal_Unicode('@'));
+ nDelta = m_aUser.set(m_aAbsURIRef, aNewUser, m_aHost.getBegin()) + 1;
+ }
+ else if (getSchemeInfo().m_bHost)
+ return false;
+ else
+ nDelta = m_aUser.set(m_aAbsURIRef, aNewUser, m_aPath.getBegin());
+ m_aAuth += nDelta;
+ m_aHost += nDelta;
+ m_aPort += nDelta;
+ m_aPath += nDelta;
+ m_aQuery += nDelta;
+ m_aFragment += nDelta;
+ return true;
+}
+
+namespace
+{
+ void lcl_Erase(rtl::OUStringBuffer &rBuf, sal_Int32 index, sal_Int32 count)
+ {
+ rtl::OUString sTemp(rBuf.makeStringAndClear());
+ rBuf.append(sTemp.replaceAt(index, count, rtl::OUString()));
+ }
+}
+
+//============================================================================
+bool INetURLObject::clearPassword()
+{
+ if (!getSchemeInfo().m_bPassword)
+ return false;
+ if (m_aAuth.isPresent())
+ {
+ lcl_Erase(m_aAbsURIRef, m_aAuth.getBegin() - 1,
+ m_aAuth.getLength() + 1);
+ sal_Int32 nDelta = m_aAuth.clear() - 1;
+ m_aHost += nDelta;
+ m_aPort += nDelta;
+ m_aPath += nDelta;
+ m_aQuery += nDelta;
+ m_aFragment += nDelta;
+ }
+ return true;
+}
+
+//============================================================================
+bool INetURLObject::setPassword(rtl::OUString const & rThePassword,
+ bool bOctets, EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ if (!getSchemeInfo().m_bPassword)
+ return false;
+ rtl::OUString aNewAuth(encodeText(rThePassword, bOctets,
+ m_eScheme == INET_PROT_VIM ?
+ PART_VIM : PART_USER_PASSWORD,
+ getEscapePrefix(), eMechanism, eCharset,
+ false));
+ sal_Int32 nDelta;
+ if (m_aAuth.isPresent())
+ nDelta = m_aAuth.set(m_aAbsURIRef, aNewAuth);
+ else if (m_aUser.isPresent())
+ {
+ m_aAbsURIRef.insert(m_aUser.getEnd(), sal_Unicode(':'));
+ nDelta
+ = m_aAuth.set(m_aAbsURIRef, aNewAuth, m_aUser.getEnd() + 1) + 1;
+ }
+ else if (m_aHost.isPresent())
+ {
+ m_aAbsURIRef.insert(m_aHost.getBegin(),
+ rtl::OUString::createFromAscii(":@"));
+ m_aUser.set(m_aAbsURIRef, rtl::OUString(), m_aHost.getBegin());
+ nDelta
+ = m_aAuth.set(m_aAbsURIRef, aNewAuth, m_aHost.getBegin() + 1) + 2;
+ }
+ else if (getSchemeInfo().m_bHost)
+ return false;
+ else
+ {
+ m_aAbsURIRef.insert(m_aPath.getBegin(), sal_Unicode(':'));
+ m_aUser.set(m_aAbsURIRef, rtl::OUString(), m_aPath.getBegin());
+ nDelta
+ = m_aAuth.set(m_aAbsURIRef, aNewAuth, m_aPath.getBegin() + 1) + 1;
+ }
+ m_aHost += nDelta;
+ m_aPort += nDelta;
+ m_aPath += nDelta;
+ m_aQuery += nDelta;
+ m_aFragment += nDelta;
+ return true;
+}
+
+//============================================================================
+// static
+bool INetURLObject::parseHost(
+ sal_Unicode const *& rBegin, sal_Unicode const * pEnd,
+ rtl::OUString & rCanonic)
+{
+ // RFC 2373 is inconsistent about how to write an IPv6 address in which an
+ // IPv4 address directly follows the abbreviating "::". The ABNF in
+ // Appendix B suggests ":::13.1.68.3", while an example in 2.2/3 explicitly
+ // mentions "::13:1.68.3". This algorithm accepts both variants:
+ enum State { STATE_INITIAL, STATE_LABEL, STATE_LABEL_HYPHEN,
+ STATE_LABEL_DOT, STATE_TOPLABEL, STATE_TOPLABEL_HYPHEN,
+ STATE_TOPLABEL_DOT, STATE_IP4, STATE_IP4_DOT, STATE_IP6,
+ STATE_IP6_COLON, STATE_IP6_2COLON, STATE_IP6_3COLON,
+ STATE_IP6_HEXSEQ1, STATE_IP6_HEXSEQ1_COLON,
+ STATE_IP6_HEXSEQ1_MAYBE_IP4, STATE_IP6_HEXSEQ2,
+ STATE_IP6_HEXSEQ2_COLON, STATE_IP6_HEXSEQ2_MAYBE_IP4,
+ STATE_IP6_IP4, STATE_IP6_IP4_DOT, STATE_IP6_DONE };
+ rtl::OUStringBuffer aTheCanonic;
+ sal_uInt32 nNumber = 0;
+ int nDigits = 0;
+ int nOctets = 0;
+ State eState = STATE_INITIAL;
+ sal_Unicode const * p = rBegin;
+ for (; p != pEnd; ++p)
+ switch (eState)
+ {
+ case STATE_INITIAL:
+ if (*p == '[')
+ {
+ aTheCanonic.append(sal_Unicode('['));
+ eState = STATE_IP6;
+ }
+ else if (INetMIME::isAlpha(*p) || *p == '_')
+ eState = STATE_TOPLABEL;
+ else if (INetMIME::isDigit(*p))
+ {
+ nNumber = INetMIME::getWeight(*p);
+ nDigits = 1;
+ nOctets = 1;
+ eState = STATE_IP4;
+ }
+ else
+ goto done;
+ break;
+
+ case STATE_LABEL:
+ if (*p == '.')
+ eState = STATE_LABEL_DOT;
+ else if (*p == '-')
+ eState = STATE_LABEL_HYPHEN;
+ else if (!INetMIME::isAlphanumeric(*p) && *p != '_')
+ goto done;
+ break;
+
+ case STATE_LABEL_HYPHEN:
+ if (INetMIME::isAlphanumeric(*p) || *p == '_')
+ eState = STATE_LABEL;
+ else if (*p != '-')
+ goto done;
+ break;
+
+ case STATE_LABEL_DOT:
+ if (INetMIME::isAlpha(*p) || *p == '_')
+ eState = STATE_TOPLABEL;
+ else if (INetMIME::isDigit(*p))
+ eState = STATE_LABEL;
+ else
+ goto done;
+ break;
+
+ case STATE_TOPLABEL:
+ if (*p == '.')
+ eState = STATE_TOPLABEL_DOT;
+ else if (*p == '-')
+ eState = STATE_TOPLABEL_HYPHEN;
+ else if (!INetMIME::isAlphanumeric(*p) && *p != '_')
+ goto done;
+ break;
+
+ case STATE_TOPLABEL_HYPHEN:
+ if (INetMIME::isAlphanumeric(*p) || *p == '_')
+ eState = STATE_TOPLABEL;
+ else if (*p != '-')
+ goto done;
+ break;
+
+ case STATE_TOPLABEL_DOT:
+ if (INetMIME::isAlpha(*p) || *p == '_')
+ eState = STATE_TOPLABEL;
+ else if (INetMIME::isDigit(*p))
+ eState = STATE_LABEL;
+ else
+ goto done;
+ break;
+
+ case STATE_IP4:
+ if (*p == '.')
+ if (nOctets < 4)
+ {
+ aTheCanonic.append(
+ rtl::OUString::valueOf(sal_Int32(nNumber)));
+ aTheCanonic.append(sal_Unicode('.'));
+ ++nOctets;
+ eState = STATE_IP4_DOT;
+ }
+ else
+ eState = STATE_LABEL_DOT;
+ else if (*p == '-')
+ eState = STATE_LABEL_HYPHEN;
+ else if (INetMIME::isAlpha(*p) || *p == '_')
+ eState = STATE_LABEL;
+ else if (INetMIME::isDigit(*p))
+ if (nDigits < 3)
+ {
+ nNumber = 10 * nNumber + INetMIME::getWeight(*p);
+ ++nDigits;
+ }
+ else
+ eState = STATE_LABEL;
+ else
+ goto done;
+ break;
+
+ case STATE_IP4_DOT:
+ if (INetMIME::isAlpha(*p) || *p == '_')
+ eState = STATE_TOPLABEL;
+ else if (INetMIME::isDigit(*p))
+ {
+ nNumber = INetMIME::getWeight(*p);
+ nDigits = 1;
+ eState = STATE_IP4;
+ }
+ else
+ goto done;
+ break;
+
+ case STATE_IP6:
+ if (*p == ':')
+ eState = STATE_IP6_COLON;
+ else if (INetMIME::isHexDigit(*p))
+ {
+ nNumber = INetMIME::getHexWeight(*p);
+ nDigits = 1;
+ eState = STATE_IP6_HEXSEQ1;
+ }
+ else
+ goto done;
+ break;
+
+ case STATE_IP6_COLON:
+ if (*p == ':')
+ {
+ aTheCanonic.appendAscii(RTL_CONSTASCII_STRINGPARAM("::"));
+ eState = STATE_IP6_2COLON;
+ }
+ else
+ goto done;
+ break;
+
+ case STATE_IP6_2COLON:
+ if (*p == ']')
+ eState = STATE_IP6_DONE;
+ else if (*p == ':')
+ {
+ aTheCanonic.append(sal_Unicode(':'));
+ eState = STATE_IP6_3COLON;
+ }
+ else if (INetMIME::isDigit(*p))
+ {
+ nNumber = INetMIME::getWeight(*p);
+ nDigits = 1;
+ eState = STATE_IP6_HEXSEQ2_MAYBE_IP4;
+ }
+ else if (INetMIME::isHexDigit(*p))
+ {
+ nNumber = INetMIME::getHexWeight(*p);
+ nDigits = 1;
+ eState = STATE_IP6_HEXSEQ2;
+ }
+ else
+ goto done;
+ break;
+
+ case STATE_IP6_3COLON:
+ if (INetMIME::isDigit(*p))
+ {
+ nNumber = INetMIME::getWeight(*p);
+ nDigits = 1;
+ nOctets = 1;
+ eState = STATE_IP6_IP4;
+ }
+ else
+ goto done;
+ break;
+
+ case STATE_IP6_HEXSEQ1:
+ if (*p == ']')
+ {
+ aTheCanonic.append(
+ rtl::OUString::valueOf(sal_Int32(nNumber), 16));
+ eState = STATE_IP6_DONE;
+ }
+ else if (*p == ':')
+ {
+ aTheCanonic.append(
+ rtl::OUString::valueOf(sal_Int32(nNumber), 16));
+ aTheCanonic.append(sal_Unicode(':'));
+ eState = STATE_IP6_HEXSEQ1_COLON;
+ }
+ else if (INetMIME::isHexDigit(*p) && nDigits < 4)
+ {
+ nNumber = 16 * nNumber + INetMIME::getHexWeight(*p);
+ ++nDigits;
+ }
+ else
+ goto done;
+ break;
+
+ case STATE_IP6_HEXSEQ1_COLON:
+ if (*p == ':')
+ {
+ aTheCanonic.append(sal_Unicode(':'));
+ eState = STATE_IP6_2COLON;
+ }
+ else if (INetMIME::isDigit(*p))
+ {
+ nNumber = INetMIME::getWeight(*p);
+ nDigits = 1;
+ eState = STATE_IP6_HEXSEQ1_MAYBE_IP4;
+ }
+ else if (INetMIME::isHexDigit(*p))
+ {
+ nNumber = INetMIME::getHexWeight(*p);
+ nDigits = 1;
+ eState = STATE_IP6_HEXSEQ1;
+ }
+ else
+ goto done;
+ break;
+
+ case STATE_IP6_HEXSEQ1_MAYBE_IP4:
+ if (*p == ']')
+ {
+ aTheCanonic.append(
+ rtl::OUString::valueOf(sal_Int32(nNumber), 16));
+ eState = STATE_IP6_DONE;
+ }
+ else if (*p == ':')
+ {
+ aTheCanonic.append(
+ rtl::OUString::valueOf(sal_Int32(nNumber), 16));
+ aTheCanonic.append(sal_Unicode(':'));
+ eState = STATE_IP6_HEXSEQ1_COLON;
+ }
+ else if (*p == '.')
+ {
+ nNumber = 100 * (nNumber >> 8) + 10 * (nNumber >> 4 & 15)
+ + (nNumber & 15);
+ aTheCanonic.append(
+ rtl::OUString::valueOf(sal_Int32(nNumber)));
+ aTheCanonic.append(sal_Unicode('.'));
+ nOctets = 2;
+ eState = STATE_IP6_IP4_DOT;
+ }
+ else if (INetMIME::isDigit(*p) && nDigits < 3)
+ {
+ nNumber = 16 * nNumber + INetMIME::getWeight(*p);
+ ++nDigits;
+ }
+ else if (INetMIME::isHexDigit(*p) && nDigits < 4)
+ {
+ nNumber = 16 * nNumber + INetMIME::getHexWeight(*p);
+ ++nDigits;
+ eState = STATE_IP6_HEXSEQ1;
+ }
+ else
+ goto done;
+ break;
+
+ case STATE_IP6_HEXSEQ2:
+ if (*p == ']')
+ {
+ aTheCanonic.append(
+ rtl::OUString::valueOf(sal_Int32(nNumber), 16));
+ eState = STATE_IP6_DONE;
+ }
+ else if (*p == ':')
+ {
+ aTheCanonic.append(
+ rtl::OUString::valueOf(sal_Int32(nNumber), 16));
+ aTheCanonic.append(sal_Unicode(':'));
+ eState = STATE_IP6_HEXSEQ2_COLON;
+ }
+ else if (INetMIME::isHexDigit(*p) && nDigits < 4)
+ {
+ nNumber = 16 * nNumber + INetMIME::getHexWeight(*p);
+ ++nDigits;
+ }
+ else
+ goto done;
+ break;
+
+ case STATE_IP6_HEXSEQ2_COLON:
+ if (INetMIME::isDigit(*p))
+ {
+ nNumber = INetMIME::getWeight(*p);
+ nDigits = 1;
+ eState = STATE_IP6_HEXSEQ2_MAYBE_IP4;
+ }
+ else if (INetMIME::isHexDigit(*p))
+ {
+ nNumber = INetMIME::getHexWeight(*p);
+ nDigits = 1;
+ eState = STATE_IP6_HEXSEQ2;
+ }
+ else
+ goto done;
+ break;
+
+ case STATE_IP6_HEXSEQ2_MAYBE_IP4:
+ if (*p == ']')
+ {
+ aTheCanonic.append(
+ rtl::OUString::valueOf(sal_Int32(nNumber), 16));
+ eState = STATE_IP6_DONE;
+ }
+ else if (*p == ':')
+ {
+ aTheCanonic.append(
+ rtl::OUString::valueOf(sal_Int32(nNumber), 16));
+ aTheCanonic.append(sal_Unicode(':'));
+ eState = STATE_IP6_HEXSEQ2_COLON;
+ }
+ else if (*p == '.')
+ {
+ nNumber = 100 * (nNumber >> 8) + 10 * (nNumber >> 4 & 15)
+ + (nNumber & 15);
+ aTheCanonic.append(
+ rtl::OUString::valueOf(sal_Int32(nNumber)));
+ aTheCanonic.append(sal_Unicode('.'));
+ nOctets = 2;
+ eState = STATE_IP6_IP4_DOT;
+ }
+ else if (INetMIME::isDigit(*p) && nDigits < 3)
+ {
+ nNumber = 16 * nNumber + INetMIME::getWeight(*p);
+ ++nDigits;
+ }
+ else if (INetMIME::isHexDigit(*p) && nDigits < 4)
+ {
+ nNumber = 16 * nNumber + INetMIME::getHexWeight(*p);
+ ++nDigits;
+ eState = STATE_IP6_HEXSEQ2;
+ }
+ else
+ goto done;
+ break;
+
+ case STATE_IP6_IP4:
+ if (*p == ']')
+ if (nOctets == 4)
+ {
+ aTheCanonic.append(
+ rtl::OUString::valueOf(sal_Int32(nNumber)));
+ eState = STATE_IP6_DONE;
+ }
+ else
+ goto done;
+ else if (*p == '.')
+ if (nOctets < 4)
+ {
+ aTheCanonic.append(
+ rtl::OUString::valueOf(sal_Int32(nNumber)));
+ aTheCanonic.append(sal_Unicode('.'));
+ ++nOctets;
+ eState = STATE_IP6_IP4_DOT;
+ }
+ else
+ goto done;
+ else if (INetMIME::isDigit(*p) && nDigits < 3)
+ {
+ nNumber = 10 * nNumber + INetMIME::getWeight(*p);
+ ++nDigits;
+ }
+ else
+ goto done;
+ break;
+
+ case STATE_IP6_IP4_DOT:
+ if (INetMIME::isDigit(*p))
+ {
+ nNumber = INetMIME::getWeight(*p);
+ nDigits = 1;
+ eState = STATE_IP6_IP4;
+ }
+ else
+ goto done;
+ break;
+
+ case STATE_IP6_DONE:
+ goto done;
+ }
+ done:
+ switch (eState)
+ {
+ case STATE_LABEL:
+ case STATE_TOPLABEL:
+ case STATE_TOPLABEL_DOT:
+ aTheCanonic.setLength(0);
+ aTheCanonic.append(rBegin, p - rBegin);
+ rBegin = p;
+ rCanonic = aTheCanonic.makeStringAndClear();
+ return true;
+
+ case STATE_IP4:
+ if (nOctets == 4)
+ {
+ aTheCanonic.append(
+ rtl::OUString::valueOf(sal_Int32(nNumber)));
+ rBegin = p;
+ rCanonic = aTheCanonic.makeStringAndClear();
+ return true;
+ }
+ return false;
+
+ case STATE_IP6_DONE:
+ aTheCanonic.append(sal_Unicode(']'));
+ rBegin = p;
+ rCanonic = aTheCanonic.makeStringAndClear();
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+//============================================================================
+// static
+bool INetURLObject::parseHostOrNetBiosName(
+ sal_Unicode const * pBegin, sal_Unicode const * pEnd, bool bOctets,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset, bool bNetBiosName,
+ rtl::OUStringBuffer* pCanonic)
+{
+ rtl::OUString aTheCanonic;
+ if (pBegin < pEnd)
+ {
+ sal_Unicode const * p = pBegin;
+ if (!parseHost(p, pEnd, aTheCanonic) || p != pEnd)
+ {
+ if (bNetBiosName)
+ {
+ rtl::OUStringBuffer buf;
+ while (pBegin < pEnd)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pBegin, pEnd, bOctets, '%',
+ eMechanism, eCharset,
+ eEscapeType);
+ if (!INetMIME::isVisible(nUTF32))
+ return false;
+ if (!INetMIME::isAlphanumeric(nUTF32))
+ switch (nUTF32)
+ {
+ case '"':
+ case '*':
+ case '+':
+ case ',':
+ case '/':
+ case ':':
+ case ';':
+ case '<':
+ case '=':
+ case '>':
+ case '?':
+ case '[':
+ case '\\':
+ case ']':
+ case '`':
+ case '|':
+ return false;;
+ }
+ if (pCanonic != NULL) {
+ appendUCS4(
+ buf, nUTF32, eEscapeType, bOctets, PART_URIC, '%',
+ eCharset, true);
+ }
+ }
+ aTheCanonic = buf.makeStringAndClear();
+ }
+ else
+ return false;
+ }
+ }
+ if (pCanonic != NULL) {
+ *pCanonic = aTheCanonic;
+ }
+ return true;
+}
+
+//============================================================================
+// static
+rtl::OUString INetURLObject::encodeHostPort(rtl::OUString const & rTheHostPort,
+ bool bOctets,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ sal_Int32 nPort = rTheHostPort.getLength();
+ if (nPort != 0)
+ {
+ sal_Int32 i = nPort - 1;
+ while (i != 0 && INetMIME::isDigit(rTheHostPort.getStr()[i]))
+ --i;
+ if (rTheHostPort.getStr()[i] == ':')
+ nPort = i;
+ }
+ rtl::OUString aResult(encodeText(rTheHostPort.copy(0, nPort), bOctets,
+ PART_HOST_EXTRA, '%', eMechanism, eCharset,
+ true));
+ aResult += rTheHostPort.copy(nPort);
+ return aResult;
+}
+
+//============================================================================
+bool INetURLObject::setHost(rtl::OUString const & rTheHost, bool bOctets,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ if (!getSchemeInfo().m_bHost)
+ return false;
+ rtl::OUStringBuffer aSynHost(rTheHost);
+ bool bNetBiosName = false;
+ switch (m_eScheme)
+ {
+ case INET_PROT_FILE:
+ {
+ rtl::OUString sTemp(aSynHost);
+ if (sTemp.equalsIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("localhost")))
+ {
+ aSynHost.setLength(0);
+ }
+ bNetBiosName = true;
+ }
+ break;
+ case INET_PROT_LDAP:
+ if (aSynHost.getLength() == 0 && m_aPort.isPresent())
+ return false;
+ break;
+
+ default:
+ if (aSynHost.getLength() == 0)
+ return false;
+ break;
+ }
+ if (!parseHostOrNetBiosName(
+ aSynHost.getStr(), aSynHost.getStr() + aSynHost.getLength(),
+ bOctets, eMechanism, eCharset, bNetBiosName, &aSynHost))
+ return false;
+ sal_Int32 nDelta = m_aHost.set(m_aAbsURIRef, aSynHost.makeStringAndClear());
+ m_aPort += nDelta;
+ m_aPath += nDelta;
+ m_aQuery += nDelta;
+ m_aFragment += nDelta;
+ return true;
+}
+
+//============================================================================
+// static
+bool INetURLObject::parsePath(INetProtocol eScheme,
+ sal_Unicode const ** pBegin,
+ sal_Unicode const * pEnd,
+ bool bOctets,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ bool bSkippedInitialSlash,
+ sal_uInt32 nSegmentDelimiter,
+ sal_uInt32 nAltSegmentDelimiter,
+ sal_uInt32 nQueryDelimiter,
+ sal_uInt32 nFragmentDelimiter,
+ rtl::OUStringBuffer &rSynPath)
+{
+ DBG_ASSERT(pBegin, "INetURLObject::parsePath(): Null output param");
+
+ sal_Unicode const * pPos = *pBegin;
+ rtl::OUStringBuffer aTheSynPath;
+
+ switch (eScheme)
+ {
+ case INET_PROT_NOT_VALID:
+ return false;
+
+ case INET_PROT_FTP:
+ case INET_PROT_IMAP:
+ if (pPos < pEnd && *pPos != '/')
+ return false;
+ while (pPos < pEnd && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+ '%', eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
+ PART_HTTP_PATH, '%', eCharset, true);
+ }
+ if (aTheSynPath.getLength() == 0)
+ aTheSynPath.append(sal_Unicode('/'));
+ break;
+
+ case INET_PROT_HTTP:
+ case INET_PROT_VND_SUN_STAR_WEBDAV:
+ case INET_PROT_HTTPS:
+ case INET_PROT_SMB:
+ if (pPos < pEnd && *pPos != '/')
+ return false;
+ while (pPos < pEnd && *pPos != nQueryDelimiter
+ && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+ '%', eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
+ PART_HTTP_PATH, '%', eCharset, true);
+ }
+ if (aTheSynPath.getLength() == 0)
+ aTheSynPath.append(sal_Unicode('/'));
+ break;
+
+ case INET_PROT_FILE:
+ {
+ if (bSkippedInitialSlash)
+ aTheSynPath.append(sal_Unicode('/'));
+ else if (pPos < pEnd
+ && *pPos != nSegmentDelimiter
+ && *pPos != nAltSegmentDelimiter)
+ return false;
+ while (pPos < pEnd && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+ '%', eMechanism,
+ eCharset, eEscapeType);
+ if (eEscapeType == ESCAPE_NO)
+ {
+ if (nUTF32 == nSegmentDelimiter
+ || nUTF32 == nAltSegmentDelimiter)
+ {
+ aTheSynPath.append(sal_Unicode('/'));
+ continue;
+ }
+ else if (nUTF32 == '|'
+ && (pPos == pEnd
+ || *pPos == nFragmentDelimiter
+ || *pPos == nSegmentDelimiter
+ || *pPos == nAltSegmentDelimiter)
+ && aTheSynPath.getLength() == 2
+ && INetMIME::isAlpha(aTheSynPath.charAt(1)))
+ {
+ // A first segment of <ALPHA "|"> is translated to
+ // <ALPHA ":">:
+ aTheSynPath.append(sal_Unicode(':'));
+ continue;
+ }
+ }
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
+ PART_PCHAR, '%', eCharset, true);
+ }
+ if (aTheSynPath.getLength() == 0)
+ aTheSynPath.append(sal_Unicode('/'));
+ break;
+ }
+
+ case INET_PROT_MAILTO:
+ while (pPos < pEnd && *pPos != nQueryDelimiter
+ && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+ '%', eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
+ PART_MAILTO, '%', eCharset, true);
+ }
+ break;
+
+ case INET_PROT_NEWS:
+ if (pPos == pEnd || *pPos == nQueryDelimiter
+ || *pPos == nFragmentDelimiter)
+ return false;
+
+ // Match <"*">:
+ if (*pPos == '*'
+ && (pEnd - pPos == 1 || pPos[1] == nQueryDelimiter
+ || pPos[1] == nFragmentDelimiter))
+ {
+ ++pPos;
+ aTheSynPath.append(sal_Unicode('*'));
+ break;
+ }
+
+ // Match <group>:
+ if (INetMIME::isAlpha(*pPos))
+ for (sal_Unicode const * p = pPos + 1;; ++p)
+ if (p == pEnd || *p == nQueryDelimiter
+ || *p == nFragmentDelimiter)
+ {
+ aTheSynPath.setLength(0);
+ aTheSynPath.append(pPos, p - pPos);
+ pPos = p;
+ goto done;
+ }
+ else if (!INetMIME::isAlphanumeric(*p) && *p != '+'
+ && *p != '-' && *p != '.' && *p != '_')
+ break;
+
+ // Match <article>:
+ for (;;)
+ {
+ if (pPos == pEnd || *pPos == nQueryDelimiter
+ || *pPos == nFragmentDelimiter)
+ return false;
+ if (*pPos == '@')
+ break;
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets, '%',
+ eMechanism, eCharset, eEscapeType);
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
+ PART_NEWS_ARTICLE_LOCALPART, '%', eCharset, true);
+ }
+ if (aTheSynPath.getLength() == 0)
+ return false;
+ ++pPos;
+ aTheSynPath.append(sal_Unicode('@'));
+ {
+ sal_Unicode const * p = pPos;
+ while (p < pEnd && *pPos != nQueryDelimiter
+ && *pPos != nFragmentDelimiter)
+ ++p;
+ rtl::OUString aCanonic;
+ if (!parseHost(pPos, p, aCanonic))
+ return false;
+ aTheSynPath.append(aCanonic);
+ }
+
+ done:
+ break;
+
+ case INET_PROT_POP3:
+ while (pPos < pEnd && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+ '%', eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
+ PART_MESSAGE_ID_PATH, '%', eCharset,
+ true);
+ }
+ break;
+
+ case INET_PROT_PRIV_SOFFICE:
+ case INET_PROT_SLOT:
+ case INET_PROT_MACRO:
+ case INET_PROT_UNO:
+ case INET_PROT_COMPONENT:
+ case INET_PROT_LDAP:
+ while (pPos < pEnd && *pPos != nQueryDelimiter
+ && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+ '%', eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
+ PART_PATH_BEFORE_QUERY, '%', eCharset,
+ true);
+ }
+ break;
+
+ case INET_PROT_VND_SUN_STAR_HELP:
+ if (pPos == pEnd
+ || *pPos == nQueryDelimiter
+ || *pPos == nFragmentDelimiter)
+ aTheSynPath.append(sal_Unicode('/'));
+ else
+ {
+ if (*pPos != '/')
+ return false;
+ while (pPos < pEnd && *pPos != nQueryDelimiter
+ && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+ '%', eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
+ PART_HTTP_PATH, '%', eCharset, true);
+ }
+ }
+ break;
+
+ case INET_PROT_JAVASCRIPT:
+ case INET_PROT_DATA:
+ case INET_PROT_CID:
+ case INET_PROT_DB:
+ while (pPos < pEnd && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+ '%', eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
+ PART_URIC, '%', eCharset, true);
+ }
+ break;
+
+ case INET_PROT_OUT:
+ if (pEnd - pPos < 2 || *pPos++ != '/' || *pPos++ != '~')
+ return false;
+ aTheSynPath.appendAscii(RTL_CONSTASCII_STRINGPARAM("/~"));
+ while (pPos < pEnd && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+ '%', eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
+ PART_URIC, '%', eCharset, true);
+ }
+ break;
+
+ case INET_PROT_VND_SUN_STAR_HIER:
+ case INET_PROT_VND_SUN_STAR_PKG:
+ if (pPos < pEnd && *pPos != '/'
+ && *pPos != nQueryDelimiter && *pPos != nFragmentDelimiter)
+ return false;
+ while (pPos < pEnd && *pPos != nQueryDelimiter
+ && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+ '%', eMechanism,
+ eCharset, eEscapeType);
+ if (eEscapeType == ESCAPE_NO && nUTF32 == '/')
+ aTheSynPath.append(sal_Unicode('/'));
+ else
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
+ PART_PCHAR, '%', eCharset, false);
+ }
+ if (aTheSynPath.getLength() == 0)
+ aTheSynPath.append(sal_Unicode('/'));
+ break;
+
+ case INET_PROT_VIM:
+ {
+/* test had to be taken out to make parsePath static; ok since INET_PROT_VIM is
+ obsolete, anyway
+ if (m_aUser.isEmpty())
+ return false;
+*/
+ sal_Unicode const * pPathEnd = pPos;
+ while (pPathEnd < pEnd && *pPathEnd != nFragmentDelimiter)
+ ++pPathEnd;
+ aTheSynPath.append(sal_Unicode('/'));
+ if (pPos == pPathEnd)
+ break;
+ else if (*pPos++ != '/')
+ return false;
+ if (pPos == pPathEnd)
+ break;
+ while (pPos < pPathEnd && *pPos != '/')
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pPathEnd, bOctets,
+ '=', eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aTheSynPath,
+ eEscapeType == ESCAPE_NO ?
+ INetMIME::toLowerCase(nUTF32) : nUTF32,
+ eEscapeType, bOctets, PART_VIM, '=',
+ eCharset, false);
+ }
+ bool bInbox;
+ rtl::OUString sCompare(aTheSynPath);
+ if (sCompare.equalsAscii("/inbox"))
+ bInbox = true;
+ else if (sCompare.equalsAscii("/newsgroups"))
+ bInbox = false;
+ else
+ return false;
+ aTheSynPath.append(sal_Unicode('/'));
+ if (pPos == pPathEnd)
+ break;
+ else if (*pPos++ != '/')
+ return false;
+ if (!bInbox)
+ {
+ bool bEmpty = true;
+ while (pPos < pPathEnd && *pPos != '/')
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pPathEnd, bOctets,
+ '=', eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
+ PART_VIM, '=', eCharset, false);
+ bEmpty = false;
+ }
+ if (bEmpty)
+ return false;
+ aTheSynPath.append(sal_Unicode('/'));
+ if (pPos == pPathEnd)
+ break;
+ else if (*pPos++ != '/')
+ return false;
+ }
+ bool bEmpty = true;
+ while (pPos < pPathEnd && *pPos != ':')
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pPathEnd, bOctets,
+ '=', eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
+ PART_VIM, '=', eCharset, false);
+ bEmpty = false;
+ }
+ if (bEmpty)
+ return false;
+ if (pPos == pPathEnd)
+ break;
+ else if (*pPos++ != ':')
+ return false;
+ aTheSynPath.append(sal_Unicode(':'));
+ for (int i = 0; i < 3; ++i)
+ {
+ if (i != 0)
+ {
+ if (pPos == pPathEnd || *pPos++ != '.')
+ return false;
+ aTheSynPath.append(sal_Unicode('.'));
+ }
+ bEmpty = true;
+ while (pPos < pPathEnd && *pPos != '.')
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pPathEnd, bOctets,
+ '=', eMechanism,
+ eCharset, eEscapeType);
+ if (!INetMIME::isDigit(nUTF32))
+ return false;
+ aTheSynPath.append(sal_Unicode(nUTF32));
+ bEmpty = false;
+ }
+ if (bEmpty)
+ return false;
+ }
+ if (pPos != pPathEnd)
+ return false;
+ break;
+ }
+
+ case INET_PROT_VND_SUN_STAR_CMD:
+ case INET_PROT_VND_SUN_STAR_EXPAND:
+ {
+ if (pPos == pEnd || *pPos == nFragmentDelimiter)
+ return false;
+ Part ePart = PART_URIC_NO_SLASH;
+ while (pPos != pEnd && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+ '%', eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets, ePart,
+ '%', eCharset, true);
+ ePart = PART_URIC;
+ }
+ break;
+ }
+
+ case INET_PROT_VND_SUN_STAR_ODMA:
+ if (pPos < pEnd)
+ {
+ if (*pPos == '/')
+ ++pPos;
+ else
+ return false;
+ }
+ aTheSynPath.append(sal_Unicode('/'));
+ while (pPos < pEnd && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+ '%', eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
+ PART_URIC_NO_SLASH, '%', eCharset, true);
+ }
+ break;
+
+ case INET_PROT_TELNET:
+ if (pPos < pEnd)
+ {
+ if (*pPos != '/' || pEnd - pPos > 1)
+ return false;
+ ++pPos;
+ }
+ aTheSynPath.append(sal_Unicode('/'));
+ break;
+
+ case INET_PROT_VND_SUN_STAR_TDOC:
+ if (pPos == pEnd || *pPos != '/')
+ return false;
+ while (pPos < pEnd && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+ '%', eMechanism,
+ eCharset, eEscapeType);
+ if (eEscapeType == ESCAPE_NO && nUTF32 == '/')
+ aTheSynPath.append(sal_Unicode('/'));
+ else
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
+ PART_PCHAR, '%', eCharset, false);
+ }
+ break;
+
+ case INET_PROT_GENERIC:
+ while (pPos < pEnd && *pPos != nFragmentDelimiter)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+ '%', eMechanism,
+ eCharset, eEscapeType);
+ appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
+ PART_URIC, '%', eCharset, true);
+ }
+ if (aTheSynPath.getLength() == 0)
+ return false;
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+
+ *pBegin = pPos;
+ rSynPath = aTheSynPath;
+ return true;
+}
+
+//============================================================================
+bool INetURLObject::setPath(rtl::OUString const & rThePath, bool bOctets,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ rtl::OUStringBuffer aSynPath;
+ sal_Unicode const * p = rThePath.getStr();
+ sal_Unicode const * pEnd = p + rThePath.getLength();
+ if (!parsePath(m_eScheme, &p, pEnd, bOctets, eMechanism, eCharset, false,
+ '/', 0x80000000, 0x80000000, 0x80000000, aSynPath)
+ || p != pEnd)
+ return false;
+ sal_Int32 nDelta = m_aPath.set(m_aAbsURIRef, aSynPath.makeStringAndClear());
+ m_aQuery += nDelta;
+ m_aFragment += nDelta;
+ return true;
+}
+
+//============================================================================
+bool INetURLObject::checkHierarchical() const {
+ if (m_eScheme == INET_PROT_VND_SUN_STAR_EXPAND) {
+ OSL_ENSURE(
+ false, "INetURLObject::checkHierarchical vnd.sun.star.expand");
+ return true;
+ } else {
+ return getSchemeInfo().m_bHierarchical;
+ }
+}
+
+//============================================================================
+bool INetURLObject::appendSegment(rtl::OUString const & rTheSegment,
+ bool bOctets, EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return insertName(rTheSegment, bOctets, false, LAST_SEGMENT, true,
+ eMechanism, eCharset);
+}
+
+//============================================================================
+INetURLObject::SubString INetURLObject::getSegment(sal_Int32 nIndex,
+ bool bIgnoreFinalSlash)
+ const
+{
+ DBG_ASSERT(nIndex >= 0 || nIndex == LAST_SEGMENT,
+ "INetURLObject::getSegment(): Bad index");
+
+ if (!checkHierarchical())
+ return SubString();
+
+ sal_Unicode const * pPathBegin
+ = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
+ sal_Unicode const * pSegBegin;
+ sal_Unicode const * pSegEnd;
+ if (nIndex == LAST_SEGMENT)
+ {
+ pSegEnd = pPathEnd;
+ if (bIgnoreFinalSlash && pSegEnd > pPathBegin && pSegEnd[-1] == '/')
+ --pSegEnd;
+ if (pSegEnd <= pPathBegin)
+ return SubString();
+ pSegBegin = pSegEnd - 1;
+ while (pSegBegin > pPathBegin && *pSegBegin != '/')
+ --pSegBegin;
+ }
+ else
+ {
+ pSegBegin = pPathBegin;
+ while (nIndex-- > 0)
+ do
+ {
+ ++pSegBegin;
+ if (pSegBegin >= pPathEnd)
+ return SubString();
+ }
+ while (*pSegBegin != '/');
+ pSegEnd = pSegBegin + 1;
+ while (pSegEnd < pPathEnd && *pSegEnd != '/')
+ ++pSegEnd;
+ }
+
+ return SubString(pSegBegin - m_aAbsURIRef.getStr(),
+ pSegEnd - pSegBegin);
+}
+
+//============================================================================
+bool INetURLObject::insertName(rtl::OUString const & rTheName, bool bOctets,
+ bool bAppendFinalSlash, sal_Int32 nIndex,
+ bool bIgnoreFinalSlash,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ DBG_ASSERT(nIndex >= 0 || nIndex == LAST_SEGMENT,
+ "INetURLObject::insertName(): Bad index");
+
+ if (!checkHierarchical())
+ return false;
+
+ sal_Unicode const * pPathBegin
+ = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
+ sal_Unicode const * pPrefixEnd;
+ bool bInsertSlash;
+ sal_Unicode const * pSuffixBegin;
+ if (nIndex == LAST_SEGMENT)
+ {
+ pPrefixEnd = pPathEnd;
+ if (bIgnoreFinalSlash && pPrefixEnd > pPathBegin &&
+ pPrefixEnd[-1] == '/')
+ {
+ --pPrefixEnd;
+ }
+ bInsertSlash = bAppendFinalSlash;
+ pSuffixBegin = pPathEnd;
+ }
+ else if (nIndex == 0)
+ {
+ pPrefixEnd = pPathBegin;
+ bInsertSlash =
+ (pPathBegin < pPathEnd && *pPathBegin != '/') ||
+ (pPathBegin == pPathEnd && bAppendFinalSlash);
+ pSuffixBegin =
+ (pPathEnd - pPathBegin == 1 && *pPathBegin == '/' &&
+ !bAppendFinalSlash && bIgnoreFinalSlash)
+ ? pPathEnd : pPathBegin;
+ }
+ else
+ {
+ pPrefixEnd = pPathBegin;
+ sal_Unicode const * pEnd = pPathEnd;
+ if (bIgnoreFinalSlash && pEnd > pPathBegin && pEnd[-1] == '/')
+ --pEnd;
+ bool bSkip = pPrefixEnd < pEnd && *pPrefixEnd == '/';
+ bInsertSlash = false;
+ pSuffixBegin = pPathEnd;
+ while (nIndex-- > 0)
+ for (;;)
+ {
+ if (bSkip)
+ ++pPrefixEnd;
+ bSkip = true;
+ if (pPrefixEnd >= pEnd)
+ {
+ if (nIndex == 0)
+ {
+ bInsertSlash = bAppendFinalSlash;
+ break;
+ }
+ else
+ return false;
+ }
+ if (*pPrefixEnd == '/')
+ {
+ pSuffixBegin = pPrefixEnd;
+ break;
+ }
+ }
+ }
+
+ rtl::OUStringBuffer aNewPath;
+ aNewPath.append(pPathBegin, pPrefixEnd - pPathBegin);
+ aNewPath.append(sal_Unicode('/'));
+ aNewPath.append(encodeText(rTheName, bOctets, PART_PCHAR, getEscapePrefix(),
+ eMechanism, eCharset, true));
+ if (bInsertSlash) {
+ aNewPath.append(sal_Unicode('/'));
+ }
+ aNewPath.append(pSuffixBegin, pPathEnd - pSuffixBegin);
+
+ return setPath(aNewPath.makeStringAndClear(), false, NOT_CANONIC,
+ RTL_TEXTENCODING_UTF8);
+}
+
+//============================================================================
+bool INetURLObject::clearQuery()
+{
+ if (HasError())
+ return false;
+ if (m_aQuery.isPresent())
+ {
+ lcl_Erase(m_aAbsURIRef, m_aQuery.getBegin() - 1,
+ m_aQuery.getLength() + 1);
+ m_aFragment += m_aQuery.clear() - 1;
+ }
+ return false;
+}
+
+//============================================================================
+bool INetURLObject::setQuery(rtl::OUString const & rTheQuery, bool bOctets,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ if (!getSchemeInfo().m_bQuery)
+ return false;
+ rtl::OUString aNewQuery(encodeText(rTheQuery, bOctets, PART_URIC,
+ getEscapePrefix(), eMechanism, eCharset,
+ true));
+ sal_Int32 nDelta;
+ if (m_aQuery.isPresent())
+ nDelta = m_aQuery.set(m_aAbsURIRef, aNewQuery);
+ else
+ {
+ m_aAbsURIRef.insert(m_aPath.getEnd(), sal_Unicode('?'));
+ nDelta = m_aQuery.set(m_aAbsURIRef, aNewQuery, m_aPath.getEnd() + 1)
+ + 1;
+ }
+ m_aFragment += nDelta;
+ return true;
+}
+
+//============================================================================
+bool INetURLObject::clearFragment()
+{
+ if (HasError())
+ return false;
+ if (m_aFragment.isPresent())
+ {
+ m_aAbsURIRef.setLength(m_aFragment.getBegin() - 1);
+ m_aFragment.clear();
+ }
+ return true;
+}
+
+//============================================================================
+bool INetURLObject::setFragment(rtl::OUString const & rTheFragment,
+ bool bOctets, EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ if (HasError())
+ return false;
+ rtl::OUString aNewFragment(encodeText(rTheFragment, bOctets, PART_URIC,
+ getEscapePrefix(), eMechanism,
+ eCharset, true));
+ if (m_aFragment.isPresent())
+ m_aFragment.set(m_aAbsURIRef, aNewFragment);
+ else
+ {
+ m_aAbsURIRef.append(sal_Unicode('#'));
+ m_aFragment.set(m_aAbsURIRef, aNewFragment, m_aAbsURIRef.getLength());
+ }
+ return true;
+}
+
+//============================================================================
+INetURLObject::FTPType INetURLObject::getFTPType() const
+{
+ if (m_eScheme == INET_PROT_FTP
+ && m_aPath.getLength() >= RTL_CONSTASCII_LENGTH(";type=") + 1
+ && rtl::OUString(m_aAbsURIRef).copy(
+ m_aPath.getEnd() - (RTL_CONSTASCII_LENGTH(";type=") + 1),
+ RTL_CONSTASCII_LENGTH(";type=")).equalsIgnoreAsciiCaseAscii(";type="))
+ switch (m_aAbsURIRef.charAt(m_aPath.getEnd()))
+ {
+ case 'A':
+ case 'a':
+ return FTP_TYPE_A;
+
+ case 'D':
+ case 'd':
+ return FTP_TYPE_D;
+
+ case 'I':
+ case 'i':
+ return FTP_TYPE_I;
+ }
+ return FTP_TYPE_NONE;
+}
+
+//============================================================================
+bool INetURLObject::hasDosVolume(FSysStyle eStyle) const
+{
+ sal_Unicode const * p = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ return (eStyle & FSYS_DOS) != 0
+ && m_aPath.getLength() >= 3
+ && p[0] == '/'
+ && INetMIME::isAlpha(p[1])
+ && p[2] == ':'
+ && (m_aPath.getLength() == 3 || p[3] == '/');
+}
+
+//============================================================================
+sal_uInt32 INetURLObject::getIMAPUID() const
+{
+ if (m_eScheme == INET_PROT_IMAP
+ && m_aPath.getLength() >= RTL_CONSTASCII_LENGTH("/;uid=") + 1)
+ {
+ sal_Unicode const * pBegin = m_aAbsURIRef.getStr()
+ + m_aPath.getBegin()
+ + RTL_CONSTASCII_LENGTH("/;uid=");
+ sal_Unicode const * pEnd = pBegin + m_aPath.getLength();
+ sal_Unicode const * p = pEnd;
+ while (p > pBegin && INetMIME::isDigit(p[-1]))
+ --p;
+ if (p < pEnd && *--p != '0'
+ && rtl::OUString(m_aAbsURIRef).copy(
+ p - RTL_CONSTASCII_LENGTH("/;uid=") - m_aAbsURIRef.getStr(),
+ RTL_CONSTASCII_LENGTH("/;uid=")).equalsIgnoreAsciiCaseAscii("/;uid=")
+ )
+ {
+ sal_uInt32 nUID;
+ if (INetMIME::scanUnsigned(p, pEnd, false, nUID))
+ return nUID;
+ }
+ }
+ return 0;
+}
+
+//============================================================================
+// static
+rtl::OUString INetURLObject::encodeText(sal_Unicode const * pBegin,
+ sal_Unicode const * pEnd, bool bOctets,
+ Part ePart, sal_Char cEscapePrefix,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ bool bKeepVisibleEscapes)
+{
+ rtl::OUStringBuffer aResult;
+ while (pBegin < pEnd)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pBegin, pEnd, bOctets, cEscapePrefix,
+ eMechanism, eCharset, eEscapeType);
+ appendUCS4(aResult, nUTF32, eEscapeType, bOctets, ePart,
+ cEscapePrefix, eCharset, bKeepVisibleEscapes);
+ }
+ return aResult.makeStringAndClear();
+}
+
+//============================================================================
+// static
+rtl::OUString INetURLObject::decode(sal_Unicode const * pBegin,
+ sal_Unicode const * pEnd,
+ sal_Char cEscapePrefix,
+ DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ switch (eMechanism)
+ {
+ case NO_DECODE:
+ return rtl::OUString(pBegin, pEnd - pBegin);
+
+ case DECODE_TO_IURI:
+ eCharset = RTL_TEXTENCODING_UTF8;
+ break;
+
+ default:
+ break;
+ }
+ rtl::OUStringBuffer aResult;
+ while (pBegin < pEnd)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(pBegin, pEnd, false, cEscapePrefix,
+ WAS_ENCODED, eCharset, eEscapeType);
+ switch (eEscapeType)
+ {
+ case ESCAPE_NO:
+ aResult.append(sal_Unicode(nUTF32));
+ break;
+
+ case ESCAPE_OCTET:
+ appendEscape(aResult, cEscapePrefix, nUTF32);
+ break;
+
+ case ESCAPE_UTF32:
+ if (
+ INetMIME::isUSASCII(nUTF32) &&
+ (
+ eMechanism == DECODE_TO_IURI ||
+ (
+ eMechanism == DECODE_UNAMBIGUOUS &&
+ mustEncode(nUTF32, PART_UNAMBIGUOUS)
+ )
+ )
+ )
+ {
+ appendEscape(aResult, cEscapePrefix, nUTF32);
+ }
+ else
+ aResult.append(sal_Unicode(nUTF32));
+ break;
+ }
+ }
+ return aResult.makeStringAndClear();
+}
+
+//============================================================================
+rtl::OUString INetURLObject::GetURLNoPass(DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset) const
+{
+ INetURLObject aTemp(*this);
+ aTemp.clearPassword();
+ return aTemp.GetMainURL(eMechanism, eCharset);
+}
+
+//============================================================================
+rtl::OUString INetURLObject::GetURLNoMark(DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset) const
+{
+ INetURLObject aTemp(*this);
+ aTemp.clearFragment();
+ return aTemp.GetMainURL(eMechanism, eCharset);
+}
+
+//============================================================================
+rtl::OUString
+INetURLObject::getAbbreviated(
+ star::uno::Reference< star::util::XStringWidth > const & rStringWidth,
+ sal_Int32 nWidth,
+ DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+ const
+{
+ OSL_ENSURE(rStringWidth.is(), "specification violation");
+ sal_Char cEscapePrefix = getEscapePrefix();
+ rtl::OUStringBuffer aBuffer;
+ // make sure that the scheme is copied for generic schemes: getSchemeInfo().m_pScheme
+ // is empty ("") in that case, so take the scheme from m_aAbsURIRef
+ if (m_eScheme != INET_PROT_GENERIC)
+ {
+ aBuffer.appendAscii(getSchemeInfo().m_pScheme);
+ }
+ else
+ {
+ if (m_aAbsURIRef)
+ {
+ sal_Unicode const * pSchemeBegin
+ = m_aAbsURIRef.getStr();
+ sal_Unicode const * pSchemeEnd = pSchemeBegin;
+
+ while (pSchemeEnd[0] != ':')
+ {
+ ++pSchemeEnd;
+ }
+ aBuffer.append(pSchemeBegin, pSchemeEnd - pSchemeBegin);
+ }
+ }
+ aBuffer.append(static_cast< sal_Unicode >(':'));
+ bool bAuthority = getSchemeInfo().m_bAuthority;
+ sal_Unicode const * pCoreBegin
+ = m_aAbsURIRef.getStr() + (bAuthority ? getAuthorityBegin() :
+ m_aPath.getBegin());
+ sal_Unicode const * pCoreEnd
+ = m_aAbsURIRef.getStr() + m_aPath.getBegin() + m_aPath.getLength();
+ bool bSegment = false;
+ if (getSchemeInfo().m_bHierarchical)
+ {
+ rtl::OUString aRest;
+ if (m_aQuery.isPresent())
+ aRest = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("?..."));
+ else if (m_aFragment.isPresent())
+ aRest = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("#..."));
+ rtl::OUStringBuffer aTrailer;
+ sal_Unicode const * pBegin = pCoreBegin;
+ sal_Unicode const * pEnd = pCoreEnd;
+ sal_Unicode const * pPrefixBegin = pBegin;
+ sal_Unicode const * pSuffixEnd = pEnd;
+ bool bPrefix = true;
+ bool bSuffix = true;
+ do
+ {
+ if (bSuffix)
+ {
+ sal_Unicode const * p = pSuffixEnd - 1;
+ if (pSuffixEnd == pCoreEnd && *p == '/')
+ --p;
+ while (*p != '/')
+ --p;
+ if (bAuthority && p == pCoreBegin + 1)
+ --p;
+ rtl::OUString
+ aSegment(decode(p + (p == pBegin && pBegin != pCoreBegin ?
+ 1 : 0),
+ pSuffixEnd,
+ cEscapePrefix,
+ eMechanism,
+ eCharset));
+ pSuffixEnd = p;
+ rtl::OUStringBuffer aResult(aBuffer);
+ if (pSuffixEnd != pBegin)
+ aResult.appendAscii(RTL_CONSTASCII_STRINGPARAM("..."));
+ aResult.append(aSegment);
+ aResult.append(aTrailer);
+ aResult.append(aRest);
+ if (rStringWidth->
+ queryStringWidth(aResult.makeStringAndClear())
+ <= nWidth)
+ {
+ aTrailer.insert(0, aSegment);
+ bSegment = true;
+ pEnd = pSuffixEnd;
+ }
+ else
+ bSuffix = false;
+ if (pPrefixBegin > pSuffixEnd)
+ pPrefixBegin = pSuffixEnd;
+ if (pBegin == pEnd)
+ break;
+ }
+ if (bPrefix)
+ {
+ sal_Unicode const * p
+ = pPrefixBegin
+ + (bAuthority && pPrefixBegin == pCoreBegin ? 2 :
+ 1);
+ OSL_ASSERT(p <= pEnd);
+ while (p < pEnd && *p != '/')
+ ++p;
+ if (p == pCoreEnd - 1 && *p == '/')
+ ++p;
+ rtl::OUString
+ aSegment(decode(pPrefixBegin
+ + (pPrefixBegin == pCoreBegin ? 0 :
+ 1),
+ p == pEnd ? p : p + 1,
+ cEscapePrefix,
+ eMechanism,
+ eCharset));
+ pPrefixBegin = p;
+ rtl::OUStringBuffer aResult(aBuffer);
+ aResult.append(aSegment);
+ if (pPrefixBegin != pEnd)
+ aResult.appendAscii(RTL_CONSTASCII_STRINGPARAM("..."));
+ aResult.append(aTrailer);
+ aResult.append(aRest);
+ if (rStringWidth->
+ queryStringWidth(aResult.makeStringAndClear())
+ <= nWidth)
+ {
+ aBuffer.append(aSegment);
+ bSegment = true;
+ pBegin = pPrefixBegin;
+ }
+ else
+ bPrefix = false;
+ if (pPrefixBegin > pSuffixEnd)
+ pSuffixEnd = pPrefixBegin;
+ if (pBegin == pEnd)
+ break;
+ }
+ }
+ while (bPrefix || bSuffix);
+ if (bSegment)
+ {
+ if (pPrefixBegin != pBegin || pSuffixEnd != pEnd)
+ aBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("..."));
+ aBuffer.append(aTrailer);
+ }
+ }
+ if (!bSegment)
+ aBuffer.append(decode(pCoreBegin,
+ pCoreEnd,
+ cEscapePrefix,
+ eMechanism,
+ eCharset));
+ if (m_aQuery.isPresent())
+ {
+ aBuffer.append(static_cast< sal_Unicode >('?'));
+ aBuffer.append(decode(m_aQuery, cEscapePrefix, eMechanism, eCharset));
+ }
+ if (m_aFragment.isPresent())
+ {
+ aBuffer.append(static_cast< sal_Unicode >('#'));
+ aBuffer.
+ append(decode(m_aFragment, cEscapePrefix, eMechanism, eCharset));
+ }
+ if (aBuffer.getLength() != 0)
+ {
+ rtl::OUStringBuffer aResult(aBuffer);
+ if (rStringWidth->queryStringWidth(aResult.makeStringAndClear())
+ > nWidth)
+ for (sal_Int32 i = aBuffer.getLength();;)
+ {
+ if (i == 0)
+ {
+ aBuffer.setLength(aBuffer.getLength() - 1);
+ if (aBuffer.getLength() == 0)
+ break;
+ }
+ else
+ {
+ aBuffer.setLength(--i);
+ aBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("..."));
+ }
+ aResult = aBuffer;
+ if (rStringWidth->
+ queryStringWidth(aResult.makeStringAndClear())
+ <= nWidth)
+ break;
+ }
+ }
+ return aBuffer.makeStringAndClear();
+}
+
+//============================================================================
+bool INetURLObject::operator ==(INetURLObject const & rObject) const
+{
+ if (m_eScheme != rObject.m_eScheme)
+ return false;
+ if (m_eScheme == INET_PROT_NOT_VALID)
+ return (m_aAbsURIRef == rObject.m_aAbsURIRef) != false;
+ if ((m_aScheme.compare(
+ rObject.m_aScheme, m_aAbsURIRef, rObject.m_aAbsURIRef)
+ != 0)
+ || GetUser(NO_DECODE) != rObject.GetUser(NO_DECODE)
+ || GetPass(NO_DECODE) != rObject.GetPass(NO_DECODE)
+ || !GetHost(NO_DECODE).equalsIgnoreAsciiCase(
+ rObject.GetHost(NO_DECODE))
+ || GetPort() != rObject.GetPort()
+ || HasParam() != rObject.HasParam()
+ || GetParam(NO_DECODE) != rObject.GetParam(NO_DECODE)
+ || GetMsgId(NO_DECODE) != rObject.GetMsgId(NO_DECODE))
+ return false;
+ rtl::OUString aPath1(GetURLPath(NO_DECODE));
+ rtl::OUString aPath2(rObject.GetURLPath(NO_DECODE));
+ switch (m_eScheme)
+ {
+ case INET_PROT_FILE:
+ {
+ // If the URL paths of two file URLs only differ in that one has a
+ // final '/' and the other has not, take the two paths as
+ // equivalent (this could be usefull for other schemes, too):
+ sal_Int32 nLength = aPath1.getLength();
+ switch (nLength - aPath2.getLength())
+ {
+ case -1:
+ if (aPath2.getStr()[nLength] != '/')
+ return false;
+ break;
+
+ case 0:
+ break;
+
+ case 1:
+ if (aPath1.getStr()[--nLength] != '/')
+ return false;
+ break;
+
+ default:
+ return false;
+ }
+ return aPath1.compareTo(aPath2, nLength) == 0;
+ }
+
+ default:
+ return (aPath1 == aPath2) != false;
+ }
+}
+
+//============================================================================
+bool INetURLObject::operator <(INetURLObject const & rObject) const
+{
+ sal_Int32 nCompare = m_aScheme.compare(
+ rObject.m_aScheme, m_aAbsURIRef, rObject.m_aAbsURIRef);
+ if (nCompare < 0) {
+ return true;
+ } else if (nCompare > 0) {
+ return false;
+ }
+ sal_uInt32 nPort1 = GetPort();
+ sal_uInt32 nPort2 = rObject.GetPort();
+ if (nPort1 < nPort2)
+ return true;
+ else if (nPort1 > nPort2)
+ return false;
+ nCompare = GetUser(NO_DECODE).compareTo(rObject.GetUser(NO_DECODE));
+ if (nCompare < 0)
+ return true;
+ else if (nCompare > 0)
+ return false;
+ nCompare = GetPass(NO_DECODE).compareTo(rObject.GetPass(NO_DECODE));
+ if (nCompare < 0)
+ return true;
+ else if (nCompare > 0)
+ return false;
+ nCompare = GetHost(NO_DECODE).compareTo(rObject.GetHost(NO_DECODE));
+ if (nCompare < 0)
+ return true;
+ else if (nCompare > 0)
+ return false;
+ const rtl::OUString &rPath1(GetURLPath(NO_DECODE));
+ const rtl::OUString &rPath2(rObject.GetURLPath(NO_DECODE));
+ nCompare = rPath1.compareTo(rPath2);
+ if (nCompare < 0)
+ return true;
+ else if (nCompare > 0)
+ return false;
+ nCompare = GetParam(NO_DECODE).compareTo(rObject.GetParam(NO_DECODE));
+ if (nCompare < 0)
+ return true;
+ else if (nCompare > 0)
+ return false;
+ return GetMsgId(NO_DECODE).compareTo(rObject.GetMsgId(NO_DECODE)) < 0;
+}
+
+//============================================================================
+bool INetURLObject::ConcatData(INetProtocol eTheScheme,
+ rtl::OUString const & rTheUser,
+ rtl::OUString const & rThePassword,
+ rtl::OUString const & rTheHost,
+ sal_uInt32 nThePort,
+ rtl::OUString const & rThePath,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ setInvalid();
+ m_eScheme = eTheScheme;
+ if (HasError() || m_eScheme == INET_PROT_GENERIC)
+ return false;
+ m_aAbsURIRef.setLength(0);
+ m_aAbsURIRef.appendAscii(getSchemeInfo().m_pScheme);
+ m_aAbsURIRef.append(sal_Unicode(':'));
+ if (getSchemeInfo().m_bAuthority)
+ {
+ m_aAbsURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ bool bUserInfo = false;
+ if (getSchemeInfo().m_bUser)
+ {
+ if (m_eScheme == INET_PROT_IMAP && rTheUser.getLength() == 0)
+ {
+ setInvalid();
+ return false;
+ }
+ if (rTheUser.getLength() != 0)
+ {
+ m_aUser.set(m_aAbsURIRef,
+ encodeText(rTheUser, false,
+ m_eScheme == INET_PROT_IMAP ?
+ PART_IMAP_ACHAR :
+ m_eScheme == INET_PROT_VIM ?
+ PART_VIM :
+ PART_USER_PASSWORD,
+ getEscapePrefix(), eMechanism,
+ eCharset, false),
+ m_aAbsURIRef.getLength());
+ bUserInfo = true;
+ }
+ }
+ else if (rTheUser.getLength() != 0)
+ {
+ setInvalid();
+ return false;
+ }
+ if (rThePassword.getLength() != 0)
+ {
+ if (getSchemeInfo().m_bPassword)
+ {
+ m_aAbsURIRef.append(sal_Unicode(':'));
+ m_aAuth.set(m_aAbsURIRef,
+ encodeText(rThePassword, false,
+ m_eScheme == INET_PROT_VIM ?
+ PART_VIM : PART_USER_PASSWORD,
+ getEscapePrefix(), eMechanism,
+ eCharset, false),
+ m_aAbsURIRef.getLength());
+ bUserInfo = true;
+ }
+ else
+ {
+ setInvalid();
+ return false;
+ }
+ }
+ if (bUserInfo && getSchemeInfo().m_bHost)
+ m_aAbsURIRef.append(sal_Unicode('@'));
+ if (getSchemeInfo().m_bHost)
+ {
+ rtl::OUStringBuffer aSynHost(rTheHost);
+ bool bNetBiosName = false;
+ switch (m_eScheme)
+ {
+ case INET_PROT_FILE:
+ {
+ rtl::OUString sTemp(aSynHost);
+ if (sTemp.equalsIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("localhost")))
+ {
+ aSynHost.setLength(0);
+ }
+ bNetBiosName = true;
+ }
+ break;
+
+ case INET_PROT_LDAP:
+ if (aSynHost.getLength() == 0 && nThePort != 0)
+ {
+ setInvalid();
+ return false;
+ }
+ break;
+
+ default:
+ if (aSynHost.getLength() == 0)
+ {
+ setInvalid();
+ return false;
+ }
+ break;
+ }
+ if (!parseHostOrNetBiosName(
+ aSynHost.getStr(), aSynHost.getStr() + aSynHost.getLength(),
+ false, eMechanism, eCharset, bNetBiosName, &aSynHost))
+ {
+ setInvalid();
+ return false;
+ }
+ m_aHost.set(m_aAbsURIRef, aSynHost.makeStringAndClear(),
+ m_aAbsURIRef.getLength());
+ if (nThePort != 0)
+ {
+ if (getSchemeInfo().m_bPort)
+ {
+ m_aAbsURIRef.append(sal_Unicode(':'));
+ m_aPort.set(m_aAbsURIRef,
+ rtl::OUString::valueOf(sal_Int64(nThePort)),
+ m_aAbsURIRef.getLength());
+ }
+ else
+ {
+ setInvalid();
+ return false;
+ }
+ }
+ }
+ else if (rTheHost.getLength() != 0 || nThePort != 0)
+ {
+ setInvalid();
+ return false;
+ }
+ }
+ rtl::OUStringBuffer aSynPath;
+ sal_Unicode const * p = rThePath.getStr();
+ sal_Unicode const * pEnd = p + rThePath.getLength();
+ if (!parsePath(m_eScheme, &p, pEnd, false, eMechanism, eCharset, false, '/',
+ 0x80000000, 0x80000000, 0x80000000, aSynPath)
+ || p != pEnd)
+ {
+ setInvalid();
+ return false;
+ }
+ m_aPath.set(m_aAbsURIRef, aSynPath.makeStringAndClear(),
+ m_aAbsURIRef.getLength());
+ return true;
+}
+
+//============================================================================
+// static
+rtl::OUString INetURLObject::GetAbsURL(rtl::OUString const & rTheBaseURIRef,
+ rtl::OUString const & rTheRelURIRef,
+ bool bIgnoreFragment,
+ EncodeMechanism eEncodeMechanism,
+ DecodeMechanism eDecodeMechanism,
+ rtl_TextEncoding eCharset,
+ FSysStyle eStyle)
+{
+ // Backwards compatibility:
+ if (rTheRelURIRef.getLength() == 0 || rTheRelURIRef[0] == '#')
+ return rTheRelURIRef;
+
+ INetURLObject aTheAbsURIRef;
+ bool bWasAbsolute;
+ return INetURLObject(rTheBaseURIRef, eEncodeMechanism, eCharset).
+ convertRelToAbs(rTheRelURIRef, false, aTheAbsURIRef,
+ bWasAbsolute, eEncodeMechanism,
+ eCharset, bIgnoreFragment, false,
+ false, eStyle)
+ || eEncodeMechanism != WAS_ENCODED
+ || eDecodeMechanism != DECODE_TO_IURI
+ || eCharset != RTL_TEXTENCODING_UTF8 ?
+ aTheAbsURIRef.GetMainURL(eDecodeMechanism, eCharset) :
+ rTheRelURIRef;
+}
+
+//============================================================================
+rtl::OUString INetURLObject::getExternalURL(DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset) const
+{
+ rtl::OUString aTheExtURIRef;
+ translateToExternal(
+ rtl::OUString(m_aAbsURIRef), aTheExtURIRef, eMechanism, eCharset);
+ return aTheExtURIRef;
+}
+
+//============================================================================
+// static
+rtl::OUString INetURLObject::GetScheme(INetProtocol eTheScheme)
+{
+ return rtl::OUString::createFromAscii(getSchemeInfo(eTheScheme).m_pPrefix);
+}
+
+//============================================================================
+// static
+INetProtocol INetURLObject::CompareProtocolScheme(rtl::OUString const &
+ rTheAbsURIRef)
+{
+ sal_Unicode const * p = rTheAbsURIRef.getStr();
+ PrefixInfo const * pPrefix = getPrefix(p, p + rTheAbsURIRef.getLength());
+ return pPrefix ? pPrefix->m_eScheme : INET_PROT_NOT_VALID;
+}
+
+//============================================================================
+bool INetURLObject::hasPassword() const
+{
+ return m_aAuth.isPresent() && getSchemeInfo().m_bPassword;
+}
+
+//============================================================================
+void INetURLObject::makeAuthCanonic()
+{
+ if (m_eScheme == INET_PROT_IMAP && m_aAuth.getLength() == 1
+ && m_aAbsURIRef.charAt(m_aAuth.getBegin()) == '*')
+ {
+ lcl_Erase(m_aAbsURIRef, m_aAuth.getBegin()
+ - RTL_CONSTASCII_LENGTH(";AUTH="),
+ RTL_CONSTASCII_LENGTH(";AUTH=*"));
+ sal_Int32 nDelta = m_aAuth.clear() - RTL_CONSTASCII_LENGTH(";AUTH=");
+ m_aPath += nDelta;
+ m_aQuery += nDelta;
+ m_aFragment += nDelta;
+ }
+}
+
+//============================================================================
+rtl::OUString INetURLObject::GetHostPort(DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ // Check because PROT_VND_SUN_STAR_HELP, PROT_VND_SUN_STAR_HIER, and
+ // PROT_VND_SUN_STAR_PKG misuse m_aHost:
+ if (!getSchemeInfo().m_bHost)
+ return rtl::OUString();
+ rtl::OUStringBuffer aHostPort(decode(m_aHost, getEscapePrefix(),
+ eMechanism, eCharset));
+ if (m_aPort.isPresent())
+ {
+ aHostPort.append(sal_Unicode(':'));
+ aHostPort.append(decode(m_aPort, getEscapePrefix(),
+ eMechanism, eCharset));
+ }
+ return aHostPort.makeStringAndClear();
+}
+
+//============================================================================
+sal_uInt32 INetURLObject::GetPort() const
+{
+ if (m_aPort.isPresent())
+ {
+ sal_Unicode const * p = m_aAbsURIRef.getStr() + m_aPort.getBegin();
+ sal_Unicode const * pEnd = p + m_aPort.getLength();
+ sal_uInt32 nThePort;
+ if (INetMIME::scanUnsigned(p, pEnd, true, nThePort) && p == pEnd)
+ return nThePort;
+ }
+ return 0;
+}
+
+//============================================================================
+bool INetURLObject::SetPort(sal_uInt32 nThePort)
+{
+ if (getSchemeInfo().m_bPort && m_aHost.isPresent())
+ {
+ rtl::OUString aNewPort(rtl::OUString::valueOf(sal_Int64(nThePort)));
+ sal_Int32 nDelta;
+ if (m_aPort.isPresent())
+ nDelta = m_aPort.set(m_aAbsURIRef, aNewPort);
+ else
+ {
+ m_aAbsURIRef.insert(m_aHost.getEnd(), sal_Unicode(':'));
+ nDelta = m_aPort.set(m_aAbsURIRef, aNewPort, m_aHost.getEnd() + 1)
+ + 1;
+ }
+ m_aPath += nDelta;
+ m_aQuery += nDelta;
+ m_aFragment += nDelta;
+ return true;
+ }
+ return false;
+}
+
+//============================================================================
+void INetURLObject::makePortCanonic()
+{
+ if (m_aPort.isPresent())
+ {
+ sal_Unicode const * p = m_aAbsURIRef.getStr() + m_aPort.getBegin();
+ sal_Unicode const * pEnd = p + m_aPort.getLength();
+ sal_uInt32 nThePort;
+ if (INetMIME::scanUnsigned(p, pEnd, true, nThePort) && p == pEnd)
+ {
+ sal_Int32 nDelta;
+ if (nThePort != 0 && nThePort == getSchemeInfo().m_nDefaultPort)
+ {
+ lcl_Erase(m_aAbsURIRef, m_aPort.getBegin() - 1,
+ m_aPort.getLength() + 1);
+ nDelta = m_aPort.clear() - 1;
+ }
+ else
+ nDelta = m_aPort.set(m_aAbsURIRef,
+ rtl::OUString::valueOf(sal_Int64(nThePort)));
+ m_aPath += nDelta;
+ m_aQuery += nDelta;
+ m_aFragment += nDelta;
+ }
+ }
+}
+
+//============================================================================
+sal_Int32 INetURLObject::getSegmentCount(bool bIgnoreFinalSlash) const
+{
+ if (!checkHierarchical())
+ return 0;
+
+ sal_Unicode const * p = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ sal_Unicode const * pEnd = p + m_aPath.getLength();
+ if (bIgnoreFinalSlash && pEnd > p && pEnd[-1] == '/')
+ --pEnd;
+ sal_Int32 n = p == pEnd || *p == '/' ? 0 : 1;
+ while (p != pEnd)
+ if (*p++ == '/')
+ ++n;
+ return n;
+}
+
+//============================================================================
+bool INetURLObject::removeSegment(sal_Int32 nIndex, bool bIgnoreFinalSlash)
+{
+ SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
+ if (!aSegment.isPresent())
+ return false;
+
+ rtl::OUStringBuffer aNewPath;
+ aNewPath.append(m_aAbsURIRef.getStr() + m_aPath.getBegin(),
+ aSegment.getBegin() - m_aPath.getBegin());
+ if (bIgnoreFinalSlash && aSegment.getEnd() == m_aPath.getEnd())
+ aNewPath.append(sal_Unicode('/'));
+ else
+ aNewPath.append(m_aAbsURIRef.getStr() + aSegment.getEnd(),
+ m_aPath.getEnd() - aSegment.getEnd());
+ if (aNewPath.getLength() == 0 && !aSegment.isEmpty() &&
+ m_aAbsURIRef[aSegment.getBegin()] == '/')
+ {
+ aNewPath.append(sal_Unicode('/'));
+ }
+
+ return setPath(aNewPath.makeStringAndClear(), false, NOT_CANONIC,
+ RTL_TEXTENCODING_UTF8);
+}
+
+//============================================================================
+rtl::OUString INetURLObject::getName(sal_Int32 nIndex, bool bIgnoreFinalSlash,
+ DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset) const
+{
+ SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
+ if (!aSegment.isPresent())
+ return rtl::OUString();
+
+ sal_Unicode const * pSegBegin
+ = m_aAbsURIRef.getStr() + aSegment.getBegin();
+ sal_Unicode const * pSegEnd = pSegBegin + aSegment.getLength();
+
+ if (pSegBegin < pSegEnd && *pSegBegin == '/')
+ ++pSegBegin;
+ sal_Unicode const * p = pSegBegin;
+ while (p != pSegEnd && *p != ';')
+ ++p;
+
+ return decode(pSegBegin, p, getEscapePrefix(), eMechanism, eCharset);
+}
+
+//============================================================================
+bool INetURLObject::setName(rtl::OUString const & rTheName, sal_Int32 nIndex,
+ bool bIgnoreFinalSlash,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
+ if (!aSegment.isPresent())
+ return false;
+
+ sal_Unicode const * pPathBegin
+ = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
+ sal_Unicode const * pSegBegin
+ = m_aAbsURIRef.getStr() + aSegment.getBegin();
+ sal_Unicode const * pSegEnd = pSegBegin + aSegment.getLength();
+
+ if (pSegBegin < pSegEnd && *pSegBegin == '/')
+ ++pSegBegin;
+ sal_Unicode const * p = pSegBegin;
+ while (p != pSegEnd && *p != ';')
+ ++p;
+
+ rtl::OUStringBuffer aNewPath;
+ aNewPath.append(pPathBegin, pSegBegin - pPathBegin);
+ aNewPath.append(encodeText(rTheName, false, PART_PCHAR, getEscapePrefix(),
+ eMechanism, eCharset, true));
+ aNewPath.append(p, pPathEnd - p);
+
+ return setPath(aNewPath.makeStringAndClear(), false, NOT_CANONIC,
+ RTL_TEXTENCODING_UTF8);
+}
+
+//============================================================================
+bool INetURLObject::hasExtension(sal_Int32 nIndex, bool bIgnoreFinalSlash)
+ const
+{
+ SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
+ if (!aSegment.isPresent())
+ return false;
+
+ sal_Unicode const * pSegBegin
+ = m_aAbsURIRef.getStr() + aSegment.getBegin();
+ sal_Unicode const * pSegEnd = pSegBegin + aSegment.getLength();
+
+ if (pSegBegin < pSegEnd && *pSegBegin == '/')
+ ++pSegBegin;
+ for (sal_Unicode const * p = pSegBegin; p != pSegEnd && *p != ';'; ++p)
+ if (*p == '.' && p != pSegBegin)
+ return true;
+ return false;
+}
+
+//============================================================================
+rtl::OUString INetURLObject::getBase(sal_Int32 nIndex, bool bIgnoreFinalSlash,
+ DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset) const
+{
+ SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
+ if (!aSegment.isPresent())
+ return rtl::OUString();
+
+ sal_Unicode const * pSegBegin
+ = m_aAbsURIRef.getStr() + aSegment.getBegin();
+ sal_Unicode const * pSegEnd = pSegBegin + aSegment.getLength();
+
+ if (pSegBegin < pSegEnd && *pSegBegin == '/')
+ ++pSegBegin;
+ sal_Unicode const * pExtension = 0;
+ sal_Unicode const * p = pSegBegin;
+ for (; p != pSegEnd && *p != ';'; ++p)
+ if (*p == '.' && p != pSegBegin)
+ pExtension = p;
+ if (!pExtension)
+ pExtension = p;
+
+ return decode(pSegBegin, pExtension, getEscapePrefix(), eMechanism,
+ eCharset);
+}
+
+//============================================================================
+bool INetURLObject::setBase(rtl::OUString const & rTheBase, sal_Int32 nIndex,
+ bool bIgnoreFinalSlash,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
+ if (!aSegment.isPresent())
+ return false;
+
+ sal_Unicode const * pPathBegin
+ = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
+ sal_Unicode const * pSegBegin
+ = m_aAbsURIRef.getStr() + aSegment.getBegin();
+ sal_Unicode const * pSegEnd = pSegBegin + aSegment.getLength();
+
+ if (pSegBegin < pSegEnd && *pSegBegin == '/')
+ ++pSegBegin;
+ sal_Unicode const * pExtension = 0;
+ sal_Unicode const * p = pSegBegin;
+ for (; p != pSegEnd && *p != ';'; ++p)
+ if (*p == '.' && p != pSegBegin)
+ pExtension = p;
+ if (!pExtension)
+ pExtension = p;
+
+ rtl::OUStringBuffer aNewPath;
+ aNewPath.append(pPathBegin, pSegBegin - pPathBegin);
+ aNewPath.append(encodeText(rTheBase, false, PART_PCHAR, getEscapePrefix(),
+ eMechanism, eCharset, true));
+ aNewPath.append(pExtension, pPathEnd - pExtension);
+
+ return setPath(aNewPath.makeStringAndClear(), false, NOT_CANONIC,
+ RTL_TEXTENCODING_UTF8);
+}
+
+//============================================================================
+rtl::OUString INetURLObject::getExtension(sal_Int32 nIndex,
+ bool bIgnoreFinalSlash,
+ DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset) const
+{
+ SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
+ if (!aSegment.isPresent())
+ return rtl::OUString();
+
+ sal_Unicode const * pSegBegin
+ = m_aAbsURIRef.getStr() + aSegment.getBegin();
+ sal_Unicode const * pSegEnd = pSegBegin + aSegment.getLength();
+
+ if (pSegBegin < pSegEnd && *pSegBegin == '/')
+ ++pSegBegin;
+ sal_Unicode const * pExtension = 0;
+ sal_Unicode const * p = pSegBegin;
+ for (; p != pSegEnd && *p != ';'; ++p)
+ if (*p == '.' && p != pSegBegin)
+ pExtension = p;
+
+ if (!pExtension)
+ return rtl::OUString();
+
+ return decode(pExtension + 1, p, getEscapePrefix(), eMechanism, eCharset);
+}
+
+//============================================================================
+bool INetURLObject::setExtension(rtl::OUString const & rTheExtension,
+ sal_Int32 nIndex, bool bIgnoreFinalSlash,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
+ if (!aSegment.isPresent())
+ return false;
+
+ sal_Unicode const * pPathBegin
+ = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
+ sal_Unicode const * pSegBegin
+ = m_aAbsURIRef.getStr() + aSegment.getBegin();
+ sal_Unicode const * pSegEnd = pSegBegin + aSegment.getLength();
+
+ if (pSegBegin < pSegEnd && *pSegBegin == '/')
+ ++pSegBegin;
+ sal_Unicode const * pExtension = 0;
+ sal_Unicode const * p = pSegBegin;
+ for (; p != pSegEnd && *p != ';'; ++p)
+ if (*p == '.' && p != pSegBegin)
+ pExtension = p;
+ if (!pExtension)
+ pExtension = p;
+
+ rtl::OUStringBuffer aNewPath;
+ aNewPath.append(pPathBegin, pExtension - pPathBegin);
+ aNewPath.append(sal_Unicode('.'));
+ aNewPath.append(encodeText(rTheExtension, false, PART_PCHAR,
+ getEscapePrefix(), eMechanism, eCharset, true));
+ aNewPath.append(p, pPathEnd - p);
+
+ return setPath(aNewPath.makeStringAndClear(), false, NOT_CANONIC,
+ RTL_TEXTENCODING_UTF8);
+}
+
+//============================================================================
+bool INetURLObject::removeExtension(sal_Int32 nIndex, bool bIgnoreFinalSlash)
+{
+ SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
+ if (!aSegment.isPresent())
+ return false;
+
+ sal_Unicode const * pPathBegin
+ = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
+ sal_Unicode const * pSegBegin
+ = m_aAbsURIRef.getStr() + aSegment.getBegin();
+ sal_Unicode const * pSegEnd = pSegBegin + aSegment.getLength();
+
+ if (pSegBegin < pSegEnd && *pSegBegin == '/')
+ ++pSegBegin;
+ sal_Unicode const * pExtension = 0;
+ sal_Unicode const * p = pSegBegin;
+ for (; p != pSegEnd && *p != ';'; ++p)
+ if (*p == '.' && p != pSegBegin)
+ pExtension = p;
+ if (!pExtension)
+ return true;
+
+ rtl::OUStringBuffer aNewPath;
+ aNewPath.append(pPathBegin, pExtension - pPathBegin);
+ aNewPath.append(p, pPathEnd - p);
+
+ return setPath(aNewPath.makeStringAndClear(), false, NOT_CANONIC,
+ RTL_TEXTENCODING_UTF8);
+}
+
+//============================================================================
+bool INetURLObject::hasFinalSlash() const
+{
+ if (!checkHierarchical())
+ return false;
+
+ sal_Unicode const * pPathBegin
+ = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
+ return pPathEnd > pPathBegin && pPathEnd[-1] == '/';
+}
+
+//============================================================================
+bool INetURLObject::setFinalSlash()
+{
+ if (!checkHierarchical())
+ return false;
+
+ sal_Unicode const * pPathBegin
+ = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
+ if (pPathEnd > pPathBegin && pPathEnd[-1] == '/')
+ return true;
+
+ rtl::OUStringBuffer aNewPath;
+ aNewPath.append(pPathBegin, pPathEnd - pPathBegin);
+ aNewPath.append(sal_Unicode('/'));
+
+ return setPath(aNewPath.makeStringAndClear(), false, NOT_CANONIC,
+ RTL_TEXTENCODING_UTF8);
+}
+
+//============================================================================
+bool INetURLObject::removeFinalSlash()
+{
+ if (!checkHierarchical())
+ return false;
+
+ sal_Unicode const * pPathBegin
+ = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
+ if (pPathEnd <= pPathBegin || pPathEnd[-1] != '/')
+ return true;
+
+ --pPathEnd;
+ if (pPathEnd == pPathBegin && *pPathBegin == '/')
+ return false;
+ rtl::OUString aNewPath(pPathBegin, pPathEnd - pPathBegin);
+
+ return setPath(aNewPath, false, NOT_CANONIC, RTL_TEXTENCODING_UTF8);
+}
+
+//============================================================================
+// static
+rtl::OUString INetURLObject::createFragment(rtl::OUString const & rText)
+{
+ rtl::OUString aFragment(rText);
+ for (sal_Int32 i = 0; i < aFragment.getLength();)
+ {
+ sal_Unicode c = aFragment.getStr()[i];
+ if (mustEncode(c, PART_CREATEFRAGMENT))
+ aFragment = aFragment.replaceAt(i, 1, rtl::OUString());
+ else
+ ++i;
+ }
+ return aFragment;
+}
+
+//============================================================================
+bool INetURLObject::setFSysPath(rtl::OUString const & rFSysPath,
+ FSysStyle eStyle)
+{
+ sal_Unicode const * pFSysBegin = rFSysPath.getStr();
+ sal_Unicode const * pFSysEnd = pFSysBegin + rFSysPath.getLength();
+
+ switch ((eStyle & FSYS_VOS ? 1 : 0)
+ + (eStyle & FSYS_UNX ? 1 : 0)
+ + (eStyle & FSYS_DOS ? 1 : 0)
+ + (eStyle & FSYS_MAC ? 1 : 0))
+ {
+ case 0:
+ return false;
+
+ case 1:
+ break;
+
+ default:
+ if (eStyle & FSYS_VOS
+ && pFSysEnd - pFSysBegin >= 2
+ && pFSysBegin[0] == '/'
+ && pFSysBegin[1] == '/')
+ {
+ if (pFSysEnd - pFSysBegin >= 3
+ && pFSysBegin[2] == '.'
+ && (pFSysEnd - pFSysBegin == 3 || pFSysBegin[3] == '/'))
+ {
+ eStyle = FSYS_VOS; // Production T1
+ break;
+ }
+
+ sal_Unicode const * p = pFSysBegin + 2;
+ rtl::OUString aHost;
+ if (parseHost(p, pFSysEnd, aHost)
+ && (p == pFSysEnd || *p == '/'))
+ {
+ eStyle = FSYS_VOS; // Production T2
+ break;
+ }
+ }
+
+ if (eStyle & FSYS_DOS
+ && pFSysEnd - pFSysBegin >= 2
+ && pFSysBegin[0] == '\\'
+ && pFSysBegin[1] == '\\')
+ {
+ sal_Unicode const * p = pFSysBegin + 2;
+ rtl::OUString aHost;
+ if (parseHost(p, pFSysEnd, aHost)
+ && (p == pFSysEnd || *p == '\\'))
+ {
+ eStyle = FSYS_DOS; // Production T3
+ break;
+ }
+ }
+
+ if (eStyle & FSYS_DOS
+ && pFSysEnd - pFSysBegin >= 2
+ && INetMIME::isAlpha(pFSysBegin[0])
+ && pFSysBegin[1] == ':'
+ && (pFSysEnd - pFSysBegin == 2
+ || pFSysBegin[2] == '/'
+ || pFSysBegin[2] == '\\'))
+ {
+ eStyle = FSYS_DOS; // Productions T4, T5
+ break;
+ }
+
+ if (!(eStyle & (FSYS_UNX | FSYS_DOS | FSYS_MAC)))
+ return false;
+
+ eStyle = guessFSysStyleByCounting(pFSysBegin, pFSysEnd, eStyle);
+ // Production T6
+ break;
+ }
+
+ rtl::OUStringBuffer aSynAbsURIRef(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file://")));
+
+ switch (eStyle)
+ {
+ case FSYS_VOS:
+ {
+ sal_Unicode const * p = pFSysBegin;
+ if (pFSysEnd - p < 2 || *p++ != '/' || *p++ != '/')
+ return false;
+ if (p != pFSysEnd && *p == '.'
+ && (pFSysEnd - p == 1 || p[1] == '/'))
+ ++p;
+ for (; p != pFSysEnd; ++p)
+ switch (*p)
+ {
+ case '#':
+ case '%':
+ appendEscape(aSynAbsURIRef, '%', *p);
+ break;
+
+ default:
+ aSynAbsURIRef.append(*p);
+ break;
+ }
+ break;
+ }
+
+ case FSYS_UNX:
+ {
+ sal_Unicode const * p = pFSysBegin;
+ if (p != pFSysEnd && *p != '/')
+ return false;
+ for (; p != pFSysEnd; ++p)
+ switch (*p)
+ {
+ case '|':
+ case '#':
+ case '%':
+ appendEscape(aSynAbsURIRef, '%', *p);
+ break;
+
+ default:
+ aSynAbsURIRef.append(*p);
+ break;
+ }
+ break;
+ }
+
+ case FSYS_DOS:
+ {
+ sal_uInt32 nAltDelimiter = 0x80000000;
+ sal_Unicode const * p = pFSysBegin;
+ if (pFSysEnd - p >= 3 && p[0] == '\\' && p[1] == '\\')
+ p += 2;
+ else
+ {
+ aSynAbsURIRef.append(sal_Unicode('/'));
+ if (pFSysEnd - p >= 2
+ && INetMIME::isAlpha(p[0])
+ && p[1] == ':'
+ && (pFSysEnd - p == 2 || p[2] == '\\' || p[2] == '/'))
+ nAltDelimiter = '/';
+ }
+ for (; p != pFSysEnd; ++p)
+ if (*p == '\\' || *p == nAltDelimiter)
+ aSynAbsURIRef.append(sal_Unicode('/'));
+ else
+ switch (*p)
+ {
+ case '/':
+ case '#':
+ case '%':
+ appendEscape(aSynAbsURIRef, '%', *p);
+ break;
+
+ default:
+ aSynAbsURIRef.append(*p);
+ break;
+ }
+ break;
+ }
+
+ case FSYS_MAC:
+ aSynAbsURIRef.append(sal_Unicode('/'));
+ {for (sal_Unicode const * p = pFSysBegin; p != pFSysEnd; ++p)
+ switch (*p)
+ {
+ case ':':
+ aSynAbsURIRef.append(sal_Unicode('/'));
+ break;
+
+ case '/':
+ case '|':
+ case '#':
+ case '%':
+ appendEscape(aSynAbsURIRef, '%', *p);
+ break;
+
+ default:
+ aSynAbsURIRef.append(*p);
+ break;
+ }
+ }
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+
+ INetURLObject aTemp(aSynAbsURIRef.makeStringAndClear(), WAS_ENCODED,
+ RTL_TEXTENCODING_UTF8);
+ if (aTemp.HasError())
+ return false;
+
+ *this = aTemp;
+ return true;
+}
+
+//============================================================================
+rtl::OUString INetURLObject::getFSysPath(FSysStyle eStyle,
+ sal_Unicode * pDelimiter) const
+{
+ if (m_eScheme != INET_PROT_FILE)
+ return rtl::OUString();
+
+ if ((eStyle & FSYS_VOS ? 1 : 0)
+ + (eStyle & FSYS_UNX ? 1 : 0)
+ + (eStyle & FSYS_DOS ? 1 : 0)
+ + (eStyle & FSYS_MAC ? 1 : 0)
+ > 1)
+ {
+ eStyle = eStyle & FSYS_VOS
+ && m_aHost.isPresent()
+ && m_aHost.getLength() > 0 ?
+ FSYS_VOS :
+ hasDosVolume(eStyle)
+ || ((eStyle & FSYS_DOS) != 0
+ && m_aHost.isPresent()
+ && m_aHost.getLength() > 0) ?
+ FSYS_DOS :
+ eStyle & FSYS_UNX
+ && (!m_aHost.isPresent() || m_aHost.getLength() == 0) ?
+ FSYS_UNX :
+ FSysStyle(0);
+ }
+
+ switch (eStyle)
+ {
+ case FSYS_VOS:
+ {
+ if (pDelimiter)
+ *pDelimiter = '/';
+
+ rtl::OUStringBuffer aSynFSysPath;
+ aSynFSysPath.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ if (m_aHost.isPresent() && m_aHost.getLength() > 0)
+ aSynFSysPath.append(decode(m_aHost, '%', DECODE_WITH_CHARSET,
+ RTL_TEXTENCODING_UTF8));
+ else
+ aSynFSysPath.append(sal_Unicode('.'));
+ aSynFSysPath.append(decode(m_aPath, '%', DECODE_WITH_CHARSET,
+ RTL_TEXTENCODING_UTF8));
+ return aSynFSysPath.makeStringAndClear();
+ }
+
+ case FSYS_UNX:
+ {
+ if (m_aHost.isPresent() && m_aHost.getLength() > 0)
+ return rtl::OUString();
+
+ if (pDelimiter)
+ *pDelimiter = '/';
+
+ return decode(m_aPath, '%', DECODE_WITH_CHARSET,
+ RTL_TEXTENCODING_UTF8);
+ }
+
+ case FSYS_DOS:
+ {
+ if (pDelimiter)
+ *pDelimiter = '\\';
+
+ rtl::OUStringBuffer aSynFSysPath;
+ if (m_aHost.isPresent() && m_aHost.getLength() > 0)
+ {
+ aSynFSysPath.appendAscii(RTL_CONSTASCII_STRINGPARAM("\\\\"));
+ aSynFSysPath.append(decode(m_aHost, '%', DECODE_WITH_CHARSET,
+ RTL_TEXTENCODING_UTF8));
+ aSynFSysPath.append(sal_Unicode('\\'));
+ }
+ sal_Unicode const * p
+ = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ sal_Unicode const * pEnd = p + m_aPath.getLength();
+ DBG_ASSERT(p < pEnd && *p == '/',
+ "INetURLObject::getFSysPath(): Bad path");
+ ++p;
+ while (p < pEnd)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(p, pEnd, false, '%', WAS_ENCODED,
+ RTL_TEXTENCODING_UTF8,
+ eEscapeType);
+ if (eEscapeType == ESCAPE_NO && nUTF32 == '/')
+ aSynFSysPath.append(sal_Unicode('\\'));
+ else
+ aSynFSysPath.appendUtf32(nUTF32);
+ }
+ return aSynFSysPath.makeStringAndClear();
+ }
+
+ case FSYS_MAC:
+ {
+ if (m_aHost.isPresent() && m_aHost.getLength() > 0)
+ return rtl::OUString();
+
+ if (pDelimiter)
+ *pDelimiter = ':';
+
+ rtl::OUStringBuffer aSynFSysPath;
+ sal_Unicode const * p
+ = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ sal_Unicode const * pEnd = p + m_aPath.getLength();
+ DBG_ASSERT(p < pEnd && *p == '/',
+ "INetURLObject::getFSysPath(): Bad path");
+ ++p;
+ while (p < pEnd)
+ {
+ EscapeType eEscapeType;
+ sal_uInt32 nUTF32 = getUTF32(p, pEnd, false, '%', WAS_ENCODED,
+ RTL_TEXTENCODING_UTF8,
+ eEscapeType);
+ if (eEscapeType == ESCAPE_NO && nUTF32 == '/')
+ aSynFSysPath.append(sal_Unicode(':'));
+ else
+ aSynFSysPath.appendUtf32(nUTF32);
+ }
+ return aSynFSysPath.makeStringAndClear();
+ }
+
+ default:
+ return rtl::OUString();
+ }
+}
+
+//============================================================================
+bool INetURLObject::HasMsgId() const
+{
+ if (m_eScheme != INET_PROT_POP3)
+ return false;
+ sal_Unicode const * p = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ sal_Unicode const * pEnd = p + m_aPath.getLength();
+ for (; p < pEnd; ++p)
+ if (*p == '<')
+ return true;
+ return false;
+}
+
+//============================================================================
+rtl::OUString INetURLObject::GetMsgId(DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset) const
+{
+ if (m_eScheme != INET_PROT_POP3)
+ return rtl::OUString();
+ sal_Unicode const * p = m_aAbsURIRef.getStr() + m_aPath.getBegin();
+ sal_Unicode const * pEnd = p + m_aPath.getLength();
+ for (; p < pEnd; ++p)
+ if (*p == '<')
+ return decode(p, pEnd, getEscapePrefix(), eMechanism, eCharset);
+ return rtl::OUString();
+}
+
+//============================================================================
+// static
+void INetURLObject::appendUCS4Escape(rtl::OUStringBuffer & rTheText,
+ sal_Char cEscapePrefix, sal_uInt32 nUCS4)
+{
+ DBG_ASSERT(nUCS4 < 0x80000000,
+ "INetURLObject::appendUCS4Escape(): Bad char");
+ if (nUCS4 < 0x80)
+ appendEscape(rTheText, cEscapePrefix, nUCS4);
+ else if (nUCS4 < 0x800)
+ {
+ appendEscape(rTheText, cEscapePrefix, nUCS4 >> 6 | 0xC0);
+ appendEscape(rTheText, cEscapePrefix, (nUCS4 & 0x3F) | 0x80);
+ }
+ else if (nUCS4 < 0x10000)
+ {
+ appendEscape(rTheText, cEscapePrefix, nUCS4 >> 12 | 0xE0);
+ appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 6 & 0x3F) | 0x80);
+ appendEscape(rTheText, cEscapePrefix, (nUCS4 & 0x3F) | 0x80);
+ }
+ else if (nUCS4 < 0x200000)
+ {
+ appendEscape(rTheText, cEscapePrefix, nUCS4 >> 18 | 0xF0);
+ appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 12 & 0x3F) | 0x80);
+ appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 6 & 0x3F) | 0x80);
+ appendEscape(rTheText, cEscapePrefix, (nUCS4 & 0x3F) | 0x80);
+ }
+ else if (nUCS4 < 0x4000000)
+ {
+ appendEscape(rTheText, cEscapePrefix, nUCS4 >> 24 | 0xF8);
+ appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 18 & 0x3F) | 0x80);
+ appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 12 & 0x3F) | 0x80);
+ appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 6 & 0x3F) | 0x80);
+ appendEscape(rTheText, cEscapePrefix, (nUCS4 & 0x3F) | 0x80);
+ }
+ else
+ {
+ appendEscape(rTheText, cEscapePrefix, nUCS4 >> 30 | 0xFC);
+ appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 24 & 0x3F) | 0x80);
+ appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 18 & 0x3F) | 0x80);
+ appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 12 & 0x3F) | 0x80);
+ appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 6 & 0x3F) | 0x80);
+ appendEscape(rTheText, cEscapePrefix, (nUCS4 & 0x3F) | 0x80);
+ }
+}
+
+//============================================================================
+// static
+void INetURLObject::appendUCS4(rtl::OUStringBuffer& rTheText, sal_uInt32 nUCS4,
+ EscapeType eEscapeType, bool bOctets,
+ Part ePart, sal_Char cEscapePrefix,
+ rtl_TextEncoding eCharset,
+ bool bKeepVisibleEscapes)
+{
+ bool bEscape;
+ rtl_TextEncoding eTargetCharset = RTL_TEXTENCODING_DONTKNOW;
+ switch (eEscapeType)
+ {
+ case ESCAPE_NO:
+ if (mustEncode(nUCS4, ePart))
+ {
+ bEscape = true;
+ eTargetCharset = bOctets ? RTL_TEXTENCODING_ISO_8859_1 :
+ RTL_TEXTENCODING_UTF8;
+ }
+ else
+ bEscape = false;
+ break;
+
+ case ESCAPE_OCTET:
+ bEscape = true;
+ eTargetCharset = RTL_TEXTENCODING_ISO_8859_1;
+ break;
+
+ case ESCAPE_UTF32:
+ if (mustEncode(nUCS4, ePart))
+ {
+ bEscape = true;
+ eTargetCharset = eCharset;
+ }
+ else if (bKeepVisibleEscapes && INetMIME::isVisible(nUCS4))
+ {
+ bEscape = true;
+ eTargetCharset = RTL_TEXTENCODING_ASCII_US;
+ }
+ else
+ bEscape = false;
+ break;
+ default:
+ bEscape = false;
+ }
+
+ if (bEscape)
+ {
+ switch (eTargetCharset)
+ {
+ default:
+ DBG_ERROR("INetURLObject::appendUCS4(): Unsupported charset");
+ case RTL_TEXTENCODING_ASCII_US:
+ case RTL_TEXTENCODING_ISO_8859_1:
+ appendEscape(rTheText, cEscapePrefix, nUCS4);
+ break;
+
+ case RTL_TEXTENCODING_UTF8:
+ appendUCS4Escape(rTheText, cEscapePrefix, nUCS4);
+ break;
+ }
+ }
+ else
+ rTheText.append(sal_Unicode(nUCS4));
+}
+
+//============================================================================
+// static
+sal_uInt32 INetURLObject::getUTF32(sal_Unicode const *& rBegin,
+ sal_Unicode const * pEnd, bool bOctets,
+ sal_Char cEscapePrefix,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ EscapeType & rEscapeType)
+{
+ DBG_ASSERT(rBegin < pEnd, "INetURLObject::getUTF32(): Bad sequence");
+ sal_uInt32 nUTF32 = bOctets ? *rBegin++ :
+ INetMIME::getUTF32Character(rBegin, pEnd);
+ switch (eMechanism)
+ {
+ case ENCODE_ALL:
+ rEscapeType = ESCAPE_NO;
+ break;
+
+ case WAS_ENCODED:
+ {
+ int nWeight1;
+ int nWeight2;
+ if (nUTF32 == sal_uChar(cEscapePrefix) && rBegin + 1 < pEnd
+ && (nWeight1 = INetMIME::getHexWeight(rBegin[0])) >= 0
+ && (nWeight2 = INetMIME::getHexWeight(rBegin[1])) >= 0)
+ {
+ rBegin += 2;
+ nUTF32 = nWeight1 << 4 | nWeight2;
+ switch (eCharset)
+ {
+ default:
+ DBG_ERROR(
+ "INetURLObject::getUTF32(): Unsupported charset");
+ case RTL_TEXTENCODING_ASCII_US:
+ rEscapeType = INetMIME::isUSASCII(nUTF32) ?
+ ESCAPE_UTF32 : ESCAPE_OCTET;
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_1:
+ rEscapeType = ESCAPE_UTF32;
+ break;
+
+ case RTL_TEXTENCODING_UTF8:
+ if (INetMIME::isUSASCII(nUTF32))
+ rEscapeType = ESCAPE_UTF32;
+ else
+ {
+ if (nUTF32 >= 0xC0 && nUTF32 <= 0xF4)
+ {
+ sal_uInt32 nEncoded;
+ int nShift;
+ sal_uInt32 nMin;
+ if (nUTF32 <= 0xDF)
+ {
+ nEncoded = (nUTF32 & 0x1F) << 6;
+ nShift = 0;
+ nMin = 0x80;
+ }
+ else if (nUTF32 <= 0xEF)
+ {
+ nEncoded = (nUTF32 & 0x0F) << 12;
+ nShift = 6;
+ nMin = 0x800;
+ }
+ else
+ {
+ nEncoded = (nUTF32 & 0x07) << 18;
+ nShift = 12;
+ nMin = 0x10000;
+ }
+ sal_Unicode const * p = rBegin;
+ bool bUTF8 = true;
+ for (;;)
+ {
+ if (pEnd - p < 3
+ || p[0] != cEscapePrefix
+ || (nWeight1
+ = INetMIME::getHexWeight(p[1]))
+ < 8
+ || nWeight1 > 11
+ || (nWeight2
+ = INetMIME::getHexWeight(p[2]))
+ < 0)
+ {
+ bUTF8 = false;
+ break;
+ }
+ p += 3;
+ nEncoded
+ |= ((nWeight1 & 3) << 4 | nWeight2)
+ << nShift;
+ if (nShift == 0)
+ break;
+ nShift -= 6;
+ }
+ if (bUTF8 && nEncoded >= nMin
+ && !INetMIME::isHighSurrogate(nEncoded)
+ && !INetMIME::isLowSurrogate(nEncoded)
+ && nEncoded <= 0x10FFFF)
+ {
+ rBegin = p;
+ nUTF32 = nEncoded;
+ rEscapeType = ESCAPE_UTF32;
+ break;
+ }
+ }
+ rEscapeType = ESCAPE_OCTET;
+ }
+ break;
+ }
+ }
+ else
+ rEscapeType = ESCAPE_NO;
+ break;
+ }
+
+ case NOT_CANONIC:
+ {
+ int nWeight1;
+ int nWeight2;
+ if (nUTF32 == sal_uChar(cEscapePrefix) && rBegin + 1 < pEnd
+ && ((nWeight1 = INetMIME::getHexWeight(rBegin[0])) >= 0)
+ && ((nWeight2 = INetMIME::getHexWeight(rBegin[1])) >= 0))
+ {
+ rBegin += 2;
+ nUTF32 = nWeight1 << 4 | nWeight2;
+ rEscapeType = ESCAPE_OCTET;
+ }
+ else
+ rEscapeType = ESCAPE_NO;
+ break;
+ }
+ }
+ return nUTF32;
+}
+
+//============================================================================
+// static
+sal_uInt32 INetURLObject::scanDomain(sal_Unicode const *& rBegin,
+ sal_Unicode const * pEnd,
+ bool bEager)
+{
+ enum State { STATE_DOT, STATE_LABEL, STATE_HYPHEN };
+ State eState = STATE_DOT;
+ sal_Int32 nLabels = 0;
+ sal_Unicode const * pLastAlphanumeric = 0;
+ for (sal_Unicode const * p = rBegin;; ++p)
+ switch (eState)
+ {
+ case STATE_DOT:
+ if (p != pEnd && (INetMIME::isAlphanumeric(*p) || *p == '_'))
+ {
+ ++nLabels;
+ eState = STATE_LABEL;
+ break;
+ }
+ if (bEager || nLabels == 0)
+ return 0;
+ rBegin = p - 1;
+ return nLabels;
+
+ case STATE_LABEL:
+ if (p != pEnd)
+ {
+ if (INetMIME::isAlphanumeric(*p) || *p == '_')
+ break;
+ else if (*p == '.')
+ {
+ eState = STATE_DOT;
+ break;
+ }
+ else if (*p == '-')
+ {
+ pLastAlphanumeric = p;
+ eState = STATE_HYPHEN;
+ break;
+ }
+ }
+ rBegin = p;
+ return nLabels;
+
+ case STATE_HYPHEN:
+ if (p != pEnd)
+ {
+ if (INetMIME::isAlphanumeric(*p) || *p == '_')
+ {
+ eState = STATE_LABEL;
+ break;
+ }
+ else if (*p == '-')
+ break;
+ }
+ if (bEager)
+ return 0;
+ rBegin = pLastAlphanumeric;
+ return nLabels;
+ }
+}
+
+//============================================================================
+// static
+bool INetURLObject::scanIPv6reference(sal_Unicode const *& rBegin,
+ sal_Unicode const * pEnd)
+{
+ if (rBegin != pEnd && *rBegin == '[') {
+ sal_Unicode const * p = rBegin + 1;
+ //TODO: check for valid IPv6address (RFC 2373):
+ while (p != pEnd && (INetMIME::isHexDigit(*p) || *p == ':' || *p == '.'))
+ {
+ ++p;
+ }
+ if (p != pEnd && *p == ']') {
+ rBegin = p + 1;
+ return true;
+ }
+ }
+ return false;
+}
+
+//============================================================================
+rtl::OUString INetURLObject::GetPartBeforeLastName(DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+ const
+{
+ if (!checkHierarchical())
+ return rtl::OUString();
+ INetURLObject aTemp(*this);
+ aTemp.clearFragment();
+ aTemp.clearQuery();
+ aTemp.removeSegment(LAST_SEGMENT, false);
+ aTemp.setFinalSlash();
+ return aTemp.GetMainURL(eMechanism, eCharset);
+}
+
+//============================================================================
+rtl::OUString INetURLObject::GetLastName(DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset) const
+{
+ return getName(LAST_SEGMENT, true, eMechanism, eCharset);
+}
+
+//============================================================================
+rtl::OUString INetURLObject::GetFileExtension(DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset) const
+{
+ return getExtension(LAST_SEGMENT, false, eMechanism, eCharset);
+}
+
+//============================================================================
+bool INetURLObject::CutLastName()
+{
+ INetURLObject aTemp(*this);
+ aTemp.clearFragment();
+ aTemp.clearQuery();
+ if (!aTemp.removeSegment(LAST_SEGMENT, false))
+ return false;
+ *this = aTemp;
+ return true;
+}
+
+//============================================================================
+rtl::OUString INetURLObject::PathToFileName() const
+{
+ if (m_eScheme != INET_PROT_FILE)
+ return rtl::OUString();
+ rtl::OUString aSystemPath;
+ if (osl::FileBase::getSystemPathFromFileURL(
+ decode(m_aAbsURIRef.getStr(),
+ m_aAbsURIRef.getStr() + m_aPath.getEnd(),
+ getEscapePrefix(), NO_DECODE, RTL_TEXTENCODING_UTF8),
+ aSystemPath)
+ != osl::FileBase::E_None)
+ return rtl::OUString();
+ return aSystemPath;
+}
+
+//============================================================================
+rtl::OUString INetURLObject::GetFull() const
+{
+ INetURLObject aTemp(*this);
+ aTemp.removeFinalSlash();
+ return aTemp.PathToFileName();
+}
+
+//============================================================================
+rtl::OUString INetURLObject::GetPath() const
+{
+ INetURLObject aTemp(*this);
+ aTemp.removeSegment(LAST_SEGMENT, true);
+ aTemp.removeFinalSlash();
+ return aTemp.PathToFileName();
+}
+
+//============================================================================
+void INetURLObject::SetBase(rtl::OUString const & rTheBase)
+{
+ setBase(rTheBase, LAST_SEGMENT, true, ENCODE_ALL);
+}
+
+//============================================================================
+rtl::OUString INetURLObject::GetBase() const
+{
+ return getBase(LAST_SEGMENT, true, DECODE_WITH_CHARSET);
+}
+
+//============================================================================
+void INetURLObject::SetName(rtl::OUString const & rTheName,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ INetURLObject aTemp(*this);
+ if (aTemp.removeSegment(LAST_SEGMENT, true)
+ && aTemp.insertName(rTheName, false, LAST_SEGMENT, true, eMechanism,
+ eCharset))
+ *this = aTemp;
+}
+
+//============================================================================
+rtl::OUString INetURLObject::CutName(DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ rtl::OUString aTheName(getName(LAST_SEGMENT, true, eMechanism, eCharset));
+ return removeSegment(LAST_SEGMENT, true) ? aTheName : rtl::OUString();
+}
+
+//============================================================================
+void INetURLObject::SetExtension(rtl::OUString const & rTheExtension,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ setExtension(rTheExtension, LAST_SEGMENT, false, eMechanism, eCharset);
+}
+
+//============================================================================
+rtl::OUString INetURLObject::CutExtension(DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ rtl::OUString aTheExtension(getExtension(LAST_SEGMENT, false, eMechanism,
+ eCharset));
+ return removeExtension(LAST_SEGMENT, false)
+ ? aTheExtension : rtl::OUString();
+}
+
+//============================================================================
+bool INetURLObject::IsCaseSensitive() const
+{
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/wldcrd.cxx b/tools/source/fsys/wldcrd.cxx
new file mode 100644
index 000000000000..183f07d3d6fb
--- /dev/null
+++ b/tools/source/fsys/wldcrd.cxx
@@ -0,0 +1,146 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <tools/wldcrd.hxx>
+
+/*************************************************************************
+|*
+|* WildCard::Match()
+|*
+|* Beschreibung WLDCRD.SDW
+|* Ersterstellung MA 19.06.91
+|* Letzte Aenderung MA 03.07.91
+|*
+*************************************************************************/
+
+/* Diese Methode ueberprueft, ob die Wilde Karte in pWild mit dem String
+ * in pStr matscht.
+ * Vertragen sich die beiden, so wird 1 zurueckgegeben, sonst 0.
+ *
+ * ein '*' in pWild bedeutet n beliebige Zeichen, mit n>=0
+ * ein '?' in pWild bedeutet genau ein beliebiges Zeichen
+ *
+ */
+
+USHORT WildCard::ImpMatch( const char *pWild, const char *pStr ) const
+{
+ int pos=0;
+ int flag=0;
+
+ while ( *pWild || flag )
+ {
+ switch (*pWild)
+ {
+ case '?':
+ if ( *pStr == '\0' )
+ return 0;
+ break;
+
+ default:
+ if ( (*pWild == '\\') && ((*(pWild+1)=='?') || (*(pWild+1) == '*')) )
+ pWild++;
+ if ( *pWild != *pStr )
+ if ( !pos )
+ return 0;
+ else
+ pWild += pos;
+ else
+ break; // ACHTUNG laeuft unter bestimmten
+ // Umstaenden in den nachsten case rein!!
+ case '*':
+ while ( *pWild == '*' )
+ pWild++;
+ if ( *pWild == '\0' )
+ return 1;
+ flag = 1;
+ pos = 0;
+ if ( *pStr == '\0' )
+ return ( *pWild == '\0' );
+ while ( *pStr && *pStr != *pWild )
+ {
+ if ( *pWild == '?' ) {
+ pWild++;
+ while ( *pWild == '*' )
+ pWild++;
+ }
+ pStr++;
+ if ( *pStr == '\0' )
+ return ( *pWild == '\0' );
+ }
+ break;
+ }
+ if ( *pWild != '\0' )
+ pWild++;
+ if ( *pStr != '\0' )
+ pStr++;
+ else
+ flag = 0;
+ if ( flag )
+ pos--;
+ }
+ return ( *pStr == '\0' ) && ( *pWild == '\0' );
+}
+
+/*************************************************************************
+|*
+|* WildCard::Matches()
+|*
+|* Beschreibung WLDCRD.SDW
+|* Ersterstellung MA 19.06.91
+|* Letzte Aenderung TH 02.02.96
+|*
+*************************************************************************/
+
+BOOL WildCard::Matches( const String& rString ) const
+{
+ ByteString aTmpWild = aWildString;
+ ByteString aString(rString, osl_getThreadTextEncoding());
+
+ USHORT nSepPos;
+
+ if ( cSepSymbol != '\0' )
+ {
+ while ( (nSepPos = aTmpWild.Search( cSepSymbol )) != STRING_NOTFOUND )
+ {
+ // alle getrennten WildCard's pruefen
+ if ( ImpMatch( aTmpWild.Copy( 0, nSepPos ).GetBuffer(), aString.GetBuffer() ) )
+ return TRUE;
+ aTmpWild.Erase( 0, nSepPos + 1 ); // Trennsymbol entfernen
+ }
+ // und noch den hinter dem letzen Trennsymbol bzw. den einzigen
+ }
+
+ if ( ImpMatch( aTmpWild.GetBuffer(), aString.GetBuffer() ) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/wntmsc.cxx b/tools/source/fsys/wntmsc.cxx
new file mode 100644
index 000000000000..4d78b575cfdc
--- /dev/null
+++ b/tools/source/fsys/wntmsc.cxx
@@ -0,0 +1,1083 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#ifdef _MSC_VER
+#pragma warning (push,1)
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#include <limits.h>
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+
+#include "wntmsc.hxx"
+#include <tools/errinf.hxx>
+#include <tools/debug.hxx>
+#include <tools/list.hxx>
+#include <tools/wldcrd.hxx>
+#include <tools/fsys.hxx>
+#include <tools/bigint.hxx>
+
+DECLARE_LIST( DirEntryList, DirEntry* );
+DECLARE_LIST( FSysSortList, FSysSort* );
+DECLARE_LIST( FileStatList, FileStat* );
+
+int Sys2SolarError_Impl( int nSysErr );
+
+static BOOL bLastCaseSensitive = FALSE;
+
+//--------------------------------------------------------------------
+
+ByteString Upper_Impl( const ByteString &rStr )
+{
+ ByteString aRet( rStr.GetBuffer() ); // es muss ein neuer String entstehen!
+ CharUpperBuff( (char*) aRet.GetBuffer(), aRet.Len() );
+ return aRet;
+}
+
+//--------------------------------------------------------------------
+
+DIR *opendir( const char* pPfad )
+{
+ DIR *pDir = new DIR;
+ if ( pDir )
+ pDir->p = (char*) pPfad;
+ return pDir;
+}
+
+struct dirent *readdir( DIR *pDir )
+{
+ bool bOk = false;
+ if ( pDir->p )
+ {
+ char *pBuf = new char[ strlen( pDir->p ) + 5 ];
+ if ( pBuf )
+ {
+ // *.* dahinter, ggf mit "\\" abtrennen (falls nicht schon da)
+ strcpy( pBuf, pDir->p );
+ strcat( pBuf, "\\*.*" + ( *(pBuf + strlen( pBuf ) - 1 ) == '\\' ) );
+ CharUpperBuff( pBuf, strlen(pBuf) );
+ pDir->h = FindFirstFile( pBuf, &pDir->aDirEnt );
+ bOk = pDir->h != INVALID_HANDLE_VALUE;
+ pDir->p = NULL;
+ delete [] pBuf;
+ }
+ else
+ pDir->h = INVALID_HANDLE_VALUE;
+ }
+ else
+ {
+ bOk = FindNextFile( pDir->h, &pDir->aDirEnt );
+ }
+
+ return bOk ? &pDir->aDirEnt : NULL;
+}
+
+int closedir( DIR *pDir )
+{
+ BOOL bOk = FALSE;
+ if ( pDir )
+ {
+ bOk = 0 != pDir->p || FindClose( pDir->h );
+ delete pDir;
+ }
+ return bOk;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::GetPathStyle() const
+|*
+|* Beschreibung
+|* Ersterstellung MI 11.05.95
+|* Letzte Aenderung MI 11.05.95
+|*
+*************************************************************************/
+
+ErrCode GetPathStyle_Impl( const String &rDevice, FSysPathStyle &rStyle )
+{
+ ByteString aRootDir(rDevice, osl_getThreadTextEncoding());
+ if ( aRootDir.Len() && aRootDir.GetBuffer()[aRootDir.Len()-1] != '\\' )
+ aRootDir += '\\';
+
+ char sVolumeName[256];
+ char sFileSysName[16];
+ DWORD nSerial[2];
+ DWORD nMaxCompLen[2];
+ DWORD nFlags[2];
+
+ // Windows95 hat VFAT, WindowsNT nicht
+ DWORD nVer = GetVersion();
+ BOOL bW95 = ( nVer & 0xFF ) >= 4;
+
+ FSysFailOnErrorImpl();
+ rStyle = FSYS_STYLE_UNKNOWN;
+ if ( GetVolumeInformation(
+ (char*) aRootDir.GetBuffer(),
+ sVolumeName, 256, (LPDWORD) &nSerial, (LPDWORD) &nMaxCompLen,
+ (LPDWORD) &nFlags, sFileSysName, 16 ) )
+ {
+ // FAT/VFAT?
+ if ( 0 == strcmp( "FAT", sFileSysName ) )
+ rStyle = bW95 ? FSYS_STYLE_VFAT : FSYS_STYLE_FAT;
+
+ // NTFS?
+ else if ( 0 == strcmp( "NTFS", sFileSysName ) )
+ rStyle = FSYS_STYLE_NTFS;
+
+ // HPFS?
+ else if ( 0 == strcmp( "HPFS", sFileSysName ) )
+ rStyle = FSYS_STYLE_HPFS;
+
+ // NWCOMPA/NWFS?
+ else if ( 0 == strncmp( "NW", sFileSysName, 2 ) )
+ rStyle = FSYS_STYLE_NWFS;
+
+ return ERRCODE_NONE;
+ }
+
+ return ERRCODE_IO_INVALIDDEVICE;
+}
+
+FSysPathStyle DirEntry::GetPathStyle( const String &rDevice )
+{
+
+ FSysPathStyle eStyle;
+ GetPathStyle_Impl( rDevice, eStyle );
+ return eStyle;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::IsCaseSensitive()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 10.06.93
+|* Letzte Aenderung TPF 26.02.1999
+|*
+*************************************************************************/
+
+BOOL DirEntry::IsCaseSensitive( FSysPathStyle eFormatter ) const
+{
+
+ if (eFormatter==FSYS_STYLE_HOST)
+ {
+/*
+ DirEntry aRoot(*this);
+ aRoot.ToAbs();
+ aRoot = aRoot[Level()-1];
+ String aRootDir = aRoot.GetFull(FSYS_STYLE_HOST, TRUE);
+
+ char sVolumeName[256];
+ DWORD nVolumeSerial;
+ DWORD nMaxCompLen;
+ DWORD nFlags;
+ char sFileSysName[16];
+
+ if ( GetVolumeInformation( (char*) aRootDir.GetStr(),
+ sVolumeName,
+ 256,
+ (LPDWORD) &nVolumeSerial,
+ (LPDWORD) &nMaxCompLen,
+ (LPDWORD) &nFlags,
+ sFileSysName,
+ 16 ))
+ {
+ return (nFlags & FS_CASE_SENSITIVE) ? TRUE : FALSE;
+ }
+ else
+ {
+ return FALSE;
+ }
+*/
+ //
+ // guter versuch, aber FS_CASE_SENSITIVE ist D?nnsinn in T?ten:
+ //
+ // sFileSysName FS_CASE_SENSITIVE
+ // FAT FALSE
+ // NTFS TRUE !!!
+ // NWCompat FALSE
+ // Samba FALSE
+ //
+ // NT spricht auch NTFS lediglich case preserving an, also ist unter NT alles case insensitiv
+ //
+
+ return FALSE;
+ }
+ else
+ {
+ BOOL isCaseSensitive = FALSE; // ich bin unter win32, also ist der default case insensitiv
+ switch ( eFormatter )
+ {
+ case FSYS_STYLE_MAC:
+ case FSYS_STYLE_FAT:
+ case FSYS_STYLE_VFAT:
+ case FSYS_STYLE_NTFS:
+ case FSYS_STYLE_NWFS:
+ case FSYS_STYLE_HPFS:
+ case FSYS_STYLE_DETECT:
+ {
+ isCaseSensitive = FALSE;
+ break;
+ }
+ case FSYS_STYLE_SYSV:
+ case FSYS_STYLE_BSD:
+ {
+ isCaseSensitive = TRUE;
+ break;
+ }
+ default:
+ {
+ isCaseSensitive = FALSE; // ich bin unter win32, also ist der default case insensitiv
+ break;
+ }
+ }
+ return isCaseSensitive;
+ }
+}
+
+/*************************************************************************
+|*
+|* DirEntry::ToAbs()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+BOOL DirEntry::ToAbs()
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ if ( FSYS_FLAG_VOLUME == eFlag )
+ {
+ eFlag = FSYS_FLAG_ABSROOT;
+ return TRUE;
+ }
+
+ if ( IsAbs() )
+ {
+ return TRUE;
+ }
+
+
+ char sBuf[256];
+ char *pOld;
+ ByteString aFullName( GetFull(), osl_getThreadTextEncoding() );
+ FSysFailOnErrorImpl();
+ if ( GetFullPathName((char*)aFullName.GetBuffer(),256,sBuf,&pOld) > 511 )
+ return FALSE;
+
+ *this = DirEntry( String(sBuf, osl_getThreadTextEncoding() ));
+ return TRUE;
+}
+
+
+/*************************************************************************
+|*
+|* DirEntry::GetVolume()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 27.08.92
+|* Letzte Aenderung MI 28.08.92
+|*
+*************************************************************************/
+
+String DirEntry::GetVolume() const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ String aRet;
+ const DirEntry *pTop = ImpGetTopPtr();
+ ByteString aName = ByteString( pTop->aName ).ToLowerAscii();
+
+ if ( ( pTop->eFlag == FSYS_FLAG_ABSROOT ||
+ pTop->eFlag == FSYS_FLAG_RELROOT ||
+ pTop->eFlag == FSYS_FLAG_VOLUME )
+ && aName != "a:" && aName != "b:" && Exists() )
+ {
+ char sFileSysName[256];
+ char sVolumeName[256];
+ DWORD nVolumeNameLen = 256;
+ DWORD nSerial[2];
+ DWORD nMaxCompLen[2];
+ DWORD nFlags[2];
+ ByteString aRootDir = pTop->aName;
+ FSysFailOnErrorImpl();
+
+ // Network-Device zuerst probieren wegen langsamer Samba-Drives
+ if ( !WNetGetConnection( (char*) aRootDir.GetBuffer(),
+ sVolumeName, &nVolumeNameLen ) )
+ aRet = String( sVolumeName, osl_getThreadTextEncoding());
+
+ // dann den VolumeNamen fuer lokale Drives
+ if ( aRet.Len() == 0 )
+ {
+ aRootDir += "\\";
+ if ( GetVolumeInformation( (char*) aRootDir.GetBuffer(),
+ sVolumeName, 256,
+ (LPDWORD) &nSerial, (LPDWORD) &nMaxCompLen,
+ (LPDWORD) &nFlags, sFileSysName, 256 ) )
+ aRet = String( sVolumeName, osl_getThreadTextEncoding());
+ }
+ }
+
+ return aRet;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::SetCWD()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MI 21.05.92
+|*
+*************************************************************************/
+
+BOOL DirEntry::SetCWD( BOOL bSloppy ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ FSysFailOnErrorImpl();
+
+ if ( eFlag == FSYS_FLAG_CURRENT && !aName.Len() )
+ return TRUE;
+
+ if ( SetCurrentDirectory(ByteString(GetFull(), osl_getThreadTextEncoding()).GetBuffer()) )
+ {
+ return TRUE;
+ }
+
+ if ( bSloppy && pParent &&
+ SetCurrentDirectory(ByteString(pParent->GetFull(), osl_getThreadTextEncoding()).GetBuffer()) )
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+//-------------------------------------------------------------------------
+
+USHORT DirReader_Impl::Init()
+{
+ // Block-Devices auflisten?
+ if ( pDir->eAttrMask & FSYS_KIND_BLOCK )
+ {
+ // CWD merken
+ DirEntry aCurrentDir;
+ aCurrentDir.ToAbs();
+
+ // einzeln auf Existenz und Masken-konformit"at pr"ufen
+ USHORT nRead = 0;
+ char sDrive[3] = { '?', ':', 0 };
+ char sRoot[4] = { '?', ':', '\\', 0 };
+ for ( char c = 'a'; c <= 'z'; c++ )
+ {
+ sDrive[0] = c;
+ sRoot[0] = c;
+ DirEntry* pDrive = new DirEntry( sDrive, FSYS_FLAG_VOLUME, FSYS_STYLE_HOST );
+ if ( pDir->aNameMask.Matches( String( ByteString(sDrive), osl_getThreadTextEncoding())) && GetDriveType( sRoot ) != 1 )
+ {
+ if ( pDir->pStatLst ) //Status fuer Sort gewuenscht?
+ {
+ FileStat *pNewStat = new FileStat( *pDrive );
+ pDir->ImpSortedInsert( pDrive, pNewStat );
+ }
+ else
+ pDir->ImpSortedInsert( pDrive, NULL );
+ ++nRead;
+ }
+ else
+ delete pDrive;
+ }
+
+ // CWD restaurieren
+ aCurrentDir.SetCWD();
+ return nRead;
+ }
+
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+USHORT DirReader_Impl::Read()
+{
+ // Directories und Files auflisten?
+ if ( ( pDir->eAttrMask & FSYS_KIND_DIR ||
+ pDir->eAttrMask & FSYS_KIND_FILE ) &&
+ ( ( pDosEntry = readdir( pDosDir ) ) != NULL ) )
+ {
+ // Gross/Kleinschreibung nicht beruecksichtigen
+ ByteString aLowerName = pDosEntry->d_name;
+ CharLowerBuff( (char*) aLowerName.GetBuffer(), aLowerName.Len() );
+
+ // Flags pruefen
+ BOOL bIsDirAndWantsDir =
+ ( ( pDir->eAttrMask & FSYS_KIND_DIR ) &&
+#ifdef ICC
+ ( pDosEntry->d_type & ( strcmp(pDosEntry->d_name,".") ||
+ strcmp(pDosEntry->d_name,"..")) ) );
+#else
+ ( pDosEntry->d_type & DOS_DIRECT ) );
+#endif
+ BOOL bIsFileAndWantsFile =
+ ( ( pDir->eAttrMask & FSYS_KIND_FILE ) &&
+#ifdef ICC
+ !( pDosEntry->d_type & ( strcmp(pDosEntry->d_name,".") ||
+ strcmp(pDosEntry->d_name,"..")) ) &&
+#else
+ !( pDosEntry->d_type & DOS_DIRECT ) &&
+#endif
+ !( pDosEntry->d_type & DOS_VOLUMEID ) );
+ BOOL bIsHidden = (pDosEntry->d_type & _A_HIDDEN) != 0;
+ BOOL bWantsHidden = 0 == ( pDir->eAttrMask & FSYS_KIND_VISIBLE );
+ if ( ( bIsDirAndWantsDir || bIsFileAndWantsFile ) &&
+ ( bWantsHidden || !bIsHidden ) &&
+ pDir->aNameMask.Matches( String(aLowerName, osl_getThreadTextEncoding()) ) )
+ {
+#ifdef DBG_UTIL
+ DbgOutf( "%s %s flags:%x found",
+ pDosEntry->d_name,
+ bIsFileAndWantsFile ? "file" : "dir",
+ pDosEntry->d_type );
+#endif
+ DirEntryFlag eFlag =
+ 0 == strcmp( pDosEntry->d_name, "." ) ? FSYS_FLAG_CURRENT
+ : 0 == strcmp( pDosEntry->d_name, ".." ) ? FSYS_FLAG_PARENT
+ : FSYS_FLAG_NORMAL;
+ DirEntry *pTemp = new DirEntry( ByteString(pDosEntry->d_name),
+ eFlag, FSYS_STYLE_NTFS );
+#ifdef FEAT_FSYS_DOUBLESPEED
+ pTemp->ImpSetStat( new FileStat( (void*) pDosDir, (void*) 0 ) );
+#endif
+ if ( pParent )
+ pTemp->ImpChangeParent( new DirEntry( *pParent ), FALSE );
+ if ( pDir->pStatLst ) //Status fuer Sort gewuenscht?
+ {
+ FileStat *pNewStat = new FileStat( (void*) pDosDir, (void*) 0 );
+ pDir->ImpSortedInsert( pTemp, pNewStat );
+ }
+ else
+ pDir->ImpSortedInsert( pTemp, NULL );
+ return 1;
+ }
+#ifdef DBG_UTIL
+ else
+ DbgOutf( "%s flags:%x skipped",
+ pDosEntry->d_name,
+ pDosEntry->d_type );
+#endif
+
+ }
+ else
+ bReady = TRUE;
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* InitFileStat()
+|*
+|* Beschreibung gemeinsamer Teil der Ctoren fuer FileStat
+|* Ersterstellung MI 28.08.92
+|* Letzte Aenderung MI 28.08.92
+|*
+*************************************************************************/
+
+void FileStat::ImpInit( void* p )
+{
+ _WIN32_FIND_DATAA *pDirEnt = (_WIN32_FIND_DATAA*) p;
+
+ nError = FSYS_ERR_OK;
+ nSize = pDirEnt->nFileSizeLow;
+
+ SYSTEMTIME aSysTime;
+ FILETIME aLocTime;
+
+ // use the last write date / time when the creation date / time isn't set
+ if ( ( pDirEnt->ftCreationTime.dwLowDateTime == 0 ) &&
+ ( pDirEnt->ftCreationTime.dwHighDateTime == 0 ) )
+ {
+ pDirEnt->ftCreationTime.dwLowDateTime = pDirEnt->ftLastWriteTime.dwLowDateTime;
+ pDirEnt->ftCreationTime.dwHighDateTime = pDirEnt->ftLastWriteTime.dwHighDateTime;
+ }
+
+ // use the last write date / time when the last accessed date / time isn't set
+ if ( ( pDirEnt->ftLastAccessTime.dwLowDateTime == 0 ) &&
+ ( pDirEnt->ftLastAccessTime.dwHighDateTime == 0 ) )
+ {
+ pDirEnt->ftLastAccessTime.dwLowDateTime = pDirEnt->ftLastWriteTime.dwLowDateTime;
+ pDirEnt->ftLastAccessTime.dwHighDateTime = pDirEnt->ftLastWriteTime.dwHighDateTime;
+ }
+
+ FileTimeToLocalFileTime( &pDirEnt->ftCreationTime, &aLocTime );
+ FileTimeToSystemTime( &aLocTime, &aSysTime );
+ aDateCreated = Date( aSysTime.wDay, aSysTime.wMonth, aSysTime.wYear );
+ aTimeCreated = Time( aSysTime.wHour, aSysTime.wMinute,
+ aSysTime.wSecond, 0 );
+
+ FileTimeToLocalFileTime( &pDirEnt->ftLastWriteTime, &aLocTime );
+ FileTimeToSystemTime( &aLocTime, &aSysTime );
+ aDateModified = Date( aSysTime.wDay, aSysTime.wMonth, aSysTime.wYear );
+ aTimeModified = Time( aSysTime.wHour, aSysTime.wMinute,
+ aSysTime.wSecond, 0 );
+
+ FileTimeToLocalFileTime( &pDirEnt->ftLastAccessTime, &aLocTime );
+ FileTimeToSystemTime( &aLocTime, &aSysTime );
+ aDateAccessed = Date( aSysTime.wDay, aSysTime.wMonth, aSysTime.wYear );
+ aTimeAccessed = Time( aSysTime.wHour, aSysTime.wMinute,
+ aSysTime.wSecond, 0 );
+
+ nKindFlags = FSYS_KIND_FILE;
+ if ( pDirEnt->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
+ nKindFlags = FSYS_KIND_DIR;
+}
+
+/*************************************************************************
+|*
+|* FileStat::FileStat()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 27.08.92
+|* Letzte Aenderung MI 28.08.92
+|*
+*************************************************************************/
+
+FileStat::FileStat( const void *pInfo, // struct dirent
+ const void * ): // dummy
+ aDateCreated(0),
+ aTimeCreated(0),
+ aDateModified(0),
+ aTimeModified(0),
+ aDateAccessed(0),
+ aTimeAccessed(0)
+{
+ ImpInit( ( (dirent*) pInfo ) );
+}
+
+/*************************************************************************
+|*
+|* FileStat::Update()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 27.08.92
+|* Letzte Aenderung MI 28.08.92
+|*
+*************************************************************************/
+
+#ifdef _MSC_VER
+#pragma warning(push, 1)
+#pragma warning(disable: 4917)
+#endif
+#include <shlobj.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#ifdef UNICODE
+#define lstrchr wcschr
+#define lstrncmp wcsncmp
+#else
+#define lstrchr strchr
+#define lstrncmp strncmp
+#endif
+
+//---------------------------------------------------------------------------
+
+void SHFreeMem( void *p )
+{
+ LPMALLOC pMalloc = NULL;
+
+ if ( SUCCEEDED(SHGetMalloc(&pMalloc)) )
+ {
+ pMalloc->Free( p );
+ pMalloc->Release();
+ }
+}
+
+//---------------------------------------------------------------------------
+
+HRESULT SHGetIDListFromPath( HWND hwndOwner, LPCTSTR pszPath, LPITEMIDLIST *ppidl )
+{
+ if ( IsBadWritePtr(ppidl, sizeof(LPITEMIDLIST)) )
+ return E_INVALIDARG;
+
+ LPSHELLFOLDER pDesktopFolder = NULL;
+
+ HRESULT hResult = SHGetDesktopFolder( &pDesktopFolder );
+ if ( FAILED(hResult) )
+ return hResult;
+
+ ULONG chEaten = lstrlen( pszPath );
+ DWORD dwAttributes = FILE_ATTRIBUTE_DIRECTORY;
+
+#ifdef UNICODE
+ LPOLESTR wszPath = pszPath;
+#else
+ WCHAR wszPath[MAX_PATH];
+ MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pszPath, -1, wszPath, MAX_PATH );
+#endif
+
+ hResult = pDesktopFolder->ParseDisplayName( hwndOwner, (LPBC)NULL, wszPath, &chEaten, ppidl, &dwAttributes );
+ pDesktopFolder->Release();
+
+ return hResult;
+}
+
+//---------------------------------------------------------------------------
+
+HRESULT SHGetFolderFromIDList( LPCITEMIDLIST pidl, LPSHELLFOLDER *ppFolder )
+{
+ if ( IsBadWritePtr(ppFolder, sizeof(LPSHELLFOLDER)) )
+ return E_INVALIDARG;
+
+ *ppFolder = NULL;
+
+ LPSHELLFOLDER pDesktopFolder = NULL;
+
+ HRESULT hResult = SHGetDesktopFolder( &pDesktopFolder );
+ if ( FAILED(hResult) )
+ return hResult;
+
+ hResult = pDesktopFolder->BindToObject( pidl, (LPBC)NULL, IID_IShellFolder, (LPVOID *)ppFolder );
+ pDesktopFolder->Release();
+
+ return hResult;
+}
+
+//---------------------------------------------------------------------------
+
+HRESULT SHResolvePath( HWND hwndOwner, LPCTSTR pszPath, LPITEMIDLIST *ppidl )
+{
+ // If hwndOwner is NULL, use the desktop window, because dialogs need a parent
+
+#ifdef BOOTSTRAP
+ return NO_ERROR;
+#else
+ if ( !hwndOwner )
+ hwndOwner = GetDesktopWindow();
+
+ HRESULT hResult = NOERROR;
+ LPTSTR pszPathCopy;
+ LPTSTR pszTrailingPath;
+ TCHAR cBackup = 0;
+
+ // First make a copy of the path
+
+ pszPathCopy = new TCHAR[lstrlen(pszPath) + 1];
+ if ( pszPathCopy )
+ lstrcpy( pszPathCopy, pszPath );
+ else
+ return E_OUTOFMEMORY;
+
+ // Determine the first token
+
+ if ( !lstrncmp( pszPathCopy, "\\\\", 2 ) )
+ pszTrailingPath = lstrchr( pszPathCopy + 2, '\\' );
+ else
+ pszTrailingPath = lstrchr( pszPathCopy, '\\' );
+
+ // Now scan the path tokens
+
+ while ( SUCCEEDED(hResult) )
+ {
+ if ( pszTrailingPath )
+ {
+ cBackup = *(++pszTrailingPath);
+ *pszTrailingPath = 0;
+ }
+
+ LPITEMIDLIST pidl = NULL;
+
+ // Make item ID list from leading path
+
+ hResult = SHGetIDListFromPath( hwndOwner, pszPathCopy, &pidl );
+
+ // if path exists try to open it as folder
+
+ if ( SUCCEEDED(hResult) )
+ {
+ // Only open the folder if it was not the last token
+
+ if ( pszTrailingPath )
+ {
+ LPSHELLFOLDER pFolder;
+
+ // Create a folder instance
+ hResult = SHGetFolderFromIDList( pidl, &pFolder);
+
+ // Is it a folder ?
+ if ( SUCCEEDED(hResult) )
+ {
+ // No try to instantiate an enumerator.
+ // This should popup a login dialog if any
+
+ LPENUMIDLIST pEnum = NULL;
+
+ hResult = pFolder->EnumObjects( hwndOwner,
+ SHCONTF_NONFOLDERS | SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN,
+ &pEnum );
+
+ // Release the enumerator interface
+ if ( SUCCEEDED(hResult) )
+ pEnum->Release();
+
+ // Release the folder interface
+ pFolder->Release();
+ }
+
+ SHFreeMem( pidl );
+ }
+ else // It was the last token
+ {
+ if ( ppidl )
+ *ppidl = pidl;
+ else
+ SHFreeMem( pidl );
+ }
+ }
+
+
+ // Forward to next token
+
+ if ( pszTrailingPath )
+ {
+ *pszTrailingPath = cBackup;
+ pszTrailingPath = lstrchr( pszTrailingPath, '\\' );
+ }
+ else
+ break;
+ }
+
+ // Free the working copy of the path
+ delete pszPathCopy;
+
+ // NOERROR or OLE error code
+ return hResult;
+#endif
+}
+
+//---------------------------------------------------------------------------
+// The Wrapper
+//---------------------------------------------------------------------------
+
+BOOL Exists_Impl( const ByteString & crPath )
+{
+ // We do not know if OLE was initialized for this thread
+
+ CoInitialize( NULL );
+
+ BOOL bSuccess = SUCCEEDED( SHResolvePath(NULL, crPath.GetBuffer(), NULL) );
+
+ CoUninitialize();
+
+ return bSuccess;
+}
+
+//---------------------------------------------------------------------------
+
+BOOL FileStat::Update( const DirEntry& rDirEntry, BOOL bForceAccess )
+{
+ nSize = 0;
+ nKindFlags = 0;
+ aCreator.Erase();
+ aType.Erase();
+ aDateCreated = Date(0);
+ aTimeCreated = Time(0);
+ aDateModified = Date(0);
+ aTimeModified = Time(0);
+ aDateAccessed = Date(0);
+ aTimeAccessed = Time(0);
+
+ if ( !rDirEntry.IsValid() )
+ {
+ nError = FSYS_ERR_UNKNOWN;
+ nKindFlags = 0;
+ return FALSE;
+ }
+
+ // Sonderbehandlung falls es sich um eine Root ohne Laufwerk handelt
+
+ if ( !rDirEntry.aName.Len() && rDirEntry.eFlag == FSYS_FLAG_ABSROOT )
+ {
+ nKindFlags = FSYS_KIND_DIR;
+ nError = FSYS_ERR_OK;
+ return TRUE;
+ }
+
+ // keine Error-Boxen anzeigen
+ FSysFailOnErrorImpl();
+
+ // Redirect
+ String aPath( rDirEntry.GetFull() );
+#ifndef BOOTSTRAP
+ FSysRedirector::DoRedirect( aPath );
+#endif
+ DirEntry aDirEntry( aPath );
+
+ // ist ein Medium im Laufwerk?
+ HACK("wie?")
+ BOOL bAccess = TRUE;
+ const DirEntry *pTop = aDirEntry.ImpGetTopPtr();
+ ByteString aName = ByteString(pTop->aName).ToLowerAscii();
+ if ( !bForceAccess &&
+ ( pTop->eFlag == FSYS_FLAG_ABSROOT ||
+ pTop->eFlag == FSYS_FLAG_RELROOT ||
+ pTop->eFlag == FSYS_FLAG_VOLUME ) )
+ if ( aName == "a:" || aName == "b:" )
+ bAccess = FALSE;
+ else
+ DBG_TRACE( "FSys: will access removable device!" );
+ if ( bAccess && ( aName == "a:" || aName == "b:" ) ) {
+ DBG_WARNING( "floppy will clatter" );
+ }
+
+ // Sonderbehandlung, falls es sich um ein Volume handelt
+ if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME ||
+ aDirEntry.eFlag == FSYS_FLAG_ABSROOT )
+ {
+ if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME )
+ nKindFlags = FSYS_KIND_DEV | ( aDirEntry.aName.Len() == 2
+ ? FSYS_KIND_BLOCK
+ : FSYS_KIND_CHAR );
+ else
+ nKindFlags = FSYS_KIND_DIR;
+
+ if ( !bAccess )
+ {
+ if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME )
+ nKindFlags |= FSYS_KIND_REMOVEABLE;
+ nError = FSYS_ERR_NOTEXISTS;
+ nKindFlags = 0;
+ return FALSE;
+ }
+
+ ByteString aRootDir = aDirEntry.aName;
+ aRootDir += ByteString( "\\" );
+ UINT nType = GetDriveType( (char *) aRootDir.GetBuffer() ); //TPF: 2i
+ if ( nType == 1 || nType == 0 )
+ {
+ nError = FSYS_ERR_NOTEXISTS;
+ nKindFlags = 0;
+ return FALSE;
+ }
+
+ if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME )
+ nKindFlags = nKindFlags |
+ ( ( nType == DRIVE_REMOVABLE ) ? FSYS_KIND_REMOVEABLE : 0 ) |
+ ( ( nType == DRIVE_FIXED ) ? FSYS_KIND_FIXED : 0 ) |
+ ( ( nType == DRIVE_REMOTE ) ? FSYS_KIND_REMOTE : 0 ) |
+ ( ( nType == DRIVE_RAMDISK ) ? FSYS_KIND_RAM : 0 ) |
+ ( ( nType == DRIVE_CDROM ) ? FSYS_KIND_CDROM : 0 ) |
+ ( ( nType == 0 ) ? FSYS_KIND_UNKNOWN : 0 );
+
+ nError = ERRCODE_NONE;
+
+ return TRUE;
+ }
+
+ // Statusinformation vom Betriebssystem holen
+ HANDLE h; //()
+ _WIN32_FIND_DATAA aEntry = {};
+ DirEntry aAbsEntry( aDirEntry );
+ if ( bAccess && aAbsEntry.ToAbs() )
+ {
+ // im Namen k"onnen auch ';*?' als normale Zeichen vorkommen
+ ByteString aFilePath( aAbsEntry.GetFull(), osl_getThreadTextEncoding() );
+
+ // MI: dann gehen Umlaute auf Novell-Servern nicht / wozu ueberhaupt
+ // CharUpperBuff( (char*) aFilePath.GetStr(), aFilePath.Len() );
+ DBG_TRACE1( "FileStat: %s", aFilePath.GetBuffer() );
+ h = aFilePath.Len() < 230
+ // die Win32-API ist hier sehr schwammig
+ ? FindFirstFile( (char *) aFilePath.GetBuffer(), &aEntry )//TPF: 2i
+ : INVALID_HANDLE_VALUE;
+
+ if ( INVALID_HANDLE_VALUE != h )
+ {
+ if ( !( aEntry.dwFileAttributes & 0x40 ) ) // com1: etc. e.g. not encrypted (means normal)
+ {
+ ByteString aUpperName = Upper_Impl(ByteString(aAbsEntry.GetName(), osl_getThreadTextEncoding()));
+
+ // HRO: #74051# Compare also with short alternate filename
+ if ( aUpperName != Upper_Impl( aEntry.cFileName ) && aUpperName != Upper_Impl( aEntry.cAlternateFileName ) )
+ h = INVALID_HANDLE_VALUE;
+ }
+ }
+
+ if ( INVALID_HANDLE_VALUE == h )
+ {
+ DWORD dwError = GetLastError();
+
+ if ( ERROR_BAD_NET_NAME == dwError )
+ {
+ nKindFlags = FSYS_KIND_UNKNOWN;
+ nError = FSYS_ERR_NOTEXISTS;
+ return FALSE;
+ }
+
+ // UNC-Volume?
+ DirEntry *pTop = aAbsEntry.ImpGetTopPtr();
+ if ( pTop->GetFlag() == FSYS_FLAG_ABSROOT &&
+ ( pTop->aName.Len() > 1 && (pTop->aName.GetBuffer()[1] != ':' )) )
+ {
+ if ( bForceAccess )
+ {
+ if ( Exists_Impl( aFilePath ) )
+ {
+ nKindFlags = FSYS_KIND_DIR|FSYS_KIND_REMOTE;
+ nError = FSYS_ERR_OK;
+ return TRUE;
+ }
+ else
+ {
+ nKindFlags = FSYS_KIND_UNKNOWN;
+ nError = FSYS_ERR_NOTEXISTS;
+ return FALSE;
+ }
+ }
+ }
+ }
+ }
+ else
+ h = INVALID_HANDLE_VALUE;
+
+ if ( h == INVALID_HANDLE_VALUE )
+ {
+ // Sonderbehandlung falls es sich um eine Wildcard handelt
+ ByteString aTempName( aDirEntry.GetName(), osl_getThreadTextEncoding() );
+ if ( strchr( aTempName.GetBuffer(), '?' ) ||
+ strchr( aTempName.GetBuffer(), '*' ) ||
+ strchr( aTempName.GetBuffer(), ';' ) )
+ {
+ nKindFlags = FSYS_KIND_WILD;
+ nError = FSYS_ERR_OK;
+ return TRUE;
+ }
+
+ if ( bAccess )
+ {
+ nError = FSYS_ERR_NOTEXISTS;
+ nKindFlags = FSYS_KIND_UNKNOWN;
+ }
+ else
+ nKindFlags = FSYS_KIND_REMOVEABLE;
+ }
+ else
+ {
+ ImpInit( &aEntry );
+ FindClose( h );
+ }
+
+ if ( 0 != nError )
+ nKindFlags = 0;
+
+ return 0 == nError;
+
+}
+
+BOOL IsRedirectable_Impl( const ByteString &rPath )
+{
+ if ( rPath.Len() >= 3 && ':' == rPath.GetBuffer()[1] )
+ {
+ ByteString aVolume = rPath.Copy( 0, 3 );
+ UINT nType = GetDriveType( (char *) aVolume.GetBuffer() );
+ SetLastError( ERROR_SUCCESS );
+ return DRIVE_FIXED != nType;
+ }
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* TempDirImpl()
+|*
+|* Beschreibung liefert den Namens des Directories fuer temporaere
+|* Dateien
+|* Ersterstellung MI 16.03.94
+|* Letzte Aenderung MI 16.03.94
+|*
+*************************************************************************/
+
+const char* TempDirImpl( char *pBuf )
+{
+ if ( !GetTempPath( MAX_PATH, pBuf ) &&
+ !GetWindowsDirectory( pBuf, MAX_PATH ) &&
+ !GetEnvironmentVariable( "HOMEPATH", pBuf, MAX_PATH ) )
+ return 0;
+
+ return pBuf;
+}
+
+//=======================================================================
+
+ErrCode FileStat::QueryDiskSpace( const String &rPath,
+ BigInt &rFreeBytes, BigInt &rTotalBytes )
+{
+ DWORD nSectorsPerCluster; /* address of sectors per cluster */
+ DWORD nBytesPerSector; /* address of bytes per sector */
+ DWORD nFreeClusters; /* address of number of free clusters */
+ DWORD nClusters; /* address of total number of clusters */
+
+ ByteString aVol( DirEntry(rPath).ImpGetTopPtr()->GetName(), osl_getThreadTextEncoding());
+ bool bOK = GetDiskFreeSpace( aVol.GetBuffer(),
+ &nSectorsPerCluster, &nBytesPerSector,
+ &nFreeClusters, &nClusters );
+ if ( !bOK )
+ return Sys2SolarError_Impl( GetLastError() );
+
+ BigInt aBytesPerCluster( BigInt(nSectorsPerCluster) *
+ BigInt(nBytesPerSector) );
+ rFreeBytes = aBytesPerCluster * BigInt(nFreeClusters);
+ rTotalBytes = aBytesPerCluster * BigInt(nClusters);
+ return 0;
+}
+
+//=========================================================================
+
+void FSysEnableSysErrorBox( BOOL bEnable )
+{ // Preserve other Bits!!
+ sal_uInt32 nErrorMode = SetErrorMode( bEnable ? 0 : SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX );
+ if ( bEnable )
+ nErrorMode &= ~(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
+ else
+ nErrorMode |= (SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
+ SetErrorMode( nErrorMode );
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/wntmsc.hxx b/tools/source/fsys/wntmsc.hxx
new file mode 100644
index 000000000000..b4226a70ec08
--- /dev/null
+++ b/tools/source/fsys/wntmsc.hxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _dosmsc_hxx
+#define _dosmsc_hxx
+
+#include <string.h>
+
+#ifndef ICC
+#include <io.h>
+#endif
+#include <sys\types.h>
+#include <sys\stat.h>
+#include <direct.h>
+
+#include <tools/svwin.h>
+#ifdef _MSC_VER
+#pragma warning (push,1)
+#endif
+#include <winbase.h>
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+#include <tools/solar.h>
+
+#include <tools/string.hxx>
+
+//--------------------------------------------------------------------
+
+#define FSYS_UNIX FALSE
+
+#define DOS_DIRECT _A_SUBDIR
+#define DOS_VOLUMEID 0x08
+#ifndef S_IFBLK
+#define S_IFBLK 0x6000
+#endif
+#define setdrive(n,a) _chdrive(n)
+#define GETDRIVE(n) (n = _getdrive())
+
+#define dirent _WIN32_FIND_DATAA
+#define d_name cFileName
+#define d_type dwFileAttributes
+
+#if defined (TCPP) || defined (tcpp)
+#define _mkdir mkdir
+#define _rmdir rmdir
+#define _chdir chdir
+#define _unlink unlink
+#define _getcwd getcwd
+#define _access access
+#endif
+
+typedef struct
+{
+ _WIN32_FIND_DATAA aDirEnt;
+ HANDLE h;
+ const char *p;
+} DIR;
+
+#define PATHDELIMITER ";"
+#define DEFSTYLE FSYS_STYLE_NTFS
+#define MKDIR( p ) mkdir( p )
+#define CMP_LOWER(s) ( ByteString(s).ToLowerAscii() )
+
+#define START_DRV 'a'
+
+inline BOOL DRIVE_EXISTS(char c)
+{
+ ByteString aDriveRoot( c );
+ aDriveRoot += ":\\";
+ return GetDriveType( aDriveRoot.GetBuffer() ) > 1;
+}
+
+const char* TempDirImpl( char *pBuf );
+
+#define FSysFailOnErrorImpl()
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/generic/b3dtrans.cxx b/tools/source/generic/b3dtrans.cxx
new file mode 100644
index 000000000000..434dafbf1c30
--- /dev/null
+++ b/tools/source/generic/b3dtrans.cxx
@@ -0,0 +1,1017 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <tools/b3dtrans.hxx>
+#include <tools/debug.hxx>
+
+/*************************************************************************
+|*
+|* Transformationen fuer alle 3D Ausgaben
+|*
+\************************************************************************/
+
+B3dTransformationSet::B3dTransformationSet()
+{
+ Reset();
+}
+
+B3dTransformationSet::~B3dTransformationSet()
+{
+}
+
+void B3dTransformationSet::Orientation(basegfx::B3DHomMatrix& rTarget, basegfx::B3DPoint aVRP, basegfx::B3DVector aVPN, basegfx::B3DVector aVUP)
+{
+ rTarget.translate( -aVRP.getX(), -aVRP.getY(), -aVRP.getZ());
+ aVUP.normalize();
+ aVPN.normalize();
+ basegfx::B3DVector aRx(aVUP);
+ basegfx::B3DVector aRy(aVPN);
+ aRx = aRx.getPerpendicular(aRy);
+ aRx.normalize();
+ aRy = aRy.getPerpendicular(aRx);
+ aRy.normalize();
+ basegfx::B3DHomMatrix aTemp;
+ aTemp.set(0, 0, aRx.getX());
+ aTemp.set(0, 1, aRx.getY());
+ aTemp.set(0, 2, aRx.getZ());
+ aTemp.set(1, 0, aRy.getX());
+ aTemp.set(1, 1, aRy.getY());
+ aTemp.set(1, 2, aRy.getZ());
+ aTemp.set(2, 0, aVPN.getX());
+ aTemp.set(2, 1, aVPN.getY());
+ aTemp.set(2, 2, aVPN.getZ());
+ rTarget *= aTemp;
+}
+
+void B3dTransformationSet::Frustum(basegfx::B3DHomMatrix& rTarget, double fLeft, double fRight, double fBottom, double fTop, double fNear, double fFar)
+{
+ if(!(fNear > 0.0))
+ {
+ fNear = 0.001;
+ }
+ if(!(fFar > 0.0))
+ {
+ fFar = 1.0;
+ }
+ if(fNear == fFar)
+ {
+ fFar = fNear + 1.0;
+ }
+ if(fLeft == fRight)
+ {
+ fLeft -= 1.0;
+ fRight += 1.0;
+ }
+ if(fTop == fBottom)
+ {
+ fBottom -= 1.0;
+ fTop += 1.0;
+ }
+ basegfx::B3DHomMatrix aTemp;
+
+ aTemp.set(0, 0, 2.0 * fNear / (fRight - fLeft));
+ aTemp.set(1, 1, 2.0 * fNear / (fTop - fBottom));
+ aTemp.set(0, 2, (fRight + fLeft) / (fRight - fLeft));
+ aTemp.set(1, 2, (fTop + fBottom) / (fTop - fBottom));
+ aTemp.set(2, 2, -1.0 * ((fFar + fNear) / (fFar - fNear)));
+ aTemp.set(3, 2, -1.0);
+ aTemp.set(2, 3, -1.0 * ((2.0 * fFar * fNear) / (fFar - fNear)));
+ aTemp.set(3, 3, 0.0);
+
+ rTarget *= aTemp;
+}
+
+void B3dTransformationSet::Ortho(basegfx::B3DHomMatrix& rTarget, double fLeft, double fRight, double fBottom, double fTop, double fNear, double fFar)
+{
+ if(fNear == fFar)
+ {
+ DBG_ERROR("Near and far clipping plane in Ortho definition are identical");
+ fFar = fNear + 1.0;
+ }
+ if(fLeft == fRight)
+ {
+ DBG_ERROR("Left and right in Ortho definition are identical");
+ fLeft -= 1.0;
+ fRight += 1.0;
+ }
+ if(fTop == fBottom)
+ {
+ DBG_ERROR("Top and bottom in Ortho definition are identical");
+ fBottom -= 1.0;
+ fTop += 1.0;
+ }
+ basegfx::B3DHomMatrix aTemp;
+
+ aTemp.set(0, 0, 2.0 / (fRight - fLeft));
+ aTemp.set(1, 1, 2.0 / (fTop - fBottom));
+ aTemp.set(2, 2, -1.0 * (2.0 / (fFar - fNear)));
+ aTemp.set(0, 3, -1.0 * ((fRight + fLeft) / (fRight - fLeft)));
+ aTemp.set(1, 3, -1.0 * ((fTop + fBottom) / (fTop - fBottom)));
+ aTemp.set(2, 3, -1.0 * ((fFar + fNear) / (fFar - fNear)));
+
+ rTarget *= aTemp;
+}
+
+/*************************************************************************
+|*
+|* Reset der Werte
+|*
+\************************************************************************/
+
+void B3dTransformationSet::Reset()
+{
+ // Matritzen auf Einheitsmatritzen
+ maObjectTrans.identity();
+ PostSetObjectTrans();
+
+ Orientation(maOrientation);
+ PostSetOrientation();
+
+ maTexture.identity();
+
+ mfLeftBound = mfBottomBound = -1.0;
+ mfRightBound = mfTopBound = 1.0;
+ mfNearBound = 0.001;
+ mfFarBound = 1.001;
+
+ meRatio = Base3DRatioGrow;
+ mfRatio = 0.0;
+
+ maViewportRectangle = Rectangle(-1, -1, 2, 2);
+ maVisibleRectangle = maViewportRectangle;
+
+ mbPerspective = sal_True;
+
+ mbProjectionValid = sal_False;
+ mbObjectToDeviceValid = sal_False;
+ mbWorldToViewValid = sal_False;
+
+ CalcViewport();
+}
+
+/*************************************************************************
+|*
+|* Objekttransformation
+|*
+\************************************************************************/
+
+void B3dTransformationSet::SetObjectTrans(const basegfx::B3DHomMatrix& rObj)
+{
+ maObjectTrans = rObj;
+
+ mbObjectToDeviceValid = sal_False;
+ mbInvTransObjectToEyeValid = sal_False;
+
+ PostSetObjectTrans();
+}
+
+void B3dTransformationSet::PostSetObjectTrans()
+{
+ // Zuweisen und Inverse bestimmen
+ maInvObjectTrans = maObjectTrans;
+ maInvObjectTrans.invert();
+}
+
+/*************************************************************************
+|*
+|* Orientierungstransformation
+|*
+\************************************************************************/
+
+void B3dTransformationSet::SetOrientation( basegfx::B3DPoint aVRP, basegfx::B3DVector aVPN, basegfx::B3DVector aVUP)
+{
+ maOrientation.identity();
+ Orientation(maOrientation, aVRP, aVPN, aVUP);
+
+ mbInvTransObjectToEyeValid = sal_False;
+ mbObjectToDeviceValid = sal_False;
+ mbWorldToViewValid = sal_False;
+
+ PostSetOrientation();
+}
+
+void B3dTransformationSet::SetOrientation(basegfx::B3DHomMatrix& mOrient)
+{
+ maOrientation = mOrient;
+
+ mbInvTransObjectToEyeValid = sal_False;
+ mbObjectToDeviceValid = sal_False;
+ mbWorldToViewValid = sal_False;
+
+ PostSetOrientation();
+}
+
+void B3dTransformationSet::PostSetOrientation()
+{
+ // Zuweisen und Inverse bestimmen
+ maInvOrientation = maOrientation;
+ maInvOrientation.invert();
+}
+
+/*************************************************************************
+|*
+|* Projektionstransformation
+|*
+\************************************************************************/
+
+void B3dTransformationSet::SetProjection(const basegfx::B3DHomMatrix& mProject)
+{
+ maProjection = mProject;
+ PostSetProjection();
+}
+
+const basegfx::B3DHomMatrix& B3dTransformationSet::GetProjection()
+{
+ if(!mbProjectionValid)
+ CalcViewport();
+ return maProjection;
+}
+
+const basegfx::B3DHomMatrix& B3dTransformationSet::GetInvProjection()
+{
+ if(!mbProjectionValid)
+ CalcViewport();
+ return maInvProjection;
+}
+
+void B3dTransformationSet::PostSetProjection()
+{
+ // Zuweisen und Inverse bestimmen
+ maInvProjection = GetProjection();
+ maInvProjection.invert();
+
+ // Abhaengige Matritzen invalidieren
+ mbObjectToDeviceValid = sal_False;
+ mbWorldToViewValid = sal_False;
+}
+
+/*************************************************************************
+|*
+|* Texturtransformation
+|*
+\************************************************************************/
+
+void B3dTransformationSet::SetTexture(const basegfx::B2DHomMatrix& rTxt)
+{
+ maTexture = rTxt;
+ PostSetTexture();
+}
+
+void B3dTransformationSet::PostSetTexture()
+{
+}
+
+/*************************************************************************
+|*
+|* Viewport-Transformation
+|*
+\************************************************************************/
+
+void B3dTransformationSet::CalcViewport()
+{
+ // Faktoren fuer die Projektion
+ double fLeft(mfLeftBound);
+ double fRight(mfRightBound);
+ double fBottom(mfBottomBound);
+ double fTop(mfTopBound);
+
+ // Soll das Seitenverhaeltnis Beachtung finden?
+ // Falls ja, Bereich der Projektion an Seitenverhaeltnis anpassen
+ if(GetRatio() != 0.0)
+ {
+ // Berechne aktuelles Seitenverhaeltnis der Bounds
+ double fBoundWidth = (double)(maViewportRectangle.GetWidth() + 1);
+ double fBoundHeight = (double)(maViewportRectangle.GetHeight() + 1);
+ double fActRatio = 1;
+ double fFactor;
+
+ if(fBoundWidth != 0.0)
+ fActRatio = fBoundHeight / fBoundWidth;
+ // FIXME else in this case has a lot of problems, should this return.
+
+ switch(meRatio)
+ {
+ case Base3DRatioShrink :
+ {
+ // Kleineren Teil vergroessern
+ if(fActRatio > mfRatio)
+ {
+ // X vergroessern
+ fFactor = 1.0 / fActRatio;
+ fRight *= fFactor;
+ fLeft *= fFactor;
+ }
+ else
+ {
+ // Y vergroessern
+ fFactor = fActRatio;
+ fTop *= fFactor;
+ fBottom *= fFactor;
+ }
+ break;
+ }
+ case Base3DRatioGrow :
+ {
+ // GroesserenTeil verkleinern
+ if(fActRatio > mfRatio)
+ {
+ // Y verkleinern
+ fFactor = fActRatio;
+ fTop *= fFactor;
+ fBottom *= fFactor;
+ }
+ else
+ {
+ // X verkleinern
+ fFactor = 1.0 / fActRatio;
+ fRight *= fFactor;
+ fLeft *= fFactor;
+ }
+ break;
+ }
+ case Base3DRatioMiddle :
+ {
+ // Mitteln
+ fFactor = ((1.0 / fActRatio) + 1.0) / 2.0;
+ fRight *= fFactor;
+ fLeft *= fFactor;
+ fFactor = (fActRatio + 1.0) / 2.0;
+ fTop *= fFactor;
+ fBottom *= fFactor;
+ break;
+ }
+ }
+ }
+
+ // Ueberschneiden sich Darstellungsflaeche und Objektflaeche?
+ maSetBound = maViewportRectangle;
+
+ // Mit den neuen Werten Projektion und ViewPort setzen
+ basegfx::B3DHomMatrix aNewProjection;
+
+ // #i36281#
+ // OpenGL needs a little more rough additional size to not let
+ // the front face vanish. Changed from SMALL_DVALUE to 0.000001,
+ // which is 1/10000th, comared with 1/tenth of a million from SMALL_DVALUE.
+ const double fDistPart((mfFarBound - mfNearBound) * 0.0001);
+
+ // Near, Far etwas grosszuegiger setzen, um falsches,
+ // zu kritisches clippen zu verhindern
+ if(mbPerspective)
+ {
+ Frustum(aNewProjection, fLeft, fRight, fBottom, fTop, mfNearBound - fDistPart, mfFarBound + fDistPart);
+ }
+ else
+ {
+ Ortho(aNewProjection, fLeft, fRight, fBottom, fTop, mfNearBound - fDistPart, mfFarBound + fDistPart);
+ }
+
+ // jetzt schon auf gueltig setzen um Endlosschleife zu vermeiden
+ mbProjectionValid = sal_True;
+
+ // Neue Projektion setzen
+ SetProjection(aNewProjection);
+
+ // fill parameters for ViewportTransformation
+ // Translation
+ maTranslate.setX((double)maSetBound.Left() + ((maSetBound.GetWidth() - 1L) / 2.0));
+ maTranslate.setY((double)maSetBound.Top() + ((maSetBound.GetHeight() - 1L) / 2.0));
+ maTranslate.setZ(ZBUFFER_DEPTH_RANGE / 2.0);
+
+ // Skalierung
+ maScale.setX((maSetBound.GetWidth() - 1L) / 2.0);
+ maScale.setY((maSetBound.GetHeight() - 1L) / -2.0);
+ maScale.setZ(ZBUFFER_DEPTH_RANGE / 2.0);
+
+ // Auf Veraenderung des ViewPorts reagieren
+ PostSetViewport();
+}
+
+void B3dTransformationSet::SetRatio(double fNew)
+{
+ if(mfRatio != fNew)
+ {
+ mfRatio = fNew;
+ mbProjectionValid = sal_False;
+ mbObjectToDeviceValid = sal_False;
+ mbWorldToViewValid = sal_False;
+ }
+}
+
+void B3dTransformationSet::SetRatioMode(Base3DRatio eNew)
+{
+ if(meRatio != eNew)
+ {
+ meRatio = eNew;
+ mbProjectionValid = sal_False;
+ mbObjectToDeviceValid = sal_False;
+ mbWorldToViewValid = sal_False;
+ }
+}
+
+void B3dTransformationSet::SetDeviceRectangle(double fL, double fR, double fB, double fT,
+ sal_Bool bBroadCastChange)
+{
+ if(fL != mfLeftBound || fR != mfRightBound || fB != mfBottomBound || fT != mfTopBound)
+ {
+ mfLeftBound = fL;
+ mfRightBound = fR;
+ mfBottomBound = fB;
+ mfTopBound = fT;
+
+ mbProjectionValid = sal_False;
+ mbObjectToDeviceValid = sal_False;
+ mbWorldToViewValid = sal_False;
+
+ // Aenderung bekanntmachen
+ if(bBroadCastChange)
+ DeviceRectangleChange();
+ }
+}
+
+void B3dTransformationSet::SetDeviceVolume(const basegfx::B3DRange& rVol, sal_Bool bBroadCastChange)
+{
+ SetDeviceRectangle(rVol.getMinX(), rVol.getMaxX(), rVol.getMinY(), rVol.getMaxY(), bBroadCastChange);
+ SetFrontClippingPlane(rVol.getMinZ());
+ SetBackClippingPlane(rVol.getMaxZ());
+}
+
+void B3dTransformationSet::DeviceRectangleChange()
+{
+}
+
+void B3dTransformationSet::GetDeviceRectangle(double &fL, double &fR, double& fB, double& fT)
+{
+ fL = mfLeftBound;
+ fR = mfRightBound;
+ fB = mfBottomBound;
+ fT = mfTopBound;
+
+ mbProjectionValid = sal_False;
+ mbObjectToDeviceValid = sal_False;
+ mbWorldToViewValid = sal_False;
+}
+
+basegfx::B3DRange B3dTransformationSet::GetDeviceVolume()
+{
+ basegfx::B3DRange aRet;
+
+ aRet.expand(basegfx::B3DTuple(mfLeftBound, mfBottomBound, mfNearBound));
+ aRet.expand(basegfx::B3DTuple(mfRightBound, mfTopBound, mfFarBound));
+
+ return aRet;
+}
+
+void B3dTransformationSet::SetFrontClippingPlane(double fF)
+{
+ if(mfNearBound != fF)
+ {
+ mfNearBound = fF;
+ mbProjectionValid = sal_False;
+ mbObjectToDeviceValid = sal_False;
+ mbWorldToViewValid = sal_False;
+ }
+}
+
+void B3dTransformationSet::SetBackClippingPlane(double fB)
+{
+ if(mfFarBound != fB)
+ {
+ mfFarBound = fB;
+ mbProjectionValid = sal_False;
+ mbObjectToDeviceValid = sal_False;
+ mbWorldToViewValid = sal_False;
+ }
+}
+
+void B3dTransformationSet::SetPerspective(sal_Bool bNew)
+{
+ if(mbPerspective != bNew)
+ {
+ mbPerspective = bNew;
+ mbProjectionValid = sal_False;
+ mbObjectToDeviceValid = sal_False;
+ mbWorldToViewValid = sal_False;
+ }
+}
+
+void B3dTransformationSet::SetViewportRectangle(Rectangle& rRect, Rectangle& rVisible)
+{
+ if(rRect != maViewportRectangle || rVisible != maVisibleRectangle)
+ {
+ maViewportRectangle = rRect;
+ maVisibleRectangle = rVisible;
+
+ mbProjectionValid = sal_False;
+ mbObjectToDeviceValid = sal_False;
+ mbWorldToViewValid = sal_False;
+ }
+}
+
+void B3dTransformationSet::PostSetViewport()
+{
+}
+
+const Rectangle& B3dTransformationSet::GetLogicalViewportBounds()
+{
+ if(!mbProjectionValid)
+ CalcViewport();
+ return maSetBound;
+}
+
+const basegfx::B3DVector& B3dTransformationSet::GetScale()
+{
+ if(!mbProjectionValid)
+ CalcViewport();
+ return maScale;
+}
+
+const basegfx::B3DVector& B3dTransformationSet::GetTranslate()
+{
+ if(!mbProjectionValid)
+ CalcViewport();
+ return maTranslate;
+}
+
+/*************************************************************************
+|*
+|* Hilfsmatrixberechnungsroutinen
+|*
+\************************************************************************/
+
+void B3dTransformationSet::CalcMatObjectToDevice()
+{
+ // ObjectToDevice berechnen (Orientation * Projection * Object)
+ maObjectToDevice = maObjectTrans;
+ maObjectToDevice *= maOrientation;
+ maObjectToDevice *= GetProjection();
+
+ // auf gueltig setzen
+ mbObjectToDeviceValid = sal_True;
+}
+
+const basegfx::B3DHomMatrix& B3dTransformationSet::GetObjectToDevice()
+{
+ if(!mbObjectToDeviceValid)
+ CalcMatObjectToDevice();
+ return maObjectToDevice;
+}
+
+void B3dTransformationSet::CalcMatInvTransObjectToEye()
+{
+ maInvTransObjectToEye = maObjectTrans;
+ maInvTransObjectToEye *= maOrientation;
+ maInvTransObjectToEye.invert();
+ maInvTransObjectToEye.transpose();
+
+ // eventuelle Translationen rausschmeissen, da diese
+ // Matrix nur zur Transformation von Vektoren gedacht ist
+ maInvTransObjectToEye.set(3, 0, 0.0);
+ maInvTransObjectToEye.set(3, 1, 0.0);
+ maInvTransObjectToEye.set(3, 2, 0.0);
+ maInvTransObjectToEye.set(3, 3, 1.0);
+
+ // auf gueltig setzen
+ mbInvTransObjectToEyeValid = sal_True;
+}
+
+const basegfx::B3DHomMatrix& B3dTransformationSet::GetInvTransObjectToEye()
+{
+ if(!mbInvTransObjectToEyeValid)
+ CalcMatInvTransObjectToEye();
+ return maInvTransObjectToEye;
+}
+
+basegfx::B3DHomMatrix B3dTransformationSet::GetMatFromObjectToView()
+{
+ basegfx::B3DHomMatrix aFromObjectToView = GetObjectToDevice();
+
+ const basegfx::B3DVector& rScale(GetScale());
+ aFromObjectToView.scale(rScale.getX(), rScale.getY(), rScale.getZ());
+ const basegfx::B3DVector& rTranslate(GetTranslate());
+ aFromObjectToView.translate(rTranslate.getX(), rTranslate.getY(), rTranslate.getZ());
+
+ return aFromObjectToView;
+}
+
+void B3dTransformationSet::CalcMatFromWorldToView()
+{
+ maMatFromWorldToView = maOrientation;
+ maMatFromWorldToView *= GetProjection();
+ const basegfx::B3DVector& rScale(GetScale());
+ maMatFromWorldToView.scale(rScale.getX(), rScale.getY(), rScale.getZ());
+ const basegfx::B3DVector& rTranslate(GetTranslate());
+ maMatFromWorldToView.translate(rTranslate.getX(), rTranslate.getY(), rTranslate.getZ());
+ maInvMatFromWorldToView = maMatFromWorldToView;
+ maInvMatFromWorldToView.invert();
+
+ // gueltig setzen
+ mbWorldToViewValid = sal_True;
+}
+
+const basegfx::B3DHomMatrix& B3dTransformationSet::GetMatFromWorldToView()
+{
+ if(!mbWorldToViewValid)
+ CalcMatFromWorldToView();
+ return maMatFromWorldToView;
+}
+
+const basegfx::B3DHomMatrix& B3dTransformationSet::GetInvMatFromWorldToView()
+{
+ if(!mbWorldToViewValid)
+ CalcMatFromWorldToView();
+ return maInvMatFromWorldToView;
+}
+
+/*************************************************************************
+|*
+|* Direkter Zugriff auf verschiedene Transformationen
+|*
+\************************************************************************/
+
+const basegfx::B3DPoint B3dTransformationSet::WorldToEyeCoor(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec *= GetOrientation();
+ return aVec;
+}
+
+const basegfx::B3DPoint B3dTransformationSet::EyeToWorldCoor(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec *= GetInvOrientation();
+ return aVec;
+}
+
+const basegfx::B3DPoint B3dTransformationSet::EyeToViewCoor(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec *= GetProjection();
+ aVec *= GetScale();
+ aVec += GetTranslate();
+ return aVec;
+}
+
+const basegfx::B3DPoint B3dTransformationSet::ViewToEyeCoor(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec -= GetTranslate();
+ aVec = aVec / GetScale();
+ aVec *= GetInvProjection();
+ return aVec;
+}
+
+const basegfx::B3DPoint B3dTransformationSet::WorldToViewCoor(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec *= GetMatFromWorldToView();
+ return aVec;
+}
+
+const basegfx::B3DPoint B3dTransformationSet::ViewToWorldCoor(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec *= GetInvMatFromWorldToView();
+ return aVec;
+}
+
+const basegfx::B3DPoint B3dTransformationSet::DeviceToViewCoor(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec *= GetScale();
+ aVec += GetTranslate();
+ return aVec;
+}
+
+const basegfx::B3DPoint B3dTransformationSet::ViewToDeviceCoor(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec -= GetTranslate();
+ aVec = aVec / GetScale();
+ return aVec;
+}
+
+const basegfx::B3DPoint B3dTransformationSet::ObjectToWorldCoor(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec *= GetObjectTrans();
+ return aVec;
+}
+
+const basegfx::B3DPoint B3dTransformationSet::WorldToObjectCoor(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec *= GetInvObjectTrans();
+ return aVec;
+}
+
+const basegfx::B3DPoint B3dTransformationSet::ObjectToViewCoor(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec *= GetObjectTrans();
+ aVec *= GetMatFromWorldToView();
+ return aVec;
+}
+
+const basegfx::B3DPoint B3dTransformationSet::ViewToObjectCoor(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec *= GetInvMatFromWorldToView();
+ aVec *= GetInvObjectTrans();
+ return aVec;
+}
+
+const basegfx::B3DPoint B3dTransformationSet::ObjectToEyeCoor(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec *= GetObjectTrans();
+ aVec *= GetOrientation();
+ return aVec;
+}
+
+const basegfx::B3DPoint B3dTransformationSet::EyeToObjectCoor(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec *= GetInvOrientation();
+ aVec *= GetInvObjectTrans();
+ return aVec;
+}
+
+const basegfx::B3DPoint B3dTransformationSet::DeviceToEyeCoor(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec *= GetInvProjection();
+ return aVec;
+}
+
+const basegfx::B3DPoint B3dTransformationSet::EyeToDeviceCoor(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec *= GetProjection();
+ return aVec;
+}
+
+const basegfx::B3DPoint B3dTransformationSet::InvTransObjectToEye(const basegfx::B3DPoint& rVec)
+{
+ basegfx::B3DPoint aVec(rVec);
+ aVec *= GetInvTransObjectToEye();
+ return aVec;
+}
+
+const basegfx::B2DPoint B3dTransformationSet::TransTextureCoor(const basegfx::B2DPoint& rVec)
+{
+ basegfx::B2DPoint aVec(rVec);
+ aVec *= GetTexture();
+ return aVec;
+}
+
+/*************************************************************************
+|*
+|* Konstruktor B3dViewport
+|*
+\************************************************************************/
+
+B3dViewport::B3dViewport()
+: B3dTransformationSet(),
+ aVRP(0, 0, 0),
+ aVPN(0, 0, 1),
+ aVUV(0, 1, 0)
+{
+ CalcOrientation();
+}
+
+B3dViewport::~B3dViewport()
+{
+}
+
+void B3dViewport::SetVRP(const basegfx::B3DPoint& rNewVRP)
+{
+ aVRP = rNewVRP;
+ CalcOrientation();
+}
+
+void B3dViewport::SetVPN(const basegfx::B3DVector& rNewVPN)
+{
+ aVPN = rNewVPN;
+ CalcOrientation();
+}
+
+void B3dViewport::SetVUV(const basegfx::B3DVector& rNewVUV)
+{
+ aVUV = rNewVUV;
+ CalcOrientation();
+}
+
+void B3dViewport::SetViewportValues(
+ const basegfx::B3DPoint& rNewVRP,
+ const basegfx::B3DVector& rNewVPN,
+ const basegfx::B3DVector& rNewVUV)
+{
+ aVRP = rNewVRP;
+ aVPN = rNewVPN;
+ aVUV = rNewVUV;
+ CalcOrientation();
+}
+
+void B3dViewport::CalcOrientation()
+{
+ SetOrientation(aVRP, aVPN, aVUV);
+}
+
+/*************************************************************************
+|*
+|* Konstruktor B3dViewport
+|*
+\************************************************************************/
+
+B3dCamera::B3dCamera(
+ const basegfx::B3DPoint& rPos, const basegfx::B3DVector& rLkAt,
+ double fFocLen, double fBnkAng, sal_Bool bUseFocLen)
+: B3dViewport(),
+ aPosition(rPos),
+ aCorrectedPosition(rPos),
+ aLookAt(rLkAt),
+ fFocalLength(fFocLen),
+ fBankAngle(fBnkAng),
+ bUseFocalLength(bUseFocLen)
+{
+ CalcNewViewportValues();
+}
+
+B3dCamera::~B3dCamera()
+{
+}
+
+void B3dCamera::SetPosition(const basegfx::B3DPoint& rNewPos)
+{
+ if(rNewPos != aPosition)
+ {
+ // Zuweisen
+ aCorrectedPosition = aPosition = rNewPos;
+
+ // Neuberechnung
+ CalcNewViewportValues();
+ }
+}
+
+void B3dCamera::SetLookAt(const basegfx::B3DVector& rNewLookAt)
+{
+ if(rNewLookAt != aLookAt)
+ {
+ // Zuweisen
+ aLookAt = rNewLookAt;
+
+ // Neuberechnung
+ CalcNewViewportValues();
+ }
+}
+
+void B3dCamera::SetPositionAndLookAt(const basegfx::B3DPoint& rNewPos, const basegfx::B3DVector& rNewLookAt)
+{
+ if(rNewPos != aPosition || rNewLookAt != aLookAt)
+ {
+ // Zuweisen
+ aPosition = rNewPos;
+ aLookAt = rNewLookAt;
+
+ // Neuberechnung
+ CalcNewViewportValues();
+ }
+}
+
+void B3dCamera::SetFocalLength(double fLen)
+{
+ if(fLen != fFocalLength)
+ {
+ // Zuweisen
+ if(fLen < 5.0)
+ fLen = 5.0;
+ fFocalLength = fLen;
+
+ // Neuberechnung
+ CalcNewViewportValues();
+ }
+}
+
+void B3dCamera::SetBankAngle(double fAngle)
+{
+ if(fAngle != fBankAngle)
+ {
+ // Zuweisen
+ fBankAngle = fAngle;
+
+ // Neuberechnung
+ CalcNewViewportValues();
+ }
+}
+
+void B3dCamera::SetUseFocalLength(sal_Bool bNew)
+{
+ if(bNew != (sal_Bool)bUseFocalLength)
+ {
+ // Zuweisen
+ bUseFocalLength = bNew;
+
+ // Neuberechnung
+ CalcNewViewportValues();
+ }
+}
+
+void B3dCamera::DeviceRectangleChange()
+{
+ // call parent
+ B3dViewport::DeviceRectangleChange();
+
+ // Auf Aenderung reagieren
+ CalcNewViewportValues();
+}
+
+void B3dCamera::CalcNewViewportValues()
+{
+ basegfx::B3DVector aViewVector(aPosition - aLookAt);
+ basegfx::B3DVector aNewVPN(aViewVector);
+
+ basegfx::B3DVector aNewVUV(0.0, 1.0, 0.0);
+ if(aNewVPN.getLength() < aNewVPN.getY())
+ aNewVUV.setX(0.5);
+
+ aNewVUV.normalize();
+ aNewVPN.normalize();
+
+ basegfx::B3DVector aNewToTheRight = aNewVPN;
+ aNewToTheRight = aNewToTheRight.getPerpendicular(aNewVUV);
+ aNewToTheRight.normalize();
+ aNewVUV = aNewToTheRight.getPerpendicular(aNewVPN);
+ aNewVUV.normalize();
+
+ SetViewportValues(aPosition, aNewVPN, aNewVUV);
+ if(CalcFocalLength())
+ SetViewportValues(aCorrectedPosition, aNewVPN, aNewVUV);
+
+ if(fBankAngle != 0.0)
+ {
+ basegfx::B3DHomMatrix aRotMat;
+ aRotMat.rotate(0.0, 0.0, fBankAngle);
+ basegfx::B3DVector aUp(0.0, 1.0, 0.0);
+ aUp *= aRotMat;
+ aUp = EyeToWorldCoor(aUp);
+ aUp.normalize();
+ SetVUV(aUp);
+ }
+}
+
+sal_Bool B3dCamera::CalcFocalLength()
+{
+ double fWidth = GetDeviceRectangleWidth();
+ sal_Bool bRetval = sal_False;
+
+ if(bUseFocalLength)
+ {
+ // Position aufgrund der FocalLength korrigieren
+ aCorrectedPosition = basegfx::B3DPoint(0.0, 0.0, fFocalLength * fWidth / 35.0);
+ aCorrectedPosition = EyeToWorldCoor(aCorrectedPosition);
+ bRetval = sal_True;
+ }
+ else
+ {
+ // FocalLength anhand der Position anpassen
+ basegfx::B3DPoint aOldPosition;
+ aOldPosition = WorldToEyeCoor(aOldPosition);
+ if(fWidth != 0.0)
+ fFocalLength = aOldPosition.getZ() / fWidth * 35.0;
+ if(fFocalLength < 5.0)
+ fFocalLength = 5.0;
+ }
+ return bRetval;
+}
+
+// eof
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/generic/bigint.cxx b/tools/source/generic/bigint.cxx
new file mode 100644
index 000000000000..02ae5455b3c9
--- /dev/null
+++ b/tools/source/generic/bigint.cxx
@@ -0,0 +1,1144 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <math.h>
+#include <tools/tools.h>
+
+#include <tools/bigint.hxx>
+#include <tools/string.hxx>
+#include <tools/debug.hxx>
+
+#include <string.h>
+#include <ctype.h>
+
+static const long MY_MAXLONG = 0x3fffffff;
+static const long MY_MINLONG = -MY_MAXLONG;
+static const long MY_MAXSHORT = 0x00007fff;
+static const long MY_MINSHORT = -MY_MAXSHORT;
+
+/* Die ganzen Algorithmen zur Addition, Subtraktion, Multiplikation und
+ * Division von langen Zahlen stammen aus SEMINUMERICAL ALGORITHMS von
+ * DONALD E. KNUTH aus der Reihe The Art of Computer Programming. Zu finden
+ * sind diese Algorithmen im Kapitel 4.3.1. The Classical Algorithms.
+ */
+
+// Muss auf UINT16/INT16/UINT32/INT32 umgestellt werden !!! W.P.
+
+// -----------------------------------------------------------------------
+
+void BigInt::MakeBigInt( const BigInt& rVal )
+{
+ if ( rVal.bIsBig )
+ {
+ memcpy( (void*)this, (const void*)&rVal, sizeof( BigInt ) );
+ while ( nLen > 1 && nNum[nLen-1] == 0 )
+ nLen--;
+ }
+ else
+ {
+ long nTmp = rVal.nVal;
+
+ nVal = rVal.nVal;
+ bIsBig = sal_True;
+ if ( nTmp < 0 )
+ {
+ bIsNeg = sal_True;
+ nTmp = -nTmp;
+ }
+ else
+ bIsNeg = sal_False;
+
+ nNum[0] = (sal_uInt16)(nTmp & 0xffffL);
+ nNum[1] = (sal_uInt16)(nTmp >> 16);
+#ifndef _WIN16
+ if ( nTmp & 0xffff0000L )
+#else
+ long l = 0xffff0000L;
+ if ( nTmp & l )
+#endif
+ nLen = 2;
+ else
+ nLen = 1;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void BigInt::Normalize()
+{
+ if ( bIsBig )
+ {
+ while ( nLen > 1 && nNum[nLen-1] == 0 )
+ nLen--;
+
+ if ( nLen < 3 )
+ {
+ if ( nLen < 2 )
+ nVal = nNum[0];
+ else if ( nNum[1] & 0x8000 )
+ return;
+ else
+ nVal = ((long)nNum[1] << 16) + nNum[0];
+
+ bIsBig = sal_False;
+
+ if ( bIsNeg )
+ nVal = -nVal;
+ }
+ // else ist nVal undefiniert !!! W.P.
+ }
+ // wozu, nLen ist doch undefiniert ??? W.P.
+ else if ( nVal & 0xFFFF0000L )
+ nLen = 2;
+ else
+ nLen = 1;
+}
+
+// -----------------------------------------------------------------------
+
+void BigInt::Mult( const BigInt &rVal, sal_uInt16 nMul )
+{
+ sal_uInt16 nK = 0;
+ for ( int i = 0; i < rVal.nLen; i++ )
+ {
+ sal_uInt32 nTmp = (sal_uInt32)rVal.nNum[i] * (sal_uInt32)nMul + nK;
+ nK = (sal_uInt16)(nTmp >> 16);
+ nNum[i] = (sal_uInt16)nTmp;
+ }
+
+ if ( nK )
+ {
+ nNum[rVal.nLen] = nK;
+ nLen = rVal.nLen + 1;
+ }
+ else
+ nLen = rVal.nLen;
+
+ bIsBig = sal_True;
+ bIsNeg = rVal.bIsNeg;
+}
+
+// -----------------------------------------------------------------------
+
+void BigInt::Div( sal_uInt16 nDiv, sal_uInt16& rRem )
+{
+ sal_uInt32 nK = 0;
+ for ( int i = nLen - 1; i >= 0; i-- )
+ {
+ sal_uInt32 nTmp = (sal_uInt32)nNum[i] + (nK << 16);
+ nNum[i] = (sal_uInt16)(nTmp / nDiv);
+ nK = nTmp % nDiv;
+ }
+ rRem = (sal_uInt16)nK;
+
+ if ( nNum[nLen-1] == 0 )
+ nLen -= 1;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool BigInt::IsLess( const BigInt& rVal ) const
+{
+ if ( rVal.nLen < nLen)
+ return sal_True;
+ if ( rVal.nLen > nLen )
+ return sal_False;
+
+ int i;
+ for ( i = nLen - 1; i > 0 && nNum[i] == rVal.nNum[i]; i-- )
+ {
+ }
+ return rVal.nNum[i] < nNum[i];
+}
+
+// -----------------------------------------------------------------------
+
+void BigInt::AddLong( BigInt& rB, BigInt& rErg )
+{
+ if ( bIsNeg == rB.bIsNeg )
+ {
+ int i;
+ char len;
+
+ // wenn die Zahlen unterschiedlich lang sind, sollte zunaechst bei
+ // der kleineren Zahl die fehlenden Ziffern mit 0 initialisert werden
+ if (nLen >= rB.nLen)
+ {
+ len = nLen;
+ for (i = rB.nLen; i < len; i++)
+ rB.nNum[i] = 0;
+ }
+ else
+ {
+ len = rB.nLen;
+ for (i = nLen; i < len; i++)
+ nNum[i] = 0;
+ }
+
+ // Die Ziffern werden von hinten nach vorne addiert
+ long k;
+ long nZ = 0;
+ for (i = 0, k = 0; i < len; i++) {
+ nZ = (long)nNum[i] + (long)rB.nNum[i] + k;
+ if (nZ & 0xff0000L)
+ k = 1;
+ else
+ k = 0;
+ rErg.nNum[i] = (sal_uInt16)(nZ & 0xffffL);
+ }
+ // Trat nach der letzten Addition ein Ueberlauf auf, muss dieser
+ // noch ins Ergebis uebernommen werden
+ if (nZ & 0xff0000L) // oder if(k)
+ {
+ rErg.nNum[i] = 1;
+ len++;
+ }
+ // Die Laenge und das Vorzeichen setzen
+ rErg.nLen = len;
+ rErg.bIsNeg = bIsNeg && rB.bIsNeg;
+ rErg.bIsBig = sal_True;
+ }
+ // Wenn nur einer der beiden Operanten negativ ist, wird aus der
+ // Addition eine Subtaktion
+ else if (bIsNeg)
+ {
+ bIsNeg = sal_False;
+ rB.SubLong(*this, rErg);
+ bIsNeg = sal_True;
+ }
+ else
+ {
+ rB.bIsNeg = sal_False;
+ SubLong(rB, rErg);
+ rB.bIsNeg = sal_True;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void BigInt::SubLong( BigInt& rB, BigInt& rErg )
+{
+ if ( bIsNeg == rB.bIsNeg )
+ {
+ int i;
+ char len;
+ long nZ, k;
+
+ // wenn die Zahlen unterschiedlich lang sind, sollte zunaechst bei
+ // der kleineren Zahl die fehlenden Ziffern mit 0 initialisert werden
+ if (nLen >= rB.nLen)
+ {
+ len = nLen;
+ for (i = rB.nLen; i < len; i++)
+ rB.nNum[i] = 0;
+ }
+ else
+ {
+ len = rB.nLen;
+ for (i = nLen; i < len; i++)
+ nNum[i] = 0;
+ }
+
+ if ( IsLess(rB) )
+ {
+ for (i = 0, k = 0; i < len; i++)
+ {
+ nZ = (long)nNum[i] - (long)rB.nNum[i] + k;
+ if (nZ < 0)
+ k = -1;
+ else
+ k = 0;
+ rErg.nNum[i] = (sal_uInt16)(nZ & 0xffffL);
+ }
+ rErg.bIsNeg = bIsNeg;
+ }
+ else
+ {
+ for (i = 0, k = 0; i < len; i++)
+ {
+ nZ = (long)rB.nNum[i] - (long)nNum[i] + k;
+ if (nZ < 0)
+ k = -1;
+ else
+ k = 0;
+ rErg.nNum[i] = (sal_uInt16)(nZ & 0xffffL);
+ }
+ // wenn a < b, dann Vorzeichen vom Ergebnis umdrehen
+ rErg.bIsNeg = !bIsNeg;
+ }
+ rErg.nLen = len;
+ rErg.bIsBig = sal_True;
+ }
+ // Wenn nur einer der beiden Operanten negativ ist, wird aus der
+ // Subtaktion eine Addition
+ else if (bIsNeg)
+ {
+ bIsNeg = sal_False;
+ AddLong(rB, rErg);
+ bIsNeg = sal_True;
+ rErg.bIsNeg = sal_True;
+ }
+ else
+ {
+ rB.bIsNeg = sal_False;
+ AddLong(rB, rErg);
+ rB.bIsNeg = sal_True;
+ rErg.bIsNeg = sal_False;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void BigInt::MultLong( const BigInt& rB, BigInt& rErg ) const
+{
+ int i, j;
+ sal_uInt32 nZ, k;
+
+ rErg.bIsNeg = bIsNeg != rB.bIsNeg;
+ rErg.bIsBig = sal_True;
+ rErg.nLen = nLen + rB.nLen;
+
+ for (i = 0; i < rErg.nLen; i++)
+ rErg.nNum[i] = 0;
+
+ for (j = 0; j < rB.nLen; j++)
+ {
+ for (i = 0, k = 0; i < nLen; i++)
+ {
+ nZ = (sal_uInt32)nNum[i] * (sal_uInt32)rB.nNum[j] +
+ (sal_uInt32)rErg.nNum[i + j] + k;
+ rErg.nNum[i + j] = (sal_uInt16)(nZ & 0xffffUL);
+ k = nZ >> 16;
+ }
+ rErg.nNum[i + j] = (sal_uInt16)k;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void BigInt::DivLong( const BigInt& rB, BigInt& rErg ) const
+{
+ int i, j;
+ long nTmp;
+ sal_uInt16 nK, nQ, nMult;
+ short nLenB = rB.nLen;
+ short nLenB1 = rB.nLen - 1;
+ BigInt aTmpA, aTmpB;
+
+ nMult = (sal_uInt16)(0x10000L / ((long)rB.nNum[nLenB1] + 1));
+
+ aTmpA.Mult( *this, nMult );
+ if ( aTmpA.nLen == nLen )
+ {
+ aTmpA.nNum[aTmpA.nLen] = 0;
+ aTmpA.nLen++;
+ }
+
+ aTmpB.Mult( rB, nMult );
+
+ for (j = aTmpA.nLen - 1; j >= nLenB; j--)
+ { // Raten des Divisors
+ nTmp = ( (long)aTmpA.nNum[j] << 16 ) + aTmpA.nNum[j - 1];
+ if (aTmpA.nNum[j] == aTmpB.nNum[nLenB1])
+ nQ = 0xFFFF;
+ else
+ nQ = (sal_uInt16)(((sal_uInt32)nTmp) / aTmpB.nNum[nLenB1]);
+
+ if ( ((sal_uInt32)aTmpB.nNum[nLenB1 - 1] * nQ) >
+ ((((sal_uInt32)nTmp) - aTmpB.nNum[nLenB1] * nQ) << 16) + aTmpA.nNum[j - 2])
+ nQ--;
+ // Und hier faengt das Teilen an
+ nK = 0;
+ nTmp = 0;
+ for (i = 0; i < nLenB; i++)
+ {
+ nTmp = (long)aTmpA.nNum[j - nLenB + i]
+ - ((long)aTmpB.nNum[i] * nQ)
+ - nK;
+ aTmpA.nNum[j - nLenB + i] = (sal_uInt16)nTmp;
+ nK = (sal_uInt16) (nTmp >> 16);
+ if ( nK )
+ nK = (sal_uInt16)(0x10000UL - nK);
+ }
+ unsigned short& rNum( aTmpA.nNum[j - nLenB + i] );
+ rNum = rNum - nK; // MSVC yields a warning on -= here, so don't use it
+ if (aTmpA.nNum[j - nLenB + i] == 0)
+ rErg.nNum[j - nLenB] = nQ;
+ else
+ {
+ rErg.nNum[j - nLenB] = nQ - 1;
+ nK = 0;
+ for (i = 0; i < nLenB; i++)
+ {
+ nTmp = aTmpA.nNum[j - nLenB + i] + aTmpB.nNum[i] + nK;
+ aTmpA.nNum[j - nLenB + i] = (sal_uInt16)(nTmp & 0xFFFFL);
+ if (nTmp & 0xFFFF0000L)
+ nK = 1;
+ else
+ nK = 0;
+ }
+ }
+ }
+
+ rErg.bIsNeg = bIsNeg != rB.bIsNeg;
+ rErg.bIsBig = sal_True;
+ rErg.nLen = nLen - rB.nLen + 1;
+}
+
+// -----------------------------------------------------------------------
+
+void BigInt::ModLong( const BigInt& rB, BigInt& rErg ) const
+{
+ short i, j;
+ long nTmp;
+ sal_uInt16 nK, nQ, nMult;
+ short nLenB = rB.nLen;
+ short nLenB1 = rB.nLen - 1;
+ BigInt aTmpA, aTmpB;
+
+ nMult = (sal_uInt16)(0x10000L / ((long)rB.nNum[nLenB1] + 1));
+
+ aTmpA.Mult( *this, nMult);
+ if ( aTmpA.nLen == nLen )
+ {
+ aTmpA.nNum[aTmpA.nLen] = 0;
+ aTmpA.nLen++;
+ }
+
+ aTmpB.Mult( rB, nMult);
+
+ for (j = aTmpA.nLen - 1; j >= nLenB; j--)
+ { // Raten des Divisors
+ nTmp = ( (long)aTmpA.nNum[j] << 16 ) + aTmpA.nNum[j - 1];
+ if (aTmpA.nNum[j] == aTmpB.nNum[nLenB1])
+ nQ = 0xFFFF;
+ else
+ nQ = (sal_uInt16)(((sal_uInt32)nTmp) / aTmpB.nNum[nLenB1]);
+
+ if ( ((sal_uInt32)aTmpB.nNum[nLenB1 - 1] * nQ) >
+ ((((sal_uInt32)nTmp) - aTmpB.nNum[nLenB1] * nQ) << 16) + aTmpA.nNum[j - 2])
+ nQ--;
+ // Und hier faengt das Teilen an
+ nK = 0;
+ nTmp = 0;
+ for (i = 0; i < nLenB; i++)
+ {
+ nTmp = (long)aTmpA.nNum[j - nLenB + i]
+ - ((long)aTmpB.nNum[i] * nQ)
+ - nK;
+ aTmpA.nNum[j - nLenB + i] = (sal_uInt16)nTmp;
+ nK = (sal_uInt16) (nTmp >> 16);
+ if ( nK )
+ nK = (sal_uInt16)(0x10000UL - nK);
+ }
+ unsigned short& rNum( aTmpA.nNum[j - nLenB + i] );
+ rNum = rNum - nK;
+ if (aTmpA.nNum[j - nLenB + i] == 0)
+ rErg.nNum[j - nLenB] = nQ;
+ else
+ {
+ rErg.nNum[j - nLenB] = nQ - 1;
+ nK = 0;
+ for (i = 0; i < nLenB; i++) {
+ nTmp = aTmpA.nNum[j - nLenB + i] + aTmpB.nNum[i] + nK;
+ aTmpA.nNum[j - nLenB + i] = (sal_uInt16)(nTmp & 0xFFFFL);
+ if (nTmp & 0xFFFF0000L)
+ nK = 1;
+ else
+ nK = 0;
+ }
+ }
+ }
+
+ rErg = aTmpA;
+ rErg.Div( nMult, nQ );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool BigInt::ABS_IsLess( const BigInt& rB ) const
+{
+ if (bIsBig || rB.bIsBig)
+ {
+ BigInt nA, nB;
+ nA.MakeBigInt( *this );
+ nB.MakeBigInt( rB );
+ if (nA.nLen == nB.nLen)
+ {
+ int i;
+ for (i = nA.nLen - 1; i > 0 && nA.nNum[i] == nB.nNum[i]; i--)
+ {
+ }
+ return nA.nNum[i] < nB.nNum[i];
+ }
+ else
+ return nA.nLen < nB.nLen;
+ }
+ if ( nVal < 0 )
+ if ( rB.nVal < 0 )
+ return nVal > rB.nVal;
+ else
+ return nVal > -rB.nVal;
+ else
+ if ( rB.nVal < 0 )
+ return nVal < -rB.nVal;
+ else
+ return nVal < rB.nVal;
+}
+
+// -----------------------------------------------------------------------
+
+BigInt::BigInt( const BigInt& rBigInt )
+{
+ if ( rBigInt.bIsBig )
+ memcpy( (void*)this, (const void*)&rBigInt, sizeof( BigInt ) );
+ else
+ {
+ bIsSet = rBigInt.bIsSet;
+ bIsBig = sal_False;
+ nVal = rBigInt.nVal;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BigInt::BigInt( const ByteString& rString )
+{
+ bIsSet = sal_True;
+ bIsNeg = sal_False;
+ bIsBig = sal_False;
+ nVal = 0;
+
+ sal_Bool bNeg = sal_False;
+ const sal_Char* p = rString.GetBuffer();
+ if ( *p == '-' )
+ {
+ bNeg = sal_True;
+ p++;
+ }
+ while( *p >= '0' && *p <= '9' )
+ {
+ *this *= 10;
+ *this += *p - '0';
+ p++;
+ }
+ if ( bIsBig )
+ bIsNeg = bNeg;
+ else if( bNeg )
+ nVal = -nVal;
+}
+
+// -----------------------------------------------------------------------
+
+BigInt::BigInt( const UniString& rString )
+{
+ bIsSet = sal_True;
+ bIsNeg = sal_False;
+ bIsBig = sal_False;
+ nVal = 0;
+
+ sal_Bool bNeg = sal_False;
+ const sal_Unicode* p = rString.GetBuffer();
+ if ( *p == '-' )
+ {
+ bNeg = sal_True;
+ p++;
+ }
+ while( *p >= '0' && *p <= '9' )
+ {
+ *this *= 10;
+ *this += *p - '0';
+ p++;
+ }
+ if ( bIsBig )
+ bIsNeg = bNeg;
+ else if( bNeg )
+ nVal = -nVal;
+}
+
+// -----------------------------------------------------------------------
+
+BigInt::BigInt( double nValue )
+{
+ bIsSet = sal_True;
+
+ if ( nValue < 0 )
+ {
+ nValue *= -1;
+ bIsNeg = sal_True;
+ }
+ else
+ {
+ bIsNeg = sal_False;
+ }
+
+ if ( nValue < 1 )
+ {
+ bIsBig = sal_False;
+ nVal = 0;
+ }
+ else
+ {
+ bIsBig = sal_True;
+
+ int i=0;
+
+ while ( ( nValue > 65536.0 ) && ( i < MAX_DIGITS ) )
+ {
+ nNum[i] = (sal_uInt16) fmod( nValue, 65536.0 );
+ nValue -= nNum[i];
+ nValue /= 65536.0;
+ i++;
+ }
+ if ( i < MAX_DIGITS )
+ nNum[i++] = (sal_uInt16) nValue;
+
+ nLen = i;
+
+ if ( i < 3 )
+ Normalize();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BigInt::BigInt( sal_uInt32 nValue )
+{
+ bIsSet = sal_True;
+ if ( nValue & 0x80000000UL )
+ {
+ bIsBig = sal_True;
+ bIsNeg = sal_False;
+ nNum[0] = (sal_uInt16)(nValue & 0xffffUL);
+ nNum[1] = (sal_uInt16)(nValue >> 16);
+ nLen = 2;
+ }
+ else
+ {
+ bIsBig = sal_False;
+ nVal = nValue;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BigInt::operator ULONG() const
+{
+ if ( !bIsBig )
+ return (sal_uInt32)nVal;
+ else if ( nLen == 2 )
+ {
+ sal_uInt32 nRet;
+ nRet = ((sal_uInt32)nNum[1]) << 16;
+ nRet += nNum[0];
+ return nRet;
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+BigInt::operator double() const
+{
+ if ( !bIsBig )
+ return (double) nVal;
+ else
+ {
+ int i = nLen-1;
+ double nRet = (double) ((sal_uInt32)nNum[i]);
+
+ while ( i )
+ {
+ nRet *= 65536.0;
+ i--;
+ nRet += (double) ((sal_uInt32)nNum[i]);
+ }
+
+ if ( bIsNeg )
+ nRet *= -1;
+
+ return nRet;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ByteString BigInt::GetByteString() const
+{
+ ByteString aString;
+
+ if ( !bIsBig )
+ aString = ByteString::CreateFromInt32( nVal );
+ else
+ {
+ BigInt aTmp( *this );
+ BigInt a1000000000( 1000000000L );
+ aTmp.Abs();
+
+ do
+ {
+ BigInt a = aTmp;
+ a %= a1000000000;
+ aTmp /= a1000000000;
+
+ ByteString aStr = aString;
+ if ( a.nVal < 100000000L )
+ { // leading 0s
+ aString = ByteString::CreateFromInt32( a.nVal + 1000000000L );
+ aString.Erase( 0, 1 );
+ }
+ else
+ aString = ByteString::CreateFromInt32( a.nVal );
+ aString += aStr;
+ }
+ while( aTmp.bIsBig );
+
+ ByteString aStr = aString;
+ if ( bIsNeg )
+ aString = ByteString::CreateFromInt32( -aTmp.nVal );
+ else
+ aString = ByteString::CreateFromInt32( aTmp.nVal );
+ aString += aStr;
+ }
+
+ return aString;
+}
+
+// -----------------------------------------------------------------------
+
+UniString BigInt::GetString() const
+{
+ UniString aString;
+
+ if ( !bIsBig )
+ aString = UniString::CreateFromInt32( nVal );
+ else
+ {
+ BigInt aTmp( *this );
+ BigInt a1000000000( 1000000000L );
+ aTmp.Abs();
+
+ do
+ {
+ BigInt a = aTmp;
+ a %= a1000000000;
+ aTmp /= a1000000000;
+
+ UniString aStr = aString;
+ if ( a.nVal < 100000000L )
+ { // leading 0s
+ aString = UniString::CreateFromInt32( a.nVal + 1000000000L );
+ aString.Erase(0,1);
+ }
+ else
+ aString = UniString::CreateFromInt32( a.nVal );
+ aString += aStr;
+ }
+ while( aTmp.bIsBig );
+
+ UniString aStr = aString;
+ if ( bIsNeg )
+ aString = UniString::CreateFromInt32( -aTmp.nVal );
+ else
+ aString = UniString::CreateFromInt32( aTmp.nVal );
+ aString += aStr;
+ }
+
+ return aString;
+}
+
+// -----------------------------------------------------------------------
+
+BigInt& BigInt::operator=( const BigInt& rBigInt )
+{
+ if ( rBigInt.bIsBig )
+ memcpy( (void*)this, (const void*)&rBigInt, sizeof( BigInt ) );
+ else
+ {
+ bIsSet = rBigInt.bIsSet;
+ bIsBig = sal_False;
+ nVal = rBigInt.nVal;
+ }
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BigInt& BigInt::operator+=( const BigInt& rVal )
+{
+ if ( !bIsBig && !rVal.bIsBig )
+ {
+ if( nVal <= MY_MAXLONG && rVal.nVal <= MY_MAXLONG
+ && nVal >= MY_MINLONG && rVal.nVal >= MY_MINLONG )
+ { // wir bewegen uns im ungefaehrlichem Bereich
+ nVal += rVal.nVal;
+ return *this;
+ }
+
+ if( (nVal < 0) != (rVal.nVal < 0) )
+ { // wir bewegen uns im ungefaehrlichem Bereich
+ nVal += rVal.nVal;
+ return *this;
+ }
+ }
+
+ BigInt aTmp1, aTmp2;
+ aTmp1.MakeBigInt( *this );
+ aTmp2.MakeBigInt( rVal );
+ aTmp1.AddLong( aTmp2, *this );
+ Normalize();
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BigInt& BigInt::operator-=( const BigInt& rVal )
+{
+ if ( !bIsBig && !rVal.bIsBig )
+ {
+ if ( nVal <= MY_MAXLONG && rVal.nVal <= MY_MAXLONG &&
+ nVal >= MY_MINLONG && rVal.nVal >= MY_MINLONG )
+ { // wir bewegen uns im ungefaehrlichem Bereich
+ nVal -= rVal.nVal;
+ return *this;
+ }
+
+ if ( (nVal < 0) == (rVal.nVal < 0) )
+ { // wir bewegen uns im ungefaehrlichem Bereich
+ nVal -= rVal.nVal;
+ return *this;
+ }
+ }
+
+ BigInt aTmp1, aTmp2;
+ aTmp1.MakeBigInt( *this );
+ aTmp2.MakeBigInt( rVal );
+ aTmp1.SubLong( aTmp2, *this );
+ Normalize();
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BigInt& BigInt::operator*=( const BigInt& rVal )
+{
+ if ( !bIsBig && !rVal.bIsBig
+ && nVal <= MY_MAXSHORT && rVal.nVal <= MY_MAXSHORT
+ && nVal >= MY_MINSHORT && rVal.nVal >= MY_MINSHORT )
+ // nicht optimal !!! W.P.
+ { // wir bewegen uns im ungefaehrlichem Bereich
+ nVal *= rVal.nVal;
+ }
+ else
+ {
+ BigInt aTmp1, aTmp2;
+ aTmp1.MakeBigInt( rVal );
+ aTmp2.MakeBigInt( *this );
+ aTmp1.MultLong(aTmp2, *this);
+ Normalize();
+ }
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BigInt& BigInt::operator/=( const BigInt& rVal )
+{
+ if ( !rVal.bIsBig )
+ {
+ if ( rVal.nVal == 0 )
+ {
+ DBG_ERROR( "BigInt::operator/ --> divide by zero" );
+ return *this;
+ }
+
+ if ( !bIsBig )
+ {
+ // wir bewegen uns im ungefaehrlichem Bereich
+ nVal /= rVal.nVal;
+ return *this;
+ }
+
+ if ( rVal.nVal == 1 )
+ return *this;
+
+ if ( rVal.nVal == -1 )
+ {
+ bIsNeg = !bIsNeg;
+ return *this;
+ }
+
+ if ( rVal.nVal <= (long)0xFFFF && rVal.nVal >= -(long)0xFFFF )
+ {
+ // ein BigInt durch ein sal_uInt16 teilen
+ sal_uInt16 nTmp;
+ if ( rVal.nVal < 0 )
+ {
+ nTmp = (sal_uInt16) -rVal.nVal;
+ bIsNeg = !bIsNeg;
+ }
+ else
+ nTmp = (sal_uInt16) rVal.nVal;
+
+ Div( nTmp, nTmp );
+ Normalize();
+ return *this;
+ }
+ }
+
+ if ( ABS_IsLess( rVal ) )
+ {
+ *this = BigInt( (long)0 );
+ return *this;
+ }
+
+ // BigInt durch BigInt teilen
+ BigInt aTmp1, aTmp2;
+ aTmp1.MakeBigInt( *this );
+ aTmp2.MakeBigInt( rVal );
+ aTmp1.DivLong(aTmp2, *this);
+ Normalize();
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+void BigInt::DivMod( const BigInt& rVal, BigInt& rMod )
+{
+ if ( !rVal.bIsBig )
+ {
+ if ( rVal.nVal == 0 )
+ {
+ DBG_ERROR( "BigInt::operator/ --> divide by zero" );
+ return;
+ }
+
+ if ( !bIsBig )
+ {
+ // wir bewegen uns im ungefaehrlichem Bereich
+ rMod = BigInt( nVal % rVal.nVal );
+ nVal /= rVal.nVal;
+ return;
+ }
+
+ if ( rVal.nVal == 1 )
+ {
+ rMod = BigInt( (long)0 );
+ return;
+ }
+
+ if ( rVal.nVal == -1 )
+ {
+ rMod = BigInt( (long)0 );
+ bIsNeg = !bIsNeg;
+ return;
+ }
+
+ if ( rVal.nVal <= (long)0xFFFF && rVal.nVal >= -(long)0xFFFF )
+ {
+ // ein BigInt durch ein sal_uInt16 teilen
+ sal_uInt16 nTmp;
+ if ( rVal.nVal < 0 )
+ {
+ nTmp = (sal_uInt16) -rVal.nVal;
+ bIsNeg = !bIsNeg;
+ }
+ else
+ nTmp = (sal_uInt16) rVal.nVal;
+
+ Div( nTmp, nTmp );
+ rMod = BigInt( (long)nTmp );
+ Normalize();
+ return;
+ }
+ }
+
+ if ( ABS_IsLess( rVal ) )
+ {
+ rMod = *this;
+ *this = BigInt( (long)0 );
+ return;
+ }
+
+ // BigInt durch BigInt teilen
+ BigInt aTmp1, aTmp2;
+ aTmp1.MakeBigInt( *this );
+ aTmp2.MakeBigInt( rVal );
+ aTmp1.DivLong(aTmp2, *this);
+ Normalize();
+ aTmp1.ModLong(aTmp2, rMod); // nicht optimal
+ rMod.Normalize();
+}
+
+// -----------------------------------------------------------------------
+
+BigInt& BigInt::operator%=( const BigInt& rVal )
+{
+ if ( !rVal.bIsBig )
+ {
+ if ( rVal.nVal == 0 )
+ {
+ DBG_ERROR( "BigInt::operator/ --> divide by zero" );
+ return *this;
+ }
+
+ if ( !bIsBig )
+ {
+ // wir bewegen uns im ungefaehrlichem Bereich
+ nVal %= rVal.nVal;
+ return *this;
+ }
+
+ if ( rVal.nVal <= (long)0xFFFF && rVal.nVal >= -(long)0xFFFF )
+ {
+ // ein BigInt durch ein short teilen
+ sal_uInt16 nTmp;
+ if ( rVal.nVal < 0 )
+ {
+ nTmp = (sal_uInt16) -rVal.nVal;
+ bIsNeg = !bIsNeg;
+ }
+ else
+ nTmp = (sal_uInt16) rVal.nVal;
+
+ Div( nTmp, nTmp );
+ *this = BigInt( (long)nTmp );
+ return *this;
+ }
+ }
+
+ if ( ABS_IsLess( rVal ) )
+ return *this;
+
+ // BigInt durch BigInt teilen
+ BigInt aTmp1, aTmp2;
+ aTmp1.MakeBigInt( *this );
+ aTmp2.MakeBigInt( rVal );
+ aTmp1.ModLong(aTmp2, *this);
+ Normalize();
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool operator==( const BigInt& rVal1, const BigInt& rVal2 )
+{
+ if ( rVal1.bIsBig || rVal2.bIsBig )
+ {
+ BigInt nA, nB;
+ nA.MakeBigInt( rVal1 );
+ nB.MakeBigInt( rVal2 );
+ if ( nA.bIsNeg == nB.bIsNeg )
+ {
+ if ( nA.nLen == nB.nLen )
+ {
+ int i;
+ for ( i = nA.nLen - 1; i > 0 && nA.nNum[i] == nB.nNum[i]; i-- )
+ {
+ }
+
+ return nA.nNum[i] == nB.nNum[i];
+ }
+ return sal_False;
+ }
+ return sal_False;
+ }
+ return rVal1.nVal == rVal2.nVal;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool operator<( const BigInt& rVal1, const BigInt& rVal2 )
+{
+ if ( rVal1.bIsBig || rVal2.bIsBig )
+ {
+ BigInt nA, nB;
+ nA.MakeBigInt( rVal1 );
+ nB.MakeBigInt( rVal2 );
+ if ( nA.bIsNeg == nB.bIsNeg )
+ {
+ if ( nA.nLen == nB.nLen )
+ {
+ int i;
+ for ( i = nA.nLen - 1; i > 0 && nA.nNum[i] == nB.nNum[i]; i-- )
+ {
+ }
+
+ if ( nA.bIsNeg )
+ return nA.nNum[i] > nB.nNum[i];
+ else
+ return nA.nNum[i] < nB.nNum[i];
+ }
+ if ( nA.bIsNeg )
+ return nA.nLen > nB.nLen;
+ else
+ return nA.nLen < nB.nLen;
+ }
+ return !nB.bIsNeg;
+ }
+ return rVal1.nVal < rVal2.nVal;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool operator >(const BigInt& rVal1, const BigInt& rVal2 )
+{
+ if ( rVal1.bIsBig || rVal2.bIsBig )
+ {
+ BigInt nA, nB;
+ nA.MakeBigInt( rVal1 );
+ nB.MakeBigInt( rVal2 );
+ if ( nA.bIsNeg == nB.bIsNeg )
+ {
+ if ( nA.nLen == nB.nLen )
+ {
+ int i;
+ for ( i = nA.nLen - 1; i > 0 && nA.nNum[i] == nB.nNum[i]; i-- )
+ {
+ }
+
+ if ( nA.bIsNeg )
+ return nA.nNum[i] < nB.nNum[i];
+ else
+ return nA.nNum[i] > nB.nNum[i];
+ }
+ if ( nA.bIsNeg )
+ return nA.nLen < nB.nLen;
+ else
+ return nA.nLen > nB.nLen;
+ }
+ return !nA.bIsNeg;
+ }
+
+ return rVal1.nVal > rVal2.nVal;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/generic/color.cxx b/tools/source/generic/color.cxx
new file mode 100644
index 000000000000..2c8e21e8e135
--- /dev/null
+++ b/tools/source/generic/color.cxx
@@ -0,0 +1,510 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <stdlib.h>
+#include <tools/color.hxx>
+#include <tools/debug.hxx>
+#include <tools/stream.hxx>
+#include <tools/rc.hxx>
+#include <tools/rcid.h>
+#include <tools/resid.hxx>
+#include <tools/rc.h>
+
+// -----------
+// - Inlines -
+// -----------
+
+static inline long _FRound( double fVal )
+{
+ return( fVal > 0.0 ? (long) ( fVal + 0.5 ) : -(long) ( -fVal + 0.5 ) );
+}
+
+// ---------
+// - Color -
+// ---------
+
+Color::Color( const ResId& rResId )
+{
+ rResId.SetRT( RSC_COLOR );
+ ResMgr* pResMgr = rResId.GetResMgr();
+ if ( pResMgr && pResMgr->GetResource( rResId ) )
+ {
+ // Header ueberspringen
+ pResMgr->Increment( sizeof( RSHEADER_TYPE ) );
+
+ // Daten laden
+ USHORT nRed = pResMgr->ReadShort();
+ USHORT nGreen = pResMgr->ReadShort();
+ USHORT nBlue = pResMgr->ReadShort();
+ // one more historical ULONG
+ pResMgr->ReadLong();
+
+ // RGB-Farbe
+ mnColor = RGB_COLORDATA( nRed>>8, nGreen>>8, nBlue>>8 );
+ }
+ else
+ {
+ mnColor = RGB_COLORDATA( 0, 0, 0 );
+ }
+}
+UINT8 Color::GetColorError( const Color& rCompareColor ) const
+{
+ const long nErrAbs = labs( (long) rCompareColor.GetRed() - GetRed() ) +
+ labs( (long) rCompareColor.GetGreen() - GetGreen() ) +
+ labs( (long) rCompareColor.GetBlue() - GetBlue() );
+
+ return (UINT8) _FRound( nErrAbs * 0.3333333333 );
+}
+
+// -----------------------------------------------------------------------
+
+void Color::IncreaseLuminance( UINT8 cLumInc )
+{
+ SetRed( (UINT8) SAL_BOUND( (long) COLORDATA_RED( mnColor ) + cLumInc, 0L, 255L ) );
+ SetGreen( (UINT8) SAL_BOUND( (long) COLORDATA_GREEN( mnColor ) + cLumInc, 0L, 255L ) );
+ SetBlue( (UINT8) SAL_BOUND( (long) COLORDATA_BLUE( mnColor ) + cLumInc, 0L, 255L ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Color::DecreaseLuminance( UINT8 cLumDec )
+{
+ SetRed( (UINT8) SAL_BOUND( (long) COLORDATA_RED( mnColor ) - cLumDec, 0L, 255L ) );
+ SetGreen( (UINT8) SAL_BOUND( (long) COLORDATA_GREEN( mnColor ) - cLumDec, 0L, 255L ) );
+ SetBlue( (UINT8) SAL_BOUND( (long) COLORDATA_BLUE( mnColor ) - cLumDec, 0L, 255L ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Color::IncreaseContrast( UINT8 cContInc )
+{
+ if( cContInc)
+ {
+ const double fM = 128.0 / ( 128.0 - 0.4985 * cContInc );
+ const double fOff = 128.0 - fM * 128.0;
+
+ SetRed( (UINT8) SAL_BOUND( _FRound( COLORDATA_RED( mnColor ) * fM + fOff ), 0L, 255L ) );
+ SetGreen( (UINT8) SAL_BOUND( _FRound( COLORDATA_GREEN( mnColor ) * fM + fOff ), 0L, 255L ) );
+ SetBlue( (UINT8) SAL_BOUND( _FRound( COLORDATA_BLUE( mnColor ) * fM + fOff ), 0L, 255L ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Color::DecreaseContrast( UINT8 cContDec )
+{
+ if( cContDec )
+ {
+ const double fM = ( 128.0 - 0.4985 * cContDec ) / 128.0;
+ const double fOff = 128.0 - fM * 128.0;
+
+ SetRed( (UINT8) SAL_BOUND( _FRound( COLORDATA_RED( mnColor ) * fM + fOff ), 0L, 255L ) );
+ SetGreen( (UINT8) SAL_BOUND( _FRound( COLORDATA_GREEN( mnColor ) * fM + fOff ), 0L, 255L ) );
+ SetBlue( (UINT8) SAL_BOUND( _FRound( COLORDATA_BLUE( mnColor ) * fM + fOff ), 0L, 255L ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Color::Invert()
+{
+ SetRed( ~COLORDATA_RED( mnColor ) );
+ SetGreen( ~COLORDATA_GREEN( mnColor ) );
+ SetBlue( ~COLORDATA_BLUE( mnColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Color::IsDark() const
+{
+ return GetLuminance() <= 38;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Color::IsBright() const
+{
+ return GetLuminance() >= 245;
+}
+
+// -----------------------------------------------------------------------
+// color space conversion
+// -----------------------------------------------------------------------
+
+void Color::RGBtoHSB( USHORT& nHue, USHORT& nSat, USHORT& nBri ) const
+{
+ UINT8 c[3];
+ UINT8 cMax, cMin;
+
+ c[0] = GetRed();
+ c[1] = GetGreen();
+ c[2] = GetBlue();
+
+ cMax = c[0];
+ if( c[1] > cMax )
+ cMax = c[1];
+ if( c[2] > cMax )
+ cMax = c[2];
+
+ // Brightness = max(R, G, B);
+ nBri = cMax * 100 / 255;
+
+ cMin = c[0];
+ if( c[1] < cMin )
+ cMin = c[1];
+ if( c[2] < cMin )
+ cMin = c[2];
+
+ UINT8 cDelta = cMax - cMin;
+
+ // Saturation = max - min / max
+ if( nBri > 0 )
+ nSat = cDelta * 100 / cMax;
+ else
+ nSat = 0;
+
+ if( nSat == 0 )
+ nHue = 0; // Default = undefined
+ else
+ {
+ double dHue = 0.0;
+
+ if( c[0] == cMax )
+ {
+ dHue = (double)( c[1] - c[2] ) / (double)cDelta;
+ }
+ else if( c[1] == cMax )
+ {
+ dHue = 2.0 + (double)( c[2] - c[0] ) / (double)cDelta;
+ }
+ else if ( c[2] == cMax )
+ {
+ dHue = 4.0 + (double)( c[0] - c[1] ) / (double)cDelta;
+ }
+ dHue *= 60.0;
+
+ if( dHue < 0.0 )
+ dHue += 360.0;
+
+ nHue = (UINT16) dHue;
+ }
+}
+
+ColorData Color::HSBtoRGB( USHORT nHue, USHORT nSat, USHORT nBri )
+{
+ UINT8 cR=0,cG=0,cB=0;
+ UINT8 nB = (UINT8) ( nBri * 255 / 100 );
+
+ if( nSat == 0 )
+ {
+ cR = nB;
+ cG = nB;
+ cB = nB;
+ }
+ else
+ {
+ double dH = nHue;
+ double f;
+ UINT16 n;
+ if( dH == 360.0 )
+ dH = 0.0;
+
+ dH /= 60.0;
+ n = (UINT16) dH;
+ f = dH - n;
+
+ UINT8 a = (UINT8) ( nB * ( 100 - nSat ) / 100 );
+ UINT8 b = (UINT8) ( nB * ( 100 - ( (double)nSat * f + 0.5 ) ) / 100 );
+ UINT8 c = (UINT8) ( nB * ( 100 - ( (double)nSat * ( 1.0 - f ) + 0.5 ) ) / 100 );
+
+ switch( n )
+ {
+ case 0: cR = nB; cG = c; cB = a; break;
+ case 1: cR = b; cG = nB; cB = a; break;
+ case 2: cR = a; cG = nB; cB = c; break;
+ case 3: cR = a; cG = b; cB = nB; break;
+ case 4: cR = c; cG = a; cB = nB; break;
+ case 5: cR = nB; cG = a; cB = b; break;
+ }
+ }
+
+ return RGB_COLORDATA( cR, cG, cB );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& Color::Read( SvStream& rIStm, BOOL bNewFormat )
+{
+ if ( bNewFormat )
+ rIStm >> mnColor;
+ else
+ rIStm >> *this;
+
+ return rIStm;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& Color::Write( SvStream& rOStm, BOOL bNewFormat )
+{
+ if ( bNewFormat )
+ rOStm << mnColor;
+ else
+ rOStm << *this;
+
+ return rOStm;
+}
+
+// -----------------------------------------------------------------------
+
+#define COL_NAME_USER ((USHORT)0x8000)
+#define COL_RED_1B ((USHORT)0x0001)
+#define COL_RED_2B ((USHORT)0x0002)
+#define COL_GREEN_1B ((USHORT)0x0010)
+#define COL_GREEN_2B ((USHORT)0x0020)
+#define COL_BLUE_1B ((USHORT)0x0100)
+#define COL_BLUE_2B ((USHORT)0x0200)
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, Color& rColor )
+{
+ DBG_ASSERTWARNING( rIStream.GetVersion(), "Color::>> - Solar-Version not set on rIStream" );
+
+ USHORT nColorName;
+ USHORT nRed;
+ USHORT nGreen;
+ USHORT nBlue;
+
+ rIStream >> nColorName;
+
+ if ( nColorName & COL_NAME_USER )
+ {
+ if ( rIStream.GetCompressMode() == COMPRESSMODE_FULL )
+ {
+ unsigned char cAry[6];
+ USHORT i = 0;
+
+ nRed = 0;
+ nGreen = 0;
+ nBlue = 0;
+
+ if ( nColorName & COL_RED_2B )
+ i += 2;
+ else if ( nColorName & COL_RED_1B )
+ i++;
+ if ( nColorName & COL_GREEN_2B )
+ i += 2;
+ else if ( nColorName & COL_GREEN_1B )
+ i++;
+ if ( nColorName & COL_BLUE_2B )
+ i += 2;
+ else if ( nColorName & COL_BLUE_1B )
+ i++;
+
+ rIStream.Read( cAry, i );
+ i = 0;
+
+ if ( nColorName & COL_RED_2B )
+ {
+ nRed = cAry[i];
+ nRed <<= 8;
+ i++;
+ nRed |= cAry[i];
+ i++;
+ }
+ else if ( nColorName & COL_RED_1B )
+ {
+ nRed = cAry[i];
+ nRed <<= 8;
+ i++;
+ }
+ if ( nColorName & COL_GREEN_2B )
+ {
+ nGreen = cAry[i];
+ nGreen <<= 8;
+ i++;
+ nGreen |= cAry[i];
+ i++;
+ }
+ else if ( nColorName & COL_GREEN_1B )
+ {
+ nGreen = cAry[i];
+ nGreen <<= 8;
+ i++;
+ }
+ if ( nColorName & COL_BLUE_2B )
+ {
+ nBlue = cAry[i];
+ nBlue <<= 8;
+ i++;
+ nBlue |= cAry[i];
+ i++;
+ }
+ else if ( nColorName & COL_BLUE_1B )
+ {
+ nBlue = cAry[i];
+ nBlue <<= 8;
+ i++;
+ }
+ }
+ else
+ {
+ rIStream >> nRed;
+ rIStream >> nGreen;
+ rIStream >> nBlue;
+ }
+
+ rColor.mnColor = RGB_COLORDATA( nRed>>8, nGreen>>8, nBlue>>8 );
+ }
+ else
+ {
+ static ColorData aColAry[] =
+ {
+ COL_BLACK, // COL_BLACK
+ COL_BLUE, // COL_BLUE
+ COL_GREEN, // COL_GREEN
+ COL_CYAN, // COL_CYAN
+ COL_RED, // COL_RED
+ COL_MAGENTA, // COL_MAGENTA
+ COL_BROWN, // COL_BROWN
+ COL_GRAY, // COL_GRAY
+ COL_LIGHTGRAY, // COL_LIGHTGRAY
+ COL_LIGHTBLUE, // COL_LIGHTBLUE
+ COL_LIGHTGREEN, // COL_LIGHTGREEN
+ COL_LIGHTCYAN, // COL_LIGHTCYAN
+ COL_LIGHTRED, // COL_LIGHTRED
+ COL_LIGHTMAGENTA, // COL_LIGHTMAGENTA
+ COL_YELLOW, // COL_YELLOW
+ COL_WHITE, // COL_WHITE
+ COL_WHITE, // COL_MENUBAR
+ COL_BLACK, // COL_MENUBARTEXT
+ COL_WHITE, // COL_POPUPMENU
+ COL_BLACK, // COL_POPUPMENUTEXT
+ COL_BLACK, // COL_WINDOWTEXT
+ COL_WHITE, // COL_WINDOWWORKSPACE
+ COL_BLACK, // COL_HIGHLIGHT
+ COL_WHITE, // COL_HIGHLIGHTTEXT
+ COL_BLACK, // COL_3DTEXT
+ COL_LIGHTGRAY, // COL_3DFACE
+ COL_WHITE, // COL_3DLIGHT
+ COL_GRAY, // COL_3DSHADOW
+ COL_LIGHTGRAY, // COL_SCROLLBAR
+ COL_WHITE, // COL_FIELD
+ COL_BLACK // COL_FIELDTEXT
+ };
+
+ if ( nColorName < (sizeof( aColAry )/sizeof(ColorData)) )
+ rColor.mnColor = aColAry[nColorName];
+ else
+ rColor.mnColor = COL_BLACK;
+ }
+
+ return rIStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const Color& rColor )
+{
+ DBG_ASSERTWARNING( rOStream.GetVersion(), "Color::<< - Solar-Version not set on rOStream" );
+
+ USHORT nColorName = COL_NAME_USER;
+ USHORT nRed = rColor.GetRed();
+ USHORT nGreen = rColor.GetGreen();
+ USHORT nBlue = rColor.GetBlue();
+ nRed = (nRed<<8) + nRed;
+ nGreen = (nGreen<<8) + nGreen;
+ nBlue = (nBlue<<8) + nBlue;
+
+ if ( rOStream.GetCompressMode() == COMPRESSMODE_FULL )
+ {
+ unsigned char cAry[6];
+ USHORT i = 0;
+
+ if ( nRed & 0x00FF )
+ {
+ nColorName |= COL_RED_2B;
+ cAry[i] = (unsigned char)(nRed & 0xFF);
+ i++;
+ cAry[i] = (unsigned char)((nRed >> 8) & 0xFF);
+ i++;
+ }
+ else if ( nRed & 0xFF00 )
+ {
+ nColorName |= COL_RED_1B;
+ cAry[i] = (unsigned char)((nRed >> 8) & 0xFF);
+ i++;
+ }
+ if ( nGreen & 0x00FF )
+ {
+ nColorName |= COL_GREEN_2B;
+ cAry[i] = (unsigned char)(nGreen & 0xFF);
+ i++;
+ cAry[i] = (unsigned char)((nGreen >> 8) & 0xFF);
+ i++;
+ }
+ else if ( nGreen & 0xFF00 )
+ {
+ nColorName |= COL_GREEN_1B;
+ cAry[i] = (unsigned char)((nGreen >> 8) & 0xFF);
+ i++;
+ }
+ if ( nBlue & 0x00FF )
+ {
+ nColorName |= COL_BLUE_2B;
+ cAry[i] = (unsigned char)(nBlue & 0xFF);
+ i++;
+ cAry[i] = (unsigned char)((nBlue >> 8) & 0xFF);
+ i++;
+ }
+ else if ( nBlue & 0xFF00 )
+ {
+ nColorName |= COL_BLUE_1B;
+ cAry[i] = (unsigned char)((nBlue >> 8) & 0xFF);
+ i++;
+ }
+
+ rOStream << nColorName;
+ rOStream.Write( cAry, i );
+ }
+ else
+ {
+ rOStream << nColorName;
+ rOStream << nRed;
+ rOStream << nGreen;
+ rOStream << nBlue;
+ }
+
+ return rOStream;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/generic/config.cxx b/tools/source/generic/config.cxx
new file mode 100644
index 000000000000..9d92affc2175
--- /dev/null
+++ b/tools/source/generic/config.cxx
@@ -0,0 +1,1306 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#define _CONFIG_CXX
+
+#include <cstddef>
+#include <cstdlib>
+#include <limits>
+#include <new>
+#include <string.h>
+
+#ifdef WNT
+#include "stdlib.h"
+#endif
+#include <osl/file.hxx>
+#include <tools/stream.hxx>
+#include <tools/debug.hxx>
+#include <tools/config.hxx>
+#include <osl/security.h>
+
+#define MAXBUFLEN 1024 // Fuer Buffer bei VOS-Funktionen
+
+// -----------------
+// - ImplConfigData -
+// -----------------
+
+struct ImplKeyData
+{
+ ImplKeyData* mpNext;
+ ByteString maKey;
+ ByteString maValue;
+ BOOL mbIsComment;
+};
+
+struct ImplGroupData
+{
+ ImplGroupData* mpNext;
+ ImplKeyData* mpFirstKey;
+ ByteString maGroupName;
+ USHORT mnEmptyLines;
+};
+
+struct ImplConfigData
+{
+ ImplGroupData* mpFirstGroup;
+ XubString maFileName;
+ ULONG mnDataUpdateId;
+ ULONG mnTimeStamp;
+ LineEnd meLineEnd;
+ USHORT mnRefCount;
+ BOOL mbModified;
+ BOOL mbRead;
+ BOOL mbIsUTF8BOM;
+};
+
+// =======================================================================
+
+static ByteString& getEmptyByteString()
+{
+ static ByteString aEmpty;
+ return aEmpty;
+}
+
+// =======================================================================
+
+static String toUncPath( const String& rPath )
+{
+ ::rtl::OUString aFileURL;
+
+ // check if rFileName is already a URL; if not make it so
+ if( rPath.CompareToAscii( "file://", 7 ) == COMPARE_EQUAL )
+ aFileURL = rPath;
+ else if( ::osl::FileBase::getFileURLFromSystemPath( rPath, aFileURL ) != ::osl::FileBase::E_None )
+ aFileURL = rPath;
+
+ return aFileURL;
+}
+
+static ULONG ImplSysGetConfigTimeStamp( const XubString& rFileName )
+{
+ ULONG nTimeStamp = 0;
+ ::osl::DirectoryItem aItem;
+ ::osl::FileStatus aStatus( osl_FileStatus_Mask_ModifyTime );
+
+ int nError = 0;
+ if( ( nError = ::osl::DirectoryItem::get( rFileName, aItem ) ) == ::osl::FileBase::E_None &&
+ aItem.getFileStatus( aStatus ) == ::osl::FileBase::E_None )
+ {
+ nTimeStamp = aStatus.getModifyTime().Seconds;
+ }
+
+ return nTimeStamp;
+}
+
+// -----------------------------------------------------------------------
+
+static BYTE* ImplSysReadConfig( const XubString& rFileName,
+ sal_uInt64& rRead, BOOL& rbRead, BOOL& rbIsUTF8BOM, ULONG& rTimeStamp )
+{
+ BYTE* pBuf = NULL;
+ ::osl::File aFile( rFileName );
+
+ if( aFile.open( osl_File_OpenFlag_Read ) == ::osl::FileBase::E_None )
+ {
+ sal_uInt64 nPos = 0, nRead = 0;
+ if( aFile.getSize( nPos ) == ::osl::FileBase::E_None )
+ {
+ if (nPos > std::numeric_limits< std::size_t >::max()) {
+ aFile.close();
+ return 0;
+ }
+ pBuf = new BYTE[static_cast< std::size_t >(nPos)];
+ if( aFile.read( pBuf, nPos, nRead ) == ::osl::FileBase::E_None && nRead == nPos )
+ {
+ //skip the byte-order-mark 0xEF 0xBB 0xBF, if it was UTF8 files
+ unsigned char BOM[3] = {0xEF, 0xBB, 0xBF};
+ if (nRead > 2 && memcmp(pBuf, BOM, 3) == 0)
+ {
+ nRead -= 3;
+ rtl_moveMemory(pBuf, pBuf + 3, sal::static_int_cast<sal_Size>(nRead * sizeof(BYTE)) );
+ rbIsUTF8BOM = TRUE;
+ }
+
+ rTimeStamp = ImplSysGetConfigTimeStamp( rFileName );
+ rbRead = TRUE;
+ rRead = nRead;
+ }
+ else
+ {
+ delete[] pBuf;
+ pBuf = NULL;
+ }
+ }
+ aFile.close();
+ }
+
+ return pBuf;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplSysWriteConfig( const XubString& rFileName,
+ const BYTE* pBuf, ULONG nBufLen, BOOL rbIsUTF8BOM, ULONG& rTimeStamp )
+{
+ BOOL bSuccess = FALSE;
+ BOOL bUTF8BOMSuccess = FALSE;
+
+ ::osl::File aFile( rFileName );
+ ::osl::FileBase::RC eError = aFile.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create );
+ if( eError != ::osl::FileBase::E_None )
+ eError = aFile.open( osl_File_OpenFlag_Write );
+ if( eError == ::osl::FileBase::E_None )
+ {
+ // truncate
+ aFile.setSize( 0 );
+ sal_uInt64 nWritten;
+
+ //write the the byte-order-mark 0xEF 0xBB 0xBF first , if it was UTF8 files
+ if ( rbIsUTF8BOM )
+ {
+ unsigned char BOM[3] = {0xEF, 0xBB, 0xBF};
+ sal_uInt64 nUTF8BOMWritten;
+ if( aFile.write( BOM, 3, nUTF8BOMWritten ) == ::osl::FileBase::E_None && 3 == nUTF8BOMWritten )
+ {
+ bUTF8BOMSuccess = TRUE;
+ }
+ }
+
+ if( aFile.write( pBuf, nBufLen, nWritten ) == ::osl::FileBase::E_None && nWritten == nBufLen )
+ {
+ bSuccess = TRUE;
+ }
+ if ( rbIsUTF8BOM ? bSuccess && bUTF8BOMSuccess : bSuccess )
+ {
+ rTimeStamp = ImplSysGetConfigTimeStamp( rFileName );
+ }
+ }
+
+ return rbIsUTF8BOM ? bSuccess && bUTF8BOMSuccess : bSuccess;
+}
+
+// -----------------------------------------------------------------------
+
+static String ImplMakeConfigName( const XubString* pFileName,
+ const XubString* pPathName )
+{
+ ::rtl::OUString aFileName;
+ ::rtl::OUString aPathName;
+ if ( pFileName )
+ {
+#ifdef UNX
+ aFileName = ::rtl::OUString::createFromAscii( "." );
+ aFileName += *pFileName;
+ aFileName += ::rtl::OUString::createFromAscii( "rc" );
+#else
+ aFileName = *pFileName;
+ aFileName += ::rtl::OUString::createFromAscii( ".ini" );
+#endif
+ }
+ else
+ {
+#ifdef UNX
+ aFileName = ::rtl::OUString::createFromAscii( ".sversionrc" );
+#else
+ aFileName = ::rtl::OUString::createFromAscii( "sversion.ini" );
+#endif
+ }
+
+ // #88208# in case pPathName is set but empty and pFileName is set
+ // and not empty just return the filename; on the default case
+ // prepend default path as usual
+ if ( pPathName && pPathName->Len() )
+ aPathName = toUncPath( *pPathName );
+ else if( pPathName && pFileName && pFileName->Len() )
+ return aFileName;
+ else
+ {
+ oslSecurity aSec = osl_getCurrentSecurity();
+ osl_getConfigDir( aSec, &aPathName.pData );
+ osl_freeSecurityHandle( aSec );
+ }
+
+ ::rtl::OUString aName( aPathName );
+ aName += ::rtl::OUString::createFromAscii( "/" );
+ aName += aFileName;
+
+ return aName;
+}
+
+// -----------------------------------------------------------------------
+
+namespace {
+
+ByteString makeByteString(BYTE const * p, sal_uInt64 n) {
+ if (n > STRING_MAXLEN) {
+ #ifdef WNT
+ abort();
+ #else
+ ::std::abort(); //TODO: handle this gracefully
+ #endif
+ }
+ return ByteString(
+ reinterpret_cast< char const * >(p),
+ sal::static_int_cast< xub_StrLen >(n));
+}
+
+}
+
+static void ImplMakeConfigList( ImplConfigData* pData,
+ const BYTE* pBuf, sal_uInt64 nLen )
+{
+ // kein Buffer, keine Daten
+ if ( !nLen )
+ return;
+
+ // Buffer parsen und Liste zusammenbauen
+ sal_uInt64 nStart;
+ sal_uInt64 nLineLen;
+ xub_StrLen nNameLen;
+ xub_StrLen nKeyLen;
+ sal_uInt64 i;
+ const BYTE* pLine;
+ ImplKeyData* pPrevKey = NULL;
+ ImplKeyData* pKey;
+ ImplGroupData* pPrevGroup = NULL;
+ ImplGroupData* pGroup = NULL;
+ i = 0;
+ while ( i < nLen )
+ {
+ // Ctrl+Z
+ if ( pBuf[i] == 0x1A )
+ break;
+
+ // Spaces und Tabs entfernen
+ while ( (pBuf[i] == ' ') || (pBuf[i] == '\t') )
+ i++;
+
+ // Zeilenanfang merken
+ nStart = i;
+ pLine = pBuf+i;
+
+ // Zeilenende suchen
+ while ( (i < nLen) && pBuf[i] && (pBuf[i] != '\r') && (pBuf[i] != '\n') &&
+ (pBuf[i] != 0x1A) )
+ i++;
+
+ nLineLen = i-nStart;
+
+ // Wenn Zeilenende (CR/LF), dann noch einen weiterschalten
+ if ( (i+1 < nLen) &&
+ (pBuf[i] != pBuf[i+1]) &&
+ ((pBuf[i+1] == '\r') || (pBuf[i+1] == '\n')) )
+ i++;
+ i++;
+
+ // Zeile auswerten
+ if ( *pLine == '[' )
+ {
+ pGroup = new ImplGroupData;
+ pGroup->mpNext = NULL;
+ pGroup->mpFirstKey = NULL;
+ pGroup->mnEmptyLines = 0;
+ if ( pPrevGroup )
+ pPrevGroup->mpNext = pGroup;
+ else
+ pData->mpFirstGroup = pGroup;
+ pPrevGroup = pGroup;
+ pPrevKey = NULL;
+ pKey = NULL;
+
+ // Gruppennamen rausfiltern
+ pLine++;
+ nLineLen--;
+ // Spaces und Tabs entfernen
+ while ( (*pLine == ' ') || (*pLine == '\t') )
+ {
+ nLineLen--;
+ pLine++;
+ }
+ nNameLen = 0;
+ while ( (nNameLen < nLineLen) && (pLine[nNameLen] != ']') )
+ nNameLen++;
+ if ( nNameLen )
+ {
+ while ( (pLine[nNameLen-1] == ' ') || (pLine[nNameLen-1] == '\t') )
+ nNameLen--;
+ }
+ pGroup->maGroupName = ByteString( (const sal_Char*)pLine, nNameLen );
+ }
+ else
+ {
+ if ( nLineLen )
+ {
+ // Wenn noch keine Gruppe existiert, dann alle Keys in die
+ // Default-Gruppe
+ if ( !pGroup )
+ {
+ pGroup = new ImplGroupData;
+ pGroup->mpNext = NULL;
+ pGroup->mpFirstKey = NULL;
+ pGroup->mnEmptyLines = 0;
+ if ( pPrevGroup )
+ pPrevGroup->mpNext = pGroup;
+ else
+ pData->mpFirstGroup = pGroup;
+ pPrevGroup = pGroup;
+ pPrevKey = NULL;
+ }
+
+ // Falls Leerzeile vorhanden, dann anhaengen
+ if ( pPrevKey )
+ {
+ while ( pGroup->mnEmptyLines )
+ {
+ pKey = new ImplKeyData;
+ pKey->mbIsComment = TRUE;
+ pPrevKey->mpNext = pKey;
+ pPrevKey = pKey;
+ pGroup->mnEmptyLines--;
+ }
+ }
+
+ // Neuen Key erzeugen
+ pKey = new ImplKeyData;
+ pKey->mpNext = NULL;
+ if ( pPrevKey )
+ pPrevKey->mpNext = pKey;
+ else
+ pGroup->mpFirstKey = pKey;
+ pPrevKey = pKey;
+ if ( pLine[0] == ';' )
+ {
+ pKey->maValue = makeByteString(pLine, nLineLen);
+ pKey->mbIsComment = TRUE;
+ }
+ else
+ {
+ pKey->mbIsComment = FALSE;
+ nNameLen = 0;
+ while ( (nNameLen < nLineLen) && (pLine[nNameLen] != '=') )
+ nNameLen++;
+ nKeyLen = nNameLen;
+ // Spaces und Tabs entfernen
+ if ( nNameLen )
+ {
+ while ( (pLine[nNameLen-1] == ' ') || (pLine[nNameLen-1] == '\t') )
+ nNameLen--;
+ }
+ pKey->maKey = ByteString( (const sal_Char*)pLine, nNameLen );
+ nKeyLen++;
+ if ( nKeyLen < nLineLen )
+ {
+ pLine += nKeyLen;
+ nLineLen -= nKeyLen;
+ // Spaces und Tabs entfernen
+ while ( (*pLine == ' ') || (*pLine == '\t') )
+ {
+ nLineLen--;
+ pLine++;
+ }
+ if ( nLineLen )
+ {
+ while ( (pLine[nLineLen-1] == ' ') || (pLine[nLineLen-1] == '\t') )
+ nLineLen--;
+ pKey->maValue = makeByteString(pLine, nLineLen);
+ }
+ }
+ }
+ }
+ else
+ {
+ // Leerzeilen werden nur gezaehlt und beim Erzeugen des
+ // naechsten Keys angehaengt, da wir Leerzeilen am Ende
+ // einer Gruppe auch nach hinzufuegen von neuen Keys nur
+ // am Ende der Gruppe wieder speichern wollen
+ if ( pGroup )
+ pGroup->mnEmptyLines++;
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static BYTE* ImplGetConfigBuffer( const ImplConfigData* pData, ULONG& rLen )
+{
+ BYTE* pWriteBuf;
+ BYTE* pBuf;
+ BYTE aLineEndBuf[2] = {0, 0};
+ ImplKeyData* pKey;
+ ImplGroupData* pGroup;
+ unsigned int nBufLen;
+ USHORT nValueLen;
+ USHORT nKeyLen;
+ USHORT nLineEndLen;
+
+ if ( pData->meLineEnd == LINEEND_CR )
+ {
+ aLineEndBuf[0] = _CR;
+ nLineEndLen = 1;
+ }
+ else if ( pData->meLineEnd == LINEEND_LF )
+ {
+ aLineEndBuf[0] = _LF;
+ nLineEndLen = 1;
+ }
+ else
+ {
+ aLineEndBuf[0] = _CR;
+ aLineEndBuf[1] = _LF;
+ nLineEndLen = 2;
+ }
+
+ // Buffergroesse ermitteln
+ nBufLen = 0;
+ pGroup = pData->mpFirstGroup;
+ while ( pGroup )
+ {
+ // Leere Gruppen werden nicht geschrieben
+ if ( pGroup->mpFirstKey )
+ {
+ nBufLen += pGroup->maGroupName.Len() + nLineEndLen + 2;
+ pKey = pGroup->mpFirstKey;
+ while ( pKey )
+ {
+ nValueLen = pKey->maValue.Len();
+ if ( pKey->mbIsComment )
+ nBufLen += nValueLen + nLineEndLen;
+ else
+ nBufLen += pKey->maKey.Len() + nValueLen + nLineEndLen + 1;
+
+ pKey = pKey->mpNext;
+ }
+
+ // Leerzeile nach jeder Gruppe auch wieder speichern
+ if ( !pGroup->mnEmptyLines )
+ pGroup->mnEmptyLines = 1;
+ nBufLen += nLineEndLen * pGroup->mnEmptyLines;
+ }
+
+ pGroup = pGroup->mpNext;
+ }
+
+ // Laenge dem Aufrufer mitteilen
+ rLen = nBufLen;
+ if ( !nBufLen )
+ {
+ pWriteBuf = new BYTE[nLineEndLen];
+ if ( pWriteBuf )
+ {
+ pWriteBuf[0] = aLineEndBuf[0];
+ if ( nLineEndLen == 2 )
+ pWriteBuf[1] = aLineEndBuf[1];
+ return pWriteBuf;
+ }
+ else
+ return 0;
+ }
+
+ // Schreibbuffer anlegen (wird vom Aufrufer zerstoert)
+ pWriteBuf = new BYTE[nBufLen];
+ if ( !pWriteBuf )
+ return 0;
+
+ // Buffer fuellen
+ pBuf = pWriteBuf;
+ pGroup = pData->mpFirstGroup;
+ while ( pGroup )
+ {
+ // Leere Gruppen werden nicht geschrieben
+ if ( pGroup->mpFirstKey )
+ {
+ *pBuf = '['; pBuf++;
+ memcpy( pBuf, pGroup->maGroupName.GetBuffer(), pGroup->maGroupName.Len() );
+ pBuf += pGroup->maGroupName.Len();
+ *pBuf = ']'; pBuf++;
+ *pBuf = aLineEndBuf[0]; pBuf++;
+ if ( nLineEndLen == 2 )
+ {
+ *pBuf = aLineEndBuf[1]; pBuf++;
+ }
+ pKey = pGroup->mpFirstKey;
+ while ( pKey )
+ {
+ nValueLen = pKey->maValue.Len();
+ if ( pKey->mbIsComment )
+ {
+ if ( nValueLen )
+ {
+ memcpy( pBuf, pKey->maValue.GetBuffer(), nValueLen );
+ pBuf += nValueLen;
+ }
+ *pBuf = aLineEndBuf[0]; pBuf++;
+ if ( nLineEndLen == 2 )
+ {
+ *pBuf = aLineEndBuf[1]; pBuf++;
+ }
+ }
+ else
+ {
+ nKeyLen = pKey->maKey.Len();
+ memcpy( pBuf, pKey->maKey.GetBuffer(), nKeyLen );
+ pBuf += nKeyLen;
+ *pBuf = '='; pBuf++;
+ memcpy( pBuf, pKey->maValue.GetBuffer(), nValueLen );
+ pBuf += nValueLen;
+ *pBuf = aLineEndBuf[0]; pBuf++;
+ if ( nLineEndLen == 2 )
+ {
+ *pBuf = aLineEndBuf[1]; pBuf++;
+ }
+ }
+
+ pKey = pKey->mpNext;
+ }
+
+ // Leerzeile nach jeder Gruppe auch wieder speichern
+ USHORT nEmptyLines = pGroup->mnEmptyLines;
+ while ( nEmptyLines )
+ {
+ *pBuf = aLineEndBuf[0]; pBuf++;
+ if ( nLineEndLen == 2 )
+ {
+ *pBuf = aLineEndBuf[1]; pBuf++;
+ }
+ nEmptyLines--;
+ }
+ }
+
+ pGroup = pGroup->mpNext;
+ }
+
+ return pWriteBuf;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplReadConfig( ImplConfigData* pData )
+{
+ ULONG nTimeStamp = 0;
+ sal_uInt64 nRead = 0;
+ BOOL bRead = FALSE;
+ BOOL bIsUTF8BOM =FALSE;
+ BYTE* pBuf = ImplSysReadConfig( pData->maFileName, nRead, bRead, bIsUTF8BOM, nTimeStamp );
+
+ // Aus dem Buffer die Config-Verwaltungsliste aufbauen
+ if ( pBuf )
+ {
+ ImplMakeConfigList( pData, pBuf, nRead );
+ delete[] pBuf;
+ }
+ pData->mnTimeStamp = nTimeStamp;
+ pData->mbModified = FALSE;
+ if ( bRead )
+ pData->mbRead = TRUE;
+ if ( bIsUTF8BOM )
+ pData->mbIsUTF8BOM = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplWriteConfig( ImplConfigData* pData )
+{
+#ifdef DBG_UTIL
+ if ( DbgIsAssert() )
+ {
+ if ( pData->mnTimeStamp != ImplSysGetConfigTimeStamp( pData->maFileName ) )
+ {
+ DBG_ERROR1( "Config overwrites modified configfile:\n %s", ByteString( pData->maFileName, RTL_TEXTENCODING_UTF8 ).GetBuffer() );
+ }
+ }
+#endif
+
+ // Aus der Config-Liste einen Buffer zusammenbauen
+ ULONG nBufLen;
+ BYTE* pBuf = ImplGetConfigBuffer( pData, nBufLen );
+ if ( pBuf )
+ {
+ if ( ImplSysWriteConfig( pData->maFileName, pBuf, nBufLen, pData->mbIsUTF8BOM, pData->mnTimeStamp ) )
+ pData->mbModified = FALSE;
+ delete[] pBuf;
+ }
+ else
+ pData->mbModified = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDeleteConfigData( ImplConfigData* pData )
+{
+ ImplKeyData* pTempKey;
+ ImplKeyData* pKey;
+ ImplGroupData* pTempGroup;
+ ImplGroupData* pGroup = pData->mpFirstGroup;
+ while ( pGroup )
+ {
+ pTempGroup = pGroup->mpNext;
+
+ // Alle Keys loeschen
+ pKey = pGroup->mpFirstKey;
+ while ( pKey )
+ {
+ pTempKey = pKey->mpNext;
+ delete pKey;
+ pKey = pTempKey;
+ }
+
+ // Gruppe loeschen und weiterschalten
+ delete pGroup;
+ pGroup = pTempGroup;
+ }
+
+ pData->mpFirstGroup = NULL;
+}
+
+// =======================================================================
+
+static ImplConfigData* ImplGetConfigData( const XubString& rFileName )
+{
+ ImplConfigData* pData;
+
+ pData = new ImplConfigData;
+ pData->maFileName = rFileName;
+ pData->mpFirstGroup = NULL;
+ pData->mnDataUpdateId = 0;
+ pData->meLineEnd = LINEEND_CRLF;
+ pData->mnRefCount = 0;
+ pData->mbRead = FALSE;
+ pData->mbIsUTF8BOM = FALSE;
+ ImplReadConfig( pData );
+
+ return pData;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplFreeConfigData( ImplConfigData* pDelData )
+{
+ ImplDeleteConfigData( pDelData );
+ delete pDelData;
+}
+
+// =======================================================================
+
+BOOL Config::ImplUpdateConfig() const
+{
+ // Wenn sich TimeStamp unterscheidet, dann Datei neu einlesen
+ if ( mpData->mnTimeStamp != ImplSysGetConfigTimeStamp( maFileName ) )
+ {
+ ImplDeleteConfigData( mpData );
+ ImplReadConfig( mpData );
+ mpData->mnDataUpdateId++;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+ImplGroupData* Config::ImplGetGroup() const
+{
+ if ( !mpActGroup || (mnDataUpdateId != mpData->mnDataUpdateId) )
+ {
+ ImplGroupData* pPrevGroup = NULL;
+ ImplGroupData* pGroup = mpData->mpFirstGroup;
+ while ( pGroup )
+ {
+ if ( pGroup->maGroupName.EqualsIgnoreCaseAscii( maGroupName ) )
+ break;
+
+ pPrevGroup = pGroup;
+ pGroup = pGroup->mpNext;
+ }
+
+ // Falls Gruppe noch nicht existiert, dann dazufuegen
+ if ( !pGroup )
+ {
+ pGroup = new ImplGroupData;
+ pGroup->mpNext = NULL;
+ pGroup->mpFirstKey = NULL;
+ pGroup->mnEmptyLines = 1;
+ if ( pPrevGroup )
+ pPrevGroup->mpNext = pGroup;
+ else
+ mpData->mpFirstGroup = pGroup;
+ }
+
+ // Gruppenname immer uebernehmen, da er auch in dieser Form
+ // geschrieben werden soll. Ausserdem die Cache-Members der
+ // Config-Klasse updaten
+ pGroup->maGroupName = maGroupName;
+ ((Config*)this)->mnDataUpdateId = mpData->mnDataUpdateId;
+ ((Config*)this)->mpActGroup = pGroup;
+ }
+
+ return mpActGroup;
+}
+
+// =======================================================================
+
+Config::Config()
+{
+ // Daten initialisieren und einlesen
+ maFileName = ImplMakeConfigName( NULL, NULL );
+ mpData = ImplGetConfigData( maFileName );
+ mpActGroup = NULL;
+ mnDataUpdateId = 0;
+ mnLockCount = 1;
+ mbPersistence = TRUE;
+
+#ifdef DBG_UTIL
+ DBG_TRACE( "Config::Config()" );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+Config::Config( const XubString& rFileName )
+{
+ // Daten initialisieren und einlesen
+ maFileName = toUncPath( rFileName );
+ mpData = ImplGetConfigData( maFileName );
+ mpActGroup = NULL;
+ mnDataUpdateId = 0;
+ mnLockCount = 1;
+ mbPersistence = TRUE;
+
+#ifdef DBG_UTIL
+ ByteString aTraceStr( "Config::Config( " );
+ aTraceStr += ByteString( maFileName, RTL_TEXTENCODING_UTF8 );
+ aTraceStr += " )";
+ DBG_TRACE( aTraceStr.GetBuffer() );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+Config::~Config()
+{
+#ifdef DBG_UTIL
+ DBG_TRACE( "Config::~Config()" );
+#endif
+
+ Flush();
+ ImplFreeConfigData( mpData );
+}
+
+// -----------------------------------------------------------------------
+
+String Config::GetDefDirectory()
+{
+ ::rtl::OUString aDefConfig;
+ oslSecurity aSec = osl_getCurrentSecurity();
+ osl_getConfigDir( aSec, &aDefConfig.pData );
+ osl_freeSecurityHandle( aSec );
+
+ return aDefConfig;
+}
+
+// -----------------------------------------------------------------------
+
+XubString Config::GetConfigName( const XubString& rPath,
+ const XubString& rBaseName )
+{
+ return ImplMakeConfigName( &rBaseName, &rPath );
+}
+
+// -----------------------------------------------------------------------
+
+void Config::SetGroup( const ByteString& rGroup )
+{
+ // Wenn neue Gruppe gesetzt wird, muss beim naechsten mal die
+ // Gruppe neu ermittelt werden
+ if ( maGroupName != rGroup )
+ {
+ maGroupName = rGroup;
+ mnDataUpdateId = mpData->mnDataUpdateId-1;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Config::DeleteGroup( const ByteString& rGroup )
+{
+ // Config-Daten evt. updaten
+ if ( !mnLockCount || !mpData->mbRead )
+ {
+ ImplUpdateConfig();
+ mpData->mbRead = TRUE;
+ }
+
+ ImplGroupData* pPrevGroup = NULL;
+ ImplGroupData* pGroup = mpData->mpFirstGroup;
+ while ( pGroup )
+ {
+ if ( pGroup->maGroupName.EqualsIgnoreCaseAscii( rGroup ) )
+ break;
+
+ pPrevGroup = pGroup;
+ pGroup = pGroup->mpNext;
+ }
+
+ if ( pGroup )
+ {
+ // Alle Keys loeschen
+ ImplKeyData* pTempKey;
+ ImplKeyData* pKey = pGroup->mpFirstKey;
+ while ( pKey )
+ {
+ pTempKey = pKey->mpNext;
+ delete pKey;
+ pKey = pTempKey;
+ }
+
+ // Gruppe weiterschalten und loeschen
+ if ( pPrevGroup )
+ pPrevGroup->mpNext = pGroup->mpNext;
+ else
+ mpData->mpFirstGroup = pGroup->mpNext;
+ delete pGroup;
+
+ // Config-Datei neu schreiben
+ if ( !mnLockCount && mbPersistence )
+ ImplWriteConfig( mpData );
+ else
+ {
+ mpData->mbModified = TRUE;
+ }
+
+ // Gruppen auf ungluetig setzen
+ mnDataUpdateId = mpData->mnDataUpdateId;
+ mpData->mnDataUpdateId++;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ByteString Config::GetGroupName( USHORT nGroup ) const
+{
+ // Config-Daten evt. updaten
+ if ( !mnLockCount )
+ ImplUpdateConfig();
+
+ ImplGroupData* pGroup = mpData->mpFirstGroup;
+ USHORT nGroupCount = 0;
+ ByteString aGroupName;
+ while ( pGroup )
+ {
+ if ( nGroup == nGroupCount )
+ {
+ aGroupName = pGroup->maGroupName;
+ break;
+ }
+
+ nGroupCount++;
+ pGroup = pGroup->mpNext;
+ }
+
+ return aGroupName;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Config::GetGroupCount() const
+{
+ // Config-Daten evt. updaten
+ if ( !mnLockCount )
+ ImplUpdateConfig();
+
+ ImplGroupData* pGroup = mpData->mpFirstGroup;
+ USHORT nGroupCount = 0;
+ while ( pGroup )
+ {
+ nGroupCount++;
+ pGroup = pGroup->mpNext;
+ }
+
+ return nGroupCount;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Config::HasGroup( const ByteString& rGroup ) const
+{
+ // Config-Daten evt. updaten
+ if ( !mnLockCount )
+ ImplUpdateConfig();
+
+ ImplGroupData* pGroup = mpData->mpFirstGroup;
+ BOOL bRet = FALSE;
+
+ while( pGroup )
+ {
+ if( pGroup->maGroupName.EqualsIgnoreCaseAscii( rGroup ) )
+ {
+ bRet = TRUE;
+ break;
+ }
+
+ pGroup = pGroup->mpNext;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+ByteString Config::ReadKey( const ByteString& rKey ) const
+{
+ return ReadKey( rKey, getEmptyByteString() );
+}
+
+// -----------------------------------------------------------------------
+
+UniString Config::ReadKey( const ByteString& rKey, rtl_TextEncoding eEncoding ) const
+{
+ if ( mpData->mbIsUTF8BOM )
+ eEncoding = RTL_TEXTENCODING_UTF8;
+ return UniString( ReadKey( rKey ), eEncoding );
+}
+
+// -----------------------------------------------------------------------
+
+ByteString Config::ReadKey( const ByteString& rKey, const ByteString& rDefault ) const
+{
+#ifdef DBG_UTIL
+ ByteString aTraceStr( "Config::ReadKey( " );
+ aTraceStr += rKey;
+ aTraceStr += " ) from ";
+ aTraceStr += GetGroup();
+ aTraceStr += " in ";
+ aTraceStr += ByteString( maFileName, RTL_TEXTENCODING_UTF8 );
+ DBG_TRACE( aTraceStr.GetBuffer() );
+#endif
+
+ // Config-Daten evt. updaten
+ if ( !mnLockCount )
+ ImplUpdateConfig();
+
+ // Key suchen und Value zurueckgeben
+ ImplGroupData* pGroup = ImplGetGroup();
+ if ( pGroup )
+ {
+ ImplKeyData* pKey = pGroup->mpFirstKey;
+ while ( pKey )
+ {
+ if ( !pKey->mbIsComment && pKey->maKey.EqualsIgnoreCaseAscii( rKey ) )
+ return pKey->maValue;
+
+ pKey = pKey->mpNext;
+ }
+ }
+
+ return rDefault;
+}
+
+// -----------------------------------------------------------------------
+
+void Config::WriteKey( const ByteString& rKey, const ByteString& rStr )
+{
+#ifdef DBG_UTIL
+ ByteString aTraceStr( "Config::WriteKey( " );
+ aTraceStr += rKey;
+ aTraceStr += ", ";
+ aTraceStr += rStr;
+ aTraceStr += " ) to ";
+ aTraceStr += GetGroup();
+ aTraceStr += " in ";
+ aTraceStr += ByteString( maFileName, RTL_TEXTENCODING_UTF8 );
+ DBG_TRACE( aTraceStr.GetBuffer() );
+ DBG_ASSERTWARNING( rStr != ReadKey( rKey ), "Config::WriteKey() with the same Value" );
+#endif
+
+ // Config-Daten evt. updaten
+ if ( !mnLockCount || !mpData->mbRead )
+ {
+ ImplUpdateConfig();
+ mpData->mbRead = TRUE;
+ }
+
+ // Key suchen und Value setzen
+ ImplGroupData* pGroup = ImplGetGroup();
+ if ( pGroup )
+ {
+ ImplKeyData* pPrevKey = NULL;
+ ImplKeyData* pKey = pGroup->mpFirstKey;
+ while ( pKey )
+ {
+ if ( !pKey->mbIsComment && pKey->maKey.EqualsIgnoreCaseAscii( rKey ) )
+ break;
+
+ pPrevKey = pKey;
+ pKey = pKey->mpNext;
+ }
+
+ BOOL bNewValue;
+ if ( !pKey )
+ {
+ pKey = new ImplKeyData;
+ pKey->mpNext = NULL;
+ pKey->maKey = rKey;
+ pKey->mbIsComment = FALSE;
+ if ( pPrevKey )
+ pPrevKey->mpNext = pKey;
+ else
+ pGroup->mpFirstKey = pKey;
+ bNewValue = TRUE;
+ }
+ else
+ bNewValue = pKey->maValue != rStr;
+
+ if ( bNewValue )
+ {
+ pKey->maValue = rStr;
+
+ if ( !mnLockCount && mbPersistence )
+ ImplWriteConfig( mpData );
+ else
+ {
+ mpData->mbModified = TRUE;
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Config::WriteKey( const ByteString& rKey, const UniString& rValue, rtl_TextEncoding eEncoding )
+{
+ if ( mpData->mbIsUTF8BOM )
+ eEncoding = RTL_TEXTENCODING_UTF8;
+ WriteKey( rKey, ByteString( rValue, eEncoding ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Config::DeleteKey( const ByteString& rKey )
+{
+ // Config-Daten evt. updaten
+ if ( !mnLockCount || !mpData->mbRead )
+ {
+ ImplUpdateConfig();
+ mpData->mbRead = TRUE;
+ }
+
+ // Key suchen und Value setzen
+ ImplGroupData* pGroup = ImplGetGroup();
+ if ( pGroup )
+ {
+ ImplKeyData* pPrevKey = NULL;
+ ImplKeyData* pKey = pGroup->mpFirstKey;
+ while ( pKey )
+ {
+ if ( !pKey->mbIsComment && pKey->maKey.EqualsIgnoreCaseAscii( rKey ) )
+ break;
+
+ pPrevKey = pKey;
+ pKey = pKey->mpNext;
+ }
+
+ if ( pKey )
+ {
+ // Gruppe weiterschalten und loeschen
+ if ( pPrevKey )
+ pPrevKey->mpNext = pKey->mpNext;
+ else
+ pGroup->mpFirstKey = pKey->mpNext;
+ delete pKey;
+
+ // Config-Datei neu schreiben
+ if ( !mnLockCount && mbPersistence )
+ ImplWriteConfig( mpData );
+ else
+ {
+ mpData->mbModified = TRUE;
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Config::GetKeyCount() const
+{
+#ifdef DBG_UTIL
+ ByteString aTraceStr( "Config::GetKeyCount()" );
+ aTraceStr += " from ";
+ aTraceStr += GetGroup();
+ aTraceStr += " in ";
+ aTraceStr += ByteString( maFileName, RTL_TEXTENCODING_UTF8 );
+ DBG_TRACE( aTraceStr.GetBuffer() );
+#endif
+
+ // Config-Daten evt. updaten
+ if ( !mnLockCount )
+ ImplUpdateConfig();
+
+ // Key suchen und Value zurueckgeben
+ USHORT nCount = 0;
+ ImplGroupData* pGroup = ImplGetGroup();
+ if ( pGroup )
+ {
+ ImplKeyData* pKey = pGroup->mpFirstKey;
+ while ( pKey )
+ {
+ if ( !pKey->mbIsComment )
+ nCount++;
+
+ pKey = pKey->mpNext;
+ }
+ }
+
+ return nCount;
+}
+
+// -----------------------------------------------------------------------
+
+ByteString Config::GetKeyName( USHORT nKey ) const
+{
+#ifdef DBG_UTIL
+ ByteString aTraceStr( "Config::GetKeyName( " );
+ aTraceStr += ByteString::CreateFromInt32(nKey);
+ aTraceStr += " ) from ";
+ aTraceStr += GetGroup();
+ aTraceStr += " in ";
+ aTraceStr += ByteString( maFileName, RTL_TEXTENCODING_UTF8 );
+ DBG_TRACE( aTraceStr.GetBuffer() );
+#endif
+
+ // Key suchen und Name zurueckgeben
+ ImplGroupData* pGroup = ImplGetGroup();
+ if ( pGroup )
+ {
+ ImplKeyData* pKey = pGroup->mpFirstKey;
+ while ( pKey )
+ {
+ if ( !pKey->mbIsComment )
+ {
+ if ( !nKey )
+ return pKey->maKey;
+ nKey--;
+ }
+
+ pKey = pKey->mpNext;
+ }
+ }
+
+ return getEmptyByteString();
+}
+
+// -----------------------------------------------------------------------
+
+ByteString Config::ReadKey( USHORT nKey ) const
+{
+#ifdef DBG_UTIL
+ ByteString aTraceStr( "Config::ReadKey( " );
+ aTraceStr += ByteString::CreateFromInt32( nKey );
+ aTraceStr += " ) from ";
+ aTraceStr += GetGroup();
+ aTraceStr += " in ";
+ aTraceStr += ByteString( maFileName, RTL_TEXTENCODING_UTF8 );
+ DBG_TRACE( aTraceStr.GetBuffer() );
+#endif
+
+ // Key suchen und Value zurueckgeben
+ ImplGroupData* pGroup = ImplGetGroup();
+ if ( pGroup )
+ {
+ ImplKeyData* pKey = pGroup->mpFirstKey;
+ while ( pKey )
+ {
+ if ( !pKey->mbIsComment )
+ {
+ if ( !nKey )
+ return pKey->maValue;
+ nKey--;
+ }
+
+ pKey = pKey->mpNext;
+ }
+ }
+
+ return getEmptyByteString();
+}
+
+// -----------------------------------------------------------------------
+
+void Config::EnterLock()
+{
+ // Config-Daten evt. updaten
+ if ( !mnLockCount )
+ ImplUpdateConfig();
+
+ mnLockCount++;
+}
+
+// -----------------------------------------------------------------------
+
+void Config::LeaveLock()
+{
+ DBG_ASSERT( mnLockCount, "Config::LeaveLook() without Config::EnterLook()" );
+ mnLockCount--;
+
+ if ( (mnLockCount == 0) && mpData->mbModified && mbPersistence )
+ ImplWriteConfig( mpData );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Config::Update()
+{
+ return ImplUpdateConfig();
+}
+
+// -----------------------------------------------------------------------
+
+void Config::Flush()
+{
+ if ( mpData->mbModified && mbPersistence )
+ ImplWriteConfig( mpData );
+}
+
+// -----------------------------------------------------------------------
+
+void Config::SetLineEnd( LineEnd eLineEnd )
+{
+ mpData->meLineEnd = eLineEnd;
+}
+
+// -----------------------------------------------------------------------
+
+LineEnd Config::GetLineEnd() const
+{
+ return mpData->meLineEnd;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/generic/fract.cxx b/tools/source/generic/fract.cxx
new file mode 100644
index 000000000000..290e566505e2
--- /dev/null
+++ b/tools/source/generic/fract.cxx
@@ -0,0 +1,737 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <limits.h>
+#include <tools/debug.hxx>
+#include <tools/fract.hxx>
+#include <tools/stream.hxx>
+
+#include <tools/bigint.hxx>
+
+/*************************************************************************
+|*
+|* GetGGT()
+|*
+|* Beschreibung Berechnet den groessten gemeinsamen Teiler von
+|* nVal1 und nVal2
+|* Parameter long nVal1, long nVal2
+|* Ersterstellung DV 20.09.90
+|* Letzte Aenderung DV 21.12.92
+|*
+*************************************************************************/
+
+// Die Funktion GetGGT berechnet den groessten gemeinsamen Teiler der
+// beiden als Parameter uebergebenen Werte nVal1 und nVal2 nach dem
+// Algorithmus von Euklid. Hat einer der beiden Parameter den Wert 0 oder
+// 1, so wird als Ergebnis der Wert 1 zurŸckgegeben. Da der Algorithmus
+// nur mit positiven Zahlen arbeitet, werden die beiden Parameter
+// entsprechend umgewandelt.
+// Zum Algorithmus: die beiden Parameter werden solange ducheinander
+// geteilt, bis sie beide gleich sind oder bis bei der Division
+// kein Rest bleibt. Der kleinere der beiden Werte ist dann der
+// GGT.
+
+static long GetGGT( long nVal1, long nVal2 )
+{
+ nVal1 = Abs( nVal1 );
+ nVal2 = Abs( nVal2 );
+
+ if ( nVal1 <= 1 || nVal2 <= 1 )
+ return 1;
+
+ while ( nVal1 != nVal2 )
+ {
+ if ( nVal1 > nVal2 )
+ {
+ nVal1 %= nVal2;
+ if ( nVal1 == 0 )
+ return nVal2;
+ }
+ else
+ {
+ nVal2 %= nVal1;
+ if ( nVal2 == 0 )
+ return nVal1;
+ }
+ }
+
+ return nVal1;
+}
+
+static void Reduce( BigInt &rVal1, BigInt &rVal2 )
+{
+ BigInt nA( rVal1 );
+ BigInt nB( rVal2 );
+ nA.Abs();
+ nB.Abs();
+
+ if ( nA.IsOne() || nB.IsOne() || nA.IsZero() || nB.IsZero() )
+ return;
+
+ while ( nA != nB )
+ {
+ if ( nA > nB )
+ {
+ nA %= nB;
+ if ( nA.IsZero() )
+ {
+ rVal1 /= nB;
+ rVal2 /= nB;
+ return;
+ }
+ }
+ else
+ {
+ nB %= nA;
+ if ( nB.IsZero() )
+ {
+ rVal1 /= nA;
+ rVal2 /= nA;
+ return;
+ }
+ }
+ }
+
+ rVal1 /= nA;
+ rVal2 /= nB;
+}
+
+/*************************************************************************
+|*
+|* Fraction::Fraction()
+|*
+|* Beschreibung FRACT.SDW
+|* Ersterstellung WP 07.03.97
+|* Letzte Aenderung
+|*
+*************************************************************************/
+
+Fraction::Fraction( long nN1, long nN2, long nD1, long nD2 )
+{
+ long n;
+ int i = 1;
+
+ if( nN1 < 0 ) { i = -i; nN1 = -nN1; }
+ if( nN2 < 0 ) { i = -i; nN2 = -nN2; }
+ if( nD1 < 0 ) { i = -i; nD1 = -nD1; }
+ if( nD2 < 0 ) { i = -i; nD2 = -nD2; }
+
+ n = GetGGT( nN1, nD1 ); if( n > 1 ) { nN1 /= n; nD1 /= n; }
+ n = GetGGT( nN1, nD2 ); if( n > 1 ) { nN1 /= n; nD2 /= n; }
+ n = GetGGT( nN2, nD1 ); if( n > 1 ) { nN2 /= n; nD1 /= n; }
+ n = GetGGT( nN2, nD2 ); if( n > 1 ) { nN2 /= n; nD2 /= n; }
+
+ BigInt nN( nN1 );
+ nN *= BigInt( nN2 );
+
+ BigInt nD( nD1 );
+ nD *= BigInt( nD2 );
+
+ while ( nN.bIsBig || nD.bIsBig )
+ {
+ BigInt n1 = 1;
+ BigInt n2 = 2;
+
+ nN += n1;
+ nN /= n2;
+ nD += n1;
+ nD /= n2;
+
+ // Kuerzen ueber Groesste Gemeinsame Teiler
+ Reduce( nN, nD );
+ }
+
+ nNumerator = i * (long)nN;
+ nDenominator = (long)nD;
+}
+
+/*************************************************************************
+|*
+|* Fraction::Fraction()
+|*
+|* Beschreibung FRACT.SDW
+|* Ersterstellung DV 20.09.90
+|* Letzte Aenderung DV 21.12.92
+|*
+*************************************************************************/
+
+// Zur Initialisierung eines Bruches wird nNum dem Zaehler und nDen dem
+// Nenner zugewiesen. Da negative Werte des Nenners einen Bruch als
+// ungueltig kennzeichnen, wird bei der Eingabe eines negativen Nenners
+// sowohl das Vorzeichen des Nenners und des Zaehlers invertiert um wieder
+// einen gueltigen Wert fuer den Bruch zu erhalten.
+
+Fraction::Fraction( long nNum, long nDen )
+{
+ nNumerator = nNum;
+ nDenominator = nDen;
+ if ( nDenominator < 0 )
+ {
+ nDenominator = -nDenominator;
+ nNumerator = -nNumerator;
+ }
+
+ // Kuerzen ueber Groesste Gemeinsame Teiler
+ long n = GetGGT( nNumerator, nDenominator );
+ nNumerator /= n;
+ nDenominator /= n;
+}
+
+/*************************************************************************
+|*
+|* Fraction::Fraction()
+|*
+|* Beschreibung FRACT.SDW
+|* Ersterstellung DV 20.09.90
+|* Letzte Aenderung DV 21.12.92
+|*
+*************************************************************************/
+
+// Wenn der Wert von dVal groesser ist als LONG_MAX, dann wird der Bruch
+// auf den Wert ungueltig gesetzt, ansonsten werden dVal und der Nenner
+// solange mit 10 multipliziert, bis entweder der Zaehler oder der Nenner
+// groesser als LONG_MAX / 10 ist. Zum Schluss wird der so entstandene Bruch
+// gekuerzt.
+
+Fraction::Fraction( double dVal )
+{
+ long nDen = 1;
+ long nMAX = LONG_MAX / 10;
+
+ if ( dVal > LONG_MAX || dVal < LONG_MIN )
+ {
+ nNumerator = 0;
+ nDenominator = -1;
+ return;
+ }
+
+ while ( Abs( (long)dVal ) < nMAX && nDen < nMAX )
+ {
+ dVal *= 10;
+ nDen *= 10;
+ }
+ nNumerator = (long)dVal;
+ nDenominator = nDen;
+
+ // Kuerzen ueber Groesste Gemeinsame Teiler
+ long n = GetGGT( nNumerator, nDenominator );
+ nNumerator /= n;
+ nDenominator /= n;
+}
+
+/*************************************************************************
+|*
+|* Fraction::operator double()
+|*
+|* Beschreibung FRACT.SDW
+|* Ersterstellung DV 20.09.90
+|* Letzte Aenderung DV 14.05.91
+|*
+*************************************************************************/
+
+Fraction::operator double() const
+{
+ if ( nDenominator > 0 )
+ return (double)nNumerator / (double)nDenominator;
+ else
+ return (double)0;
+}
+
+/*************************************************************************
+|*
+|* Fraction::operator+=()
+|*
+|* Beschreibung FRACT.SDW
+|* Ersterstellung DV 20.09.90
+|* Letzte Aenderung DV 21.12.92
+|*
+*************************************************************************/
+
+// Zunaechst werden die beiden Parameter auf ihre Gueltigkeit ueberprueft.
+// Ist einer der Parameter ungueltig, dann ist auch des Ergebnis
+// ungueltig. Zur Addition werden die beiden Brueche erst durch
+// Erweiterung mit den Nenner des jeweils anderen Bruches auf einen
+// gemeinsamen Nenner gebracht. Anschliessend werden die beiden Zaehler
+// addiert und das Ergebnis gekuerzt (durch Division von Zaehler und
+// Nenner mit nGGT). Innerhalb der Funktion wird mit dem Datentyp SLong
+// gerechnet, um einen Moeglichen Ueberlauf erkennen zu koennen. Bei
+// einem Ueberlauf wird das Ergebnis auf den Wert ungueltig gesetzt.
+
+Fraction& Fraction::operator += ( const Fraction& rVal )
+{
+ if ( !rVal.IsValid() )
+ {
+ nNumerator = 0;
+ nDenominator = -1;
+ }
+ if ( !IsValid() )
+ return *this;
+
+ // (a/b) + (c/d) = ( (a*d) + (c*b) ) / (b*d)
+ BigInt nN( nNumerator );
+ nN *= BigInt( rVal.nDenominator );
+ BigInt nW1Temp( nDenominator );
+ nW1Temp *= BigInt( rVal.nNumerator );
+ nN += nW1Temp;
+
+ BigInt nD( nDenominator );
+ nD *= BigInt( rVal.nDenominator );
+
+ Reduce( nN, nD );
+
+ if ( nN.bIsBig || nD.bIsBig )
+ {
+ nNumerator = 0;
+ nDenominator = -1;
+ }
+ else
+ {
+ nNumerator = (long)nN,
+ nDenominator = (long)nD;
+ }
+
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* Fraction::operator-=()
+|*
+|* Beschreibung FRACT.SDW
+|* Ersterstellung DV 20.09.90
+|* Letzte Aenderung DV 21.12.92
+|*
+*************************************************************************/
+
+// Zunaechst werden die beiden Parameter auf ihre Gueltigkeit ueberprueft.
+// Ist einer der Parameter ungueltig, dann ist auch des Ergebnis
+// ungueltig. Zur Subtraktion werden die beiden Brueche erst durch
+// Erweiterung mit den Nenner des jeweils anderen Bruches auf einen
+// gemeinsamen Nenner gebracht. Anschliessend werden die beiden Zaehler
+// subtrahiert und das Ergebnis gekuerzt (durch Division von Zaehler und
+// Nenner mit nGGT). Innerhalb der Funktion wird mit dem Datentyp BigInt
+// gerechnet, um einen Moeglichen Ueberlauf erkennen zu koennen. Bei
+// einem Ueberlauf wird das Ergebnis auf den Wert ungueltig gesetzt.
+
+Fraction& Fraction::operator -= ( const Fraction& rVal )
+{
+ if ( !rVal.IsValid() )
+ {
+ nNumerator = 0;
+ nDenominator = -1;
+ }
+ if ( !IsValid() )
+ return *this;
+
+ // (a/b) - (c/d) = ( (a*d) - (c*b) ) / (b*d)
+ BigInt nN( nNumerator );
+ nN *= BigInt( rVal.nDenominator );
+ BigInt nW1Temp( nDenominator );
+ nW1Temp *= BigInt( rVal.nNumerator );
+ nN -= nW1Temp;
+
+ BigInt nD( nDenominator );
+ nD *= BigInt( rVal.nDenominator );
+
+ Reduce( nN, nD );
+
+ if ( nN.bIsBig || nD.bIsBig )
+ {
+ nNumerator = 0;
+ nDenominator = -1;
+ }
+ else
+ {
+ nNumerator = (long)nN,
+ nDenominator = (long)nD;
+ }
+
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* Fraction::operator*=()
+|*
+|* Beschreibung FRACT.SDW
+|* Ersterstellung DV 20.09.90
+|* Letzte Aenderung TH 19.08.92
+|*
+*************************************************************************/
+
+// Zunaechst werden die beiden Parameter auf ihre Gueltigkeit ueberprueft.
+// Ist einer der Parameter ungueltig, dann ist auch des Ergebnis
+// ungueltig. Zur Multiplikation werden jeweils die beiden Zaehler und
+// Nenner miteinander multipliziert. Um Ueberlaufe zu vermeiden, werden
+// vorher jeweils der GGT zwischen dem Zaehler des einen und dem Nenner
+// des anderen Bruches bestimmt und bei der Multiplikation Zaehler und
+// Nenner durch die entsprechenden Werte geteilt.
+// Innerhalb der Funktion wird mit dem Datentyp BigInt gerechnet, um
+// einen Moeglichen Ueberlauf erkennen zu koennen. Bei einem Ueberlauf
+// wird das Ergebnis auf den Wert ungueltig gesetzt.
+
+Fraction& Fraction::operator *= ( const Fraction& rVal )
+{
+ if ( !rVal.IsValid() )
+ {
+ nNumerator = 0;
+ nDenominator = -1;
+ }
+ if ( !IsValid() )
+ return *this;
+
+ long nGGT1 = GetGGT( nNumerator, rVal.nDenominator );
+ long nGGT2 = GetGGT( rVal.nNumerator, nDenominator );
+ BigInt nN( nNumerator / nGGT1 );
+ nN *= BigInt( rVal.nNumerator / nGGT2 );
+ BigInt nD( nDenominator / nGGT2 );
+ nD *= BigInt( rVal.nDenominator / nGGT1 );
+
+ if ( nN.bIsBig || nD.bIsBig )
+ {
+ nNumerator = 0;
+ nDenominator = -1;
+ }
+ else
+ {
+ nNumerator = (long)nN,
+ nDenominator = (long)nD;
+ }
+
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* Fraction::operator/=()
+|*
+|* Beschreibung FRACT.SDW
+|* Ersterstellung DV 20.09.90
+|* Letzte Aenderung DV 21.12.92
+|*
+*************************************************************************/
+
+// Zunaechst werden die beiden Parameter auf ihre Gueltigkeit ueberprueft.
+// Ist einer der Parameter ungueltig, dann ist auch des Ergebnis
+// ungueltig.
+// Um den Bruch a durch b zu teilen, wird a mit dem Kehrwert von b
+// multipliziert. Analog zu Multiplikation wird jezt jeweils der Zaehler
+// des einen Bruches mit dem Nenner des anderen multipliziert.
+// Um Ueberlaufe zu vermeiden, werden vorher jeweils der GGT zwischen den
+// beiden Zaehlern und den beiden Nennern bestimmt und bei der
+// Multiplikation Zaehler und Nenner durch die entsprechenden Werte
+// geteilt.
+// Innerhalb der Funktion wird mit dem Datentyp BigInt gerechnet, um
+// einen Moeglichen Ueberlauf erkennen zu koennen. Bei einem Ueberlauf
+// wird das Ergebnis auf den Wert ungueltig gesetzt.
+
+Fraction& Fraction::operator /= ( const Fraction& rVal )
+{
+ if ( !rVal.IsValid() )
+ {
+ nNumerator = 0;
+ nDenominator = -1;
+ }
+ if ( !IsValid() )
+ return *this;
+
+ long nGGT1 = GetGGT( nNumerator, rVal.nNumerator );
+ long nGGT2 = GetGGT( rVal.nDenominator, nDenominator );
+ BigInt nN( nNumerator / nGGT1 );
+ nN *= BigInt( rVal.nDenominator / nGGT2 );
+ BigInt nD( nDenominator / nGGT2 );
+ nD *= BigInt( rVal.nNumerator / nGGT1 );
+
+ if ( nN.bIsBig || nD.bIsBig )
+ {
+ nNumerator = 0;
+ nDenominator = -1;
+ }
+ else
+ {
+ nNumerator = (long)nN,
+ nDenominator = (long)nD;
+ if ( nDenominator < 0 )
+ {
+ nDenominator = -nDenominator;
+ nNumerator = -nNumerator;
+ }
+ }
+
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* Fraction::ReduceInaccurate()
+|*
+|* Beschreibung FRACT.SDW
+|* Ersterstellung JOE 17.09.95
+|* Letzte Aenderung kendy 2007-06-13
+|*
+*************************************************************************/
+
+
+// Similar to clz_table that can be googled
+const char nbits_table[32] =
+{
+ 32, 1, 23, 2, 29, 24, 14, 3,
+ 30, 27, 25, 18, 20, 15, 10, 4,
+ 31, 22, 28, 13, 26, 17, 19, 9,
+ 21, 12, 16, 8, 11, 7, 6, 5
+};
+
+static int impl_NumberOfBits( unsigned long nNum )
+{
+ // http://en.wikipedia.org/wiki/De_Bruijn_sequence
+ //
+ // background paper: Using de Bruijn Sequences to Index a 1 in a
+ // Computer Word (1998) Charles E. Leiserson,
+ // Harald Prokop, Keith H. Randall
+ // (e.g. http://citeseer.ist.psu.edu/leiserson98using.html)
+ const sal_uInt32 nDeBruijn = 0x7DCD629;
+
+ if ( nNum == 0 )
+ return 0;
+
+ // Get it to form like 0000001111111111b
+ nNum |= ( nNum >> 1 );
+ nNum |= ( nNum >> 2 );
+ nNum |= ( nNum >> 4 );
+ nNum |= ( nNum >> 8 );
+ nNum |= ( nNum >> 16 );
+
+ sal_uInt32 nNumber;
+ int nBonus = 0;
+
+#if SAL_TYPES_SIZEOFLONG == 4
+ nNumber = nNum;
+#elif SAL_TYPES_SIZEOFLONG == 8
+ nNum |= ( nNum >> 32 );
+
+ if ( nNum & 0x80000000 )
+ {
+ nNumber = sal_uInt32( nNum >> 32 );
+ nBonus = 32;
+
+ if ( nNumber == 0 )
+ return 32;
+ }
+ else
+ nNumber = sal_uInt32( nNum & 0xFFFFFFFF );
+#else
+#error "Unknown size of long!"
+#endif
+
+ // De facto shift left of nDeBruijn using multiplication (nNumber
+ // is all ones from topmost bit, thus nDeBruijn + (nDeBruijn *
+ // nNumber) => nDeBruijn * (nNumber+1) clears all those bits to
+ // zero, sets the next bit to one, and thus effectively shift-left
+ // nDeBruijn by lg2(nNumber+1). This generates a distinct 5bit
+ // sequence in the msb for each distinct position of the last
+ // leading 0 bit - that's the property of a de Bruijn number.
+ nNumber = nDeBruijn + ( nDeBruijn * nNumber );
+
+ // 5-bit window indexes the result
+ return ( nbits_table[nNumber >> 27] ) + nBonus;
+}
+
+/** Inaccurate cancellation for a fraction.
+
+ Clip both nominator and denominator to said number of bits. If
+ either of those already have equal or less number of bits used,
+ this method does nothing.
+
+ @param nSignificantBits denotes, how many significant binary
+ digits to maintain, in both nominator and denominator.
+
+ @example ReduceInaccurate(8) has an error <1% [1/2^(8-1)] - the
+ largest error occurs with the following pair of values:
+
+ binary 1000000011111111111111111111111b/1000000000000000000000000000000b
+ = 1082130431/1073741824
+ = approx. 1.007812499
+
+ A ReduceInaccurate(8) yields 1/1.
+*/
+void Fraction::ReduceInaccurate( unsigned nSignificantBits )
+{
+ if ( !nNumerator || !nDenominator )
+ return;
+
+ // Count with unsigned longs only
+ const bool bNeg = ( nNumerator < 0 );
+ unsigned long nMul = (unsigned long)( bNeg? -nNumerator: nNumerator );
+ unsigned long nDiv = (unsigned long)( nDenominator );
+
+ DBG_ASSERT(nSignificantBits<65, "More than 64 bit of significance is overkill!");
+
+ // How much bits can we lose?
+ const int nMulBitsToLose = Max( ( impl_NumberOfBits( nMul ) - int( nSignificantBits ) ), 0 );
+ const int nDivBitsToLose = Max( ( impl_NumberOfBits( nDiv ) - int( nSignificantBits ) ), 0 );
+
+ const int nToLose = Min( nMulBitsToLose, nDivBitsToLose );
+
+ // Remove the bits
+ nMul >>= nToLose;
+ nDiv >>= nToLose;
+
+ if ( !nMul || !nDiv )
+ {
+ // Return without reduction
+ DBG_ERROR( "Oops, we reduced too much..." );
+ return;
+ }
+
+ // Reduce
+ long n1 = GetGGT( nMul, nDiv );
+ if ( n1 != 1 )
+ {
+ nMul /= n1;
+ nDiv /= n1;
+ }
+
+ nNumerator = bNeg? -long( nMul ): long( nMul );
+ nDenominator = nDiv;
+}
+
+/*************************************************************************
+|*
+|* Fraction::operator ==()
+|*
+|* Beschreibung FRACT.SDW
+|* Ersterstellung DV 20.09.90
+|* Letzte Aenderung TH 19.08.92
+|*
+*************************************************************************/
+
+BOOL operator == ( const Fraction& rVal1, const Fraction& rVal2 )
+{
+ if ( !rVal1.IsValid() || !rVal2.IsValid() )
+ return FALSE;
+
+ return rVal1.nNumerator == rVal2.nNumerator
+ && rVal1.nDenominator == rVal2.nDenominator;
+}
+
+/*************************************************************************
+|*
+|* Fraction::operator <()
+|*
+|* Beschreibung FRACT.SDW
+|* Ersterstellung DV 20.09.90
+|* Letzte Aenderung DV 21.12.92
+|*
+*************************************************************************/
+
+// Beide Operanden werden zunaechst auf ihre Gueltigkeit ueberprueft und
+// anschliessend zur Sicherheit noch einmal gekuerzt. Um die Brueche
+// (a/b) und (c/d) zu vergleichen, werden sie zunaechst auf einen
+// gemeinsamen Nenner gebracht (b*d), um dann die beiden Zaehler (a*d)
+// und (c*b) zu vergleichen. Das Ergebnis dieses Vergleichs wird
+// zurueckgegeben.
+
+BOOL operator < ( const Fraction& rVal1, const Fraction& rVal2 )
+{
+ if ( !rVal1.IsValid() || !rVal2.IsValid() )
+ return FALSE;
+
+ BigInt nN( rVal1.nNumerator );
+ nN *= BigInt( rVal2.nDenominator );
+ BigInt nD( rVal1.nDenominator );
+ nD *= BigInt( rVal2.nNumerator );
+
+ return nN < nD;
+}
+
+/*************************************************************************
+|*
+|* Fraction::operator >()
+|*
+|* Beschreibung FRACT.SDW
+|* Ersterstellung DV 20.09.90
+|* Letzte Aenderung TH 19.08.92
+|*
+*************************************************************************/
+
+// Beide Operanden werden zunaechst auf ihre Gueltigkeit ueberprueft und
+// anschliessend zur Sicherheit noch einmal gekuerzt. Um die Brueche
+// (a/b) und (c/d) zu vergleichen, werden sie zunaechst auf einen
+// gemeinsamen Nenner gebracht (b*d), um dann die beiden Zaehler (a*d)
+// und (c*b) zu vergleichen. Das Ergebnis dieses Vergleichs wird
+// zurueckgegeben.
+
+BOOL operator > ( const Fraction& rVal1, const Fraction& rVal2 )
+{
+ if ( !rVal1.IsValid() || !rVal2.IsValid() )
+ return FALSE;
+
+ BigInt nN( rVal1.nNumerator );
+ nN *= BigInt( rVal2.nDenominator );
+ BigInt nD( rVal1.nDenominator);
+ nD *= BigInt( rVal2.nNumerator );
+
+ return nN > nD;
+}
+
+/*************************************************************************
+|*
+|* SvStream& operator>>( SvStream& rIStream, Fraction& rFract )
+|*
+|* Beschreibung FRACT.SDW
+|* Ersterstellung MM 08.01.96
+|* Letzte Aenderung MM 08.01.96
+|*
+*************************************************************************/
+SvStream& operator >> ( SvStream& rIStream, Fraction& rFract )
+{
+ rIStream >> rFract.nNumerator;
+ rIStream >> rFract.nDenominator;
+ return rIStream;
+}
+
+/*************************************************************************
+|*
+|* SvStream& operator<<( SvStream& rIStream, Fraction& rFract )
+|*
+|* Beschreibung FRACT.SDW
+|* Ersterstellung MM 08.01.96
+|* Letzte Aenderung MM 08.01.96
+|*
+*************************************************************************/
+SvStream& operator << ( SvStream& rOStream, const Fraction& rFract )
+{
+ rOStream << rFract.nNumerator;
+ rOStream << rFract.nDenominator;
+ return rOStream;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/generic/gen.cxx b/tools/source/generic/gen.cxx
new file mode 100644
index 000000000000..2d6c5705aff9
--- /dev/null
+++ b/tools/source/generic/gen.cxx
@@ -0,0 +1,664 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <tools/debug.hxx>
+#include <tools/gen.hxx>
+#include <tools/stream.hxx>
+
+// =======================================================================
+
+SvStream& operator>>( SvStream& rIStream, Pair& rPair )
+{
+ DBG_ASSERTWARNING( rIStream.GetVersion(), "Pair::>> - Solar-Version not set on rIStream" );
+
+ if ( rIStream.GetCompressMode() == COMPRESSMODE_FULL )
+ {
+ unsigned char cId;
+ unsigned char cAry[8];
+ int i;
+ int i1;
+ int i2;
+ UINT32 nNum;
+
+ rIStream >> cId;
+ i1 = (cId & 0x70) >> 4;
+ i2 = cId & 0x07;
+ rIStream.Read( cAry, i1+i2 );
+
+ nNum = 0;
+ i = i1;
+ while ( i )
+ {
+ i--;
+ nNum <<= 8;
+ nNum |= cAry[i];
+ }
+ if ( cId & 0x80 )
+ nNum ^= 0xFFFFFFFF;
+ rPair.nA = (INT32)nNum;
+
+ nNum = 0;
+ i = i1+i2;
+ while ( i > i1 )
+ {
+ i--;
+ nNum <<= 8;
+ nNum |= cAry[i];
+ }
+ if ( cId & 0x08 )
+ nNum ^= 0xFFFFFFFF;
+ rPair.nB = (INT32)nNum;
+ }
+ else
+ {
+ rIStream >> rPair.nA >> rPair.nB;
+ }
+
+ return rIStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const Pair& rPair )
+{
+ DBG_ASSERTWARNING( rOStream.GetVersion(), "Pair::<< - Solar-Version not set on rOStream" );
+
+ if ( rOStream.GetCompressMode() == COMPRESSMODE_FULL )
+ {
+ unsigned char cAry[9];
+ int i = 1;
+ UINT32 nNum;
+
+ cAry[0] = 0;
+
+ nNum = (UINT32)(INT32)rPair.nA;
+ if ( rPair.nA < 0 )
+ {
+ cAry[0] |= 0x80;
+ nNum ^= 0xFFFFFFFF;
+ }
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+ cAry[0] |= 0x40;
+ }
+ else
+ cAry[0] |= 0x30;
+ }
+ else
+ cAry[0] |= 0x20;
+ }
+ else
+ cAry[0] |= 0x10;
+ }
+
+ nNum = (UINT32)(INT32)rPair.nB;
+ if ( rPair.nB < 0 )
+ {
+ cAry[0] |= 0x08;
+ nNum ^= 0xFFFFFFFF;
+ }
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+ cAry[0] |= 0x04;
+ }
+ else
+ cAry[0] |= 0x03;
+ }
+ else
+ cAry[0] |= 0x02;
+ }
+ else
+ cAry[0] |= 0x01;
+ }
+
+ rOStream.Write( cAry, i );
+ }
+ else
+ {
+ rOStream << rPair.nA << rPair.nB;
+ }
+
+ return rOStream;
+}
+
+/*************************************************************************
+|*
+|* Rectangle::SetSize()
+|*
+|* Beschreibung GEN.SDW
+|* Ersterstellung DV 29.10.91
+|* Letzte Aenderung MM 21.04.94
+|*
+*************************************************************************/
+
+void Rectangle::SetSize( const Size& rSize )
+{
+ if ( rSize.Width() < 0 )
+ nRight = nLeft + rSize.Width() +1;
+ else if ( rSize.Width() > 0 )
+ nRight = nLeft + rSize.Width() -1;
+ else
+ nRight = RECT_EMPTY;
+
+ if ( rSize.Height() < 0 )
+ nBottom = nTop + rSize.Height() +1;
+ else if ( rSize.Height() > 0 )
+ nBottom = nTop + rSize.Height() -1;
+ else
+ nBottom = RECT_EMPTY;
+}
+
+/*************************************************************************
+|*
+|* Rectangle::Union()
+|*
+|* Beschreibung GEN.SDW
+|* Ersterstellung TH 20.10.92
+|* Letzte Aenderung MM 21.04.94
+|*
+*************************************************************************/
+
+Rectangle& Rectangle::Union( const Rectangle& rRect )
+{
+ if ( rRect.IsEmpty() )
+ return *this;
+
+ if ( IsEmpty() )
+ *this = rRect;
+ else
+ {
+ nLeft = Min( Min( nLeft, rRect.nLeft ), Min( nRight, rRect.nRight ) );
+ nRight = Max( Max( nLeft, rRect.nLeft ), Max( nRight, rRect.nRight ) );
+ nTop = Min( Min( nTop, rRect.nTop ), Min( nBottom, rRect.nBottom ) );
+ nBottom = Max( Max( nTop, rRect.nTop ), Max( nBottom, rRect.nBottom ) );
+ }
+
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* Rectangle::Intersection()
+|*
+|* Beschreibung GEN.SDW
+|* Ersterstellung TH 20.10.92
+|* Letzte Aenderung MM 21.04.94
+|*
+*************************************************************************/
+
+Rectangle& Rectangle::Intersection( const Rectangle& rRect )
+{
+ if ( IsEmpty() )
+ return *this;
+ if ( rRect.IsEmpty() )
+ {
+ *this = Rectangle();
+ return *this;
+ }
+
+ // nicht mit umgedrehten Rechtecken arbeiten
+ Rectangle aTmpRect( rRect );
+ Justify();
+ aTmpRect.Justify();
+
+ // Schnitt bilden
+ nLeft = Max( nLeft, aTmpRect.nLeft );
+ nRight = Min( nRight, aTmpRect.nRight );
+ nTop = Max( nTop, aTmpRect.nTop );
+ nBottom= Min( nBottom, aTmpRect.nBottom );
+
+ // Feststellen ob Schnitt leer
+ if ( nRight < nLeft || nBottom < nTop )
+ *this = Rectangle();
+
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* Rectangle::Justify()
+|*
+|* Beschreibung GEN.SDW
+|* Ersterstellung DV 07.03.91
+|* Letzte Aenderung DV 07.03.91
+|*
+*************************************************************************/
+
+void Rectangle::Justify()
+{
+ long nHelp;
+
+ // Abfrage, ob Right kleiner Left
+ if ( (nRight < nLeft) && (nRight != RECT_EMPTY) )
+ {
+ nHelp = nLeft;
+ nLeft = nRight;
+ nRight = nHelp;
+ }
+
+ // Abfrage, ob Bottom kleiner Top
+ if ( (nBottom < nTop) && (nBottom != RECT_EMPTY) )
+ {
+ nHelp = nBottom;
+ nBottom = nTop;
+ nTop = nHelp;
+ }
+}
+
+/*************************************************************************
+|*
+|* Rectangle::IsInside()
+|*
+|* Beschreibung GEN.SDW
+|* Ersterstellung TH 19.03.90
+|* Letzte Aenderung MM 21.04.94
+|*
+*************************************************************************/
+
+BOOL Rectangle::IsInside( const Point& rPoint ) const
+{
+ if ( IsEmpty() )
+ return FALSE;
+
+ BOOL bRet = TRUE;
+ if ( nLeft <= nRight )
+ {
+ if ( (rPoint.X() < nLeft) || (rPoint.X() > nRight) )
+ bRet = FALSE;
+ }
+ else
+ {
+ if ( (rPoint.X() > nLeft) || (rPoint.X() < nRight) )
+ bRet = FALSE;
+ }
+ if ( nTop <= nBottom )
+ {
+ if ( (rPoint.Y() < nTop) || (rPoint.Y() > nBottom) )
+ bRet = FALSE;
+ }
+ else
+ {
+ if ( (rPoint.Y() > nTop) || (rPoint.Y() < nBottom) )
+ bRet = FALSE;
+ }
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|* Rectangle::IsInside()
+|*
+|* Beschreibung GEN.SDW
+|* Ersterstellung TH 19.03.90
+|* Letzte Aenderung MM 21.04.94
+|*
+*************************************************************************/
+
+BOOL Rectangle::IsInside( const Rectangle& rRect ) const
+{
+ if ( IsInside( rRect.TopLeft() ) && IsInside( rRect.BottomRight() ) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* Rectangle::IsOver()
+|*
+|* Beschreibung GEN.SDW
+|* Ersterstellung TH 19.03.90
+|* Letzte Aenderung MM 21.04.94
+|*
+*************************************************************************/
+
+BOOL Rectangle::IsOver( const Rectangle& rRect ) const
+{
+ // Wenn sie sich nicht schneiden, ueberlappen sie auch nicht
+ return !GetIntersection( rRect ).IsEmpty();
+}
+
+// =======================================================================
+
+SvStream& operator>>( SvStream& rIStream, Rectangle& rRect )
+{
+ DBG_ASSERTWARNING( rIStream.GetVersion(), "Rectangle::>> - Solar-Version not set on rIStream" );
+
+ if ( rIStream.GetCompressMode() == COMPRESSMODE_FULL )
+ {
+ unsigned char cIdAry[2];
+ unsigned char cAry[16];
+ int i;
+ int iLast;
+ int i1;
+ int i2;
+ int i3;
+ int i4;
+ UINT32 nNum;
+
+ rIStream.Read( cIdAry, 2 );
+ i1 = (cIdAry[0] & 0x70) >> 4;
+ i2 = cIdAry[0] & 0x07;
+ i3 = (cIdAry[1] & 0x70) >> 4;
+ i4 = cIdAry[1] & 0x07;
+ rIStream.Read( cAry, i1+i2+i3+i4 );
+
+ nNum = 0;
+ i = i1;
+ iLast = i;
+ while ( i )
+ {
+ i--;
+ nNum <<= 8;
+ nNum |= cAry[i];
+ }
+ iLast = i1;
+ if ( cIdAry[0] & 0x80 )
+ nNum ^= 0xFFFFFFFF;
+ rRect.nLeft = (INT32)nNum;
+
+ nNum = 0;
+ i = iLast+i2;
+ while ( i > iLast )
+ {
+ i--;
+ nNum <<= 8;
+ nNum |= cAry[i];
+ }
+ iLast += i2;
+ if ( cIdAry[0] & 0x08 )
+ nNum ^= 0xFFFFFFFF;
+ rRect.nTop = (INT32)nNum;
+
+ nNum = 0;
+ i = iLast+i3;
+ while ( i > iLast )
+ {
+ i--;
+ nNum <<= 8;
+ nNum |= cAry[i];
+ }
+ iLast += i3;
+ if ( cIdAry[1] & 0x80 )
+ nNum ^= 0xFFFFFFFF;
+ rRect.nRight = (INT32)nNum;
+
+ nNum = 0;
+ i = iLast+i4;
+ while ( i > iLast )
+ {
+ i--;
+ nNum <<= 8;
+ nNum |= cAry[i];
+ }
+ if ( cIdAry[1] & 0x08 )
+ nNum ^= 0xFFFFFFFF;
+ rRect.nBottom = (INT32)nNum;
+ }
+ else
+ {
+ rIStream >> rRect.nLeft >> rRect.nTop >> rRect.nRight >> rRect.nBottom;
+ }
+
+ return rIStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const Rectangle& rRect )
+{
+ DBG_ASSERTWARNING( rOStream.GetVersion(), "Rectangle::<< - Solar-Version not set on rOStream" );
+
+ if ( rOStream.GetCompressMode() == COMPRESSMODE_FULL )
+ {
+ unsigned char cAry[18];
+ int i = 2;
+ UINT32 nNum;
+
+ cAry[0] = 0;
+ cAry[1] = 0;
+
+ nNum = (UINT32)(INT32)rRect.nLeft;
+ if ( rRect.nLeft < 0 )
+ {
+ cAry[0] |= 0x80;
+ nNum ^= 0xFFFFFFFF;
+ }
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+ cAry[0] |= 0x40;
+ }
+ else
+ cAry[0] |= 0x30;
+ }
+ else
+ cAry[0] |= 0x20;
+ }
+ else
+ cAry[0] |= 0x10;
+ }
+
+ nNum = (UINT32)(INT32)rRect.nTop;
+ if ( rRect.nTop < 0 )
+ {
+ cAry[0] |= 0x08;
+ nNum ^= 0xFFFFFFFF;
+ }
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+ cAry[0] |= 0x04;
+ }
+ else
+ cAry[0] |= 0x03;
+ }
+ else
+ cAry[0] |= 0x02;
+ }
+ else
+ cAry[0] |= 0x01;
+ }
+
+ nNum = (UINT32)(INT32)rRect.nRight;
+ if ( rRect.nRight < 0 )
+ {
+ cAry[1] |= 0x80;
+ nNum ^= 0xFFFFFFFF;
+ }
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+ cAry[1] |= 0x40;
+ }
+ else
+ cAry[1] |= 0x30;
+ }
+ else
+ cAry[1] |= 0x20;
+ }
+ else
+ cAry[1] |= 0x10;
+ }
+
+ nNum = (UINT32)(INT32)rRect.nBottom;
+ if ( rRect.nBottom < 0 )
+ {
+ cAry[1] |= 0x08;
+ nNum ^= 0xFFFFFFFF;
+ }
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+
+ if ( nNum )
+ {
+ cAry[i] = (unsigned char)(nNum & 0xFF);
+ nNum >>= 8;
+ i++;
+ cAry[1] |= 0x04;
+ }
+ else
+ cAry[1] |= 0x03;
+ }
+ else
+ cAry[1] |= 0x02;
+ }
+ else
+ cAry[1] |= 0x01;
+ }
+
+ rOStream.Write( cAry, i );
+ }
+ else
+ {
+ rOStream << rRect.nLeft << rRect.nTop << rRect.nRight << rRect.nBottom;
+ }
+
+ return rOStream;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/generic/line.cxx b/tools/source/generic/line.cxx
new file mode 100644
index 000000000000..022c0c36406a
--- /dev/null
+++ b/tools/source/generic/line.cxx
@@ -0,0 +1,366 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#define _LINE_CXX
+#include <tools/link.hxx>
+#include <tools/line.hxx>
+#include <tools/debug.hxx>
+
+#include <cstdlib>
+#include <math.h>
+
+// --------
+// - Line -
+// --------
+
+double Line::GetLength() const
+{
+ return hypot( maStart.X() - maEnd.X(), maStart.Y() - maEnd.Y() );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Line::Intersection( const Line& rLine, Point& rIntersection ) const
+{
+ double fX, fY;
+ BOOL bRet;
+
+ if( Intersection( rLine, fX, fY ) )
+ {
+ rIntersection.X() = FRound( fX );
+ rIntersection.Y() = FRound( fY );
+ bRet = TRUE;
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Line::Intersection( const Line& rLine, double& rIntersectionX, double& rIntersectionY ) const
+{
+ const double fAx = maEnd.X() - maStart.X();
+ const double fAy = maEnd.Y() - maStart.Y();
+ const double fBx = rLine.maStart.X() - rLine.maEnd.X();
+ const double fBy = rLine.maStart.Y() - rLine.maEnd.Y();
+ const double fDen = fAy * fBx - fAx * fBy;
+ BOOL bOk = FALSE;
+
+ if( fDen != 0. )
+ {
+ const double fCx = maStart.X() - rLine.maStart.X();
+ const double fCy = maStart.Y() - rLine.maStart.Y();
+ const double fA = fBy * fCx - fBx * fCy;
+ const BOOL bGreater = ( fDen > 0. );
+
+ bOk = TRUE;
+
+ if ( bGreater )
+ {
+ if ( ( fA < 0. ) || ( fA > fDen ) )
+ bOk = FALSE;
+ }
+ else if ( ( fA > 0. ) || ( fA < fDen ) )
+ bOk = FALSE;
+
+ if ( bOk )
+ {
+ const double fB = fAx * fCy - fAy * fCx;
+
+ if ( bGreater )
+ {
+ if ( ( fB < 0. ) || ( fB > fDen ) )
+ bOk = FALSE;
+ }
+ else if ( ( fB > 0. ) || ( fB < fDen ) )
+ bOk = FALSE;
+
+ if( bOk )
+ {
+ const double fAlpha = fA / fDen;
+
+ rIntersectionX = ( maStart.X() + fAlpha * fAx );
+ rIntersectionY = ( maStart.Y() + fAlpha * fAy );
+ }
+ }
+ }
+
+ return bOk;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Line::Intersection( const Rectangle& rRect, Line& rIntersection ) const
+{
+ const BOOL bStartInside = rRect.IsInside( maStart );
+ const BOOL bEndInside = rRect.IsInside( maEnd );
+ BOOL bRet = TRUE;
+
+ if( bStartInside && bEndInside )
+ {
+ // line completely inside rect
+ rIntersection.maStart = maStart;
+ rIntersection.maEnd = maEnd;
+ }
+ else
+ {
+ // calculate intersections
+ const Point aTL( rRect.TopLeft() ), aTR( rRect.TopRight() );
+ const Point aBR( rRect.BottomRight() ), aBL( rRect.BottomLeft() );
+ Point aIntersect1, aIntersect2;
+ Point* pCurIntersection = &aIntersect1;
+
+ if( Intersection( Line( aTL, aTR ), *pCurIntersection ) )
+ pCurIntersection = &aIntersect2;
+
+ if( Intersection( Line( aTR, aBR ), *pCurIntersection ) )
+ pCurIntersection = ( pCurIntersection == &aIntersect1 ) ? &aIntersect2 : NULL;
+
+ if( pCurIntersection && Intersection( Line( aBR, aBL ), *pCurIntersection ) )
+ pCurIntersection = ( pCurIntersection == &aIntersect1 ) ? &aIntersect2 : NULL;
+
+ if( pCurIntersection && Intersection( Line( aBL, aTL ), *pCurIntersection ) )
+ pCurIntersection = ( pCurIntersection == &aIntersect1 ) ? &aIntersect2 : NULL;
+
+ if( !pCurIntersection )
+ {
+ // two intersections
+ rIntersection.maStart = aIntersect1;
+ rIntersection.maEnd = aIntersect2;
+ }
+ else if( pCurIntersection == &aIntersect2 )
+ {
+ // one intersection
+ rIntersection.maStart = aIntersect1;
+
+ if( ( maStart != aIntersect1 ) && bStartInside )
+ rIntersection.maEnd = maStart;
+ else if( ( maEnd != aIntersect1 ) && bEndInside )
+ rIntersection.maEnd = maEnd;
+ else
+ rIntersection.maEnd = rIntersection.maStart;
+ }
+ else
+ bRet = FALSE;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+Point Line::NearestPoint( const Point& rPoint ) const
+{
+ Point aRetPt;
+
+ if ( maStart != maEnd )
+ {
+ const double fDistX = maEnd.X() - maStart.X();
+ const double fDistY = maStart.Y() - maEnd.Y();
+ const double fTau = ( ( maStart.Y() - rPoint.Y() ) * fDistY -
+ ( maStart.X() - rPoint.X() ) * fDistX ) /
+ ( fDistX * fDistX + fDistY * fDistY );
+
+ if( fTau < 0.0 )
+ aRetPt = maStart;
+ else if( fTau <= 1.0 )
+ {
+ aRetPt.X() = FRound( maStart.X() + fTau * fDistX );
+ aRetPt.Y() = FRound( maStart.Y() - fTau * fDistY );
+ }
+ else
+ aRetPt = maEnd;
+ }
+ else
+ aRetPt = maStart;
+
+ return aRetPt;
+}
+
+// ------------------------------------------------------------------------
+
+double Line::GetDistance( const double& rPtX, const double& rPtY ) const
+{
+ double fDist;
+
+ if( maStart != maEnd )
+ {
+ const double fDistX = maEnd.X() - maStart.X();
+ const double fDistY = maEnd.Y() - maStart.Y();
+ const double fACX = maStart.X() - rPtX;
+ const double fACY = maStart.Y() - rPtY;
+ const double fL2 = fDistX * fDistX + fDistY * fDistY;
+ const double fR = ( fACY * -fDistY - fACX * fDistX ) / fL2;
+ const double fS = ( fACY * fDistX - fACX * fDistY ) / fL2;
+
+ if( fR < 0.0 )
+ {
+ fDist = hypot( maStart.X() - rPtX, maStart.Y() - rPtY );
+
+ if( fS < 0.0 )
+ fDist *= -1.0;
+ }
+ else if( fR <= 1.0 )
+ fDist = fS * sqrt( fL2 );
+ else
+ {
+ fDist = hypot( maEnd.X() - rPtX, maEnd.Y() - rPtY );
+
+ if( fS < 0.0 )
+ fDist *= -1.0;
+ }
+ }
+ else
+ fDist = hypot( maStart.X() - rPtX, maStart.Y() - rPtY );
+
+ return fDist;
+}
+
+// ------------------------------------------------------------------------
+
+void Line::Enum( const Link& rEnumLink )
+{
+ DBG_ASSERT( rEnumLink.IsSet(), "This call doesn't make any sense with !rEnumLink.IsSet()" );
+
+ Point aEnum;
+ long nX;
+ long nY;
+
+ if( maStart.X() == maEnd.X() )
+ {
+ const long nEndY = maEnd.Y();
+
+ nX = maStart.X();
+ nY = maStart.Y();
+
+ if( nEndY > nY )
+ {
+ while( nY <= nEndY )
+ {
+ aEnum.X() = nX;
+ aEnum.Y() = nY++;
+ rEnumLink.Call( &aEnum );
+ }
+ }
+ else
+ {
+ while( nY >= nEndY )
+ {
+ aEnum.X() = nX;
+ aEnum.Y() = nY--;
+ rEnumLink.Call( &aEnum );
+ }
+ }
+ }
+ else if( maStart.Y() == maEnd.Y() )
+ {
+ const long nEndX = maEnd.X();
+
+ nX = maStart.X();
+ nY = maStart.Y();
+
+ if( nEndX > nX )
+ {
+ while( nX <= nEndX )
+ {
+ aEnum.X() = nX++;
+ aEnum.Y() = nY;
+ rEnumLink.Call( &aEnum );
+ }
+ }
+ else
+ {
+ while( nX >= nEndX )
+ {
+ aEnum.X() = nX--;
+ aEnum.Y() = nY;
+ rEnumLink.Call( &aEnum );
+ }
+ }
+ }
+ else
+ {
+ const long nDX = labs( maEnd.X() - maStart.X() );
+ const long nDY = labs( maEnd.Y() - maStart.Y() );
+ const long nStartX = maStart.X();
+ const long nStartY = maStart.Y();
+ const long nEndX = maEnd.X();
+ const long nEndY = maEnd.Y();
+ const long nXInc = ( nStartX < nEndX ) ? 1L : -1L;
+ const long nYInc = ( nStartY < nEndY ) ? 1L : -1L;
+
+ if( nDX >= nDY )
+ {
+ const long nDYX = ( nDY - nDX ) << 1;
+ const long nDY2 = nDY << 1;
+ long nD = nDY2 - nDX;
+
+ for( nX = nStartX, nY = nStartY; nX != nEndX; nX += nXInc )
+ {
+ aEnum.X() = nX;
+ aEnum.Y() = nY;
+ rEnumLink.Call( &aEnum );
+
+ if( nD < 0L )
+ nD += nDY2;
+ else
+ nD += nDYX, nY += nYInc;
+ }
+ }
+ else
+ {
+ const long nDYX = ( nDX - nDY ) << 1;
+ const long nDY2 = nDX << 1;
+ long nD = nDY2 - nDY;
+
+ for( nX = nStartX, nY = nStartY; nY != nEndY; nY += nYInc )
+ {
+ aEnum.X() = nX;
+ aEnum.Y() = nY;
+ rEnumLink.Call( &aEnum );
+
+ if( nD < 0L )
+ nD += nDY2;
+ else
+ nD += nDYX, nX += nXInc;
+ }
+ }
+
+ // last point
+ aEnum.X() = nEndX;
+ aEnum.Y() = nEndY;
+ rEnumLink.Call( &aEnum );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/generic/link.cxx b/tools/source/generic/link.cxx
new file mode 100644
index 000000000000..bf6bfd15da3a
--- /dev/null
+++ b/tools/source/generic/link.cxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <tools/link.hxx>
+
+/*************************************************************************
+|*
+|* Link::operator==()
+|*
+|* Beschreibung LINK.SDW
+|* Ersterstellung AM 14.02.91
+|* Letzte Aenderung TH 07.11.95
+|*
+*************************************************************************/
+
+BOOL Link::operator==( const Link& rLink ) const
+{
+ if ( pFunc == rLink.pFunc )
+ {
+ if ( pFunc )
+ {
+ if ( pInst == rLink.pInst )
+ return TRUE;
+ else
+ return FALSE;
+ }
+ else
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/generic/makefile.mk b/tools/source/generic/makefile.mk
new file mode 100644
index 000000000000..07bab82f32b0
--- /dev/null
+++ b/tools/source/generic/makefile.mk
@@ -0,0 +1,71 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=tools
+TARGET=gen
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+EXCEPTIONSFILES = $(SLO)$/poly.obj $(OBJ)$/poly.obj $(SLO)$/svlibrary.obj
+
+SLOFILES= $(SLO)$/toolsin.obj \
+ $(SLO)$/svlibrary.obj \
+ $(SLO)$/b3dtrans.obj \
+ $(SLO)$/link.obj \
+ $(SLO)$/bigint.obj \
+ $(SLO)$/fract.obj \
+ $(SLO)$/color.obj \
+ $(SLO)$/gen.obj \
+ $(SLO)$/config.obj \
+ $(SLO)$/poly.obj \
+ $(SLO)$/poly2.obj \
+ $(SLO)$/svborder.obj \
+ $(SLO)$/line.obj
+
+OBJFILES= $(OBJ)$/toolsin.obj \
+ $(OBJ)$/b3dtrans.obj \
+ $(OBJ)$/link.obj \
+ $(OBJ)$/bigint.obj \
+ $(OBJ)$/fract.obj \
+ $(OBJ)$/color.obj \
+ $(OBJ)$/gen.obj \
+ $(OBJ)$/config.obj \
+ $(OBJ)$/poly.obj \
+ $(OBJ)$/poly2.obj \
+ $(OBJ)$/svborder.obj \
+ $(OBJ)$/line.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/tools/source/generic/poly.cxx b/tools/source/generic/poly.cxx
new file mode 100644
index 000000000000..ce81ab6157e0
--- /dev/null
+++ b/tools/source/generic/poly.cxx
@@ -0,0 +1,2379 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#define _SV_POLY_CXX
+#include <osl/endian.h>
+#include <tools/bigint.hxx>
+#include <tools/debug.hxx>
+#include <tools/stream.hxx>
+#include <tools/vcompat.hxx>
+#include <poly.h>
+#include <tools/line.hxx>
+#include <tools/vector2d.hxx>
+#include <tools/poly.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/curve/b2dcubicbezier.hxx>
+
+#include <vector>
+#include <iterator>
+#include <algorithm>
+#include <cstring>
+#include <limits.h>
+#include <cmath>
+
+
+// =======================================================================
+
+DBG_NAME( Polygon )
+
+// -----------------------------------------------------------------------
+
+#define EDGE_LEFT 1
+#define EDGE_TOP 2
+#define EDGE_RIGHT 4
+#define EDGE_BOTTOM 8
+#define EDGE_HORZ (EDGE_RIGHT | EDGE_LEFT)
+#define EDGE_VERT (EDGE_TOP | EDGE_BOTTOM)
+#define SMALL_DVALUE 0.0000001
+#define FSQRT2 1.4142135623730950488016887242097
+
+// -----------------------------------------------------------------------
+
+static ImplPolygonData aStaticImplPolygon =
+{
+ NULL, NULL, 0, 0
+};
+
+// =======================================================================
+
+ImplPolygon::ImplPolygon( USHORT nInitSize, BOOL bFlags )
+{
+ if ( nInitSize )
+ {
+ mpPointAry = (Point*)new char[(ULONG)nInitSize*sizeof(Point)];
+ memset( mpPointAry, 0, (ULONG)nInitSize*sizeof(Point) );
+ }
+ else
+ mpPointAry = NULL;
+
+ if( bFlags )
+ {
+ mpFlagAry = new BYTE[ nInitSize ];
+ memset( mpPointAry, 0, nInitSize );
+ }
+ else
+ mpFlagAry = NULL;
+
+ mnRefCount = 1;
+ mnPoints = nInitSize;
+}
+
+// -----------------------------------------------------------------------
+
+ImplPolygon::ImplPolygon( const ImplPolygon& rImpPoly )
+{
+ if ( rImpPoly.mnPoints )
+ {
+ mpPointAry = (Point*)new char[(ULONG)rImpPoly.mnPoints*sizeof(Point)];
+ memcpy( mpPointAry, rImpPoly.mpPointAry, (ULONG)rImpPoly.mnPoints*sizeof(Point) );
+
+ if( rImpPoly.mpFlagAry )
+ {
+ mpFlagAry = new BYTE[ rImpPoly.mnPoints ];
+ memcpy( mpFlagAry, rImpPoly.mpFlagAry, rImpPoly.mnPoints );
+ }
+ else
+ mpFlagAry = NULL;
+ }
+ else
+ {
+ mpPointAry = NULL;
+ mpFlagAry = NULL;
+ }
+
+ mnRefCount = 1;
+ mnPoints = rImpPoly.mnPoints;
+}
+
+// -----------------------------------------------------------------------
+
+ImplPolygon::ImplPolygon( USHORT nInitSize, const Point* pInitAry, const BYTE* pInitFlags )
+{
+ if ( nInitSize )
+ {
+ mpPointAry = (Point*)new char[(ULONG)nInitSize*sizeof(Point)];
+ memcpy( mpPointAry, pInitAry, (ULONG)nInitSize*sizeof( Point ) );
+
+ if( pInitFlags )
+ {
+ mpFlagAry = new BYTE[ nInitSize ];
+ memcpy( mpFlagAry, pInitFlags, nInitSize );
+ }
+ else
+ mpFlagAry = NULL;
+ }
+ else
+ {
+ mpPointAry = NULL;
+ mpFlagAry = NULL;
+ }
+
+ mnRefCount = 1;
+ mnPoints = nInitSize;
+}
+
+// -----------------------------------------------------------------------
+
+ImplPolygon::~ImplPolygon()
+{
+ if ( mpPointAry )
+ {
+ delete[] (char*) mpPointAry;
+ }
+
+ if( mpFlagAry )
+ delete[] mpFlagAry;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplPolygon::ImplSetSize( USHORT nNewSize, BOOL bResize )
+{
+ if( mnPoints == nNewSize )
+ return;
+
+ Point* pNewAry;
+
+ if ( nNewSize )
+ {
+ pNewAry = (Point*)new char[(ULONG)nNewSize*sizeof(Point)];
+
+ if ( bResize )
+ {
+ // Alte Punkte kopieren
+ if ( mnPoints < nNewSize )
+ {
+ // Neue Punkte mit 0 initialisieren
+ memset( pNewAry+mnPoints, 0, (ULONG)(nNewSize-mnPoints)*sizeof(Point) );
+ if ( mpPointAry )
+ memcpy( pNewAry, mpPointAry, mnPoints*sizeof(Point) );
+ }
+ else
+ {
+ if ( mpPointAry )
+ memcpy( pNewAry, mpPointAry, (ULONG)nNewSize*sizeof(Point) );
+ }
+ }
+ }
+ else
+ pNewAry = NULL;
+
+ if ( mpPointAry )
+ delete[] (char*) mpPointAry;
+
+ // ggf. FlagArray beruecksichtigen
+ if( mpFlagAry )
+ {
+ BYTE* pNewFlagAry;
+
+ if( nNewSize )
+ {
+ pNewFlagAry = new BYTE[ nNewSize ];
+
+ if( bResize )
+ {
+ // Alte Flags kopieren
+ if ( mnPoints < nNewSize )
+ {
+ // Neue Punkte mit 0 initialisieren
+ memset( pNewFlagAry+mnPoints, 0, nNewSize-mnPoints );
+ memcpy( pNewFlagAry, mpFlagAry, mnPoints );
+ }
+ else
+ memcpy( pNewFlagAry, mpFlagAry, nNewSize );
+ }
+ }
+ else
+ pNewFlagAry = NULL;
+
+ delete[] mpFlagAry;
+ mpFlagAry = pNewFlagAry;
+ }
+
+ mpPointAry = pNewAry;
+ mnPoints = nNewSize;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplPolygon::ImplSplit( USHORT nPos, USHORT nSpace, ImplPolygon* pInitPoly )
+{
+ const ULONG nSpaceSize = nSpace * sizeof( Point );
+
+ //Can't fit this in :-(, throw ?
+ if (mnPoints + nSpace > USHRT_MAX)
+ return;
+
+ const USHORT nNewSize = mnPoints + nSpace;
+
+ if( nPos >= mnPoints )
+ {
+ // Hinten anhaengen
+ nPos = mnPoints;
+ ImplSetSize( nNewSize, TRUE );
+
+ if( pInitPoly )
+ {
+ memcpy( mpPointAry + nPos, pInitPoly->mpPointAry, nSpaceSize );
+
+ if( pInitPoly->mpFlagAry )
+ memcpy( mpFlagAry + nPos, pInitPoly->mpFlagAry, nSpace );
+ }
+ }
+ else
+ {
+ // PointArray ist in diesem Zweig immer vorhanden
+ const USHORT nSecPos = nPos + nSpace;
+ const USHORT nRest = mnPoints - nPos;
+
+ Point* pNewAry = (Point*) new char[ (ULONG) nNewSize * sizeof( Point ) ];
+
+ memcpy( pNewAry, mpPointAry, nPos * sizeof( Point ) );
+
+ if( pInitPoly )
+ memcpy( pNewAry + nPos, pInitPoly->mpPointAry, nSpaceSize );
+ else
+ memset( pNewAry + nPos, 0, nSpaceSize );
+
+ memcpy( pNewAry + nSecPos, mpPointAry + nPos, nRest * sizeof( Point ) );
+ delete[] (char*) mpPointAry;
+
+ // ggf. FlagArray beruecksichtigen
+ if( mpFlagAry )
+ {
+ BYTE* pNewFlagAry = new BYTE[ nNewSize ];
+
+ memcpy( pNewFlagAry, mpFlagAry, nPos );
+
+ if( pInitPoly && pInitPoly->mpFlagAry )
+ memcpy( pNewFlagAry + nPos, pInitPoly->mpFlagAry, nSpace );
+ else
+ memset( pNewFlagAry + nPos, 0, nSpace );
+
+ memcpy( pNewFlagAry + nSecPos, mpFlagAry + nPos, nRest );
+ delete[] mpFlagAry;
+ mpFlagAry = pNewFlagAry;
+ }
+
+ mpPointAry = pNewAry;
+ mnPoints = nNewSize;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplPolygon::ImplRemove( USHORT nPos, USHORT nCount )
+{
+ const USHORT nRemoveCount = Min( (USHORT) ( mnPoints - nPos ), (USHORT) nCount );
+
+ if( nRemoveCount )
+ {
+ const USHORT nNewSize = mnPoints - nRemoveCount;
+ const USHORT nSecPos = nPos + nRemoveCount;
+ const USHORT nRest = mnPoints - nSecPos;
+
+ Point* pNewAry = (Point*) new char[ (ULONG) nNewSize * sizeof( Point ) ];
+
+ memcpy( pNewAry, mpPointAry, nPos * sizeof( Point ) );
+ memcpy( pNewAry + nPos, mpPointAry + nSecPos, nRest * sizeof( Point ) );
+
+ delete[] (char*) mpPointAry;
+
+ // ggf. FlagArray beruecksichtigen
+ if( mpFlagAry )
+ {
+ BYTE* pNewFlagAry = new BYTE[ nNewSize ];
+
+ memcpy( pNewFlagAry, mpFlagAry, nPos );
+ memcpy( pNewFlagAry + nPos, mpFlagAry + nSecPos, nRest );
+ delete[] mpFlagAry;
+ mpFlagAry = pNewFlagAry;
+ }
+
+ mpPointAry = pNewAry;
+ mnPoints = nNewSize;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplPolygon::ImplCreateFlagArray()
+{
+ if( !mpFlagAry )
+ {
+ mpFlagAry = new BYTE[ mnPoints ];
+ memset( mpFlagAry, 0, mnPoints );
+ }
+}
+
+// =======================================================================
+
+inline void Polygon::ImplMakeUnique()
+{
+ // Falls noch andere Referenzen bestehen, dann kopieren
+ if ( mpImplPolygon->mnRefCount != 1 )
+ {
+ if ( mpImplPolygon->mnRefCount )
+ mpImplPolygon->mnRefCount--;
+ mpImplPolygon = new ImplPolygon( *mpImplPolygon );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+inline double ImplGetAngle( const Point& rCenter, const Point& rPt )
+{
+ const long nDX = rPt.X() - rCenter.X();
+ return( atan2( -rPt.Y() + rCenter.Y(), ( ( nDX == 0L ) ? 0.000000001 : nDX ) ) );
+}
+
+// -----------------------------------------------------------------------
+
+Polygon::Polygon()
+{
+ DBG_CTOR( Polygon, NULL );
+ mpImplPolygon = (ImplPolygon*)(&aStaticImplPolygon);
+}
+
+// -----------------------------------------------------------------------
+
+Polygon::Polygon( USHORT nSize )
+{
+ DBG_CTOR( Polygon, NULL );
+
+ if ( nSize )
+ mpImplPolygon = new ImplPolygon( nSize );
+ else
+ mpImplPolygon = (ImplPolygon*)(&aStaticImplPolygon);
+}
+
+// -----------------------------------------------------------------------
+
+Polygon::Polygon( USHORT nPoints, const Point* pPtAry, const BYTE* pFlagAry )
+{
+ DBG_CTOR( Polygon, NULL );
+
+ if( nPoints )
+ mpImplPolygon = new ImplPolygon( nPoints, pPtAry, pFlagAry );
+ else
+ mpImplPolygon = (ImplPolygon*)(&aStaticImplPolygon);
+}
+
+// -----------------------------------------------------------------------
+
+Polygon::Polygon( const Polygon& rPoly )
+{
+ DBG_CTOR( Polygon, NULL );
+ DBG_CHKOBJ( &rPoly, Polygon, NULL );
+ DBG_ASSERT( rPoly.mpImplPolygon->mnRefCount < 0xFFFFFFFE, "Polygon: RefCount overflow" );
+
+ mpImplPolygon = rPoly.mpImplPolygon;
+ if ( mpImplPolygon->mnRefCount )
+ mpImplPolygon->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+Polygon::Polygon( const Rectangle& rRect )
+{
+ DBG_CTOR( Polygon, NULL );
+
+ if ( rRect.IsEmpty() )
+ mpImplPolygon = (ImplPolygon*)(&aStaticImplPolygon);
+ else
+ {
+ mpImplPolygon = new ImplPolygon( 5 );
+ mpImplPolygon->mpPointAry[0] = rRect.TopLeft();
+ mpImplPolygon->mpPointAry[1] = rRect.TopRight();
+ mpImplPolygon->mpPointAry[2] = rRect.BottomRight();
+ mpImplPolygon->mpPointAry[3] = rRect.BottomLeft();
+ mpImplPolygon->mpPointAry[4] = rRect.TopLeft();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Polygon::Polygon( const Rectangle& rRect, ULONG nHorzRound, ULONG nVertRound )
+{
+ DBG_CTOR( Polygon, NULL );
+
+ if ( rRect.IsEmpty() )
+ mpImplPolygon = (ImplPolygon*)(&aStaticImplPolygon);
+ else
+ {
+ Rectangle aRect( rRect );
+ aRect.Justify(); // SJ: i9140
+
+ nHorzRound = Min( nHorzRound, (ULONG) labs( aRect.GetWidth() >> 1 ) );
+ nVertRound = Min( nVertRound, (ULONG) labs( aRect.GetHeight() >> 1 ) );
+
+ if( !nHorzRound && !nVertRound )
+ {
+ mpImplPolygon = new ImplPolygon( 5 );
+ mpImplPolygon->mpPointAry[0] = aRect.TopLeft();
+ mpImplPolygon->mpPointAry[1] = aRect.TopRight();
+ mpImplPolygon->mpPointAry[2] = aRect.BottomRight();
+ mpImplPolygon->mpPointAry[3] = aRect.BottomLeft();
+ mpImplPolygon->mpPointAry[4] = aRect.TopLeft();
+ }
+ else
+ {
+ const Point aTL( aRect.Left() + nHorzRound, aRect.Top() + nVertRound );
+ const Point aTR( aRect.Right() - nHorzRound, aRect.Top() + nVertRound );
+ const Point aBR( aRect.Right() - nHorzRound, aRect.Bottom() - nVertRound );
+ const Point aBL( aRect.Left() + nHorzRound, aRect.Bottom() - nVertRound );
+ Polygon* pEllipsePoly = new Polygon( Point(), nHorzRound, nVertRound );
+ USHORT i, nEnd, nSize4 = pEllipsePoly->GetSize() >> 2;
+
+ mpImplPolygon = new ImplPolygon( pEllipsePoly->GetSize() + 1 );
+
+ const Point* pSrcAry = pEllipsePoly->GetConstPointAry();
+ Point* pDstAry = mpImplPolygon->mpPointAry;
+
+ for( i = 0, nEnd = nSize4; i < nEnd; i++ )
+ ( pDstAry[ i ] = pSrcAry[ i ] ) += aTR;
+
+ for( nEnd = nEnd + nSize4; i < nEnd; i++ )
+ ( pDstAry[ i ] = pSrcAry[ i ] ) += aTL;
+
+ for( nEnd = nEnd + nSize4; i < nEnd; i++ )
+ ( pDstAry[ i ] = pSrcAry[ i ] ) += aBL;
+
+ for( nEnd = nEnd + nSize4; i < nEnd; i++ )
+ ( pDstAry[ i ] = pSrcAry[ i ] ) += aBR;
+
+ pDstAry[ nEnd ] = pDstAry[ 0 ];
+ delete pEllipsePoly;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Polygon::Polygon( const Point& rCenter, long nRadX, long nRadY, USHORT nPoints )
+{
+ DBG_CTOR( Polygon, NULL );
+
+ if( nRadX && nRadY )
+ {
+ // Default berechnen (abhaengig von Groesse)
+ if( !nPoints )
+ {
+ nPoints = (USHORT) ( F_PI * ( 1.5 * ( nRadX + nRadY ) -
+ sqrt( (double) labs( nRadX * nRadY ) ) ) );
+
+ nPoints = (USHORT) MinMax( nPoints, 32, 256 );
+
+ if( ( nRadX > 32 ) && ( nRadY > 32 ) && ( nRadX + nRadY ) < 8192 )
+ nPoints >>= 1;
+ }
+
+ // Anzahl der Punkte auf durch 4 teilbare Zahl aufrunden
+ mpImplPolygon = new ImplPolygon( nPoints = (nPoints + 3) & ~3 );
+
+ Point* pPt;
+ USHORT i;
+ USHORT nPoints2 = nPoints >> 1;
+ USHORT nPoints4 = nPoints >> 2;
+ double nAngle;
+ double nAngleStep = F_PI2 / ( nPoints4 - 1 );
+
+ for( i=0, nAngle = 0.0; i < nPoints4; i++, nAngle += nAngleStep )
+ {
+ long nX = FRound( nRadX * cos( nAngle ) );
+ long nY = FRound( -nRadY * sin( nAngle ) );
+
+ pPt = &(mpImplPolygon->mpPointAry[i]);
+ pPt->X() = nX + rCenter.X();
+ pPt->Y() = nY + rCenter.Y();
+ pPt = &(mpImplPolygon->mpPointAry[nPoints2-i-1]);
+ pPt->X() = -nX + rCenter.X();
+ pPt->Y() = nY + rCenter.Y();
+ pPt = &(mpImplPolygon->mpPointAry[i+nPoints2]);
+ pPt->X() = -nX + rCenter.X();
+ pPt->Y() = -nY + rCenter.Y();
+ pPt = &(mpImplPolygon->mpPointAry[nPoints-i-1]);
+ pPt->X() = nX + rCenter.X();
+ pPt->Y() = -nY + rCenter.Y();
+ }
+ }
+ else
+ mpImplPolygon = (ImplPolygon*)(&aStaticImplPolygon);
+}
+
+// -----------------------------------------------------------------------
+
+Polygon::Polygon( const Rectangle& rBound,
+ const Point& rStart, const Point& rEnd, PolyStyle eStyle )
+{
+ DBG_CTOR( Polygon, NULL );
+
+ const long nWidth = rBound.GetWidth();
+ const long nHeight = rBound.GetHeight();
+
+ if( ( nWidth > 1 ) && ( nHeight > 1 ) )
+ {
+ const Point aCenter( rBound.Center() );
+ const long nRadX = aCenter.X() - rBound.Left();
+ const long nRadY = aCenter.Y() - rBound.Top();
+ USHORT nPoints;
+
+ nPoints = (USHORT) ( F_PI * ( 1.5 * ( nRadX + nRadY ) -
+ sqrt( (double) labs( nRadX * nRadY ) ) ) );
+
+ nPoints = (USHORT) MinMax( nPoints, 32, 256 );
+
+ if( ( nRadX > 32 ) && ( nRadY > 32 ) && ( nRadX + nRadY ) < 8192 )
+ nPoints >>= 1;
+
+ // Winkel berechnen
+ const double fRadX = nRadX;
+ const double fRadY = nRadY;
+ const double fCenterX = aCenter.X();
+ const double fCenterY = aCenter.Y();
+ double fStart = ImplGetAngle( aCenter, rStart );
+ double fEnd = ImplGetAngle( aCenter, rEnd );
+ double fDiff = fEnd - fStart;
+ double fStep;
+ USHORT nStart;
+ USHORT nEnd;
+
+ if( fDiff < 0. )
+ fDiff += F_2PI;
+
+ // Punktanzahl proportional verkleinern ( fDiff / (2PI) );
+ // ist eingentlich nur fuer einen Kreis richtig; wir
+ // machen es hier aber trotzdem
+ nPoints = Max( (USHORT) ( ( fDiff * 0.1591549 ) * nPoints ), (USHORT) 16 );
+ fStep = fDiff / ( nPoints - 1 );
+
+ if( POLY_PIE == eStyle )
+ {
+ const Point aCenter2( FRound( fCenterX ), FRound( fCenterY ) );
+
+ nStart = 1;
+ nEnd = nPoints + 1;
+ mpImplPolygon = new ImplPolygon( nPoints + 2 );
+ mpImplPolygon->mpPointAry[ 0 ] = aCenter2;
+ mpImplPolygon->mpPointAry[ nEnd ] = aCenter2;
+ }
+ else
+ {
+ mpImplPolygon = new ImplPolygon( ( POLY_CHORD == eStyle ) ? ( nPoints + 1 ) : nPoints );
+ nStart = 0;
+ nEnd = nPoints;
+ }
+
+ for(; nStart < nEnd; nStart++, fStart += fStep )
+ {
+ Point& rPt = mpImplPolygon->mpPointAry[ nStart ];
+
+ rPt.X() = FRound( fCenterX + fRadX * cos( fStart ) );
+ rPt.Y() = FRound( fCenterY - fRadY * sin( fStart ) );
+ }
+
+ if( POLY_CHORD == eStyle )
+ mpImplPolygon->mpPointAry[ nPoints ] = mpImplPolygon->mpPointAry[ 0 ];
+ }
+ else
+ mpImplPolygon = (ImplPolygon*) &aStaticImplPolygon;
+}
+
+// -----------------------------------------------------------------------
+
+Polygon::Polygon( const Point& rBezPt1, const Point& rCtrlPt1,
+ const Point& rBezPt2, const Point& rCtrlPt2,
+ USHORT nPoints )
+{
+ DBG_CTOR( Polygon, NULL );
+
+ nPoints = ( 0 == nPoints ) ? 25 : ( ( nPoints < 2 ) ? 2 : nPoints );
+
+ const double fInc = 1.0 / ( nPoints - 1 );
+ double fK_1 = 0.0, fK1_1 = 1.0;
+ double fK_2, fK_3, fK1_2, fK1_3, fK12, fK21;
+ const double fX0 = rBezPt1.X();
+ const double fY0 = rBezPt1.Y();
+ const double fX1 = 3.0 * rCtrlPt1.X();
+ const double fY1 = 3.0 * rCtrlPt1.Y();
+ const double fX2 = 3.0 * rCtrlPt2.X();;
+ const double fY2 = 3.0 * rCtrlPt2.Y();;
+ const double fX3 = rBezPt2.X();
+ const double fY3 = rBezPt2.Y();
+
+ mpImplPolygon = new ImplPolygon( nPoints );
+
+ for( USHORT i = 0; i < nPoints; i++, fK_1 += fInc, fK1_1 -= fInc )
+ {
+ Point& rPt = mpImplPolygon->mpPointAry[ i ];
+
+ fK_2 = fK_1, fK_3 = ( fK_2 *= fK_1 ), fK_3 *= fK_1;
+ fK1_2 = fK1_1, fK1_3 = ( fK1_2 *= fK1_1 ), fK1_3 *= fK1_1;
+ fK12 = fK_1 * fK1_2, fK21 = fK_2 * fK1_1;
+
+ rPt.X() = FRound( fK1_3 * fX0 + fK12 * fX1 + fK21 * fX2 + fK_3 * fX3 );
+ rPt.Y() = FRound( fK1_3 * fY0 + fK12 * fY1 + fK21 * fY2 + fK_3 * fY3 );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Polygon::~Polygon()
+{
+ DBG_DTOR( Polygon, NULL );
+
+ // Wenn es keine statischen ImpDaten sind, dann loeschen, wenn es
+ // die letzte Referenz ist, sonst Referenzcounter decrementieren
+ if ( mpImplPolygon->mnRefCount )
+ {
+ if ( mpImplPolygon->mnRefCount > 1 )
+ mpImplPolygon->mnRefCount--;
+ else
+ delete mpImplPolygon;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Point* Polygon::ImplGetPointAry()
+{
+ DBG_CHKTHIS( Polygon, NULL );
+
+ ImplMakeUnique();
+ return (Point*)mpImplPolygon->mpPointAry;
+}
+
+// -----------------------------------------------------------------------
+
+BYTE* Polygon::ImplGetFlagAry()
+{
+ DBG_CHKTHIS( Polygon, NULL );
+
+ ImplMakeUnique();
+ mpImplPolygon->ImplCreateFlagArray();
+ return mpImplPolygon->mpFlagAry;
+}
+
+// -----------------------------------------------------------------------
+
+const Point* Polygon::GetConstPointAry() const
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ return (Point*)mpImplPolygon->mpPointAry;
+}
+
+// -----------------------------------------------------------------------
+
+const BYTE* Polygon::GetConstFlagAry() const
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ return mpImplPolygon->mpFlagAry;
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::SetPoint( const Point& rPt, USHORT nPos )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ DBG_ASSERT( nPos < mpImplPolygon->mnPoints,
+ "Polygon::SetPoint(): nPos >= nPoints" );
+
+ ImplMakeUnique();
+ mpImplPolygon->mpPointAry[nPos] = rPt;
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::SetFlags( USHORT nPos, PolyFlags eFlags )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ DBG_ASSERT( nPos < mpImplPolygon->mnPoints,
+ "Polygon::SetFlags(): nPos >= nPoints" );
+
+ // we do only want to create the flag array if there
+ // is at least one flag different to POLY_NORMAL
+ if ( mpImplPolygon || ( eFlags != POLY_NORMAL ) )
+ {
+ ImplMakeUnique();
+ mpImplPolygon->ImplCreateFlagArray();
+ mpImplPolygon->mpFlagAry[ nPos ] = (BYTE) eFlags;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+const Point& Polygon::GetPoint( USHORT nPos ) const
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ DBG_ASSERT( nPos < mpImplPolygon->mnPoints,
+ "Polygon::GetPoint(): nPos >= nPoints" );
+
+ return mpImplPolygon->mpPointAry[nPos];
+}
+
+// -----------------------------------------------------------------------
+
+PolyFlags Polygon::GetFlags( USHORT nPos ) const
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ DBG_ASSERT( nPos < mpImplPolygon->mnPoints,
+ "Polygon::GetFlags(): nPos >= nPoints" );
+ return( mpImplPolygon->mpFlagAry ?
+ (PolyFlags) mpImplPolygon->mpFlagAry[ nPos ] :
+ POLY_NORMAL );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Polygon::HasFlags() const
+{
+ return mpImplPolygon->mpFlagAry != NULL;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Polygon::IsControl(USHORT nPos) const
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ DBG_ASSERT( nPos < mpImplPolygon->mnPoints,
+ "Polygon::GetFlags(): nPos >= nPoints" );
+ PolyFlags eFlags = mpImplPolygon->mpFlagAry ?
+ (PolyFlags) mpImplPolygon->mpFlagAry[ nPos ] : POLY_NORMAL;
+
+ return( POLY_CONTROL == eFlags );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Polygon::IsSmooth(USHORT nPos) const
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ DBG_ASSERT( nPos < mpImplPolygon->mnPoints,
+ "Polygon::GetFlags(): nPos >= nPoints" );
+ PolyFlags eFlags = mpImplPolygon->mpFlagAry ?
+ (PolyFlags) mpImplPolygon->mpFlagAry[ nPos ] : POLY_NORMAL;
+
+ return( ( POLY_SMOOTH == eFlags ) || ( POLY_SYMMTR == eFlags ) );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Polygon::IsRect() const
+{
+ BOOL bIsRect = FALSE;
+ if ( mpImplPolygon->mpFlagAry == NULL )
+ {
+ if ( ( ( mpImplPolygon->mnPoints == 5 ) && ( mpImplPolygon->mpPointAry[ 0 ] == mpImplPolygon->mpPointAry[ 4 ] ) ) ||
+ ( mpImplPolygon->mnPoints == 4 ) )
+ {
+ if ( ( mpImplPolygon->mpPointAry[ 0 ].X() == mpImplPolygon->mpPointAry[ 3 ].X() ) &&
+ ( mpImplPolygon->mpPointAry[ 0 ].Y() == mpImplPolygon->mpPointAry[ 1 ].Y() ) &&
+ ( mpImplPolygon->mpPointAry[ 1 ].X() == mpImplPolygon->mpPointAry[ 2 ].X() ) &&
+ ( mpImplPolygon->mpPointAry[ 2 ].Y() == mpImplPolygon->mpPointAry[ 3 ].Y() ) )
+ bIsRect = TRUE;
+ }
+ }
+ return bIsRect;
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::SetSize( USHORT nNewSize )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+
+ if( nNewSize != mpImplPolygon->mnPoints )
+ {
+ ImplMakeUnique();
+ mpImplPolygon->ImplSetSize( nNewSize );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Polygon::GetSize() const
+{
+ DBG_CHKTHIS( Polygon, NULL );
+
+ return mpImplPolygon->mnPoints;
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::Clear()
+{
+ DBG_CHKTHIS( Polygon, NULL );
+
+ if ( mpImplPolygon->mnRefCount )
+ {
+ if ( mpImplPolygon->mnRefCount > 1 )
+ mpImplPolygon->mnRefCount--;
+ else
+ delete mpImplPolygon;
+ }
+
+ mpImplPolygon = (ImplPolygon*)(&aStaticImplPolygon);
+}
+
+// -----------------------------------------------------------------------
+
+double Polygon::CalcDistance( USHORT nP1, USHORT nP2 )
+{
+ DBG_ASSERT( nP1 < mpImplPolygon->mnPoints,
+ "Polygon::CalcDistance(): nPos1 >= nPoints" );
+ DBG_ASSERT( nP2 < mpImplPolygon->mnPoints,
+ "Polygon::CalcDistance(): nPos2 >= nPoints" );
+
+ const Point& rP1 = mpImplPolygon->mpPointAry[ nP1 ];
+ const Point& rP2 = mpImplPolygon->mpPointAry[ nP2 ];
+ const double fDx = rP2.X() - rP1.X();
+ const double fDy = rP2.Y() - rP1.Y();
+
+ return sqrt( fDx * fDx + fDy * fDy );
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::Optimize( ULONG nOptimizeFlags, const PolyOptimizeData* pData )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ DBG_ASSERT( !mpImplPolygon->mpFlagAry, "Optimizing could fail with beziers!" );
+
+ USHORT nSize = mpImplPolygon->mnPoints;
+
+ if( nOptimizeFlags && nSize )
+ {
+ if( nOptimizeFlags & POLY_OPTIMIZE_EDGES )
+ {
+ const Rectangle aBound( GetBoundRect() );
+ const double fArea = ( aBound.GetWidth() + aBound.GetHeight() ) * 0.5;
+ const USHORT nPercent = pData ? pData->GetPercentValue() : 50;
+
+ Optimize( POLY_OPTIMIZE_NO_SAME );
+ ImplReduceEdges( *this, fArea, nPercent );
+ }
+ else if( nOptimizeFlags & ( POLY_OPTIMIZE_REDUCE | POLY_OPTIMIZE_NO_SAME ) )
+ {
+ Polygon aNewPoly;
+ const Point& rFirst = mpImplPolygon->mpPointAry[ 0 ];
+ ULONG nReduce;
+
+ if( nOptimizeFlags & ( POLY_OPTIMIZE_REDUCE ) )
+ nReduce = pData ? pData->GetAbsValue() : 4UL;
+ else
+ nReduce = 0UL;
+
+ while( nSize && ( mpImplPolygon->mpPointAry[ nSize - 1 ] == rFirst ) )
+ nSize--;
+
+ if( nSize > 1 )
+ {
+ USHORT nLast = 0, nNewCount = 1;
+
+ aNewPoly.SetSize( nSize );
+ aNewPoly[ 0 ] = rFirst;
+
+ for( USHORT i = 1; i < nSize; i++ )
+ {
+ if( ( mpImplPolygon->mpPointAry[ i ] != mpImplPolygon->mpPointAry[ nLast ] ) &&
+ ( !nReduce || ( nReduce < (ULONG) FRound( CalcDistance( nLast, i ) ) ) ) )
+ {
+ aNewPoly[ nNewCount++ ] = mpImplPolygon->mpPointAry[ nLast = i ];
+ }
+ }
+
+ if( nNewCount == 1 )
+ aNewPoly.Clear();
+ else
+ aNewPoly.SetSize( nNewCount );
+ }
+
+ *this = aNewPoly;
+ }
+
+ nSize = mpImplPolygon->mnPoints;
+
+ if( nSize > 1 )
+ {
+ if( ( nOptimizeFlags & POLY_OPTIMIZE_CLOSE ) &&
+ ( mpImplPolygon->mpPointAry[ 0 ] != mpImplPolygon->mpPointAry[ nSize - 1 ] ) )
+ {
+ SetSize( mpImplPolygon->mnPoints + 1 );
+ mpImplPolygon->mpPointAry[ mpImplPolygon->mnPoints - 1 ] = mpImplPolygon->mpPointAry[ 0 ];
+ }
+ else if( ( nOptimizeFlags & POLY_OPTIMIZE_OPEN ) &&
+ ( mpImplPolygon->mpPointAry[ 0 ] == mpImplPolygon->mpPointAry[ nSize - 1 ] ) )
+ {
+ const Point& rFirst = mpImplPolygon->mpPointAry[ 0 ];
+
+ while( nSize && ( mpImplPolygon->mpPointAry[ nSize - 1 ] == rFirst ) )
+ nSize--;
+
+ SetSize( nSize );
+ }
+ }
+ }
+}
+
+// =======================================================================
+
+/* Recursively subdivide cubic bezier curve via deCasteljau.
+
+ @param rPointIter
+ Output iterator, where the subdivided polylines are written to.
+
+ @param d
+ Squared difference of curve to a straight line
+
+ @param P*
+ Exactly four points, interpreted as support and control points of
+ a cubic bezier curve. Must be in device coordinates, since stop
+ criterion is based on the following assumption: the device has a
+ finite resolution, it is thus sufficient to stop subdivision if the
+ curve does not deviate more than one pixel from a straight line.
+
+*/
+static void ImplAdaptiveSubdivide( ::std::back_insert_iterator< ::std::vector< Point > >& rPointIter,
+ const double old_d2,
+ int recursionDepth,
+ const double d2,
+ const double P1x, const double P1y,
+ const double P2x, const double P2y,
+ const double P3x, const double P3y,
+ const double P4x, const double P4y )
+{
+ // Hard limit on recursion depth, empiric number.
+ enum {maxRecursionDepth=128};
+
+ // Perform bezier flatness test (lecture notes from R. Schaback,
+ // Mathematics of Computer-Aided Design, Uni Goettingen, 2000)
+ //
+ // ||P(t) - L(t)|| <= max ||b_j - b_0 - j/n(b_n - b_0)||
+ // 0<=j<=n
+ //
+ // What is calculated here is an upper bound to the distance from
+ // a line through b_0 and b_3 (P1 and P4 in our notation) and the
+ // curve. We can drop 0 and n from the running indices, since the
+ // argument of max becomes zero for those cases.
+ const double fJ1x( P2x - P1x - 1.0/3.0*(P4x - P1x) );
+ const double fJ1y( P2y - P1y - 1.0/3.0*(P4y - P1y) );
+ const double fJ2x( P3x - P1x - 2.0/3.0*(P4x - P1x) );
+ const double fJ2y( P3y - P1y - 2.0/3.0*(P4y - P1y) );
+ const double distance2( ::std::max( fJ1x*fJ1x + fJ1y*fJ1y,
+ fJ2x*fJ2x + fJ2y*fJ2y) );
+
+ // stop if error measure does not improve anymore. This is a
+ // safety guard against floating point inaccuracies.
+ // stop at recursion level 128. This is a safety guard against
+ // floating point inaccuracies.
+ // stop if distance from line is guaranteed to be bounded by d
+ if( old_d2 > d2 &&
+ recursionDepth < maxRecursionDepth &&
+ distance2 >= d2 )
+ {
+ // deCasteljau bezier arc, split at t=0.5
+ // Foley/vanDam, p. 508
+ const double L1x( P1x ), L1y( P1y );
+ const double L2x( (P1x + P2x)*0.5 ), L2y( (P1y + P2y)*0.5 );
+ const double Hx ( (P2x + P3x)*0.5 ), Hy ( (P2y + P3y)*0.5 );
+ const double L3x( (L2x + Hx)*0.5 ), L3y( (L2y + Hy)*0.5 );
+ const double R4x( P4x ), R4y( P4y );
+ const double R3x( (P3x + P4x)*0.5 ), R3y( (P3y + P4y)*0.5 );
+ const double R2x( (Hx + R3x)*0.5 ), R2y( (Hy + R3y)*0.5 );
+ const double R1x( (L3x + R2x)*0.5 ), R1y( (L3y + R2y)*0.5 );
+ const double L4x( R1x ), L4y( R1y );
+
+ // subdivide further
+ ++recursionDepth;
+ ImplAdaptiveSubdivide(rPointIter, distance2, recursionDepth, d2, L1x, L1y, L2x, L2y, L3x, L3y, L4x, L4y);
+ ImplAdaptiveSubdivide(rPointIter, distance2, recursionDepth, d2, R1x, R1y, R2x, R2y, R3x, R3y, R4x, R4y);
+ }
+ else
+ {
+ // requested resolution reached.
+ // Add end points to output iterator.
+ // order is preserved, since this is so to say depth first traversal.
+ *rPointIter++ = Point( FRound(P1x), FRound(P1y) );
+ }
+}
+
+// =======================================================================
+
+void Polygon::AdaptiveSubdivide( Polygon& rResult, const double d ) const
+{
+ if( !mpImplPolygon->mpFlagAry )
+ {
+ rResult = *this;
+ }
+ else
+ {
+ USHORT i;
+ USHORT nPts( GetSize() );
+ ::std::vector< Point > aPoints;
+ aPoints.reserve( nPts );
+ ::std::back_insert_iterator< ::std::vector< Point > > aPointIter( aPoints );
+
+ for(i=0; i<nPts;)
+ {
+ if( ( i + 3 ) < nPts )
+ {
+ BYTE P1( mpImplPolygon->mpFlagAry[ i ] );
+ BYTE P4( mpImplPolygon->mpFlagAry[ i + 3 ] );
+
+ if( ( POLY_NORMAL == P1 || POLY_SMOOTH == P1 || POLY_SYMMTR == P1 ) &&
+ ( POLY_CONTROL == mpImplPolygon->mpFlagAry[ i + 1 ] ) &&
+ ( POLY_CONTROL == mpImplPolygon->mpFlagAry[ i + 2 ] ) &&
+ ( POLY_NORMAL == P4 || POLY_SMOOTH == P4 || POLY_SYMMTR == P4 ) )
+ {
+ ImplAdaptiveSubdivide( aPointIter, d*d+1.0, 0, d*d,
+ mpImplPolygon->mpPointAry[ i ].X(), mpImplPolygon->mpPointAry[ i ].Y(),
+ mpImplPolygon->mpPointAry[ i+1 ].X(), mpImplPolygon->mpPointAry[ i+1 ].Y(),
+ mpImplPolygon->mpPointAry[ i+2 ].X(), mpImplPolygon->mpPointAry[ i+2 ].Y(),
+ mpImplPolygon->mpPointAry[ i+3 ].X(), mpImplPolygon->mpPointAry[ i+3 ].Y() );
+ i += 3;
+ continue;
+ }
+ }
+
+ *aPointIter++ = mpImplPolygon->mpPointAry[ i++ ];
+ }
+
+ // fill result polygon
+ rResult = Polygon( (USHORT)aPoints.size() ); // ensure sufficient size for copy
+ ::std::copy(aPoints.begin(), aPoints.end(), rResult.mpImplPolygon->mpPointAry);
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::GetIntersection( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
+{
+ const PolyPolygon aTmp( *this );
+ aTmp.GetIntersection( rPolyPoly, rResult );
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::GetUnion( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
+{
+ const PolyPolygon aTmp( *this );
+ aTmp.GetUnion( rPolyPoly, rResult );
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::GetDifference( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
+{
+ const PolyPolygon aTmp( *this );
+ aTmp.GetDifference( rPolyPoly, rResult );
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::GetXOR( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
+{
+ const PolyPolygon aTmp( *this );
+ aTmp.GetXOR( rPolyPoly, rResult );
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::ImplReduceEdges( Polygon& rPoly, const double& rArea, USHORT nPercent )
+{
+ const double fBound = 2000.0 * ( 100 - nPercent ) * 0.01;
+ USHORT nNumNoChange = 0, nNumRuns = 0;
+
+ while( nNumNoChange < 2 )
+ {
+ USHORT nPntCnt = rPoly.GetSize(), nNewPos = 0;
+ Polygon aNewPoly( nPntCnt );
+ BOOL bChangeInThisRun = FALSE;
+
+ for( USHORT n = 0; n < nPntCnt; n++ )
+ {
+ BOOL bDeletePoint = FALSE;
+
+ if( ( n + nNumRuns ) % 2 )
+ {
+ USHORT nIndPrev = !n ? nPntCnt - 1 : n - 1;
+ USHORT nIndPrevPrev = !nIndPrev ? nPntCnt - 1 : nIndPrev - 1;
+ USHORT nIndNext = ( n == nPntCnt-1 ) ? 0 : n + 1;
+ USHORT nIndNextNext = ( nIndNext == nPntCnt - 1 ) ? 0 : nIndNext + 1;
+ Vector2D aVec1( rPoly[ nIndPrev ] ); aVec1 -= rPoly[ nIndPrevPrev ];
+ Vector2D aVec2( rPoly[ n ] ); aVec2 -= rPoly[ nIndPrev ];
+ Vector2D aVec3( rPoly[ nIndNext ] ); aVec3 -= rPoly[ n ];
+ Vector2D aVec4( rPoly[ nIndNextNext ] ); aVec4 -= rPoly[ nIndNext ];
+ double fDist1 = aVec1.GetLength(), fDist2 = aVec2.GetLength();
+ double fDist3 = aVec3.GetLength(), fDist4 = aVec4.GetLength();
+ double fTurnB = aVec2.Normalize().Scalar( aVec3.Normalize() );
+
+ if( fabs( fTurnB ) < ( 1.0 + SMALL_DVALUE ) && fabs( fTurnB ) > ( 1.0 - SMALL_DVALUE ) )
+ bDeletePoint = TRUE;
+ else
+ {
+ Vector2D aVecB( rPoly[ nIndNext ] );
+ double fDistB = ( aVecB -= rPoly[ nIndPrev ] ).GetLength();
+ double fLenWithB = fDist2 + fDist3;
+ double fLenFact = ( fDistB != 0.0 ) ? fLenWithB / fDistB : 1.0;
+ double fTurnPrev = aVec1.Normalize().Scalar( aVec2 );
+ double fTurnNext = aVec3.Scalar( aVec4.Normalize() );
+ double fGradPrev, fGradB, fGradNext;
+
+ if( fabs( fTurnPrev ) < ( 1.0 + SMALL_DVALUE ) && fabs( fTurnPrev ) > ( 1.0 - SMALL_DVALUE ) )
+ fGradPrev = 0.0;
+ else
+ fGradPrev = acos( fTurnPrev ) / ( aVec1.IsNegative( aVec2 ) ? -F_PI180 : F_PI180 );
+
+ fGradB = acos( fTurnB ) / ( aVec2.IsNegative( aVec3 ) ? -F_PI180 : F_PI180 );
+
+ if( fabs( fTurnNext ) < ( 1.0 + SMALL_DVALUE ) && fabs( fTurnNext ) > ( 1.0 - SMALL_DVALUE ) )
+ fGradNext = 0.0;
+ else
+ fGradNext = acos( fTurnNext ) / ( aVec3.IsNegative( aVec4 ) ? -F_PI180 : F_PI180 );
+
+ if( ( fGradPrev > 0.0 && fGradB < 0.0 && fGradNext > 0.0 ) ||
+ ( fGradPrev < 0.0 && fGradB > 0.0 && fGradNext < 0.0 ) )
+ {
+ if( ( fLenFact < ( FSQRT2 + SMALL_DVALUE ) ) &&
+ ( ( ( fDist1 + fDist4 ) / ( fDist2 + fDist3 ) ) * 2000.0 ) > fBound )
+ {
+ bDeletePoint = TRUE;
+ }
+ }
+ else
+ {
+ double fRelLen = 1.0 - sqrt( fDistB / rArea );
+
+ if( fRelLen < 0.0 )
+ fRelLen = 0.0;
+ else if( fRelLen > 1.0 )
+ fRelLen = 1.0;
+
+ if( ( (UINT32) ( ( ( fLenFact - 1.0 ) * 1000000.0 ) + 0.5 ) < fBound ) &&
+ ( fabs( fGradB ) <= ( fRelLen * fBound * 0.01 ) ) )
+ {
+ bDeletePoint = TRUE;
+ }
+ }
+ }
+ }
+
+ if( !bDeletePoint )
+ aNewPoly[ nNewPos++ ] = rPoly[ n ];
+ else
+ bChangeInThisRun = TRUE;
+ }
+
+ if( bChangeInThisRun && nNewPos )
+ {
+ aNewPoly.SetSize( nNewPos );
+ rPoly = aNewPoly;
+ nNumNoChange = 0;
+ }
+ else
+ nNumNoChange++;
+
+ nNumRuns++;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::Move( long nHorzMove, long nVertMove )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+
+ // Diese Abfrage sollte man fuer die DrawEngine durchfuehren
+ if ( !nHorzMove && !nVertMove )
+ return;
+
+ ImplMakeUnique();
+
+ // Punkte verschieben
+ USHORT nCount = mpImplPolygon->mnPoints;
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ Point* pPt = &(mpImplPolygon->mpPointAry[i]);
+ pPt->X() += nHorzMove;
+ pPt->Y() += nVertMove;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::Translate(const Point& rTrans)
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ ImplMakeUnique();
+
+ for ( USHORT i = 0, nCount = mpImplPolygon->mnPoints; i < nCount; i++ )
+ mpImplPolygon->mpPointAry[ i ] += rTrans;
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::Scale( double fScaleX, double fScaleY )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ ImplMakeUnique();
+
+ for ( USHORT i = 0, nCount = mpImplPolygon->mnPoints; i < nCount; i++ )
+ {
+ Point& rPnt = mpImplPolygon->mpPointAry[i];
+ rPnt.X() = (long) ( fScaleX * rPnt.X() );
+ rPnt.Y() = (long) ( fScaleY * rPnt.Y() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::Rotate( const Point& rCenter, USHORT nAngle10 )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ nAngle10 %= 3600;
+
+ if( nAngle10 )
+ {
+ const double fAngle = F_PI1800 * nAngle10;
+ Rotate( rCenter, sin( fAngle ), cos( fAngle ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::Rotate( const Point& rCenter, double fSin, double fCos )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ ImplMakeUnique();
+
+ long nX, nY;
+ long nCenterX = rCenter.X();
+ long nCenterY = rCenter.Y();
+
+ for( USHORT i = 0, nCount = mpImplPolygon->mnPoints; i < nCount; i++ )
+ {
+ Point& rPt = mpImplPolygon->mpPointAry[ i ];
+
+ nX = rPt.X() - nCenterX;
+ nY = rPt.Y() - nCenterY;
+ rPt.X() = (long) FRound( fCos * nX + fSin * nY ) + nCenterX;
+ rPt.Y() = -(long) FRound( fSin * nX - fCos * nY ) + nCenterY;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::SlantX( long nYRef, double fSin, double fCos )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ ImplMakeUnique();
+
+ for( USHORT i = 0, nCount = mpImplPolygon->mnPoints; i < nCount; i++ )
+ {
+ Point& rPnt = mpImplPolygon->mpPointAry[ i ];
+ const long nDy = rPnt.Y() - nYRef;
+
+ rPnt.X() += (long)( fSin * nDy );
+ rPnt.Y() = nYRef + (long)( fCos * nDy );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::SlantY( long nXRef, double fSin, double fCos )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ ImplMakeUnique();
+
+ for( USHORT i = 0, nCount = mpImplPolygon->mnPoints; i < nCount; i++ )
+ {
+ Point& rPnt = mpImplPolygon->mpPointAry[ i ];
+ const long nDx = rPnt.X() - nXRef;
+
+ rPnt.X() = nXRef + (long)( fCos * nDx );
+ rPnt.Y() -= (long)( fSin * nDx );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::Distort( const Rectangle& rRefRect, const Polygon& rDistortedRect )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ ImplMakeUnique();
+
+ long Xr, Wr, X1, X2, X3, X4;
+ long Yr, Hr, Y1, Y2, Y3, Y4;
+ double fTx, fTy, fUx, fUy;
+
+ Xr = rRefRect.Left();
+ Yr = rRefRect.Top();
+ Wr = rRefRect.GetWidth();
+ Hr = rRefRect.GetHeight();
+
+ if( Wr && Hr )
+ {
+ DBG_ASSERT( rDistortedRect.mpImplPolygon->mnPoints >= 4, "Distort rect too small!" );
+
+ X1 = rDistortedRect[0].X();
+ Y1 = rDistortedRect[0].Y();
+ X2 = rDistortedRect[1].X();
+ Y2 = rDistortedRect[1].Y();
+ X3 = rDistortedRect[3].X();
+ Y3 = rDistortedRect[3].Y();
+ X4 = rDistortedRect[2].X();
+ Y4 = rDistortedRect[2].Y();
+
+ for( USHORT i = 0, nCount = mpImplPolygon->mnPoints; i < nCount; i++ )
+ {
+ Point& rPnt = mpImplPolygon->mpPointAry[ i ];
+
+ fTx = (double)( rPnt.X() - Xr) / Wr;
+ fTy = (double)( rPnt.Y() - Yr) / Hr;
+ fUx = 1.0 - fTx;
+ fUy = 1.0 - fTy;
+
+ rPnt.X() = (long) ( fUy * (fUx * X1 + fTx * X2) + fTy * (fUx * X3 + fTx * X4) );
+ rPnt.Y() = (long) ( fUx * (fUy * Y1 + fTy * Y3) + fTx * (fUy * Y2 + fTy * Y4) );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+class ImplPointFilter
+{
+public:
+ virtual void LastPoint() = 0;
+ virtual void Input( const Point& rPoint ) = 0;
+};
+
+class ImplPolygonPointFilter : public ImplPointFilter
+{
+public:
+ ImplPolygon* mpPoly; // Nicht loeschen, wird dem Polygon zugewiesen
+ USHORT mnSize;
+
+ ImplPolygonPointFilter( USHORT nDestSize ) :
+ mnSize( 0 )
+ {
+ mpPoly = new ImplPolygon( nDestSize );
+ }
+
+ virtual void LastPoint();
+ virtual void Input( const Point& rPoint );
+};
+
+void ImplPolygonPointFilter::Input( const Point& rPoint )
+{
+ if ( !mnSize || (rPoint != mpPoly->mpPointAry[mnSize-1]) )
+ {
+ mnSize++;
+ if ( mnSize > mpPoly->mnPoints )
+ mpPoly->ImplSetSize( mnSize );
+ mpPoly->mpPointAry[mnSize-1] = rPoint;
+ }
+}
+
+void ImplPolygonPointFilter::LastPoint()
+{
+ if ( mnSize < mpPoly->mnPoints )
+ mpPoly->ImplSetSize( mnSize );
+};
+
+class ImplEdgePointFilter : public ImplPointFilter
+{
+ Point maFirstPoint;
+ Point maLastPoint;
+ ImplPointFilter& mrNextFilter;
+ const long mnLow;
+ const long mnHigh;
+ const int mnEdge;
+ int mnLastOutside;
+ BOOL mbFirst;
+
+public:
+ ImplEdgePointFilter( int nEdge, long nLow, long nHigh,
+ ImplPointFilter& rNextFilter ) :
+ mrNextFilter( rNextFilter ),
+ mnLow( nLow ),
+ mnHigh( nHigh ),
+ mnEdge( nEdge ),
+ mbFirst( TRUE )
+ {
+ }
+
+ Point EdgeSection( const Point& rPoint, int nEdge ) const;
+ int VisibleSide( const Point& rPoint ) const;
+ int IsPolygon() const
+ { return maFirstPoint == maLastPoint; }
+
+ virtual void Input( const Point& rPoint );
+ virtual void LastPoint();
+};
+
+inline int ImplEdgePointFilter::VisibleSide( const Point& rPoint ) const
+{
+ if ( mnEdge & EDGE_HORZ )
+ {
+ return rPoint.X() < mnLow ? EDGE_LEFT :
+ rPoint.X() > mnHigh ? EDGE_RIGHT : 0;
+ }
+ else
+ {
+ return rPoint.Y() < mnLow ? EDGE_TOP :
+ rPoint.Y() > mnHigh ? EDGE_BOTTOM : 0;
+ }
+}
+
+Point ImplEdgePointFilter::EdgeSection( const Point& rPoint, int nEdge ) const
+{
+ long lx = maLastPoint.X();
+ long ly = maLastPoint.Y();
+ long md = rPoint.X() - lx;
+ long mn = rPoint.Y() - ly;
+ long nNewX;
+ long nNewY;
+
+ if ( nEdge & EDGE_VERT )
+ {
+ nNewY = (nEdge == EDGE_TOP) ? mnLow : mnHigh;
+ long dy = nNewY - ly;
+ if ( !md )
+ nNewX = lx;
+ else if ( (LONG_MAX / Abs(md)) >= Abs(dy) )
+ nNewX = (dy * md) / mn + lx;
+ else
+ {
+ BigInt ady = dy;
+ ady *= md;
+ if( ady.IsNeg() )
+ if( mn < 0 )
+ ady += mn/2;
+ else
+ ady -= (mn-1)/2;
+ else
+ if( mn < 0 )
+ ady -= (mn+1)/2;
+ else
+ ady += mn/2;
+ ady /= mn;
+ nNewX = (long)ady + lx;
+ }
+ }
+ else
+ {
+ nNewX = (nEdge == EDGE_LEFT) ? mnLow : mnHigh;
+ long dx = nNewX - lx;
+ if ( !mn )
+ nNewY = ly;
+ else if ( (LONG_MAX / Abs(mn)) >= Abs(dx) )
+ nNewY = (dx * mn) / md + ly;
+ else
+ {
+ BigInt adx = dx;
+ adx *= mn;
+ if( adx.IsNeg() )
+ if( md < 0 )
+ adx += md/2;
+ else
+ adx -= (md-1)/2;
+ else
+ if( md < 0 )
+ adx -= (md+1)/2;
+ else
+ adx += md/2;
+ adx /= md;
+ nNewY = (long)adx + ly;
+ }
+ }
+
+ return Point( nNewX, nNewY );
+}
+
+void ImplEdgePointFilter::Input( const Point& rPoint )
+{
+ int nOutside = VisibleSide( rPoint );
+
+ if ( mbFirst )
+ {
+ maFirstPoint = rPoint;
+ mbFirst = FALSE;
+ if ( !nOutside )
+ mrNextFilter.Input( rPoint );
+ }
+ else if ( rPoint == maLastPoint )
+ return;
+ else if ( !nOutside )
+ {
+ if ( mnLastOutside )
+ mrNextFilter.Input( EdgeSection( rPoint, mnLastOutside ) );
+ mrNextFilter.Input( rPoint );
+ }
+ else if ( !mnLastOutside )
+ mrNextFilter.Input( EdgeSection( rPoint, nOutside ) );
+ else if ( nOutside != mnLastOutside )
+ {
+ mrNextFilter.Input( EdgeSection( rPoint, mnLastOutside ) );
+ mrNextFilter.Input( EdgeSection( rPoint, nOutside ) );
+ }
+
+ maLastPoint = rPoint;
+ mnLastOutside = nOutside;
+}
+
+void ImplEdgePointFilter::LastPoint()
+{
+ if ( !mbFirst )
+ {
+ int nOutside = VisibleSide( maFirstPoint );
+
+ if ( nOutside != mnLastOutside )
+ Input( maFirstPoint );
+ mrNextFilter.LastPoint();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::Clip( const Rectangle& rRect, BOOL bPolygon )
+{
+ // #105251# Justify rect befor edge filtering
+ Rectangle aJustifiedRect( rRect );
+ aJustifiedRect.Justify();
+
+ USHORT nSourceSize = mpImplPolygon->mnPoints;
+ ImplPolygonPointFilter aPolygon( nSourceSize );
+ ImplEdgePointFilter aHorzFilter( EDGE_HORZ, aJustifiedRect.Left(), aJustifiedRect.Right(),
+ aPolygon );
+ ImplEdgePointFilter aVertFilter( EDGE_VERT, aJustifiedRect.Top(), aJustifiedRect.Bottom(),
+ aHorzFilter );
+
+ for ( USHORT i = 0; i < nSourceSize; i++ )
+ aVertFilter.Input( mpImplPolygon->mpPointAry[i] );
+ if ( bPolygon || aVertFilter.IsPolygon() )
+ aVertFilter.LastPoint();
+ else
+ aPolygon.LastPoint();
+
+ // Alte ImpPolygon-Daten loeschen und die vom ImpPolygonPointFilter
+ // zuweisen
+ if ( mpImplPolygon->mnRefCount )
+ {
+ if ( mpImplPolygon->mnRefCount > 1 )
+ mpImplPolygon->mnRefCount--;
+ else
+ delete mpImplPolygon;
+ }
+ mpImplPolygon = aPolygon.mpPoly;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle Polygon::GetBoundRect() const
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ // Removing the assert. Bezier curves have the attribute that each single
+ // curve segment defined by four points can not exit the four-point polygon
+ // defined by that points. This allows to say that the curve segment can also
+ // never leave the Range of it's defining points.
+ // The result is that Polygon::GetBoundRect() may not create the minimal
+ // BoundRect of the Polygon (to get that, use basegfx::B2DPolygon classes),
+ // but will always create a valid BoundRect, at least as long as this method
+ // 'blindly' travels over all points, including control points.
+ //
+ // DBG_ASSERT( !mpImplPolygon->mpFlagAry, "GetBoundRect could fail with beziers!" );
+
+ USHORT nCount = mpImplPolygon->mnPoints;
+ if( ! nCount )
+ return Rectangle();
+
+ long nXMin, nXMax, nYMin, nYMax;
+
+ const Point* pPt = &(mpImplPolygon->mpPointAry[0]);
+ nXMin = nXMax = pPt->X();
+ nYMin = nYMax = pPt->Y();
+
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ pPt = &(mpImplPolygon->mpPointAry[i]);
+
+ if ( pPt->X() < nXMin )
+ nXMin = pPt->X();
+ if ( pPt->X() > nXMax )
+ nXMax = pPt->X();
+ if ( pPt->Y() < nYMin )
+ nYMin = pPt->Y();
+ if ( pPt->Y() > nYMax )
+ nYMax = pPt->Y();
+ }
+
+ return Rectangle( nXMin, nYMin, nXMax, nYMax );
+}
+
+// -----------------------------------------------------------------------
+
+double Polygon::GetArea() const
+{
+ const double fArea = GetSignedArea();
+ return( ( fArea < 0.0 ) ? -fArea : fArea );
+}
+
+// -----------------------------------------------------------------------
+
+double Polygon::GetSignedArea() const
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ DBG_ASSERT( !mpImplPolygon->mpFlagAry, "GetArea could fail with beziers!" );
+
+ double fArea = 0.0;
+
+ if( mpImplPolygon->mnPoints > 2 )
+ {
+ const USHORT nCount1 = mpImplPolygon->mnPoints - 1;
+
+ for( USHORT i = 0; i < nCount1; )
+ {
+ const Point& rPt = mpImplPolygon->mpPointAry[ i ];
+ const Point& rPt1 = mpImplPolygon->mpPointAry[ ++i ];
+ fArea += ( rPt.X() - rPt1.X() ) * ( rPt.Y() + rPt1.Y() );
+ }
+
+ const Point& rPt = mpImplPolygon->mpPointAry[ nCount1 ];
+ const Point& rPt0 = mpImplPolygon->mpPointAry[ 0 ];
+ fArea += ( rPt.X() - rPt0.X() ) * ( rPt.Y() + rPt0.Y() );
+ }
+
+ return fArea;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Polygon::IsInside( const Point& rPoint ) const
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ DBG_ASSERT( !mpImplPolygon->mpFlagAry, "IsInside could fail with beziers!" );
+
+ const Rectangle aBound( GetBoundRect() );
+ const Line aLine( rPoint, Point( aBound.Right() + 100L, rPoint.Y() ) );
+ USHORT nCount = mpImplPolygon->mnPoints;
+ USHORT nPCounter = 0;
+
+ if ( ( nCount > 2 ) && aBound.IsInside( rPoint ) )
+ {
+ Point aPt1( mpImplPolygon->mpPointAry[ 0 ] );
+ Point aIntersection;
+ Point aLastIntersection;
+
+ while ( ( aPt1 == mpImplPolygon->mpPointAry[ nCount - 1 ] ) && ( nCount > 3 ) )
+ nCount--;
+
+ for ( USHORT i = 1; i <= nCount; i++ )
+ {
+ const Point& rPt2 = mpImplPolygon->mpPointAry[ ( i < nCount ) ? i : 0 ];
+
+ if ( aLine.Intersection( Line( aPt1, rPt2 ), aIntersection ) )
+ {
+ // Hiermit verhindern wir das Einfuegen von
+ // doppelten Intersections, die gleich hintereinander folgen
+ if ( nPCounter )
+ {
+ if ( aIntersection != aLastIntersection )
+ {
+ aLastIntersection = aIntersection;
+ nPCounter++;
+ }
+ }
+ else
+ {
+ aLastIntersection = aIntersection;
+ nPCounter++;
+ }
+ }
+
+ aPt1 = rPt2;
+ }
+ }
+
+ // innerhalb, wenn die Anzahl der Schnittpunkte ungerade ist
+ return ( ( nPCounter & 1 ) == 1 );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Polygon::IsRightOrientated() const
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ return GetSignedArea() >= 0.0;
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::Insert( USHORT nPos, const Point& rPt, PolyFlags eFlags )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ ImplMakeUnique();
+
+ if( nPos >= mpImplPolygon->mnPoints )
+ nPos = mpImplPolygon->mnPoints;
+
+ mpImplPolygon->ImplSplit( nPos, 1 );
+ mpImplPolygon->mpPointAry[ nPos ] = rPt;
+
+ if( POLY_NORMAL != eFlags )
+ {
+ mpImplPolygon->ImplCreateFlagArray();
+ mpImplPolygon->mpFlagAry[ nPos ] = (BYTE) eFlags;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::Insert( USHORT nPos, const Polygon& rPoly )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ const USHORT nInsertCount = rPoly.mpImplPolygon->mnPoints;
+
+ if( nInsertCount )
+ {
+ ImplMakeUnique();
+
+ if( nPos >= mpImplPolygon->mnPoints )
+ nPos = mpImplPolygon->mnPoints;
+
+ if( rPoly.mpImplPolygon->mpFlagAry )
+ mpImplPolygon->ImplCreateFlagArray();
+
+ mpImplPolygon->ImplSplit( nPos, nInsertCount, rPoly.mpImplPolygon );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::Remove( USHORT nPos, USHORT nCount )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ if( nCount && ( nPos < mpImplPolygon->mnPoints ) )
+ {
+ ImplMakeUnique();
+ mpImplPolygon->ImplRemove( nPos, nCount );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Point& Polygon::operator[]( USHORT nPos )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ DBG_ASSERT( nPos < mpImplPolygon->mnPoints, "Polygon::[]: nPos >= nPoints" );
+
+ ImplMakeUnique();
+ return mpImplPolygon->mpPointAry[nPos];
+}
+
+// -----------------------------------------------------------------------
+
+Polygon& Polygon::operator=( const Polygon& rPoly )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ DBG_CHKOBJ( &rPoly, Polygon, NULL );
+ DBG_ASSERT( rPoly.mpImplPolygon->mnRefCount < 0xFFFFFFFE, "Polygon: RefCount overflow" );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ // RefCount == 0 fuer statische Objekte
+ if ( rPoly.mpImplPolygon->mnRefCount )
+ rPoly.mpImplPolygon->mnRefCount++;
+
+ // Wenn es keine statischen ImpDaten sind, dann loeschen, wenn es
+ // die letzte Referenz ist, sonst Referenzcounter decrementieren
+ if ( mpImplPolygon->mnRefCount )
+ {
+ if ( mpImplPolygon->mnRefCount > 1 )
+ mpImplPolygon->mnRefCount--;
+ else
+ delete mpImplPolygon;
+ }
+
+ mpImplPolygon = rPoly.mpImplPolygon;
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Polygon::operator==( const Polygon& rPoly ) const
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ DBG_CHKOBJ( &rPoly, Polygon, NULL );
+
+ if ( (rPoly.mpImplPolygon == mpImplPolygon) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Polygon::IsEqual( const Polygon& rPoly ) const
+{
+ sal_Bool bIsEqual = sal_True;;
+ sal_uInt16 i;
+ if ( GetSize() != rPoly.GetSize() )
+ bIsEqual = sal_False;
+ else
+ {
+ for ( i = 0; i < GetSize(); i++ )
+ {
+ if ( ( GetPoint( i ) != rPoly.GetPoint( i ) ) ||
+ ( GetFlags( i ) != rPoly.GetFlags( i ) ) )
+ {
+ bIsEqual = sal_False;
+ break;
+ }
+ }
+ }
+ return bIsEqual;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, Polygon& rPoly )
+{
+ DBG_CHKOBJ( &rPoly, Polygon, NULL );
+ DBG_ASSERTWARNING( rIStream.GetVersion(), "Polygon::>> - Solar-Version not set on rIStream" );
+
+ USHORT i;
+ USHORT nStart;
+ USHORT nCurPoints;
+ USHORT nPoints;
+ unsigned char bShort;
+ short nShortX;
+ short nShortY;
+ long nLongX;
+ long nLongY;
+
+ // Anzahl der Punkte einlesen und Array erzeugen
+ rIStream >> nPoints;
+ if ( rPoly.mpImplPolygon->mnRefCount != 1 )
+ {
+ if ( rPoly.mpImplPolygon->mnRefCount )
+ rPoly.mpImplPolygon->mnRefCount--;
+ rPoly.mpImplPolygon = new ImplPolygon( nPoints );
+ }
+ else
+ rPoly.mpImplPolygon->ImplSetSize( nPoints, FALSE );
+
+ // Je nach CompressMode das Polygon einlesen
+ if ( rIStream.GetCompressMode() == COMPRESSMODE_FULL )
+ {
+ i = 0;
+ while ( i < nPoints )
+ {
+ rIStream >> bShort >> nCurPoints;
+
+ if ( bShort )
+ {
+ for ( nStart = i; i < nStart+nCurPoints; i++ )
+ {
+ rIStream >> nShortX >> nShortY;
+ rPoly.mpImplPolygon->mpPointAry[i].X() = nShortX;
+ rPoly.mpImplPolygon->mpPointAry[i].Y() = nShortY;
+ }
+ }
+ else
+ {
+ for ( nStart = i; i < nStart+nCurPoints; i++ )
+ {
+ rIStream >> nLongX >> nLongY;
+ rPoly.mpImplPolygon->mpPointAry[i].X() = nLongX;
+ rPoly.mpImplPolygon->mpPointAry[i].Y() = nLongY;
+ }
+ }
+ }
+ }
+ else
+ {
+ // Feststellen, ob ueber die Operatoren geschrieben werden muss
+#if (SAL_TYPES_SIZEOFLONG) != 4
+ if ( 1 )
+#else
+#ifdef OSL_BIGENDIAN
+ if ( rIStream.GetNumberFormatInt() != NUMBERFORMAT_INT_BIGENDIAN )
+#else
+ if ( rIStream.GetNumberFormatInt() != NUMBERFORMAT_INT_LITTLEENDIAN )
+#endif
+#endif
+ {
+ for( i = 0; i < nPoints; i++ )
+ {
+ rIStream >> rPoly.mpImplPolygon->mpPointAry[i].X()
+ >> rPoly.mpImplPolygon->mpPointAry[i].Y();
+ }
+ }
+ else
+ rIStream.Read( rPoly.mpImplPolygon->mpPointAry, nPoints*sizeof(Point) );
+ }
+
+ return rIStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const Polygon& rPoly )
+{
+ DBG_CHKOBJ( &rPoly, Polygon, NULL );
+ DBG_ASSERTWARNING( rOStream.GetVersion(), "Polygon::<< - Solar-Version not set on rOStream" );
+
+ unsigned char bShort;
+ unsigned char bCurShort;
+ USHORT nStart;
+ USHORT i;
+ USHORT nPoints = rPoly.GetSize();
+
+ // Anzahl der Punkte rausschreiben
+ rOStream << nPoints;
+
+ // Je nach CompressMode das Polygon rausschreiben
+ if ( rOStream.GetCompressMode() == COMPRESSMODE_FULL )
+ {
+ i = 0;
+ while ( i < nPoints )
+ {
+ nStart = i;
+
+ // Feststellen, welcher Typ geschrieben werden soll
+ if ( ((rPoly.mpImplPolygon->mpPointAry[nStart].X() >= SHRT_MIN) &&
+ (rPoly.mpImplPolygon->mpPointAry[nStart].X() <= SHRT_MAX)) &&
+ ((rPoly.mpImplPolygon->mpPointAry[nStart].Y() >= SHRT_MIN) &&
+ (rPoly.mpImplPolygon->mpPointAry[nStart].Y() <= SHRT_MAX)) )
+ bShort = TRUE;
+ else
+ bShort = FALSE;
+ while ( i < nPoints )
+ {
+ // Feststellen, welcher Typ geschrieben werden soll
+ if ( ((rPoly.mpImplPolygon->mpPointAry[nStart].X() >= SHRT_MIN) &&
+ (rPoly.mpImplPolygon->mpPointAry[nStart].X() <= SHRT_MAX)) &&
+ ((rPoly.mpImplPolygon->mpPointAry[nStart].Y() >= SHRT_MIN) &&
+ (rPoly.mpImplPolygon->mpPointAry[nStart].Y() <= SHRT_MAX)) )
+ bCurShort = TRUE;
+ else
+ bCurShort = FALSE;
+
+ // Wenn sich die Werte in einen anderen Bereich begeben,
+ // muessen wir neu rausschreiben
+ if ( bCurShort != bShort )
+ {
+ bShort = bCurShort;
+ break;
+ }
+
+ i++;
+ }
+
+ rOStream << bShort << (USHORT)(i-nStart);
+
+ if ( bShort )
+ {
+ for( ; nStart < i; nStart++ )
+ {
+ rOStream << (short)rPoly.mpImplPolygon->mpPointAry[nStart].X()
+ << (short)rPoly.mpImplPolygon->mpPointAry[nStart].Y();
+ }
+ }
+ else
+ {
+ for( ; nStart < i; nStart++ )
+ {
+ rOStream << rPoly.mpImplPolygon->mpPointAry[nStart].X()
+ << rPoly.mpImplPolygon->mpPointAry[nStart].Y();
+ }
+ }
+ }
+ }
+ else
+ {
+ // Feststellen, ob ueber die Operatoren geschrieben werden muss
+#if (SAL_TYPES_SIZEOFLONG) != 4
+ if ( 1 )
+#else
+#ifdef OSL_BIGENDIAN
+ if ( rOStream.GetNumberFormatInt() != NUMBERFORMAT_INT_BIGENDIAN )
+#else
+ if ( rOStream.GetNumberFormatInt() != NUMBERFORMAT_INT_LITTLEENDIAN )
+#endif
+#endif
+ {
+ for( i = 0; i < nPoints; i++ )
+ {
+ rOStream << rPoly.mpImplPolygon->mpPointAry[i].X()
+ << rPoly.mpImplPolygon->mpPointAry[i].Y();
+ }
+ }
+ else
+ {
+ if ( nPoints )
+ rOStream.Write( rPoly.mpImplPolygon->mpPointAry, nPoints*sizeof(Point) );
+ }
+ }
+
+ return rOStream;
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::ImplRead( SvStream& rIStream )
+{
+ sal_uInt8 bHasPolyFlags;
+
+ rIStream >> *this
+ >> bHasPolyFlags;
+
+ if ( bHasPolyFlags )
+ {
+ mpImplPolygon->mpFlagAry = new sal_uInt8[ mpImplPolygon->mnPoints ];
+ rIStream.Read( mpImplPolygon->mpFlagAry, mpImplPolygon->mnPoints );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::Read( SvStream& rIStream )
+{
+ VersionCompat aCompat( rIStream, STREAM_READ );
+
+ ImplRead( rIStream );
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::ImplWrite( SvStream& rOStream ) const
+{
+ sal_uInt8 bHasPolyFlags = mpImplPolygon->mpFlagAry != NULL;
+ rOStream << *this
+ << bHasPolyFlags;
+
+ if ( bHasPolyFlags )
+ rOStream.Write( mpImplPolygon->mpFlagAry, mpImplPolygon->mnPoints );
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::Write( SvStream& rOStream ) const
+{
+ VersionCompat aCompat( rOStream, STREAM_WRITE, 1 );
+
+ ImplWrite( rOStream );
+}
+
+// -----------------------------------------------------------------------
+// #i74631# numerical correction method for B2DPolygon
+void impCorrectContinuity(basegfx::B2DPolygon& roPolygon, sal_uInt32 nIndex, BYTE nCFlag)
+{
+ const sal_uInt32 nPointCount(roPolygon.count());
+ OSL_ENSURE(nIndex < nPointCount, "impCorrectContinuity: index access out of range (!)");
+
+ if(nIndex < nPointCount && (POLY_SMOOTH == nCFlag || POLY_SYMMTR == nCFlag))
+ {
+ if(roPolygon.isPrevControlPointUsed(nIndex) && roPolygon.isNextControlPointUsed(nIndex))
+ {
+ const basegfx::B2DPoint aPoint(roPolygon.getB2DPoint(nIndex));
+
+ if(POLY_SMOOTH == nCFlag)
+ {
+ // C1: apply inverse direction of prev to next, keep length of next
+ const basegfx::B2DVector aOriginalNext(roPolygon.getNextControlPoint(nIndex) - aPoint);
+ basegfx::B2DVector aNewNext(aPoint - roPolygon.getPrevControlPoint(nIndex));
+
+ aNewNext.setLength(aOriginalNext.getLength());
+ roPolygon.setNextControlPoint(nIndex, basegfx::B2DPoint(aPoint + aNewNext));
+ }
+ else // POLY_SYMMTR
+ {
+ // C2: apply inverse control point to next
+ roPolygon.setNextControlPoint(nIndex, (2.0 * aPoint) - roPolygon.getPrevControlPoint(nIndex));
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+// convert to basegfx::B2DPolygon and return
+basegfx::B2DPolygon Polygon::getB2DPolygon() const
+{
+ basegfx::B2DPolygon aRetval;
+ const sal_uInt16 nCount(mpImplPolygon->mnPoints);
+
+ if(nCount)
+ {
+ if(mpImplPolygon->mpFlagAry)
+ {
+ // handling for curves. Add start point
+ const Point aStartPoint(mpImplPolygon->mpPointAry[0]);
+ BYTE nPointFlag(mpImplPolygon->mpFlagAry[0]);
+ aRetval.append(basegfx::B2DPoint(aStartPoint.X(), aStartPoint.Y()));
+ Point aControlA, aControlB;
+
+ for(sal_uInt16 a(1); a < nCount;)
+ {
+ bool bControlA(false);
+ bool bControlB(false);
+
+ if(POLY_CONTROL == mpImplPolygon->mpFlagAry[a])
+ {
+ aControlA = mpImplPolygon->mpPointAry[a++];
+ bControlA = true;
+ }
+
+ if(a < nCount && POLY_CONTROL == mpImplPolygon->mpFlagAry[a])
+ {
+ aControlB = mpImplPolygon->mpPointAry[a++];
+ bControlB = true;
+ }
+
+ // assert invalid polygons
+ OSL_ENSURE(bControlA == bControlB, "Polygon::getB2DPolygon: Invalid source polygon (!)");
+
+ if(a < nCount)
+ {
+ const Point aEndPoint(mpImplPolygon->mpPointAry[a]);
+
+ if(bControlA)
+ {
+ // bezier edge, add
+ aRetval.appendBezierSegment(
+ basegfx::B2DPoint(aControlA.X(), aControlA.Y()),
+ basegfx::B2DPoint(aControlB.X(), aControlB.Y()),
+ basegfx::B2DPoint(aEndPoint.X(), aEndPoint.Y()));
+
+ impCorrectContinuity(aRetval, aRetval.count() - 2, nPointFlag);
+ }
+ else
+ {
+ // no bezier edge, add end point
+ aRetval.append(basegfx::B2DPoint(aEndPoint.X(), aEndPoint.Y()));
+ }
+
+ nPointFlag = mpImplPolygon->mpFlagAry[a++];
+ }
+ }
+
+ // if exist, remove double first/last points, set closed and correct control points
+ basegfx::tools::checkClosed(aRetval);
+
+ if(aRetval.isClosed())
+ {
+ // closeWithGeometryChange did really close, so last point(s) were removed.
+ // Correct the continuity in the changed point
+ impCorrectContinuity(aRetval, 0, mpImplPolygon->mpFlagAry[0]);
+ }
+ }
+ else
+ {
+ // extra handling for non-curves (most-used case) for speedup
+ for(sal_uInt16 a(0); a < nCount; a++)
+ {
+ // get point and add
+ const Point aPoint(mpImplPolygon->mpPointAry[a]);
+ aRetval.append(basegfx::B2DPoint(aPoint.X(), aPoint.Y()));
+ }
+
+ // set closed flag
+ basegfx::tools::checkClosed(aRetval);
+ }
+ }
+
+ return aRetval;
+}
+
+// -----------------------------------------------------------------------
+// constructor to convert from basegfx::B2DPolygon
+// #i76891# Needed to change from adding all control points (even for unused
+// edges) and creating a fixed-size Polygon in the first run to creating the
+// minimal Polygon. This requires a temporary Point- and Flag-Array for curves
+// and a memcopy at ImplPolygon creation, but contains no zero-controlpoints
+// for straight edges.
+Polygon::Polygon(const basegfx::B2DPolygon& rPolygon)
+: mpImplPolygon(0)
+{
+ DBG_CTOR( Polygon, NULL );
+
+ const bool bCurve(rPolygon.areControlPointsUsed());
+ const bool bClosed(rPolygon.isClosed());
+ sal_uInt32 nB2DLocalCount(rPolygon.count());
+
+ if(bCurve)
+ {
+ // #127979# Reduce source point count hard to the limit of the tools Polygon
+ if(nB2DLocalCount > ((0x0000ffff / 3L) - 1L))
+ {
+ DBG_ERROR("Polygon::Polygon: Too many points in given B2DPolygon, need to reduce hard to maximum of tools Polygon (!)");
+ nB2DLocalCount = ((0x0000ffff / 3L) - 1L);
+ }
+
+ // calculate target point count
+ const sal_uInt32 nLoopCount(bClosed ? nB2DLocalCount : (nB2DLocalCount ? nB2DLocalCount - 1L : 0L ));
+
+ if(nLoopCount)
+ {
+ // calculate maximum array size and allocate; prepare insert index
+ const sal_uInt32 nMaxTargetCount((nLoopCount * 3) + 1);
+ mpImplPolygon = new ImplPolygon(static_cast< sal_uInt16 >(nMaxTargetCount), true);
+
+ // prepare insert index and current point
+ sal_uInt32 nArrayInsert(0);
+ basegfx::B2DCubicBezier aBezier;
+ aBezier.setStartPoint(rPolygon.getB2DPoint(0));
+
+ for(sal_uInt32 a(0L); a < nLoopCount; a++)
+ {
+ // add current point (always) and remember StartPointIndex for evtl. later corrections
+ const Point aStartPoint(FRound(aBezier.getStartPoint().getX()), FRound(aBezier.getStartPoint().getY()));
+ const sal_uInt32 nStartPointIndex(nArrayInsert);
+ mpImplPolygon->mpPointAry[nStartPointIndex] = aStartPoint;
+ mpImplPolygon->mpFlagAry[nStartPointIndex] = (BYTE)POLY_NORMAL;
+ nArrayInsert++;
+
+ // prepare next segment
+ const sal_uInt32 nNextIndex((a + 1) % nB2DLocalCount);
+ aBezier.setEndPoint(rPolygon.getB2DPoint(nNextIndex));
+ aBezier.setControlPointA(rPolygon.getNextControlPoint(a));
+ aBezier.setControlPointB(rPolygon.getPrevControlPoint(nNextIndex));
+
+ if(aBezier.isBezier())
+ {
+ // if one is used, add always two control points due to the old schema
+ mpImplPolygon->mpPointAry[nArrayInsert] = Point(FRound(aBezier.getControlPointA().getX()), FRound(aBezier.getControlPointA().getY()));
+ mpImplPolygon->mpFlagAry[nArrayInsert] = (BYTE)POLY_CONTROL;
+ nArrayInsert++;
+
+ mpImplPolygon->mpPointAry[nArrayInsert] = Point(FRound(aBezier.getControlPointB().getX()), FRound(aBezier.getControlPointB().getY()));
+ mpImplPolygon->mpFlagAry[nArrayInsert] = (BYTE)POLY_CONTROL;
+ nArrayInsert++;
+ }
+
+ // test continuity with previous control point to set flag value
+ if(aBezier.getControlPointA() != aBezier.getStartPoint() && (bClosed || a))
+ {
+ const basegfx::B2VectorContinuity eCont(rPolygon.getContinuityInPoint(a));
+
+ if(basegfx::CONTINUITY_C1 == eCont)
+ {
+ mpImplPolygon->mpFlagAry[nStartPointIndex] = (BYTE)POLY_SMOOTH;
+ }
+ else if(basegfx::CONTINUITY_C2 == eCont)
+ {
+ mpImplPolygon->mpFlagAry[nStartPointIndex] = (BYTE)POLY_SYMMTR;
+ }
+ }
+
+ // prepare next polygon step
+ aBezier.setStartPoint(aBezier.getEndPoint());
+ }
+
+ if(bClosed)
+ {
+ // add first point again as closing point due to old definition
+ mpImplPolygon->mpPointAry[nArrayInsert] = mpImplPolygon->mpPointAry[0];
+ mpImplPolygon->mpFlagAry[nArrayInsert] = (BYTE)POLY_NORMAL;
+ nArrayInsert++;
+ }
+ else
+ {
+ // add last point as closing point
+ const basegfx::B2DPoint aClosingPoint(rPolygon.getB2DPoint(nB2DLocalCount - 1L));
+ const Point aEnd(FRound(aClosingPoint.getX()), FRound(aClosingPoint.getY()));
+ mpImplPolygon->mpPointAry[nArrayInsert] = aEnd;
+ mpImplPolygon->mpFlagAry[nArrayInsert] = (BYTE)POLY_NORMAL;
+ nArrayInsert++;
+ }
+
+ DBG_ASSERT(nArrayInsert <= nMaxTargetCount, "Polygon::Polygon from basegfx::B2DPolygon: wrong max point count estimation (!)");
+
+ if(nArrayInsert != nMaxTargetCount)
+ {
+ mpImplPolygon->ImplSetSize(static_cast< sal_uInt16 >(nArrayInsert), true);
+ }
+ }
+ }
+ else
+ {
+ // #127979# Reduce source point count hard to the limit of the tools Polygon
+ if(nB2DLocalCount > (0x0000ffff - 1L))
+ {
+ DBG_ERROR("Polygon::Polygon: Too many points in given B2DPolygon, need to reduce hard to maximum of tools Polygon (!)");
+ nB2DLocalCount = (0x0000ffff - 1L);
+ }
+
+ if(nB2DLocalCount)
+ {
+ // point list creation
+ const sal_uInt32 nTargetCount(nB2DLocalCount + (bClosed ? 1L : 0L));
+ mpImplPolygon = new ImplPolygon( static_cast< sal_uInt16 >(nTargetCount) );
+ sal_uInt16 nIndex(0);
+
+ for(sal_uInt32 a(0L); a < nB2DLocalCount; a++)
+ {
+ basegfx::B2DPoint aB2DPoint(rPolygon.getB2DPoint(a));
+ Point aPoint(FRound(aB2DPoint.getX()), FRound(aB2DPoint.getY()));
+ mpImplPolygon->mpPointAry[nIndex++] = aPoint;
+ }
+
+ if(bClosed)
+ {
+ // add first point as closing point
+ mpImplPolygon->mpPointAry[nIndex] = mpImplPolygon->mpPointAry[0];
+ }
+ }
+ }
+
+ if(!mpImplPolygon)
+ {
+ // no content yet, create empty polygon
+ mpImplPolygon = (ImplPolygon*)(&aStaticImplPolygon);
+ }
+}
+
+// eof
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/generic/poly2.cxx b/tools/source/generic/poly2.cxx
new file mode 100644
index 000000000000..a6b270fd8eff
--- /dev/null
+++ b/tools/source/generic/poly2.cxx
@@ -0,0 +1,894 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#define _SV_POLY2_CXX
+
+#define POLY_CLIP_INT 0
+#define POLY_CLIP_UNION 1
+#define POLY_CLIP_DIFF 2
+#define POLY_CLIP_XOR 3
+
+#include <rtl/math.hxx>
+#include <poly.h>
+#include <tools/poly.hxx>
+#include <tools/debug.hxx>
+#include <tools/stream.hxx>
+#include <tools/vcompat.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
+
+// ---------------
+// - PolyPolygon -
+// ---------------
+
+DBG_NAME( PolyPolygon )
+
+// -----------------------------------------------------------------------
+
+ImplPolyPolygon::ImplPolyPolygon( USHORT nInitSize )
+{
+ mnRefCount = 1;
+ mnCount = nInitSize;
+ mnSize = nInitSize;
+ mnResize = 16;
+ mpPolyAry = new SVPPOLYGON[ nInitSize ];
+}
+
+// -----------------------------------------------------------------------
+
+ImplPolyPolygon::ImplPolyPolygon( const ImplPolyPolygon& rImplPolyPoly )
+{
+ mnRefCount = 1;
+ mnCount = rImplPolyPoly.mnCount;
+ mnSize = rImplPolyPoly.mnSize;
+ mnResize = rImplPolyPoly.mnResize;
+
+ if ( rImplPolyPoly.mpPolyAry )
+ {
+ mpPolyAry = new SVPPOLYGON[mnSize];
+ for ( USHORT i = 0; i < mnCount; i++ )
+ mpPolyAry[i] = new Polygon( *rImplPolyPoly.mpPolyAry[i] );
+ }
+ else
+ mpPolyAry = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ImplPolyPolygon::~ImplPolyPolygon()
+{
+ if ( mpPolyAry )
+ {
+ for ( USHORT i = 0; i < mnCount; i++ )
+ delete mpPolyAry[i];
+ delete[] mpPolyAry;
+ }
+}
+
+// =======================================================================
+
+PolyPolygon::PolyPolygon( USHORT nInitSize, USHORT nResize )
+{
+ DBG_CTOR( PolyPolygon, NULL );
+
+ if ( nInitSize > MAX_POLYGONS )
+ nInitSize = MAX_POLYGONS;
+ else if ( !nInitSize )
+ nInitSize = 1;
+ if ( nResize > MAX_POLYGONS )
+ nResize = MAX_POLYGONS;
+ else if ( !nResize )
+ nResize = 1;
+ mpImplPolyPolygon = new ImplPolyPolygon( nInitSize, nResize );
+}
+
+// -----------------------------------------------------------------------
+
+PolyPolygon::PolyPolygon( const Polygon& rPoly )
+{
+ DBG_CTOR( PolyPolygon, NULL );
+
+ if ( rPoly.GetSize() )
+ {
+ mpImplPolyPolygon = new ImplPolyPolygon( 1 );
+ mpImplPolyPolygon->mpPolyAry[0] = new Polygon( rPoly );
+ }
+ else
+ mpImplPolyPolygon = new ImplPolyPolygon( 16, 16 );
+}
+
+// -----------------------------------------------------------------------
+
+PolyPolygon::PolyPolygon( USHORT nPoly, const USHORT* pPointCountAry,
+ const Point* pPtAry )
+{
+ DBG_CTOR( PolyPolygon, NULL );
+
+ if ( nPoly > MAX_POLYGONS )
+ nPoly = MAX_POLYGONS;
+
+ mpImplPolyPolygon = new ImplPolyPolygon( nPoly );
+ for ( USHORT i = 0; i < nPoly; i++ )
+ {
+ mpImplPolyPolygon->mpPolyAry[i] = new Polygon( *pPointCountAry, pPtAry );
+ pPtAry += *pPointCountAry;
+ pPointCountAry++;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+PolyPolygon::PolyPolygon( const PolyPolygon& rPolyPoly )
+{
+ DBG_CTOR( PolyPolygon, NULL );
+ DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
+ DBG_ASSERT( rPolyPoly.mpImplPolyPolygon->mnRefCount < 0xFFFFFFFE, "PolyPolygon: RefCount overflow" );
+
+ mpImplPolyPolygon = rPolyPoly.mpImplPolyPolygon;
+ mpImplPolyPolygon->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+PolyPolygon::~PolyPolygon()
+{
+ DBG_DTOR( PolyPolygon, NULL );
+
+ if ( mpImplPolyPolygon->mnRefCount > 1 )
+ mpImplPolyPolygon->mnRefCount--;
+ else
+ delete mpImplPolyPolygon;
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::Insert( const Polygon& rPoly, USHORT nPos )
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+
+ if ( mpImplPolyPolygon->mnCount >= MAX_POLYGONS )
+ return;
+
+ if ( mpImplPolyPolygon->mnRefCount > 1 )
+ {
+ mpImplPolyPolygon->mnRefCount--;
+ mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
+ }
+
+ if ( nPos > mpImplPolyPolygon->mnCount )
+ nPos = mpImplPolyPolygon->mnCount;
+
+ if ( !mpImplPolyPolygon->mpPolyAry )
+ mpImplPolyPolygon->mpPolyAry = new SVPPOLYGON[mpImplPolyPolygon->mnSize];
+ else if ( mpImplPolyPolygon->mnCount == mpImplPolyPolygon->mnSize )
+ {
+ USHORT nOldSize = mpImplPolyPolygon->mnSize;
+ USHORT nNewSize = nOldSize + mpImplPolyPolygon->mnResize;
+ SVPPOLYGON* pNewAry;
+
+ if ( nNewSize >= MAX_POLYGONS )
+ nNewSize = MAX_POLYGONS;
+ pNewAry = new SVPPOLYGON[nNewSize];
+ memcpy( pNewAry, mpImplPolyPolygon->mpPolyAry, nPos*sizeof(SVPPOLYGON) );
+ memcpy( pNewAry+nPos+1, mpImplPolyPolygon->mpPolyAry+nPos,
+ (nOldSize-nPos)*sizeof(SVPPOLYGON) );
+ delete[] mpImplPolyPolygon->mpPolyAry;
+ mpImplPolyPolygon->mpPolyAry = pNewAry;
+ mpImplPolyPolygon->mnSize = nNewSize;
+ }
+ else if ( nPos < mpImplPolyPolygon->mnCount )
+ {
+ memmove( mpImplPolyPolygon->mpPolyAry+nPos+1,
+ mpImplPolyPolygon->mpPolyAry+nPos,
+ (mpImplPolyPolygon->mnCount-nPos)*sizeof(SVPPOLYGON) );
+ }
+
+ mpImplPolyPolygon->mpPolyAry[nPos] = new Polygon( rPoly );
+ mpImplPolyPolygon->mnCount++;
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::Remove( USHORT nPos )
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+ DBG_ASSERT( nPos < Count(), "PolyPolygon::Remove(): nPos >= nSize" );
+
+ if ( mpImplPolyPolygon->mnRefCount > 1 )
+ {
+ mpImplPolyPolygon->mnRefCount--;
+ mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
+ }
+
+ delete mpImplPolyPolygon->mpPolyAry[nPos];
+ mpImplPolyPolygon->mnCount--;
+ memmove( mpImplPolyPolygon->mpPolyAry+nPos,
+ mpImplPolyPolygon->mpPolyAry+nPos+1,
+ (mpImplPolyPolygon->mnCount-nPos)*sizeof(SVPPOLYGON) );
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::Replace( const Polygon& rPoly, USHORT nPos )
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+ DBG_ASSERT( nPos < Count(), "PolyPolygon::Replace(): nPos >= nSize" );
+
+ if ( mpImplPolyPolygon->mnRefCount > 1 )
+ {
+ mpImplPolyPolygon->mnRefCount--;
+ mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
+ }
+
+ delete mpImplPolyPolygon->mpPolyAry[nPos];
+ mpImplPolyPolygon->mpPolyAry[nPos] = new Polygon( rPoly );
+}
+
+// -----------------------------------------------------------------------
+
+const Polygon& PolyPolygon::GetObject( USHORT nPos ) const
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+ DBG_ASSERT( nPos < Count(), "PolyPolygon::GetObject(): nPos >= nSize" );
+
+ return *(mpImplPolyPolygon->mpPolyAry[nPos]);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL PolyPolygon::IsRect() const
+{
+ BOOL bIsRect = FALSE;
+ if ( Count() == 1 )
+ bIsRect = mpImplPolyPolygon->mpPolyAry[ 0 ]->IsRect();
+ return bIsRect;
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::Clear()
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+
+ if ( mpImplPolyPolygon->mnRefCount > 1 )
+ {
+ mpImplPolyPolygon->mnRefCount--;
+ mpImplPolyPolygon = new ImplPolyPolygon( mpImplPolyPolygon->mnResize,
+ mpImplPolyPolygon->mnResize );
+ }
+ else
+ {
+ if ( mpImplPolyPolygon->mpPolyAry )
+ {
+ for ( USHORT i = 0; i < mpImplPolyPolygon->mnCount; i++ )
+ delete mpImplPolyPolygon->mpPolyAry[i];
+ delete[] mpImplPolyPolygon->mpPolyAry;
+ mpImplPolyPolygon->mpPolyAry = NULL;
+ mpImplPolyPolygon->mnCount = 0;
+ mpImplPolyPolygon->mnSize = mpImplPolyPolygon->mnResize;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::Optimize( ULONG nOptimizeFlags, const PolyOptimizeData* pData )
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+
+ if( nOptimizeFlags )
+ {
+ double fArea;
+ const BOOL bEdges = ( nOptimizeFlags & POLY_OPTIMIZE_EDGES ) == POLY_OPTIMIZE_EDGES;
+ USHORT nPercent = 0;
+
+ if( bEdges )
+ {
+ const Rectangle aBound( GetBoundRect() );
+
+ fArea = ( aBound.GetWidth() + aBound.GetHeight() ) * 0.5;
+ nPercent = pData ? pData->GetPercentValue() : 50;
+ nOptimizeFlags &= ~POLY_OPTIMIZE_EDGES;
+ }
+
+ // watch for ref counter
+ if( mpImplPolyPolygon->mnRefCount > 1 )
+ {
+ mpImplPolyPolygon->mnRefCount--;
+ mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
+ }
+
+ // Optimize polygons
+ for( USHORT i = 0, nPolyCount = mpImplPolyPolygon->mnCount; i < nPolyCount; i++ )
+ {
+ if( bEdges )
+ {
+ mpImplPolyPolygon->mpPolyAry[ i ]->Optimize( POLY_OPTIMIZE_NO_SAME );
+ Polygon::ImplReduceEdges( *( mpImplPolyPolygon->mpPolyAry[ i ] ), fArea, nPercent );
+ }
+
+ if( nOptimizeFlags )
+ mpImplPolyPolygon->mpPolyAry[ i ]->Optimize( nOptimizeFlags, pData );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::AdaptiveSubdivide( PolyPolygon& rResult, const double d ) const
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+
+ rResult.Clear();
+
+ Polygon aPolygon;
+
+ for( USHORT i = 0; i < mpImplPolyPolygon->mnCount; i++ )
+ {
+ mpImplPolyPolygon->mpPolyAry[ i ]->AdaptiveSubdivide( aPolygon, d );
+ rResult.Insert( aPolygon );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::GetIntersection( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
+{
+ ImplDoOperation( rPolyPoly, rResult, POLY_CLIP_INT );
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::GetUnion( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
+{
+ ImplDoOperation( rPolyPoly, rResult, POLY_CLIP_UNION );
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::GetDifference( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
+{
+ ImplDoOperation( rPolyPoly, rResult, POLY_CLIP_DIFF );
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::GetXOR( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
+{
+ ImplDoOperation( rPolyPoly, rResult, POLY_CLIP_XOR );
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::ImplDoOperation( const PolyPolygon& rPolyPoly, PolyPolygon& rResult, ULONG nOperation ) const
+{
+ // Convert to B2DPolyPolygon, temporarily. It might be
+ // advantageous in the future, to have a PolyPolygon adaptor that
+ // just simulates a B2DPolyPolygon here...
+ basegfx::B2DPolyPolygon aMergePolyPolygonA( getB2DPolyPolygon() );
+ basegfx::B2DPolyPolygon aMergePolyPolygonB( rPolyPoly.getB2DPolyPolygon() );
+
+ // normalize the two polypolygons before. Force properly oriented
+ // polygons.
+ aMergePolyPolygonA = basegfx::tools::prepareForPolygonOperation( aMergePolyPolygonA );
+ aMergePolyPolygonB = basegfx::tools::prepareForPolygonOperation( aMergePolyPolygonB );
+
+ switch( nOperation )
+ {
+ // All code extracted from svx/source/svdraw/svedtv2.cxx
+ // -----------------------------------------------------
+
+ case POLY_CLIP_UNION:
+ {
+ // merge A and B (OR)
+ aMergePolyPolygonA = basegfx::tools::solvePolygonOperationOr(aMergePolyPolygonA, aMergePolyPolygonB);
+ break;
+ }
+
+ case POLY_CLIP_DIFF:
+ {
+ // substract B from A (DIFF)
+ aMergePolyPolygonA = basegfx::tools::solvePolygonOperationDiff(aMergePolyPolygonA, aMergePolyPolygonB);
+ break;
+ }
+
+ case POLY_CLIP_XOR:
+ {
+ // compute XOR between poly A and B
+ aMergePolyPolygonA = basegfx::tools::solvePolygonOperationXor(aMergePolyPolygonA, aMergePolyPolygonB);
+ break;
+ }
+
+ default:
+ case POLY_CLIP_INT:
+ {
+ // cut poly 1 against polys 2..n (AND)
+ aMergePolyPolygonA = basegfx::tools::solvePolygonOperationAnd(aMergePolyPolygonA, aMergePolyPolygonB);
+ break;
+ }
+ }
+
+ rResult = PolyPolygon( aMergePolyPolygonA );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT PolyPolygon::Count() const
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+ return mpImplPolyPolygon->mnCount;
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::Move( long nHorzMove, long nVertMove )
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+
+ // Diese Abfrage sollte man fuer die DrawEngine durchfuehren
+ if( nHorzMove || nVertMove )
+ {
+ // Referenzcounter beruecksichtigen
+ if ( mpImplPolyPolygon->mnRefCount > 1 )
+ {
+ mpImplPolyPolygon->mnRefCount--;
+ mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
+ }
+
+ // Punkte verschieben
+ USHORT nPolyCount = mpImplPolyPolygon->mnCount;
+ for ( USHORT i = 0; i < nPolyCount; i++ )
+ mpImplPolyPolygon->mpPolyAry[i]->Move( nHorzMove, nVertMove );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::Translate( const Point& rTrans )
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+
+ // Referenzcounter beruecksichtigen
+ if( mpImplPolyPolygon->mnRefCount > 1 )
+ {
+ mpImplPolyPolygon->mnRefCount--;
+ mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
+ }
+
+ // Punkte verschieben
+ for ( USHORT i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
+ mpImplPolyPolygon->mpPolyAry[ i ]->Translate( rTrans );
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::Scale( double fScaleX, double fScaleY )
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+
+ // Referenzcounter beruecksichtigen
+ if( mpImplPolyPolygon->mnRefCount > 1 )
+ {
+ mpImplPolyPolygon->mnRefCount--;
+ mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
+ }
+
+ // Punkte verschieben
+ for ( USHORT i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
+ mpImplPolyPolygon->mpPolyAry[ i ]->Scale( fScaleX, fScaleY );
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::Rotate( const Point& rCenter, USHORT nAngle10 )
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+ nAngle10 %= 3600;
+
+ if( nAngle10 )
+ {
+ const double fAngle = F_PI1800 * nAngle10;
+ Rotate( rCenter, sin( fAngle ), cos( fAngle ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::Rotate( const Point& rCenter, double fSin, double fCos )
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+
+ // Referenzcounter beruecksichtigen
+ if( mpImplPolyPolygon->mnRefCount > 1 )
+ {
+ mpImplPolyPolygon->mnRefCount--;
+ mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
+ }
+
+ // Punkte verschieben
+ for ( USHORT i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
+ mpImplPolyPolygon->mpPolyAry[ i ]->Rotate( rCenter, fSin, fCos );
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::SlantX( long nYRef, double fSin, double fCos )
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+
+ // Referenzcounter beruecksichtigen
+ if( mpImplPolyPolygon->mnRefCount > 1 )
+ {
+ mpImplPolyPolygon->mnRefCount--;
+ mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
+ }
+
+ // Punkte verschieben
+ for ( USHORT i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
+ mpImplPolyPolygon->mpPolyAry[ i ]->SlantX( nYRef, fSin, fCos );
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::SlantY( long nXRef, double fSin, double fCos )
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+
+ // Referenzcounter beruecksichtigen
+ if( mpImplPolyPolygon->mnRefCount > 1 )
+ {
+ mpImplPolyPolygon->mnRefCount--;
+ mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
+ }
+
+ // Punkte verschieben
+ for ( USHORT i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
+ mpImplPolyPolygon->mpPolyAry[ i ]->SlantY( nXRef, fSin, fCos );
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::Distort( const Rectangle& rRefRect, const Polygon& rDistortedRect )
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+
+ // Referenzcounter beruecksichtigen
+ if( mpImplPolyPolygon->mnRefCount > 1 )
+ {
+ mpImplPolyPolygon->mnRefCount--;
+ mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
+ }
+
+ // Punkte verschieben
+ for ( USHORT i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
+ mpImplPolyPolygon->mpPolyAry[ i ]->Distort( rRefRect, rDistortedRect );
+}
+
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::Clip( const Rectangle& rRect )
+{
+ // Polygon-Clippen
+ USHORT nPolyCount = mpImplPolyPolygon->mnCount;
+ USHORT i;
+
+ if ( !nPolyCount )
+ return;
+
+ // Referenzcounter beruecksichtigen
+ if ( mpImplPolyPolygon->mnRefCount > 1 )
+ {
+ mpImplPolyPolygon->mnRefCount--;
+ mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
+ }
+
+ // Erst jedes Polygon Clippen und dann die leeren entfernen
+ for ( i = 0; i < nPolyCount; i++ )
+ mpImplPolyPolygon->mpPolyAry[i]->Clip( rRect );
+ while ( nPolyCount )
+ {
+ if ( GetObject( nPolyCount-1 ).GetSize() <= 2 )
+ Remove( nPolyCount-1 );
+ nPolyCount--;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle PolyPolygon::GetBoundRect() const
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+
+ long nXMin=0, nXMax=0, nYMin=0, nYMax=0;
+ BOOL bFirst = TRUE;
+ USHORT nPolyCount = mpImplPolyPolygon->mnCount;
+
+ for ( USHORT n = 0; n < nPolyCount; n++ )
+ {
+ const Polygon* pPoly = mpImplPolyPolygon->mpPolyAry[n];
+ const Point* pAry = pPoly->GetConstPointAry();
+ USHORT nPointCount = pPoly->GetSize();
+
+ for ( USHORT i = 0; i < nPointCount; i++ )
+ {
+ const Point* pPt = &pAry[ i ];
+
+ if ( bFirst )
+ {
+ nXMin = nXMax = pPt->X();
+ nYMin = nYMax = pPt->Y();
+ bFirst = FALSE;
+ }
+ else
+ {
+ if ( pPt->X() < nXMin )
+ nXMin = pPt->X();
+ if ( pPt->X() > nXMax )
+ nXMax = pPt->X();
+ if ( pPt->Y() < nYMin )
+ nYMin = pPt->Y();
+ if ( pPt->Y() > nYMax )
+ nYMax = pPt->Y();
+ }
+ }
+ }
+
+ if ( !bFirst )
+ return Rectangle( nXMin, nYMin, nXMax, nYMax );
+ else
+ return Rectangle();
+}
+
+// -----------------------------------------------------------------------
+
+Polygon& PolyPolygon::operator[]( USHORT nPos )
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+ DBG_ASSERT( nPos < Count(), "PolyPolygon::[](): nPos >= nSize" );
+
+ if ( mpImplPolyPolygon->mnRefCount > 1 )
+ {
+ mpImplPolyPolygon->mnRefCount--;
+ mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
+ }
+
+ return *(mpImplPolyPolygon->mpPolyAry[nPos]);
+}
+
+// -----------------------------------------------------------------------
+
+PolyPolygon& PolyPolygon::operator=( const PolyPolygon& rPolyPoly )
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+ DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
+ DBG_ASSERT( rPolyPoly.mpImplPolyPolygon->mnRefCount < 0xFFFFFFFE, "PolyPolygon: RefCount overflow" );
+
+ rPolyPoly.mpImplPolyPolygon->mnRefCount++;
+
+ if ( mpImplPolyPolygon->mnRefCount > 1 )
+ mpImplPolyPolygon->mnRefCount--;
+ else
+ delete mpImplPolyPolygon;
+
+ mpImplPolyPolygon = rPolyPoly.mpImplPolyPolygon;
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL PolyPolygon::operator==( const PolyPolygon& rPolyPoly ) const
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+ DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
+
+ if ( rPolyPoly.mpImplPolyPolygon == mpImplPolyPolygon )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool PolyPolygon::IsEqual( const PolyPolygon& rPolyPoly ) const
+{
+ sal_Bool bIsEqual = sal_True;
+ if ( Count() != rPolyPoly.Count() )
+ bIsEqual = sal_False;
+ else
+ {
+ sal_uInt16 i;
+ for ( i = 0; i < Count(); i++ )
+ {
+ if (!GetObject( i ).IsEqual( rPolyPoly.GetObject( i ) ) )
+ {
+ bIsEqual = sal_False;
+ break;
+ }
+ }
+ }
+ return bIsEqual;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, PolyPolygon& rPolyPoly )
+{
+ DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
+ DBG_ASSERTWARNING( rIStream.GetVersion(), "PolyPolygon::>> - Solar-Version not set on rIStream" );
+
+ Polygon* pPoly;
+ USHORT nPolyCount;
+
+ // Anzahl der Polygone einlesen
+ rIStream >> nPolyCount;
+
+ // Daten anlegen
+ if( nPolyCount )
+ {
+ // Referenzcounter beruecksichtigen
+ if ( rPolyPoly.mpImplPolyPolygon->mnRefCount > 1 )
+ rPolyPoly.mpImplPolyPolygon->mnRefCount--;
+ else
+ delete rPolyPoly.mpImplPolyPolygon;
+
+ rPolyPoly.mpImplPolyPolygon = new ImplPolyPolygon( nPolyCount );
+
+ for ( USHORT i = 0; i < nPolyCount; i++ )
+ {
+ pPoly = new Polygon;
+ rIStream >> *pPoly;
+ rPolyPoly.mpImplPolyPolygon->mpPolyAry[i] = pPoly;
+ }
+ }
+ else
+ rPolyPoly = PolyPolygon();
+
+ return rIStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const PolyPolygon& rPolyPoly )
+{
+ DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
+ DBG_ASSERTWARNING( rOStream.GetVersion(), "PolyPolygon::<< - Solar-Version not set on rOStream" );
+
+ // Anzahl der Polygone rausschreiben
+ USHORT nPolyCount = rPolyPoly.mpImplPolyPolygon->mnCount;
+ rOStream << nPolyCount;
+
+ // Die einzelnen Polygone ausgeben
+ for ( USHORT i = 0; i < nPolyCount; i++ )
+ rOStream << *(rPolyPoly.mpImplPolyPolygon->mpPolyAry[i]);
+
+ return rOStream;
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::Read( SvStream& rIStream )
+{
+ VersionCompat aCompat( rIStream, STREAM_READ );
+
+ DBG_CHKTHIS( PolyPolygon, NULL );
+ DBG_ASSERTWARNING( rIStream.GetVersion(), "PolyPolygon::>> - Solar-Version not set on rIStream" );
+
+ Polygon* pPoly;
+ USHORT nPolyCount;
+
+ // Anzahl der Polygone einlesen
+ rIStream >> nPolyCount;
+
+ // Daten anlegen
+ if( nPolyCount )
+ {
+ // Referenzcounter beruecksichtigen
+ if ( mpImplPolyPolygon->mnRefCount > 1 )
+ mpImplPolyPolygon->mnRefCount--;
+ else
+ delete mpImplPolyPolygon;
+
+ mpImplPolyPolygon = new ImplPolyPolygon( nPolyCount );
+
+ for ( USHORT i = 0; i < nPolyCount; i++ )
+ {
+ pPoly = new Polygon;
+ pPoly->ImplRead( rIStream );
+ mpImplPolyPolygon->mpPolyAry[i] = pPoly;
+ }
+ }
+ else
+ *this = PolyPolygon();
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::Write( SvStream& rOStream ) const
+{
+ VersionCompat aCompat( rOStream, STREAM_WRITE, 1 );
+
+ DBG_CHKTHIS( PolyPolygon, NULL );
+ DBG_ASSERTWARNING( rOStream.GetVersion(), "PolyPolygon::<< - Solar-Version not set on rOStream" );
+
+ // Anzahl der Polygone rausschreiben
+ USHORT nPolyCount = mpImplPolyPolygon->mnCount;
+ rOStream << nPolyCount;
+
+ // Die einzelnen Polygone ausgeben
+ for ( USHORT i = 0; i < nPolyCount; i++ )
+ mpImplPolyPolygon->mpPolyAry[i]->ImplWrite( rOStream );;
+}
+
+// -----------------------------------------------------------------------
+// convert to basegfx::B2DPolyPolygon and return
+basegfx::B2DPolyPolygon PolyPolygon::getB2DPolyPolygon() const
+{
+ basegfx::B2DPolyPolygon aRetval;
+
+ for(sal_uInt16 a(0); a < mpImplPolyPolygon->mnCount; a++)
+ {
+ Polygon* pCandidate = mpImplPolyPolygon->mpPolyAry[a];
+ aRetval.append(pCandidate->getB2DPolygon());
+ }
+
+ return aRetval;
+}
+
+// -----------------------------------------------------------------------
+// constructor to convert from basegfx::B2DPolyPolygon
+PolyPolygon::PolyPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon)
+{
+ DBG_CTOR( PolyPolygon, NULL );
+ const sal_uInt16 nCount(sal_uInt16(rPolyPolygon.count()));
+ DBG_ASSERT(sal_uInt32(nCount) == rPolyPolygon.count(),
+ "PolyPolygon::PolyPolygon: Too many sub-polygons in given basegfx::B2DPolyPolygon (!)");
+
+ if ( nCount )
+ {
+ mpImplPolyPolygon = new ImplPolyPolygon( nCount );
+
+ for(sal_uInt16 a(0); a < nCount; a++)
+ {
+ basegfx::B2DPolygon aCandidate(rPolyPolygon.getB2DPolygon(sal_uInt32(a)));
+ mpImplPolyPolygon->mpPolyAry[a] = new Polygon( aCandidate );
+ }
+ }
+ else
+ {
+ mpImplPolyPolygon = new ImplPolyPolygon( 16, 16 );
+ }
+}
+
+// eof
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/generic/svborder.cxx b/tools/source/generic/svborder.cxx
new file mode 100644
index 000000000000..8410c7f304cd
--- /dev/null
+++ b/tools/source/generic/svborder.cxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <tools/svborder.hxx>
+#include <osl/diagnose.h>
+
+SvBorder::SvBorder( const Rectangle & rOuter, const Rectangle & rInner )
+{
+ Rectangle aOuter( rOuter );
+ aOuter.Justify();
+ Rectangle aInner( rInner );
+ if( aInner.IsEmpty() )
+ aInner = Rectangle( aOuter.Center(), aOuter.Center() );
+ else
+ aInner.Justify();
+
+ OSL_ENSURE( aOuter.IsInside( aInner ),
+ "SvBorder::SvBorder: FALSE == aOuter.IsInside( aInner )" );
+ nTop = aInner.Top() - aOuter.Top();
+ nRight = aOuter.Right() - aInner.Right();
+ nBottom = aOuter.Bottom() - aInner.Bottom();
+ nLeft = aInner.Left() - aOuter.Left();
+}
+
+Rectangle & operator += ( Rectangle & rRect, const SvBorder & rBorder )
+{
+ // wegen Empty-Rect, GetSize muss als erstes gerufen werden
+ Size aS( rRect.GetSize() );
+ aS.Width() += rBorder.Left() + rBorder.Right();
+ aS.Height() += rBorder.Top() + rBorder.Bottom();
+
+ rRect.Left() -= rBorder.Left();
+ rRect.Top() -= rBorder.Top();
+ rRect.SetSize( aS );
+ return rRect;
+}
+
+Rectangle & operator -= ( Rectangle & rRect, const SvBorder & rBorder )
+{
+ // wegen Empty-Rect, GetSize muss als erstes gerufen werden
+ Size aS( rRect.GetSize() );
+ aS.Width() -= rBorder.Left() + rBorder.Right();
+ aS.Height() -= rBorder.Top() + rBorder.Bottom();
+
+ rRect.Left() += rBorder.Left();
+ rRect.Top() += rBorder.Top();
+ rRect.SetSize( aS );
+ return rRect;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/generic/svlibrary.cxx b/tools/source/generic/svlibrary.cxx
new file mode 100644
index 000000000000..be6772ffbcfa
--- /dev/null
+++ b/tools/source/generic/svlibrary.cxx
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <tools/svlibrary.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/util/XMacroExpander.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <comphelper/processfactory.hxx>
+#include <tools/string.hxx>
+#include <rtl/uri.hxx>
+
+using namespace com::sun::star;
+
+static uno::Sequence< rtl::OUString > GetMultiPaths_Impl()
+{
+ uno::Sequence< rtl::OUString > aRes;
+ uno::Sequence< rtl::OUString > aInternalPaths;
+ uno::Sequence< rtl::OUString > aUserPaths;
+
+ bool bSuccess = true;
+ uno::Reference< lang::XMultiServiceFactory > xMgr( comphelper::getProcessServiceFactory() );
+ if (xMgr.is())
+ {
+ try
+ {
+ String aInternal;
+ aInternal.AppendAscii("Libraries");
+ String aUser;
+ aUser.AppendAscii("Libraries");
+ aInternal .AppendAscii( "_internal" );
+ aUser .AppendAscii( "_user" );
+
+ uno::Reference< beans::XPropertySet > xPathSettings( xMgr->createInstance(
+ rtl::OUString::createFromAscii( "com.sun.star.util.PathSettings" ) ), uno::UNO_QUERY_THROW );
+ xPathSettings->getPropertyValue( aInternal ) >>= aInternalPaths;
+ xPathSettings->getPropertyValue( aUser ) >>= aUserPaths;
+ }
+ catch (uno::Exception &)
+ {
+ bSuccess = false;
+ }
+ }
+ if (bSuccess)
+ {
+ sal_Int32 nMaxEntries = aInternalPaths.getLength() + aUserPaths.getLength();
+ aRes.realloc( nMaxEntries );
+ rtl::OUString *pRes = aRes.getArray();
+ sal_Int32 nCount = 0; // number of actually added entries
+ for (int i = 0; i < 2; ++i)
+ {
+ const uno::Sequence< rtl::OUString > &rPathSeq = i == 0 ? aUserPaths : aInternalPaths;
+ const rtl::OUString *pPathSeq = rPathSeq.getConstArray();
+ for (sal_Int32 k = 0; k < rPathSeq.getLength(); ++k)
+ {
+ const bool bAddUser = (&rPathSeq == &aUserPaths);
+ const bool bAddInternal = (&rPathSeq == &aInternalPaths);
+ if ((bAddUser || bAddInternal) && pPathSeq[k].getLength() > 0)
+ pRes[ nCount++ ] = pPathSeq[k];
+ }
+ }
+ aRes.realloc( nCount );
+ }
+
+ return aRes;
+}
+
+bool SvLibrary::LoadModule( osl::Module& rModule, const rtl::OUString& rLibName, ::oslGenericFunction baseModule, ::sal_Int32 mode )
+{
+ static uno::Sequence < rtl::OUString > aPaths = GetMultiPaths_Impl();
+ bool bLoaded = false;
+
+ for (sal_Int32 n=0; n<aPaths.getLength(); n++)
+ {
+ rtl::OUString aMod = aPaths[n];
+ if ( aPaths[n].indexOfAsciiL("vnd.sun.star.expand",19) == 0)
+ {
+ uno::Reference< uno::XComponentContext > xComponentContext = comphelper::getProcessComponentContext();
+ uno::Reference< util::XMacroExpander > xMacroExpander;
+ xComponentContext->getValueByName(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.util.theMacroExpander") ) )
+ >>= xMacroExpander;
+
+ aMod = aMod.copy( sizeof("vnd.sun.star.expand:") -1 );
+ aMod = ::rtl::Uri::decode( aMod, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ aMod = xMacroExpander->expandMacros( aMod );
+ }
+
+ aMod += ::rtl::OUString( sal_Unicode('/') );
+ aMod += rLibName;
+ bLoaded = rModule.load( aMod, mode );
+ if ( bLoaded )
+ break;
+ }
+
+ if (!bLoaded )
+ bLoaded = rModule.loadRelative( baseModule, rLibName, mode );
+
+ return bLoaded;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/generic/toolsin.cxx b/tools/source/generic/toolsin.cxx
new file mode 100644
index 000000000000..39e611319e68
--- /dev/null
+++ b/tools/source/generic/toolsin.cxx
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#define _TOOLS_TOOLSIN_CXX
+
+#include <string.h>
+#include <tools/shl.hxx>
+#include <tools/debug.hxx>
+#include <toolsin.hxx>
+
+#if defined WNT || defined OS2
+#include <dll.hxx>
+#endif
+
+void ImplDeleteCharTabData();
+
+// =======================================================================
+
+TOOLSINDATA* ImplGetToolsInData()
+{
+ TOOLSINDATA** ppData = (TOOLSINDATA**)GetAppData( SHL_TOOLS );
+ if ( !(*ppData) )
+ {
+ TOOLSINDATA* pData = new TOOLSINDATA;
+ memset( pData, 0, sizeof( TOOLSINDATA ) );
+ *ppData = pData;
+ }
+
+ return *ppData;
+}
+
+// =======================================================================
+
+void InitTools()
+{
+ DBG_DEBUGSTART();
+}
+
+// -----------------------------------------------------------------------
+
+void DeInitTools()
+{
+ TOOLSINDATA** ppData = (TOOLSINDATA**)GetAppData( SHL_TOOLS );
+ TOOLSINDATA* pData = *ppData;
+
+ if ( pData )
+ {
+ ImplDeleteCharTabData();
+ delete pData;
+ *ppData = NULL;
+ }
+
+ DBG_DEBUGEND();
+}
+
+// -----------------------------------------------------------------------
+
+void GlobalDeInitTools()
+{
+ DBG_GLOBALDEBUGEND();
+
+#if defined WNT
+ ImpDeInitWinTools();
+#endif
+#ifdef OS2
+ ImpDeInitOS2Tools();
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/inet/inetmime.cxx b/tools/source/inet/inetmime.cxx
new file mode 100644
index 000000000000..6490abef10d9
--- /dev/null
+++ b/tools/source/inet/inetmime.cxx
@@ -0,0 +1,4565 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <cstddef>
+#include <limits>
+
+#include "rtl/tencinfo.h"
+#include <tools/datetime.hxx>
+#include <tools/inetmime.hxx>
+
+namespace unnamed_tools_inetmime {} using namespace unnamed_tools_inetmime;
+ // unnamed namespaces don't work well yet
+
+//============================================================================
+namespace unnamed_tools_inetmime {
+
+class Charset
+{
+ rtl_TextEncoding m_eEncoding;
+ const sal_uInt32 * m_pRanges;
+
+public:
+ inline Charset(rtl_TextEncoding eTheEncoding,
+ const sal_uInt32 * pTheRanges);
+
+ rtl_TextEncoding getEncoding() const { return m_eEncoding; }
+
+ bool contains(sal_uInt32 nChar) const;
+};
+
+inline Charset::Charset(rtl_TextEncoding eTheEncoding,
+ const sal_uInt32 * pTheRanges):
+ m_eEncoding(eTheEncoding),
+ m_pRanges(pTheRanges)
+{
+ DBG_ASSERT(m_pRanges, "Charset::Charset(): Bad ranges");
+}
+
+//============================================================================
+void appendISO88591(UniString & rText, sal_Char const * pBegin,
+ sal_Char const * pEnd);
+
+}
+
+//============================================================================
+class INetMIMECharsetList_Impl
+{
+ struct Node
+ {
+ Charset m_aCharset;
+ bool m_bDisabled;
+ Node * m_pNext;
+
+ inline Node(const Charset & rTheCharset, bool bTheDisabled,
+ Node * pTheNext);
+ };
+
+ Node * m_pFirst;
+
+public:
+ INetMIMECharsetList_Impl(): m_pFirst(0) {}
+
+ ~INetMIMECharsetList_Impl();
+
+ void prepend(const Charset & rCharset)
+ { m_pFirst = new Node(rCharset, false, m_pFirst); }
+
+ void includes(sal_uInt32 nChar);
+
+ rtl_TextEncoding getPreferredEncoding(rtl_TextEncoding eDefault
+ = RTL_TEXTENCODING_DONTKNOW)
+ const;
+
+ void reset();
+};
+
+inline INetMIMECharsetList_Impl::Node::Node(const Charset & rTheCharset,
+ bool bTheDisabled,
+ Node * pTheNext):
+ m_aCharset(rTheCharset),
+ m_bDisabled(bTheDisabled),
+ m_pNext(pTheNext)
+{}
+
+//============================================================================
+namespace unnamed_tools_inetmime {
+
+struct Parameter
+{
+ Parameter * m_pNext;
+ ByteString m_aAttribute;
+ ByteString m_aCharset;
+ ByteString m_aLanguage;
+ ByteString m_aValue;
+ sal_uInt32 m_nSection;
+ bool m_bExtended;
+
+ inline Parameter(Parameter * pTheNext, ByteString const & rTheAttribute,
+ ByteString const & rTheCharset,
+ ByteString const & rTheLanguage,
+ ByteString const & rTheValue, sal_uInt32 nTheSection,
+ bool bTheExtended);
+};
+
+inline Parameter::Parameter(Parameter * pTheNext,
+ ByteString const & rTheAttribute,
+ ByteString const & rTheCharset,
+ ByteString const & rTheLanguage,
+ ByteString const & rTheValue,
+ sal_uInt32 nTheSection, bool bTheExtended):
+ m_pNext(pTheNext),
+ m_aAttribute(rTheAttribute),
+ m_aCharset(rTheCharset),
+ m_aLanguage(rTheLanguage),
+ m_aValue(rTheValue),
+ m_nSection(nTheSection),
+ m_bExtended(bTheExtended)
+{}
+
+//============================================================================
+struct ParameterList
+{
+ Parameter * m_pList;
+
+ ParameterList(): m_pList(0) {}
+
+ inline ~ParameterList();
+
+ Parameter ** find(ByteString const & rAttribute, sal_uInt32 nSection,
+ bool & rPresent);
+};
+
+inline ParameterList::~ParameterList()
+{
+ while (m_pList)
+ {
+ Parameter * pNext = m_pList->m_pNext;
+ delete m_pList;
+ m_pList = pNext;
+ }
+}
+
+//============================================================================
+bool parseParameters(ParameterList const & rInput,
+ INetContentTypeParameterList * pOutput);
+
+}
+
+//============================================================================
+//
+// Charset
+//
+//============================================================================
+
+bool Charset::contains(sal_uInt32 nChar) const
+{
+ for (const sal_uInt32 * p = m_pRanges;;)
+ {
+ if (nChar < *p++)
+ return false;
+ if (nChar <= *p++)
+ return true;
+ }
+}
+
+//============================================================================
+//
+// appendISO88591
+//
+//============================================================================
+
+namespace unnamed_tools_inetmime {
+
+void appendISO88591(UniString & rText, sal_Char const * pBegin,
+ sal_Char const * pEnd)
+{
+ xub_StrLen nLength = static_cast< xub_StrLen >(pEnd - pBegin);
+ sal_Unicode * pBuffer = new sal_Unicode[nLength];
+ for (sal_Unicode * p = pBuffer; pBegin != pEnd;)
+ *p++ = sal_uChar(*pBegin++);
+ rText.Append(pBuffer, nLength);
+ delete[] pBuffer;
+}
+
+}
+
+//============================================================================
+//
+// INetMIMECharsetList_Impl
+//
+//============================================================================
+
+INetMIMECharsetList_Impl::~INetMIMECharsetList_Impl()
+{
+ while (m_pFirst)
+ {
+ Node * pRemove = m_pFirst;
+ m_pFirst = m_pFirst->m_pNext;
+ delete pRemove;
+ }
+}
+
+//============================================================================
+void INetMIMECharsetList_Impl::includes(sal_uInt32 nChar)
+{
+ for (Node * p = m_pFirst; p; p = p->m_pNext)
+ if (!(p->m_bDisabled || p->m_aCharset.contains(nChar)))
+ p->m_bDisabled = true;
+}
+
+//============================================================================
+rtl_TextEncoding
+INetMIMECharsetList_Impl::getPreferredEncoding(rtl_TextEncoding eDefault)
+ const
+{
+ for (Node * p = m_pFirst; p; p = p->m_pNext)
+ if (!p->m_bDisabled)
+ return p->m_aCharset.getEncoding();
+ return eDefault;
+}
+
+//============================================================================
+void INetMIMECharsetList_Impl::reset()
+{
+ for (Node * p = m_pFirst; p; p = p->m_pNext)
+ p->m_bDisabled = false;
+}
+
+//============================================================================
+//
+// ParameterList
+//
+//============================================================================
+
+Parameter ** ParameterList::find(ByteString const & rAttribute,
+ sal_uInt32 nSection, bool & rPresent)
+{
+ Parameter ** p = &m_pList;
+ for (; *p; p = &(*p)->m_pNext)
+ {
+ StringCompare eCompare = rAttribute.CompareTo((*p)->m_aAttribute);
+ if (eCompare == COMPARE_GREATER)
+ break;
+ else if (eCompare == COMPARE_EQUAL)
+ {
+ if (nSection > (*p)->m_nSection)
+ break;
+ else if (nSection == (*p)->m_nSection)
+ {
+ rPresent = true;
+ return p;
+ }
+ }
+ }
+ rPresent = false;
+ return p;
+}
+
+//============================================================================
+//
+// parseParameters
+//
+//============================================================================
+
+namespace unnamed_tools_inetmime {
+
+bool parseParameters(ParameterList const & rInput,
+ INetContentTypeParameterList * pOutput)
+{
+ if (pOutput)
+ pOutput->Clear();
+
+ Parameter * pPrev = 0;
+ for (Parameter * p = rInput.m_pList; p; p = p->m_pNext)
+ {
+ if (p->m_nSection > 0
+ && (!pPrev
+ || pPrev->m_nSection != p->m_nSection - 1
+ || pPrev->m_aAttribute != p->m_aAttribute))
+ return false;
+ pPrev = p;
+ }
+
+ if (pOutput)
+ for (Parameter * p = rInput.m_pList; p;)
+ {
+ bool bCharset = p->m_aCharset.Len() != 0;
+ rtl_TextEncoding eEncoding = RTL_TEXTENCODING_DONTKNOW;
+ if (bCharset)
+ eEncoding
+ = INetMIME::getCharsetEncoding(p->m_aCharset.GetBuffer(),
+ p->m_aCharset.GetBuffer()
+ + rInput.m_pList->
+ m_aCharset.
+ Len());
+ UniString aValue;
+ bool bBadEncoding = false;
+ Parameter * pNext = p;
+ do
+ {
+ sal_Size nSize;
+ sal_Unicode * pUnicode
+ = INetMIME::convertToUnicode(pNext->m_aValue.GetBuffer(),
+ pNext->m_aValue.GetBuffer()
+ + pNext->m_aValue.Len(),
+ bCharset && p->m_bExtended ?
+ eEncoding :
+ RTL_TEXTENCODING_UTF8,
+ nSize);
+ if (!pUnicode && !(bCharset && p->m_bExtended))
+ pUnicode = INetMIME::convertToUnicode(
+ pNext->m_aValue.GetBuffer(),
+ pNext->m_aValue.GetBuffer()
+ + pNext->m_aValue.Len(),
+ RTL_TEXTENCODING_ISO_8859_1, nSize);
+ if (!pUnicode)
+ {
+ bBadEncoding = true;
+ break;
+ }
+ aValue += UniString(pUnicode, static_cast< xub_StrLen >(nSize));
+ delete[] pUnicode;
+ pNext = pNext->m_pNext;
+ }
+ while (pNext && pNext->m_nSection > 0);
+ if (bBadEncoding)
+ {
+ aValue.Erase();
+ for (pNext = p;;)
+ {
+ if (pNext->m_bExtended)
+ for (xub_StrLen i = 0; i < pNext->m_aValue.Len(); ++i)
+ aValue += sal_Unicode(
+ sal_Unicode(
+ sal_uChar(pNext->m_aValue.GetChar(i)))
+ | 0xF800);
+ else
+ for (xub_StrLen i = 0; i < pNext->m_aValue.Len(); ++i)
+ aValue
+ += sal_Unicode(sal_uChar
+ (pNext->
+ m_aValue.GetChar(i)));
+ pNext = pNext->m_pNext;
+ if (!pNext || pNext->m_nSection == 0)
+ break;
+ };
+ }
+ pOutput->Insert(new INetContentTypeParameter(p->m_aAttribute,
+ p->m_aCharset,
+ p->m_aLanguage,
+ aValue,
+ !bBadEncoding),
+ LIST_APPEND);
+ p = pNext;
+ }
+ return true;
+}
+
+}
+
+//============================================================================
+//
+// INetMIME
+//
+//============================================================================
+
+// static
+bool INetMIME::isAtomChar(sal_uInt32 nChar)
+{
+ static const bool aMap[128]
+ = { false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, true, false, true, true, true, true, true, // !"#$%&'
+ false, false, true, true, false, true, false, true, //()*+,-./
+ true, true, true, true, true, true, true, true, //01234567
+ true, true, false, false, false, true, false, true, //89:;<=>?
+ false, true, true, true, true, true, true, true, //@ABCDEFG
+ true, true, true, true, true, true, true, true, //HIJKLMNO
+ true, true, true, true, true, true, true, true, //PQRSTUVW
+ true, true, true, false, false, false, true, true, //XYZ[\]^_
+ true, true, true, true, true, true, true, true, //`abcdefg
+ true, true, true, true, true, true, true, true, //hijklmno
+ true, true, true, true, true, true, true, true, //pqrstuvw
+ true, true, true, true, true, true, true, false //xyz{|}~
+ };
+ return isUSASCII(nChar) && aMap[nChar];
+}
+
+//============================================================================
+// static
+bool INetMIME::isTokenChar(sal_uInt32 nChar)
+{
+ static const sal_Char aMap[128]
+ = { false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, true, false, true, true, true, true, true, // !"#$%&'
+ false, false, true, true, false, true, true, false, //()*+,-./
+ true, true, true, true, true, true, true, true, //01234567
+ true, true, false, false, false, false, false, false, //89:;<=>?
+ false, true, true, true, true, true, true, true, //@ABCDEFG
+ true, true, true, true, true, true, true, true, //HIJKLMNO
+ true, true, true, true, true, true, true, true, //PQRSTUVW
+ true, true, true, false, false, false, true, true, //XYZ[\]^_
+ true, true, true, true, true, true, true, true, //`abcdefg
+ true, true, true, true, true, true, true, true, //hijklmno
+ true, true, true, true, true, true, true, true, //pqrstuvw
+ true, true, true, true, true, true, true, false //xyz{|}~
+ };
+ return isUSASCII(nChar) && aMap[nChar];
+}
+
+//============================================================================
+// static
+bool INetMIME::isEncodedWordTokenChar(sal_uInt32 nChar)
+{
+ static const sal_Char aMap[128]
+ = { false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, true, false, true, true, true, true, true, // !"#$%&'
+ false, false, true, true, false, true, false, false, //()*+,-./
+ true, true, true, true, true, true, true, true, //01234567
+ true, true, false, false, false, false, false, false, //89:;<=>?
+ false, true, true, true, true, true, true, true, //@ABCDEFG
+ true, true, true, true, true, true, true, true, //HIJKLMNO
+ true, true, true, true, true, true, true, true, //PQRSTUVW
+ true, true, true, false, false, false, true, true, //XYZ[\]^_
+ true, true, true, true, true, true, true, true, //`abcdefg
+ true, true, true, true, true, true, true, true, //hijklmno
+ true, true, true, true, true, true, true, true, //pqrstuvw
+ true, true, true, true, true, true, true, false //xyz{|}~
+ };
+ return isUSASCII(nChar) && aMap[nChar];
+}
+
+//============================================================================
+// static
+bool INetMIME::isIMAPAtomChar(sal_uInt32 nChar)
+{
+ static const sal_Char aMap[128]
+ = { false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, true, false, true, true, false, true, true, // !"#$%&'
+ false, false, false, true, true, true, true, true, //()*+,-./
+ true, true, true, true, true, true, true, true, //01234567
+ true, true, true, true, true, true, true, true, //89:;<=>?
+ true, true, true, true, true, true, true, true, //@ABCDEFG
+ true, true, true, true, true, true, true, true, //HIJKLMNO
+ true, true, true, true, true, true, true, true, //PQRSTUVW
+ true, true, true, true, false, true, true, true, //XYZ[\]^_
+ true, true, true, true, true, true, true, true, //`abcdefg
+ true, true, true, true, true, true, true, true, //hijklmno
+ true, true, true, true, true, true, true, true, //pqrstuvw
+ true, true, true, false, true, true, true, false //xyz{|}~
+ };
+ return isUSASCII(nChar) && aMap[nChar];
+}
+
+//============================================================================
+// static
+sal_uInt32 INetMIME::getDigit(int nWeight)
+{
+ DBG_ASSERT(nWeight >= 0 && nWeight < 10,
+ "INetMIME::getDigit(): Bad weight");
+
+ static const sal_Char aDigits[16]
+ = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
+ return aDigits[nWeight];
+}
+
+//============================================================================
+// static
+sal_uInt32 INetMIME::getHexDigit(int nWeight)
+{
+ DBG_ASSERT(nWeight >= 0 && nWeight < 16,
+ "INetMIME::getHexDigit(): Bad weight");
+
+ static const sal_Char aDigits[16]
+ = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
+ 'D', 'E', 'F' };
+ return aDigits[nWeight];
+}
+
+//============================================================================
+// static
+sal_uInt32 INetMIME::getBase64Digit(int nWeight)
+{
+ DBG_ASSERT(nWeight >= 0 && nWeight < 64,
+ "INetMIME::getBase64Digit(): Bad weight");
+
+ static const sal_Char aDigits[64]
+ = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };
+ return aDigits[nWeight];
+}
+
+//============================================================================
+// static
+bool INetMIME::equalIgnoreCase(const sal_Char * pBegin1,
+ const sal_Char * pEnd1,
+ const sal_Char * pBegin2,
+ const sal_Char * pEnd2)
+{
+ DBG_ASSERT(pBegin1 && pBegin1 <= pEnd1 && pBegin2 && pBegin2 <= pEnd2,
+ "INetMIME::equalIgnoreCase(): Bad sequences");
+
+ if (pEnd1 - pBegin1 != pEnd2 - pBegin2)
+ return false;
+ while (pBegin1 != pEnd1)
+ if (toUpperCase(*pBegin1++) != toUpperCase(*pBegin2++))
+ return false;
+ return true;
+}
+
+//============================================================================
+// static
+bool INetMIME::equalIgnoreCase(const sal_Char * pBegin1,
+ const sal_Char * pEnd1,
+ const sal_Char * pString2)
+{
+ DBG_ASSERT(pBegin1 && pBegin1 <= pEnd1 && pString2,
+ "INetMIME::equalIgnoreCase(): Bad sequences");
+
+ while (*pString2 != 0)
+ if (pBegin1 == pEnd1
+ || toUpperCase(*pBegin1++) != toUpperCase(*pString2++))
+ return false;
+ return pBegin1 == pEnd1;
+}
+
+//============================================================================
+// static
+bool INetMIME::equalIgnoreCase(const sal_Unicode * pBegin1,
+ const sal_Unicode * pEnd1,
+ const sal_Char * pString2)
+{
+ DBG_ASSERT(pBegin1 && pBegin1 <= pEnd1 && pString2,
+ "INetMIME::equalIgnoreCase(): Bad sequences");
+
+ while (*pString2 != 0)
+ if (pBegin1 == pEnd1
+ || toUpperCase(*pBegin1++) != toUpperCase(*pString2++))
+ return false;
+ return pBegin1 == pEnd1;
+}
+
+//============================================================================
+// static
+const sal_Char * INetMIME::skipLinearWhiteSpace(const sal_Char * pBegin,
+ const sal_Char * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIME::skipLinearWhiteSpace(): Bad sequence");
+
+ while (pBegin != pEnd)
+ switch (*pBegin)
+ {
+ case '\t':
+ case ' ':
+ ++pBegin;
+ break;
+
+ case 0x0D: // CR
+ if (startsWithLineFolding(pBegin, pEnd))
+ pBegin += 3;
+ else
+ return pBegin;
+ break;
+
+ default:
+ return pBegin;
+ }
+ return pBegin;
+}
+
+//============================================================================
+// static
+const sal_Unicode * INetMIME::skipLinearWhiteSpace(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIME::skipLinearWhiteSpace(): Bad sequence");
+
+ while (pBegin != pEnd)
+ switch (*pBegin)
+ {
+ case '\t':
+ case ' ':
+ ++pBegin;
+ break;
+
+ case 0x0D: // CR
+ if (startsWithLineFolding(pBegin, pEnd))
+ pBegin += 3;
+ else
+ return pBegin;
+ break;
+
+ default:
+ return pBegin;
+ }
+ return pBegin;
+}
+
+//============================================================================
+// static
+const sal_Char * INetMIME::skipComment(const sal_Char * pBegin,
+ const sal_Char * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIME::skipComment(): Bad sequence");
+
+ if (pBegin != pEnd && *pBegin == '(')
+ {
+ sal_uInt32 nLevel = 0;
+ for (const sal_Char * p = pBegin; p != pEnd;)
+ switch (*p++)
+ {
+ case '(':
+ ++nLevel;
+ break;
+
+ case ')':
+ if (--nLevel == 0)
+ return p;
+ break;
+
+ case '\\':
+ if (p != pEnd)
+ ++p;
+ break;
+ }
+ }
+ return pBegin;
+}
+
+//============================================================================
+// static
+const sal_Unicode * INetMIME::skipComment(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIME::skipComment(): Bad sequence");
+
+ if (pBegin != pEnd && *pBegin == '(')
+ {
+ sal_uInt32 nLevel = 0;
+ for (const sal_Unicode * p = pBegin; p != pEnd;)
+ switch (*p++)
+ {
+ case '(':
+ ++nLevel;
+ break;
+
+ case ')':
+ if (--nLevel == 0)
+ return p;
+ break;
+
+ case '\\':
+ if (p != pEnd)
+ ++p;
+ break;
+ }
+ }
+ return pBegin;
+}
+
+//============================================================================
+// static
+const sal_Char * INetMIME::skipLinearWhiteSpaceComment(const sal_Char *
+ pBegin,
+ const sal_Char * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIME::skipLinearWhiteSpaceComment(): Bad sequence");
+
+ while (pBegin != pEnd)
+ switch (*pBegin)
+ {
+ case '\t':
+ case ' ':
+ ++pBegin;
+ break;
+
+ case 0x0D: // CR
+ if (startsWithLineFolding(pBegin, pEnd))
+ pBegin += 3;
+ else
+ return pBegin;
+ break;
+
+ case '(':
+ {
+ const sal_Char * p = skipComment(pBegin, pEnd);
+ if (p == pBegin)
+ return pBegin;
+ pBegin = p;
+ break;
+ }
+
+ default:
+ return pBegin;
+ }
+ return pBegin;
+}
+
+//============================================================================
+// static
+const sal_Unicode * INetMIME::skipLinearWhiteSpaceComment(const sal_Unicode *
+ pBegin,
+ const sal_Unicode *
+ pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIME::skipLinearWhiteSpaceComment(): Bad sequence");
+
+ while (pBegin != pEnd)
+ switch (*pBegin)
+ {
+ case '\t':
+ case ' ':
+ ++pBegin;
+ break;
+
+ case 0x0D: // CR
+ if (startsWithLineFolding(pBegin, pEnd))
+ pBegin += 3;
+ else
+ return pBegin;
+ break;
+
+ case '(':
+ {
+ const sal_Unicode * p = skipComment(pBegin, pEnd);
+ if (p == pBegin)
+ return pBegin;
+ pBegin = p;
+ break;
+ }
+
+ default:
+ return pBegin;
+ }
+ return pBegin;
+}
+
+//============================================================================
+// static
+const sal_Char * INetMIME::skipQuotedString(const sal_Char * pBegin,
+ const sal_Char * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIME::skipQuotedString(): Bad sequence");
+
+ if (pBegin != pEnd && *pBegin == '"')
+ for (const sal_Char * p = pBegin + 1; p != pEnd;)
+ switch (*p++)
+ {
+ case 0x0D: // CR
+ if (pEnd - p < 2 || *p++ != 0x0A // LF
+ || !isWhiteSpace(*p++))
+ return pBegin;
+ break;
+
+ case '"':
+ return p;
+
+ case '\\':
+ if (p != pEnd)
+ ++p;
+ break;
+ }
+ return pBegin;
+}
+
+//============================================================================
+// static
+const sal_Unicode * INetMIME::skipQuotedString(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIME::skipQuotedString(): Bad sequence");
+
+ if (pBegin != pEnd && *pBegin == '"')
+ for (const sal_Unicode * p = pBegin + 1; p != pEnd;)
+ switch (*p++)
+ {
+ case 0x0D: // CR
+ if (pEnd - p < 2 || *p++ != 0x0A // LF
+ || !isWhiteSpace(*p++))
+ return pBegin;
+ break;
+
+ case '"':
+ return p;
+
+ case '\\':
+ if (p != pEnd)
+ ++p;
+ break;
+ }
+ return pBegin;
+}
+
+//============================================================================
+// static
+const sal_Char * INetMIME::scanAtom(const sal_Char * pBegin,
+ const sal_Char * pEnd)
+{
+ while (pBegin != pEnd && isAtomChar(*pBegin))
+ ++pBegin;
+ return pBegin;
+}
+
+//============================================================================
+// static
+const sal_Unicode * INetMIME::scanAtom(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd)
+{
+ while (pBegin != pEnd && isAtomChar(*pBegin))
+ ++pBegin;
+ return pBegin;
+}
+
+//============================================================================
+// static
+bool INetMIME::scanUnsigned(const sal_Char *& rBegin, const sal_Char * pEnd,
+ bool bLeadingZeroes, sal_uInt32 & rValue)
+{
+ sal_uInt64 nTheValue = 0;
+ const sal_Char * p = rBegin;
+ for ( ; p != pEnd; ++p)
+ {
+ int nWeight = getWeight(*p);
+ if (nWeight < 0)
+ break;
+ nTheValue = 10 * nTheValue + nWeight;
+ if (nTheValue > std::numeric_limits< sal_uInt32 >::max())
+ return false;
+ }
+ if (nTheValue == 0 && (p == rBegin || (!bLeadingZeroes && p - rBegin != 1)))
+ return false;
+ rBegin = p;
+ rValue = sal_uInt32(nTheValue);
+ return true;
+}
+
+//============================================================================
+// static
+bool INetMIME::scanUnsigned(const sal_Unicode *& rBegin,
+ const sal_Unicode * pEnd, bool bLeadingZeroes,
+ sal_uInt32 & rValue)
+{
+ sal_uInt64 nTheValue = 0;
+ const sal_Unicode * p = rBegin;
+ for ( ; p != pEnd; ++p)
+ {
+ int nWeight = getWeight(*p);
+ if (nWeight < 0)
+ break;
+ nTheValue = 10 * nTheValue + nWeight;
+ if (nTheValue > std::numeric_limits< sal_uInt32 >::max())
+ return false;
+ }
+ if (nTheValue == 0 && (p == rBegin || (!bLeadingZeroes && p - rBegin != 1)))
+ return false;
+ rBegin = p;
+ rValue = sal_uInt32(nTheValue);
+ return true;
+}
+
+//============================================================================
+// static
+bool INetMIME::scanUnsignedHex(const sal_Char *& rBegin,
+ const sal_Char * pEnd, bool bLeadingZeroes,
+ sal_uInt32 & rValue)
+{
+ sal_uInt64 nTheValue = 0;
+ const sal_Char * p = rBegin;
+ for ( p = rBegin; p != pEnd; ++p)
+ {
+ int nWeight = getHexWeight(*p);
+ if (nWeight < 0)
+ break;
+ nTheValue = nTheValue << 4 | nWeight;
+ if (nTheValue > std::numeric_limits< sal_uInt32 >::max())
+ return false;
+ }
+ if (nTheValue == 0 && (p == rBegin || (!bLeadingZeroes && p - rBegin != 1)))
+ return false;
+ rBegin = p;
+ rValue = sal_uInt32(nTheValue);
+ return true;
+}
+
+//============================================================================
+// static
+bool INetMIME::scanUnsignedHex(const sal_Unicode *& rBegin,
+ const sal_Unicode * pEnd, bool bLeadingZeroes,
+ sal_uInt32 & rValue)
+{
+ sal_uInt64 nTheValue = 0;
+ const sal_Unicode * p = rBegin;
+ for ( ; p != pEnd; ++p)
+ {
+ int nWeight = getHexWeight(*p);
+ if (nWeight < 0)
+ break;
+ nTheValue = nTheValue << 4 | nWeight;
+ if (nTheValue > std::numeric_limits< sal_uInt32 >::max())
+ return false;
+ }
+ if (nTheValue == 0 && (p == rBegin || (!bLeadingZeroes && p - rBegin != 1)))
+ return false;
+ rBegin = p;
+ rValue = sal_uInt32(nTheValue);
+ return true;
+}
+
+//============================================================================
+// static
+const sal_Char * INetMIME::scanQuotedBlock(const sal_Char * pBegin,
+ const sal_Char * pEnd,
+ sal_uInt32 nOpening,
+ sal_uInt32 nClosing,
+ sal_Size & rLength,
+ bool & rModify)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIME::scanQuotedBlock(): Bad sequence");
+
+ if (pBegin != pEnd && static_cast< unsigned char >(*pBegin) == nOpening)
+ {
+ ++rLength;
+ ++pBegin;
+ while (pBegin != pEnd)
+ if (static_cast< unsigned char >(*pBegin) == nClosing)
+ {
+ ++rLength;
+ return ++pBegin;
+ }
+ else
+ {
+ sal_uInt32 c = *pBegin++;
+ switch (c)
+ {
+ case 0x0D: // CR
+ if (pBegin != pEnd && *pBegin == 0x0A) // LF
+ if (pEnd - pBegin >= 2 && isWhiteSpace(pBegin[1]))
+ {
+ ++rLength;
+ rModify = true;
+ pBegin += 2;
+ }
+ else
+ {
+ rLength += 3;
+ rModify = true;
+ ++pBegin;
+ }
+ else
+ ++rLength;
+ break;
+
+ case '\\':
+ ++rLength;
+ if (pBegin != pEnd)
+ {
+ if (startsWithLineBreak(pBegin, pEnd)
+ && (pEnd - pBegin < 3
+ || !isWhiteSpace(pBegin[2])))
+ {
+ rLength += 3;
+ rModify = true;
+ pBegin += 2;
+ }
+ else
+ ++pBegin;
+ }
+ break;
+
+ default:
+ ++rLength;
+ if (!isUSASCII(c))
+ rModify = true;
+ break;
+ }
+ }
+ }
+ return pBegin;
+}
+
+//============================================================================
+// static
+const sal_Unicode * INetMIME::scanQuotedBlock(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd,
+ sal_uInt32 nOpening,
+ sal_uInt32 nClosing,
+ sal_Size & rLength,
+ bool & rModify)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIME::scanQuotedBlock(): Bad sequence");
+
+ if (pBegin != pEnd && *pBegin == nOpening)
+ {
+ ++rLength;
+ ++pBegin;
+ while (pBegin != pEnd)
+ if (*pBegin == nClosing)
+ {
+ ++rLength;
+ return ++pBegin;
+ }
+ else
+ {
+ sal_uInt32 c = *pBegin++;
+ switch (c)
+ {
+ case 0x0D: // CR
+ if (pBegin != pEnd && *pBegin == 0x0A) // LF
+ if (pEnd - pBegin >= 2 && isWhiteSpace(pBegin[1]))
+ {
+ ++rLength;
+ rModify = true;
+ pBegin += 2;
+ }
+ else
+ {
+ rLength += 3;
+ rModify = true;
+ ++pBegin;
+ }
+ else
+ ++rLength;
+ break;
+
+ case '\\':
+ ++rLength;
+ if (pBegin != pEnd)
+ {
+ if (startsWithLineBreak(pBegin, pEnd)
+ && (pEnd - pBegin < 3
+ || !isWhiteSpace(pBegin[2])))
+ {
+ rLength += 3;
+ rModify = true;
+ pBegin += 2;
+ }
+ else
+ ++pBegin;
+ }
+ break;
+
+ default:
+ ++rLength;
+ if (!isUSASCII(c))
+ rModify = true;
+ break;
+ }
+ }
+ }
+ return pBegin;
+}
+
+//============================================================================
+// static
+sal_Char const * INetMIME::scanParameters(sal_Char const * pBegin,
+ sal_Char const * pEnd,
+ INetContentTypeParameterList *
+ pParameters)
+{
+ ParameterList aList;
+ sal_Char const * pParameterBegin = pBegin;
+ for (sal_Char const * p = pParameterBegin;; pParameterBegin = p)
+ {
+ pParameterBegin = skipLinearWhiteSpaceComment(p, pEnd);
+ if (pParameterBegin == pEnd || *pParameterBegin != ';')
+ break;
+ p = pParameterBegin + 1;
+
+ sal_Char const * pAttributeBegin = skipLinearWhiteSpaceComment(p,
+ pEnd);
+ p = pAttributeBegin;
+ bool bDowncaseAttribute = false;
+ while (p != pEnd && isTokenChar(*p) && *p != '*')
+ {
+ bDowncaseAttribute = bDowncaseAttribute || isUpperCase(*p);
+ ++p;
+ }
+ if (p == pAttributeBegin)
+ break;
+ ByteString aAttribute(
+ pAttributeBegin, static_cast< xub_StrLen >(p - pAttributeBegin));
+ if (bDowncaseAttribute)
+ aAttribute.ToLowerAscii();
+
+ sal_uInt32 nSection = 0;
+ if (p != pEnd && *p == '*')
+ {
+ ++p;
+ if (p != pEnd && isDigit(*p)
+ && !scanUnsigned(p, pEnd, false, nSection))
+ break;
+ }
+
+ bool bPresent;
+ Parameter ** pPos = aList.find(aAttribute, nSection, bPresent);
+ if (bPresent)
+ break;
+
+ bool bExtended = false;
+ if (p != pEnd && *p == '*')
+ {
+ ++p;
+ bExtended = true;
+ }
+
+ p = skipLinearWhiteSpaceComment(p, pEnd);
+
+ if (p == pEnd || *p != '=')
+ break;
+
+ p = skipLinearWhiteSpaceComment(p + 1, pEnd);
+
+ ByteString aCharset;
+ ByteString aLanguage;
+ ByteString aValue;
+ if (bExtended)
+ {
+ if (nSection == 0)
+ {
+ sal_Char const * pCharsetBegin = p;
+ bool bDowncaseCharset = false;
+ while (p != pEnd && isTokenChar(*p) && *p != '\'')
+ {
+ bDowncaseCharset = bDowncaseCharset || isUpperCase(*p);
+ ++p;
+ }
+ if (p == pCharsetBegin)
+ break;
+ if (pParameters)
+ {
+ aCharset = ByteString(
+ pCharsetBegin,
+ static_cast< xub_StrLen >(p - pCharsetBegin));
+ if (bDowncaseCharset)
+ aCharset.ToLowerAscii();
+ }
+
+ if (p == pEnd || *p != '\'')
+ break;
+ ++p;
+
+ sal_Char const * pLanguageBegin = p;
+ bool bDowncaseLanguage = false;
+ int nLetters = 0;
+ for (; p != pEnd; ++p)
+ if (isAlpha(*p))
+ {
+ if (++nLetters > 8)
+ break;
+ bDowncaseLanguage = bDowncaseLanguage
+ || isUpperCase(*p);
+ }
+ else if (*p == '-')
+ {
+ if (nLetters == 0)
+ break;
+ nLetters = 0;
+ }
+ else
+ break;
+ if (nLetters == 0 || nLetters > 8)
+ break;
+ if (pParameters)
+ {
+ aLanguage = ByteString(
+ pLanguageBegin,
+ static_cast< xub_StrLen >(p - pLanguageBegin));
+ if (bDowncaseLanguage)
+ aLanguage.ToLowerAscii();
+ }
+
+ if (p == pEnd || *p != '\'')
+ break;
+ ++p;
+ }
+ if (pParameters)
+ while (p != pEnd && (isTokenChar(*p) || !isUSASCII(*p)))
+ {
+ if (*p == '%')
+ {
+ if (p + 2 < pEnd)
+ {
+ int nWeight1 = getHexWeight(p[1]);
+ int nWeight2 = getHexWeight(p[2]);
+ if (nWeight1 >= 0 && nWeight2 >= 0)
+ {
+ aValue += sal_Char(nWeight1 << 4 | nWeight2);
+ p += 3;
+ continue;
+ }
+ }
+ }
+ aValue += *p++;
+ }
+ else
+ while (p != pEnd && (isTokenChar(*p) || !isUSASCII(*p)))
+ ++p;
+ }
+ else if (p != pEnd && *p == '"')
+ if (pParameters)
+ {
+ bool bInvalid = false;
+ for (++p;;)
+ {
+ if (p == pEnd)
+ {
+ bInvalid = true;
+ break;
+ }
+ else if (*p == '"')
+ {
+ ++p;
+ break;
+ }
+ else if (*p == 0x0D) // CR
+ {
+ if (pEnd - p < 3 || p[1] != 0x0A // LF
+ || !isWhiteSpace(p[2]))
+ {
+ bInvalid = true;
+ break;
+ }
+ p += 2;
+ }
+ else if (*p == '\\' && ++p == pEnd)
+ {
+ bInvalid = true;
+ break;
+ }
+ aValue += *p++;
+ }
+ if (bInvalid)
+ break;
+ }
+ else
+ {
+ sal_Char const * pStringEnd = skipQuotedString(p, pEnd);
+ if (p == pStringEnd)
+ break;
+ p = pStringEnd;
+ }
+ else
+ {
+ sal_Char const * pTokenBegin = p;
+ while (p != pEnd && (isTokenChar(*p) || !isUSASCII(*p)))
+ ++p;
+ if (p == pTokenBegin)
+ break;
+ if (pParameters)
+ aValue = ByteString(
+ pTokenBegin, static_cast< xub_StrLen >(p - pTokenBegin));
+ }
+
+ *pPos = new Parameter(*pPos, aAttribute, aCharset, aLanguage, aValue,
+ nSection, bExtended);
+ }
+ return parseParameters(aList, pParameters) ? pParameterBegin : pBegin;
+}
+
+//============================================================================
+// static
+sal_Unicode const * INetMIME::scanParameters(sal_Unicode const * pBegin,
+ sal_Unicode const * pEnd,
+ INetContentTypeParameterList *
+ pParameters)
+{
+ ParameterList aList;
+ sal_Unicode const * pParameterBegin = pBegin;
+ for (sal_Unicode const * p = pParameterBegin;; pParameterBegin = p)
+ {
+ pParameterBegin = skipLinearWhiteSpaceComment(p, pEnd);
+ if (pParameterBegin == pEnd || *pParameterBegin != ';')
+ break;
+ p = pParameterBegin + 1;
+
+ sal_Unicode const * pAttributeBegin
+ = skipLinearWhiteSpaceComment(p, pEnd);
+ p = pAttributeBegin;
+ bool bDowncaseAttribute = false;
+ while (p != pEnd && isTokenChar(*p) && *p != '*')
+ {
+ bDowncaseAttribute = bDowncaseAttribute || isUpperCase(*p);
+ ++p;
+ }
+ if (p == pAttributeBegin)
+ break;
+ ByteString aAttribute = ByteString(
+ pAttributeBegin, static_cast< xub_StrLen >(p - pAttributeBegin),
+ RTL_TEXTENCODING_ASCII_US);
+ if (bDowncaseAttribute)
+ aAttribute.ToLowerAscii();
+
+ sal_uInt32 nSection = 0;
+ if (p != pEnd && *p == '*')
+ {
+ ++p;
+ if (p != pEnd && isDigit(*p)
+ && !scanUnsigned(p, pEnd, false, nSection))
+ break;
+ }
+
+ bool bPresent;
+ Parameter ** pPos = aList.find(aAttribute, nSection, bPresent);
+ if (bPresent)
+ break;
+
+ bool bExtended = false;
+ if (p != pEnd && *p == '*')
+ {
+ ++p;
+ bExtended = true;
+ }
+
+ p = skipLinearWhiteSpaceComment(p, pEnd);
+
+ if (p == pEnd || *p != '=')
+ break;
+
+ p = skipLinearWhiteSpaceComment(p + 1, pEnd);
+
+ ByteString aCharset;
+ ByteString aLanguage;
+ ByteString aValue;
+ if (bExtended)
+ {
+ if (nSection == 0)
+ {
+ sal_Unicode const * pCharsetBegin = p;
+ bool bDowncaseCharset = false;
+ while (p != pEnd && isTokenChar(*p) && *p != '\'')
+ {
+ bDowncaseCharset = bDowncaseCharset || isUpperCase(*p);
+ ++p;
+ }
+ if (p == pCharsetBegin)
+ break;
+ if (pParameters)
+ {
+ aCharset = ByteString(
+ pCharsetBegin,
+ static_cast< xub_StrLen >(p - pCharsetBegin),
+ RTL_TEXTENCODING_ASCII_US);
+ if (bDowncaseCharset)
+ aCharset.ToLowerAscii();
+ }
+
+ if (p == pEnd || *p != '\'')
+ break;
+ ++p;
+
+ sal_Unicode const * pLanguageBegin = p;
+ bool bDowncaseLanguage = false;
+ int nLetters = 0;
+ for (; p != pEnd; ++p)
+ if (isAlpha(*p))
+ {
+ if (++nLetters > 8)
+ break;
+ bDowncaseLanguage = bDowncaseLanguage
+ || isUpperCase(*p);
+ }
+ else if (*p == '-')
+ {
+ if (nLetters == 0)
+ break;
+ nLetters = 0;
+ }
+ else
+ break;
+ if (nLetters == 0 || nLetters > 8)
+ break;
+ if (pParameters)
+ {
+ aLanguage = ByteString(
+ pLanguageBegin,
+ static_cast< xub_StrLen >(p - pLanguageBegin),
+ RTL_TEXTENCODING_ASCII_US);
+ if (bDowncaseLanguage)
+ aLanguage.ToLowerAscii();
+ }
+
+ if (p == pEnd || *p != '\'')
+ break;
+ ++p;
+ }
+ if (pParameters)
+ {
+ INetMIMEStringOutputSink
+ aSink(0, INetMIMEOutputSink::NO_LINE_LENGTH_LIMIT);
+ while (p != pEnd)
+ {
+ sal_uInt32 nChar = INetMIME::getUTF32Character(p, pEnd);
+ if (isUSASCII(nChar) && !isTokenChar(nChar))
+ break;
+ if (nChar == '%' && p + 1 < pEnd)
+ {
+ int nWeight1 = getHexWeight(p[0]);
+ int nWeight2 = getHexWeight(p[1]);
+ if (nWeight1 >= 0 && nWeight2 >= 0)
+ {
+ aSink << sal_Char(nWeight1 << 4 | nWeight2);
+ p += 2;
+ continue;
+ }
+ }
+ INetMIME::writeUTF8(aSink, nChar);
+ }
+ aValue = aSink.takeBuffer();
+ }
+ else
+ while (p != pEnd && (isTokenChar(*p) || !isUSASCII(*p)))
+ ++p;
+ }
+ else if (p != pEnd && *p == '"')
+ if (pParameters)
+ {
+ INetMIMEStringOutputSink
+ aSink(0, INetMIMEOutputSink::NO_LINE_LENGTH_LIMIT);
+ bool bInvalid = false;
+ for (++p;;)
+ {
+ if (p == pEnd)
+ {
+ bInvalid = true;
+ break;
+ }
+ sal_uInt32 nChar = INetMIME::getUTF32Character(p, pEnd);
+ if (nChar == '"')
+ break;
+ else if (nChar == 0x0D) // CR
+ {
+ if (pEnd - p < 2 || *p++ != 0x0A // LF
+ || !isWhiteSpace(*p))
+ {
+ bInvalid = true;
+ break;
+ }
+ nChar = sal_uChar(*p++);
+ }
+ else if (nChar == '\\')
+ {
+ if (p == pEnd)
+ {
+ bInvalid = true;
+ break;
+ }
+ nChar = INetMIME::getUTF32Character(p, pEnd);
+ }
+ INetMIME::writeUTF8(aSink, nChar);
+ }
+ if (bInvalid)
+ break;
+ aValue = aSink.takeBuffer();
+ }
+ else
+ {
+ sal_Unicode const * pStringEnd = skipQuotedString(p, pEnd);
+ if (p == pStringEnd)
+ break;
+ p = pStringEnd;
+ }
+ else
+ {
+ sal_Unicode const * pTokenBegin = p;
+ while (p != pEnd && (isTokenChar(*p) || !isUSASCII(*p)))
+ ++p;
+ if (p == pTokenBegin)
+ break;
+ if (pParameters)
+ aValue = ByteString(
+ pTokenBegin, static_cast< xub_StrLen >(p - pTokenBegin),
+ RTL_TEXTENCODING_UTF8);
+ }
+
+ *pPos = new Parameter(*pPos, aAttribute, aCharset, aLanguage, aValue,
+ nSection, bExtended);
+ }
+ return parseParameters(aList, pParameters) ? pParameterBegin : pBegin;
+}
+
+//============================================================================
+// static
+const sal_Char * INetMIME::getCharsetName(rtl_TextEncoding eEncoding)
+{
+ if (rtl_isOctetTextEncoding(eEncoding))
+ {
+ char const * p = rtl_getMimeCharsetFromTextEncoding(eEncoding);
+ DBG_ASSERT(p, "INetMIME::getCharsetName(): Unsupported encoding");
+ return p;
+ }
+ else
+ switch (eEncoding)
+ {
+ case RTL_TEXTENCODING_UCS4:
+ return "ISO-10646-UCS-4";
+
+ case RTL_TEXTENCODING_UCS2:
+ return "ISO-10646-UCS-2";
+
+ default:
+ DBG_ERROR("INetMIME::getCharsetName(): Unsupported encoding");
+ return 0;
+ }
+}
+
+//============================================================================
+namespace unnamed_tools_inetmime {
+
+struct EncodingEntry
+{
+ sal_Char const * m_aName;
+ rtl_TextEncoding m_eEncoding;
+};
+
+//============================================================================
+// The source for the following table is <ftp://ftp.iana.org/in-notes/iana/
+// assignments/character-sets> as of Jan, 21 2000 12:46:00, unless otherwise
+// noted:
+EncodingEntry const aEncodingMap[]
+ = { { "US-ASCII", RTL_TEXTENCODING_ASCII_US },
+ { "ANSI_X3.4-1968", RTL_TEXTENCODING_ASCII_US },
+ { "ISO-IR-6", RTL_TEXTENCODING_ASCII_US },
+ { "ANSI_X3.4-1986", RTL_TEXTENCODING_ASCII_US },
+ { "ISO_646.IRV:1991", RTL_TEXTENCODING_ASCII_US },
+ { "ASCII", RTL_TEXTENCODING_ASCII_US },
+ { "ISO646-US", RTL_TEXTENCODING_ASCII_US },
+ { "US", RTL_TEXTENCODING_ASCII_US },
+ { "IBM367", RTL_TEXTENCODING_ASCII_US },
+ { "CP367", RTL_TEXTENCODING_ASCII_US },
+ { "CSASCII", RTL_TEXTENCODING_ASCII_US },
+ { "ISO-8859-1", RTL_TEXTENCODING_ISO_8859_1 },
+ { "ISO_8859-1:1987", RTL_TEXTENCODING_ISO_8859_1 },
+ { "ISO-IR-100", RTL_TEXTENCODING_ISO_8859_1 },
+ { "ISO_8859-1", RTL_TEXTENCODING_ISO_8859_1 },
+ { "LATIN1", RTL_TEXTENCODING_ISO_8859_1 },
+ { "L1", RTL_TEXTENCODING_ISO_8859_1 },
+ { "IBM819", RTL_TEXTENCODING_ISO_8859_1 },
+ { "CP819", RTL_TEXTENCODING_ISO_8859_1 },
+ { "CSISOLATIN1", RTL_TEXTENCODING_ISO_8859_1 },
+ { "ISO-8859-2", RTL_TEXTENCODING_ISO_8859_2 },
+ { "ISO_8859-2:1987", RTL_TEXTENCODING_ISO_8859_2 },
+ { "ISO-IR-101", RTL_TEXTENCODING_ISO_8859_2 },
+ { "ISO_8859-2", RTL_TEXTENCODING_ISO_8859_2 },
+ { "LATIN2", RTL_TEXTENCODING_ISO_8859_2 },
+ { "L2", RTL_TEXTENCODING_ISO_8859_2 },
+ { "CSISOLATIN2", RTL_TEXTENCODING_ISO_8859_2 },
+ { "ISO-8859-3", RTL_TEXTENCODING_ISO_8859_3 },
+ { "ISO_8859-3:1988", RTL_TEXTENCODING_ISO_8859_3 },
+ { "ISO-IR-109", RTL_TEXTENCODING_ISO_8859_3 },
+ { "ISO_8859-3", RTL_TEXTENCODING_ISO_8859_3 },
+ { "LATIN3", RTL_TEXTENCODING_ISO_8859_3 },
+ { "L3", RTL_TEXTENCODING_ISO_8859_3 },
+ { "CSISOLATIN3", RTL_TEXTENCODING_ISO_8859_3 },
+ { "ISO-8859-4", RTL_TEXTENCODING_ISO_8859_4 },
+ { "ISO_8859-4:1988", RTL_TEXTENCODING_ISO_8859_4 },
+ { "ISO-IR-110", RTL_TEXTENCODING_ISO_8859_4 },
+ { "ISO_8859-4", RTL_TEXTENCODING_ISO_8859_4 },
+ { "LATIN4", RTL_TEXTENCODING_ISO_8859_4 },
+ { "L4", RTL_TEXTENCODING_ISO_8859_4 },
+ { "CSISOLATIN4", RTL_TEXTENCODING_ISO_8859_4 },
+ { "ISO-8859-5", RTL_TEXTENCODING_ISO_8859_5 },
+ { "ISO_8859-5:1988", RTL_TEXTENCODING_ISO_8859_5 },
+ { "ISO-IR-144", RTL_TEXTENCODING_ISO_8859_5 },
+ { "ISO_8859-5", RTL_TEXTENCODING_ISO_8859_5 },
+ { "CYRILLIC", RTL_TEXTENCODING_ISO_8859_5 },
+ { "CSISOLATINCYRILLIC", RTL_TEXTENCODING_ISO_8859_5 },
+ { "ISO-8859-6", RTL_TEXTENCODING_ISO_8859_6 },
+ { "ISO_8859-6:1987", RTL_TEXTENCODING_ISO_8859_6 },
+ { "ISO-IR-127", RTL_TEXTENCODING_ISO_8859_6 },
+ { "ISO_8859-6", RTL_TEXTENCODING_ISO_8859_6 },
+ { "ECMA-114", RTL_TEXTENCODING_ISO_8859_6 },
+ { "ASMO-708", RTL_TEXTENCODING_ISO_8859_6 },
+ { "ARABIC", RTL_TEXTENCODING_ISO_8859_6 },
+ { "CSISOLATINARABIC", RTL_TEXTENCODING_ISO_8859_6 },
+ { "ISO-8859-7", RTL_TEXTENCODING_ISO_8859_7 },
+ { "ISO_8859-7:1987", RTL_TEXTENCODING_ISO_8859_7 },
+ { "ISO-IR-126", RTL_TEXTENCODING_ISO_8859_7 },
+ { "ISO_8859-7", RTL_TEXTENCODING_ISO_8859_7 },
+ { "ELOT_928", RTL_TEXTENCODING_ISO_8859_7 },
+ { "ECMA-118", RTL_TEXTENCODING_ISO_8859_7 },
+ { "GREEK", RTL_TEXTENCODING_ISO_8859_7 },
+ { "GREEK8", RTL_TEXTENCODING_ISO_8859_7 },
+ { "CSISOLATINGREEK", RTL_TEXTENCODING_ISO_8859_7 },
+ { "ISO-8859-8", RTL_TEXTENCODING_ISO_8859_8 },
+ { "ISO_8859-8:1988", RTL_TEXTENCODING_ISO_8859_8 },
+ { "ISO-IR-138", RTL_TEXTENCODING_ISO_8859_8 },
+ { "ISO_8859-8", RTL_TEXTENCODING_ISO_8859_8 },
+ { "HEBREW", RTL_TEXTENCODING_ISO_8859_8 },
+ { "CSISOLATINHEBREW", RTL_TEXTENCODING_ISO_8859_8 },
+ { "ISO-8859-9", RTL_TEXTENCODING_ISO_8859_9 },
+ { "ISO_8859-9:1989", RTL_TEXTENCODING_ISO_8859_9 },
+ { "ISO-IR-148", RTL_TEXTENCODING_ISO_8859_9 },
+ { "ISO_8859-9", RTL_TEXTENCODING_ISO_8859_9 },
+ { "LATIN5", RTL_TEXTENCODING_ISO_8859_9 },
+ { "L5", RTL_TEXTENCODING_ISO_8859_9 },
+ { "CSISOLATIN5", RTL_TEXTENCODING_ISO_8859_9 },
+ { "ISO-8859-14", RTL_TEXTENCODING_ISO_8859_14 }, // RFC 2047
+ { "ISO_8859-15", RTL_TEXTENCODING_ISO_8859_15 },
+ { "ISO-8859-15", RTL_TEXTENCODING_ISO_8859_15 }, // RFC 2047
+ { "MACINTOSH", RTL_TEXTENCODING_APPLE_ROMAN },
+ { "MAC", RTL_TEXTENCODING_APPLE_ROMAN },
+ { "CSMACINTOSH", RTL_TEXTENCODING_APPLE_ROMAN },
+ { "IBM437", RTL_TEXTENCODING_IBM_437 },
+ { "CP437", RTL_TEXTENCODING_IBM_437 },
+ { "437", RTL_TEXTENCODING_IBM_437 },
+ { "CSPC8CODEPAGE437", RTL_TEXTENCODING_IBM_437 },
+ { "IBM850", RTL_TEXTENCODING_IBM_850 },
+ { "CP850", RTL_TEXTENCODING_IBM_850 },
+ { "850", RTL_TEXTENCODING_IBM_850 },
+ { "CSPC850MULTILINGUAL", RTL_TEXTENCODING_IBM_850 },
+ { "IBM860", RTL_TEXTENCODING_IBM_860 },
+ { "CP860", RTL_TEXTENCODING_IBM_860 },
+ { "860", RTL_TEXTENCODING_IBM_860 },
+ { "CSIBM860", RTL_TEXTENCODING_IBM_860 },
+ { "IBM861", RTL_TEXTENCODING_IBM_861 },
+ { "CP861", RTL_TEXTENCODING_IBM_861 },
+ { "861", RTL_TEXTENCODING_IBM_861 },
+ { "CP-IS", RTL_TEXTENCODING_IBM_861 },
+ { "CSIBM861", RTL_TEXTENCODING_IBM_861 },
+ { "IBM863", RTL_TEXTENCODING_IBM_863 },
+ { "CP863", RTL_TEXTENCODING_IBM_863 },
+ { "863", RTL_TEXTENCODING_IBM_863 },
+ { "CSIBM863", RTL_TEXTENCODING_IBM_863 },
+ { "IBM865", RTL_TEXTENCODING_IBM_865 },
+ { "CP865", RTL_TEXTENCODING_IBM_865 },
+ { "865", RTL_TEXTENCODING_IBM_865 },
+ { "CSIBM865", RTL_TEXTENCODING_IBM_865 },
+ { "IBM775", RTL_TEXTENCODING_IBM_775 },
+ { "CP775", RTL_TEXTENCODING_IBM_775 },
+ { "CSPC775BALTIC", RTL_TEXTENCODING_IBM_775 },
+ { "IBM852", RTL_TEXTENCODING_IBM_852 },
+ { "CP852", RTL_TEXTENCODING_IBM_852 },
+ { "852", RTL_TEXTENCODING_IBM_852 },
+ { "CSPCP852", RTL_TEXTENCODING_IBM_852 },
+ { "IBM855", RTL_TEXTENCODING_IBM_855 },
+ { "CP855", RTL_TEXTENCODING_IBM_855 },
+ { "855", RTL_TEXTENCODING_IBM_855 },
+ { "CSIBM855", RTL_TEXTENCODING_IBM_855 },
+ { "IBM857", RTL_TEXTENCODING_IBM_857 },
+ { "CP857", RTL_TEXTENCODING_IBM_857 },
+ { "857", RTL_TEXTENCODING_IBM_857 },
+ { "CSIBM857", RTL_TEXTENCODING_IBM_857 },
+ { "IBM862", RTL_TEXTENCODING_IBM_862 },
+ { "CP862", RTL_TEXTENCODING_IBM_862 },
+ { "862", RTL_TEXTENCODING_IBM_862 },
+ { "CSPC862LATINHEBREW", RTL_TEXTENCODING_IBM_862 },
+ { "IBM864", RTL_TEXTENCODING_IBM_864 },
+ { "CP864", RTL_TEXTENCODING_IBM_864 },
+ { "CSIBM864", RTL_TEXTENCODING_IBM_864 },
+ { "IBM866", RTL_TEXTENCODING_IBM_866 },
+ { "CP866", RTL_TEXTENCODING_IBM_866 },
+ { "866", RTL_TEXTENCODING_IBM_866 },
+ { "CSIBM866", RTL_TEXTENCODING_IBM_866 },
+ { "IBM869", RTL_TEXTENCODING_IBM_869 },
+ { "CP869", RTL_TEXTENCODING_IBM_869 },
+ { "869", RTL_TEXTENCODING_IBM_869 },
+ { "CP-GR", RTL_TEXTENCODING_IBM_869 },
+ { "CSIBM869", RTL_TEXTENCODING_IBM_869 },
+ { "WINDOWS-1250", RTL_TEXTENCODING_MS_1250 },
+ { "WINDOWS-1251", RTL_TEXTENCODING_MS_1251 },
+ { "WINDOWS-1253", RTL_TEXTENCODING_MS_1253 },
+ { "WINDOWS-1254", RTL_TEXTENCODING_MS_1254 },
+ { "WINDOWS-1255", RTL_TEXTENCODING_MS_1255 },
+ { "WINDOWS-1256", RTL_TEXTENCODING_MS_1256 },
+ { "WINDOWS-1257", RTL_TEXTENCODING_MS_1257 },
+ { "WINDOWS-1258", RTL_TEXTENCODING_MS_1258 },
+ { "SHIFT_JIS", RTL_TEXTENCODING_SHIFT_JIS },
+ { "MS_KANJI", RTL_TEXTENCODING_SHIFT_JIS },
+ { "CSSHIFTJIS", RTL_TEXTENCODING_SHIFT_JIS },
+ { "GB2312", RTL_TEXTENCODING_GB_2312 },
+ { "CSGB2312", RTL_TEXTENCODING_GB_2312 },
+ { "BIG5", RTL_TEXTENCODING_BIG5 },
+ { "CSBIG5", RTL_TEXTENCODING_BIG5 },
+ { "EUC-JP", RTL_TEXTENCODING_EUC_JP },
+ { "EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE",
+ RTL_TEXTENCODING_EUC_JP },
+ { "CSEUCPKDFMTJAPANESE", RTL_TEXTENCODING_EUC_JP },
+ { "ISO-2022-JP", RTL_TEXTENCODING_ISO_2022_JP },
+ { "CSISO2022JP", RTL_TEXTENCODING_ISO_2022_JP },
+ { "ISO-2022-CN", RTL_TEXTENCODING_ISO_2022_CN },
+ { "KOI8-R", RTL_TEXTENCODING_KOI8_R },
+ { "CSKOI8R", RTL_TEXTENCODING_KOI8_R },
+ { "UTF-7", RTL_TEXTENCODING_UTF7 },
+ { "UTF-8", RTL_TEXTENCODING_UTF8 },
+ { "ISO-8859-10", RTL_TEXTENCODING_ISO_8859_10 }, // RFC 2047
+ { "ISO-8859-13", RTL_TEXTENCODING_ISO_8859_13 }, // RFC 2047
+ { "EUC-KR", RTL_TEXTENCODING_EUC_KR },
+ { "CSEUCKR", RTL_TEXTENCODING_EUC_KR },
+ { "ISO-2022-KR", RTL_TEXTENCODING_ISO_2022_KR },
+ { "CSISO2022KR", RTL_TEXTENCODING_ISO_2022_KR },
+ { "ISO-10646-UCS-4", RTL_TEXTENCODING_UCS4 },
+ { "CSUCS4", RTL_TEXTENCODING_UCS4 },
+ { "ISO-10646-UCS-2", RTL_TEXTENCODING_UCS2 },
+ { "CSUNICODE", RTL_TEXTENCODING_UCS2 } };
+
+//============================================================================
+template< typename T >
+inline rtl_TextEncoding getCharsetEncoding_Impl(T const * pBegin,
+ T const * pEnd)
+{
+ for (sal_Size i = 0; i < sizeof aEncodingMap / sizeof (EncodingEntry);
+ ++i)
+ if (INetMIME::equalIgnoreCase(pBegin, pEnd, aEncodingMap[i].m_aName))
+ return aEncodingMap[i].m_eEncoding;
+ return RTL_TEXTENCODING_DONTKNOW;
+}
+
+}
+
+//============================================================================
+// static
+rtl_TextEncoding INetMIME::getCharsetEncoding(sal_Char const * pBegin,
+ sal_Char const * pEnd)
+{
+ return getCharsetEncoding_Impl(pBegin, pEnd);
+}
+
+//============================================================================
+// static
+rtl_TextEncoding INetMIME::getCharsetEncoding(sal_Unicode const * pBegin,
+ sal_Unicode const * pEnd)
+{
+ return getCharsetEncoding_Impl(pBegin, pEnd);
+}
+
+//============================================================================
+// static
+INetMIMECharsetList_Impl *
+INetMIME::createPreferredCharsetList(rtl_TextEncoding eEncoding)
+{
+ static const sal_uInt32 aUSASCIIRanges[] = { 0, 0x7F, sal_uInt32(-1) };
+
+ static const sal_uInt32 aISO88591Ranges[] = { 0, 0xFF, sal_uInt32(-1) };
+ // <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-1.TXT> version
+ // 1.0 of 1999 July 27
+
+ static const sal_uInt32 aISO88592Ranges[]
+ = { 0, 0xA0, 0xA4, 0xA4, 0xA7, 0xA8, 0xAD, 0xAD, 0xB0, 0xB0,
+ 0xB4, 0xB4, 0xB8, 0xB8, 0xC1, 0xC2, 0xC4, 0xC4, 0xC7, 0xC7,
+ 0xC9, 0xC9, 0xCB, 0xCB, 0xCD, 0xCE, 0xD3, 0xD4, 0xD6, 0xD7,
+ 0xDA, 0xDA, 0xDC, 0xDD, 0xDF, 0xDF, 0xE1, 0xE2, 0xE4, 0xE4,
+ 0xE7, 0xE7, 0xE9, 0xE9, 0xEB, 0xEB, 0xED, 0xEE, 0xF3, 0xF4,
+ 0xF6, 0xF7, 0xFA, 0xFA, 0xFC, 0xFD, 0x102, 0x107, 0x10C, 0x111,
+ 0x118, 0x11B, 0x139, 0x13A, 0x13D, 0x13E, 0x141, 0x144,
+ 0x147, 0x148, 0x150, 0x151, 0x154, 0x155, 0x158, 0x15B,
+ 0x15E, 0x165, 0x16E, 0x171, 0x179, 0x17E, 0x2C7, 0x2C7,
+ 0x2D8, 0x2D9, 0x2DB, 0x2DB, 0x2DD, 0x2DD, sal_uInt32(-1) };
+ // <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-2.TXT> version
+ // 1.0 of 1999 July 27
+
+ static const sal_uInt32 aISO88593Ranges[]
+ = { 0, 0xA0, 0xA3, 0xA4, 0xA7, 0xA8, 0xAD, 0xAD, 0xB0, 0xB0,
+ 0xB2, 0xB5, 0xB7, 0xB8, 0xBD, 0xBD, 0xC0, 0xC2, 0xC4, 0xC4,
+ 0xC7, 0xCF, 0xD1, 0xD4, 0xD6, 0xD7, 0xD9, 0xDC, 0xDF, 0xE2,
+ 0xE4, 0xE4, 0xE7, 0xEF, 0xF1, 0xF4, 0xF6, 0xF7, 0xF9, 0xFC,
+ 0x108, 0x10B, 0x11C, 0x121, 0x124, 0x127, 0x130, 0x131,
+ 0x134, 0x135, 0x15C, 0x15F, 0x16C, 0x16D, 0x17B, 0x17C,
+ 0x2D8, 0x2D9, sal_uInt32(-1) };
+ // <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-3.TXT> version
+ // 1.0 of 1999 July 27
+
+ static const sal_uInt32 aISO88594Ranges[]
+ = { 0, 0xA0, 0xA4, 0xA4, 0xA7, 0xA8, 0xAD, 0xAD, 0xAF, 0xB0,
+ 0xB4, 0xB4, 0xB8, 0xB8, 0xC1, 0xC6, 0xC9, 0xC9, 0xCB, 0xCB,
+ 0xCD, 0xCE, 0xD4, 0xD8, 0xDA, 0xDC, 0xDF, 0xDF, 0xE1, 0xE6,
+ 0xE9, 0xE9, 0xEB, 0xEB, 0xED, 0xEE, 0xF4, 0xF8, 0xFA, 0xFC,
+ 0x100, 0x101, 0x104, 0x105, 0x10C, 0x10D, 0x110, 0x113,
+ 0x116, 0x119, 0x122, 0x123, 0x128, 0x12B, 0x12E, 0x12F,
+ 0x136, 0x138, 0x13B, 0x13C, 0x145, 0x146, 0x14A, 0x14D,
+ 0x156, 0x157, 0x160, 0x161, 0x166, 0x16B, 0x172, 0x173,
+ 0x17D, 0x17E, 0x2C7, 0x2C7, 0x2D9, 0x2D9, 0x2DB, 0x2DB,
+ sal_uInt32(-1) };
+ // <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-4.TXT> version
+ // 1.0 of 1999 July 27
+
+ static const sal_uInt32 aISO88595Ranges[]
+ = { 0, 0xA0, 0xA7, 0xA7, 0xAD, 0xAD, 0x401, 0x40C, 0x40E, 0x44F,
+ 0x451, 0x45C, 0x45E, 0x45F, 0x2116, 0x2116, sal_uInt32(-1) };
+ // <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-5.TXT> version
+ // 1.0 of 1999 July 27
+
+ static const sal_uInt32 aISO88596Ranges[]
+ = { 0, 0xA0, 0xA4, 0xA4, 0xAD, 0xAD, 0x60C, 0x60C, 0x61B, 0x61B,
+ 0x61F, 0x61F, 0x621, 0x63A, 0x640, 0x652, sal_uInt32(-1) };
+ // <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-6.TXT> version
+ // 1.0 of 1999 July 27
+
+ static const sal_uInt32 aISO88597Ranges[]
+ = { 0, 0xA0, 0xA3, 0xA3, 0xA6, 0xA9, 0xAB, 0xAD, 0xB0, 0xB3,
+ 0xB7, 0xB7, 0xBB, 0xBB, 0xBD, 0xBD, 0x384, 0x386, 0x388, 0x38A,
+ 0x38C, 0x38C, 0x38E, 0x3A1, 0x3A3, 0x3CE, 0x2015, 0x2015,
+ 0x2018, 0x2019, sal_uInt32(-1) };
+ // <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-7.TXT> version
+ // 1.0 of 1999 July 27
+
+ static const sal_uInt32 aISO88598Ranges[]
+ = { 0, 0xA0, 0xA2, 0xA9, 0xAB, 0xB9, 0xBB, 0xBE, 0xD7, 0xD7,
+ 0xF7, 0xF7, 0x5D0, 0x5EA, 0x200E, 0x200F, 0x2017, 0x2017,
+ sal_uInt32(-1) };
+ // <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-8.TXT> version
+ // 1.1 of 2000-Jan-03
+
+ static const sal_uInt32 aISO88599Ranges[]
+ = { 0, 0xCF, 0xD1, 0xDC, 0xDF, 0xEF, 0xF1, 0xFC, 0xFF, 0xFF,
+ 0x11E, 0x11F, 0x130, 0x131, 0x15E, 0x15F, sal_uInt32(-1) };
+ // <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-9.TXT> version
+ // 1.0 of 1999 July 27
+
+ static const sal_uInt32 aISO885910Ranges[]
+ = { 0, 0xA0, 0xA7, 0xA7, 0xAD, 0xAD, 0xB0, 0xB0, 0xB7, 0xB7,
+ 0xC1, 0xC6, 0xC9, 0xC9, 0xCB, 0xCB, 0xCD, 0xD0, 0xD3, 0xD6,
+ 0xD8, 0xD8, 0xDA, 0xDF, 0xE1, 0xE6, 0xE9, 0xE9, 0xEB, 0xEB,
+ 0xED, 0xF0, 0xF3, 0xF6, 0xF8, 0xF8, 0xFA, 0xFE, 0x100, 0x101,
+ 0x104, 0x105, 0x10C, 0x10D, 0x110, 0x113, 0x116, 0x119,
+ 0x122, 0x123, 0x128, 0x12B, 0x12E, 0x12F, 0x136, 0x138,
+ 0x13B, 0x13C, 0x145, 0x146, 0x14A, 0x14D, 0x160, 0x161,
+ 0x166, 0x16B, 0x172, 0x173, 0x17D, 0x17E, 0x2015, 0x2015,
+ sal_uInt32(-1) };
+ // <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-10.TXT> version
+ // 1.1 of 1999 October 11
+
+ static const sal_uInt32 aISO885913Ranges[]
+ = { 0, 0xA0, 0xA2, 0xA4, 0xA6, 0xA7, 0xA9, 0xA9, 0xAB, 0xAE,
+ 0xB0, 0xB3, 0xB5, 0xB7, 0xB9, 0xB9, 0xBB, 0xBE, 0xC4, 0xC6,
+ 0xC9, 0xC9, 0xD3, 0xD3, 0xD5, 0xD8, 0xDC, 0xDC, 0xDF, 0xDF,
+ 0xE4, 0xE6, 0xE9, 0xE9, 0xF3, 0xF3, 0xF5, 0xF8, 0xFC, 0xFC,
+ 0x100, 0x101, 0x104, 0x107, 0x10C, 0x10D, 0x112, 0x113,
+ 0x116, 0x119, 0x122, 0x123, 0x12A, 0x12B, 0x12E, 0x12F,
+ 0x136, 0x137, 0x13B, 0x13C, 0x141, 0x146, 0x14C, 0x14D,
+ 0x156, 0x157, 0x15A, 0x15B, 0x160, 0x161, 0x16A, 0x16B,
+ 0x172, 0x173, 0x179, 0x17E, 0x2019, 0x2019, 0x201C, 0x201E,
+ sal_uInt32(-1) };
+ // <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-13.TXT> version
+ // 1.0 of 1999 July 27
+
+ static const sal_uInt32 aISO885914Ranges[]
+ = { 0, 0xA0, 0xA3, 0xA3, 0xA7, 0xA7, 0xA9, 0xA9, 0xAD, 0xAE,
+ 0xB6, 0xB6, 0xC0, 0xCF, 0xD1, 0xD6, 0xD8, 0xDD, 0xDF, 0xEF,
+ 0xF1, 0xF6, 0xF8, 0xFD, 0xFF, 0xFF, 0x10A, 0x10B, 0x120, 0x121,
+ 0x174, 0x178, 0x1E02, 0x1E03, 0x1E0A, 0x1E0B, 0x1E1E, 0x1E1F,
+ 0x1E40, 0x1E41, 0x1E56, 0x1E57, 0x1E60, 0x1E61, 0x1E6A, 0x1E6B,
+ 0x1E80, 0x1E85, 0x1EF2, 0x1EF3, sal_uInt32(-1) };
+ // <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-14.TXT> version
+ // 1.0 of 1999 July 27
+
+ static const sal_uInt32 aISO885915Ranges[]
+ = { 0, 0xA3, 0xA5, 0xA5, 0xA7, 0xA7, 0xA9, 0xB3, 0xB5, 0xB7,
+ 0xB9, 0xBB, 0xBF, 0xFF, 0x152, 0x153, 0x160, 0x161, 0x178, 0x178,
+ 0x17D, 0x17E, 0x20AC, 0x20AC, sal_uInt32(-1) };
+ // <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-15.TXT> version
+ // 1.0 of 1999 July 27
+
+ static const sal_uInt32 aKOI8RRanges[]
+ = { 0, 0x7F, 0xA0, 0xA0, 0xA9, 0xA9, 0xB0, 0xB0, 0xB2, 0xB2,
+ 0xB7, 0xB7, 0xF7, 0xF7, 0x401, 0x401, 0x410, 0x44F, 0x451, 0x451,
+ 0x2219, 0x221A, 0x2248, 0x2248, 0x2264, 0x2265, 0x2320, 0x2321,
+ 0x2500, 0x2500, 0x2502, 0x2502, 0x250C, 0x250C, 0x2510, 0x2510,
+ 0x2514, 0x2514, 0x2518, 0x2518, 0x251C, 0x251C, 0x2524, 0x2524,
+ 0x252C, 0x252C, 0x2534, 0x2534, 0x253C, 0x253C, 0x2550, 0x256C,
+ 0x2580, 0x2580, 0x2584, 0x2584, 0x2588, 0x2588, 0x258C, 0x258C,
+ 0x2590, 0x2593, 0x25A0, 0x25A0, sal_uInt32(-1) };
+ // <ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MISC/KOI8-R.TXT>
+ // version 1.0 of 18 August 1999
+
+#if defined WNT
+ static const sal_uInt32 aWindows1252Ranges[]
+ = { 0, 0x7F, 0xA0, 0xFF, 0x152, 0x153, 0x160, 0x161, 0x178, 0x178,
+ 0x17D, 0x17E, 0x192, 0x192, 0x2C6, 0x2C6, 0x2DC, 0x2DC,
+ 0x2013, 0x2014, 0x2018, 0x201A, 0x201C, 0x201E, 0x2020, 0x2022,
+ 0x2026, 0x2026, 0x2030, 0x2030, 0x2039, 0x203A, 0x20AC, 0x20AC,
+ 0x2122, 0x2122, sal_uInt32(-1) };
+ // <ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/
+ // CP1252.TXT> version 2.01 of 04/15/98
+#endif // WNT
+
+ INetMIMECharsetList_Impl * pList = new INetMIMECharsetList_Impl;
+ switch (eEncoding)
+ {
+ case RTL_TEXTENCODING_MS_1252:
+#if defined WNT
+ pList->prepend(Charset(RTL_TEXTENCODING_MS_1252,
+ aWindows1252Ranges));
+#endif // WNT
+ case RTL_TEXTENCODING_ISO_8859_1:
+ case RTL_TEXTENCODING_UTF7:
+ case RTL_TEXTENCODING_UTF8:
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_2:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_2,
+ aISO88592Ranges));
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_3:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_3,
+ aISO88593Ranges));
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_4:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_4,
+ aISO88594Ranges));
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_5:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_5,
+ aISO88595Ranges));
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_6:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_6,
+ aISO88596Ranges));
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_7:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_7,
+ aISO88597Ranges));
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_8:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_8,
+ aISO88598Ranges));
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_9:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_9,
+ aISO88599Ranges));
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_10:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_10,
+ aISO885910Ranges));
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_13:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_13,
+ aISO885913Ranges));
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_14:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_14,
+ aISO885914Ranges));
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_15:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_15,
+ aISO885915Ranges));
+ break;
+
+ case RTL_TEXTENCODING_MS_1250:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_2,
+ aISO88592Ranges));
+ break;
+
+ case RTL_TEXTENCODING_MS_1251:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_5,
+ aISO88595Ranges));
+ break;
+
+ case RTL_TEXTENCODING_MS_1253:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_7,
+ aISO88597Ranges));
+ break;
+
+ case RTL_TEXTENCODING_MS_1254:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_9,
+ aISO88599Ranges));
+ break;
+
+ case RTL_TEXTENCODING_MS_1255:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_8,
+ aISO88598Ranges));
+ break;
+
+ case RTL_TEXTENCODING_MS_1256:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_6,
+ aISO88596Ranges));
+ break;
+
+ case RTL_TEXTENCODING_MS_1257:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_4,
+ aISO88594Ranges));
+ break;
+
+ case RTL_TEXTENCODING_KOI8_R:
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_5,
+ aISO88595Ranges));
+ pList->prepend(Charset(RTL_TEXTENCODING_KOI8_R, aKOI8RRanges));
+ break;
+
+ default: //@@@ more cases are missing!
+ DBG_ERROR("INetMIME::createPreferredCharsetList():"
+ " Unsupported encoding");
+ break;
+ }
+ pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_1, aISO88591Ranges));
+ pList->prepend(Charset(RTL_TEXTENCODING_ASCII_US, aUSASCIIRanges));
+ return pList;
+}
+
+//============================================================================
+// static
+sal_Unicode * INetMIME::convertToUnicode(const sal_Char * pBegin,
+ const sal_Char * pEnd,
+ rtl_TextEncoding eEncoding,
+ sal_Size & rSize)
+{
+ if (eEncoding == RTL_TEXTENCODING_DONTKNOW)
+ return 0;
+ rtl_TextToUnicodeConverter hConverter
+ = rtl_createTextToUnicodeConverter(eEncoding);
+ rtl_TextToUnicodeContext hContext
+ = rtl_createTextToUnicodeContext(hConverter);
+ sal_Unicode * pBuffer;
+ sal_uInt32 nInfo;
+ for (sal_Size nBufferSize = pEnd - pBegin;;
+ nBufferSize += nBufferSize / 3 + 1)
+ {
+ pBuffer = new sal_Unicode[nBufferSize];
+ sal_Size nSrcCvtBytes;
+ rSize = rtl_convertTextToUnicode(
+ hConverter, hContext, pBegin, pEnd - pBegin, pBuffer,
+ nBufferSize,
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
+ &nInfo, &nSrcCvtBytes);
+ if (nInfo != RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL)
+ break;
+ delete[] pBuffer;
+ rtl_resetTextToUnicodeContext(hConverter, hContext);
+ }
+ rtl_destroyTextToUnicodeContext(hConverter, hContext);
+ rtl_destroyTextToUnicodeConverter(hConverter);
+ if (nInfo != 0)
+ {
+ delete[] pBuffer;
+ pBuffer = 0;
+ }
+ return pBuffer;
+}
+
+//============================================================================
+// static
+sal_Char * INetMIME::convertFromUnicode(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd,
+ rtl_TextEncoding eEncoding,
+ sal_Size & rSize)
+{
+ if (eEncoding == RTL_TEXTENCODING_DONTKNOW)
+ return 0;
+ rtl_UnicodeToTextConverter hConverter
+ = rtl_createUnicodeToTextConverter(eEncoding);
+ rtl_UnicodeToTextContext hContext
+ = rtl_createUnicodeToTextContext(hConverter);
+ sal_Char * pBuffer;
+ sal_uInt32 nInfo;
+ for (sal_Size nBufferSize = pEnd - pBegin;;
+ nBufferSize += nBufferSize / 3 + 1)
+ {
+ pBuffer = new sal_Char[nBufferSize];
+ sal_Size nSrcCvtBytes;
+ rSize = rtl_convertUnicodeToText(
+ hConverter, hContext, pBegin, pEnd - pBegin, pBuffer,
+ nBufferSize,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
+ | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR
+ | RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE
+ | RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACESTR,
+ &nInfo, &nSrcCvtBytes);
+ if (nInfo != RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL)
+ break;
+ delete[] pBuffer;
+ rtl_resetUnicodeToTextContext(hConverter, hContext);
+ }
+ rtl_destroyUnicodeToTextContext(hConverter, hContext);
+ rtl_destroyUnicodeToTextConverter(hConverter);
+ if (nInfo != 0)
+ {
+ delete[] pBuffer;
+ pBuffer = 0;
+ }
+ return pBuffer;
+}
+
+//============================================================================
+// static
+void INetMIME::writeUTF8(INetMIMEOutputSink & rSink, sal_uInt32 nChar)
+{
+ // See RFC 2279 for a discussion of UTF-8.
+ DBG_ASSERT(nChar < 0x80000000, "INetMIME::writeUTF8(): Bad char");
+
+ if (nChar < 0x80)
+ rSink << sal_Char(nChar);
+ else if (nChar < 0x800)
+ rSink << sal_Char(nChar >> 6 | 0xC0)
+ << sal_Char((nChar & 0x3F) | 0x80);
+ else if (nChar < 0x10000)
+ rSink << sal_Char(nChar >> 12 | 0xE0)
+ << sal_Char((nChar >> 6 & 0x3F) | 0x80)
+ << sal_Char((nChar & 0x3F) | 0x80);
+ else if (nChar < 0x200000)
+ rSink << sal_Char(nChar >> 18 | 0xF0)
+ << sal_Char((nChar >> 12 & 0x3F) | 0x80)
+ << sal_Char((nChar >> 6 & 0x3F) | 0x80)
+ << sal_Char((nChar & 0x3F) | 0x80);
+ else if (nChar < 0x4000000)
+ rSink << sal_Char(nChar >> 24 | 0xF8)
+ << sal_Char((nChar >> 18 & 0x3F) | 0x80)
+ << sal_Char((nChar >> 12 & 0x3F) | 0x80)
+ << sal_Char((nChar >> 6 & 0x3F) | 0x80)
+ << sal_Char((nChar & 0x3F) | 0x80);
+ else
+ rSink << sal_Char(nChar >> 30 | 0xFC)
+ << sal_Char((nChar >> 24 & 0x3F) | 0x80)
+ << sal_Char((nChar >> 18 & 0x3F) | 0x80)
+ << sal_Char((nChar >> 12 & 0x3F) | 0x80)
+ << sal_Char((nChar >> 6 & 0x3F) | 0x80)
+ << sal_Char((nChar & 0x3F) | 0x80);
+}
+
+//============================================================================
+// static
+void INetMIME::writeUnsigned(INetMIMEOutputSink & rSink, sal_uInt32 nValue,
+ int nMinDigits)
+{
+ sal_Char aBuffer[10];
+ // max unsigned 32 bit value (4294967295) has 10 places
+ sal_Char * p = aBuffer;
+ for (; nValue > 0; nValue /= 10)
+ *p++ = sal_Char(getDigit(nValue % 10));
+ nMinDigits -= p - aBuffer;
+ while (nMinDigits-- > 0)
+ rSink << '0';
+ while (p != aBuffer)
+ rSink << *--p;
+}
+
+//============================================================================
+// static
+void INetMIME::writeDateTime(INetMIMEOutputSink & rSink,
+ const DateTime & rUTC)
+{
+ static const sal_Char aDay[7][3]
+ = { { 'M', 'o', 'n' },
+ { 'T', 'u', 'e' },
+ { 'W', 'e', 'd' },
+ { 'T', 'h', 'u' },
+ { 'F', 'r', 'i' },
+ { 'S', 'a', 't' },
+ { 'S', 'u', 'n' } };
+ const sal_Char * pTheDay = aDay[rUTC.GetDayOfWeek()];
+ rSink.write(pTheDay, pTheDay + 3);
+ rSink << ", ";
+ writeUnsigned(rSink, rUTC.GetDay());
+ rSink << ' ';
+ static const sal_Char aMonth[12][3]
+ = { { 'J', 'a', 'n' },
+ { 'F', 'e', 'b' },
+ { 'M', 'a', 'r' },
+ { 'A', 'p', 'r' },
+ { 'M', 'a', 'y' },
+ { 'J', 'u', 'n' },
+ { 'J', 'u', 'l' },
+ { 'A', 'u', 'g' },
+ { 'S', 'e', 'p' },
+ { 'O', 'c', 't' },
+ { 'N', 'o', 'v' },
+ { 'D', 'e', 'c' } };
+ const sal_Char * pTheMonth = aMonth[rUTC.GetMonth() - 1];
+ rSink.write(pTheMonth, pTheMonth + 3);
+ rSink << ' ';
+ writeUnsigned(rSink, rUTC.GetYear());
+ rSink << ' ';
+ writeUnsigned(rSink, rUTC.GetHour(), 2);
+ rSink << ':';
+ writeUnsigned(rSink, rUTC.GetMin(), 2);
+ rSink << ':';
+ writeUnsigned(rSink, rUTC.GetSec(), 2);
+ rSink << " +0000";
+}
+
+//============================================================================
+// static
+void INetMIME::writeHeaderFieldBody(INetMIMEOutputSink & rSink,
+ HeaderFieldType eType,
+ const ByteString & rBody,
+ rtl_TextEncoding ePreferredEncoding,
+ bool bInitialSpace)
+{
+ writeHeaderFieldBody(rSink, eType,
+ UniString(rBody, RTL_TEXTENCODING_UTF8),
+ ePreferredEncoding, bInitialSpace);
+}
+
+//============================================================================
+// static
+void INetMIME::writeHeaderFieldBody(INetMIMEOutputSink & rSink,
+ HeaderFieldType eType,
+ const UniString & rBody,
+ rtl_TextEncoding ePreferredEncoding,
+ bool bInitialSpace)
+{
+ if (eType == HEADER_FIELD_TEXT)
+ {
+ INetMIMEEncodedWordOutputSink
+ aOutput(rSink, INetMIMEEncodedWordOutputSink::CONTEXT_TEXT,
+ bInitialSpace ?
+ INetMIMEEncodedWordOutputSink::SPACE_ALWAYS :
+ INetMIMEEncodedWordOutputSink::SPACE_NO,
+ ePreferredEncoding);
+ aOutput.write(rBody.GetBuffer(), rBody.GetBuffer() + rBody.Len());
+ aOutput.flush();
+ }
+ else
+ {
+ enum Brackets { BRACKETS_OUTSIDE, BRACKETS_OPENING, BRACKETS_INSIDE };
+ Brackets eBrackets = BRACKETS_OUTSIDE;
+
+ const sal_Unicode * pBodyPtr = rBody.GetBuffer();
+ const sal_Unicode * pBodyEnd = pBodyPtr + rBody.Len();
+ while (pBodyPtr != pBodyEnd)
+ switch (*pBodyPtr)
+ {
+ case '\t':
+ case ' ':
+ // A WSP adds to accumulated space:
+ bInitialSpace = true;
+ ++pBodyPtr;
+ break;
+
+ case '(':
+ {
+ // Write a pending '<' if necessary:
+ if (eBrackets == BRACKETS_OPENING)
+ {
+ if (rSink.getColumn() + (bInitialSpace ? 1 : 0)
+ >= rSink.getLineLengthLimit())
+ rSink << INetMIMEOutputSink::endl << ' ';
+ else if (bInitialSpace)
+ rSink << ' ';
+ rSink << '<';
+ bInitialSpace = false;
+ eBrackets = BRACKETS_INSIDE;
+ }
+
+ // Write the comment, introducing encoded-words where
+ // necessary:
+ int nLevel = 0;
+ INetMIMEEncodedWordOutputSink
+ aOutput(
+ rSink,
+ INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT,
+ INetMIMEEncodedWordOutputSink::SPACE_NO,
+ ePreferredEncoding);
+ while (pBodyPtr != pBodyEnd)
+ switch (*pBodyPtr)
+ {
+ case '(':
+ aOutput.flush();
+ if (rSink.getColumn()
+ + (bInitialSpace ? 1 : 0)
+ >= rSink.getLineLengthLimit())
+ rSink << INetMIMEOutputSink::endl << ' ';
+ else if (bInitialSpace)
+ rSink << ' ';
+ rSink << '(';
+ bInitialSpace = false;
+ ++nLevel;
+ ++pBodyPtr;
+ break;
+
+ case ')':
+ aOutput.flush();
+ if (rSink.getColumn()
+ >= rSink.getLineLengthLimit())
+ rSink << INetMIMEOutputSink::endl << ' ';
+ rSink << ')';
+ ++pBodyPtr;
+ if (--nLevel == 0)
+ goto comment_done;
+ break;
+
+ case '\\':
+ if (++pBodyPtr == pBodyEnd)
+ break;
+ default:
+ aOutput << *pBodyPtr++;
+ break;
+ }
+ comment_done:
+ break;
+ }
+
+ case '<':
+ // Write an already pending '<' if necessary:
+ if (eBrackets == BRACKETS_OPENING)
+ {
+ if (rSink.getColumn() + (bInitialSpace ? 1 : 0)
+ >= rSink.getLineLengthLimit())
+ rSink << INetMIMEOutputSink::endl << ' ';
+ else if (bInitialSpace)
+ rSink << ' ';
+ rSink << '<';
+ bInitialSpace = false;
+ }
+
+ // Remember this '<' as pending, and open a bracketed
+ // block:
+ eBrackets = BRACKETS_OPENING;
+ ++pBodyPtr;
+ break;
+
+ case '>':
+ // Write a pending '<' if necessary:
+ if (eBrackets == BRACKETS_OPENING)
+ {
+ if (rSink.getColumn() + (bInitialSpace ? 1 : 0)
+ >= rSink.getLineLengthLimit())
+ rSink << INetMIMEOutputSink::endl << ' ';
+ else if (bInitialSpace)
+ rSink << ' ';
+ rSink << '<';
+ bInitialSpace = false;
+ }
+
+ // Write this '>', and close any bracketed block:
+ if (rSink.getColumn() + (bInitialSpace ? 1 : 0)
+ >= rSink.getLineLengthLimit())
+ rSink << INetMIMEOutputSink::endl << ' ';
+ else if (bInitialSpace)
+ rSink << ' ';
+ rSink << '>';
+ bInitialSpace = false;
+ eBrackets = BRACKETS_OUTSIDE;
+ ++pBodyPtr;
+ break;
+
+ case ',':
+ case ':':
+ case ';':
+ case '\\':
+ case ']':
+ // Write a pending '<' if necessary:
+ if (eBrackets == BRACKETS_OPENING)
+ {
+ if (rSink.getColumn() + (bInitialSpace ? 1 : 0)
+ >= rSink.getLineLengthLimit())
+ rSink << INetMIMEOutputSink::endl << ' ';
+ else if (bInitialSpace)
+ rSink << ' ';
+ rSink << '<';
+ bInitialSpace = false;
+ eBrackets = BRACKETS_INSIDE;
+ }
+
+ // Write this specials:
+ if (rSink.getColumn() + (bInitialSpace ? 1 : 0)
+ >= rSink.getLineLengthLimit())
+ rSink << INetMIMEOutputSink::endl << ' ';
+ else if (bInitialSpace)
+ rSink << ' ';
+ rSink << sal_Char(*pBodyPtr++);
+ bInitialSpace = false;
+ break;
+
+ case '\x0D': // CR
+ // A <CRLF WSP> adds to accumulated space, a <CR> not
+ // followed by <LF WSP> starts 'junk':
+ if (startsWithLineFolding(pBodyPtr, pBodyEnd))
+ {
+ bInitialSpace = true;
+ pBodyPtr += 3;
+ break;
+ }
+ default:
+ {
+ // The next token is either one of <"." / "@" / atom /
+ // quoted-string / domain-literal>, or it's 'junk'; if it
+ // is not 'junk', it is either a 'phrase' (i.e., it may
+ // contain encoded-words) or a 'non-phrase' (i.e., it may
+ // not contain encoded-words):
+ enum Entity { ENTITY_JUNK, ENTITY_NON_PHRASE,
+ ENTITY_PHRASE };
+ Entity eEntity = ENTITY_JUNK;
+ switch (*pBodyPtr)
+ {
+ case '.':
+ case '@':
+ case '[':
+ // A token of <"." / "@" / domain-literal> always
+ // starts a 'non-phrase':
+ eEntity = ENTITY_NON_PHRASE;
+ break;
+
+ default:
+ if (isUSASCII(*pBodyPtr)
+ && !isAtomChar(*pBodyPtr))
+ {
+ eEntity = ENTITY_JUNK;
+ break;
+ }
+ case '"':
+ // A token of <atom / quoted-string> can either be
+ // a 'phrase' or a 'non-phrase':
+ switch (eType)
+ {
+ case HEADER_FIELD_STRUCTURED:
+ eEntity = ENTITY_NON_PHRASE;
+ break;
+
+ case HEADER_FIELD_PHRASE:
+ eEntity = ENTITY_PHRASE;
+ break;
+
+ case HEADER_FIELD_MESSAGE_ID:
+ // A 'phrase' if and only if outside any
+ // bracketed block:
+ eEntity
+ = eBrackets == BRACKETS_OUTSIDE ?
+ ENTITY_PHRASE :
+ ENTITY_NON_PHRASE;
+ break;
+
+ case HEADER_FIELD_ADDRESS:
+ {
+ // A 'non-phrase' if and only if, after
+ // skipping this token and any following
+ // <linear-white-space> and <comment>s,
+ // there is no token left, or the next
+ // token is any of <"." / "@" / ">" / ","
+ // / ";">, or the next token is <":"> and
+ // is within a bracketed block:
+ const sal_Unicode * pLookAhead = pBodyPtr;
+ if (*pLookAhead == '"')
+ {
+ pLookAhead
+ = skipQuotedString(pLookAhead,
+ pBodyEnd);
+ if (pLookAhead == pBodyPtr)
+ pLookAhead = pBodyEnd;
+ }
+ else
+ while (pLookAhead != pBodyEnd
+ && (isAtomChar(*pLookAhead)
+ || !isUSASCII(
+ *pLookAhead)))
+ ++pLookAhead;
+ while (pLookAhead != pBodyEnd)
+ switch (*pLookAhead)
+ {
+ case '\t':
+ case ' ':
+ ++pLookAhead;
+ break;
+
+ case '(':
+ {
+ const sal_Unicode * pPast
+ = skipComment(pLookAhead,
+ pBodyEnd);
+ pLookAhead
+ = pPast == pLookAhead ?
+ pBodyEnd : pPast;
+ break;
+ }
+
+ case ',':
+ case '.':
+ case ';':
+ case '>':
+ case '@':
+ eEntity = ENTITY_NON_PHRASE;
+ goto entity_determined;
+
+ case ':':
+ eEntity
+ = eBrackets
+ == BRACKETS_OUTSIDE ?
+ ENTITY_PHRASE :
+ ENTITY_NON_PHRASE;
+ goto entity_determined;
+
+ case '\x0D': // CR
+ if (startsWithLineFolding(
+ pLookAhead, pBodyEnd))
+ {
+ pLookAhead += 3;
+ break;
+ }
+ default:
+ eEntity = ENTITY_PHRASE;
+ goto entity_determined;
+ }
+ eEntity = ENTITY_NON_PHRASE;
+ entity_determined:
+ break;
+ }
+
+ case HEADER_FIELD_TEXT:
+ OSL_ASSERT(false);
+ break;
+ }
+
+ // In a 'non-phrase', a non-US-ASCII character
+ // cannot be part of an <atom>, but instead the
+ // whole entity is 'junk' rather than 'non-
+ // phrase':
+ if (eEntity == ENTITY_NON_PHRASE
+ && !isUSASCII(*pBodyPtr))
+ eEntity = ENTITY_JUNK;
+ break;
+ }
+
+ switch (eEntity)
+ {
+ case ENTITY_JUNK:
+ {
+ // Write a pending '<' if necessary:
+ if (eBrackets == BRACKETS_OPENING)
+ {
+ if (rSink.getColumn()
+ + (bInitialSpace ? 1 : 0)
+ >= rSink.getLineLengthLimit())
+ rSink << INetMIMEOutputSink::endl << ' ';
+ else if (bInitialSpace)
+ rSink << ' ';
+ rSink << '<';
+ bInitialSpace = false;
+ eBrackets = BRACKETS_INSIDE;
+ }
+
+ // Calculate the length of in- and output:
+ const sal_Unicode * pStart = pBodyPtr;
+ sal_Size nLength = 0;
+ bool bModify = false;
+ bool bEnd = false;
+ while (pBodyPtr != pBodyEnd && !bEnd)
+ switch (*pBodyPtr)
+ {
+ case '\x0D': // CR
+ if (startsWithLineFolding(pBodyPtr,
+ pBodyEnd))
+ bEnd = true;
+ else if (startsWithLineBreak(
+ pBodyPtr, pBodyEnd))
+ {
+ nLength += 3;
+ bModify = true;
+ pBodyPtr += 2;
+ }
+ else
+ {
+ ++nLength;
+ ++pBodyPtr;
+ }
+ break;
+
+ case '\t':
+ case ' ':
+ bEnd = true;
+ break;
+
+ default:
+ if (isVisible(*pBodyPtr))
+ bEnd = true;
+ else if (isUSASCII(*pBodyPtr))
+ {
+ ++nLength;
+ ++pBodyPtr;
+ }
+ else
+ {
+ nLength += getUTF8OctetCount(
+ *pBodyPtr++);
+ bModify = true;
+ }
+ break;
+ }
+
+ // Write the output:
+ if (rSink.getColumn() + (bInitialSpace ? 1 : 0)
+ + nLength
+ > rSink.getLineLengthLimit())
+ rSink << INetMIMEOutputSink::endl << ' ';
+ else if (bInitialSpace)
+ rSink << ' ';
+ bInitialSpace = false;
+ if (bModify)
+ while (pStart != pBodyPtr)
+ if (startsWithLineBreak(pStart, pBodyPtr))
+ {
+ rSink << "\x0D\\\x0A"; // CR, '\', LF
+ pStart += 2;
+ }
+ else
+ writeUTF8(rSink, *pStart++);
+ else
+ rSink.write(pStart, pBodyPtr);
+ break;
+ }
+
+ case ENTITY_NON_PHRASE:
+ {
+ // Calculate the length of in- and output:
+ const sal_Unicode * pStart = pBodyPtr;
+ sal_Size nLength = 0;
+ bool bBracketedBlock = false;
+ bool bSymbol = *pStart != '.' && *pStart != '@';
+ bool bModify = false;
+ bool bEnd = false;
+ while (pBodyPtr != pBodyEnd && !bEnd)
+ switch (*pBodyPtr)
+ {
+ case '\t':
+ case ' ':
+ case '\x0D': // CR
+ {
+ const sal_Unicode * pLookAhead
+ = skipLinearWhiteSpace(pBodyPtr,
+ pBodyEnd);
+ if (pLookAhead < pBodyEnd
+ && (bSymbol ?
+ isAtomChar(*pLookAhead)
+ || *pLookAhead == '"'
+ || *pLookAhead == '[' :
+ *pLookAhead == '.'
+ || *pLookAhead == '@'
+ || (*pLookAhead == '>'
+ && eType
+ >= HEADER_FIELD_MESSAGE_ID
+ && eBrackets
+ == BRACKETS_OPENING)))
+ {
+ bModify = true;
+ pBodyPtr = pLookAhead;
+ }
+ else
+ bEnd = true;
+ break;
+ }
+
+ case '"':
+ if (bSymbol)
+ {
+ pBodyPtr
+ = scanQuotedBlock(pBodyPtr,
+ pBodyEnd,
+ '"', '"',
+ nLength,
+ bModify);
+ bSymbol = false;
+ }
+ else
+ bEnd = true;
+ break;
+
+ case '[':
+ if (bSymbol)
+ {
+ pBodyPtr
+ = scanQuotedBlock(pBodyPtr,
+ pBodyEnd,
+ '[', ']',
+ nLength,
+ bModify);
+ bSymbol = false;
+ }
+ else
+ bEnd = true;
+ break;
+
+ case '.':
+ case '@':
+ if (bSymbol)
+ bEnd = true;
+ else
+ {
+ ++nLength;
+ bSymbol = true;
+ ++pBodyPtr;
+ }
+ break;
+
+ case '>':
+ if (eBrackets == BRACKETS_OPENING
+ && eType
+ >= HEADER_FIELD_MESSAGE_ID)
+ {
+ ++nLength;
+ bBracketedBlock = true;
+ ++pBodyPtr;
+ }
+ bEnd = true;
+ break;
+
+ default:
+ if (isAtomChar(*pBodyPtr) && bSymbol)
+ {
+ while (pBodyPtr != pBodyEnd
+ && isAtomChar(*pBodyPtr))
+ {
+ ++nLength;
+ ++pBodyPtr;
+ }
+ bSymbol = false;
+ }
+ else
+ {
+ if (!isUSASCII(*pBodyPtr))
+ bModify = true;
+ bEnd = true;
+ }
+ break;
+ }
+
+ // Write a pending '<' if necessary:
+ if (eBrackets == BRACKETS_OPENING
+ && !bBracketedBlock)
+ {
+ if (rSink.getColumn()
+ + (bInitialSpace ? 1 : 0)
+ >= rSink.getLineLengthLimit())
+ rSink << INetMIMEOutputSink::endl << ' ';
+ else if (bInitialSpace)
+ rSink << ' ';
+ rSink << '<';
+ bInitialSpace = false;
+ eBrackets = BRACKETS_INSIDE;
+ }
+
+ // Write the output:
+ if (rSink.getColumn() + (bInitialSpace ? 1 : 0)
+ + nLength
+ > rSink.getLineLengthLimit())
+ rSink << INetMIMEOutputSink::endl << ' ';
+ else if (bInitialSpace)
+ rSink << ' ';
+ bInitialSpace = false;
+ if (bBracketedBlock)
+ {
+ rSink << '<';
+ eBrackets = BRACKETS_OUTSIDE;
+ }
+ if (bModify)
+ {
+ enum Mode { MODE_PLAIN, MODE_QUOTED_STRING,
+ MODE_DOMAIN_LITERAL };
+ Mode eMode = MODE_PLAIN;
+ while (pStart != pBodyPtr)
+ switch (*pStart)
+ {
+ case '\x0D': // CR
+ if (startsWithLineFolding(
+ pStart, pBodyPtr))
+ {
+ if (eMode != MODE_PLAIN)
+ rSink << sal_Char(
+ pStart[2]);
+ pStart += 3;
+ }
+ else if (startsWithLineBreak(
+ pStart, pBodyPtr))
+ {
+ rSink << "\x0D\\\x0A";
+ // CR, '\', LF
+ pStart += 2;
+ }
+ else
+ {
+ rSink << '\x0D'; // CR
+ ++pStart;
+ }
+ break;
+
+ case '\t':
+ case ' ':
+ if (eMode != MODE_PLAIN)
+ rSink << sal_Char(*pStart);
+ ++pStart;
+ break;
+
+ case '"':
+ if (eMode == MODE_PLAIN)
+ eMode = MODE_QUOTED_STRING;
+ else if (eMode
+ == MODE_QUOTED_STRING)
+ eMode = MODE_PLAIN;
+ rSink << '"';
+ ++pStart;
+ break;
+
+ case '[':
+ if (eMode == MODE_PLAIN)
+ eMode = MODE_DOMAIN_LITERAL;
+ rSink << '[';
+ ++pStart;
+ break;
+
+ case ']':
+ if (eMode == MODE_DOMAIN_LITERAL)
+ eMode = MODE_PLAIN;
+ rSink << ']';
+ ++pStart;
+ break;
+
+ case '\\':
+ rSink << '\\';
+ if (++pStart < pBodyPtr)
+ writeUTF8(rSink, *pStart++);
+ break;
+
+ default:
+ writeUTF8(rSink, *pStart++);
+ break;
+ }
+ }
+ else
+ rSink.write(pStart, pBodyPtr);
+ break;
+ }
+
+ case ENTITY_PHRASE:
+ {
+ // Write a pending '<' if necessary:
+ if (eBrackets == BRACKETS_OPENING)
+ {
+ if (rSink.getColumn()
+ + (bInitialSpace ? 1 : 0)
+ >= rSink.getLineLengthLimit())
+ rSink << INetMIMEOutputSink::endl << ' ';
+ else if (bInitialSpace)
+ rSink << ' ';
+ rSink << '<';
+ bInitialSpace = false;
+ eBrackets = BRACKETS_INSIDE;
+ }
+
+ // Calculate the length of in- and output:
+ const sal_Unicode * pStart = pBodyPtr;
+ bool bQuotedString = false;
+ bool bEnd = false;
+ while (pBodyPtr != pBodyEnd && !bEnd)
+ switch (*pBodyPtr)
+ {
+ case '\t':
+ case ' ':
+ case '\x0D': // CR
+ if (bQuotedString)
+ ++pBodyPtr;
+ else
+ {
+ const sal_Unicode * pLookAhead
+ = skipLinearWhiteSpace(
+ pBodyPtr, pBodyEnd);
+ if (pLookAhead != pBodyEnd
+ && (isAtomChar(*pLookAhead)
+ || !isUSASCII(*pLookAhead)
+ || *pLookAhead == '"'))
+ pBodyPtr = pLookAhead;
+ else
+ bEnd = true;
+ }
+ break;
+
+ case '"':
+ bQuotedString = !bQuotedString;
+ ++pBodyPtr;
+ break;
+
+ case '\\':
+ if (bQuotedString)
+ {
+ if (++pBodyPtr != pBodyEnd)
+ ++pBodyPtr;
+ }
+ else
+ bEnd = true;
+ break;
+
+ default:
+ if (bQuotedString
+ || isAtomChar(*pBodyPtr)
+ || !isUSASCII(*pBodyPtr))
+ ++pBodyPtr;
+ else
+ bEnd = true;
+ break;
+ }
+
+ // Write the phrase, introducing encoded-words
+ // where necessary:
+ INetMIMEEncodedWordOutputSink
+ aOutput(
+ rSink,
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,
+ bInitialSpace ?
+ INetMIMEEncodedWordOutputSink::SPACE_ALWAYS :
+ INetMIMEEncodedWordOutputSink::SPACE_ENCODED,
+ ePreferredEncoding);
+ while (pStart != pBodyPtr)
+ switch (*pStart)
+ {
+ case '"':
+ ++pStart;
+ break;
+
+ case '\\':
+ if (++pStart != pBodyPtr)
+ aOutput << *pStart++;
+ break;
+
+ case '\x0D': // CR
+ pStart += 2;
+ aOutput << *pStart++;
+ break;
+
+ default:
+ aOutput << *pStart++;
+ break;
+ }
+ bInitialSpace = aOutput.flush();
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+
+//============================================================================
+// static
+bool INetMIME::translateUTF8Char(const sal_Char *& rBegin,
+ const sal_Char * pEnd,
+ rtl_TextEncoding eEncoding,
+ sal_uInt32 & rCharacter)
+{
+ if (rBegin == pEnd || static_cast< unsigned char >(*rBegin) < 0x80
+ || static_cast< unsigned char >(*rBegin) >= 0xFE)
+ return false;
+
+ int nCount;
+ sal_uInt32 nMin;
+ sal_uInt32 nUCS4;
+ const sal_Char * p = rBegin;
+ if (static_cast< unsigned char >(*p) < 0xE0)
+ {
+ nCount = 1;
+ nMin = 0x80;
+ nUCS4 = static_cast< unsigned char >(*p) & 0x1F;
+ }
+ else if (static_cast< unsigned char >(*p) < 0xF0)
+ {
+ nCount = 2;
+ nMin = 0x800;
+ nUCS4 = static_cast< unsigned char >(*p) & 0xF;
+ }
+ else if (static_cast< unsigned char >(*p) < 0xF8)
+ {
+ nCount = 3;
+ nMin = 0x10000;
+ nUCS4 = static_cast< unsigned char >(*p) & 7;
+ }
+ else if (static_cast< unsigned char >(*p) < 0xFC)
+ {
+ nCount = 4;
+ nMin = 0x200000;
+ nUCS4 = static_cast< unsigned char >(*p) & 3;
+ }
+ else
+ {
+ nCount = 5;
+ nMin = 0x4000000;
+ nUCS4 = static_cast< unsigned char >(*p) & 1;
+ }
+ ++p;
+
+ for (; nCount-- > 0; ++p)
+ if ((static_cast< unsigned char >(*p) & 0xC0) == 0x80)
+ nUCS4 = (nUCS4 << 6) | (static_cast< unsigned char >(*p) & 0x3F);
+ else
+ return false;
+
+ if (nUCS4 < nMin || nUCS4 > 0x10FFFF)
+ return false;
+
+ if (eEncoding >= RTL_TEXTENCODING_UCS4)
+ rCharacter = nUCS4;
+ else
+ {
+ sal_Unicode aUTF16[2];
+ const sal_Unicode * pUTF16End = putUTF32Character(aUTF16, nUCS4);
+ sal_Size nSize;
+ sal_Char * pBuffer = convertFromUnicode(aUTF16, pUTF16End, eEncoding,
+ nSize);
+ if (!pBuffer)
+ return false;
+ DBG_ASSERT(nSize == 1,
+ "INetMIME::translateUTF8Char(): Bad conversion");
+ rCharacter = *pBuffer;
+ delete[] pBuffer;
+ }
+ rBegin = p;
+ return true;
+}
+
+//============================================================================
+// static
+ByteString INetMIME::decodeUTF8(const ByteString & rText,
+ rtl_TextEncoding eEncoding)
+{
+ const sal_Char * p = rText.GetBuffer();
+ const sal_Char * pEnd = p + rText.Len();
+ ByteString sDecoded;
+ while (p != pEnd)
+ {
+ sal_uInt32 nCharacter;
+ if (translateUTF8Char(p, pEnd, eEncoding, nCharacter))
+ sDecoded += sal_Char(nCharacter);
+ else
+ sDecoded += sal_Char(*p++);
+ }
+ return sDecoded;
+}
+
+//============================================================================
+// static
+UniString INetMIME::decodeHeaderFieldBody(HeaderFieldType eType,
+ const ByteString & rBody)
+{
+ // Due to a bug in INetCoreRFC822MessageStream::ConvertTo7Bit(), old
+ // versions of StarOffice send mails with header fields where encoded
+ // words can be preceded by '=', ',', '.', '"', or '(', and followed by
+ // '=', ',', '.', '"', ')', without any required white space in between.
+ // And there appear to exist some broken mailers that only encode single
+ // letters within words, like "Appel
+ // =?iso-8859-1?Q?=E0?=t=?iso-8859-1?Q?=E9?=moin", so it seems best to
+ // detect encoded words even when not propperly surrounded by white space.
+ //
+ // Non US-ASCII characters in rBody are treated as ISO-8859-1.
+ //
+ // encoded-word = "=?"
+ // 1*(%x21 / %x23-27 / %x2A-2B / %x2D / %30-39 / %x41-5A / %x5E-7E)
+ // ["*" 1*8ALPHA *("-" 1*8ALPHA)] "?"
+ // ("B?" *(4base64) (4base64 / 3base64 "=" / 2base64 "==")
+ // / "Q?" 1*(%x21-3C / %x3E / %x40-7E / "=" 2HEXDIG))
+ // "?="
+ //
+ // base64 = ALPHA / DIGIT / "+" / "/"
+
+ const sal_Char * pBegin = rBody.GetBuffer();
+ const sal_Char * pEnd = pBegin + rBody.Len();
+
+ UniString sDecoded;
+ const sal_Char * pCopyBegin = pBegin;
+
+ /* bool bStartEncodedWord = true; */
+ const sal_Char * pWSPBegin = pBegin;
+ UniString sEncodedText;
+ bool bQuotedEncodedText = false;
+ sal_uInt32 nCommentLevel = 0;
+
+ for (const sal_Char * p = pBegin; p != pEnd;)
+ {
+ if (p != pEnd && *p == '=' /* && bStartEncodedWord */)
+ {
+ const sal_Char * q = p + 1;
+ bool bEncodedWord = q != pEnd && *q++ == '?';
+
+ rtl_TextEncoding eCharsetEncoding = RTL_TEXTENCODING_DONTKNOW;
+ if (bEncodedWord)
+ {
+ const sal_Char * pCharsetBegin = q;
+ const sal_Char * pLanguageBegin = 0;
+ int nAlphaCount = 0;
+ for (bool bDone = false; !bDone;)
+ if (q == pEnd)
+ {
+ bEncodedWord = false;
+ bDone = true;
+ }
+ else
+ {
+ sal_Char cChar = *q++;
+ switch (cChar)
+ {
+ case '*':
+ pLanguageBegin = q - 1;
+ nAlphaCount = 0;
+ break;
+
+ case '-':
+ if (pLanguageBegin != 0)
+ {
+ if (nAlphaCount == 0)
+ pLanguageBegin = 0;
+ else
+ nAlphaCount = 0;
+ }
+ break;
+
+ case '?':
+ if (pCharsetBegin == q - 1)
+ bEncodedWord = false;
+ else
+ {
+ eCharsetEncoding
+ = getCharsetEncoding(
+ pCharsetBegin,
+ pLanguageBegin == 0
+ || nAlphaCount == 0 ?
+ q - 1 : pLanguageBegin);
+ bEncodedWord = isMIMECharsetEncoding(
+ eCharsetEncoding);
+ eCharsetEncoding
+ = translateFromMIME(eCharsetEncoding);
+ }
+ bDone = true;
+ break;
+
+ default:
+ if (pLanguageBegin != 0
+ && (!isAlpha(cChar) || ++nAlphaCount > 8))
+ pLanguageBegin = 0;
+ break;
+ }
+ }
+ }
+
+ bool bEncodingB = false;
+ if (bEncodedWord)
+ {
+ if (q == pEnd)
+ bEncodedWord = false;
+ else
+ {
+ switch (*q++)
+ {
+ case 'B':
+ case 'b':
+ bEncodingB = true;
+ break;
+
+ case 'Q':
+ case 'q':
+ bEncodingB = false;
+ break;
+
+ default:
+ bEncodedWord = false;
+ break;
+ }
+ }
+ }
+
+ bEncodedWord = bEncodedWord && q != pEnd && *q++ == '?';
+
+ ByteString sText;
+ if (bEncodedWord)
+ {
+ if (bEncodingB)
+ {
+ for (bool bDone = false; !bDone;)
+ {
+ if (pEnd - q < 4)
+ {
+ bEncodedWord = false;
+ bDone = true;
+ }
+ else
+ {
+ bool bFinal = false;
+ int nCount = 3;
+ sal_uInt32 nValue = 0;
+ for (int nShift = 18; nShift >= 0; nShift -= 6)
+ {
+ int nWeight = getBase64Weight(*q++);
+ if (nWeight == -2)
+ {
+ bEncodedWord = false;
+ bDone = true;
+ break;
+ }
+ if (nWeight == -1)
+ {
+ if (!bFinal)
+ {
+ if (nShift >= 12)
+ {
+ bEncodedWord = false;
+ bDone = true;
+ break;
+ }
+ bFinal = true;
+ nCount = nShift == 6 ? 1 : 2;
+ }
+ }
+ else
+ nValue |= nWeight << nShift;
+ }
+ if (bEncodedWord)
+ {
+ for (int nShift = 16; nCount-- > 0;
+ nShift -= 8)
+ sText += sal_Char(nValue >> nShift
+ & 0xFF);
+ if (*q == '?')
+ {
+ ++q;
+ bDone = true;
+ }
+ if (bFinal && !bDone)
+ {
+ bEncodedWord = false;
+ bDone = true;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ const sal_Char * pEncodedTextBegin = q;
+ const sal_Char * pEncodedTextCopyBegin = q;
+ for (bool bDone = false; !bDone;)
+ if (q == pEnd)
+ {
+ bEncodedWord = false;
+ bDone = true;
+ }
+ else
+ {
+ sal_uInt32 nChar = *q++;
+ switch (nChar)
+ {
+ case '=':
+ {
+ if (pEnd - q < 2)
+ {
+ bEncodedWord = false;
+ bDone = true;
+ break;
+ }
+ int nDigit1 = getHexWeight(q[0]);
+ int nDigit2 = getHexWeight(q[1]);
+ if (nDigit1 < 0 || nDigit2 < 0)
+ {
+ bEncodedWord = false;
+ bDone = true;
+ break;
+ }
+ sText += rBody.Copy(
+ static_cast< xub_StrLen >(
+ pEncodedTextCopyBegin - pBegin),
+ static_cast< xub_StrLen >(
+ q - 1 - pEncodedTextCopyBegin));
+ sText += sal_Char(nDigit1 << 4 | nDigit2);
+ q += 2;
+ pEncodedTextCopyBegin = q;
+ break;
+ }
+
+ case '?':
+ if (q - pEncodedTextBegin > 1)
+ sText += rBody.Copy(
+ static_cast< xub_StrLen >(
+ pEncodedTextCopyBegin - pBegin),
+ static_cast< xub_StrLen >(
+ q - 1 - pEncodedTextCopyBegin));
+ else
+ bEncodedWord = false;
+ bDone = true;
+ break;
+
+ case '_':
+ sText += rBody.Copy(
+ static_cast< xub_StrLen >(
+ pEncodedTextCopyBegin - pBegin),
+ static_cast< xub_StrLen >(
+ q - 1 - pEncodedTextCopyBegin));
+ sText += ' ';
+ pEncodedTextCopyBegin = q;
+ break;
+
+ default:
+ if (!isVisible(nChar))
+ {
+ bEncodedWord = false;
+ bDone = true;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ bEncodedWord = bEncodedWord && q != pEnd && *q++ == '=';
+
+// if (bEncodedWord && q != pEnd)
+// switch (*q)
+// {
+// case '\t':
+// case ' ':
+// case '"':
+// case ')':
+// case ',':
+// case '.':
+// case '=':
+// break;
+//
+// default:
+// bEncodedWord = false;
+// break;
+// }
+
+ sal_Unicode * pUnicodeBuffer = 0;
+ sal_Size nUnicodeSize = 0;
+ if (bEncodedWord)
+ {
+ pUnicodeBuffer
+ = convertToUnicode(sText.GetBuffer(),
+ sText.GetBuffer() + sText.Len(),
+ eCharsetEncoding, nUnicodeSize);
+ if (pUnicodeBuffer == 0)
+ bEncodedWord = false;
+ }
+
+ if (bEncodedWord)
+ {
+ appendISO88591(sDecoded, pCopyBegin, pWSPBegin);
+ if (eType == HEADER_FIELD_TEXT)
+ sDecoded.Append(
+ pUnicodeBuffer,
+ static_cast< xub_StrLen >(nUnicodeSize));
+ else if (nCommentLevel == 0)
+ {
+ sEncodedText.Append(
+ pUnicodeBuffer,
+ static_cast< xub_StrLen >(nUnicodeSize));
+ if (!bQuotedEncodedText)
+ {
+ const sal_Unicode * pTextPtr = pUnicodeBuffer;
+ const sal_Unicode * pTextEnd = pTextPtr
+ + nUnicodeSize;
+ for (; pTextPtr != pTextEnd; ++pTextPtr)
+ if (!isEncodedWordTokenChar(*pTextPtr))
+ {
+ bQuotedEncodedText = true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ const sal_Unicode * pTextPtr = pUnicodeBuffer;
+ const sal_Unicode * pTextEnd = pTextPtr + nUnicodeSize;
+ for (; pTextPtr != pTextEnd; ++pTextPtr)
+ {
+ switch (*pTextPtr)
+ {
+ case '(':
+ case ')':
+ case '\\':
+ case '\x0D':
+ case '=':
+ sDecoded += '\\';
+ break;
+ }
+ sDecoded += *pTextPtr;
+ }
+ }
+ delete[] pUnicodeBuffer;
+ p = q;
+ pCopyBegin = p;
+
+ pWSPBegin = p;
+ while (p != pEnd && isWhiteSpace(*p))
+ ++p;
+ /* bStartEncodedWord = p != pWSPBegin; */
+ continue;
+ }
+ }
+
+ if (sEncodedText.Len() != 0)
+ {
+ if (bQuotedEncodedText)
+ {
+ sDecoded += '"';
+ const sal_Unicode * pTextPtr = sEncodedText.GetBuffer();
+ const sal_Unicode * pTextEnd = pTextPtr + sEncodedText.Len();
+ for (;pTextPtr != pTextEnd; ++pTextPtr)
+ {
+ switch (*pTextPtr)
+ {
+ case '"':
+ case '\\':
+ case '\x0D':
+ sDecoded += '\\';
+ break;
+ }
+ sDecoded += *pTextPtr;
+ }
+ sDecoded += '"';
+ }
+ else
+ sDecoded += sEncodedText;
+ sEncodedText.Erase();
+ bQuotedEncodedText = false;
+ }
+
+ if (p == pEnd)
+ break;
+
+ switch (*p++)
+ {
+// case '\t':
+// case ' ':
+// case ',':
+// case '.':
+// case '=':
+// bStartEncodedWord = true;
+// break;
+
+ case '"':
+ if (eType != HEADER_FIELD_TEXT && nCommentLevel == 0)
+ {
+ const sal_Char * pQuotedStringEnd
+ = skipQuotedString(p - 1, pEnd);
+ p = pQuotedStringEnd == p - 1 ? pEnd : pQuotedStringEnd;
+ }
+ /* bStartEncodedWord = true; */
+ break;
+
+ case '(':
+ if (eType != HEADER_FIELD_TEXT)
+ ++nCommentLevel;
+ /* bStartEncodedWord = true; */
+ break;
+
+ case ')':
+ if (nCommentLevel > 0)
+ --nCommentLevel;
+ /* bStartEncodedWord = false; */
+ break;
+
+ default:
+ {
+ const sal_Char * pUTF8Begin = p - 1;
+ const sal_Char * pUTF8End = pUTF8Begin;
+ sal_uInt32 nCharacter;
+ if (translateUTF8Char(pUTF8End, pEnd, RTL_TEXTENCODING_UCS4,
+ nCharacter))
+ {
+ appendISO88591(sDecoded, pCopyBegin, p - 1);
+ sal_Unicode aUTF16Buf[2];
+ xub_StrLen nUTF16Len = static_cast< xub_StrLen >(
+ putUTF32Character(aUTF16Buf, nCharacter) - aUTF16Buf);
+ sDecoded.Append(aUTF16Buf, nUTF16Len);
+ p = pUTF8End;
+ pCopyBegin = p;
+ }
+ /* bStartEncodedWord = false; */
+ break;
+ }
+ }
+ pWSPBegin = p;
+ }
+
+ appendISO88591(sDecoded, pCopyBegin, pEnd);
+ return sDecoded;
+}
+
+//============================================================================
+//
+// INetMIMEOutputSink
+//
+//============================================================================
+
+// virtual
+sal_Size INetMIMEOutputSink::writeSequence(const sal_Char * pSequence)
+{
+ sal_Size nLength = rtl_str_getLength(pSequence);
+ writeSequence(pSequence, pSequence + nLength);
+ return nLength;
+}
+
+//============================================================================
+// virtual
+void INetMIMEOutputSink::writeSequence(const sal_uInt32 * pBegin,
+ const sal_uInt32 * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIMEOutputSink::writeSequence(): Bad sequence");
+
+ sal_Char * pBufferBegin = new sal_Char[pEnd - pBegin];
+ sal_Char * pBufferEnd = pBufferBegin;
+ while (pBegin != pEnd)
+ {
+ DBG_ASSERT(*pBegin < 256,
+ "INetMIMEOutputSink::writeSequence(): Bad octet");
+ *pBufferEnd++ = sal_Char(*pBegin++);
+ }
+ writeSequence(pBufferBegin, pBufferEnd);
+ delete[] pBufferBegin;
+}
+
+//============================================================================
+// virtual
+void INetMIMEOutputSink::writeSequence(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIMEOutputSink::writeSequence(): Bad sequence");
+
+ sal_Char * pBufferBegin = new sal_Char[pEnd - pBegin];
+ sal_Char * pBufferEnd = pBufferBegin;
+ while (pBegin != pEnd)
+ {
+ DBG_ASSERT(*pBegin < 256,
+ "INetMIMEOutputSink::writeSequence(): Bad octet");
+ *pBufferEnd++ = sal_Char(*pBegin++);
+ }
+ writeSequence(pBufferBegin, pBufferEnd);
+ delete[] pBufferBegin;
+}
+
+//============================================================================
+// virtual
+ErrCode INetMIMEOutputSink::getError() const
+{
+ return ERRCODE_NONE;
+}
+
+//============================================================================
+void INetMIMEOutputSink::writeLineEnd()
+{
+ static const sal_Char aCRLF[2] = { 0x0D, 0x0A };
+ writeSequence(aCRLF, aCRLF + 2);
+ m_nColumn = 0;
+}
+
+//============================================================================
+//
+// INetMIMEStringOutputSink
+//
+//============================================================================
+
+// virtual
+void INetMIMEStringOutputSink::writeSequence(const sal_Char * pBegin,
+ const sal_Char * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIMEStringOutputSink::writeSequence(): Bad sequence");
+
+ m_bOverflow = m_bOverflow
+ || pEnd - pBegin > STRING_MAXLEN - m_aBuffer.Len();
+ if (!m_bOverflow)
+ m_aBuffer.Append(pBegin, static_cast< xub_StrLen >(pEnd - pBegin));
+}
+
+//============================================================================
+// virtual
+ErrCode INetMIMEStringOutputSink::getError() const
+{
+ return m_bOverflow ? ERRCODE_IO_OUTOFMEMORY : ERRCODE_NONE;
+}
+
+//============================================================================
+//
+// INetMIMEUnicodeOutputSink
+//
+//============================================================================
+
+// virtual
+void INetMIMEUnicodeOutputSink::writeSequence(const sal_Char * pBegin,
+ const sal_Char * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIMEUnicodeOutputSink::writeSequence(): Bad sequence");
+
+ sal_Unicode * pBufferBegin = new sal_Unicode[pEnd - pBegin];
+ sal_Unicode * pBufferEnd = pBufferBegin;
+ while (pBegin != pEnd)
+ *pBufferEnd++ = sal_uChar(*pBegin++);
+ writeSequence(pBufferBegin, pBufferEnd);
+ delete[] pBufferBegin;
+}
+
+//============================================================================
+// virtual
+void INetMIMEUnicodeOutputSink::writeSequence(const sal_uInt32 * pBegin,
+ const sal_uInt32 * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIMEUnicodeOutputSink::writeSequence(): Bad sequence");
+
+ sal_Unicode * pBufferBegin = new sal_Unicode[pEnd - pBegin];
+ sal_Unicode * pBufferEnd = pBufferBegin;
+ while (pBegin != pEnd)
+ {
+ DBG_ASSERT(*pBegin < 256,
+ "INetMIMEOutputSink::writeSequence(): Bad octet");
+ *pBufferEnd++ = sal_Unicode(*pBegin++);
+ }
+ writeSequence(pBufferBegin, pBufferEnd);
+ delete[] pBufferBegin;
+}
+
+//============================================================================
+// virtual
+void INetMIMEUnicodeOutputSink::writeSequence(const sal_Unicode * pBegin,
+ const sal_Unicode * pEnd)
+{
+ DBG_ASSERT(pBegin && pBegin <= pEnd,
+ "INetMIMEUnicodeOutputSink::writeSequence(): Bad sequence");
+
+ m_bOverflow = m_bOverflow
+ || pEnd - pBegin > STRING_MAXLEN - m_aBuffer.Len();
+ if (!m_bOverflow)
+ m_aBuffer.Append(pBegin, static_cast< xub_StrLen >(pEnd - pBegin));
+}
+
+//============================================================================
+// virtual
+ErrCode INetMIMEUnicodeOutputSink::getError() const
+{
+ return m_bOverflow ? ERRCODE_IO_OUTOFMEMORY : ERRCODE_NONE;
+}
+
+//============================================================================
+//
+// INetMIMEEncodedWordOutputSink
+//
+//============================================================================
+
+static const sal_Char aEscape[128]
+ = { INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x00
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x01
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x02
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x03
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x04
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x05
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x06
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x07
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x08
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x09
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x0A
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x0B
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x0C
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x0D
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x0E
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x0F
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x10
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x11
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x12
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x13
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x14
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x15
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x16
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x17
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x18
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x19
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x1A
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x1B
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x1C
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x1D
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x1E
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // 0x1F
+ 0, // ' '
+ 0, // '!'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '"'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '#'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '$'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '%'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '&'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '''
+ INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '('
+ INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // ')'
+ 0, // '*'
+ 0, // '+'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // ','
+ 0, // '-'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '.'
+ 0, // '/'
+ 0, // '0'
+ 0, // '1'
+ 0, // '2'
+ 0, // '3'
+ 0, // '4'
+ 0, // '5'
+ 0, // '6'
+ 0, // '7'
+ 0, // '8'
+ 0, // '9'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // ':'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // ';'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '<'
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '='
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '>'
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '?'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '@'
+ 0, // 'A'
+ 0, // 'B'
+ 0, // 'C'
+ 0, // 'D'
+ 0, // 'E'
+ 0, // 'F'
+ 0, // 'G'
+ 0, // 'H'
+ 0, // 'I'
+ 0, // 'J'
+ 0, // 'K'
+ 0, // 'L'
+ 0, // 'M'
+ 0, // 'N'
+ 0, // 'O'
+ 0, // 'P'
+ 0, // 'Q'
+ 0, // 'R'
+ 0, // 'S'
+ 0, // 'T'
+ 0, // 'U'
+ 0, // 'V'
+ 0, // 'W'
+ 0, // 'X'
+ 0, // 'Y'
+ 0, // 'Z'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '['
+ INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '\'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // ']'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '^'
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '_'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '`'
+ 0, // 'a'
+ 0, // 'b'
+ 0, // 'c'
+ 0, // 'd'
+ 0, // 'e'
+ 0, // 'f'
+ 0, // 'g'
+ 0, // 'h'
+ 0, // 'i'
+ 0, // 'j'
+ 0, // 'k'
+ 0, // 'l'
+ 0, // 'm'
+ 0, // 'n'
+ 0, // 'o'
+ 0, // 'p'
+ 0, // 'q'
+ 0, // 'r'
+ 0, // 's'
+ 0, // 't'
+ 0, // 'u'
+ 0, // 'v'
+ 0, // 'w'
+ 0, // 'x'
+ 0, // 'y'
+ 0, // 'z'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '{'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '|'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '}'
+ INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE, // '~'
+ INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE }; // DEL
+
+inline bool
+INetMIMEEncodedWordOutputSink::needsEncodedWordEscape(sal_uInt32 nChar) const
+{
+ return !INetMIME::isUSASCII(nChar) || aEscape[nChar] & m_eContext;
+}
+
+//============================================================================
+void INetMIMEEncodedWordOutputSink::finish(bool bWriteTrailer)
+{
+ if (m_eInitialSpace == SPACE_ALWAYS && m_nExtraSpaces == 0)
+ m_nExtraSpaces = 1;
+
+ if (m_eEncodedWordState == STATE_SECOND_EQUALS)
+ {
+ // If the text is already an encoded word, copy it verbatim:
+ sal_uInt32 nSize = m_pBufferEnd - m_pBuffer;
+ switch (m_ePrevCoding)
+ {
+ case CODING_QUOTED:
+ m_rSink << '"';
+ case CODING_NONE:
+ if (m_eInitialSpace == SPACE_ENCODED && m_nExtraSpaces == 0)
+ m_nExtraSpaces = 1;
+ for (; m_nExtraSpaces > 1; --m_nExtraSpaces)
+ {
+ if (m_rSink.getColumn() >= m_rSink.getLineLengthLimit())
+ m_rSink << INetMIMEOutputSink::endl;
+ m_rSink << ' ';
+ }
+ if (m_nExtraSpaces == 1)
+ {
+ if (m_rSink.getColumn() + nSize
+ >= m_rSink.getLineLengthLimit())
+ m_rSink << INetMIMEOutputSink::endl;
+ m_rSink << ' ';
+ }
+ break;
+
+ case CODING_ENCODED:
+ {
+ const sal_Char * pCharsetName
+ = INetMIME::getCharsetName(m_ePrevMIMEEncoding);
+ while (m_nExtraSpaces-- > 0)
+ {
+ if (m_rSink.getColumn()
+ > m_rSink.getLineLengthLimit() - 3)
+ m_rSink << "?=" << INetMIMEOutputSink::endl << " =?"
+ << pCharsetName << "?Q?";
+ m_rSink << '_';
+ }
+ m_rSink << "?=";
+ }
+ case CODING_ENCODED_TERMINATED:
+ if (m_rSink.getColumn() + nSize
+ > m_rSink.getLineLengthLimit() - 1)
+ m_rSink << INetMIMEOutputSink::endl;
+ m_rSink << ' ';
+ break;
+ }
+ m_rSink.write(m_pBuffer, m_pBufferEnd);
+ m_eCoding = CODING_ENCODED_TERMINATED;
+ }
+ else
+ {
+ // If the text itself is too long to fit into a single line, make it
+ // into multiple encoded words:
+ switch (m_eCoding)
+ {
+ case CODING_NONE:
+ if (m_nExtraSpaces == 0)
+ {
+ DBG_ASSERT(m_ePrevCoding == CODING_NONE
+ || m_pBuffer == m_pBufferEnd,
+ "INetMIMEEncodedWordOutputSink::finish():"
+ " Bad state");
+ if (m_rSink.getColumn() + (m_pBufferEnd - m_pBuffer)
+ > m_rSink.getLineLengthLimit())
+ m_eCoding = CODING_ENCODED;
+ }
+ else
+ {
+ OSL_ASSERT(m_pBufferEnd >= m_pBuffer);
+ if (static_cast< std::size_t >(m_pBufferEnd - m_pBuffer)
+ > m_rSink.getLineLengthLimit() - 1)
+ {
+ m_eCoding = CODING_ENCODED;
+ }
+ }
+ break;
+
+ case CODING_QUOTED:
+ if (m_nExtraSpaces == 0)
+ {
+ DBG_ASSERT(m_ePrevCoding == CODING_NONE,
+ "INetMIMEEncodedWordOutputSink::finish():"
+ " Bad state");
+ if (m_rSink.getColumn() + (m_pBufferEnd - m_pBuffer)
+ + m_nQuotedEscaped
+ > m_rSink.getLineLengthLimit() - 2)
+ m_eCoding = CODING_ENCODED;
+ }
+ else if ((m_pBufferEnd - m_pBuffer) + m_nQuotedEscaped
+ > m_rSink.getLineLengthLimit() - 3)
+ m_eCoding = CODING_ENCODED;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (m_eCoding)
+ {
+ case CODING_NONE:
+ switch (m_ePrevCoding)
+ {
+ case CODING_QUOTED:
+ if (m_rSink.getColumn() + m_nExtraSpaces
+ + (m_pBufferEnd - m_pBuffer)
+ < m_rSink.getLineLengthLimit())
+ m_eCoding = CODING_QUOTED;
+ else
+ m_rSink << '"';
+ break;
+
+ case CODING_ENCODED:
+ m_rSink << "?=";
+ break;
+
+ default:
+ break;
+ }
+ for (; m_nExtraSpaces > 1; --m_nExtraSpaces)
+ {
+ if (m_rSink.getColumn() >= m_rSink.getLineLengthLimit())
+ m_rSink << INetMIMEOutputSink::endl;
+ m_rSink << ' ';
+ }
+ if (m_nExtraSpaces == 1)
+ {
+ if (m_rSink.getColumn() + (m_pBufferEnd - m_pBuffer)
+ >= m_rSink.getLineLengthLimit())
+ m_rSink << INetMIMEOutputSink::endl;
+ m_rSink << ' ';
+ }
+ m_rSink.write(m_pBuffer, m_pBufferEnd);
+ if (m_eCoding == CODING_QUOTED && bWriteTrailer)
+ {
+ m_rSink << '"';
+ m_eCoding = CODING_NONE;
+ }
+ break;
+
+ case CODING_QUOTED:
+ {
+ bool bInsertLeadingQuote = true;
+ sal_uInt32 nSize = (m_pBufferEnd - m_pBuffer)
+ + m_nQuotedEscaped + 2;
+ switch (m_ePrevCoding)
+ {
+ case CODING_QUOTED:
+ if (m_rSink.getColumn() + m_nExtraSpaces + nSize - 1
+ < m_rSink.getLineLengthLimit())
+ {
+ bInsertLeadingQuote = false;
+ --nSize;
+ }
+ else
+ m_rSink << '"';
+ break;
+
+ case CODING_ENCODED:
+ m_rSink << "?=";
+ break;
+
+ default:
+ break;
+ }
+ for (; m_nExtraSpaces > 1; --m_nExtraSpaces)
+ {
+ if (m_rSink.getColumn() >= m_rSink.getLineLengthLimit())
+ m_rSink << INetMIMEOutputSink::endl;
+ m_rSink << ' ';
+ }
+ if (m_nExtraSpaces == 1)
+ {
+ if (m_rSink.getColumn() + nSize
+ >= m_rSink.getLineLengthLimit())
+ m_rSink << INetMIMEOutputSink::endl;
+ m_rSink << ' ';
+ }
+ if (bInsertLeadingQuote)
+ m_rSink << '"';
+ for (const sal_Unicode * p = m_pBuffer; p != m_pBufferEnd;
+ ++p)
+ {
+ if (INetMIME::needsQuotedStringEscape(*p))
+ m_rSink << '\\';
+ m_rSink << sal_Char(*p);
+ }
+ if (bWriteTrailer)
+ {
+ m_rSink << '"';
+ m_eCoding = CODING_NONE;
+ }
+ break;
+ }
+
+ case CODING_ENCODED:
+ {
+ rtl_TextEncoding eCharsetEncoding
+ = m_pEncodingList->
+ getPreferredEncoding(RTL_TEXTENCODING_UTF8);
+ rtl_TextEncoding eMIMEEncoding
+ = INetMIME::translateToMIME(eCharsetEncoding);
+
+ // The non UTF-8 code will only work for stateless single byte
+ // character encodings (see also below):
+ sal_Char * pTargetBuffer = NULL;
+ sal_Size nTargetSize = 0;
+ sal_uInt32 nSize;
+ if (eMIMEEncoding == RTL_TEXTENCODING_UTF8)
+ {
+ nSize = 0;
+ for (sal_Unicode const * p = m_pBuffer;
+ p != m_pBufferEnd;)
+ {
+ sal_uInt32 nUTF32
+ = INetMIME::getUTF32Character(p, m_pBufferEnd);
+ nSize += needsEncodedWordEscape(nUTF32) ?
+ 3 * INetMIME::getUTF8OctetCount(nUTF32) :
+ 1;
+ // only US-ASCII characters (that are converted to
+ // a single byte by UTF-8) need no encoded word
+ // escapes...
+ }
+ }
+ else
+ {
+ rtl_UnicodeToTextConverter hConverter
+ = rtl_createUnicodeToTextConverter(eCharsetEncoding);
+ rtl_UnicodeToTextContext hContext
+ = rtl_createUnicodeToTextContext(hConverter);
+ for (sal_Size nBufferSize = m_pBufferEnd - m_pBuffer;;
+ nBufferSize += nBufferSize / 3 + 1)
+ {
+ pTargetBuffer = new sal_Char[nBufferSize];
+ sal_uInt32 nInfo;
+ sal_Size nSrcCvtBytes;
+ nTargetSize
+ = rtl_convertUnicodeToText(
+ hConverter, hContext, m_pBuffer,
+ m_pBufferEnd - m_pBuffer, pTargetBuffer,
+ nBufferSize,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE
+ | RTL_UNICODETOTEXT_FLAGS_INVALID_IGNORE,
+ &nInfo, &nSrcCvtBytes);
+ if (!(nInfo
+ & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
+ break;
+ delete[] pTargetBuffer;
+ pTargetBuffer = NULL;
+ rtl_resetUnicodeToTextContext(hConverter, hContext);
+ }
+ rtl_destroyUnicodeToTextContext(hConverter, hContext);
+ rtl_destroyUnicodeToTextConverter(hConverter);
+
+ nSize = nTargetSize;
+ for (sal_Size k = 0; k < nTargetSize; ++k)
+ if (needsEncodedWordEscape(sal_uChar(
+ pTargetBuffer[k])))
+ nSize += 2;
+ }
+
+ const sal_Char * pCharsetName
+ = INetMIME::getCharsetName(eMIMEEncoding);
+ sal_uInt32 nWrapperSize = rtl_str_getLength(pCharsetName) + 7;
+ // '=?', '?Q?', '?='
+
+ switch (m_ePrevCoding)
+ {
+ case CODING_QUOTED:
+ m_rSink << '"';
+ case CODING_NONE:
+ if (m_eInitialSpace == SPACE_ENCODED
+ && m_nExtraSpaces == 0)
+ m_nExtraSpaces = 1;
+ nSize += nWrapperSize;
+ for (; m_nExtraSpaces > 1; --m_nExtraSpaces)
+ {
+ if (m_rSink.getColumn()
+ >= m_rSink.getLineLengthLimit())
+ m_rSink << INetMIMEOutputSink::endl;
+ m_rSink << ' ';
+ }
+ if (m_nExtraSpaces == 1)
+ {
+ if (m_rSink.getColumn() + nSize
+ >= m_rSink.getLineLengthLimit())
+ m_rSink << INetMIMEOutputSink::endl;
+ m_rSink << ' ';
+ }
+ m_rSink << "=?" << pCharsetName << "?Q?";
+ break;
+
+ case CODING_ENCODED:
+ if (m_ePrevMIMEEncoding != eMIMEEncoding
+ || m_rSink.getColumn() + m_nExtraSpaces + nSize
+ > m_rSink.getLineLengthLimit() - 2)
+ {
+ m_rSink << "?=";
+ if (m_rSink.getColumn() + nWrapperSize
+ + m_nExtraSpaces + nSize
+ > m_rSink.getLineLengthLimit() - 1)
+ m_rSink << INetMIMEOutputSink::endl;
+ m_rSink << " =?" << pCharsetName << "?Q?";
+ }
+ while (m_nExtraSpaces-- > 0)
+ {
+ if (m_rSink.getColumn()
+ > m_rSink.getLineLengthLimit() - 3)
+ m_rSink << "?=" << INetMIMEOutputSink::endl
+ << " =?" << pCharsetName << "?Q?";
+ m_rSink << '_';
+ }
+ break;
+
+ case CODING_ENCODED_TERMINATED:
+ if (m_rSink.getColumn() + nWrapperSize
+ + m_nExtraSpaces + nSize
+ > m_rSink.getLineLengthLimit() - 1)
+ m_rSink << INetMIMEOutputSink::endl;
+ m_rSink << " =?" << pCharsetName << "?Q?";
+ while (m_nExtraSpaces-- > 0)
+ {
+ if (m_rSink.getColumn()
+ > m_rSink.getLineLengthLimit() - 3)
+ m_rSink << "?=" << INetMIMEOutputSink::endl
+ << " =?" << pCharsetName << "?Q?";
+ m_rSink << '_';
+ }
+ break;
+ }
+
+ // The non UTF-8 code will only work for stateless single byte
+ // character encodings (see also above):
+ if (eMIMEEncoding == RTL_TEXTENCODING_UTF8)
+ {
+ bool bInitial = true;
+ for (sal_Unicode const * p = m_pBuffer;
+ p != m_pBufferEnd;)
+ {
+ sal_uInt32 nUTF32
+ = INetMIME::getUTF32Character(p, m_pBufferEnd);
+ bool bEscape = needsEncodedWordEscape(nUTF32);
+ sal_uInt32 nWidth
+ = bEscape ?
+ 3 * INetMIME::getUTF8OctetCount(nUTF32) : 1;
+ // only US-ASCII characters (that are converted to
+ // a single byte by UTF-8) need no encoded word
+ // escapes...
+ if (!bInitial
+ && m_rSink.getColumn() + nWidth + 2
+ > m_rSink.getLineLengthLimit())
+ m_rSink << "?=" << INetMIMEOutputSink::endl
+ << " =?" << pCharsetName << "?Q?";
+ if (bEscape)
+ {
+ DBG_ASSERT(
+ nUTF32 < 0x10FFFF,
+ "INetMIMEEncodedWordOutputSink::finish():"
+ " Bad char");
+ if (nUTF32 < 0x80)
+ INetMIME::writeEscapeSequence(m_rSink,
+ nUTF32);
+ else if (nUTF32 < 0x800)
+ {
+ INetMIME::writeEscapeSequence(m_rSink,
+ (nUTF32 >> 6)
+ | 0xC0);
+ INetMIME::writeEscapeSequence(m_rSink,
+ (nUTF32 & 0x3F)
+ | 0x80);
+ }
+ else if (nUTF32 < 0x10000)
+ {
+ INetMIME::writeEscapeSequence(m_rSink,
+ (nUTF32 >> 12)
+ | 0xE0);
+ INetMIME::writeEscapeSequence(m_rSink,
+ ((nUTF32 >> 6)
+ & 0x3F)
+ | 0x80);
+ INetMIME::writeEscapeSequence(m_rSink,
+ (nUTF32 & 0x3F)
+ | 0x80);
+ }
+ else
+ {
+ INetMIME::writeEscapeSequence(m_rSink,
+ (nUTF32 >> 18)
+ | 0xF0);
+ INetMIME::writeEscapeSequence(m_rSink,
+ ((nUTF32 >> 12)
+ & 0x3F)
+ | 0x80);
+ INetMIME::writeEscapeSequence(m_rSink,
+ ((nUTF32 >> 6)
+ & 0x3F)
+ | 0x80);
+ INetMIME::writeEscapeSequence(m_rSink,
+ (nUTF32 & 0x3F)
+ | 0x80);
+ }
+ }
+ else
+ m_rSink << sal_Char(nUTF32);
+ bInitial = false;
+ }
+ }
+ else
+ {
+ for (sal_Size k = 0; k < nTargetSize; ++k)
+ {
+ sal_uInt32 nUCS4 = sal_uChar(pTargetBuffer[k]);
+ bool bEscape = needsEncodedWordEscape(nUCS4);
+ if (k > 0
+ && m_rSink.getColumn() + (bEscape ? 5 : 3)
+ > m_rSink.getLineLengthLimit())
+ m_rSink << "?=" << INetMIMEOutputSink::endl
+ << " =?" << pCharsetName << "?Q?";
+ if (bEscape)
+ INetMIME::writeEscapeSequence(m_rSink, nUCS4);
+ else
+ m_rSink << sal_Char(nUCS4);
+ }
+ delete[] pTargetBuffer;
+ }
+
+ if (bWriteTrailer)
+ {
+ m_rSink << "?=";
+ m_eCoding = CODING_ENCODED_TERMINATED;
+ }
+
+ m_ePrevMIMEEncoding = eMIMEEncoding;
+ break;
+ }
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ }
+
+ m_eInitialSpace = SPACE_NO;
+ m_nExtraSpaces = 0;
+ m_pEncodingList->reset();
+ m_pBufferEnd = m_pBuffer;
+ m_ePrevCoding = m_eCoding;
+ m_eCoding = CODING_NONE;
+ m_nQuotedEscaped = 0;
+ m_eEncodedWordState = STATE_INITIAL;
+}
+
+//============================================================================
+INetMIMEEncodedWordOutputSink::~INetMIMEEncodedWordOutputSink()
+{
+ rtl_freeMemory(m_pBuffer);
+ delete m_pEncodingList;
+}
+
+//============================================================================
+INetMIMEEncodedWordOutputSink &
+INetMIMEEncodedWordOutputSink::operator <<(sal_uInt32 nChar)
+{
+ if (nChar == ' ')
+ {
+ if (m_pBufferEnd != m_pBuffer)
+ finish(false);
+ ++m_nExtraSpaces;
+ }
+ else
+ {
+ // Check for an already encoded word:
+ switch (m_eEncodedWordState)
+ {
+ case STATE_INITIAL:
+ if (nChar == '=')
+ m_eEncodedWordState = STATE_FIRST_EQUALS;
+ else
+ m_eEncodedWordState = STATE_BAD;
+ break;
+
+ case STATE_FIRST_EQUALS:
+ if (nChar == '?')
+ m_eEncodedWordState = STATE_FIRST_EQUALS;
+ else
+ m_eEncodedWordState = STATE_BAD;
+ break;
+
+ case STATE_FIRST_QUESTION:
+ if (INetMIME::isEncodedWordTokenChar(nChar))
+ m_eEncodedWordState = STATE_CHARSET;
+ else
+ m_eEncodedWordState = STATE_BAD;
+ break;
+
+ case STATE_CHARSET:
+ if (nChar == '?')
+ m_eEncodedWordState = STATE_SECOND_QUESTION;
+ else if (!INetMIME::isEncodedWordTokenChar(nChar))
+ m_eEncodedWordState = STATE_BAD;
+ break;
+
+ case STATE_SECOND_QUESTION:
+ if (nChar == 'B' || nChar == 'Q'
+ || nChar == 'b' || nChar == 'q')
+ m_eEncodedWordState = STATE_ENCODING;
+ else
+ m_eEncodedWordState = STATE_BAD;
+ break;
+
+ case STATE_ENCODING:
+ if (nChar == '?')
+ m_eEncodedWordState = STATE_THIRD_QUESTION;
+ else
+ m_eEncodedWordState = STATE_BAD;
+ break;
+
+ case STATE_THIRD_QUESTION:
+ if (INetMIME::isVisible(nChar) && nChar != '?')
+ m_eEncodedWordState = STATE_ENCODED_TEXT;
+ else
+ m_eEncodedWordState = STATE_BAD;
+ break;
+
+ case STATE_ENCODED_TEXT:
+ if (nChar == '?')
+ m_eEncodedWordState = STATE_FOURTH_QUESTION;
+ else if (!INetMIME::isVisible(nChar))
+ m_eEncodedWordState = STATE_BAD;
+ break;
+
+ case STATE_FOURTH_QUESTION:
+ if (nChar == '=')
+ m_eEncodedWordState = STATE_SECOND_EQUALS;
+ else
+ m_eEncodedWordState = STATE_BAD;
+ break;
+
+ case STATE_SECOND_EQUALS:
+ m_eEncodedWordState = STATE_BAD;
+ break;
+
+ case STATE_BAD:
+ break;
+ }
+
+ // Update encoding:
+ m_pEncodingList->includes(nChar);
+
+ // Update coding:
+ enum { TENQ = 1, // CONTEXT_TEXT, CODING_ENCODED
+ CENQ = 2, // CONTEXT_COMMENT, CODING_ENCODED
+ PQTD = 4, // CONTEXT_PHRASE, CODING_QUOTED
+ PENQ = 8 }; // CONTEXT_PHRASE, CODING_ENCODED
+ static const sal_Char aMinimal[128]
+ = { TENQ | CENQ | PENQ, // 0x00
+ TENQ | CENQ | PENQ, // 0x01
+ TENQ | CENQ | PENQ, // 0x02
+ TENQ | CENQ | PENQ, // 0x03
+ TENQ | CENQ | PENQ, // 0x04
+ TENQ | CENQ | PENQ, // 0x05
+ TENQ | CENQ | PENQ, // 0x06
+ TENQ | CENQ | PENQ, // 0x07
+ TENQ | CENQ | PENQ, // 0x08
+ TENQ | CENQ | PENQ, // 0x09
+ TENQ | CENQ | PENQ, // 0x0A
+ TENQ | CENQ | PENQ, // 0x0B
+ TENQ | CENQ | PENQ, // 0x0C
+ TENQ | CENQ | PENQ, // 0x0D
+ TENQ | CENQ | PENQ, // 0x0E
+ TENQ | CENQ | PENQ, // 0x0F
+ TENQ | CENQ | PENQ, // 0x10
+ TENQ | CENQ | PENQ, // 0x11
+ TENQ | CENQ | PENQ, // 0x12
+ TENQ | CENQ | PENQ, // 0x13
+ TENQ | CENQ | PENQ, // 0x14
+ TENQ | CENQ | PENQ, // 0x15
+ TENQ | CENQ | PENQ, // 0x16
+ TENQ | CENQ | PENQ, // 0x17
+ TENQ | CENQ | PENQ, // 0x18
+ TENQ | CENQ | PENQ, // 0x19
+ TENQ | CENQ | PENQ, // 0x1A
+ TENQ | CENQ | PENQ, // 0x1B
+ TENQ | CENQ | PENQ, // 0x1C
+ TENQ | CENQ | PENQ, // 0x1D
+ TENQ | CENQ | PENQ, // 0x1E
+ TENQ | CENQ | PENQ, // 0x1F
+ 0, // ' '
+ 0, // '!'
+ PQTD , // '"'
+ 0, // '#'
+ 0, // '$'
+ 0, // '%'
+ 0, // '&'
+ 0, // '''
+ CENQ | PQTD , // '('
+ CENQ | PQTD , // ')'
+ 0, // '*'
+ 0, // '+'
+ PQTD , // ','
+ 0, // '-'
+ PQTD , // '.'
+ 0, // '/'
+ 0, // '0'
+ 0, // '1'
+ 0, // '2'
+ 0, // '3'
+ 0, // '4'
+ 0, // '5'
+ 0, // '6'
+ 0, // '7'
+ 0, // '8'
+ 0, // '9'
+ PQTD , // ':'
+ PQTD , // ';'
+ PQTD , // '<'
+ 0, // '='
+ PQTD , // '>'
+ 0, // '?'
+ PQTD , // '@'
+ 0, // 'A'
+ 0, // 'B'
+ 0, // 'C'
+ 0, // 'D'
+ 0, // 'E'
+ 0, // 'F'
+ 0, // 'G'
+ 0, // 'H'
+ 0, // 'I'
+ 0, // 'J'
+ 0, // 'K'
+ 0, // 'L'
+ 0, // 'M'
+ 0, // 'N'
+ 0, // 'O'
+ 0, // 'P'
+ 0, // 'Q'
+ 0, // 'R'
+ 0, // 'S'
+ 0, // 'T'
+ 0, // 'U'
+ 0, // 'V'
+ 0, // 'W'
+ 0, // 'X'
+ 0, // 'Y'
+ 0, // 'Z'
+ PQTD , // '['
+ CENQ | PQTD , // '\'
+ PQTD , // ']'
+ 0, // '^'
+ 0, // '_'
+ 0, // '`'
+ 0, // 'a'
+ 0, // 'b'
+ 0, // 'c'
+ 0, // 'd'
+ 0, // 'e'
+ 0, // 'f'
+ 0, // 'g'
+ 0, // 'h'
+ 0, // 'i'
+ 0, // 'j'
+ 0, // 'k'
+ 0, // 'l'
+ 0, // 'm'
+ 0, // 'n'
+ 0, // 'o'
+ 0, // 'p'
+ 0, // 'q'
+ 0, // 'r'
+ 0, // 's'
+ 0, // 't'
+ 0, // 'u'
+ 0, // 'v'
+ 0, // 'w'
+ 0, // 'x'
+ 0, // 'y'
+ 0, // 'z'
+ 0, // '{'
+ 0, // '|'
+ 0, // '}'
+ 0, // '~'
+ TENQ | CENQ | PENQ }; // DEL
+ Coding eNewCoding = !INetMIME::isUSASCII(nChar) ? CODING_ENCODED :
+ m_eContext == CONTEXT_PHRASE ?
+ Coding(aMinimal[nChar] >> 2) :
+ aMinimal[nChar] & m_eContext ? CODING_ENCODED :
+ CODING_NONE;
+ if (eNewCoding > m_eCoding)
+ m_eCoding = eNewCoding;
+ if (m_eCoding == CODING_QUOTED
+ && INetMIME::needsQuotedStringEscape(nChar))
+ ++m_nQuotedEscaped;
+
+ // Append to buffer:
+ if (sal_uInt32(m_pBufferEnd - m_pBuffer) == m_nBufferSize)
+ {
+ m_pBuffer
+ = static_cast< sal_Unicode * >(
+ rtl_reallocateMemory(m_pBuffer,
+ (m_nBufferSize + BUFFER_SIZE)
+ * sizeof (sal_Unicode)));
+ m_pBufferEnd = m_pBuffer + m_nBufferSize;
+ m_nBufferSize += BUFFER_SIZE;
+ }
+ *m_pBufferEnd++ = sal_Unicode(nChar);
+ }
+ return *this;
+}
+
+//============================================================================
+//
+// INetContentTypeParameterList
+//
+//============================================================================
+
+void INetContentTypeParameterList::Clear()
+{
+ while (Count() > 0)
+ delete static_cast< INetContentTypeParameter * >(Remove(Count() - 1));
+}
+
+//============================================================================
+const INetContentTypeParameter *
+INetContentTypeParameterList::find(const ByteString & rAttribute) const
+{
+ for (ULONG i = 0; i < Count(); ++i)
+ {
+ const INetContentTypeParameter * pParameter = GetObject(i);
+ if (pParameter->m_sAttribute.EqualsIgnoreCaseAscii(rAttribute))
+ return pParameter;
+ }
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/inet/inetmsg.cxx b/tools/source/inet/inetmsg.cxx
new file mode 100644
index 000000000000..241957ab8823
--- /dev/null
+++ b/tools/source/inet/inetmsg.cxx
@@ -0,0 +1,1646 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <sal/types.h>
+#include <tools/datetime.hxx>
+#include <tools/inetmime.hxx>
+#include <tools/inetmsg.hxx>
+#include <tools/inetstrm.hxx>
+#include <rtl/instance.hxx>
+
+#include <stdio.h>
+
+//=======================================================================
+
+inline sal_Bool ascii_isDigit( sal_Unicode ch )
+{
+ return ((ch >= 0x0030) && (ch <= 0x0039));
+}
+
+inline sal_Bool ascii_isLetter( sal_Unicode ch )
+{
+ return (( (ch >= 0x0041) && (ch <= 0x005A)) || ((ch >= 0x0061) && (ch <= 0x007A)));
+}
+
+inline sal_Unicode ascii_toLowerCase( sal_Unicode ch )
+{
+ if ( (ch >= 0x0041) && (ch <= 0x005A) )
+ return ch + 0x20;
+ else
+ return ch;
+}
+
+/*=======================================================================
+ *
+ * INetMessage Implementation.
+ *
+ *=====================================================================*/
+#define CONSTASCII_STRINGPARAM(a) (a), RTL_TEXTENCODING_ASCII_US
+#define HEADERFIELD INetMessageHeader
+
+/*
+ * ~INetMessage.
+ */
+INetMessage::~INetMessage (void)
+{
+ ListCleanup_Impl();
+}
+
+/*
+ * ListCleanup_Impl.
+ */
+void INetMessage::ListCleanup_Impl (void)
+{
+ // Cleanup.
+ ULONG i, n = m_aHeaderList.Count();
+ for (i = 0; i < n; i++)
+ delete ((HEADERFIELD*)(m_aHeaderList.GetObject(i)));
+ m_aHeaderList.Clear();
+}
+
+/*
+ * ListCopy.
+ */
+void INetMessage::ListCopy (const INetMessage &rMsg)
+{
+ if (!(this == &rMsg))
+ {
+ // Cleanup.
+ ListCleanup_Impl();
+
+ // Copy.
+ ULONG i, n = rMsg.GetHeaderCount();
+ for (i = 0; i < n; i++)
+ {
+ HEADERFIELD *p = (HEADERFIELD*)(rMsg.m_aHeaderList.GetObject(i));
+ m_aHeaderList.Insert (new HEADERFIELD(*p), LIST_APPEND);
+ }
+ }
+}
+
+/*
+ * SetHeaderField_Impl.
+ */
+void INetMessage::SetHeaderField_Impl (
+ INetMIME::HeaderFieldType eType,
+ const ByteString &rName,
+ const UniString &rValue,
+ ULONG &rnIndex)
+{
+ INetMIMEStringOutputSink aSink (0, STRING_MAXLEN);
+ INetMIME::writeHeaderFieldBody (
+ aSink, eType, rValue, gsl_getSystemTextEncoding(), false);
+ SetHeaderField_Impl (
+ INetMessageHeader (rName, aSink.takeBuffer()), rnIndex);
+}
+
+/*
+ * SetHeaderField.
+ */
+ULONG INetMessage::SetHeaderField (
+ const UniString& rName, const UniString& rValue, ULONG nIndex)
+{
+ ULONG nResult = nIndex;
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_TEXT,
+ ByteString (rName, RTL_TEXTENCODING_ASCII_US), rValue,
+ nResult);
+ return nResult;
+}
+
+/*
+ * SetHeaderField.
+ */
+ULONG INetMessage::SetHeaderField (
+ const INetMessageHeader &rHeader, ULONG nIndex)
+{
+ ULONG nResult = nIndex;
+ SetHeaderField_Impl (rHeader, nResult);
+ return nResult;
+}
+
+
+/*
+ * operator<<
+ */
+SvStream& INetMessage::operator<< (SvStream& rStrm) const
+{
+ rStrm << static_cast<sal_uInt32>(m_nDocSize);
+ rStrm.WriteByteString (m_aDocName, RTL_TEXTENCODING_UTF8);
+
+ ULONG i, n = m_aHeaderList.Count();
+ rStrm << static_cast<sal_uInt32>(n);
+
+ for (i = 0; i < n; i++)
+ rStrm << *((HEADERFIELD *)(m_aHeaderList.GetObject(i)));
+
+ return rStrm;
+}
+
+/*
+ * operator>>
+ */
+SvStream& INetMessage::operator>> (SvStream& rStrm)
+{
+ // Cleanup.
+ m_nDocSize = 0;
+ m_xDocLB.Clear();
+ ListCleanup_Impl();
+
+ sal_uInt32 nTemp;
+
+ // Copy.
+ rStrm >> nTemp;
+ m_nDocSize = nTemp;
+ rStrm.ReadByteString (m_aDocName, RTL_TEXTENCODING_UTF8);
+
+ ULONG i, n = 0;
+ rStrm >> nTemp;
+ n = nTemp;
+
+ for (i = 0; i < n; i++)
+ {
+ HEADERFIELD *p = new HEADERFIELD();
+ rStrm >> *p;
+ m_aHeaderList.Insert (p, LIST_APPEND);
+ }
+
+ // Done.
+ return rStrm;
+}
+
+/*=======================================================================
+ *
+ * INetMessageHeaderIterator Implementation.
+ *
+ *=====================================================================*/
+INetMessageHeaderIterator::INetMessageHeaderIterator (
+ const INetMessage& rMsg, const UniString& rHdrName)
+{
+ ULONG i, n = rMsg.GetHeaderCount();
+ for (i = 0; i < n; i++)
+ {
+ if (rHdrName.CompareIgnoreCaseToAscii (rMsg.GetHeaderName(i)) == 0)
+ {
+ UniString *pValue = new UniString (rMsg.GetHeaderValue(i));
+ aValueList.Insert (pValue, LIST_APPEND);
+ }
+ }
+ nValueCount = aValueList.Count();
+}
+
+INetMessageHeaderIterator::~INetMessageHeaderIterator (void)
+{
+ ULONG i, n = aValueList.Count();
+ for (i = 0; i < n; i++)
+ delete ((UniString*)(aValueList.GetObject(i)));
+ aValueList.Clear();
+}
+
+/*=======================================================================
+ *
+ * INetRFC822Message Implementation.
+ *
+ *=====================================================================*/
+/*
+ * ImplINetRFC822MessageHeaderData.
+ */
+namespace
+{
+ struct ImplINetRFC822MessageHeaderDataImpl
+ {
+ const ByteString* operator()()
+ {
+ static const ByteString _ImplINetRFC822MessageHeaderData[] =
+ {
+ ByteString ("BCC"),
+ ByteString ("CC"),
+ ByteString ("Comments"),
+ ByteString ("Date"),
+ ByteString ("From"),
+ ByteString ("In-Reply-To"),
+ ByteString ("Keywords"),
+ ByteString ("Message-ID"),
+ ByteString ("References"),
+ ByteString ("Reply-To"),
+ ByteString ("Return-Path"),
+ ByteString ("Subject"),
+ ByteString ("Sender"),
+ ByteString ("To"),
+ ByteString ("X-Mailer"),
+ ByteString ("Return-Receipt-To")
+ };
+ return &_ImplINetRFC822MessageHeaderData[0];
+ }
+ };
+
+ struct ImplINetRFC822MessageHeaderData
+ : public rtl::StaticAggregate< const ByteString, ImplINetRFC822MessageHeaderDataImpl > {};
+}
+
+#define HDR(n) ImplINetRFC822MessageHeaderData::get()[(n)]
+
+/*
+ * _ImplINetRFC822MessageHeaderState.
+ */
+enum _ImplINetRFC822MessageHeaderState
+{
+ INETMSG_RFC822_BEGIN,
+ INETMSG_RFC822_CHECK,
+ INETMSG_RFC822_OK,
+ INETMSG_RFC822_JUNK,
+
+ INETMSG_RFC822_TOKEN_RE,
+ INETMSG_RFC822_TOKEN_RETURNMINUS,
+ INETMSG_RFC822_TOKEN_XMINUS,
+ INETMSG_RFC822_LETTER_C,
+ INETMSG_RFC822_LETTER_S
+};
+
+/*
+ * INetRFC822Message.
+ */
+INetRFC822Message::INetRFC822Message (void)
+ : INetMessage()
+{
+ for (USHORT i = 0; i < INETMSG_RFC822_NUMHDR; i++)
+ m_nIndex[i] = LIST_ENTRY_NOTFOUND;
+}
+
+INetRFC822Message::INetRFC822Message (const INetRFC822Message& rMsg)
+ : INetMessage (rMsg)
+{
+ for (USHORT i = 0; i < INETMSG_RFC822_NUMHDR; i++)
+ m_nIndex[i] = rMsg.m_nIndex[i];
+}
+
+/*
+ * operator=
+ */
+INetRFC822Message& INetRFC822Message::operator= (const INetRFC822Message& rMsg)
+{
+ if (this != &rMsg)
+ {
+ INetMessage::operator= (rMsg);
+
+ for (USHORT i = 0; i < INETMSG_RFC822_NUMHDR; i++)
+ m_nIndex[i] = rMsg.m_nIndex[i];
+ }
+ return *this;
+}
+
+/*
+ * ~INetRFC822Message.
+ */
+INetRFC822Message::~INetRFC822Message (void)
+{
+}
+
+/*
+ * <Generate|Parse>DateField and local helper functions.
+ *
+ * GenerateDateField.
+ * Generates a String from Date and Time objects in format:
+ * Wkd, 00 Mon 0000 00:00:00 [GMT] (rfc822, rfc1123)
+ *
+ * ParseDateField.
+ * Parses a String in (implied) GMT format into class Date and Time objects.
+ * Four formats are accepted:
+ *
+ * [Wkd,] 1*2DIGIT Mon 2*4DIGIT 00:00:00 [GMT] (rfc1123)
+ * [Wkd,] 00 Mon 0000 00:00:00 [GMT]) (rfc822, rfc1123)
+ * Weekday, 00-Mon-00 00:00:00 [GMT] (rfc850, rfc1036)
+ * Wkd Mon 00 00:00:00 0000 [GMT] (ctime)
+ * 1*DIGIT (delta seconds)
+ *
+ */
+
+// Months and Weekdays.
+static const sal_Char *months[12] =
+{
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+static const sal_Char *wkdays[7] =
+{
+ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
+};
+
+/*
+ * GenerateDateField.
+ */
+BOOL INetRFC822Message::GenerateDateField (
+ const DateTime& rDateTime, UniString& rDateFieldW)
+{
+ // Check arguments.
+ if (!rDateTime.IsValid() ||
+ (rDateTime.GetSec() > 59) ||
+ (rDateTime.GetMin() > 59) ||
+ (rDateTime.GetHour() > 23) ) return FALSE;
+
+ // Prepare output string.
+ ByteString rDateField;
+
+ // Insert Date.
+ rDateField += wkdays[(USHORT)(rDateTime.GetDayOfWeek())];
+ rDateField += ", ";
+
+ USHORT nNum = rDateTime.GetDay();
+ if (nNum < 10) rDateField += '0';
+ rDateField += ByteString::CreateFromInt32(nNum);
+ rDateField += ' ';
+
+ rDateField += months[(USHORT)(rDateTime.GetMonth() - 1)];
+ rDateField += ' ';
+
+ rDateField += ByteString::CreateFromInt32(rDateTime.GetYear());
+ rDateField += ' ';
+
+ // Insert Time.
+ nNum = rDateTime.GetHour();
+ if (nNum < 10) rDateField += '0';
+ rDateField += ByteString::CreateFromInt32(nNum);
+ rDateField += ':';
+
+ nNum = rDateTime.GetMin();
+ if (nNum < 10) rDateField += '0';
+ rDateField += ByteString::CreateFromInt32(nNum);
+ rDateField += ':';
+
+ nNum = rDateTime.GetSec();
+ if (nNum < 10) rDateField += '0';
+ rDateField += ByteString::CreateFromInt32(nNum);
+ rDateField += " GMT";
+
+ // Done.
+ rDateFieldW = UniString (rDateField, RTL_TEXTENCODING_ASCII_US);
+ return TRUE;
+}
+
+/*
+ * ParseDateField and local helper functions.
+ */
+static USHORT ParseNumber (const ByteString& rStr, USHORT& nIndex)
+{
+ USHORT n = nIndex;
+ while ((n < rStr.Len()) && ascii_isDigit(rStr.GetChar(n))) n++;
+
+ ByteString aNum (rStr.Copy (nIndex, (n - nIndex)));
+ nIndex = n;
+
+ return (USHORT)(aNum.ToInt32());
+}
+
+static USHORT ParseMonth (const ByteString& rStr, USHORT& nIndex)
+{
+ USHORT n = nIndex;
+ while ((n < rStr.Len()) && ascii_isLetter(rStr.GetChar(n))) n++;
+
+ ByteString aMonth (rStr.Copy (nIndex, 3));
+ nIndex = n;
+
+ USHORT i;
+ for (i = 0; i < 12; i++)
+ if (aMonth.CompareIgnoreCaseToAscii (months[i]) == 0) break;
+ return (i + 1);
+}
+
+BOOL INetRFC822Message::ParseDateField (
+ const UniString& rDateFieldW, DateTime& rDateTime)
+{
+ ByteString rDateField (rDateFieldW, RTL_TEXTENCODING_ASCII_US);
+ if (rDateField.Len() == 0) return FALSE;
+
+ if (rDateField.Search (':') != STRING_NOTFOUND)
+ {
+ // Some DateTime format.
+ USHORT nIndex = 0;
+
+ // Skip over <Wkd> or <Weekday>, leading and trailing space.
+ while ((nIndex < rDateField.Len()) &&
+ (rDateField.GetChar(nIndex) == ' '))
+ nIndex++;
+
+ while (
+ (nIndex < rDateField.Len()) &&
+ (ascii_isLetter (rDateField.GetChar(nIndex)) ||
+ (rDateField.GetChar(nIndex) == ',') ))
+ nIndex++;
+
+ while ((nIndex < rDateField.Len()) &&
+ (rDateField.GetChar(nIndex) == ' '))
+ nIndex++;
+
+ if (ascii_isLetter (rDateField.GetChar(nIndex)))
+ {
+ // Format: ctime().
+ if ((rDateField.Len() - nIndex) < 20) return FALSE;
+
+ rDateTime.SetMonth (ParseMonth (rDateField, nIndex)); nIndex++;
+ rDateTime.SetDay (ParseNumber (rDateField, nIndex)); nIndex++;
+
+ rDateTime.SetHour (ParseNumber (rDateField, nIndex)); nIndex++;
+ rDateTime.SetMin (ParseNumber (rDateField, nIndex)); nIndex++;
+ rDateTime.SetSec (ParseNumber (rDateField, nIndex)); nIndex++;
+ rDateTime.Set100Sec (0);
+
+ USHORT nYear = ParseNumber (rDateField, nIndex);
+ if (nYear < 100) nYear += 1900;
+ rDateTime.SetYear (nYear);
+ }
+ else
+ {
+ // Format: RFC1036 or RFC1123.
+ if ((rDateField.Len() - nIndex) < 17) return FALSE;
+
+ rDateTime.SetDay (ParseNumber (rDateField, nIndex)); nIndex++;
+ rDateTime.SetMonth (ParseMonth (rDateField, nIndex)); nIndex++;
+
+ USHORT nYear = ParseNumber (rDateField, nIndex); nIndex++;
+ if (nYear < 100) nYear += 1900;
+ rDateTime.SetYear (nYear);
+
+ rDateTime.SetHour (ParseNumber (rDateField, nIndex)); nIndex++;
+ rDateTime.SetMin (ParseNumber (rDateField, nIndex)); nIndex++;
+ rDateTime.SetSec (ParseNumber (rDateField, nIndex)); nIndex++;
+ rDateTime.Set100Sec (0);
+
+ if ((rDateField.GetChar(nIndex) == '+') ||
+ (rDateField.GetChar(nIndex) == '-') )
+ {
+ // Offset from GMT: "(+|-)HHMM".
+ BOOL bEast = (rDateField.GetChar(nIndex++) == '+');
+ USHORT nOffset = ParseNumber (rDateField, nIndex);
+ if (nOffset > 0)
+ {
+ Time aDiff;
+ aDiff.SetHour (nOffset / 100);
+ aDiff.SetMin (nOffset % 100);
+ aDiff.SetSec (0);
+ aDiff.Set100Sec (0);
+
+ if (bEast)
+ rDateTime -= aDiff;
+ else
+ rDateTime += aDiff;
+ }
+ }
+ }
+ }
+ else if (rDateField.IsNumericAscii())
+ {
+ // Format: delta seconds.
+ Time aDelta (0);
+ aDelta.SetTime (rDateField.ToInt32() * 100);
+
+ DateTime aNow;
+ aNow += aDelta;
+ aNow.ConvertToUTC();
+
+ rDateTime.SetDate (aNow.GetDate());
+ rDateTime.SetTime (aNow.GetTime());
+ }
+ else
+ {
+ // Junk.
+ return FALSE;
+ }
+
+ return (rDateTime.IsValid() &&
+ !((rDateTime.GetSec() > 59) ||
+ (rDateTime.GetMin() > 59) ||
+ (rDateTime.GetHour() > 23) ));
+}
+
+/*
+ * SetHeaderField.
+ * (Header Field Parser).
+ */
+ULONG INetRFC822Message::SetHeaderField (
+ const INetMessageHeader &rHeader, ULONG nNewIndex)
+{
+ ByteString aName (rHeader.GetName());
+ const sal_Char *pData = aName.GetBuffer();
+ const sal_Char *pStop = pData + aName.Len() + 1;
+ const sal_Char *check = "";
+
+ ULONG nIdx = LIST_APPEND;
+ int eState = INETMSG_RFC822_BEGIN;
+ int eOkState = INETMSG_RFC822_OK;
+
+ while (pData < pStop)
+ {
+ switch (eState)
+ {
+ case INETMSG_RFC822_BEGIN:
+ eState = INETMSG_RFC822_CHECK;
+ eOkState = INETMSG_RFC822_OK;
+
+ switch (ascii_toLowerCase (*pData))
+ {
+ case 'b':
+ check = "cc";
+ nIdx = INETMSG_RFC822_BCC;
+ break;
+
+ case 'c':
+ eState = INETMSG_RFC822_LETTER_C;
+ break;
+
+ case 'd':
+ check = "ate";
+ nIdx = INETMSG_RFC822_DATE;
+ break;
+
+ case 'f':
+ check = "rom";
+ nIdx = INETMSG_RFC822_FROM;
+ break;
+
+ case 'i':
+ check = "n-reply-to";
+ nIdx = INETMSG_RFC822_IN_REPLY_TO;
+ break;
+
+ case 'k':
+ check = "eywords";
+ nIdx = INETMSG_RFC822_KEYWORDS;
+ break;
+
+ case 'm':
+ check = "essage-id";
+ nIdx = INETMSG_RFC822_MESSAGE_ID;
+ break;
+
+ case 'r':
+ check = "e";
+ eOkState = INETMSG_RFC822_TOKEN_RE;
+ break;
+
+ case 's':
+ eState = INETMSG_RFC822_LETTER_S;
+ break;
+
+ case 't':
+ check = "o";
+ nIdx = INETMSG_RFC822_TO;
+ break;
+
+ case 'x':
+ check = "-";
+ eOkState = INETMSG_RFC822_TOKEN_XMINUS;
+ break;
+
+ default:
+ eState = INETMSG_RFC822_JUNK;
+ break;
+ }
+ pData++;
+ break;
+
+ case INETMSG_RFC822_TOKEN_RE:
+ eState = INETMSG_RFC822_CHECK;
+ eOkState = INETMSG_RFC822_OK;
+
+ switch (ascii_toLowerCase (*pData))
+ {
+ case 'f':
+ check = "erences";
+ nIdx = INETMSG_RFC822_REFERENCES;
+ break;
+
+ case 'p':
+ check = "ly-to";
+ nIdx = INETMSG_RFC822_REPLY_TO;
+ break;
+
+ case 't':
+ check = "urn-";
+ eOkState = INETMSG_RFC822_TOKEN_RETURNMINUS;
+ break;
+
+ default:
+ eState = INETMSG_RFC822_JUNK;
+ break;
+ }
+ pData++;
+ break;
+
+ case INETMSG_RFC822_TOKEN_RETURNMINUS:
+ eState = INETMSG_RFC822_CHECK;
+ eOkState = INETMSG_RFC822_OK;
+
+ switch (ascii_toLowerCase (*pData))
+ {
+ case 'p':
+ check = "ath";
+ nIdx = INETMSG_RFC822_RETURN_PATH;
+ break;
+
+ case 'r':
+ check = "eceipt-to";
+ nIdx = INETMSG_RFC822_RETURN_RECEIPT_TO;
+ break;
+
+ default:
+ eState = INETMSG_RFC822_JUNK;
+ break;
+ }
+ pData++;
+ break;
+
+ case INETMSG_RFC822_TOKEN_XMINUS:
+ eState = INETMSG_RFC822_CHECK;
+ eOkState = INETMSG_RFC822_OK;
+
+ switch (ascii_toLowerCase (*pData))
+ {
+ case 'm':
+ check = "ailer";
+ nIdx = INETMSG_RFC822_X_MAILER;
+ break;
+
+ default:
+ eState = INETMSG_RFC822_JUNK;
+ break;
+ }
+ pData++;
+ break;
+
+ case INETMSG_RFC822_LETTER_C:
+ eState = INETMSG_RFC822_CHECK;
+ eOkState = INETMSG_RFC822_OK;
+
+ switch (ascii_toLowerCase (*pData))
+ {
+ case 'c':
+ check = "";
+ nIdx = INETMSG_RFC822_CC;
+ break;
+
+ case 'o':
+ check = "mments";
+ nIdx = INETMSG_RFC822_COMMENTS;
+ break;
+
+ default:
+ eState = INETMSG_RFC822_JUNK;
+ break;
+ }
+ pData++;
+ break;
+
+ case INETMSG_RFC822_LETTER_S:
+ eState = INETMSG_RFC822_CHECK;
+ eOkState = INETMSG_RFC822_OK;
+
+ switch (ascii_toLowerCase (*pData))
+ {
+ case 'e':
+ check = "nder";
+ nIdx = INETMSG_RFC822_SENDER;
+ break;
+
+ case 'u':
+ check = "bject";
+ nIdx = INETMSG_RFC822_SUBJECT;
+ break;
+
+ default:
+ eState = INETMSG_RFC822_JUNK;
+ break;
+ }
+ pData++;
+ break;
+
+ case INETMSG_RFC822_CHECK:
+ if (*check)
+ {
+ while (*pData && *check &&
+ (ascii_toLowerCase (*pData) == *check))
+ {
+ pData++;
+ check++;
+ }
+ }
+ else
+ {
+ check = pData;
+ }
+ eState = (*check == '\0') ? eOkState : INETMSG_RFC822_JUNK;
+ break;
+
+ case INETMSG_RFC822_OK:
+ pData = pStop;
+ SetHeaderField_Impl (
+ HEADERFIELD (HDR(nIdx), rHeader.GetValue()),
+ m_nIndex[nIdx]);
+ nNewIndex = m_nIndex[nIdx];
+ break;
+
+ default: // INETMSG_RFC822_JUNK
+ pData = pStop;
+ nNewIndex = INetMessage::SetHeaderField (rHeader, nNewIndex);
+ break;
+ }
+ }
+ return nNewIndex;
+}
+
+/*
+ * Specific Set-Methods.
+ */
+void INetRFC822Message::SetBCC (const UniString& rBCC)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_ADDRESS,
+ HDR(INETMSG_RFC822_BCC), rBCC,
+ m_nIndex[INETMSG_RFC822_BCC]);
+}
+
+void INetRFC822Message::SetCC (const UniString& rCC)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_ADDRESS,
+ HDR(INETMSG_RFC822_CC), rCC,
+ m_nIndex[INETMSG_RFC822_CC]);
+}
+
+void INetRFC822Message::SetComments (const UniString& rComments)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_TEXT,
+ HDR(INETMSG_RFC822_COMMENTS), rComments,
+ m_nIndex[INETMSG_RFC822_COMMENTS]);
+}
+
+void INetRFC822Message::SetDate (const UniString& rDate)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_STRUCTURED,
+ HDR(INETMSG_RFC822_DATE), rDate,
+ m_nIndex[INETMSG_RFC822_DATE]);
+}
+
+void INetRFC822Message::SetFrom (const UniString& rFrom)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_ADDRESS,
+ HDR(INETMSG_RFC822_FROM), rFrom,
+ m_nIndex[INETMSG_RFC822_FROM]);
+}
+
+void INetRFC822Message::SetInReplyTo (const UniString& rInReplyTo)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_ADDRESS, // ??? MESSAGE_ID ???
+ HDR(INETMSG_RFC822_IN_REPLY_TO), rInReplyTo,
+ m_nIndex[INETMSG_RFC822_IN_REPLY_TO]);
+}
+
+void INetRFC822Message::SetKeywords (const UniString& rKeywords)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_PHRASE,
+ HDR(INETMSG_RFC822_KEYWORDS), rKeywords,
+ m_nIndex[INETMSG_RFC822_KEYWORDS]);
+}
+
+void INetRFC822Message::SetMessageID (const UniString& rMessageID)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_MESSAGE_ID,
+ HDR(INETMSG_RFC822_MESSAGE_ID), rMessageID,
+ m_nIndex[INETMSG_RFC822_MESSAGE_ID]);
+}
+
+void INetRFC822Message::SetReferences (const UniString& rReferences)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_MESSAGE_ID,
+ HDR(INETMSG_RFC822_REFERENCES), rReferences,
+ m_nIndex[INETMSG_RFC822_REFERENCES]);
+}
+
+void INetRFC822Message::SetReplyTo (const UniString& rReplyTo)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_ADDRESS,
+ HDR(INETMSG_RFC822_REPLY_TO), rReplyTo,
+ m_nIndex[INETMSG_RFC822_REPLY_TO]);
+}
+
+void INetRFC822Message::SetReturnPath (const UniString& rReturnPath)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_ADDRESS,
+ HDR(INETMSG_RFC822_RETURN_PATH), rReturnPath,
+ m_nIndex[INETMSG_RFC822_RETURN_PATH]);
+}
+
+void INetRFC822Message::SetReturnReceiptTo (const UniString& rValue)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_ADDRESS,
+ HDR(INETMSG_RFC822_RETURN_RECEIPT_TO), rValue,
+ m_nIndex[INETMSG_RFC822_RETURN_RECEIPT_TO]);
+}
+
+void INetRFC822Message::SetSender (const UniString& rSender)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_ADDRESS,
+ HDR(INETMSG_RFC822_SENDER), rSender,
+ m_nIndex[INETMSG_RFC822_SENDER]);
+}
+
+void INetRFC822Message::SetSubject (const UniString& rSubject)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_TEXT,
+ HDR(INETMSG_RFC822_SUBJECT), rSubject,
+ m_nIndex[INETMSG_RFC822_SUBJECT]);
+}
+
+void INetRFC822Message::SetTo (const UniString& rTo)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_ADDRESS,
+ HDR(INETMSG_RFC822_TO), rTo,
+ m_nIndex[INETMSG_RFC822_TO]);
+}
+
+void INetRFC822Message::SetXMailer (const UniString& rXMailer)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_TEXT,
+ HDR(INETMSG_RFC822_X_MAILER), rXMailer,
+ m_nIndex[INETMSG_RFC822_X_MAILER]);
+}
+
+/*
+ * operator<<
+ */
+SvStream& INetRFC822Message::operator<< (SvStream& rStrm) const
+{
+ INetMessage::operator<< (rStrm);
+
+ for (USHORT i = 0; i < INETMSG_RFC822_NUMHDR; i++)
+ rStrm << static_cast<sal_uInt32>(m_nIndex[i]);
+
+ return rStrm;
+}
+
+/*
+ * operator>>
+ */
+SvStream& INetRFC822Message::operator>> (SvStream& rStrm)
+{
+ INetMessage::operator>> (rStrm);
+
+ sal_uInt32 nTemp;
+ for (USHORT i = 0; i < INETMSG_RFC822_NUMHDR; i++)
+ {
+ rStrm >> nTemp;
+ m_nIndex[i] = nTemp;
+ }
+
+ return rStrm;
+}
+
+/*=======================================================================
+ *
+ * INetMIMEMessage Implementation.
+ *
+ *=====================================================================*/
+/*
+ * _ImplINetMIMEMessageHeaderData.
+ */
+namespace
+{
+ struct ImplINetMIMEMessageHeaderDataImpl
+ {
+ const ByteString* operator()()
+ {
+ static const ByteString _ImplINetMIMEMessageHeaderData[] =
+ {
+ ByteString ("MIME-Version"),
+ ByteString ("Content-Description"),
+ ByteString ("Content-Disposition"),
+ ByteString ("Content-ID"),
+ ByteString ("Content-Type"),
+ ByteString ("Content-Transfer-Encoding")
+ };
+ return &_ImplINetMIMEMessageHeaderData[0];
+ }
+ };
+
+ struct ImplINetMIMEMessageHeaderData
+ : public rtl::StaticAggregate< const ByteString, ImplINetMIMEMessageHeaderDataImpl > {};
+}
+
+#define MIMEHDR(n) ImplINetMIMEMessageHeaderData::get()[(n)]
+
+/*
+ * _ImplINetMIMEMessageHeaderState.
+ */
+enum _ImplINetMIMEMessageHeaderState
+{
+ INETMSG_MIME_BEGIN,
+ INETMSG_MIME_CHECK,
+ INETMSG_MIME_OK,
+ INETMSG_MIME_JUNK,
+
+ INETMSG_MIME_TOKEN_CONTENT,
+ INETMSG_MIME_TOKEN_CONTENT_D,
+ INETMSG_MIME_TOKEN_CONTENT_T
+};
+
+/*
+ * INetMIMEMessage.
+ */
+INetMIMEMessage::INetMIMEMessage (void)
+ : INetRFC822Message (),
+ pParent (NULL),
+ nNumChildren (0),
+ bHeaderParsed (FALSE)
+{
+ for (USHORT i = 0; i < INETMSG_MIME_NUMHDR; i++)
+ m_nIndex[i] = LIST_ENTRY_NOTFOUND;
+}
+
+INetMIMEMessage::INetMIMEMessage (const INetMIMEMessage& rMsg)
+ : INetRFC822Message (rMsg)
+{
+ // Copy.
+ CopyImp (rMsg);
+}
+
+/*
+ * operator=
+ */
+INetMIMEMessage& INetMIMEMessage::operator= (
+ const INetMIMEMessage& rMsg)
+{
+ if (this != &rMsg)
+ {
+ // Assign base.
+ INetRFC822Message::operator= (rMsg);
+
+ // Cleanup.
+ CleanupImp();
+
+ // Copy.
+ CopyImp (rMsg);
+ }
+ return *this;
+}
+
+/*
+ * ~INetMIMEMessage.
+ */
+INetMIMEMessage::~INetMIMEMessage (void)
+{
+ // Cleanup.
+ CleanupImp();
+}
+
+/*
+ * CleanupImp.
+ */
+void INetMIMEMessage::CleanupImp (void)
+{
+ INetMIMEMessage *pChild = NULL;
+ while ((pChild = (INetMIMEMessage *)(aChildren.Remove())) != NULL)
+ if (pChild->pParent == this) delete pChild;
+}
+
+/*
+ * CopyImp.
+ */
+void INetMIMEMessage::CopyImp (const INetMIMEMessage& rMsg)
+{
+ bHeaderParsed = rMsg.bHeaderParsed;
+
+ USHORT i;
+ for (i = 0; i < INETMSG_MIME_NUMHDR; i++)
+ m_nIndex[i] = rMsg.m_nIndex[i];
+
+ m_aBoundary = rMsg.m_aBoundary;
+ nNumChildren = rMsg.nNumChildren;
+
+ for (i = 0; i < rMsg.aChildren.Count(); i++)
+ {
+ INetMIMEMessage *pChild =
+ (INetMIMEMessage *)(rMsg.aChildren.GetObject (i));
+
+ if (pChild->pParent == &rMsg)
+ {
+ pChild = pChild->CreateMessage (*pChild);
+ pChild->pParent = this;
+ }
+ aChildren.Insert (pChild, LIST_APPEND);
+ }
+}
+
+/*
+ * CreateMessage.
+ */
+INetMIMEMessage *INetMIMEMessage::CreateMessage (
+ const INetMIMEMessage& rMsg) const
+{
+ return (new INetMIMEMessage (rMsg));
+}
+
+/*
+ * SetHeaderField.
+ * (Header Field Parser).
+ */
+ULONG INetMIMEMessage::SetHeaderField (
+ const INetMessageHeader &rHeader, ULONG nNewIndex)
+{
+ ByteString aName (rHeader.GetName());
+ const sal_Char *pData = aName.GetBuffer();
+ const sal_Char *pStop = pData + aName.Len() + 1;
+ const sal_Char *check = "";
+
+ ULONG nIdx = LIST_APPEND;
+ int eState = INETMSG_MIME_BEGIN;
+ int eOkState = INETMSG_MIME_OK;
+
+ while (pData < pStop)
+ {
+ switch (eState)
+ {
+ case INETMSG_MIME_BEGIN:
+ eState = INETMSG_MIME_CHECK;
+ eOkState = INETMSG_MIME_OK;
+
+ switch (ascii_toLowerCase (*pData))
+ {
+ case 'c':
+ check = "ontent-";
+ eOkState = INETMSG_MIME_TOKEN_CONTENT;
+ break;
+
+ case 'm':
+ check = "ime-version";
+ nIdx = INETMSG_MIME_VERSION;
+ break;
+
+ default:
+ eState = INETMSG_MIME_JUNK;
+ break;
+ }
+ pData++;
+ break;
+
+ case INETMSG_MIME_TOKEN_CONTENT:
+ eState = INETMSG_MIME_CHECK;
+ eOkState = INETMSG_MIME_OK;
+
+ switch (ascii_toLowerCase (*pData))
+ {
+ case 'd':
+ eState = INETMSG_MIME_TOKEN_CONTENT_D;
+ break;
+
+ case 'i':
+ check = "d";
+ nIdx = INETMSG_MIME_CONTENT_ID;
+ break;
+
+ case 't':
+ eState = INETMSG_MIME_TOKEN_CONTENT_T;
+ break;
+
+ default:
+ eState = INETMSG_MIME_JUNK;
+ break;
+ }
+ pData++;
+ break;
+
+ case INETMSG_MIME_TOKEN_CONTENT_D:
+ eState = INETMSG_MIME_CHECK;
+ eOkState = INETMSG_MIME_OK;
+
+ switch (ascii_toLowerCase (*pData))
+ {
+ case 'e':
+ check = "scription";
+ nIdx = INETMSG_MIME_CONTENT_DESCRIPTION;
+ break;
+
+ case 'i':
+ check = "sposition";
+ nIdx = INETMSG_MIME_CONTENT_DISPOSITION;
+ break;
+
+ default:
+ eState = INETMSG_MIME_JUNK;
+ break;
+ }
+ pData++;
+ break;
+
+ case INETMSG_MIME_TOKEN_CONTENT_T:
+ eState = INETMSG_MIME_CHECK;
+ eOkState = INETMSG_MIME_OK;
+
+ switch (ascii_toLowerCase (*pData))
+ {
+ case 'r':
+ check = "ansfer-encoding";
+ nIdx = INETMSG_MIME_CONTENT_TRANSFER_ENCODING;
+ break;
+
+ case 'y':
+ check = "pe";
+ nIdx = INETMSG_MIME_CONTENT_TYPE;
+ break;
+
+ default:
+ eState = INETMSG_MIME_JUNK;
+ break;
+ }
+ pData++;
+ break;
+
+ case INETMSG_MIME_CHECK:
+ if (*check)
+ {
+ while (*pData && *check &&
+ (ascii_toLowerCase (*pData) == *check))
+ {
+ pData++;
+ check++;
+ }
+ }
+ else
+ {
+ check = pData;
+ }
+ eState = (*check == '\0') ? eOkState : INETMSG_MIME_JUNK;
+ break;
+
+ case INETMSG_MIME_OK:
+ pData = pStop;
+ SetHeaderField_Impl (
+ HEADERFIELD (MIMEHDR(nIdx), rHeader.GetValue()),
+ m_nIndex[nIdx]);
+ nNewIndex = m_nIndex[nIdx];
+ break;
+
+ default: // INETMSG_MIME_JUNK
+ pData = pStop;
+ nNewIndex = INetRFC822Message::SetHeaderField (
+ rHeader, nNewIndex);
+ break;
+ }
+ }
+ return nNewIndex;
+}
+
+/*
+ * Specific Set-Methods.
+ */
+void INetMIMEMessage::SetMIMEVersion (const UniString& rVersion)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_TEXT,
+ MIMEHDR(INETMSG_MIME_VERSION), rVersion,
+ m_nIndex[INETMSG_MIME_VERSION]);
+}
+
+void INetMIMEMessage::SetContentDescription (const String& rDescription)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_TEXT,
+ MIMEHDR(INETMSG_MIME_CONTENT_DESCRIPTION), rDescription,
+ m_nIndex[INETMSG_MIME_CONTENT_DESCRIPTION]);
+}
+
+void INetMIMEMessage::SetContentDisposition (const String& rDisposition)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_TEXT,
+ MIMEHDR(INETMSG_MIME_CONTENT_DISPOSITION), rDisposition,
+ m_nIndex[INETMSG_MIME_CONTENT_DISPOSITION]);
+}
+
+void INetMIMEMessage::SetContentID (const String& rID)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_TEXT,
+ MIMEHDR(INETMSG_MIME_CONTENT_ID), rID,
+ m_nIndex[INETMSG_MIME_CONTENT_ID]);
+}
+
+void INetMIMEMessage::SetContentType (const String& rType)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_TEXT,
+ MIMEHDR(INETMSG_MIME_CONTENT_TYPE), rType,
+ m_nIndex[INETMSG_MIME_CONTENT_TYPE]);
+}
+
+void INetMIMEMessage::SetContentTransferEncoding (
+ const String& rEncoding)
+{
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_TEXT,
+ MIMEHDR(INETMSG_MIME_CONTENT_TRANSFER_ENCODING), rEncoding,
+ m_nIndex[INETMSG_MIME_CONTENT_TRANSFER_ENCODING]);
+}
+
+/*
+ * GetDefaultContentType.
+ */
+void INetMIMEMessage::GetDefaultContentType (String& rContentType)
+{
+ String aDefaultCT (
+ "text/plain; charset=us-ascii", RTL_TEXTENCODING_ASCII_US);
+ if (pParent == NULL)
+ {
+ rContentType = aDefaultCT;
+ }
+ else
+ {
+ String aParentCT (pParent->GetContentType());
+ if (aParentCT.Len() == 0)
+ pParent->GetDefaultContentType (aParentCT);
+
+ if (aParentCT.CompareIgnoreCaseToAscii ("message/", 8) == 0)
+ {
+ rContentType = aDefaultCT;
+ }
+ else if (aParentCT.CompareIgnoreCaseToAscii ("multipart/", 10) == 0)
+ {
+ if (aParentCT.CompareIgnoreCaseToAscii ("multipart/digest") == 0)
+ rContentType.AssignAscii ("message/rfc822");
+ else
+ rContentType = aDefaultCT;
+ }
+ else
+ {
+ rContentType = aDefaultCT;
+ }
+ }
+}
+
+/*
+ * EnableAttachChild.
+ */
+BOOL INetMIMEMessage::EnableAttachChild (INetMessageContainerType eType)
+{
+ // Check context.
+ if (IsContainer())
+ return FALSE;
+
+ // Setup Content-Type header field.
+ ByteString aContentType;
+ switch (eType)
+ {
+ case INETMSG_MESSAGE_RFC822:
+ aContentType = "message/rfc822";
+ break;
+
+ case INETMSG_MULTIPART_ALTERNATIVE:
+ aContentType = "multipart/alternative";
+ break;
+
+ case INETMSG_MULTIPART_DIGEST:
+ aContentType = "multipart/digest";
+ break;
+
+ case INETMSG_MULTIPART_PARALLEL:
+ aContentType = "multipart/parallel";
+ break;
+
+ case INETMSG_MULTIPART_RELATED:
+ aContentType = "multipart/related";
+ break;
+
+ case INETMSG_MULTIPART_FORM_DATA:
+ aContentType = "multipart/form-data";
+ break;
+
+ default:
+ aContentType = "multipart/mixed";
+ break;
+ }
+
+ // Setup boundary for multipart types.
+ if (aContentType.CompareIgnoreCaseToAscii ("multipart/", 10) == 0)
+ {
+ // Generate a unique boundary from current time.
+ sal_Char sTail[16 + 1];
+ Time aCurTime;
+ sal_uInt64 nThis = reinterpret_cast< sal_uIntPtr >( this ); // we can be on a 64bit architecture
+ nThis = ( ( nThis >> 32 ) ^ nThis ) & SAL_MAX_UINT32;
+ sprintf (sTail, "%08X%08X",
+ static_cast< unsigned int >(aCurTime.GetTime()),
+ static_cast< unsigned int >(nThis));
+ m_aBoundary = "------------_4D48";
+ m_aBoundary += sTail;
+
+ // Append boundary as ContentType parameter.
+ aContentType += "; boundary=";
+ aContentType += m_aBoundary;
+ }
+
+ // Set header fields.
+ SetMIMEVersion (String (CONSTASCII_STRINGPARAM("1.0")));
+ SetContentType (String (aContentType, RTL_TEXTENCODING_ASCII_US));
+ SetContentTransferEncoding (String (CONSTASCII_STRINGPARAM("7bit")));
+
+ // Done.
+ return TRUE;
+}
+
+/*
+ * AttachChild.
+ */
+BOOL INetMIMEMessage::AttachChild (
+ INetMIMEMessage& rChildMsg, BOOL bOwner)
+{
+ if (IsContainer() /*&& rChildMsg.GetContentType().Len() */)
+ {
+ if (bOwner) rChildMsg.pParent = this;
+ aChildren.Insert (&rChildMsg, LIST_APPEND);
+ nNumChildren = aChildren.Count();
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * DetachChild.
+ */
+BOOL INetMIMEMessage::DetachChild (
+ ULONG nIndex, INetMIMEMessage& rChildMsg) const
+{
+ if (IsContainer())
+ {
+ // Check document stream.
+ if (GetDocumentLB() == NULL) return FALSE;
+ SvStream *pDocStrm = new SvStream (GetDocumentLB());
+
+ // Initialize message buffer.
+ char pMsgBuffer[1024];
+ char *pMsgRead, *pMsgWrite;
+ pMsgRead = pMsgWrite = pMsgBuffer;
+
+ // Initialize message parser stream.
+ INetMIMEMessageStream *pMsgStrm = NULL;
+
+ // Check for "multipart/uvw" or "message/xyz".
+ if (IsMultipart())
+ {
+ // Multipart message body. Initialize multipart delimiters.
+ ByteString aDelim ("--");
+ aDelim += GetMultipartBoundary();
+ ByteString aClose = aDelim;
+ aClose += "--";
+
+ // Initialize line buffer.
+ SvMemoryStream aLineBuf;
+
+ // Initialize control variables.
+ INetMessageStreamState eState = INETMSG_EOL_SCR;
+ int nCurIndex = -1;
+
+ // Go!
+ while (nCurIndex < (int)(nIndex + 1))
+ {
+ if ((pMsgRead - pMsgWrite) > 0)
+ {
+ // Bytes still in buffer.
+ if (eState == INETMSG_EOL_FCR)
+ {
+ // Check for 2nd line break character.
+ if ((*pMsgWrite == '\r') || (*pMsgWrite == '\n'))
+ aLineBuf << *pMsgWrite++;
+
+ // Check current index.
+ if (nCurIndex == (int)nIndex)
+ {
+ // Found requested part.
+ if (pMsgStrm == NULL)
+ {
+ // Create message parser stream.
+ pMsgStrm = new INetMIMEMessageStream;
+ pMsgStrm->SetTargetMessage (&rChildMsg);
+ }
+
+ // Put message down-stream.
+ int status = pMsgStrm->Write (
+ (const sal_Char *) aLineBuf.GetData(), aLineBuf.Tell());
+ if (status != INETSTREAM_STATUS_OK)
+ {
+ // Cleanup.
+ delete pDocStrm;
+ delete pMsgStrm;
+
+ // Finish.
+ return (!(status == INETSTREAM_STATUS_OK));
+ }
+ }
+
+ // Reset to <Begin-of-Line>.
+ aLineBuf.Seek (STREAM_SEEK_TO_BEGIN);
+ eState = INETMSG_EOL_SCR;
+ }
+ else if ((*pMsgWrite == '\r') || (*pMsgWrite == '\n'))
+ {
+ /*
+ * Found any line break character.
+ * Compare buffered line with part/close delimiter.
+ * Increment current part index upon match.
+ */
+ USHORT nLen = (USHORT)(aLineBuf.Tell() & 0xffff);
+ if (nLen == aDelim.Len())
+ {
+ if (aDelim.CompareTo ((const sal_Char *) aLineBuf.GetData(), nLen)
+ == COMPARE_EQUAL) nCurIndex++;
+ }
+ else if (nLen == aClose.Len())
+ {
+ if (aClose.CompareTo ((const sal_Char *) aLineBuf.GetData(), nLen)
+ == COMPARE_EQUAL) nCurIndex++;
+ }
+ aLineBuf << *pMsgWrite++;
+ eState = INETMSG_EOL_FCR;
+ }
+ else
+ {
+ // Insert into line buffer.
+ aLineBuf << *pMsgWrite;
+ }
+ }
+ else
+ {
+ // Buffer empty. Reset to <Begin-of-Buffer>.
+ pMsgRead = pMsgWrite = pMsgBuffer;
+
+ // Read document stream.
+ ULONG nRead = pDocStrm->Read (
+ pMsgBuffer, sizeof (pMsgBuffer));
+ if (nRead > 0)
+ {
+ // Set read pointer.
+ pMsgRead += nRead;
+ }
+ else
+ {
+ // Premature end.
+ if (pMsgStrm)
+ {
+ // Assume end of requested part.
+ nCurIndex++;
+ }
+ else
+ {
+ // Requested part not found.
+ delete pDocStrm;
+ return FALSE;
+ }
+ }
+ }
+ } // while (nCurIndex < (nIndex + 1))
+ }
+ else
+ {
+ // Encapsulated message body. Create message parser stream.
+ pMsgStrm = new INetMIMEMessageStream;
+ pMsgStrm->SetTargetMessage (&rChildMsg);
+
+ // Initialize control variables.
+ INetMessageStreamState eState = INETMSG_EOL_BEGIN;
+
+ // Go.
+ while (eState == INETMSG_EOL_BEGIN)
+ {
+ if ((pMsgRead - pMsgWrite) > 0)
+ {
+ // Bytes still in buffer. Put message down-stream.
+ int status = pMsgStrm->Write (
+ pMsgBuffer, (pMsgRead - pMsgWrite));
+ if (status != INETSTREAM_STATUS_OK)
+ {
+ // Cleanup.
+ delete pDocStrm;
+ delete pMsgStrm;
+
+ // Finish.
+ return (!(status == INETSTREAM_STATUS_ERROR));
+ }
+ pMsgWrite = pMsgBuffer + (pMsgRead - pMsgWrite);
+ }
+ else
+ {
+ // Buffer empty. Reset to <Begin-of-Buffer>.
+ pMsgRead = pMsgWrite = pMsgBuffer;
+
+ // Read document stream.
+ ULONG nRead = pDocStrm->Read (
+ pMsgBuffer, sizeof (pMsgBuffer));
+ if (nRead > 0)
+ {
+ // Set read pointer.
+ pMsgRead += nRead;
+ }
+ else
+ {
+ // Mark we're done.
+ eState = INETMSG_EOL_DONE;
+ }
+ }
+ } // while (eState == INETMSG_EOL_BEGIN)
+ }
+
+ // Done.
+ if (pDocStrm) delete pDocStrm;
+ if (pMsgStrm) delete pMsgStrm;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * operator<<
+ */
+SvStream& INetMIMEMessage::operator<< (SvStream& rStrm) const
+{
+ INetRFC822Message::operator<< (rStrm);
+
+ for (USHORT i = 0; i < INETMSG_MIME_NUMHDR; i++)
+ rStrm << static_cast<sal_uInt32>(m_nIndex[i]);
+
+#ifdef ENABLE_BYTESTRING_STREAM_OPERATORS
+ rStrm << m_aBoundary;
+#else
+ rStrm.WriteByteString (m_aBoundary);
+#endif
+ rStrm << static_cast<sal_uInt32>(nNumChildren);
+
+ return rStrm;
+}
+
+/*
+ * operator>>
+ */
+SvStream& INetMIMEMessage::operator>> (SvStream& rStrm)
+{
+ INetRFC822Message::operator>> (rStrm);
+
+ sal_uInt32 nTemp;
+ for (USHORT i = 0; i < INETMSG_MIME_NUMHDR; i++)
+ {
+ rStrm >> nTemp;
+ m_nIndex[i] = nTemp;
+ }
+
+#ifdef ENABLE_BYTESTRING_STREAM_OPERATORS
+ rStrm >> m_aBoundary;
+#else
+ rStrm.ReadByteString (m_aBoundary);
+#endif
+ rStrm >> nTemp;
+ nNumChildren = nTemp;
+
+ return rStrm;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/inet/inetstrm.cxx b/tools/source/inet/inetstrm.cxx
new file mode 100644
index 000000000000..b681e7978217
--- /dev/null
+++ b/tools/source/inet/inetstrm.cxx
@@ -0,0 +1,1823 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <sal/types.h>
+#include <rtl/memory.h>
+#include <tools/cachestr.hxx>
+#include <tools/debug.hxx>
+#include <tools/inetmsg.hxx>
+#include <tools/inetstrm.hxx>
+
+#include <ctype.h> // toupper
+
+inline sal_Bool SAL_CALL ascii_isWhitespace( sal_Unicode ch )
+{
+ return ((ch <= 0x20) && ch);
+}
+
+#define CONSTASCII_STRINGPARAM(a) (a), RTL_TEXTENCODING_ASCII_US
+
+/*=======================================================================
+ *
+ * INetMessageEncodeQPStream Interface.
+ * (Quoted-Printable Encoding)
+ *
+ *=====================================================================*/
+class INetMessageEncodeQPStream_Impl : public INetMessageIStream
+{
+ SvStream *pMsgStrm;
+
+ ULONG nMsgBufSiz;
+ sal_Char *pMsgBuffer;
+ sal_Char *pMsgRead;
+ sal_Char *pMsgWrite;
+
+ ULONG nTokBufSiz;
+ sal_Char *pTokBuffer;
+ sal_Char *pTokRead;
+ sal_Char *pTokWrite;
+
+ INetMessageStreamState eState;
+ BOOL bDone;
+
+ virtual int GetMsgLine (sal_Char *pData, ULONG nSize);
+
+public:
+ INetMessageEncodeQPStream_Impl (ULONG nMsgBufferSize = 1024);
+ virtual ~INetMessageEncodeQPStream_Impl (void);
+};
+
+/*=====================================================================
+ *
+ * INetMessageDecodeQPStream Interface.
+ * (Quoted-Printable Decoding)
+ *
+ *====================================================================*/
+class INetMessageDecodeQPStream_Impl : public INetMessageOStream
+{
+ INetMessageStreamState eState;
+ SvMemoryStream *pMsgBuffer;
+
+ ULONG nTokBufLen;
+ sal_Char pTokBuffer[4];
+
+ virtual int PutMsgLine (const sal_Char *pData, ULONG nSize);
+
+public:
+ INetMessageDecodeQPStream_Impl (void);
+ virtual ~INetMessageDecodeQPStream_Impl (void);
+};
+
+/*======================================================================
+ *
+ * INetMessageEncode64Stream Interface.
+ * (Base64 Encoding)
+ *
+ *====================================================================*/
+class INetMessageEncode64Stream_Impl : public INetMessageIStream
+{
+ SvStream *pMsgStrm;
+
+ ULONG nMsgBufSiz;
+ sal_uInt8 *pMsgBuffer;
+ sal_uInt8 *pMsgRead;
+ sal_uInt8 *pMsgWrite;
+
+ ULONG nTokBufSiz;
+ sal_Char *pTokBuffer;
+ sal_Char *pTokRead;
+ sal_Char *pTokWrite;
+
+ BOOL bDone;
+
+ virtual int GetMsgLine (sal_Char *pData, ULONG nSize);
+
+public:
+ INetMessageEncode64Stream_Impl (ULONG nMsgBufferSize = 2048);
+ virtual ~INetMessageEncode64Stream_Impl (void);
+};
+
+/*======================================================================
+ *
+ * INetMessageDecode64Stream Interface.
+ * (Base64 Decoding)
+ *
+ *====================================================================*/
+class INetMessageDecode64Stream_Impl : public INetMessageOStream
+{
+ INetMessageStreamState eState;
+
+ ULONG nMsgBufSiz;
+ sal_Char *pMsgBuffer;
+ sal_Char *pMsgRead;
+ sal_Char *pMsgWrite;
+
+ virtual int PutMsgLine (const sal_Char *pData, ULONG nSize);
+
+public:
+ INetMessageDecode64Stream_Impl (ULONG nMsgBufferSize = 128);
+ virtual ~INetMessageDecode64Stream_Impl (void);
+};
+
+/*=========================================================================
+ *
+ * INetIStream Implementation.
+ *
+ *=======================================================================*/
+/*
+ * INetIStream.
+ */
+INetIStream::INetIStream ()
+{
+}
+
+/*
+ * ~INetIStream.
+ */
+INetIStream::~INetIStream (void)
+{
+}
+
+/*
+ * Read.
+ */
+int INetIStream::Read (sal_Char *pData, ULONG nSize)
+{
+ return GetData (pData, nSize);
+}
+
+/*
+ * Decode64.
+ */
+void INetIStream::Decode64 (SvStream& rIn, SvStream& rOut)
+{
+ INetMessage aMsg;
+ aMsg.SetDocumentLB(new SvAsyncLockBytes(&rOut, FALSE));
+
+ INetMessageDecode64Stream_Impl aStream (8192);
+ aStream.SetTargetMessage (&aMsg);
+
+ sal_Char* pBuf = new sal_Char[8192];
+
+ int nRead = 0;
+ while ((nRead = rIn.Read (pBuf, 8192)) > 0)
+ aStream.Write( pBuf, nRead );
+ aStream.Write ("\r\n", 2);
+
+ delete[] pBuf;
+}
+
+/*
+ * Encode64.
+ */
+void INetIStream::Encode64 (SvStream& rIn, SvStream& rOut)
+{
+ INetMessage aMsg;
+ aMsg.SetDocumentLB (
+ new SvLockBytes (&rIn, FALSE));
+
+ INetMessageEncode64Stream_Impl aStream (8192);
+ aStream.SetSourceMessage (&aMsg);
+
+ sal_Char* pBuf = new sal_Char[8192];
+
+ int nRead = 0;
+ while ((nRead = aStream.Read (pBuf, 8192)) > 0)
+ rOut.Write( pBuf, nRead );
+
+ delete[] pBuf;
+}
+
+/*=========================================================================
+ *
+ * INetOStream Implementation.
+ *
+ *=======================================================================*/
+/*
+ * INetOStream.
+ */
+INetOStream::INetOStream ()
+{
+}
+
+/*
+ * ~INetOStream.
+ */
+INetOStream::~INetOStream (void)
+{
+}
+
+/*
+ * Write.
+ */
+int INetOStream::Write (const sal_Char *pData, ULONG nSize)
+{
+ return PutData (pData, nSize);
+}
+
+/*=========================================================================
+ *
+ * INetMessageIStream Implementation.
+ *
+ *=======================================================================*/
+/*
+ * INetMessageIStream.
+ */
+INetMessageIStream::INetMessageIStream (ULONG nBufferSize)
+ : pSourceMsg (NULL),
+ bHeaderGenerated (FALSE),
+ nBufSiz (nBufferSize),
+ pMsgStrm (NULL),
+ pMsgBuffer (new SvMemoryStream)
+{
+ pMsgBuffer->SetStreamCharSet (RTL_TEXTENCODING_ASCII_US);
+ pBuffer = new sal_Char[nBufSiz];
+ pRead = pWrite = pBuffer;
+}
+
+/*
+ * ~INetMessageIStream.
+ */
+INetMessageIStream::~INetMessageIStream (void)
+{
+ delete [] pBuffer;
+ delete pMsgBuffer;
+ delete pMsgStrm;
+}
+
+/*
+ * GetData.
+ */
+int INetMessageIStream::GetData (sal_Char *pData, ULONG nSize)
+{
+ if (pSourceMsg == NULL) return INETSTREAM_STATUS_ERROR;
+
+ sal_Char *pWBuf = pData;
+ sal_Char *pWEnd = pData + nSize;
+
+ while (pWBuf < pWEnd)
+ {
+ // Caller's buffer not yet filled.
+ ULONG n = pRead - pWrite;
+ if (n > 0)
+ {
+ // Bytes still in buffer.
+ ULONG m = pWEnd - pWBuf;
+ if (m < n) n = m;
+ for (ULONG i = 0; i < n; i++) *pWBuf++ = *pWrite++;
+ }
+ else
+ {
+ // Buffer empty. Reset to <Begin-of-Buffer>.
+ pRead = pWrite = pBuffer;
+
+ // Read next message line.
+ int nRead = GetMsgLine (pBuffer, nBufSiz);
+ if (nRead > 0)
+ {
+ // Set read pointer.
+ pRead = pBuffer + nRead;
+ }
+ else
+ {
+ if (!bHeaderGenerated)
+ {
+ // Header generated. Insert empty line.
+ bHeaderGenerated = TRUE;
+ *pRead++ = '\r';
+ *pRead++ = '\n';
+ }
+ else
+ {
+ // Body generated.
+ return (pWBuf - pData);
+ }
+ }
+ }
+ }
+ return (pWBuf - pData);
+}
+
+/*
+ * GetMsgLine.
+ */
+int INetMessageIStream::GetMsgLine (sal_Char *pData, ULONG nSize)
+{
+ if (pSourceMsg == NULL) return INETSTREAM_STATUS_ERROR;
+
+ sal_Char *pWBuf = pData;
+ sal_Char *pWEnd = pData + nSize;
+
+ if (!bHeaderGenerated)
+ {
+ ULONG i, n;
+
+ if (pMsgBuffer->Tell() == 0)
+ {
+ // Insert formatted header into buffer.
+ n = pSourceMsg->GetHeaderCount();
+ for (i = 0; i < n; i++)
+ {
+ INetMessageHeader aHeader (pSourceMsg->GetHeaderField(i));
+ if (aHeader.GetValue().Len())
+ {
+ // NYI: Folding long lines.
+ *pMsgBuffer << (sal_Char*)(aHeader.GetName().GetBuffer());
+ *pMsgBuffer << ": ";
+ *pMsgBuffer << (sal_Char*)(aHeader.GetValue().GetBuffer());
+ *pMsgBuffer << "\r\n";
+ }
+ }
+
+ pMsgWrite = (sal_Char *)(pMsgBuffer->GetData());
+ pMsgRead = pMsgWrite + pMsgBuffer->Tell();
+ }
+
+ n = pMsgRead - pMsgWrite;
+ if (n > 0)
+ {
+ // Move to caller.
+ if (nSize < n) n = nSize;
+ for (i = 0; i < n; i++) *pWBuf++ = *pMsgWrite++;
+ }
+ else
+ {
+ // Reset buffer.
+ pMsgBuffer->Seek (STREAM_SEEK_TO_BEGIN);
+ }
+ }
+ else
+ {
+ if (pSourceMsg->GetDocumentLB())
+ {
+ if (pMsgStrm == NULL)
+ pMsgStrm = new SvStream (pSourceMsg->GetDocumentLB());
+
+ ULONG nRead = pMsgStrm->Read (pWBuf, (pWEnd - pWBuf));
+ pWBuf += nRead;
+ }
+ }
+ return (pWBuf - pData);
+}
+
+/*=========================================================================
+ *
+ * INetMessageOStream Implementation.
+ *
+ *=======================================================================*/
+/*
+ * INetMessageOStream.
+ */
+INetMessageOStream::INetMessageOStream (void)
+ : pTargetMsg (NULL),
+ bHeaderParsed (FALSE),
+ eOState (INETMSG_EOL_BEGIN),
+ pMsgBuffer (new SvMemoryStream)
+{
+}
+
+/*
+ * ~INetMessageOStream.
+ */
+INetMessageOStream::~INetMessageOStream (void)
+{
+ if (pMsgBuffer->Tell() > 0)
+ PutMsgLine ((const sal_Char *) pMsgBuffer->GetData(), pMsgBuffer->Tell());
+ delete pMsgBuffer;
+
+ if (pTargetMsg)
+ {
+ SvOpenLockBytes *pLB =
+ PTR_CAST (SvOpenLockBytes, pTargetMsg->GetDocumentLB());
+ if (pLB)
+ {
+ pLB->Flush();
+ pLB->Terminate();
+ }
+ }
+}
+
+/*
+ * PutData.
+ * (Simple Field Parsing (RFC822, Appendix B)).
+ */
+int INetMessageOStream::PutData (const sal_Char *pData, ULONG nSize)
+{
+ if (pTargetMsg == NULL) return INETSTREAM_STATUS_ERROR;
+
+ const sal_Char *pStop = (pData + nSize);
+
+ while (!bHeaderParsed && (pData < pStop))
+ {
+ if (eOState == INETMSG_EOL_BEGIN)
+ {
+ if ((*pData == '\r') || (*pData == '\n'))
+ {
+ /*
+ * Empty Line. Separates header fields from message body.
+ * Skip this and any 2nd line break character (if any).
+ */
+ pData++;
+ if ((pData < pStop) && ((*pData == '\r') || (*pData == '\n')))
+ pData++;
+
+ // Emit any buffered last header field.
+ if (pMsgBuffer->Tell() > 0)
+ {
+ *pMsgBuffer << '\0';
+ int status = PutMsgLine (
+ (const sal_Char *) pMsgBuffer->GetData(),
+ pMsgBuffer->Tell());
+ if (status != INETSTREAM_STATUS_OK) return status;
+ }
+
+ // Reset to begin.
+ eOState = INETMSG_EOL_BEGIN;
+ pMsgBuffer->Seek (STREAM_SEEK_TO_BEGIN);
+
+ // Mark header parsed.
+ bHeaderParsed = TRUE;
+ }
+ else if ((*pData == ' ') || (*pData == '\t'))
+ {
+ // Continuation line. Unfold multi-line field-body.
+ *pMsgBuffer << ' ';
+ pData++;
+ }
+ else
+ {
+ // Begin of new header field.
+ if (pMsgBuffer->Tell() > 0)
+ {
+ // Emit buffered header field now.
+ *pMsgBuffer << '\0';
+ int status = PutMsgLine (
+ (const sal_Char *) pMsgBuffer->GetData(),
+ pMsgBuffer->Tell());
+ if (status != INETSTREAM_STATUS_OK) return status;
+ }
+
+ // Reset to begin of buffer.
+ pMsgBuffer->Seek (STREAM_SEEK_TO_BEGIN);
+
+ // Insert current character into buffer.
+ *pMsgBuffer << *pData++;
+ }
+
+ // Search for next line break character.
+ if (!bHeaderParsed) eOState = INETMSG_EOL_SCR;
+ }
+ else if (eOState == INETMSG_EOL_FCR)
+ {
+ // Skip line break character.
+ pData++;
+
+ // Mark begin of line.
+ eOState = INETMSG_EOL_BEGIN;
+ }
+ else if ((*pData == '\r') || (*pData == '\n'))
+ {
+ if (*pData == '\r') pData++;
+ eOState = INETMSG_EOL_FCR;
+ }
+ else if (ascii_isWhitespace (*pData & 0x7f))
+ {
+ // Any <LWS> is folded into a single <SP> character.
+ sal_Char c = *((const sal_Char *) pMsgBuffer->GetData() + pMsgBuffer->Tell() - 1);
+ if (!ascii_isWhitespace (c & 0x7f)) *pMsgBuffer << ' ';
+
+ // Skip over this <LWS> character.
+ pData++;
+ }
+ else
+ {
+ // Any other character is inserted into line buffer.
+ *pMsgBuffer << *pData++;
+ }
+ }
+
+ if (bHeaderParsed && (pData < pStop))
+ {
+ // Put message body down-stream.
+ return PutMsgLine (pData, (pStop - pData));
+ }
+
+ return INETSTREAM_STATUS_OK;
+}
+
+/*
+ * PutMsgLine.
+ */
+int INetMessageOStream::PutMsgLine (const sal_Char *pData, ULONG nSize)
+{
+ // Check for message container.
+ if (pTargetMsg == NULL) return INETSTREAM_STATUS_ERROR;
+
+ // Check for header or body.
+ if (!IsHeaderParsed())
+ {
+ ByteString aField (pData);
+ USHORT nPos = aField.Search (':');
+ if (nPos != STRING_NOTFOUND)
+ {
+ ByteString aName (
+ aField.Copy (0, nPos));
+ ByteString aValue (
+ aField.Copy (nPos + 1, aField.Len() - nPos + 1));
+ aValue.EraseLeadingChars (' ');
+
+ pTargetMsg->SetHeaderField (
+ INetMessageHeader (aName, aValue));
+ }
+ }
+ else
+ {
+ SvOpenLockBytes *pLB =
+ PTR_CAST(SvOpenLockBytes, pTargetMsg->GetDocumentLB());
+ if (pLB == NULL)
+ return INETSTREAM_STATUS_WOULDBLOCK;
+
+ sal_Size nDocSiz = pTargetMsg->GetDocumentSize();
+ sal_Size nWrite = 0;
+
+ pLB->FillAppend ((sal_Char *)pData, nSize, &nWrite);
+ pTargetMsg->SetDocumentSize (nDocSiz + nWrite);
+
+ if (nWrite < nSize) return INETSTREAM_STATUS_ERROR;
+ }
+ return INETSTREAM_STATUS_OK;
+}
+
+/*=========================================================================
+ *
+ * INetMessageIOStream Implementation.
+ *
+ *=======================================================================*/
+/*
+ * INetMessageIOStream.
+ */
+INetMessageIOStream::INetMessageIOStream (ULONG nBufferSize)
+ : INetMessageIStream (nBufferSize),
+ INetMessageOStream ()
+{
+}
+
+/*
+ * ~INetMessageIOStream.
+ */
+INetMessageIOStream::~INetMessageIOStream (void)
+{
+}
+
+/*=======================================================================
+ *
+ * INetMessageEncodeQPStream_Impl Implementation.
+ * (Quoted-Printable Encoding)
+ *
+ *=====================================================================*/
+static const sal_Char hex2pr[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F'
+};
+
+static const sal_Char ebcdic[] = {
+ '!', '"', '#', '$', '@', '[', '\\', ']', '^', '`', '{', '|', '}', '~'
+};
+
+/*
+ * INetMessageEncodeQPStream_Impl.
+ */
+INetMessageEncodeQPStream_Impl::INetMessageEncodeQPStream_Impl (
+ ULONG nMsgBufferSize)
+ : INetMessageIStream (),
+ pMsgStrm (NULL),
+ nMsgBufSiz (nMsgBufferSize),
+ nTokBufSiz (80),
+ eState (INETMSG_EOL_SCR),
+ bDone (FALSE)
+{
+ GenerateHeader (FALSE);
+
+ pMsgBuffer = new sal_Char[nMsgBufSiz];
+ pMsgRead = pMsgWrite = pMsgBuffer;
+
+ pTokBuffer = new sal_Char[nTokBufSiz];
+ pTokRead = pTokWrite = pTokBuffer;
+}
+
+/*
+ * ~INetMessageEncodeQPStream_Impl.
+ */
+INetMessageEncodeQPStream_Impl::~INetMessageEncodeQPStream_Impl (void)
+{
+ delete pMsgStrm;
+ delete [] pMsgBuffer;
+ delete [] pTokBuffer;
+}
+
+/*
+ * GetMsgLine.
+ */
+int INetMessageEncodeQPStream_Impl::GetMsgLine (sal_Char *pData, ULONG nSize)
+{
+ INetMessage *pMsg = GetSourceMessage ();
+ if (pMsg == NULL) return INETSTREAM_STATUS_ERROR;
+
+ if (pMsg->GetDocumentLB() == NULL) return 0;
+ if (pMsgStrm == NULL) pMsgStrm = new SvStream (pMsg->GetDocumentLB());
+
+ sal_Char *pWBuf = pData;
+ while (pWBuf < (pData + nSize))
+ {
+ // Caller's buffer not yet filled.
+ if ((pMsgRead - pMsgWrite) > 0)
+ {
+ // Bytes still in message buffer.
+ if ((eState != INETMSG_EOL_BEGIN) &&
+ ((pTokRead - pTokBuffer) < 72))
+ {
+ // Token buffer not yet filled.
+ if (eState == INETMSG_EOL_FCR)
+ {
+ eState = INETMSG_EOL_BEGIN;
+ if (*pMsgWrite != '\n')
+ {
+ // Convert orphant <CR> into <CR><LF> sequence.
+ *pTokRead++ = '\n';
+ }
+ *pTokRead++ = *pMsgWrite++;
+ }
+ else if ((*pMsgWrite == ' ') || (*pMsgWrite == '\t'))
+ {
+ eState = INETMSG_EOL_FSP;
+ *pTokRead++ = *pMsgWrite++;
+ }
+ else if (*pMsgWrite == '\r')
+ {
+ // Found <CR>.
+ if (eState == INETMSG_EOL_FSP)
+ {
+ // Encode last (trailing space) character.
+ sal_uInt8 c = (sal_uInt8)(*(--pTokRead));
+ *pTokRead++ = '=';
+ *pTokRead++ = hex2pr[((c & 0xf0) >> 4)];
+ *pTokRead++ = hex2pr[((c & 0x0f) )];
+ }
+ eState = INETMSG_EOL_FCR;
+ *pTokRead++ = *pMsgWrite++;
+ }
+ else if (*pMsgWrite == '\n')
+ {
+ // Found <LF> only.
+ if (eState == INETMSG_EOL_FSP)
+ {
+ // Encode last (trailing space) character.
+ sal_uInt8 c = (sal_uInt8)(*(--pTokRead));
+ *pTokRead++ = '=';
+ *pTokRead++ = hex2pr[((c & 0xf0) >> 4)];
+ *pTokRead++ = hex2pr[((c & 0x0f) )];
+ }
+ eState = INETMSG_EOL_BEGIN;
+
+ // Convert orphant <LF> into <CR><LF> sequence.
+ *pTokRead++ = '\r';
+ *pTokRead++ = *pMsgWrite++;
+ }
+ else if (*pMsgWrite == '=')
+ {
+ // Escape character itself MUST be encoded, of course.
+ sal_uInt8 c = (sal_uInt8)(*pMsgWrite++);
+ *pTokRead++ = '=';
+ *pTokRead++ = hex2pr[((c & 0xf0) >> 4)];
+ *pTokRead++ = hex2pr[((c & 0x0f) )];
+
+ eState = INETMSG_EOL_SCR;
+ }
+ else if (((sal_uInt8)(*pMsgWrite) > 0x20) &&
+ ((sal_uInt8)(*pMsgWrite) < 0x7f) )
+ {
+ /*
+ * Some printable ASCII character.
+ * (Encode EBCDIC special characters (NYI)).
+ */
+ *pTokRead++ = *pMsgWrite++;
+ eState = INETMSG_EOL_SCR;
+ }
+ else
+ {
+ // Encode any other character.
+ sal_uInt8 c = (sal_uInt8)(*pMsgWrite++);
+ *pTokRead++ = '=';
+ *pTokRead++ = hex2pr[((c & 0xf0) >> 4)];
+ *pTokRead++ = hex2pr[((c & 0x0f) )];
+
+ eState = INETMSG_EOL_SCR;
+ }
+ }
+ else
+ {
+ // Check for maximum line length.
+ if (eState != INETMSG_EOL_BEGIN)
+ {
+ // Insert soft line break.
+ *pTokRead++ = '=';
+ *pTokRead++ = '\r';
+ *pTokRead++ = '\n';
+
+ eState = INETMSG_EOL_BEGIN;
+ }
+
+ // Copy to caller's buffer.
+ if ((pTokRead - pTokWrite) > 0)
+ {
+ // Bytes still in token buffer.
+ *pWBuf++ = *pTokWrite++;
+ }
+ else
+ {
+ // Token buffer empty. Reset to <Begin-of-Buffer>.
+ pTokRead = pTokWrite = pTokBuffer;
+ eState = INETMSG_EOL_SCR;
+ }
+ }
+ }
+ else
+ {
+ // Message buffer empty. Reset to <Begin-of-Buffer>.
+ pMsgRead = pMsgWrite = pMsgBuffer;
+
+ // Read next message block.
+ ULONG nRead = pMsgStrm->Read (pMsgBuffer, nMsgBufSiz);
+ if (nRead > 0)
+ {
+ // Set read pointer.
+ pMsgRead = (pMsgBuffer + nRead);
+ }
+ else
+ {
+ // Nothing more ro read.
+ if (!bDone)
+ {
+ // Append final <CR><LF> and mark we're done.
+ *pTokRead++ = '\r';
+ *pTokRead++ = '\n';
+
+ bDone = TRUE;
+ }
+ else
+ {
+ // Already done all encoding.
+ if ((pTokRead - pTokWrite) > 0)
+ {
+ // Bytes still in token buffer.
+ *pWBuf++ = *pTokWrite++;
+ }
+ else
+ {
+ // Token buffer empty. Reset to <Begin-of-Buffer>.
+ pTokRead = pTokWrite = pTokBuffer;
+
+ // Return.
+ return (pWBuf - pData);
+ }
+ }
+ }
+ }
+ }
+ return (pWBuf - pData);
+}
+
+/*=====================================================================
+ *
+ * INetMessageDecodeQPStream_Impl Implementation.
+ * (Quoted-Printable Decoding)
+ *
+ *====================================================================*/
+static const sal_uInt8 pr2hex[128] = {
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+
+ 0x10, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10
+};
+
+/*
+ * INetMessageDecodeQPStream_Impl.
+ */
+INetMessageDecodeQPStream_Impl::INetMessageDecodeQPStream_Impl (void)
+ : INetMessageOStream (),
+ eState (INETMSG_EOL_BEGIN),
+ pMsgBuffer (new SvMemoryStream),
+ nTokBufLen (0)
+{
+ ParseHeader (FALSE);
+}
+
+/*
+ * ~INetMessageDecodeQPStream_Impl.
+ */
+INetMessageDecodeQPStream_Impl::~INetMessageDecodeQPStream_Impl (void)
+{
+ delete pMsgBuffer;
+}
+
+/*
+ * PutMsgLine.
+ */
+int INetMessageDecodeQPStream_Impl::PutMsgLine (
+ const sal_Char *pData, ULONG nSize)
+{
+ INetMessage *pMsg = GetTargetMessage();
+ if (pMsg == NULL) return INETSTREAM_STATUS_ERROR;
+
+ SvOpenLockBytes * pLB = PTR_CAST(SvOpenLockBytes, pMsg->GetDocumentLB());
+ if (pLB == NULL) return INETSTREAM_STATUS_WOULDBLOCK;
+
+ const sal_Char *pStop = pData + nSize;
+ while (pData < pStop)
+ {
+ if (eState == INETMSG_EOL_FESC)
+ {
+ *(pTokBuffer + nTokBufLen++) = static_cast< char >(toupper(*pData));
+ pData++;
+ if (nTokBufLen == 2)
+ {
+ if ((*pTokBuffer == '\r') || (*pTokBuffer == '\n'))
+ {
+ // Soft line break (=<CR><LF>). Emit buffer now.
+ eState = INETMSG_EOL_BEGIN;
+ }
+ else
+ {
+ // Decode token.
+ *pMsgBuffer << sal_uInt8 (
+ (pr2hex[(int)(pTokBuffer[0] & 0x7f)] << 4) |
+ (pr2hex[(int)(pTokBuffer[1] & 0x7f)] & 15) );
+
+ // Search for next <CR>.
+ eState = INETMSG_EOL_SCR;
+ }
+
+ // Reset token buffer.
+ nTokBufLen = 0;
+ }
+ }
+ else if (*pData == '=')
+ {
+ // Found escape character.
+ pData++;
+ eState = INETMSG_EOL_FESC;
+ }
+ else if (eState == INETMSG_EOL_FCR)
+ {
+ *pMsgBuffer << *pData++;
+ eState = INETMSG_EOL_BEGIN;
+ }
+ else if (*pData == '\r')
+ {
+ *pMsgBuffer << *pData++;
+ eState = INETMSG_EOL_FCR;
+ }
+ else
+ {
+ *pMsgBuffer << *pData++;
+ }
+
+ if (eState == INETMSG_EOL_BEGIN)
+ {
+ sal_Size nRead = pMsgBuffer->Tell();
+ if (nRead > 0)
+ {
+ // Emit buffer.
+ sal_Size nDocSiz = pMsg->GetDocumentSize();
+ sal_Size nWrite = 0;
+
+ pLB->FillAppend (
+ (sal_Char *)(pMsgBuffer->GetData()), nRead, &nWrite);
+ pMsg->SetDocumentSize (nDocSiz + nWrite);
+
+ if (nWrite < nRead) return INETSTREAM_STATUS_ERROR;
+
+ pMsgBuffer->Seek (STREAM_SEEK_TO_BEGIN);
+ }
+ eState = INETMSG_EOL_SCR;
+ }
+ }
+ return INETSTREAM_STATUS_OK;
+}
+
+/*======================================================================
+ *
+ * INetMessageEncode64Stream_Impl Implementation.
+ * (Base64 Encoding)
+ *
+ *====================================================================*/
+static const sal_Char six2pr[64] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
+};
+
+/*
+ * INetMessageEncode64Stream_Impl.
+ */
+INetMessageEncode64Stream_Impl::INetMessageEncode64Stream_Impl (
+ ULONG nMsgBufferSize)
+ : INetMessageIStream (),
+ pMsgStrm (NULL),
+ nMsgBufSiz (nMsgBufferSize),
+ nTokBufSiz (80),
+ bDone (FALSE)
+{
+ GenerateHeader (FALSE);
+
+ pMsgBuffer = new sal_uInt8[nMsgBufSiz];
+ pMsgRead = pMsgWrite = pMsgBuffer;
+
+ pTokBuffer = new sal_Char[nTokBufSiz];
+ pTokRead = pTokWrite = pTokBuffer;
+}
+
+/*
+ * ~INetMessageEncode64Stream_Impl.
+ */
+INetMessageEncode64Stream_Impl::~INetMessageEncode64Stream_Impl (void)
+{
+ delete pMsgStrm;
+ delete [] pMsgBuffer;
+ delete [] pTokBuffer;
+}
+
+/*
+ * GetMsgLine.
+ */
+int INetMessageEncode64Stream_Impl::GetMsgLine (sal_Char *pData, ULONG nSize)
+{
+ INetMessage *pMsg = GetSourceMessage ();
+ if (pMsg == NULL) return INETSTREAM_STATUS_ERROR;
+
+ if (pMsg->GetDocumentLB() == NULL) return 0;
+ if (pMsgStrm == NULL) pMsgStrm = new SvStream (pMsg->GetDocumentLB());
+
+ sal_Char *pWBuf = pData;
+ while (pWBuf < (pData + nSize))
+ {
+ // Caller's buffer not yet filled.
+ if ((pMsgRead - pMsgWrite) > 0)
+ {
+ // Bytes still in message buffer.
+ if ((pTokRead - pTokBuffer) < 72)
+ {
+ // Token buffer not yet filled.
+ switch ((pTokRead - pTokBuffer) % 4)
+ {
+ case 0:
+ *pTokRead++ = six2pr[(int)(*pMsgWrite >> 2)];
+ break;
+
+ case 1:
+ *pTokRead++ = six2pr[
+ (int)(((*pMsgWrite << 4) & 060) |
+ (((*(pMsgWrite + 1)) >> 4) & 017))];
+ pMsgWrite++;
+ break;
+
+ case 2:
+ *pTokRead++ = six2pr[
+ (int)(((*pMsgWrite << 2) & 074) |
+ (((*(pMsgWrite + 1)) >> 6) & 003))];
+ pMsgWrite++;
+ break;
+
+ default: // == case 3
+ *pTokRead++ = six2pr[(int)(*pMsgWrite & 077)];
+ pMsgWrite++;
+ break;
+ }
+ }
+ else if ((pTokRead - pTokBuffer) == 72)
+ {
+ // Maximum line length. Append <CR><LF>.
+ *pTokRead++ = '\r';
+ *pTokRead++ = '\n';
+ }
+ else
+ {
+ if ((pTokRead - pTokWrite) > 0)
+ {
+ // Bytes still in token buffer.
+ *pWBuf++ = *pTokWrite++;
+ }
+ else
+ {
+ // Token buffer empty. Reset to <Begin-of-Buffer>.
+ pTokRead = pTokWrite = pTokBuffer;
+ }
+ }
+ }
+ else
+ {
+ // Message buffer empty. Reset to <Begin-of-Buffer>.
+ pMsgRead = pMsgWrite = pMsgBuffer;
+
+ // Read next message block.
+ ULONG nRead = pMsgStrm->Read (pMsgBuffer, nMsgBufSiz);
+ if (nRead > 0)
+ {
+ // Set read pointer.
+ pMsgRead = (pMsgBuffer + nRead);
+ }
+ else
+ {
+ // Nothing more to read.
+ if (!bDone)
+ {
+ // Append pad character(s) and final <CR><LF>.
+ switch ((pTokRead - pTokBuffer) % 4)
+ {
+ case 2:
+ *pTokRead++ = '=';
+ // Fall through for 2nd pad character.
+
+ case 3:
+ *pTokRead++ = '=';
+ break;
+
+ default:
+ break;
+ }
+ *pTokRead++ = '\r';
+ *pTokRead++ = '\n';
+
+ // Mark we're done.
+ bDone = TRUE;
+ }
+ else
+ {
+ // Already done all encoding.
+ if ((pTokRead - pTokWrite) > 0)
+ {
+ // Bytes still in token buffer.
+ *pWBuf++ = *pTokWrite++;
+ }
+ else
+ {
+ // Token buffer empty. Reset to <Begin-of-Buffer>.
+ pTokRead = pTokWrite = pTokBuffer;
+
+ // Reset done flag, if everything has been done.
+ // if (pWBuf == pData) bDone = FALSE;
+
+ // Return.
+ return (pWBuf - pData);
+ }
+ }
+ }
+ }
+ } // while (pWBuf < (pData + nSize))
+ return (pWBuf - pData);
+}
+
+/*======================================================================
+ *
+ * INetMessageDecode64Stream_Impl Implementation.
+ * (Base64 Decoding)
+ *
+ *====================================================================*/
+static const sal_uInt8 pr2six[256] = {
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x3E, 0x40, 0x40, 0x40, 0x3F,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
+ 0x3C, 0x3D, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+
+ 0x40, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
+ 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+ 0x17, 0x18, 0x19, 0x40, 0x40, 0x40, 0x40, 0x40,
+
+ 0x40, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
+ 0x31, 0x32, 0x33, 0x40, 0x40, 0x40, 0x40, 0x40,
+
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
+};
+
+/*
+ * INetMessageDecode64Stream_Impl.
+ */
+INetMessageDecode64Stream_Impl::INetMessageDecode64Stream_Impl (
+ ULONG nMsgBufferSize)
+ : INetMessageOStream (),
+ eState (INETMSG_EOL_SCR),
+ nMsgBufSiz (nMsgBufferSize)
+{
+ ParseHeader (FALSE);
+
+ pMsgBuffer = new sal_Char[nMsgBufSiz];
+ pMsgRead = pMsgWrite = pMsgBuffer;
+}
+
+/*
+ * ~INetMessageDecode64Stream_Impl.
+ */
+INetMessageDecode64Stream_Impl::~INetMessageDecode64Stream_Impl (void)
+{
+ delete [] pMsgBuffer;
+}
+
+/*
+ * PutMsgLine.
+ */
+int INetMessageDecode64Stream_Impl::PutMsgLine (
+ const sal_Char *pData, ULONG nSize)
+{
+ INetMessage *pMsg = GetTargetMessage ();
+ if (pMsg == NULL) return INETSTREAM_STATUS_ERROR;
+
+ SvOpenLockBytes * pLB = PTR_CAST(SvOpenLockBytes, pMsg->GetDocumentLB());
+ if (pLB == NULL) return INETSTREAM_STATUS_WOULDBLOCK;
+
+ const sal_Char *pStop = (pData + nSize);
+ while (pData < pStop)
+ {
+ if (pr2six[(int)(*pData)] > 63)
+ {
+ /*
+ * Character not in base64 alphabet.
+ * Check for <End-of-Stream> or Junk.
+ */
+ if (*pData == '=')
+ {
+ // Final pad character -> Done.
+ sal_Size nDocSiz = pMsg->GetDocumentSize();
+ sal_Size nRead = pMsgWrite - pMsgBuffer;
+ sal_Size nWrite = 0;
+
+ pLB->FillAppend (pMsgBuffer, nRead, &nWrite);
+ pMsg->SetDocumentSize (nDocSiz + nWrite);
+
+ if (nWrite < nRead)
+ return INETSTREAM_STATUS_ERROR;
+ else
+ return INETSTREAM_STATUS_LOADED;
+ }
+ else if (eState == INETMSG_EOL_FCR)
+ {
+ // Skip any line break character.
+ if ((*pData == '\r') || (*pData == '\n')) pData++;
+
+ // Store decoded message buffer contents.
+ sal_Size nDocSiz = pMsg->GetDocumentSize();
+ sal_Size nRead = pMsgWrite - pMsgBuffer;
+ sal_Size nWrite = 0;
+
+ pLB->FillAppend (pMsgBuffer, nRead, &nWrite);
+ pMsg->SetDocumentSize (nDocSiz + nWrite);
+
+ if (nWrite < nRead) return INETSTREAM_STATUS_ERROR;
+
+ // Reset to <Begin-of-Buffer>.
+ pMsgWrite = pMsgBuffer;
+ eState = INETMSG_EOL_SCR;
+ }
+ else if ((*pData == '\r') || (*pData == '\n'))
+ {
+ // Skip any line break character.
+ pData++;
+ eState = INETMSG_EOL_FCR;
+ }
+ else
+ {
+ // Skip any junk character (may be transmission error).
+ pData++;
+ }
+ }
+ else
+ {
+ // Decode any other character into message buffer.
+ switch ((pMsgRead - pMsgBuffer) % 4)
+ {
+ case 0:
+ *pMsgWrite = (pr2six[(int)(*pData++)] << 2);
+ pMsgRead++;
+ break;
+
+ case 1:
+ *pMsgWrite++ |= (pr2six[(int)(*pData )] >> 4);
+ *pMsgWrite = (pr2six[(int)(*pData++)] << 4);
+ pMsgRead++;
+ break;
+
+ case 2:
+ *pMsgWrite++ |= (pr2six[(int)(*pData )] >> 2);
+ *pMsgWrite = (pr2six[(int)(*pData++)] << 6);
+ pMsgRead++;
+ break;
+
+ default: // == case 3
+ *pMsgWrite++ |= (pr2six[(int)(*pData++)]);
+ pMsgRead = pMsgBuffer;
+ break;
+ } // switch ((pMsgRead - pMsgBuffer) % 4)
+ }
+ } // while (pData < pStop)
+ return INETSTREAM_STATUS_OK;
+}
+
+/*=========================================================================
+ *
+ * INetMIMEMessageStream Implementation.
+ *
+ *=======================================================================*/
+/*
+ * INetMIMEMessageStream.
+ */
+INetMIMEMessageStream::INetMIMEMessageStream (ULONG nBufferSize)
+ : INetMessageIOStream (nBufferSize),
+ eState (INETMSG_EOL_BEGIN),
+ nChildIndex (0),
+ pChildStrm (NULL),
+ eEncoding (INETMSG_ENCODING_BINARY),
+ pEncodeStrm (NULL),
+ pDecodeStrm (NULL),
+ pMsgBuffer (NULL)
+{
+}
+
+/*
+ * ~INetMIMEMessageStream.
+ */
+INetMIMEMessageStream::~INetMIMEMessageStream (void)
+{
+ delete pChildStrm;
+ delete pEncodeStrm;
+ delete pDecodeStrm;
+ delete pMsgBuffer;
+}
+
+/*
+ * GetMsgEncoding.
+ */
+INetMessageEncoding
+INetMIMEMessageStream::GetMsgEncoding (const String& rContentType)
+{
+ if ((rContentType.CompareIgnoreCaseToAscii ("message" , 7) == 0) ||
+ (rContentType.CompareIgnoreCaseToAscii ("multipart", 9) == 0) )
+ return INETMSG_ENCODING_7BIT;
+
+ if (rContentType.CompareIgnoreCaseToAscii ("text", 4) == 0)
+ {
+ if (rContentType.CompareIgnoreCaseToAscii ("text/plain", 10) == 0)
+ {
+ if (rContentType.GetTokenCount ('=') > 1)
+ {
+ String aCharset (rContentType.GetToken (1, '='));
+ aCharset.EraseLeadingChars (' ');
+ aCharset.EraseLeadingChars ('"');
+
+ if (aCharset.CompareIgnoreCaseToAscii ("us-ascii", 8) == 0)
+ return INETMSG_ENCODING_7BIT;
+ else
+ return INETMSG_ENCODING_QUOTED;
+ }
+ else
+ return INETMSG_ENCODING_7BIT;
+ }
+ else
+ return INETMSG_ENCODING_QUOTED;
+ }
+
+ return INETMSG_ENCODING_BASE64;
+}
+
+/*
+ * GetMsgLine.
+ * (Message Generator).
+ */
+int INetMIMEMessageStream::GetMsgLine (sal_Char *pData, ULONG nSize)
+{
+ // Check for message container.
+ INetMIMEMessage *pMsg = GetSourceMessage();
+ if (pMsg == NULL) return INETSTREAM_STATUS_ERROR;
+
+ // Check for header or body.
+ if (!IsHeaderGenerated())
+ {
+ if (eState == INETMSG_EOL_BEGIN)
+ {
+ // Prepare special header fields.
+ if (pMsg->GetParent())
+ {
+ String aPCT (pMsg->GetParent()->GetContentType());
+ if (aPCT.CompareIgnoreCaseToAscii ("message/rfc822", 14) == 0)
+ pMsg->SetMIMEVersion (
+ String(CONSTASCII_STRINGPARAM("1.0")));
+ else
+ pMsg->SetMIMEVersion (String());
+ }
+ else
+ {
+ pMsg->SetMIMEVersion (String(CONSTASCII_STRINGPARAM("1.0")));
+ }
+
+ // Check ContentType.
+ String aContentType (pMsg->GetContentType());
+ if (aContentType.Len())
+ {
+ // Determine default Content-Type.
+ String aDefaultType;
+ pMsg->GetDefaultContentType (aDefaultType);
+
+ if (aDefaultType.CompareIgnoreCaseToAscii (
+ aContentType, aContentType.Len()) == 0)
+ {
+ // No need to specify default.
+ pMsg->SetContentType (String());
+ }
+ }
+
+ // Check Encoding.
+ String aEncoding (pMsg->GetContentTransferEncoding());
+ if (aEncoding.Len())
+ {
+ // Use given Encoding.
+ if (aEncoding.CompareIgnoreCaseToAscii (
+ "base64", 6) == 0)
+ eEncoding = INETMSG_ENCODING_BASE64;
+ else if (aEncoding.CompareIgnoreCaseToAscii (
+ "quoted-printable", 16) == 0)
+ eEncoding = INETMSG_ENCODING_QUOTED;
+ else
+ eEncoding = INETMSG_ENCODING_7BIT;
+ }
+ else
+ {
+ // Use default Encoding for (given|default) Content-Type.
+ if (aContentType.Len() == 0)
+ {
+ // Determine default Content-Type.
+ pMsg->GetDefaultContentType (aContentType);
+ }
+ eEncoding = GetMsgEncoding (aContentType);
+ }
+
+ // Set Content-Transfer-Encoding header.
+ if (eEncoding == INETMSG_ENCODING_BASE64)
+ {
+ // Base64.
+ pMsg->SetContentTransferEncoding (
+ String(CONSTASCII_STRINGPARAM("base64")));
+ }
+ else if (eEncoding == INETMSG_ENCODING_QUOTED)
+ {
+ // Quoted-Printable.
+ pMsg->SetContentTransferEncoding (
+ String(CONSTASCII_STRINGPARAM("quoted-printable")));
+ }
+ else
+ {
+ // No need to specify default.
+ pMsg->SetContentTransferEncoding (String());
+ }
+
+ // Mark we're done.
+ eState = INETMSG_EOL_DONE;
+ }
+
+ // Generate the message header.
+ int nRead = INetMessageIOStream::GetMsgLine (pData, nSize);
+ if (nRead <= 0)
+ {
+ // Reset state.
+ eState = INETMSG_EOL_BEGIN;
+ }
+ return nRead;
+ }
+ else
+ {
+ // Generate the message body.
+ if (pMsg->IsContainer())
+ {
+ // Encapsulated message body.
+ while (eState == INETMSG_EOL_BEGIN)
+ {
+ if (pChildStrm == NULL)
+ {
+ INetMIMEMessage *pChild = pMsg->GetChild (nChildIndex);
+ if (pChild)
+ {
+ // Increment child index.
+ nChildIndex++;
+
+ // Create child stream.
+ pChildStrm = new INetMIMEMessageStream;
+ pChildStrm->SetSourceMessage (pChild);
+
+ if (pMsg->IsMultipart())
+ {
+ // Insert multipart delimiter.
+ ByteString aDelim ("--");
+ aDelim += pMsg->GetMultipartBoundary();
+ aDelim += "\r\n";
+
+ rtl_copyMemory (
+ pData, aDelim.GetBuffer(), aDelim.Len());
+ return aDelim.Len();
+ }
+ }
+ else
+ {
+ // No more parts. Mark we're done.
+ eState = INETMSG_EOL_DONE;
+ nChildIndex = 0;
+
+ if (pMsg->IsMultipart())
+ {
+ // Insert close delimiter.
+ ByteString aDelim ("--");
+ aDelim += pMsg->GetMultipartBoundary();
+ aDelim += "--\r\n";
+
+ rtl_copyMemory (
+ pData, aDelim.GetBuffer(), aDelim.Len());
+ return aDelim.Len();
+ }
+ }
+ }
+ else
+ {
+ // Read current child stream.
+ int nRead = pChildStrm->Read (pData, nSize);
+ if (nRead > 0)
+ {
+ return nRead;
+ }
+ else
+ {
+ // Cleanup exhausted child stream.
+ delete pChildStrm;
+ pChildStrm = NULL;
+ }
+ }
+ }
+ return 0;
+ }
+ else
+ {
+ // Single part message body.
+ if (pMsg->GetDocumentLB() == NULL)
+ {
+ // Empty message body.
+ return 0;
+ }
+ else
+ {
+ // Check whether message body needs to be encoded.
+ if (eEncoding == INETMSG_ENCODING_7BIT)
+ {
+ // No Encoding.
+ return INetMessageIOStream::GetMsgLine (pData, nSize);
+ }
+ else
+ {
+ // Apply appropriate Encoding.
+ while (eState == INETMSG_EOL_BEGIN)
+ {
+ if (pEncodeStrm == NULL)
+ {
+ // Create encoder stream.
+ if (eEncoding == INETMSG_ENCODING_QUOTED)
+ {
+ // Quoted-Printable Encoding.
+ pEncodeStrm
+ = new INetMessageEncodeQPStream_Impl;
+ }
+ else
+ {
+ // Base64 Encoding.
+ pEncodeStrm
+ = new INetMessageEncode64Stream_Impl;
+ }
+ pEncodeStrm->SetSourceMessage (pMsg);
+ }
+
+ // Read encoded message.
+ int nRead = pEncodeStrm->Read (pData, nSize);
+ if (nRead > 0)
+ {
+ return nRead;
+ }
+ else
+ {
+ // Cleanup exhausted encoder stream.
+ delete pEncodeStrm;
+ pEncodeStrm = NULL;
+
+ // Mark we're done.
+ eState = INETMSG_EOL_DONE;
+ }
+ }
+ return 0;
+ }
+ }
+ }
+ }
+}
+
+/*
+ * PutMsgLine.
+ * (Message Parser).
+ */
+int INetMIMEMessageStream::PutMsgLine (const sal_Char *pData, ULONG nSize)
+{
+ // Check for message container.
+ INetMIMEMessage *pMsg = GetTargetMessage();
+ if (pMsg == NULL) return INETSTREAM_STATUS_ERROR;
+
+ // Check for header or body.
+ if (!IsHeaderParsed())
+ {
+ // Parse the message header.
+ int nRet = INetMessageIOStream::PutMsgLine (pData, nSize);
+ return nRet;
+ }
+ else
+ {
+ pMsg->SetHeaderParsed();
+ // Parse the message body.
+ if (pMsg->IsContainer())
+ {
+
+ // Content-Transfer-Encoding MUST be "7bit" (RFC1521).
+ if (pMsg->IsMessage())
+ {
+ if( !pChildStrm )
+ {
+ // Encapsulated message.
+ pMsg->SetChildCount( pMsg->GetChildCount() + 1);
+ INetMIMEMessage* pNewMessage = new INetMIMEMessage;
+ pNewMessage->SetDocumentLB (
+ new SvAsyncLockBytes(new SvCacheStream, FALSE));
+ pMsg->AttachChild( *pNewMessage, TRUE );
+
+ // Encapsulated message body. Create message parser stream.
+ pChildStrm = new INetMIMEMessageStream;
+ pChildStrm->SetTargetMessage ( pNewMessage );
+
+ // Initialize control variables.
+ eState = INETMSG_EOL_BEGIN;
+ }
+ if ( nSize > 0)
+ {
+ // Bytes still in buffer. Put message down-stream.
+ int status = pChildStrm->Write( pData, nSize );
+ if (status != INETSTREAM_STATUS_OK)
+ return status;
+ }
+
+ return INetMessageIOStream::PutMsgLine (pData, nSize);
+ }
+ else
+ {
+
+ // Multipart message body. Initialize multipart delimiters.
+ // Multipart message.
+ if (pMsg->GetMultipartBoundary().Len() == 0)
+ {
+ // Determine boundary.
+ ByteString aType (
+ pMsg->GetContentType(), RTL_TEXTENCODING_ASCII_US);
+ ByteString aLowerType (aType);
+ aLowerType.ToLowerAscii();
+
+ USHORT nPos = aLowerType.Search ("boundary=");
+ ByteString aBoundary (aType.Copy (nPos + 9));
+
+ aBoundary.EraseLeadingAndTrailingChars (' ');
+ aBoundary.EraseLeadingAndTrailingChars ('"');
+
+ // Save boundary.
+ pMsg->SetMultipartBoundary (aBoundary);
+ }
+
+ ByteString aPlainDelim (pMsg->GetMultipartBoundary());
+ ByteString aDelim ("--");
+ aDelim += aPlainDelim;
+
+ ByteString aPlainClose (aPlainDelim);
+ aPlainClose += "--";
+
+ ByteString aClose (aDelim);
+ aClose += "--";
+
+ if (pMsgBuffer == NULL) pMsgBuffer = new SvMemoryStream;
+ pMsgBuffer->Write (pData, nSize);
+ ULONG nBufSize = pMsgBuffer->Tell();
+
+ const sal_Char* pChar;
+ const sal_Char* pOldPos;
+ for( pOldPos = pChar = (const sal_Char *) pMsgBuffer->GetData(); nBufSize--;
+ pChar++ )
+ {
+ int status;
+ if( *pChar == '\r' || *pChar == '\n' )
+ {
+ if( aDelim.CompareTo (pOldPos, aDelim.Len())
+ != COMPARE_EQUAL &&
+ aClose.CompareTo (pOldPos, aClose.Len())
+ != COMPARE_EQUAL &&
+ aPlainDelim.CompareTo (pOldPos, aPlainDelim.Len())
+ != COMPARE_EQUAL &&
+ aPlainClose.CompareTo(pOldPos, aPlainClose.Len())
+ != COMPARE_EQUAL )
+ {
+ if( nBufSize &&
+ ( pChar[1] == '\r' || pChar[1] == '\n' ) )
+ nBufSize--, pChar++;
+ if( pChildStrm )
+ {
+ status = pChildStrm->Write(
+ pOldPos, pChar - pOldPos + 1 );
+ if( status != INETSTREAM_STATUS_OK )
+ return status;
+ }
+ else {
+ DBG_ERRORFILE( "Die Boundary nicht gefunden" );
+ }
+ status = INetMessageIOStream::PutMsgLine(
+ pOldPos, pChar - pOldPos + 1 );
+ if( status != INETSTREAM_STATUS_OK )
+ return status;
+ pOldPos = pChar + 1;
+ }
+ else
+ {
+ if( nBufSize &&
+ ( pChar[1] == '\r' || pChar[1] == '\n' ) )
+ nBufSize--, pChar++;
+ pOldPos = pChar + 1;
+ DELETEZ( pChildStrm );
+
+ if (aClose.CompareTo (pOldPos, aClose.Len())
+ != COMPARE_EQUAL &&
+ aPlainClose.CompareTo (pOldPos, aClose.Len())
+ != COMPARE_EQUAL )
+ {
+ // Encapsulated message.
+ pMsg->SetChildCount(pMsg->GetChildCount() + 1);
+ INetMIMEMessage* pNewMessage =
+ new INetMIMEMessage;
+ pNewMessage->SetDocumentLB (
+ new SvAsyncLockBytes (
+ new SvCacheStream, FALSE));
+
+ pMsg->AttachChild( *pNewMessage, TRUE );
+
+ // Encapsulated message body. Create message parser stream.
+ pChildStrm = new INetMIMEMessageStream;
+ pChildStrm->SetTargetMessage ( pNewMessage );
+
+ // Initialize control variables.
+ }
+ eState = INETMSG_EOL_BEGIN;
+ status = INetMessageIOStream::PutMsgLine(
+ pOldPos, pChar - pOldPos + 1 );
+ if( status != INETSTREAM_STATUS_OK )
+ return status;
+ }
+ }
+ }
+ if( pOldPos < pChar )
+ {
+ SvMemoryStream* pNewStream = new SvMemoryStream;
+ pNewStream->Write( pOldPos, pChar - pOldPos );
+ SvMemoryStream* pTmp = pMsgBuffer;
+ pMsgBuffer = pNewStream;
+ delete pTmp;
+ }
+ else
+ {
+ pMsgBuffer->Seek( 0L );
+ pMsgBuffer->SetStreamSize( 0 );
+ }
+ return INETSTREAM_STATUS_OK;
+ }
+ }
+ else
+ {
+ /*
+ * Single part message.
+ * Remove any ContentTransferEncoding.
+ */
+ if (pMsg->GetContentType().Len() == 0)
+ {
+ String aDefaultCT;
+ pMsg->GetDefaultContentType (aDefaultCT);
+ pMsg->SetContentType (aDefaultCT);
+ }
+
+ if (eEncoding == INETMSG_ENCODING_BINARY)
+ {
+ String aEncoding (pMsg->GetContentTransferEncoding());
+ if (aEncoding.CompareIgnoreCaseToAscii (
+ "base64", 6) == COMPARE_EQUAL)
+ eEncoding = INETMSG_ENCODING_BASE64;
+ else if (aEncoding.CompareIgnoreCaseToAscii (
+ "quoted-printable", 16) == COMPARE_EQUAL)
+ eEncoding = INETMSG_ENCODING_QUOTED;
+ else
+ eEncoding = INETMSG_ENCODING_7BIT;
+ }
+
+ if (eEncoding == INETMSG_ENCODING_7BIT)
+ {
+ // No decoding necessary.
+ return INetMessageIOStream::PutMsgLine (pData, nSize);
+ }
+ else
+ {
+ if (pDecodeStrm == NULL)
+ {
+ if (eEncoding == INETMSG_ENCODING_QUOTED)
+ pDecodeStrm = new INetMessageDecodeQPStream_Impl;
+ else
+ pDecodeStrm = new INetMessageDecode64Stream_Impl;
+
+ pDecodeStrm->SetTargetMessage (pMsg);
+ }
+ return pDecodeStrm->Write (pData, nSize);
+ }
+ }
+ }
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/inet/makefile.mk b/tools/source/inet/makefile.mk
new file mode 100644
index 000000000000..1e0bdfdd2391
--- /dev/null
+++ b/tools/source/inet/makefile.mk
@@ -0,0 +1,45 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..
+PRJNAME = tools
+TARGET = inet
+
+.INCLUDE: settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+SLOFILES=\
+ $(SLO)$/inetmime.obj \
+ $(SLO)$/inetmsg.obj \
+ $(SLO)$/inetstrm.obj
+
+OBJFILES=\
+ $(OBJ)$/inetmime.obj \
+ $(OBJ)$/inetmsg.obj \
+ $(OBJ)$/inetstrm.obj
+
+.INCLUDE: target.mk
diff --git a/tools/source/makefile.mk b/tools/source/makefile.mk
new file mode 100644
index 000000000000..8c3f3167635e
--- /dev/null
+++ b/tools/source/makefile.mk
@@ -0,0 +1,58 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..
+
+TARGET=source
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)" == "UNX"
+SUBDIRS+= solar
+.ENDIF
+
+SUBDIRS+= \
+ datetime \
+ timestamp \
+ debug \
+ fsys \
+ generic \
+ intntl \
+ memtools \
+ misc \
+ rc \
+ ref \
+ stream \
+ zcodec
+
+
+.INCLUDE : target.mk
+
diff --git a/tools/source/memtools/contnr.cxx b/tools/source/memtools/contnr.cxx
new file mode 100644
index 000000000000..1f8d874d532b
--- /dev/null
+++ b/tools/source/memtools/contnr.cxx
@@ -0,0 +1,1705 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <limits.h>
+
+#include <string.h>
+
+#include <stdio.h>
+#include <tools/solar.h>
+#include <impcont.hxx>
+#include <tools/contnr.hxx>
+#include <tools/debug.hxx>
+
+// -----------------------------------------------------------------------
+
+DBG_NAME( CBlock )
+DBG_NAME( Container )
+
+/*************************************************************************
+|*
+|* DbgCheckCBlock()
+|*
+|* Beschreibung Pruefung eines CBlock fuer Debug-Utilities
+|* Ersterstellung MI 30.01.92
+|* Letzte Aenderung TH 24.01.96
+|*
+*************************************************************************/
+
+#ifdef DBG_UTIL
+const char* CBlock::DbgCheckCBlock( const void* pBlock )
+{
+ CBlock* p = (CBlock*)pBlock;
+
+ if ( p->nCount > p->nSize )
+ return "nCount > nSize";
+
+ if ( p->nSize && !p->pNodes )
+ return "nSize > 0 && pNodes == NULL";
+
+ return NULL;
+}
+#endif
+
+/*************************************************************************
+|*
+|* CBlock::CBlock()
+|*
+|* Beschreibung Construktor des Verwaltungsblocks
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+CBlock::CBlock( USHORT nInitSize, CBlock* _pPrev, CBlock* _pNext )
+{
+ DBG_CTOR( CBlock, DbgCheckCBlock );
+
+ pPrev = _pPrev;
+ pNext = _pNext;
+ nSize = nInitSize;
+ nCount = 0;
+
+ // Datenpuffer anlegen
+ pNodes = new PVOID[nSize];
+}
+
+/*************************************************************************
+|*
+|* CBlock::CBlock()
+|*
+|* Beschreibung Construktor des Verwaltungsblocks
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+CBlock::CBlock( USHORT _nSize, CBlock* _pPrev )
+{
+ DBG_CTOR( CBlock, DbgCheckCBlock );
+ DBG_ASSERT( _nSize, "CBlock::CBlock(): nSize == 0" );
+
+ pPrev = _pPrev;
+ pNext = NULL;
+ nSize = _nSize;
+ nCount = _nSize;
+
+ // Datenpuffer anlegen und initialisieren
+ pNodes = new PVOID[nSize];
+ memset( pNodes, 0, nSize*sizeof(PVOID) );
+}
+
+/*************************************************************************
+|*
+|* CBlock::CBlock()
+|*
+|* Beschreibung Copy-Construktor des Verwaltungsblocks
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+CBlock::CBlock( const CBlock& r, CBlock* _pPrev )
+{
+ DBG_CTOR( CBlock, DbgCheckCBlock );
+ DBG_CHKOBJ( &r, CBlock, DbgCheckCBlock );
+
+ pPrev = _pPrev;
+ pNext = NULL;
+ nSize = r.nSize;
+ nCount = r.nCount;
+
+ // Datenpuffer anlegen und Daten kopieren
+ pNodes = new PVOID[nSize];
+ memcpy( pNodes, r.pNodes, nCount*sizeof(PVOID) );
+}
+
+/*************************************************************************
+|*
+|* CBlock::~CBlock()
+|*
+|* Beschreibung Destruktor des Verwaltungsblocks
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+inline CBlock::~CBlock()
+{
+ DBG_DTOR( CBlock, DbgCheckCBlock );
+
+ // Daten loeschen
+ delete[] pNodes;
+}
+
+/*************************************************************************
+|*
+|* CBlock::Insert()
+|*
+|* Beschreibung Fuegt einen Pointer ein
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void CBlock::Insert( void* p, USHORT nIndex, USHORT nReSize )
+{
+ DBG_CHKTHIS( CBlock, DbgCheckCBlock );
+ DBG_ASSERT( nIndex <= nCount, "CBlock::Insert(): Index > nCount" );
+
+ // Muss Block realokiert werden
+ if ( nCount == nSize )
+ {
+ // Neue Daten anlegen
+ nSize = nSize + nReSize; // MSVC warns here if += is used
+ void** pNewNodes = new PVOID[nSize];
+
+ // Wird angehaengt
+ if ( nCount == nIndex )
+ {
+ // Daten kopieren
+ memcpy( pNewNodes, pNodes, nCount*sizeof(PVOID) );
+ }
+ else
+ {
+ // Daten kopieren
+ memcpy( pNewNodes, pNodes, nIndex*sizeof(PVOID) );
+ memcpy( pNewNodes + nIndex + 1,
+ pNodes + nIndex,
+ (nCount-nIndex)*sizeof(PVOID) );
+ }
+
+ // Alte Daten loeschen und neue setzen
+ delete[] pNodes;
+ pNodes = pNewNodes;
+ }
+ else
+ {
+ if ( nIndex < nCount )
+ {
+ memmove( pNodes + nIndex + 1,
+ pNodes + nIndex,
+ (nCount-nIndex)*sizeof(PVOID) );
+ }
+ }
+
+ // Neuen Pointer setzen und Elementgroesse erhoehen
+ pNodes[nIndex] = p;
+ nCount++;
+}
+
+/*************************************************************************
+|*
+|* CBlock::Split()
+|*
+|* Beschreibung Fuegt einen Pointer ein und splittet den Block
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+CBlock* CBlock::Split( void* p, USHORT nIndex, USHORT nReSize )
+{
+ DBG_CHKTHIS( CBlock, DbgCheckCBlock );
+
+ USHORT nNewSize;
+ USHORT nMiddle;
+ CBlock* pNewBlock;
+
+ nMiddle = nCount/2;
+
+ if ( ( nIndex == nCount ) || ( nIndex == 0 ) )
+ nNewSize = nReSize;
+ else
+ {
+ // Der aktuelle Block wird in der Mitte geteilt
+ nNewSize = (nCount+1) / 2;
+
+ if ( nNewSize < nReSize )
+ nNewSize = nReSize;
+ else
+ {
+ // Neue Groesse muss ein vielfaches von Resize sein
+ if ( nNewSize % nReSize )
+ nNewSize += nReSize - (nNewSize % nReSize);
+ else
+ nNewSize = nNewSize + nReSize; // MSVC warns here if += is used
+ }
+ }
+
+ // Vor oder hinter dem aktuellem Block einfuegen?
+ if ( nIndex > nMiddle )
+ {
+ // Neuen Split-Block anlegen und hinter dem aktuellem Block einfuegen
+ pNewBlock = new CBlock( nNewSize, this, pNext );
+
+ if ( pNext )
+ pNext->pPrev = pNewBlock;
+ pNext = pNewBlock;
+
+ if ( nIndex == nCount )
+ {
+ // Neuen Pointer einfuegen
+ pNewBlock->pNodes[0] = p;
+ pNewBlock->nCount = 1;
+ }
+ else
+ {
+ nIndex = nIndex - nMiddle; // MSVC warns here if += is used
+ // Alles von Mitte bis Index kopieren
+ if ( nIndex )
+ memcpy( pNewBlock->pNodes, pNodes+nMiddle, nIndex*sizeof(PVOID) );
+
+ // Neuen Pointer einfuegen
+ pNewBlock->pNodes[nIndex] = p;
+
+ // Alles von Mitte bis Ende hinter Index kopieren
+ memcpy( pNewBlock->pNodes+nIndex+1,
+ pNodes+nMiddle+nIndex,
+ (nCount-nMiddle-nIndex) * sizeof(PVOID) );
+
+ pNewBlock->nCount = (nCount-nMiddle+1);
+ nCount = nMiddle;
+
+ // Den aktuellen Datenbereich auch halbieren
+ if ( nSize != nNewSize )
+ {
+ void** pNewNodes = new PVOID[nNewSize];
+ memcpy( pNewNodes, pNodes, nCount*sizeof(PVOID) );
+ delete[] pNodes;
+ pNodes = pNewNodes;
+ nSize = nNewSize;
+ }
+ }
+ }
+ else
+ {
+ // Neuen Split-Block anlegen und vor dem aktuellem Block einfuegen
+ pNewBlock = new CBlock( nNewSize, pPrev, this );
+
+ if ( pPrev )
+ pPrev->pNext = pNewBlock;
+ pPrev = pNewBlock;
+
+ if ( nIndex == 0 )
+ {
+ // Neuen Pointer einfuegen
+ pNewBlock->pNodes[0] = p;
+ pNewBlock->nCount = 1;
+ }
+ else
+ {
+ // Alles von Anfang bis Index kopieren
+ memcpy( pNewBlock->pNodes, pNodes, nIndex*sizeof(PVOID) );
+
+ // Neuen Pointer einfuegen
+ pNewBlock->pNodes[nIndex] = p;
+
+ // Alles von Index bis Mitte hinter Index kopieren
+ if ( nIndex != nMiddle )
+ {
+ memcpy( pNewBlock->pNodes+nIndex+1,
+ pNodes+nIndex,
+ (nMiddle-nIndex) * sizeof(PVOID) );
+ }
+
+ pNewBlock->nCount = nMiddle+1;
+ nCount = nCount - nMiddle; // MSVC warns here if += is used
+
+ // Die zweite Haelfte in einen neuen Block kopieren
+ if ( nSize != nNewSize )
+ {
+ void** pNewNodes = new PVOID[nNewSize];
+ memcpy( pNewNodes, pNodes+nMiddle, nCount*sizeof(PVOID) );
+ delete[] pNodes;
+ pNodes = pNewNodes;
+ nSize = nNewSize;
+ }
+ else
+ memmove( pNodes, pNodes+nMiddle, nCount*sizeof(PVOID) );
+ }
+ }
+
+ // Neu angelegten Block zurueckgeben, da gegebenfalls die Blockpointer
+ // im Container angepast werden koennen
+ return pNewBlock;
+}
+
+/*************************************************************************
+|*
+|* CBlock::Remove()
+|*
+|* Beschreibung Entfernt einen Pointer
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void* CBlock::Remove( USHORT nIndex, USHORT nReSize )
+{
+ DBG_CHKTHIS( CBlock, DbgCheckCBlock );
+
+ // Alten Pointer sichern
+ void* pOld = pNodes[nIndex];
+
+ // 1 Element weniger
+ nCount--;
+
+ // Block verkleinern (wenn Reallokationsgroesse um 4 unterschritten wird)
+ if ( nCount == (nSize-nReSize-4) )
+ {
+ // Neue Daten anlegen
+ nSize = nSize - nReSize; // MSVC warns here if += is used
+ void** pNewNodes = new PVOID[nSize];
+
+ // Wird letzter Eintrag geloescht
+ if ( nIndex == nCount )
+ {
+ // Daten kopieren
+ memcpy( pNewNodes, pNodes, nCount*sizeof(PVOID) );
+ }
+ else
+ {
+ // Daten kopieren
+ memcpy( pNewNodes, pNodes, nIndex*sizeof(PVOID) );
+ memcpy( pNewNodes + nIndex, pNodes + nIndex+1,
+ (nCount-nIndex)*sizeof(PVOID) );
+ }
+
+ // Alte Daten loeschen und neue setzen
+ delete[] pNodes;
+ pNodes = pNewNodes;
+ }
+ else
+ {
+ // Wenn nicht das letzte Element, dann zusammenschieben
+ if ( nIndex < nCount )
+ {
+ memmove( pNodes + nIndex, pNodes + nIndex + 1,
+ (nCount-nIndex)*sizeof(PVOID) );
+ }
+ }
+
+ // Alten Pointer zurueckgeben
+ return pOld;
+}
+
+/*************************************************************************
+|*
+|* CBlock::Replace()
+|*
+|* Beschreibung Ersetzt einen Pointer
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+inline void* CBlock::Replace( void* p, USHORT nIndex )
+{
+ DBG_CHKTHIS( CBlock, DbgCheckCBlock );
+
+ // Alten Pointer sichern, neuen setzen und alten zurueckgeben
+ void* pOld = pNodes[nIndex];
+ pNodes[nIndex] = p;
+ return pOld;
+}
+
+/*************************************************************************
+|*
+|* CBlock::GetObjectPtr()
+|*
+|* Beschreibung Gibt einen Pointer auf den Pointer aus dem Block
+|* zurueck
+|* Ersterstellung TH 26.01.93
+|* Letzte Aenderung TH 26.01.93
+|*
+*************************************************************************/
+
+inline void** CBlock::GetObjectPtr( USHORT nIndex )
+{
+ DBG_CHKTHIS( CBlock, DbgCheckCBlock );
+
+ return &(pNodes[nIndex]);
+}
+
+/*************************************************************************
+|*
+|* CBlock::SetSize()
+|*
+|* Beschreibung Aendert die Groesse des Blocks
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void CBlock::SetSize( USHORT nNewSize )
+{
+ DBG_CHKTHIS( CBlock, DbgCheckCBlock );
+ DBG_ASSERT( nNewSize, "CBlock::SetSize(): nNewSize == 0" );
+
+ // Unterscheidet sich die Groesse
+ if ( nNewSize != nCount )
+ {
+ // Array erweitern
+ void** pNewNodes = new PVOID[nNewSize];
+
+ // Alte Tabelle in die Neue kopieren
+ if ( nNewSize < nCount )
+ memcpy( pNewNodes, pNodes, nNewSize*sizeof(PVOID) );
+ else
+ {
+ memcpy( pNewNodes, pNodes, nCount*sizeof(PVOID) );
+
+ // Array mit 0 initialisieren
+ memset( pNewNodes+nCount, 0, (nNewSize-nCount)*sizeof(PVOID) );
+ }
+
+ // Altes Array loeschen und neue Werte setzen
+ nSize = nNewSize;
+ nCount = nSize;
+ delete[] pNodes;
+ pNodes = pNewNodes;
+ }
+}
+
+//------------------------------------------------------------------------
+
+/*************************************************************************
+|*
+|* DbgCheckContainer()
+|*
+|* Beschreibung Pruefung eines Container fuer Debug-Utilities
+|* Ersterstellung MI 30.01.92
+|* Letzte Aenderung TH 24.01.96
+|*
+*************************************************************************/
+
+#ifdef DBG_UTIL
+const char* Container::DbgCheckContainer( const void* pCont )
+{
+ Container* p = (Container*)pCont;
+
+ if ( p->nCount && (!p->pFirstBlock || !p->pLastBlock || !p->pCurBlock) )
+ return "nCount > 0 but no CBlocks";
+
+ return NULL;
+}
+#endif
+
+/*************************************************************************
+|*
+|* ImpCopyContainer()
+|*
+|* Beschreibung Kopiert alle Daten des Containers
+|* Ersterstellung TH 24.01.96
+|* Letzte Aenderung TH 24.01.96
+|*
+*************************************************************************/
+
+void Container::ImpCopyContainer( const Container* pCont2 )
+{
+ // Werte vom uebergebenen Container uebernehmen
+ nCount = pCont2->nCount;
+ nCurIndex = pCont2->nCurIndex;
+ nInitSize = pCont2->nInitSize;
+ nReSize = pCont2->nReSize;
+ nBlockSize = pCont2->nBlockSize;
+
+ // Alle Bloecke kopieren
+ if ( pCont2->nCount )
+ {
+ CBlock* pBlock1;
+ CBlock* pBlock2;
+ CBlock* pTempBlock;
+
+ // Erstmal ersten Block kopieren
+ pBlock2 = pCont2->pFirstBlock;
+ pFirstBlock = new CBlock( *pBlock2, NULL );
+ // Ist erster Block der Current-Block, dann Current-Block setzen
+ if ( pBlock2 == pCont2->pCurBlock )
+ pCurBlock = pFirstBlock;
+ pBlock1 = pFirstBlock;
+ pBlock2 = pBlock2->GetNextBlock();
+ while ( pBlock2 )
+ {
+ // Neuen Block anlegen und aus der uebergebenen Liste kopieren
+ pTempBlock = new CBlock( *pBlock2, pBlock1 );
+ pBlock1->SetNextBlock( pTempBlock );
+ pBlock1 = pTempBlock;
+
+ // Current-Block beruecksichtigen
+ if ( pBlock2 == pCont2->pCurBlock )
+ pCurBlock = pBlock1;
+
+ // Auf naechsten Block weitersetzen
+ pBlock2 = pBlock2->GetNextBlock();
+ }
+
+ // Letzten Block setzen
+ pLastBlock = pBlock1;
+ }
+ else
+ {
+ pFirstBlock = NULL;
+ pLastBlock = NULL;
+ pCurBlock = NULL;
+ }
+}
+
+/*************************************************************************
+|*
+|* Container::Container()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+Container::Container( USHORT _nBlockSize, USHORT _nInitSize, USHORT _nReSize )
+{
+ DBG_CTOR( Container, DbgCheckContainer );
+
+ // BlockSize muss mindestens 4 sein und kleiner als 64 KB
+ if ( _nBlockSize < 4 )
+ nBlockSize = 4;
+ else
+ {
+ if ( _nBlockSize < CONTAINER_MAXBLOCKSIZE )
+ nBlockSize = _nBlockSize;
+ else
+ nBlockSize = CONTAINER_MAXBLOCKSIZE;
+ }
+
+ // ReSize muss mindestens 2 sein und kleiner als BlockSize
+ if ( _nReSize >= nBlockSize )
+ nReSize = nBlockSize;
+ else
+ {
+ if ( _nReSize < 2 )
+ nReSize = 2;
+ else
+ nReSize = _nReSize;
+
+ // BlockSize muss ein vielfaches der Resizegroesse sein
+ if ( nBlockSize % nReSize )
+ nBlockSize -= nReSize - (nBlockSize % nReSize);
+ }
+
+ // InitSize muss groesser gleich ReSize sein und kleiner als BlockSize
+ if ( _nInitSize <= nReSize )
+ nInitSize = nReSize;
+ else
+ {
+ if ( _nInitSize >= nBlockSize )
+ nInitSize = nBlockSize;
+ else
+ {
+ nInitSize = _nInitSize;
+
+ // InitSize muss ein vielfaches der Resizegroesse sein
+ if ( nInitSize % nReSize )
+ nInitSize -= nReSize - (nInitSize % nReSize);
+ }
+ }
+
+ // Werte initialisieren
+ pFirstBlock = NULL;
+ pLastBlock = NULL;
+ pCurBlock = NULL;
+ nCount = 0;
+ nCurIndex = 0;
+}
+
+/*************************************************************************
+|*
+|* Container::Container()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+Container::Container( ULONG nSize )
+{
+ DBG_CTOR( Container, DbgCheckContainer );
+
+ nCount = nSize;
+ nCurIndex = 0;
+ nBlockSize = CONTAINER_MAXBLOCKSIZE;
+ nInitSize = 1;
+ nReSize = 1;
+
+ if ( !nSize )
+ {
+ pFirstBlock = NULL;
+ pLastBlock = NULL;
+ pCurBlock = NULL;
+ }
+ else
+ {
+ // Muss mehr als ein Block angelegt werden
+ if ( nSize <= nBlockSize )
+ {
+ pFirstBlock = new CBlock( (USHORT)nSize, NULL );
+ pLastBlock = pFirstBlock;
+ }
+ else
+ {
+ CBlock* pBlock1;
+ CBlock* pBlock2;
+
+ pFirstBlock = new CBlock( nBlockSize, NULL );
+ pBlock1 = pFirstBlock;
+ nSize -= nBlockSize;
+
+ // Solange die Blockgroesse ueberschritten wird, neue Bloecke anlegen
+ while ( nSize > nBlockSize )
+ {
+ pBlock2 = new CBlock( nBlockSize, pBlock1 );
+ pBlock1->SetNextBlock( pBlock2 );
+ pBlock1 = pBlock2;
+ nSize -= nBlockSize;
+ }
+
+ pLastBlock = new CBlock( (USHORT)nSize, pBlock1 );
+ pBlock1->SetNextBlock( pLastBlock );
+ }
+
+ pCurBlock = pFirstBlock;
+ }
+}
+
+/*************************************************************************
+|*
+|* Container::Container()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+Container::Container( const Container& r )
+{
+ DBG_CTOR( Container, DbgCheckContainer );
+
+ // Daten kopieren
+ ImpCopyContainer( &r );
+}
+
+/*************************************************************************
+|*
+|* Container::~Container()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+Container::~Container()
+{
+ DBG_DTOR( Container, DbgCheckContainer );
+
+ // Alle Bloecke loeschen
+ CBlock* pBlock = pFirstBlock;
+ while ( pBlock )
+ {
+ CBlock* pTemp = pBlock->GetNextBlock();
+ delete pBlock;
+ pBlock = pTemp;
+ }
+}
+
+/*************************************************************************
+|*
+|* Container::ImpInsert()
+|*
+|* Beschreibung Interne Methode zum Einfuegen eines Pointers
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung DV 01.07.97
+|*
+*************************************************************************/
+
+void Container::ImpInsert( void* p, CBlock* pBlock, USHORT nIndex )
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ if ( !nCount )
+ {
+ if ( !pBlock )
+ {
+ pFirstBlock = new CBlock( nInitSize, NULL, NULL );
+ pLastBlock = pFirstBlock;
+ pCurBlock = pFirstBlock;
+ }
+ pFirstBlock->Insert( p, nIndex, nReSize );
+ }
+ else
+ {
+ // Ist im Block die maximale Blockgroesse erreicht,
+ // dann neuen Block anlegen
+ if ( pBlock->Count() == nBlockSize )
+ {
+ // Block auftrennen
+ CBlock* pNewBlock = pBlock->Split( p, nIndex, nReSize );
+
+ // Wurde Block dahinter angehaegnt
+ if ( pBlock->pNext == pNewBlock )
+ {
+ // Gegebenenfalls LastBlock anpassen
+ if ( pBlock == pLastBlock )
+ pLastBlock = pNewBlock;
+
+ // Current-Position nachfuehren
+ if ( pBlock == pCurBlock )
+ {
+ if ( pBlock->nCount <= nCurIndex )
+ {
+ if ( nIndex <= nCurIndex )
+ nCurIndex++;
+ pCurBlock = pNewBlock;
+ nCurIndex = nCurIndex - pBlock->nCount; // MSVC warns here if += is used
+ }
+ }
+ }
+ else
+ {
+ // Gegebenenfalls FirstBlock anpassen
+ if ( pBlock == pFirstBlock )
+ pFirstBlock = pNewBlock;
+
+ // Current-Position nachfuehren
+ if ( pBlock == pCurBlock )
+ {
+ if ( nIndex <= nCurIndex )
+ nCurIndex++;
+ if ( pNewBlock->nCount <= nCurIndex )
+ nCurIndex = nCurIndex - pNewBlock->nCount; // MSVC warns here if += is used
+ else
+ pCurBlock = pNewBlock;
+ }
+ }
+ }
+ else
+ {
+ // Sonst reicht normales einfuegen in den Block
+ pBlock->Insert( p, nIndex, nReSize );
+
+ // Current-Position nachfuehren
+ if ( (pBlock == pCurBlock) && (nIndex <= nCurIndex) )
+ nCurIndex++;
+ }
+ }
+
+ // Ein neues Item im Container
+ nCount++;
+}
+
+/*************************************************************************
+|*
+|* Container::Insert()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void Container::Insert( void* p )
+{
+ ImpInsert( p, pCurBlock, nCurIndex );
+}
+
+/*************************************************************************
+|*
+|* Container::Insert()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void Container::Insert( void* p, ULONG nIndex )
+{
+ if ( nCount <= nIndex )
+ {
+ if ( pLastBlock )
+ ImpInsert( p, pLastBlock, pLastBlock->Count() );
+ else
+ ImpInsert( p, NULL, 0 );
+ }
+ else
+ {
+ // Block suchen
+ CBlock* pTemp = pFirstBlock;
+ while ( pTemp->Count() < nIndex )
+ {
+ nIndex -= pTemp->Count();
+ pTemp = pTemp->GetNextBlock();
+ }
+
+ ImpInsert( p, pTemp, (USHORT)nIndex );
+ }
+}
+
+/*************************************************************************
+|*
+|* Container::Insert()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void Container::Insert( void* pNew, void* pOld )
+{
+ ULONG nIndex = GetPos( pOld );
+ if ( nIndex != CONTAINER_ENTRY_NOTFOUND )
+ Insert( pNew, nIndex );
+}
+
+/*************************************************************************
+|*
+|* Container::ImpRemove()
+|*
+|* Beschreibung Interne Methode zum Entfernen eines Pointers
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void* Container::ImpRemove( CBlock* pBlock, USHORT nIndex )
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ void* pOld;
+
+ // Ist Liste danach leer
+ if ( nCount == 1 )
+ {
+ // Block und CurIndex zuruecksetzen
+ pOld = pBlock->GetObject( nIndex );
+ pBlock->Reset();
+ nCurIndex = 0;
+ }
+ else
+ {
+ // Ist Block nach Remove leer
+ if ( pBlock->Count() == 1 )
+ {
+ // dann Block entfernen und Block-Pointer umsetzen
+ if ( pBlock->GetPrevBlock() )
+ (pBlock->GetPrevBlock())->SetNextBlock( pBlock->GetNextBlock() );
+ else
+ pFirstBlock = pBlock->GetNextBlock();
+
+ if ( pBlock->GetNextBlock() )
+ (pBlock->GetNextBlock())->SetPrevBlock( pBlock->GetPrevBlock() );
+ else
+ pLastBlock = pBlock->GetPrevBlock();
+
+ // Current-Position nachfuehren
+ if ( pBlock == pCurBlock )
+ {
+ if ( pBlock->GetNextBlock() )
+ {
+ pCurBlock = pBlock->GetNextBlock();
+ nCurIndex = 0;
+ }
+ else
+ {
+ pCurBlock = pBlock->GetPrevBlock();
+ nCurIndex = pCurBlock->Count()-1;
+ }
+ }
+
+ pOld = pBlock->GetObject( nIndex );
+ delete pBlock;
+ }
+ else
+ {
+ // Sonst Item aus dem Block entfernen
+ pOld = pBlock->Remove( nIndex, nReSize );
+
+ // Current-Position nachfuehren
+ if ( (pBlock == pCurBlock) &&
+ ((nIndex < nCurIndex) || ((nCurIndex == pBlock->Count()) && nCurIndex)) )
+ nCurIndex--;
+ }
+ }
+
+ // Jetzt gibt es ein Item weniger
+ nCount--;
+
+ // Und den Pointer zurueckgeben, der entfernt wurde
+ return pOld;
+}
+
+/*************************************************************************
+|*
+|* Container::Remove()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void* Container::Remove()
+{
+ // Wenn kein Item vorhanden ist, NULL zurueckgeben
+ if ( !nCount )
+ return NULL;
+ else
+ return ImpRemove( pCurBlock, nCurIndex );
+}
+
+/*************************************************************************
+|*
+|* Container::Remove()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void* Container::Remove( ULONG nIndex )
+{
+ // Ist Index nicht innerhalb des Containers, dann NULL zurueckgeben
+ if ( nCount <= nIndex )
+ return NULL;
+ else
+ {
+ // Block suchen
+ CBlock* pTemp = pFirstBlock;
+ while ( pTemp->Count() <= nIndex )
+ {
+ nIndex -= pTemp->Count();
+ pTemp = pTemp->GetNextBlock();
+ }
+
+ return ImpRemove( pTemp, (USHORT)nIndex );
+ }
+}
+
+/*************************************************************************
+|*
+|* Container::Replace()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void* Container::Replace( void* p )
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ if ( !nCount )
+ return NULL;
+ else
+ return pCurBlock->Replace( p, nCurIndex );
+}
+
+/*************************************************************************
+|*
+|* Container::Replace()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void* Container::Replace( void* p, ULONG nIndex )
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ // Ist Index nicht innerhalb des Containers, dann NULL zurueckgeben
+ if ( nCount <= nIndex )
+ return NULL;
+ else
+ {
+ // Block suchen
+ CBlock* pTemp = pFirstBlock;
+ while ( pTemp->Count() <= nIndex )
+ {
+ nIndex -= pTemp->Count();
+ pTemp = pTemp->GetNextBlock();
+ }
+
+ return pTemp->Replace( p, (USHORT)nIndex );
+ }
+}
+
+/*************************************************************************
+|*
+|* Container::SetSize()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void Container::SetSize( ULONG nNewSize )
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ if ( nNewSize )
+ {
+ // Unterscheiden sich die Groessen
+ if ( nNewSize != nCount )
+ {
+ CBlock* pTemp;
+ ULONG nTemp;
+
+ // Wird verkleinert
+ if ( nNewSize < nCount )
+ {
+ pTemp = pFirstBlock;
+ nTemp = 0;
+ while ( (nTemp+pTemp->Count()) < nNewSize )
+ {
+ nTemp += pTemp->Count();
+ pTemp = pTemp->GetNextBlock();
+ }
+
+ // Alle folgenden Bloecke loeschen
+ BOOL bLast = FALSE;
+ CBlock* pDelNext;
+ CBlock* pDelBlock = pTemp->GetNextBlock();
+ while ( pDelBlock )
+ {
+ // Muss CurrentBlock umgesetzt werden
+ if ( pDelBlock == pCurBlock )
+ bLast = TRUE;
+ pDelNext = pDelBlock->GetNextBlock();
+ delete pDelBlock;
+ pDelBlock = pDelNext;
+ }
+
+ // Block in der Groesse anpassen, oder bei Groesse 0 loeschen
+ if ( nNewSize > nTemp )
+ {
+ pLastBlock = pTemp;
+ pTemp->SetNextBlock( NULL );
+ pTemp->SetSize( (USHORT)(nNewSize-nTemp) );
+ }
+ else
+ {
+ pLastBlock = pTemp->GetPrevBlock();
+ pLastBlock->SetNextBlock( NULL );
+ delete pTemp;
+ }
+
+ nCount = nNewSize;
+ if ( bLast )
+ {
+ pCurBlock = pLastBlock;
+ nCurIndex = pCurBlock->Count()-1;
+ }
+ }
+ else
+ {
+ // Auf den letzen Puffer setzen
+ pTemp = pLastBlock;
+ nTemp = nNewSize - nCount;
+
+ if ( !pTemp )
+ {
+ // Muss mehr als ein Block angelegt werden
+ if ( nNewSize <= nBlockSize )
+ {
+ pFirstBlock = new CBlock( (USHORT)nNewSize, NULL );
+ pLastBlock = pFirstBlock;
+ }
+ else
+ {
+ CBlock* pBlock1;
+ CBlock* pBlock2;
+
+ pFirstBlock = new CBlock( nBlockSize, NULL );
+ pBlock1 = pFirstBlock;
+ nNewSize -= nBlockSize;
+
+ // Solange die Blockgroesse ueberschritten wird, neue Bloecke anlegen
+ while ( nNewSize > nBlockSize )
+ {
+ pBlock2 = new CBlock( nBlockSize, pBlock1 );
+ pBlock1->SetNextBlock( pBlock2 );
+ pBlock1 = pBlock2;
+ nNewSize -= nBlockSize;
+ }
+
+ pLastBlock = new CBlock( (USHORT)nNewSize, pBlock1 );
+ pBlock1->SetNextBlock( pLastBlock );
+ }
+
+ pCurBlock = pFirstBlock;
+ }
+ // Reicht es, den letzen Puffer in der Groesse anzupassen
+ else if ( (nTemp+pTemp->Count()) <= nBlockSize )
+ pTemp->SetSize( (USHORT)(nTemp+pTemp->Count()) );
+ else
+ {
+ // Puffer auf max. Blockgroesse setzen
+ nTemp -= nBlockSize - pTemp->GetSize();
+ pTemp->SetSize( nBlockSize );
+
+ CBlock* pTemp2;
+ // Solange die Blockgroesse ueberschritten wird,
+ // neue Bloecke anlegen
+ while ( nTemp > nBlockSize )
+ {
+ pTemp2 = new CBlock( nBlockSize, pTemp );
+ pTemp->SetNextBlock( pTemp2 );
+ pTemp = pTemp2;
+ nTemp -= nBlockSize;
+ }
+
+ // Den letzten Block anlegen
+ if ( nTemp )
+ {
+ pLastBlock = new CBlock( (USHORT)nTemp, pTemp );
+ pTemp->SetNextBlock( pLastBlock );
+ }
+ else
+ pLastBlock = pTemp;
+ }
+
+ nCount = nNewSize;
+ }
+ }
+ }
+ else
+ Clear();
+}
+
+/*************************************************************************
+|*
+|* Container::Clear()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void Container::Clear()
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ // Erst alle Bloecke loeschen
+ CBlock* pBlock = pFirstBlock;
+ while ( pBlock )
+ {
+ CBlock* pTemp = pBlock->GetNextBlock();
+ delete pBlock;
+ pBlock = pTemp;
+ }
+
+ // Werte zuruecksetzen
+ pFirstBlock = NULL;
+ pLastBlock = NULL;
+ pCurBlock = NULL;
+ nCount = 0;
+ nCurIndex = 0;
+}
+
+/*************************************************************************
+|*
+|* Container::GetCurObject()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void* Container::GetCurObject() const
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ // NULL, wenn Container leer
+ if ( !nCount )
+ return NULL;
+ else
+ return pCurBlock->GetObject( nCurIndex );
+}
+
+/*************************************************************************
+|*
+|* Container::GetCurPos()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+ULONG Container::GetCurPos() const
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ // CONTAINER_ENTRY_NOTFOUND, wenn Container leer
+ if ( !nCount )
+ return CONTAINER_ENTRY_NOTFOUND;
+ else
+ {
+ // Block suchen
+ CBlock* pTemp = pFirstBlock;
+ ULONG nTemp = 0;
+ while ( pTemp != pCurBlock )
+ {
+ nTemp += pTemp->Count();
+ pTemp = pTemp->GetNextBlock();
+ }
+
+ return nTemp+nCurIndex;
+ }
+}
+
+/*************************************************************************
+|*
+|* Container::GetObjectPtr()
+|*
+|* Beschreibung Interne Methode fuer Referenz-Container
+|* Ersterstellung TH 26.01.93
+|* Letzte Aenderung TH 26.01.93
+|*
+*************************************************************************/
+
+void** Container::GetObjectPtr( ULONG nIndex )
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ // Ist Index nicht innerhalb des Containers, dann NULL zurueckgeben
+ if ( nCount <= nIndex )
+ return NULL;
+ else
+ {
+ // Block suchen
+ CBlock* pTemp = pFirstBlock;
+ while ( pTemp->Count() <= nIndex )
+ {
+ nIndex -= pTemp->Count();
+ pTemp = pTemp->GetNextBlock();
+ }
+
+ // Item innerhalb des gefundenen Blocks zurueckgeben
+ return pTemp->GetObjectPtr( (USHORT)nIndex );
+ }
+}
+
+/*************************************************************************
+|*
+|* Container::GetObject()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void* Container::GetObject( ULONG nIndex ) const
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ // Ist Index nicht innerhalb des Containers, dann NULL zurueckgeben
+ if ( nCount <= nIndex )
+ return NULL;
+ else
+ {
+ // Block suchen
+ CBlock* pTemp = pFirstBlock;
+ while ( pTemp->Count() <= nIndex )
+ {
+ nIndex -= pTemp->Count();
+ pTemp = pTemp->GetNextBlock();
+ }
+
+ // Item innerhalb des gefundenen Blocks zurueckgeben
+ return pTemp->GetObject( (USHORT)nIndex );
+ }
+}
+
+/*************************************************************************
+|*
+|* Container::GetPos()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+ULONG Container::GetPos( const void* p ) const
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ void** pNodes;
+ CBlock* pTemp;
+ ULONG nTemp;
+ USHORT nBlockCount;
+ USHORT i;
+
+ // Block suchen
+ pTemp = pFirstBlock;
+ nTemp = 0;
+ while ( pTemp )
+ {
+ pNodes = pTemp->GetNodes();
+ i = 0;
+ nBlockCount = pTemp->Count();
+ while ( i < nBlockCount )
+ {
+ if ( p == *pNodes )
+ return nTemp+i;
+ pNodes++;
+ i++;
+ }
+ nTemp += nBlockCount;
+ pTemp = pTemp->GetNextBlock();
+ }
+
+ return CONTAINER_ENTRY_NOTFOUND;
+}
+
+/*************************************************************************
+|*
+|* Container::GetPos()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 14.09.94
+|* Letzte Aenderung TH 14.09.94
+|*
+*************************************************************************/
+
+ULONG Container::GetPos( const void* p, ULONG nStartIndex,
+ BOOL bForward ) const
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ // Ist Index nicht innerhalb des Containers, dann NOTFOUND zurueckgeben
+ if ( nCount <= nStartIndex )
+ return CONTAINER_ENTRY_NOTFOUND;
+ else
+ {
+ void** pNodes;
+ USHORT nBlockCount;
+ USHORT i;
+
+ // Block suchen
+ CBlock* pTemp = pFirstBlock;
+ ULONG nTemp = 0;
+ while ( nTemp+pTemp->Count() <= nStartIndex )
+ {
+ nTemp += pTemp->Count();
+ pTemp = pTemp->GetNextBlock();
+ }
+
+ // Jetzt den Pointer suchen
+ if ( bForward )
+ {
+ // Alle Bloecke durchrsuchen
+ i = (USHORT)(nStartIndex - nTemp);
+ pNodes = pTemp->GetObjectPtr( i );
+ do
+ {
+ nBlockCount = pTemp->Count();
+ while ( i < nBlockCount )
+ {
+ if ( p == *pNodes )
+ return nTemp+i;
+ pNodes++;
+ i++;
+ }
+ nTemp += nBlockCount;
+ pTemp = pTemp->GetNextBlock();
+ if ( pTemp )
+ {
+ i = 0;
+ pNodes = pTemp->GetNodes();
+ }
+ else
+ break;
+ }
+ while ( TRUE );
+ }
+ else
+ {
+ // Alle Bloecke durchrsuchen
+ i = (USHORT)(nStartIndex-nTemp)+1;
+ pNodes = pTemp->GetObjectPtr( i-1 );
+ do
+ {
+ do
+ {
+ if ( p == *pNodes )
+ return nTemp+i-1;
+ pNodes--;
+ i--;
+ }
+ while ( i );
+ nTemp -= pTemp->Count();
+ pTemp = pTemp->GetPrevBlock();
+ if ( pTemp )
+ {
+ i = pTemp->Count();
+ // Leere Bloecke in der Kette darf es nicht geben. Nur
+ // wenn ein Block existiert, darf dieser leer sein
+ pNodes = pTemp->GetObjectPtr( i-1 );
+ }
+ else
+ break;
+ }
+ while ( TRUE );
+ }
+ }
+
+ return CONTAINER_ENTRY_NOTFOUND;
+}
+
+/*************************************************************************
+|*
+|* Container::Seek()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void* Container::Seek( ULONG nIndex )
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ // Ist der Container leer, dann NULL zurueckgeben
+ if ( nCount <= nIndex )
+ return NULL;
+ else
+ {
+ // Block suchen
+ CBlock* pTemp = pFirstBlock;
+ while ( pTemp->Count() <= nIndex )
+ {
+ nIndex -= pTemp->Count();
+ pTemp = pTemp->GetNextBlock();
+ }
+
+ // Item innerhalb des gefundenen Blocks zurueckgeben
+ pCurBlock = pTemp;
+ nCurIndex = (USHORT)nIndex;
+ return pCurBlock->GetObject( nCurIndex );
+ }
+}
+
+/*************************************************************************
+|*
+|* Container::First()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void* Container::First()
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ // Ist Container leer, dann NULL zurueckgeben
+ if ( !nCount )
+ return NULL;
+ else
+ {
+ // Block und Index setzen und ersten Pointer zurueckgeben
+ pCurBlock = pFirstBlock;
+ nCurIndex = 0;
+ return pCurBlock->GetObject( nCurIndex );
+ }
+}
+
+/*************************************************************************
+|*
+|* Container::Last()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void* Container::Last()
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ // Ist Container leer, dann NULL zurueckgeben
+ if ( !nCount )
+ return NULL;
+ else
+ {
+ // Block und Index setzen und ersten Pointer zurueckgeben
+ pCurBlock = pLastBlock;
+ nCurIndex = pCurBlock->Count()-1;
+ return pCurBlock->GetObject( nCurIndex );
+ }
+}
+
+/*************************************************************************
+|*
+|* Container::Next()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void* Container::Next()
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ // Ist Container leer, dann NULL zurueckgeben, ansonsten preufen ob
+ // naechste Position noch im aktuellen Block ist. Falls nicht, dann
+ // einen Block weiterschalten (geht ohne Gefahr, da leere Bloecke
+ // nicht vorkommen duerfen, es sein denn, es ist der einzige).
+ if ( !nCount )
+ return NULL;
+ else if ( (nCurIndex+1) < pCurBlock->Count() )
+ return pCurBlock->GetObject( ++nCurIndex );
+ else if ( pCurBlock->GetNextBlock() )
+ {
+ pCurBlock = pCurBlock->GetNextBlock();
+ nCurIndex = 0;
+ return pCurBlock->GetObject( nCurIndex );
+ }
+ else
+ return NULL;
+}
+
+/*************************************************************************
+|*
+|* Container::Prev()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void* Container::Prev()
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ // Ist Container leer, dann NULL zurueckgeben, ansonsten preufen ob
+ // vorherige Position noch im aktuellen Block ist. Falls nicht, dann
+ // einen Block zurueckschalten (geht ohne Gefahr, da leere Bloecke
+ // nicht vorkommen duerfen, es sein denn, es ist der einzige).
+ if ( !nCount )
+ return NULL;
+ else if ( nCurIndex )
+ return pCurBlock->GetObject( --nCurIndex );
+ else if ( pCurBlock->GetPrevBlock() )
+ {
+ pCurBlock = pCurBlock->GetPrevBlock();
+ nCurIndex = pCurBlock->Count() - 1;
+ return pCurBlock->GetObject( nCurIndex );
+ }
+ else
+ return NULL;
+}
+
+/*************************************************************************
+|*
+|* Container::operator =()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+Container& Container::operator =( const Container& r )
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ // Erst alle Bloecke loeschen
+ CBlock* pBlock = pFirstBlock;
+ while ( pBlock )
+ {
+ CBlock* pTemp = pBlock->GetNextBlock();
+ delete pBlock;
+ pBlock = pTemp;
+ }
+
+ // Daten kopieren
+ ImpCopyContainer( &r );
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* Container::operator ==()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+BOOL Container::operator ==( const Container& r ) const
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ if ( nCount != r.nCount )
+ return FALSE;
+
+ ULONG i = 0;
+ while ( i < nCount )
+ {
+ if ( GetObject( i ) != r.GetObject( i ) )
+ return FALSE;
+ i++;
+ }
+
+ return TRUE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/memtools/makefile.mk b/tools/source/memtools/makefile.mk
new file mode 100644
index 000000000000..de03a0d50cc3
--- /dev/null
+++ b/tools/source/memtools/makefile.mk
@@ -0,0 +1,56 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=tools
+TARGET=mtools
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/contnr.obj \
+ $(SLO)$/table.obj \
+ $(SLO)$/unqidx.obj \
+ $(SLO)$/mempool.obj \
+ $(SLO)$/multisel.obj
+
+EXCEPTIONSFILES= $(SLO)$/multisel.obj $(OBJ)$/multisel.obj
+
+OBJFILES= $(OBJ)$/contnr.obj \
+ $(OBJ)$/table.obj \
+ $(OBJ)$/unqidx.obj \
+ $(OBJ)$/mempool.obj \
+ $(OBJ)$/multisel.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/tools/source/memtools/mempool.cxx b/tools/source/memtools/mempool.cxx
new file mode 100644
index 000000000000..7bec8980aaba
--- /dev/null
+++ b/tools/source/memtools/mempool.cxx
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <tools/mempool.hxx>
+#include "rtl/alloc.h"
+
+#include <stdio.h>
+
+/*************************************************************************
+|*
+|* FixedMemPool::FixedMemPool()
+|*
+*************************************************************************/
+
+FixedMemPool::FixedMemPool (
+ USHORT _nTypeSize, USHORT, USHORT)
+{
+ char name[RTL_CACHE_NAME_LENGTH + 1];
+ snprintf (name, sizeof(name), "FixedMemPool_%d", (int)_nTypeSize);
+ m_pImpl = (FixedMemPool_Impl*)rtl_cache_create (name, _nTypeSize, 0, NULL, NULL, NULL, 0, NULL, 0);
+}
+
+/*************************************************************************
+|*
+|* FixedMemPool::~FixedMemPool()
+|*
+*************************************************************************/
+
+FixedMemPool::~FixedMemPool()
+{
+ rtl_cache_destroy ((rtl_cache_type*)(m_pImpl));
+}
+
+/*************************************************************************
+|*
+|* FixedMemPool::Alloc()
+|*
+*************************************************************************/
+
+void* FixedMemPool::Alloc()
+{
+ return rtl_cache_alloc ((rtl_cache_type*)(m_pImpl));
+}
+
+/*************************************************************************
+|*
+|* FixedMemPool::Free()
+|*
+*************************************************************************/
+
+void FixedMemPool::Free( void* pFree )
+{
+ rtl_cache_free ((rtl_cache_type*)(m_pImpl), pFree);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/memtools/multisel.cxx b/tools/source/memtools/multisel.cxx
new file mode 100644
index 000000000000..c7586af67f94
--- /dev/null
+++ b/tools/source/memtools/multisel.cxx
@@ -0,0 +1,1164 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#define _SV_MULTISEL_CXX
+
+#ifdef MI_DEBUG
+#define private public
+#include <stdio.h>
+#endif
+
+#include <tools/debug.hxx>
+#include <tools/multisel.hxx>
+
+#include "rtl/ustrbuf.hxx"
+
+#ifdef MI_DEBUG
+#define DBG(x) x
+#else
+#define DBG(x)
+#endif
+
+using namespace rtl;
+
+//==================================================================
+
+#ifdef MI_DEBUG
+
+static void Print( const MultiSelection* pSel )
+{
+ DbgOutf( "TotRange: %4ld-%4ld\n",
+ pSel->aTotRange.Min(), pSel->aTotRange.Max() );
+ if ( pSel->bCurValid )
+ {
+ DbgOutf( "CurSubSel: %4ld\n", pSel->nCurSubSel );
+ DbgOutf( "CurIndex: %4ld\n", pSel->nCurIndex );
+ }
+ DbgOutf( "SelCount: %4ld\n", pSel->nSelCount );
+ DbgOutf( "SubCount: %4ld\n", pSel->aSels.Count() );
+ for ( ULONG nPos = 0; nPos < pSel->aSels.Count(); ++nPos )
+ {
+ DbgOutf( "SubSel #%2ld: %4ld-%4ld\n", nPos,
+ pSel->aSels.GetObject(nPos)->Min(),
+ pSel->aSels.GetObject(nPos)->Max() );
+ }
+ DbgOutf( "\n" );
+ fclose( pFile );
+}
+
+#endif
+
+// -----------------------------------------------------------------------
+
+void MultiSelection::ImplClear()
+{
+ // no selected indexes
+ nSelCount = 0;
+
+ Range* pRange = aSels.First();
+ while ( pRange )
+ {
+ delete pRange;
+ pRange = aSels.Next();
+ }
+ aSels.Clear();
+}
+
+// -----------------------------------------------------------------------
+
+ULONG MultiSelection::ImplFindSubSelection( long nIndex ) const
+{
+ // iterate through the sub selections
+ ULONG n = 0;
+ for ( ;
+ n < aSels.Count() && nIndex > aSels.GetObject(n)->Max();
+ ++n ) {} /* empty loop */
+ return n;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL MultiSelection::ImplMergeSubSelections( ULONG nPos1, ULONG nPos2 )
+{
+ // didn't a sub selection at nPos2 exist?
+ if ( nPos2 >= aSels.Count() )
+ return FALSE;
+
+ // did the sub selections touch each other?
+ if ( (aSels.GetObject(nPos1)->Max() + 1) == aSels.GetObject(nPos2)->Min() )
+ {
+ // merge them
+ aSels.GetObject(nPos1)->Max() = aSels.GetObject(nPos2)->Max();
+ delete aSels.Remove(nPos2);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+MultiSelection::MultiSelection():
+ aTotRange( 0, -1 ),
+ nCurSubSel(0),
+ nSelCount(0),
+ bCurValid(FALSE),
+ bSelectNew(FALSE)
+{
+}
+
+// -----------------------------------------------------------------------
+
+MultiSelection::MultiSelection( const UniString& rString, sal_Unicode cRange, sal_Unicode cSep ):
+ aTotRange(0,RANGE_MAX),
+ nCurSubSel(0),
+ nSelCount(0),
+ bCurValid(FALSE),
+ bSelectNew(FALSE)
+{
+ // Dies ist nur ein Schnellschuss und sollte bald optimiert,
+ // an die verschiedenen Systeme (UNIX etc.)
+ // und die gewuenschte Eingabe-Syntax angepasst werden.
+
+ UniString aStr( rString );
+ sal_Unicode* pStr = aStr.GetBufferAccess();
+ sal_Unicode* pOld = pStr;
+ BOOL bReady = FALSE;
+ BOOL bUntil = FALSE;
+ xub_StrLen nCut = 0;
+
+ // Hier normieren wir den String, sodass nur Ziffern,
+ // Semikola als Trenn- und Minus als VonBis-Zeichen
+ // uebrigbleiben, z.B. "99-117;55;34;-17;37-43"
+ while ( *pOld )
+ {
+ switch( *pOld )
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ DBG_ASSERT( *pOld != cRange, "digit for range char not allowed" );
+ DBG_ASSERT( *pOld != cSep, "digit for separator not allowed" );
+ if( bReady )
+ {
+ *pStr++ = ';';
+ nCut++;
+ bReady = FALSE;
+ }
+ *pStr++ = *pOld;
+ nCut++;
+ bUntil = FALSE;
+ break;
+
+ case '-':
+ case ':':
+ case '/':
+ if ( *pOld != cSep )
+ {
+ if ( !bUntil )
+ {
+ *pStr++ = '-';
+ nCut++;
+ bUntil = TRUE;
+ }
+ bReady = FALSE;
+ }
+ else
+ bReady = TRUE;
+ break;
+
+ case ' ':
+ DBG_ASSERT( *pOld != cRange, "SPACE for range char not allowed" );
+ DBG_ASSERT( *pOld != cSep, "SPACE for separator not allowed" );
+ bReady = !bUntil;
+ break;
+
+ default:
+ if ( *pOld == cRange )
+ {
+ if ( !bUntil )
+ {
+ *pStr++ = '-';
+ nCut++;
+ bUntil = TRUE;
+ }
+ bReady = FALSE;
+ }
+ else
+ bReady = TRUE;
+ break;
+ }
+
+ pOld++;
+ }
+ aStr.ReleaseBufferAccess( nCut );
+
+ // Jetzt wird der normierte String ausgewertet ..
+ UniString aNumStr;
+ Range aRg( 1, RANGE_MAX );
+ const sal_Unicode* pCStr = aStr.GetBuffer();
+ long nPage = 1;
+ long nNum = 1;
+ bUntil = FALSE;
+ while ( *pCStr )
+ {
+ switch ( *pCStr )
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ aNumStr += *pCStr;
+ break;
+ case ';':
+ nNum = aNumStr.ToInt32();
+ if ( bUntil )
+ {
+ if ( !aNumStr.Len() )
+ nNum = RANGE_MAX;
+ aRg.Min() = nPage;
+ aRg.Max() = nNum;
+ aRg.Justify();
+ Select( aRg );
+ }
+ else
+ Select( nNum );
+ nPage = 0;
+ aNumStr.Erase();
+ bUntil = FALSE;
+ break;
+
+ case '-':
+ nPage = aNumStr.ToInt32();
+ aNumStr.Erase();
+ bUntil = TRUE;
+ break;
+ }
+
+ pCStr++;
+ }
+
+ nNum = aNumStr.ToInt32();
+ if ( bUntil )
+ {
+ if ( !aNumStr.Len() )
+ nNum = RANGE_MAX;
+ aRg.Min() = nPage;
+ aRg.Max() = nNum;
+ aRg.Justify();
+ Select( aRg );
+ }
+ else
+ Select( nNum );
+}
+
+// -----------------------------------------------------------------------
+
+MultiSelection::MultiSelection( const MultiSelection& rOrig ) :
+ aTotRange(rOrig.aTotRange),
+ nSelCount(rOrig.nSelCount),
+ bCurValid(rOrig.bCurValid),
+ bSelectNew(FALSE)
+{
+ if ( bCurValid )
+ {
+ nCurSubSel = rOrig.nCurSubSel;
+ nCurIndex = rOrig.nCurIndex;
+ }
+
+ // copy the sub selections
+ for ( ULONG n = 0; n < rOrig.aSels.Count(); ++n )
+ aSels.Insert( new Range( *rOrig.aSels.GetObject(n) ), LIST_APPEND );
+}
+
+// -----------------------------------------------------------------------
+
+MultiSelection::MultiSelection( const Range& rRange ):
+ aTotRange(rRange),
+ nCurSubSel(0),
+ nSelCount(0),
+ bCurValid(FALSE),
+ bSelectNew(FALSE)
+{
+}
+
+// -----------------------------------------------------------------------
+
+MultiSelection::~MultiSelection()
+{
+ Range* pRange = aSels.First();
+ while ( pRange )
+ {
+ delete pRange;
+ pRange = aSels.Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+MultiSelection& MultiSelection::operator= ( const MultiSelection& rOrig )
+{
+ aTotRange = rOrig.aTotRange;
+ bCurValid = rOrig.bCurValid;
+ if ( bCurValid )
+ {
+ nCurSubSel = rOrig.nCurSubSel;
+ nCurIndex = rOrig.nCurIndex;
+ }
+
+ // clear the old and copy the sub selections
+ ImplClear();
+ for ( ULONG n = 0; n < rOrig.aSels.Count(); ++n )
+ aSels.Insert( new Range( *rOrig.aSels.GetObject(n) ), LIST_APPEND );
+ nSelCount = rOrig.nSelCount;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL MultiSelection::operator== ( MultiSelection& rWith )
+{
+ if ( aTotRange != rWith.aTotRange || nSelCount != rWith.nSelCount ||
+ aSels.Count() != rWith.aSels.Count() )
+ return FALSE;
+
+ // compare the sub seletions
+ for ( ULONG n = 0; n < aSels.Count(); ++n )
+ if ( *aSels.GetObject(n) != *rWith.aSels.GetObject(n) )
+ return FALSE;
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void MultiSelection::SelectAll( BOOL bSelect )
+{
+ DBG(DbgOutf( "::SelectAll(%s)\n", bSelect ? "TRUE" : "FALSE" ));
+
+ ImplClear();
+ if ( bSelect )
+ {
+ aSels.Insert( new Range(aTotRange), LIST_APPEND );
+ nSelCount = aTotRange.Len();
+ }
+
+ DBG(Print( this ));
+}
+
+// -----------------------------------------------------------------------
+
+BOOL MultiSelection::Select( long nIndex, BOOL bSelect )
+{
+ DBG_ASSERT( aTotRange.IsInside(nIndex), "selected index out of range" );
+
+ // out of range?
+ if ( !aTotRange.IsInside(nIndex) )
+ return FALSE;
+
+ // find the virtual target position
+ ULONG nSubSelPos = ImplFindSubSelection( nIndex );
+
+ if ( bSelect )
+ {
+ // is it included in the found sub selection?
+ if ( nSubSelPos < aSels.Count() &&
+ aSels.GetObject(nSubSelPos)->IsInside( nIndex ) )
+ // already selected, nothing to do
+ return FALSE;
+
+ // it will become selected
+ ++nSelCount;
+
+ // is it at the end of the previous sub selection
+ if ( nSubSelPos > 0 &&
+ aSels.GetObject(nSubSelPos-1)->Max() == (nIndex-1) )
+ {
+ // expand the previous sub selection
+ aSels.GetObject(nSubSelPos-1)->Max() = nIndex;
+
+ // try to merge the previous sub selection
+ ImplMergeSubSelections( nSubSelPos-1, nSubSelPos );
+ }
+ // is is at the beginning of the found sub selection
+ else if ( nSubSelPos < aSels.Count() &&
+ aSels.GetObject(nSubSelPos)->Min() == (nIndex+1) )
+ // expand the found sub selection
+ aSels.GetObject(nSubSelPos)->Min() = nIndex;
+ else
+ {
+ // create a new sub selection
+ aSels.Insert( new Range( nIndex, nIndex ), nSubSelPos );
+ if ( bCurValid && nCurSubSel >= nSubSelPos )
+ ++nCurSubSel;
+ }
+ }
+ else
+ {
+ // is it excluded from the found sub selection?
+ if ( nSubSelPos >= aSels.Count() ||
+ !aSels.GetObject(nSubSelPos)->IsInside( nIndex ) )
+ {
+ // not selected, nothing to do
+ DBG(Print( this ));
+ return FALSE;
+ }
+
+ // it will become deselected
+ --nSelCount;
+
+ // is it the only index in the found sub selection?
+ if ( aSels.GetObject(nSubSelPos)->Len() == 1 )
+ {
+ // remove the complete sub selection
+ delete aSels.Remove( nSubSelPos );
+ DBG(Print( this ));
+ return TRUE;
+ }
+
+ // is it at the beginning of the found sub selection?
+ if ( aSels.GetObject(nSubSelPos)->Min() == nIndex )
+ ++aSels.GetObject(nSubSelPos)->Min();
+ // is it at the end of the found sub selection?
+ else if ( aSels.GetObject(nSubSelPos)->Max() == nIndex )
+ --aSels.GetObject(nSubSelPos)->Max();
+ // it is in the middle of the found sub selection?
+ else
+ {
+ // split the sub selection
+ aSels.Insert(
+ new Range( aSels.GetObject(nSubSelPos)->Min(), nIndex-1 ),
+ nSubSelPos );
+ aSels.GetObject(nSubSelPos+1)->Min() = nIndex + 1;
+ }
+ }
+
+ DBG(Print( this ));
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void MultiSelection::Select( const Range& rIndexRange, BOOL bSelect )
+{
+ Range* pRange;
+ long nOld;
+
+ ULONG nTmpMin = rIndexRange.Min();
+ ULONG nTmpMax = rIndexRange.Max();
+ ULONG nCurMin = FirstSelected();
+ ULONG nCurMax = LastSelected();
+ DBG_ASSERT(aTotRange.IsInside(nTmpMax), "selected index out of range" );
+ DBG_ASSERT(aTotRange.IsInside(nTmpMin), "selected index out of range" );
+
+ // gesamte Selektion ersetzen ?
+ if( nTmpMin <= nCurMin && nTmpMax >= nCurMax )
+ {
+ ImplClear();
+ if ( bSelect )
+ {
+ aSels.Insert( new Range(rIndexRange), LIST_APPEND );
+ nSelCount = rIndexRange.Len();
+ }
+ return;
+ }
+ // links erweitern ?
+ if( nTmpMax < nCurMin )
+ {
+ if( bSelect )
+ {
+ // ersten Range erweitern ?
+ if( nCurMin > (nTmpMax+1) )
+ {
+ pRange = new Range( rIndexRange );
+ aSels.Insert( pRange, (ULONG)0 );
+ nSelCount += pRange->Len();
+ }
+ else
+ {
+ pRange = aSels.First();
+ nOld = pRange->Min();
+ pRange->Min() = (long)nTmpMin;
+ nSelCount += ( nOld - nTmpMin );
+ }
+ bCurValid = FALSE;
+ }
+ return;
+ }
+ // rechts erweitern ?
+ else if( nTmpMin > nCurMax )
+ {
+ if( bSelect )
+ {
+ // letzten Range erweitern ?
+ if( nTmpMin > (nCurMax+1) )
+ {
+ pRange = new Range( rIndexRange );
+ aSels.Insert( pRange, LIST_APPEND );
+ nSelCount += pRange->Len();
+ }
+ else
+ {
+ pRange = aSels.Last();
+ nOld = pRange->Max();
+ pRange->Max() = (long)nTmpMax;
+ nSelCount += ( nTmpMax - nOld );
+ }
+ bCurValid = FALSE;
+ }
+ return;
+ }
+
+ //HACK(Hier muss noch optimiert werden)
+ while( nTmpMin <= nTmpMax )
+ {
+ Select( nTmpMin, bSelect );
+ nTmpMin++;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL MultiSelection::IsSelected( long nIndex ) const
+{
+ // find the virtual target position
+ ULONG nSubSelPos = ImplFindSubSelection( nIndex );
+
+ return nSubSelPos < aSels.Count() &&
+ aSels.GetObject(nSubSelPos)->IsInside(nIndex);
+}
+
+// -----------------------------------------------------------------------
+
+void MultiSelection::Insert( long nIndex, long nCount )
+{
+ DBG(DbgOutf( "::Insert(%ld, %ld)\n", nIndex, nCount ));
+
+ // find the virtual target position
+ ULONG nSubSelPos = ImplFindSubSelection( nIndex );
+
+ // did we need to shift the sub selections?
+ if ( nSubSelPos < aSels.Count() )
+ {
+ // did we insert an unselected into an existing sub selection?
+ if ( !bSelectNew && aSels.GetObject(nSubSelPos)->Min() != nIndex &&
+ aSels.GetObject(nSubSelPos)->IsInside(nIndex) )
+ {
+ // split the sub selection
+ aSels.Insert(
+ new Range( aSels.GetObject(nSubSelPos)->Min(), nIndex-1 ),
+ nSubSelPos );
+ ++nSubSelPos;
+ aSels.GetObject(nSubSelPos)->Min() = nIndex;
+ }
+
+ // did we append an selected to an existing sub selection?
+ else if ( bSelectNew && nSubSelPos > 0 &&
+ aSels.GetObject(nSubSelPos)->Max() == nIndex-1 )
+ // expand the previous sub selection
+ aSels.GetObject(nSubSelPos-1)->Max() += nCount;
+
+ // did we insert an selected into an existing sub selection?
+ else if ( bSelectNew && aSels.GetObject(nSubSelPos)->Min() == nIndex )
+ {
+ // expand the sub selection
+ aSels.GetObject(nSubSelPos)->Max() += nCount;
+ ++nSubSelPos;
+ }
+
+ // shift the sub selections behind the inserting position
+ for ( ULONG nPos = nSubSelPos; nPos < aSels.Count(); ++nPos )
+ {
+ aSels.GetObject(nPos)->Min() += nCount;
+ aSels.GetObject(nPos)->Max() += nCount;
+ }
+ }
+
+ bCurValid = FALSE;
+ aTotRange.Max() += nCount;
+ if ( bSelectNew )
+ nSelCount += nCount;
+
+ DBG(Print( this ));
+}
+
+// -----------------------------------------------------------------------
+
+void MultiSelection::Remove( long nIndex )
+{
+ DBG(DbgOutf( "::Remove(%ld)\n", nIndex ));
+
+ // find the virtual target position
+ ULONG nSubSelPos = ImplFindSubSelection( nIndex );
+
+ // did we remove from an existing sub selection?
+ if ( nSubSelPos < aSels.Count() &&
+ aSels.GetObject(nSubSelPos)->IsInside(nIndex) )
+ {
+ // does this sub selection only contain the index to be deleted
+ if ( aSels.GetObject(nSubSelPos)->Len() == 1 )
+ // completely remove the sub selection
+ aSels.Remove(nSubSelPos);
+ else
+ // shorten this sub selection
+ --( aSels.GetObject(nSubSelPos++)->Max() );
+
+ // adjust the selected counter
+ --nSelCount;
+ }
+
+ // shift the sub selections behind the removed index
+ for ( ULONG nPos = nSubSelPos; nPos < aSels.Count(); ++nPos )
+ {
+ --( aSels.GetObject(nPos)->Min() );
+ --( aSels.GetObject(nPos)->Max() );
+ }
+
+ bCurValid = FALSE;
+ aTotRange.Max() -= 1;
+
+ DBG(Print( this ));
+}
+
+// -----------------------------------------------------------------------
+
+void MultiSelection::Append( long nCount )
+{
+ long nPrevLast = aTotRange.Max();
+ aTotRange.Max() += nCount;
+ if ( bSelectNew )
+ {
+ nSelCount += nCount;
+ aSels.Insert( new Range( nPrevLast+1, nPrevLast + nCount ),
+ LIST_APPEND );
+ if ( aSels.Count() > 1 )
+ ImplMergeSubSelections( aSels.Count() - 2, aSels.Count() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long MultiSelection::ImplFwdUnselected()
+{
+ if ( !bCurValid )
+ return SFX_ENDOFSELECTION;
+
+ if ( ( nCurSubSel < aSels.Count() ) &&
+ ( aSels.GetObject(nCurSubSel)->Min() <= nCurIndex ) )
+ nCurIndex = aSels.GetObject(nCurSubSel++)->Max() + 1;
+
+ if ( nCurIndex <= aTotRange.Max() )
+ return nCurIndex;
+ else
+ return SFX_ENDOFSELECTION;
+}
+
+// -----------------------------------------------------------------------
+
+long MultiSelection::ImplBwdUnselected()
+{
+ if ( !bCurValid )
+ return SFX_ENDOFSELECTION;
+
+ if ( aSels.GetObject(nCurSubSel)->Max() < nCurIndex )
+ return nCurIndex;
+
+ nCurIndex = aSels.GetObject(nCurSubSel--)->Min() - 1;
+ if ( nCurIndex >= 0 )
+ return nCurIndex;
+ else
+ return SFX_ENDOFSELECTION;
+}
+
+// -----------------------------------------------------------------------
+
+long MultiSelection::FirstSelected( BOOL bInverse )
+{
+ bInverseCur = bInverse;
+ nCurSubSel = 0;
+
+ if ( bInverseCur )
+ {
+ bCurValid = nSelCount < ULONG(aTotRange.Len());
+ if ( bCurValid )
+ {
+ nCurIndex = 0;
+ return ImplFwdUnselected();
+ }
+ }
+ else
+ {
+ bCurValid = aSels.Count() > 0;
+ if ( bCurValid )
+ return nCurIndex = aSels.GetObject(0)->Min();
+ }
+
+ return SFX_ENDOFSELECTION;
+}
+
+// -----------------------------------------------------------------------
+
+long MultiSelection::LastSelected()
+{
+ nCurSubSel = aSels.Count() - 1;
+ bCurValid = aSels.Count() > 0;
+
+ if ( bCurValid )
+ return nCurIndex = aSels.GetObject(nCurSubSel)->Max();
+
+ return SFX_ENDOFSELECTION;
+}
+
+// -----------------------------------------------------------------------
+
+long MultiSelection::NextSelected()
+{
+ if ( !bCurValid )
+ return SFX_ENDOFSELECTION;
+
+ if ( bInverseCur )
+ {
+ ++nCurIndex;
+ return ImplFwdUnselected();
+ }
+ else
+ {
+ // is the next index in the current sub selection too?
+ if ( nCurIndex < aSels.GetObject(nCurSubSel)->Max() )
+ return ++nCurIndex;
+
+ // are there further sub selections?
+ if ( ++nCurSubSel < aSels.Count() )
+ return nCurIndex = aSels.GetObject(nCurSubSel)->Min();
+
+ // we are at the end!
+ return SFX_ENDOFSELECTION;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long MultiSelection::PrevSelected()
+{
+ if ( !bCurValid )
+ return SFX_ENDOFSELECTION;
+
+ if ( bInverseCur )
+ {
+ --nCurIndex;
+ return ImplBwdUnselected();
+ }
+ else
+ {
+ // is the previous index in the current sub selection too?
+ if ( nCurIndex > aSels.GetObject(nCurSubSel)->Min() )
+ return --nCurIndex;
+
+ // are there previous sub selections?
+ if ( nCurSubSel > 0 )
+ {
+ --nCurSubSel;
+ return nCurIndex = aSels.GetObject(nCurSubSel)->Max();
+ }
+
+ // we are at the beginning!
+ return SFX_ENDOFSELECTION;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void MultiSelection::SetTotalRange( const Range& rTotRange )
+{
+ aTotRange = rTotRange;
+
+ // die untere Bereichsgrenze anpassen
+ Range* pRange = aSels.GetObject( 0 );
+ while( pRange )
+ {
+ if( pRange->Max() < aTotRange.Min() )
+ {
+ delete pRange;
+ aSels.Remove( (ULONG)0 );
+ }
+ else if( pRange->Min() < aTotRange.Min() )
+ {
+ pRange->Min() = aTotRange.Min();
+ break;
+ }
+ else
+ break;
+
+ pRange = aSels.GetObject( 0 );
+ }
+
+ // die obere Bereichsgrenze anpassen
+ ULONG nCount = aSels.Count();
+ while( nCount )
+ {
+ pRange = aSels.GetObject( nCount - 1 );
+ if( pRange->Min() > aTotRange.Max() )
+ {
+ delete pRange;
+ aSels.Remove( (ULONG)(nCount - 1) );
+ }
+ else if( pRange->Max() > aTotRange.Max() )
+ {
+ pRange->Max() = aTotRange.Max();
+ break;
+ }
+ else
+ break;
+
+ nCount = aSels.Count();
+ }
+
+ // Selection-Count neu berechnen
+ nSelCount = 0;
+ pRange = aSels.First();
+ while( pRange )
+ {
+ nSelCount += pRange->Len();
+ pRange = aSels.Next();
+ }
+
+ bCurValid = FALSE;
+ nCurIndex = 0;
+}
+
+// -----------------------------------------------------------------------
+//
+// StringRangeEnumerator
+//
+// -----------------------------------------------------------------------
+StringRangeEnumerator::StringRangeEnumerator( const rtl::OUString& i_rInput,
+ sal_Int32 i_nMinNumber,
+ sal_Int32 i_nMaxNumber,
+ sal_Int32 i_nLogicalOffset
+ )
+ : mnCount( 0 )
+ , mnMin( i_nMinNumber )
+ , mnMax( i_nMaxNumber )
+ , mnOffset( i_nLogicalOffset )
+{
+ setRange( i_rInput );
+}
+
+bool StringRangeEnumerator::checkValue( sal_Int32 i_nValue, const std::set< sal_Int32 >* i_pPossibleValues ) const
+{
+ if( mnMin >= 0 && i_nValue < mnMin )
+ return false;
+ if( mnMax >= 0 && i_nValue > mnMax )
+ return false;
+ if( i_nValue < 0 )
+ return false;
+ if( i_pPossibleValues && i_pPossibleValues->find( i_nValue ) == i_pPossibleValues->end() )
+ return false;
+ return true;
+}
+
+bool StringRangeEnumerator::insertRange( sal_Int32 i_nFirst, sal_Int32 i_nLast, bool bSequence, bool bMayAdjust )
+{
+ bool bSuccess = true;
+ if( bSequence )
+ {
+ if( i_nFirst == -1 )
+ i_nFirst = mnMin;
+ if( i_nLast == -1 )
+ i_nLast = mnMax;
+ if( bMayAdjust )
+ {
+ if( i_nFirst < mnMin )
+ i_nFirst = mnMin;
+ if( i_nFirst > mnMax )
+ i_nFirst = mnMax;
+ if( i_nLast < mnMin )
+ i_nLast = mnMin;
+ if( i_nLast > mnMax )
+ i_nLast = mnMax;
+ }
+ if( checkValue( i_nFirst ) && checkValue( i_nLast ) )
+ {
+ maSequence.push_back( Range( i_nFirst, i_nLast ) );
+ sal_Int32 nNumber = i_nLast - i_nFirst;
+ nNumber = nNumber < 0 ? -nNumber : nNumber;
+ mnCount += nNumber + 1;
+ }
+ else
+ bSuccess = false;
+ }
+ else
+ {
+ if( i_nFirst >= 0 )
+ {
+ if( checkValue( i_nFirst ) )
+ {
+ maSequence.push_back( Range( i_nFirst, i_nFirst ) );
+ mnCount++;
+ }
+ else
+ bSuccess = false;
+ }
+ if( i_nLast >= 0 )
+ {
+ if( checkValue( i_nLast ) )
+ {
+ maSequence.push_back( Range( i_nLast, i_nLast ) );
+ mnCount++;
+ }
+ else
+ bSuccess = false;
+ }
+ }
+
+ return bSuccess;
+}
+
+bool StringRangeEnumerator::setRange( const rtl::OUString& i_rNewRange, bool i_bStrict )
+{
+ mnCount = 0;
+ maSequence.clear();
+
+ // we love special cases
+ if( i_rNewRange.getLength() == 0 )
+ {
+ if( mnMin >= 0 && mnMax >= 0 )
+ {
+ insertRange( mnMin, mnMax, mnMin != mnMax, ! i_bStrict );
+ }
+ return true;
+ }
+
+ const sal_Unicode* pInput = i_rNewRange.getStr();
+ rtl::OUStringBuffer aNumberBuf( 16 );
+ sal_Int32 nLastNumber = -1, nNumber = -1;
+ bool bSequence = false;
+ bool bSuccess = true;
+ while( *pInput )
+ {
+ while( *pInput >= sal_Unicode('0') && *pInput <= sal_Unicode('9') )
+ aNumberBuf.append( *pInput++ );
+ if( aNumberBuf.getLength() )
+ {
+ if( nNumber != -1 )
+ {
+ if( bSequence )
+ {
+ if( ! insertRange( nLastNumber, nNumber, true, ! i_bStrict ) && i_bStrict )
+ {
+ bSuccess = false;
+ break;
+ }
+ nLastNumber = -1;
+ }
+ else
+ {
+ if( ! insertRange( nNumber, nNumber, false, ! i_bStrict ) && i_bStrict )
+ {
+ bSuccess = false;
+ break;
+ }
+ }
+ }
+ nNumber = aNumberBuf.makeStringAndClear().toInt32();
+ nNumber += mnOffset;
+ }
+ bool bInsertRange = false;
+ if( *pInput == sal_Unicode('-') )
+ {
+ nLastNumber = nNumber;
+ nNumber = -1;
+ bSequence = true;
+ }
+ else if( *pInput == ' ' )
+ {
+ }
+ else if( *pInput == sal_Unicode(',') || *pInput == sal_Unicode(';') )
+ bInsertRange = true;
+ else if( *pInput )
+ {
+
+ bSuccess = false;
+ break; // parse error
+ }
+
+ if( bInsertRange )
+ {
+ if( ! insertRange( nLastNumber, nNumber, bSequence, ! i_bStrict ) && i_bStrict )
+ {
+ bSuccess = false;
+ break;
+ }
+ nNumber = nLastNumber = -1;
+ bSequence = false;
+ }
+ if( *pInput )
+ pInput++;
+ }
+ // insert last entries
+ insertRange( nLastNumber, nNumber, bSequence, ! i_bStrict );
+
+ return bSuccess;
+}
+
+bool StringRangeEnumerator::hasValue( sal_Int32 i_nValue, const std::set< sal_Int32 >* i_pPossibleValues ) const
+{
+ if( i_pPossibleValues && i_pPossibleValues->find( i_nValue ) == i_pPossibleValues->end() )
+ return false;
+ size_t n = maSequence.size();
+ for( size_t i= 0; i < n; ++i )
+ {
+ const StringRangeEnumerator::Range rRange( maSequence[i] );
+ if( rRange.nFirst < rRange.nLast )
+ {
+ if( i_nValue >= rRange.nFirst && i_nValue <= rRange.nLast )
+ return true;
+ }
+ else
+ {
+ if( i_nValue >= rRange.nLast && i_nValue <= rRange.nFirst )
+ return true;
+ }
+ }
+ return false;
+}
+
+StringRangeEnumerator::Iterator& StringRangeEnumerator::Iterator::operator++()
+{
+ if( nRangeIndex >= 0 && nCurrent >= 0 && pEnumerator )
+ {
+ const StringRangeEnumerator::Range& rRange( pEnumerator->maSequence[nRangeIndex] );
+ bool bRangeChange = false;
+ if( rRange.nLast < rRange.nFirst )
+ {
+ // backward range
+ if( nCurrent > rRange.nLast )
+ nCurrent--;
+ else
+ bRangeChange = true;
+ }
+ else
+ {
+ // forward range
+ if( nCurrent < rRange.nLast )
+ nCurrent++;
+ else
+ bRangeChange = true;
+ }
+ if( bRangeChange )
+ {
+ nRangeIndex++;
+ if( size_t(nRangeIndex) == pEnumerator->maSequence.size() )
+ {
+ // reached the end
+ nRangeIndex = nCurrent = -1;
+ }
+ else
+ nCurrent = pEnumerator->maSequence[nRangeIndex].nFirst;
+ }
+ if( nRangeIndex != -1 && nCurrent != -1 )
+ {
+ if( ! pEnumerator->checkValue( nCurrent, pPossibleValues ) )
+ return ++(*this);
+ }
+ }
+ return *this;
+}
+
+sal_Int32 StringRangeEnumerator::Iterator::operator*() const
+{
+ return nCurrent;
+}
+
+bool StringRangeEnumerator::Iterator::operator==( const Iterator& i_rCompare ) const
+{
+ return i_rCompare.pEnumerator == pEnumerator && i_rCompare.nRangeIndex == nRangeIndex && i_rCompare.nCurrent == nCurrent;
+}
+
+StringRangeEnumerator::Iterator StringRangeEnumerator::begin( const std::set< sal_Int32 >* i_pPossibleValues ) const
+{
+ StringRangeEnumerator::Iterator it( this,
+ i_pPossibleValues,
+ maSequence.empty() ? -1 : 0,
+ maSequence.empty() ? -1 : maSequence[0].nFirst );
+ if( ! checkValue(*it, i_pPossibleValues ) )
+ ++it;
+ return it;
+}
+
+StringRangeEnumerator::Iterator StringRangeEnumerator::end( const std::set< sal_Int32 >* i_pPossibleValues ) const
+{
+ return StringRangeEnumerator::Iterator( this, i_pPossibleValues, -1, -1 );
+}
+
+bool StringRangeEnumerator::getRangesFromString( const OUString& i_rPageRange,
+ std::vector< sal_Int32 >& o_rPageVector,
+ sal_Int32 i_nMinNumber,
+ sal_Int32 i_nMaxNumber,
+ sal_Int32 i_nLogicalOffset,
+ std::set< sal_Int32 >* i_pPossibleValues
+ )
+{
+ StringRangeEnumerator aEnum;
+ aEnum.setMin( i_nMinNumber );
+ aEnum.setMax( i_nMaxNumber );
+ aEnum.setLogicalOffset( i_nLogicalOffset );
+
+ bool bRes = aEnum.setRange( i_rPageRange );
+ if( bRes )
+ {
+ o_rPageVector.clear();
+ o_rPageVector.reserve( aEnum.size() );
+ for( StringRangeEnumerator::Iterator it = aEnum.begin( i_pPossibleValues );
+ it != aEnum.end( i_pPossibleValues ); ++it )
+ {
+ o_rPageVector.push_back( *it );
+ }
+ }
+
+ return bRes;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/memtools/table.cxx b/tools/source/memtools/table.cxx
new file mode 100644
index 000000000000..18f8cbb64a1a
--- /dev/null
+++ b/tools/source/memtools/table.cxx
@@ -0,0 +1,416 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#define _TOOLS_TABLE_CXX
+
+// -----------------------------------------------------------------------
+#include <tools/debug.hxx>
+#include <impcont.hxx>
+#include <tools/table.hxx>
+
+// =======================================================================
+
+ULONG Table::ImplGetIndex( ULONG nKey, ULONG* pIndex ) const
+{
+ // Abpruefen, ob der erste Key groesser als der Vergleichskey ist
+ if ( !nCount || (nKey < (ULONG)Container::ImpGetObject(0)) )
+ return TABLE_ENTRY_NOTFOUND;
+
+ ULONG nLow;
+ ULONG nHigh;
+ ULONG nMid;
+ ULONG nCompareKey;
+ void** pNodes = Container::ImpGetOnlyNodes();
+
+ // Binaeres Suchen
+ nLow = 0;
+ nHigh = nCount-1;
+ if ( pNodes )
+ {
+ do
+ {
+ nMid = (nLow + nHigh) / 2;
+ nCompareKey = (ULONG)pNodes[nMid*2];
+ if ( nKey < nCompareKey )
+ nHigh = nMid-1;
+ else
+ {
+ if ( nKey > nCompareKey )
+ nLow = nMid + 1;
+ else
+ return nMid*2;
+ }
+ }
+ while ( nLow <= nHigh );
+ }
+ else
+ {
+ do
+ {
+ nMid = (nLow + nHigh) / 2;
+ nCompareKey = (ULONG)Container::ImpGetObject( nMid*2 );
+ if ( nKey < nCompareKey )
+ nHigh = nMid-1;
+ else
+ {
+ if ( nKey > nCompareKey )
+ nLow = nMid + 1;
+ else
+ return nMid*2;
+ }
+ }
+ while ( nLow <= nHigh );
+ }
+
+ if ( pIndex )
+ {
+ if ( nKey > nCompareKey )
+ *pIndex = (nMid+1)*2;
+ else
+ *pIndex = nMid*2;
+ }
+
+ return TABLE_ENTRY_NOTFOUND;
+}
+
+// =======================================================================
+
+Table::Table( USHORT _nInitSize, USHORT _nReSize ) :
+ Container( CONTAINER_MAXBLOCKSIZE, _nInitSize*2, _nReSize*2 )
+{
+ DBG_ASSERT( _nInitSize <= 32767, "Table::Table(): InitSize > 32767" );
+ DBG_ASSERT( _nReSize <= 32767, "Table::Table(): ReSize > 32767" );
+ nCount = 0;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Table::Insert( ULONG nKey, void* p )
+{
+ // Tabellenelement einsortieren
+ ULONG i;
+ if ( nCount )
+ {
+ if ( nCount <= 24 )
+ {
+ USHORT n = 0;
+ USHORT nTempCount = (USHORT)nCount * 2;
+ //<!--Modified by PengYunQuan for resolving a NULL pointer access
+
+ if( void** pNodes = Container::ImpGetOnlyNodes() )
+ {
+ ULONG nCompareKey = (ULONG)(*pNodes);
+ while ( nKey > nCompareKey )
+ {
+ n += 2;
+ pNodes += 2;
+ if ( n < nTempCount )
+ nCompareKey = (ULONG)(*pNodes);
+ else
+ {
+ nCompareKey = 0;
+ break;
+ }
+ }
+
+ // Testen, ob sich der Key schon in der Tabelle befindet
+ if ( nKey == nCompareKey )
+ return FALSE;
+
+ i = n;
+ }
+ else
+ {
+ i = 0;
+ if ( ImplGetIndex( nKey, &i ) != TABLE_ENTRY_NOTFOUND )
+ return FALSE;
+ }
+ //-->Modified by PengYunQuan for resolving a NULL pointer access
+ }
+ else
+ {
+ i = 0;
+ if ( ImplGetIndex( nKey, &i ) != TABLE_ENTRY_NOTFOUND )
+ return FALSE;
+ }
+ }
+ else
+ i = 0;
+
+ // Eintrag einfuegen (Key vor Pointer)
+ Container::Insert( (void*)nKey, i );
+ Container::Insert( p, i+1 );
+
+ // Ein neuer Eintrag
+ nCount++;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void* Table::Remove( ULONG nKey )
+{
+ // Index besorgen
+ ULONG nIndex = ImplGetIndex( nKey );
+
+ // Testen, ob sich der Key in der Tabelle befindet
+ if ( nIndex == TABLE_ENTRY_NOTFOUND )
+ return NULL;
+
+ // Itemanzahl erniedrigen
+ nCount--;
+
+ // Key entfernen
+ Container::Remove( nIndex );
+
+ // Pointer entfernen und zurueckgeben
+ return Container::Remove( nIndex );
+}
+
+// -----------------------------------------------------------------------
+
+void* Table::Replace( ULONG nKey, void* p )
+{
+ // Index abfragen
+ ULONG nIndex = ImplGetIndex( nKey );
+
+ // Existiert kein Eintrag mit dem Schluessel
+ if ( nIndex == TABLE_ENTRY_NOTFOUND )
+ return NULL;
+ else
+ return Container::Replace( p, nIndex+1 );
+}
+
+// -----------------------------------------------------------------------
+
+void* Table::Get( ULONG nKey ) const
+{
+ // Index besorgen
+ ULONG nIndex = ImplGetIndex( nKey );
+
+ // Testen, ob sich der Key in der Tabelle befindet
+ if ( nIndex == TABLE_ENTRY_NOTFOUND )
+ return NULL;
+ else
+ return Container::ImpGetObject( nIndex+1 );
+}
+
+// -----------------------------------------------------------------------
+
+void* Table::GetCurObject() const
+{
+ return Container::ImpGetObject( Container::GetCurPos()+1 );
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Table::GetKey( const void* p ) const
+{
+ ULONG nIndex = 0;
+
+ // Solange noch Eintraege Vorhanden sind
+ while ( nIndex < nCount )
+ {
+ // Stimmt der Pointer ueberein, wird der Key zurueckgegeben
+ if ( p == Container::ImpGetObject( (nIndex*2)+1 ) )
+ return (ULONG)Container::ImpGetObject( nIndex*2 );
+
+ nIndex++;
+ }
+
+ return TABLE_ENTRY_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Table::IsKeyValid( ULONG nKey ) const
+{
+ return (ImplGetIndex( nKey ) != TABLE_ENTRY_NOTFOUND) ? TRUE : FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Table::GetUniqueKey( ULONG nStartKey ) const
+{
+ DBG_ASSERT( (nStartKey > 1) && (nStartKey < 0xFFFFFFFF),
+ "Table::GetUniqueKey() - nStartKey == 0 or nStartKey >= 0xFFFFFFFF" );
+
+ if ( !nCount )
+ return nStartKey;
+
+ ULONG nLastKey = (ULONG)Container::GetObject( (nCount*2)-2 );
+ if ( nLastKey < nStartKey )
+ return nStartKey;
+ else
+ {
+ if ( nLastKey < 0xFFFFFFFE )
+ return nLastKey+1;
+ else
+ {
+ ULONG nPos;
+ ULONG nTempPos = ImplGetIndex( nStartKey, &nPos );
+ if ( nTempPos != TABLE_ENTRY_NOTFOUND )
+ nPos = nTempPos;
+ nLastKey = (ULONG)Container::GetObject( nPos );
+ if ( nStartKey < nLastKey )
+ return nStartKey;
+ while ( nLastKey < 0xFFFFFFFE )
+ {
+ nPos += 2;
+ nLastKey++;
+ if ( nLastKey != (ULONG)Container::GetObject( nPos ) )
+ return nLastKey;
+ }
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Table::SearchKey( ULONG nKey, ULONG* pPos ) const
+{
+ *pPos = 0;
+ ULONG nPos = ImplGetIndex( nKey, pPos );
+ if ( nPos != TABLE_ENTRY_NOTFOUND )
+ {
+ nPos /= 2;
+ *pPos = nPos;
+ }
+ else
+ *pPos /= 2;
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+void* Table::Seek( ULONG nKey )
+{
+ // Testen, ob ein Eintrag vorhanden ist
+ if ( nCount )
+ {
+ ULONG nIndex = ImplGetIndex( nKey );
+
+ // Ist Key nicht enthalten
+ if ( nIndex == TABLE_ENTRY_NOTFOUND )
+ return NULL;
+ else
+ {
+ // Index setzen
+ Container::Seek( nIndex );
+
+ // Pointer zurueckgeben
+ return Container::ImpGetObject( Container::GetCurPos() + 1 );
+ }
+ }
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void* Table::Seek( void* p )
+{
+ ULONG nKey = GetKey( p );
+
+ // Ist Key vorhanden, dann als aktuellen Eintrag setzen
+ if ( nKey != TABLE_ENTRY_NOTFOUND )
+ return Seek( nKey );
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void* Table::First()
+{
+ // Testen, ob ein Eintrag vorhanden ist
+ if ( nCount )
+ {
+ // Auf ersten Eintag setzen
+ Container::First();
+
+ // Pointer zurueckgeben
+ return Container::ImpGetObject( 1 );
+ }
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void* Table::Last()
+{
+ // Testen, ob ein Eintrag vorhanden ist
+ if ( nCount )
+ {
+ // Last auf letzten Eintrag setzen
+ void* p = Container::Last();
+ Container::Prev();
+
+ // Pointer zurueckgeben
+ return p;
+ }
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void* Table::Next()
+{
+ // Ueber den Pointer weiterschalten
+ Container::Next();
+
+ // Nachsten Eintag
+ Container::Next();
+
+ // Pointer vom naechsten Key zurueckgeben
+ return Container::ImpGetObject( Container::GetCurPos() + 1 );
+}
+
+// -----------------------------------------------------------------------
+
+void* Table::Prev()
+{
+ // Ueber den Pointer weiterschalten
+ void* p = Container::Prev();
+
+ // Nachsten Eintag
+ Container::Prev();
+
+ // Pointer vom vorherigen Key zurueckgeben
+ return p;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/memtools/unqidx.cxx b/tools/source/memtools/unqidx.cxx
new file mode 100644
index 000000000000..9252068b8d35
--- /dev/null
+++ b/tools/source/memtools/unqidx.cxx
@@ -0,0 +1,604 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <impcont.hxx>
+#include <tools/unqidx.hxx>
+#include <tools/unqid.hxx>
+
+/*************************************************************************
+|*
+|* UniqueIndex::UniqueIndex()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+UniqueIndex::UniqueIndex( ULONG _nStartIndex,
+ ULONG _nInitSize, ULONG _nReSize ) :
+ Container( _nInitSize )
+{
+ nReSize = _nReSize;
+ nStartIndex = _nStartIndex;
+ nUniqIndex = 0;
+ nCount = 0;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::UniqueIndex()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+UniqueIndex::UniqueIndex( const UniqueIndex& rIdx ) :
+ Container( rIdx )
+{
+ nReSize = rIdx.nReSize;
+ nStartIndex = rIdx.nStartIndex;
+ nUniqIndex = rIdx.nUniqIndex;
+ nCount = rIdx.nCount;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::Insert()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+ULONG UniqueIndex::Insert( void* p )
+{
+ // NULL-Pointer ist nicht erlaubt
+ if ( !p )
+ return UNIQUEINDEX_ENTRY_NOTFOUND;
+
+ // Ist Array voll, dann expandieren
+ if ( nCount == Container::GetSize() )
+ SetSize( nCount + nReSize );
+
+ // Damit UniqIndex nicht ueberlaeuft, wenn Items geloescht wurden
+ nUniqIndex = nUniqIndex % Container::GetSize();
+
+ // Leeren Eintrag suchen
+ while ( Container::ImpGetObject( nUniqIndex ) != NULL )
+ nUniqIndex = (nUniqIndex+1) % Container::GetSize();
+
+ // Object im Array speichern
+ Container::Replace( p, nUniqIndex );
+
+ // Anzahl der Eintraege erhoehen und Index zurueckgeben
+ nCount++;
+ nUniqIndex++;
+ return ( nUniqIndex + nStartIndex - 1 );
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::Insert()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung MM 21.04.96
+|* Letzte Aenderung MM 21.04.96
+|*
+*************************************************************************/
+
+ULONG UniqueIndex::Insert( ULONG nIndex, void* p )
+{
+ // NULL-Pointer ist nicht erlaubt
+ if ( !p )
+ return UNIQUEINDEX_ENTRY_NOTFOUND;
+
+ ULONG nContIndex = nIndex - nStartIndex;
+ // Ist Array voll, dann expandieren
+ if ( nContIndex >= Container::GetSize() )
+ SetSize( nContIndex + nReSize );
+
+ // Object im Array speichern
+ Container::Replace( p, nContIndex );
+
+ // Anzahl der Eintraege erhoehen und Index zurueckgeben
+ nCount++;
+ return nIndex;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::Remove()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+void* UniqueIndex::Remove( ULONG nIndex )
+{
+ // Ist Index zulaessig
+ if ( (nIndex >= nStartIndex) &&
+ (nIndex < (Container::GetSize()+nStartIndex)) )
+ {
+ // Index-Eintrag als leeren Eintrag setzen und Anzahl der
+ // gespeicherten Indexe erniedriegen, wenn Eintrag belegt war
+ void* p = Container::Replace( NULL, nIndex-nStartIndex );
+ if ( p )
+ nCount--;
+ return p;
+ }
+ else
+ return NULL;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::Replace()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+void* UniqueIndex::Replace( ULONG nIndex, void* p )
+{
+ // NULL-Pointer ist nicht erlaubt
+ if ( !p )
+ return NULL;
+
+ // Ist Index zulaessig
+ if ( IsIndexValid( nIndex ) )
+ {
+ // Index-Eintrag ersetzen und alten zurueckgeben
+ return Container::Replace( p, nIndex-nStartIndex );
+ }
+ else
+ return NULL;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::Get()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+void* UniqueIndex::Get( ULONG nIndex ) const
+{
+ // Ist Index zulaessig
+ if ( (nIndex >= nStartIndex) &&
+ (nIndex < (Container::GetSize()+nStartIndex)) )
+ return Container::ImpGetObject( nIndex-nStartIndex );
+ else
+ return NULL;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::GetCurIndex()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+ULONG UniqueIndex::GetCurIndex() const
+{
+ ULONG nPos = Container::GetCurPos();
+
+ // Ist der Current-Index nicht belegt, dann gibt es keinen Current-Index
+ if ( !Container::ImpGetObject( nPos ) )
+ return UNIQUEINDEX_ENTRY_NOTFOUND;
+ else
+ return nPos+nStartIndex;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::GetIndex()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+ULONG UniqueIndex::GetIndex( const void* p ) const
+{
+ // Wird ein NULL-Pointer uebergeben, dann wurde Pointer nicht gefunden
+ if ( !p )
+ return UNIQUEINDEX_ENTRY_NOTFOUND;
+
+ ULONG nIndex = Container::GetPos( p );
+
+ if ( nIndex != CONTAINER_ENTRY_NOTFOUND )
+ return nIndex+nStartIndex;
+ else
+ return UNIQUEINDEX_ENTRY_NOTFOUND;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::IsIndexValid()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+BOOL UniqueIndex::IsIndexValid( ULONG nIndex ) const
+{
+ // Ist Index zulaessig
+ if ( (nIndex >= nStartIndex) &&
+ (nIndex < (Container::GetSize()+nStartIndex)) )
+ {
+ // Index ist nur zulaessig, wenn Eintrag auch belegt ist
+ if ( Container::ImpGetObject( nIndex-nStartIndex ) )
+ return TRUE;
+ else
+ return FALSE;
+ }
+ else
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::Seek()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+void* UniqueIndex::Seek( ULONG nIndex )
+{
+ // Index-Eintrag als aktuellen setzten, wenn er gueltig ist
+ if ( IsIndexValid( nIndex ) )
+ return Container::Seek( nIndex-nStartIndex );
+ else
+ return NULL;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::Seek()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+void* UniqueIndex::Seek( void* p )
+{
+ // Wird ein NULL-Pointer uebergeben, dann wurde Pointer nicht gefunden
+ if ( !p )
+ return NULL;
+
+ ULONG nIndex = GetIndex( p );
+
+ // Ist Index vorhanden, dann als aktuellen Eintrag setzen
+ if ( nIndex != UNIQUEINDEX_ENTRY_NOTFOUND )
+ return Container::Seek( nIndex-nStartIndex );
+ else
+ return NULL;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::First()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+void* UniqueIndex::First()
+{
+ void* p = Container::First();
+
+ while ( !p && (Container::GetCurPos() < (Container::GetSize()-1)) )
+ p = Container::Next();
+
+ return p;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::Last()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+void* UniqueIndex::Last()
+{
+ void* p = Container::Last();
+
+ while ( !p && Container::GetCurPos() )
+ p = Container::Prev();
+
+ return p;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::Next()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+void* UniqueIndex::Next()
+{
+ void* p = NULL;
+
+ while ( !p && (Container::GetCurPos() < (Container::GetSize()-1)) )
+ p = Container::Next();
+
+ return p;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::Prev()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+void* UniqueIndex::Prev()
+{
+ void* p = NULL;
+
+ while ( !p && Container::GetCurPos() )
+ p = Container::Prev();
+
+ return p;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::operator =()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+UniqueIndex& UniqueIndex::operator =( const UniqueIndex& rIdx )
+{
+ // Neue Werte zuweisen
+ Container::operator =( rIdx );
+ nReSize = rIdx.nReSize;
+ nStartIndex = rIdx.nStartIndex;
+ nUniqIndex = rIdx.nUniqIndex;
+ nCount = rIdx.nCount;
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::operator ==()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+BOOL UniqueIndex::operator ==( const UniqueIndex& rIdx ) const
+{
+ // Neue Werte zuweisen
+ if ( (nStartIndex == rIdx.nStartIndex) &&
+ (nCount == rIdx.nCount) &&
+ (Container::operator ==( rIdx )) )
+ return TRUE;
+ else
+ return FALSE;
+}
+/*************************************************************************
+|*
+|* UniqueIdContainer::UniqueIdContainer ()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung MM 29.04.96
+|* Letzte Aenderung MM 29.04.96
+|*
+*************************************************************************/
+
+UniqueIdContainer::UniqueIdContainer( const UniqueIdContainer& rObj )
+ : UniqueIndex( rObj )
+ , nCollectCount( rObj.nCollectCount )
+{
+ ULONG nCur = GetCurIndex();
+
+ ImpUniqueId * pEle = (ImpUniqueId *)First();
+ while( pEle )
+ {
+ pEle->nRefCount++;
+ pEle = (ImpUniqueId *)Next();
+ }
+ Seek( nCur );
+}
+
+/*************************************************************************
+|*
+|* UniqueIdContainer::operator = ()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung MM 01.08.94
+|* Letzte Aenderung MM 01.08.94
+|*
+*************************************************************************/
+
+UniqueIdContainer& UniqueIdContainer::operator = ( const UniqueIdContainer & rObj )
+{
+ UniqueIndex::operator = ( rObj );
+ nCollectCount = rObj.nCollectCount;
+
+ ULONG nCur = GetCurIndex();
+
+ ImpUniqueId * pEle = (ImpUniqueId *)First();
+ while( pEle )
+ {
+ pEle->nRefCount++;
+ pEle = (ImpUniqueId *)Next();
+ }
+ Seek( nCur );
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* UniqueIdContainer::Clear()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung MM 01.08.94
+|* Letzte Aenderung MM 01.08.94
+|*
+*************************************************************************/
+
+void UniqueIdContainer::Clear( BOOL bAll )
+{
+ USHORT nFree = bAll ? 0xFFFF : 1;
+
+ ImpUniqueId* pId = (ImpUniqueId*)Last();
+ BOOL bLast = TRUE;
+ while ( pId )
+ {
+ if ( pId->nRefCount <= nFree )
+ {
+ ((ImpUniqueId *)Remove( pId->nId ))->Release();
+ if( bLast )
+ pId = (ImpUniqueId *)Last();
+ else
+ pId = (ImpUniqueId *)Prev();
+ }
+ else
+ {
+ pId = (ImpUniqueId *)Prev();
+ bLast = FALSE;
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* UniqueIdContainer::CreateId()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung MM 01.08.94
+|* Letzte Aenderung MM 01.08.94
+|*
+*************************************************************************/
+
+UniqueItemId UniqueIdContainer::CreateId()
+{
+ if( nCollectCount > 50 )
+ { // aufraeumen
+ Clear( FALSE );
+ nCollectCount = 0;
+ }
+ nCollectCount++;
+
+ ImpUniqueId * pId = new ImpUniqueId;
+ pId->nRefCount = 1;
+ pId->nId = Insert( pId );
+ return UniqueItemId( pId );
+}
+
+/*************************************************************************
+|*
+|* UniqueIdContainer::CreateIdProt()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung MM 01.08.94
+|* Letzte Aenderung MM 01.08.94
+|*
+*************************************************************************/
+
+UniqueItemId UniqueIdContainer::CreateFreeId( ULONG nId )
+{
+ // Einfach erzeugen, fuer abgeleitete Klasse
+ ImpUniqueId * pId = new ImpUniqueId;
+ pId->nRefCount = 0;
+ pId->nId = nId;
+ return UniqueItemId( pId );
+}
+
+/*************************************************************************
+|*
+|* UniqueIdContainer::CreateIdProt()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung MM 01.08.94
+|* Letzte Aenderung MM 01.08.94
+|*
+*************************************************************************/
+
+UniqueItemId UniqueIdContainer::CreateIdProt( ULONG nId )
+{
+ if ( IsIndexValid( nId ) )
+ return UniqueItemId( (ImpUniqueId *)Get( nId ) );
+
+ ImpUniqueId * pId;
+ do
+ {
+ pId = new ImpUniqueId;
+ pId->nRefCount = 1;
+ pId->nId = Insert( pId );
+ }
+ while( pId->nId != nId );
+ return UniqueItemId( pId );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/misc/appendunixshellword.cxx b/tools/source/misc/appendunixshellword.cxx
new file mode 100644
index 000000000000..a39b81d87343
--- /dev/null
+++ b/tools/source/misc/appendunixshellword.cxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_tools.hxx"
+#include "sal/config.h"
+
+#if defined UNX
+
+#include <cstddef>
+
+#include "osl/diagnose.h"
+#include "rtl/strbuf.hxx"
+#include "rtl/string.h"
+#include "rtl/string.hxx"
+#include "sal/types.h"
+#include "tools/appendunixshellword.hxx"
+
+namespace tools {
+
+void appendUnixShellWord(
+ rtl::OStringBuffer * accumulator, rtl::OString const & text)
+{
+ OSL_ASSERT(accumulator != NULL);
+ if (text.getLength() == 0) {
+ accumulator->append(RTL_CONSTASCII_STRINGPARAM("''"));
+ } else {
+ bool quoted = false;
+ for (sal_Int32 i = 0; i < text.getLength(); ++i) {
+ char c = text[i];
+ if (c == '\'') {
+ if (quoted) {
+ accumulator->append('\'');
+ quoted = false;
+ }
+ accumulator->append(RTL_CONSTASCII_STRINGPARAM("\\'"));
+ } else {
+ if (!quoted) {
+ accumulator->append('\'');
+ quoted = true;
+ }
+ accumulator->append(c);
+ }
+ }
+ if (quoted) {
+ accumulator->append('\'');
+ }
+ }
+}
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/misc/extendapplicationenvironment.cxx b/tools/source/misc/extendapplicationenvironment.cxx
new file mode 100644
index 000000000000..341deeef107d
--- /dev/null
+++ b/tools/source/misc/extendapplicationenvironment.cxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_tools.hxx"
+#include "sal/config.h"
+
+#include <stdlib.h>
+
+#if defined UNX
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#endif
+
+#include "osl/process.h"
+#include "osl/thread.h"
+#include "rtl/bootstrap.hxx"
+#include "rtl/string.hxx"
+#include "rtl/textcvt.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "tools/extendapplicationenvironment.hxx"
+
+namespace tools {
+
+void extendApplicationEnvironment() {
+#if defined UNX
+ // Try to set RLIMIT_NOFILE as large as possible (failure is harmless):
+ rlimit l;
+ if (getrlimit(RLIMIT_NOFILE, &l) == 0) {
+ l.rlim_cur = l.rlim_max;
+ setrlimit(RLIMIT_NOFILE, &l);
+ }
+#endif
+
+ // Make sure URE_BOOTSTRAP environment variable is set (failure is fatal):
+ rtl::OUStringBuffer env;
+ rtl::OUString envVar(RTL_CONSTASCII_USTRINGPARAM("URE_BOOTSTRAP"));
+ rtl::OUString uri;
+ if (rtl::Bootstrap::get(envVar, uri))
+ {
+ if (!uri.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.pathname:")))
+ {
+ uri = rtl::Bootstrap::encode(uri);
+ }
+ env.append(uri);
+ } else {
+ if (osl_getExecutableFile(&uri.pData) != osl_Process_E_None) {
+ abort();
+ }
+ sal_Int32 i = uri.lastIndexOf('/');
+ if (i >= 0) {
+ uri = uri.copy(0, i + 1);
+ }
+ env.append(rtl::Bootstrap::encode(uri));
+ env.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM(SAL_CONFIGFILE("fundamental")));
+ }
+ rtl::OUString envValue(env.makeStringAndClear());
+ if (osl_setEnvironment(envVar.pData, envValue.pData) != osl_Process_E_None) {
+ abort();
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/misc/getprocessworkingdir.cxx b/tools/source/misc/getprocessworkingdir.cxx
new file mode 100644
index 000000000000..9cd51317259d
--- /dev/null
+++ b/tools/source/misc/getprocessworkingdir.cxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_tools.hxx"
+#include "sal/config.h"
+
+#include <cstddef>
+
+#include "osl/diagnose.h"
+#include "osl/file.hxx"
+#include "osl/process.h"
+#include "rtl/bootstrap.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "tools/getprocessworkingdir.hxx"
+
+namespace tools {
+
+bool getProcessWorkingDir(rtl::OUString * url) {
+ OSL_ASSERT(url != NULL);
+ rtl::OUString s(RTL_CONSTASCII_USTRINGPARAM("$OOO_CWD"));
+ rtl::Bootstrap::expandMacros(s);
+ if (s.getLength() == 0) {
+ if (osl_getProcessWorkingDir(&url->pData) == osl_Process_E_None) {
+ return true;
+ }
+ } else if (s[0] == '1') {
+ *url = s.copy(1);
+ return true;
+ } else if (s[0] == '2' &&
+ (osl::FileBase::getFileURLFromSystemPath(s.copy(1), *url) ==
+ osl::FileBase::E_None))
+ {
+ return true;
+ }
+ *url = rtl::OUString();
+ return false;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/misc/makefile.mk b/tools/source/misc/makefile.mk
new file mode 100644
index 000000000000..a426bb4053c3
--- /dev/null
+++ b/tools/source/misc/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..
+PRJNAME = tools
+TARGET = misc
+LIBTARGET = NO
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE: settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+LIB1TARGET = $(SLB)$/$(TARGET).lib
+LIB1OBJFILES = \
+ $(SLO)$/appendunixshellword.obj \
+ $(SLO)$/extendapplicationenvironment.obj \
+ $(SLO)$/solarmutex.obj \
+ $(SLO)$/getprocessworkingdir.obj
+
+OBJFILES = $(OBJ)$/pathutils.obj
+SLOFILES = $(SLO)$/pathutils.obj $(LIB1OBJFILES) $(SLO)$/solarmutex.obj
+
+.INCLUDE: target.mk
diff --git a/tools/source/misc/pathutils.cxx b/tools/source/misc/pathutils.cxx
new file mode 100644
index 000000000000..ab586797ae6b
--- /dev/null
+++ b/tools/source/misc/pathutils.cxx
@@ -0,0 +1,222 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_tools.hxx"
+#include "sal/config.h"
+
+#if defined WNT
+
+#include <cstddef>
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include "sal/types.h"
+#include "tools/pathutils.hxx"
+
+namespace tools {
+
+WCHAR * filename(WCHAR * path) {
+ WCHAR * f = path;
+ for (WCHAR * p = path;;) {
+ switch (*p++) {
+ case L'\0':
+ return f;
+ case L'\\':
+ f = p;
+ break;
+ }
+ }
+}
+
+WCHAR * buildPath(
+ WCHAR * path, WCHAR const * frontBegin, WCHAR const * frontEnd,
+ WCHAR const * backBegin, std::size_t backLength)
+{
+ // Remove leading ".." segments in the second path together with matching
+ // segments in the first path that are neither empty nor "." nor ".." nor
+ // end in ":" (which is not foolprove, as it can erroneously erase the start
+ // of a UNC path, but only if the input is bad data):
+ while (backLength >= 2 && backBegin[0] == L'.' && backBegin[1] == L'.' &&
+ (backLength == 2 || backBegin[2] == L'\\'))
+ {
+ if (frontEnd - frontBegin < 2 || frontEnd[-1] != L'\\' ||
+ frontEnd[-2] == L'\\' || frontEnd[-2] == L':' ||
+ (frontEnd[-2] == L'.' &&
+ (frontEnd - frontBegin < 3 || frontEnd[-3] == L'\\' ||
+ (frontEnd[-3] == L'.' &&
+ (frontEnd - frontBegin < 4 || frontEnd[-4] == L'\\')))))
+ {
+ break;
+ }
+ WCHAR const * p = frontEnd - 1;
+ while (p != frontBegin && p[-1] != L'\\') {
+ --p;
+ }
+ if (p == frontBegin) {
+ break;
+ }
+ frontEnd = p;
+ if (backLength == 2) {
+ backBegin += 2;
+ backLength -= 2;
+ } else {
+ backBegin += 3;
+ backLength -= 3;
+ }
+ }
+ if (backLength <
+ static_cast< std::size_t >(MAX_PATH - (frontEnd - frontBegin)))
+ // hopefully std::size_t is large enough
+ {
+ WCHAR * p;
+ if (frontBegin == path) {
+ p = const_cast< WCHAR * >(frontEnd);
+ } else {
+ p = path;
+ while (frontBegin != frontEnd) {
+ *p++ = *frontBegin++;
+ }
+ }
+ for (; backLength > 0; --backLength) {
+ *p++ = *backBegin++;
+ }
+ *p = L'\0';
+ return p;
+ } else {
+ SetLastError(ERROR_FILENAME_EXCED_RANGE);
+ return NULL;
+ }
+}
+
+WCHAR * resolveLink(WCHAR * path) {
+ HANDLE h = CreateFileW(
+ path, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ return NULL;
+ }
+ char p1[MAX_PATH];
+ DWORD n;
+ BOOL ok = ReadFile(h, p1, MAX_PATH, &n, NULL);
+ CloseHandle(h);
+ if (!ok) {
+ return NULL;
+ }
+ WCHAR p2[MAX_PATH];
+ std::size_t n2 = 0;
+ bool colon = false;
+ for (DWORD i = 0; i < n;) {
+ unsigned char c = static_cast< unsigned char >(p1[i++]);
+ switch (c) {
+ case '\0':
+ SetLastError(ERROR_BAD_PATHNAME);
+ return NULL;
+ case '\x0A':
+ case '\x0D':
+ if (n2 == MAX_PATH) {
+ SetLastError(ERROR_FILENAME_EXCED_RANGE);
+ return NULL;
+ }
+ p2[n2] = L'\0';
+ break;
+ case ':':
+ colon = true;
+ // fall through
+ default:
+ // Convert from UTF-8 to UTF-16:
+ if (c <= 0x7F) {
+ p2[n2++] = c;
+ } else if (c >= 0xC2 && c <= 0xDF && i < n &&
+ static_cast< unsigned char >(p1[i]) >= 0x80 &&
+ static_cast< unsigned char >(p1[i]) <= 0xBF)
+ {
+ p2[n2++] = ((c & 0x1F) << 6) |
+ (static_cast< unsigned char >(p1[i++]) & 0x3F);
+ } else if (n - i > 1 &&
+ ((c == 0xE0 &&
+ static_cast< unsigned char >(p1[i]) >= 0xA0 &&
+ static_cast< unsigned char >(p1[i]) <= 0xBF) ||
+ ((c >= 0xE1 && c <= 0xEC || c >= 0xEE && c <= 0xEF) &&
+ static_cast< unsigned char >(p1[i]) >= 0x80 &&
+ static_cast< unsigned char >(p1[i]) <= 0xBF) ||
+ (c == 0xED &&
+ static_cast< unsigned char >(p1[i]) >= 0x80 &&
+ static_cast< unsigned char >(p1[i]) <= 0x9F)) &&
+ static_cast< unsigned char >(p1[i + 1]) >= 0x80 &&
+ static_cast< unsigned char >(p1[i + 1]) <= 0xBF)
+ {
+ p2[n2++] = ((c & 0x0F) << 12) |
+ ((static_cast< unsigned char >(p1[i]) & 0x3F) << 6) |
+ (static_cast< unsigned char >(p1[i + 1]) & 0x3F);
+ i += 2;
+ } else if (n - 2 > 1 &&
+ ((c == 0xF0 &&
+ static_cast< unsigned char >(p1[i]) >= 0x90 &&
+ static_cast< unsigned char >(p1[i]) <= 0xBF) ||
+ (c >= 0xF1 && c <= 0xF3 &&
+ static_cast< unsigned char >(p1[i]) >= 0x80 &&
+ static_cast< unsigned char >(p1[i]) <= 0xBF) ||
+ (c == 0xF4 &&
+ static_cast< unsigned char >(p1[i]) >= 0x80 &&
+ static_cast< unsigned char >(p1[i]) <= 0x8F)) &&
+ static_cast< unsigned char >(p1[i + 1]) >= 0x80 &&
+ static_cast< unsigned char >(p1[i + 1]) <= 0xBF &&
+ static_cast< unsigned char >(p1[i + 2]) >= 0x80 &&
+ static_cast< unsigned char >(p1[i + 2]) <= 0xBF)
+ {
+ sal_Int32 u = ((c & 0x07) << 18) |
+ ((static_cast< unsigned char >(p1[i]) & 0x3F) << 12) |
+ ((static_cast< unsigned char >(p1[i + 1]) & 0x3F) << 6) |
+ (static_cast< unsigned char >(p1[i + 2]) & 0x3F);
+ i += 3;
+ p2[n2++] = static_cast< WCHAR >(((u - 0x10000) >> 10) | 0xD800);
+ p2[n2++] = static_cast< WCHAR >(
+ ((u - 0x10000) & 0x3FF) | 0xDC00);
+ } else {
+ SetLastError(ERROR_BAD_PATHNAME);
+ return NULL;
+ }
+ break;
+ }
+ }
+ WCHAR * end;
+ if (colon || p2[0] == L'\\') {
+ // Interpret p2 as an absolute path:
+ end = path;
+ } else {
+ // Interpret p2 as a relative path:
+ end = filename(path);
+ }
+ return buildPath(path, path, end, p2, n2);
+}
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/misc/solarmutex.cxx b/tools/source/misc/solarmutex.cxx
new file mode 100644
index 000000000000..e32a26284225
--- /dev/null
+++ b/tools/source/misc/solarmutex.cxx
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <tools/solarmutex.hxx>
+
+namespace tools
+{
+ static ::osl::SolarMutex* pSolarMutex = 0;
+
+ ::osl::SolarMutex* SolarMutex::GetSolarMutex()
+ {
+ return pSolarMutex;
+ }
+
+ void SolarMutex::SetSolarMutex( ::osl::SolarMutex* pMutex )
+ {
+ pSolarMutex = pMutex;
+ }
+
+ bool SolarMutex::Acquire()
+ {
+ if ( pSolarMutex )
+ pSolarMutex->acquire();
+ else
+ return false;
+ return true;
+ }
+
+ void SolarMutex::Release()
+ {
+ if ( pSolarMutex )
+ pSolarMutex->release();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/rc/isofallback.cxx b/tools/source/rc/isofallback.cxx
new file mode 100644
index 000000000000..0d072d1c7ff8
--- /dev/null
+++ b/tools/source/rc/isofallback.cxx
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <tools/isofallback.hxx>
+
+// -----------------------------------------------------------------------
+
+// Return true if valid fallback found
+sal_Bool GetIsoFallback( ByteString& rLanguage )
+{
+ rLanguage.EraseLeadingAndTrailingChars();
+ if( rLanguage.Len() ){
+ xub_StrLen nSepPos = rLanguage.Search( '-' );
+ if ( nSepPos == STRING_NOTFOUND ){
+ if ( rLanguage.Equals("en"))
+ {
+ // en -> ""
+ rLanguage.Erase();
+ return false;
+ }
+ else
+ {
+ // de -> en-US ;
+ rLanguage = ByteString("en-US");
+ return true;
+ }
+ }
+ else if( !( nSepPos == 1 && ( rLanguage.GetChar(0) == 'x' || rLanguage.GetChar(0) == 'X' ) ) )
+ {
+ // de-CH -> de ;
+ // try erase from -
+ rLanguage = rLanguage.GetToken( 0, '-');
+ return true;
+ }
+ }
+ // "" -> ""; x-no-translate -> ""
+ rLanguage.Erase();
+ return false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/rc/makefile.mk b/tools/source/rc/makefile.mk
new file mode 100644
index 000000000000..f8b46f38a0f7
--- /dev/null
+++ b/tools/source/rc/makefile.mk
@@ -0,0 +1,53 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=tools
+TARGET=rc
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/rc.obj \
+ $(SLO)$/isofallback.obj \
+ $(SLO)$/resmgr.obj \
+ $(SLO)$/resary.obj
+
+OBJFILES= $(OBJ)$/rc.obj \
+ $(OBJ)$/isofallback.obj \
+ $(OBJ)$/resmgr.obj \
+ $(OBJ)$/resary.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/tools/source/rc/rc.cxx b/tools/source/rc/rc.cxx
new file mode 100644
index 000000000000..ec43b9e1902c
--- /dev/null
+++ b/tools/source/rc/rc.cxx
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#define _TOOLS_RC_CXX
+
+#include <string.h>
+#include <tools/date.hxx>
+#include <tools/time.hxx>
+#include <tools/rc.hxx>
+#include <tools/rcid.h>
+
+// =======================================================================
+
+Resource::Resource( const ResId& rResId )
+{
+ GetRes( rResId.SetRT( RSC_RESOURCE ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Resource::GetRes( const ResId& rResId )
+{
+ if( rResId.GetResMgr() )
+ m_pResMgr = rResId.GetResMgr();
+ m_pResMgr->GetResource( rResId, this );
+ IncrementRes( sizeof( RSHEADER_TYPE ) );
+}
+
+// -----------------------------------------------------------------------
+
+// =======================================================================
+
+Time::Time( const ResId& rResId )
+{
+ nTime = 0;
+ rResId.SetRT( RSC_TIME );
+ ResMgr* pResMgr = NULL;
+
+ ResMgr::GetResourceSkipHeader( rResId, &pResMgr );
+
+ ULONG nObjMask = (USHORT)pResMgr->ReadLong();
+
+ if ( 0x01 & nObjMask )
+ SetHour( (USHORT)pResMgr->ReadShort() );
+ if ( 0x02 & nObjMask )
+ SetMin( (USHORT)pResMgr->ReadShort() );
+ if ( 0x04 & nObjMask )
+ SetSec( (USHORT)pResMgr->ReadShort() );
+ if ( 0x08 & nObjMask )
+ Set100Sec( (USHORT)pResMgr->ReadShort() );
+}
+
+// =======================================================================
+
+Date::Date( const ResId& rResId ) : nDate(0)
+{
+ rResId.SetRT( RSC_DATE );
+ ResMgr* pResMgr = NULL;
+
+ ResMgr::GetResourceSkipHeader( rResId, &pResMgr );
+
+ ULONG nObjMask = (USHORT)pResMgr->ReadLong();
+
+ if ( 0x01 & nObjMask )
+ SetYear( (USHORT)pResMgr->ReadShort() );
+ if ( 0x02 & nObjMask )
+ SetMonth( (USHORT)pResMgr->ReadShort() );
+ if ( 0x04 & nObjMask )
+ SetDay( (USHORT)pResMgr->ReadShort() );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/rc/resary.cxx b/tools/source/rc/resary.cxx
new file mode 100644
index 000000000000..b680e7d730c7
--- /dev/null
+++ b/tools/source/rc/resary.cxx
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#define _TOOLS_RESARY_CXX
+#include <tools/resary.hxx>
+#include <tools/rcid.h>
+
+// =======================================================================
+
+ResStringArray::ResStringArray( const ResId& rResId )
+{
+ rResId.SetRT( RSC_STRINGARRAY );
+ ResMgr* pMgr = rResId.GetResMgr();
+ if( pMgr && pMgr->GetResource( rResId ) )
+ {
+ pMgr->GetClass();
+ pMgr->Increment( sizeof( RSHEADER_TYPE ) );
+ const sal_uInt32 nItems = pMgr->ReadLong();
+ if ( nItems )
+ {
+ m_aStrings.reserve( nItems );
+ for ( sal_uInt32 i = 0; i < nItems; i++ )
+ {
+ // load string
+ m_aStrings.push_back( ImplResStringItem( pMgr->ReadString() ) );
+
+ // load value
+ m_aStrings[i].m_nValue = pMgr->ReadLong();
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ResStringArray::~ResStringArray()
+{
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt32 ResStringArray::FindIndex( long nValue ) const
+{
+ const sal_uInt32 nItems = m_aStrings.size();
+ for ( sal_uInt32 i = 0; i < nItems; i++ )
+ {
+ if ( m_aStrings[i].m_nValue == nValue )
+ return i;
+ }
+ return RESARRAY_INDEX_NOTFOUND;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/rc/resmgr.cxx b/tools/source/rc/resmgr.cxx
new file mode 100644
index 000000000000..0b350acdeb79
--- /dev/null
+++ b/tools/source/rc/resmgr.cxx
@@ -0,0 +1,2076 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <tools/debug.hxx>
+#include <tools/table.hxx>
+#include <tools/stream.hxx>
+#include <tools/resmgr.hxx>
+#include <tools/rc.hxx>
+#include <tools/rcid.h>
+#include <osl/endian.h>
+#include <osl/process.h>
+#include <osl/thread.h>
+#include <osl/file.hxx>
+#include <osl/mutex.hxx>
+#include <osl/signal.h>
+#include <rtl/ustrbuf.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/instance.hxx>
+#include <rtl/bootstrap.hxx>
+#include <i18npool/mslangid.hxx>
+#include <tools/simplerm.hxx>
+
+#include <tools/isofallback.hxx>
+
+#include <functional>
+#include <algorithm>
+#include <hash_map>
+#include <list>
+#include <set>
+
+#ifdef UNX
+#define SEARCH_PATH_DELIMITER_CHAR_STRING ":"
+#define SEARCH_PATH_DELIMITER ':'
+#else
+#define SEARCH_PATH_DELIMITER_CHAR_STRING ";"
+#define SEARCH_PATH_DELIMITER ';'
+#endif
+
+#define SEARCH_PATH_DELIMITER_STRING ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SEARCH_PATH_DELIMITER_CHAR_STRING ) )
+
+using namespace rtl;
+using namespace osl;
+
+// for thread safety
+static osl::Mutex* pResMgrMutex = NULL;
+static osl::Mutex& getResMgrMutex()
+{
+ if( !pResMgrMutex )
+ {
+ osl::Guard<osl::Mutex> aGuard( *osl::Mutex::getGlobalMutex() );
+ if( ! pResMgrMutex )
+ pResMgrMutex = new osl::Mutex();
+ }
+ return *pResMgrMutex;
+}
+
+struct ImpContent;
+class InternalResMgr
+{
+ friend class ResMgr;
+ friend class SimpleResMgr;
+ friend class ResMgrContainer;
+
+ ImpContent * pContent;
+ UINT32 nOffCorrection;
+ BYTE * pStringBlock;
+ SvStream * pStm;
+ BOOL bEqual2Content;
+ UINT32 nEntries;
+ OUString aFileName;
+ OUString aPrefix;
+ OUString aResName;
+ bool bSingular;
+ com::sun::star::lang::Locale aLocale;
+ std::hash_map<sal_uInt64, int>* pResUseDump;
+
+ InternalResMgr( const OUString& rFileURL,
+ const OUString& aPrefix,
+ const OUString& aResName,
+ const com::sun::star::lang::Locale& rLocale );
+ ~InternalResMgr();
+ BOOL Create();
+
+ BOOL IsGlobalAvailable( RESOURCE_TYPE nRT, sal_uInt32 nId ) const;
+ void * LoadGlobalRes( RESOURCE_TYPE nRT, sal_uInt32 nId,
+ void **pResHandle );
+public:
+ void FreeGlobalRes( void *, void * );
+
+ SvStream * GetBitmapStream( sal_uInt32 nResId );
+};
+
+// =======================================================================
+
+class ResMgrContainer
+{
+ static ResMgrContainer* pOneInstance;
+
+ struct ContainerElement
+ {
+ InternalResMgr* pResMgr;
+ OUString aFileURL;
+ int nRefCount;
+ int nLoadCount;
+
+ ContainerElement() :
+ pResMgr( NULL ),
+ nRefCount( 0 ),
+ nLoadCount( 0 )
+ {}
+ };
+
+ std::hash_map< OUString, ContainerElement, OUStringHash> m_aResFiles;
+ com::sun::star::lang::Locale m_aDefLocale;
+
+ ResMgrContainer() { init(); }
+ ~ResMgrContainer();
+
+ void init();
+ public:
+
+ static ResMgrContainer& get();
+ static void release();
+
+ InternalResMgr* getResMgr( const OUString& rPrefix,
+ com::sun::star::lang::Locale& rLocale,
+ bool bForceNewInstance = false
+ );
+ InternalResMgr* getNextFallback( InternalResMgr* pResMgr );
+
+ void freeResMgr( InternalResMgr* pResMgr );
+
+ void setDefLocale( const com::sun::star::lang::Locale& rLocale )
+ { m_aDefLocale = rLocale; }
+ const com::sun::star::lang::Locale& getDefLocale() const
+ { return m_aDefLocale; }
+};
+
+ResMgrContainer* ResMgrContainer::pOneInstance = NULL;
+
+ResMgrContainer& ResMgrContainer::get()
+{
+ if( ! pOneInstance )
+ pOneInstance = new ResMgrContainer();
+ return *pOneInstance;
+}
+
+ResMgrContainer::~ResMgrContainer()
+{
+ for( std::hash_map< OUString, ContainerElement, OUStringHash >::iterator it =
+ m_aResFiles.begin(); it != m_aResFiles.end(); ++it )
+ {
+ OSL_TRACE( "Resource file %s loaded %d times\n",
+ OUStringToOString( it->second.aFileURL, osl_getThreadTextEncoding() ).getStr(),
+ it->second.nLoadCount );
+ delete it->second.pResMgr;
+ }
+}
+
+void ResMgrContainer::release()
+{
+ delete pOneInstance;
+ pOneInstance = NULL;
+}
+
+void ResMgrContainer::init()
+{
+ // get resource path
+ std::list< OUString > aDirs;
+ sal_Int32 nIndex = 0;
+
+ // 1. fixed locations
+ rtl::OUString uri(
+ RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/program/resource"));
+ rtl::Bootstrap::expandMacros(uri);
+ aDirs.push_back(uri);
+ uri = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/program/resource"));
+ rtl::Bootstrap::expandMacros(uri);
+ aDirs.push_back(uri);
+
+ // 2. in STAR_RESOURCEPATH
+ const sal_Char* pEnv = getenv( "STAR_RESOURCEPATH" );
+ if( pEnv )
+ {
+ OUString aEnvPath( OStringToOUString( OString( pEnv ), osl_getThreadTextEncoding() ) );
+ nIndex = 0;
+ while( nIndex >= 0 )
+ {
+ OUString aPathElement( aEnvPath.getToken( 0, SEARCH_PATH_DELIMITER, nIndex ) );
+ if( aPathElement.getLength() )
+ {
+ OUString aFileURL;
+ File::getFileURLFromSystemPath( aPathElement, aFileURL );
+ aDirs.push_back( aFileURL);
+ }
+ }
+ }
+
+ // collect all possible resource files
+ for( std::list< OUString >::const_iterator dir_it = aDirs.begin(); dir_it != aDirs.end(); ++dir_it )
+ {
+ Directory aDir( *dir_it );
+ if( aDir.open() == FileBase::E_None )
+ {
+ DirectoryItem aItem;
+ while( aDir.getNextItem( aItem ) == FileBase::E_None )
+ {
+ FileStatus aStatus(FileStatusMask_FileName);
+ if( aItem.getFileStatus( aStatus ) == FileBase::E_None )
+ {
+ OUString aFileName = aStatus.getFileName();
+ if( aFileName.getLength() < 5 )
+ continue;
+ if( ! aFileName.endsWithIgnoreAsciiCaseAsciiL( ".res", 4 ) )
+ continue;
+ OUString aResName = aFileName.copy( 0, aFileName.getLength()-4 );
+ if( m_aResFiles.find( aResName ) != m_aResFiles.end() )
+ continue;
+ OUStringBuffer aURL( dir_it->getLength() + aFileName.getLength() + 1 );
+ aURL.append( *dir_it );
+ if( !dir_it->endsWithIgnoreAsciiCaseAsciiL( "/", 1 ) )
+ aURL.append( sal_Unicode('/') );
+ aURL.append( aFileName );
+ m_aResFiles[ aResName ].aFileURL = aURL.makeStringAndClear();
+ }
+ }
+ }
+ #if OSL_DEBUG_LEVEL > 1
+ else
+ OSL_TRACE( "opening dir %s failed\n", OUStringToOString( *dir_it, osl_getThreadTextEncoding() ).getStr() );
+ #endif
+ }
+ #if OSL_DEBUG_LEVEL > 1
+ for( std::hash_map< OUString, ContainerElement, OUStringHash >::const_iterator it =
+ m_aResFiles.begin(); it != m_aResFiles.end(); ++it )
+ {
+ OSL_TRACE( "ResMgrContainer: %s -> %s\n",
+ OUStringToOString( it->first, osl_getThreadTextEncoding() ).getStr(),
+ OUStringToOString( it->second.aFileURL, osl_getThreadTextEncoding() ).getStr() );
+ }
+ #endif
+
+ // set default language
+ LanguageType nLang = MsLangId::getSystemUILanguage();
+ MsLangId::convertLanguageToLocale(nLang, m_aDefLocale);
+}
+
+InternalResMgr* ResMgrContainer::getResMgr( const OUString& rPrefix,
+ com::sun::star::lang::Locale& rLocale,
+ bool bForceNewInstance
+ )
+{
+ com::sun::star::lang::Locale aLocale( rLocale );
+ OUStringBuffer aSearch( rPrefix.getLength() + 16 );
+ std::hash_map< OUString, ContainerElement, OUStringHash >::iterator it = m_aResFiles.end();
+
+ int nTries = 0;
+ if( aLocale.Language.getLength() > 0 )
+ nTries = 1;
+ if( aLocale.Country.getLength() > 0 )
+ nTries = 2;
+ if( aLocale.Variant.getLength() > 0 )
+ nTries = 3;
+ while( nTries-- )
+ {
+ aSearch.append( rPrefix );
+ if( nTries > -1 )
+ {
+ aSearch.append( aLocale.Language );
+ }
+ if( nTries > 0 )
+ {
+ aSearch.append( sal_Unicode('-') );
+ aSearch.append( aLocale.Country );
+ }
+ if( nTries > 1 )
+ {
+ aSearch.append( sal_Unicode('-') );
+ aSearch.append( aLocale.Variant );
+ }
+ it = m_aResFiles.find( aSearch.makeStringAndClear() );
+ if( it != m_aResFiles.end() )
+ {
+ // ensure InternalResMgr existance
+ if( ! it->second.pResMgr )
+ {
+ InternalResMgr* pImp =
+ new InternalResMgr( it->second.aFileURL, rPrefix, it->first, aLocale );
+ if( ! pImp->Create() )
+ {
+ delete pImp;
+ continue;
+ }
+ it->second.pResMgr = pImp;
+ }
+ break;
+ }
+ if( nTries == 0 && !aLocale.Language.equalsIgnoreAsciiCaseAscii( "en" ) )
+ {
+ // locale fallback failed
+ // fallback to en-US locale
+ nTries = 2;
+ aLocale.Language = OUString( RTL_CONSTASCII_USTRINGPARAM( "en" ) );
+ aLocale.Country = OUString( RTL_CONSTASCII_USTRINGPARAM( "US" ) );
+ aLocale.Variant = OUString();
+ }
+ }
+ // try if there is anything with this prefix at all
+ if( it == m_aResFiles.end() )
+ {
+ aLocale = com::sun::star::lang::Locale();
+ it = m_aResFiles.find( rPrefix );
+ if( it == m_aResFiles.end() )
+ {
+ for( it = m_aResFiles.begin(); it != m_aResFiles.end(); ++it )
+ {
+ if( it->first.matchIgnoreAsciiCase( rPrefix ) )
+ {
+ // ensure InternalResMgr existance
+ if( ! it->second.pResMgr )
+ {
+ InternalResMgr* pImp =
+ new InternalResMgr( it->second.aFileURL,
+ rPrefix,
+ it->first,
+ aLocale );
+ if( ! pImp->Create() )
+ {
+ delete pImp;
+ continue;
+ }
+ it->second.pResMgr = pImp;
+ }
+ // try to guess locale
+ sal_Int32 nIndex = rPrefix.getLength();
+ aLocale.Language = it->first.getToken( 0, '-', nIndex );
+ if( nIndex > 0 )
+ aLocale.Country = it->first.getToken( 0, '-', nIndex );
+ if( nIndex > 0 )
+ aLocale.Variant = it->first.getToken( 0, '-', nIndex );
+ break;
+ }
+ }
+ }
+ }
+ // give up
+ if( it == m_aResFiles.end() )
+ {
+ OUStringBuffer sKey = rPrefix;
+ sKey.append( rLocale.Language );
+ if( rLocale.Country.getLength() )
+ {
+ sKey.append( sal_Unicode('-') );
+ sKey.append( rLocale.Country );
+ }
+ if( rLocale.Variant.getLength() )
+ {
+ sKey.append( sal_Unicode('-') );
+ sKey.append( rLocale.Variant );
+ } // if( aLocale.Variant.getLength() )
+ ::rtl::OUString sURL = sKey.makeStringAndClear();
+ sURL += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".res"));
+ if ( m_aResFiles.find(sURL) == m_aResFiles.end() )
+ {
+ m_aResFiles[ sURL ].aFileURL = sURL;
+ return getResMgr(rPrefix,rLocale,bForceNewInstance);
+ } // if ( m_aResFiles.find(sURL) == m_aResFiles.end() )
+ return NULL;
+ }
+
+ rLocale = aLocale;
+ // at this point it->second.pResMgr must be filled either by creating a new one
+ // (then the refcount is still 0) or because we already had one
+ InternalResMgr* pImp = it->second.pResMgr;
+
+ if( it->second.nRefCount == 0 )
+ it->second.nLoadCount++;
+
+ // for SimpleResMgr
+ if( bForceNewInstance )
+ {
+ if( it->second.nRefCount == 0 )
+ {
+ // shortcut: the match algorithm already created the InternalResMgr
+ // take it instead of creating yet another one
+ it->second.pResMgr = NULL;
+ pImp->bSingular = true;
+ }
+ else
+ {
+ pImp = new InternalResMgr( it->second.aFileURL, rPrefix, it->first, aLocale );
+ pImp->bSingular = true;
+ if( !pImp->Create() )
+ {
+ delete pImp;
+ pImp = NULL;
+ }
+ else
+ it->second.nLoadCount++;
+ }
+ }
+ else
+ it->second.nRefCount++;
+
+ return pImp;
+}
+
+InternalResMgr* ResMgrContainer::getNextFallback( InternalResMgr* pMgr )
+{
+ com::sun::star::lang::Locale aLocale = pMgr->aLocale;
+ if( aLocale.Variant.getLength() )
+ aLocale.Variant = OUString();
+ else if( aLocale.Country.getLength() )
+ aLocale.Country = OUString();
+ else if( ! aLocale.Language.equalsIgnoreAsciiCaseAscii( "en" ) )
+ {
+ aLocale.Language = OUString( RTL_CONSTASCII_USTRINGPARAM( "en" ) );
+ aLocale.Country = OUString( RTL_CONSTASCII_USTRINGPARAM( "US" ) );
+ }
+ InternalResMgr* pNext = getResMgr( pMgr->aPrefix, aLocale, pMgr->bSingular );
+ // prevent recursion
+ if( pNext == pMgr || pNext->aResName.equals( pMgr->aResName ) )
+ {
+ if( pNext->bSingular )
+ delete pNext;
+ pNext = NULL;
+ }
+ return pNext;
+}
+
+void ResMgrContainer::freeResMgr( InternalResMgr* pResMgr )
+{
+ if( pResMgr->bSingular )
+ delete pResMgr;
+ else
+ {
+ std::hash_map< OUString, ContainerElement, OUStringHash >::iterator it =
+ m_aResFiles.find( pResMgr->aResName );
+ if( it != m_aResFiles.end() )
+ {
+ DBG_ASSERT( it->second.nRefCount > 0, "InternalResMgr freed too often" );
+ if( it->second.nRefCount > 0 )
+ it->second.nRefCount--;
+ if( it->second.nRefCount == 0 )
+ {
+ delete it->second.pResMgr;
+ it->second.pResMgr = NULL;
+ }
+ }
+ }
+}
+
+// =======================================================================
+
+void Resource::TestRes()
+{
+ if( m_pResMgr )
+ m_pResMgr->TestStack( this );
+}
+
+struct ImpContent
+{
+ sal_uInt64 nTypeAndId;
+ sal_uInt32 nOffset;
+};
+
+struct ImpContentLessCompare : public ::std::binary_function< ImpContent, ImpContent, bool>
+{
+ inline bool operator() (const ImpContent& lhs, const ImpContent& rhs) const
+ {
+ return lhs.nTypeAndId < rhs.nTypeAndId;
+ }
+};
+
+struct ImpContentMixLessCompare : public ::std::binary_function< ImpContent, sal_uInt64, bool>
+{
+ inline bool operator() (const ImpContent& lhs, const sal_uInt64& rhs) const
+ {
+ return lhs.nTypeAndId < rhs;
+ }
+ inline bool operator() (const sal_uInt64& lhs, const ImpContent& rhs) const
+ {
+ return lhs < rhs.nTypeAndId;
+ }
+};
+
+
+// =======================================================================
+
+static ResHookProc pImplResHookProc = 0;
+
+// =======================================================================
+
+SvStream * InternalResMgr::GetBitmapStream( sal_uInt32 nId )
+{
+ // Anfang der Strings suchen
+ ImpContent * pFind = ::std::lower_bound(pContent,
+ pContent + nEntries,
+ ((sal_uInt64(RT_SYS_BITMAP) << 32) | nId),
+ ImpContentMixLessCompare());
+ if ( (pFind != (pContent + nEntries)) && (pFind->nTypeAndId == ((sal_uInt64(RT_SYS_BITMAP) << 32) | nId)) )
+ {
+ pStm->Seek( pFind->nOffset );
+ return pStm;
+ }
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+InternalResMgr::InternalResMgr( const OUString& rFileURL,
+ const OUString& rPrefix,
+ const OUString& rResName,
+ const com::sun::star::lang::Locale& rLocale )
+ : pContent( NULL )
+ , pStringBlock( NULL )
+ , pStm( NULL )
+ , bEqual2Content( TRUE )
+ , nEntries( 0 )
+ , aFileName( rFileURL )
+ , aPrefix( rPrefix )
+ , aResName( rResName )
+ , bSingular( false )
+ , aLocale( rLocale )
+ , pResUseDump( 0 )
+{
+}
+
+// -----------------------------------------------------------------------
+
+InternalResMgr::~InternalResMgr()
+{
+ rtl_freeMemory(pContent);
+ rtl_freeMemory(pStringBlock);
+ delete pStm;
+
+#ifdef DBG_UTIL
+ if( pResUseDump )
+ {
+ const sal_Char* pLogFile = getenv( "STAR_RESOURCE_LOGGING" );
+ if ( pLogFile )
+ {
+ SvFileStream aStm( UniString( pLogFile, RTL_TEXTENCODING_ASCII_US ), STREAM_WRITE );
+ aStm.Seek( STREAM_SEEK_TO_END );
+ ByteString aLine( "FileName: " );
+ aLine.Append( ByteString( OUStringToOString( aFileName, RTL_TEXTENCODING_UTF8 ) ) );
+ aStm.WriteLine( aLine );
+
+ for( std::hash_map<sal_uInt64, int>::const_iterator it = pResUseDump->begin();
+ it != pResUseDump->end(); ++it )
+ {
+ sal_uInt64 nKeyId = it->first;
+ aLine.Assign( "Type/Id: " );
+ aLine.Append( ByteString::CreateFromInt32( sal::static_int_cast< sal_Int32 >((nKeyId >> 32) & 0xFFFFFFFF) ) );
+ aLine.Append( '/' );
+ aLine.Append( ByteString::CreateFromInt32( sal::static_int_cast< sal_Int32 >(nKeyId & 0xFFFFFFFF) ) );
+ aStm.WriteLine( aLine );
+ }
+ }
+ }
+#endif
+
+ delete pResUseDump;
+}
+
+// -----------------------------------------------------------------------
+
+
+BOOL InternalResMgr::Create()
+{
+ ResMgrContainer::get();
+ BOOL bDone = FALSE;
+
+ pStm = new SvFileStream( aFileName, (STREAM_READ | STREAM_SHARE_DENYWRITE | STREAM_NOCREATE) );
+ if( pStm->GetError() == 0 )
+ {
+ INT32 lContLen = 0;
+
+ pStm->Seek( STREAM_SEEK_TO_END );
+ /*
+ if( ( pInternalResMgr->pHead = (RSHEADER_TYPE *)mmap( 0, nResourceFileSize,
+ PROT_READ, MAP_PRIVATE,
+ fRes, 0 ) ) != (RSHEADER_TYPE *)-1)
+ */
+ pStm->SeekRel( - (int)sizeof( lContLen ) );
+ pStm->Read( &lContLen, sizeof( lContLen ) );
+ // is bigendian, swab to the right endian
+ lContLen = ResMgr::GetLong( &lContLen );
+ pStm->SeekRel( -lContLen );
+ // allocate stored ImpContent data (12 bytes per unit)
+ BYTE* pContentBuf = (BYTE*)rtl_allocateMemory( lContLen );
+ pStm->Read( pContentBuf, lContLen );
+ // allocate ImpContent space (sizeof(ImpContent) per unit, not necessarily 12)
+ pContent = (ImpContent *)rtl_allocateMemory( sizeof(ImpContent)*lContLen/12 );
+ // Auf die Anzahl der ImpContent k�rzen
+ nEntries = (UINT32)lContLen / 12;
+ bEqual2Content = TRUE; // Die Daten der Resourcen liegen
+ // genauso wie das Inhaltsverzeichnis
+ BOOL bSorted = TRUE;
+ if( nEntries )
+ {
+#ifdef DBG_UTIL
+ const sal_Char* pLogFile = getenv( "STAR_RESOURCE_LOGGING" );
+ if ( pLogFile )
+ {
+ pResUseDump = new std::hash_map<sal_uInt64, int>;
+ for( sal_uInt32 i = 0; i < nEntries; ++i )
+ (*pResUseDump)[pContent[i].nTypeAndId] = 1;
+ }
+#endif
+ // swap the content to the right endian
+ pContent[0].nTypeAndId = ResMgr::GetUInt64( pContentBuf );
+ pContent[0].nOffset = ResMgr::GetLong( pContentBuf+8 );
+ sal_uInt32 nCount = nEntries - 1;
+ for( sal_uInt32 i = 0,j=1; i < nCount; ++i,++j )
+ {
+ // swap the content to the right endian
+ pContent[j].nTypeAndId = ResMgr::GetUInt64( pContentBuf + (12*j) );
+ pContent[j].nOffset = ResMgr::GetLong( pContentBuf + (12*j+8) );
+ if( pContent[i].nTypeAndId >= pContent[j].nTypeAndId )
+ bSorted = FALSE;
+ if( (pContent[i].nTypeAndId & 0xFFFFFFFF00000000LL) == (pContent[j].nTypeAndId & 0xFFFFFFFF00000000LL)
+ && pContent[i].nOffset >= pContent[j].nOffset )
+ bEqual2Content = FALSE;
+ }
+ }
+ rtl_freeMemory( pContentBuf );
+#ifndef OS2
+ OSL_ENSURE( bSorted, "content not sorted" );
+#endif
+ OSL_ENSURE( bEqual2Content, "resource structure wrong" );
+ if( !bSorted )
+ ::std::sort(pContent,pContent+nEntries,ImpContentLessCompare());
+ // qsort( pContent, nEntries, sizeof( ImpContent ), Compare );
+
+ bDone = TRUE;
+ }
+
+ return bDone;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL InternalResMgr::IsGlobalAvailable( RESOURCE_TYPE nRT, sal_uInt32 nId ) const
+{
+ // Anfang der Strings suchen
+ sal_uInt64 nValue = ((sal_uInt64(nRT) << 32) | nId);
+ ImpContent * pFind = ::std::lower_bound(pContent,
+ pContent + nEntries,
+ nValue,
+ ImpContentMixLessCompare());
+ return (pFind != (pContent + nEntries)) && (pFind->nTypeAndId == nValue);
+}
+
+// -----------------------------------------------------------------------
+
+void* InternalResMgr::LoadGlobalRes( RESOURCE_TYPE nRT, sal_uInt32 nId,
+ void **pResHandle )
+{
+#ifdef DBG_UTIL
+ if( pResUseDump )
+ pResUseDump->erase( (sal_uInt64(nRT) << 32) | nId );
+#endif
+ // Anfang der Strings suchen
+ sal_uInt64 nValue = ((sal_uInt64(nRT) << 32) | nId);
+ ImpContent* pEnd = (pContent + nEntries);
+ ImpContent* pFind = ::std::lower_bound( pContent,
+ pEnd,
+ nValue,
+ ImpContentMixLessCompare());
+ if( pFind && (pFind != pEnd) && (pFind->nTypeAndId == nValue) )
+ {
+ if( nRT == RSC_STRING && bEqual2Content )
+ {
+ // String Optimierung
+ if( !pStringBlock )
+ {
+ // Anfang der Strings suchen
+ ImpContent * pFirst = pFind;
+ ImpContent * pLast = pFirst;
+ while( pFirst > pContent && ((pFirst -1)->nTypeAndId >> 32) == RSC_STRING )
+ --pFirst;
+ while( pLast < pEnd && (pLast->nTypeAndId >> 32) == RSC_STRING )
+ ++pLast;
+ nOffCorrection = pFirst->nOffset;
+ UINT32 nSize;
+ --pLast;
+ pStm->Seek( pLast->nOffset );
+ RSHEADER_TYPE aHdr;
+ pStm->Read( &aHdr, sizeof( aHdr ) );
+ nSize = pLast->nOffset + aHdr.GetGlobOff() - nOffCorrection;
+ pStringBlock = (BYTE*)rtl_allocateMemory( nSize );
+ pStm->Seek( pFirst->nOffset );
+ pStm->Read( pStringBlock, nSize );
+ }
+ *pResHandle = pStringBlock;
+ return (BYTE*)pStringBlock + pFind->nOffset - nOffCorrection;
+ } // if( nRT == RSC_STRING && bEqual2Content )
+ else
+ {
+ *pResHandle = 0;
+ RSHEADER_TYPE aHeader;
+ pStm->Seek( pFind->nOffset );
+ pStm->Read( &aHeader, sizeof( RSHEADER_TYPE ) );
+ void * pRes = rtl_allocateMemory( aHeader.GetGlobOff() );
+ memcpy( pRes, &aHeader, sizeof( RSHEADER_TYPE ) );
+ pStm->Read( (BYTE*)pRes + sizeof( RSHEADER_TYPE ),
+ aHeader.GetGlobOff() - sizeof( RSHEADER_TYPE ) );
+ return pRes;
+ }
+ } // if( pFind && (pFind != pEnd) && (pFind->nTypeAndId == nValue) )
+ *pResHandle = 0;
+ //Resource holen
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void InternalResMgr::FreeGlobalRes( void * pResHandle, void * pResource )
+{
+ if ( !pResHandle )
+ // REsource wurde extra allokiert
+ rtl_freeMemory(pResource);
+}
+
+// =======================================================================
+
+#ifdef DBG_UTIL
+
+UniString GetTypeRes_Impl( const ResId& rTypeId )
+{
+ // Funktion verlassen, falls Resourcefehler in dieser Funktion
+ static int bInUse = FALSE;
+ UniString aTypStr( UniString::CreateFromInt32( rTypeId.GetId() ) );
+
+ if ( !bInUse )
+ {
+ bInUse = TRUE;
+
+ ResId aResId( sal_uInt32(RSCVERSION_ID), *rTypeId.GetResMgr() );
+ aResId.SetRT( RSC_VERSIONCONTROL );
+
+ if ( rTypeId.GetResMgr()->GetResource( aResId ) )
+ {
+ rTypeId.SetRT( RSC_STRING );
+ if ( rTypeId.GetResMgr()->IsAvailable( rTypeId ) )
+ {
+ aTypStr = UniString( rTypeId );
+ // Versions Resource Klassenzeiger ans Ende setzen
+ rTypeId.GetResMgr()->Increment( sizeof( RSHEADER_TYPE ) );
+ }
+ }
+ bInUse = FALSE;
+ }
+
+ return aTypStr;
+}
+
+// -----------------------------------------------------------------------
+
+void ResMgr::RscError_Impl( const sal_Char* pMessage, ResMgr* pResMgr,
+ RESOURCE_TYPE nRT, sal_uInt32 nId,
+ std::vector< ImpRCStack >& rResStack, int nDepth )
+{
+ // create a separate ResMgr with its own stack
+ // first get a second reference of the InternalResMgr
+ InternalResMgr* pImp =
+ ResMgrContainer::get().getResMgr( pResMgr->pImpRes->aPrefix,
+ pResMgr->pImpRes->aLocale,
+ true );
+
+ ResMgr* pNewResMgr = new ResMgr( pImp );
+
+ ByteString aStr = OUStringToOString( pResMgr->GetFileName(), RTL_TEXTENCODING_UTF8 );
+ if ( aStr.Len() )
+ aStr += '\n';
+
+ aStr.Append( "Class: " );
+ aStr.Append( ByteString( GetTypeRes_Impl( ResId( nRT, *pNewResMgr ) ), RTL_TEXTENCODING_UTF8 ) );
+ aStr.Append( ", Id: " );
+ aStr.Append( ByteString::CreateFromInt32( (long)nId ) );
+ aStr.Append( ". " );
+ aStr.Append( pMessage );
+
+ aStr.Append( "\nResource Stack\n" );
+ while( nDepth > 0 )
+ {
+ aStr.Append( "Class: " );
+ aStr.Append( ByteString( GetTypeRes_Impl( ResId( rResStack[nDepth].pResource->GetRT(), *pNewResMgr ) ), RTL_TEXTENCODING_UTF8 ) );
+ aStr.Append( ", Id: " );
+ aStr.Append( ByteString::CreateFromInt32( (long)rResStack[nDepth].pResource->GetId() ) );
+ nDepth--;
+ }
+
+ // clean up
+ delete pNewResMgr;
+
+ DBG_ERROR( aStr.GetBuffer() );
+}
+
+#endif
+
+// =======================================================================
+
+static void RscException_Impl()
+{
+ switch ( osl_raiseSignal( OSL_SIGNAL_USER_RESOURCEFAILURE, (void*)"" ) )
+ {
+ case osl_Signal_ActCallNextHdl:
+ abort();
+
+ case osl_Signal_ActIgnore:
+ return;
+
+ case osl_Signal_ActAbortApp:
+ abort();
+
+ default:
+ case osl_Signal_ActKillApp:
+ exit(-1);
+ }
+}
+
+// =======================================================================
+
+void ImpRCStack::Init( ResMgr* pMgr, const Resource* pObj, sal_uInt32 Id )
+{
+ pResource = NULL;
+ pClassRes = NULL;
+ Flags = RC_NOTYPE;
+ aResHandle = NULL;
+ pResObj = pObj;
+ nId = Id & ~RSC_DONTRELEASE; //TLX: Besser Init aendern
+ pResMgr = pMgr;
+ if ( !(Id & RSC_DONTRELEASE) )
+ Flags |= RC_AUTORELEASE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImpRCStack::Clear()
+{
+ pResource = NULL;
+ pClassRes = NULL;
+ Flags = RC_NOTYPE;
+ aResHandle = NULL;
+ pResObj = NULL;
+ nId = 0;
+ pResMgr = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+static RSHEADER_TYPE* LocalResource( const ImpRCStack* pStack,
+ RESOURCE_TYPE nRTType,
+ sal_uInt32 nId )
+{
+ // Gibt die Position der Resource zurueck, wenn sie gefunden wurde.
+ // Ansonsten gibt die Funktion Null zurueck.
+ RSHEADER_TYPE* pTmp; // Zeiger auf Kind-Resourceobjekte
+ RSHEADER_TYPE* pEnd; // Zeiger auf das Ende der Resource
+
+ if ( pStack->pResource && pStack->pClassRes )
+ {
+ pTmp = (RSHEADER_TYPE*)
+ ((BYTE*)pStack->pResource + pStack->pResource->GetLocalOff());
+ pEnd = (RSHEADER_TYPE*)
+ ((BYTE*)pStack->pResource + pStack->pResource->GetGlobOff());
+ while ( pTmp != pEnd )
+ {
+ if ( pTmp->GetRT() == nRTType && pTmp->GetId() == nId )
+ return pTmp;
+ pTmp = (RSHEADER_TYPE*)((BYTE*)pTmp + pTmp->GetGlobOff());
+ }
+ }
+
+ return NULL;
+}
+
+// =======================================================================
+
+void* ResMgr::pEmptyBuffer = NULL;
+
+void* ResMgr::getEmptyBuffer()
+{
+ if( ! pEmptyBuffer )
+ pEmptyBuffer = rtl_allocateZeroMemory( 1024 );
+ return pEmptyBuffer;
+}
+
+void ResMgr::DestroyAllResMgr()
+{
+ {
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+ if( pEmptyBuffer )
+ {
+ rtl_freeMemory( pEmptyBuffer );
+ pEmptyBuffer = NULL;
+ }
+ ResMgrContainer::release();
+ }
+ delete pResMgrMutex;
+ pResMgrMutex = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void ResMgr::Init( const OUString& rFileName )
+{
+ (void) rFileName; // avoid warning about unused parameter
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if ( !pImpRes )
+ {
+#ifdef DBG_UTIL
+ ByteString aStr( "Resourcefile not found:\n" );
+ aStr += ByteString( OUStringToOString( rFileName, RTL_TEXTENCODING_UTF8 ) );
+ DBG_ERROR( aStr.GetBuffer() );
+#endif
+ RscException_Impl();
+ }
+#ifdef DBG_UTIL
+ else
+ {
+ void* aResHandle = 0; // Hilfvariable fuer Resource
+ void* pVoid; // Zeiger auf die Resource
+
+ pVoid = pImpRes->LoadGlobalRes( RSC_VERSIONCONTROL, RSCVERSION_ID,
+ &aResHandle );
+ if ( pVoid )
+ pImpRes->FreeGlobalRes( aResHandle, pVoid );
+ else
+ {
+ ByteString aStr( "Wrong version:\n" );
+ aStr += ByteString( OUStringToOString( pImpRes->aFileName, RTL_TEXTENCODING_UTF8 ) );
+ DbgError( aStr.GetBuffer() );
+ }
+ }
+#endif
+ nCurStack = -1;
+ aStack.clear();
+ pFallbackResMgr = pOriginalResMgr = NULL;
+ incStack();
+}
+
+// -----------------------------------------------------------------------
+
+ResMgr::ResMgr( InternalResMgr * pImpMgr )
+{
+ pImpRes = pImpMgr;
+ Init( pImpMgr->aFileName );
+}
+
+// -----------------------------------------------------------------------
+
+ResMgr::~ResMgr()
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ ResMgrContainer::get().freeResMgr( pImpRes );
+
+ // clean up possible left rc stack frames
+ while( nCurStack > 0 )
+ {
+ if( ( aStack[nCurStack].Flags & (RC_GLOBAL | RC_NOTFOUND) ) == RC_GLOBAL )
+ pImpRes->FreeGlobalRes( aStack[nCurStack].aResHandle,
+ aStack[nCurStack].pResource );
+ nCurStack--;
+ }
+}
+
+
+void ResMgr::incStack()
+{
+ nCurStack++;
+ if( nCurStack >= int(aStack.size()) )
+ aStack.push_back( ImpRCStack() );
+ aStack[nCurStack].Clear();
+
+ DBG_ASSERT( nCurStack < 32, "Resource stack unreasonably large" );
+}
+
+void ResMgr::decStack()
+{
+ DBG_ASSERT( nCurStack > 0, "resource stack underrun !" );
+ if( (aStack[nCurStack].Flags & RC_FALLBACK_UP) )
+ {
+ nCurStack--;
+ // warning: this will delete *this, see below
+ pOriginalResMgr->decStack();
+ }
+ else
+ {
+ ImpRCStack& rTop = aStack[nCurStack];
+ if( (rTop.Flags & RC_FALLBACK_DOWN) )
+ {
+ #if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "returning from fallback %s\n",
+ OUStringToOString(pFallbackResMgr->GetFileName(), osl_getThreadTextEncoding() ).getStr() );
+ #endif
+ delete pFallbackResMgr;
+ pFallbackResMgr = NULL;
+ }
+ nCurStack--;
+ }
+}
+
+#ifdef DBG_UTIL
+
+void ResMgr::TestStack( const Resource* pResObj )
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if ( DbgIsResource() )
+ {
+ for( int i = 1; i <= nCurStack; ++i )
+ {
+ if ( aStack[i].pResObj == pResObj )
+ {
+#ifdef DBG_UTIL
+ RscError_Impl( "Resource not freed! ", this,
+ aStack[i].pResource->GetRT(),
+ aStack[i].pResource->GetId(),
+ aStack, i-1 );
+#endif
+ }
+ }
+ }
+}
+
+#else
+
+void ResMgr::TestStack( const Resource* )
+{
+}
+
+#endif
+
+// -----------------------------------------------------------------------
+BOOL ResMgr::IsAvailable( const ResId& rId, const Resource* pResObj ) const
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ BOOL bAvailable = FALSE;
+ RSHEADER_TYPE* pClassRes = rId.GetpResource();
+ RESOURCE_TYPE nRT = rId.GetRT2();
+ sal_uInt32 nId = rId.GetId();
+ const ResMgr* pMgr = rId.GetResMgr();
+
+ if ( !pMgr )
+ pMgr = this;
+
+ if( pMgr->pFallbackResMgr )
+ {
+ ResId aId( rId );
+ aId.SetResMgr( NULL );
+ return pMgr->pFallbackResMgr->IsAvailable( aId, pResObj );
+ }
+
+ if ( !pResObj || pResObj == pMgr->aStack[pMgr->nCurStack].pResObj )
+ {
+ if ( !pClassRes )
+ pClassRes = LocalResource( &pMgr->aStack[pMgr->nCurStack], nRT, nId );
+ if ( pClassRes )
+ {
+ if ( pClassRes->GetRT() == nRT )
+ bAvailable = TRUE;
+ }
+ }
+
+ // vieleicht globale Resource
+ if ( !pClassRes )
+ bAvailable = pMgr->pImpRes->IsGlobalAvailable( nRT, nId );
+
+ return bAvailable;
+}
+
+// -----------------------------------------------------------------------
+
+void* ResMgr::GetClass()
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if( pFallbackResMgr )
+ return pFallbackResMgr->GetClass();
+
+ return aStack[nCurStack].pClassRes;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ResMgr::GetResource( const ResId& rId, const Resource* pResObj )
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if( pFallbackResMgr )
+ {
+ ResId aId( rId );
+ aId.SetResMgr( NULL );
+ return pFallbackResMgr->GetResource( aId, pResObj );
+ }
+
+ ResMgr* pMgr = rId.GetResMgr();
+ if ( pMgr && (this != pMgr) )
+ return pMgr->GetResource( rId, pResObj );
+
+ // normally Increment will pop the context; this is
+ // not possible in RC_NOTFOUND case, so pop a frame here
+ ImpRCStack* pTop = &aStack[nCurStack];
+ if( (pTop->Flags & RC_NOTFOUND) )
+ {
+ decStack();
+ }
+
+ RSHEADER_TYPE* pClassRes = rId.GetpResource();
+ RESOURCE_TYPE nRT = rId.GetRT2();
+ sal_uInt32 nId = rId.GetId();
+
+ incStack();
+ pTop = &aStack[nCurStack];
+ pTop->Init( pMgr, pResObj, nId |
+ (rId.IsAutoRelease() ? 0 : RSC_DONTRELEASE) );
+
+ if ( pClassRes )
+ {
+ if ( pClassRes->GetRT() == nRT )
+ pTop->pClassRes = pClassRes;
+ else
+ {
+#ifdef DBG_UTIL
+ RscError_Impl( "Different class and resource type!",
+ this, nRT, nId, aStack, nCurStack-1 );
+#endif
+ pTop->Flags |= RC_NOTFOUND;
+ pTop->pClassRes = getEmptyBuffer();
+ pTop->pResource = (RSHEADER_TYPE*)pTop->pClassRes;
+ return FALSE;
+ }
+ }
+ else
+ {
+ OSL_ENSURE( nCurStack > 0, "stack of 1 to shallow" );
+ pTop->pClassRes = LocalResource( &aStack[nCurStack-1], nRT, nId );
+ }
+
+ if ( pTop->pClassRes )
+ // lokale Resource, nicht system Resource
+ pTop->pResource = (RSHEADER_TYPE *)pTop->pClassRes;
+ else
+ {
+ pTop->pClassRes = pImpRes->LoadGlobalRes( nRT, nId, &pTop->aResHandle );
+ if ( pTop->pClassRes )
+ {
+ pTop->Flags |= RC_GLOBAL;
+ pTop->pResource = (RSHEADER_TYPE *)pTop->pClassRes;
+ }
+ else
+ {
+ // try to get a fallback resource
+ pFallbackResMgr = CreateFallbackResMgr( rId, pResObj );
+ if( pFallbackResMgr )
+ {
+ pTop->Flags |= RC_FALLBACK_DOWN;
+ #ifdef DBG_UTIL
+ ByteString aMess( "found resource " );
+ aMess.Append( ByteString::CreateFromInt32( nId ) );
+ aMess.Append( " in fallback " );
+ aMess.Append( ByteString( OUStringToOString( pFallbackResMgr->GetFileName(), osl_getThreadTextEncoding() ) ) );
+ aMess.Append( "\n" );
+ RscError_Impl( aMess.GetBuffer(),
+ this, nRT, nId, aStack, nCurStack-1 );
+ #endif
+ }
+ else
+ {
+ #ifdef DBG_UTIL
+ RscError_Impl( "Cannot load resource! ",
+ this, nRT, nId, aStack, nCurStack-1 );
+ #endif
+ pTop->Flags |= RC_NOTFOUND;
+ pTop->pClassRes = getEmptyBuffer();
+ pTop->pResource = (RSHEADER_TYPE*)pTop->pClassRes;
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void * ResMgr::GetResourceSkipHeader( const ResId& rResId, ResMgr ** ppResMgr )
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ DBG_ASSERT( rResId.GetResMgr(), "illegal ResId without ResMgr" );
+ *ppResMgr = rResId.GetResMgr();
+ if( *ppResMgr )
+ {
+ (*ppResMgr)->GetResource( rResId );
+ (*ppResMgr)->Increment( sizeof( RSHEADER_TYPE ) );
+ return (*ppResMgr)->GetClass();
+ }
+ return getEmptyBuffer();
+}
+
+// -----------------------------------------------------------------------
+
+void ResMgr::PopContext( const Resource* pResObj )
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if( pFallbackResMgr )
+ {
+ pFallbackResMgr->PopContext( pResObj );
+ return;
+ }
+
+#ifdef DBG_UTIL
+ if ( DbgIsResource() )
+ {
+ if ( (aStack[nCurStack].pResObj != pResObj) || nCurStack == 0 )
+ {
+ RscError_Impl( "Cannot free resource! ", this,
+ RSC_NOTYPE, 0, aStack, nCurStack );
+ }
+ }
+#endif
+
+ if ( nCurStack > 0 )
+ {
+ ImpRCStack* pTop = &aStack[nCurStack];
+#ifdef DBG_UTIL
+ if ( DbgIsResource() && !(pTop->Flags & RC_NOTFOUND) )
+ {
+ void* pRes = (BYTE*)pTop->pResource +
+ pTop->pResource->GetLocalOff();
+
+ if ( pTop->pClassRes != pRes )
+ {
+ RscError_Impl( "Classpointer not at the end!",
+ this, pTop->pResource->GetRT(),
+ pTop->pResource->GetId(),
+ aStack, nCurStack-1 );
+ }
+ }
+#endif
+
+ // Resource freigeben
+ if( (pTop->Flags & (RC_GLOBAL | RC_NOTFOUND)) == RC_GLOBAL )
+ // kann auch Fremd-Ressource sein
+ pImpRes->FreeGlobalRes( pTop->aResHandle, pTop->pResource );
+ decStack();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+RSHEADER_TYPE* ResMgr::CreateBlock( const ResId& rId )
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if( pFallbackResMgr )
+ {
+ ResId aId( rId );
+ aId.SetResMgr( NULL );
+ return pFallbackResMgr->CreateBlock( aId );
+ }
+
+ RSHEADER_TYPE* pHeader = NULL;
+ if ( GetResource( rId ) )
+ {
+ // Der Zeiger steht am Anfang, deswegen zeigt der Klassen-Pointer
+ // auf den Header und die restliche Groesse ist die Gesammte.
+ pHeader = (RSHEADER_TYPE*)rtl_allocateMemory( GetRemainSize() );
+ memcpy( pHeader, GetClass(), GetRemainSize() );
+ Increment( pHeader->GetLocalOff() ); //ans Ende setzen
+ if ( pHeader->GetLocalOff() != pHeader->GetGlobOff() )
+ // Hat Sub-Ressourcen, deshalb extra freigeben
+ PopContext();
+ }
+
+ return pHeader;
+}
+
+// ------------------------------------------------------------------
+
+INT16 ResMgr::GetShort( void * pShort )
+{
+ return ((*((sal_uInt8*)pShort + 0) << 8) |
+ (*((sal_uInt8*)pShort + 1) << 0) );
+}
+
+// ------------------------------------------------------------------
+
+INT32 ResMgr::GetLong( void * pLong )
+{
+ return ((*((sal_uInt8*)pLong + 0) << 24) |
+ (*((sal_uInt8*)pLong + 1) << 16) |
+ (*((sal_uInt8*)pLong + 2) << 8) |
+ (*((sal_uInt8*)pLong + 3) << 0) );
+}
+
+// ------------------------------------------------------------------
+
+sal_uInt64 ResMgr::GetUInt64( void* pDatum )
+{
+ return ((sal_uInt64(*((sal_uInt8*)pDatum + 0)) << 56) |
+ (sal_uInt64(*((sal_uInt8*)pDatum + 1)) << 48) |
+ (sal_uInt64(*((sal_uInt8*)pDatum + 2)) << 40) |
+ (sal_uInt64(*((sal_uInt8*)pDatum + 3)) << 32) |
+ (sal_uInt64(*((sal_uInt8*)pDatum + 4)) << 24) |
+ (sal_uInt64(*((sal_uInt8*)pDatum + 5)) << 16) |
+ (sal_uInt64(*((sal_uInt8*)pDatum + 6)) << 8) |
+ (sal_uInt64(*((sal_uInt8*)pDatum + 7)) << 0) );
+}
+
+// -----------------------------------------------------------------------
+sal_uInt32 ResMgr::GetStringWithoutHook( UniString& rStr, const BYTE* pStr )
+{
+ sal_uInt32 nRet = GetStringSize( pStr );
+ UniString aString( (sal_Char*)pStr, RTL_TEXTENCODING_UTF8,
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MAPTOPRIVATE |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT );
+ rStr = aString;
+ return nRet;
+}
+
+sal_uInt32 ResMgr::GetString( UniString& rStr, const BYTE* pStr )
+{
+ UniString aString;
+ sal_uInt32 nRet = GetStringWithoutHook( aString, pStr );
+ if ( pImplResHookProc )
+ pImplResHookProc( aString );
+ rStr = aString;
+ return nRet;
+}
+
+// ------------------------------------------------------------------
+
+sal_uInt32 ResMgr::GetStringSize( const BYTE* pStr )
+{
+ return GetStringSize( strlen( (const char*)pStr ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt32 ResMgr::GetRemainSize()
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if( pFallbackResMgr )
+ return pFallbackResMgr->GetRemainSize();
+
+ const ImpRCStack& rTop = aStack[nCurStack];
+ return (sal_uInt32)((long)(BYTE *)rTop.pResource +
+ rTop.pResource->GetLocalOff() -
+ (long)(BYTE *)rTop.pClassRes);
+}
+
+// -----------------------------------------------------------------------
+
+void* ResMgr::Increment( sal_uInt32 nSize )
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if( pFallbackResMgr )
+ return pFallbackResMgr->Increment( nSize );
+
+ ImpRCStack& rStack = aStack[nCurStack];
+ if( (rStack.Flags & RC_NOTFOUND) )
+ return rStack.pClassRes;
+
+ BYTE* pClassRes = (BYTE*)rStack.pClassRes + nSize;
+
+ rStack.pClassRes = pClassRes;
+
+ RSHEADER_TYPE* pRes = rStack.pResource;
+
+ sal_uInt32 nLocalOff = pRes->GetLocalOff();
+ if ( (pRes->GetGlobOff() == nLocalOff) &&
+ (((char*)pRes + nLocalOff) == rStack.pClassRes) &&
+ (rStack.Flags & RC_AUTORELEASE))
+ {
+ PopContext( rStack.pResObj );
+ }
+
+ return pClassRes;
+}
+
+ResMgr* ResMgr::CreateFallbackResMgr( const ResId& rId, const Resource* pResource )
+{
+ ResMgr *pFallback = NULL;
+ if( nCurStack > 0 )
+ {
+ // get the next fallback level in resource file scope
+ InternalResMgr* pRes = ResMgrContainer::get().getNextFallback( pImpRes );
+ if( pRes )
+ {
+ // check that the fallback locale is not already in the chain of
+ // fallbacks - prevent fallback loops
+ ResMgr* pResMgr = this;
+ while( pResMgr &&
+ ( pResMgr->pImpRes->aLocale.Language != pRes->aLocale.Language ||
+ pResMgr->pImpRes->aLocale.Country != pRes->aLocale.Country ||
+ pResMgr->pImpRes->aLocale.Variant != pRes->aLocale.Variant )
+ )
+ {
+ pResMgr = pResMgr->pOriginalResMgr;
+ }
+ if( pResMgr )
+ {
+ // found a recursion, no fallback possible
+ ResMgrContainer::get().freeResMgr( pRes );
+ return NULL;
+ }
+ OSL_TRACE( "trying fallback: %s\n", OUStringToOString( pRes->aFileName, osl_getThreadTextEncoding() ).getStr() );
+ pFallback = new ResMgr( pRes );
+ pFallback->pOriginalResMgr = this;
+ // try to recreate the resource stack
+ bool bHaveStack = true;
+ for( int i = 1; i < nCurStack; i++ )
+ {
+ if( !aStack[i].pResource )
+ {
+ bHaveStack = false;
+ break;
+ }
+ ResId aId( aStack[i].pResource->GetId(), *pFallbackResMgr );
+ aId.SetRT( aStack[i].pResource->GetRT() );
+ if( !pFallback->GetResource( aId ) )
+ {
+ bHaveStack = false;
+ break;
+ }
+ }
+ if( bHaveStack )
+ {
+ ResId aId( rId.GetId(), *pFallback );
+ aId.SetRT( rId.GetRT() );
+ if( !pFallback->GetResource( aId, pResource ) )
+ bHaveStack = false;
+ else
+ pFallback->aStack[pFallback->nCurStack].Flags |= RC_FALLBACK_UP;
+ }
+ if( !bHaveStack )
+ {
+ delete pFallback;
+ pFallback = NULL;
+ }
+ }
+ }
+ return pFallback;
+}
+
+//---------------------------------------------------------------------------
+//
+// method left here for SDK compatibility,
+// used in "framework/source/services/substitutepathvars.cxx"
+//
+// phone numbers no longer in use for resource files
+//
+//---------------------------------------------------------------------------
+
+const char* ResMgr::GetLang( LanguageType& nType, USHORT nPrio )
+{
+ if ( nType == LANGUAGE_SYSTEM || nType == LANGUAGE_DONTKNOW )
+ nType = MsLangId::getSystemUILanguage();
+
+ if ( nPrio == 0 )
+ {
+ switch ( nType )
+ {
+ case LANGUAGE_DANISH:
+ return "45";
+
+ case LANGUAGE_DUTCH:
+ case LANGUAGE_DUTCH_BELGIAN:
+ return "31";
+
+ case LANGUAGE_ENGLISH:
+ case LANGUAGE_ENGLISH_UK:
+ case LANGUAGE_ENGLISH_EIRE:
+ case LANGUAGE_ENGLISH_SAFRICA:
+ case LANGUAGE_ENGLISH_JAMAICA:
+ case LANGUAGE_ENGLISH_BELIZE:
+ case LANGUAGE_ENGLISH_TRINIDAD:
+ case LANGUAGE_ENGLISH_ZIMBABWE:
+ case LANGUAGE_ENGLISH_PHILIPPINES:
+ return "44";
+
+ case LANGUAGE_ENGLISH_US:
+ case LANGUAGE_ENGLISH_CAN:
+ return "01";
+
+ case LANGUAGE_ENGLISH_AUS:
+ case LANGUAGE_ENGLISH_NZ:
+ return "61";
+ case LANGUAGE_ESTONIAN:
+ return "77";
+
+
+ case LANGUAGE_FINNISH:
+ return "35";
+
+ case LANGUAGE_FRENCH_CANADIAN:
+ return "02";
+
+ case LANGUAGE_FRENCH:
+ case LANGUAGE_FRENCH_BELGIAN:
+ case LANGUAGE_FRENCH_SWISS:
+ case LANGUAGE_FRENCH_LUXEMBOURG:
+ case LANGUAGE_FRENCH_MONACO:
+ return "33";
+
+ case LANGUAGE_GERMAN:
+ case LANGUAGE_GERMAN_SWISS:
+ case LANGUAGE_GERMAN_AUSTRIAN:
+ case LANGUAGE_GERMAN_LUXEMBOURG:
+ case LANGUAGE_GERMAN_LIECHTENSTEIN:
+ return "49";
+
+ case LANGUAGE_ITALIAN:
+ case LANGUAGE_ITALIAN_SWISS:
+ return "39";
+
+ case LANGUAGE_NORWEGIAN:
+ case LANGUAGE_NORWEGIAN_BOKMAL:
+ return "47";
+
+ case LANGUAGE_PORTUGUESE:
+ return "03";
+
+ case LANGUAGE_PORTUGUESE_BRAZILIAN:
+ return "55";
+
+ case LANGUAGE_SPANISH_DATED:
+ case LANGUAGE_SPANISH_MEXICAN:
+ case LANGUAGE_SPANISH_MODERN:
+ case LANGUAGE_SPANISH_GUATEMALA:
+ case LANGUAGE_SPANISH_COSTARICA:
+ case LANGUAGE_SPANISH_PANAMA:
+ case LANGUAGE_SPANISH_DOMINICAN_REPUBLIC:
+ case LANGUAGE_SPANISH_VENEZUELA:
+ case LANGUAGE_SPANISH_COLOMBIA:
+ case LANGUAGE_SPANISH_PERU:
+ case LANGUAGE_SPANISH_ARGENTINA:
+ case LANGUAGE_SPANISH_ECUADOR:
+ case LANGUAGE_SPANISH_CHILE:
+ case LANGUAGE_SPANISH_URUGUAY:
+ case LANGUAGE_SPANISH_PARAGUAY:
+ case LANGUAGE_SPANISH_BOLIVIA:
+ return "34";
+
+ case LANGUAGE_SWEDISH:
+ return "46";
+
+ case LANGUAGE_POLISH:
+ return "48";
+ case LANGUAGE_CZECH:
+ return "42";
+ case LANGUAGE_SLOVENIAN:
+ return "50";
+ case LANGUAGE_HUNGARIAN:
+ return "36";
+ case LANGUAGE_RUSSIAN:
+ return "07";
+ case LANGUAGE_SLOVAK:
+ return "43";
+ case LANGUAGE_GREEK:
+ return "30";
+ case LANGUAGE_TURKISH:
+ return "90";
+
+ case LANGUAGE_CHINESE_SIMPLIFIED:
+ return "86";
+ case LANGUAGE_CHINESE_TRADITIONAL:
+ return "88";
+ case LANGUAGE_JAPANESE:
+ return "81";
+ case LANGUAGE_KOREAN:
+ case LANGUAGE_KOREAN_JOHAB:
+ return "82";
+ case LANGUAGE_THAI:
+ return "66";
+ case LANGUAGE_HINDI:
+ return "91";
+
+ case LANGUAGE_ARABIC_PRIMARY_ONLY:
+ case LANGUAGE_ARABIC_IRAQ:
+ case LANGUAGE_ARABIC_EGYPT:
+ case LANGUAGE_ARABIC_LIBYA:
+ case LANGUAGE_ARABIC_ALGERIA:
+ case LANGUAGE_ARABIC_MOROCCO:
+ case LANGUAGE_ARABIC_TUNISIA:
+ case LANGUAGE_ARABIC_OMAN:
+ case LANGUAGE_ARABIC_YEMEN:
+ case LANGUAGE_ARABIC_SYRIA:
+ case LANGUAGE_ARABIC_JORDAN:
+ case LANGUAGE_ARABIC_LEBANON:
+ case LANGUAGE_ARABIC_KUWAIT:
+ case LANGUAGE_ARABIC_UAE:
+ case LANGUAGE_ARABIC_BAHRAIN:
+ case LANGUAGE_ARABIC_QATAR:
+ return "96";
+
+ case LANGUAGE_HEBREW:
+ return "97";
+
+ case LANGUAGE_CATALAN:
+ return "37";
+
+ default:
+ return "99";
+ }
+ }
+ else if ( nPrio == 1 )
+ {
+ switch ( nType )
+ {
+ case LANGUAGE_FRENCH_CANADIAN:
+ return "33";
+
+ case LANGUAGE_PORTUGUESE_BRAZILIAN:
+ return "03";
+
+ default:
+ return NULL;
+ }
+ }
+ else if ( nPrio == 2 )
+ return "01";
+ else if ( nPrio == 3 )
+ return "44";
+ else if ( nPrio == 4 )
+ return "49";
+ else
+ return "99";
+}
+
+// -----------------------------------------------------------------------
+
+ResMgr* ResMgr::CreateResMgr( const sal_Char* pPrefixName,
+ com::sun::star::lang::Locale aLocale )
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ OUString aPrefix( pPrefixName, strlen( pPrefixName ), osl_getThreadTextEncoding() );
+
+ if( ! aLocale.Language.getLength() )
+ aLocale = ResMgrContainer::get().getDefLocale();
+
+ InternalResMgr* pImp = ResMgrContainer::get().getResMgr( aPrefix, aLocale );
+ return pImp ? new ResMgr( pImp ) : NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ResMgr* ResMgr::SearchCreateResMgr(
+ const sal_Char* pPrefixName,
+ com::sun::star::lang::Locale& rLocale )
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ OUString aPrefix( pPrefixName, strlen( pPrefixName ), osl_getThreadTextEncoding() );
+
+ if( ! rLocale.Language.getLength() )
+ rLocale = ResMgrContainer::get().getDefLocale();
+
+ InternalResMgr* pImp = ResMgrContainer::get().getResMgr( aPrefix, rLocale );
+ return pImp ? new ResMgr( pImp ) : NULL;
+}
+
+// -----------------------------------------------------------------------
+
+INT16 ResMgr::ReadShort()
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if( pFallbackResMgr )
+ return pFallbackResMgr->ReadShort();
+
+ INT16 n = GetShort( GetClass() );
+ Increment( sizeof( INT16 ) );
+ return n;
+}
+
+// -----------------------------------------------------------------------
+
+INT32 ResMgr::ReadLong()
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if( pFallbackResMgr )
+ return pFallbackResMgr->ReadLong();
+
+ INT32 n = GetLong( GetClass() );
+ Increment( sizeof( INT32 ) );
+ return n;
+}
+
+// -----------------------------------------------------------------------
+
+UniString ResMgr::ReadStringWithoutHook()
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if( pFallbackResMgr )
+ return pFallbackResMgr->ReadStringWithoutHook();
+
+ UniString aRet;
+
+ const ImpRCStack& rTop = aStack[nCurStack];
+ if( (rTop.Flags & RC_NOTFOUND) )
+ {
+ #if OSL_DEBUG_LEVEL > 0
+ aRet = OUString( RTL_CONSTASCII_USTRINGPARAM( "<resource not found>" ) );
+ #endif
+ }
+ else
+ Increment( GetStringWithoutHook( aRet, (const BYTE*)GetClass() ) );
+
+ return aRet;
+}
+
+UniString ResMgr::ReadString()
+{
+ UniString aRet = ReadStringWithoutHook();
+ if ( pImplResHookProc )
+ pImplResHookProc( aRet );
+ return aRet;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG ResMgr::GetAutoHelpId()
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if( pFallbackResMgr )
+ return pFallbackResMgr->GetAutoHelpId();
+
+ DBG_ASSERT( nCurStack, "resource stack empty in Auto help id generation" );
+ if( nCurStack < 1 || nCurStack > 2 )
+ return 0;
+
+ const ImpRCStack *pRC = StackTop( nCurStack==1 ? 0 : 1 );
+
+ DBG_ASSERT( pRC->pResource, "MM hat gesagt, dass der immer einen hat" );
+ ULONG nGID = pRC->pResource->GetId();
+
+ if( !nGID || nGID > 32767 )
+ return 0;
+
+ ULONG nHID = 0;
+
+ // GGGg gggg::gggg gggg::ggLL LLLl::llll llll
+ switch( pRC->pResource->GetRT() ) { // maximal 7
+ case RSC_DOCKINGWINDOW:
+ nHID += 0x20000000L;
+ case RSC_WORKWIN:
+ nHID += 0x20000000L;
+ case RSC_MODELESSDIALOG:
+ nHID += 0x20000000L;
+ case RSC_FLOATINGWINDOW:
+ nHID += 0x20000000L;
+ case RSC_MODALDIALOG:
+ nHID += 0x20000000L;
+ case RSC_TABPAGE:
+ nHID += 0x20000000L;
+
+ if( nCurStack == 2 ) {
+ pRC = StackTop();
+ ULONG nLID = pRC->pResource->GetId();
+
+ if( !nLID || nLID > 511 )
+ return 0;
+
+ switch( pRC->pResource->GetRT() ) { // maximal 32
+ case RSC_TABCONTROL: nHID |= 0x0000; break;
+ case RSC_RADIOBUTTON: nHID |= 0x0200; break;
+ case RSC_CHECKBOX: nHID |= 0x0400; break;
+ case RSC_TRISTATEBOX: nHID |= 0x0600; break;
+ case RSC_EDIT: nHID |= 0x0800; break;
+ case RSC_MULTILINEEDIT: nHID |= 0x0A00; break;
+ case RSC_MULTILISTBOX: nHID |= 0x0C00; break;
+ case RSC_LISTBOX: nHID |= 0x0E00; break;
+ case RSC_COMBOBOX: nHID |= 0x1000; break;
+ case RSC_PUSHBUTTON: nHID |= 0x1200; break;
+ case RSC_SPINFIELD: nHID |= 0x1400; break;
+ case RSC_PATTERNFIELD: nHID |= 0x1600; break;
+ case RSC_NUMERICFIELD: nHID |= 0x1800; break;
+ case RSC_METRICFIELD: nHID |= 0x1A00; break;
+ case RSC_CURRENCYFIELD: nHID |= 0x1C00; break;
+ case RSC_DATEFIELD: nHID |= 0x1E00; break;
+ case RSC_TIMEFIELD: nHID |= 0x2000; break;
+ case RSC_IMAGERADIOBUTTON: nHID |= 0x2200; break;
+ case RSC_NUMERICBOX: nHID |= 0x2400; break;
+ case RSC_METRICBOX: nHID |= 0x2600; break;
+ case RSC_CURRENCYBOX: nHID |= 0x2800; break;
+ case RSC_DATEBOX: nHID |= 0x2A00; break;
+ case RSC_TIMEBOX: nHID |= 0x2C00; break;
+ case RSC_IMAGEBUTTON: nHID |= 0x2E00; break;
+ case RSC_MENUBUTTON: nHID |= 0x3000; break;
+ case RSC_MOREBUTTON: nHID |= 0x3200; break;
+ default:
+ return 0;
+ } // of switch
+ nHID |= nLID;
+ } // of if
+ break;
+ default:
+ return 0;
+ } // of switch
+ nHID |= nGID << 14;
+
+ return nHID;
+}
+
+// -----------------------------------------------------------------------
+
+void ResMgr::SetReadStringHook( ResHookProc pProc )
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+ pImplResHookProc = pProc;
+}
+
+// -----------------------------------------------------------------------
+
+ResHookProc ResMgr::GetReadStringHook()
+{
+ return pImplResHookProc;
+}
+
+// -----------------------------------------------------------------------
+
+void ResMgr::SetDefaultLocale( const com::sun::star::lang::Locale& rLocale )
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+ ResMgrContainer::get().setDefLocale( rLocale );
+}
+
+// -----------------------------------------------------------------------
+
+const OUString& ResMgr::GetFileName() const
+{
+ return pImpRes->aFileName;
+}
+
+// =======================================================================
+
+SimpleResMgr::SimpleResMgr( const sal_Char* pPrefixName,
+ const ::com::sun::star::lang::Locale& rLocale )
+{
+ OUString aPrefix( pPrefixName, strlen( pPrefixName ), osl_getThreadTextEncoding() );
+ com::sun::star::lang::Locale aLocale( rLocale );
+
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+ if( ! aLocale.Language.getLength() )
+ aLocale = ResMgrContainer::get().getDefLocale();
+
+ m_pResImpl = ResMgrContainer::get().getResMgr( aPrefix, aLocale, true );
+ DBG_ASSERT( m_pResImpl, "SimpleResMgr::SimpleResMgr : have no impl class !" );
+}
+
+// -----------------------------------------------------------------------
+SimpleResMgr::SimpleResMgr( const ::rtl::OUString& _rPrefixName, ::com::sun::star::lang::Locale& _inout_Locale )
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+ m_pResImpl = ResMgrContainer::get().getResMgr( _rPrefixName, _inout_Locale, true );
+}
+
+// -----------------------------------------------------------------------
+SimpleResMgr::~SimpleResMgr()
+{
+ delete m_pResImpl;
+}
+
+// -----------------------------------------------------------------------
+SimpleResMgr* SimpleResMgr::Create( const sal_Char* pPrefixName, com::sun::star::lang::Locale aLocale )
+{
+ return new SimpleResMgr( pPrefixName, aLocale );
+}
+
+// -----------------------------------------------------------------------
+bool SimpleResMgr::IsAvailable( RESOURCE_TYPE _resourceType, sal_uInt32 _resourceId )
+{
+ osl::MutexGuard aGuard(m_aAccessSafety);
+
+ if ( ( RSC_STRING != _resourceType ) && ( RSC_RESOURCE != _resourceType ) )
+ return false;
+
+ DBG_ASSERT( m_pResImpl, "SimpleResMgr::IsAvailable: have no impl class !" );
+ return m_pResImpl->IsGlobalAvailable( _resourceType, _resourceId );
+}
+
+// -----------------------------------------------------------------------
+UniString SimpleResMgr::ReadString( sal_uInt32 nId )
+{
+ osl::MutexGuard aGuard(m_aAccessSafety);
+
+ DBG_ASSERT( m_pResImpl, "SimpleResMgr::ReadString : have no impl class !" );
+ // perhaps constructed with an invalid filename ?
+
+ UniString sReturn;
+ if ( !m_pResImpl )
+ return sReturn;
+
+ void* pResHandle = NULL;
+ InternalResMgr* pFallback = m_pResImpl;
+ RSHEADER_TYPE* pResHeader = (RSHEADER_TYPE*)m_pResImpl->LoadGlobalRes( RSC_STRING, nId, &pResHandle );
+ if ( !pResHeader )
+ {
+ osl::Guard<osl::Mutex> aGuard2( getResMgrMutex() );
+
+ // try fallback
+ while( ! pResHandle && pFallback )
+ {
+ InternalResMgr* pOldFallback = pFallback;
+ pFallback = ResMgrContainer::get().getNextFallback( pFallback );
+ if( pOldFallback != m_pResImpl )
+ ResMgrContainer::get().freeResMgr( pOldFallback );
+ if( pFallback )
+ {
+ // handle possible recursion
+ if( pFallback->aLocale.Language != m_pResImpl->aLocale.Language ||
+ pFallback->aLocale.Country != m_pResImpl->aLocale.Country ||
+ pFallback->aLocale.Variant != m_pResImpl->aLocale.Variant )
+ {
+ pResHeader = (RSHEADER_TYPE*)pFallback->LoadGlobalRes( RSC_STRING, nId, &pResHandle );
+ }
+ else
+ {
+ ResMgrContainer::get().freeResMgr( pFallback );
+ pFallback = NULL;
+ }
+ }
+ }
+ if( ! pResHandle )
+ // no such resource
+ return sReturn;
+ }
+
+ // ULONG nLen = pResHeader->GetLocalOff() - sizeof(RSHEADER_TYPE);
+ ResMgr::GetString( sReturn, (const BYTE*)(pResHeader+1) );
+
+ // not neccessary with te current implementation which holds the string table permanently, but to be sure ....
+ // note: pFallback cannot be NULL here and is either the fallback or m_pResImpl
+ pFallback->FreeGlobalRes( pResHeader, pResHandle );
+ if( m_pResImpl != pFallback )
+ {
+ osl::Guard<osl::Mutex> aGuard2( getResMgrMutex() );
+
+ ResMgrContainer::get().freeResMgr( pFallback );
+ }
+ return sReturn;
+}
+
+// -----------------------------------------------------------------------
+
+const ::com::sun::star::lang::Locale& SimpleResMgr::GetLocale() const
+{
+ DBG_ASSERT( IsValid(), "SimpleResMgr::ReadBlob: invalid, this will crash!" );
+ return m_pResImpl->aLocale;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt32 SimpleResMgr::ReadBlob( sal_uInt32 nId, void** pBuffer )
+{
+ osl::MutexGuard aGuard(m_aAccessSafety);
+
+ DBG_ASSERT( m_pResImpl, "SimpleResMgr::ReadBlob : have no impl class !" );
+
+ // perhaps constructed with an invalid filename ?
+ DBG_ASSERT( pBuffer, "SimpleResMgr::ReadBlob : invalid argument !" );
+ *pBuffer = NULL;
+
+ void* pResHandle = NULL;
+ InternalResMgr* pFallback = m_pResImpl;
+ RSHEADER_TYPE* pResHeader = (RSHEADER_TYPE*)m_pResImpl->LoadGlobalRes( RSC_RESOURCE, nId, &pResHandle );
+ DBG_ASSERT( pResHeader, "SimpleResMgr::ReadBlob : couldn't find the resource with the given id !" );
+
+ if ( !pResHeader )
+ {
+ osl::Guard<osl::Mutex> aGuard2( getResMgrMutex() );
+
+ // try fallback
+ while( ! pResHandle && pFallback )
+ {
+ InternalResMgr* pOldFallback = pFallback;
+ pFallback = ResMgrContainer::get().getNextFallback( pFallback );
+ if( pOldFallback != m_pResImpl )
+ ResMgrContainer::get().freeResMgr( pOldFallback );
+ if( pFallback )
+ {
+ // handle possible recursion
+ if( pFallback->aLocale.Language != m_pResImpl->aLocale.Language ||
+ pFallback->aLocale.Country != m_pResImpl->aLocale.Country ||
+ pFallback->aLocale.Variant != m_pResImpl->aLocale.Variant )
+ {
+ pResHeader = (RSHEADER_TYPE*)pFallback->LoadGlobalRes( RSC_RESOURCE, nId, &pResHandle );
+ }
+ else
+ {
+ ResMgrContainer::get().freeResMgr( pFallback );
+ pFallback = NULL;
+ }
+ }
+ }
+ if( ! pResHandle )
+ // no exception handling, this would require the locking of the solar mutex which isn't allowed within this class
+ return 0;
+ }
+
+ DBG_ASSERT( pResHandle == NULL, "SimpleResMgr::ReadBlob : behaviour of LoadGlobalRes changed !" );
+ // if pResHandle is not NULL the FreeBlob wouldn't have to delete the pointer given as pBuffer, but
+ // FreeBlob doesn't know that so it would probably crash ....
+
+ sal_uInt32 nRemaining = pResHeader->GetLocalOff() - sizeof(RSHEADER_TYPE);
+ *pBuffer = (void*)(((BYTE*)pResHeader) + sizeof(RSHEADER_TYPE));
+
+ // free an eventual fallback InternalResMgr
+ if( m_pResImpl != pFallback )
+ {
+ osl::Guard<osl::Mutex> aGuard2( getResMgrMutex() );
+
+ ResMgrContainer::get().freeResMgr( pFallback );
+ }
+
+ return nRemaining;
+}
+
+// -----------------------------------------------------------------------
+
+void SimpleResMgr::FreeBlob( void* pBuffer )
+{
+ void* pCompleteBuffer = (void*)(((BYTE*)pBuffer) - sizeof(RSHEADER_TYPE));
+ rtl_freeMemory(pCompleteBuffer);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/ref/errinf.cxx b/tools/source/ref/errinf.cxx
new file mode 100644
index 000000000000..c40a3c28b335
--- /dev/null
+++ b/tools/source/ref/errinf.cxx
@@ -0,0 +1,464 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <limits.h>
+#include <tools/shl.hxx>
+#include <tools/debug.hxx>
+#include <tools/errinf.hxx>
+#include <tools/string.hxx>
+
+class ErrorHandler;
+
+namespace {
+
+typedef void (* DisplayFnPtr)();
+
+}
+
+struct EDcrData
+{
+ public:
+
+ ErrorHandler *pFirstHdl;
+ ErrorContext *pFirstCtx;
+ DisplayFnPtr pDsp;
+ BOOL bIsWindowDsp;
+
+
+ DynamicErrorInfo *ppDcr[ERRCODE_DYNAMIC_COUNT];
+ USHORT nNextDcr;
+ EDcrData();
+
+static EDcrData *GetData();
+
+};
+
+class EDcr_Impl
+{
+ ULONG lErrId;
+ USHORT nMask;
+
+ void RegisterEDcr(DynamicErrorInfo *);
+ void UnRegisterEDcr(DynamicErrorInfo *);
+ static ErrorInfo *GetDynamicErrorInfo(ULONG lId);
+
+friend class DynamicErrorInfo;
+friend class ErrorInfo;
+};
+
+
+EDcrData::EDcrData()
+{
+ for(USHORT n=0;n<ERRCODE_DYNAMIC_COUNT;n++)
+ ppDcr[n]=0;
+ nNextDcr=0;
+ pFirstHdl=0;
+ pDsp=0;
+ pFirstCtx=0;
+}
+
+
+EDcrData *EDcrData::GetData()
+{
+#ifdef BOOTSTRAP
+ return 0x0;
+#else
+ EDcrData **ppDat=(EDcrData **)GetAppData(SHL_ERR);
+ if(!*ppDat)
+ {
+ return (*ppDat=new EDcrData);
+ }
+ else
+ return *ppDat;
+#endif
+}
+
+void EDcr_Impl::RegisterEDcr(DynamicErrorInfo *pDcr)
+{
+ //Vergibt eine dynamische Id
+
+ EDcrData* pData=EDcrData::GetData();
+ lErrId= (((ULONG)pData->nNextDcr + 1) << ERRCODE_DYNAMIC_SHIFT) +
+ pDcr->GetErrorCode();
+ DynamicErrorInfo **ppDcr=pData->ppDcr;
+ USHORT nNext=pData->nNextDcr;
+
+ // bei einem Ringbuffer koennen wir uns das ASSERT wohl sparen!
+ // DBG_ASSERT(ppDcr[nNext]==0,"ErrHdl: Alle Errors belegt");
+ if(ppDcr[nNext])
+ {
+ delete ppDcr[nNext];
+ }
+ ppDcr[nNext]=pDcr;
+ if(++pData->nNextDcr>=ERRCODE_DYNAMIC_COUNT)
+ pData->nNextDcr=0;
+}
+
+
+void EDcr_Impl::UnRegisterEDcr(DynamicErrorInfo *pDcr)
+{
+
+ EDcrData* pData=EDcrData::GetData();
+ DynamicErrorInfo **ppDcr=pData->ppDcr;
+ ULONG lIdx=(
+ ((ULONG)(*pDcr) & ERRCODE_DYNAMIC_MASK)>>ERRCODE_DYNAMIC_SHIFT)-1;
+ DBG_ASSERT(ppDcr[lIdx]==pDcr,"ErrHdl: Error nicht gefunden");
+ if(ppDcr[lIdx]==pDcr)
+ ppDcr[lIdx]=0;
+}
+
+TYPEINIT0(ErrorInfo);
+TYPEINIT1(DynamicErrorInfo, ErrorInfo);
+TYPEINIT1(StandardErrorInfo, DynamicErrorInfo);
+TYPEINIT1(StringErrorInfo, DynamicErrorInfo);
+TYPEINIT1(TwoStringErrorInfo, DynamicErrorInfo);
+TYPEINIT1(MessageInfo, DynamicErrorInfo);
+
+
+ErrorInfo *ErrorInfo::GetErrorInfo(ULONG lId)
+{
+ if(lId & ERRCODE_DYNAMIC_MASK)
+ return EDcr_Impl::GetDynamicErrorInfo(lId);
+ else
+ return new ErrorInfo(lId);
+}
+
+DynamicErrorInfo::operator ULONG() const
+{
+ return pImpl->lErrId;
+}
+
+DynamicErrorInfo::DynamicErrorInfo(ULONG lArgUserId, USHORT nMask)
+: ErrorInfo(lArgUserId)
+{
+ pImpl=new EDcr_Impl;
+ pImpl->RegisterEDcr(this);
+ pImpl->nMask=nMask;
+}
+
+DynamicErrorInfo::~DynamicErrorInfo()
+{
+ pImpl->UnRegisterEDcr(this);
+ delete pImpl;
+}
+
+ErrorInfo* EDcr_Impl::GetDynamicErrorInfo(ULONG lId)
+{
+ ULONG lIdx=((lId & ERRCODE_DYNAMIC_MASK)>>ERRCODE_DYNAMIC_SHIFT)-1;
+ DynamicErrorInfo* pDcr=EDcrData::GetData()->ppDcr[lIdx];
+ if(pDcr && (ULONG)(*pDcr)==lId)
+ return pDcr;
+ else
+ return new ErrorInfo(lId & ~ERRCODE_DYNAMIC_MASK);
+}
+
+
+USHORT DynamicErrorInfo::GetDialogMask() const
+{
+ return pImpl->nMask;
+}
+
+
+StandardErrorInfo::StandardErrorInfo(
+ ULONG UserId, ULONG lArgExtId, USHORT nFlags)
+: DynamicErrorInfo(UserId, nFlags), lExtId(lArgExtId)
+{
+}
+
+
+StringErrorInfo::StringErrorInfo(
+ ULONG UserId, const String& aStringP, USHORT nFlags)
+: DynamicErrorInfo(UserId, nFlags), aString(aStringP)
+{
+}
+
+
+class ErrHdl_Impl
+{
+ public:
+
+ ErrorHandler *pNext;
+ static BOOL CreateString(const ErrorHandler *pStart,
+ const ErrorInfo*, String&, USHORT&);
+};
+
+
+static void aDspFunc(const String &rErr, const String &rAction)
+{
+ ByteString aErr("Aktion: ");
+ aErr+= ByteString( rAction, RTL_TEXTENCODING_ASCII_US );
+ aErr+=" Fehler: ";
+ aErr+= ByteString( rErr, RTL_TEXTENCODING_ASCII_US );
+ DBG_ERROR(aErr.GetBuffer());
+}
+
+
+ErrorContext::ErrorContext(Window *pWinP)
+{
+ EDcrData *pData=EDcrData::GetData();
+ ErrorContext *&pHdl=pData->pFirstCtx;
+ pWin=pWinP;
+ pNext=pHdl;
+ pHdl=this;
+}
+
+ErrorContext::~ErrorContext()
+{
+ ErrorContext **ppCtx=&(EDcrData::GetData()->pFirstCtx);
+ while(*ppCtx && *ppCtx!=this)
+ ppCtx=&((*ppCtx)->pNext);
+ if(*ppCtx)
+ *ppCtx=(*ppCtx)->pNext;
+}
+
+ErrorContext *ErrorContext::GetContext()
+{
+ return EDcrData::GetData()->pFirstCtx;
+}
+
+ErrorHandler::ErrorHandler()
+{
+ pImpl=new ErrHdl_Impl;
+ EDcrData *pData=EDcrData::GetData();
+ ErrorHandler *&pHdl=pData->pFirstHdl;
+ pImpl->pNext=pHdl;
+ pHdl=this;
+ if(!pData->pDsp)
+ RegisterDisplay(&aDspFunc);
+}
+
+ErrorHandler::~ErrorHandler()
+{
+ ErrorHandler **ppHdl=&(EDcrData::GetData()->pFirstHdl);
+ while(*ppHdl && *ppHdl!=this)
+ ppHdl=&((*ppHdl)->pImpl->pNext);
+ if(*ppHdl)
+ *ppHdl=(*ppHdl)->pImpl->pNext;
+ delete pImpl;
+}
+
+void ErrorHandler::RegisterDisplay(WindowDisplayErrorFunc *aDsp)
+{
+ EDcrData *pData=EDcrData::GetData();
+ pData->bIsWindowDsp=TRUE;
+ pData->pDsp = reinterpret_cast< DisplayFnPtr >(aDsp);
+}
+
+void ErrorHandler::RegisterDisplay(BasicDisplayErrorFunc *aDsp)
+{
+ EDcrData *pData=EDcrData::GetData();
+ pData->bIsWindowDsp=FALSE;
+ pData->pDsp = reinterpret_cast< DisplayFnPtr >(aDsp);
+}
+
+USHORT ErrorHandler::HandleError_Impl(
+ ULONG lId, USHORT nFlags, BOOL bJustCreateString, String & rError)
+{
+
+/* [Beschreibung]
+ Handelt einen Fehler ab. lId ist die FehlerId, nFlags sind die
+ ErrorFlags. Werden nFlags nicht abgegeben, so werden die in
+ der DynamicErrorInfo angegebenen Flags bzw. die aus der Resource
+ verwendet.
+
+ Also:
+
+ 1. nFlags,
+ 2. Resource Flags
+ 3. Dynamic Flags
+ 4. Default ERRCODE_BUTTON_OK, ERRCODE_MSG_ERROR
+
+
+ */
+
+ String aErr;
+ String aAction;
+ if(!lId || lId == ERRCODE_ABORT)
+ return 0;
+ EDcrData *pData=EDcrData::GetData();
+ ErrorInfo *pInfo=ErrorInfo::GetErrorInfo(lId);
+ ErrorContext *pCtx=ErrorContext::GetContext();
+ if(pCtx)
+ pCtx->GetString(pInfo->GetErrorCode(), aAction);
+ Window *pParent=0;
+ //Nimm den Parent aus dem Konext
+ for(;pCtx;pCtx=pCtx->pNext)
+ if(pCtx->GetParent())
+ {
+ pParent=pCtx->GetParent();
+ break;
+ }
+
+ BOOL bWarning = ((lId & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK);
+ USHORT nErrFlags = ERRCODE_BUTTON_DEF_OK | ERRCODE_BUTTON_OK;
+ if (bWarning)
+ nErrFlags |= ERRCODE_MSG_WARNING;
+ else
+ nErrFlags |= ERRCODE_MSG_ERROR;
+
+ DynamicErrorInfo* pDynPtr=PTR_CAST(DynamicErrorInfo,pInfo);
+ if(pDynPtr)
+ {
+ USHORT nDynFlags = pDynPtr->GetDialogMask();
+ if( nDynFlags )
+ nErrFlags = nDynFlags;
+ }
+
+ if(ErrHdl_Impl::CreateString(pData->pFirstHdl,pInfo,aErr,nErrFlags))
+ {
+ if (bJustCreateString)
+ {
+ rError = aErr;
+ return 1;
+ }
+ else
+ {
+ if(!pData->pDsp)
+ {
+ ByteString aStr("Action: ");
+ aStr += ByteString( aAction, RTL_TEXTENCODING_ASCII_US );
+ aStr += ByteString("\nFehler: ");
+ aStr += ByteString( aErr, RTL_TEXTENCODING_ASCII_US );
+ DBG_ERROR( aStr.GetBuffer() );
+ }
+ else
+ {
+ delete pInfo;
+ if(!pData->bIsWindowDsp)
+ {
+ (*(BasicDisplayErrorFunc*)pData->pDsp)(aErr,aAction);
+ return 0;
+ }
+ else
+ {
+ if( nFlags != USHRT_MAX )
+ nErrFlags = nFlags;
+ return (*(WindowDisplayErrorFunc*)pData->pDsp)(
+ pParent, nErrFlags, aErr, aAction);
+ }
+ }
+ }
+ }
+ DBG_ERROR("Error nicht behandelt");
+ // Error 1 ist General Error im Sfx
+ if(pInfo->GetErrorCode()!=1) {
+ HandleError_Impl(1, USHRT_MAX, bJustCreateString, rError);
+ }
+ else {
+ DBG_ERROR("Error 1 nicht gehandeled");
+ }
+ delete pInfo;
+ return 0;
+}
+
+// static
+BOOL ErrorHandler::GetErrorString(ULONG lId, String& rStr)
+{
+ return (BOOL)HandleError_Impl( lId, USHRT_MAX, TRUE, rStr );
+}
+
+USHORT ErrorHandler::HandleError(ULONG lId, USHORT nFlags)
+{
+
+/* [Beschreibung]
+ Handelt einen Fehler ab. lId ist die FehlerId, nFlags sind die
+ ErrorFlags. Werden nFlags nicht abgegeben, so werden die in
+ der DynamicErrorInfo angegebenen Flags bzw. die aus der Resource
+ verwendet.
+
+ Also:
+
+ 1. nFlags,
+ 2. Resource Flags
+ 3. Dynamic Flags
+ 4. Default ERRCODE_BUTTON_OK, ERRCODE_MSG_ERROR
+
+
+ */
+
+ String aDummy;
+ return HandleError_Impl( lId, nFlags, FALSE, aDummy );
+}
+
+BOOL ErrorHandler::ForwCreateString(const ErrorInfo* pInfo, String& rStr, USHORT &rFlags) const
+{
+ return ErrHdl_Impl::CreateString(this->pImpl->pNext, pInfo, rStr, rFlags);
+}
+
+BOOL ErrHdl_Impl::CreateString( const ErrorHandler *pStart,
+ const ErrorInfo* pInfo, String& pStr,
+ USHORT &rFlags)
+{
+ for(const ErrorHandler *pHdl=pStart;pHdl;pHdl=pHdl->pImpl->pNext)
+ {
+ if(pHdl->CreateString( pInfo, pStr, rFlags))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL SimpleErrorHandler::CreateString(
+ const ErrorInfo *pInfo, String &rStr, USHORT &) const
+{
+ ULONG nId = pInfo->GetErrorCode();
+ ByteString aStr;
+ aStr="Id ";
+ aStr+=ByteString::CreateFromInt32(nId);
+ aStr+=" only handled by SimpleErrorHandler";
+ aStr+="\nErrorCode: ";
+ aStr+=ByteString::CreateFromInt32(nId & ((1L << ERRCODE_CLASS_SHIFT) - 1 ));
+ aStr+="\nErrorClass: ";
+ aStr+=ByteString::CreateFromInt32((nId & ERRCODE_CLASS_MASK) >> ERRCODE_CLASS_SHIFT);
+ aStr+="\nErrorArea: ";
+ aStr+=ByteString::CreateFromInt32((nId & ERRCODE_ERROR_MASK &
+ ~((1 << ERRCODE_AREA_SHIFT ) -1 ) ) >> ERRCODE_AREA_SHIFT);
+ DynamicErrorInfo *pDyn=PTR_CAST(DynamicErrorInfo,pInfo);
+ if(pDyn)
+ {
+ aStr+="\nDId ";
+ aStr+=ByteString::CreateFromInt32((ULONG)*pDyn);
+ }
+ StandardErrorInfo *pStd=PTR_CAST(StandardErrorInfo,pInfo);
+ if(pStd)
+ {
+ aStr+="\nXId ";
+ aStr+=ByteString::CreateFromInt32(pStd->GetExtendedErrorCode());
+ }
+ rStr = String( aStr, RTL_TEXTENCODING_ASCII_US );
+ return TRUE;
+}
+
+SimpleErrorHandler::SimpleErrorHandler()
+ : ErrorHandler()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/ref/globname.cxx b/tools/source/ref/globname.cxx
new file mode 100644
index 000000000000..7a7f5c56c738
--- /dev/null
+++ b/tools/source/ref/globname.cxx
@@ -0,0 +1,511 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <tools/stream.hxx>
+#include <tools/globname.hxx>
+
+/************** class ImpSvGlobalName ************************************/
+ImpSvGlobalName::ImpSvGlobalName( const ImpSvGlobalName & rObj )
+{
+ nRefCount = 0;
+ memcpy( szData, rObj.szData, sizeof( szData ) );
+}
+
+/************** class ImpSvGlobalName ************************************/
+ImpSvGlobalName::ImpSvGlobalName( int )
+{
+ nRefCount = 1;
+ memset( szData, 0, sizeof( szData ) );
+}
+
+/*************************************************************************
+|* ImpSvGlobalName::operator ==()
+*************************************************************************/
+BOOL ImpSvGlobalName::operator == ( const ImpSvGlobalName & rObj ) const
+{
+ return !memcmp( szData, rObj.szData, sizeof( szData ) );
+}
+
+/*************************************************************************
+|* SvGlobalName::SvGlobalName()
+*************************************************************************/
+SvGlobalName::SvGlobalName()
+{
+ static ImpSvGlobalName aNoName( 0 );
+
+ pImp = &aNoName;
+ pImp->nRefCount++;
+}
+
+// locker die Struktur von Windows kopiert
+#ifdef WNT
+struct _GUID
+#else
+struct GUID
+#endif
+{
+ UINT32 Data1;
+ UINT16 Data2;
+ UINT16 Data3;
+ BYTE Data4[8];
+};
+SvGlobalName::SvGlobalName( const CLSID & rId )
+{
+ pImp = new ImpSvGlobalName();
+ pImp->nRefCount++;
+ memcpy( pImp->szData, &rId, sizeof( pImp->szData ) );
+}
+
+SvGlobalName::SvGlobalName( UINT32 n1, USHORT n2, USHORT n3,
+ BYTE b8, BYTE b9, BYTE b10, BYTE b11,
+ BYTE b12, BYTE b13, BYTE b14, BYTE b15 )
+{
+ pImp = new ImpSvGlobalName();
+ pImp->nRefCount++;
+
+ memcpy(pImp->szData, &n1, sizeof(n1));
+ memcpy(pImp->szData+4, &n2, sizeof(n2));
+ memcpy(pImp->szData+6, &n3, sizeof(n3));
+ pImp->szData[ 8 ] = b8;
+ pImp->szData[ 9 ] = b9;
+ pImp->szData[ 10 ] = b10;
+ pImp->szData[ 11 ] = b11;
+ pImp->szData[ 12 ] = b12;
+ pImp->szData[ 13 ] = b13;
+ pImp->szData[ 14 ] = b14;
+ pImp->szData[ 15 ] = b15;
+}
+
+/*************************************************************************
+|* SvGlobalName::~SvGlobalName()
+*************************************************************************/
+SvGlobalName::~SvGlobalName()
+{
+ pImp->nRefCount--;
+ if( !pImp->nRefCount )
+ delete pImp;
+}
+
+/*************************************************************************
+|* SvGlobalName::operator = ()
+*************************************************************************/
+SvGlobalName & SvGlobalName::operator = ( const SvGlobalName & rObj )
+{
+ rObj.pImp->nRefCount++;
+ pImp->nRefCount--;
+ if( !pImp->nRefCount )
+ delete pImp;
+ pImp = rObj.pImp;
+ return *this;
+}
+
+/*************************************************************************
+|* SvGlobalName::NewImp()
+*************************************************************************/
+void SvGlobalName::NewImp()
+{
+ if( pImp->nRefCount > 1 )
+ {
+ pImp->nRefCount--;
+ pImp = new ImpSvGlobalName( *pImp );
+ pImp->nRefCount++;
+ }
+}
+
+/*************************************************************************
+|* SvGlobalName::operator << ()
+|* SvGlobalName::operator >> ()
+*************************************************************************/
+SvStream& operator << ( SvStream& rOStr, const SvGlobalName & rObj )
+{
+ sal_uInt32 a;
+ memcpy(&a, rObj.pImp->szData, sizeof(sal_uInt32));
+ rOStr << a;
+
+ sal_uInt16 b;
+ memcpy(&b, rObj.pImp->szData+4, sizeof(sal_uInt16));
+ rOStr << b;
+
+ memcpy(&b, rObj.pImp->szData+6, sizeof(sal_uInt16));
+ rOStr << b;
+
+ rOStr.Write( (sal_Char *)&rObj.pImp->szData[ 8 ], 8 );
+ return rOStr;
+}
+
+SvStream& operator >> ( SvStream& rStr, SvGlobalName & rObj )
+{
+ rObj.NewImp(); // kopieren, falls noetig
+
+ sal_uInt32 a;
+ rStr >> a;
+ memcpy(rObj.pImp->szData, &a, sizeof(sal_uInt32));
+
+ sal_uInt16 b;
+ rStr >> b;
+ memcpy(rObj.pImp->szData+4, &b, sizeof(sal_uInt16));
+
+ rStr >> b;
+ memcpy(rObj.pImp->szData+6, &b, sizeof(sal_uInt16));
+
+ rStr.Read( (sal_Char *)&rObj.pImp->szData[ 8 ], 8 );
+ return rStr;
+}
+
+
+/*************************************************************************
+|* SvGlobalName::operator < ()
+*************************************************************************/
+BOOL SvGlobalName::operator < ( const SvGlobalName & rObj ) const
+{
+ int n = memcmp( pImp->szData +6, rObj.pImp->szData +6,
+ sizeof( pImp->szData ) -6);
+ if( n < 0 )
+ return TRUE;
+ else if( n > 0 )
+ return FALSE;
+
+ sal_uInt16 Data2_a;
+ memcpy(&Data2_a, pImp->szData+4, sizeof(sal_uInt16));
+
+ sal_uInt16 Data2_b;
+ memcpy(&Data2_b, rObj.pImp->szData+4, sizeof(sal_uInt16));
+
+ if( Data2_a < Data2_b )
+ return TRUE;
+ else if( Data2_a == Data2_b )
+ {
+ sal_uInt32 Data1_a;
+ memcpy(&Data1_a, pImp->szData+4, sizeof(sal_uInt32));
+
+ sal_uInt32 Data1_b;
+ memcpy(&Data1_b, rObj.pImp->szData+4, sizeof(sal_uInt32));
+
+ return Data1_a < Data1_b;
+ }
+ else
+ return FALSE;
+
+}
+
+/*************************************************************************
+|* SvGlobalName::operator +=()
+*************************************************************************/
+SvGlobalName & SvGlobalName::operator += ( UINT32 n )
+{
+ NewImp();
+
+ sal_uInt32 nOld;
+ memcpy(&nOld, pImp->szData, sizeof(sal_uInt32));
+ sal_uInt32 nNew = nOld + n;
+ memcpy(pImp->szData, &nNew, sizeof(sal_uInt32));
+
+ if( nOld > nNew )
+ {
+ // overflow
+ sal_uInt16 Data2;
+ memcpy(&Data2, pImp->szData + 4, sizeof(sal_uInt16));
+ ++Data2;
+ memcpy(pImp->szData + 4, &Data2, sizeof(sal_uInt16));
+ }
+ return *this;
+}
+
+/*************************************************************************
+|* SvGlobalName::operator ==()
+*************************************************************************/
+BOOL SvGlobalName::operator == ( const SvGlobalName & rObj ) const
+{
+ return *pImp == *rObj.pImp;
+}
+
+void SvGlobalName::MakeFromMemory( void * pData )
+{
+ NewImp();
+ memcpy( pImp->szData, pData, sizeof( pImp->szData ) );
+}
+
+/*************************************************************************
+|* SvGlobalName::MakeId()
+*************************************************************************/
+BOOL SvGlobalName::MakeId( const String & rIdStr )
+{
+ ByteString aStr( rIdStr, RTL_TEXTENCODING_ASCII_US );
+ sal_Char * pStr = (sal_Char *)aStr.GetBuffer();
+ if( rIdStr.Len() == 36
+ && '-' == pStr[ 8 ] && '-' == pStr[ 13 ]
+ && '-' == pStr[ 18 ] && '-' == pStr[ 23 ] )
+ {
+ UINT32 nFirst = 0;
+ int i = 0;
+ for( i = 0; i < 8; i++ )
+ {
+ if( isxdigit( *pStr ) )
+ if( isdigit( *pStr ) )
+ nFirst = nFirst * 16 + (*pStr - '0');
+ else
+ nFirst = nFirst * 16 + (toupper( *pStr ) - 'A' + 10 );
+ else
+ return FALSE;
+ pStr++;
+ }
+
+ UINT16 nSec = 0;
+ pStr++;
+ for( i = 0; i < 4; i++ )
+ {
+ if( isxdigit( *pStr ) )
+ if( isdigit( *pStr ) )
+ nSec = nSec * 16 + (*pStr - '0');
+ else
+ nSec = nSec * 16 + (UINT16)(toupper( *pStr ) - 'A' + 10 );
+ else
+ return FALSE;
+ pStr++;
+ }
+
+ UINT16 nThird = 0;
+ pStr++;
+ for( i = 0; i < 4; i++ )
+ {
+ if( isxdigit( *pStr ) )
+ if( isdigit( *pStr ) )
+ nThird = nThird * 16 + (*pStr - '0');
+ else
+ nThird = nThird * 16 + (UINT16)(toupper( *pStr ) - 'A' + 10 );
+ else
+ return FALSE;
+ pStr++;
+ }
+
+ BYTE szRemain[ 8 ];
+ memset( szRemain, 0, sizeof( szRemain ) );
+ pStr++;
+ for( i = 0; i < 16; i++ )
+ {
+ if( isxdigit( *pStr ) )
+ if( isdigit( *pStr ) )
+ szRemain[i/2] = szRemain[i/2] * 16 + (*pStr - '0');
+ else
+ szRemain[i/2] = szRemain[i/2] * 16 + (BYTE)(toupper( *pStr ) - 'A' + 10 );
+ else
+ return FALSE;
+ pStr++;
+ if( i == 3 )
+ pStr++;
+ }
+
+ NewImp();
+ memcpy(&pImp->szData[0], &nFirst, sizeof(nFirst));
+ memcpy(&pImp->szData[4], &nSec, sizeof(nSec));
+ memcpy(&pImp->szData[6], &nThird, sizeof(nThird));
+ memcpy(&pImp->szData[ 8 ], szRemain, 8);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*************************************************************************
+|* SvGlobalName::GetctorName()
+*************************************************************************/
+String SvGlobalName::GetctorName() const
+{
+ ByteString aRet;
+
+ sal_Char buf[ 20 ];
+ sal_uInt32 Data1;
+ memcpy(&Data1, pImp->szData, sizeof(sal_uInt32));
+ sprintf( buf, "0x%8.8" SAL_PRIXUINT32, Data1 );
+ aRet += buf;
+ USHORT i;
+ for( i = 4; i < 8; i += 2 )
+ {
+ aRet += ',';
+ sal_uInt16 Data2;
+ memcpy(&Data2, pImp->szData+i, sizeof(sal_uInt16));
+ sprintf( buf, "0x%4.4X", Data2 );
+ aRet += buf;
+ }
+ for( i = 8; i < 16; i++ )
+ {
+ aRet += ',';
+ sprintf( buf, "0x%2.2x", pImp->szData[ i ] );
+ aRet += buf;
+ }
+ return String( aRet, RTL_TEXTENCODING_ASCII_US );
+}
+
+/*************************************************************************
+|* SvGlobalName::GetHexName()
+*************************************************************************/
+String SvGlobalName::GetHexName() const
+{
+ ByteString aRet;
+
+ sal_Char buf[ 10 ];
+ sal_uInt32 Data1;
+ memcpy(&Data1, pImp->szData, sizeof(sal_uInt32));
+ sprintf( buf, "%8.8" SAL_PRIXUINT32, Data1 );
+ aRet += buf;
+ aRet += '-';
+ USHORT i ;
+ for( i = 4; i < 8; i += 2 )
+ {
+ sal_uInt16 Data2;
+ memcpy(&Data2, pImp->szData+i, sizeof(sal_uInt16));
+ sprintf( buf, "%4.4X", Data2 );
+ aRet += buf;
+ aRet += '-';
+ }
+ for( i = 8; i < 10; i++ )
+ {
+ sprintf( buf, "%2.2x", pImp->szData[ i ] );
+ aRet += buf;
+ }
+ aRet += '-';
+ for( i = 10; i < 16; i++ )
+ {
+ sprintf( buf, "%2.2x", pImp->szData[ i ] );
+ aRet += buf;
+ }
+ return String( aRet, RTL_TEXTENCODING_ASCII_US );
+}
+
+/************** SvGlobalNameList ****************************************/
+/************************************************************************/
+/*************************************************************************
+|* SvGlobalNameList::SvGlobalNameList()
+*************************************************************************/
+SvGlobalNameList::SvGlobalNameList()
+ : aList( 1, 1 )
+{
+}
+
+/*************************************************************************
+|* SvGlobalNameList::~SvGlobalNameList()
+*************************************************************************/
+SvGlobalNameList::~SvGlobalNameList()
+{
+ for( ULONG i = Count(); i > 0; i-- )
+ {
+ ImpSvGlobalName * pImp = (ImpSvGlobalName *)aList.GetObject( i -1 );
+ pImp->nRefCount--;
+ if( !pImp->nRefCount )
+ delete pImp;
+ }
+}
+
+/*************************************************************************
+|* SvGlobalNameList::Append()
+*************************************************************************/
+void SvGlobalNameList::Append( const SvGlobalName & rName )
+{
+ rName.pImp->nRefCount++;
+ aList.Insert( rName.pImp, LIST_APPEND );
+}
+
+/*************************************************************************
+|* SvGlobalNameList::GetObject()
+*************************************************************************/
+SvGlobalName SvGlobalNameList::GetObject( ULONG nPos )
+{
+ return SvGlobalName( (ImpSvGlobalName *)aList.GetObject( nPos ) );
+}
+
+/*************************************************************************
+|* SvGlobalNameList::IsEntry()
+*************************************************************************/
+BOOL SvGlobalNameList::IsEntry( const SvGlobalName & rName )
+{
+ for( ULONG i = Count(); i > 0; i-- )
+ {
+ if( *rName.pImp == *(ImpSvGlobalName *)aList.GetObject( i -1 ) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+com::sun::star::uno::Sequence < sal_Int8 > SvGlobalName::GetByteSequence() const
+{
+ // platform independent representation of a "GlobalName"
+ // maybe transported remotely
+ com::sun::star::uno::Sequence< sal_Int8 > aResult( 16 );
+
+ sal_uInt32 Data1;
+ memcpy(&Data1, pImp->szData, sizeof(sal_uInt32));
+ aResult[0] = (sal_Int8) (Data1 >> 24);
+ aResult[1] = (sal_Int8) ((Data1 << 8 ) >> 24);
+ aResult[2] = (sal_Int8) ((Data1 << 16 ) >> 24);
+ aResult[3] = (sal_Int8) ((Data1 << 24 ) >> 24);
+ sal_uInt16 Data2;
+ memcpy(&Data2, pImp->szData+4, sizeof(sal_uInt16));
+ aResult[4] = (sal_Int8) (Data2 >> 8);
+ aResult[5] = (sal_Int8) ((Data2 << 8 ) >> 8);
+ sal_uInt16 Data3;
+ memcpy(&Data3, pImp->szData+6, sizeof(sal_uInt16));
+ aResult[6] = (sal_Int8) (Data3 >> 8);
+ aResult[7] = (sal_Int8) ((Data3 << 8 ) >> 8);
+ aResult[8] = pImp->szData[ 8 ];
+ aResult[9] = pImp->szData[ 9 ];
+ aResult[10] = pImp->szData[ 10 ];
+ aResult[11] = pImp->szData[ 11 ];
+ aResult[12] = pImp->szData[ 12 ];
+ aResult[13] = pImp->szData[ 13 ];
+ aResult[14] = pImp->szData[ 14 ];
+ aResult[15] = pImp->szData[ 15 ];
+
+ return aResult;
+}
+
+SvGlobalName::SvGlobalName( const com::sun::star::uno::Sequence < sal_Int8 >& aSeq )
+{
+ // create SvGlobalName from a platform independent representation
+ GUID aResult;
+ memset( &aResult, 0, sizeof( aResult ) );
+ if ( aSeq.getLength() == 16 )
+ {
+ aResult.Data1 = ( ( ( ( ( ( sal_uInt8 )aSeq[0] << 8 ) + ( sal_uInt8 )aSeq[1] ) << 8 ) + ( sal_uInt8 )aSeq[2] ) << 8 ) + ( sal_uInt8 )aSeq[3];
+ aResult.Data2 = ( ( sal_uInt8 )aSeq[4] << 8 ) + ( sal_uInt8 )aSeq[5];
+ aResult.Data3 = ( ( sal_uInt8 )aSeq[6] << 8 ) + ( sal_uInt8 )aSeq[7];
+ for( int nInd = 0; nInd < 8; nInd++ )
+ aResult.Data4[nInd] = ( sal_uInt8 )aSeq[nInd+8];
+ }
+
+ pImp = new ImpSvGlobalName();
+ pImp->nRefCount++;
+ memcpy( pImp->szData, &aResult, sizeof( pImp->szData ) );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/ref/makefile.mk b/tools/source/ref/makefile.mk
new file mode 100644
index 000000000000..c87f8a740a4f
--- /dev/null
+++ b/tools/source/ref/makefile.mk
@@ -0,0 +1,53 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=tools
+TARGET=ref
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/ref.obj \
+ $(SLO)$/pstm.obj \
+ $(SLO)$/globname.obj \
+ $(SLO)$/errinf.obj
+
+OBJFILES= $(OBJ)$/ref.obj \
+ $(OBJ)$/pstm.obj \
+ $(OBJ)$/globname.obj \
+ $(OBJ)$/errinf.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/tools/source/ref/pstm.cxx b/tools/source/ref/pstm.cxx
new file mode 100644
index 000000000000..48db82685b31
--- /dev/null
+++ b/tools/source/ref/pstm.cxx
@@ -0,0 +1,917 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <tools/debug.hxx>
+#include <tools/pstm.hxx>
+
+#define STOR_NO_OPTIMIZE
+
+/***********************************************************************/
+/************************************************************************
+|* SvClassManager::Register()
+*************************************************************************/
+void SvClassManager::Register( USHORT nClassId, SvCreateInstancePersist pFunc )
+{
+#ifdef DBG_UTIL
+ SvCreateInstancePersist p;
+ p = Get( nClassId );
+ DBG_ASSERT( !p || p == pFunc, "register class with same id" );
+#endif
+ aAssocTable.insert(Map::value_type(nClassId, pFunc));
+}
+
+/************************************************************************
+|* SvClassManager::Get()
+*************************************************************************/
+SvCreateInstancePersist SvClassManager::Get( USHORT nClassId )
+{
+ Map::const_iterator i(aAssocTable.find(nClassId));
+ return i == aAssocTable.end() ? 0 : i->second;
+}
+
+/****************** SvRttiBase *******************************************/
+TYPEINIT0( SvRttiBase );
+
+/****************** SvPersistBaseMemberList ******************************/
+
+SvPersistBaseMemberList::SvPersistBaseMemberList(){}
+SvPersistBaseMemberList::SvPersistBaseMemberList(
+ USHORT nInitSz, USHORT nResize )
+ : SuperSvPersistBaseMemberList( nInitSz, nResize ){}
+
+#define PERSIST_LIST_VER (BYTE)0
+#define PERSIST_LIST_DBGUTIL (BYTE)0x80
+
+/************************************************************************
+|* SvPersistBaseMemberList::WriteOnlyStreamedObjects()
+*************************************************************************/
+void SvPersistBaseMemberList::WriteObjects( SvPersistStream & rStm,
+ BOOL bOnlyStreamed ) const
+{
+#ifdef STOR_NO_OPTIMIZE
+ rStm << (BYTE)(PERSIST_LIST_VER | PERSIST_LIST_DBGUTIL);
+ UINT32 nObjPos = rStm.WriteDummyLen();
+#else
+ BYTE bTmp = PERSIST_LIST_VER;
+ rStm << bTmp;
+#endif
+ UINT32 nCountMember = Count();
+ ULONG nCountPos = rStm.Tell();
+ UINT32 nWriteCount = 0;
+ rStm << nCountMember;
+ //bloss die Liste nicht veraendern,
+ //wegen Seiteneffekten beim Save
+ for( ULONG n = 0; n < nCountMember; n++ )
+ {
+ SvPersistBase * pObj = GetObject( n );
+ if( !bOnlyStreamed || rStm.IsStreamed( pObj ) )
+ { // Objekt soll geschrieben werden
+ rStm << GetObject( n );
+ nWriteCount++;
+ }
+ }
+ if( nWriteCount != nCountMember )
+ {
+ // nicht alle Objekte geschrieben, Count anpassen
+ ULONG nPos = rStm.Tell();
+ rStm.Seek( nCountPos );
+ rStm << nWriteCount;
+ rStm.Seek( nPos );
+ }
+#ifdef STOR_NO_OPTIMIZE
+ rStm.WriteLen( nObjPos );
+#endif
+}
+
+/************************************************************************
+|* operator << ()
+*************************************************************************/
+SvPersistStream& operator << ( SvPersistStream & rStm,
+ const SvPersistBaseMemberList & rLst )
+{
+ rLst.WriteObjects( rStm );
+ return rStm;
+}
+
+/************************************************************************
+|* operator >> ()
+*************************************************************************/
+SvPersistStream& operator >> ( SvPersistStream & rStm,
+ SvPersistBaseMemberList & rLst )
+{
+ BYTE nVer;
+ rStm >> nVer;
+
+ if( (nVer & ~PERSIST_LIST_DBGUTIL) != PERSIST_LIST_VER )
+ {
+ rStm.SetError( SVSTREAM_GENERALERROR );
+ DBG_ERROR( "persist list, false version" );
+ }
+
+ UINT32 nObjLen(0), nObjPos(0);
+ if( nVer & PERSIST_LIST_DBGUTIL )
+ nObjLen = rStm.ReadLen( &nObjPos );
+
+ sal_uInt32 nCount;
+ rStm >> nCount;
+ for( ULONG n = 0; n < nCount && rStm.GetError() == SVSTREAM_OK; n++ )
+ {
+ SvPersistBase * pObj;
+ rStm >> pObj;
+ if( pObj )
+ rLst.Append( pObj );
+ }
+#ifdef DBG_UTIL
+ if( nObjLen + nObjPos != rStm.Tell() )
+ {
+ ByteString aStr( "false list len: read = " );
+ aStr += ByteString::CreateFromInt32( (long)(rStm.Tell() - nObjPos) );
+ aStr += ", should = ";
+ aStr += ByteString::CreateFromInt64(nObjLen);
+ DBG_ERROR( aStr.GetBuffer() );
+ }
+#endif
+ return rStm;
+}
+
+//=========================================================================
+SvPersistStream::SvPersistStream
+(
+ SvClassManager & rMgr, /* Alle Factorys, deren Objekt geladen und
+ gespeichert werdn k"onnen */
+ SvStream * pStream, /* Dieser Stream wird als Medium genommen, auf
+ dem der PersistStream arbeitet */
+ UINT32 nStartIdxP /* Ab diesem Index werden die Id's f"ur
+ die Objekte vergeben, er muss gr"osser
+ als Null sein. */
+)
+ : rClassMgr( rMgr )
+ , pStm( pStream )
+ , aPUIdx( nStartIdxP )
+ , nStartIdx( nStartIdxP )
+ , pRefStm( NULL )
+ , nFlags( 0 )
+/* [Beschreibung]
+
+ Der Konstruktor der Klasse SvPersistStream. Die Objekte rMgr und
+ pStream d"urfen nicht ver"andert werden, solange sie in einem
+ SvPersistStream eingesetzt sind. Eine Aussnahme gibt es f"ur
+ pStream (siehe <SvPersistStream::SetStream>).
+*/
+{
+ DBG_ASSERT( nStartIdx != 0, "zero index not allowed" );
+ bIsWritable = TRUE;
+ if( pStm )
+ {
+ SetVersion( pStm->GetVersion() );
+ SetError( pStm->GetError() );
+ SyncSvStream( pStm->Tell() );
+ }
+}
+
+//=========================================================================
+SvPersistStream::SvPersistStream
+(
+ SvClassManager & rMgr, /* Alle Factorys, deren Objekt geladen und
+ gespeichert werdn k"onnen */
+ SvStream * pStream, /* Dieser Stream wird als Medium genommen, auf
+ dem der PersistStream arbeitet */
+ const SvPersistStream & rPersStm
+ /* Wenn PersistStream's verschachtelt werden,
+ dann ist dies der Parent-Stream. */
+)
+ : rClassMgr( rMgr )
+ , pStm( pStream )
+ // Bereiche nicht ueberschneiden, deshalb nur groessere Indexe
+ , aPUIdx( rPersStm.GetCurMaxIndex() +1 )
+ , nStartIdx( rPersStm.GetCurMaxIndex() +1 )
+ , pRefStm( &rPersStm )
+ , nFlags( 0 )
+/* [Beschreibung]
+
+ Der Konstruktor der Klasse SvPersistStream. Die Objekte rMgr und
+ pStream d"urfen nicht ver"andert werden, solange sie in einem
+ SvPersistStream eingesetzt sind. Eine Aussnahme gibt es f"ur
+ pStream (siehe <SvPersistStream::SetStream>).
+ Durch diesen Konstruktor wird eine Hierarchiebildung unterst"utzt.
+ Alle Objekte aus einer Hierarchie m"ussen erst geladen werden,
+ wenn das erste aus dieser Hierarchie benutzt werden soll.
+*/
+{
+ bIsWritable = TRUE;
+ if( pStm )
+ {
+ SetVersion( pStm->GetVersion() );
+ SetError( pStm->GetError() );
+ SyncSvStream( pStm->Tell() );
+ }
+}
+
+//=========================================================================
+SvPersistStream::~SvPersistStream()
+/* [Beschreibung]
+
+ Der Detruktor ruft die Methode <SvPersistStream::SetStream>
+ mit NULL.
+*/
+{
+ SetStream( NULL );
+}
+
+//=========================================================================
+void SvPersistStream::SetStream
+(
+ SvStream * pStream /* auf diesem Stream arbeitet der PersistStream */
+
+)
+/* [Beschreibung]
+
+ Es wird ein Medium (pStream) eingesetzt, auf dem PersistStream arbeitet.
+ Dieses darf nicht von aussen modifiziert werden, solange es
+ eingesetzt ist. Es sei denn, w"ahrend auf dem Medium gearbeitet
+ wird, wird keine Methode von SvPersistStream gerufen, bevor
+ nicht <SvPersistStream::SetStream> mit demselben Medium gerufen
+ wurde.
+*/
+{
+ if( pStm != pStream )
+ {
+ if( pStm )
+ {
+ SyncSysStream();
+ pStm->SetError( GetError() );
+ }
+ pStm = pStream;
+ }
+ if( pStm )
+ {
+ SetVersion( pStm->GetVersion() );
+ SetError( pStm->GetError() );
+ SyncSvStream( pStm->Tell() );
+ }
+}
+
+//=========================================================================
+USHORT SvPersistStream::IsA() const
+/* [Beschreibung]
+
+ Gibt den Identifier dieses Streamklasse zur"uck.
+
+ [R"uckgabewert]
+
+ USHORT ID_PERSISTSTREAM wird zur"uckgegeben.
+
+
+ [Querverweise]
+
+ <SvStream::IsA>
+*/
+{
+ return ID_PERSISTSTREAM;
+}
+
+
+/*************************************************************************
+|* SvPersistStream::ResetError()
+*************************************************************************/
+void SvPersistStream::ResetError()
+{
+ SvStream::ResetError();
+ DBG_ASSERT( pStm, "stream not set" );
+ pStm->ResetError();
+}
+
+/*************************************************************************
+|* SvPersistStream::GetData()
+*************************************************************************/
+ULONG SvPersistStream::GetData( void* pData, ULONG nSize )
+{
+ DBG_ASSERT( pStm, "stream not set" );
+ ULONG nRet = pStm->Read( pData, nSize );
+ SetError( pStm->GetError() );
+ return nRet;
+}
+
+/*************************************************************************
+|* SvPersistStream::PutData()
+*************************************************************************/
+ULONG SvPersistStream::PutData( const void* pData, ULONG nSize )
+{
+ DBG_ASSERT( pStm, "stream not set" );
+ ULONG nRet = pStm->Write( pData, nSize );
+ SetError( pStm->GetError() );
+ return nRet;
+}
+
+/*************************************************************************
+|* SvPersistStream::Seek()
+*************************************************************************/
+ULONG SvPersistStream::SeekPos( ULONG nPos )
+{
+ DBG_ASSERT( pStm, "stream not set" );
+ ULONG nRet = pStm->Seek( nPos );
+ SetError( pStm->GetError() );
+ return nRet;
+}
+
+/*************************************************************************
+|* SvPersistStream::FlushData()
+*************************************************************************/
+void SvPersistStream::FlushData()
+{
+}
+
+/*************************************************************************
+|* SvPersistStream::GetCurMaxIndex()
+*************************************************************************/
+ULONG SvPersistStream::GetCurMaxIndex( const SvPersistUIdx & rIdx ) const
+{
+ // const bekomme ich nicht den hoechsten Index
+ SvPersistUIdx * p = (SvPersistUIdx *)&rIdx;
+ // alten merken
+ ULONG nCurIdx = p->GetCurIndex();
+ p->Last();
+ // Bereiche nicht ueberschneiden, deshalb nur groessere Indexe
+ ULONG nMaxIdx = p->GetCurIndex();
+ // wieder herstellen
+ p->Seek( nCurIdx );
+ return nMaxIdx;
+}
+
+/*************************************************************************
+|* SvPersistStream::GetIndex()
+*************************************************************************/
+ULONG SvPersistStream::GetIndex( SvPersistBase * pObj ) const
+{
+ ULONG nId = (ULONG)aPTable.Get( (ULONG)pObj );
+ if( !nId && pRefStm )
+ return pRefStm->GetIndex( pObj );
+ return nId;
+}
+
+/*************************************************************************
+|* SvPersistStream::GetObject)
+*************************************************************************/
+SvPersistBase * SvPersistStream::GetObject( ULONG nIdx ) const
+{
+ if( nIdx >= nStartIdx )
+ return aPUIdx.Get( nIdx );
+ else if( pRefStm )
+ return pRefStm->GetObject( nIdx );
+ return NULL;
+}
+
+//=========================================================================
+#define LEN_1 0x80
+#define LEN_2 0x40
+#define LEN_4 0x20
+#define LEN_5 0x10
+UINT32 SvPersistStream::ReadCompressed
+(
+ SvStream & rStm /* Aus diesem Stream werden die komprimierten Daten
+ gelesen */
+)
+/* [Beschreibung]
+
+ Ein im Stream komprimiert abgelegtes Wort wird gelesen. In welchem
+ Format komprimiert wird, siehe <SvPersistStream::WriteCompressed>.
+
+ [R"uckgabewert]
+
+ UINT32 Das nicht komprimierte Wort wird zur"uckgegeben.
+
+ [Querverweise]
+
+*/
+{
+ UINT32 nRet(0);
+ BYTE nMask;
+ rStm >> nMask;
+ if( nMask & LEN_1 )
+ nRet = ~LEN_1 & nMask;
+ else if( nMask & LEN_2 )
+ {
+ nRet = ~LEN_2 & nMask;
+ nRet <<= 8;
+ rStm >> nMask;
+ nRet |= nMask;
+ }
+ else if( nMask & LEN_4 )
+ {
+ nRet = ~LEN_4 & nMask;
+ nRet <<= 8;
+ rStm >> nMask;
+ nRet |= nMask;
+ nRet <<= 16;
+ USHORT n;
+ rStm >> n;
+ nRet |= n;
+ }
+ else if( nMask & LEN_5 )
+ {
+ if( nMask & 0x0F )
+ {
+ rStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ DBG_ERROR( "format error" );
+ }
+ rStm >> nRet;
+ }
+ else
+ {
+ rStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ DBG_ERROR( "format error" );
+ }
+ return nRet;
+}
+
+//=========================================================================
+void SvPersistStream::WriteCompressed
+(
+ SvStream & rStm,/* Aus diesem Stream werden die komprimierten Daten
+ gelesen */
+ UINT32 nVal /* Dieser Wert wird komprimiert geschrieben */
+)
+/* [Beschreibung]
+
+ Das "ubergebene Wort wird komprimiert und in den Stream
+ geschrieben. Folgendermassen wir komprimiert.
+ nVal < 0x80 => 0x80 + nVal ist 1 Byte gross.
+ nVal < 0x4000 => 0x4000 + nVal ist 2 Byte gross.
+ nVal < 0x20000000 => 0x20000000 + nVal ist 4 Byte gross.
+ nVal > 0x1FFFFFFF => 0x1000000000+ nVal ist 5 Byte gross.
+
+ [Querverweise]
+
+ <SvPersistStream::ReadCompressed>
+*/
+{
+#ifdef STOR_NO_OPTIMIZE
+ if( nVal < 0x80 )
+ rStm << (BYTE)(LEN_1 | nVal);
+ else if( nVal < 0x4000 )
+ {
+ rStm << (BYTE)(LEN_2 | (nVal >> 8));
+ rStm << (BYTE)nVal;
+ }
+ else if( nVal < 0x20000000 )
+ {
+ // hoechstes BYTE
+ rStm << (BYTE)(LEN_4 | (nVal >> 24));
+ // 2. hoechstes BYTE
+ rStm << (BYTE)(nVal >> 16);
+ rStm << (USHORT)(nVal);
+ }
+ else
+#endif
+ {
+ rStm << (BYTE)LEN_5;
+ rStm << nVal;
+ }
+}
+
+//=========================================================================
+UINT32 SvPersistStream::WriteDummyLen()
+/* [Beschreibung]
+
+ Die Methode schreibt 4 Byte in den Stream und gibt die Streamposition
+ zur"uck.
+
+ [R"uckgabewert]
+
+ UINT32 Die Position hinter der L"angenangabe wird zur"uckgegeben.
+
+ [Beispiel]
+
+ UINT32 nObjPos = rStm.WriteDummyLen();
+ ...
+ // Daten schreiben
+ ...
+ rStm.WriteLen( nObjPos );
+
+ [Querverweise]
+
+ <SvPersistStream::ReadLen>, <SvPersistStream::WriteLen>
+
+*/
+{
+#ifdef DBG_UTIL
+ UINT32 nPos = Tell();
+#endif
+ UINT32 n0 = 0;
+ *this << n0; // wegen Sun sp
+ // keine Assertion bei Streamfehler
+ DBG_ASSERT( GetError() != SVSTREAM_OK
+ || (sizeof( UINT32 ) == Tell() -nPos),
+ "keine 4-Byte fuer Langenangabe" );
+ return Tell();
+}
+
+//=========================================================================
+void SvPersistStream::WriteLen
+(
+ UINT32 nObjPos /* die Position + 4, an der die L"ange geschrieben
+ wird. */
+)
+/* [Beschreibung]
+
+ Die Methode schreibt die Differenz zwischen der aktuellen und
+ nObjPos als UINT32 an die Position nObjPos -4 im Stream. Danach
+ wird der Stream wieder auf die alte Position gestellt.
+
+ [Beispiel]
+
+ Die Differenz enth"alt nicht die L"angenangabe.
+
+ UINT32 nObjPos = rStm.WriteDummyLen();
+ ...
+ // Daten schreiben
+ ...
+ rStm.WriteLen( nObjPos );
+ // weitere Daten schreiben
+
+ [Querverweise]
+
+ <SvPersistStream::ReadLen>, <SvPersistStream::WriteDummyLen>
+*/
+{
+ UINT32 nPos = Tell();
+ UINT32 nLen = nPos - nObjPos;
+ // die Laenge mu� im stream 4-Byte betragen
+ Seek( nObjPos - sizeof( UINT32 ) );
+ // Laenge schreiben
+ *this << nLen;
+ Seek( nPos );
+}
+
+//=========================================================================
+UINT32 SvPersistStream::ReadLen
+(
+ UINT32 * pTestPos /* Die Position des Streams, nach dem Lesen der
+ L"ange, wird zur"uckgegeben. Es darf auch NULL
+ "ubergeben werden. */
+)
+/* [Beschreibung]
+
+ Liest die L"ange die vorher mit <SvPersistStream::WriteDummyLen>
+ und <SvPersistStream::WriteLen> geschrieben wurde.
+*/
+{
+ UINT32 nLen;
+ *this >> nLen;
+ if( pTestPos )
+ *pTestPos = Tell();
+ return nLen;
+}
+
+//=========================================================================
+// Dateirormat abw"arts kompatibel
+#ifdef STOR_NO_OPTIMIZE
+#define P_VER (BYTE)0x00
+#else
+#define P_VER (BYTE)0x01
+#endif
+#define P_VER_MASK (BYTE)0x0F
+#define P_ID_0 (BYTE)0x80
+#define P_OBJ (BYTE)0x40
+#define P_DBGUTIL (BYTE)0x20
+#define P_ID (BYTE)0x10
+#ifdef STOR_NO_OPTIMIZE
+#define P_STD P_DBGUTIL
+#else
+#define P_STD 0
+#endif
+
+static void WriteId
+(
+ SvStream & rStm,
+ BYTE nHdr,
+ UINT32 nId,
+ USHORT nClassId
+)
+{
+#ifdef STOR_NO_OPTIMIZE
+ nHdr |= P_ID;
+#endif
+ nHdr |= P_VER;
+ if( nHdr & P_ID )
+ {
+ if( (nHdr & P_OBJ) || nId != 0 )
+ { // Id nur bei Zeiger, oder DBGUTIL
+ rStm << (BYTE)(nHdr);
+ SvPersistStream::WriteCompressed( rStm, nId );
+ }
+ else
+ { // NULL Pointer
+ rStm << (BYTE)(nHdr | P_ID_0);
+ return;
+ }
+ }
+ else
+ rStm << nHdr;
+
+ if( (nHdr & P_DBGUTIL) || (nHdr & P_OBJ) )
+ // Objekte haben immer eine Klasse,
+ // Pointer nur bei DBG_UTIL und != NULL
+ SvPersistStream::WriteCompressed( rStm, nClassId );
+}
+
+//=========================================================================
+static void ReadId
+(
+ SvStream & rStm,
+ BYTE & nHdr,
+ UINT32 & nId,
+ USHORT & nClassId
+)
+{
+ nClassId = 0;
+ rStm >> nHdr;
+ if( nHdr & P_ID_0 )
+ nId = 0;
+ else
+ {
+ if( (nHdr & P_VER_MASK) == 0 )
+ {
+ if( (nHdr & P_DBGUTIL) || !(nHdr & P_OBJ) )
+ nId = SvPersistStream::ReadCompressed( rStm );
+ else
+ nId = 0;
+ }
+ else if( nHdr & P_ID )
+ nId = SvPersistStream::ReadCompressed( rStm );
+
+ if( (nHdr & P_DBGUTIL) || (nHdr & P_OBJ) )
+ nClassId = (USHORT)SvPersistStream::ReadCompressed( rStm );
+ }
+}
+
+//=========================================================================
+void SvPersistStream::WriteObj
+(
+ BYTE nHdr,
+ SvPersistBase * pObj
+)
+{
+#ifdef STOR_NO_OPTIMIZE
+ UINT32 nObjPos = 0;
+ if( nHdr & P_DBGUTIL )
+ // Position fuer Laenge merken
+ nObjPos = WriteDummyLen();
+#endif
+ pObj->Save( *this );
+#ifdef STOR_NO_OPTIMIZE
+ if( nHdr & P_DBGUTIL )
+ WriteLen( nObjPos );
+#endif
+}
+
+//=========================================================================
+SvPersistStream& SvPersistStream::WritePointer
+(
+ SvPersistBase * pObj
+)
+{
+ BYTE nP = P_STD;
+
+ if( pObj )
+ {
+ ULONG nId = GetIndex( pObj );
+ if( nId )
+ nP |= P_ID;
+ else
+ {
+ nId = aPUIdx.Insert( pObj );
+ aPTable.Insert( (ULONG)pObj, (void *)nId );
+ nP |= P_OBJ;
+ }
+ WriteId( *this, nP, nId, pObj->GetClassId() );
+ if( nP & P_OBJ )
+ WriteObj( nP, pObj );
+ }
+ else
+ { // NULL Pointer
+ WriteId( *this, nP | P_ID, 0, 0 );
+ }
+ return *this;
+}
+
+//=========================================================================
+UINT32 SvPersistStream::ReadObj
+(
+ SvPersistBase * & rpObj,
+ BOOL bRegister
+)
+{
+ BYTE nHdr;
+ UINT32 nId = 0;
+ USHORT nClassId;
+
+ rpObj = NULL; // Spezifikation: Im Fehlerfall 0.
+ ReadId( *this, nHdr, nId, nClassId );
+
+ // reine Versionsnummer durch maskieren
+ if( P_VER < (nHdr & P_VER_MASK) )
+ {
+ SetError( SVSTREAM_FILEFORMAT_ERROR );
+ DBG_ERROR( "false version" );
+ }
+
+ if( !(nHdr & P_ID_0) && GetError() == SVSTREAM_OK )
+ {
+ if( P_OBJ & nHdr )
+ { // read object, nId nur bei P_DBGUTIL gesetzt
+ DBG_ASSERT( !(nHdr & P_DBGUTIL) || NULL == aPUIdx.Get( nId ),
+ "object already exist" );
+ SvCreateInstancePersist pFunc = rClassMgr.Get( nClassId );
+
+ UINT32 nObjLen(0), nObjPos(0);
+ if( nHdr & P_DBGUTIL )
+ nObjLen = ReadLen( &nObjPos );
+ if( !pFunc )
+ {
+#ifdef DBG_UTIL
+ ByteString aStr( "no class with id: " );
+ aStr += ByteString::CreateFromInt32( nClassId );
+ aStr += " registered";
+ DBG_WARNING( aStr.GetBuffer() );
+#endif
+ SetError( ERRCODE_IO_NOFACTORY );
+ return 0;
+ }
+ pFunc( &rpObj );
+ // Sichern
+ rpObj->AddRef();
+
+ if( bRegister )
+ {
+ // unbedingt erst in Tabelle eintragen
+ ULONG nNewId = aPUIdx.Insert( rpObj );
+ // um den gleichen Zustand, wie nach dem Speichern herzustellen
+ aPTable.Insert( (ULONG)rpObj, (void *)nNewId );
+ DBG_ASSERT( !(nHdr & P_DBGUTIL) || nId == nNewId,
+ "read write id conflict: not the same" );
+ }
+ // und dann Laden
+ rpObj->Load( *this );
+#ifdef DBG_UTIL
+ if( nObjLen + nObjPos != Tell() )
+ {
+ ByteString aStr( "false object len: read = " );
+ aStr += ByteString::CreateFromInt32( (long)(Tell() - nObjPos) );
+ aStr += ", should = ";
+ aStr += ByteString::CreateFromInt32( nObjLen );
+ DBG_ERROR( aStr.GetBuffer() );
+ }
+#endif
+ rpObj->RestoreNoDelete();
+ rpObj->ReleaseRef();
+ }
+ else
+ {
+ rpObj = GetObject( nId );
+ DBG_ASSERT( rpObj != NULL, "object does not exist" );
+ DBG_ASSERT( rpObj->GetClassId() == nClassId, "class mismatch" );
+ }
+ }
+ return nId;
+}
+
+//=========================================================================
+SvPersistStream& SvPersistStream::ReadPointer
+(
+ SvPersistBase * & rpObj
+)
+{
+ ReadObj( rpObj, TRUE );
+ return *this;
+}
+
+//=========================================================================
+SvPersistStream& operator <<
+(
+ SvPersistStream & rStm,
+ SvPersistBase * pObj
+)
+{
+ return rStm.WritePointer( pObj );
+}
+
+//=========================================================================
+SvPersistStream& operator >>
+(
+ SvPersistStream & rStm,
+ SvPersistBase * & rpObj
+)
+{
+ return rStm.ReadPointer( rpObj );
+}
+
+//=========================================================================
+SvStream& operator <<
+(
+ SvStream & rStm,
+ SvPersistStream & rThis
+)
+{
+ SvStream * pOldStm = rThis.GetStream();
+ rThis.SetStream( &rStm );
+
+ BYTE bTmp = 0;
+ rThis << bTmp; // Version
+ UINT32 nCount = (UINT32)rThis.aPUIdx.Count();
+ rThis << nCount;
+ SvPersistBase * pEle = rThis.aPUIdx.First();
+ for( UINT32 i = 0; i < nCount; i++ )
+ {
+ BYTE nP = P_OBJ | P_ID | P_STD;
+ WriteId( rThis, nP, rThis.aPUIdx.GetCurIndex(),
+ pEle->GetClassId() );
+ rThis.WriteObj( nP, pEle );
+ pEle = rThis.aPUIdx.Next();
+ }
+ rThis.SetStream( pOldStm );
+ return rStm;
+}
+
+//=========================================================================
+SvStream& operator >>
+(
+ SvStream & rStm,
+ SvPersistStream & rThis
+)
+{
+ SvStream * pOldStm = rThis.GetStream();
+ rThis.SetStream( &rStm );
+
+ BYTE nVers;
+ rThis >> nVers; // Version
+ if( 0 == nVers )
+ {
+ UINT32 nCount = 0;
+ rThis >> nCount;
+ for( UINT32 i = 0; i < nCount; i++ )
+ {
+ SvPersistBase * pEle;
+ // Lesen, ohne in die Tabellen einzutragen
+ UINT32 nId = rThis.ReadObj( pEle, FALSE );
+ if( rThis.GetError() )
+ break;
+
+ // Die Id eines Objektes wird nie modifiziert
+ rThis.aPUIdx.Insert( nId, pEle );
+ rThis.aPTable.Insert( (ULONG)pEle, (void *)nId );
+ }
+ }
+ else
+ rThis.SetError( SVSTREAM_FILEFORMAT_ERROR );
+
+ rThis.SetStream( pOldStm );
+ return rStm;
+}
+
+//=========================================================================
+ULONG SvPersistStream::InsertObj( SvPersistBase * pObj )
+{
+ ULONG nId = aPUIdx.Insert( pObj );
+ aPTable.Insert( (ULONG)pObj, (void *)nId );
+ return nId;
+}
+
+//=========================================================================
+ULONG SvPersistStream::RemoveObj( SvPersistBase * pObj )
+{
+ ULONG nIdx = GetIndex( pObj );
+ aPUIdx.Remove( nIdx );
+ aPTable.Remove( (ULONG)pObj );
+ return nIdx;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/ref/ref.cxx b/tools/source/ref/ref.cxx
new file mode 100644
index 000000000000..42ae49975a50
--- /dev/null
+++ b/tools/source/ref/ref.cxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <tools/ref.hxx>
+
+/****************** SvRefBaseMemberList **********************************/
+SV_IMPL_REF_LIST( SvRefBase,SvRefBase* )
+
+/**************************************************************************
+#* SvRefBase::~SvRefBase()
+**************************************************************************/
+SvRefBase::~SvRefBase()
+{
+}
+
+/**************************************************************************
+#* SvRefBase::QueryDelete()
+**************************************************************************/
+void SvRefBase::QueryDelete()
+{
+ nRefCount = SV_NO_DELETE_REFCOUNT / 2;
+ delete this;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/solar/makefile.mk b/tools/source/solar/makefile.mk
new file mode 100644
index 000000000000..6f5dd85c608b
--- /dev/null
+++ b/tools/source/solar/makefile.mk
@@ -0,0 +1,63 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=tools
+TARGET=mksvconf
+TARGETTYPE=CUI
+
+LIBSALCPPRT=$(0)
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+CFILES= solar.c
+
+OBJFILES= $(OBJ)$/solar.obj
+
+APP1TARGET= $(TARGET)
+APP1OBJS= $(OBJFILES)
+APP1STDLIBS=
+APP1DEPN=
+APP1DEF=
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.IF "$(L10N-framework)"==""
+ALLTAR : $(INCCOM)$/svconf.h
+.ENDIF # "$(L10N-framework)"==""
+
+$(INCCOM)$/svconf.h : $(BIN)$/$(TARGET)
+ $(BIN)$/$(TARGET) $@
+
diff --git a/tools/source/solar/solar.c b/tools/source/solar/solar.c
new file mode 100644
index 000000000000..1834ab033cab
--- /dev/null
+++ b/tools/source/solar/solar.c
@@ -0,0 +1,565 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/* POSIX defines that a program is undefined after a SIG_SEGV. The
+ * code stopped working on Linux Kernel 2.6 so I have moved this back to
+ * use FORK.
+ * If at a later time the signals work correctly with the Linux Kernel 2.6
+ * then this change may be reverted although not strictly posix safe. */
+#define USE_FORK_TO_CHECK 1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#define I_STDARG
+#ifdef I_STDARG
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#define NO_USE_FORK_TO_CHECK
+#ifdef USE_FORK_TO_CHECK
+#include <sys/wait.h>
+#else
+#include <signal.h>
+#include <setjmp.h>
+#endif
+
+#define printTypeSize(Type,Name) printf( "sizeof(%s)\t= %d\n", Name, sizeof (Type) )
+
+#define isSignedType(Type) (((Type)-1) < 0)
+#define printTypeSign(Type,Name) printf( "%s\t= %s %s\n", Name, ( isSignedType(Type) ? "signed" : "unsigned" ), Name )
+
+
+/*************************************************************************
+|*
+|* IsBigEndian()
+|*
+|* Beschreibung True, wenn CPU BigEndian ist
+|*
+|* Ersterstellung EG 26.06.96
+|* Letzte Aenderung
+|*
+*************************************************************************/
+int IsBigEndian()
+{
+ long l = 1;
+ return ! *(char*)&l;
+}
+
+/*************************************************************************
+|*
+|* IsStackGrowingDown()
+|*
+|* Beschreibung True, wenn der Stack nach unten waechst
+|*
+|* Ersterstellung EG 26.06.96
+|* Letzte Aenderung
+|*
+*************************************************************************/
+int IsStackGrowingDown_2( int * pI )
+{
+ int i = 1;
+ return ((unsigned long)&i) < (unsigned long)pI;
+}
+
+int IsStackGrowingDown()
+{
+ int i = 1;
+ return IsStackGrowingDown_2(&i);
+}
+
+/*************************************************************************
+|*
+|* GetStackAlignment()
+|*
+|* Beschreibung Alignment von char Parametern, die (hoffentlich)
+|* ueber den Stack uebergeben werden
+|*
+|* Ersterstellung EG 26.06.96
+|* Letzte Aenderung
+|*
+*************************************************************************/
+int GetStackAlignment_3( char*p, long l, int i, short s, char b, char c, ... )
+{
+ if ( IsStackGrowingDown() )
+ return &c - &b;
+ else
+ return &b - &c;
+}
+
+int GetStackAlignment_2( char*p, long l, int i, short s, char b, char c )
+{
+ if ( IsStackGrowingDown() )
+ return &c - &b;
+ else
+ return &b - &c;
+}
+
+int GetStackAlignment()
+{
+ int nStackAlignment = GetStackAlignment_3(0,1,2,3,4,5);
+ if ( nStackAlignment != GetStackAlignment_2(0,1,2,3,4,5) )
+ printf( "Pascal calling convention\n" );
+ return nStackAlignment;
+}
+
+
+/*************************************************************************
+|*
+|* Typdeclarations for memory access test functions
+|*
+*************************************************************************/
+typedef enum { t_char, t_short, t_int, t_long, t_double } Type;
+typedef int (*TestFunc)( Type, void* );
+
+
+/*************************************************************************
+|*
+|* PrintArgs()
+|*
+|* Beschreibung Testfunktion fuer variable Parameter
+|*
+|* Ersterstellung EG 26.06.96
+|* Letzte Aenderung
+|*
+*************************************************************************/
+#ifdef I_STDARG
+void PrintArgs( int p, ... )
+#else
+void PrintArgs( p, va_alist )
+int p;
+va_dcl
+#endif
+{
+ int value;
+ va_list ap;
+
+#ifdef I_STDARG
+ va_start( ap, p );
+#else
+ va_start( ap );
+#endif
+
+ printf( "value = %d", p );
+
+ while ( ( value = va_arg(ap, int) ) != 0 )
+ printf( " %d", value );
+
+ printf( "\n" );
+ va_end(ap);
+}
+
+#ifndef USE_FORK_TO_CHECK
+/*************************************************************************
+|*
+|* SignalHdl()
+|*
+|* Beschreibung faengt SIGBUS und SIGSEGV in check() ab
+|*
+|* Ersterstellung EG 26.06.96
+|* Letzte Aenderung
+|*
+*************************************************************************/
+static jmp_buf check_env;
+static int bSignal;
+void SignalHdl( int sig )
+{
+ bSignal = 1;
+
+ fprintf( stderr, "Signal %d caught\n", sig );
+ signal( SIGSEGV, SIG_DFL );
+ signal( SIGBUS, SIG_DFL );
+ siglongjmp( check_env, sig );
+}
+#endif
+
+/*************************************************************************
+|*
+|* check()
+|*
+|* Beschreibung Testet MemoryZugriff (read/write)
+|*
+|* Ersterstellung EG 26.06.96
+|* Letzte Aenderung
+|*
+*************************************************************************/
+int check( TestFunc func, Type eT, void* p )
+{
+#ifdef USE_FORK_TO_CHECK
+ pid_t nChild = fork();
+ if ( nChild )
+ {
+ int exitVal;
+ wait( &exitVal );
+ if ( exitVal & 0xff )
+ return -1;
+ else
+ return exitVal >> 8;
+ }
+ else
+ {
+ exit( func( eT, p ) );
+ }
+#else
+ int result;
+
+ bSignal = 0;
+
+ if ( !sigsetjmp( check_env, 1 ) )
+ {
+ signal( SIGSEGV, SignalHdl );
+ signal( SIGBUS, SignalHdl );
+ result = func( eT, p );
+ signal( SIGSEGV, SIG_DFL );
+ signal( SIGBUS, SIG_DFL );
+ }
+
+ if ( bSignal )
+ return -1;
+ else
+ return 0;
+#endif
+}
+
+/*************************************************************************
+|*
+|* GetAtAddress()
+|*
+|* Beschreibung memory read access
+|*
+|* Ersterstellung EG 26.06.96
+|* Letzte Aenderung
+|*
+*************************************************************************/
+int GetAtAddress( Type eT, void* p )
+{
+ switch ( eT )
+ {
+ case t_char: return *((char*)p);
+ case t_short: return *((short*)p);
+ case t_int: return *((int*)p);
+ case t_long: return *((long*)p);
+ case t_double: return *((double*)p);
+ }
+ abort();
+}
+
+/*************************************************************************
+|*
+|* SetAtAddress()
+|*
+|* Beschreibung memory write access
+|*
+|* Ersterstellung EG 26.06.96
+|* Letzte Aenderung
+|*
+*************************************************************************/
+int SetAtAddress( Type eT, void* p )
+{
+ switch ( eT )
+ {
+ case t_char: return *((char*)p) = 0;
+ case t_short: return *((short*)p) = 0;
+ case t_int: return *((int*)p) = 0;
+ case t_long: return *((long*)p) = 0;
+ case t_double: return *((double*)p)= 0;
+ }
+ abort();
+}
+
+char* TypeName( Type eT )
+{
+ switch ( eT )
+ {
+ case t_char: return "char";
+ case t_short: return "short";
+ case t_int: return "int";
+ case t_long: return "long";
+ case t_double: return "double";
+ }
+ abort();
+}
+
+/*************************************************************************
+|*
+|* Check(Get|Set)Access()
+|*
+|* Beschreibung Testet MemoryZugriff (read/write)
+|* Zugriffsverletzungen werden abgefangen
+|*
+|* Ersterstellung EG 26.06.96
+|* Letzte Aenderung
+|*
+*************************************************************************/
+int CheckGetAccess( Type eT, void* p )
+{
+ int b;
+ b = -1 != check( (TestFunc)GetAtAddress, eT, p );
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,
+ "%s read %s at %p\n",
+ (b? "can" : "can not" ), TypeName(eT), p );
+#endif
+ return b;
+}
+int CheckSetAccess( Type eT, void* p )
+{
+ int b;
+
+ b = -1 != check( (TestFunc)SetAtAddress, eT, p );
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,
+ "%s write %s at %p\n",
+ (b? "can" : "can not" ), TypeName(eT), p );
+#endif
+ return b;
+}
+
+/*************************************************************************
+|*
+|* GetAlignment()
+|*
+|* Beschreibung Bestimmt das Alignment verschiedener Typen
+|*
+|* Ersterstellung EG 26.06.96
+|* Letzte Aenderung
+|*
+*************************************************************************/
+int GetAlignment( Type eT )
+{
+ char a[ 16*8 ];
+ long p = (long)(void*)a;
+ int i;
+
+ /* clear a[...] to set legal value for double access */
+ for ( i = 0; i < 16*8; i++ )
+ a[i] = 0;
+
+ p = ( p + 0xF ) & ~0xF;
+ for ( i = 1; i < 16; i++ )
+ if ( CheckGetAccess( eT, (void*)(p+i) ) )
+ return i;
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* struct Description
+|*
+|* Beschreibung Beschreibt die Parameter der Architektur
+|*
+|* Ersterstellung EG 26.06.96
+|* Letzte Aenderung
+|*
+*************************************************************************/
+struct Description
+{
+ int bBigEndian;
+ int bStackGrowsDown;
+ int nStackAlignment;
+ int nAlignment[3]; /* 2,4,8 */
+};
+
+/*************************************************************************
+|*
+|* Description_Ctor()
+|*
+|* Beschreibung Bestimmt die Parameter der Architektur
+|*
+|* Ersterstellung EG 26.06.96
+|* Letzte Aenderung
+|*
+*************************************************************************/
+void Description_Ctor( struct Description* pThis )
+{
+ pThis->bBigEndian = IsBigEndian();
+ pThis->bStackGrowsDown = IsStackGrowingDown();
+ pThis->nStackAlignment = GetStackAlignment();
+
+ if ( sizeof(short) != 2 )
+ abort();
+ pThis->nAlignment[0] = GetAlignment( t_short );
+ if ( sizeof(int) != 4 )
+ abort();
+ pThis->nAlignment[1] = GetAlignment( t_int );
+
+ if ( sizeof(long) == 8 )
+ pThis->nAlignment[2] = GetAlignment( t_long );
+ else if ( sizeof(double) == 8 )
+ pThis->nAlignment[2] = GetAlignment( t_double );
+ else
+ abort();
+}
+
+/*************************************************************************
+|*
+|* Description_Print()
+|*
+|* Beschreibung Schreibt die Parameter der Architektur als Header
+|*
+|* Ersterstellung EG 26.06.96
+|* Letzte Aenderung
+|*
+*************************************************************************/
+void Description_Print( struct Description* pThis, char* name )
+{
+ int i;
+ FILE* f = fopen( name, "w" );
+ if( ! f ) {
+ fprintf( stderr, "Unable to open file %s: %s\n", name, strerror( errno ) );
+ exit( 99 );
+ }
+ fprintf( f, "#define __%s\n",
+ pThis->bBigEndian ? "BIGENDIAN" : "LITTLEENDIAN" );
+ for ( i = 0; i < 3; i++ )
+ fprintf( f, "#define __ALIGNMENT%d\t%d\n",
+ 1 << (i+1), pThis->nAlignment[i] );
+ fprintf( f, "/* Stack alignment is not used... */\n" );
+ fprintf( f, "#define __STACKALIGNMENT\t%d\n", pThis->nStackAlignment );
+ fprintf( f, "#define __STACKDIRECTION\t%d\n",
+ pThis->bStackGrowsDown ? -1 : 1 );
+ fprintf( f, "#define __SIZEOFCHAR\t%d\n", sizeof( char ) );
+ fprintf( f, "#define __SIZEOFSHORT\t%d\n", sizeof( short ) );
+ fprintf( f, "#define __SIZEOFINT\t%d\n", sizeof( int ) );
+ fprintf( f, "#define __SIZEOFLONG\t%d\n", sizeof( long ) );
+ fprintf( f, "#define __SIZEOFPOINTER\t%d\n", sizeof( void* ) );
+ fprintf( f, "#define __SIZEOFDOUBLE\t%d\n", sizeof( double ) );
+ fprintf( f, "#define __IEEEDOUBLE\n" );
+ fclose( f );
+}
+
+/*************************************************************************
+|*
+|* InfoMemoryAccess()
+|*
+|* Beschreibung Informeller Bytezugriffstest
+|*
+|* Ersterstellung EG 26.06.96
+|* Letzte Aenderung
+|*
+*************************************************************************/
+void InfoMemoryAccess( char* p )
+{
+ if ( CheckGetAccess( t_char, p ) )
+ printf( "can read address %p\n", p );
+ else
+ printf( "can not read address %p\n", p );
+
+ if ( CheckSetAccess( t_char, p ) )
+ printf( "can write address %p\n", p );
+ else
+ printf( "can not write address %p\n", p );
+}
+
+/*************************************************************************
+|*
+|* InfoMemoryTypeAccess()
+|*
+|* Beschreibung Informeller Zugriffstest verschiedener Typen
+|*
+|* Ersterstellung EG 15.08.96
+|* Letzte Aenderung
+|*
+*************************************************************************/
+void InfoMemoryTypeAccess( Type eT )
+{
+ char a[64];
+ int i;
+
+ /* clear a[...] to set legal value for double access */
+ for ( i = 0; i < 64; i++ )
+ a[i] = 0;
+
+ for ( i = 56; i >= 7; i >>= 1 )
+ {
+ printf( "Zugriff %s auf %i-Aligned Adresse : ", TypeName( eT ), i / 7 );
+ printf( ( CheckGetAccess( eT, (long*)&a[i] ) ? "OK\n" : "ERROR\n" ) );
+ }
+}
+/************************************************************************
+ *
+ * Use C code to determine the characteristics of the building platform.
+ *
+ ************************************************************************/
+int main( int argc, char* argv[] )
+{
+ printTypeSign( char, "char" );
+ printTypeSign( short, "short" );
+ printTypeSign( int, "int" );
+ printTypeSign( long, "long" );
+
+ printTypeSize( char, "char" );
+ printTypeSize( short, "short" );
+ printTypeSize( int, "int" );
+ printTypeSize( long, "long" );
+ printTypeSize( float, "float" );
+ printTypeSize( double, "double" );
+ printTypeSize( void *, "void *" );
+
+ if ( IsBigEndian() )
+ printf( "BIGENDIAN (Sparc, MC680x0, RS6000, IP22, IP32, g3)\n" );
+ else
+ printf( "LITTLEENDIAN (Intel, VAX, PowerPC)\n" );
+
+ if( IsStackGrowingDown() )
+ printf( "Stack waechst nach unten\n" );
+ else
+ printf( "Stack waechst nach oben\n" );
+
+ printf( "STACKALIGNMENT : %d\n", GetStackAlignment() );
+
+ /* PrintArgs( 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 ); */
+
+ if ( argc > 1 )
+ {
+ struct Description description;
+ Description_Ctor( &description );
+ Description_Print( &description, argv[1] );
+ }
+ {
+ char* p = NULL;
+ InfoMemoryAccess( p );
+ p = (char*)&p;
+ InfoMemoryAccess( p );
+ InfoMemoryTypeAccess( t_short );
+ InfoMemoryTypeAccess( t_int );
+ InfoMemoryTypeAccess( t_long );
+ InfoMemoryTypeAccess( t_double );
+ }
+
+ exit( 0 );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/stream/cachestr.cxx b/tools/source/stream/cachestr.cxx
new file mode 100644
index 000000000000..5c5d4bc273a7
--- /dev/null
+++ b/tools/source/stream/cachestr.cxx
@@ -0,0 +1,293 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <tools/debug.hxx>
+#include <tools/stream.hxx>
+#include <tools/cachestr.hxx>
+#include <tools/tempfile.hxx>
+
+/*************************************************************************
+|*
+|* SvCacheStream::SvCacheStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 27.09.94
+|* Letzte Aenderung OV 27.09.94
+|*
+*************************************************************************/
+
+SvCacheStream::SvCacheStream( ULONG nMaxMemSize )
+{
+ if( !nMaxMemSize )
+ nMaxMemSize = 20480;
+ SvStream::bIsWritable = TRUE;
+ nMaxSize = nMaxMemSize;
+ bPersistent = FALSE;
+ pSwapStream = 0;
+ pCurrentStream = new SvMemoryStream( nMaxMemSize );
+ pTempFile = 0;
+}
+
+/*************************************************************************
+|*
+|* SvCacheStream::SvCacheStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 27.09.94
+|* Letzte Aenderung OV 27.09.94
+|*
+*************************************************************************/
+
+SvCacheStream::SvCacheStream( const String &rFileName,
+ ULONG nExpectedSize,
+ ULONG nMaxMemSize )
+{
+ if( !nMaxMemSize )
+ nMaxMemSize = 20480;
+
+ if( nExpectedSize > nMaxMemSize )
+ nExpectedSize = nMaxMemSize; // oder gleich in File schreiben
+ else if( !nExpectedSize )
+ nExpectedSize = 4096;
+
+ SvStream::bIsWritable = TRUE;
+ nMaxSize = nMaxMemSize;
+ bPersistent = TRUE;
+ aFileName = rFileName;
+ pSwapStream = 0;
+ pCurrentStream = new SvMemoryStream( nExpectedSize );
+ pTempFile = 0;
+}
+
+/*************************************************************************
+|*
+|* SvCacheStream::~SvCacheStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 27.09.94
+|* Letzte Aenderung OV 27.09.94
+|*
+*************************************************************************/
+
+SvCacheStream::~SvCacheStream()
+{
+ if( pCurrentStream != pSwapStream )
+ delete pSwapStream;
+ delete pCurrentStream;
+
+ if( pSwapStream && !bPersistent && pTempFile )
+ {
+ // temporaeres File loeschen
+ pTempFile->EnableKillingFile( TRUE );
+ }
+
+ delete pTempFile;
+}
+
+/*************************************************************************
+|*
+|* SvCacheStream::SwapOut()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 27.09.94
+|* Letzte Aenderung OV 27.09.94
+|*
+*************************************************************************/
+
+void SvCacheStream::SwapOut()
+{
+ if( pCurrentStream != pSwapStream )
+ {
+ if( !pSwapStream && !aFileName.Len() )
+ {
+ if (aFilenameLinkHdl.IsSet())
+ {
+ // pSwapStream wird zum Schutz gegen Reentranz genutzt
+ pSwapStream = pCurrentStream;
+ Link aLink( aFilenameLinkHdl );
+ aFilenameLinkHdl = Link();
+ aLink.Call(this);
+ // pSwapStream nur zuruecksetzen, wenn nicht ueber
+ // SetSwapStream geaendert
+ if( pSwapStream == pCurrentStream ) pSwapStream = 0;
+ }
+ else
+ {
+ pTempFile = new TempFile;
+ aFileName = pTempFile->GetName();
+ }
+ }
+
+ ULONG nPos = pCurrentStream->Tell();
+ pCurrentStream->Seek( 0 );
+ if( !pSwapStream )
+ pSwapStream = new SvFileStream( aFileName, STREAM_READWRITE | STREAM_TRUNC );
+ *pSwapStream << *pCurrentStream;
+ pSwapStream->Flush();
+ delete pCurrentStream;
+ pCurrentStream = pSwapStream;
+ pCurrentStream->Seek( nPos );
+ }
+}
+
+/*************************************************************************
+|*
+|* SvCacheStream::GetData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 27.09.94
+|* Letzte Aenderung OV 27.09.94
+|*
+*************************************************************************/
+
+ULONG SvCacheStream::GetData( void* pData, ULONG nSize )
+{
+ return pCurrentStream->Read( pData, nSize );
+}
+
+/*************************************************************************
+|*
+|* SvCacheStream::PutData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 27.09.94
+|* Letzte Aenderung OV 27.09.94
+|*
+*************************************************************************/
+
+ULONG SvCacheStream::PutData( const void* pData, ULONG nSize )
+{
+ // lieber unnoetig auslagern als unnoetig umkopieren
+ if( pCurrentStream != pSwapStream
+ && pCurrentStream->Tell() + nSize > nMaxSize )
+ SwapOut();
+ return pCurrentStream->Write( pData, nSize );
+}
+
+/*************************************************************************
+|*
+|* SvCacheStream::SeekPos()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 27.09.94
+|* Letzte Aenderung OV 27.09.94
+|*
+*************************************************************************/
+
+ULONG SvCacheStream::SeekPos( ULONG nPos )
+{
+ return pCurrentStream->Seek( nPos );
+}
+
+/*************************************************************************
+|*
+|* SvCacheStream::FlushData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 27.09.94
+|* Letzte Aenderung OV 27.09.94
+|*
+*************************************************************************/
+
+void SvCacheStream::FlushData()
+{
+ pCurrentStream->Flush();
+ if( pCurrentStream != pSwapStream
+ && ((SvMemoryStream*)pCurrentStream)->GetSize() > nMaxSize )
+ SwapOut();
+}
+
+/*************************************************************************
+|*
+|* SvCacheStream::GetStr()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 27.09.94
+|* Letzte Aenderung OV 27.09.94
+|*
+*************************************************************************/
+
+const void* SvCacheStream::GetBuffer()
+{
+ Flush();
+ if( pCurrentStream != pSwapStream )
+ return ((SvMemoryStream*)pCurrentStream)->GetData();
+ else
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* SvCacheStream::SetSize()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 27.09.94
+|* Letzte Aenderung OV 27.09.94
+|*
+*************************************************************************/
+
+void SvCacheStream::SetSize( ULONG nSize )
+{
+ pCurrentStream->SetStreamSize( nSize );
+}
+
+/*************************************************************************
+|*
+|* SvCacheStream::GetSize()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 27.09.94
+|* Letzte Aenderung OV 27.09.94
+|*
+*************************************************************************/
+
+ULONG SvCacheStream::GetSize()
+{
+ // ACHTUNG: SvMemoryStream::GetSize() gibt Groesse
+ // des allozierten Buffers zurueck
+ Flush();
+ ULONG nTemp = Tell();
+ ULONG nLength = Seek( STREAM_SEEK_TO_END );
+ Seek( nTemp );
+ return nLength;
+}
+
+void SvCacheStream::SetFilenameHdl( const Link& rLink)
+{
+ aFilenameLinkHdl = rLink;
+}
+
+const Link& SvCacheStream::GetFilenameHdl() const
+{
+ return aFilenameLinkHdl;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/stream/makefile.mk b/tools/source/stream/makefile.mk
new file mode 100644
index 000000000000..ee548934c6c6
--- /dev/null
+++ b/tools/source/stream/makefile.mk
@@ -0,0 +1,58 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=tools
+TARGET=stream
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/stream.obj \
+ $(SLO)$/strmsys.obj \
+ $(SLO)$/cachestr.obj \
+ $(SLO)$/vcompat.obj
+
+OBJFILES+= $(OBJ)$/stream.obj \
+ $(OBJ)$/strmsys.obj \
+ $(OBJ)$/cachestr.obj \
+ $(OBJ)$/vcompat.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/strmsys.obj : \
+ strmwnt.cxx \
+ strmos2.cxx \
+ strmunx.cxx
+
diff --git a/tools/source/stream/stream.cxx b/tools/source/stream/stream.cxx
new file mode 100644
index 000000000000..0b13c3e567a0
--- /dev/null
+++ b/tools/source/stream/stream.cxx
@@ -0,0 +1,2859 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+// ToDo:
+// - Read->RefreshBuffer->Auf Aenderungen von nBufActualLen reagieren
+
+#include <cstddef>
+
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h> // isspace
+#include <stdlib.h> // strtol, _crotl
+
+#include "boost/static_assert.hpp"
+
+/*
+#if defined( DBG_UTIL ) && (OSL_DEBUG_LEVEL > 1)
+// prueft Synchronisation des Buffers nach allen Read, Write, Seek
+#define OV_DEBUG
+#endif
+*/
+
+#include <tools/solar.h>
+
+#if defined(BLC)
+#define SWAPNIBBLES(c) c=_crotl(c,4);
+#else
+#define SWAPNIBBLES(c) \
+unsigned char nSwapTmp=c; \
+nSwapTmp <<= 4; \
+c >>= 4; \
+c |= nSwapTmp;
+#endif
+
+#include <tools/debug.hxx>
+#define ENABLE_BYTESTRING_STREAM_OPERATORS
+#include <tools/stream.hxx>
+#include <osl/thread.h>
+#include <algorithm>
+
+// -----------------------------------------------------------------------
+
+DBG_NAME( Stream )
+
+// -----------------------------------------------------------------------
+
+// sprintf Param-Mode
+#define SPECIAL_PARAM_NONE 0 // Format-Str, Number
+#define SPECIAL_PARAM_WIDTH 1 // Format-Str, Width, Number
+#define SPECIAL_PARAM_PRECISION 2 // Format-Str, Precision, Number
+#define SPECIAL_PARAM_BOTH 3 // Format-Str, Width, Precision, Number
+
+// -----------------------------------------------------------------------
+
+// !!! Nicht inline, wenn Operatoren <<,>> inline sind
+inline static void SwapUShort( sal_uInt16& r )
+ { r = SWAPSHORT(r); }
+inline static void SwapShort( short& r )
+ { r = SWAPSHORT(r); }
+inline static void SwapLong( long& r )
+ { r = SWAPLONG(r); }
+inline static void SwapULong( sal_uInt32& r )
+ { r = SWAPLONG(r); }
+inline static void SwapLongInt( int& r )
+ { r = SWAPLONG(r); }
+inline static void SwapLongUInt( unsigned int& r )
+ { r = SWAPLONG(r); }
+#ifdef UNX
+inline static void SwapFloat( float& r )
+ {
+ union
+ {
+ float f;
+ sal_uInt32 c;
+ } s;
+
+ s.f = r;
+ s.c = SWAPLONG( s.c );
+ r = s.f;
+ }
+inline static void SwapDouble( double& r )
+ {
+ if( sizeof(double) != 8 )
+ {
+ DBG_ASSERT( FALSE, "Can only swap 8-Byte-doubles\n" );
+ }
+ else
+ {
+ union
+ {
+ double d;
+ sal_uInt32 c[2];
+ } s;
+
+ s.d = r;
+ s.c[0] ^= s.c[1]; // zwei 32-Bit-Werte in situ vertauschen
+ s.c[1] ^= s.c[0];
+ s.c[0] ^= s.c[1];
+ s.c[0] = SWAPLONG(s.c[0]); // und die beiden 32-Bit-Werte selbst in situ drehen
+ s.c[1] = SWAPLONG(s.c[1]);
+ r = s.d;
+ }
+ }
+#endif
+
+//SDO
+
+#define READNUMBER_WITHOUT_SWAP(datatype,value) \
+{\
+int tmp = eIOMode; \
+if( (tmp == STREAM_IO_READ) && sizeof(datatype)<=nBufFree) \
+{\
+ for (std::size_t i = 0; i < sizeof(datatype); i++)\
+ ((char *)&value)[i] = pBufPos[i];\
+ nBufActualPos += sizeof(datatype);\
+ pBufPos += sizeof(datatype);\
+ nBufFree -= sizeof(datatype);\
+}\
+else\
+ Read( (char*)&value, sizeof(datatype) );\
+}
+
+#define WRITENUMBER_WITHOUT_SWAP(datatype,value) \
+{\
+int tmp = eIOMode; \
+if( (tmp==STREAM_IO_WRITE) && sizeof(datatype) <= nBufFree)\
+{\
+ for (std::size_t i = 0; i < sizeof(datatype); i++)\
+ pBufPos[i] = ((char *)&value)[i];\
+ nBufFree -= sizeof(datatype);\
+ nBufActualPos += sizeof(datatype);\
+ if( nBufActualPos > nBufActualLen )\
+ nBufActualLen = nBufActualPos;\
+ pBufPos += sizeof(datatype);\
+ bIsDirty = TRUE;\
+}\
+else\
+ Write( (char*)&value, sizeof(datatype) );\
+}
+
+//============================================================================
+//
+// class SvLockBytes
+//
+//============================================================================
+
+void SvLockBytes::close()
+{
+ if (m_bOwner)
+ delete m_pStream;
+ m_pStream = 0;
+}
+
+//============================================================================
+TYPEINIT0(SvLockBytes);
+
+//============================================================================
+// virtual
+ErrCode SvLockBytes::ReadAt(sal_Size nPos, void * pBuffer, sal_Size nCount,
+ sal_Size * pRead) const
+{
+ if (!m_pStream)
+ {
+ DBG_ERROR("SvLockBytes::ReadAt(): Bad stream");
+ return ERRCODE_NONE;
+ }
+
+ m_pStream->Seek(nPos);
+ sal_Size nTheRead = m_pStream->Read(pBuffer, nCount);
+ if (pRead)
+ *pRead = nTheRead;
+ return m_pStream->GetErrorCode();
+}
+
+//============================================================================
+// virtual
+ErrCode SvLockBytes::WriteAt(sal_Size nPos, const void * pBuffer, sal_Size nCount,
+ sal_Size * pWritten)
+{
+ if (!m_pStream)
+ {
+ DBG_ERROR("SvLockBytes::WriteAt(): Bad stream");
+ return ERRCODE_NONE;
+ }
+
+ m_pStream->Seek(nPos);
+ sal_Size nTheWritten = m_pStream->Write(pBuffer, nCount);
+ if (pWritten)
+ *pWritten = nTheWritten;
+ return m_pStream->GetErrorCode();
+}
+
+//============================================================================
+// virtual
+ErrCode SvLockBytes::Flush() const
+{
+ if (!m_pStream)
+ {
+ DBG_ERROR("SvLockBytes::Flush(): Bad stream");
+ return ERRCODE_NONE;
+ }
+
+ m_pStream->Flush();
+ return m_pStream->GetErrorCode();
+}
+
+//============================================================================
+// virtual
+ErrCode SvLockBytes::SetSize(sal_Size nSize)
+{
+ if (!m_pStream)
+ {
+ DBG_ERROR("SvLockBytes::SetSize(): Bad stream");
+ return ERRCODE_NONE;
+ }
+
+ m_pStream->SetStreamSize(nSize);
+ return m_pStream->GetErrorCode();
+}
+
+//============================================================================
+ErrCode SvLockBytes::LockRegion(sal_Size, sal_Size, LockType)
+{
+ DBG_ERROR("SvLockBytes::LockRegion(): Not implemented");
+ return ERRCODE_NONE;
+}
+
+//============================================================================
+
+ErrCode SvLockBytes::UnlockRegion(sal_Size, sal_Size, LockType)
+{
+ DBG_ERROR("SvLockBytes::UnlockRegion(): Not implemented");
+ return ERRCODE_NONE;
+}
+
+//============================================================================
+ErrCode SvLockBytes::Stat(SvLockBytesStat * pStat, SvLockBytesStatFlag) const
+{
+ if (!m_pStream)
+ {
+ DBG_ERROR("SvLockBytes::Stat(): Bad stream");
+ return ERRCODE_NONE;
+ }
+
+ if (pStat)
+ {
+ sal_Size nPos = m_pStream->Tell();
+ pStat->nSize = m_pStream->Seek(STREAM_SEEK_TO_END);
+ m_pStream->Seek(nPos);
+ }
+ return ERRCODE_NONE;
+}
+
+//============================================================================
+//
+// class SvOpenLockBytes
+//
+//============================================================================
+
+TYPEINIT1(SvOpenLockBytes, SvLockBytes);
+
+//============================================================================
+//
+// class SvAsyncLockBytes
+//
+//============================================================================
+
+TYPEINIT1(SvAsyncLockBytes, SvOpenLockBytes);
+
+//============================================================================
+// virtual
+ErrCode SvAsyncLockBytes::ReadAt(sal_Size nPos, void * pBuffer, sal_Size nCount,
+ sal_Size * pRead) const
+{
+ if (m_bTerminated)
+ return SvOpenLockBytes::ReadAt(nPos, pBuffer, nCount, pRead);
+ else
+ {
+ sal_Size nTheCount = std::min(nPos < m_nSize ? m_nSize - nPos : 0, nCount);
+ ErrCode nError = SvOpenLockBytes::ReadAt(nPos, pBuffer, nTheCount,
+ pRead);
+ return !nCount || nTheCount == nCount || nError ? nError :
+ ERRCODE_IO_PENDING;
+ }
+}
+
+//============================================================================
+// virtual
+ErrCode SvAsyncLockBytes::WriteAt(sal_Size nPos, const void * pBuffer,
+ sal_Size nCount, sal_Size * pWritten)
+{
+ if (m_bTerminated)
+ return SvOpenLockBytes::WriteAt(nPos, pBuffer, nCount, pWritten);
+ else
+ {
+ sal_Size nTheCount = std::min(nPos < m_nSize ? m_nSize - nPos : 0, nCount);
+ ErrCode nError = SvOpenLockBytes::WriteAt(nPos, pBuffer, nTheCount,
+ pWritten);
+ return !nCount || nTheCount == nCount || nError ? nError :
+ ERRCODE_IO_PENDING;
+ }
+}
+
+//============================================================================
+// virtual
+ErrCode SvAsyncLockBytes::FillAppend(const void * pBuffer, sal_Size nCount,
+ sal_Size * pWritten)
+{
+ sal_Size nTheWritten;
+ ErrCode nError = SvOpenLockBytes::WriteAt(m_nSize, pBuffer, nCount,
+ &nTheWritten);
+ if (!nError)
+ m_nSize += nTheWritten;
+ if (pWritten)
+ *pWritten = nTheWritten;
+ return nError;
+}
+
+//============================================================================
+// virtual
+sal_Size SvAsyncLockBytes::Seek(sal_Size nPos)
+{
+ if (nPos != STREAM_SEEK_TO_END)
+ m_nSize = nPos;
+ return m_nSize;
+}
+
+//============================================================================
+//
+// class SvStream
+//
+//============================================================================
+
+sal_Size SvStream::GetData( void* pData, sal_Size nSize )
+{
+ if( !GetError() )
+ {
+ DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
+ sal_Size nRet;
+ nError = xLockBytes->ReadAt( nActPos, pData, nSize, &nRet );
+ nActPos += nRet;
+ return nRet;
+ }
+ else return 0;
+}
+
+ErrCode SvStream::SetLockBytes( SvLockBytesRef& rLB )
+{
+ xLockBytes = rLB;
+ RefreshBuffer();
+ return ERRCODE_NONE;
+}
+
+//========================================================================
+
+sal_Size SvStream::PutData( const void* pData, sal_Size nSize )
+{
+ if( !GetError() )
+ {
+ DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
+ sal_Size nRet;
+ nError = xLockBytes->WriteAt( nActPos, pData, nSize, &nRet );
+ nActPos += nRet;
+ return nRet;
+ }
+ else return 0;
+}
+
+//========================================================================
+
+sal_Size SvStream::SeekPos( sal_Size nPos )
+{
+ if( !GetError() && nPos == STREAM_SEEK_TO_END )
+ {
+ DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
+ SvLockBytesStat aStat;
+ xLockBytes->Stat( &aStat, SVSTATFLAG_DEFAULT );
+ nActPos = aStat.nSize;
+ }
+ else
+ nActPos = nPos;
+ return nActPos;
+}
+
+//========================================================================
+
+void SvStream::FlushData()
+{
+ if( !GetError() )
+ {
+ DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
+ nError = xLockBytes->Flush();
+ }
+}
+
+//========================================================================
+
+void SvStream::SetSize( sal_Size nSize )
+{
+ DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
+ nError = xLockBytes->SetSize( nSize );
+}
+
+void SvStream::ImpInit()
+{
+ nActPos = 0;
+ nCompressMode = COMPRESSMODE_NONE;
+ eStreamCharSet = osl_getThreadTextEncoding();
+// eTargetCharSet = osl_getThreadTextEncoding();
+ nCryptMask = 0;
+ bIsEof = FALSE;
+#if defined UNX
+ eLineDelimiter = LINEEND_LF; // UNIX-Format
+#else
+ eLineDelimiter = LINEEND_CRLF; // DOS-Format
+#endif
+
+ SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ nBufFilePos = 0;
+ nBufActualPos = 0;
+ bIsDirty = FALSE;
+ bIsConsistent = TRUE;
+ bIsWritable = TRUE;
+
+ pRWBuf = 0;
+ pBufPos = 0;
+ nBufSize = 0;
+ nBufActualLen = 0;
+ eIOMode = STREAM_IO_DONTKNOW;
+ nBufFree = 0;
+
+ nRadix = 10;
+ nPrecision = 0; // all significant digits
+ nWidth = 0; // default width
+ cFiller = ' ';
+ nJustification = JUSTIFY_RIGHT;
+ eStreamMode = 0;
+ CreateFormatString();
+
+ nVersion = 0;
+
+ ClearError();
+}
+
+/*************************************************************************
+|*
+|* Stream::Stream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+SvStream::SvStream( SvLockBytes* pLockBytesP )
+{
+ DBG_CTOR( Stream, NULL );
+
+ ImpInit();
+ xLockBytes = pLockBytesP;
+ const SvStream* pStrm;
+ if( pLockBytesP ) {
+ pStrm = pLockBytesP->GetStream();
+ if( pStrm ) {
+ SetError( pStrm->GetErrorCode() );
+ }
+ }
+ SetBufferSize( 256 );
+}
+
+SvStream::SvStream()
+{
+ DBG_CTOR( Stream, NULL );
+
+ ImpInit();
+}
+
+/*************************************************************************
+|*
+|* Stream::~Stream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+SvStream::~SvStream()
+{
+ DBG_DTOR( Stream, NULL );
+
+ if ( xLockBytes.Is() )
+ Flush();
+
+ if( pRWBuf )
+ delete[] pRWBuf;
+}
+
+/*************************************************************************
+|*
+|* Stream::IsA()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_uInt16 SvStream::IsA() const
+{
+ return (sal_uInt16)ID_STREAM;
+}
+
+/*************************************************************************
+|*
+|* Stream::ClearError()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::ClearError()
+{
+ bIsEof = FALSE;
+ nError = SVSTREAM_OK;
+}
+
+/*************************************************************************
+|*
+|* Stream::SetError()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::SetError( sal_uInt32 nErrorCode )
+{
+ if ( nError == SVSTREAM_OK )
+ nError = nErrorCode;
+}
+
+
+/*************************************************************************
+|*
+|* Stream::SetNumberFormatInt()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::SetNumberFormatInt( sal_uInt16 nNewFormat )
+{
+ nNumberFormatInt = nNewFormat;
+ bSwap = FALSE;
+#ifdef OSL_BIGENDIAN
+ if( nNumberFormatInt == NUMBERFORMAT_INT_LITTLEENDIAN )
+ bSwap = TRUE;
+#else
+ if( nNumberFormatInt == NUMBERFORMAT_INT_BIGENDIAN )
+ bSwap = TRUE;
+#endif
+}
+
+/*************************************************************************
+|*
+|* Stream::SetBufferSize()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::SetBufferSize( sal_uInt16 nBufferSize )
+{
+ sal_Size nActualFilePos = Tell();
+ sal_Bool bDontSeek = (sal_Bool)(pRWBuf == 0);
+
+ if( bIsDirty && bIsConsistent && bIsWritable ) // wg. Windows NT: Access denied
+ Flush();
+
+ if( nBufSize )
+ {
+ delete[] pRWBuf;
+ nBufFilePos += nBufActualPos;
+ }
+
+ pRWBuf = 0;
+ nBufActualLen = 0;
+ nBufActualPos = 0;
+ nBufSize = nBufferSize;
+ if( nBufSize )
+ pRWBuf = new BYTE[ nBufSize ];
+ bIsConsistent = TRUE;
+ pBufPos = pRWBuf;
+ eIOMode = STREAM_IO_DONTKNOW;
+ if( !bDontSeek )
+ SeekPos( nActualFilePos );
+}
+
+/*************************************************************************
+|*
+|* Stream::ClearBuffer()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::ClearBuffer()
+{
+ nBufActualLen = 0;
+ nBufActualPos = 0;
+ nBufFilePos = 0;
+ pBufPos = pRWBuf;
+ bIsDirty = FALSE;
+ bIsConsistent = TRUE;
+ eIOMode = STREAM_IO_DONTKNOW;
+
+ bIsEof = FALSE;
+}
+
+/*************************************************************************
+|*
+|* Stream::ResetError()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::ResetError()
+{
+ ClearError();
+}
+
+/*************************************************************************
+|*
+|* Stream::ReadLine()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvStream::ReadByteStringLine( String& rStr, rtl_TextEncoding eSrcCharSet )
+{
+ sal_Bool bRet;
+ ByteString aStr;
+
+ bRet = ReadLine(aStr);
+ rStr = UniString( aStr, eSrcCharSet );
+ return bRet;
+}
+
+sal_Bool SvStream::ReadLine( ByteString& rStr )
+{
+ sal_Char buf[256+1];
+ sal_Bool bEnd = FALSE;
+ sal_Size nOldFilePos = Tell();
+ sal_Char c = 0;
+ sal_Size nTotalLen = 0;
+
+ rStr.Erase();
+ while( !bEnd && !GetError() ) // !!! nicht auf EOF testen,
+ // !!! weil wir blockweise
+ // !!! lesen
+ {
+ sal_uInt16 nLen = (sal_uInt16)Read( buf, sizeof(buf)-1 );
+ if ( !nLen )
+ {
+ if ( rStr.Len() == 0 )
+ {
+ // der allererste Blockread hat fehlgeschlagen -> Abflug
+ bIsEof = TRUE;
+ return FALSE;
+ }
+ else
+ break;
+ }
+
+ sal_uInt16 j, n;
+ for( j = n = 0; j < nLen ; ++j )
+ {
+ c = buf[j];
+ if ( c == '\n' || c == '\r' )
+ {
+ bEnd = TRUE;
+ break;
+ }
+ // erAck 26.02.01: Old behavior was no special treatment of '\0'
+ // character here, but a following rStr+=c did ignore it. Is this
+ // really intended? Or should a '\0' better terminate a line?
+ // The nOldFilePos stuff wasn't correct then anyways.
+ if ( c )
+ {
+ if ( n < j )
+ buf[n] = c;
+ ++n;
+ }
+ }
+ if ( n )
+ rStr.Append( buf, n );
+ nTotalLen += j;
+ }
+
+ if ( !bEnd && !GetError() && rStr.Len() )
+ bEnd = TRUE;
+
+ nOldFilePos += nTotalLen;
+ if( Tell() > nOldFilePos )
+ nOldFilePos++;
+ Seek( nOldFilePos ); // seeken wg. obigem BlockRead!
+
+ if ( bEnd && (c=='\r' || c=='\n') ) // Sonderbehandlung DOS-Dateien
+ {
+ char cTemp;
+ sal_Size nLen = Read((char*)&cTemp , sizeof(cTemp) );
+ if ( nLen ) {
+ if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
+ Seek( nOldFilePos );
+ }
+ }
+
+ if ( bEnd )
+ bIsEof = FALSE;
+ return bEnd;
+}
+
+sal_Bool SvStream::ReadUniStringLine( String& rStr )
+{
+ sal_Unicode buf[256+1];
+ sal_Bool bEnd = FALSE;
+ sal_Size nOldFilePos = Tell();
+ sal_Unicode c = 0;
+ sal_Size nTotalLen = 0;
+
+ DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "ReadUniStringLine: swapping sizeof(sal_Unicode) not implemented" );
+
+ rStr.Erase();
+ while( !bEnd && !GetError() ) // !!! nicht auf EOF testen,
+ // !!! weil wir blockweise
+ // !!! lesen
+ {
+ sal_uInt16 nLen = (sal_uInt16)Read( (char*)buf, sizeof(buf)-sizeof(sal_Unicode) );
+ nLen /= sizeof(sal_Unicode);
+ if ( !nLen )
+ {
+ if ( rStr.Len() == 0 )
+ {
+ // der allererste Blockread hat fehlgeschlagen -> Abflug
+ bIsEof = TRUE;
+ return FALSE;
+ }
+ else
+ break;
+ }
+
+ sal_uInt16 j, n;
+ for( j = n = 0; j < nLen ; ++j )
+ {
+ if ( bSwap )
+ SwapUShort( buf[n] );
+ c = buf[j];
+ if ( c == '\n' || c == '\r' )
+ {
+ bEnd = TRUE;
+ break;
+ }
+ // erAck 26.02.01: Old behavior was no special treatment of '\0'
+ // character here, but a following rStr+=c did ignore it. Is this
+ // really intended? Or should a '\0' better terminate a line?
+ // The nOldFilePos stuff wasn't correct then anyways.
+ if ( c )
+ {
+ if ( n < j )
+ buf[n] = c;
+ ++n;
+ }
+ }
+ if ( n )
+ rStr.Append( buf, n );
+ nTotalLen += j;
+ }
+
+ if ( !bEnd && !GetError() && rStr.Len() )
+ bEnd = TRUE;
+
+ nOldFilePos += nTotalLen * sizeof(sal_Unicode);
+ if( Tell() > nOldFilePos )
+ nOldFilePos += sizeof(sal_Unicode);
+ Seek( nOldFilePos ); // seeken wg. obigem BlockRead!
+
+ if ( bEnd && (c=='\r' || c=='\n') ) // Sonderbehandlung DOS-Dateien
+ {
+ sal_Unicode cTemp;
+ Read( (char*)&cTemp, sizeof(cTemp) );
+ if ( bSwap )
+ SwapUShort( cTemp );
+ if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
+ Seek( nOldFilePos );
+ }
+
+ if ( bEnd )
+ bIsEof = FALSE;
+ return bEnd;
+}
+
+sal_Bool SvStream::ReadUniOrByteStringLine( String& rStr, rtl_TextEncoding eSrcCharSet )
+{
+ if ( eSrcCharSet == RTL_TEXTENCODING_UNICODE )
+ return ReadUniStringLine( rStr );
+ else
+ return ReadByteStringLine( rStr, eSrcCharSet );
+}
+
+/*************************************************************************
+|*
+|* Stream::ReadCString
+|*
+*************************************************************************/
+
+sal_Bool SvStream::ReadCString( ByteString& rStr )
+{
+ if( rStr.Len() )
+ rStr.Erase();
+
+ sal_Char buf[ 256 + 1 ];
+ sal_Bool bEnd = FALSE;
+ sal_Size nFilePos = Tell();
+
+ while( !bEnd && !GetError() )
+ {
+ sal_uInt16 nLen = (sal_uInt16)Read( buf, sizeof(buf)-1 );
+ sal_uInt16 nReallyRead = nLen;
+ if( !nLen )
+ break;
+
+ const sal_Char* pPtr = buf;
+ while( *pPtr && nLen )
+ ++pPtr, --nLen;
+
+ bEnd = ( nReallyRead < sizeof(buf)-1 ) // read less than attempted to read
+ || ( ( nLen > 0 ) // OR it is inside the block we read
+ && ( 0 == *pPtr ) // AND found a string terminator
+ );
+
+ rStr.Append( buf, ::sal::static_int_cast< xub_StrLen >( pPtr - buf ) );
+ }
+
+ nFilePos += rStr.Len();
+ if( Tell() > nFilePos )
+ nFilePos++;
+ Seek( nFilePos ); // seeken wg. obigem BlockRead!
+ return bEnd;
+}
+
+sal_Bool SvStream::ReadCString( String& rStr, rtl_TextEncoding eToEncode )
+{
+ ByteString sStr;
+ sal_Bool bRet = ReadCString( sStr );
+ rStr = String( sStr, eToEncode );
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|* Stream::WriteUnicodeText()
+|*
+*************************************************************************/
+
+sal_Bool SvStream::WriteUnicodeText( const String& rStr )
+{
+ DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "WriteUnicodeText: swapping sizeof(sal_Unicode) not implemented" );
+ if ( bSwap )
+ {
+ xub_StrLen nLen = rStr.Len();
+ sal_Unicode aBuf[384];
+ sal_Unicode* const pTmp = ( nLen > 384 ? new sal_Unicode[nLen] : aBuf);
+ memcpy( pTmp, rStr.GetBuffer(), nLen * sizeof(sal_Unicode) );
+ sal_Unicode* p = pTmp;
+ const sal_Unicode* const pStop = pTmp + nLen;
+ while ( p < pStop )
+ {
+ SwapUShort( *p );
+ p++;
+ }
+ Write( (char*)pTmp, nLen * sizeof(sal_Unicode) );
+ if ( pTmp != aBuf )
+ delete [] pTmp;
+ }
+ else
+ Write( (char*)rStr.GetBuffer(), rStr.Len() * sizeof(sal_Unicode) );
+ return nError == SVSTREAM_OK;
+}
+
+sal_Bool SvStream::WriteUnicodeOrByteText( const String& rStr, rtl_TextEncoding eDestCharSet )
+{
+ if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
+ return WriteUnicodeText( rStr );
+ else
+ {
+ ByteString aStr( rStr, eDestCharSet );
+ Write( aStr.GetBuffer(), aStr.Len() );
+ return nError == SVSTREAM_OK;
+ }
+}
+
+/*************************************************************************
+|*
+|* Stream::WriteLine()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvStream::WriteByteStringLine( const String& rStr, rtl_TextEncoding eDestCharSet )
+{
+ return WriteLine( ByteString( rStr, eDestCharSet ) );
+}
+
+sal_Bool SvStream::WriteLine( const ByteString& rStr )
+{
+ Write( rStr.GetBuffer(), rStr.Len() );
+ endl(*this);
+ return nError == SVSTREAM_OK;
+}
+
+sal_Bool SvStream::WriteUniStringLine( const String& rStr )
+{
+ WriteUnicodeText( rStr );
+ endlu(*this);
+ return nError == SVSTREAM_OK;
+}
+
+sal_Bool SvStream::WriteUniOrByteStringLine( const String& rStr, rtl_TextEncoding eDestCharSet )
+{
+ if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
+ return WriteUniStringLine( rStr );
+ else
+ return WriteByteStringLine( rStr, eDestCharSet );
+}
+
+/*************************************************************************
+|*
+|* Stream::WriteLines()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 17.07.95
+|* Letzte Aenderung OV 17.07.95
+|*
+*************************************************************************/
+
+sal_Bool SvStream::WriteByteStringLines( const String& rStr, rtl_TextEncoding eDestCharSet )
+{
+ return WriteLines( ByteString( rStr, eDestCharSet ) );
+}
+
+sal_Bool SvStream::WriteLines( const ByteString& rStr )
+{
+ ByteString aStr( rStr );
+ aStr.ConvertLineEnd( eLineDelimiter );
+ Write( aStr.GetBuffer(), aStr.Len() );
+ endl( *this );
+ return (sal_Bool)(nError == SVSTREAM_OK);
+}
+
+sal_Bool SvStream::WriteUniStringLines( const String& rStr )
+{
+ String aStr( rStr );
+ aStr.ConvertLineEnd( eLineDelimiter );
+ WriteUniStringLine( aStr );
+ return nError == SVSTREAM_OK;
+}
+
+sal_Bool SvStream::WriteUniOrByteStringLines( const String& rStr, rtl_TextEncoding eDestCharSet )
+{
+ if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
+ return WriteUniStringLines( rStr );
+ else
+ return WriteByteStringLines( rStr, eDestCharSet );
+}
+
+/*************************************************************************
+|*
+|* Stream::WriteUniOrByteChar()
+|*
+*************************************************************************/
+
+sal_Bool SvStream::WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet )
+{
+ if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
+ *this << ch;
+ else
+ {
+ ByteString aStr( ch, eDestCharSet );
+ Write( aStr.GetBuffer(), aStr.Len() );
+ }
+ return nError == SVSTREAM_OK;
+}
+
+/*************************************************************************
+|*
+|* Stream::StartWritingUnicodeText()
+|*
+*************************************************************************/
+
+sal_Bool SvStream::StartWritingUnicodeText()
+{
+ SetEndianSwap( FALSE ); // write native format
+ // BOM, Byte Order Mark, U+FEFF, see
+ // http://www.unicode.org/faq/utf_bom.html#BOM
+ // Upon read: 0xfeff(-257) => no swap; 0xfffe(-2) => swap
+ *this << sal_uInt16( 0xfeff );
+ return nError == SVSTREAM_OK;
+}
+
+/*************************************************************************
+|*
+|* Stream::StartReadingUnicodeText()
+|*
+*************************************************************************/
+
+sal_Bool SvStream::StartReadingUnicodeText()
+{
+ sal_uInt16 nFlag;
+ *this >> nFlag;
+ switch ( nFlag )
+ {
+ case 0xfeff :
+ // native
+ break;
+ case 0xfffe :
+ SetEndianSwap( !bSwap );
+ break;
+ default:
+ SeekRel( -((sal_sSize)sizeof(nFlag)) ); // no BOM, pure data
+ }
+ return nError == SVSTREAM_OK;
+}
+
+/*************************************************************************
+|*
+|* Stream::ReadCsvLine()
+|*
+*************************************************************************/
+
+// Precondition: pStr is guaranteed to be non-NULL and points to a 0-terminated
+// array.
+inline const sal_Unicode* lcl_UnicodeStrChr( const sal_Unicode* pStr,
+ sal_Unicode c )
+{
+ while (*pStr)
+ {
+ if (*pStr == c)
+ return pStr;
+ ++pStr;
+ }
+ return 0;
+}
+
+sal_Bool SvStream::ReadCsvLine( String& rStr, sal_Bool bEmbeddedLineBreak,
+ const String& rFieldSeparators, sal_Unicode cFieldQuote,
+ sal_Bool bAllowBackslashEscape)
+{
+ ReadUniOrByteStringLine( rStr);
+
+ if (bEmbeddedLineBreak)
+ {
+ const sal_Unicode* pSeps = rFieldSeparators.GetBuffer();
+ xub_StrLen nLastOffset = 0;
+ xub_StrLen nQuotes = 0;
+ while (!IsEof() && rStr.Len() < STRING_MAXLEN)
+ {
+ bool bBackslashEscaped = false;
+ const sal_Unicode *p, *pStart;
+ p = pStart = rStr.GetBuffer();
+ p += nLastOffset;
+ while (*p)
+ {
+ if (nQuotes)
+ {
+ if (*p == cFieldQuote && !bBackslashEscaped)
+ ++nQuotes;
+ else if (bAllowBackslashEscape)
+ {
+ if (*p == '\\')
+ bBackslashEscaped = !bBackslashEscaped;
+ else
+ bBackslashEscaped = false;
+ }
+ }
+ else if (*p == cFieldQuote && (p == pStart ||
+ lcl_UnicodeStrChr( pSeps, p[-1])))
+ nQuotes = 1;
+ // A quote character inside a field content does not start
+ // a quote.
+ ++p;
+ }
+
+ if (nQuotes % 2 == 0)
+ break;
+ else
+ {
+ nLastOffset = rStr.Len();
+ String aNext;
+ ReadUniOrByteStringLine( aNext);
+ rStr += sal_Unicode(_LF);
+ rStr += aNext;
+ }
+ }
+ }
+ return nError == SVSTREAM_OK;
+}
+
+/*************************************************************************
+|*
+|* Stream::SeekRel()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_Size SvStream::SeekRel( sal_sSize nPos )
+{
+ sal_Size nActualPos = Tell();
+
+ if ( nPos >= 0 )
+ {
+ if ( SAL_MAX_SIZE - nActualPos > (sal_Size)nPos )
+ nActualPos += nPos;
+ }
+ else
+ {
+ sal_Size nAbsPos = (sal_Size)-nPos;
+ if ( nActualPos >= nAbsPos )
+ nActualPos -= nAbsPos;
+ }
+
+ pBufPos = pRWBuf + nActualPos;
+ return Seek( nActualPos );
+}
+
+/*************************************************************************
+|*
+|* Stream::operator>>()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+SvStream& SvStream::operator >> ( sal_uInt16& r )
+{
+ READNUMBER_WITHOUT_SWAP(sal_uInt16,r)
+ if( bSwap )
+ SwapUShort(r);
+ return *this;
+}
+
+SvStream& SvStream::operator>> ( sal_uInt32& r )
+{
+ READNUMBER_WITHOUT_SWAP(sal_uInt32,r)
+ if( bSwap )
+ SwapULong(r);
+ return *this;
+}
+
+SvStream& SvStream::operator >> ( long& r )
+{
+#if(SAL_TYPES_SIZEOFLONG != 4)
+ int tmp = r;
+ *this >> tmp;
+ r = tmp;
+#else
+ READNUMBER_WITHOUT_SWAP(long,r)
+ if( bSwap )
+ SwapLong(r);
+#endif
+ return *this;
+}
+
+SvStream& SvStream::operator >> ( short& r )
+{
+ READNUMBER_WITHOUT_SWAP(short,r)
+ if( bSwap )
+ SwapShort(r);
+ return *this;
+}
+
+SvStream& SvStream::operator >> ( int& r )
+{
+ READNUMBER_WITHOUT_SWAP(int,r)
+ if( bSwap )
+ SwapLongInt(r);
+ return *this;
+}
+
+SvStream& SvStream::operator>>( signed char& r )
+{
+ if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
+ sizeof(signed char) <= nBufFree )
+ {
+ r = *pBufPos;
+ nBufActualPos += sizeof(signed char);
+ pBufPos += sizeof(signed char);
+ nBufFree -= sizeof(signed char);
+ }
+ else
+ Read( (char*)&r, sizeof(signed char) );
+ return *this;
+}
+
+// Sonderbehandlung fuer Chars wegen PutBack
+
+SvStream& SvStream::operator>>( char& r )
+{
+ if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
+ sizeof(char) <= nBufFree )
+ {
+ r = *pBufPos;
+ nBufActualPos += sizeof(char);
+ pBufPos += sizeof(char);
+ nBufFree -= sizeof(char);
+ }
+ else
+ Read( (char*)&r, sizeof(char) );
+ return *this;
+}
+
+SvStream& SvStream::operator>>( unsigned char& r )
+{
+ if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
+ sizeof(char) <= nBufFree )
+ {
+ r = *pBufPos;
+ nBufActualPos += sizeof(char);
+ pBufPos += sizeof(char);
+ nBufFree -= sizeof(char);
+ }
+ else
+ Read( (char*)&r, sizeof(char) );
+ return *this;
+}
+
+SvStream& SvStream::operator>>( float& r )
+{
+ // Read( (char*)&r, sizeof(float) );
+ READNUMBER_WITHOUT_SWAP(float,r)
+#if defined UNX
+ if( bSwap )
+ SwapFloat(r);
+#endif
+ return *this;
+}
+
+SvStream& SvStream::operator>>( double& r )
+{
+ // Read( (char*)&r, sizeof(double) );
+ READNUMBER_WITHOUT_SWAP(double,r)
+#if defined UNX
+ if( bSwap )
+ SwapDouble(r);
+#endif
+ return *this;
+}
+
+SvStream& SvStream::operator>> ( SvStream& rStream )
+{
+ const sal_uInt32 cBufLen = 0x8000;
+ char* pBuf = new char[ cBufLen ];
+
+ sal_uInt32 nCount;
+ do {
+ nCount = Read( pBuf, cBufLen );
+ rStream.Write( pBuf, nCount );
+ } while( nCount == cBufLen );
+
+ delete[] pBuf;
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* Stream::operator<<()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+SvStream& SvStream::operator<< ( sal_uInt16 v )
+{
+ if( bSwap )
+ SwapUShort(v);
+ WRITENUMBER_WITHOUT_SWAP(sal_uInt16,v)
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( sal_uInt32 v )
+{
+ if( bSwap )
+ SwapULong(v);
+ WRITENUMBER_WITHOUT_SWAP(sal_uInt32,v)
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( long v )
+{
+#if(SAL_TYPES_SIZEOFLONG != 4)
+ int tmp = v;
+ *this << tmp;
+#else
+ if( bSwap )
+ SwapLong(v);
+ WRITENUMBER_WITHOUT_SWAP(long,v)
+#endif
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( short v )
+{
+ if( bSwap )
+ SwapShort(v);
+ WRITENUMBER_WITHOUT_SWAP(short,v)
+ return *this;
+}
+
+SvStream& SvStream::operator<<( int v )
+{
+ if( bSwap )
+ SwapLongInt( v );
+ WRITENUMBER_WITHOUT_SWAP(int,v)
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( signed char v )
+{
+ //SDO
+ int tmp = eIOMode;
+ if(tmp == STREAM_IO_WRITE && sizeof(signed char) <= nBufFree )
+ {
+ *pBufPos = v;
+ pBufPos++; // sizeof(char);
+ nBufActualPos++;
+ if( nBufActualPos > nBufActualLen ) // Append ?
+ nBufActualLen = nBufActualPos;
+ nBufFree--; // = sizeof(char);
+ bIsDirty = TRUE;
+ }
+ else
+ Write( (char*)&v, sizeof(signed char) );
+ return *this;
+}
+
+// Sonderbehandlung fuer chars wegen PutBack
+
+SvStream& SvStream::operator<< ( char v )
+{
+ //SDO
+ int tmp = eIOMode;
+ if(tmp == STREAM_IO_WRITE && sizeof(char) <= nBufFree )
+ {
+ *pBufPos = v;
+ pBufPos++; // sizeof(char);
+ nBufActualPos++;
+ if( nBufActualPos > nBufActualLen ) // Append ?
+ nBufActualLen = nBufActualPos;
+ nBufFree--; // = sizeof(char);
+ bIsDirty = TRUE;
+ }
+ else
+ Write( (char*)&v, sizeof(char) );
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( unsigned char v )
+{
+//SDO
+ int tmp = eIOMode;
+ if(tmp == STREAM_IO_WRITE && sizeof(char) <= nBufFree )
+ {
+ *(unsigned char*)pBufPos = v;
+ pBufPos++; // = sizeof(char);
+ nBufActualPos++; // = sizeof(char);
+ if( nBufActualPos > nBufActualLen ) // Append ?
+ nBufActualLen = nBufActualPos;
+ nBufFree--;
+ bIsDirty = TRUE;
+ }
+ else
+ Write( (char*)&v, sizeof(char) );
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( float v )
+{
+#ifdef UNX
+ if( bSwap )
+ SwapFloat(v);
+#endif
+ WRITENUMBER_WITHOUT_SWAP(float,v)
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( const double& r )
+{
+// Write( (char*)&r, sizeof( double ) );
+#if defined UNX
+ if( bSwap )
+ {
+ double nHelp = r;
+ SwapDouble(nHelp);
+ WRITENUMBER_WITHOUT_SWAP(double,nHelp)
+ return *this;
+ }
+ else
+#endif
+ WRITENUMBER_WITHOUT_SWAP(double,r)
+
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( const char* pBuf )
+{
+ Write( pBuf, strlen( pBuf ) );
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( const unsigned char* pBuf )
+{
+ Write( (char*)pBuf, strlen( (char*)pBuf ) );
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( SvStream& rStream )
+{
+ const sal_uInt32 cBufLen = 0x8000;
+ char* pBuf = new char[ cBufLen ];
+ sal_uInt32 nCount;
+ do {
+ nCount = rStream.Read( pBuf, cBufLen );
+ Write( pBuf, nCount );
+ } while( nCount == cBufLen );
+
+ delete[] pBuf;
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvStream::ReadByteString( UniString& rStr, rtl_TextEncoding eSrcCharSet )
+{
+ // read UTF-16 string directly from stream ?
+ if (eSrcCharSet == RTL_TEXTENCODING_UNICODE)
+ {
+ sal_uInt32 nLen;
+ operator>> (nLen);
+ if (nLen)
+ {
+ if (nLen > STRING_MAXLEN) {
+ SetError(SVSTREAM_GENERALERROR);
+ return *this;
+ }
+ sal_Unicode *pStr = rStr.AllocBuffer(
+ static_cast< xub_StrLen >(nLen));
+ BOOST_STATIC_ASSERT(STRING_MAXLEN <= SAL_MAX_SIZE / 2);
+ Read( pStr, nLen << 1 );
+
+ if (bSwap)
+ for (sal_Unicode *pEnd = pStr + nLen; pStr < pEnd; pStr++)
+ SwapUShort(*pStr);
+ }
+ else
+ rStr.Erase();
+
+ return *this;
+ }
+
+ ByteString aStr;
+ ReadByteString( aStr );
+ rStr = UniString( aStr, eSrcCharSet );
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvStream::ReadByteString( ByteString& rStr )
+{
+ sal_uInt16 nLen = 0;
+ operator>>( nLen );
+ if( nLen )
+ {
+ char* pTmp = rStr.AllocBuffer( nLen );
+ nLen = (sal_uInt16)Read( pTmp, nLen );
+ }
+ else
+ rStr.Erase();
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvStream::WriteByteString( const UniString& rStr, rtl_TextEncoding eDestCharSet )
+{
+ // write UTF-16 string directly into stream ?
+ if (eDestCharSet == RTL_TEXTENCODING_UNICODE)
+ {
+ sal_uInt32 nLen = rStr.Len();
+ operator<< (nLen);
+ if (nLen)
+ {
+ if (bSwap)
+ {
+ const sal_Unicode *pStr = rStr.GetBuffer();
+ const sal_Unicode *pEnd = pStr + nLen;
+
+ for (; pStr < pEnd; pStr++)
+ {
+ sal_Unicode c = *pStr;
+ SwapUShort(c);
+ WRITENUMBER_WITHOUT_SWAP(sal_uInt16,c)
+ }
+ }
+ else
+ Write( rStr.GetBuffer(), nLen << 1 );
+ }
+
+ return *this;
+ }
+
+ return WriteByteString(ByteString( rStr, eDestCharSet ));
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvStream::WriteByteString( const ByteString& rStr)
+{
+ sal_uInt16 nLen = rStr.Len();
+ operator<< ( nLen );
+ if( nLen != 0 )
+ Write( rStr.GetBuffer(), nLen );
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* Stream::Read()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_Size SvStream::Read( void* pData, sal_Size nCount )
+{
+ sal_Size nSaveCount = nCount;
+ if( !bIsConsistent )
+ RefreshBuffer();
+
+ if( !pRWBuf )
+ {
+ nCount = GetData( (char*)pData,nCount);
+ if( nCryptMask )
+ EncryptBuffer(pData, nCount);
+ nBufFilePos += nCount;
+ }
+ else
+ {
+ // ist Block komplett im Puffer
+ eIOMode = STREAM_IO_READ;
+ if( nCount <= (sal_Size)(nBufActualLen - nBufActualPos ) )
+ {
+ // Ja!
+ memcpy(pData, pBufPos, (size_t) nCount);
+ nBufActualPos = nBufActualPos + (sal_uInt16)nCount;
+ pBufPos += nCount;
+ nBufFree = nBufFree - (sal_uInt16)nCount;
+ }
+ else
+ {
+ if( bIsDirty ) // Flushen ?
+ {
+ SeekPos( nBufFilePos );
+ if( nCryptMask )
+ CryptAndWriteBuffer(pRWBuf, nBufActualLen);
+ else
+ PutData( pRWBuf, nBufActualLen );
+ bIsDirty = FALSE;
+ }
+
+ // passt der Datenblock in den Puffer ?
+ if( nCount > nBufSize )
+ {
+ // Nein! Deshalb ohne Umweg ueber den Puffer direkt
+ // in den Zielbereich einlesen
+
+ eIOMode = STREAM_IO_DONTKNOW;
+
+ SeekPos( nBufFilePos + nBufActualPos );
+ nBufActualLen = 0;
+ pBufPos = pRWBuf;
+ nCount = GetData( (char*)pData, nCount );
+ if( nCryptMask )
+ EncryptBuffer(pData, nCount);
+ nBufFilePos += nCount;
+ nBufFilePos += nBufActualPos;
+ nBufActualPos = 0;
+ }
+ else
+ {
+ // Der Datenblock passt komplett in den Puffer. Deshalb
+ // Puffer fuellen und dann die angeforderten Daten in den
+ // Zielbereich kopieren.
+
+ nBufFilePos += nBufActualPos;
+ SeekPos( nBufFilePos );
+
+ // TODO: Typecast vor GetData, sal_uInt16 nCountTmp
+ sal_Size nCountTmp = GetData( pRWBuf, nBufSize );
+ if( nCryptMask )
+ EncryptBuffer(pRWBuf, nCountTmp);
+ nBufActualLen = (sal_uInt16)nCountTmp;
+ if( nCount > nCountTmp )
+ {
+ nCount = nCountTmp; // zurueckstutzen, Eof siehe unten
+ }
+ memcpy( pData, pRWBuf, (size_t)nCount );
+ nBufActualPos = (sal_uInt16)nCount;
+ pBufPos = pRWBuf + nCount;
+ }
+ }
+ }
+ bIsEof = FALSE;
+ nBufFree = nBufActualLen - nBufActualPos;
+ if( nCount != nSaveCount && nError != ERRCODE_IO_PENDING )
+ bIsEof = TRUE;
+ if( nCount == nSaveCount && nError == ERRCODE_IO_PENDING )
+ nError = ERRCODE_NONE;
+ return nCount;
+}
+
+/*************************************************************************
+|*
+|* Stream::Write()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_Size SvStream::Write( const void* pData, sal_Size nCount )
+{
+ if( !nCount )
+ return 0;
+ if( !bIsWritable )
+ {
+ SetError( ERRCODE_IO_CANTWRITE );
+ return 0;
+ }
+ if( !bIsConsistent )
+ RefreshBuffer(); // Aenderungen des Puffers durch PutBack loeschen
+
+ if( !pRWBuf )
+ {
+ if( nCryptMask )
+ nCount = CryptAndWriteBuffer( pData, nCount );
+ else
+ nCount = PutData( (char*)pData, nCount );
+ nBufFilePos += nCount;
+ return nCount;
+ }
+
+ eIOMode = STREAM_IO_WRITE;
+ if( nCount <= (sal_Size)(nBufSize - nBufActualPos) )
+ {
+ memcpy( pBufPos, pData, (size_t)nCount );
+ nBufActualPos = nBufActualPos + (sal_uInt16)nCount;
+ // wurde der Puffer erweitert ?
+ if( nBufActualPos > nBufActualLen )
+ nBufActualLen = nBufActualPos;
+
+ pBufPos += nCount;
+ bIsDirty = TRUE;
+ }
+ else
+ {
+ // Flushen ?
+ if( bIsDirty )
+ {
+ SeekPos( nBufFilePos );
+ if( nCryptMask )
+ CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
+ else
+ PutData( pRWBuf, nBufActualLen );
+ bIsDirty = FALSE;
+ }
+
+ // passt der Block in den Puffer ?
+ if( nCount > nBufSize )
+ {
+ eIOMode = STREAM_IO_DONTKNOW;
+ nBufFilePos += nBufActualPos;
+ nBufActualLen = 0;
+ nBufActualPos = 0;
+ pBufPos = pRWBuf;
+ SeekPos( nBufFilePos );
+ if( nCryptMask )
+ nCount = CryptAndWriteBuffer( pData, nCount );
+ else
+ nCount = PutData( (char*)pData, nCount );
+ nBufFilePos += nCount;
+ }
+ else
+ {
+ // Block in Puffer stellen
+ memcpy( pRWBuf, pData, (size_t)nCount );
+
+ // Reihenfolge!
+ nBufFilePos += nBufActualPos;
+ nBufActualPos = (sal_uInt16)nCount;
+ pBufPos = pRWBuf + nCount;
+ nBufActualLen = (sal_uInt16)nCount;
+ bIsDirty = TRUE;
+ }
+ }
+ nBufFree = nBufSize - nBufActualPos;
+ return nCount;
+}
+
+
+/*************************************************************************
+|*
+|* Stream::Seek()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_Size SvStream::Seek( sal_Size nFilePos )
+{
+ eIOMode = STREAM_IO_DONTKNOW;
+
+ bIsEof = FALSE;
+ if( !pRWBuf )
+ {
+ nBufFilePos = SeekPos( nFilePos );
+ DBG_ASSERT(Tell()==nBufFilePos,"Out Of Sync!");
+ return nBufFilePos;
+ }
+
+ // Ist Position im Puffer ?
+ if( nFilePos >= nBufFilePos && nFilePos <= (nBufFilePos + nBufActualLen))
+ {
+ nBufActualPos = (sal_uInt16)(nFilePos - nBufFilePos);
+ pBufPos = pRWBuf + nBufActualPos;
+ // nBufFree korrigieren, damit wir nicht von einem
+ // PutBack (ignoriert den StreamMode) getoetet werden
+ nBufFree = nBufActualLen - nBufActualPos;
+ }
+ else
+ {
+ if( bIsDirty && bIsConsistent)
+ {
+ SeekPos( nBufFilePos );
+ if( nCryptMask )
+ CryptAndWriteBuffer( pRWBuf, nBufActualLen );
+ else
+ PutData( pRWBuf, nBufActualLen );
+ bIsDirty = FALSE;
+ }
+ nBufActualLen = 0;
+ nBufActualPos = 0;
+ pBufPos = pRWBuf;
+ nBufFilePos = SeekPos( nFilePos );
+ }
+#ifdef OV_DEBUG
+ {
+ sal_Size nDebugTemp = nBufFilePos + nBufActualPos;
+ DBG_ASSERT(Tell()==nDebugTemp,"Sync?");
+ }
+#endif
+ return nBufFilePos + nBufActualPos;
+}
+
+/*************************************************************************
+|*
+|* Stream::Flush()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::Flush()
+{
+ if( bIsDirty && bIsConsistent )
+ {
+ SeekPos( nBufFilePos );
+ if( nCryptMask )
+ CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
+ else
+ if( PutData( pRWBuf, nBufActualLen ) != nBufActualLen )
+ SetError( SVSTREAM_WRITE_ERROR );
+ bIsDirty = FALSE;
+ }
+ if( bIsWritable )
+ FlushData();
+}
+
+
+/*************************************************************************
+|*
+|* Stream::PutBack()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 01.08.94
+|* Letzte Aenderung OV 01.08.94
+|*
+*************************************************************************/
+
+/*
+ 4 Faelle :
+
+ 1. Datenzeiger steht mitten im Puffer (nBufActualPos >= 1)
+ 2. Datenzeiger auf Position 0, Puffer ist voll
+ 3. Datenzeiger auf Position 0, Puffer ist teilweise gefuellt
+ 4. Datenzeiger auf Position 0, Puffer ist leer -> Fehler!
+*/
+
+SvStream& SvStream::PutBack( char aCh )
+{
+ // wenn kein Buffer oder Zurueckscrollen nicht moeglich -> Fehler
+ if( !pRWBuf || !nBufActualLen || ( !nBufActualPos && !nBufFilePos ) )
+ {
+ // 4. Fall
+ SetError( SVSTREAM_GENERALERROR );
+ return *this;
+ }
+
+ // Flush() (Phys. Flushen aber nicht notwendig, deshalb selbst schreiben)
+ if( bIsConsistent && bIsDirty )
+ {
+ SeekPos( nBufFilePos );
+ if( nCryptMask )
+ CryptAndWriteBuffer( pRWBuf, nBufActualLen );
+ else
+ PutData( pRWBuf, nBufActualLen );
+ bIsDirty = FALSE;
+ }
+ bIsConsistent = FALSE; // Puffer enthaelt jetzt TRASH
+ if( nBufActualPos )
+ {
+ // 1. Fall
+ nBufActualPos--;
+ pBufPos--;
+ *pBufPos = aCh;
+ nBufFree++;
+ }
+ else // Puffer muss verschoben werden
+ {
+ // Ist Puffer am Anschlag ?
+ if( nBufSize == nBufActualLen )
+ {
+ // 2. Fall
+ memmove( pRWBuf+1, pRWBuf, nBufSize-1 );
+ // nBufFree behaelt den Wert!
+ }
+ else
+ {
+ // 3. Fall -> Puffer vergroessern
+ memmove( pRWBuf+1, pRWBuf, (sal_uInt16)nBufActualLen );
+ nBufActualLen++;
+ nBufFree++;
+ }
+ nBufFilePos--;
+ *pRWBuf = aCh;
+ }
+ eIOMode = STREAM_IO_DONTKNOW;
+ bIsEof = FALSE;
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* Stream::EatWhite()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 01.08.94
+|* Letzte Aenderung OV 01.08.94
+|*
+*************************************************************************/
+
+void SvStream::EatWhite()
+{
+ char aCh;
+ Read(&aCh, sizeof(char) );
+ while( !bIsEof && isspace((int)aCh) ) //( aCh == ' ' || aCh == '\t' ) )
+ Read(&aCh, sizeof(char) );
+ if( !bIsEof ) // konnte das letzte Char gelesen werden ?
+ SeekRel( -1L );
+}
+
+/*************************************************************************
+|*
+|* Stream::RefreshBuffer()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 01.08.94
+|* Letzte Aenderung OV 01.08.94
+|*
+*************************************************************************/
+
+void SvStream::RefreshBuffer()
+{
+ if( bIsDirty && bIsConsistent )
+ {
+ SeekPos( nBufFilePos );
+ if( nCryptMask )
+ CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
+ else
+ PutData( pRWBuf, nBufActualLen );
+ bIsDirty = FALSE;
+ }
+ SeekPos( nBufFilePos );
+ nBufActualLen = (sal_uInt16)GetData( pRWBuf, nBufSize );
+ if( nBufActualLen && nError == ERRCODE_IO_PENDING )
+ nError = ERRCODE_NONE;
+ if( nCryptMask )
+ EncryptBuffer(pRWBuf, (sal_Size)nBufActualLen);
+ bIsConsistent = TRUE;
+ eIOMode = STREAM_IO_DONTKNOW;
+}
+
+
+/*************************************************************************
+|*
+|* Stream::CreateFormatString()
+|*
+|* Beschreibung Baut Formatstring zusammen
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::CreateFormatString()
+{
+ aFormatString = '%';
+ nPrintfParams = SPECIAL_PARAM_NONE;
+
+ if( nJustification )
+ {
+ aFormatString += '-';
+ }
+
+ if( nWidth )
+ {
+ if( cFiller != ' ' )
+ aFormatString += '0';
+ aFormatString += '*';
+ nPrintfParams = SPECIAL_PARAM_WIDTH;
+ }
+
+ if( nPrecision )
+ {
+ aFormatString += ".*";
+ if( nWidth )
+ nPrintfParams = SPECIAL_PARAM_BOTH;
+ else
+ nPrintfParams = SPECIAL_PARAM_PRECISION;
+ }
+}
+
+/*************************************************************************
+|*
+|* Stream::ReadNumber()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+#define BUFSIZE_LONG 21 // log( 2 hoch 64 ) + 1
+
+SvStream& SvStream::ReadNumber( long& rLong )
+{
+ EatWhite();
+ if( bIsEof || nError )
+ {
+ SetError( SVSTREAM_GENERALERROR );
+ return *this;
+ }
+ sal_Size nFPtr = Tell();
+ char buf[ BUFSIZE_LONG ];
+ memset( buf, 0, BUFSIZE_LONG );
+ sal_Size nTemp = Read( buf, BUFSIZE_LONG-1 );
+ if( !nTemp || nError )
+ {
+ SetError( SVSTREAM_GENERALERROR );
+ return *this;
+ }
+ char *pEndPtr;
+ rLong = strtol( buf, &pEndPtr, (int)nRadix );
+ nFPtr += ( (sal_Size)pEndPtr - (sal_Size)(&(buf[0])) );
+ Seek( nFPtr );
+ bIsEof = FALSE;
+ return *this;
+}
+
+SvStream& SvStream::ReadNumber( sal_uInt32& rUInt32 )
+{
+ EatWhite();
+ if( bIsEof || nError )
+ {
+ SetError( SVSTREAM_GENERALERROR );
+ return *this;
+ }
+ sal_Size nFPtr = Tell();
+ char buf[ BUFSIZE_LONG ];
+ memset( buf, 0, BUFSIZE_LONG );
+ sal_Size nTemp = Read( buf, BUFSIZE_LONG-1 );
+ if( !nTemp || nError )
+ {
+ SetError( SVSTREAM_GENERALERROR );
+ return *this;
+ }
+ char *pEndPtr;
+ rUInt32 = strtoul( buf, &pEndPtr, (int)nRadix );
+ nFPtr += ( (sal_uIntPtr)pEndPtr - (sal_uIntPtr)buf );
+ Seek( nFPtr );
+ bIsEof = FALSE;
+ return *this;
+}
+
+SvStream& SvStream::ReadNumber( double& rDouble )
+{
+ EatWhite();
+ if( bIsEof || nError )
+ {
+ SetError( SVSTREAM_GENERALERROR );
+ return *this;
+ }
+ sal_Size nFPtr = Tell();
+ char buf[ BUFSIZE_LONG ];
+ memset( buf, 0, BUFSIZE_LONG );
+ sal_Size nTemp = Read( buf, BUFSIZE_LONG-1 );
+ if( !nTemp || nError )
+ {
+ SetError( SVSTREAM_GENERALERROR );
+ return *this;
+ }
+ char *pEndPtr;
+ rDouble = strtod( buf, &pEndPtr );
+ nFPtr += ( (sal_Size)pEndPtr - (sal_Size)buf );
+ Seek( nFPtr );
+ bIsEof = FALSE;
+ return *this;
+}
+
+
+/*************************************************************************
+|*
+|* Stream::WriteNumber()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+SvStream& SvStream::WriteNumber( long nLong )
+{
+ char buffer[256+12];
+ char pType[] = "ld"; // Nicht static!
+ if( nRadix == 16 )
+ pType[1] = 'x';
+ else if( nRadix == 8 )
+ pType[1] = 'o';
+ ByteString aFStr( aFormatString);
+ aFStr += pType;
+ int nLen;
+ switch ( nPrintfParams )
+ {
+ case SPECIAL_PARAM_NONE :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), nLong );
+ break;
+ case SPECIAL_PARAM_WIDTH :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), nWidth, nLong );
+ break;
+ case SPECIAL_PARAM_PRECISION :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), nPrecision,nLong);
+ break;
+ default:
+ nLen=sprintf(buffer, aFStr.GetBuffer(),nWidth,nPrecision,nLong);
+ }
+ Write( buffer, (long)nLen );
+ return *this;
+}
+
+SvStream& SvStream::WriteNumber( sal_uInt32 nUInt32 )
+{
+ char buffer[256+12];
+ char pType[] = "lu"; // Nicht static!
+ if( nRadix == 16 )
+ pType[1] = 'x';
+ else if( nRadix == 8 )
+ pType[1] = 'o';
+ ByteString aFStr( aFormatString);
+ aFStr += pType;
+ int nLen;
+ switch ( nPrintfParams )
+ {
+ case SPECIAL_PARAM_NONE :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), nUInt32 );
+ break;
+ case SPECIAL_PARAM_WIDTH :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), nWidth, nUInt32 );
+ break;
+ case SPECIAL_PARAM_PRECISION :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), nPrecision, nUInt32 );
+ break;
+ default:
+ nLen=sprintf(buffer,aFStr.GetBuffer(),nWidth,nPrecision,nUInt32 );
+ }
+ Write( buffer, (long)nLen );
+ return *this;
+}
+
+
+SvStream& SvStream::WriteNumber( const double& rDouble )
+{
+ char buffer[256+24];
+ ByteString aFStr( aFormatString);
+ aFStr += "lf";
+ int nLen;
+ switch ( nPrintfParams )
+ {
+ case SPECIAL_PARAM_NONE :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), rDouble );
+ break;
+ case SPECIAL_PARAM_WIDTH :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), nWidth, rDouble );
+ break;
+ case SPECIAL_PARAM_PRECISION :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), nPrecision, rDouble);
+ break;
+ default:
+ nLen=sprintf(buffer, aFStr.GetBuffer(),nWidth,nPrecision,rDouble);
+ }
+ Write( buffer, (long)nLen );
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* Stream::CryptAndWriteBuffer()
+|*
+|* Beschreibung Verschluesseln und Schreiben
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+#define CRYPT_BUFSIZE 1024
+
+sal_Size SvStream::CryptAndWriteBuffer( const void* pStart, sal_Size nLen)
+{
+ unsigned char pTemp[CRYPT_BUFSIZE];
+ unsigned char* pDataPtr = (unsigned char*)pStart;
+ sal_Size nCount = 0;
+ sal_Size nBufCount;
+ unsigned char nMask = nCryptMask;
+ do
+ {
+ if( nLen >= CRYPT_BUFSIZE )
+ nBufCount = CRYPT_BUFSIZE;
+ else
+ nBufCount = nLen;
+ nLen -= nBufCount;
+ memcpy( pTemp, pDataPtr, (sal_uInt16)nBufCount );
+ // **** Verschluesseln *****
+ for ( sal_uInt16 n=0; n < CRYPT_BUFSIZE; n++ )
+ {
+ unsigned char aCh = pTemp[n];
+ aCh ^= nMask;
+ SWAPNIBBLES(aCh)
+ pTemp[n] = aCh;
+ }
+ // *************************
+ nCount += PutData( (char*)pTemp, nBufCount );
+ pDataPtr += nBufCount;
+ }
+ while ( nLen );
+ return nCount;
+}
+
+/*************************************************************************
+|*
+|* Stream::EncryptBuffer()
+|*
+|* Beschreibung Buffer entschluesseln
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvStream::EncryptBuffer(void* pStart, sal_Size nLen)
+{
+ unsigned char* pTemp = (unsigned char*)pStart;
+ unsigned char nMask = nCryptMask;
+
+ for ( sal_Size n=0; n < nLen; n++, pTemp++ )
+ {
+ unsigned char aCh = *pTemp;
+ SWAPNIBBLES(aCh)
+ aCh ^= nMask;
+ *pTemp = aCh;
+ }
+ return TRUE;
+}
+
+/*************************************************************************
+|*
+|* Stream::SetKey()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+unsigned char implGetCryptMask(const sal_Char* pStr, sal_Int32 nLen, long nVersion)
+{
+ unsigned char nCryptMask = 0;
+
+ if (!nLen)
+ return nCryptMask;
+
+ if( nVersion <= SOFFICE_FILEFORMAT_31 )
+ {
+ while( nLen )
+ {
+ nCryptMask ^= *pStr;
+ pStr++;
+ nLen--;
+ }
+ }
+ else // BugFix #25888#
+ {
+ for( sal_uInt16 i = 0; i < nLen; i++ ) {
+ nCryptMask ^= pStr[i];
+ if( nCryptMask & 0x80 ) {
+ nCryptMask <<= 1;
+ nCryptMask++;
+ }
+ else
+ nCryptMask <<= 1;
+ }
+ }
+
+ if( !nCryptMask )
+ nCryptMask = 67;
+
+ return nCryptMask;
+}
+
+void SvStream::SetKey( const ByteString& rKey )
+{
+ aKey = rKey;
+ nCryptMask = implGetCryptMask( aKey.GetBuffer(), aKey.Len(), GetVersion() );
+}
+
+/*************************************************************************
+|*
+|* Stream::SyncSvStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::SyncSvStream( sal_Size nNewStreamPos )
+{
+ ClearBuffer();
+ SvStream::nBufFilePos = nNewStreamPos;
+}
+
+/*************************************************************************
+|*
+|* Stream::SyncSysStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::SyncSysStream()
+{
+ Flush();
+ SeekPos( Tell() );
+}
+
+/*************************************************************************
+|*
+|* Stream::SetStreamSize()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvStream::SetStreamSize( sal_Size nSize )
+{
+#ifdef DBG_UTIL
+ sal_Size nFPos = Tell();
+#endif
+ sal_uInt16 nBuf = nBufSize;
+ SetBufferSize( 0 );
+ SetSize( nSize );
+ SetBufferSize( nBuf );
+ DBG_ASSERT(Tell()==nFPos,"SetStreamSize failed");
+ return (sal_Bool)(nError == 0);
+}
+
+//============================================================================
+
+void SvStream::AddMark( sal_Size )
+{
+}
+
+//============================================================================
+
+void SvStream::RemoveMark( sal_Size )
+{
+}
+
+/*************************************************************************
+|*
+|* endl()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung TH 13.11.96
+|*
+*************************************************************************/
+
+SvStream& endl( SvStream& rStr )
+{
+ LineEnd eDelim = rStr.GetLineDelimiter();
+ if ( eDelim == LINEEND_CR )
+ rStr << _CR;
+ else if( eDelim == LINEEND_LF )
+ rStr << _LF;
+ else
+ rStr << _CR << _LF;
+ return rStr;
+}
+
+SvStream& endlu( SvStream& rStrm )
+{
+ switch ( rStrm.GetLineDelimiter() )
+ {
+ case LINEEND_CR :
+ rStrm << sal_Unicode(_CR);
+ break;
+ case LINEEND_LF :
+ rStrm << sal_Unicode(_LF);
+ break;
+ default:
+ rStrm << sal_Unicode(_CR) << sal_Unicode(_LF);
+ }
+ return rStrm;
+}
+
+SvStream& endlub( SvStream& rStrm )
+{
+ if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
+ return endlu( rStrm );
+ else
+ return endl( rStrm );
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::SvMemoryStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+SvMemoryStream::SvMemoryStream( void* pBuffer, sal_Size bufSize,
+ StreamMode eMode )
+{
+ if( eMode & STREAM_WRITE )
+ bIsWritable = TRUE;
+ else
+ bIsWritable = FALSE;
+ nEndOfData = bufSize;
+ bOwnsData = FALSE;
+ pBuf = (BYTE *) pBuffer;
+ nResize = 0L;
+ nSize = bufSize;
+ nPos = 0L;
+ SetBufferSize( 0 );
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::SvMemoryStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+SvMemoryStream::SvMemoryStream( sal_Size nInitSize, sal_Size nResizeOffset )
+{
+ bIsWritable = TRUE;
+ bOwnsData = TRUE;
+ nEndOfData = 0L;
+ nResize = nResizeOffset;
+ nPos = 0;
+ pBuf = 0;
+ if( nResize != 0 && nResize < 16 )
+ nResize = 16;
+ if( nInitSize && !AllocateMemory( nInitSize ) )
+ {
+ SetError( SVSTREAM_OUTOFMEMORY );
+ nSize = 0;
+ }
+ else
+ nSize = nInitSize;
+ SetBufferSize( 64 );
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::~SvMemoryStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+SvMemoryStream::~SvMemoryStream()
+{
+ if( pBuf )
+ {
+ if( bOwnsData )
+ FreeMemory();
+ else
+ Flush();
+ }
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::IsA()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+sal_uInt16 SvMemoryStream::IsA() const
+{
+ return (sal_uInt16)ID_MEMORYSTREAM;
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::SetBuffer()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+void* SvMemoryStream::SetBuffer( void* pNewBuf, sal_Size nCount,
+ sal_Bool bOwnsDat, sal_Size nEOF )
+{
+ void* pResult;
+ SetBufferSize( 0 ); // Buffering in der Basisklasse initialisieren
+ Seek( 0 );
+ if( bOwnsData )
+ {
+ pResult = 0;
+ if( pNewBuf != pBuf )
+ FreeMemory();
+ }
+ else
+ pResult = pBuf;
+
+ pBuf = (BYTE *) pNewBuf;
+ nPos = 0;
+ nSize = nCount;
+ nResize = 0;
+ bOwnsData = bOwnsDat;
+
+ if( nEOF > nCount )
+ nEOF = nCount;
+ nEndOfData = nEOF;
+
+ ResetError();
+
+ DBG_ASSERT( nEndOfData<STREAM_SEEK_TO_END,"Invalid EOF");
+ return pResult;
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::GetData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+sal_Size SvMemoryStream::GetData( void* pData, sal_Size nCount )
+{
+ sal_Size nMaxCount = nEndOfData-nPos;
+ if( nCount > nMaxCount )
+ nCount = nMaxCount;
+ memcpy( pData, pBuf+nPos, (size_t)nCount );
+ nPos += nCount;
+ return nCount;
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::PutData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+sal_Size SvMemoryStream::PutData( const void* pData, sal_Size nCount )
+{
+ if( GetError() )
+ return 0L;
+
+ sal_Size nMaxCount = nSize-nPos;
+
+ // auf Ueberlauf testen
+ if( nCount > nMaxCount )
+ {
+ if( nResize == 0 )
+ {
+ // soviel wie moeglich rueberschaufeln
+ nCount = nMaxCount;
+ SetError( SVSTREAM_OUTOFMEMORY );
+ }
+ else
+ {
+ long nNewResize;
+ if( nSize && nSize > nResize )
+ nNewResize = nSize;
+ else
+ nNewResize = nResize;
+
+ if( (nCount-nMaxCount) < nResize )
+ {
+ // fehlender Speicher ist kleiner als Resize-Offset,
+ // deshalb um Resize-Offset vergroessern
+ if( !ReAllocateMemory( nNewResize) )
+ {
+ nCount = 0;
+ SetError( SVSTREAM_WRITE_ERROR );
+ }
+ }
+ else
+ {
+ // fehlender Speicher ist groesser als Resize-Offset
+ // deshalb um Differenz+ResizeOffset vergroessern
+ if( !ReAllocateMemory( nCount-nMaxCount+nNewResize ) )
+ {
+ nCount = 0;
+ SetError( SVSTREAM_WRITE_ERROR );
+ }
+ }
+ }
+ }
+ DBG_ASSERT(pBuf,"Possibly Reallocate failed");
+ memcpy( pBuf+nPos, pData, (size_t)nCount);
+
+ nPos += nCount;
+ if( nPos > nEndOfData )
+ nEndOfData = nPos;
+ return nCount;
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::SeekPos()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+// nEndOfData: Erste Position im Stream, die nicht gelesen werden darf
+// nSize: Groesse des allozierten Speichers
+
+sal_Size SvMemoryStream::SeekPos( sal_Size nNewPos )
+{
+ if( nNewPos < nEndOfData )
+ nPos = nNewPos;
+ else if( nNewPos == STREAM_SEEK_TO_END )
+ nPos = nEndOfData;
+ else
+ {
+ if( nNewPos >= nSize ) // muss Buffer vergroessert werden ?
+ {
+ if( nResize ) // ist vergroeseern erlaubt ?
+ {
+ long nDiff = (long)(nNewPos - nSize + 1);
+ nDiff += (long)nResize;
+ ReAllocateMemory( nDiff );
+ nPos = nNewPos;
+ nEndOfData = nNewPos;
+ }
+ else // vergroessern ist nicht erlaubt -> ans Ende setzen
+ {
+ // SetError( SVSTREAM_OUTOFMEMORY );
+ nPos = nEndOfData;
+ }
+ }
+ else // gueltigen Bereich innerhalb des Buffers vergroessern
+ {
+ nPos = nNewPos;
+ nEndOfData = nNewPos;
+ }
+ }
+ return nPos;
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::FlushData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+void SvMemoryStream::FlushData()
+{
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::ResetError()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+void SvMemoryStream::ResetError()
+{
+ SvStream::ClearError();
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::AllocateMemory()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvMemoryStream::AllocateMemory( sal_Size nNewSize )
+{
+ pBuf = new BYTE[nNewSize];
+ return( pBuf != 0 );
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::ReAllocateMemory() (Bozo-Algorithmus)
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvMemoryStream::ReAllocateMemory( long nDiff )
+{
+ sal_Bool bRetVal = FALSE;
+ long nTemp = (long)nSize;
+ nTemp += nDiff;
+ sal_Size nNewSize = (sal_Size)nTemp;
+
+ if( nNewSize )
+ {
+ BYTE* pNewBuf = new BYTE[nNewSize];
+
+ if( pNewBuf )
+ {
+ bRetVal = TRUE; // Success!
+ if( nNewSize < nSize ) // Verkleinern ?
+ {
+ memcpy( pNewBuf, pBuf, (size_t)nNewSize );
+ if( nPos > nNewSize )
+ nPos = 0L;
+ if( nEndOfData >= nNewSize )
+ nEndOfData = nNewSize-1L;
+ }
+ else
+ {
+ memcpy( pNewBuf, pBuf, (size_t)nSize );
+ }
+
+ FreeMemory();
+
+ pBuf = pNewBuf;
+ nSize = nNewSize;
+ }
+ }
+ else
+ {
+ bRetVal = TRUE;
+ FreeMemory();
+ pBuf = 0;
+ nSize = 0;
+ nEndOfData = 0;
+ nPos = 0;
+ }
+
+ return bRetVal;
+}
+
+void SvMemoryStream::FreeMemory()
+{
+ delete[] pBuf;
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::SwitchBuffer()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 26.07.94
+|* Letzte Aenderung OV 26.07.94
+|*
+*************************************************************************/
+
+void* SvMemoryStream::SwitchBuffer( sal_Size nInitSize, sal_Size nResizeOffset)
+{
+ Flush();
+ if( !bOwnsData )
+ return 0;
+ Seek( STREAM_SEEK_TO_BEGIN );
+
+ void* pRetVal = pBuf;
+ pBuf = 0;
+ nEndOfData = 0L;
+ nResize = nResizeOffset;
+ nPos = 0;
+
+ if( nResize != 0 && nResize < 16 )
+ nResize = 16;
+
+ ResetError();
+
+ if( nInitSize && !AllocateMemory(nInitSize) )
+ {
+ SetError( SVSTREAM_OUTOFMEMORY );
+ nSize = 0;
+ }
+ else
+ nSize = nInitSize;
+
+ SetBufferSize( 64 );
+ return pRetVal;
+}
+
+void SvMemoryStream::SetSize( sal_Size nNewSize )
+{
+ long nDiff = (long)nNewSize - (long)nSize;
+ ReAllocateMemory( nDiff );
+}
+
+TYPEINIT0 ( SvDataCopyStream )
+
+void SvDataCopyStream::Assign( const SvDataCopyStream& )
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/stream/strmos2.cxx b/tools/source/stream/strmos2.cxx
new file mode 100644
index 000000000000..b760364d3230
--- /dev/null
+++ b/tools/source/stream/strmos2.cxx
@@ -0,0 +1,687 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <string.h>
+#include <limits.h>
+
+#define INCL_PM
+#define INCL_DOS
+#define INCL_DOSERRORS
+#include <svpm.h>
+
+#include <tools/debug.hxx>
+#include <tools/fsys.hxx>
+#include <tools/stream.hxx>
+
+// class FileBase
+#include <osl/file.hxx>
+
+using namespace osl;
+
+// class FileBase
+#include <osl/file.hxx>
+
+using namespace osl;
+
+// -----------------------------------------------------------------------
+
+// --------------
+// - StreamData -
+// --------------
+
+class StreamData
+{
+public:
+ HFILE hFile;
+ BOOL bIsEof;
+
+ StreamData()
+ {
+ hFile = 0;
+ bIsEof = TRUE;
+ }
+};
+
+// -----------------------------------------------------------------------
+
+ULONG GetSvError( APIRET nPMError )
+{
+ static struct { APIRET pm; ULONG sv; } errArr[] =
+ {
+ { ERROR_FILE_NOT_FOUND, SVSTREAM_FILE_NOT_FOUND },
+ { ERROR_PATH_NOT_FOUND, SVSTREAM_PATH_NOT_FOUND },
+ { ERROR_TOO_MANY_OPEN_FILES, SVSTREAM_TOO_MANY_OPEN_FILES },
+ { ERROR_ACCESS_DENIED, SVSTREAM_ACCESS_DENIED },
+ { ERROR_INVALID_ACCESS, SVSTREAM_INVALID_ACCESS },
+ { ERROR_SHARING_VIOLATION, SVSTREAM_SHARING_VIOLATION },
+ { ERROR_SHARING_BUFFER_EXCEEDED,SVSTREAM_SHARE_BUFF_EXCEEDED },
+ { ERROR_CANNOT_MAKE, SVSTREAM_CANNOT_MAKE },
+ { ERROR_INVALID_PARAMETER, SVSTREAM_INVALID_PARAMETER },
+ { ERROR_DRIVE_LOCKED, SVSTREAM_LOCKING_VIOLATION },
+ { ERROR_LOCK_VIOLATION, SVSTREAM_LOCKING_VIOLATION },
+ { ERROR_FILENAME_EXCED_RANGE, SVSTREAM_INVALID_PARAMETER },
+ { ERROR_ATOMIC_LOCK_NOT_SUPPORTED, SVSTREAM_INVALID_PARAMETER },
+ { ERROR_READ_LOCKS_NOT_SUPPORTED, SVSTREAM_INVALID_PARAMETER },
+
+
+ { 0xFFFF, SVSTREAM_GENERALERROR }
+ };
+
+ ULONG nRetVal = SVSTREAM_GENERALERROR; // Standardfehler
+ int i=0;
+ do
+ {
+ if( errArr[i].pm == nPMError )
+ {
+ nRetVal = errArr[i].sv;
+ break;
+ }
+ i++;
+ }
+ while( errArr[i].pm != 0xFFFF );
+ return nRetVal;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::SvFileStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+SvFileStream::SvFileStream( const String& rFileName, StreamMode nOpenMode )
+{
+ bIsOpen = FALSE;
+ nLockCounter = 0;
+ bIsWritable = FALSE;
+ pInstanceData = new StreamData;
+
+ SetBufferSize( 8192 );
+ // convert URL to SystemPath, if necessary
+ ::rtl::OUString aFileName, aNormPath;
+
+ if ( FileBase::getSystemPathFromFileURL( rFileName, aFileName ) != FileBase::E_None )
+ aFileName = rFileName;
+ Open( aFileName, nOpenMode );
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::SvFileStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 22.11.94
+|* Letzte Aenderung OV 22.11.94
+|*
+*************************************************************************/
+
+SvFileStream::SvFileStream()
+{
+ bIsOpen = FALSE;
+ nLockCounter = 0;
+ bIsWritable = FALSE;
+ pInstanceData = new StreamData;
+ SetBufferSize( 8192 );
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::~SvFileStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 14.06.94
+|* Letzte Aenderung OV 14.06.94
+|*
+*************************************************************************/
+
+SvFileStream::~SvFileStream()
+{
+ Close();
+ if( pInstanceData )
+ delete pInstanceData;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::GetFileHandle()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 14.06.94
+|* Letzte Aenderung OV 14.06.94
+|*
+*************************************************************************/
+
+ULONG SvFileStream::GetFileHandle() const
+{
+ return (ULONG)pInstanceData->hFile;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::IsA()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 14.06.94
+|* Letzte Aenderung OV 14.06.94
+|*
+*************************************************************************/
+
+USHORT SvFileStream::IsA() const
+{
+ return ID_FILESTREAM;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::GetData()
+|*
+|* Beschreibung STREAM.SDW, Prueft nicht Eof; IsEof danach rufbar
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+ULONG SvFileStream::GetData( void* pData, ULONG nSize )
+{
+#ifdef DBG_UTIL
+ ByteString aTraceStr( "SvFileStream::GetData(): " );
+ aTraceStr += ByteString::CreateFromInt64(nSize);
+ aTraceStr += " Bytes from ";
+ aTraceStr += ByteString(aFilename, osl_getThreadTextEncoding());
+ DBG_TRACE( aTraceStr.GetBuffer() );
+#endif
+
+ ULONG nCount = 0L;
+ if( IsOpen() )
+ {
+ APIRET nResult;
+ nResult = DosRead( pInstanceData->hFile,(PVOID)pData,nSize,&nCount );
+ if( nResult )
+ SetError(::GetSvError(nResult) );
+ }
+ return nCount;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::PutData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+ULONG SvFileStream::PutData( const void* pData, ULONG nSize )
+{
+#ifdef DBG_UTIL
+ ByteString aTraceStr( "SvFileStrean::PutData: " );
+ aTraceStr += ByteString::CreateFromInt64(nSize);
+ aTraceStr += " Bytes to ";
+ aTraceStr += ByteString(aFilename, osl_getThreadTextEncoding());
+ DBG_TRACE( aTraceStr.GetBuffer() );
+#endif
+
+ ULONG nCount = 0L;
+ if( IsOpen() )
+ {
+ APIRET nResult;
+ nResult = DosWrite( pInstanceData->hFile,(PVOID)pData,nSize,&nCount );
+ if( nResult )
+ SetError(::GetSvError(nResult) );
+ else if( !nCount )
+ SetError( SVSTREAM_DISK_FULL );
+ }
+ return nCount;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::SeekPos()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+ULONG SvFileStream::SeekPos( ULONG nPos )
+{
+ ULONG nNewPos = 0L;
+ if( IsOpen() )
+ {
+ APIRET nResult;
+
+ if( nPos != STREAM_SEEK_TO_END )
+ nResult = DosSetFilePtr( pInstanceData->hFile,(long)nPos,
+ FILE_BEGIN, &nNewPos );
+ else
+ nResult = DosSetFilePtr( pInstanceData->hFile,0L,
+ FILE_END, &nNewPos );
+
+ if( nResult )
+ SetError(::GetSvError(nResult) );
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return nNewPos;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::Tell()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+/*
+ULONG SvFileStream::Tell()
+{
+ ULONG nPos = 0L;
+
+ if( IsOpen() )
+ {
+ APIRET nResult;
+ nResult = DosSetFilePtr(pInstanceData->hFile,0L,FILE_CURRENT,&nPos);
+ if( nResult )
+ SetError(::GetSvError(nResult) );
+ }
+ return nPos;
+}
+*/
+
+/*************************************************************************
+|*
+|* SvFileStream::FlushData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+void SvFileStream::FlushData()
+{
+ if( IsOpen() )
+ {
+ APIRET nResult;
+ nResult = DosResetBuffer(pInstanceData->hFile );
+ if( nResult )
+ SetError(::GetSvError(nResult) );
+ }
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::LockRange()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvFileStream::LockRange( ULONG nByteOffset, ULONG nBytes )
+{
+ sal_Bool bRetVal = FALSE;
+ if( IsOpen() )
+ {
+ APIRET nResult;
+ FILELOCK aLockArea, aUnlockArea;
+ aUnlockArea.lOffset = 0L;
+ aUnlockArea.lRange = 0L;
+ aLockArea.lOffset = (long)nByteOffset;
+ aLockArea.lRange = (long)nBytes;
+
+ nResult = DosSetFileLocks(pInstanceData->hFile,
+ &aUnlockArea, &aLockArea,
+ 1000UL, // Zeit in ms bis Abbruch
+ 0L // kein Atomic-Lock
+ );
+
+ if( nResult )
+ SetError(::GetSvError(nResult) );
+ else
+ bRetVal = TRUE;
+ }
+ return bRetVal;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::UnlockRange()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvFileStream::UnlockRange( ULONG nByteOffset, ULONG nBytes )
+{
+ sal_Bool bRetVal = FALSE;
+ if( IsOpen() )
+ {
+ APIRET nResult;
+ FILELOCK aLockArea, aUnlockArea;
+ aLockArea.lOffset = 0L;
+ aLockArea.lRange = 0L;
+ aUnlockArea.lOffset = (long)nByteOffset;
+ aUnlockArea.lRange = (long)nBytes;
+
+ nResult = DosSetFileLocks(pInstanceData->hFile,
+ &aUnlockArea, &aLockArea,
+ 1000UL, // Zeit in ms bis Abbruch
+ 0L // kein Atomic-Lock
+ );
+
+ if( nResult )
+ SetError(::GetSvError(nResult) );
+ else
+ bRetVal = TRUE;
+ }
+ return bRetVal;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::LockFile()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvFileStream::LockFile()
+{
+ sal_Bool bRetVal = FALSE;
+ if( !nLockCounter )
+ {
+ if( LockRange( 0L, LONG_MAX ) )
+ {
+ nLockCounter = 1;
+ bRetVal = TRUE;
+ }
+ }
+ else
+ {
+ nLockCounter++;
+ bRetVal = TRUE;
+ }
+ return bRetVal;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::UnlockFile()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvFileStream::UnlockFile()
+{
+ sal_Bool bRetVal = FALSE;
+ if( nLockCounter > 0)
+ {
+ if( nLockCounter == 1)
+ {
+ if( UnlockRange( 0L, LONG_MAX ) )
+ {
+ nLockCounter = 0;
+ bRetVal = TRUE;
+ }
+ }
+ else
+ {
+ nLockCounter--;
+ bRetVal = TRUE;
+ }
+ }
+ return bRetVal;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::Open()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+void SvFileStream::Open( const String& rFilename, StreamMode nOpenMode )
+{
+ String aParsedFilename;
+
+ {
+ aParsedFilename = rFilename;
+ }
+
+ Close();
+ SvStream::ClearBuffer();
+
+ ULONG nActionTaken;
+ ULONG nOpenAction = 0L;
+ ULONG nShareBits = 0L;
+ ULONG nReadWriteBits = 0L;
+
+ eStreamMode = nOpenMode;
+ eStreamMode &= ~STREAM_TRUNC; // beim ReOpen nicht cutten
+
+ nOpenMode |= STREAM_SHARE_DENYNONE; // definierten Zustand garantieren
+
+ // ********* Zugriffsflags ***********
+ if( nOpenMode & STREAM_SHARE_DENYNONE)
+ nShareBits = OPEN_SHARE_DENYNONE;
+
+ if( nOpenMode & STREAM_SHARE_DENYREAD)
+ nShareBits = OPEN_SHARE_DENYREAD;
+
+ if( nOpenMode & STREAM_SHARE_DENYWRITE)
+ nShareBits = OPEN_SHARE_DENYWRITE;
+
+ if( nOpenMode & STREAM_SHARE_DENYALL)
+ nShareBits = OPEN_SHARE_DENYREADWRITE;
+
+ if( (nOpenMode & STREAM_READ) )
+ {
+ if( nOpenMode & STREAM_WRITE )
+ nReadWriteBits |= OPEN_ACCESS_READWRITE;
+ else
+ {
+ nReadWriteBits |= OPEN_ACCESS_READONLY;
+ nOpenMode |= STREAM_NOCREATE;
+ }
+ }
+ else
+ nReadWriteBits |= OPEN_ACCESS_WRITEONLY;
+
+
+ if( nOpenMode & STREAM_NOCREATE )
+ {
+ // Datei nicht erzeugen
+ nOpenAction = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
+ }
+ else
+ {
+ // Datei erzeugen, wenn nicht vorhanden
+ nOpenAction = OPEN_ACTION_CREATE_IF_NEW;
+ if( nOpenMode & STREAM_TRUNC )
+ // Auf Nullaenge kuerzen, wenn existiert
+ nOpenAction |= OPEN_ACTION_REPLACE_IF_EXISTS;
+ else
+ // Inhalt der Datei nicht wegwerfen
+ nOpenAction |= OPEN_ACTION_OPEN_IF_EXISTS;
+ }
+
+ aFilename = aParsedFilename;
+ ByteString aFileNameA( aFilename, gsl_getSystemTextEncoding());
+ FSysRedirector::DoRedirect( aFilename );
+
+#ifdef DBG_UTIL
+ ByteString aTraceStr( "SvFileStream::Open(): " );
+ aTraceStr += aFileNameA;
+ DBG_TRACE( aTraceStr.GetBuffer() );
+#endif
+
+ APIRET nRet = DosOpen( aFileNameA.GetBuffer(), &pInstanceData->hFile,
+ &nActionTaken, 0L, FILE_NORMAL, nOpenAction,
+ nReadWriteBits | nShareBits | OPEN_FLAGS_NOINHERIT, 0L);
+
+ if( nRet == ERROR_TOO_MANY_OPEN_FILES )
+ {
+ long nToAdd = 10;
+ ULONG nCurMaxFH;
+ nRet = DosSetRelMaxFH( &nToAdd, &nCurMaxFH );
+ nRet = DosOpen( aFileNameA.GetBuffer(), &pInstanceData->hFile,
+ &nActionTaken, 0L, FILE_NORMAL, nOpenAction,
+ nReadWriteBits | nShareBits | OPEN_FLAGS_NOINHERIT, 0L);
+ }
+
+ // Bei Fehler pruefen, ob wir lesen duerfen
+ if( nRet==ERROR_ACCESS_DENIED || nRet==ERROR_SHARING_VIOLATION )
+ {
+ nReadWriteBits = OPEN_ACCESS_READONLY;
+ nRet = DosOpen( aFileNameA.GetBuffer(), &pInstanceData->hFile,
+ &nActionTaken, 0L, FILE_NORMAL, nOpenAction,
+ nReadWriteBits | nShareBits | OPEN_FLAGS_NOINHERIT, 0L);
+ }
+
+ if( nRet )
+ {
+ bIsOpen = FALSE;
+ SetError(::GetSvError(nRet) );
+ }
+ else
+ {
+ bIsOpen = TRUE;
+ pInstanceData->bIsEof = FALSE;
+ if( nReadWriteBits != OPEN_ACCESS_READONLY )
+ bIsWritable = TRUE;
+ }
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::ReOpen()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+void SvFileStream::ReOpen()
+{
+ if( !bIsOpen && aFilename.Len() )
+ Open( aFilename, eStreamMode );
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::Close()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+void SvFileStream::Close()
+{
+ if( IsOpen() )
+ {
+#ifdef DBG_UTIL
+ ByteString aTraceStr( "SvFileStream::Close(): " );
+ aTraceStr += ByteString(aFilename, osl_getThreadTextEncoding());
+ DBG_TRACE( aTraceStr.GetBuffer() );
+#endif
+
+ if( nLockCounter )
+ {
+ nLockCounter = 1;
+ UnlockFile();
+ }
+ Flush();
+ DosClose( pInstanceData->hFile );
+ }
+
+ bIsOpen = FALSE;
+ nLockCounter= 0;
+ bIsWritable = FALSE;
+ pInstanceData->bIsEof = TRUE;
+ SvStream::ClearBuffer();
+ SvStream::ClearError();
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::ResetError()
+|*
+|* Beschreibung STREAM.SDW; Setzt Filepointer auf Dateianfang
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+void SvFileStream::ResetError()
+{
+ SvStream::ClearError();
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::SetSize()
+|*
+|* Beschreibung
+|* Ersterstellung OV 19.10.95
+|* Letzte Aenderung OV 19.10.95
+|*
+*************************************************************************/
+
+void SvFileStream::SetSize( ULONG nSize )
+{
+ if( IsOpen() )
+ {
+ APIRET nRet = DosSetFileSize( pInstanceData->hFile, nSize );
+ if( nRet )
+ SetError( ::GetSvError( nRet ) );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/stream/strmsys.cxx b/tools/source/stream/strmsys.cxx
new file mode 100644
index 000000000000..9a1ce77d256e
--- /dev/null
+++ b/tools/source/stream/strmsys.cxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#if defined WNT
+#include "strmwnt.cxx"
+#elif defined UNX
+#include "strmunx.cxx"
+#elif defined OS2
+#include "strmos2.cxx"
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/stream/strmunx.cxx b/tools/source/stream/strmunx.cxx
new file mode 100644
index 000000000000..61313bce3f0b
--- /dev/null
+++ b/tools/source/stream/strmunx.cxx
@@ -0,0 +1,924 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// no include "precompiled_tools.hxx" because this file is included in strmsys.cxx
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <limits.h>
+#include <stdlib.h> // fuer getenv()
+
+#include <tools/debug.hxx>
+#include <tools/fsys.hxx>
+#include <tools/stream.hxx>
+
+#include <osl/mutex.hxx>
+#include <osl/thread.h> // osl_getThreadTextEncoding
+
+// class FileBase
+#include <osl/file.hxx>
+#include <rtl/instance.hxx>
+
+using namespace osl;
+
+// -----------------------------------------------------------------------
+
+// ----------------
+// - InternalLock -
+// ----------------
+
+class InternalStreamLock;
+DECLARE_LIST( InternalStreamLockList, InternalStreamLock* )
+namespace { struct LockList : public rtl::Static< InternalStreamLockList, LockList > {}; }
+
+#ifndef BOOTSTRAP
+namespace { struct LockMutex : public rtl::Static< osl::Mutex, LockMutex > {}; }
+#endif
+
+class InternalStreamLock
+{
+ sal_Size m_nStartPos;
+ sal_Size m_nEndPos;
+ SvFileStream* m_pStream;
+ struct stat m_aStat;
+
+ InternalStreamLock( sal_Size, sal_Size, SvFileStream* );
+ ~InternalStreamLock();
+public:
+ static sal_Bool LockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* );
+ static void UnlockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* );
+};
+
+InternalStreamLock::InternalStreamLock(
+ sal_Size nStart,
+ sal_Size nEnd,
+ SvFileStream* pStream ) :
+ m_nStartPos( nStart ),
+ m_nEndPos( nEnd ),
+ m_pStream( pStream )
+{
+ ByteString aFileName(m_pStream->GetFileName(), osl_getThreadTextEncoding());
+ stat( aFileName.GetBuffer(), &m_aStat );
+ LockList::get().Insert( this, LIST_APPEND );
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "locked %s", aFileName.GetBuffer() );
+ if( m_nStartPos || m_nEndPos )
+ fprintf(stderr, " [ %ld ... %ld ]", m_nStartPos, m_nEndPos );
+ fprintf( stderr, "\n" );
+#endif
+}
+
+InternalStreamLock::~InternalStreamLock()
+{
+ LockList::get().Remove( this );
+#if OSL_DEBUG_LEVEL > 1
+ ByteString aFileName(m_pStream->GetFileName(), osl_getThreadTextEncoding());
+ fprintf( stderr, "unlocked %s", aFileName.GetBuffer() );
+ if( m_nStartPos || m_nEndPos )
+ fprintf(stderr, " [ %ld ... %ld ]", m_nStartPos, m_nEndPos );
+ fprintf( stderr, "\n" );
+#endif
+}
+
+sal_Bool InternalStreamLock::LockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream )
+{
+#ifndef BOOTSTRAP
+ osl::MutexGuard aGuard( LockMutex::get() );
+#endif
+ ByteString aFileName(pStream->GetFileName(), osl_getThreadTextEncoding());
+ struct stat aStat;
+ if( stat( aFileName.GetBuffer(), &aStat ) )
+ return sal_False;
+
+ if( S_ISDIR( aStat.st_mode ) )
+ return sal_True;
+
+ InternalStreamLock* pLock = NULL;
+ InternalStreamLockList &rLockList = LockList::get();
+ for( ULONG i = 0; i < rLockList.Count(); ++i )
+ {
+ pLock = rLockList.GetObject( i );
+ if( aStat.st_ino == pLock->m_aStat.st_ino )
+ {
+ sal_Bool bDenyByOptions = sal_False;
+ StreamMode nLockMode = pLock->m_pStream->GetStreamMode();
+ StreamMode nNewMode = pStream->GetStreamMode();
+
+ if( nLockMode & STREAM_SHARE_DENYALL )
+ bDenyByOptions = sal_True;
+ else if( ( nLockMode & STREAM_SHARE_DENYWRITE ) &&
+ ( nNewMode & STREAM_WRITE ) )
+ bDenyByOptions = sal_True;
+ else if( ( nLockMode & STREAM_SHARE_DENYREAD ) &&
+ ( nNewMode & STREAM_READ ) )
+ bDenyByOptions = sal_True;
+
+ if( bDenyByOptions )
+ {
+ if( pLock->m_nStartPos == 0 && pLock->m_nEndPos == 0 ) // whole file is already locked
+ return sal_False;
+ if( nStart == 0 && nEnd == 0) // cannot lock whole file
+ return sal_False;
+
+ if( ( nStart < pLock->m_nStartPos && nEnd > pLock->m_nStartPos ) ||
+ ( nStart < pLock->m_nEndPos && nEnd > pLock->m_nEndPos ) )
+ return sal_False;
+ }
+ }
+ }
+ pLock = new InternalStreamLock( nStart, nEnd, pStream );
+ return sal_True;
+}
+
+void InternalStreamLock::UnlockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream )
+{
+#ifndef BOOTSTRAP
+ osl::MutexGuard aGuard( LockMutex::get() );
+#endif
+ InternalStreamLock* pLock = NULL;
+ InternalStreamLockList &rLockList = LockList::get();
+ if( nStart == 0 && nEnd == 0 )
+ {
+ for( ULONG i = 0; i < rLockList.Count(); ++i )
+ {
+ if( ( pLock = rLockList.GetObject( i ) )->m_pStream == pStream )
+ {
+ delete pLock;
+ i--;
+ }
+ }
+ return;
+ }
+ for( ULONG i = 0; i < rLockList.Count(); ++i )
+ {
+ if( ( pLock = rLockList.GetObject( i ) )->m_pStream == pStream &&
+ nStart == pLock->m_nStartPos && nEnd == pLock->m_nEndPos )
+ {
+ delete pLock;
+ return;
+ }
+ }
+}
+
+// --------------
+// - StreamData -
+// --------------
+
+class StreamData
+{
+public:
+ int nHandle;
+
+ StreamData() { nHandle = 0; }
+};
+
+// -----------------------------------------------------------------------
+
+static sal_uInt32 GetSvError( int nErrno )
+{
+ static struct { int nErr; sal_uInt32 sv; } errArr[] =
+ {
+ { 0, SVSTREAM_OK },
+ { EACCES, SVSTREAM_ACCESS_DENIED },
+ { EBADF, SVSTREAM_INVALID_HANDLE },
+#if defined( RS6000 ) || defined( ALPHA ) || defined( HP9000 ) || defined( NETBSD ) || defined(FREEBSD) || defined(MACOSX) || \
+ defined(OPENBSD) || defined(__FreeBSD_kernel__) || defined ( AIX )
+ { EDEADLK, SVSTREAM_LOCKING_VIOLATION },
+#else
+ { EDEADLOCK, SVSTREAM_LOCKING_VIOLATION },
+#endif
+ { EINVAL, SVSTREAM_INVALID_PARAMETER },
+ { EMFILE, SVSTREAM_TOO_MANY_OPEN_FILES },
+ { ENFILE, SVSTREAM_TOO_MANY_OPEN_FILES },
+ { ENOENT, SVSTREAM_FILE_NOT_FOUND },
+ { EPERM, SVSTREAM_ACCESS_DENIED },
+ { EROFS, SVSTREAM_ACCESS_DENIED },
+ { EAGAIN, SVSTREAM_LOCKING_VIOLATION },
+ { EISDIR, SVSTREAM_PATH_NOT_FOUND },
+ { ELOOP, SVSTREAM_PATH_NOT_FOUND },
+#if ! defined( RS6000 ) && ! defined( ALPHA ) && ! defined( NETBSD ) && ! defined (FREEBSD) && ! defined (MACOSX) && \
+ !defined(OPENBSD) && ! defined(__FreeBSD_kernel__)
+ { EMULTIHOP, SVSTREAM_PATH_NOT_FOUND },
+ { ENOLINK, SVSTREAM_PATH_NOT_FOUND },
+#endif
+ { ENOTDIR, SVSTREAM_PATH_NOT_FOUND },
+ { ETXTBSY, SVSTREAM_ACCESS_DENIED },
+ { EEXIST, SVSTREAM_CANNOT_MAKE },
+ { ENOSPC, SVSTREAM_DISK_FULL },
+ { (int)0xFFFF, SVSTREAM_GENERALERROR }
+ };
+
+ sal_uInt32 nRetVal = SVSTREAM_GENERALERROR; // Standardfehler
+ int i=0;
+ do
+ {
+ if ( errArr[i].nErr == nErrno )
+ {
+ nRetVal = errArr[i].sv;
+ break;
+ }
+ ++i;
+ }
+ while( errArr[i].nErr != 0xFFFF );
+ return nRetVal;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::SvFileStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+SvFileStream::SvFileStream( const String& rFileName, StreamMode nOpenMode )
+{
+ bIsOpen = sal_False;
+ nLockCounter = 0;
+ bIsWritable = sal_False;
+ pInstanceData = new StreamData;
+
+ SetBufferSize( 1024 );
+ // convert URL to SystemPath, if necessary
+ ::rtl::OUString aSystemFileName;
+ if( FileBase::getSystemPathFromFileURL( rFileName , aSystemFileName )
+ != FileBase::E_None )
+ {
+ aSystemFileName = rFileName;
+ }
+ Open( aSystemFileName, nOpenMode );
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::SvFileStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 22.11.94
+|* Letzte Aenderung OV 22.11.94
+|*
+*************************************************************************/
+
+SvFileStream::SvFileStream()
+{
+ bIsOpen = sal_False;
+ nLockCounter = 0;
+ bIsWritable = sal_False;
+ pInstanceData = new StreamData;
+ SetBufferSize( 1024 );
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::~SvFileStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 22.11.94
+|* Letzte Aenderung OV 22.11.94
+|*
+*************************************************************************/
+
+SvFileStream::~SvFileStream()
+{
+ Close();
+
+ InternalStreamLock::UnlockFile( 0, 0, this );
+
+ if (pInstanceData)
+ delete pInstanceData;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::GetFileHandle()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 22.11.94
+|* Letzte Aenderung OV 22.11.94
+|*
+*************************************************************************/
+
+sal_uInt32 SvFileStream::GetFileHandle() const
+{
+ return (sal_uInt32)pInstanceData->nHandle;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::IsA()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 14.06.94
+|* Letzte Aenderung OV 14.06.94
+|*
+*************************************************************************/
+
+sal_uInt16 SvFileStream::IsA() const
+{
+ return ID_FILESTREAM;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::GetData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+sal_Size SvFileStream::GetData( void* pData, sal_Size nSize )
+{
+#ifdef DBG_UTIL
+ ByteString aTraceStr( "SvFileStream::GetData(): " );
+ aTraceStr += ByteString::CreateFromInt64(nSize);
+ aTraceStr += " Bytes from ";
+ aTraceStr += ByteString(aFilename, osl_getThreadTextEncoding());
+ DBG_TRACE( aTraceStr.GetBuffer() );
+#endif
+
+ int nRead = 0;
+ if ( IsOpen() )
+ {
+ nRead = read(pInstanceData->nHandle,pData,(unsigned)nSize);
+ if ( nRead == -1 )
+ SetError( ::GetSvError( errno ));
+ }
+ return (sal_Size)nRead;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::PutData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+sal_Size SvFileStream::PutData( const void* pData, sal_Size nSize )
+{
+#ifdef DBG_UTIL
+ ByteString aTraceStr( "SvFileStrean::PutData: " );
+ aTraceStr += ByteString::CreateFromInt64(nSize);
+ aTraceStr += " Bytes to ";
+ aTraceStr += ByteString(aFilename, osl_getThreadTextEncoding());
+ DBG_TRACE( aTraceStr.GetBuffer() );
+#endif
+
+ int nWrite = 0;
+ if ( IsOpen() )
+ {
+ nWrite = write(pInstanceData->nHandle,pData,(unsigned)nSize);
+ if ( nWrite == -1 )
+ SetError( ::GetSvError( errno ) );
+ else if( !nWrite )
+ SetError( SVSTREAM_DISK_FULL );
+ }
+ return (sal_Size)nWrite;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::SeekPos()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+sal_Size SvFileStream::SeekPos( sal_Size nPos )
+{
+ if ( IsOpen() )
+ {
+ long nNewPos;
+ if ( nPos != STREAM_SEEK_TO_END )
+ nNewPos = lseek( pInstanceData->nHandle, (long)nPos, SEEK_SET );
+ else
+ nNewPos = lseek( pInstanceData->nHandle, 0L, SEEK_END );
+
+ if ( nNewPos == -1 )
+ {
+ SetError( SVSTREAM_SEEK_ERROR );
+ return 0L;
+ }
+ // langsam aber sicherer als return nNewPos
+ return lseek(pInstanceData->nHandle,0L,SEEK_CUR);
+ // return nNewPos;
+ }
+ SetError( SVSTREAM_GENERALERROR );
+ return 0L;
+}
+
+
+/*************************************************************************
+|*
+|* SvFileStream::FlushData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+void SvFileStream::FlushData()
+{
+// lokal gibt es nicht
+}
+
+static char *pFileLockEnvVar = (char*)1;
+
+/*************************************************************************
+|*
+|* SvFileStream::LockRange()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvFileStream::LockRange( sal_Size nByteOffset, sal_Size nBytes )
+{
+ struct flock aflock;
+ aflock.l_start = nByteOffset;
+ aflock.l_whence = SEEK_SET;
+ aflock.l_len = nBytes;
+
+ int nLockMode = 0;
+
+ if ( ! IsOpen() )
+ return sal_False;
+
+ if ( eStreamMode & STREAM_SHARE_DENYALL )
+ {
+ if (bIsWritable)
+ nLockMode = F_WRLCK;
+ else
+ nLockMode = F_RDLCK;
+ }
+
+ if ( eStreamMode & STREAM_SHARE_DENYREAD )
+ {
+ if (bIsWritable)
+ nLockMode = F_WRLCK;
+ else
+ {
+ SetError(SVSTREAM_LOCKING_VIOLATION);
+ return sal_False;
+ }
+ }
+
+ if ( eStreamMode & STREAM_SHARE_DENYWRITE )
+ {
+ if (bIsWritable)
+ nLockMode = F_WRLCK;
+ else
+ nLockMode = F_RDLCK;
+ }
+
+ if (!nLockMode)
+ return sal_True;
+
+ if( ! InternalStreamLock::LockFile( nByteOffset, nByteOffset+nBytes, this ) )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "InternalLock on %s [ %ld ... %ld ] failed\n",
+ ByteString(aFilename, osl_getThreadTextEncoding()).GetBuffer(), nByteOffset, nByteOffset+nBytes );
+#endif
+ return sal_False;
+ }
+
+ // HACK: File-Locking nur via Environmentvariable einschalten
+ // um einen Haenger im Zusammenspiel mit einem Linux
+ // NFS-2-Server (kein Lockdaemon) zu verhindern.
+ // File-Locking ?ber NFS ist generell ein Performancekiller.
+ // HR, 22.10.1997 fuer SOLARIS
+ // CP, 30.11.1997 fuer HPUX
+ // ER, 18.12.1997 fuer IRIX
+ // HR, 18.05.1998 Environmentvariable
+
+ if ( pFileLockEnvVar == (char*)1 )
+ pFileLockEnvVar = getenv("STAR_ENABLE_FILE_LOCKING");
+ if ( ! pFileLockEnvVar )
+ return sal_True;
+
+ aflock.l_type = nLockMode;
+ if (fcntl(pInstanceData->nHandle, F_GETLK, &aflock) == -1)
+ {
+ #if ( defined HPUX && defined BAD_UNION )
+ #ifdef DBG_UTIL
+ fprintf( stderr, "***** FCNTL(lock):errno = %d\n", errno );
+ #endif
+ if ( errno == EINVAL || errno == ENOSYS )
+ return sal_True;
+ #endif
+ #if defined SINIX
+ if (errno == EINVAL)
+ return sal_True;
+ #endif
+ #if defined SOLARIS
+ if (errno == ENOSYS)
+ return sal_True;
+ #endif
+ SetError( ::GetSvError( errno ));
+ return sal_False;
+ }
+ if (aflock.l_type != F_UNLCK)
+ {
+ SetError(SVSTREAM_LOCKING_VIOLATION);
+ return sal_False;
+ }
+
+ aflock.l_type = nLockMode;
+ if (fcntl(pInstanceData->nHandle, F_SETLK, &aflock) == -1)
+ {
+ SetError( ::GetSvError( errno ));
+ return sal_False;
+ }
+ return sal_True;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::UnlockRange()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvFileStream::UnlockRange( sal_Size nByteOffset, sal_Size nBytes )
+{
+
+ struct flock aflock;
+ aflock.l_type = F_UNLCK;
+ aflock.l_start = nByteOffset;
+ aflock.l_whence = SEEK_SET;
+ aflock.l_len = nBytes;
+
+ if ( ! IsOpen() )
+ return sal_False;
+
+ InternalStreamLock::UnlockFile( nByteOffset, nByteOffset+nBytes, this );
+
+ if ( ! (eStreamMode &
+ (STREAM_SHARE_DENYALL | STREAM_SHARE_DENYREAD | STREAM_SHARE_DENYWRITE)))
+ return sal_True;
+
+ // wenn File Locking ausgeschaltet, siehe SvFileStream::LockRange
+ if ( ! pFileLockEnvVar )
+ return sal_True;
+
+ if (fcntl(pInstanceData->nHandle, F_SETLK, &aflock) != -1)
+ return sal_True;
+
+#if ( defined HPUX && defined BAD_UNION )
+#ifdef DBG_UTIL
+ fprintf( stderr, "***** FCNTL(unlock):errno = %d\n", errno );
+#endif
+ if ( errno == EINVAL || errno == ENOSYS )
+ return sal_True;
+#endif
+#if ( defined SINIX )
+ if (errno == EINVAL)
+ return sal_True;
+#endif
+
+ SetError( ::GetSvError( errno ));
+ return sal_False;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::LockFile()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvFileStream::LockFile()
+{
+ return LockRange( 0UL, 0UL );
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::UnlockFile()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvFileStream::UnlockFile()
+{
+ return UnlockRange( 0UL, 0UL );
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::Open()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+void SvFileStream::Open( const String& rFilename, StreamMode nOpenMode )
+{
+ int nAccess, nAccessRW;
+ int nMode;
+ int nHandleTmp;
+ struct stat buf;
+ sal_Bool bStatValid = sal_False;
+
+ Close();
+ errno = 0;
+ eStreamMode = nOpenMode;
+ eStreamMode &= ~STREAM_TRUNC; // beim ReOpen nicht cutten
+
+// !!! NoOp: Ansonsten ToAbs() verwendern
+// !!! DirEntry aDirEntry( rFilename );
+// !!! aFilename = aDirEntry.GetFull();
+ aFilename = rFilename;
+#ifndef BOOTSTRAP
+ FSysRedirector::DoRedirect( aFilename );
+#endif
+ ByteString aLocalFilename(aFilename, osl_getThreadTextEncoding());
+
+#ifdef DBG_UTIL
+ ByteString aTraceStr( "SvFileStream::Open(): " );
+ aTraceStr += aLocalFilename;
+ DBG_TRACE( aTraceStr.GetBuffer() );
+#endif
+
+ if ( lstat( aLocalFilename.GetBuffer(), &buf ) == 0 )
+ {
+ bStatValid = sal_True;
+ // SvFileStream soll kein Directory oeffnen
+ if( S_ISDIR( buf.st_mode ) )
+ {
+ SetError( ::GetSvError( EISDIR ) );
+ return;
+ }
+ }
+
+
+ if ( !( nOpenMode & STREAM_WRITE ) )
+ nAccessRW = O_RDONLY;
+ else if ( !( nOpenMode & STREAM_READ ) )
+ nAccessRW = O_WRONLY;
+ else
+ nAccessRW = O_RDWR;
+
+ nAccess = 0;
+ // Fix (MDA, 18.01.95): Bei RD_ONLY nicht mit O_CREAT oeffnen
+ // Wichtig auf Read-Only-Dateisystemen (wie CDROM)
+ if ( (!( nOpenMode & STREAM_NOCREATE )) && ( nAccessRW != O_RDONLY ) )
+ nAccess |= O_CREAT;
+ if ( nOpenMode & STREAM_TRUNC )
+ nAccess |= O_TRUNC;
+
+ nMode = S_IREAD | S_IROTH | S_IRGRP;
+ if ( nOpenMode & STREAM_WRITE)
+ {
+ nMode |= (S_IWRITE | S_IWOTH | S_IWGRP);
+
+ if ( nOpenMode & STREAM_COPY_ON_SYMLINK )
+ {
+ if ( bStatValid && S_ISLNK( buf.st_mode ) < 0 )
+ {
+ char *pBuf = new char[ 1024+1 ];
+ if ( readlink( aLocalFilename.GetBuffer(), pBuf, 1024 ) > 0 )
+ {
+ if ( unlink(aLocalFilename.GetBuffer()) == 0 )
+ {
+#ifdef DBG_UTIL
+ fprintf( stderr,
+ "Copying file on symbolic link (%s).\n",
+ aLocalFilename.GetBuffer() );
+#endif
+ String aTmpString( pBuf, osl_getThreadTextEncoding() );
+ const DirEntry aSourceEntry( aTmpString );
+ const DirEntry aTargetEntry( aFilename );
+ FileCopier aFileCopier( aSourceEntry, aTargetEntry );
+ aFileCopier.Execute();
+ }
+ }
+ delete [] pBuf;
+ }
+ }
+ }
+
+
+ nHandleTmp = open(aLocalFilename.GetBuffer(),nAccessRW|nAccess, nMode );
+
+ if ( nHandleTmp == -1 )
+ {
+ if ( nAccessRW != O_RDONLY )
+ {
+ // auf Lesen runterschalten
+ nAccessRW = O_RDONLY;
+ nAccess = 0;
+ nMode = S_IREAD | S_IROTH | S_IRGRP;
+ nHandleTmp =open( aLocalFilename.GetBuffer(),
+ nAccessRW|nAccess,
+ nMode );
+ }
+ }
+ if ( nHandleTmp != -1 )
+ {
+ pInstanceData->nHandle = nHandleTmp;
+ bIsOpen = sal_True;
+ if ( nAccessRW != O_RDONLY )
+ bIsWritable = sal_True;
+
+ if ( !LockFile() ) // ganze Datei
+ {
+ close( nHandleTmp );
+ bIsOpen = sal_False;
+ bIsWritable = sal_False;
+ pInstanceData->nHandle = 0;
+ }
+ }
+ else
+ SetError( ::GetSvError( errno ) );
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::ReOpen()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+void SvFileStream::ReOpen()
+{
+ if ( !bIsOpen && aFilename.Len() )
+ Open( aFilename, eStreamMode );
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::Close()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+void SvFileStream::Close()
+{
+ InternalStreamLock::UnlockFile( 0, 0, this );
+
+ if ( IsOpen() )
+ {
+#ifdef DBG_UTIL
+ ByteString aTraceStr( "SvFileStream::Close(): " );
+ aTraceStr += ByteString(aFilename, osl_getThreadTextEncoding());
+ DBG_TRACE( aTraceStr.GetBuffer() );
+#endif
+
+ Flush();
+ close( pInstanceData->nHandle );
+ pInstanceData->nHandle = 0;
+ }
+
+ bIsOpen = sal_False;
+ bIsWritable = sal_False;
+ SvStream::ClearBuffer();
+ SvStream::ClearError();
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::ResetError()
+|*
+|* Beschreibung STREAM.SDW; Setzt Filepointer auf Dateianfang
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+void SvFileStream::ResetError()
+{
+ SvStream::ClearError();
+}
+
+
+/*************************************************************************
+|*
+|* SvFileStream::SetSize()
+|*
+|* Beschreibung STREAM.SDW;
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+void SvFileStream::SetSize (sal_Size nSize)
+{
+ if (IsOpen())
+ {
+ int fd = pInstanceData->nHandle;
+ if (::ftruncate (fd, (off_t)nSize) < 0)
+ {
+ // Save original error.
+ sal_uInt32 nErr = ::GetSvError (errno);
+
+ // Check against current size. Fail upon 'shrink'.
+ struct stat aStat;
+ if (::fstat (fd, &aStat) < 0)
+ {
+ SetError (nErr);
+ return;
+ }
+ if ((sal::static_int_cast< sal_sSize >(nSize) <= aStat.st_size))
+ {
+ // Failure upon 'shrink'. Return original error.
+ SetError (nErr);
+ return;
+ }
+
+ // Save current position.
+ sal_Size nCurPos = (sal_Size)::lseek (fd, (off_t)0, SEEK_CUR);
+ if (nCurPos == (sal_Size)(-1))
+ {
+ SetError (nErr);
+ return;
+ }
+
+ // Try 'expand' via 'lseek()' and 'write()'.
+ if (::lseek (fd, (off_t)(nSize - 1), SEEK_SET) < 0)
+ {
+ SetError (nErr);
+ return;
+ }
+ if (::write (fd, (char*)"", (size_t)1) < 0)
+ {
+ // Failure. Restore saved position.
+ if (::lseek (fd, (off_t)nCurPos, SEEK_SET) < 0)
+ {
+ // Double failure.
+ }
+
+ SetError (nErr);
+ return;
+ }
+
+ // Success. Restore saved position.
+ if (::lseek (fd, (off_t)nCurPos, SEEK_SET) < 0)
+ {
+ SetError (nErr);
+ return;
+ }
+ }
+ }
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/stream/strmwnt.cxx b/tools/source/stream/strmwnt.cxx
new file mode 100644
index 000000000000..107e1a0bcfda
--- /dev/null
+++ b/tools/source/stream/strmwnt.cxx
@@ -0,0 +1,691 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// no include "precompiled_tools.hxx" because this file is included in strmsys.cxx
+
+/*
+ Todo: StreamMode <-> AllocateMemory
+*/
+
+#include <string.h>
+#include <limits.h>
+
+#include <tools/svwin.h>
+
+#include <tools/debug.hxx>
+#include <tools/fsys.hxx>
+#include <tools/stream.hxx>
+
+// class FileBase
+#include <osl/file.hxx>
+using namespace osl;
+
+// -----------------------------------------------------------------------
+
+// --------------
+// - StreamData -
+// --------------
+
+class StreamData
+{
+public:
+ HANDLE hFile;
+
+ StreamData()
+ {
+ hFile = 0;
+ }
+};
+
+// -----------------------------------------------------------------------
+
+static ULONG GetSvError( DWORD nWntError )
+{
+ static struct { DWORD wnt; ULONG sv; } errArr[] =
+ {
+ { ERROR_SUCCESS, SVSTREAM_OK },
+ { ERROR_ACCESS_DENIED, SVSTREAM_ACCESS_DENIED },
+ { ERROR_ACCOUNT_DISABLED, SVSTREAM_ACCESS_DENIED },
+ { ERROR_ACCOUNT_EXPIRED, SVSTREAM_ACCESS_DENIED },
+ { ERROR_ACCOUNT_RESTRICTION, SVSTREAM_ACCESS_DENIED },
+ { ERROR_ATOMIC_LOCKS_NOT_SUPPORTED, SVSTREAM_INVALID_PARAMETER },
+ { ERROR_BAD_PATHNAME, SVSTREAM_PATH_NOT_FOUND },
+ // Filename too long
+ { ERROR_BUFFER_OVERFLOW, SVSTREAM_INVALID_PARAMETER },
+ { ERROR_DIRECTORY, SVSTREAM_INVALID_PARAMETER },
+ { ERROR_DRIVE_LOCKED, SVSTREAM_LOCKING_VIOLATION },
+ { ERROR_FILE_NOT_FOUND, SVSTREAM_FILE_NOT_FOUND },
+ { ERROR_FILENAME_EXCED_RANGE, SVSTREAM_INVALID_PARAMETER },
+ { ERROR_INVALID_ACCESS, SVSTREAM_INVALID_ACCESS },
+ { ERROR_INVALID_DRIVE, SVSTREAM_PATH_NOT_FOUND },
+ { ERROR_INVALID_HANDLE, SVSTREAM_INVALID_HANDLE },
+ { ERROR_INVALID_NAME, SVSTREAM_PATH_NOT_FOUND },
+ { ERROR_INVALID_PARAMETER, SVSTREAM_INVALID_PARAMETER },
+ { ERROR_IS_SUBST_PATH, SVSTREAM_INVALID_PARAMETER },
+ { ERROR_IS_SUBST_TARGET, SVSTREAM_INVALID_PARAMETER },
+ { ERROR_LOCK_FAILED, SVSTREAM_LOCKING_VIOLATION },
+ { ERROR_LOCK_VIOLATION, SVSTREAM_LOCKING_VIOLATION },
+ { ERROR_NEGATIVE_SEEK, SVSTREAM_SEEK_ERROR },
+ { ERROR_PATH_NOT_FOUND, SVSTREAM_PATH_NOT_FOUND },
+ { ERROR_READ_FAULT, SVSTREAM_READ_ERROR },
+ { ERROR_SEEK, SVSTREAM_SEEK_ERROR },
+ { ERROR_SEEK_ON_DEVICE, SVSTREAM_SEEK_ERROR },
+ { ERROR_SHARING_BUFFER_EXCEEDED,SVSTREAM_SHARE_BUFF_EXCEEDED },
+ { ERROR_SHARING_PAUSED, SVSTREAM_SHARING_VIOLATION },
+ { ERROR_SHARING_VIOLATION, SVSTREAM_SHARING_VIOLATION },
+ { ERROR_TOO_MANY_OPEN_FILES, SVSTREAM_TOO_MANY_OPEN_FILES },
+ { ERROR_WRITE_FAULT, SVSTREAM_WRITE_ERROR },
+ { ERROR_WRITE_PROTECT, SVSTREAM_ACCESS_DENIED },
+ { ERROR_DISK_FULL, SVSTREAM_DISK_FULL },
+
+ { (DWORD)0xFFFFFFFF, SVSTREAM_GENERALERROR }
+ };
+
+ ULONG nRetVal = SVSTREAM_GENERALERROR; // Standardfehler
+ int i=0;
+ do
+ {
+ if( errArr[i].wnt == nWntError )
+ {
+ nRetVal = errArr[i].sv;
+ break;
+ }
+ i++;
+ } while( errArr[i].wnt != (DWORD)0xFFFFFFFF );
+ return nRetVal;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::SvFileStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 17.06.94
+|* Letzte Aenderung TPF 15.07.98
+|*
+*************************************************************************/
+
+SvFileStream::SvFileStream( const String& rFileName, StreamMode nMode )
+{
+ bIsOpen = FALSE;
+ nLockCounter = 0;
+ bIsWritable = FALSE;
+ pInstanceData = new StreamData;
+
+ SetBufferSize( 8192 );
+ // convert URL to SystemPath, if necessary
+ ::rtl::OUString aFileName, aNormPath;
+
+ if ( FileBase::getSystemPathFromFileURL( rFileName, aFileName ) != FileBase::E_None )
+ aFileName = rFileName;
+ Open( aFileName, nMode );
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::SvFileStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 22.11.94
+|* Letzte Aenderung TPF 15.07.98
+|*
+*************************************************************************/
+
+SvFileStream::SvFileStream()
+{
+ bIsOpen = FALSE;
+ nLockCounter = 0;
+ bIsWritable = FALSE;
+ pInstanceData = new StreamData;
+
+ SetBufferSize( 8192 );
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::~SvFileStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 14.06.94
+|* Letzte Aenderung OV 14.06.94
+|*
+*************************************************************************/
+
+SvFileStream::~SvFileStream()
+{
+ Close();
+ if (pInstanceData)
+ delete pInstanceData;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::GetFileHandle()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 14.06.94
+|* Letzte Aenderung OV 14.06.94
+|*
+*************************************************************************/
+
+ULONG SvFileStream::GetFileHandle() const
+{
+ return (ULONG)pInstanceData->hFile;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::IsA()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 14.06.94
+|* Letzte Aenderung OV 14.06.94
+|*
+*************************************************************************/
+
+USHORT SvFileStream::IsA() const
+{
+ return ID_FILESTREAM;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::GetData()
+|*
+|* Beschreibung STREAM.SDW, Prueft nicht Eof; IsEof danach rufbar
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung TPF 15.07.98
+|*
+*************************************************************************/
+
+ULONG SvFileStream::GetData( void* pData, ULONG nSize )
+{
+ DWORD nCount = 0;
+ if( IsOpen() )
+ {
+ bool bResult = ReadFile(pInstanceData->hFile,(LPVOID)pData,nSize,&nCount,NULL);
+ if( !bResult )
+ {
+ ULONG nTestError = GetLastError();
+ SetError(::GetSvError( nTestError ) );
+ }
+ }
+ return (DWORD)nCount;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::PutData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung TPF 15.07.98
+|*
+*************************************************************************/
+
+ULONG SvFileStream::PutData( const void* pData, ULONG nSize )
+{
+ DWORD nCount = 0;
+ if( IsOpen() )
+ {
+ if(!WriteFile(pInstanceData->hFile,(LPVOID)pData,nSize,&nCount,NULL))
+ SetError(::GetSvError( GetLastError() ) );
+ }
+ return nCount;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::SeekPos()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung TPF 15.07.98
+|*
+*************************************************************************/
+
+ULONG SvFileStream::SeekPos( ULONG nPos )
+{
+ DWORD nNewPos = 0;
+ if( IsOpen() )
+ {
+ if( nPos != STREAM_SEEK_TO_END )
+ // 64-Bit files werden nicht unterstuetzt
+ nNewPos=SetFilePointer(pInstanceData->hFile,nPos,NULL,FILE_BEGIN);
+ else
+ nNewPos=SetFilePointer(pInstanceData->hFile,0L,NULL,FILE_END);
+
+ if( nNewPos == 0xFFFFFFFF )
+ {
+ SetError(::GetSvError( GetLastError() ) );
+ nNewPos = 0L;
+ }
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return (ULONG)nNewPos;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::Tell()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+/*
+ULONG SvFileStream::Tell()
+{
+ ULONG nPos = 0L;
+
+ if( IsOpen() )
+ {
+ DWORD nPos;
+ nPos = SetFilePointer(pInstanceData->hFile,0L,NULL,FILE_CURRENT);
+ if( nPos = 0xFFFFFFFF )
+ {
+ SetError( ::GetSvError( GetLastError() ) );
+ nPos = 0L;
+ }
+ }
+ return nPos;
+}
+*/
+
+/*************************************************************************
+|*
+|* SvFileStream::FlushData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung TPF 15.07.98
+|*
+*************************************************************************/
+
+void SvFileStream::FlushData()
+{
+ if( IsOpen() )
+ {
+ if( !FlushFileBuffers(pInstanceData->hFile) )
+ SetError(::GetSvError(GetLastError()));
+ }
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::LockRange()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung TPF 15.07.98
+|*
+*************************************************************************/
+
+BOOL SvFileStream::LockRange( ULONG nByteOffset, ULONG nBytes )
+{
+ bool bRetVal = false;
+ if( IsOpen() )
+ {
+ bRetVal = ::LockFile(pInstanceData->hFile,nByteOffset,0L,nBytes,0L );
+ if( !bRetVal )
+ SetError(::GetSvError(GetLastError()));
+ }
+ return bRetVal;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::UnlockRange()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung TPF 15.07.98
+|*
+*************************************************************************/
+
+BOOL SvFileStream::UnlockRange( ULONG nByteOffset, ULONG nBytes )
+{
+ bool bRetVal = false;
+ if( IsOpen() )
+ {
+ bRetVal = ::UnlockFile(pInstanceData->hFile,nByteOffset,0L,nBytes,0L );
+ if( !bRetVal )
+ SetError(::GetSvError(GetLastError()));
+ }
+ return bRetVal;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::LockFile()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+BOOL SvFileStream::LockFile()
+{
+ BOOL bRetVal = FALSE;
+ if( !nLockCounter )
+ {
+ if( LockRange( 0L, LONG_MAX ) )
+ {
+ nLockCounter = 1;
+ bRetVal = TRUE;
+ }
+ }
+ else
+ {
+ nLockCounter++;
+ bRetVal = TRUE;
+ }
+ return bRetVal;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::UnlockFile()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+BOOL SvFileStream::UnlockFile()
+{
+ BOOL bRetVal = FALSE;
+ if( nLockCounter > 0)
+ {
+ if( nLockCounter == 1)
+ {
+ if( UnlockRange( 0L, LONG_MAX ) )
+ {
+ nLockCounter = 0;
+ bRetVal = TRUE;
+ }
+ }
+ else
+ {
+ nLockCounter--;
+ bRetVal = TRUE;
+ }
+ }
+ return bRetVal;
+}
+
+
+/*************************************************************************
+|*
+|* SvFileStream::Open()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung TPF 15.07.98
+|*
+*************************************************************************/
+/*
+ NOCREATE TRUNC NT-Action
+ ----------------------------------------------
+ 0 (Create) 0 OPEN_ALWAYS
+ 0 (Create) 1 CREATE_ALWAYS
+ 1 0 OPEN_EXISTING
+ 1 1 TRUNCATE_EXISTING
+*/
+
+void SvFileStream::Open( const String& rFilename, StreamMode nMode )
+{
+ String aParsedFilename(rFilename);
+
+ SetLastError( ERROR_SUCCESS );
+ Close();
+ SvStream::ClearBuffer();
+
+ eStreamMode = nMode;
+ eStreamMode &= ~STREAM_TRUNC; // beim ReOpen nicht cutten
+
+ // !!! NoOp: Ansonsten ToAbs() verwendern
+ // !!! DirEntry aDirEntry( rFilename );
+ // !!! aFilename = aDirEntry.GetFull();
+ aFilename = aParsedFilename;
+#ifdef BOOTSTRAP
+ ByteString aFileNameA( aFilename, gsl_getSystemTextEncoding());
+#else
+ ByteString aFileNameA( aFilename, osl_getThreadTextEncoding());
+ FSysRedirector::DoRedirect( aFilename );
+#endif
+ SetLastError( ERROR_SUCCESS ); // ggf. durch Redirector geaendert!
+
+ /*
+ #ifdef DBG_UTIL
+ String aTraceStr( "SvFileStream::Open(): " );
+ aTraceStr += aFilename;
+ DBG_TRACE( aTraceStr );
+ #endif
+ */
+
+ DWORD nOpenAction;
+ DWORD nShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
+ DWORD nAccessMode = 0L;
+ UINT nOldErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX );
+
+ if( nMode & STREAM_SHARE_DENYREAD)
+ nShareMode &= ~FILE_SHARE_READ;
+
+ if( nMode & STREAM_SHARE_DENYWRITE)
+ nShareMode &= ~FILE_SHARE_WRITE;
+
+ if( nMode & STREAM_SHARE_DENYALL)
+ nShareMode = 0;
+
+ if( (nMode & STREAM_READ) )
+ nAccessMode |= GENERIC_READ;
+ if( (nMode & STREAM_WRITE) )
+ nAccessMode |= GENERIC_WRITE;
+
+ if( nAccessMode == GENERIC_READ ) // ReadOnly ?
+ nMode |= STREAM_NOCREATE; // wenn ja, nicht erzeugen
+
+ // Zuordnung siehe obige Wahrheitstafel
+ if( !(nMode & STREAM_NOCREATE) )
+ {
+ if( nMode & STREAM_TRUNC )
+ nOpenAction = CREATE_ALWAYS;
+ else
+ nOpenAction = OPEN_ALWAYS;
+ }
+ else
+ {
+ if( nMode & STREAM_TRUNC )
+ nOpenAction = TRUNCATE_EXISTING;
+ else
+ nOpenAction = OPEN_EXISTING;
+ }
+
+ pInstanceData->hFile = CreateFile(
+ aFileNameA.GetBuffer(),
+ nAccessMode,
+ nShareMode,
+ (LPSECURITY_ATTRIBUTES)NULL,
+ nOpenAction,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+ (HANDLE) NULL
+ );
+
+ if( pInstanceData->hFile!=INVALID_HANDLE_VALUE && (
+ // Hat Create Always eine existierende Datei ueberschrieben ?
+ GetLastError() == ERROR_ALREADY_EXISTS ||
+ // Hat Open Always eine neue Datei angelegt ?
+ GetLastError() == ERROR_FILE_NOT_FOUND ))
+ {
+ // wenn ja, dann alles OK
+ if( nOpenAction == OPEN_ALWAYS || nOpenAction == CREATE_ALWAYS )
+ SetLastError( ERROR_SUCCESS );
+ }
+
+ // Bei Fehler pruefen, ob wir lesen duerfen
+ if( (pInstanceData->hFile==INVALID_HANDLE_VALUE) &&
+ (nAccessMode & GENERIC_WRITE))
+ {
+ ULONG nErr = ::GetSvError( GetLastError() );
+ if(nErr==SVSTREAM_ACCESS_DENIED || nErr==SVSTREAM_SHARING_VIOLATION)
+ {
+ nMode &= (~STREAM_WRITE);
+ nAccessMode = GENERIC_READ;
+ // OV, 28.1.97: Win32 setzt die Datei auf 0-Laenge, wenn
+ // die Openaction CREATE_ALWAYS ist!!!!
+ nOpenAction = OPEN_EXISTING;
+ SetLastError( ERROR_SUCCESS );
+ pInstanceData->hFile = CreateFile(
+ aFileNameA.GetBuffer(),
+ GENERIC_READ,
+ nShareMode,
+ (LPSECURITY_ATTRIBUTES)NULL,
+ nOpenAction,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+ (HANDLE) NULL
+ );
+ if( GetLastError() == ERROR_ALREADY_EXISTS )
+ SetLastError( ERROR_SUCCESS );
+ }
+ }
+
+ if( GetLastError() != ERROR_SUCCESS )
+ {
+ bIsOpen = FALSE;
+ SetError(::GetSvError( GetLastError() ) );
+ }
+ else
+ {
+ bIsOpen = TRUE;
+ // pInstanceData->bIsEof = FALSE;
+ if( nAccessMode & GENERIC_WRITE )
+ bIsWritable = TRUE;
+ }
+ SetErrorMode( nOldErrorMode );
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::ReOpen()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+void SvFileStream::ReOpen()
+{
+ if( !bIsOpen && aFilename.Len() )
+ Open( aFilename, eStreamMode );
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::Close()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung TPF 15.07.98
+|*
+*************************************************************************/
+
+void SvFileStream::Close()
+{
+ if( IsOpen() )
+ {
+ if( nLockCounter )
+ {
+ nLockCounter = 1;
+ UnlockFile();
+ }
+ Flush();
+ CloseHandle( pInstanceData->hFile );
+ }
+ bIsOpen = FALSE;
+ nLockCounter= 0;
+ bIsWritable = FALSE;
+ SvStream::ClearBuffer();
+ SvStream::ClearError();
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::ResetError()
+|*
+|* Beschreibung STREAM.SDW; Setzt Filepointer auf Dateianfang
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+void SvFileStream::ResetError()
+{
+ SvStream::ClearError();
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::SetSize()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 19.10.95
+|* Letzte Aenderung TPF 15.07.98
+|*
+*************************************************************************/
+
+void SvFileStream::SetSize( ULONG nSize )
+{
+
+ if( IsOpen() )
+ {
+ int bError = FALSE;
+ HANDLE hFile = pInstanceData->hFile;
+ ULONG nOld = SetFilePointer( hFile, 0L, NULL, FILE_CURRENT );
+ if( nOld != 0xffffffff )
+ {
+ if( SetFilePointer(hFile,nSize,NULL,FILE_BEGIN ) != 0xffffffff)
+ {
+ bool bSucc = SetEndOfFile( hFile );
+ if( !bSucc )
+ bError = TRUE;
+ }
+ if( SetFilePointer( hFile,nOld,NULL,FILE_BEGIN ) == 0xffffffff)
+ bError = TRUE;
+ }
+ if( bError )
+ SetError(::GetSvError( GetLastError() ) );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/stream/vcompat.cxx b/tools/source/stream/vcompat.cxx
new file mode 100644
index 000000000000..f6223e8aed5d
--- /dev/null
+++ b/tools/source/stream/vcompat.cxx
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#define _VCOMPAT_CXX
+#include <tools/stream.hxx>
+#include <tools/vcompat.hxx>
+
+// -----------------
+// - VersionCompat -
+// -----------------
+
+VersionCompat::VersionCompat( SvStream& rStm, USHORT nStreamMode, USHORT nVersion ) :
+ mpRWStm ( &rStm ),
+ mnStmMode ( nStreamMode ),
+ mnVersion ( nVersion )
+{
+ if( !mpRWStm->GetError() )
+ {
+ if( STREAM_WRITE == mnStmMode )
+ {
+ *mpRWStm << mnVersion;
+ mnTotalSize = ( mnCompatPos = mpRWStm->Tell() ) + 4UL;
+ mpRWStm->SeekRel( 4L );
+ }
+ else
+ {
+ *mpRWStm >> mnVersion;
+ *mpRWStm >> mnTotalSize;
+ mnCompatPos = mpRWStm->Tell();
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+VersionCompat::~VersionCompat()
+{
+ if( STREAM_WRITE == mnStmMode )
+ {
+ const UINT32 nEndPos = mpRWStm->Tell();
+
+ mpRWStm->Seek( mnCompatPos );
+ *mpRWStm << ( nEndPos - mnTotalSize );
+ mpRWStm->Seek( nEndPos );
+ }
+ else
+ {
+ const UINT32 nReadSize = mpRWStm->Tell() - mnCompatPos;
+
+ if( mnTotalSize > nReadSize )
+ mpRWStm->SeekRel( mnTotalSize - nReadSize );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/string/debugprint.cxx b/tools/source/string/debugprint.cxx
new file mode 100644
index 000000000000..a93343dc2460
--- /dev/null
+++ b/tools/source/string/debugprint.cxx
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+// =======================================================================
+
+#include <tools/string.hxx>
+
+const sal_Char *dbg_dump(const ByteString &rStr)
+{
+ static ByteString aStr;
+ aStr = rStr;
+ aStr.Append(static_cast<char>(0));
+ return aStr.GetBuffer();
+}
+
+const sal_Char *dbg_dump(const UniString &rStr)
+{
+ return dbg_dump(ByteString(rStr, RTL_TEXTENCODING_UTF8));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/string/makefile.mk b/tools/source/string/makefile.mk
new file mode 100644
index 000000000000..255feac2e6f9
--- /dev/null
+++ b/tools/source/string/makefile.mk
@@ -0,0 +1,81 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=tools
+TARGET=str
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(OS)"!="AIX"
+ALWAYSDBGFILES = $(SLO)$/debugprint.obj
+.ENDIF
+
+.IF "$(ALWAYSDBGFILES)" != ""
+ALWAYSDBGTARGET=do_it_alwaysdebug
+.ENDIF
+
+SLOFILES= $(SLO)$/tstring.obj \
+ $(SLO)$/tustring.obj \
+ $(SLO)$/tenccvt.obj \
+ $(SLO)$/debugprint.obj
+
+OBJFILES= $(OBJ)$/tstring.obj \
+ $(OBJ)$/tustring.obj \
+ $(OBJ)$/tenccvt.obj \
+ $(OBJ)$/debugprint.obj
+
+# --- Targets ------------------------------------------------------
+
+.IF "$(ALWAYSDBG_FLAG)"==""
+TARGETDEPS+=$(ALWAYSDBGTARGET)
+.ENDIF
+
+.INCLUDE : target.mk
+
+.IF "$(ALWAYSDBGTARGET)" != ""
+.IF "$(ALWAYSDBG_FLAG)" == ""
+# --------------------------------------------------
+# - ALWAYSDBG - files always compiled with debugging
+# --------------------------------------------------
+$(ALWAYSDBGTARGET):
+ @echo --- ALWAYSDBGFILES ---
+ @dmake $(MFLAGS) $(MAKEFILE) debug=true $(ALWAYSDBGFILES) ALWAYSDBG_FLAG=TRUE $(CALLMACROS)
+ @echo --- ALWAYSDBGFILES OVER ---
+
+$(ALWAYSDBGFILES):
+ @echo --- ALWAYSDBG ---
+ @dmake $(MFLAGS) $(MAKEFILE) debug=true ALWAYSDBG_FLAG=TRUE $(CALLMACROS) $@
+ @echo --- ALWAYSDBG OVER ---
+.ENDIF
+.ENDIF
diff --git a/tools/source/string/strascii.cxx b/tools/source/string/strascii.cxx
new file mode 100644
index 000000000000..341f77609ada
--- /dev/null
+++ b/tools/source/string/strascii.cxx
@@ -0,0 +1,640 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// no include "precompiled_tools.hxx" because this is included in other cxx files.
+
+// =======================================================================
+
+#ifdef DBG_UTIL
+
+static BOOL ImplDbgCheckAsciiStr( const sal_Char* pAsciiStr, sal_Int32 nLen )
+{
+ while ( nLen && *pAsciiStr )
+ {
+ if ( ((unsigned char)*pAsciiStr) > 127 )
+ return FALSE;
+ ++pAsciiStr,
+ --nLen;
+ }
+
+ return TRUE;
+}
+
+#endif
+
+// =======================================================================
+
+static void ImplCopyAsciiStr( sal_Unicode* pDest, const sal_Char* pSrc,
+ sal_Int32 nLen )
+{
+ DBG_ASSERT( ImplDbgCheckAsciiStr( pSrc, nLen ),
+ "UniString::CopyAsciiStr() - pAsciiStr include characters > 127" );
+
+ while ( nLen )
+ {
+ *pDest = (unsigned char)*pSrc;
+ ++pDest,
+ ++pSrc,
+ --nLen;
+ }
+}
+
+// =======================================================================
+
+static sal_Int32 ImplStringCompareAscii( const sal_Unicode* pStr1, const sal_Char* pStr2 )
+{
+ sal_Int32 nRet;
+ while ( ((nRet = ((sal_Int32)*pStr1)-((sal_Int32)((unsigned char)*pStr2))) == 0) &&
+ *pStr2 )
+ {
+ ++pStr1,
+ ++pStr2;
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static sal_Int32 ImplStringCompareAscii( const sal_Unicode* pStr1, const sal_Char* pStr2,
+ xub_StrLen nCount )
+{
+ sal_Int32 nRet = 0;
+ while ( nCount &&
+ ((nRet = ((sal_Int32)*pStr1)-((sal_Int32)((unsigned char)*pStr2))) == 0) &&
+ *pStr2 )
+ {
+ ++pStr1,
+ ++pStr2,
+ --nCount;
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static sal_Int32 ImplStringCompareWithoutZeroAscii( const sal_Unicode* pStr1, const sal_Char* pStr2,
+ xub_StrLen nCount )
+{
+ sal_Int32 nRet = 0;
+ while ( nCount &&
+ ((nRet = ((sal_Int32)*pStr1)-((sal_Int32)((unsigned char)*pStr2))) == 0) )
+ {
+ ++pStr1,
+ ++pStr2,
+ --nCount;
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static sal_Int32 ImplStringICompareAscii( const sal_Unicode* pStr1, const sal_Char* pStr2 )
+{
+ sal_Int32 nRet;
+ sal_Unicode c1;
+ sal_Char c2;
+ do
+ {
+ // Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln
+ c1 = *pStr1;
+ c2 = *pStr2;
+ if ( (c1 >= 65) && (c1 <= 90) )
+ c1 += 32;
+ if ( (c2 >= 65) && (c2 <= 90) )
+ c2 += 32;
+ nRet = ((sal_Int32)c1)-((sal_Int32)((unsigned char)c2));
+ if ( nRet != 0 )
+ break;
+
+ ++pStr1,
+ ++pStr2;
+ }
+ while ( c2 );
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static sal_Int32 ImplStringICompareAscii( const sal_Unicode* pStr1, const sal_Char* pStr2,
+ xub_StrLen nCount )
+{
+ sal_Int32 nRet = 0;
+ sal_Unicode c1;
+ sal_Char c2;
+ do
+ {
+ if ( !nCount )
+ break;
+
+ // Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln
+ c1 = *pStr1;
+ c2 = *pStr2;
+ if ( (c1 >= 65) && (c1 <= 90) )
+ c1 += 32;
+ if ( (c2 >= 65) && (c2 <= 90) )
+ c2 += 32;
+ nRet = ((sal_Int32)c1)-((sal_Int32)((unsigned char)c2));
+ if ( nRet != 0 )
+ break;
+
+ ++pStr1,
+ ++pStr2,
+ --nCount;
+ }
+ while ( c2 );
+
+ return nRet;
+}
+
+// =======================================================================
+
+UniString UniString::CreateFromAscii( const sal_Char* pAsciiStr )
+{
+ DBG_ASSERT( pAsciiStr, "UniString::CreateFromAscii() - pAsciiStr is NULL" );
+
+ // Stringlaenge ermitteln
+ xub_StrLen nLen = ImplStringLen( pAsciiStr );
+
+ UniString aTempStr;
+ if ( nLen )
+ {
+ ImplCopyAsciiStr( aTempStr.AllocBuffer( nLen ), pAsciiStr, nLen );
+ }
+ return aTempStr;
+}
+
+// -----------------------------------------------------------------------
+
+UniString UniString::CreateFromAscii( const sal_Char* pAsciiStr, xub_StrLen nLen )
+{
+ DBG_ASSERT( pAsciiStr, "UniString::CreateFromAscii() - pAsciiStr is NULL" );
+
+ // Stringlaenge ermitteln
+ if ( nLen == STRING_LEN )
+ nLen = ImplStringLen( pAsciiStr );
+
+ UniString aTempStr;
+
+ if ( nLen )
+ {
+ ImplCopyAsciiStr( aTempStr.AllocBuffer( nLen ), pAsciiStr, nLen );
+ }
+ return aTempStr;
+}
+
+// -----------------------------------------------------------------------
+
+UniString& UniString::AssignAscii( const sal_Char* pAsciiStr )
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+ DBG_ASSERT( pAsciiStr, "UniString::AssignAscii() - pAsciiStr is NULL" );
+
+ // Stringlaenge ermitteln
+ xub_StrLen nLen = ImplStringLen( pAsciiStr );
+
+ if ( !nLen )
+ {
+ STRING_NEW((STRING_TYPE **)&mpData);
+ }
+ else
+ {
+ // Wenn String genauso lang ist, wie der String, dann direkt kopieren
+ if ( (nLen == mpData->mnLen) && (mpData->mnRefCount == 1) )
+ ImplCopyAsciiStr( mpData->maStr, pAsciiStr, nLen );
+ else
+ {
+ // Alte Daten loeschen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+
+ // Daten initialisieren und String kopieren
+ mpData = ImplAllocData( nLen );
+ ImplCopyAsciiStr( mpData->maStr, pAsciiStr, nLen );
+ }
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+UniString& UniString::AssignAscii( const sal_Char* pAsciiStr, xub_StrLen nLen )
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+ DBG_ASSERT( pAsciiStr, "UniString::AssignAscii() - pAsciiStr is NULL" );
+
+ if ( nLen == STRING_LEN )
+ nLen = ImplStringLen( pAsciiStr );
+
+#ifdef DBG_UTIL
+ if ( DbgIsAssert() )
+ {
+ for ( xub_StrLen i = 0; i < nLen; ++i )
+ {
+ if ( !pAsciiStr[i] )
+ {
+ DBG_ERROR( "UniString::AssignAscii() : nLen is wrong" );
+ }
+ }
+ }
+#endif
+
+ if ( !nLen )
+ {
+ STRING_NEW((STRING_TYPE **)&mpData);
+ }
+ else
+ {
+ // Wenn String genauso lang ist, wie der String, dann direkt kopieren
+ if ( (nLen == mpData->mnLen) && (mpData->mnRefCount == 1) )
+ ImplCopyAsciiStr( mpData->maStr, pAsciiStr, nLen );
+ else
+ {
+ // Alte Daten loeschen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+
+ // Daten initialisieren und String kopieren
+ mpData = ImplAllocData( nLen );
+ ImplCopyAsciiStr( mpData->maStr, pAsciiStr, nLen );
+ }
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+UniString& UniString::AppendAscii( const sal_Char* pAsciiStr )
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+ DBG_ASSERT( pAsciiStr, "UniString::AppendAscii() - pAsciiStr is NULL" );
+
+ // Stringlaenge ermitteln
+ sal_Int32 nCopyLen = ImplStringLen( pAsciiStr );
+
+ // Ueberlauf abfangen
+ nCopyLen = ImplGetCopyLen( mpData->mnLen, nCopyLen );
+
+ // Ist es kein leerer String
+ if ( nCopyLen )
+ {
+ // Neue Datenstruktur und neuen String erzeugen
+ UniStringData* pNewData = ImplAllocData( mpData->mnLen+nCopyLen );
+
+ // String kopieren
+ memcpy( pNewData->maStr, mpData->maStr, mpData->mnLen*sizeof( sal_Unicode ) );
+ ImplCopyAsciiStr( pNewData->maStr+mpData->mnLen, pAsciiStr, nCopyLen );
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+UniString& UniString::AppendAscii( const sal_Char* pAsciiStr, xub_StrLen nLen )
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+ DBG_ASSERT( pAsciiStr, "UniString::AppendAscii() - pAsciiStr is NULL" );
+
+ if ( nLen == STRING_LEN )
+ nLen = ImplStringLen( pAsciiStr );
+
+#ifdef DBG_UTIL
+ if ( DbgIsAssert() )
+ {
+ for ( xub_StrLen i = 0; i < nLen; ++i )
+ {
+ if ( !pAsciiStr[i] )
+ {
+ DBG_ERROR( "UniString::AppendAscii() : nLen is wrong" );
+ }
+ }
+ }
+#endif
+
+ // Ueberlauf abfangen
+ sal_Int32 nCopyLen = ImplGetCopyLen( mpData->mnLen, nLen );
+
+ // Ist es kein leerer String
+ if ( nCopyLen )
+ {
+ // Neue Datenstruktur und neuen String erzeugen
+ UniStringData* pNewData = ImplAllocData( mpData->mnLen+nCopyLen );
+
+ // String kopieren
+ memcpy( pNewData->maStr, mpData->maStr, mpData->mnLen*sizeof( sal_Unicode ) );
+ ImplCopyAsciiStr( pNewData->maStr+mpData->mnLen, pAsciiStr, nCopyLen );
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+UniString& UniString::InsertAscii( const char* pAsciiStr, xub_StrLen nIndex )
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+ DBG_ASSERT( pAsciiStr, "UniString::InsertAscii() - pAsciiStr is NULL" );
+
+ // Stringlaenge ermitteln
+ sal_Int32 nCopyLen = ImplStringLen( pAsciiStr );
+
+ // Ueberlauf abfangen
+ nCopyLen = ImplGetCopyLen( mpData->mnLen, nCopyLen );
+
+ // Ist der einzufuegende String ein Leerstring
+ if ( !nCopyLen )
+ return *this;
+
+ // Index groesser als Laenge
+ if ( nIndex > mpData->mnLen )
+ nIndex = static_cast< xub_StrLen >(mpData->mnLen);
+
+ // Neue Laenge ermitteln und neuen String anlegen
+ UniStringData* pNewData = ImplAllocData( mpData->mnLen+nCopyLen );
+
+ // String kopieren
+ memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( sal_Unicode ) );
+ ImplCopyAsciiStr( pNewData->maStr+nIndex, pAsciiStr, nCopyLen );
+ memcpy( pNewData->maStr+nIndex+nCopyLen, mpData->maStr+nIndex,
+ (mpData->mnLen-nIndex)*sizeof( sal_Unicode ) );
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+UniString& UniString::ReplaceAscii( xub_StrLen nIndex, xub_StrLen nCount,
+ const sal_Char* pAsciiStr, xub_StrLen nStrLen )
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+ DBG_ASSERT( pAsciiStr, "UniString::ReplaceAscii() - pAsciiStr is NULL" );
+
+ // Wenn Index groessergleich Laenge ist, dann ist es ein Append
+ if ( nIndex >= mpData->mnLen )
+ {
+ AppendAscii( pAsciiStr, nStrLen );
+ return *this;
+ }
+
+ // Ist es eine Zuweisung
+ if ( (nIndex == 0) && (nCount >= mpData->mnLen) )
+ {
+ AssignAscii( pAsciiStr, nStrLen );
+ return *this;
+ }
+
+ // Reicht ein Erase
+ if ( nStrLen == STRING_LEN )
+ nStrLen = ImplStringLen( pAsciiStr );
+ if ( !nStrLen )
+ return Erase( nIndex, nCount );
+
+ // nCount darf nicht ueber das Stringende hinnausgehen
+ if ( nCount > mpData->mnLen - nIndex )
+ nCount = static_cast< xub_StrLen >(mpData->mnLen-nIndex);
+
+ // Reicht eine zeichenweise Zuweisung
+ if ( nCount == nStrLen )
+ {
+ ImplCopyData();
+ ImplCopyAsciiStr( mpData->maStr+nIndex, pAsciiStr, nStrLen );
+ return *this;
+ }
+
+ // Ueberlauf abfangen
+ sal_Int32 n = ImplGetCopyLen( mpData->mnLen-nCount, nStrLen );
+
+ // Neue Daten anlegen
+ STRINGDATA* pNewData = ImplAllocData( mpData->mnLen-nCount+n );
+
+ // String kopieren
+ memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) );
+ ImplCopyAsciiStr( pNewData->maStr+nIndex, pAsciiStr, n );
+ memcpy( pNewData->maStr+nIndex+n, mpData->maStr+nIndex+nCount,
+ (mpData->mnLen-nIndex-nCount+1)*sizeof( STRCODE ) );
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+StringCompare UniString::CompareToAscii( const sal_Char* pAsciiStr,
+ xub_StrLen nLen ) const
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+ DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, nLen ),
+ "UniString::CompareToAscii() - pAsciiStr include characters > 127" );
+
+ // String vergleichen
+ sal_Int32 nCompare = ImplStringCompareAscii( mpData->maStr, pAsciiStr, nLen );
+
+ // Rueckgabewert anpassen
+ if ( nCompare == 0 )
+ return COMPARE_EQUAL;
+ else if ( nCompare < 0 )
+ return COMPARE_LESS;
+ else
+ return COMPARE_GREATER;
+}
+
+// -----------------------------------------------------------------------
+
+StringCompare UniString::CompareIgnoreCaseToAscii( const sal_Char* pAsciiStr,
+ xub_StrLen nLen ) const
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+ DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, nLen ),
+ "UniString::CompareIgnoreCaseToAscii() - pAsciiStr include characters > 127" );
+
+ // String vergleichen
+ sal_Int32 nCompare = ImplStringICompareAscii( mpData->maStr, pAsciiStr, nLen );
+
+ // Rueckgabewert anpassen
+ if ( nCompare == 0 )
+ return COMPARE_EQUAL;
+ else if ( nCompare < 0 )
+ return COMPARE_LESS;
+ else
+ return COMPARE_GREATER;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL UniString::EqualsAscii( const sal_Char* pAsciiStr ) const
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+ DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, STRING_LEN ),
+ "UniString::EqualsAscii() - pAsciiStr include characters > 127" );
+
+ return (ImplStringCompareAscii( mpData->maStr, pAsciiStr ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL UniString::EqualsIgnoreCaseAscii( const sal_Char* pAsciiStr ) const
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+ DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, STRING_LEN ),
+ "UniString::EqualsIgnoreCaseAscii() - pAsciiStr include characters > 127" );
+
+ return (ImplStringICompareAscii( mpData->maStr, pAsciiStr ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL UniString::EqualsAscii( const sal_Char* pAsciiStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+ DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, nLen ),
+ "UniString::EqualsAscii() - pAsciiStr include characters > 127" );
+
+ // Are there enough codes for comparing?
+ if ( nIndex > mpData->mnLen )
+ return (*pAsciiStr == 0);
+
+ return (ImplStringCompareAscii( mpData->maStr+nIndex, pAsciiStr, nLen ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL UniString::EqualsIgnoreCaseAscii( const sal_Char* pAsciiStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+ DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, nLen ),
+ "UniString::EqualsIgnoreCaseAscii() - pAsciiStr include characters > 127" );
+
+ // Are there enough codes for comparing?
+ if ( nIndex > mpData->mnLen )
+ return (*pAsciiStr == 0);
+
+ return (ImplStringICompareAscii( mpData->maStr+nIndex, pAsciiStr, nLen ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen UniString::SearchAscii( const sal_Char* pAsciiStr, xub_StrLen nIndex ) const
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+ DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, STRING_LEN ),
+ "UniString::SearchAscii() - pAsciiStr include characters > 127" );
+
+ sal_Int32 nLen = mpData->mnLen;
+ xub_StrLen nStrLen = ImplStringLen( pAsciiStr );
+
+ // Falls die Laenge des uebergebenen Strings 0 ist oder der Index
+ // hinter dem String liegt, dann wurde der String nicht gefunden
+ if ( !nStrLen || (nIndex >= nLen) )
+ return STRING_NOTFOUND;
+
+ const sal_Unicode* pStr = mpData->maStr;
+ pStr += nIndex;
+
+ if ( nStrLen == 1 )
+ {
+ sal_Unicode cSearch = (unsigned char)*pAsciiStr;
+ while ( nIndex < nLen )
+ {
+ if ( *pStr == cSearch )
+ return nIndex;
+ ++pStr,
+ ++nIndex;
+ }
+ }
+ else
+ {
+ // Nur innerhalb des Strings suchen
+ while ( nLen - nIndex >= nStrLen )
+ {
+ // Stimmt der String ueberein
+ if ( ImplStringCompareWithoutZeroAscii( pStr, pAsciiStr, nStrLen ) == 0 )
+ return nIndex;
+ ++pStr,
+ ++nIndex;
+ }
+ }
+
+ return STRING_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen UniString::SearchAndReplaceAscii( const sal_Char* pAsciiStr, const UniString& rRepStr,
+ xub_StrLen nIndex )
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+ DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, STRING_LEN ),
+ "UniString::SearchAndReplaceAscii() - pAsciiStr include characters > 127" );
+
+ xub_StrLen nSPos = SearchAscii( pAsciiStr, nIndex );
+ if ( nSPos != STRING_NOTFOUND )
+ Replace( nSPos, ImplStringLen( pAsciiStr ), rRepStr );
+
+ return nSPos;
+}
+
+// -----------------------------------------------------------------------
+
+void UniString::SearchAndReplaceAllAscii( const sal_Char* pAsciiStr, const UniString& rRepStr )
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+ DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, STRING_LEN ),
+ "UniString::SearchAndReplaceAllAscii() - pAsciiStr include characters > 127" );
+
+ xub_StrLen nCharLen = ImplStringLen( pAsciiStr );
+ xub_StrLen nSPos = SearchAscii( pAsciiStr, 0 );
+ while ( nSPos != STRING_NOTFOUND )
+ {
+ Replace( nSPos, nCharLen, rRepStr );
+ nSPos = nSPos + rRepStr.Len();
+ nSPos = SearchAscii( pAsciiStr, nSPos );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/string/strcvt.cxx b/tools/source/string/strcvt.cxx
new file mode 100644
index 000000000000..c8ae9b4f4ce6
--- /dev/null
+++ b/tools/source/string/strcvt.cxx
@@ -0,0 +1,616 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// no include "precompiled_tools.hxx" because this is included in other cxx files.
+
+// -----------------------------------------------------------------------
+
+void ByteString::ImplUpdateStringFromUniString(
+ const sal_Unicode* pUniStr, sal_Size nUniLen,
+ rtl_TextEncoding eTextEncoding, sal_uInt32 nCvtFlags )
+{
+ ByteStringData* pNewStringData = NULL;
+ rtl_uString2String( (rtl_String **)(&pNewStringData),
+ pUniStr, nUniLen,
+ eTextEncoding, nCvtFlags );
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewStringData;
+}
+
+// =======================================================================
+
+ByteString::ByteString( const UniString& rUniStr, rtl_TextEncoding eTextEncoding, sal_uInt32 nCvtFlags )
+{
+ DBG_CTOR( ByteString, DbgCheckByteString );
+ DBG_CHKOBJ( &rUniStr, UniString, DbgCheckUniString );
+
+ mpData = NULL;
+ rtl_uString2String( (rtl_String **)(&mpData),
+ rUniStr.mpData->maStr, rUniStr.mpData->mnLen,
+ eTextEncoding, nCvtFlags );
+}
+
+// -----------------------------------------------------------------------
+
+ByteString::ByteString( const UniString& rUniStr, xub_StrLen nPos, xub_StrLen nLen,
+ rtl_TextEncoding eTextEncoding, sal_uInt32 nCvtFlags )
+{
+ DBG_CTOR( ByteString, DbgCheckByteString );
+ DBG_CHKOBJ( &rUniStr, UniString, DbgCheckUniString );
+
+ // Stringlaenge ermitteln
+ if ( nPos > rUniStr.mpData->mnLen )
+ nLen = 0;
+ else
+ {
+ // Laenge korrigieren, wenn noetig
+ sal_Int32 nMaxLen = rUniStr.mpData->mnLen-nPos;
+ if ( nLen > nMaxLen )
+ nLen = static_cast< xub_StrLen >(nMaxLen);
+ }
+
+ mpData = NULL;
+ rtl_uString2String( (rtl_String **)(&mpData),
+ rUniStr.mpData->maStr+nPos, nLen,
+ eTextEncoding, nCvtFlags );
+}
+
+// -----------------------------------------------------------------------
+
+ByteString::ByteString( const sal_Unicode* pUniStr,
+ rtl_TextEncoding eTextEncoding, sal_uInt32 nCvtFlags )
+{
+ DBG_CTOR( ByteString, DbgCheckByteString );
+ DBG_ASSERT( pUniStr, "ByteString::ByteString() - pUniStr is NULL" );
+
+ mpData = NULL;
+ rtl_uString2String( (rtl_String **)(&mpData),
+ pUniStr, ImplStringLen( pUniStr ),
+ eTextEncoding, nCvtFlags );
+}
+
+// -----------------------------------------------------------------------
+
+ByteString::ByteString( const sal_Unicode* pUniStr, xub_StrLen nLen,
+ rtl_TextEncoding eTextEncoding, sal_uInt32 nCvtFlags )
+{
+ DBG_CTOR( ByteString, DbgCheckByteString );
+ DBG_ASSERT( pUniStr, "ByteString::ByteString() - pUniStr is NULL" );
+
+ if ( nLen == STRING_LEN )
+ nLen = ImplStringLen( pUniStr );
+
+ mpData = NULL;
+ rtl_uString2String( (rtl_String **)(&mpData),
+ pUniStr, nLen,
+ eTextEncoding, nCvtFlags );
+}
+
+// =======================================================================
+
+static sal_uChar aImplByteTab[256] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167,
+ 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183,
+ 184, 185, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199,
+ 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215,
+ 216, 217, 218, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231,
+ 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247,
+ 248, 249, 250, 251, 252, 253, 254, 255
+};
+
+// =======================================================================
+
+struct Impl1ByteUnicodeTabData
+{
+ rtl_TextEncoding meTextEncoding;
+ sal_Unicode maUniTab[256];
+ Impl1ByteUnicodeTabData* mpNext;
+};
+
+// -----------------------------------------------------------------------
+
+struct Impl1ByteConvertTabData
+{
+ rtl_TextEncoding meSrcTextEncoding;
+ rtl_TextEncoding meDestTextEncoding;
+ sal_uChar maConvertTab[256];
+ sal_uChar maRepConvertTab[256];
+ Impl1ByteConvertTabData* mpNext;
+};
+
+// =======================================================================
+
+sal_Unicode* ImplGet1ByteUnicodeTab( rtl_TextEncoding eTextEncoding )
+{
+#ifndef BOOTSTRAP
+ TOOLSINDATA* pToolsData = ImplGetToolsInData();
+#else
+ TOOLSINDATA* pToolsData = 0x0;
+#endif
+ Impl1ByteUnicodeTabData* pTab = pToolsData->mpFirstUniTabData;
+
+ while ( pTab )
+ {
+ if ( pTab->meTextEncoding == eTextEncoding )
+ return pTab->maUniTab;
+ pTab = pTab->mpNext;
+ }
+
+ // get TextEncodingInfo
+ rtl_TextEncodingInfo aTextEncInfo;
+ aTextEncInfo.StructSize = sizeof( aTextEncInfo );
+ rtl_getTextEncodingInfo( eTextEncoding, &aTextEncInfo );
+
+ if ( aTextEncInfo.MaximumCharSize == 1 )
+ {
+ pTab = new Impl1ByteUnicodeTabData;
+ pTab->meTextEncoding = eTextEncoding;
+ pTab->mpNext = pToolsData->mpFirstUniTabData;
+
+ rtl_TextToUnicodeConverter hConverter;
+ sal_uInt32 nInfo;
+ sal_Size nSrcBytes;
+ sal_Size nDestChars;
+ hConverter = rtl_createTextToUnicodeConverter( eTextEncoding );
+ nDestChars = rtl_convertTextToUnicode( hConverter, 0,
+ (const sal_Char*)aImplByteTab, 256,
+ pTab->maUniTab, 256,
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MAPTOPRIVATE |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT,
+ &nInfo, &nSrcBytes );
+ rtl_destroyTextToUnicodeConverter( hConverter );
+
+ if ( (nSrcBytes != 256) || (nDestChars != 256) )
+ delete pTab;
+ else
+ {
+ pToolsData->mpFirstUniTabData = pTab;
+ return pTab->maUniTab;
+ }
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+static sal_uChar* ImplGet1ByteConvertTab( rtl_TextEncoding eSrcTextEncoding,
+ rtl_TextEncoding eDestTextEncoding,
+ BOOL bReplace )
+{
+#ifndef BOOTSTRAP
+ TOOLSINDATA* pToolsData = ImplGetToolsInData();
+#else
+ TOOLSINDATA* pToolsData = 0x0;
+#endif
+ Impl1ByteConvertTabData* pTab = pToolsData->mpFirstConvertTabData;
+
+ while ( pTab )
+ {
+ if ( (pTab->meSrcTextEncoding == eSrcTextEncoding) &&
+ (pTab->meDestTextEncoding == eDestTextEncoding) )
+ {
+ if ( bReplace )
+ return pTab->maRepConvertTab;
+ else
+ return pTab->maConvertTab;
+ }
+ pTab = pTab->mpNext;
+ }
+
+ // get TextEncodingInfo
+ rtl_TextEncodingInfo aTextEncInfo1;
+ aTextEncInfo1.StructSize = sizeof( aTextEncInfo1 );
+ rtl_getTextEncodingInfo( eSrcTextEncoding, &aTextEncInfo1 );
+ rtl_TextEncodingInfo aTextEncInfo2;
+ aTextEncInfo2.StructSize = sizeof( aTextEncInfo2 );
+ rtl_getTextEncodingInfo( eDestTextEncoding, &aTextEncInfo2 );
+
+ if ( (aTextEncInfo1.MaximumCharSize == 1) &&
+ (aTextEncInfo2.MaximumCharSize == 1) )
+ {
+ pTab = new Impl1ByteConvertTabData;
+ pTab->meSrcTextEncoding = eSrcTextEncoding;
+ pTab->meDestTextEncoding = eDestTextEncoding;
+ pTab->mpNext = pToolsData->mpFirstConvertTabData;
+
+ rtl_TextToUnicodeConverter hConverter;
+ rtl_UnicodeToTextConverter hConverter2;
+ sal_uInt32 nInfo;
+ sal_Size nSrcBytes;
+ sal_Size nDestChars;
+ sal_Size nSrcChars;
+ sal_Size nDestBytes;
+ sal_Unicode aTempBuf[256];
+ hConverter = rtl_createTextToUnicodeConverter( eSrcTextEncoding );
+ nDestChars = rtl_convertTextToUnicode( hConverter, 0,
+ (const sal_Char*)aImplByteTab, 256,
+ aTempBuf, 256,
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT,
+ &nInfo, &nSrcBytes );
+ rtl_destroyTextToUnicodeConverter( hConverter );
+ if ( (nSrcBytes != 256) || (nDestChars != 256) )
+ delete pTab;
+ else
+ {
+ hConverter2 = rtl_createUnicodeToTextConverter( eDestTextEncoding );
+ nDestBytes = rtl_convertUnicodeToText( hConverter2, 0,
+ aTempBuf, 256,
+ (sal_Char*)pTab->maConvertTab, 256,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_0 |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT,
+ &nInfo, &nSrcChars );
+ if ( (nDestBytes == 256) || (nSrcChars == 256) )
+ {
+ nDestBytes = rtl_convertUnicodeToText( hConverter2, 0,
+ aTempBuf, 256,
+ (sal_Char*)pTab->maRepConvertTab, 256,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT |
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE,
+ &nInfo, &nSrcChars );
+ }
+ rtl_destroyUnicodeToTextConverter( hConverter2 );
+ if ( (nDestBytes != 256) || (nSrcChars != 256) )
+ delete pTab;
+ else
+ {
+ pToolsData->mpFirstConvertTabData = pTab;
+ if ( bReplace )
+ return pTab->maRepConvertTab;
+ else
+ return pTab->maConvertTab;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+// =======================================================================
+
+void ImplDeleteCharTabData()
+{
+#ifndef BOOTSTRAP
+ TOOLSINDATA* pToolsData = ImplGetToolsInData();
+#else
+ TOOLSINDATA* pToolsData = 0x0;
+#endif
+ Impl1ByteUnicodeTabData* pTempUniTab;
+ Impl1ByteUnicodeTabData* pUniTab = pToolsData->mpFirstUniTabData;
+ while ( pUniTab )
+ {
+ pTempUniTab = pUniTab->mpNext;
+ delete pUniTab;
+ pUniTab = pTempUniTab;
+ }
+ pToolsData->mpFirstUniTabData = NULL;
+
+ Impl1ByteConvertTabData* pTempConvertTab;
+ Impl1ByteConvertTabData* pConvertTab = pToolsData->mpFirstConvertTabData;
+ while ( pConvertTab )
+ {
+ pTempConvertTab = pConvertTab->mpNext;
+ delete pConvertTab;
+ pConvertTab = pTempConvertTab;
+ }
+ pToolsData->mpFirstConvertTabData = NULL;
+}
+
+// =======================================================================
+
+void ByteString::ImplStringConvert(
+ rtl_TextEncoding eSource, rtl_TextEncoding eTarget, BOOL bReplace )
+{
+ sal_uChar* pConvertTab = ImplGet1ByteConvertTab( eSource, eTarget, bReplace );
+ if ( pConvertTab )
+ {
+ char* pStr = mpData->maStr;
+ while ( *pStr )
+ {
+ sal_uChar c = (sal_uChar)*pStr;
+ sal_uChar cConv = pConvertTab[c];
+ if ( c != cConv )
+ {
+ pStr = ImplCopyStringData( pStr );
+ *pStr = (char)cConv;
+ }
+
+ pStr++;
+ }
+ }
+ else
+ {
+ rtl_UnicodeToTextConverter hSrcConverter = rtl_createTextToUnicodeConverter( eSource );
+ sal_uInt32 nInfo;
+ sal_Size nSrcBytes;
+ sal_Size nDestChars;
+ sal_Size nTempLen;
+ sal_Unicode* pTempBuf;
+ nTempLen = mpData->mnLen;
+ pTempBuf = new sal_Unicode[nTempLen];
+ nDestChars = rtl_convertTextToUnicode( hSrcConverter, 0,
+ mpData->maStr, mpData->mnLen,
+ pTempBuf, nTempLen,
+ RTL_TEXTTOUNICODE_FLAGS_FLUSH |
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MAPTOPRIVATE |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT,
+ &nInfo, &nSrcBytes );
+ rtl_destroyTextToUnicodeConverter( hSrcConverter );
+ // Hier werten wir bReplace nicht aus, da fuer MultiByte-Textencodings
+ // sowieso keine Ersatzdarstellung moeglich ist. Da sich der String
+ // sowieso in der Laenge aendern kann, nehmen wir auch sonst keine
+ // Ruecksicht darauf, das die Laenge erhalten bleibt.
+ ImplUpdateStringFromUniString( pTempBuf, nDestChars, eTarget,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT |
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE |
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACESTR |
+ RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 |
+ RTL_UNICODETOTEXT_FLAGS_NONSPACING_IGNORE |
+ RTL_UNICODETOTEXT_FLAGS_CONTROL_IGNORE );
+ delete [] pTempBuf;
+ }
+}
+
+// =======================================================================
+
+ByteString& ByteString::Convert( rtl_TextEncoding eSource, rtl_TextEncoding eTarget, BOOL bReplace )
+{
+ DBG_CHKTHIS( ByteString, DbgCheckByteString );
+
+ // rtl_TextEncoding Dontknow kann nicht konvertiert werden
+ if ( (eSource == RTL_TEXTENCODING_DONTKNOW) || (eTarget == RTL_TEXTENCODING_DONTKNOW) )
+ return *this;
+
+ // Wenn Source und Target gleich sind, muss nicht konvertiert werden
+ if ( eSource == eTarget )
+ return *this;
+
+ // rtl_TextEncoding Symbol nur nach Unicode oder von Unicode wandeln, ansonsten
+ // wollen wir die Zeichencodes beibehalten
+ if ( (eSource == RTL_TEXTENCODING_SYMBOL) &&
+ (eTarget != RTL_TEXTENCODING_UTF7) &&
+ (eTarget != RTL_TEXTENCODING_UTF8) )
+ return *this;
+ if ( (eTarget == RTL_TEXTENCODING_SYMBOL) &&
+ (eSource != RTL_TEXTENCODING_UTF7) &&
+ (eSource != RTL_TEXTENCODING_UTF8) )
+ return *this;
+
+ // Zeichensatz umwandeln
+ ImplStringConvert( eSource, eTarget, bReplace );
+
+ return *this;
+}
+
+// =======================================================================
+
+char ByteString::Convert( char c,
+ rtl_TextEncoding eSource, rtl_TextEncoding eTarget,
+ BOOL bReplace )
+{
+ // TextEncoding Dontknow kann nicht konvertiert werden
+ if ( (eSource == RTL_TEXTENCODING_DONTKNOW) || (eTarget == RTL_TEXTENCODING_DONTKNOW) )
+ return '\0';
+
+ // Wenn Source und Target gleich sind, muss nicht konvertiert werden
+ if ( eSource == eTarget )
+ return c;
+
+ // TextEncoding Symbol nur nach Unicode oder von Unicode wandeln, ansonsten
+ // wollen wir die Zeichencodes beibehalten
+ if ( (eSource == RTL_TEXTENCODING_SYMBOL) &&
+ (eTarget != RTL_TEXTENCODING_UTF7) &&
+ (eTarget != RTL_TEXTENCODING_UTF8) )
+ return '\0';
+ if ( (eTarget == RTL_TEXTENCODING_SYMBOL) &&
+ (eSource != RTL_TEXTENCODING_UTF7) &&
+ (eSource != RTL_TEXTENCODING_UTF8) )
+ return '\0';
+
+ sal_uChar* pConvertTab = ImplGet1ByteConvertTab( eSource, eTarget, bReplace );
+ if ( pConvertTab )
+ return (char)pConvertTab[(sal_uChar)c];
+ else
+ return '\0';
+}
+
+// =======================================================================
+
+sal_Unicode ByteString::ConvertToUnicode( char c, rtl_TextEncoding eTextEncoding )
+{
+ sal_Size nLen = 1;
+ return ConvertToUnicode( &c, &nLen, eTextEncoding );
+}
+
+// -----------------------------------------------------------------------
+
+char ByteString::ConvertFromUnicode( sal_Unicode c, rtl_TextEncoding eTextEncoding, BOOL bReplace )
+{
+ sal_Size nLen;
+ char aBuf[30];
+ nLen = ConvertFromUnicode( c, aBuf, sizeof( aBuf ), eTextEncoding, bReplace );
+ if ( nLen == 1 )
+ return aBuf[0];
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Unicode ByteString::ConvertToUnicode( const char* pChar, sal_Size* pLen, rtl_TextEncoding eTextEncoding )
+{
+ // TextEncoding Dontknow wird nicht konvertiert
+ if ( eTextEncoding == RTL_TEXTENCODING_DONTKNOW )
+ return 0;
+
+ rtl_TextToUnicodeConverter hConverter;
+ sal_uInt32 nInfo;
+ sal_Size nSrcBytes;
+ sal_Size nDestChars;
+ sal_Unicode nConvChar;
+ hConverter = rtl_createTextToUnicodeConverter( eTextEncoding );
+ nDestChars = rtl_convertTextToUnicode( hConverter, 0,
+ (const sal_Char*)pChar, *pLen,
+ &nConvChar, 1,
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_FLUSH,
+ &nInfo, &nSrcBytes );
+ rtl_destroyTextToUnicodeConverter( hConverter );
+
+ if ( nDestChars == 1 )
+ {
+ *pLen = nSrcBytes;
+ return nConvChar;
+ }
+ else
+ {
+ *pLen = 0;
+ return 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+sal_Size ByteString::ConvertFromUnicode( sal_Unicode c, char* pBuf, sal_Size nBufLen, rtl_TextEncoding eTextEncoding,
+ BOOL bReplace )
+{
+ // TextEncoding Dontknow wird nicht konvertiert
+ if ( eTextEncoding == RTL_TEXTENCODING_DONTKNOW )
+ return '\0';
+
+ rtl_UnicodeToTextConverter hConverter;
+ sal_uInt32 nInfo;
+ sal_Size nSrcChars;
+ sal_Size nDestBytes;
+ sal_Unicode cUni = c;
+ sal_uInt32 nFlags = RTL_UNICODETOTEXT_FLAGS_NONSPACING_IGNORE |
+ RTL_UNICODETOTEXT_FLAGS_CONTROL_IGNORE |
+ RTL_UNICODETOTEXT_FLAGS_FLUSH;
+ if ( bReplace )
+ {
+ nFlags |= RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT;
+ nFlags |= RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE;
+ if ( nBufLen > 1 )
+ nFlags |= RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACESTR;
+ }
+ else
+ {
+ nFlags |= RTL_UNICODETOTEXT_FLAGS_UNDEFINED_0 |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_0;
+ }
+
+ hConverter = rtl_createUnicodeToTextConverter( eTextEncoding );
+ nDestBytes = rtl_convertUnicodeToText( hConverter, 0,
+ &cUni, 1,
+ (sal_Char*)pBuf, nBufLen,
+ nFlags,
+ &nInfo, &nSrcChars );
+ rtl_destroyUnicodeToTextConverter( hConverter );
+ return nDestBytes;
+}
+
+// =======================================================================
+
+ByteString::ByteString( const rtl::OString& rStr )
+ : mpData(NULL)
+{
+ DBG_CTOR( ByteString, DbgCheckByteString );
+
+ OSL_ENSURE(rStr.pData->length < STRING_MAXLEN,
+ "Overflowing rtl::OString -> ByteString cut to zero length");
+
+ if (rStr.pData->length < STRING_MAXLEN)
+ {
+ mpData = reinterpret_cast< ByteStringData * >(const_cast< rtl::OString & >(rStr).pData);
+ STRING_ACQUIRE((STRING_TYPE *)mpData);
+ }
+ else
+ {
+ STRING_NEW((STRING_TYPE **)&mpData);
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ByteString& ByteString::Assign( const rtl::OString& rStr )
+{
+ DBG_CHKTHIS( ByteString, DbgCheckByteString );
+
+ OSL_ENSURE(rStr.pData->length < STRING_MAXLEN,
+ "Overflowing rtl::OString -> ByteString cut to zero length");
+
+ if (rStr.pData->length < STRING_MAXLEN)
+ {
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = reinterpret_cast< ByteStringData * >(const_cast< rtl::OString & >(rStr).pData);
+ STRING_ACQUIRE((STRING_TYPE *)mpData);
+ }
+ else
+ {
+ STRING_NEW((STRING_TYPE **)&mpData);
+ }
+
+ return *this;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/string/strimp.cxx b/tools/source/string/strimp.cxx
new file mode 100644
index 000000000000..e77a4ace4874
--- /dev/null
+++ b/tools/source/string/strimp.cxx
@@ -0,0 +1,2118 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// no include "precompiled_tools.hxx" because this is included in other cxx files.
+
+// =======================================================================
+
+static sal_Int32 ImplStringCompare( const STRCODE* pStr1, const STRCODE* pStr2 )
+{
+ sal_Int32 nRet;
+ while ( ((nRet = ((sal_Int32)((STRCODEU)*pStr1))-((sal_Int32)((STRCODEU)*pStr2))) == 0) &&
+ *pStr2 )
+ {
+ ++pStr1,
+ ++pStr2;
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static sal_Int32 ImplStringCompare( const STRCODE* pStr1, const STRCODE* pStr2,
+ xub_StrLen nCount )
+{
+ sal_Int32 nRet = 0;
+ while ( nCount &&
+ ((nRet = ((sal_Int32)((STRCODEU)*pStr1))-((sal_Int32)((STRCODEU)*pStr2))) == 0) &&
+ *pStr2 )
+ {
+ ++pStr1,
+ ++pStr2,
+ --nCount;
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static sal_Int32 ImplStringCompareWithoutZero( const STRCODE* pStr1, const STRCODE* pStr2,
+ sal_Int32 nCount )
+{
+ sal_Int32 nRet = 0;
+ while ( nCount &&
+ ((nRet = ((sal_Int32)((STRCODEU)*pStr1))-((sal_Int32)((STRCODEU)*pStr2))) == 0) )
+ {
+ ++pStr1,
+ ++pStr2,
+ --nCount;
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static sal_Int32 ImplStringICompare( const STRCODE* pStr1, const STRCODE* pStr2 )
+{
+ sal_Int32 nRet;
+ STRCODE c1;
+ STRCODE c2;
+ do
+ {
+ // Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln
+ c1 = *pStr1;
+ c2 = *pStr2;
+ if ( (c1 >= 65) && (c1 <= 90) )
+ c1 += 32;
+ if ( (c2 >= 65) && (c2 <= 90) )
+ c2 += 32;
+ nRet = ((sal_Int32)((STRCODEU)c1))-((sal_Int32)((STRCODEU)c2));
+ if ( nRet != 0 )
+ break;
+
+ ++pStr1,
+ ++pStr2;
+ }
+ while ( c2 );
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static sal_Int32 ImplStringICompare( const STRCODE* pStr1, const STRCODE* pStr2,
+ xub_StrLen nCount )
+{
+ sal_Int32 nRet = 0;
+ STRCODE c1;
+ STRCODE c2;
+ do
+ {
+ if ( !nCount )
+ break;
+
+ // Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln
+ c1 = *pStr1;
+ c2 = *pStr2;
+ if ( (c1 >= 65) && (c1 <= 90) )
+ c1 += 32;
+ if ( (c2 >= 65) && (c2 <= 90) )
+ c2 += 32;
+ nRet = ((sal_Int32)((STRCODEU)c1))-((sal_Int32)((STRCODEU)c2));
+ if ( nRet != 0 )
+ break;
+
+ ++pStr1,
+ ++pStr2,
+ --nCount;
+ }
+ while ( c2 );
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static sal_Int32 ImplStringICompareWithoutZero( const STRCODE* pStr1, const STRCODE* pStr2,
+ sal_Int32 nCount )
+{
+ sal_Int32 nRet = 0;
+ STRCODE c1;
+ STRCODE c2;
+ do
+ {
+ if ( !nCount )
+ break;
+
+ // Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln
+ c1 = *pStr1;
+ c2 = *pStr2;
+ if ( (c1 >= 65) && (c1 <= 90) )
+ c1 += 32;
+ if ( (c2 >= 65) && (c2 <= 90) )
+ c2 += 32;
+ nRet = ((sal_Int32)((STRCODEU)c1))-((sal_Int32)((STRCODEU)c2));
+
+ ++pStr1,
+ ++pStr2,
+ --nCount;
+ }
+ while ( nRet == 0 );
+
+ return nRet;
+}
+
+// =======================================================================
+
+#ifdef DBG_UTIL
+const char* DBGCHECKSTRING( const void* pString )
+{
+ STRING* p = (STRING*)pString;
+
+ if ( p->GetBuffer()[p->Len()] != 0 )
+ return "String damaged: aStr[nLen] != 0";
+
+ return NULL;
+}
+#endif
+
+// =======================================================================
+
+static STRINGDATA* ImplAllocData( sal_Int32 nLen )
+{
+ // Dann kopiere die Daten
+ STRINGDATA* pData = (STRINGDATA*)rtl_allocateMemory( sizeof(STRINGDATA)+(nLen*sizeof( STRCODE )) );
+ pData->mnRefCount = 1;
+ pData->mnLen = nLen;
+ pData->maStr[nLen] = 0;
+ return pData;
+}
+
+// -----------------------------------------------------------------------
+
+static STRINGDATA* _ImplCopyData( STRINGDATA* pData )
+{
+ unsigned int nSize = sizeof(STRINGDATA)+(pData->mnLen*sizeof( STRCODE ));
+ STRINGDATA* pNewData = (STRINGDATA*)rtl_allocateMemory( nSize );
+ memcpy( pNewData, pData, nSize );
+ pNewData->mnRefCount = 1;
+ STRING_RELEASE((STRING_TYPE *)pData);
+ return pNewData;
+}
+
+// -----------------------------------------------------------------------
+
+inline void STRING::ImplCopyData()
+{
+ DBG_ASSERT( (mpData->mnRefCount != 0), "String::ImplCopyData() - RefCount == 0" );
+
+ // ist es ein referenzierter String, dann die Daten abkoppeln
+ if ( mpData->mnRefCount != 1 )
+ mpData = _ImplCopyData( mpData );
+}
+
+// -----------------------------------------------------------------------
+
+inline STRCODE* STRING::ImplCopyStringData( STRCODE* pStr )
+{
+ // Ist der Referenzzaehler groesser 0
+ if ( mpData->mnRefCount != 1 ) {
+ DBG_ASSERT( (pStr >= mpData->maStr) &&
+ ((pStr-mpData->maStr) < mpData->mnLen),
+ "ImplCopyStringData - pStr from other String-Instanz" );
+ unsigned int nIndex = (unsigned int)(pStr-mpData->maStr);
+ mpData = _ImplCopyData( mpData );
+ pStr = mpData->maStr + nIndex;
+ }
+ return pStr;
+}
+
+// -----------------------------------------------------------------------
+
+inline sal_Int32 ImplGetCopyLen( sal_Int32 nStrLen, sal_Int32 nCopyLen )
+{
+ OSL_ASSERT(nStrLen <= STRING_MAXLEN && nCopyLen <= STRING_MAXLEN);
+ if ( nCopyLen > STRING_MAXLEN-nStrLen )
+ nCopyLen = STRING_MAXLEN-nStrLen;
+ return nCopyLen;
+}
+
+// =======================================================================
+
+STRING::STRING()
+ : mpData(NULL)
+{
+ DBG_CTOR( STRING, DBGCHECKSTRING );
+
+ STRING_NEW((STRING_TYPE **)&mpData);
+}
+
+// -----------------------------------------------------------------------
+
+STRING::STRING( const STRING& rStr )
+{
+ DBG_CTOR( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+
+ // Pointer auf die Daten des uebergebenen Strings setzen und
+ // Referenzzaehler erhoehen
+ STRING_ACQUIRE((STRING_TYPE *)rStr.mpData);
+ mpData = rStr.mpData;
+}
+
+// -----------------------------------------------------------------------
+
+STRING::STRING( const STRING& rStr, xub_StrLen nPos, xub_StrLen nLen )
+: mpData( NULL )
+{
+ DBG_CTOR( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+
+ // Stringlaenge ermitteln
+ if ( nPos > rStr.mpData->mnLen )
+ nLen = 0;
+ else
+ {
+ // Laenge korrigieren, wenn noetig
+ sal_Int32 nMaxLen = rStr.mpData->mnLen-nPos;
+ if ( nLen > nMaxLen )
+ nLen = static_cast< xub_StrLen >(nMaxLen);
+ }
+
+ // Ist es kein leerer String
+ if ( nLen )
+ {
+ // Reicht ein einfaches erhoehen des Referenzcounters
+ if ( (nPos == 0) && (nLen == rStr.mpData->mnLen) )
+ {
+ STRING_ACQUIRE((STRING_TYPE *)rStr.mpData);
+ mpData = rStr.mpData;
+ }
+ else
+ {
+ // Verwaltungsdaten anlegen und String kopieren
+ mpData = ImplAllocData( nLen );
+ memcpy( mpData->maStr, rStr.mpData->maStr+nPos, nLen*sizeof( STRCODE ) );
+ }
+ }
+ else
+ {
+ STRING_NEW((STRING_TYPE **)&mpData);
+ }
+}
+
+// -----------------------------------------------------------------------
+
+STRING::STRING( const STRCODE* pCharStr )
+ : mpData(NULL)
+{
+ DBG_CTOR( STRING, DBGCHECKSTRING );
+
+ // Stringlaenge ermitteln
+ // Bei diesem Ctor darf NULL uebergeben werden
+ xub_StrLen nLen;
+ if ( pCharStr )
+ nLen = ImplStringLen( pCharStr );
+ else
+ nLen = 0;
+
+ // Ist es kein leerer String
+ if ( nLen )
+ {
+ // Verwaltungsdaten anlegen und String kopieren
+ mpData = ImplAllocData( nLen );
+ memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) );
+ }
+ else
+ {
+ STRING_NEW((STRING_TYPE **)&mpData);
+ }
+}
+
+// -----------------------------------------------------------------------
+
+STRING::STRING( const STRCODE* pCharStr, xub_StrLen nLen )
+: mpData(NULL)
+{
+ DBG_CTOR( STRING, DBGCHECKSTRING );
+ DBG_ASSERT( pCharStr, "String::String() - pCharStr is NULL" );
+
+ if ( nLen == STRING_LEN )
+ nLen = ImplStringLen( pCharStr );
+
+#ifdef DBG_UTIL
+ if ( DbgIsAssert() )
+ {
+ for ( xub_StrLen i = 0; i < nLen; i++ )
+ {
+ if ( !pCharStr[i] )
+ {
+ DBG_ERROR( "String::String() : nLen is wrong" );
+ }
+ }
+ }
+#endif
+
+ // Ist es kein leerer String
+ if ( nLen )
+ {
+ // Verwaltungsdaten anlegen und String kopieren
+ mpData = ImplAllocData( nLen );
+ memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) );
+ }
+ else
+ {
+ STRING_NEW((STRING_TYPE **)&mpData);
+ }
+}
+
+// -----------------------------------------------------------------------
+
+STRING::STRING( STRCODE c )
+{
+ DBG_CTOR( STRING, DBGCHECKSTRING );
+ DBG_ASSERT( c, "String::String() - c is 0" );
+
+ // Verwaltungsdaten anlegen und initialisieren
+ mpData = ImplAllocData( 1 );
+ mpData->maStr[0] = c;
+}
+
+// -----------------------------------------------------------------------
+
+STRING::~STRING()
+{
+ DBG_DTOR( STRING, DBGCHECKSTRING );
+
+ // Daten loeschen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Assign( const STRING& rStr )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+
+ STRING_ACQUIRE((STRING_TYPE *)rStr.mpData);
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = rStr.mpData;
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Assign( const STRCODE* pCharStr )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_ASSERT( pCharStr, "String::Assign() - pCharStr is NULL" );
+
+ // Stringlaenge ermitteln
+ xub_StrLen nLen = ImplStringLen( pCharStr );
+
+ if ( !nLen )
+ {
+ STRING_NEW((STRING_TYPE **)&mpData);
+ }
+ else
+ {
+ // Wenn String genauso lang ist, wie der String, dann direkt kopieren
+ if ( (nLen == mpData->mnLen) && (mpData->mnRefCount == 1) )
+ memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) );
+ else
+ {
+ // Alte Daten loeschen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+
+ // Daten initialisieren und String kopieren
+ mpData = ImplAllocData( nLen );
+ memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) );
+ }
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Assign( const STRCODE* pCharStr, xub_StrLen nLen )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_ASSERT( pCharStr, "String::Assign() - pCharStr is NULL" );
+
+ if ( nLen == STRING_LEN )
+ nLen = ImplStringLen( pCharStr );
+
+#ifdef DBG_UTIL
+ if ( DbgIsAssert() )
+ {
+ for ( xub_StrLen i = 0; i < nLen; i++ )
+ {
+ if ( !pCharStr[i] )
+ {
+ DBG_ERROR( "String::Assign() : nLen is wrong" );
+ }
+ }
+ }
+#endif
+
+ if ( !nLen )
+ {
+ STRING_NEW((STRING_TYPE **)&mpData);
+ }
+ else
+ {
+ // Wenn String genauso lang ist, wie der String, dann direkt kopieren
+ if ( (nLen == mpData->mnLen) && (mpData->mnRefCount == 1) )
+ memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) );
+ else
+ {
+ // Alte Daten loeschen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+
+ // Daten initialisieren und String kopieren
+ mpData = ImplAllocData( nLen );
+ memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) );
+ }
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Assign( STRCODE c )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_ASSERT( c, "String::Assign() - c is 0" );
+
+ // Verwaltungsdaten anlegen und initialisieren
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = ImplAllocData( 1 );
+ mpData->maStr[0] = c;
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Append( const STRING& rStr )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+
+ // Wenn String leer, dann reicht eine Zuweisung
+ sal_Int32 nLen = mpData->mnLen;
+ if ( !nLen )
+ {
+ STRING_ACQUIRE((STRING_TYPE *)rStr.mpData);
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = rStr.mpData;
+ }
+ else
+ {
+ // Ueberlauf abfangen
+ sal_Int32 nCopyLen = ImplGetCopyLen( nLen, rStr.mpData->mnLen );
+
+ // Ist der uebergebene String kein Leerstring
+ if ( nCopyLen )
+ {
+ // Neue Datenstruktur und neuen String erzeugen
+ STRINGDATA* pNewData = ImplAllocData( nLen+nCopyLen );
+
+ // String kopieren
+ memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) );
+ memcpy( pNewData->maStr+nLen, rStr.mpData->maStr, nCopyLen*sizeof( STRCODE ) );
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+ }
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Append( const STRCODE* pCharStr )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_ASSERT( pCharStr, "String::Append() - pCharStr is NULL" );
+
+ // Stringlaenge ermitteln
+ sal_Int32 nLen = mpData->mnLen;
+ sal_Int32 nCopyLen = ImplStringLen( pCharStr );
+
+ // Ueberlauf abfangen
+ nCopyLen = ImplGetCopyLen( nLen, nCopyLen );
+
+ // Ist es kein leerer String
+ if ( nCopyLen )
+ {
+ // Neue Datenstruktur und neuen String erzeugen
+ STRINGDATA* pNewData = ImplAllocData( nLen+nCopyLen );
+
+ // String kopieren
+ memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) );
+ memcpy( pNewData->maStr+nLen, pCharStr, nCopyLen*sizeof( STRCODE ) );
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Append( const STRCODE* pCharStr, xub_StrLen nCharLen )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_ASSERT( pCharStr, "String::Append() - pCharStr is NULL" );
+
+ if ( nCharLen == STRING_LEN )
+ nCharLen = ImplStringLen( pCharStr );
+
+#ifdef DBG_UTIL
+ if ( DbgIsAssert() )
+ {
+ for ( xub_StrLen i = 0; i < nCharLen; i++ )
+ {
+ if ( !pCharStr[i] )
+ {
+ DBG_ERROR( "String::Append() : nLen is wrong" );
+ }
+ }
+ }
+#endif
+
+ // Ueberlauf abfangen
+ sal_Int32 nLen = mpData->mnLen;
+ sal_Int32 nCopyLen = ImplGetCopyLen( nLen, nCharLen );
+
+ // Ist es kein leerer String
+ if ( nCopyLen )
+ {
+ // Neue Datenstruktur und neuen String erzeugen
+ STRINGDATA* pNewData = ImplAllocData( nLen+nCopyLen );
+
+ // String kopieren
+ memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) );
+ memcpy( pNewData->maStr+nLen, pCharStr, nCopyLen*sizeof( STRCODE ) );
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Append( STRCODE c )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ // kein 0-Character und maximale Stringlaenge nicht ueberschreiten
+ sal_Int32 nLen = mpData->mnLen;
+ if ( c && (nLen < STRING_MAXLEN) )
+ {
+ // Neue Datenstruktur und neuen String erzeugen
+ STRINGDATA* pNewData = ImplAllocData( nLen+1 );
+
+ // String kopieren
+ memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) );
+ pNewData->maStr[nLen] = c;
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+void STRING::SetChar( xub_StrLen nIndex, STRCODE c )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_ASSERT( nIndex < mpData->mnLen, "String::SetChar() - nIndex > String.Len()" );
+
+ // Daten kopieren, wenn noetig und Character zuweisen
+ ImplCopyData();
+ mpData->maStr[nIndex] = c;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Insert( const STRING& rStr, xub_StrLen nIndex )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+
+ // Ueberlauf abfangen
+ sal_Int32 nCopyLen = ImplGetCopyLen( mpData->mnLen, rStr.mpData->mnLen );
+
+ // Ist der einzufuegende String ein Leerstring
+ if ( !nCopyLen )
+ return *this;
+
+ // Index groesser als Laenge
+ if ( nIndex > mpData->mnLen )
+ nIndex = static_cast< xub_StrLen >(mpData->mnLen);
+
+ // Neue Laenge ermitteln und neuen String anlegen
+ STRINGDATA* pNewData = ImplAllocData( mpData->mnLen+nCopyLen );
+
+ // String kopieren
+ memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) );
+ memcpy( pNewData->maStr+nIndex, rStr.mpData->maStr, nCopyLen*sizeof( STRCODE ) );
+ memcpy( pNewData->maStr+nIndex+nCopyLen, mpData->maStr+nIndex,
+ (mpData->mnLen-nIndex)*sizeof( STRCODE ) );
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Insert( const STRING& rStr, xub_StrLen nPos, xub_StrLen nLen,
+ xub_StrLen nIndex )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+
+ // Stringlaenge ermitteln
+ if ( nPos > rStr.mpData->mnLen )
+ nLen = 0;
+ else
+ {
+ // Laenge korrigieren, wenn noetig
+ sal_Int32 nMaxLen = rStr.mpData->mnLen-nPos;
+ if ( nLen > nMaxLen )
+ nLen = static_cast< xub_StrLen >(nMaxLen);
+ }
+
+ // Ueberlauf abfangen
+ sal_Int32 nCopyLen = ImplGetCopyLen( mpData->mnLen, nLen );
+
+ // Ist der einzufuegende String ein Leerstring
+ if ( !nCopyLen )
+ return *this;
+
+ // Index groesser als Laenge
+ if ( nIndex > mpData->mnLen )
+ nIndex = static_cast< xub_StrLen >(mpData->mnLen);
+
+ // Neue Laenge ermitteln und neuen String anlegen
+ STRINGDATA* pNewData = ImplAllocData( mpData->mnLen+nCopyLen );
+
+ // String kopieren
+ memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) );
+ memcpy( pNewData->maStr+nIndex, rStr.mpData->maStr+nPos, nCopyLen*sizeof( STRCODE ) );
+ memcpy( pNewData->maStr+nIndex+nCopyLen, mpData->maStr+nIndex,
+ (mpData->mnLen-nIndex)*sizeof( STRCODE ) );
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Insert( const STRCODE* pCharStr, xub_StrLen nIndex )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_ASSERT( pCharStr, "String::Insert() - pCharStr is NULL" );
+
+ // Stringlaenge ermitteln
+ sal_Int32 nCopyLen = ImplStringLen( pCharStr );
+
+ // Ueberlauf abfangen
+ nCopyLen = ImplGetCopyLen( mpData->mnLen, nCopyLen );
+
+ // Ist der einzufuegende String ein Leerstring
+ if ( !nCopyLen )
+ return *this;
+
+ // Index groesser als Laenge
+ if ( nIndex > mpData->mnLen )
+ nIndex = static_cast< xub_StrLen >(mpData->mnLen);
+
+ // Neue Laenge ermitteln und neuen String anlegen
+ STRINGDATA* pNewData = ImplAllocData( mpData->mnLen+nCopyLen );
+
+ // String kopieren
+ memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) );
+ memcpy( pNewData->maStr+nIndex, pCharStr, nCopyLen*sizeof( STRCODE ) );
+ memcpy( pNewData->maStr+nIndex+nCopyLen, mpData->maStr+nIndex,
+ (mpData->mnLen-nIndex)*sizeof( STRCODE ) );
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Insert( STRCODE c, xub_StrLen nIndex )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ // Ist es kein 0-Character
+ if ( !c || (mpData->mnLen == STRING_MAXLEN) )
+ return *this;
+
+ // Index groesser als Laenge
+ if ( nIndex > mpData->mnLen )
+ nIndex = static_cast< xub_StrLen >(mpData->mnLen);
+
+ // Neue Laenge ermitteln und neuen String anlegen
+ STRINGDATA* pNewData = ImplAllocData( mpData->mnLen+1 );
+
+ // String kopieren
+ memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) );
+ pNewData->maStr[nIndex] = c;
+ memcpy( pNewData->maStr+nIndex+1, mpData->maStr+nIndex,
+ (mpData->mnLen-nIndex)*sizeof( STRCODE ) );
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Replace( xub_StrLen nIndex, xub_StrLen nCount, const STRING& rStr )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+
+ // Wenn Index groessergleich Laenge ist, dann ist es ein Append
+ if ( nIndex >= mpData->mnLen )
+ {
+ Append( rStr );
+ return *this;
+ }
+
+ // Ist es eine Zuweisung
+ if ( (nIndex == 0) && (nCount >= mpData->mnLen) )
+ {
+ Assign( rStr );
+ return *this;
+ }
+
+ // Reicht ein Erase
+ sal_Int32 nStrLen = rStr.mpData->mnLen;
+ if ( !nStrLen )
+ return Erase( nIndex, nCount );
+
+ // nCount darf nicht ueber das Stringende hinnausgehen
+ if ( nCount > mpData->mnLen - nIndex )
+ nCount = static_cast< xub_StrLen >(mpData->mnLen-nIndex);
+
+ // Reicht ein Insert
+ if ( !nCount )
+ return Insert( rStr, nIndex );
+
+ // Reicht eine zeichenweise Zuweisung
+ if ( nCount == nStrLen )
+ {
+ ImplCopyData();
+ memcpy( mpData->maStr+nIndex, rStr.mpData->maStr, nCount*sizeof( STRCODE ) );
+ return *this;
+ }
+
+ // Ueberlauf abfangen
+ nStrLen = ImplGetCopyLen( mpData->mnLen-nCount, nStrLen );
+
+ // Neue Daten anlegen
+ STRINGDATA* pNewData = ImplAllocData( mpData->mnLen-nCount+nStrLen );
+
+ // String kopieren
+ memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) );
+ memcpy( pNewData->maStr+nIndex, rStr.mpData->maStr, nStrLen*sizeof( STRCODE ) );
+ memcpy( pNewData->maStr+nIndex+nStrLen, mpData->maStr+nIndex+nCount,
+ (mpData->mnLen-nIndex-nCount+1)*sizeof( STRCODE ) );
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Erase( xub_StrLen nIndex, xub_StrLen nCount )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ // Ist der Index ausserhalb des Strings oder ist nCount == 0
+ if ( (nIndex >= mpData->mnLen) || !nCount )
+ return *this;
+
+ // nCount darf nicht ueber das Stringende hinnausgehen
+ if ( nCount > mpData->mnLen - nIndex )
+ nCount = static_cast< xub_StrLen >(mpData->mnLen-nIndex);
+
+ // Ist das Ergebnis kein Leerstring
+ if ( mpData->mnLen - nCount )
+ {
+ // Neue Daten anlegen
+ STRINGDATA* pNewData = ImplAllocData( mpData->mnLen-nCount );
+
+ // String kopieren
+ memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) );
+ memcpy( pNewData->maStr+nIndex, mpData->maStr+nIndex+nCount,
+ (mpData->mnLen-nIndex-nCount+1)*sizeof( STRCODE ) );
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+ }
+ else
+ {
+ STRING_NEW((STRING_TYPE **)&mpData);
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Fill( xub_StrLen nCount, STRCODE cFillChar )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ if ( !nCount )
+ return *this;
+
+ // Ist nCount groesser wie der jetzige String, dann verlaengern
+ if ( nCount > mpData->mnLen )
+ {
+ // dann neuen String mit der neuen Laenge anlegen
+ STRINGDATA* pNewData = ImplAllocData( nCount );
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+ }
+ else
+ ImplCopyData();
+
+ STRCODE* pStr = mpData->maStr;
+ do
+ {
+ *pStr = cFillChar;
+ ++pStr,
+ --nCount;
+ }
+ while ( nCount );
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Expand( xub_StrLen nCount, STRCODE cExpandChar )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ // Muss der String erweitert werden
+ sal_Int32 nLen = mpData->mnLen;
+ if ( nCount <= nLen )
+ return *this;
+
+ // Neuen String anlegen
+ STRINGDATA* pNewData = ImplAllocData( nCount );
+
+ // Alten String kopieren
+ memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) );
+
+ // und initialisieren
+ STRCODE* pStr = pNewData->maStr;
+ pStr += nLen;
+ for (sal_Int32 i = nCount - nLen; i > 0; --i) {
+ *pStr++ = cExpandChar;
+ }
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::EraseLeadingChars( STRCODE c )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ if ( mpData->maStr[0] != c )
+ return *this;
+
+ xub_StrLen nStart = 0;
+ while ( mpData->maStr[nStart] == c )
+ ++nStart;
+
+ return Erase( 0, nStart );
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::EraseTrailingChars( STRCODE c )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ sal_Int32 nEnd = mpData->mnLen;
+ while ( nEnd && (mpData->maStr[nEnd-1] == c) )
+ nEnd--;
+
+ if ( nEnd != mpData->mnLen )
+ Erase( static_cast< xub_StrLen >(nEnd) );
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::EraseLeadingAndTrailingChars( STRCODE c )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ xub_StrLen nStart = 0;
+ while ( mpData->maStr[nStart] == c )
+ ++nStart;
+ if ( nStart )
+ Erase( 0, nStart );
+
+ sal_Int32 nEnd = mpData->mnLen;
+ while ( nEnd && (mpData->maStr[nEnd-1] == c) )
+ nEnd--;
+ if ( nEnd != mpData->mnLen )
+ Erase( static_cast< xub_StrLen >(nEnd) );
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::EraseAllChars( STRCODE c )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ sal_Int32 nCount = 0;
+ for (sal_Int32 i = 0; i < mpData->mnLen; ++i) {
+ if ( mpData->maStr[i] == c )
+ ++nCount;
+ }
+
+ if ( nCount )
+ {
+ if ( nCount == mpData->mnLen )
+ {
+ STRING_NEW((STRING_TYPE **)&mpData);
+ }
+ else
+ {
+ // Neuen String anlegen
+ STRINGDATA* pNewData = ImplAllocData( mpData->mnLen-nCount );
+
+ // Alten String kopieren und initialisieren
+ nCount = 0;
+ for( xub_StrLen j = 0; j < mpData->mnLen; ++j )
+ {
+ if ( mpData->maStr[j] != c )
+ {
+ pNewData->maStr[nCount] = mpData->maStr[j];
+ ++nCount;
+ }
+ }
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+ }
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::Reverse()
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ if ( !mpData->mnLen )
+ return *this;
+
+ // Daten kopieren, wenn noetig
+ ImplCopyData();
+
+ // Reverse
+ sal_Int32 nCount = mpData->mnLen / 2;
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ {
+ STRCODE cTemp = mpData->maStr[i];
+ mpData->maStr[i] = mpData->maStr[mpData->mnLen-i-1];
+ mpData->maStr[mpData->mnLen-i-1] = cTemp;
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::ToLowerAscii()
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ sal_Int32 nIndex = 0;
+ sal_Int32 nLen = mpData->mnLen;
+ STRCODE* pStr = mpData->maStr;
+ while ( nIndex < nLen )
+ {
+ // Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln
+ if ( (*pStr >= 65) && (*pStr <= 90) )
+ {
+ // Daten kopieren, wenn noetig
+ pStr = ImplCopyStringData( pStr );
+ *pStr += 32;
+ }
+
+ ++pStr,
+ ++nIndex;
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::ToUpperAscii()
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ sal_Int32 nIndex = 0;
+ sal_Int32 nLen = mpData->mnLen;
+ STRCODE* pStr = mpData->maStr;
+ while ( nIndex < nLen )
+ {
+ // Ist das Zeichen zwischen 'a' und 'z' dann umwandeln
+ if ( (*pStr >= 97) && (*pStr <= 122) )
+ {
+ // Daten kopieren, wenn noetig
+ pStr = ImplCopyStringData( pStr );
+ *pStr -= 32;
+ }
+
+ ++pStr,
+ ++nIndex;
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+STRING& STRING::ConvertLineEnd( LineEnd eLineEnd )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ // Zeilenumbrueche ermitteln und neue Laenge berechnen
+ BOOL bConvert = FALSE; // Muss konvertiert werden
+ const STRCODE* pStr = mpData->maStr; // damit es schneller geht
+ xub_StrLen nLineEndLen = (eLineEnd == LINEEND_CRLF) ? 2 : 1;
+ xub_StrLen nLen = 0; // Ziel-Laenge
+ xub_StrLen i = 0; // Source-Zaehler
+
+ while ( i < mpData->mnLen )
+ {
+ // Bei \r oder \n gibt es neuen Zeilenumbruch
+ if ( (pStr[i] == _CR) || (pStr[i] == _LF) )
+ {
+ nLen = nLen + nLineEndLen;
+
+ // Wenn schon gesetzt, dann brauchen wir keine aufwendige Abfrage
+ if ( !bConvert )
+ {
+ // Muessen wir Konvertieren
+ if ( ((eLineEnd != LINEEND_LF) && (pStr[i] == _LF)) ||
+ ((eLineEnd == LINEEND_CRLF) && (pStr[i+1] != _LF)) ||
+ ((eLineEnd == LINEEND_LF) &&
+ ((pStr[i] == _CR) || (pStr[i+1] == _CR))) ||
+ ((eLineEnd == LINEEND_CR) &&
+ ((pStr[i] == _LF) || (pStr[i+1] == _LF))) )
+ bConvert = TRUE;
+ }
+
+ // \r\n oder \n\r, dann Zeichen ueberspringen
+ if ( ((pStr[i+1] == _CR) || (pStr[i+1] == _LF)) &&
+ (pStr[i] != pStr[i+1]) )
+ ++i;
+ }
+ else
+ ++nLen;
+ ++i;
+
+ // Wenn String zu lang, dann konvertieren wir nicht
+ if ( nLen >= STRING_MAXLEN )
+ return *this;
+ }
+
+ // Zeilenumbrueche konvertieren
+ if ( bConvert )
+ {
+ // Neuen String anlegen
+ STRINGDATA* pNewData = ImplAllocData( nLen );
+ xub_StrLen j = 0;
+ i = 0;
+ while ( i < mpData->mnLen )
+ {
+ // Bei \r oder \n gibt es neuen Zeilenumbruch
+ if ( (pStr[i] == _CR) || (pStr[i] == _LF) )
+ {
+ if ( eLineEnd == LINEEND_CRLF )
+ {
+ pNewData->maStr[j] = _CR;
+ pNewData->maStr[j+1] = _LF;
+ j += 2;
+ }
+ else
+ {
+ if ( eLineEnd == LINEEND_CR )
+ pNewData->maStr[j] = _CR;
+ else
+ pNewData->maStr[j] = _LF;
+ ++j;
+ }
+
+ if ( ((pStr[i+1] == _CR) || (pStr[i+1] == _LF)) &&
+ (pStr[i] != pStr[i+1]) )
+ ++i;
+ }
+ else
+ {
+ pNewData->maStr[j] = mpData->maStr[i];
+ ++j;
+ }
+
+ ++i;
+ }
+
+ // Alte Daten loeschen und Neue zuweisen
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+StringCompare STRING::CompareTo( const STRING& rStr, xub_StrLen nLen ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+
+ // Auf Gleichheit der Pointer testen
+ if ( mpData == rStr.mpData )
+ return COMPARE_EQUAL;
+
+ // Maximale Laenge ermitteln
+ if ( mpData->mnLen < nLen )
+ nLen = static_cast< xub_StrLen >(mpData->mnLen+1);
+ if ( rStr.mpData->mnLen < nLen )
+ nLen = static_cast< xub_StrLen >(rStr.mpData->mnLen+1);
+
+ // String vergleichen
+ sal_Int32 nCompare = ImplStringCompareWithoutZero( mpData->maStr, rStr.mpData->maStr, nLen );
+
+ // Rueckgabewert anpassen
+ if ( nCompare == 0 )
+ return COMPARE_EQUAL;
+ else if ( nCompare < 0 )
+ return COMPARE_LESS;
+ else
+ return COMPARE_GREATER;
+}
+
+// -----------------------------------------------------------------------
+
+StringCompare STRING::CompareTo( const STRCODE* pCharStr, xub_StrLen nLen ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ // String vergleichen
+ sal_Int32 nCompare = ImplStringCompare( mpData->maStr, pCharStr, nLen );
+
+ // Rueckgabewert anpassen
+ if ( nCompare == 0 )
+ return COMPARE_EQUAL;
+ else if ( nCompare < 0 )
+ return COMPARE_LESS;
+ else
+ return COMPARE_GREATER;
+}
+
+// -----------------------------------------------------------------------
+
+StringCompare STRING::CompareIgnoreCaseToAscii( const STRING& rStr,
+ xub_StrLen nLen ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+
+ // Auf Gleichheit der Pointer testen
+ if ( mpData == rStr.mpData )
+ return COMPARE_EQUAL;
+
+ // Maximale Laenge ermitteln
+ if ( mpData->mnLen < nLen )
+ nLen = static_cast< xub_StrLen >(mpData->mnLen+1);
+ if ( rStr.mpData->mnLen < nLen )
+ nLen = static_cast< xub_StrLen >(rStr.mpData->mnLen+1);
+
+ // String vergleichen
+ sal_Int32 nCompare = ImplStringICompareWithoutZero( mpData->maStr, rStr.mpData->maStr, nLen );
+
+ // Rueckgabewert anpassen
+ if ( nCompare == 0 )
+ return COMPARE_EQUAL;
+ else if ( nCompare < 0 )
+ return COMPARE_LESS;
+ else
+ return COMPARE_GREATER;
+}
+
+// -----------------------------------------------------------------------
+
+StringCompare STRING::CompareIgnoreCaseToAscii( const STRCODE* pCharStr,
+ xub_StrLen nLen ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ // String vergleichen
+ sal_Int32 nCompare = ImplStringICompare( mpData->maStr, pCharStr, nLen );
+
+ // Rueckgabewert anpassen
+ if ( nCompare == 0 )
+ return COMPARE_EQUAL;
+ else if ( nCompare < 0 )
+ return COMPARE_LESS;
+ else
+ return COMPARE_GREATER;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL STRING::Equals( const STRING& rStr ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+
+ // Sind die Daten gleich
+ if ( mpData == rStr.mpData )
+ return TRUE;
+
+ // Gleiche Laenge
+ if ( mpData->mnLen != rStr.mpData->mnLen )
+ return FALSE;
+
+ // String vergleichen
+ return (ImplStringCompareWithoutZero( mpData->maStr, rStr.mpData->maStr, mpData->mnLen ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL STRING::Equals( const STRCODE* pCharStr ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ return (ImplStringCompare( mpData->maStr, pCharStr ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL STRING::EqualsIgnoreCaseAscii( const STRING& rStr ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+
+ // Sind die Daten gleich
+ if ( mpData == rStr.mpData )
+ return TRUE;
+
+ // Gleiche Laenge
+ if ( mpData->mnLen != rStr.mpData->mnLen )
+ return FALSE;
+
+ // String vergleichen
+ return (ImplStringICompareWithoutZero( mpData->maStr, rStr.mpData->maStr, mpData->mnLen ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL STRING::EqualsIgnoreCaseAscii( const STRCODE* pCharStr ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ return (ImplStringICompare( mpData->maStr, pCharStr ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL STRING::Equals( const STRING& rStr, xub_StrLen nIndex, xub_StrLen nLen ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+
+ // Are there enough codes for comparing?
+ if ( nIndex > mpData->mnLen )
+ return (rStr.mpData->mnLen == 0);
+ sal_Int32 nMaxLen = mpData->mnLen-nIndex;
+ if ( nMaxLen < nLen )
+ {
+ if ( rStr.mpData->mnLen != nMaxLen )
+ return FALSE;
+ nLen = static_cast< xub_StrLen >(nMaxLen);
+ }
+
+ // String vergleichen
+ return (ImplStringCompareWithoutZero( mpData->maStr+nIndex, rStr.mpData->maStr, nLen ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL STRING::Equals( const STRCODE* pCharStr, xub_StrLen nIndex, xub_StrLen nLen ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ // Are there enough codes for comparing?
+ if ( nIndex > mpData->mnLen )
+ return (*pCharStr == 0);
+
+ return (ImplStringCompare( mpData->maStr+nIndex, pCharStr, nLen ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL STRING::EqualsIgnoreCaseAscii( const STRING& rStr, xub_StrLen nIndex, xub_StrLen nLen ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+
+ // Are there enough codes for comparing?
+ if ( nIndex > mpData->mnLen )
+ return (rStr.mpData->mnLen == 0);
+ sal_Int32 nMaxLen = mpData->mnLen-nIndex;
+ if ( nMaxLen < nLen )
+ {
+ if ( rStr.mpData->mnLen != nMaxLen )
+ return FALSE;
+ nLen = static_cast< xub_StrLen >(nMaxLen);
+ }
+
+ // String vergleichen
+ return (ImplStringICompareWithoutZero( mpData->maStr+nIndex, rStr.mpData->maStr, nLen ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL STRING::EqualsIgnoreCaseAscii( const STRCODE* pCharStr, xub_StrLen nIndex, xub_StrLen nLen ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ // Are there enough codes for comparing?
+ if ( nIndex > mpData->mnLen )
+ return (*pCharStr == 0);
+
+ return (ImplStringICompare( mpData->maStr+nIndex, pCharStr, nLen ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen STRING::Match( const STRING& rStr ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+
+ // Ist dieser String leer
+ if ( !mpData->mnLen )
+ return STRING_MATCH;
+
+ // Suche bis Stringende nach dem ersten nicht uebereinstimmenden Zeichen
+ const STRCODE* pStr1 = mpData->maStr;
+ const STRCODE* pStr2 = rStr.mpData->maStr;
+ xub_StrLen i = 0;
+ while ( i < mpData->mnLen )
+ {
+ // Stimmt das Zeichen nicht ueberein, dann abbrechen
+ if ( *pStr1 != *pStr2 )
+ return i;
+ ++pStr1,
+ ++pStr2,
+ ++i;
+ }
+
+ return STRING_MATCH;
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen STRING::Match( const STRCODE* pCharStr ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ // Ist dieser String leer
+ if ( !mpData->mnLen )
+ return STRING_MATCH;
+
+ // Suche bis Stringende nach dem ersten nicht uebereinstimmenden Zeichen
+ const STRCODE* pStr = mpData->maStr;
+ xub_StrLen i = 0;
+ while ( i < mpData->mnLen )
+ {
+ // Stimmt das Zeichen nicht ueberein, dann abbrechen
+ if ( *pStr != *pCharStr )
+ return i;
+ ++pStr,
+ ++pCharStr,
+ ++i;
+ }
+
+ return STRING_MATCH;
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen STRING::Search( STRCODE c, xub_StrLen nIndex ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ sal_Int32 nLen = mpData->mnLen;
+ const STRCODE* pStr = mpData->maStr;
+ pStr += nIndex;
+ while ( nIndex < nLen )
+ {
+ if ( *pStr == c )
+ return nIndex;
+ ++pStr,
+ ++nIndex;
+ }
+
+ return STRING_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen STRING::Search( const STRING& rStr, xub_StrLen nIndex ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+
+ sal_Int32 nLen = mpData->mnLen;
+ sal_Int32 nStrLen = rStr.mpData->mnLen;
+
+ // Falls die Laenge des uebergebenen Strings 0 ist oder der Index
+ // hinter dem String liegt, dann wurde der String nicht gefunden
+ if ( !nStrLen || (nIndex >= nLen) )
+ return STRING_NOTFOUND;
+
+ const STRCODE* pStr1 = mpData->maStr;
+ pStr1 += nIndex;
+
+ if ( nStrLen == 1 )
+ {
+ STRCODE cSearch = rStr.mpData->maStr[0];
+ while ( nIndex < nLen )
+ {
+ if ( *pStr1 == cSearch )
+ return nIndex;
+ ++pStr1,
+ ++nIndex;
+ }
+ }
+ else
+ {
+ const STRCODE* pStr2 = rStr.mpData->maStr;
+
+ // Nur innerhalb des Strings suchen
+ while ( nLen - nIndex >= nStrLen )
+ {
+ // Stimmt der String ueberein
+ if ( ImplStringCompareWithoutZero( pStr1, pStr2, nStrLen ) == 0 )
+ return nIndex;
+ ++pStr1,
+ ++nIndex;
+ }
+ }
+
+ return STRING_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen STRING::Search( const STRCODE* pCharStr, xub_StrLen nIndex ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ sal_Int32 nLen = mpData->mnLen;
+ xub_StrLen nStrLen = ImplStringLen( pCharStr );
+
+ // Falls die Laenge des uebergebenen Strings 0 ist oder der Index
+ // hinter dem String liegt, dann wurde der String nicht gefunden
+ if ( !nStrLen || (nIndex >= nLen) )
+ return STRING_NOTFOUND;
+
+ const STRCODE* pStr = mpData->maStr;
+ pStr += nIndex;
+
+ if ( nStrLen == 1 )
+ {
+ STRCODE cSearch = *pCharStr;
+ while ( nIndex < nLen )
+ {
+ if ( *pStr == cSearch )
+ return nIndex;
+ ++pStr,
+ ++nIndex;
+ }
+ }
+ else
+ {
+ // Nur innerhalb des Strings suchen
+ while ( nLen - nIndex >= nStrLen )
+ {
+ // Stimmt der String ueberein
+ if ( ImplStringCompareWithoutZero( pStr, pCharStr, nStrLen ) == 0 )
+ return nIndex;
+ ++pStr,
+ ++nIndex;
+ }
+ }
+
+ return STRING_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen STRING::SearchBackward( STRCODE c, xub_StrLen nIndex ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ if ( nIndex > mpData->mnLen )
+ nIndex = (xub_StrLen)mpData->mnLen;
+
+ const STRCODE* pStr = mpData->maStr;
+ pStr += nIndex;
+
+ while ( nIndex )
+ {
+ nIndex--;
+ pStr--;
+ if ( *pStr == c )
+ return nIndex;
+ }
+
+ return STRING_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen STRING::SearchChar( const STRCODE* pChars, xub_StrLen nIndex ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ sal_Int32 nLen = mpData->mnLen;
+ const STRCODE* pStr = mpData->maStr;
+ pStr += nIndex;
+ while ( nIndex < nLen )
+ {
+ STRCODE c = *pStr;
+ const STRCODE* pCompStr = pChars;
+ while ( *pCompStr )
+ {
+ if ( *pCompStr == c )
+ return nIndex;
+ ++pCompStr;
+ }
+ ++pStr,
+ ++nIndex;
+ }
+
+ return STRING_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen STRING::SearchCharBackward( const STRCODE* pChars, xub_StrLen nIndex ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ if ( nIndex > mpData->mnLen )
+ nIndex = (xub_StrLen)mpData->mnLen;
+
+ const STRCODE* pStr = mpData->maStr;
+ pStr += nIndex;
+
+ while ( nIndex )
+ {
+ nIndex--;
+ pStr--;
+
+ STRCODE c =*pStr;
+ const STRCODE* pCompStr = pChars;
+ while ( *pCompStr )
+ {
+ if ( *pCompStr == c )
+ return nIndex;
+ ++pCompStr;
+ }
+ }
+
+ return STRING_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen STRING::SearchAndReplace( STRCODE c, STRCODE cRep, xub_StrLen nIndex )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ sal_Int32 nLen = mpData->mnLen;
+ const STRCODE* pStr = mpData->maStr;
+ pStr += nIndex;
+ while ( nIndex < nLen )
+ {
+ if ( *pStr == c )
+ {
+ ImplCopyData();
+ mpData->maStr[nIndex] = cRep;
+ return nIndex;
+ }
+ ++pStr,
+ ++nIndex;
+ }
+
+ return STRING_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen STRING::SearchAndReplace( const STRING& rStr, const STRING& rRepStr,
+ xub_StrLen nIndex )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rRepStr, STRING, DBGCHECKSTRING );
+
+ xub_StrLen nSPos = Search( rStr, nIndex );
+ if ( nSPos != STRING_NOTFOUND )
+ Replace( nSPos, rStr.Len(), rRepStr );
+
+ return nSPos;
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen STRING::SearchAndReplace( const STRCODE* pCharStr, const STRING& rRepStr,
+ xub_StrLen nIndex )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rRepStr, STRING, DBGCHECKSTRING );
+
+ xub_StrLen nSPos = Search( pCharStr, nIndex );
+ if ( nSPos != STRING_NOTFOUND )
+ Replace( nSPos, ImplStringLen( pCharStr ), rRepStr );
+
+ return nSPos;
+}
+
+// -----------------------------------------------------------------------
+
+void STRING::SearchAndReplaceAll( STRCODE c, STRCODE cRep )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ sal_Int32 nLen = mpData->mnLen;
+ const STRCODE* pStr = mpData->maStr;
+ sal_Int32 nIndex = 0;
+ while ( nIndex < nLen )
+ {
+ if ( *pStr == c )
+ {
+ ImplCopyData();
+ mpData->maStr[nIndex] = cRep;
+ }
+ ++pStr,
+ ++nIndex;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void STRING::SearchAndReplaceAll( const STRCODE* pCharStr, const STRING& rRepStr )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rRepStr, STRING, DBGCHECKSTRING );
+
+ xub_StrLen nCharLen = ImplStringLen( pCharStr );
+ xub_StrLen nSPos = Search( pCharStr, 0 );
+ while ( nSPos != STRING_NOTFOUND )
+ {
+ Replace( nSPos, nCharLen, rRepStr );
+ nSPos = nSPos + rRepStr.Len();
+ nSPos = Search( pCharStr, nSPos );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void STRING::SearchAndReplaceAll( const STRING& rStr, const STRING& rRepStr )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rRepStr, STRING, DBGCHECKSTRING );
+
+ xub_StrLen nSPos = Search( rStr, 0 );
+ while ( nSPos != STRING_NOTFOUND )
+ {
+ Replace( nSPos, rStr.Len(), rRepStr );
+ nSPos = nSPos + rRepStr.Len();
+ nSPos = Search( rStr, nSPos );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen STRING::GetTokenCount( STRCODE cTok ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ // Leerer String: TokenCount per Definition 0
+ if ( !mpData->mnLen )
+ return 0;
+
+ xub_StrLen nTokCount = 1;
+ sal_Int32 nLen = mpData->mnLen;
+ const STRCODE* pStr = mpData->maStr;
+ sal_Int32 nIndex = 0;
+ while ( nIndex < nLen )
+ {
+ // Stimmt das Tokenzeichen ueberein, dann erhoehe TokCount
+ if ( *pStr == cTok )
+ ++nTokCount;
+ ++pStr,
+ ++nIndex;
+ }
+
+ return nTokCount;
+}
+
+// -----------------------------------------------------------------------
+
+void STRING::SetToken( xub_StrLen nToken, STRCODE cTok, const STRING& rStr,
+ xub_StrLen nIndex )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
+
+ const STRCODE* pStr = mpData->maStr;
+ xub_StrLen nLen = (xub_StrLen)mpData->mnLen;
+ xub_StrLen nTok = 0;
+ xub_StrLen nFirstChar = nIndex;
+ xub_StrLen i = nFirstChar;
+
+ // Bestimme die Token-Position und Laenge
+ pStr += i;
+ while ( i < nLen )
+ {
+ // Stimmt das Tokenzeichen ueberein, dann erhoehe TokCount
+ if ( *pStr == cTok )
+ {
+ ++nTok;
+
+ if ( nTok == nToken )
+ nFirstChar = i+1;
+ else
+ {
+ if ( nTok > nToken )
+ break;
+ }
+ }
+
+ ++pStr,
+ ++i;
+ }
+
+ if ( nTok >= nToken )
+ Replace( nFirstChar, i-nFirstChar, rStr );
+}
+
+// -----------------------------------------------------------------------
+
+STRING STRING::GetToken( xub_StrLen nToken, STRCODE cTok, xub_StrLen& rIndex ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ const STRCODE* pStr = mpData->maStr;
+ xub_StrLen nLen = (xub_StrLen)mpData->mnLen;
+ xub_StrLen nTok = 0;
+ xub_StrLen nFirstChar = rIndex;
+ xub_StrLen i = nFirstChar;
+
+ // Bestimme die Token-Position und Laenge
+ pStr += i;
+ while ( i < nLen )
+ {
+ // Stimmt das Tokenzeichen ueberein, dann erhoehe TokCount
+ if ( *pStr == cTok )
+ {
+ ++nTok;
+
+ if ( nTok == nToken )
+ nFirstChar = i+1;
+ else
+ {
+ if ( nTok > nToken )
+ break;
+ }
+ }
+
+ ++pStr,
+ ++i;
+ }
+
+ if ( nTok >= nToken )
+ {
+ if ( i < nLen )
+ rIndex = i+1;
+ else
+ rIndex = STRING_NOTFOUND;
+ return Copy( nFirstChar, i-nFirstChar );
+ }
+ else
+ {
+ rIndex = STRING_NOTFOUND;
+ return STRING();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen STRING::GetQuotedTokenCount( const STRING& rQuotedPairs, STRCODE cTok ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rQuotedPairs, STRING, DBGCHECKSTRING );
+ DBG_ASSERT( !(rQuotedPairs.Len()%2), "String::GetQuotedTokenCount() - QuotedString%2 != 0" );
+ DBG_ASSERT( rQuotedPairs.Search(cTok) == STRING_NOTFOUND, "String::GetQuotedTokenCount() - cTok in QuotedString" );
+
+ // Leerer String: TokenCount per Definition 0
+ if ( !mpData->mnLen )
+ return 0;
+
+ xub_StrLen nTokCount = 1;
+ sal_Int32 nLen = mpData->mnLen;
+ xub_StrLen nQuotedLen = rQuotedPairs.Len();
+ STRCODE cQuotedEndChar = 0;
+ const STRCODE* pQuotedStr = rQuotedPairs.mpData->maStr;
+ const STRCODE* pStr = mpData->maStr;
+ sal_Int32 nIndex = 0;
+ while ( nIndex < nLen )
+ {
+ STRCODE c = *pStr;
+ if ( cQuotedEndChar )
+ {
+ // Ende des Quotes erreicht ?
+ if ( c == cQuotedEndChar )
+ cQuotedEndChar = 0;
+ }
+ else
+ {
+ // Ist das Zeichen ein Quote-Anfang-Zeichen ?
+ xub_StrLen nQuoteIndex = 0;
+ while ( nQuoteIndex < nQuotedLen )
+ {
+ if ( pQuotedStr[nQuoteIndex] == c )
+ {
+ cQuotedEndChar = pQuotedStr[nQuoteIndex+1];
+ break;
+ }
+ else
+ nQuoteIndex += 2;
+ }
+
+ // Stimmt das Tokenzeichen ueberein, dann erhoehe TokCount
+ if ( c == cTok )
+ ++nTokCount;
+ }
+
+ ++pStr,
+ ++nIndex;
+ }
+
+ return nTokCount;
+}
+
+// -----------------------------------------------------------------------
+
+STRING STRING::GetQuotedToken( xub_StrLen nToken, const STRING& rQuotedPairs,
+ STRCODE cTok, xub_StrLen& rIndex ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+ DBG_CHKOBJ( &rQuotedPairs, STRING, DBGCHECKSTRING );
+ DBG_ASSERT( !(rQuotedPairs.Len()%2), "String::GetQuotedToken() - QuotedString%2 != 0" );
+ DBG_ASSERT( rQuotedPairs.Search(cTok) == STRING_NOTFOUND, "String::GetQuotedToken() - cTok in QuotedString" );
+
+ const STRCODE* pStr = mpData->maStr;
+ const STRCODE* pQuotedStr = rQuotedPairs.mpData->maStr;
+ STRCODE cQuotedEndChar = 0;
+ xub_StrLen nQuotedLen = rQuotedPairs.Len();
+ xub_StrLen nLen = (xub_StrLen)mpData->mnLen;
+ xub_StrLen nTok = 0;
+ xub_StrLen nFirstChar = rIndex;
+ xub_StrLen i = nFirstChar;
+
+ // Bestimme die Token-Position und Laenge
+ pStr += i;
+ while ( i < nLen )
+ {
+ STRCODE c = *pStr;
+ if ( cQuotedEndChar )
+ {
+ // Ende des Quotes erreicht ?
+ if ( c == cQuotedEndChar )
+ cQuotedEndChar = 0;
+ }
+ else
+ {
+ // Ist das Zeichen ein Quote-Anfang-Zeichen ?
+ xub_StrLen nQuoteIndex = 0;
+ while ( nQuoteIndex < nQuotedLen )
+ {
+ if ( pQuotedStr[nQuoteIndex] == c )
+ {
+ cQuotedEndChar = pQuotedStr[nQuoteIndex+1];
+ break;
+ }
+ else
+ nQuoteIndex += 2;
+ }
+
+ // Stimmt das Tokenzeichen ueberein, dann erhoehe TokCount
+ if ( c == cTok )
+ {
+ ++nTok;
+
+ if ( nTok == nToken )
+ nFirstChar = i+1;
+ else
+ {
+ if ( nTok > nToken )
+ break;
+ }
+ }
+ }
+
+ ++pStr,
+ ++i;
+ }
+
+ if ( nTok >= nToken )
+ {
+ if ( i < nLen )
+ rIndex = i+1;
+ else
+ rIndex = STRING_NOTFOUND;
+ return Copy( nFirstChar, i-nFirstChar );
+ }
+ else
+ {
+ rIndex = STRING_NOTFOUND;
+ return STRING();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+STRCODE* STRING::GetBufferAccess()
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ // Daten kopieren, wenn noetig
+ if ( mpData->mnLen )
+ ImplCopyData();
+
+ // Pointer auf den String zurueckgeben
+ return mpData->maStr;
+}
+
+// -----------------------------------------------------------------------
+
+void STRING::ReleaseBufferAccess( xub_StrLen nLen )
+{
+ // Hier ohne Funktionstest, da String nicht konsistent
+ DBG_CHKTHIS( STRING, NULL );
+ DBG_ASSERT( mpData->mnRefCount == 1, "String::ReleaseCharStr() called for String with RefCount" );
+
+ if ( nLen > mpData->mnLen )
+ nLen = ImplStringLen( mpData->maStr );
+ OSL_ASSERT(nLen <= mpData->mnLen);
+ if ( !nLen )
+ {
+ STRING_NEW((STRING_TYPE **)&mpData);
+ }
+ // Bei mehr als 8 Zeichen unterschied, kuerzen wir den Buffer
+ else if ( mpData->mnLen - nLen > 8 )
+ {
+ STRINGDATA* pNewData = ImplAllocData( nLen );
+ memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) );
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = pNewData;
+ }
+ else
+ mpData->mnLen = nLen;
+}
+
+// -----------------------------------------------------------------------
+
+STRCODE* STRING::AllocBuffer( xub_StrLen nLen )
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ if ( nLen )
+ mpData = ImplAllocData( nLen );
+ else
+ {
+ mpData = NULL;
+ STRING_NEW((STRING_TYPE **)&mpData);
+ }
+
+ return mpData->maStr;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/string/strucvt.cxx b/tools/source/string/strucvt.cxx
new file mode 100644
index 000000000000..48801e67c0a0
--- /dev/null
+++ b/tools/source/string/strucvt.cxx
@@ -0,0 +1,215 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// no include "precompiled_tools.hxx" because this is included in other cxx files.
+
+// =======================================================================
+
+void UniString::InitStringRes( const char* pUTF8Str, sal_Int32 nLen )
+{
+ DBG_CTOR( UniString, DbgCheckUniString );
+ OSL_ENSURE(nLen <= STRING_MAXLEN, "Overflowing UniString");
+
+ mpData = NULL;
+ rtl_string2UString( (rtl_uString **)(&mpData),
+ pUTF8Str, nLen,
+ RTL_TEXTENCODING_UTF8,
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MAPTOPRIVATE |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT );
+}
+
+// =======================================================================
+
+UniString::UniString( const ByteString& rByteStr, rtl_TextEncoding eTextEncoding, sal_uInt32 nCvtFlags )
+{
+ DBG_CTOR( UniString, DbgCheckUniString );
+ DBG_CHKOBJ( &rByteStr, ByteString, DbgCheckByteString );
+
+ mpData = NULL;
+ rtl_string2UString( (rtl_uString **)(&mpData),
+ rByteStr.mpData->maStr, rByteStr.mpData->mnLen,
+ eTextEncoding, nCvtFlags );
+}
+
+// -----------------------------------------------------------------------
+
+UniString::UniString( const ByteString& rByteStr, xub_StrLen nPos, xub_StrLen nLen,
+ rtl_TextEncoding eTextEncoding, sal_uInt32 nCvtFlags )
+{
+ DBG_CTOR( UniString, DbgCheckUniString );
+ DBG_CHKOBJ( &rByteStr, ByteString, DbgCheckByteString );
+
+ // Stringlaenge ermitteln
+ if ( nPos > rByteStr.mpData->mnLen )
+ nLen = 0;
+ else
+ {
+ // Laenge korrigieren, wenn noetig
+ sal_Int32 nMaxLen = rByteStr.mpData->mnLen-nPos;
+ if ( nLen > nMaxLen )
+ nLen = static_cast< xub_StrLen >(nMaxLen);
+ }
+
+ mpData = NULL;
+ rtl_string2UString( (rtl_uString **)(&mpData),
+ rByteStr.mpData->maStr+nPos, nLen,
+ eTextEncoding, nCvtFlags );
+}
+
+// -----------------------------------------------------------------------
+
+UniString::UniString( const char* pByteStr,
+ rtl_TextEncoding eTextEncoding, sal_uInt32 nCvtFlags )
+{
+ DBG_CTOR( UniString, DbgCheckUniString );
+ DBG_ASSERT( pByteStr, "UniString::UniString() - pByteStr is NULL" );
+
+ mpData = NULL;
+ rtl_string2UString( (rtl_uString **)(&mpData),
+ pByteStr, ImplStringLen( pByteStr ),
+ eTextEncoding, nCvtFlags );
+}
+
+// -----------------------------------------------------------------------
+
+UniString::UniString( const char* pByteStr, xub_StrLen nLen,
+ rtl_TextEncoding eTextEncoding, sal_uInt32 nCvtFlags )
+{
+ DBG_CTOR( UniString, DbgCheckUniString );
+ DBG_ASSERT( pByteStr, "UniString::UniString() - pByteStr is NULL" );
+
+ if ( nLen == STRING_LEN )
+ nLen = ImplStringLen( pByteStr );
+
+ mpData = NULL;
+ rtl_string2UString( (rtl_uString **)(&mpData),
+ pByteStr, nLen,
+ eTextEncoding, nCvtFlags );
+}
+
+// =======================================================================
+
+UniString::UniString( const rtl::OUString& rStr )
+ : mpData(NULL)
+{
+ DBG_CTOR( UniString, DbgCheckUniString );
+
+ OSL_ENSURE(rStr.pData->length < STRING_MAXLEN,
+ "Overflowing rtl::OUString -> UniString cut to zero length");
+
+
+ if (rStr.pData->length < STRING_MAXLEN)
+ {
+ mpData = reinterpret_cast< UniStringData * >(const_cast< rtl::OUString & >(rStr).pData);
+ STRING_ACQUIRE((STRING_TYPE *)mpData);
+ }
+ else
+ {
+ STRING_NEW((STRING_TYPE **)&mpData);
+ }
+}
+
+// -----------------------------------------------------------------------
+
+UniString& UniString::Assign( const rtl::OUString& rStr )
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+
+ OSL_ENSURE(rStr.pData->length < STRING_MAXLEN,
+ "Overflowing rtl::OUString -> UniString cut to zero length");
+
+
+ if (rStr.pData->length < STRING_MAXLEN)
+ {
+ STRING_RELEASE((STRING_TYPE *)mpData);
+ mpData = reinterpret_cast< UniStringData * >(const_cast< rtl::OUString & >(rStr).pData);
+ STRING_ACQUIRE((STRING_TYPE *)mpData);
+ }
+ else
+ {
+ STRING_NEW((STRING_TYPE **)&mpData);
+ }
+
+ return *this;
+}
+
+UniString UniString::intern() const
+{
+ UniString aStr;
+
+ rtl_uString_intern( reinterpret_cast<rtl_uString **>(&aStr.mpData),
+ (rtl_uString *)(mpData) );
+
+ return aStr;
+}
+
+// =======================================================================
+
+#include <tools/rc.hxx>
+#include <tools/rcid.h>
+
+UniString::UniString( const ResId& rResId )
+{
+ rResId.SetRT( RSC_STRING );
+ ResMgr* pResMgr = rResId.GetResMgr();
+ mpData = NULL;
+ if ( pResMgr && pResMgr->GetResource( rResId ) )
+ {
+ // String laden
+ RSHEADER_TYPE * pResHdr = (RSHEADER_TYPE*)pResMgr->GetClass();
+ //sal_uInt32 nLen = pResHdr->GetLocalOff() - sizeof( RSHEADER_TYPE );
+
+ sal_Int32 nStringLen = rtl_str_getLength( (char*)(pResHdr+1) );
+ InitStringRes( (const char*)(pResHdr+1), nStringLen );
+
+ sal_uInt32 nSize = sizeof( RSHEADER_TYPE )
+ + sal::static_int_cast< sal_uInt32 >(nStringLen) + 1;
+ nSize += nSize % 2;
+ pResMgr->Increment( nSize );
+ }
+ else
+ {
+ STRING_NEW((STRING_TYPE **)&mpData);
+
+#if OSL_DEBUG_LEVEL > 0
+ *this = UniString::CreateFromAscii( "<resource id " );
+ Append( UniString::CreateFromInt32( rResId.GetId() ) );
+ AppendAscii( " not found>" );
+#endif
+ if( pResMgr )
+ pResMgr->PopContext();
+ }
+
+
+ ResHookProc pImplResHookProc = ResMgr::GetReadStringHook();
+ if ( pImplResHookProc )
+ pImplResHookProc( *this );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/string/tenccvt.cxx b/tools/source/string/tenccvt.cxx
new file mode 100644
index 000000000000..4ae8df5d5da4
--- /dev/null
+++ b/tools/source/string/tenccvt.cxx
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <rtl/tencinfo.h>
+#include <tools/tenccvt.hxx>
+
+// =======================================================================
+
+rtl_TextEncoding GetExtendedCompatibilityTextEncoding( rtl_TextEncoding eEncoding )
+{
+ // Latin1
+ if ( eEncoding == RTL_TEXTENCODING_ISO_8859_1 )
+ return RTL_TEXTENCODING_MS_1252;
+ // Turkey
+ else if ( eEncoding == RTL_TEXTENCODING_ISO_8859_9 )
+ return RTL_TEXTENCODING_MS_1254;
+ else
+ return eEncoding;
+}
+
+// -----------------------------------------------------------------------
+
+rtl_TextEncoding GetExtendedTextEncoding( rtl_TextEncoding eEncoding )
+{
+ // Cyr
+ if ( eEncoding == RTL_TEXTENCODING_ISO_8859_5 )
+ return RTL_TEXTENCODING_MS_1251;
+ // Greek (2 Characters different: A1 (0x2018/0x0385), A2 (0x2019/0x0386) -
+ // so it is handled in this function and not in GetExtendedCompatibilityTextEncoding)
+ else if ( eEncoding == RTL_TEXTENCODING_ISO_8859_7 )
+ return RTL_TEXTENCODING_MS_1253;
+ // East-Europe - Latin2
+ else if ( eEncoding == RTL_TEXTENCODING_ISO_8859_2 )
+ return RTL_TEXTENCODING_MS_1250;
+ // Latin-15 - Latin 1 mit Euro-Sign
+ else if ( eEncoding == RTL_TEXTENCODING_ISO_8859_15 )
+ return RTL_TEXTENCODING_MS_1252;
+ else
+ return GetExtendedCompatibilityTextEncoding( eEncoding );
+}
+
+// -----------------------------------------------------------------------
+
+rtl_TextEncoding GetOneByteTextEncoding( rtl_TextEncoding eEncoding )
+{
+ rtl_TextEncodingInfo aTextEncInfo;
+ aTextEncInfo.StructSize = sizeof( aTextEncInfo );
+ if ( rtl_getTextEncodingInfo( eEncoding, &aTextEncInfo ) )
+ {
+ if ( aTextEncInfo.MaximumCharSize > 1 )
+ return RTL_TEXTENCODING_MS_1252;
+ else
+ return eEncoding;
+ }
+ else
+ return RTL_TEXTENCODING_MS_1252;
+}
+
+// -----------------------------------------------------------------------
+
+rtl_TextEncoding GetSOLoadTextEncoding( rtl_TextEncoding eEncoding, USHORT /* nVersion = SOFFICE_FILEFORMAT_50 */ )
+{
+ return GetExtendedCompatibilityTextEncoding( GetOneByteTextEncoding( eEncoding ) );
+}
+
+// -----------------------------------------------------------------------
+
+rtl_TextEncoding GetSOStoreTextEncoding( rtl_TextEncoding eEncoding, USHORT /* nVersion = SOFFICE_FILEFORMAT_50 */ )
+{
+ return GetExtendedTextEncoding( GetOneByteTextEncoding( eEncoding ) );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/string/tstring.cxx b/tools/source/string/tstring.cxx
new file mode 100644
index 000000000000..c82338e2eeaf
--- /dev/null
+++ b/tools/source/string/tstring.cxx
@@ -0,0 +1,290 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <string.h>
+
+#include "boost/static_assert.hpp"
+
+#include "osl/diagnose.h"
+#include <osl/interlck.h>
+#include <rtl/alloc.h>
+#include <rtl/memory.h>
+#include <rtl/tencinfo.h>
+#include <rtl/instance.hxx>
+
+#include <tools/string.hxx>
+#include <impstrg.hxx>
+
+// For shared byte convert tables
+#include <toolsin.hxx>
+
+#include <tools/debug.hxx>
+
+// =======================================================================
+
+DBG_NAME( ByteString )
+DBG_NAMEEX( UniString )
+
+// -----------------------------------------------------------------------
+
+#define STRCODE sal_Char
+#define STRCODEU unsigned char
+#define STRING ByteString
+#define STRINGDATA ByteStringData
+#define DBGCHECKSTRING DbgCheckByteString
+#define STRING_TYPE rtl_String
+#define STRING_ACQUIRE rtl_string_acquire
+#define STRING_RELEASE rtl_string_release
+#define STRING_NEW rtl_string_new
+
+
+// -----------------------------------------------------------------------
+
+xub_StrLen ImplStringLen( const sal_Char* pStr )
+{
+ const sal_Char* pTempStr = pStr;
+ while( *pTempStr )
+ ++pTempStr;
+ return (xub_StrLen)(pTempStr-pStr);
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen ImplStringLen( const sal_Unicode* pStr )
+{
+ const sal_Unicode* pTempStr = pStr;
+ while( *pTempStr )
+ ++pTempStr;
+ return (xub_StrLen)(pTempStr-pStr);
+}
+
+// -----------------------------------------------------------------------
+
+#include <strimp.cxx>
+#include <strcvt.cxx>
+
+// -----------------------------------------------------------------------
+
+ByteString ByteString::CreateFromInt32( sal_Int32 n, sal_Int16 nRadix )
+{
+ sal_Char aBuf[RTL_STR_MAX_VALUEOFINT32];
+ BOOST_STATIC_ASSERT(RTL_STR_MAX_VALUEOFINT32 <= STRING_MAXLEN);
+ return ByteString(
+ aBuf,
+ static_cast< xub_StrLen >(rtl_str_valueOfInt32( aBuf, n, nRadix )) );
+}
+
+// -----------------------------------------------------------------------
+
+ByteString ByteString::CreateFromInt64( sal_Int64 n, sal_Int16 nRadix )
+{
+ sal_Char aBuf[RTL_STR_MAX_VALUEOFINT64];
+ BOOST_STATIC_ASSERT(RTL_STR_MAX_VALUEOFINT64 <= STRING_MAXLEN);
+ return ByteString(
+ aBuf,
+ static_cast< xub_StrLen >(rtl_str_valueOfInt64( aBuf, n, nRadix )) );
+}
+
+// -----------------------------------------------------------------------
+
+ByteString ByteString::CreateFromFloat( float f )
+{
+ sal_Char aBuf[RTL_STR_MAX_VALUEOFFLOAT];
+ BOOST_STATIC_ASSERT(RTL_STR_MAX_VALUEOFFLOAT <= STRING_MAXLEN);
+ return ByteString(
+ aBuf, static_cast< xub_StrLen >(rtl_str_valueOfFloat( aBuf, f )) );
+}
+
+// -----------------------------------------------------------------------
+
+ByteString ByteString::CreateFromDouble( double d )
+{
+ sal_Char aBuf[RTL_STR_MAX_VALUEOFDOUBLE];
+ BOOST_STATIC_ASSERT(RTL_STR_MAX_VALUEOFDOUBLE <= STRING_MAXLEN);
+ return ByteString(
+ aBuf, static_cast< xub_StrLen >(rtl_str_valueOfDouble( aBuf, d )) );
+}
+
+// -----------------------------------------------------------------------
+
+namespace { struct Empty : public rtl::Static< const ByteString, Empty> {}; }
+const ByteString& ByteString::EmptyString()
+{
+ return Empty::get();
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int32 ByteString::ToInt32() const
+{
+ DBG_CHKTHIS( ByteString, DbgCheckByteString );
+
+ return atoi( mpData->maStr );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 ByteString::ToInt64() const
+{
+ DBG_CHKTHIS( ByteString, DbgCheckByteString );
+
+ return atoi( mpData->maStr );
+}
+
+// -----------------------------------------------------------------------
+
+float ByteString::ToFloat() const
+{
+ DBG_CHKTHIS( ByteString, DbgCheckByteString );
+
+ OSL_ENSURE(false, "ByteString::ToFloat unusable");
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+double ByteString::ToDouble() const
+{
+ DBG_CHKTHIS( ByteString, DbgCheckByteString );
+
+ OSL_ENSURE(false, "ByteString::ToDouble unusable");
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ByteString::IsLowerAscii() const
+{
+ DBG_CHKTHIS( ByteString, DbgCheckByteString );
+
+ sal_Int32 nIndex = 0;
+ sal_Int32 nLen = mpData->mnLen;
+ const sal_Char* pStr = mpData->maStr;
+ while ( nIndex < nLen )
+ {
+ if ( (*pStr >= 65) && (*pStr <= 90) )
+ return FALSE;
+
+ ++pStr,
+ ++nIndex;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ByteString::IsUpperAscii() const
+{
+ DBG_CHKTHIS( ByteString, DbgCheckByteString );
+
+ sal_Int32 nIndex = 0;
+ sal_Int32 nLen = mpData->mnLen;
+ const sal_Char* pStr = mpData->maStr;
+ while ( nIndex < nLen )
+ {
+ if ( (*pStr >= 97) && (*pStr <= 122) )
+ return FALSE;
+
+ ++pStr,
+ ++nIndex;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ByteString::IsAlphaAscii() const
+{
+ DBG_CHKTHIS( ByteString, DbgCheckByteString );
+
+ sal_Int32 nIndex = 0;
+ sal_Int32 nLen = mpData->mnLen;
+ const sal_Char* pStr = mpData->maStr;
+ while ( nIndex < nLen )
+ {
+ if ( !(((*pStr >= 97) && (*pStr <= 122)) ||
+ ((*pStr >= 65) && (*pStr <= 90))) )
+ return FALSE;
+
+ ++pStr,
+ ++nIndex;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ByteString::IsNumericAscii() const
+{
+ DBG_CHKTHIS( ByteString, DbgCheckByteString );
+
+ sal_Int32 nIndex = 0;
+ sal_Int32 nLen = mpData->mnLen;
+ const sal_Char* pStr = mpData->maStr;
+ while ( nIndex < nLen )
+ {
+ if ( !((*pStr >= 48) && (*pStr <= 57)) )
+ return FALSE;
+
+ ++pStr,
+ ++nIndex;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ByteString::IsAlphaNumericAscii() const
+{
+ DBG_CHKTHIS( ByteString, DbgCheckByteString );
+
+ sal_Int32 nIndex = 0;
+ sal_Int32 nLen = mpData->mnLen;
+ const sal_Char* pStr = mpData->maStr;
+ while ( nIndex < nLen )
+ {
+ if ( !(((*pStr >= 97) && (*pStr <= 122)) ||
+ ((*pStr >= 65) && (*pStr <= 90)) ||
+ ((*pStr >= 48) && (*pStr <= 57))) )
+ return FALSE;
+
+ ++pStr,
+ ++nIndex;
+ }
+
+ return TRUE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/string/tustring.cxx b/tools/source/string/tustring.cxx
new file mode 100644
index 000000000000..c99d0a812e37
--- /dev/null
+++ b/tools/source/string/tustring.cxx
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <string.h>
+
+#include "boost/static_assert.hpp"
+
+#include <osl/interlck.h>
+#include <rtl/alloc.h>
+#include <rtl/memory.h>
+#include <rtl/tencinfo.h>
+#include <rtl/instance.hxx>
+
+#include <tools/string.hxx>
+#include <impstrg.hxx>
+
+#include <tools/debug.hxx>
+
+// =======================================================================
+
+DBG_NAME( UniString )
+DBG_NAMEEX( ByteString )
+
+// -----------------------------------------------------------------------
+
+#define STRCODE sal_Unicode
+#define STRCODEU sal_Unicode
+#define STRING UniString
+#define STRINGDATA UniStringData
+#define DBGCHECKSTRING DbgCheckUniString
+#define STRING_TYPE rtl_uString
+#define STRING_ACQUIRE rtl_uString_acquire
+#define STRING_RELEASE rtl_uString_release
+#define STRING_NEW rtl_uString_new
+
+// -----------------------------------------------------------------------
+
+#include <strimp.cxx>
+#include <strucvt.cxx>
+#include <strascii.cxx>
+
+UniString::UniString(char c): mpData(ImplAllocData(1)) { mpData->maStr[0] = c; }
+
+// -----------------------------------------------------------------------
+
+UniString UniString::CreateFromInt32( sal_Int32 n, sal_Int16 nRadix )
+{
+ sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFINT32];
+ BOOST_STATIC_ASSERT(RTL_USTR_MAX_VALUEOFINT32 <= STRING_MAXLEN);
+ return UniString(
+ aBuf,
+ static_cast< xub_StrLen >(rtl_ustr_valueOfInt32( aBuf, n, nRadix )) );
+}
+
+// -----------------------------------------------------------------------
+
+UniString UniString::CreateFromInt64( sal_Int64 n, sal_Int16 nRadix )
+{
+ sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFINT64];
+ BOOST_STATIC_ASSERT(RTL_USTR_MAX_VALUEOFINT64 <= STRING_MAXLEN);
+ return UniString(
+ aBuf,
+ static_cast< xub_StrLen >(rtl_ustr_valueOfInt64( aBuf, n, nRadix )) );
+}
+
+// -----------------------------------------------------------------------
+
+UniString UniString::CreateFromFloat( float f )
+{
+ sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFFLOAT];
+ BOOST_STATIC_ASSERT(RTL_USTR_MAX_VALUEOFFLOAT <= STRING_MAXLEN);
+ return UniString(
+ aBuf, static_cast< xub_StrLen >(rtl_ustr_valueOfFloat( aBuf, f )) );
+}
+
+// -----------------------------------------------------------------------
+
+UniString UniString::CreateFromDouble( double d )
+{
+ sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFDOUBLE];
+ BOOST_STATIC_ASSERT(RTL_USTR_MAX_VALUEOFDOUBLE <= STRING_MAXLEN);
+ return UniString(
+ aBuf, static_cast< xub_StrLen >(rtl_ustr_valueOfDouble( aBuf, d )) );
+}
+
+// -----------------------------------------------------------------------
+
+namespace { struct Empty : public rtl::Static< const UniString, Empty> {}; }
+const UniString& UniString::EmptyString()
+{
+ return Empty::get();
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int32 UniString::ToInt32() const
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+
+ return rtl_ustr_toInt32( mpData->maStr, 10 );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 UniString::ToInt64() const
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+
+ return rtl_ustr_toInt64( mpData->maStr, 10 );
+}
+
+// -----------------------------------------------------------------------
+
+float UniString::ToFloat() const
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+
+ return rtl_ustr_toFloat( mpData->maStr );
+}
+
+// -----------------------------------------------------------------------
+
+double UniString::ToDouble() const
+{
+ DBG_CHKTHIS( UniString, DbgCheckUniString );
+
+ return rtl_ustr_toDouble( mpData->maStr );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/testtoolloader/makefile.mk b/tools/source/testtoolloader/makefile.mk
new file mode 100644
index 000000000000..3d5cb8223e3f
--- /dev/null
+++ b/tools/source/testtoolloader/makefile.mk
@@ -0,0 +1,45 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=TOOLS
+TARGET=testtoolloader
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/testtoolloader.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/tools/source/testtoolloader/testtoolloader.cxx b/tools/source/testtoolloader/testtoolloader.cxx
new file mode 100644
index 000000000000..c0e60ca53c9a
--- /dev/null
+++ b/tools/source/testtoolloader/testtoolloader.cxx
@@ -0,0 +1,186 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include "tools/testtoolloader.hxx"
+#include <osl/module.h>
+#include <rtl/logfile.hxx>
+#include <osl/process.h>
+#include "tools/solar.h"
+#include "tools/string.hxx"
+#include "tools/debug.hxx"
+
+#include <comphelper/uieventslogger.hxx>
+
+using namespace rtl;
+
+namespace tools
+{
+ typedef void ( *pfunc_CreateRemoteControl)();
+ typedef void ( *pfunc_DestroyRemoteControl)();
+
+ typedef void ( *pfunc_CreateEventLogger)();
+ typedef void ( *pfunc_DestroyEventLogger)();
+
+static oslModule aTestToolModule = 0;
+// are we to be automated at all?
+static bool bAutomate = false;
+static bool bLoggerStarted = false;
+
+
+sal_uInt32 GetCommandLineParamCount()
+{
+ return osl_getCommandArgCount();
+}
+
+String GetCommandLineParam( sal_uInt32 nParam )
+{
+ ::rtl::OUString aParam;
+ oslProcessError eError = osl_getCommandArg( nParam, &aParam.pData );
+ if ( eError == osl_Process_E_None )
+ return String( aParam );
+ else
+ {
+ DBG_ERROR( "Unable to get CommandLineParam" );
+ return String();
+ }
+}
+
+extern "C" { static void SAL_CALL thisModule() {} }
+
+void LoadLib()
+{
+ if ( !aTestToolModule )
+ {
+ aTestToolModule = osl_loadModuleRelative(
+ &thisModule,
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SVLIBRARY("sts"))).pData,
+ SAL_LOADMODULE_GLOBAL );
+ }
+}
+
+void InitTestToolLib()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::InitTestToolLib" );
+
+ sal_uInt32 i;
+
+ for ( i = 0 ; i < GetCommandLineParamCount() ; i++ )
+ {
+ if ( GetCommandLineParam( i ).EqualsIgnoreCaseAscii("/enableautomation")
+ || GetCommandLineParam( i ).EqualsIgnoreCaseAscii("-enableautomation"))
+ {
+ bAutomate = true;
+ break;
+ }
+ }
+
+ if ( bAutomate )
+ {
+ OUString aFuncName( RTL_CONSTASCII_USTRINGPARAM( "CreateRemoteControl" ));
+
+ LoadLib();
+ if ( aTestToolModule )
+ {
+ oslGenericFunction pInitFunc = osl_getFunctionSymbol(
+ aTestToolModule, aFuncName.pData );
+ if ( pInitFunc )
+ (reinterpret_cast< pfunc_CreateRemoteControl >(pInitFunc))();
+ else
+ {
+ DBG_ERROR1( "Unable to get Symbol 'CreateRemoteControl' from library %s while loading testtool support.", SVLIBRARY( "sts" ) );
+ }
+ }
+ else
+ {
+ DBG_ERROR1( "Unable to access library %s while loading testtool support.", SVLIBRARY( "sts" ) );
+ }
+ }
+
+ if ( ::comphelper::UiEventsLogger::isEnabled() )
+ {
+ OUString aFuncName( RTL_CONSTASCII_USTRINGPARAM( "CreateEventLogger" ));
+
+ LoadLib();
+ if ( aTestToolModule )
+ {
+ oslGenericFunction pInitFunc = osl_getFunctionSymbol(
+ aTestToolModule, aFuncName.pData );
+ if ( pInitFunc )
+ {
+ (reinterpret_cast< pfunc_CreateEventLogger >(pInitFunc))();
+ bLoggerStarted = TRUE;
+ }
+ else
+ {
+ DBG_ERROR1( "Unable to get Symbol 'CreateEventLogger' from library %s while loading testtool support.", SVLIBRARY( "sts" ) );
+ }
+ }
+ else
+ {
+ DBG_ERROR1( "Unable to access library %s while loading testtool support.", SVLIBRARY( "sts" ) );
+ }
+ }
+}
+
+void DeInitTestToolLib()
+{
+ if ( aTestToolModule )
+ {
+ if ( bAutomate )
+ {
+ OUString aFuncName( RTL_CONSTASCII_USTRINGPARAM( "DestroyRemoteControl" ));
+
+ oslGenericFunction pDeInitFunc = osl_getFunctionSymbol(
+ aTestToolModule, aFuncName.pData );
+ if ( pDeInitFunc )
+ (reinterpret_cast< pfunc_DestroyRemoteControl >(pDeInitFunc))();
+ }
+
+ if ( bLoggerStarted /*::comphelper::UiEventsLogger::isEnabled()*/ )
+ {
+ OUString aFuncName( RTL_CONSTASCII_USTRINGPARAM( "DestroyEventLogger" ));
+
+ oslGenericFunction pDeInitFunc = osl_getFunctionSymbol(
+ aTestToolModule, aFuncName.pData );
+ if ( pDeInitFunc )
+ {
+ (reinterpret_cast< pfunc_DestroyEventLogger >(pDeInitFunc))();
+ bLoggerStarted = FALSE;
+ }
+ }
+
+ osl_unloadModule( aTestToolModule );
+ }
+}
+
+} // namespace tools
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/zcodec/makefile.mk b/tools/source/zcodec/makefile.mk
new file mode 100644
index 000000000000..9067b45c3b5d
--- /dev/null
+++ b/tools/source/zcodec/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=tools
+TARGET=zcodec
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(SYSTEM_ZLIB)" == "YES"
+CFLAGS+=-DSYSTEM_ZLIB
+.ENDIF
+SLOFILES= $(SLO)$/zcodec.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/tools/source/zcodec/zcodec.cxx b/tools/source/zcodec/zcodec.cxx
new file mode 100644
index 000000000000..5ff57cd3cd43
--- /dev/null
+++ b/tools/source/zcodec/zcodec.cxx
@@ -0,0 +1,490 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <tools/stream.hxx>
+#ifndef _ZLIB_H
+#ifdef SYSTEM_ZLIB
+#include "zlib.h"
+#else
+#include "zlib/zlib.h"
+#endif
+#endif
+#include <tools/zcodec.hxx>
+#include <rtl/crc.h>
+#include <osl/endian.h>
+
+// -----------
+// - Defines -
+// -----------
+
+#define PZSTREAM ((z_stream*) mpsC_Stream)
+
+/* gzip flag byte */
+#define GZ_ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
+#define GZ_HEAD_CRC 0x02 /* bit 1 set: header CRC present */
+#define GZ_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define GZ_ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define GZ_COMMENT 0x10 /* bit 4 set: file comment present */
+#define GZ_RESERVED 0xE0 /* bits 5..7: reserved */
+
+static int gz_magic[2] = { 0x1f, 0x8b }; /* gzip magic header */
+
+
+// ----------
+// - ZCodec -
+// ----------
+
+ZCodec::ZCodec( ULONG nInBufSize, ULONG nOutBufSize, ULONG nMemUsage )
+ : mnCRC(0)
+{
+ mnMemUsage = nMemUsage;
+ mnInBufSize = nInBufSize;
+ mnOutBufSize = nOutBufSize;
+ mpsC_Stream = new z_stream;
+}
+
+ZCodec::ZCodec( void )
+ : mnCRC(0)
+{
+ mnMemUsage = MAX_MEM_USAGE;
+ mnInBufSize = DEFAULT_IN_BUFSIZE;
+ mnOutBufSize = DEFAULT_OUT_BUFSIZE;
+ mpsC_Stream = new z_stream;
+}
+
+// ------------------------------------------------------------------------
+
+ZCodec::~ZCodec()
+{
+ delete (z_stream*) mpsC_Stream;
+}
+
+// ------------------------------------------------------------------------
+
+void ZCodec::BeginCompression( ULONG nCompressMethod )
+{
+ mbInit = 0;
+ mbStatus = TRUE;
+ mbFinish = FALSE;
+ mpIStm = mpOStm = NULL;
+ mnInToRead = 0xffffffff;
+ mpInBuf = mpOutBuf = NULL;
+ PZSTREAM->total_out = PZSTREAM->total_in = 0;
+ mnCompressMethod = nCompressMethod;
+ PZSTREAM->zalloc = ( alloc_func )0;
+ PZSTREAM->zfree = ( free_func )0;
+ PZSTREAM->opaque = ( voidpf )0;
+ PZSTREAM->avail_out = PZSTREAM->avail_in = 0;
+}
+
+// ------------------------------------------------------------------------
+
+long ZCodec::EndCompression()
+{
+ long retvalue = 0;
+
+ if ( mbInit != 0 )
+ {
+ if ( mbInit & 2 ) // 1->decompress, 3->compress
+ {
+ do
+ {
+ ImplWriteBack();
+ }
+ while ( deflate( PZSTREAM, Z_FINISH ) != Z_STREAM_END );
+
+ ImplWriteBack();
+
+ retvalue = PZSTREAM->total_in;
+ deflateEnd( PZSTREAM );
+ }
+ else
+ {
+ retvalue = PZSTREAM->total_out;
+ inflateEnd( PZSTREAM );
+ }
+ delete[] mpOutBuf;
+ delete[] mpInBuf;
+ }
+ return ( mbStatus ) ? retvalue : -1;
+}
+
+
+// ------------------------------------------------------------------------
+
+long ZCodec::Compress( SvStream& rIStm, SvStream& rOStm )
+{
+ long nOldTotal_In = PZSTREAM->total_in;
+
+ if ( mbInit == 0 )
+ {
+ mpIStm = &rIStm;
+ mpOStm = &rOStm;
+ ImplInitBuf( FALSE );
+ mpInBuf = new BYTE[ mnInBufSize ];
+ }
+ while (( PZSTREAM->avail_in = mpIStm->Read( PZSTREAM->next_in = mpInBuf, mnInBufSize )) != 0 )
+ {
+ if ( PZSTREAM->avail_out == 0 )
+ ImplWriteBack();
+ if ( deflate( PZSTREAM, Z_NO_FLUSH ) < 0 )
+ {
+ mbStatus = FALSE;
+ break;
+ }
+ };
+ return ( mbStatus ) ? (long)(PZSTREAM->total_in - nOldTotal_In) : -1;
+}
+
+// ------------------------------------------------------------------------
+
+long ZCodec::Decompress( SvStream& rIStm, SvStream& rOStm )
+{
+ int err;
+ ULONG nInToRead;
+ long nOldTotal_Out = PZSTREAM->total_out;
+
+ if ( mbFinish )
+ return PZSTREAM->total_out - nOldTotal_Out;
+
+ if ( mbInit == 0 )
+ {
+ mpIStm = &rIStm;
+ mpOStm = &rOStm;
+ ImplInitBuf( TRUE );
+ PZSTREAM->next_out = mpOutBuf = new BYTE[ PZSTREAM->avail_out = mnOutBufSize ];
+ }
+ do
+ {
+ if ( PZSTREAM->avail_out == 0 ) ImplWriteBack();
+ if ( PZSTREAM->avail_in == 0 && mnInToRead )
+ {
+ nInToRead = ( mnInBufSize > mnInToRead ) ? mnInToRead : mnInBufSize;
+ PZSTREAM->avail_in = mpIStm->Read( PZSTREAM->next_in = mpInBuf, nInToRead );
+ mnInToRead -= nInToRead;
+
+ if ( mnCompressMethod & ZCODEC_UPDATE_CRC )
+ mnCRC = UpdateCRC( mnCRC, mpInBuf, nInToRead );
+
+ }
+ err = inflate( PZSTREAM, Z_NO_FLUSH );
+ if ( err < 0 )
+ {
+ mbStatus = FALSE;
+ break;
+ }
+
+ }
+ while ( ( err != Z_STREAM_END) && ( PZSTREAM->avail_in || mnInToRead ) );
+ ImplWriteBack();
+
+ if ( err == Z_STREAM_END )
+ mbFinish = TRUE;
+ return ( mbStatus ) ? (long)(PZSTREAM->total_out - nOldTotal_Out) : -1;
+}
+
+// ------------------------------------------------------------------------
+
+long ZCodec::Write( SvStream& rOStm, const BYTE* pData, ULONG nSize )
+{
+ if ( mbInit == 0 )
+ {
+ mpOStm = &rOStm;
+ ImplInitBuf( FALSE );
+ }
+
+ PZSTREAM->avail_in = nSize;
+ PZSTREAM->next_in = (unsigned char*)pData;
+
+ while ( PZSTREAM->avail_in || ( PZSTREAM->avail_out == 0 ) )
+ {
+ if ( PZSTREAM->avail_out == 0 )
+ ImplWriteBack();
+
+ if ( deflate( PZSTREAM, Z_NO_FLUSH ) < 0 )
+ {
+ mbStatus = FALSE;
+ break;
+ }
+ }
+ return ( mbStatus ) ? (long)nSize : -1;
+}
+
+// ------------------------------------------------------------------------
+
+long ZCodec::Read( SvStream& rIStm, BYTE* pData, ULONG nSize )
+{
+ int err;
+ ULONG nInToRead;
+
+ if ( mbFinish )
+ return 0; // PZSTREAM->total_out;
+
+ mpIStm = &rIStm;
+ if ( mbInit == 0 )
+ {
+ ImplInitBuf( TRUE );
+ }
+ PZSTREAM->avail_out = nSize;
+ PZSTREAM->next_out = pData;
+ do
+ {
+ if ( PZSTREAM->avail_in == 0 && mnInToRead )
+ {
+ nInToRead = (mnInBufSize > mnInToRead) ? mnInToRead : mnInBufSize;
+ PZSTREAM->avail_in = mpIStm->Read (
+ PZSTREAM->next_in = mpInBuf, nInToRead);
+ mnInToRead -= nInToRead;
+
+ if ( mnCompressMethod & ZCODEC_UPDATE_CRC )
+ mnCRC = UpdateCRC( mnCRC, mpInBuf, nInToRead );
+
+ }
+ err = inflate( PZSTREAM, Z_NO_FLUSH );
+ if ( err < 0 )
+ {
+ // Accept Z_BUF_ERROR as EAGAIN or EWOULDBLOCK.
+ mbStatus = (err == Z_BUF_ERROR);
+ break;
+ }
+ }
+ while ( (err != Z_STREAM_END) &&
+ (PZSTREAM->avail_out != 0) &&
+ (PZSTREAM->avail_in || mnInToRead) );
+ if ( err == Z_STREAM_END )
+ mbFinish = TRUE;
+
+ return (mbStatus ? (long)(nSize - PZSTREAM->avail_out) : -1);
+}
+
+// ------------------------------------------------------------------------
+
+long ZCodec::ReadAsynchron( SvStream& rIStm, BYTE* pData, ULONG nSize )
+{
+ int err = 0;
+ ULONG nInToRead;
+
+ if ( mbFinish )
+ return 0; // PZSTREAM->total_out;
+
+ if ( mbInit == 0 )
+ {
+ mpIStm = &rIStm;
+ ImplInitBuf( TRUE );
+ }
+ PZSTREAM->avail_out = nSize;
+ PZSTREAM->next_out = pData;
+ do
+ {
+ if ( PZSTREAM->avail_in == 0 && mnInToRead )
+ {
+ nInToRead = (mnInBufSize > mnInToRead) ? mnInToRead : mnInBufSize;
+
+ ULONG nStreamPos = rIStm.Tell();
+ rIStm.Seek( STREAM_SEEK_TO_END );
+ ULONG nMaxPos = rIStm.Tell();
+ rIStm.Seek( nStreamPos );
+ if ( ( nMaxPos - nStreamPos ) < nInToRead )
+ {
+ rIStm.SetError( ERRCODE_IO_PENDING );
+ err= ! Z_STREAM_END; // TODO What is appropriate code for this?
+ break;
+ }
+
+ PZSTREAM->avail_in = mpIStm->Read (
+ PZSTREAM->next_in = mpInBuf, nInToRead);
+ mnInToRead -= nInToRead;
+
+ if ( mnCompressMethod & ZCODEC_UPDATE_CRC )
+ mnCRC = UpdateCRC( mnCRC, mpInBuf, nInToRead );
+
+ }
+ err = inflate( PZSTREAM, Z_NO_FLUSH );
+ if ( err < 0 )
+ {
+ // Accept Z_BUF_ERROR as EAGAIN or EWOULDBLOCK.
+ mbStatus = (err == Z_BUF_ERROR);
+ break;
+ }
+ }
+ while ( (err != Z_STREAM_END) &&
+ (PZSTREAM->avail_out != 0) &&
+ (PZSTREAM->avail_in || mnInToRead) );
+ if ( err == Z_STREAM_END )
+ mbFinish = TRUE;
+
+ return (mbStatus ? (long)(nSize - PZSTREAM->avail_out) : -1);
+}
+
+// ------------------------------------------------------------------------
+
+void ZCodec::ImplWriteBack()
+{
+ ULONG nAvail = mnOutBufSize - PZSTREAM->avail_out;
+
+ if ( nAvail )
+ {
+ if ( mbInit & 2 && ( mnCompressMethod & ZCODEC_UPDATE_CRC ) )
+ mnCRC = UpdateCRC( mnCRC, mpOutBuf, nAvail );
+ mpOStm->Write( PZSTREAM->next_out = mpOutBuf, nAvail );
+ PZSTREAM->avail_out = mnOutBufSize;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void ZCodec::SetBreak( ULONG nInToRead )
+{
+ mnInToRead = nInToRead;
+}
+
+// ------------------------------------------------------------------------
+
+ULONG ZCodec::GetBreak( void )
+{
+ return ( mnInToRead + PZSTREAM->avail_in );
+}
+
+// ------------------------------------------------------------------------
+
+void ZCodec::SetCRC( ULONG nCRC )
+{
+ mnCRC = nCRC;
+}
+
+// ------------------------------------------------------------------------
+
+ULONG ZCodec::GetCRC()
+{
+ return mnCRC;
+}
+
+// ------------------------------------------------------------------------
+
+void ZCodec::ImplInitBuf ( BOOL nIOFlag )
+{
+ if ( mbInit == 0 )
+ {
+ if ( nIOFlag )
+ {
+ mbInit = 1;
+ if ( mbStatus && ( mnCompressMethod & ZCODEC_GZ_LIB ) )
+ {
+ BYTE n1, n2, j, nMethod, nFlags;
+ for ( int i = 0; i < 2; i++ ) // gz - magic number
+ {
+ *mpIStm >> j;
+ if ( j != gz_magic[ i ] )
+ mbStatus = FALSE;
+ }
+ *mpIStm >> nMethod;
+ *mpIStm >> nFlags;
+ if ( nMethod != Z_DEFLATED )
+ mbStatus = FALSE;
+ if ( ( nFlags & GZ_RESERVED ) != 0 )
+ mbStatus = FALSE;
+ /* Discard time, xflags and OS code: */
+ mpIStm->SeekRel( 6 );
+ /* skip the extra field */
+ if ( nFlags & GZ_EXTRA_FIELD )
+ {
+ *mpIStm >> n1 >> n2;
+ mpIStm->SeekRel( n1 + ( n2 << 8 ) );
+ }
+ /* skip the original file name */
+ if ( nFlags & GZ_ORIG_NAME)
+ {
+ do
+ {
+ *mpIStm >> j;
+ }
+ while ( j && !mpIStm->IsEof() );
+ }
+ /* skip the .gz file comment */
+ if ( nFlags & GZ_COMMENT )
+ {
+ do
+ {
+ *mpIStm >> j;
+ }
+ while ( j && !mpIStm->IsEof() );
+ }
+ /* skip the header crc */
+ if ( nFlags & GZ_HEAD_CRC )
+ mpIStm->SeekRel( 2 );
+ if ( mbStatus )
+ mbStatus = ( inflateInit2( PZSTREAM, -MAX_WBITS) != Z_OK ) ? FALSE : TRUE;
+ }
+ else
+ {
+ mbStatus = ( inflateInit( PZSTREAM ) >= 0 );
+ }
+ mpInBuf = new BYTE[ mnInBufSize ];
+ }
+ else
+ {
+ mbInit = 3;
+
+ mbStatus = ( deflateInit2_( PZSTREAM, mnCompressMethod & 0xff, Z_DEFLATED,
+ MAX_WBITS, mnMemUsage, ( mnCompressMethod >> 8 ) & 0xff,
+ ZLIB_VERSION, sizeof( z_stream ) ) >= 0 );
+
+ PZSTREAM->next_out = mpOutBuf = new BYTE[ PZSTREAM->avail_out = mnOutBufSize ];
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+ULONG ZCodec::UpdateCRC ( ULONG nLatestCRC, ULONG nNumber )
+{
+
+#ifdef OSL_LITENDIAN
+ nNumber = SWAPLONG( nNumber );
+#endif
+ return rtl_crc32( nLatestCRC, &nNumber, 4 );
+}
+
+// ------------------------------------------------------------------------
+
+ULONG ZCodec::UpdateCRC ( ULONG nLatestCRC, BYTE* pSource, long nDatSize)
+{
+ return rtl_crc32( nLatestCRC, pSource, nDatSize );
+}
+
+// ------------------------------------------------------------------------
+
+void GZCodec::BeginCompression( ULONG nCompressMethod )
+{
+ ZCodec::BeginCompression( nCompressMethod | ZCODEC_GZ_LIB );
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/test/export.map b/tools/test/export.map
new file mode 100644
index 000000000000..0dbbcc5a7372
--- /dev/null
+++ b/tools/test/export.map
@@ -0,0 +1,34 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+UDK_3_0_0 {
+ global:
+ cppunitTestPlugIn;
+
+ local:
+ *;
+};
diff --git a/tools/test/makefile.mk b/tools/test/makefile.mk
new file mode 100644
index 000000000000..573dd91f736d
--- /dev/null
+++ b/tools/test/makefile.mk
@@ -0,0 +1,64 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=tools
+TARGET=tests
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+CFLAGSCXX += $(CPPUNIT_CFLAGS)
+
+# --- Common ----------------------------------------------------------
+
+SHL1OBJS= \
+ $(SLO)$/tests.obj
+
+SHL1TARGET= tests
+SHL1STDLIBS= $(SALLIB) \
+ $(TOOLSLIB) \
+ $(CPPUNITLIB)
+
+SHL1IMPLIB= i$(SHL1TARGET)
+
+DEF1NAME =$(SHL1TARGET)
+SHL1VERSIONMAP = export.map
+
+#------------------------------- All object files ----------------------------
+
+# do this here, so we get right dependencies
+SLOFILES=$(SHL1OBJS)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+.INCLUDE : _cppunit.mk
diff --git a/tools/test/tests.cxx b/tools/test/tests.cxx
new file mode 100644
index 000000000000..14559ee1298a
--- /dev/null
+++ b/tools/test/tests.cxx
@@ -0,0 +1,124 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+// autogenerated file with codegen.pl
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <rtl/math.hxx>
+#include <tools/fract.hxx>
+
+namespace tools
+{
+
+class FractionTest : public CppUnit::TestFixture
+{
+public:
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ void testFraction()
+ {
+ const Fraction aFract(1082130431,1073741824);
+ CPPUNIT_ASSERT_MESSAGE( "Fraction #1 not approximately equal to 1.007812499068677",
+ rtl::math::approxEqual((double)aFract,1.007812499068677) );
+
+ Fraction aFract2( aFract );
+ aFract2.ReduceInaccurate(8);
+ CPPUNIT_ASSERT_MESSAGE( "Fraction #2 not 1",
+ aFract2.GetNumerator() == 1 &&
+ aFract2.GetDenominator() == 1 );
+
+ Fraction aFract3( 0x7AAAAAAA, 0x35555555 );
+ CPPUNIT_ASSERT_MESSAGE( "Fraction #3 cancellation wrong",
+ aFract3.GetNumerator() == 0x7AAAAAAA &&
+ aFract3.GetDenominator() == 0x35555555 );
+ aFract3.ReduceInaccurate(30);
+ CPPUNIT_ASSERT_MESSAGE( "Fraction #3 ReduceInaccurate errorneously cut precision",
+ aFract3.GetNumerator() == 0x7AAAAAAA &&
+ aFract3.GetDenominator() == 0x35555555 );
+
+ aFract3.ReduceInaccurate(29);
+ CPPUNIT_ASSERT_MESSAGE( "Fraction #3 reduce to 29 bits failed",
+ aFract3.GetNumerator() == 0x3D555555 &&
+ aFract3.GetDenominator() == 0x1AAAAAAA );
+
+ aFract3.ReduceInaccurate(9);
+ CPPUNIT_ASSERT_MESSAGE( "Fraction #3 reduce to 9 bits failed",
+ aFract3.GetNumerator() == 0x0147 &&
+ aFract3.GetDenominator() == 0x008E );
+
+ aFract3.ReduceInaccurate(1);
+ CPPUNIT_ASSERT_MESSAGE( "Fraction #3 reduce to 1 bit failed",
+ aFract3.GetNumerator() == 2 &&
+ aFract3.GetDenominator() == 1 );
+
+ aFract3.ReduceInaccurate(0);
+ CPPUNIT_ASSERT_MESSAGE( "Fraction #3 reduce to 0 bits failed",
+ aFract3.GetNumerator() == 2 &&
+ aFract3.GetDenominator() == 1 );
+
+#if SAL_TYPES_SIZEOFLONG == 8
+ Fraction aFract4(0x7AAAAAAAAAAAAAAA, 0x3555555555555555);
+ CPPUNIT_ASSERT_MESSAGE( "Fraction #4 cancellation wrong",
+ aFract4.GetNumerator() == 0x7AAAAAAAAAAAAAAA &&
+ aFract4.GetDenominator() == 0x3555555555555555 );
+ aFract4.ReduceInaccurate(62);
+ CPPUNIT_ASSERT_MESSAGE( "Fraction #4 ReduceInaccurate errorneously cut precision",
+ aFract4.GetNumerator() == 0x7AAAAAAAAAAAAAAA &&
+ aFract4.GetDenominator() == 0x3555555555555555 );
+
+ aFract4.ReduceInaccurate(61);
+ CPPUNIT_ASSERT_MESSAGE( "Fraction #4 ReduceInaccurate reduce to 61 bit failed",
+ aFract4.GetNumerator() == 0x3D55555555555555 &&
+ aFract4.GetDenominator() == 0x1AAAAAAAAAAAAAAA );
+#endif
+ }
+
+ CPPUNIT_TEST_SUITE(FractionTest);
+ CPPUNIT_TEST(testFraction);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+// -----------------------------------------------------------------------------
+CPPUNIT_TEST_SUITE_REGISTRATION(FractionTest);
+} // namespace tools
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/unx/source/dll/makefile.mk b/tools/unx/source/dll/makefile.mk
new file mode 100644
index 000000000000..da1d73f04682
--- /dev/null
+++ b/tools/unx/source/dll/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=TOOLS
+TARGET=dll
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES= toolsdll.cxx
+
+SLOFILES= $(SLO)$/toolsdll.obj
+
+OBJFILES= $(OBJ)$/toolsdll.obj
+
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/tools/unx/source/dll/toolsdll.cxx b/tools/unx/source/dll/toolsdll.cxx
new file mode 100644
index 000000000000..60c223c85774
--- /dev/null
+++ b/tools/unx/source/dll/toolsdll.cxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <tools/shl.hxx>
+
+static void* aAppData[SHL_COUNT];
+
+/***************************************************************************
+|*
+|* GetAppData()
+|*
+|* Beschreibung Daten fuer andere Libs abfragen
+|* Ersterstellung TH 19.01.95
+|* Letzte Aenderung TH 19.01.95
+|*
+***************************************************************************/
+
+void** GetAppData( USHORT nSharedLib )
+{
+ return &(aAppData[nSharedLib]);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/util/makefile.mk b/tools/util/makefile.mk
new file mode 100644
index 000000000000..7a2008c0b864
--- /dev/null
+++ b/tools/util/makefile.mk
@@ -0,0 +1,173 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=TOOLS
+TARGET=tools
+ENABLE_EXCEPTIONS=true
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Allgemein ----------------------------------------------------
+
+# --- STDSTRM.LIB ---
+LIB3TARGET= $(LB)$/stdstrm.lib
+LIB3ARCHIV= $(LB)$/libstdstrm.a
+LIB3FILES= $(LB)$/stream.lib
+
+LIB7TARGET= $(LB)$/a$(TARGET).lib
+LIB7ARCHIV= $(LB)$/liba$(TARGET).a
+LIB7FILES= $(LB)$/gen.lib \
+ $(LB)$/str.lib \
+ $(LB)$/mtools.lib \
+ $(LB)$/datetime.lib \
+ $(LB)$/fsys.lib \
+ $(LB)$/communi.lib \
+ $(LB)$/stream.lib \
+ $(LB)$/ref.lib \
+ $(LB)$/rc.lib \
+ $(LB)$/inet.lib \
+ $(LB)$/debug.lib
+
+
+LIB7FILES+= $(LB)$/dll.lib
+
+# --- TOOLS.LIB ---
+LIB1TARGET:= $(SLB)$/$(TARGET).lib
+LIB1FILES+= \
+ $(SLB)$/gen.lib \
+ $(SLB)$/str.lib \
+ $(SLB)$/mtools.lib \
+ $(SLB)$/datetime.lib \
+ $(SLB)$/fsys.lib \
+ $(SLB)$/communi.lib \
+ $(SLB)$/stream.lib \
+ $(SLB)$/ref.lib \
+ $(SLB)$/rc.lib \
+ $(SLB)$/debug.lib \
+ $(SLB)$/zcodec.lib \
+ $(SLB)$/inet.lib \
+ $(SLB)$/testtoolloader.lib \
+ $(SLB)$/misc.lib
+
+.IF "$(OS)"=="MACOSX"
+SHL1STDLIBS += $(CPPULIB) \
+ $(ZLIB3RDLIB)
+.ELSE
+SHL1STDLIBS += $(ZLIB3RDLIB) \
+ $(CPPULIB)
+.ENDIF
+
+LIB1FILES+= $(SLB)$/dll.lib
+
+
+.IF "$(BIG_TOOLS)"!=""
+.IF "$(GUI)"=="WNT"
+#SOLARLIBDIR=$(SOLARVER)\$((INPATH)\lib
+#SOLARLIBDIR=..\$(INPATH)\lib
+# bei lokalen osl rtl oder vos das SOLARLIBDIR bitte patchen !
+LIB1FILES+= $(SOLARLIBDIR)\xosl.lib \
+ $(SOLARLIBDIR)\xrtl.lib
+
+SHL1STDLIBS+= $(WSOCK32LIB)
+.ENDIF
+.ENDIF # "$(BIG_TOOLS)"!=""
+
+# --- TOOLS.DLL ---
+
+SHL1TARGET= tl$(DLLPOSTFIX)
+SHL1LIBS= $(LIB1TARGET)
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB= itools
+SHL1USE_EXPORTS=name
+SHL1STDLIBS+= $(SALLIB) $(BASEGFXLIB) $(I18NISOLANGLIB) $(COMPHELPERLIB)
+
+.IF "$(GUI)"=="WNT"
+SHL1STDLIBS+= $(SHELL32LIB) \
+ $(MPRLIB) \
+ $(OLE32LIB) \
+ $(UUIDLIB) \
+ $(ADVAPI32LIB)
+.ENDIF
+
+DEF1NAME =$(SHL1TARGET)
+DEF1DEPN = \
+ $(MISC)$/$(SHL1TARGET).flt \
+ $(HXX1FILES) \
+ $(HXX2FILES) \
+ $(HXX3FILES) \
+ $(HXX4FILES) \
+ $(HXX5FILES) \
+ $(HXX6FILES) \
+ $(HXX7FILES) \
+ $(HXX8FILES) \
+ $(HXX9FILES) \
+ $(HXX10FILES) \
+ $(HXX11FILES) \
+ $(HXX12FILES) \
+ $(HXX13FILES) \
+ $(HXX14FILES) \
+ $(HXX15FILES) \
+ $(HXX16FILES) \
+ $(HXX17FILES) \
+ $(HXX18FILES) \
+ $(HXX19FILES) \
+ $(HXX20FILES) \
+ makefile.mk
+
+DEFLIB1NAME =tools
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# --- TOOLS.FLT ---
+$(MISC)$/$(SHL1TARGET).flt: makefile.mk
+ @echo ------------------------------
+ @echo Making: $@
+ @echo Imp>$@
+ @echo PointerList>>$@
+ @echo DbgCheck>>$@
+ @echo LabelList>>$@
+ @echo ActionList>>$@
+ @echo CBlock>>$@
+ @echo DirEntryStack>>$@
+ @echo readdir>>$@
+ @echo closedir>>$@
+ @echo opendir>>$@
+ @echo volumeid>>$@
+ @echo MsDos2Time>>$@
+ @echo MsDos2Date>>$@
+ @echo __new_alloc>>$@
+ @echo __CT>>$@
+ @echo unnamed>>$@
+.IF "$(COM)"=="BLC"
+ @echo WEP>>$@
+.ENDIF
diff --git a/tools/util/makefile.pmk b/tools/util/makefile.pmk
new file mode 100644
index 000000000000..9d8fc0d3ad24
--- /dev/null
+++ b/tools/util/makefile.pmk
@@ -0,0 +1,31 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+# define TOOLS_DLLIMPLEMENTATION (see @ toolsdllapi.h)
+CDEFS += -DTOOLS_DLLIMPLEMENTATION
+
+VISIBILITY_HIDDEN=TRUE
diff --git a/tools/util/tools.r b/tools/util/tools.r
new file mode 100644
index 000000000000..0d1e8739bd42
--- /dev/null
+++ b/tools/util/tools.r
@@ -0,0 +1,17 @@
+#include "CodeFragmentTypes.r"
+
+resource 'cfrg' (0) {
+ {
+ kPowerPC, /* instruction set architecture */
+ kFullLib, /* base-level library */
+ kNoVersionNum, /* no implementation version number */
+ kNoVersionNum, /* no definition version number */
+ kDefaultStackSize, /* use default stack size */
+ kNoAppSubFolder, /* no library directory */
+ kIsLib, /* fragment is an application */
+ kOnDiskFlat, /* fragment is on disk */
+ kZeroOffset, /* fragment starts at fork start */
+ kWholeFork, /* fragment occupies entire fork */
+ "Tools.pef" /* name of the application */
+ }
+};
diff --git a/tools/win/inc/dll.hxx b/tools/win/inc/dll.hxx
new file mode 100644
index 000000000000..a85cc0d2e357
--- /dev/null
+++ b/tools/win/inc/dll.hxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DLL_HXX
+#define _DLL_HXX
+
+#ifdef WIN
+
+#include <tools/svwin.h>
+
+// ----------------------
+// - Zugriffsfunktionen -
+// ----------------------
+
+struct SVDATA;
+
+extern "C"
+{
+// IN APPDATA.ASM
+SVDATA* FAR PASCAL GetSVData();
+}
+
+// IN TOOLSDLL.CXX
+void SetSVData( SVDATA* pSVData );
+
+#endif
+
+// -------------------------------
+// - Sonstige Funktionen fuer SV -
+// -------------------------------
+
+// Um Resourcen wieder freizugeben
+inline void ImpDeInitWinTools() {}
+
+#endif /* _DLL_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/win/inc/parser.hxx b/tools/win/inc/parser.hxx
new file mode 100644
index 000000000000..96333f169cfb
--- /dev/null
+++ b/tools/win/inc/parser.hxx
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _PARSER_HXX
+#define _PARSER_HXX
+
+#if defined WNT
+
+#include <tools/string.hxx>
+#include <winshell.hxx>
+
+void * NewBinaryFromString( const String & rBinStr );
+String CreateStringFromData( const void *pData, ULONG nBytes );
+
+String CreateStringFromItemIDList( const CItemIDList & rIDList );
+
+String GetURLFromHostNotation( const String & rPath );
+String GetHostNotationFromURL( const String & rURL );
+
+CItemIDList MakeIDToken( const String &rToken );
+CItemIDList ParseSpecialURL( const String & rURL );
+
+#endif
+
+#endif // _PARSER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/win/inc/shellex.h b/tools/win/inc/shellex.h
new file mode 100644
index 000000000000..d4f932063fad
--- /dev/null
+++ b/tools/win/inc/shellex.h
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _SHELLEX_H_
+#define _SHELLEX_H_
+
+#ifndef _SHLOBJ_H_
+#include <shlobj.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#define WINSHELLCALL inline
+#else
+#define WINSHELLCALL static
+#endif
+
+#define SHChangeNotifyRegister_PROC_STR MAKEINTRESOURCE(2)
+#define SHChangeNotifyDeregister_PROC_STR MAKEINTRESOURCE(4)
+
+#define SHCNF_ACCEPT_INTERRUPTS 0x0001
+#define SHCNF_ACCEPT_NON_INTERRUPTS 0x0002
+#define SHCNF_NO_PROXY 0x8000
+
+#define SHCNF_ACCEPT_ALL (SHCNF_ACCEPT_INTERRUPTS | SHCNF_ACCEPT_NON_INTERRUPTS)
+
+typedef struct tagNOTIFYREGISTER {
+ LPCITEMIDLIST pidlPath;
+ BOOL bWatchSubtree;
+} NOTIFYREGISTER;
+
+typedef NOTIFYREGISTER *LPNOTIFYREGISTER;
+typedef NOTIFYREGISTER const *LPCNOTIFYREGISTER;
+
+typedef HANDLE (WINAPI *SHChangeNotifyRegister_PROC)(
+ HWND hWnd,
+ DWORD dwFlags,
+ LONG wEventMask,
+ UINT uMsg,
+ ULONG cItems,
+ LPCNOTIFYREGISTER lpItems);
+
+
+WINSHELLCALL HANDLE WINAPI SHChangeNotifyRegister(
+ HWND hWnd,
+ DWORD dwFlags,
+ LONG wEventMask,
+ UINT uMsg,
+ ULONG cItems,
+ LPCNOTIFYREGISTER lpItems)
+
+{
+ HMODULE hModule = GetModuleHandle( "SHELL32" );
+ HANDLE hNotify = NULL;
+
+ if ( hModule )
+ {
+ SHChangeNotifyRegister_PROC lpfnSHChangeNotifyRegister = (SHChangeNotifyRegister_PROC)GetProcAddress( hModule, SHChangeNotifyRegister_PROC_STR );
+ if ( lpfnSHChangeNotifyRegister )
+ hNotify = lpfnSHChangeNotifyRegister( hWnd, dwFlags, wEventMask, uMsg, cItems, lpItems );
+ }
+
+ return hNotify;
+}
+
+
+
+typedef BOOL (WINAPI *SHChangeNotifyDeregister_PROC)(
+ HANDLE hNotify);
+
+WINSHELLCALL BOOL WINAPI SHChangeNotifyDeregister( HANDLE hNotify )
+{
+ HMODULE hModule = GetModuleHandle( "SHELL32" );
+ BOOL fSuccess = FALSE;
+
+ if ( hModule )
+ {
+ SHChangeNotifyDeregister_PROC lpfnSHChangeNotifyDeregister = (SHChangeNotifyDeregister_PROC)GetProcAddress( hModule, SHChangeNotifyDeregister_PROC_STR );
+ if ( lpfnSHChangeNotifyDeregister )
+ fSuccess = lpfnSHChangeNotifyDeregister( hNotify );
+ }
+
+ return fSuccess;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/win/inc/shutil.h b/tools/win/inc/shutil.h
new file mode 100644
index 000000000000..6264f83c8bd7
--- /dev/null
+++ b/tools/win/inc/shutil.h
@@ -0,0 +1,217 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SHUTIL_H_
+#define _SHUTIL_H_
+
+#if defined WNT
+
+#ifndef _SHOBJ_H
+#include <shlobj.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PROTOCOL_FILE "file:"
+#define MAX_URL (MAX_PATH + sizeof(PROTOCOL_FILE))
+
+#define SHUTIL_TO_DELIVER
+
+//--------------------------------------------------------------------------
+
+void * WINAPI WIN_SHAlloc( ULONG cb );
+void * WINAPI WIN_SHRealloc( void *pv, ULONG cb );
+void WINAPI WIN_SHFree( void *pv );
+
+//--------------------------------------------------------------------------
+
+ULONG WINAPI WIN_SHGetIDListSize( LPCITEMIDLIST pidl );
+BOOL WINAPI WIN_SHCloneIDList( LPCITEMIDLIST pidl, LPITEMIDLIST *ppidl );
+BOOL WINAPI WIN_SHAppendIDList( LPCITEMIDLIST pidl, LPITEMIDLIST *ppidl );
+LONG WINAPI WIN_SHCompareIDList( LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2 );
+
+LONG WINAPI WIN_SHGetIDListTokenCount( LPCITEMIDLIST pidl );
+BOOL WINAPI WIN_SHGetIDListToken( LPCITEMIDLIST pidl, ULONG nToken, LPITEMIDLIST *ppidl );
+
+BOOL WINAPI WIN_SHSplitIDList(
+ LPCITEMIDLIST pidl,
+ LPITEMIDLIST * pidlFolder,
+ LPITEMIDLIST * pidlItem
+ );
+
+BOOL WINAPI WIN_SHSplitIDListEx(
+ LPCITEMIDLIST pidl,
+ LPITEMIDLIST * pidlParent,
+ LPITEMIDLIST * pidlChild,
+ ULONG nLevel
+ );
+
+//--------------------------------------------------------------------------
+
+#define WIN_SHGetSpecialFolderLocation( nFolder, ppidl ) \
+ ((BOOL)(NOERROR == SHGetSpecialFolderLocation( GetFocus(), nFolder, ppidl )))
+
+#define WIN_SHGetPathFromIDList( pidl, pszPath ) \
+ SHGetPathFromIDList( pidl, pszPath )
+
+// #define SHGP_CLSID 0x00000001
+
+// BOOL WINAPI WIN_SHGetPathFromIDListEx( LPCITEMIDLIST pidl, LPSTR pszBuffer, UINT uFlags );
+
+BOOL WINAPI WIN_SHGetIDListFromPath( LPCSTR pszPath, LPITEMIDLIST *ppidl );
+
+BOOL WINAPI WIN_SHGetPathFromURL( LPCSTR pszURL, LPSTR pszPath );
+BOOL WINAPI WIN_SHGetURLFromPath( LPCSTR pszPath, LPSTR pszURL );
+
+BOOL WINAPI WIN_SHGetFolderFromIDList( LPCITEMIDLIST pidl, LPSHELLFOLDER *ppshf );
+BOOL WINAPI WIN_SHGetSpecialFolder( int nFolder, LPSHELLFOLDER *ppshf );
+BOOL WINAPI WIN_SHGetFolderFromPath( LPCSTR pszPath, LPSHELLFOLDER *ppshf );
+
+BOOL WINAPI WIN_SHGetSpecialFolderPath( int nFolder, LPSTR pszPath );
+
+HRESULT WINAPI WIN_SHGetDataFromIDList(
+ LPSHELLFOLDER psf,
+ LPCITEMIDLIST pidl,
+ int nFormat,
+ PVOID pv,
+ int cb
+ );
+
+
+//--------------------------------------------------------------------------
+
+#define SHIC_PIDL 0x00000001
+#define SHIC_NO_UI 0x00000002
+
+#define CMDSTR_OPENA "open"
+#define CMDSTR_EXPLOREA "explore"
+#define CMDSTR_FINDA "find"
+
+#define CMDSTR_OPENW L"open"
+#define CMDSTR_EXPLOREW L"explore"
+#define CMDSTR_FINDW L"find"
+
+#ifdef UNICODE
+#define CMDSTR_OPEN CMDSTR_OPENW
+#define CMDSTR_EXPLORE CMDSTR_EXPLOREW
+#define CMDSTR_FIND CMDSTR_FINDW
+#else
+#define CMDSTR_OPEN CMDSTR_OPENA
+#define CMDSTR_EXPLORE CMDSTR_EXPLOREA
+#define CMDSTR_FIND CMDSTR_FINDA
+#endif
+
+#define CMDSTR_DEFAULT MAKEINTRESOURCE(0x00)
+
+#define CMDSTR_LINK MAKEINTRESOURCE(0x10)
+#define CMDSTR_DELETE MAKEINTRESOURCE(0x11)
+#define CMDSTR_RENAME MAKEINTRESOURCE(0x12)
+#define CMDSTR_PROPERTIES MAKEINTRESOURCE(0x13)
+#define CMDSTR_CUT MAKEINTRESOURCE(0x18)
+#define CMDSTR_COPY MAKEINTRESOURCE(0x19)
+
+BOOL WINAPI WIN_SHInvokeCommand(
+ HWND hwndOwner,
+ DWORD dwFlags,
+ LPCTSTR lpPath,
+ LPCSTR lpVerb,
+ LPCSTR lpParameters,
+ LPCSTR lpDirectory,
+ int nShow
+ );
+
+//--------------------------------------------------------------------------
+
+BOOL WINAPI WIN_SHStrRetToMultiByte(
+ LPCITEMIDLIST pidl,
+ const STRRET * pStr,
+ LPSTR lpMultiByte,
+ int cchMultiByte
+ );
+
+DWORD WIN_SHBuildCRC( LPVOID pBytes, ULONG nBytes );
+
+DWORD WINAPI WIN_GetShellVersion(VOID);
+
+HIMAGELIST WINAPI WIN_SHGetSystemImageList( UINT uFlags );
+
+//--------------------------------------------------------------------------
+
+/*
+
+ULONG WINAPI WIN_CreateStringFromBinary (
+ LPCVOID pv,
+ ULONG cbSize,
+ LPSTR pszString,
+ ULONG cbStringSize
+ );
+
+ULONG WINAPI WIN_CreateBinaryFromString(
+ LPCSTR pszStr,
+ LPVOID pBuffer,
+ ULONG cbSize
+ );
+*/
+
+//--------------------------------------------------------------------------
+
+DWORD WINAPI WIN_SHSetValue(
+ HKEY hKey,
+ LPCTSTR pszSubKey,
+ LPCTSTR pszValue,
+ DWORD dwType,
+ LPCVOID pvData,
+ DWORD cbData
+ );
+
+DWORD WINAPI WIN_SHGetValue(
+ HKEY hKey,
+ LPCTSTR pszSubKey,
+ LPCTSTR pszValue,
+ LPDWORD pdwType,
+ LPVOID pvData,
+ LPDWORD pcbData
+ );
+
+DWORD WINAPI WIN_SHDeleteValue(
+ HKEY hKey,
+ LPCTSTR pszSubKey,
+ LPCTSTR pszValue
+ );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif // _SHUTIL_H_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/win/inc/toolsdll.hxx b/tools/win/inc/toolsdll.hxx
new file mode 100644
index 000000000000..0fef2770a8c1
--- /dev/null
+++ b/tools/win/inc/toolsdll.hxx
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _TOOLSDLL_HXX
+#define _TOOLSDLL_HXX
+
+#ifdef WIN
+
+#include <string.h>
+#include <tools/svwin.h>
+#include <tools/solar.h>
+#include <tools/shl.hxx>
+
+// ----------------
+// - MemMgr-Daten -
+// ----------------
+
+// Anzahl Freispeicherlisten
+#define MEM_FREELIST_COUNT 15
+
+
+// --------------
+// - Tools-Data -
+// --------------
+
+struct SVDATA;
+struct FreeBlock;
+
+struct MemData
+{
+ FreeBlock* pFirstBlocks[MEM_FREELIST_COUNT]; // Erste Bloecke in Freispeicherlisten
+ void* pNewHandler; // New-Handler
+ int nMultiThread; // MultiThread an/aus
+};
+
+struct ToolsData
+{
+ // !!! SVDATA muss in jedem Fall ganz vorne in der Struktur stehen !!!
+ SVDATA* pSVData; // Pointer auf StarView-Daten
+ HANDLE hMem; // Handler der Tools-Daten
+ MemData aMemD; // Daten der Speicherverwaltung
+ void* aAppData[SHL_COUNT]; // Daten fuer andere Shared Libs
+};
+
+
+// ----------------------
+// - Zugriffsfunktionen -
+// ----------------------
+
+// IN APPDATA.ASM
+extern "C"
+{
+ToolsData* FAR PASCAL ImpGetAppData();
+void FAR PASCAL ImpSetAppData( ToolsData* pData );
+}
+
+// IN TOOLSDLL.CXX
+ToolsData* ImpGetToolsData();
+
+#endif
+
+#endif // _DLL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/win/inc/winshell.hxx b/tools/win/inc/winshell.hxx
new file mode 100644
index 000000000000..66c5aeffe7b3
--- /dev/null
+++ b/tools/win/inc/winshell.hxx
@@ -0,0 +1,389 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _WINSHELL_HXX
+#define _WINSHELL_HXX
+
+#if defined WNT
+
+#include <tools/prewin.h>
+#include "shutil.h"
+#include <tools/postwin.h>
+
+#include <tools/string.hxx>
+
+//----------------------------------------------------------------------------
+// CItemIDList
+//----------------------------------------------------------------------------
+
+class CItemIDList
+{
+public:
+ CItemIDList();
+ CItemIDList( const CItemIDList & );
+ CItemIDList( LPCITEMIDLIST );
+ CItemIDList( const String & );
+ CItemIDList( int nFolder );
+ ~CItemIDList();
+
+ CItemIDList & operator = ( const CItemIDList & );
+ CItemIDList & operator += ( const CItemIDList & );
+ CItemIDList operator + ( const CItemIDList & ) const;
+
+ int operator == ( const CItemIDList & ) const;
+ int operator != ( const CItemIDList & rIDList ) const
+ { return ! operator == ( rIDList ); };
+
+ operator LPCITEMIDLIST() const
+ { return m_pidl; };
+
+ int GetTokenCount() const;
+ CItemIDList GetToken( int nIndex ) const;
+ CItemIDList GetParent( int nLevelFromBottom = 1) const;
+ CItemIDList GetChild( int nLevelFromBottom = 1 ) const;
+ void Split( CItemIDList & rParent, CItemIDList & rChild, int nLevelFromBottom = 1 ) const;
+
+ CItemIDList operator []( int nIndex ) const
+ { return GetToken( nIndex ); };
+
+ String GetFilePath() const;
+
+ BOOL IsValid() const
+ { return m_pidl != NULL && m_pidl->mkid.cb != sizeof(USHORT); }
+
+ int GetRootID() const
+ { return m_nFolder; }
+
+protected:
+ ITEMIDLIST *m_pidl;
+ int m_nFolder;
+};
+
+
+inline CItemIDList CItemIDList::operator + ( const CItemIDList & rIDList ) const
+{
+ CItemIDList aCopy( *this );
+ aCopy += rIDList;
+ return aCopy;
+}
+
+//----------------------------------------------------------------------------
+// Types for CShellFolder
+//----------------------------------------------------------------------------
+
+// Notification Events fuer CShellFolder
+
+enum NotificationEvent
+{
+ NotificationEvent_Error,
+ NotificationEvent_Signaled,
+ NotificationEvent_Canceled
+};
+
+// Volume information
+
+typedef struct _WIN32_VOLUME_DATA
+{
+ TCHAR cDeviceName[MAX_PATH];
+ TCHAR cVolumeName[MAX_PATH];
+ TCHAR cFileSystemName[MAX_PATH];
+ DWORD dwSerialNumber;
+ DWORD dwFileSystemFlags;
+ DWORD nMaxComponentLength;
+} WIN32_VOLUME_DATA;
+
+// Bekannte Class-IDs fuer wichtige Ordner
+
+// {871C5380-42A0-1069-A2EA-08002B30309D} Internet Explorer 4.0
+static const GUID CLSID_IE4 =
+{ 0x871C5380, 0x42A0, 0x1069, { 0xA2, 0xEA, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D } };
+
+// {208D2C60-3AEA-1069-A2D7-08002B30309D} Netzwerkumgebung
+static const GUID CLSID_Network =
+{ 0x208D2C60, 0x3AEA, 0x1069, { 0xA2, 0xD7, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D } };
+
+// {645FF040-5081-101B-9F08-00AA002F954E} Papierkorb
+static const GUID CLSID_RecycleBin =
+{ 0x645FF040, 0x5081, 0x101B, { 0x9F, 0x08, 0x00, 0xAA, 0x00, 0x2F, 0x95, 0x4E } };
+
+// {20D04FE0-3AEA-1069-A2D8-08002B30309D} Arbeitsplatz
+static const GUID CLSID_MyComputer =
+{ 0x20D04FE0, 0x3AEA, 0x1069, { 0xA2, 0xD8, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D } };
+
+// {D6277990-4C6A-11CF-8D87-00AA0060F5BF} Geplante Vorgänge
+static const GUID CLSID_Tasks =
+{ 0xD6277990, 0x4C6A, 0x11CF, { 0x8D, 0x87, 0x00, 0xAA, 0x00, 0x60, 0xF5, 0xBF } };
+
+// Fehlt im Header
+
+#define SHGDN_INCLUDE_NONFILESYS 0x2000
+
+#define CSIDL_UNKNOWN -1
+#define CSIDL_ROOT -2
+#define CSIDL_SYSTEM -3
+
+// Suchmaske fuer IEnumIDList
+
+#define SHCONTF_ALL (SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN)
+
+// SHITEM Prefix Kinds
+
+#define SHGII_CONTAINER_MASK 0x70
+
+#define SHGII_COMPUTER 0x20
+
+#define SHGII_COMPUTER_REMOVABLE 0x22
+#define SHGII_COMPUTER_FIXED 0x23
+#define SHGII_COMPUTER_REMOTE 0x24
+#define SHGII_COMPUTER_CDROM 0x25
+#define SHGII_COMPUTER_RAMDISK 0x26
+#define SHGII_COMPUTER_FLOPPY525 0x28
+#define SHGII_COMPUTER_FLOPPY35 0x29
+#define SHGII_COMPUTER_NETWORK 0x2A
+#define SHGII_COMPUTER_REGITEM 0x2E
+
+#define SHGII_ROOT 0x10
+#define SHGII_ROOT_REGITEM 0x1F
+
+#define SHGII_NETWORK 0x40
+#define SHGII_NETWORK_TREE 0x47
+#define SHGII_NETWORK_SERVER 0x42
+#define SHGII_NETWORK_DIRECTORY 0x43
+#define SHGII_NETWORK_PRINTER 0x41
+
+#define SHGII_FILESYSTEM 0x30
+#define SHGII_FILESYSTEM_FILE 0x31
+#define SHGII_FILESYSTEM_DIRECTORY 0x32
+
+#define SHGII_ANCESTOR 0x80
+
+#define SHITEMCONTAINER( pidl ) ((pidl)->mkid.abID[0] & SHGII_CONTAINER_MASK)
+#define SHITEMKIND( pidl ) ((pidl)->mkid.abID[0] & 0x7F)
+
+//----------------------------------------------------------------------------
+// CShellFolderData
+//----------------------------------------------------------------------------
+
+class CShellFolderData
+{
+protected:
+ CShellFolderData();
+ virtual ~CShellFolderData();
+
+ IShellFolder *m_pShellFolder;
+ IEnumIDList *m_pEnumIDList;
+ IShellIcon *m_pShellIcon;
+ BOOL m_bIsOpen;
+ HANDLE m_hCancelEvent;
+ DWORD m_dwContentFlags;
+};
+
+//----------------------------------------------------------------------------
+// CShellFolder
+//----------------------------------------------------------------------------
+
+// Ganz "normaler" Ordner basierend auf dem IShellFolder Interface
+
+class CShellFolder : public CShellFolderData
+{
+public:
+ CShellFolder( const CItemIDList & );
+ CShellFolder( const CShellFolder & );
+ CShellFolder( IShellFolder * );
+
+ // Retrieval of Item IDs
+
+ virtual BOOL Reset();
+
+ BOOL GetNextValidID( CItemIDList & );
+
+ virtual BOOL GetNextID( CItemIDList & );
+ virtual BOOL ValidateID( const CItemIDList & );
+
+ // Getting information about Items
+
+ virtual BOOL GetAttributesOf( const CItemIDList &, LPDWORD pdwInOut );
+ virtual BOOL GetNameOf( const CItemIDList &, String & );
+
+ virtual BOOL GetFileInfo( const CItemIDList &, WIN32_FIND_DATA * );
+ virtual BOOL GetVolumeInfo( const CItemIDList & rIDList, WIN32_VOLUME_DATA * );
+
+ // Modifying the folder contents
+
+ virtual BOOL SetNameOf( const CItemIDList &, const String &, CItemIDList & );
+ virtual BOOL DeleteItem( const CItemIDList & );
+
+ // Comparison of IDs
+
+ virtual int CompareIDs( const CItemIDList &, const CItemIDList & );
+
+ // UI Components
+
+ virtual IContextMenu *GetContextMenu( int nItems, const CItemIDList * );
+ virtual String GetIconLocation( const CItemIDList & );
+
+ // Notifications
+
+ virtual NotificationEvent WaitForChanges();
+ virtual void CancelWaitNotifications();
+
+protected:
+ CShellFolder() : CShellFolderData() {};
+
+ void Initialize( IShellFolder *pShellFolder );
+ void Initialize( LPCITEMIDLIST );
+};
+
+//----------------------------------------------------------------------------
+// CFileSystemFolder
+//----------------------------------------------------------------------------
+
+// Reiner !!! Filesystem-Ordner. Benutzt optimierten Notification Mechanismus
+
+class CFileSystemFolder : public CShellFolder
+{
+public:
+ CFileSystemFolder( LPCSTR pszPath );
+
+ virtual NotificationEvent WaitForChanges();
+
+protected:
+ CFileSystemFolder() : CShellFolder() {};
+
+ void Initialize( LPCTSTR pszPath );
+
+ TCHAR m_szPath[MAX_PATH];
+};
+
+//----------------------------------------------------------------------------
+// CSpecialFolder
+//----------------------------------------------------------------------------
+
+// Wie SHellFolder, aber andere Konstruktion ueber definierte Junktion-Points
+
+class CSpecialFolder : public CShellFolder
+{
+public:
+ CSpecialFolder( int nFolder );
+
+protected:
+ CSpecialFolder() : CShellFolder() {};
+
+ void Initialize( int nFolder );
+
+ int m_nFolder;
+};
+
+//----------------------------------------------------------------------------
+// CMyComputerFolder
+//----------------------------------------------------------------------------
+
+// Der MS-Windows "Arbeitsplatz"
+
+class CMyComputerFolder : public CSpecialFolder
+{
+public:
+ CMyComputerFolder() : CSpecialFolder( CSIDL_DRIVES ) {};
+};
+
+//----------------------------------------------------------------------------
+// CVolumesFolder
+//----------------------------------------------------------------------------
+
+// Wie CMyComputersFolder, enthält aber nur die Laufwerke
+
+class CVolumesFolder : public CMyComputerFolder
+{
+public:
+ CVolumesFolder() : CMyComputerFolder() {};
+
+ virtual BOOL ValidateID( const CItemIDList & );
+ virtual NotificationEvent WaitForChanges();
+};
+
+//----------------------------------------------------------------------------
+// CWorkplaceFolder
+//----------------------------------------------------------------------------
+
+// Wie CMyComputersFolder, enthält aber keine!!! Laufwerke
+
+class CWorkplaceFolder : public CMyComputerFolder
+{
+ CWorkplaceFolder() : CMyComputerFolder() {};
+
+ virtual BOOL ValidateID( const CItemIDList & );
+ virtual NotificationEvent WaitForChanges();
+};
+
+//----------------------------------------------------------------------------
+// CDesktopFolder
+//----------------------------------------------------------------------------
+
+// Der MS-Windows Desktop
+
+class CDesktopFolder : public CSpecialFolder
+{
+public:
+ CDesktopFolder() : CSpecialFolder( CSIDL_DESKTOP ) {};
+};
+
+//----------------------------------------------------------------------------
+// CDesktopAncestorsFolder
+//----------------------------------------------------------------------------
+
+// Wie CDesktopFolder, enthält aber nur Arbeitsplatz und Netzwerk
+
+class CDesktopAncestorsFolder : public CDesktopFolder
+{
+public:
+ CDesktopAncestorsFolder() : CDesktopFolder() {};
+
+ virtual BOOL ValidateID( const CItemIDList & );
+ virtual NotificationEvent WaitForChanges();
+};
+
+//----------------------------------------------------------------------------
+// CDesktopContentsFolder
+//----------------------------------------------------------------------------
+
+// Wie CDesktopFolder, aber ohne!!! Arbeitsplatz und Netzwerk
+
+class CDesktopContentsFolder : public CDesktopFolder
+{
+public:
+ CDesktopContentsFolder() : CDesktopFolder() {};
+
+ virtual BOOL ValidateID( const CItemIDList & );
+ virtual NotificationEvent WaitForChanges();
+};
+
+#endif
+
+#endif // _WINSHELL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/win/source/dll/makefile.mk b/tools/win/source/dll/makefile.mk
new file mode 100644
index 000000000000..403da065d653
--- /dev/null
+++ b/tools/win/source/dll/makefile.mk
@@ -0,0 +1,56 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=TOOLS
+TARGET=dll
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- WNT ----------------------------------------------------------
+
+.IF "$(GUI)" == "WNT"
+
+# --- Files --------------------------------------------------------
+
+CXXFILES= toolsdll.cxx
+
+SLOFILES= $(SLO)$/toolsdll.obj
+
+OBJFILES= $(OBJ)$/toolsdll.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.ENDIF
+
diff --git a/tools/win/source/dll/toolsdll.cxx b/tools/win/source/dll/toolsdll.cxx
new file mode 100644
index 000000000000..1e170bd94eb4
--- /dev/null
+++ b/tools/win/source/dll/toolsdll.cxx
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <tools/svwin.h>
+#include <dll.hxx>
+#include <toolsdll.hxx>
+#include <tools/shl.hxx>
+
+// =======================================================================
+
+#ifdef WNT
+
+static void* aAppData[SHL_COUNT];
+
+// -----------------------------------------------------------------------
+
+void** GetAppData( USHORT nSharedLib )
+{
+ return &(aAppData[nSharedLib]);
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/win/source/fastfsys/makefile.mk b/tools/win/source/fastfsys/makefile.mk
new file mode 100644
index 000000000000..12df85d6a2f3
--- /dev/null
+++ b/tools/win/source/fastfsys/makefile.mk
@@ -0,0 +1,71 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..\..\..
+
+PRJNAME=TOOLS
+TARGET=fastfsys
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- WNT ----------------------------------------------------------
+
+.IF "$(GUI)" == "WNT"
+
+# --- Files --------------------------------------------------------
+
+
+OBJFILES= $(OBJ)$/shutil.obj \
+ $(OBJ)$/shidl.obj \
+ $(OBJ)$/shmalloc.obj \
+ $(OBJ)$/fffolder.obj \
+ $(OBJ)$/ffmenu.obj \
+ $(OBJ)$/ffitem.obj \
+ $(OBJ)$/fflink.obj \
+ $(OBJ)$/ffparser.obj \
+ $(OBJ)$/wincidl.obj \
+ $(OBJ)$/wincshf.obj
+
+
+SLOFILES= $(SLO)$/shutil.obj \
+ $(SLO)$/shidl.obj \
+ $(SLO)$/shmalloc.obj \
+ $(SLO)$/fffolder.obj \
+ $(SLO)$/ffmenu.obj \
+ $(SLO)$/ffitem.obj \
+ $(SLO)$/fflink.obj \
+ $(SLO)$/ffparser.obj \
+ $(SLO)$/wincidl.obj \
+ $(SLO)$/wincshf.obj
+
+# --- Targets ------------------------------------------------------
+
+.ENDIF
+
+.INCLUDE : target.mk
diff --git a/tools/workben/fstest.cxx b/tools/workben/fstest.cxx
new file mode 100644
index 000000000000..0c9fa2879bc7
--- /dev/null
+++ b/tools/workben/fstest.cxx
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#define _FSTEST_CXX "$Revision: 1.5 $"
+#include <tools/solar.h>
+
+#include <stdio.h>
+#include <tools/stream.hxx>
+#include <tools/fsys.hxx>
+#include <tools/date.hxx>
+#include <tools/time.hxx>
+
+void CheckTimes(DirEntry aDE);
+
+/*
+ * main.
+ */
+int main (int argc, char **argv)
+{
+ DirEntry aDir;
+ if (aDir.Exists())
+ {
+ aDir.ToAbs();
+ String sTmp(aDir.GetFull(FSYS_STYLE_HOST));
+ printf("Directory = %s\n", sTmp.GetStr());
+ CheckTimes(aDir);
+ DirEntry aFile =
+ aDir + DirEntry("testfile.txt", FSYS_STYLE_HOST);
+ SvFileStream aStream;
+ aStream.Open(aFile.GetFull(FSYS_STYLE_HOST), STREAM_WRITE);
+ aStream << "Test";
+ aStream.Close();
+ ULONG i, nWaitFor = 2000 + Time::GetSystemTicks();
+ for (i=Time::GetSystemTicks();
+ i < nWaitFor;
+ i = Time::GetSystemTicks())
+ ;
+ CheckTimes(aDir);
+ nWaitFor = 2000 + Time::GetSystemTicks();
+ for (i=Time::GetSystemTicks();
+ i < nWaitFor;
+ i = Time::GetSystemTicks())
+ ;
+ aFile.Kill();
+ }
+ else
+ puts("MakeDir failed!");
+ return 0;
+}
+
+void CheckTimes(DirEntry aDE)
+{
+ FileStat aDirStat(aDE);
+ aDirStat.Update(aDE);
+ Date aDateCreated(aDirStat.DateCreated());
+ Date aDateModified(aDirStat.DateModified());
+ Time aTimeCreated(aDirStat.TimeCreated());
+ Time aTimeModified(aDirStat.TimeModified());
+ printf(
+ "DirDateCreated = %i, DirTimeCreated = %i\n",
+ aDateCreated.GetDate(), aTimeCreated.GetTime());
+ printf(
+ "DirDateModified = %i, DirTimeModified = %i\n",
+ aDateModified.GetDate(), aTimeModified.GetTime());
+ return;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/workben/hashtbl.cxx b/tools/workben/hashtbl.cxx
new file mode 100644
index 000000000000..a4c13162c261
--- /dev/null
+++ b/tools/workben/hashtbl.cxx
@@ -0,0 +1,518 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <tlgen.hxx>
+#include "hashtbl.hxx"
+
+#include <algorithm>
+
+// -------------------------------------------------------------
+// class HashItem
+//
+class HashItem
+{
+ enum ETag { TAG_EMPTY, TAG_USED, TAG_DELETED };
+
+ void* m_pObject;
+ ETag m_Tag;
+ String m_Key;
+
+public:
+ HashItem() { m_Tag = TAG_EMPTY; m_pObject = NULL; }
+
+ BOOL IsDeleted() const
+ { return m_Tag == TAG_DELETED; }
+
+ BOOL IsEmpty() const
+ { return m_Tag == TAG_DELETED || m_Tag == TAG_EMPTY; }
+
+ BOOL IsFree() const
+ { return m_Tag == TAG_EMPTY; }
+
+ BOOL IsUsed() const
+ { return m_Tag == TAG_USED; }
+
+ void Delete()
+ { m_Tag = TAG_DELETED; m_Key = ""; m_pObject = NULL; }
+
+ String const& GetKey() const
+ { return m_Key; }
+
+ void* GetObject() const
+ { return m_pObject; }
+
+ void SetObject(String const Key, void *pObject)
+ { m_Tag = TAG_USED; m_Key = Key; m_pObject = pObject; }
+};
+
+// #define MIN(a,b) (a)<(b)?(a):(b)
+// #define MAX(a,b) (a)>(b)?(a):(b)
+
+// -------------------------------------------------------------
+// class HashTable
+//
+
+/*static*/ double HashTable::m_defMaxLoadFactor = 0.8;
+/*static*/ double HashTable::m_defDefGrowFactor = 2.0;
+
+HashTable::HashTable(ULONG lSize, BOOL bOwner, double dMaxLoadFactor, double dGrowFactor)
+{
+ m_lSize = lSize;
+ m_bOwner = bOwner;
+ m_lElem = 0;
+ m_dMaxLoadFactor = std::max(0.5,std::min(1.0,dMaxLoadFactor)); // 0.5 ... 1.0
+ m_dGrowFactor = std::max(1.3,(5.0,dGrowFactor)); // 1.3 ... 5.0
+ m_pData = new HashItem [lSize];
+
+// Statistik
+#ifdef DBG_UTIL
+ m_aStatistic.m_lSingleHash = 0;
+ m_aStatistic.m_lDoubleHash = 0;
+ m_aStatistic.m_lProbe = 0;
+#endif
+}
+
+HashTable::~HashTable()
+{
+ // Wenn die HashTable der Owner der Objecte ist,
+ // müssen die Destruktoren separat gerufen werden.
+ // Dies geschieht über die virtuelle Methode OnDeleteObject()
+ //
+ // Problem: Virtuelle Funktionen sind im Destructor nicht virtuell!!
+ // Der Code muß deshalb ins Macro
+
+ /*
+ if (m_bOwner)
+ {
+ for (ULONG i=0; i<GetSize(); i++)
+ {
+ void *pObject = GetObjectAt(i);
+
+ if (pObject != NULL)
+ OnDeleteObject(pObject());
+ }
+ }
+ */
+
+ // Speicher für HashItems freigeben
+ delete [] m_pData;
+}
+
+void* HashTable::GetObjectAt(ULONG lPos) const
+// Gibt Objekt zurück, wenn es eines gibt, sonst NULL;
+{
+ DBG_ASSERT(lPos<m_lSize, "HashTable::GetObjectAt()");
+
+ HashItem *pItem = &m_pData[lPos];
+
+ return pItem->IsUsed() ? pItem->GetObject() : NULL;
+}
+
+void HashTable::OnDeleteObject(void*)
+{
+ DBG_ERROR("HashTable::OnDeleteObject(void*) nicht überladen");
+}
+
+ULONG HashTable::Hash(String const& Key) const
+{
+ /*
+ ULONG lHash = 0;
+ ULONG i,n;
+
+ for (i=0,n=Key.Len(); i<n; i++)
+ {
+ lHash *= 256L;
+ lHash += (ULONG)(USHORT)Key.GetStr()[i];
+ lHash %= m_lSize;
+ }
+ return lHash;
+ */
+
+ // Hashfunktion von P.J. Weinberger
+ // aus dem "Drachenbuch" von Aho/Sethi/Ullman
+ ULONG i,n;
+ ULONG h = 0;
+ ULONG g = 0;
+
+ for (i=0,n=Key.Len(); i<n; i++)
+ {
+ h = (h<<4) + (ULONG)(USHORT)Key.GetStr()[i];
+ g = h & 0xf0000000;
+
+ if (g != 0)
+ {
+ h = h ^ (g >> 24);
+ h = h ^ g;
+ }
+ }
+
+ return h % m_lSize;
+}
+
+ULONG HashTable::DHash(String const& Key, ULONG lOldHash) const
+{
+ ULONG lHash = lOldHash;
+ ULONG i,n;
+
+ for (i=0,n=Key.Len(); i<n; i++)
+ {
+ lHash *= 256L;
+ lHash += (ULONG)(USHORT)Key.GetStr()[i];
+ lHash %= m_lSize;
+ }
+ return lHash;
+
+/* return
+ (
+ lHash
+ + (char)Key.GetStr()[0] * 256
+ + (char)Key.GetStr()[Key.Len()-1]
+ + 1
+ )
+ % m_lSize;
+*/
+}
+
+ULONG HashTable::Probe(ULONG lPos) const
+// gibt den Folgewert von lPos zurück
+{
+ lPos++; if (lPos==m_lSize) lPos=0;
+ return lPos;
+}
+
+BOOL HashTable::IsFull() const
+{
+ return m_lElem>=m_lSize;
+}
+
+BOOL HashTable::Insert(String const& Key, void* pObject)
+// pre: Key ist nicht im Dictionary enthalten, sonst return FALSE
+// Dictionary ist nicht voll, sonst return FALSE
+// post: pObject ist unter Key im Dictionary; m_nElem wurde erhöht
+{
+ SmartGrow();
+
+ if (IsFull())
+ {
+ DBG_ERROR("HashTable::Insert() is full");
+ return FALSE;
+ }
+
+ if (FindPos(Key) != NULL )
+ return FALSE;
+
+ ULONG lPos = Hash(Key);
+ HashItem *pItem = &m_pData[lPos];
+
+ // first hashing
+ //
+ if (pItem->IsEmpty())
+ {
+ pItem->SetObject(Key, pObject);
+ m_lElem++;
+
+ #ifdef DBG_UTIL
+ m_aStatistic.m_lSingleHash++;
+ #endif
+
+ return TRUE;
+ }
+
+ // double hashing
+ //
+ lPos = DHash(Key,lPos);
+ pItem = &m_pData[lPos];
+
+ if (pItem->IsEmpty())
+ {
+ pItem->SetObject(Key, pObject);
+ m_lElem++;
+
+ #ifdef DBG_UTIL
+ m_aStatistic.m_lDoubleHash++;
+ #endif
+
+ return TRUE;
+ }
+
+ // linear probing
+ //
+ do
+ {
+ #ifdef DBG_UTIL
+ m_aStatistic.m_lProbe++;
+ #endif
+
+ lPos = Probe(lPos);
+ pItem = &m_pData[lPos];
+ }
+ while(!pItem->IsEmpty());
+
+ pItem->SetObject(Key, pObject);
+ m_lElem++;
+ return TRUE;
+}
+
+HashItem* HashTable::FindPos(String const& Key) const
+// sucht den Key; gibt Refrenz auf den Eintrag (gefunden)
+// oder NULL (nicht gefunden) zurück
+//
+// pre: -
+// post: -
+{
+ // first hashing
+ //
+ ULONG lPos = Hash(Key);
+ HashItem *pItem = &m_pData[lPos];
+
+ if (pItem->IsUsed()
+ && pItem->GetKey() == Key)
+ {
+ return pItem;
+ }
+
+ // double hashing
+ //
+ if (pItem->IsDeleted() || pItem->IsUsed())
+ {
+ lPos = DHash(Key,lPos);
+ pItem = &m_pData[lPos];
+
+ if (pItem->IsUsed()
+ && pItem->GetKey() == Key)
+ {
+ return pItem;
+ }
+
+ // linear probing
+ //
+ if (pItem->IsDeleted() || pItem->IsUsed())
+ {
+ ULONG n = 0;
+ BOOL bFound = FALSE;
+ BOOL bEnd = FALSE;
+
+ do
+ {
+ n++;
+ lPos = Probe(lPos);
+ pItem = &m_pData[lPos];
+
+ bFound = pItem->IsUsed()
+ && pItem->GetKey() == Key;
+
+ bEnd = !(n<m_lSize || pItem->IsFree());
+ }
+ while(!bFound && !bEnd);
+
+ return bFound ? pItem : NULL;
+ }
+ }
+
+ // nicht gefunden
+ //
+ return NULL;
+}
+
+void* HashTable::Find(String const& Key) const
+// Gibt Verweis des Objektes zurück, das unter Key abgespeichert ist,
+// oder NULL wenn nicht vorhanden.
+//
+// pre: -
+// post: -
+{
+ HashItem *pItem = FindPos(Key);
+
+ if (pItem != NULL
+ && pItem->GetKey() == Key)
+ return pItem->GetObject();
+ else
+ return NULL;
+}
+
+void* HashTable::Delete(String const& Key)
+// Löscht Objekt, das unter Key abgespeichert ist und gibt Verweis
+// darauf zurück.
+// Gibt NULL zurück, wenn Key nicht vorhanden ist.
+//
+// pre: -
+// post: Objekt ist nicht mehr enthalten; m_lElem dekrementiert
+// Wenn die HashTable der Owner ist, wurde das Object gelöscht
+{
+ HashItem *pItem = FindPos(Key);
+
+ if (pItem != NULL
+ && pItem->GetKey() == Key)
+ {
+ void* pObject = pItem->GetObject();
+
+ if (m_bOwner)
+ OnDeleteObject(pObject);
+
+ pItem->Delete();
+ m_lElem--;
+ return pObject;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+double HashTable::CalcLoadFactor() const
+// prozentuale Belegung der Hashtabelle berechnen
+{
+ return double(m_lElem) / double(m_lSize);
+}
+
+void HashTable::SmartGrow()
+// Achtung: da die Objekte umkopiert werden, darf die OnDeleteObject-Methode
+// nicht gerufen werden
+{
+ double dLoadFactor = CalcLoadFactor();
+
+ if (dLoadFactor <= m_dMaxLoadFactor)
+ return; // nothing to grow
+
+ ULONG lOldSize = m_lSize; // alte Daten sichern
+ HashItem* pOldData = m_pData;
+
+ m_lSize = ULONG (m_dGrowFactor * m_lSize); // neue Größe
+ m_pData = new HashItem[m_lSize]; // neue Daten holen
+
+ // kein Speicher:
+ // Zustand "Tabelle voll" wird in Insert abgefangen
+ //
+ if (m_pData == NULL)
+ {
+ m_lSize = lOldSize;
+ m_pData = pOldData;
+ return;
+ }
+
+ m_lElem = 0; // noch keine neuen Daten
+
+ // Umkopieren der Daten
+ //
+ for (ULONG i=0; i<lOldSize; i++)
+ {
+ HashItem *pItem = &pOldData[i];
+
+ if (pItem->IsUsed())
+ Insert(pItem->GetKey(),pItem->GetObject());
+ }
+
+ delete [] pOldData;
+}
+
+// Iterator ---------------------------------------------------------
+//
+
+HashTableIterator::HashTableIterator(HashTable const& aTable)
+: m_aTable(aTable)
+{
+ m_lAt = 0;
+}
+
+void* HashTableIterator::GetFirst()
+{
+ m_lAt = 0;
+ return FindValidObject(TRUE /* forward */);
+}
+
+void* HashTableIterator::GetLast()
+{
+ m_lAt = m_aTable.GetSize() -1;
+ return FindValidObject(FALSE /* backward */);
+}
+
+void* HashTableIterator::GetNext()
+{
+ if (m_lAt+1 >= m_aTable.GetSize())
+ return NULL;
+
+ m_lAt++;
+ return FindValidObject(TRUE /* forward */);
+}
+
+void* HashTableIterator::GetPrev()
+{
+ if (m_lAt <= 0)
+ return NULL;
+
+ m_lAt--;
+ return FindValidObject(FALSE /* backward */);
+}
+
+void* HashTableIterator::FindValidObject(BOOL bForward)
+// Sucht nach einem vorhandenen Objekt ab der aktuellen
+// Position.
+//
+// pre: ab inkl. m_lAt soll die Suche beginnen
+// post: if not found then
+// if bForward == TRUE then
+// m_lAt == m_aTable.GetSize() -1
+// else
+// m_lAt == 0
+// else
+// m_lAt ist die gefundene Position
+{
+ void *pObject = m_aTable.GetObjectAt(m_lAt);
+
+ if (pObject != NULL)
+ return pObject;
+
+ while (pObject == NULL
+ && (bForward ? ((m_lAt+1) < m_aTable.GetSize())
+ : m_lAt > 0))
+ {
+ if (bForward)
+ m_lAt++;
+ else
+ m_lAt--;
+
+ pObject = m_aTable.GetObjectAt(m_lAt);
+ }
+
+#ifdef DBG_UTIL
+
+ if (pObject == NULL)
+ {
+ DBG_ASSERT(bForward ? m_lAt == m_aTable.GetSize() -1 : m_lAt == 0,
+ "HashTableIterator::FindValidObject()");
+ }
+
+#endif
+
+ return pObject;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/workben/hashtbl.hxx b/tools/workben/hashtbl.hxx
new file mode 100644
index 000000000000..884f398f837f
--- /dev/null
+++ b/tools/workben/hashtbl.hxx
@@ -0,0 +1,205 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _HASHTBL_HXX
+#define _HASHTBL_HXX
+
+#include <tlgen.hxx>
+
+// ADT hash table
+//
+// Invariante:
+// 1. m_lElem < m_lSize
+// 2. die Elemente in m_Array wurden double-hashed erzeugt
+//
+class HashItem;
+
+class HashTable
+{
+ ULONG m_lSize;
+ ULONG m_lElem;
+ HashItem *m_pData;
+ double m_dMaxLoadFactor;
+ double m_dGrowFactor;
+ BOOL m_bOwner;
+
+ ULONG Hash(String const& Key) const;
+ ULONG DHash(String const& Key, ULONG lHash) const;
+ ULONG Probe(ULONG lPos) const;
+
+ HashItem* FindPos(String const& Key) const;
+ void SmartGrow();
+ double CalcLoadFactor() const;
+
+// Statistik
+#ifdef DBG_UTIL
+private:
+ struct
+ {
+ ULONG m_lSingleHash;
+ ULONG m_lDoubleHash;
+ ULONG m_lProbe;
+ }
+ m_aStatistic;
+#endif
+
+protected:
+ friend class HashTableIterator;
+
+ virtual void OnDeleteObject(void* pObject);
+
+ void* GetObjectAt(ULONG lPos) const;
+
+// Default-Werte
+public:
+ static double m_defMaxLoadFactor;
+ static double m_defDefGrowFactor;
+
+public:
+ HashTable
+ (
+ ULONG lSize,
+ BOOL bOwner,
+ double dMaxLoadFactor = HashTable::m_defMaxLoadFactor /* 0.8 */,
+ double dGrowFactor = HashTable::m_defDefGrowFactor /* 2.0 */
+ );
+
+ ~HashTable();
+
+ BOOL IsFull() const;
+ ULONG GetSize() const { return m_lSize; }
+
+ void* Find (String const& Key) const;
+ BOOL Insert (String const& Key, void* pObject);
+ void* Delete (String const& Key);
+};
+
+// ADT hash table iterator
+//
+// Invariante: 0 <= m_lAt < m_aTable.GetCount()
+//
+class HashTableIterator
+{
+ ULONG m_lAt;
+ HashTable const& m_aTable;
+
+ void* FindValidObject(BOOL bForward);
+
+protected:
+ void* GetFirst(); // Interation _ohne_ Sortierung
+ void* GetNext();
+ void* GetLast();
+ void* GetPrev();
+
+public:
+ HashTableIterator(HashTable const&);
+};
+
+// typsichere Makros ---------------------------------------------------
+
+#define DECLARE_HASHTABLE_INTERN(ClassName,Owner,KeyType,ObjType) \
+ class ClassName : public HashTable \
+ { \
+ public: \
+ ClassName \
+ ( \
+ ULONG lSize, \
+ double dMaxLoadFactor = HashTable::m_defMaxLoadFactor, \
+ double dGrowFactor = HashTable::m_defDefGrowFactor \
+ ) \
+ : HashTable(lSize,Owner,dMaxLoadFactor,dGrowFactor) {} \
+ \
+ ObjType Find (KeyType const& Key) const \
+ { return (ObjType) HashTable::Find(String(Key)); } \
+ \
+ BOOL Insert (KeyType const& Key, ObjType Object) \
+ { return HashTable::Insert(String(Key), (void*) Object); } \
+ \
+ ObjType Delete (KeyType const&Key) \
+ { return (ObjType) HashTable::Delete (String(Key)); } \
+ };
+
+// HashTable OHNE Owner-Verhalten
+#define DECLARE_HASHTABLE(ClassName,KeyType,ObjType) \
+ DECLARE_HASHTABLE_INTERN(ClassName,FALSE,KeyType,ObjType)
+
+// HashTable MIT Owner-Verhalten
+#define DECLARE_HASHTABLE_OWNER(ClassName,KeyType,ObjType) \
+ DECLARE_HASHTABLE_INTERN(ClassName##2,TRUE,KeyType,ObjType) \
+ class ClassName : public ClassName##2 \
+ { \
+ protected: \
+ virtual void OnDeleteObject(void* pObject); \
+ public: \
+ ClassName \
+ ( \
+ ULONG lSize, \
+ double dMaxLoadFactor = HashTable::m_defMaxLoadFactor, \
+ double dGrowFactor = HashTable::m_defDefGrowFactor \
+ ) \
+ : ClassName##2(lSize,dMaxLoadFactor,dGrowFactor) {} \
+ ~ClassName(); \
+ };
+
+#define IMPLEMENT_HASHTABLE_OWNER(ClassName,KeyType,ObjType) \
+ void ClassName::OnDeleteObject(void* pObject) \
+ { delete (ObjType) pObject; } \
+ \
+ ClassName::~ClassName() \
+ { \
+ for (ULONG i=0; i<GetSize(); i++) \
+ { \
+ void *pObject = GetObjectAt(i); \
+ if (pObject != NULL) \
+ OnDeleteObject(pObject); \
+ } \
+ }
+
+// Iterator-Makros --------------------------------------------------
+
+#define DECLARE_HASHTABLE_ITERATOR(ClassName,ObjType) \
+ class ClassName : public HashTableIterator \
+ { \
+ public: \
+ ClassName(HashTable const& aTable) \
+ : HashTableIterator(aTable) {} \
+ \
+ ObjType GetFirst() \
+ { return (ObjType)HashTableIterator::GetFirst(); } \
+ ObjType GetNext() \
+ { return (ObjType)HashTableIterator::GetNext(); } \
+ ObjType GetLast() \
+ { return (ObjType)HashTableIterator::GetLast(); } \
+ ObjType GetPrev() \
+ { return (ObjType)HashTableIterator::GetPrev(); } \
+ };
+
+
+#endif // _HASHTBL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/workben/helloworld.c b/tools/workben/helloworld.c
new file mode 100644
index 000000000000..6a484f4bb39f
--- /dev/null
+++ b/tools/workben/helloworld.c
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <stdlib.h>
+#include <io.h>
+main( )
+{
+
+ printf( "%s\n", "hello world");
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/workben/inetmimetest.cxx b/tools/workben/inetmimetest.cxx
new file mode 100644
index 000000000000..27f62a605c07
--- /dev/null
+++ b/tools/workben/inetmimetest.cxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <tools/inetmime.hxx>
+
+#include "rtl/textenc.h"
+#include "rtl/ustring.hxx"
+
+#include <cstdlib>
+#include <iostream>
+
+namespace {
+
+bool testDecode(char const * input, char const * expected) {
+ rtl::OUString result = INetMIME::decodeHeaderFieldBody(
+ INetMIME::HEADER_FIELD_TEXT, input);
+ bool success = result.equalsAscii(expected);
+ if (!success) {
+ std::cout
+ << "FAILED: decodeHeaderFieldBody(\"" << input << "\"): \""
+ << rtl::OUStringToOString(
+ result, RTL_TEXTENCODING_ASCII_US).getStr()
+ << "\" != \"" << expected << "\"\n";
+ }
+ return success;
+}
+
+}
+
+int
+#if defined WNT
+__cdecl
+#endif
+main() {
+ bool success = true;
+ success &= testDecode("=?iso-8859-1?B?QQ==?=", "A");
+ success &= testDecode("=?iso-8859-1?B?QUI=?=", "AB");
+ success &= testDecode("=?iso-8859-1?B?QUJD?=", "ABC");
+ return success ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/workben/makefile.mk b/tools/workben/makefile.mk
new file mode 100644
index 000000000000..97e7ebfa9a15
--- /dev/null
+++ b/tools/workben/makefile.mk
@@ -0,0 +1,89 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..
+PRJNAME = tl
+TARGET = tldem
+LIBTARGET = NO
+TARGETTYPE = CUI
+ENABLE_EXCEPTIONS=TRUE
+
+.INCLUDE: settings.mk
+
+OBJFILES = \
+ $(OBJ)$/solar.obj \
+ $(OBJ)$/urltest.obj \
+ $(OBJ)$/inetmimetest.obj
+# $(OBJ)$/demostor.obj \
+# $(OBJ)$/fstest.obj \
+# $(OBJ)$/tldem.obj \
+
+APP1TARGET = solar
+APP1OBJS = $(OBJ)$/solar.obj
+.IF "$(GUI)" == "UNX" || "$(GUI)" == "OS2"
+APP1STDLIBS = $(TOOLSLIB)
+.ELSE
+APP1LIBS = $(LB)$/itools.lib
+.ENDIF
+
+APP2TARGET = urltest
+APP2OBJS = $(OBJ)$/urltest.obj
+.IF "$(GUI)" == "UNX" || "$(GUI)" == "OS2"
+APP2STDLIBS = $(TOOLSLIB) $(SALLIB) $(CPPULIB) $(CPPUHELPERLIB)
+.ELSE
+APP2STDLIBS = $(LB)$/itools.lib $(SALLIB) $(CPPULIB) $(CPPUHELPERLIB)
+.ENDIF
+
+APP3TARGET = inetmimetest
+APP3OBJS = $(OBJ)$/inetmimetest.obj
+APP3STDLIBS = $(SALLIB) $(TOOLSLIB)
+
+# APP3TARGET = tldem
+# APP3OBJS = $(OBJ)$/tldem.obj
+# .IF "$(GUI)" == "UNX"
+# APP3STDLIBS = $(TOOLSLIB)
+# .ELSE
+# APP3STDLIBS = $(LB)$/itools.lib
+# .ENDIF
+
+# APP4TARGET = demostor
+# APP4OBJS = $(OBJ)$/demostor.obj
+# .IF "$(GUI)" == "UNX"
+# APP4STDLIBS = $(TOOLSLIB) $(SALLIB)
+# .ELSE
+# APP4STDLIBS = $(LB)$/itools.lib $(SALLIB)
+# .ENDIF
+
+# APP5TARGET = fstest
+# APP5OBJS = $(OBJ)$/fstest.obj
+# .IF "$(GUI)" == "UNX"
+# APP5STDLIBS = $(TOOLSLIB) $(SALLIB)
+# .ELSE
+# APP5STDLIBS = $(LB)$/itools.lib $(SALLIB)
+# .ENDIF
+
+.INCLUDE: target.mk
diff --git a/tools/workben/solar.c b/tools/workben/solar.c
new file mode 100644
index 000000000000..e5b5e1ea741f
--- /dev/null
+++ b/tools/workben/solar.c
@@ -0,0 +1,430 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef enum { t_char, t_short, t_int, t_long, t_double } Type;
+typedef int (*TestFunc)( Type, void* );
+
+struct Description;
+
+int IsBigEndian(void);
+int IsStackGrowingDown_2( int * pI );
+int IsStackGrowingDown(void);
+int GetStackAlignment_3( char*p, long l, int i, short s, char b, char c, ... );
+int GetStackAlignment_2( char*p, long l, int i, short s, char b, char c );
+int GetStackAlignment(void);
+void PrintArgs( int p, ... );
+int check( TestFunc func, Type eT, void* p );
+
+#if defined (UNX) || defined (WNT) || defined (OS2)
+
+#ifdef UNX
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+
+#define I_STDARG
+#ifdef I_STDARG
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#define NO_USE_FORK_TO_CHECK
+#ifdef USE_FORK_TO_CHECK
+#include <sys/wait.h>
+#else
+#include <signal.h>
+#include <setjmp.h>
+#endif
+
+#else
+#endif
+
+#define printTypeSize(Type,Name) printf( "sizeof(%s)\t= %d\n", Name, \
+ sizeof (Type) )
+
+#define isSignedType(Type) (((Type)-1) < 0)
+#define printTypeSign(Type,Name) printf( "%s\t= %s %s\n", Name, \
+ ( isSignedType(Type) ? "unsigned" : "signed" ), Name )
+
+
+int IsBigEndian()
+{
+ long l = 1;
+ return ! *(char*)&l;
+}
+
+int IsStackGrowingDown_2( int * pI )
+{
+ int i = 1;
+ return ((unsigned long)&i) < (unsigned long)pI;
+}
+
+int IsStackGrowingDown()
+{
+ int i = 1;
+ return IsStackGrowingDown_2(&i);
+}
+
+int GetStackAlignment_3( char*p, long l, int i, short s, char b, char c, ... )
+{
+ (void) p; (void) l; (void) i; (void) s; /* unused */
+ if ( IsStackGrowingDown() )
+ return &c - &b;
+ else
+ return &b - &c;
+}
+
+int GetStackAlignment_2( char*p, long l, int i, short s, char b, char c )
+{
+ (void) p; (void) l; (void) i; (void) s; /* unused */
+ if ( IsStackGrowingDown() )
+ return &c - &b;
+ else
+ return &b - &c;
+}
+
+int GetStackAlignment()
+{
+ int nStackAlignment = GetStackAlignment_3(0,1,2,3,4,5);
+ if ( nStackAlignment != GetStackAlignment_2(0,1,2,3,4,5) )
+ printf( "Pascal calling convention\n" );
+ return nStackAlignment;
+}
+
+
+
+
+#if defined (UNX) || defined (WNT) || defined (OS2)
+
+#ifdef I_STDARG
+void PrintArgs( int p, ... )
+#else
+void PrintArgs( p, va_alist )
+int p;
+va_dcl
+#endif
+{
+ int value;
+ va_list ap;
+
+#ifdef I_STDARG
+ va_start( ap, p );
+#else
+ va_start( ap );
+#endif
+
+ printf( "value = %d", p );
+
+ while ( ( value = va_arg(ap, int) ) != 0 )
+ printf( " %d", value );
+
+ printf( "\n" );
+ va_end(ap);
+}
+
+#ifndef USE_FORK_TO_CHECK
+static jmp_buf check_env;
+static int bSignal;
+#if defined (UNX) || defined (OS2)
+void SignalHandler( int sig )
+#else
+void __cdecl SignalHandler( int sig )
+#endif
+{
+ bSignal = 1;
+ /*
+ fprintf( stderr, "Signal %d caught\n", sig );
+ signal( sig, SignalHandler );
+ */
+ longjmp( check_env, sig );
+}
+#endif
+
+int check( TestFunc func, Type eT, void* p )
+{
+#ifdef USE_FORK_TO_CHECK
+ pid_t nChild = fork();
+ if ( nChild )
+ {
+ int exitVal;
+ wait( &exitVal );
+ if ( exitVal & 0xff )
+ return -1;
+ else
+ return exitVal >> 8;
+ }
+ else
+ {
+ exit( func( eT, p ) );
+ }
+#else
+ int result;
+
+ bSignal = 0;
+
+ if ( !setjmp( check_env ) )
+ {
+ signal( SIGSEGV, SignalHandler );
+#ifdef UNX
+ signal( SIGBUS, SignalHandler );
+#else
+#endif
+ result = func( eT, p );
+ signal( SIGSEGV, SIG_DFL );
+#ifdef UNX
+ signal( SIGBUS, SIG_DFL );
+#else
+#endif
+ }
+
+ if ( bSignal )
+ return -1;
+ else
+ return 0;
+#endif
+}
+
+#endif
+
+
+int GetAtAddress( Type eT, void* p )
+{
+ switch ( eT )
+ {
+ case t_char: return *((char*)p);
+ case t_short: return *((short*)p);
+ case t_int: return *((int*)p);
+ case t_long: return *((long*)p);
+ case t_double: return *((double*)p);
+ }
+ abort();
+}
+
+int SetAtAddress( Type eT, void* p )
+{
+ switch ( eT )
+ {
+ case t_char: return *((char*)p) = 0;
+ case t_short: return *((short*)p) = 0;
+ case t_int: return *((int*)p) = 0;
+ case t_long: return *((long*)p) = 0;
+ case t_double: return *((double*)p)= 0;
+ }
+ abort();
+}
+
+char* TypeName( Type eT )
+{
+ switch ( eT )
+ {
+ case t_char: return "char";
+ case t_short: return "short";
+ case t_int: return "int";
+ case t_long: return "long";
+ case t_double: return "double";
+ }
+ abort();
+}
+
+int CheckGetAccess( Type eT, void* p )
+{
+ int b;
+ b = -1 != check( (TestFunc)GetAtAddress, eT, p );
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,
+ "%s read %s at %p\n",
+ (b? "can" : "can not" ), TypeName(eT), p );
+#endif
+ return b;
+}
+int CheckSetAccess( Type eT, void* p )
+{
+ int b;
+ b = -1 != check( (TestFunc)SetAtAddress, eT, p );
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,
+ "%s write %s at %p\n",
+ (b? "can" : "can not" ), TypeName(eT), p );
+#endif
+ return b;
+}
+
+int GetAlignment( Type eT )
+{
+ char a[ 16*8 ];
+ int p = (int)(void*)&a;
+ int i;
+ p = ( p + 0xF ) & ~0xF;
+ for ( i = 1; i < 16; i++ )
+ if ( CheckGetAccess( eT, (void*)(p+i) ) )
+ return i;
+ return 0;
+}
+
+int CheckCharAccess( char* p )
+{
+ if ( CheckGetAccess( t_char, p ) )
+ printf( "can read address %p\n", p );
+ else
+ printf( "can not read address %p\n", p );
+
+ if ( CheckSetAccess( t_char, p ) )
+ printf( "can write address %p\n", p );
+ else
+ printf( "can not write address %p\n", p );
+
+ return 0;
+}
+
+struct Description
+{
+ int bBigEndian;
+ int bStackGrowsDown;
+ int nStackAlignment;
+ int nAlignment[3]; /* 2,4,8 */
+};
+
+void Description_Ctor( struct Description* pThis )
+{
+ pThis->bBigEndian = IsBigEndian();
+ pThis->bStackGrowsDown = IsStackGrowingDown();
+ pThis->nStackAlignment = GetStackAlignment();
+
+ if ( sizeof(short) != 2 )
+ abort();
+ pThis->nAlignment[0] = GetAlignment( t_short );
+ if ( sizeof(int) != 4 )
+ abort();
+ pThis->nAlignment[1] = GetAlignment( t_int );
+ if ( sizeof(double) != 8 )
+ abort();
+ pThis->nAlignment[2] = GetAlignment( t_double );
+}
+
+void Description_Print( struct Description* pThis, char* name )
+{
+ int i;
+ FILE* f = fopen( name, "w" );
+ fprintf( f, "#define __%s\n",
+ pThis->bBigEndian ? "BIGENDIAN" : "LITTLEENDIAN" );
+ for ( i = 0; i < 3; i++ )
+ fprintf( f, "#define __ALIGNMENT%d\t%d\n",
+ 1 << (i+1), pThis->nAlignment[i] );
+ fprintf( f, "#define __STACKALIGNMENT wird nicht benutzt\t%d\n", pThis->nStackAlignment );
+ fprintf( f, "#define __STACKDIRECTION\t%d\n",
+ pThis->bStackGrowsDown ? -1 : 1 );
+ fprintf( f, "#define __SIZEOFCHAR\t%d\n", sizeof( char ) );
+ fprintf( f, "#define __SIZEOFSHORT\t%d\n", sizeof( short ) );
+ fprintf( f, "#define __SIZEOFINT\t%d\n", sizeof( int ) );
+ fprintf( f, "#define __SIZEOFLONG\t%d\n", sizeof( long ) );
+ fprintf( f, "#define __SIZEOFPOINTER\t%d\n", sizeof( void* ) );
+ fprintf( f, "#define __SIZEOFDOUBLE\t%d\n", sizeof( double ) );
+ fprintf( f, "#define __IEEEDOUBLE\n" );
+ fprintf( f, "#define _SOLAR_NODESCRIPTION\n" );
+
+ fclose(f);
+}
+
+int
+#ifdef WNT
+__cdecl
+#endif
+main( int argc, char* argv[] )
+{
+ printTypeSign( char, "char" );
+ printTypeSign( short, "short" );
+ printTypeSign( int, "int" );
+ printTypeSign( long, "long" );
+
+ printTypeSize( char, "char" );
+ printTypeSize( short, "short" );
+ printTypeSize( int, "int" );
+ printTypeSize( long, "long" );
+ printTypeSize( float, "float" );
+ printTypeSize( double, "double" );
+ printTypeSize( void *, "void *" );
+
+ if ( IsBigEndian() )
+ printf( "BIGENDIAN (Sparc, MC680x0, RS6000)\n" );
+ else
+ printf( "LITTLEENDIAN (Intel, VAX, PowerPC)\n" );
+
+ if( IsStackGrowingDown() )
+ printf( "Stack waechst nach unten\n" );
+ else
+ printf( "Stack waechst nach oben\n" );
+
+ printf( "STACKALIGNMENT : %d\n", GetStackAlignment() );
+
+ PrintArgs( 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 );
+
+ {
+ char a[64];
+ int i = 56;
+ do
+ {
+ printf( "Zugriff long auf %i-Aligned Adresse : ", i / 7 );
+ printf( ( CheckGetAccess( t_long, (long*)&a[i] ) ? "OK\n" : "ERROR\n" ) );
+ i >>= 1;
+ } while( i >= 7 );
+ }
+
+ {
+ char a[64];
+ int i = 56;
+ do
+ {
+ printf( "Zugriff double auf %i-Aligned Adresse : ", i / 7 );
+ printf( ( CheckGetAccess( t_double, (double*)&a[i] ) ? "OK\n" : "ERROR\n" ) );
+ i >>= 1;
+ } while( i >= 7 );
+ }
+
+ {
+ char* p = NULL;
+ CheckCharAccess( p );
+ p = (char*)&p;
+ CheckCharAccess( p );
+ }
+
+ if ( argc > 1 )
+ {
+ struct Description description;
+ Description_Ctor( &description );
+ Description_Print( &description, argv[1] );
+ }
+
+ exit( 0 );
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/workben/tldem.cxx b/tools/workben/tldem.cxx
new file mode 100644
index 000000000000..e83bc860e8bb
--- /dev/null
+++ b/tools/workben/tldem.cxx
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <tools/fsys.hxx>
+#include <tools/stream.hxx>
+#include <sstring.hxx>
+
+int
+#ifdef WNT
+__cdecl
+#endif
+main( int argc, char **argv )
+{
+ String aString;
+ aString = "*.*";
+ Dir aDir(aString);
+ SvFileStream aFile;
+ SvFileStream aSortedFile;
+
+ StringList *pList = new StringList;
+ SStringList *pSortedList = new SStringList;
+ ULONG nCount = aDir.Count();
+
+ for ( ULONG i=0; i<nCount; i++ )
+ {
+ aString = aDir[i].GetName();
+ pList->Insert( new String( aString ), LIST_APPEND );
+ pSortedList->PutString( new String( aString ));
+ }
+
+ aFile.Open( "test.dir", STREAM_WRITE );
+ for ( ULONG j=0; j<nCount; j++ )
+ {
+ aFile.WriteLine( *pList->GetObject(j) );
+ }
+ aFile.Close();
+
+
+ aSortedFile.Open( "stest.dir", STREAM_WRITE );
+ for ( ULONG k=0; k<nCount; k++ )
+ {
+ aSortedFile.WriteLine( *pSortedList->GetObject(k) );
+ }
+ if ( pSortedList->IsString( new String("bloedString")) != NOT_THERE )
+ aSortedFile.WriteLine( "Fehler !" );
+ if ( pSortedList->IsString( new String(".")) == NOT_THERE )
+ aSortedFile.WriteLine( "Fehler ?!?" );
+ aSortedFile.Close();
+
+ delete pList;
+ delete pSortedList;
+ return 0;
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/workben/urltest.cxx b/tools/workben/urltest.cxx
new file mode 100644
index 000000000000..98424a55114b
--- /dev/null
+++ b/tools/workben/urltest.cxx
@@ -0,0 +1,1910 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <tools/inetmime.hxx>
+#include <tools/urlobj.hxx>
+#include "com/sun/star/util/XStringWidth.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "osl/thread.h"
+#include "rtl/string.h"
+#include "rtl/string.hxx"
+#include "rtl/textenc.h"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include <sal/macros.h>
+
+#include <cstddef>
+#include <cstdlib>
+#include <iostream>
+#include <ostream>
+#include <stdio.h>
+
+using namespace com::sun;
+
+std::ostream & operator <<(std::ostream & out, rtl::OUString const & value) {
+ out << rtl::OUStringToOString(value, RTL_TEXTENCODING_ASCII_US).getStr();
+ return out;
+}
+
+namespace {
+
+template< typename T1, typename T2 > bool assertEqual(
+ rtl::OUString const & message, T1 const & expected, T2 const & actual)
+{
+ bool success = expected == actual;
+ if (!success) {
+ std::cout
+ << "FAILED " << message << ": " << expected << " != " << actual
+ << '\n';
+ }
+ return success;
+}
+
+}
+
+//============================================================================
+//
+// testRelToAbs
+//
+//============================================================================
+
+struct RelToAbsTest
+{
+ sal_Char const * m_pBase;
+ sal_Char const * m_pRel;
+ sal_Char const * m_pAbs;
+ sal_Char const * m_pAlt;
+};
+
+//============================================================================
+bool testRelToAbs(RelToAbsTest const * pTest, std::size_t nSize)
+{
+ bool bSuccess = true;
+ INetURLObject aBase;
+ String aTest;
+ for (std::size_t i = 0; i < nSize; ++i)
+ {
+ if (pTest[i].m_pBase)
+ {
+ aBase.SetURL(pTest[i].m_pBase);
+ }
+ if (aBase.HasError())
+ {
+ printf(" BAD BASE %s\n",
+ pTest[i].m_pBase ? pTest[i].m_pBase : "");
+ bSuccess = false;
+ continue;
+ }
+ INetURLObject aAbs;
+ aBase.GetNewAbsURL(pTest[i].m_pRel, &aAbs);
+ ByteString aTheAbs(String(aAbs.GetMainURL(INetURLObject::NO_DECODE)),
+ RTL_TEXTENCODING_ISO_8859_1);
+ if (!(aTheAbs.Equals(pTest[i].m_pAbs)
+ || pTest[i].m_pAlt && aTheAbs.Equals(pTest[i].m_pAlt)))
+ {
+ printf(" BAD GetNewAbsURL %s -> %s (%s)\n", pTest[i].m_pRel,
+ aTheAbs.GetBuffer(), pTest[i].m_pAbs);
+ bSuccess = false;
+ }
+ aTheAbs = ByteString(
+ String(
+ INetURLObject::GetAbsURL(
+ aBase.GetMainURL(INetURLObject::NO_DECODE),
+ UniString(pTest[i].m_pRel, RTL_TEXTENCODING_ISO_8859_1))),
+ RTL_TEXTENCODING_ISO_8859_1);
+ if (!(aTheAbs.Equals(pTest[i].m_pAbs)
+ || pTest[i].m_pAlt && aTheAbs.Equals(pTest[i].m_pAlt)))
+ {
+ printf(" BAD GetAbsURL %s -> %s (%s)\n", pTest[i].m_pRel,
+ aTheAbs.GetBuffer(), pTest[i].m_pAbs);
+ bSuccess = false;
+ }
+ }
+ printf("\n");
+ return bSuccess;
+}
+
+//============================================================================
+//
+// testSetFSys
+//
+//============================================================================
+
+struct SetFSysTest
+{
+ sal_Char const * m_pPath;
+ INetURLObject::FSysStyle m_eStyle;
+ sal_Char const * m_pUrl;
+};
+
+//============================================================================
+inline sal_Char const * toString(INetURLObject::FSysStyle eStyle)
+{
+ static sal_Char aBuffer[5];
+ int i = 0;
+ if (eStyle & INetURLObject::FSYS_VOS)
+ aBuffer[i++] = 'V';
+ if (eStyle & INetURLObject::FSYS_UNX)
+ aBuffer[i++] = 'U';
+ if (eStyle & INetURLObject::FSYS_DOS)
+ aBuffer[i++] = 'D';
+ if (eStyle & INetURLObject::FSYS_MAC)
+ aBuffer[i++] = 'M';
+ if (i == 0)
+ aBuffer[i++] = '-';
+ aBuffer[i] = '\0';
+ return aBuffer;
+}
+
+//============================================================================
+bool testSetFSys(SetFSysTest const * pTest, std::size_t nSize)
+{
+ bool bSuccess = true;
+ String aPath;
+ for (std::size_t i = 0; i < nSize; ++i)
+ {
+ if (pTest[i].m_pPath)
+ aPath = String::CreateFromAscii(pTest[i].m_pPath);
+ if (aPath.Len() == 0)
+ {
+ printf(" NO PATH\n");
+ continue;
+ }
+ INetURLObject aUrl1(aPath, pTest[i].m_eStyle);
+ INetURLObject aUrl2;
+ aUrl2.setFSysPath(aPath, pTest[i].m_eStyle);
+ if (aUrl1.GetMainURL(INetURLObject::NO_DECODE).
+ equalsAscii(pTest[i].m_pUrl)
+ && aUrl2.GetMainURL(INetURLObject::NO_DECODE).
+ equalsAscii(pTest[i].m_pUrl))
+ printf(" ok %s %s -> %s\n",
+ ByteString(aPath, RTL_TEXTENCODING_ISO_8859_1).GetBuffer(),
+ toString(pTest[i].m_eStyle), pTest[i].m_pUrl);
+ else
+ {
+ String aTestA = aUrl1.GetMainURL(INetURLObject::NO_DECODE);
+ String aTestB = aUrl2.GetMainURL(INetURLObject::NO_DECODE);
+
+ printf(" BAD %s %s -> %s, %s (%s)\n",
+ ByteString(aPath, RTL_TEXTENCODING_ISO_8859_1).GetBuffer(),
+ toString(pTest[i].m_eStyle),
+ ByteString(aTestA, RTL_TEXTENCODING_ISO_8859_1).GetBuffer(),
+ ByteString(aTestB, RTL_TEXTENCODING_ISO_8859_1).GetBuffer(),
+ pTest[i].m_pUrl);
+ bSuccess = false;
+ }
+ }
+ printf("\n");
+ return bSuccess;
+}
+
+//============================================================================
+//
+// main
+//
+//============================================================================
+
+namespace {
+
+class StringWidth: public cppu::WeakImplHelper1< star::util::XStringWidth >
+{
+public:
+ virtual sal_Int32 SAL_CALL queryStringWidth(rtl::OUString const & rString)
+ throw (star::uno::RuntimeException)
+ {
+ return rString.getLength();
+ }
+};
+
+void abbreviate(INetURLObject aObj)
+{
+ star::uno::Reference< star::util::XStringWidth > xWidth(new StringWidth);
+ sal_Int32 nMax = aObj.GetMainURL(INetURLObject::NO_DECODE).getLength() + 10;
+ for (sal_Int32 i = -10; i <= nMax; ++i)
+ {
+ rtl::OString
+ aAbbreviated(rtl::OUStringToOString(
+ aObj.getAbbreviated(xWidth,
+ i,
+ INetURLObject::NO_DECODE),
+ RTL_TEXTENCODING_UTF8));
+ printf(
+ "%4ld: <%s", static_cast< long int >(i), aAbbreviated.getStr());
+ for (sal_Int32 j = aAbbreviated.getLength(); j < i; ++j)
+ printf(" ");
+ printf(">\n");
+ }
+}
+
+bool test_getSegmentCount(
+ char const * url, bool ignoreFinalSlash, sal_Int32 result)
+{
+ return
+ assertEqual(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("test_getSegmentCount")),
+ result,
+ INetURLObject(rtl::OUString::createFromAscii(url)).getSegmentCount(
+ ignoreFinalSlash));
+}
+
+bool test_insertName(
+ char const * url, char const * name, bool appendFinalSlash, sal_Int32 index,
+ bool ignoreFinalSlash, bool success, char const * result)
+{
+ INetURLObject tmp(rtl::OUString::createFromAscii(url));
+ return
+ assertEqual(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("test_insertName")),
+ success,
+ tmp.insertName(
+ rtl::OUString::createFromAscii(name), appendFinalSlash, index,
+ ignoreFinalSlash)) &
+ assertEqual(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("test_insertName")),
+ rtl::OUString::createFromAscii(result),
+ tmp.GetMainURL(INetURLObject::NO_DECODE));
+}
+
+bool test_removeSegment(
+ char const * url, sal_Int32 index, bool ignoreFinalSlash, bool success,
+ char const * result)
+{
+ INetURLObject tmp(rtl::OUString::createFromAscii(url));
+ return
+ assertEqual(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("test_removeSegment")),
+ success, tmp.removeSegment(index, ignoreFinalSlash)) &
+ assertEqual(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("test_removeSegment")),
+ rtl::OUString::createFromAscii(result),
+ tmp.GetMainURL(INetURLObject::NO_DECODE));
+}
+
+}
+
+int
+#if defined WNT
+__cdecl
+#endif // WNT
+main()
+{
+ bool bSuccess = true;
+
+ if (true)
+ {
+ // The data for this test is taken from the files
+ // <http://www.ics.uci.edu/~fielding/url/testN.html> with N = 1,
+ // ..., 3, as of August 28, 2000:
+ static RelToAbsTest const aTest[]
+ = { //{ "http://a/b/c/d;p?q", "g:h", "g:h", 0 },
+ { "http://a/b/c/d;p?q", "g", "http://a/b/c/g", 0 },
+ { 0, "./g", "http://a/b/c/g", 0 },
+ { 0, "g/", "http://a/b/c/g/", 0 },
+ { 0, "/g", "http://a/g", 0 },
+ { 0, "//g", "http://g", "http://g/" },
+ //{ 0, "?y", "http://a/b/c/d;p?y", 0 },
+ { 0, "g?y", "http://a/b/c/g?y", 0 },
+ //{ 0, "#s", "http://a/b/c/d;p?q#s", 0 },
+ { 0, "g#s", "http://a/b/c/g#s", 0 },
+ { 0, "g?y#s", "http://a/b/c/g?y#s", 0 },
+ { 0, ";x", "http://a/b/c/;x", 0 },
+ { 0, "g;x", "http://a/b/c/g;x", 0 },
+ { 0, "g;x?y#s", "http://a/b/c/g;x?y#s", 0 },
+ { 0, ".", "http://a/b/c/", 0 },
+ { 0, "./", "http://a/b/c/", 0 },
+ { 0, "..", "http://a/b/", 0 },
+ { 0, "../", "http://a/b/", 0 },
+ { 0, "../g", "http://a/b/g", 0 },
+ { 0, "../..", "http://a/", 0 },
+ { 0, "../../", "http://a/", 0 },
+ { 0, "../../g", "http://a/g", 0 },
+ //{ 0, "", "http://a/b/c/d;p?q", 0 },
+ { 0, "../../../g", "http://a/../g", "http://a/g" },
+ { 0, "../../../../g", "http://a/../../g", "http://a/g" },
+ { 0, "/./g", "http://a/./g", 0 },
+ { 0, "/../g", "http://a/../g", 0 },
+ { 0, "g.", "http://a/b/c/g.", 0 },
+ { 0, ".g", "http://a/b/c/.g", 0 },
+ { 0, "g..", "http://a/b/c/g..", 0 },
+ { 0, "..g", "http://a/b/c/..g", 0 },
+ { 0, "./../g", "http://a/b/g", 0 },
+ { 0, "./g/.", "http://a/b/c/g/", 0 },
+ { 0, "g/./h", "http://a/b/c/g/h", 0 },
+ { 0, "g/../h", "http://a/b/c/h", 0 },
+ { 0, "g;x=1/./y", "http://a/b/c/g;x=1/y", 0 },
+ { 0, "g;x=1/../y", "http://a/b/c/y", 0 },
+ { 0, "g?y/./x", "http://a/b/c/g?y/./x", 0 },
+ { 0, "g?y/../x", "http://a/b/c/g?y/../x", 0 },
+ { 0, "g#s/./x", "http://a/b/c/g#s/./x", 0 },
+ { 0, "g#s/../x", "http://a/b/c/g#s/../x", 0 },
+ { 0, "http:g", "http:g", "http://a/b/c/g" },
+ //{ 0, "http:", "http:", 0 },
+ { "http://a/b/c/d;p?q=1/2", "g", "http://a/b/c/g", 0 },
+ { 0, "./g", "http://a/b/c/g", 0 },
+ { 0, "g/", "http://a/b/c/g/", 0 },
+ { 0, "/g", "http://a/g", 0 },
+ { 0, "//g", "http://g", "http://g/" },
+ { 0, "g?y", "http://a/b/c/g?y", 0 },
+ { 0, "g?y/./x", "http://a/b/c/g?y/./x", 0 },
+ { 0, "g?y/../x", "http://a/b/c/g?y/../x", 0 },
+ { 0, "g#s", "http://a/b/c/g#s", 0 },
+ { 0, "g#s/./x", "http://a/b/c/g#s/./x", 0 },
+ { 0, "g#s/../x", "http://a/b/c/g#s/../x", 0 },
+ { 0, "./", "http://a/b/c/", 0 },
+ { 0, "../", "http://a/b/", 0 },
+ { 0, "../g", "http://a/b/g", 0 },
+ { 0, "../../", "http://a/", 0 },
+ { 0, "../../g", "http://a/g", 0 },
+ { "http://a/b/c/d;p=1/2?q", "g", "http://a/b/c/d;p=1/g", 0 },
+ { 0, "./g", "http://a/b/c/d;p=1/g", 0 },
+ { 0, "g/", "http://a/b/c/d;p=1/g/", 0 },
+ { 0, "g?y", "http://a/b/c/d;p=1/g?y", 0 },
+ { 0, ";x", "http://a/b/c/d;p=1/;x", 0 },
+ { 0, "g;x", "http://a/b/c/d;p=1/g;x", 0 },
+ { 0, "g;x=1/./y", "http://a/b/c/d;p=1/g;x=1/y", 0 },
+ { 0, "g;x=1/../y", "http://a/b/c/d;p=1/y", 0 },
+ { 0, "./", "http://a/b/c/d;p=1/", 0 },
+ { 0, "../", "http://a/b/c/", 0 },
+ { 0, "../g", "http://a/b/c/g", 0 },
+ { 0, "../../", "http://a/b/", 0 },
+ { 0, "../../g", "http://a/b/g", 0 },
+ { "file:///", "generic:", "file:///generic:", 0 },
+ { 0, "generic:#fragment", "file:///generic:#fragment", 0 },
+ { 0, "generic:something", "generic:something", 0 },
+ { 0, "c:/foo/bar", "file:///c:/foo/bar", 0 },
+ { 0, "c:\\foo\\bar", "file:///c:%5Cfoo%5Cbar", 0 } };
+ if (!testRelToAbs(aTest, sizeof aTest / sizeof (RelToAbsTest)))
+ bSuccess = false;
+ }
+
+ if (false)
+ {
+ static SetFSysTest const aTest[]
+ = { { "//.", INetURLObject::FSysStyle(0), "" },
+ { 0, INetURLObject::FSysStyle(1), "file:///" },
+ { 0, INetURLObject::FSysStyle(2), "file:////." },
+ { 0, INetURLObject::FSysStyle(3), "file:///" },
+ { 0, INetURLObject::FSysStyle(4), "file:///%2F%2F." },
+ { 0, INetURLObject::FSysStyle(5), "file:///" },
+ { 0, INetURLObject::FSysStyle(6), "file:////." },
+ { 0, INetURLObject::FSysStyle(7), "file:///" },
+ { 0, INetURLObject::FSysStyle(8), "file:///%2F%2F." },
+ { 0, INetURLObject::FSysStyle(9), "file:///" },
+ { 0, INetURLObject::FSysStyle(10), "file:////." },
+ { 0, INetURLObject::FSysStyle(11), "file:///" },
+ { 0, INetURLObject::FSysStyle(12), "file:///%2F%2F." },
+ { 0, INetURLObject::FSysStyle(13), "file:///" },
+ { 0, INetURLObject::FSysStyle(14), "file:////." },
+ { 0, INetURLObject::FSysStyle(15), "file:///" },
+ { "//./", INetURLObject::FSysStyle(0), "" },
+ { 0, INetURLObject::FSysStyle(1), "file:///" },
+ { 0, INetURLObject::FSysStyle(2), "file:////./" },
+ { 0, INetURLObject::FSysStyle(3), "file:///" },
+ { 0, INetURLObject::FSysStyle(4), "file:///%2F%2F.%2F" },
+ { 0, INetURLObject::FSysStyle(5), "file:///" },
+ { 0, INetURLObject::FSysStyle(6), "file:////./" },
+ { 0, INetURLObject::FSysStyle(7), "file:///" },
+ { 0, INetURLObject::FSysStyle(8), "file:///%2F%2F.%2F" },
+ { 0, INetURLObject::FSysStyle(9), "file:///" },
+ { 0, INetURLObject::FSysStyle(10), "file:////./" },
+ { 0, INetURLObject::FSysStyle(11), "file:///" },
+ { 0, INetURLObject::FSysStyle(12), "file:///%2F%2F.%2F" },
+ { 0, INetURLObject::FSysStyle(13), "file:///" },
+ { 0, INetURLObject::FSysStyle(14), "file:////./" },
+ { 0, INetURLObject::FSysStyle(15), "file:///" },
+ { "//./a/b\\c:d", INetURLObject::FSysStyle(0), "" },
+ { 0, INetURLObject::FSysStyle(1), "file:///a/b%5Cc:d" },
+ { 0, INetURLObject::FSysStyle(2), "file:////./a/b%5Cc:d" },
+ { 0, INetURLObject::FSysStyle(3), "file:///a/b%5Cc:d" },
+ { 0, INetURLObject::FSysStyle(4), "file:///%2F%2F.%2Fa%2Fb/c:d" },
+ { 0, INetURLObject::FSysStyle(5), "file:///a/b%5Cc:d" },
+ { 0, INetURLObject::FSysStyle(6), "file:////./a/b%5Cc:d" },
+ { 0, INetURLObject::FSysStyle(7), "file:///a/b%5Cc:d" },
+ { 0, INetURLObject::FSysStyle(8), "file:///%2F%2F.%2Fa%2Fb%5Cc/d" },
+ { 0, INetURLObject::FSysStyle(9), "file:///a/b%5Cc:d" },
+ { 0, INetURLObject::FSysStyle(10), "file:////./a/b%5Cc:d" },
+ { 0, INetURLObject::FSysStyle(11), "file:///a/b%5Cc:d" },
+ { 0, INetURLObject::FSysStyle(12), "file:///%2F%2F.%2Fa%2Fb/c:d" },
+ { 0, INetURLObject::FSysStyle(13), "file:///a/b%5Cc:d" },
+ { 0, INetURLObject::FSysStyle(14), "file:////./a/b%5Cc:d" },
+ { 0, INetURLObject::FSysStyle(15), "file:///a/b%5Cc:d" } };
+ if (!testSetFSys(aTest, sizeof aTest / sizeof (SetFSysTest)))
+ bSuccess = false;
+ }
+
+/*
+ if (false)
+ {
+ bool bAbs = false;
+ INetURLObject aUrl1(INetURLObject().smartRel2Abs(L"/export/home/mba/Office/user/Basic/soffice.sbl", bAbs));
+
+ INetURLObject aUrl2a(L"/export/home/mba/Office/user/Basic/soffice.sbl", INET_PROT_FILE);
+
+ INetURLObject aUrl2b(L"file:///export/home/mba/Office/user/Basic/soffice.sbl", INET_PROT_FILE);
+
+ INetURLObject aUrl3a(L"/export/home/mba/Office/user/Basic/soffice.sbl", INetURLObject::FSYS_DETECT);
+
+ INetURLObject aUrl3b(L"file:///export/home/mba/Office/user/Basic/soffice.sbl", INetURLObject::FSYS_DETECT);
+ }
+*/
+
+ if (true)
+ {
+ INetURLObject aUrl1("http://host:1234/xy/~zw?xxx=yyy");
+ if (aUrl1.HasError())
+ {
+ printf("BAD http\n");
+ bSuccess = false;
+ }
+ INetURLObject aUrl2("vnd.sun.star.webdav://host:1234/xy/~zw?xxx=yyy");
+ if (aUrl2.HasError())
+ {
+ printf("BAD vnd.sun.star.webdav\n");
+ bSuccess = false;
+ }
+ }
+
+ if (true)
+ {
+ struct Test { char const * in; char const * out; };
+ static Test const aTest[]
+ = { { "vnd.sun.star.help://", "vnd.sun.star.help:///" },
+ { "vnd.sun.star.help:///", 0 },
+ { "vnd.sun.star.help://swriter",
+ "vnd.sun.star.help://swriter/" },
+ { "vnd.sun.star.help://swriter/", 0 },
+ { "vnd.sun.star.help://swriter/12345", 0 },
+ { "vnd.sun.star.help://swriter/1234X", 0 },
+ { "vnd.sun.star.help://swriter/?a=b?c=d", 0 },
+ { "vnd.sun.star.help://swriter/12345?a=b?c=d", 0 },
+ { "vnd.sun.star.help://swriter/12345???", 0 },
+ { "vnd.sun.star.help://swriter/#xxx", 0 },
+ { "vnd.sun.star.help://swriter/12345#xxx", 0 },
+ { "vnd.sun.star.help://swriter/1234X#xxx", 0 },
+ { "vnd.sun.star.help://swriter/?a=b?c=d#xxx", 0 },
+ { "vnd.sun.star.help://swriter/12345?a=b?c=d#xxx", 0 },
+ { "vnd.sun.star.help://swriter/12345???#xxx", 0 },
+ { "vnd.sun.star.help://swriter/start", 0 },
+ { "vnd.sun.star.help://swriter/s/t/a/r/t", 0 },
+ { "vnd.sun.star.help://swriter/a%2Fb%3Fc%2534d/e?f", 0 },
+ { "vnd.sun.star.help://swriter?foo",
+ "vnd.sun.star.help://swriter/?foo" },
+ { "vnd.sun.star.help://swriter/?foo", 0 } };
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS( aTest ); ++i)
+ {
+ INetURLObject aUrl(aTest[i].in);
+ if (aUrl.HasError())
+ printf("BAD %s\n", aTest[i].in);
+ else if (aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI).
+ equalsAscii(
+ aTest[i].out == 0 ? aTest[i].in : aTest[i].out)
+ != sal_True)
+ {
+ String sTest(aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI));
+ printf("BAD %s -> %s\n",
+ aTest[i].in,
+ ByteString(sTest, RTL_TEXTENCODING_ASCII_US).
+ GetBuffer());
+ }
+ }
+ }
+
+ if (true)
+ {
+ static sal_Char const * const aTest[]
+ = { /*TODO "vnd.sun.star.wfs://",*/
+ /*TODO "vnd.sun.star.wfs://LocalHost",*/
+ /*TODO "vnd.sun.star.wfs:///c|/xyz/",*/
+ /*TODO "vnd.sun.star.wfs://xxx/yyy?zzz",*/
+ "vnd.sun.star.wfs:///x/y/z",
+ "vnd.sun.star.generic:///x/y/z",
+ "vnd.sun.star.generic://host:34/x/y/z"
+ /*TODO "wfs://",*/
+ /*TODO "wfs://LocalHost",*/
+ /*TODO "wfs:///c|/xyz/",*/
+ /*TODO "wfs://xxx/yyy?zzz",*/
+ /*TODO "wfs:///x/y/z"*/ };
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS(aTest); ++i)
+ {
+ INetURLObject aUrl(aTest[i]);
+ if (aUrl.HasError())
+ printf("BAD %s\n", aTest[i]);
+ else
+ {
+ if (aUrl.GetProtocol() != INET_PROT_GENERIC) {
+ printf("BAD PROTOCOL %i -> %i\n",
+ aUrl.GetProtocol(),
+ INET_PROT_GENERIC);
+ }
+ if (aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI).
+ equalsAscii(aTest[i]) != sal_True)
+ {
+ String sTest(aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI));
+ printf("BAD %s -> %s\n",
+ aTest[i],
+ ByteString(sTest, RTL_TEXTENCODING_ASCII_US).GetBuffer());
+ }
+ }
+ }
+ }
+
+ if (true)
+ {
+ static sal_Char const * const aTest[]
+ = { /*TODO "vnd.sun.star.pkg:",*/
+ /*TODO "vnd.sun.star.pkg:/",*/
+ /*TODO "vnd.sun.star.pkg://abc",*/
+ /*TODO "vnd.sun.star.pkg://file:%2F%2F%2Fa:%2Fb%20c",*/
+ "vnd.sun.star.pkg://file:%2F%2F%2Fa:%2Fb%20c/",
+ "vnd.sun.star.pkg://file:%2F%2F%2Fa:%2Fb%20c/xx",
+ /*TODO "vnd.sun.star.pkg://file:%2F%2F%2Fa:%2Fb%20c/xx;yy",*/
+ "vnd.sun.star.pkg://file:%2F%2F%2Fa:%2Fb%20c/xx//yy" };
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS(aTest); ++i)
+ {
+ INetURLObject aUrl(aTest[i]);
+ if (aUrl.HasError())
+ printf("BAD %s\n", aTest[i]);
+ else if (aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI).
+ equalsAscii(aTest[i]) != sal_True)
+ {
+ String sTest(aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI));
+ printf("BAD %s -> %s\n",
+ aTest[i],
+ ByteString(sTest, RTL_TEXTENCODING_ASCII_US).GetBuffer());
+ }
+ }
+ }
+
+ if (true)
+ {
+ static sal_Char const * const aTest[]
+ = { /*TODO "vnd.sun.star.cmd:",*/
+ /*TODO "vnd.sun.star.cmd:/",*/
+ "vnd.sun.star.cmd:logout",
+ "vnd.sun.star.cmd:log/out",
+ /*TODO "vnd.sun.star.cmd:[logout]",*/
+ "vnd.sun.star.cmd:log[out]" };
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS( aTest ); ++i)
+ {
+ INetURLObject aUrl(aTest[i]);
+ if (aUrl.HasError())
+ printf("BAD %s\n", aTest[i]);
+ else if (aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI).
+ equalsAscii(aTest[i]) != sal_True)
+ {
+ String sTest(aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI));
+ printf("BAD %s -> %s\n",
+ aTest[i],
+ ByteString(sTest, RTL_TEXTENCODING_ASCII_US).GetBuffer());
+ }
+ }
+ }
+
+ if (true)
+ {
+ rtl::OUString
+ aParameters(rtl::OUString::createFromAscii("; CharSet=UTF-8 ; Blubber=Blob"));
+ sal_Unicode const * pBegin = aParameters.getStr();
+ sal_Unicode const * pEnd = pBegin + aParameters.getLength();
+ INetContentTypeParameterList aList;
+ if (INetMIME::scanParameters(pBegin, pEnd, &aList) == pEnd)
+ {
+ ULONG nCount = aList.Count();
+ for (ULONG i = 0; i < nCount; ++i)
+ {
+ INetContentTypeParameter const * p = aList.GetObject(i);
+ if (p)
+ {
+/*
+ printf("attribute: '%s'\n charset: '%s'\n language: '%s'\n value: '%s'\n converted: %s\n",
+ p->m_sAttribute.GetBuffer(),
+ p->m_sCharset.GetBuffer(),
+ p->m_sLanguage.GetBuffer(),
+ rtl::OUStringToOString(p->m_sValue,RTL_TEXTENCODING_UTF8).getStr(),
+ p->m_bConverted ? "true" : "false");
+*/
+ }
+ else
+ printf("BAD INetContentTypeParameter\n");
+ }
+ }
+ else
+ {
+ printf("BAD INetMIME::scanParameters()\n");
+ bSuccess = false;
+ }
+ }
+
+ if (true)
+ {
+ {
+ INetURLObject aObj;
+ aObj.setFSysPath(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a:")),
+ INetURLObject::FSYS_DETECT);
+ if (!rtl::OUString(aObj.GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("file:///a:")))
+ {
+ printf("BAD setFSysPath(\"a:\")\n");
+ bSuccess = false;
+ }
+ }
+ {
+ INetURLObject aObj;
+ aObj.setFSysPath(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "a:/")),
+ INetURLObject::FSYS_DETECT);
+ if (!rtl::OUString(aObj.GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("file:///a:/")))
+ {
+ printf("BAD setFSysPath(\"a:/\")\n");
+ bSuccess = false;
+ }
+ }
+ {
+ INetURLObject aObj;
+ aObj.setFSysPath(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "a:\\")),
+ INetURLObject::FSYS_DETECT);
+ if (!rtl::OUString(aObj.GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("file:///a:/")))
+ {
+ printf("BAD setFSysPath(\"a:\\\")\n");
+ bSuccess = false;
+ }
+ }
+
+ if (!rtl::OUString(INetURLObject("file:///a:").
+ getFSysPath(INetURLObject::FSYS_DETECT)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("a:")))
+ {
+ printf("BAD getFSysPath(\"file:///a:\")\n");
+ bSuccess = false;
+ }
+ if (!rtl::OUString(INetURLObject("file:///a:/").
+ getFSysPath(INetURLObject::FSYS_DETECT)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("a:\\")))
+ {
+ printf("BAD getFSysPath(\"file:///a:/\")\n");
+ bSuccess = false;
+ }
+
+ {
+ bool bWasAbsolute;
+ if (!rtl::OUString(INetURLObject(rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "file:///"))).
+ smartRel2Abs(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "a:")),
+ bWasAbsolute).
+ GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("file:///a:"))
+ || !bWasAbsolute)
+ {
+ printf("BAD smartRel2Abs(\"a:\")\n");
+ bSuccess = false;
+ }
+ }
+ {
+ bool bWasAbsolute;
+ if (!rtl::OUString(INetURLObject(rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "file:///"))).
+ smartRel2Abs(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "a:/")),
+ bWasAbsolute).
+ GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("file:///a:/"))
+ || !bWasAbsolute)
+ {
+ printf("BAD smartRel2Abs(\"a:/\")\n");
+ bSuccess = false;
+ }
+ }
+ {
+ bool bWasAbsolute;
+ if (!rtl::OUString(INetURLObject(rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "file:///"))).
+ smartRel2Abs(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "a:\\")),
+ bWasAbsolute).
+ GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("file:///a:/"))
+ || !bWasAbsolute)
+ {
+ printf("BAD smartRel2Abs(\"a:\\\")\n");
+ bSuccess = false;
+ }
+ }
+ {
+ bool bWasAbsolute;
+ if (!rtl::OUString(INetURLObject(rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "file:///"))).
+ smartRel2Abs(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "generic:")),
+ bWasAbsolute).
+ GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("file:///generic:"))
+ || bWasAbsolute)
+ {
+ printf("BAD smartRel2Abs(\"generic:\")\n");
+ bSuccess = false;
+ }
+ }
+ {
+ bool bWasAbsolute;
+ if (!rtl::OUString(INetURLObject(rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "file:///"))).
+ smartRel2Abs(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "generic:#fragment")),
+ bWasAbsolute).
+ GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "file:///generic:#fragment"))
+ || bWasAbsolute)
+ {
+ printf("BAD smartRel2Abs(\"generic:#fragment\")\n");
+ bSuccess = false;
+ }
+ }
+ {
+ bool bWasAbsolute;
+ if (!rtl::OUString(INetURLObject(rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "file:///"))).
+ smartRel2Abs(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "generic:something")),
+ bWasAbsolute).
+ GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("generic:something"))
+ || !bWasAbsolute)
+ {
+ printf("BAD smartRel2Abs(\"generic:something\")\n");
+ bSuccess = false;
+ }
+ }
+ {
+ bool bWasAbsolute;
+ if (!rtl::OUString(INetURLObject(rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "file:///"))).
+ smartRel2Abs(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "\\\\unc_host\\path")),
+ bWasAbsolute).
+ GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("file://unc_host/path"))
+ || !bWasAbsolute)
+ {
+ printf("BAD smartRel2Abs(\"\\\\unc_host\\path\")\n");
+ bSuccess = false;
+ }
+ }
+ }
+
+ if (true)
+ {
+/*TODO
+ {
+ INetURLObject aObj(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("http://xxx/yyy?abc/def~")));
+ if (!rtl::OUString(aObj.GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("http://xxx/yyy?abc%2Fdef%7E")))
+ {
+ printf("BAD http query 1\n");
+ bSuccess = false;
+ }
+ }
+*/
+ {
+ INetURLObject aObj(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("https://xxx/yyy?abc/def~")));
+ if (!rtl::OUString(aObj.GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("https://xxx/yyy?abc/def~")))
+ {
+ printf("BAD https query 1\n");
+ bSuccess = false;
+ }
+ }
+/*TODO
+ {
+ INetURLObject aObj(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("http://xxx/yyy")));
+ aObj.SetParam("abc/def~");
+ if (!rtl::OUString(aObj.GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("http://xxx/yyy?abc%2Fdef%7E")))
+ {
+ printf("BAD http query 2\n");
+ bSuccess = false;
+ }
+ }
+*/
+ {
+ INetURLObject aObj(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("https://xxx/yyy")));
+ aObj.SetParam("abc/def~");
+ if (!rtl::OUString(aObj.GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("https://xxx/yyy?abc/def~")))
+ {
+ printf("BAD https query 2\n");
+ bSuccess = false;
+ }
+ }
+ }
+
+ if (true)
+ {
+ if (INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.hier:"))).HasError())
+ {
+ printf("BAD vnd.sun.star.hier test 1\n");
+ bSuccess = false;
+ }
+ if (!INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.hier://"))).HasError())
+ {
+ printf("BAD vnd.sun.star.hier test 2\n");
+ bSuccess = false;
+ }
+ if (!INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.hier:///"))).HasError())
+ {
+ printf("BAD vnd.sun.star.hier test 3\n");
+ bSuccess = false;
+ }
+ if (!INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.hier:///abc"))).HasError())
+ {
+ printf("BAD vnd.sun.star.hier test 4\n");
+ bSuccess = false;
+ }
+ if (INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.hier://abc"))).HasError())
+ {
+ printf("BAD vnd.sun.star.hier test 5\n");
+ bSuccess = false;
+ }
+ if (INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.hier://abc/def"))).HasError())
+ {
+ printf("BAD vnd.sun.star.hier test 6\n");
+ bSuccess = false;
+ }
+ }
+
+ if (false)
+ {
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file:///"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file:///a"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file:///a/def/"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file:///ab/def/"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file:///abc/def/"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file:///a/def"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file:///ab/def"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file:///abc/def"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file:///abcdef/d"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file:///abcdef/de"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file:///abcdef/def"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file://some.host/"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file://some.host/a"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file://some.host/a/def/"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file://some.host/ab/def/"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file://some.host/abc/def/"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file://some.host/a/def"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file://some.host/ab/def"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file://some.host/abc/def"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file://some.host/abcdef/d"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file://some.host/abcdef/de"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file://some.host/abcdef/def"))));
+ abbreviate(INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "http://foo/aa/bb//cc/d/eee////ff/ggggggg/hhhhhh/iii/j/"
+ "kkkkkkkkkkkkk/ll/mm/nn/oo/p"))));
+ }
+
+ if (true)
+ {
+ {
+ rtl::OUString
+ aBase(RTL_CONSTASCII_USTRINGPARAM("file:///a:/b/c"));
+ rtl::OUString aAbs(RTL_CONSTASCII_USTRINGPARAM("file:///a:/d/e"));
+ rtl::OUString aRel(INetURLObject::GetRelURL(aBase, aAbs));
+ if (!aRel.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("../d/e")))
+ {
+ printf("BAD GetRelURL(%s, %s) = %s\n",
+ rtl::OUStringToOString(aBase, RTL_TEXTENCODING_UTF8).
+ getStr(),
+ rtl::OUStringToOString(aAbs, RTL_TEXTENCODING_UTF8).
+ getStr(),
+ rtl::OUStringToOString(aRel, RTL_TEXTENCODING_UTF8).
+ getStr());
+ bSuccess = false;
+ }
+ }
+ {
+ rtl::OUString
+ aBase(RTL_CONSTASCII_USTRINGPARAM("file:///a:/b/c"));
+ rtl::OUString aAbs(RTL_CONSTASCII_USTRINGPARAM("file:///d:/e/f"));
+ rtl::OUString aRel(INetURLObject::GetRelURL(aBase, aAbs));
+ if (aRel != aAbs)
+ {
+ printf("BAD GetRelURL(%s, %s) = %s\n",
+ rtl::OUStringToOString(aBase, RTL_TEXTENCODING_UTF8).
+ getStr(),
+ rtl::OUStringToOString(aAbs, RTL_TEXTENCODING_UTF8).
+ getStr(),
+ rtl::OUStringToOString(aRel, RTL_TEXTENCODING_UTF8).
+ getStr());
+ bSuccess = false;
+ }
+ }
+ {
+ rtl::OUString
+ aBase(RTL_CONSTASCII_USTRINGPARAM("file:///a:/b/c"));
+ rtl::OUString aAbs(RTL_CONSTASCII_USTRINGPARAM("file:///d/e/f"));
+ rtl::OUString aRel(INetURLObject::GetRelURL(aBase, aAbs));
+ if (!aRel.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("../../d/e/f")))
+ {
+ printf("BAD GetRelURL(%s, %s) = %s\n",
+ rtl::OUStringToOString(aBase, RTL_TEXTENCODING_UTF8).
+ getStr(),
+ rtl::OUStringToOString(aAbs, RTL_TEXTENCODING_UTF8).
+ getStr(),
+ rtl::OUStringToOString(aRel, RTL_TEXTENCODING_UTF8).
+ getStr());
+ bSuccess = false;
+ }
+ }
+ {
+ rtl::OUString
+ aBase(RTL_CONSTASCII_USTRINGPARAM("file:///a:/b/c"));
+ rtl::OUString aAbs(RTL_CONSTASCII_USTRINGPARAM("file:///d:/e/f"));
+ rtl::OUString
+ aRel(INetURLObject::GetRelURL(aBase,
+ aAbs,
+ INetURLObject::WAS_ENCODED,
+ INetURLObject::DECODE_TO_IURI,
+ RTL_TEXTENCODING_UTF8,
+ INetURLObject::FSYS_UNX));
+ if (!aRel.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
+ "../../d:/e/f")))
+ {
+ printf("BAD GetRelURL(%s, %s) = %s\n",
+ rtl::OUStringToOString(aBase, RTL_TEXTENCODING_UTF8).
+ getStr(),
+ rtl::OUStringToOString(aAbs, RTL_TEXTENCODING_UTF8).
+ getStr(),
+ rtl::OUStringToOString(aRel, RTL_TEXTENCODING_UTF8).
+ getStr());
+ bSuccess = false;
+ }
+ }
+/*TODO
+ {
+ rtl::OUString
+ aBase(RTL_CONSTASCII_USTRINGPARAM("file:///test.html"));
+ rtl::OUString
+ aAbs(RTL_CONSTASCII_USTRINGPARAM("/images/myimage.gif"));
+ rtl::OUString aRel(INetURLObject::GetRelURL(aBase, aAbs));
+ if (aRel != aAbs)
+ {
+ printf("BAD GetRelURL(%s, %s) = %s\n",
+ rtl::OUStringToOString(aBase, RTL_TEXTENCODING_UTF8).
+ getStr(),
+ rtl::OUStringToOString(aAbs, RTL_TEXTENCODING_UTF8).
+ getStr(),
+ rtl::OUStringToOString(aRel, RTL_TEXTENCODING_UTF8).
+ getStr());
+ bSuccess = false;
+ }
+ }
+*/
+ }
+
+ if (true)
+ {
+ INetURLObject aUrl(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file://host/dir/file")));
+ rtl::OUString aPath;
+ aPath = aUrl.getFSysPath(INetURLObject::FSYS_DETECT);
+ if (!aPath.
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("//host/dir/file")))
+ {
+ printf("BAD getFSysPath(VOS|UNX|DOS|MAC) = %s\n",
+ rtl::OUStringToOString(aPath, RTL_TEXTENCODING_UTF8).
+ getStr());
+ bSuccess = false;
+ }
+ aPath = aUrl.getFSysPath(INetURLObject::FSysStyle(
+ INetURLObject::FSYS_UNX
+ | INetURLObject::FSYS_DOS
+ | INetURLObject::FSYS_MAC));
+ if (!aPath.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
+ "\\\\host\\dir\\file")))
+ {
+ printf("BAD getFSysPath(UNX|DOS|MAC) = %s\n",
+ rtl::OUStringToOString(aPath, RTL_TEXTENCODING_UTF8).
+ getStr());
+ bSuccess = false;
+ }
+ aPath = aUrl.getFSysPath(INetURLObject::FSysStyle(
+ INetURLObject::FSYS_UNX
+ | INetURLObject::FSYS_MAC));
+ if (aPath.getLength() != 0)
+ {
+ printf("BAD getFSysPath(UNX|MAC) = %s\n",
+ rtl::OUStringToOString(aPath, RTL_TEXTENCODING_UTF8).
+ getStr());
+ bSuccess = false;
+ }
+ }
+
+ if (true)
+ {
+ {
+ INetURLObject aUrl1(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.odma:")));
+ rtl::OUString aUrl2(aUrl1.GetMainURL(
+ INetURLObject::DECODE_TO_IURI));
+ if (!aUrl2.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.odma:/")))
+ {
+ printf("BAD vnd.sun.star.odma: != %s\n",
+ rtl::OUStringToOString(aUrl2, RTL_TEXTENCODING_UTF8).
+ getStr());
+ bSuccess = false;
+ }
+ }
+ {
+ INetURLObject aUrl1(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.odma:/")));
+ rtl::OUString aUrl2(aUrl1.GetMainURL(
+ INetURLObject::DECODE_TO_IURI));
+ if (!aUrl2.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.odma:/")))
+ {
+ printf("BAD vnd.sun.star.odma:/ != %s\n",
+ rtl::OUStringToOString(aUrl2, RTL_TEXTENCODING_UTF8).
+ getStr());
+ bSuccess = false;
+ }
+ }
+ {
+ INetURLObject aUrl1(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.odma:/bla/bla")));
+ rtl::OUString aUrl2(aUrl1.GetMainURL(
+ INetURLObject::DECODE_TO_IURI));
+ if (!aUrl2.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.odma:/bla%2Fbla")))
+ {
+ printf("BAD vnd.sun.star.odma:/bla/bla != %s\n",
+ rtl::OUStringToOString(aUrl2, RTL_TEXTENCODING_UTF8).
+ getStr());
+ bSuccess = false;
+ }
+ }
+ }
+
+ if (true)
+ {
+ struct Test
+ {
+ char const * m_pInput;
+ char const * m_pOutput;
+ };
+ static Test const aTest[]
+ = { { "file:///abc", "file:///abc" },
+ { "file://localhost/abc", "file:///abc" },
+ { "file://LocalHost/abc", "file:///abc" },
+ { "file://LOCALHOST/abc", "file:///abc" },
+ { "file://127.0.0.1/abc", "file://127.0.0.1/abc" },
+ { "file://xxx.yyy-zzz/abc", "file://xxx.yyy-zzz/abc" },
+ { "file://xxx_yyy/abc", "file://xxx_yyy/abc" },
+ { "file://!%23$%&'()-.@^_{}~/abc",
+ "file://!%23$%25&'()-.@%5E_%7B%7D~/abc" },
+ { "file://d:\\dir1\\file1", 0 },
+ { "http://as@alaska:8000/test/test.sxw", 0 },
+ { "telnet:", 0 },
+ { "telnet://", 0 },
+ { "telnet://ab:cd@ef:", "telnet://ab:cd@ef:/" },
+ { "telnet://ab:cd@ef:123", "telnet://ab:cd@ef:123/" },
+ { "TELNET://abc.def.ghi/", "telnet://abc.def.ghi/" },
+ { "telnet://abc.def.ghi/jkl", 0 },
+ { "telnet://abc.def.ghi?jkl", 0 },
+ { "telnet://abc.def.ghi/?jkl", 0 },
+ { "file:", 0 },
+ { "file:/", "file:///" },
+ { "file:/abc", "file:///abc" },
+ { "file:/abc/def", "file:///abc/def" },
+ { "file:/localhost", "file:///localhost" },
+ { "file://", "file:///" },
+ { "file:///", "file:///" },
+ { "http:", 0 },
+ { "http:/abc", 0 },
+ { "news:", 0 },
+ { "news:*", "news:*" },
+ { "news:**", 0 },
+ { "news:%2A", 0 },
+ { "news:a", "news:a" },
+ { "news:A", "news:A" },
+ { "news:+-._", 0 },
+ { "news:A0+-._", "news:A0+-._" },
+ { "news:0", 0 },
+ { "news:AB,", 0 },
+ { "news:abc@def", "news:abc@def" },
+ { "news:abc@def:33", 0 },
+ { "news:abc@123.456.789.0", "news:abc@123.456.789.0" },
+ { "news:abc@def.", "news:abc@def." },
+ { "news:abc@def.ghi", "news:abc@def.ghi" },
+ { "news:abc@def.-ghi", 0 },
+ { "news:abc@def.ghi@", 0 },
+ { "news:%21%22%23@def", "news:%21%22%23@def" },
+ { "news:!%22%23@def", "news:!%22%23@def" },
+ { "news: @def", "news:%20@def" },
+ { "vnd.sun.star.tdoc:", 0 },
+ { "vnd.sun.star.tdoc:a/b/c", 0 },
+ { "vnd.sun.star.tdoc:/", "vnd.sun.star.tdoc:/" },
+ { "vnd.sun.star.tdoc:/a;b/", "vnd.sun.star.tdoc:/a%3Bb/" },
+ { "vnd.sun.star.tdoc:/a?b", "vnd.sun.star.tdoc:/a%3Fb" },
+ { "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/x",
+ "http://[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:80/x" },
+ { "http://[1080:0:0:0:8:800:200C:417A]/index.html",
+ "http://[1080:0:0:0:8:800:200c:417a]/index.html" },
+ { "http://[3ffe:2a00:100:7031::1]",
+ "http://[3ffe:2a00:100:7031::1]/" },
+ { "http://[1080::8:800:200c:417a]/foo",
+ "http://[1080::8:800:200c:417a]/foo" },
+ { "http://[::192.9.5.5]/ipng", "http://[::192.9.5.5]/ipng" },
+ { "http://[:::192.9.5.5]/ipng", "http://[:::192.9.5.5]/ipng" },
+ { "http://[::FFFF:129.144.52.38]:80/index.html",
+ "http://[::ffff:129.144.52.38]:80/index.html" },
+ { "http://[2010:836B:4179::836B:4179]",
+ "http://[2010:836b:4179::836b:4179]/" },
+ { "http://[::1]", "http://[::1]/" },
+ { "http://[0:0:0:0:0:0:13.1.68.3]/",
+ "http://[0:0:0:0:0:0:13.1.68.3]/" },
+ { "http://[0:0:0:0:0:FFFF:129.144.52.38]/",
+ "http://[0:0:0:0:0:ffff:129.144.52.38]/" },
+ { "smb://", "smb:///" },
+ { "smb://foo", "smb://foo/" },
+ { "smb://x;foo:bar@baz.xyz:12345/ab?cd",
+ "smb://x;foo:bar@baz.xyz:12345/ab?cd" } };
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS( aTest ); ++i)
+ {
+ INetURLObject aUrl(aTest[i].m_pInput);
+ if (aTest[i].m_pOutput == 0
+ ? !aUrl.HasError()
+ : (aUrl.HasError()
+ || (aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI).
+ equalsAscii(aTest[i].m_pOutput)
+ != sal_True)))
+ {
+ String sTest(aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI));
+ printf("BAD %s -> %s != %s\n",
+ aTest[i].m_pInput,
+ aUrl.HasError() ? "<none>"
+ : ByteString(sTest, RTL_TEXTENCODING_ASCII_US).GetBuffer(),
+ aTest[i].m_pOutput == 0 ? "<none>" : aTest[i].m_pOutput);
+ }
+ }
+ }
+
+ if (true)
+ {
+ struct Test
+ {
+ char const * m_pInput;
+ char const * m_pOutput;
+ };
+ static Test const aTest[]
+ = { { "file://d:\\dir1\\file1", "file:///d:/dir1/file1" },
+ { "http://as@alaska:8000/test/test.sxw", 0 } };
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS( aTest ); ++i)
+ {
+ INetURLObject aUrl = INetURLObject(
+ String(aTest[i].m_pInput, RTL_TEXTENCODING_UTF8),
+ INET_PROT_HTTP);
+ if (aTest[i].m_pOutput == 0
+ ? !aUrl.HasError()
+ : (aUrl.HasError()
+ || (aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI).
+ equalsAscii(aTest[i].m_pOutput)
+ != sal_True)))
+ {
+ String sTest(aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI));
+ printf("BAD %s -> %s != %s\n",
+ aTest[i].m_pInput,
+ aUrl.HasError() ? "<none>"
+ : ByteString(sTest, RTL_TEXTENCODING_ASCII_US).GetBuffer(),
+ aTest[i].m_pOutput == 0 ? "<none>" : aTest[i].m_pOutput);
+ }
+ }
+ }
+
+ if (true)
+ {
+ INetURLObject aUrl;
+ rtl::OUString aUser;
+ aUrl = INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "ftp://test")));
+ aUser = aUrl.GetUser();
+ if (aUser.getLength() != 0)
+ printf(
+ "BAD <ftp://test> user: \"%s\" != \"\"",
+ rtl::OUStringToOString(aUser, RTL_TEXTENCODING_UTF8).getStr());
+ aUrl = INetURLObject(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "ftp://user@test")));
+ aUser = aUrl.GetUser();
+ if (!aUser.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("user")))
+ printf(
+ "BAD <ftp://user@test> user: \"%s\" != \"user\"",
+ rtl::OUStringToOString(aUser, RTL_TEXTENCODING_UTF8).getStr());
+ }
+
+ if (true)
+ {
+ INetURLObject aUrl;
+
+ aUrl = INetURLObject("vnd.sun.star.pkg://foo.bar/a/b/c?abc/def?");
+ if (aUrl.GetProtocol() != INET_PROT_VND_SUN_STAR_PKG)
+ printf("BAD <vnd.sun.star.pkg://foo.bar/a/b/c?abc/def?>:"
+ " scheme = %d\n",
+ static_cast< int >(aUrl.GetProtocol()));
+ else
+ {
+ if (!rtl::OUString(aUrl.GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
+ "vnd.sun.star.pkg://foo.bar/a/b/c?abc/def?")))
+ printf("BAD <vnd.sun.star.pkg://foo.bar/a/b/c?abc/def?>:"
+ " URL = %s\n",
+ rtl::OUStringToOString(
+ aUrl.GetMainURL(INetURLObject::NO_DECODE),
+ RTL_TEXTENCODING_UTF8).getStr());
+ if (!rtl::OUString(aUrl.GetParam(INetURLObject::NO_DECODE)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("abc/def?")))
+ printf("BAD <vnd.sun.star.pkg://foo.bar/a/b/c?abc/def?>:"
+ " query = %s\n",
+ rtl::OUStringToOString(
+ aUrl.GetParam(INetURLObject::NO_DECODE),
+ RTL_TEXTENCODING_UTF8).getStr());
+ }
+
+ aUrl = INetURLObject("vnd.sun.star.pkg://foo.bar/a/b/c%3Fabc/def%3F");
+ if (aUrl.GetProtocol() != INET_PROT_VND_SUN_STAR_PKG)
+ printf("BAD <vnd.sun.star.pkg://foo.bar/a/b/c%%3Fabc/def%%3F>:"
+ " scheme = %d\n",
+ static_cast< int >(aUrl.GetProtocol()));
+ else
+ {
+ if (!rtl::OUString(aUrl.GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "vnd.sun.star.pkg://foo.bar/a/b/c%3Fabc/def%3F")))
+ printf("BAD <vnd.sun.star.pkg://foo.bar/a/b/c?abc/def?>:"
+ " URL = %s\n",
+ rtl::OUStringToOString(
+ aUrl.GetMainURL(INetURLObject::NO_DECODE),
+ RTL_TEXTENCODING_UTF8).getStr());
+ if (!rtl::OUString(aUrl.GetParam(INetURLObject::NO_DECODE)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("")))
+ printf("BAD <vnd.sun.star.pkg://foo.bar/a/b/c%%3Fabc/def%%3F>:"
+ " query = %s\n",
+ rtl::OUStringToOString(
+ aUrl.GetParam(INetURLObject::NO_DECODE),
+ RTL_TEXTENCODING_UTF8).getStr());
+ }
+ }
+
+ if (true)
+ {
+ struct Test
+ {
+ INetProtocol eScheme;
+ char const * pPath;
+ char const * pUri;
+ };
+ static Test const aTest[]
+ = { { INET_PROT_FILE, "", "file:///" },
+ { INET_PROT_FILE, "/", "file:///" },
+ { INET_PROT_FILE, "abc", 0 },
+ { INET_PROT_FILE, "/abc/", "file:///abc/" },
+ { INET_PROT_NEWS, "", 0 },
+ { INET_PROT_NEWS, "*", "news:*" },
+ { INET_PROT_NEWS, "**", 0 },
+ { INET_PROT_NEWS, "%2A", 0 },
+ { INET_PROT_NEWS, "a", "news:a" },
+ { INET_PROT_NEWS, "A", "news:A" },
+ { INET_PROT_NEWS, "+-._", 0 },
+ { INET_PROT_NEWS, "A0+-._", "news:A0+-._" },
+ { INET_PROT_NEWS, "0", 0 },
+ { INET_PROT_NEWS, "AB,", 0 },
+ { INET_PROT_NEWS, "abc@def", "news:abc@def" },
+ { INET_PROT_NEWS, "abc@def:33", 0 },
+ { INET_PROT_NEWS, "abc@123.456.789.0",
+ "news:abc@123.456.789.0" },
+ { INET_PROT_NEWS, "abc@def.", "news:abc@def." },
+ { INET_PROT_NEWS, "abc@def.ghi", "news:abc@def.ghi" },
+ { INET_PROT_NEWS, "abc@def.-ghi", 0 },
+ { INET_PROT_NEWS, "abc@def.ghi@", 0 },
+ { INET_PROT_NEWS, "!\"#@def", "news:!%22%23@def" },
+ { INET_PROT_NEWS, " @def", "news:%20@def" } };
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS( aTest ); ++i)
+ {
+ INetURLObject aUri;
+ bool bOk = aUri.ConcatData(aTest[i].eScheme, String(), String(),
+ String(), 0,
+ String(aTest[i].pPath,
+ RTL_TEXTENCODING_ASCII_US),
+ INetURLObject::ENCODE_ALL);
+ if (bOk == aUri.HasError())
+ printf(
+ "BAD ConcatData(%d, ..., %s) = %d, HasError() = %d\n",
+ static_cast< int >(aTest[i].eScheme), aTest[i].pPath,
+ static_cast< int >(bOk),
+ static_cast< int >(aUri.HasError()));
+ else if (aTest[i].pUri == 0
+ ? !aUri.HasError()
+ : (aUri.HasError()
+ || (aUri.GetMainURL(INetURLObject::DECODE_TO_IURI).
+ equalsAscii(aTest[i].pUri)
+ != sal_True)))
+ {
+ String sTest(aUri.GetMainURL(INetURLObject::DECODE_TO_IURI));
+ printf("BAD ConcatData(%d, ..., %s) -> %s != %s\n",
+ static_cast< int >(aTest[i].eScheme), aTest[i].pPath,
+ aUri.HasError() ? "<none>"
+ : ByteString(sTest, RTL_TEXTENCODING_ASCII_US).GetBuffer(),
+ aTest[i].pUri == 0 ? "<none>" : aTest[i].pUri);
+ }
+ }
+ }
+
+ if (true)
+ {
+ // #i13760#
+
+ // Test for unrelated URLs.
+ const rtl::OUString aBaseURL(RTL_CONSTASCII_USTRINGPARAM(
+ "http://www.openoffice.org"));
+ rtl::OUString aRelURL (RTL_CONSTASCII_USTRINGPARAM(
+ "http://www.sun.com"));
+
+ rtl::OUString aRelURLToTest(
+ INetURLObject::GetRelURL(aBaseURL, aRelURL));
+
+ if (INetURLObject(aRelURLToTest) != INetURLObject(aRelURL))
+ printf("BAD GetRelURL(%s, %s), ret = %s\n",
+ ByteString(aBaseURL.getStr(),
+ RTL_TEXTENCODING_ASCII_US).GetBuffer(),
+ ByteString(aRelURL.getStr(),
+ RTL_TEXTENCODING_ASCII_US).GetBuffer(),
+ ByteString(aRelURLToTest.getStr(),
+ RTL_TEXTENCODING_ASCII_US).GetBuffer());
+
+ // Test for related URLs.
+ aRelURL = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "http://www.openoffice.org/api/test.html"));
+ aRelURLToTest = rtl::OUString(
+ INetURLObject::GetRelURL(aBaseURL, aRelURL));
+
+ if (!aRelURLToTest.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("api/test.html")))
+ printf("BAD GetRelURL(%s, %s), ret = %s\n",
+ ByteString(aBaseURL.getStr(),
+ RTL_TEXTENCODING_ASCII_US).GetBuffer(),
+ ByteString(aRelURL.getStr(),
+ RTL_TEXTENCODING_ASCII_US).GetBuffer(),
+ ByteString(aRelURLToTest.getStr(),
+ RTL_TEXTENCODING_ASCII_US).GetBuffer());
+ }
+
+ if (true) { // #112130#
+ INetURLObject url1(rtl::OUString::createFromAscii(".uno:abc%3Fdef"));
+ if (url1.GetProtocol() != INET_PROT_UNO) {
+ printf("BAD .uno:abc%%3Fdef\n");
+ bSuccess = false;
+ }
+ if (!rtl::OUString(url1.GetURLPath(INetURLObject::NO_DECODE)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("abc%3Fdef"))) {
+ printf(
+ "BAD GetURLPath(.uno:abc%%3Fdef): %s\n",
+ rtl::OUStringToOString(
+ url1.GetURLPath(INetURLObject::NO_DECODE),
+ osl_getThreadTextEncoding()).getStr());
+ bSuccess = false;
+ }
+ if (url1.HasParam()) {
+ printf("BAD HasParam(.uno:abc%%3Fdef)\n");
+ bSuccess = false;
+ }
+ INetURLObject url2(rtl::OUString::createFromAscii(".uno:abc?def?ghi"));
+ if (url2.GetProtocol() != INET_PROT_UNO) {
+ printf("BAD .uno:abc?def?ghi\n");
+ bSuccess = false;
+ }
+ if (!rtl::OUString(url2.GetURLPath(INetURLObject::NO_DECODE)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("abc"))) {
+ printf(
+ "BAD GetURLPath(.uno:abc?def?ghi): %s\n",
+ rtl::OUStringToOString(
+ url2.GetURLPath(INetURLObject::NO_DECODE),
+ osl_getThreadTextEncoding()).getStr());
+ bSuccess = false;
+ }
+ if (!url2.HasParam()) {
+ printf("BAD HasParam(.uno:abc?def?ghi)\n");
+ bSuccess = false;
+ }
+ if (!rtl::OUString(url2.GetParam(INetURLObject::NO_DECODE)).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("def?ghi"))) {
+ printf(
+ "BAD GetURLPath(.uno:abc?def?ghi): %s\n",
+ rtl::OUStringToOString(
+ url2.GetParam(INetURLObject::NO_DECODE),
+ osl_getThreadTextEncoding()).getStr());
+ bSuccess = false;
+ }
+ }
+
+ if (true) { // #116269#
+ rtl::OUString url;
+ INetURLObject urlobj;
+
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("A-b.3:/%2f?x#y"));
+ urlobj = INetURLObject(url);
+ bSuccess &= assertEqual(url, INET_PROT_GENERIC, urlobj.GetProtocol());
+ bSuccess &= assertEqual(
+ url, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a-b.3:/%2F?x#y")),
+ rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
+ bSuccess &= assertEqual(url, false, urlobj.HasUserData());
+ bSuccess &= assertEqual(url, false, urlobj.hasPassword());
+ bSuccess &= assertEqual(url, false, urlobj.HasPort());
+ bSuccess &= assertEqual(
+ url, rtl::OUString(), rtl::OUString(urlobj.GetHost()));
+ bSuccess &= assertEqual(
+ url, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/%2F?x")),
+ rtl::OUString(urlobj.GetURLPath()));
+ bSuccess &= assertEqual(url, false, urlobj.HasParam());
+ bSuccess &= assertEqual(url, true, urlobj.HasMark());
+ bSuccess &= assertEqual(
+ url, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("y")),
+ rtl::OUString(urlobj.GetMark()));
+
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foo:"));
+ urlobj = INetURLObject(url);
+ bSuccess &= assertEqual(url, true, urlobj.HasError());
+
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foo:#"));
+ urlobj = INetURLObject(url);
+ bSuccess &= assertEqual(url, true, urlobj.HasError());
+
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foo:/"));
+ urlobj = INetURLObject(url);
+ bSuccess &= assertEqual(url, INET_PROT_GENERIC, urlobj.GetProtocol());
+ bSuccess &= assertEqual(
+ url, url,
+ rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
+
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".foo:/"));
+ urlobj = INetURLObject(url);
+ bSuccess &= assertEqual(url, true, urlobj.HasError());
+
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("C:\\bla"));
+ urlobj = INetURLObject(url);
+ bSuccess &= assertEqual(url, true, urlobj.HasError());
+
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("C:\\bla"));
+ urlobj = INetURLObject(url, INET_PROT_FILE);
+ bSuccess &= assertEqual(url, INET_PROT_FILE, urlobj.GetProtocol());
+ bSuccess &= assertEqual(
+ url, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file:///C:/bla")),
+ rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
+
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LPR:\\bla"));
+ urlobj = INetURLObject(url);
+ bSuccess &= assertEqual(url, INET_PROT_GENERIC, urlobj.GetProtocol());
+ bSuccess &= assertEqual(
+ url, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("lpr:%5Cbla")),
+ rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
+
+ url = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("private:factory/swriter"));
+ urlobj = INetURLObject(url);
+ bSuccess &= assertEqual(
+ url, INET_PROT_PRIV_SOFFICE, urlobj.GetProtocol());
+ bSuccess &= assertEqual(
+ url, url,
+ rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
+
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("A-b.3:/%2f?x#y"));
+ urlobj = INetURLObject(url, INET_PROT_CID);
+ bSuccess &= assertEqual(url, INET_PROT_GENERIC, urlobj.GetProtocol());
+ bSuccess &= assertEqual(
+ url, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a-b.3:/%2F?x#y")),
+ rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
+
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foo:"));
+ urlobj = INetURLObject(url, INET_PROT_CID);
+ bSuccess &= assertEqual(url, INET_PROT_CID, urlobj.GetProtocol());
+ bSuccess &= assertEqual(
+ url, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cid:foo:")),
+ rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
+
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foo:#"));
+ urlobj = INetURLObject(url, INET_PROT_CID);
+ bSuccess &= assertEqual(url, INET_PROT_CID, urlobj.GetProtocol());
+ bSuccess &= assertEqual(
+ url, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cid:foo:#")),
+ rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
+
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foo:/"));
+ urlobj = INetURLObject(url, INET_PROT_CID);
+ bSuccess &= assertEqual(url, INET_PROT_GENERIC, urlobj.GetProtocol());
+ bSuccess &= assertEqual(
+ url, url,
+ rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
+
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".foo:/"));
+ urlobj = INetURLObject(url, INET_PROT_CID);
+ bSuccess &= assertEqual(url, INET_PROT_CID, urlobj.GetProtocol());
+ bSuccess &= assertEqual(
+ url, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cid:.foo:/")),
+ rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
+
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("C:\\bla"));
+ urlobj = INetURLObject(url, INET_PROT_CID);
+ bSuccess &= assertEqual(url, INET_PROT_FILE, urlobj.GetProtocol());
+ bSuccess &= assertEqual(
+ url, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file:///C:/bla")),
+ rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
+
+ url = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("private:factory/swriter"));
+ urlobj = INetURLObject(url, INET_PROT_CID);
+ bSuccess &= assertEqual(
+ url, INET_PROT_PRIV_SOFFICE, urlobj.GetProtocol());
+ bSuccess &= assertEqual(
+ url, url,
+ rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
+
+ // #i80134#:
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\\\\foobar\\%20#"));
+ urlobj = INetURLObject(url, INET_PROT_FILE);
+ bSuccess &= assertEqual(url, INET_PROT_FILE, urlobj.GetProtocol());
+ bSuccess &= assertEqual(
+ url,
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("file://foobar/%2520%23")),
+ rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\\\\foo_bar\\%20#"));
+ urlobj = INetURLObject(url, INET_PROT_FILE);
+ bSuccess &= assertEqual(url, INET_PROT_FILE, urlobj.GetProtocol());
+ bSuccess &= assertEqual(
+ url,
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("file://foo_bar/%2520%23")),
+ rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
+ }
+
+ if (true) { // #i53184#
+ rtl::OUString url(RTL_CONSTASCII_USTRINGPARAM("file://comp_name/path"));
+ bSuccess &= assertEqual(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("#i53184# smart INET_PROT_FILE")),
+ INetURLObject(url, INET_PROT_FILE).GetMainURL(
+ INetURLObject::NO_DECODE),
+ url);
+ bSuccess &= assertEqual(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("#i53184# strict")),
+ INetURLObject(url).GetMainURL(INetURLObject::NO_DECODE), url);
+ }
+
+ if (true) {
+ rtl::OUString path;
+ path = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/a/b/c"));
+ bSuccess &= assertEqual(
+ path,
+ rtl::OUString(
+ INetURLObject(path, INetURLObject::FSYS_DETECT).GetMainURL(
+ INetURLObject::NO_DECODE)),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file:///a/b/c")));
+ path = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a\\b\\c"));
+ bSuccess &= assertEqual(
+ path,
+ rtl::OUString(
+ INetURLObject(path, INetURLObject::FSYS_DETECT).GetMainURL(
+ INetURLObject::NO_DECODE)),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file:///a/b/c")));
+ path = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a:b:c"));
+ bSuccess &= assertEqual(
+ path, INetURLObject(path, INetURLObject::FSYS_DETECT).HasError(),
+ true);
+ bSuccess &= assertEqual(
+ path,
+ rtl::OUString(
+ INetURLObject(
+ path,
+ INetURLObject::FSysStyle(
+ INetURLObject::FSYS_DETECT | INetURLObject::FSYS_MAC)).
+ GetMainURL(INetURLObject::NO_DECODE)),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file:///a/b/c")));
+ rtl::OUString url;
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/a/b/c"));
+ bSuccess &= assertEqual(
+ url,
+ rtl::OUString(
+ INetURLObject(url, INET_PROT_HTTP).GetMainURL(
+ INetURLObject::NO_DECODE)),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file:///a/b/c")));
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a:\\b\\c"));
+ bSuccess &= assertEqual(
+ url,
+ rtl::OUString(
+ INetURLObject(url, INET_PROT_HTTP).GetMainURL(
+ INetURLObject::NO_DECODE)),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file:///a:/b/c")));
+ url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a:b:c"));
+ bSuccess &= assertEqual(
+ url, INetURLObject(url, INET_PROT_HTTP).HasError(), true);
+ bSuccess &= assertEqual(
+ url,
+ (INetURLObject(
+ url, INET_PROT_HTTP, INetURLObject::WAS_ENCODED,
+ RTL_TEXTENCODING_UTF8,
+ INetURLObject::FSysStyle(
+ INetURLObject::FSYS_DETECT | INetURLObject::FSYS_MAC)).
+ HasError()),
+ true);
+ }
+
+ bSuccess &= test_getSegmentCount("mailto:a@b", false, 0);
+ bSuccess &= test_getSegmentCount("vnd.sun.star.expand:$PREFIX", false, 1);
+ bSuccess &= test_getSegmentCount("vnd.sun.star.expand:$PREFIX", true, 1);
+ bSuccess &= test_getSegmentCount("vnd.sun.star.expand:$PREFIX/", false, 2);
+ bSuccess &= test_getSegmentCount("vnd.sun.star.expand:$PREFIX/", true, 1);
+ bSuccess &= test_getSegmentCount(
+ "vnd.sun.star.expand:$PREFIX/foo", false, 2);
+ bSuccess &= test_getSegmentCount(
+ "vnd.sun.star.expand:$PREFIX/foo", true, 2);
+ bSuccess &= test_getSegmentCount("file:///", false, 1);
+ bSuccess &= test_getSegmentCount("file:///", true, 0);
+ bSuccess &= test_getSegmentCount("file:///foo", false, 1);
+ bSuccess &= test_getSegmentCount("file:///foo", true, 1);
+
+ bSuccess &= test_insertName(
+ "mailto:a@b", "foo", false, 0, false, false, "mailto:a@b");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX", "foo", false, 0, false, true,
+ "vnd.sun.star.expand:%2Ffoo/$PREFIX");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX", "foo", false, 0, true, true,
+ "vnd.sun.star.expand:%2Ffoo/$PREFIX");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX", "foo", true, 0, false, true,
+ "vnd.sun.star.expand:%2Ffoo/$PREFIX");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX", "foo", true, 0, true, true,
+ "vnd.sun.star.expand:%2Ffoo/$PREFIX");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX", "foo", false, 1, false, true,
+ "vnd.sun.star.expand:$PREFIX/foo");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX", "foo", false, 1, true, true,
+ "vnd.sun.star.expand:$PREFIX/foo");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX", "foo", true, 1, false, true,
+ "vnd.sun.star.expand:$PREFIX/foo/");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX", "foo", true, 1, true, true,
+ "vnd.sun.star.expand:$PREFIX/foo/");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX", "foo", false,
+ INetURLObject::LAST_SEGMENT, false, true,
+ "vnd.sun.star.expand:$PREFIX/foo");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX", "foo", false,
+ INetURLObject::LAST_SEGMENT, true, true,
+ "vnd.sun.star.expand:$PREFIX/foo");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX", "foo", true,
+ INetURLObject::LAST_SEGMENT, false, true,
+ "vnd.sun.star.expand:$PREFIX/foo/");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX", "foo", true,
+ INetURLObject::LAST_SEGMENT, true, true,
+ "vnd.sun.star.expand:$PREFIX/foo/");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX/", "foo", false,
+ 1, false, true,
+ "vnd.sun.star.expand:$PREFIX/foo/");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX/", "foo", false,
+ 1, true, true,
+ "vnd.sun.star.expand:$PREFIX/foo");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX/", "foo", true,
+ 1, false, true,
+ "vnd.sun.star.expand:$PREFIX/foo/");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX/", "foo", true,
+ 1, true, true,
+ "vnd.sun.star.expand:$PREFIX/foo/");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX/", "foo", false,
+ INetURLObject::LAST_SEGMENT, false, true,
+ "vnd.sun.star.expand:$PREFIX//foo");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX/", "foo", false,
+ INetURLObject::LAST_SEGMENT, true, true,
+ "vnd.sun.star.expand:$PREFIX/foo");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX/", "foo", true,
+ INetURLObject::LAST_SEGMENT, false, true,
+ "vnd.sun.star.expand:$PREFIX//foo/");
+ bSuccess &= test_insertName(
+ "vnd.sun.star.expand:$PREFIX/", "foo", true,
+ INetURLObject::LAST_SEGMENT, true, true,
+ "vnd.sun.star.expand:$PREFIX/foo/");
+ bSuccess &= test_insertName(
+ "file:///", "foo", false, 0, false, true, "file:///foo/");
+ bSuccess &= test_insertName(
+ "file:///", "foo", false, 0, true, true, "file:///foo");
+ bSuccess &= test_insertName(
+ "file:///", "foo", true, 0, false, true, "file:///foo/");
+ bSuccess &= test_insertName(
+ "file:///", "foo", true, 0, true, true, "file:///foo/");
+ bSuccess &= test_insertName(
+ "file:///bar", "foo", false, 0, false, true, "file:///foo/bar");
+ bSuccess &= test_insertName(
+ "file:///bar", "foo", false, 0, true, true, "file:///foo/bar");
+ bSuccess &= test_insertName(
+ "file:///bar", "foo", true, 0, false, true, "file:///foo/bar");
+ bSuccess &= test_insertName(
+ "file:///bar", "foo", true, 0, true, true, "file:///foo/bar");
+
+ bSuccess &= test_removeSegment("mailto:a@b", 0, false, false, "mailto:a@b");
+ bSuccess &= test_removeSegment(
+ "vnd.sun.star.expand:$PREFIX", 0, false, false,
+ "vnd.sun.star.expand:$PREFIX");
+ bSuccess &= test_removeSegment(
+ "vnd.sun.star.expand:$PREFIX", 0, true, true,
+ "vnd.sun.star.expand:%2F");
+ bSuccess &= test_removeSegment(
+ "vnd.sun.star.expand:$PREFIX", 1, false, false,
+ "vnd.sun.star.expand:$PREFIX");
+ bSuccess &= test_removeSegment(
+ "vnd.sun.star.expand:$PREFIX", 1, true, false,
+ "vnd.sun.star.expand:$PREFIX");
+ bSuccess &= test_removeSegment(
+ "vnd.sun.star.expand:$PREFIX", 2, false, false,
+ "vnd.sun.star.expand:$PREFIX");
+ bSuccess &= test_removeSegment(
+ "vnd.sun.star.expand:$PREFIX", 2, true, false,
+ "vnd.sun.star.expand:$PREFIX");
+ bSuccess &= test_removeSegment(
+ "vnd.sun.star.expand:$PREFIX", INetURLObject::LAST_SEGMENT, false,
+ false, "vnd.sun.star.expand:$PREFIX");
+ bSuccess &= test_removeSegment(
+ "vnd.sun.star.expand:$PREFIX", INetURLObject::LAST_SEGMENT, true, true,
+ "vnd.sun.star.expand:%2F");
+ bSuccess &= test_removeSegment(
+ "vnd.sun.star.expand:$PREFIX/", 0, false, true,
+ "vnd.sun.star.expand:%2F");
+ bSuccess &= test_removeSegment(
+ "vnd.sun.star.expand:$PREFIX/", 0, true, true,
+ "vnd.sun.star.expand:%2F");
+ bSuccess &= test_removeSegment(
+ "vnd.sun.star.expand:$PREFIX/", 1, false, true,
+ "vnd.sun.star.expand:$PREFIX");
+ bSuccess &= test_removeSegment(
+ "vnd.sun.star.expand:$PREFIX/", 1, true, true,
+ "vnd.sun.star.expand:$PREFIX/");
+ bSuccess &= test_removeSegment(
+ "vnd.sun.star.expand:$PREFIX/", 2, false, false,
+ "vnd.sun.star.expand:$PREFIX/");
+ bSuccess &= test_removeSegment(
+ "vnd.sun.star.expand:$PREFIX/", 2, true, false,
+ "vnd.sun.star.expand:$PREFIX/");
+ bSuccess &= test_removeSegment(
+ "vnd.sun.star.expand:$PREFIX/", INetURLObject::LAST_SEGMENT, false,
+ true, "vnd.sun.star.expand:$PREFIX");
+ bSuccess &= test_removeSegment(
+ "vnd.sun.star.expand:$PREFIX/", INetURLObject::LAST_SEGMENT, true,
+ true, "vnd.sun.star.expand:%2F");
+ bSuccess &= test_removeSegment("file:///", 0, false, true, "file:///");
+ bSuccess &= test_removeSegment("file:///", 0, true, true, "file:///");
+ bSuccess &= test_removeSegment("file:///", 1, false, false, "file:///");
+ bSuccess &= test_removeSegment("file:///", 1, true, false, "file:///");
+ bSuccess &= test_removeSegment("file:///", 2, false, false, "file:///");
+ bSuccess &= test_removeSegment("file:///", 2, true, false, "file:///");
+ bSuccess &= test_removeSegment(
+ "file:///", INetURLObject::LAST_SEGMENT, false, true, "file:///");
+ bSuccess &= test_removeSegment(
+ "file:///", INetURLObject::LAST_SEGMENT, true, false, "file:///");
+ bSuccess &= test_removeSegment("file:///foo", 0, false, true, "file:///");
+ bSuccess &= test_removeSegment("file:///foo", 0, true, true, "file:///");
+ bSuccess &= test_removeSegment(
+ "file:///foo", 1, false, false, "file:///foo");
+ bSuccess &= test_removeSegment(
+ "file:///foo", 1, true, false, "file:///foo");
+ bSuccess &= test_removeSegment(
+ "file:///foo", 2, false, false, "file:///foo");
+ bSuccess &= test_removeSegment(
+ "file:///foo", 2, true, false, "file:///foo");
+ bSuccess &= test_removeSegment(
+ "file:///foo", INetURLObject::LAST_SEGMENT, false, true, "file:///");
+ bSuccess &= test_removeSegment(
+ "file:///foo", INetURLObject::LAST_SEGMENT, true, true, "file:///");
+ bSuccess &= test_removeSegment("file:///foo/", 0, false, true, "file:///");
+ bSuccess &= test_removeSegment("file:///foo/", 0, true, true, "file:///");
+ bSuccess &= test_removeSegment(
+ "file:///foo/", 1, false, true, "file:///foo");
+ bSuccess &= test_removeSegment(
+ "file:///foo/", 1, true, true, "file:///foo/");
+ bSuccess &= test_removeSegment(
+ "file:///foo/", 2, false, false, "file:///foo/");
+ bSuccess &= test_removeSegment(
+ "file:///foo/", 2, true, false, "file:///foo/");
+ bSuccess &= test_removeSegment(
+ "file:///foo/", INetURLObject::LAST_SEGMENT, false, true,
+ "file:///foo");
+ bSuccess &= test_removeSegment(
+ "file:///foo/", INetURLObject::LAST_SEGMENT, true, true, "file:///");
+
+ return bSuccess ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */