summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/Executable_mkunroll.mk61
-rw-r--r--tools/Executable_rscdep.mk71
-rw-r--r--tools/Executable_so_checksum.mk54
-rw-r--r--tools/Executable_sspretty.mk59
-rw-r--r--tools/Library_tl.mk168
-rw-r--r--tools/Makefile38
-rw-r--r--tools/Module_tools.mk41
-rw-r--r--tools/Package_inc.mk110
-rwxr-xr-xtools/StaticLibrary_ooopathutils.mk54
-rw-r--r--tools/bootstrp/addexes/replace.cxx76
-rw-r--r--tools/bootstrp/addexes2/mkfilt.cxx237
-rw-r--r--tools/bootstrp/appdef.cxx168
-rw-r--r--tools/bootstrp/cppdep.cxx246
-rw-r--r--tools/bootstrp/cppdep.hxx58
-rw-r--r--tools/bootstrp/inimgr.cxx210
-rw-r--r--tools/bootstrp/iserver.cxx152
-rw-r--r--tools/bootstrp/md5.cxx149
-rw-r--r--tools/bootstrp/md5.hxx32
-rw-r--r--tools/bootstrp/mkcreate.cxx945
-rw-r--r--tools/bootstrp/prj.cxx171
-rw-r--r--tools/bootstrp/rscdep.cxx299
-rw-r--r--tools/bootstrp/so_checksum.cxx56
-rw-r--r--tools/bootstrp/sspretty.cxx60
-rw-r--r--tools/inc/bootstrp/appdef.hxx68
-rw-r--r--tools/inc/bootstrp/inimgr.hxx61
-rw-r--r--tools/inc/bootstrp/mkcreate.hxx297
-rw-r--r--tools/inc/bootstrp/prj.hxx58
-rw-r--r--tools/inc/impcont.hxx147
-rw-r--r--tools/inc/impstrg.hxx54
-rw-r--r--tools/inc/pch/precompiled_tools.cxx29
-rw-r--r--tools/inc/pch/precompiled_tools.hxx92
-rw-r--r--tools/inc/poly.h92
-rw-r--r--tools/inc/tools/StringListResource.hxx56
-rw-r--r--tools/inc/tools/appendunixshellword.hxx59
-rw-r--r--tools/inc/tools/b3dtrans.hxx352
-rw-r--r--tools/inc/tools/bigint.hxx328
-rw-r--r--tools/inc/tools/cachestr.hxx83
-rw-r--r--tools/inc/tools/color.hxx239
-rw-r--r--tools/inc/tools/config.hxx101
-rw-r--r--tools/inc/tools/contnr.hxx123
-rw-r--r--tools/inc/tools/date.hxx120
-rw-r--r--tools/inc/tools/datetime.hxx111
-rw-r--r--tools/inc/tools/debug.hxx783
-rw-r--r--tools/inc/tools/diagnose_ex.h175
-rw-r--r--tools/inc/tools/dynary.hxx110
-rw-r--r--tools/inc/tools/errcode.hxx323
-rw-r--r--tools/inc/tools/errinf.hxx243
-rw-r--r--tools/inc/tools/extendapplicationenvironment.hxx42
-rw-r--r--tools/inc/tools/fldunit.hxx40
-rw-r--r--tools/inc/tools/fontenum.hxx172
-rw-r--r--tools/inc/tools/fract.hxx165
-rw-r--r--tools/inc/tools/fsys.hxx564
-rw-r--r--tools/inc/tools/gen.hxx712
-rw-r--r--tools/inc/tools/geninfo.hxx230
-rw-r--r--tools/inc/tools/getprocessworkingdir.hxx48
-rwxr-xr-xtools/inc/tools/globname.hxx138
-rw-r--r--tools/inc/tools/inetdef.hxx111
-rwxr-xr-xtools/inc/tools/inetmime.hxx1445
-rw-r--r--tools/inc/tools/inetmsg.hxx623
-rw-r--r--tools/inc/tools/inetstrm.hxx275
-rw-r--r--tools/inc/tools/iparser.hxx147
-rw-r--r--tools/inc/tools/isofallback.hxx38
-rw-r--r--tools/inc/tools/line.hxx75
-rw-r--r--tools/inc/tools/link.hxx158
-rw-r--r--tools/inc/tools/list.hxx143
-rw-r--r--tools/inc/tools/mapunit.hxx40
-rw-r--r--tools/inc/tools/mempool.hxx125
-rw-r--r--tools/inc/tools/multisel.hxx216
-rw-r--r--tools/inc/tools/ownlist.hxx94
-rw-r--r--tools/inc/tools/pathutils.hxx101
-rw-r--r--tools/inc/tools/poly.hxx347
-rw-r--r--tools/inc/tools/postsys.h244
-rw-r--r--tools/inc/tools/postwin.h257
-rw-r--r--tools/inc/tools/postx.h73
-rw-r--r--tools/inc/tools/presys.h40
-rw-r--r--tools/inc/tools/prewin.h71
-rw-r--r--tools/inc/tools/prex.h74
-rw-r--r--tools/inc/tools/pstm.hxx261
-rw-r--r--tools/inc/tools/queue.hxx104
-rw-r--r--tools/inc/tools/rc.h221
-rw-r--r--tools/inc/tools/rc.hxx111
-rw-r--r--tools/inc/tools/rcid.h134
-rw-r--r--tools/inc/tools/ref.hxx456
-rw-r--r--tools/inc/tools/resary.hxx93
-rw-r--r--tools/inc/tools/resid.hxx162
-rw-r--r--tools/inc/tools/resmgr.hxx241
-rw-r--r--tools/inc/tools/rtti.hxx174
-rw-r--r--tools/inc/tools/shl.hxx114
-rw-r--r--tools/inc/tools/simplerm.hxx117
-rw-r--r--tools/inc/tools/solar.h370
-rw-r--r--tools/inc/tools/solarmutex.hxx45
-rw-r--r--tools/inc/tools/stack.hxx105
-rw-r--r--tools/inc/tools/stream.hxx867
-rwxr-xr-xtools/inc/tools/string.hxx691
-rw-r--r--tools/inc/tools/svborder.hxx97
-rw-r--r--tools/inc/tools/svlibrary.hxx42
-rw-r--r--tools/inc/tools/svwin.h36
-rw-r--r--tools/inc/tools/table.hxx152
-rw-r--r--tools/inc/tools/tempfile.hxx77
-rw-r--r--tools/inc/tools/tenccvt.hxx58
-rw-r--r--tools/inc/tools/testtoolloader.hxx39
-rw-r--r--tools/inc/tools/time.hxx112
-rw-r--r--tools/inc/tools/tools.h38
-rw-r--r--tools/inc/tools/toolsdllapi.h41
-rw-r--r--tools/inc/tools/unqid.hxx109
-rw-r--r--tools/inc/tools/unqidx.hxx151
-rw-r--r--tools/inc/tools/urlobj.hxx1922
-rw-r--r--tools/inc/tools/vcompat.hxx70
-rw-r--r--tools/inc/tools/vector2d.hxx119
-rw-r--r--tools/inc/tools/weakbase.h160
-rw-r--r--tools/inc/tools/weakbase.hxx183
-rw-r--r--tools/inc/tools/wintypes.hxx344
-rw-r--r--tools/inc/tools/wldcrd.hxx91
-rw-r--r--tools/inc/tools/zcodec.hxx128
-rw-r--r--tools/inc/toolsin.hxx52
-rw-r--r--tools/os2/inc/dll.hxx39
-rw-r--r--tools/os2/source/dll/toolsdll.cxx48
-rw-r--r--tools/prj/build.lst2
-rw-r--r--tools/prj/d.lst0
-rw-r--r--tools/prj/makefile.mk40
-rw-r--r--tools/qa/test_pathutils.cxx76
-rw-r--r--tools/qa/version.map34
-rw-r--r--tools/source/communi/geninfo.cxx408
-rw-r--r--tools/source/communi/parser.cxx469
-rw-r--r--tools/source/datetime/datetime.cxx442
-rw-r--r--tools/source/datetime/tdate.cxx494
-rw-r--r--tools/source/datetime/ttime.cxx445
-rw-r--r--tools/source/debug/debug.cxx1826
-rw-r--r--tools/source/debug/stcktree.cxx320
-rw-r--r--tools/source/fsys/comdep.cxx44
-rwxr-xr-xtools/source/fsys/comdep.hxx156
-rwxr-xr-xtools/source/fsys/dirent.cxx3213
-rwxr-xr-xtools/source/fsys/filecopy.cxx486
-rwxr-xr-xtools/source/fsys/fstat.cxx414
-rw-r--r--tools/source/fsys/os2.cxx1014
-rw-r--r--tools/source/fsys/os2.hxx93
-rwxr-xr-xtools/source/fsys/tdir.cxx768
-rw-r--r--tools/source/fsys/tempfile.cxx301
-rw-r--r--tools/source/fsys/unx.cxx660
-rw-r--r--tools/source/fsys/unx.hxx95
-rw-r--r--tools/source/fsys/urlobj.cxx5579
-rwxr-xr-xtools/source/fsys/wldcrd.cxx143
-rwxr-xr-xtools/source/fsys/wntmsc.cxx1081
-rwxr-xr-xtools/source/fsys/wntmsc.hxx102
-rw-r--r--tools/source/generic/b3dtrans.cxx1014
-rw-r--r--tools/source/generic/bigint.cxx1141
-rw-r--r--tools/source/generic/color.cxx510
-rw-r--r--tools/source/generic/config.cxx1304
-rw-r--r--tools/source/generic/fract.cxx736
-rw-r--r--tools/source/generic/gen.cxx661
-rw-r--r--tools/source/generic/line.cxx363
-rw-r--r--tools/source/generic/link.cxx58
-rw-r--r--tools/source/generic/poly.cxx2380
-rw-r--r--tools/source/generic/poly2.cxx891
-rw-r--r--tools/source/generic/svborder.cxx77
-rw-r--r--tools/source/generic/svlibrary.cxx129
-rw-r--r--tools/source/generic/toolsin.cxx95
-rw-r--r--tools/source/inet/inetmime.cxx4563
-rw-r--r--tools/source/inet/inetmsg.cxx1653
-rw-r--r--tools/source/inet/inetstrm.cxx1821
-rwxr-xr-xtools/source/memtools/contnr.cxx1708
-rwxr-xr-xtools/source/memtools/mempool.cxx87
-rwxr-xr-xtools/source/memtools/multisel.cxx1162
-rwxr-xr-xtools/source/memtools/table.cxx413
-rwxr-xr-xtools/source/memtools/unqidx.cxx601
-rw-r--r--tools/source/misc/appendunixshellword.cxx76
-rw-r--r--tools/source/misc/extendapplicationenvironment.cxx92
-rw-r--r--tools/source/misc/getprocessworkingdir.cxx64
-rw-r--r--tools/source/misc/pathutils.cxx218
-rw-r--r--tools/source/misc/solarmutex.cxx60
-rw-r--r--tools/source/rc/isofallback.cxx67
-rw-r--r--tools/source/rc/rc.cxx97
-rw-r--r--tools/source/rc/resary.cxx78
-rw-r--r--tools/source/rc/resmgr.cxx2120
-rw-r--r--tools/source/ref/errinf.cxx462
-rwxr-xr-xtools/source/ref/globname.cxx453
-rw-r--r--tools/source/ref/pstm.cxx915
-rw-r--r--tools/source/ref/ref.cxx51
-rw-r--r--tools/source/stream/cachestr.cxx290
-rwxr-xr-xtools/source/stream/stream.cxx2879
-rw-r--r--tools/source/stream/strmos2.cxx758
-rw-r--r--tools/source/stream/strmsys.cxx37
-rw-r--r--tools/source/stream/strmunx.cxx920
-rw-r--r--tools/source/stream/strmwnt.cxx689
-rw-r--r--tools/source/stream/vcompat.cxx80
-rw-r--r--tools/source/string/debugprint.cxx48
-rw-r--r--tools/source/string/strascii.cxx637
-rw-r--r--tools/source/string/strcvt.cxx613
-rw-r--r--tools/source/string/strimp.cxx2115
-rw-r--r--tools/source/string/strucvt.cxx213
-rw-r--r--tools/source/string/tenccvt.cxx97
-rw-r--r--tools/source/string/tstring.cxx295
-rw-r--r--tools/source/string/tustring.cxx162
-rw-r--r--tools/source/testtoolloader/testtoolloader.cxx185
-rw-r--r--tools/source/zcodec/zcodec.cxx488
-rw-r--r--tools/test/export.map34
-rw-r--r--tools/test/tests.cxx126
-rw-r--r--tools/unx/source/dll/toolsdll.cxx47
-rw-r--r--tools/win/inc/dll.hxx34
-rw-r--r--tools/win/source/dll/toolsdll.cxx47
-rw-r--r--tools/workben/fstest.cxx94
-rw-r--r--tools/workben/hashtbl.cxx515
-rw-r--r--tools/workben/hashtbl.hxx203
-rw-r--r--tools/workben/helloworld.c33
-rw-r--r--tools/workben/inetmimetest.cxx67
-rw-r--r--tools/workben/makefile.mk68
-rw-r--r--tools/workben/mempooltest.cxx18
-rw-r--r--tools/workben/solar.c427
-rw-r--r--tools/workben/tldem.cxx82
-rw-r--r--tools/workben/urltest.cxx1906
210 files changed, 81833 insertions, 0 deletions
diff --git a/tools/Executable_mkunroll.mk b/tools/Executable_mkunroll.mk
new file mode 100644
index 000000000000..60c6e676057e
--- /dev/null
+++ b/tools/Executable_mkunroll.mk
@@ -0,0 +1,61 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+$(eval $(call gb_Executable_Executable,mkunroll))
+
+$(eval $(call gb_Executable_set_include,mkunroll,\
+ $$(INCLUDE) \
+ -I$(SRCDIR)/tools/inc/ \
+ -I$(SRCDIR)/tools/inc/pch \
+ -I$(SRCDIR)/tools/bootstrp/ \
+))
+
+$(eval $(call gb_Executable_set_cxxflags,mkunroll,\
+ $$(CXXFLAGS) \
+ -D_TOOLS_STRINGLIST \
+))
+
+$(eval $(call gb_Executable_add_linked_libs,mkunroll,\
+ basegfx \
+ sal \
+ stl \
+ tl \
+ vos3 \
+ $(gb_STDLIBS) \
+))
+
+# used to link against basegfxlx comphelp4gcc3 i18nisolang1gcc3 ucbhelper4gcc3 uno_cppu uno_cppuhelpergcc3 uno_salhelpergcc3 - seems to be superficial
+
+$(eval $(call gb_Executable_add_exception_objects,mkunroll,\
+ tools/bootstrp/addexes2/mkfilt \
+ tools/bootstrp/appdef \
+ tools/bootstrp/cppdep \
+ tools/bootstrp/inimgr \
+ tools/bootstrp/prj \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/tools/Executable_rscdep.mk b/tools/Executable_rscdep.mk
new file mode 100644
index 000000000000..8d8c55fa585d
--- /dev/null
+++ b/tools/Executable_rscdep.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.
+#
+#*************************************************************************
+
+$(eval $(call gb_Executable_Executable,rscdep))
+
+$(eval $(call gb_Executable_set_include,rscdep,\
+ $$(INCLUDE) \
+ -I$(SRCDIR)/tools/inc/ \
+ -I$(SRCDIR)/tools/inc/pch \
+ -I$(SRCDIR)/tools/bootstrp/ \
+))
+
+$(eval $(call gb_Executable_set_cxxflags,rscdep,\
+ $$(CXXFLAGS) \
+ -D_TOOLS_STRINGLIST \
+))
+
+$(eval $(call gb_Executable_add_linked_libs,rscdep,\
+ sal \
+ stl \
+ tl \
+ vos3 \
+ $(gb_STDLIBS) \
+))
+
+$(eval $(call gb_Executable_add_exception_objects,rscdep,\
+ tools/bootstrp/appdef \
+ tools/bootstrp/cppdep \
+ tools/bootstrp/inimgr \
+ tools/bootstrp/prj \
+ tools/bootstrp/rscdep \
+))
+
+ifeq ($(OS),WNT)
+ifeq ($(HAVE_GETOPT),YES)
+$(eval $(call gb_Executable_set_cxxflags,rscdep,\
+ $$(CXXFLAGS) \
+ -DHAVE_GETOPT \
+))
+else
+$(eval $(call gb_Executable_add_linked_libs,rscdep,\
+ gnu_getopt \
+))
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/tools/Executable_so_checksum.mk b/tools/Executable_so_checksum.mk
new file mode 100644
index 000000000000..32b95bedd6da
--- /dev/null
+++ b/tools/Executable_so_checksum.mk
@@ -0,0 +1,54 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+$(eval $(call gb_Executable_Executable,so_checksum))
+
+$(eval $(call gb_Executable_set_include,so_checksum,\
+ $$(INCLUDE) \
+ -I$(SRCDIR)/tools/inc/ \
+ -I$(SRCDIR)/tools/inc/pch \
+ -I$(SRCDIR)/tools/bootstrp/ \
+))
+
+$(eval $(call gb_Executable_set_cxxflags,so_checksum,\
+ $$(CXXFLAGS) \
+ -D_TOOLS_STRINGLIST \
+))
+
+$(eval $(call gb_Executable_add_linked_libs,so_checksum,\
+ sal \
+ tl \
+ $(gb_STDLIBS) \
+))
+# used to link against basegfxlx comphelp4gcc3 i18nisolang1gcc3 ucbhelper4gcc3 uno_cppu uno_cppuhelpergcc3 uno_salhelpergcc3 vos3gcc3 - seems to be superficial
+
+$(eval $(call gb_Executable_add_exception_objects,so_checksum,\
+ tools/bootstrp/md5 \
+ tools/bootstrp/so_checksum \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/tools/Executable_sspretty.mk b/tools/Executable_sspretty.mk
new file mode 100644
index 000000000000..ab8379bae5bd
--- /dev/null
+++ b/tools/Executable_sspretty.mk
@@ -0,0 +1,59 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+$(eval $(call gb_Executable_Executable,sspretty))
+
+$(eval $(call gb_Executable_set_include,sspretty,\
+ $$(INCLUDE) \
+ -I$(SRCDIR)/tools/inc/ \
+ -I$(SRCDIR)/tools/inc/pch \
+ -I$(SRCDIR)/tools/bootstrp/ \
+))
+
+$(eval $(call gb_Executable_set_cxxflags,sspretty,\
+ $$(CXXFLAGS) \
+ -D_TOOLS_STRINGLIST \
+))
+
+$(eval $(call gb_Executable_add_linked_libs,sspretty,\
+ sal \
+ stl \
+ tl \
+ vos3 \
+ $(gb_STDLIBS) \
+))
+# used to link against basegfxlx comphelp4gcc3 i18nisolang1gcc3 ucbhelper4gcc3 uno_cppu uno_cppuhelpergcc3 uno_salhelpergcc3 - seems to be superficial
+
+$(eval $(call gb_Executable_add_exception_objects,sspretty,\
+ tools/bootstrp/appdef \
+ tools/bootstrp/cppdep \
+ tools/bootstrp/inimgr \
+ tools/bootstrp/prj \
+ tools/bootstrp/sspretty \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/tools/Library_tl.mk b/tools/Library_tl.mk
new file mode 100644
index 000000000000..4e676f2c3436
--- /dev/null
+++ b/tools/Library_tl.mk
@@ -0,0 +1,168 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+$(eval $(call gb_Library_Library,tl))
+
+$(eval $(call gb_Library_add_package_headers,tl,tools_inc))
+
+$(eval $(call gb_Library_add_precompiled_header,tl,$(SRCDIR)/tools/inc/pch/precompiled_tools))
+
+$(eval $(call gb_Library_set_include,tl,\
+ $$(INCLUDE) \
+ -I$(SRCDIR)/tools/inc \
+ -I$(SRCDIR)/tools/inc/pch \
+ -I$(SRCDIR)/solenv/inc \
+ -I$(SRCDIR)/solenv/inc/Xp31 \
+ -I$(OUTDIR)/inc/offuh \
+ -I$(OUTDIR)/inc/stl \
+))
+
+$(eval $(call gb_Library_set_defs,tl,\
+ $$(DEFS) \
+ -DTOOLS_DLLIMPLEMENTATION \
+ -DVCL \
+))
+
+$(eval $(call gb_Library_add_linked_libs,tl,\
+ basegfx \
+ comphelper \
+ i18nisolang1 \
+ stl \
+ cppu \
+ sal \
+ vos3 \
+ $(gb_STDLIBS) \
+))
+
+
+$(eval $(call gb_Library_add_exception_objects,tl,\
+ tools/source/communi/geninfo \
+ tools/source/communi/parser \
+ tools/source/datetime/datetime \
+ tools/source/datetime/tdate \
+ tools/source/datetime/ttime \
+ tools/source/debug/debug \
+ tools/source/debug/stcktree \
+ tools/source/fsys/comdep \
+ tools/source/fsys/dirent \
+ tools/source/fsys/filecopy \
+ tools/source/fsys/fstat \
+ tools/source/fsys/tdir \
+ tools/source/fsys/tempfile \
+ tools/source/fsys/urlobj \
+ tools/source/fsys/wldcrd \
+ tools/source/generic/b3dtrans \
+ tools/source/generic/bigint \
+ tools/source/generic/color \
+ tools/source/generic/config \
+ tools/source/generic/fract \
+ tools/source/generic/gen \
+ tools/source/generic/line \
+ tools/source/generic/link \
+ tools/source/generic/poly \
+ tools/source/generic/poly2 \
+ tools/source/generic/svborder \
+ tools/source/generic/toolsin \
+ tools/source/generic/svlibrary \
+ tools/source/inet/inetmime \
+ tools/source/inet/inetmsg \
+ tools/source/inet/inetstrm \
+ tools/source/memtools/contnr \
+ tools/source/memtools/mempool \
+ tools/source/memtools/multisel \
+ tools/source/memtools/table \
+ tools/source/memtools/unqidx \
+ tools/source/misc/appendunixshellword \
+ tools/source/misc/extendapplicationenvironment \
+ tools/source/misc/getprocessworkingdir \
+ tools/source/misc/solarmutex \
+ tools/source/rc/isofallback \
+ tools/source/rc/rc \
+ tools/source/rc/resary \
+ tools/source/rc/resmgr \
+ tools/source/ref/errinf \
+ tools/source/ref/globname \
+ tools/source/ref/pstm \
+ tools/source/ref/ref \
+ tools/source/stream/cachestr \
+ tools/source/stream/stream \
+ tools/source/stream/strmsys \
+ tools/source/stream/vcompat \
+ tools/source/string/debugprint \
+ tools/source/string/tenccvt \
+ tools/source/string/tstring \
+ tools/source/string/tustring \
+ tools/source/testtoolloader/testtoolloader \
+ tools/source/zcodec/zcodec \
+))
+
+ifeq ($(GUI),UNX)
+$(eval $(call gb_Library_add_exception_objects,tl,\
+ tools/unx/source/dll/toolsdll \
+))
+endif
+
+ifeq ($(SYSTEM_ZLIB),YES)
+$(eval $(call gb_Library_set_cxxflags,tl,\
+ $$(CXXFLAGS) \
+ -DSYSTEM_ZLIB \
+))
+$(eval $(call gb_Library_add_linked_libs,tl,\
+ z \
+))
+else
+$(eval $(call gb_Library_add_linked_static_libs,tl,\
+ zlib \
+))
+endif
+
+ifeq ($(OS),WNT)
+
+$(eval $(call gb_Library_set_include,tl,\
+ $$(INCLUDE) \
+ -I$(SRCDIR)/tools/win/inc \
+))
+
+$(eval $(call gb_Library_add_exception_objects,tl,\
+ tools/win/source/dll/toolsdll \
+))
+
+$(eval $(call gb_Library_add_linked_libs,tl,\
+ mpr \
+ ole32 \
+ shell32 \
+ user32 \
+ uuid \
+))
+
+endif
+
+# tools/source/string/debugprint -DDEBUG -DEXCEPTIONS_OFF -DOSL_DEBUG_LEVEL=2 -DSHAREDLIB -DTOOLS_DLLIMPLEMENTATION -D_DLL_ -O0 -fno-exceptions -fpic -fvisibility=hidden -g
+# -DOPTIMIZE
+# no -DTOOLS_DLLIMPLEMENTATION on toolsdll
+# -DEXCEPTIONS_OFF -fno-exceptions on geninfo parser datetime tdate ttime bigint color config fract gen line link poly2 svborder toolsin inetmime inetmsg inetstrm contnr mempool multisel table unqidx cachestr stream strmsys vcompat tenccvt tstring tustring testtoolloader
+# vim: set noet sw=4 ts=4:
diff --git a/tools/Makefile b/tools/Makefile
new file mode 100644
index 000000000000..a79aff831024
--- /dev/null
+++ b/tools/Makefile
@@ -0,0 +1,38 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+ifeq ($(strip $(SOLARENV)),)
+$(error No environment set!)
+endif
+
+gb_PARTIALBUILD := T
+GBUILDDIR := $(SOLARENV)/gbuild
+include $(GBUILDDIR)/gbuild.mk
+
+$(eval $(call gb_Module_make_global_targets,$(shell ls $(dir $(realpath $(firstword $(MAKEFILE_LIST))))/Module*.mk)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/tools/Module_tools.mk b/tools/Module_tools.mk
new file mode 100644
index 000000000000..9e233408b317
--- /dev/null
+++ b/tools/Module_tools.mk
@@ -0,0 +1,41 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+
+$(eval $(call gb_Module_Module,tools))
+
+$(eval $(call gb_Module_add_targets,tools,\
+ Executable_mkunroll \
+ Executable_rscdep \
+ Executable_so_checksum \
+ Executable_sspretty \
+ Library_tl \
+ Package_inc \
+ StaticLibrary_ooopathutils \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/tools/Package_inc.mk b/tools/Package_inc.mk
new file mode 100644
index 000000000000..97d99653c312
--- /dev/null
+++ b/tools/Package_inc.mk
@@ -0,0 +1,110 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+$(eval $(call gb_Package_Package,tools_inc,$(SRCDIR)/tools/inc))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/StringListResource.hxx,tools/StringListResource.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/appendunixshellword.hxx,tools/appendunixshellword.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/b3dtrans.hxx,tools/b3dtrans.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/bigint.hxx,tools/bigint.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/cachestr.hxx,tools/cachestr.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/color.hxx,tools/color.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/config.hxx,tools/config.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/contnr.hxx,tools/contnr.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/date.hxx,tools/date.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/datetime.hxx,tools/datetime.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/debug.hxx,tools/debug.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/diagnose_ex.h,tools/diagnose_ex.h))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/dynary.hxx,tools/dynary.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/errcode.hxx,tools/errcode.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/errinf.hxx,tools/errinf.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/extendapplicationenvironment.hxx,tools/extendapplicationenvironment.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/fldunit.hxx,tools/fldunit.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/fontenum.hxx,tools/fontenum.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/fract.hxx,tools/fract.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/fsys.hxx,tools/fsys.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/gen.hxx,tools/gen.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/geninfo.hxx,tools/geninfo.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/getprocessworkingdir.hxx,tools/getprocessworkingdir.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/globname.hxx,tools/globname.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/inetdef.hxx,tools/inetdef.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/inetmime.hxx,tools/inetmime.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/inetmsg.hxx,tools/inetmsg.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/inetstrm.hxx,tools/inetstrm.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/iparser.hxx,tools/iparser.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/isofallback.hxx,tools/isofallback.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/line.hxx,tools/line.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/link.hxx,tools/link.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/list.hxx,tools/list.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/mapunit.hxx,tools/mapunit.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/mempool.hxx,tools/mempool.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/multisel.hxx,tools/multisel.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/ownlist.hxx,tools/ownlist.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/pathutils.hxx,tools/pathutils.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/poly.hxx,tools/poly.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/postsys.h,tools/postsys.h))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/postwin.h,tools/postwin.h))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/postx.h,tools/postx.h))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/presys.h,tools/presys.h))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/prewin.h,tools/prewin.h))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/prex.h,tools/prex.h))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/pstm.hxx,tools/pstm.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/queue.hxx,tools/queue.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/rc.h,tools/rc.h))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/rc.hxx,tools/rc.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/rcid.h,tools/rcid.h))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/ref.hxx,tools/ref.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/resary.hxx,tools/resary.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/resid.hxx,tools/resid.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/resmgr.hxx,tools/resmgr.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/rtti.hxx,tools/rtti.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/shl.hxx,tools/shl.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/simplerm.hxx,tools/simplerm.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/solar.h,tools/solar.h))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/solarmutex.hxx,tools/solarmutex.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/stack.hxx,tools/stack.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/stream.hxx,tools/stream.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/string.hxx,tools/string.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/svborder.hxx,tools/svborder.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/svlibrary.hxx,tools/svlibrary.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/svwin.h,tools/svwin.h))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/table.hxx,tools/table.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/tempfile.hxx,tools/tempfile.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/tenccvt.hxx,tools/tenccvt.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/testtoolloader.hxx,tools/testtoolloader.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/time.hxx,tools/time.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/tools.h,tools/tools.h))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/toolsdllapi.h,tools/toolsdllapi.h))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/unqid.hxx,tools/unqid.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/unqidx.hxx,tools/unqidx.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/urlobj.hxx,tools/urlobj.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/vcompat.hxx,tools/vcompat.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/vector2d.hxx,tools/vector2d.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/weakbase.h,tools/weakbase.h))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/weakbase.hxx,tools/weakbase.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/wintypes.hxx,tools/wintypes.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/wldcrd.hxx,tools/wldcrd.hxx))
+$(eval $(call gb_Package_add_file,tools_inc,inc/tools/zcodec.hxx,tools/zcodec.hxx))
diff --git a/tools/StaticLibrary_ooopathutils.mk b/tools/StaticLibrary_ooopathutils.mk
new file mode 100755
index 000000000000..a5b12532c60b
--- /dev/null
+++ b/tools/StaticLibrary_ooopathutils.mk
@@ -0,0 +1,54 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,ooopathutils))
+
+$(eval $(call gb_StaticLibrary_add_package_headers,ooopathutils,tools_inc))
+
+$(eval $(call gb_StaticLibrary_add_exception_objects,ooopathutils,\
+ tools/source/misc/pathutils \
+))
+
+
+# HACK for now
+# We really should fix the clients of this to link against the static library
+# Instead of this evil linking of an object from $(OUTDIR)
+define StaticLibrary_ooopathutils_hack
+$(call gb_StaticLibrary_get_target,ooopathutils) : $(OUTDIR)/lib/$(1)
+$$(eval $$(call gb_Deliver_add_deliverable,$(OUTDIR)/lib/$(1),$(call gb_CxxObject_get_target,tools/source/misc/pathutils)))
+
+$(OUTDIR)/lib/$(1) : $(call gb_CxxObject_get_target,tools/source/misc/pathutils)
+ $$(call gb_Deliver_deliver,$$<,$$@)
+
+endef
+
+ifeq ($(OS),WNT)
+$(eval $(call StaticLibrary_ooopathutils_hack,pathutils-obj.obj))
+else
+$(eval $(call StaticLibrary_ooopathutils_hack,pathutils-obj.o))
+endif
+# vim: set noet sw=4 ts=4:
diff --git a/tools/bootstrp/addexes/replace.cxx b/tools/bootstrp/addexes/replace.cxx
new file mode 100644
index 000000000000..37304ab18870
--- /dev/null
+++ b/tools/bootstrp/addexes/replace.cxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * 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();
+
+
+ sal_uIntPtr 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;
+}
diff --git a/tools/bootstrp/addexes2/mkfilt.cxx b/tools/bootstrp/addexes2/mkfilt.cxx
new file mode 100644
index 000000000000..9dae100352c3
--- /dev/null
+++ b/tools/bootstrp/addexes2/mkfilt.cxx
@@ -0,0 +1,237 @@
+/*************************************************************************
+ *
+ * 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;
+ sal_Bool bOut;
+ sal_Bool bHier;
+
+ MkLine();
+};
+
+MkLine::MkLine()
+{
+ bOut = sal_False;
+ bHier = sal_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 = sal_False;
+
+ pLst->Insert( pMkLine, LIST_APPEND );
+ }
+ else if ( nState == 1 )
+ {
+ sal_Bool bInTnrList = sal_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 = sal_True;
+ ByteString *pByteString = new ByteString("# do not delete this line === mkfilter3i\n");
+ p_MkLine->aLine = *pByteString;
+ p_MkLine->bOut = sal_False;
+ p_MkLine->pPrivateTnrLst = pTnrLst;
+ pTnrLst = new ByteStringList();
+ pLst->Insert( p_MkLine, LIST_APPEND );
+ nState = 0;
+ bInTnrList = sal_False;
+ }
+ ByteString *pStr = new ByteString( aLineBuf );
+ pMkLine->aLine = *pStr;
+ pMkLine->bOut = sal_False;
+
+ if ( bInTnrList )
+ pTnrLst->Insert( pMkLine, LIST_APPEND );
+ }
+ else {
+ /* Zeilen ignorieren */;
+ }
+ } // End Of File
+ fprintf( stderr, "\n" );
+
+ // das File wieder ausgegeben
+ sal_uIntPtr nLines = pLst->Count();
+ for ( sal_uIntPtr j=0; j<nLines; j++ )
+ {
+ MkLine *pLine = pLst->GetObject( j );
+ if ( pLine->bHier )
+ {
+ // die List n - Mal abarbeiten
+ for ( sal_uInt16 n=1; n<11; n++)
+ {
+ sal_uIntPtr nCount = pLine->pPrivateTnrLst->Count();
+ for ( sal_uIntPtr i=0; i<nCount; i++ )
+ {
+ MkLine *pMkLine = pLine->pPrivateTnrLst->GetObject(i);
+ ByteString aLine = pMkLine->aLine;
+ while( aLine.SearchAndReplace( aTnr, ByteString::CreateFromInt32( n )) != (sal_uInt16)-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;
+}
diff --git a/tools/bootstrp/appdef.cxx b/tools/bootstrp/appdef.cxx
new file mode 100644
index 000000000000..ac6212724afc
--- /dev/null
+++ b/tools/bootstrp/appdef.cxx
@@ -0,0 +1,168 @@
+/*************************************************************************
+ *
+ * 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;
+}
diff --git a/tools/bootstrp/cppdep.cxx b/tools/bootstrp/cppdep.cxx
new file mode 100644
index 000000000000..28410a575b5a
--- /dev/null
+++ b/tools/bootstrp/cppdep.cxx
@@ -0,0 +1,246 @@
+/*************************************************************************
+ *
+ * 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()
+{
+ sal_uIntPtr nCount = pSources->Count();
+ for ( sal_uIntPtr n=0; n<nCount;n++)
+ {
+ ByteString *pStr = pSources->GetObject(n);
+ Search( *pStr );
+ }
+}
+
+sal_Bool CppDep::AddSearchPath( const char* aPath )
+{
+ ByteString *pStr = new ByteString( aPath );
+ pSearchPath->Insert( pStr, LIST_APPEND );
+ return sal_False;
+}
+
+sal_Bool CppDep::AddSource( const char* aSource )
+{
+ ByteString *pStr = new ByteString( aSource );
+ pSources->Insert( pStr, LIST_APPEND );
+ return sal_False;
+}
+
+sal_Bool CppDep::Search( ByteString aFileName )
+{
+#ifdef DEBUG_VERBOSE
+ fprintf( stderr, "SEARCH : %s\n", aFileName.GetBuffer());
+#endif
+ sal_Bool bRet = sal_False;
+
+ SvFileStream aFile;
+ ByteString aReadLine;
+
+ UniString suFileName( aFileName, gsl_getSystemTextEncoding());
+
+ aFile.Open( suFileName, STREAM_READ );
+ while ( aFile.ReadLine( aReadLine ))
+ {
+ sal_uInt16 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 )) != "" )
+ {
+ sal_Bool bFound = sal_False;
+ sal_uIntPtr nCount = pFileList->Count();
+ for ( sal_uIntPtr i=0; i<nCount; i++ )
+ {
+ ByteString *pStr = pFileList->GetObject(i);
+ if ( *pStr == aNewFile )
+ bFound = sal_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
+
+ sal_uIntPtr nCount = pSearchPath->Count();
+ for ( sal_uIntPtr 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 );
+ sal_uInt16 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
diff --git a/tools/bootstrp/cppdep.hxx b/tools/bootstrp/cppdep.hxx
new file mode 100644
index 000000000000..0744a94d8964
--- /dev/null
+++ b/tools/bootstrp/cppdep.hxx
@@ -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.
+ *
+ ************************************************************************/
+
+#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;
+
+ sal_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;}
+ sal_Bool AddSearchPath( const char* aPath );
+ sal_Bool AddSource( const char * aSource );
+};
+
diff --git a/tools/bootstrp/inimgr.cxx b/tools/bootstrp/inimgr.cxx
new file mode 100644
index 000000000000..0907f8f9e102
--- /dev/null
+++ b/tools/bootstrp/inimgr.cxx
@@ -0,0 +1,210 @@
+/*************************************************************************
+ *
+ * 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( sal_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( sal_True )
+{
+ sLocalPath = GetLocalIni();
+ sGlobalDir = rDir;
+#if !defined( UNX ) && !defined( OS2 )
+ mkdir(( char * ) sLocalPath.GetBuffer());
+#else
+ mkdir( sLocalPath.GetBuffer() ,00777 );
+#endif
+}
+
+/****************************************************************************/
+IniManager::IniManager()
+/****************************************************************************/
+ : bUpdate( sal_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 ( sal_uInt16 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 = sal_False;
+ }
+}
diff --git a/tools/bootstrp/iserver.cxx b/tools/bootstrp/iserver.cxx
new file mode 100644
index 000000000000..63b1b333b22f
--- /dev/null
+++ b/tools/bootstrp/iserver.cxx
@@ -0,0 +1,152 @@
+/*************************************************************************
+ *
+ * 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 {
+ sal_Bool bError = sal_False;
+ sal_Bool bList = sal_False;
+ ByteString sInfo( "" );
+ ByteString sDataBase( GetDefStandList());
+
+ sal_Bool bGetNow = sal_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 = sal_True;
+ }
+ else if ( ByteString( argv[nCount] ).ToUpperAscii() == "-D" ) {
+ // requestet info path
+ nCount++;
+ if( nCount < argc ) {
+ sDataBase = ByteString( argv[nCount] );
+ nCount++;
+ }
+ else bError = sal_True;
+ }
+ else if ( ByteString( argv[nCount] ).ToUpperAscii() == "-L" ) {
+ // request list of childs
+ nCount++;
+ bList = sal_True;
+ }
+ else if ( ByteString( argv[nCount] ).ToUpperAscii() == "-N" ) {
+ // request list of childs
+ nCount++;
+ bGetNow = sal_True;
+ }
+ else {
+ bError = sal_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, sal_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( sal_uIntPtr 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( sal_uIntPtr i = 0; i < pList->Count(); i++ ) {
+ GenericInformation *pInfo = pList->GetObject( i );
+ if ( bGetNow ) {
+ ByteString sPath( "settings/now" );
+ GenericInformation *pSubInfo = pInfo->GetSubInfo( sPath, sal_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;
+}
+
diff --git a/tools/bootstrp/md5.cxx b/tools/bootstrp/md5.cxx
new file mode 100644
index 000000000000..687441c5c511
--- /dev/null
+++ b/tools/bootstrp/md5.cxx
@@ -0,0 +1,149 @@
+/*************************************************************************
+ *
+ * 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;
+}
diff --git a/tools/bootstrp/md5.hxx b/tools/bootstrp/md5.hxx
new file mode 100644
index 000000000000..55aa97e941c9
--- /dev/null
+++ b/tools/bootstrp/md5.hxx
@@ -0,0 +1,32 @@
+/*************************************************************************
+ *
+ * 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 );
+
diff --git a/tools/bootstrp/mkcreate.cxx b/tools/bootstrp/mkcreate.cxx
new file mode 100644
index 000000000000..adf9dde2ddaa
--- /dev/null
+++ b/tools/bootstrp/mkcreate.cxx
@@ -0,0 +1,945 @@
+/*************************************************************************
+ *
+ * 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,
+ sal_uInt16 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, sal_uInt16 nOperatingSystems )
+/*****************************************************************************/
+{
+ CodedDependency *pReturn = NULL;
+
+ if ( !pCodedDependencies ) {
+ pCodedDependencies = new SByteStringList();
+ pReturn = new CodedDependency( rCodedIdentifier, nOperatingSystems );
+ pCodedDependencies->PutString(( ByteString * ) pReturn );
+ }
+ else {
+ sal_uIntPtr 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, sal_uInt16 nOperatingSystems )
+/*****************************************************************************/
+{
+ CodedDependency *pReturn = NULL;
+
+ if ( !pCodedIdentifier ) {
+ pCodedIdentifier = new SByteStringList();
+ pReturn = new CodedDependency( rCodedIdentifier, nOperatingSystems );
+ pCodedIdentifier->PutString(( ByteString * ) pReturn );
+ }
+ else {
+ sal_uIntPtr 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, sal_uInt16 nOperatingSystem )
+/*****************************************************************************/
+{
+ ByteString sSearch;
+
+ sal_Bool bSubs = sal_True;
+ sal_uIntPtr nIndex = 0;
+
+ while ( bSubs && ByteString( LimitedPath[ nIndex ]) != "EndOf_LimitedPath" ) {
+ SourceDirectory *pActDir = this;
+ ByteString sLimitation( LimitedPath[ nIndex ]);
+
+ sal_Bool bBreak = sal_False;
+ for ( sal_uIntPtr i = sLimitation.GetTokenCount( '\\' ); i > 0 && !bBreak; i-- ) {
+ if (( !pActDir ) || ( *pActDir != sLimitation.GetToken(( sal_uInt16 )( i - 1 ), '\\' )))
+ bBreak = sal_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, sal_uInt16 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,
+ sal_uInt16 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;
+
+ sal_uIntPtr nPos = pCodedIdentifier->IsString( pCodedDependency );
+ if ( nPos != NOT_THERE ) {
+ CodedDependency *pIdentifier =
+ ( CodedDependency * ) pCodedIdentifier->GetObject( nPos );
+ sal_uInt16 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 ( sal_uIntPtr 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(( sal_uIntPtr ) 0 );
+
+ for (
+ sal_uIntPtr 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(( sal_uIntPtr ) 0 );
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+ByteString SourceDirectory::GetTarget()
+/*****************************************************************************/
+{
+ ByteString sReturn;
+
+ if ( !pDependencies )
+ return sReturn;
+
+ sal_uIntPtr 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;
+ }
+
+ sal_Bool bDependsOnPlatform = sal_False;
+ for ( sal_uIntPtr i = 0; i < pDependencies->Count(); i++ )
+ if ((( Dependency * ) pDependencies->GetObject( i ))->
+ GetOperatingSystem() != OS_ALL )
+ bDependsOnPlatform = sal_True;
+
+ ByteString sTarget( *this );
+ sTarget.SearchAndReplaceAll( "\\", "$/" );
+ if ( !bDependsOnPlatform ) {
+ sReturn = sTarget;
+ sReturn += " :";
+ for ( sal_uIntPtr 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 += " :";
+ sal_Bool bUNX = sal_False;
+
+ ByteString sWNT( ".IF \"$(GUI)\" == \"WNT\"\n" );
+ sWNT += sTarget;
+ sWNT += " :";
+ sal_Bool bWNT = sal_False;
+
+ ByteString sOS2( ".IF \"$(GUI)\" == \"OS2\"\n" );
+ sOS2 += sTarget;
+ sOS2 += " :";
+ sal_Bool bOS2 = sal_False;
+
+ for ( sal_uIntPtr 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 = sal_True;
+ }
+ if ( pDependency->GetOperatingSystem() & OS_WIN32 ) {
+ sWNT += " ";
+ sWNT += sDependency;
+ bWNT = sal_True;
+ }
+ if ( pDependency->GetOperatingSystem() & OS_OS2 ) {
+ sOS2 += " ";
+ sOS2 += sDependency;
+ bOS2 = sal_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 ) {
+ sal_Bool bDependsOnPlatform = sal_False;
+ for ( sal_uIntPtr i = 0; i < pSubDirectories->Count(); i++ )
+ if ((( SourceDirectory * ) pSubDirectories->GetObject( i ))->
+ GetOperatingSystems() != OS_ALL )
+ bDependsOnPlatform = sal_True;
+
+ if ( !bDependsOnPlatform ) {
+ sReturn = "RC_SUBDIRS = ";
+
+ for ( sal_uIntPtr 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 = ";
+ sal_Bool bUNX = sal_False;
+
+ ByteString sWNT( ".IF \"$(GUI)\" == \"WNT\"\n" );
+ sWNT += "RC_SUBDIRS = ";
+ sal_Bool bWNT = sal_False;
+
+ ByteString sOS2( ".IF \"$(GUI)\" == \"OS2\"\n" );
+ sOS2 += "RC_SUBDIRS = ";
+ sal_Bool bOS2 = sal_False;
+
+ for ( sal_uIntPtr 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 = sal_True;
+ }
+ if ( pDirectory->GetOperatingSystems() & OS_WIN32 ) {
+ sWNT += " \\\n\t";
+ sWNT += sDirectory;
+ bWNT = sal_True;
+ }
+ if ( pDirectory->GetOperatingSystems() & OS_OS2 ) {
+ sOS2 += " \\\n\t";
+ sOS2 += sDirectory;
+ bOS2 = sal_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;
+}
+
+/*****************************************************************************/
+sal_uInt16 SourceDirectory::GetOSType( const ByteString &sDependExt )
+/*****************************************************************************/
+{
+ sal_uInt16 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, sal_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, sal_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, sal_True, rRoot.GetBuffer());
+// fprintf( stderr,
+// "Creating virtual directory tree ...\n" );
+
+
+ SourceDirectory *pSourceRoot = new SourceDirectory( rRoot, OS_ALL );
+
+ for ( sal_uIntPtr i = 0; i < aStar.Count(); i++ ) {
+ Prj *pPrj = aStar.GetObject( i );
+
+ sal_Bool bBuildable = sal_True;
+ sal_uIntPtr 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( sal_False );
+ if ( pPrjDependencies )
+ for ( sal_uIntPtr x = 0; x < pPrjDependencies->Count(); x++ )
+ pProject->AddCodedDependency( *pPrjDependencies->GetObject( x ), OS_ALL );
+
+ pProject->AddCodedIdentifier( pPrj->GetProjectName(), OS_ALL );
+
+ for ( sal_uIntPtr 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 ( sal_uIntPtr 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;
+}
+
+/*****************************************************************************/
+sal_Bool SourceDirectory::RemoveDirectoryTreeAndAllDependencies()
+/*****************************************************************************/
+{
+ if ( !pParent )
+ return sal_False;
+
+ SourceDirectoryList *pParentContent = pParent->pSubDirectories;
+ sal_uIntPtr i = 0;
+ while ( i < pParentContent->Count()) {
+ SourceDirectory *pCandidate =
+ ( SourceDirectory * )pParentContent->GetObject( i );
+ if ( pCandidate == this ) {
+ pParentContent->Remove( i );
+ }
+ else {
+ if ( pCandidate->pDependencies ) {
+ sal_uIntPtr nPos = pCandidate->pDependencies->IsString( this );
+ if ( nPos != NOT_THERE )
+ delete pCandidate->pDependencies->Remove( nPos );
+ }
+ i++;
+ }
+ }
+ delete this;
+ return sal_True;
+}
+
+/*****************************************************************************/
+sal_Bool SourceDirectory::CreateRecursiveMakefile( sal_Bool bAllChilds )
+/*****************************************************************************/
+{
+ if ( !pSubDirectories )
+ return sal_True;
+
+ fprintf( stdout, "%s", GetFullPath().GetBuffer());
+
+ String aTmpStr( GetFullPath(), gsl_getSystemTextEncoding());
+ DirEntry aEntry( aTmpStr );
+ if ( !aEntry.Exists()) {
+ fprintf( stdout, " ... no directory!n" );
+ return sal_False;
+ }
+
+ sal_uIntPtr 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;
+
+ sal_Bool bMakefileMk = sal_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 = sal_True;
+ }
+ }
+
+ SvFileStream aMakefile( aRCEntry.GetFull(), STREAM_STD_WRITE | STREAM_TRUNC );
+ if ( !aMakefile.IsOpen()) {
+ fprintf( stdout, " ... failed!\n" );
+ return sal_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 ( sal_uIntPtr 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" );
+
+ sal_Bool bSuccess = sal_True;
+ if ( bAllChilds )
+ for ( sal_uIntPtr k = 0; k < pSubDirectories->Count(); k++ )
+ if ( !(( SourceDirectory * ) pSubDirectories->GetObject( k ))->
+ CreateRecursiveMakefile( sal_True ))
+ bSuccess = sal_False;
+
+ return bSuccess;
+}
+
+//
+// class SourceDirectoryList
+//
+
+/*****************************************************************************/
+SourceDirectoryList::~SourceDirectoryList()
+/*****************************************************************************/
+{
+ for ( sal_uIntPtr i = 0; i < Count(); i++ )
+ delete GetObject( i );
+}
+
+/*****************************************************************************/
+SourceDirectory *SourceDirectoryList::Search(
+ const ByteString &rDirectoryName )
+/*****************************************************************************/
+{
+ sal_uIntPtr nPos = IsString( ( ByteString * ) (&rDirectoryName) );
+ if ( nPos != LIST_ENTRY_NOTFOUND )
+ return ( SourceDirectory * ) GetObject( nPos );
+
+ return NULL;
+}
+
+
diff --git a/tools/bootstrp/prj.cxx b/tools/bootstrp/prj.cxx
new file mode 100644
index 000000000000..b4dee65f9673
--- /dev/null
+++ b/tools/bootstrp/prj.cxx
@@ -0,0 +1,171 @@
+/*************************************************************************
+ *
+ * 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 <vos/mutex.hxx>
+
+#include <tools/stream.hxx>
+#include <tools/geninfo.hxx>
+#include "bootstrp/prj.hxx"
+#include "bootstrp/inimgr.hxx"
+
+DECLARE_LIST( UniStringList, UniString* )
+
+//#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();
+ sal_Bool bFound = sal_False;
+ ByteString aEraseString;
+ for ( sal_uInt16 i = 0; i<= nLength; i++)
+ {
+ if ( aTmpStr.GetChar( i ) == 0x20 && !bFound )
+ aTmpStr.SetChar( i, 0x09 );
+ }
+ return aTmpStr;
+}
+
+/*****************************************************************************/
+ByteString SimpleConfig::GetCleanedNextLine( sal_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') ) != (sal_uInt16)-1 );
+ int nLength = aTmpStr.Len();
+ ByteString aEraseString;
+ sal_Bool bFirstTab = sal_True;
+ for ( sal_uInt16 i = 0; i<= nLength; i++)
+ {
+ if ( aTmpStr.GetChar( i ) == 0x20 )
+ aTmpStr.SetChar( i, 0x09 );
+
+ if ( aTmpStr.GetChar( i ) == 0x09 )
+ {
+ if ( bFirstTab )
+ bFirstTab = sal_False;
+ else
+ {
+ aTmpStr.SetChar( i, 0x20 );
+ }
+ }
+ else
+ bFirstTab = sal_True;
+
+ }
+ aTmpStr.EraseAllChars(' ');
+ return aTmpStr;
+
+}
+
diff --git a/tools/bootstrp/rscdep.cxx b/tools/bootstrp/rscdep.cxx
new file mode 100644
index 000000000000..7bcf036f6fa4
--- /dev/null
+++ b/tools/bootstrp/rscdep.cxx
@@ -0,0 +1,299 @@
+/*************************************************************************
+ *
+ * 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;
+
+int main( int argc, char** argv )
+{
+ int c;
+ char aBuf[255];
+ char pFileNamePrefix[255];
+ char pOutputFileName[255];
+ char pSrsFileName[255];
+ String aSrsBaseName;
+ sal_Bool bSource = sal_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 = sal_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\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());
+/* sal_uInt16 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();
+ sal_uIntPtr nCount = pLst->Count();
+ if ( nCount == 0 )
+ {
+ aOutStream.WriteLine( aString );
+ }
+ else
+ {
+ aString += ByteString( "\\" );
+ aOutStream.WriteLine( aString );
+ }
+
+ for ( sal_uIntPtr 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;
+}
+
diff --git a/tools/bootstrp/so_checksum.cxx b/tools/bootstrp/so_checksum.cxx
new file mode 100644
index 000000000000..716e99eff9f1
--- /dev/null
+++ b/tools/bootstrp/so_checksum.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// 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;
+}
+
+
+
diff --git a/tools/bootstrp/sspretty.cxx b/tools/bootstrp/sspretty.cxx
new file mode 100644
index 000000000000..143705b6a2ea
--- /dev/null
+++ b/tools/bootstrp/sspretty.cxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * 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;
+}
+
diff --git a/tools/inc/bootstrp/appdef.hxx b/tools/inc/bootstrp/appdef.hxx
new file mode 100644
index 000000000000..bf73b215205e
--- /dev/null
+++ b/tools/inc/bootstrp/appdef.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/inc/bootstrp/inimgr.hxx b/tools/inc/bootstrp/inimgr.hxx
new file mode 100644
index 000000000000..d72df34f19af
--- /dev/null
+++ b/tools/inc/bootstrp/inimgr.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * 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:
+ sal_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
+
diff --git a/tools/inc/bootstrp/mkcreate.hxx b/tools/inc/bootstrp/mkcreate.hxx
new file mode 100644
index 000000000000..96f272533d55
--- /dev/null
+++ b/tools/inc/bootstrp/mkcreate.hxx
@@ -0,0 +1,297 @@
+/*************************************************************************
+ *
+ * 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"
+
+DECLARE_LIST( UniStringList, UniString* )
+
+#include <tools/list.hxx>
+#include "bootstrp/prj.hxx"
+
+class SvStream;
+class SourceDirectoryList;
+
+//
+// class SourceDirectoryDependency
+//
+
+class CodedDependency : public ByteString
+{
+private:
+ sal_uInt16 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
+ sal_uInt16 nOperatingSystems // the operating systems where this dependency exists
+ ) :
+ ByteString( rCodedIdentifier ),
+ nOSType( nOperatingSystems )
+ {
+ }
+
+ /* returns the operating system
+ */
+ sal_uInt16 GetOperatingSystem()
+ {
+ return nOSType;
+ }
+
+ /* set operating system
+ */
+ void SetOperatingSystem( sal_uInt16 nOperatingSystems )
+ {
+ nOSType = nOperatingSystems;
+ }
+
+ /* add operating systems if same dependency
+ */
+ sal_Bool TryToMerge(
+ const ByteString &rCodedIdentifier, // the coded name of the directory
+ sal_uInt16 nOperatingSystems // the operating systems where this dependency exists
+ )
+ {
+ if ( rCodedIdentifier != *this )
+ return sal_False;
+ nOSType |= nOperatingSystems;
+ return sal_True;
+ }
+};
+
+//
+// class Dependecy
+//
+
+class Dependency : public ByteString
+{
+private:
+ sal_uInt16 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
+ sal_uInt16 nOperatingSystems // the operating systems where this dependency exists
+ ) :
+ ByteString( rDirectoryName ),
+ nOSType( nOperatingSystems )
+ {
+ }
+
+ /* returns the operating system
+ */
+ sal_uInt16 GetOperatingSystem()
+ {
+ return nOSType;
+ }
+};
+
+//
+// class SourceDirectory
+//
+
+class SourceDirectory : public ByteString
+{
+private:
+ SourceDirectory *pParent; // the parent directory
+ SourceDirectoryList *pSubDirectories; // list of sub directories
+ sal_uInt16 nOSType; // operating systems where this directory is used
+ sal_uInt16 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 sal_uInt16 GetOSType(
+ const ByteString &sDependExt // the corresponding dependency extension (see also prj.hxx)
+ );
+
+ /* removes this and all sub directories with all dependencies
+ */
+ sal_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
+ sal_uInt16 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
+ */
+ sal_uInt16 GetOperatingSystems() { return nOSType; }
+
+ /* returns the given directory
+ */
+ SourceDirectory *GetDirectory(
+ const ByteString &rDirectoryName, // full path
+ sal_uInt16 nOperatingSystem // the operating systems where this directory is used
+ );
+
+ /* create the directory and all mandatory parents
+ */
+ SourceDirectory *InsertFull(
+ const ByteString &rDirectoryName, // full path
+ sal_uInt16 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
+ sal_uInt16 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
+ sal_uInt16 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
+ sal_uInt16 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
+ sal_uInt16 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.)
+ sal_Bool bAll = sal_False // add all directories or only buildable ones
+ );
+
+ /* create the makefile.rc in file system
+ */
+ sal_Bool CreateRecursiveMakefile(
+ sal_Bool bAllChilds = sal_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
+ */
+ sal_uIntPtr InsertSorted(
+ SourceDirectory *pDirectory // directory
+ )
+ {
+ return PutString(( ByteString * ) pDirectory );
+ }
+};
+
+#endif
diff --git a/tools/inc/bootstrp/prj.hxx b/tools/inc/bootstrp/prj.hxx
new file mode 100644
index 000000000000..9e16ab2ee9a3
--- /dev/null
+++ b/tools/inc/bootstrp/prj.hxx
@@ -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.
+ *
+ ************************************************************************/
+
+#ifndef _PRJ_HXX
+#define _PRJ_HXX
+
+#include <tools/fsys.hxx>
+#include <tools/stream.hxx>
+
+/*********************************************************************
+*
+* 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( sal_Bool bReadComments = sal_False );
+};
+
+#endif
diff --git a/tools/inc/impcont.hxx b/tools/inc/impcont.hxx
new file mode 100644
index 000000000000..9be0a909474d
--- /dev/null
+++ b/tools/inc/impcont.hxx
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * 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
+ sal_uInt16 nSize; // Groesse des Blocks
+ sal_uInt16 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( sal_uInt16 nSize, CBlock* pPrev, CBlock* pNext );
+ // Fuer Array-Container
+ CBlock( sal_uInt16 nSize, CBlock* pPrev );
+ // Copy-Ctor
+ CBlock( const CBlock& r, CBlock* pPrev );
+ ~CBlock();
+
+ void Insert( void* p, sal_uInt16 nIndex, sal_uInt16 nReSize );
+ CBlock* Split( void* p, sal_uInt16 nIndex, sal_uInt16 nReSize );
+ void* Remove( sal_uInt16 nIndex, sal_uInt16 nReSize );
+ void* Replace( void* pNew, sal_uInt16 nIndex );
+
+ void** GetNodes() const { return pNodes; }
+ void** GetObjectPtr( sal_uInt16 nIndex );
+ void* GetObject( sal_uInt16 nIndex ) const;
+
+ void SetSize( sal_uInt16 nNewSize );
+
+ sal_uInt16 GetSize() const { return nCount; }
+ sal_uInt16 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( sal_uInt16 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( sal_uIntPtr nIndex ) const
+{
+ if ( pFirstBlock && (nIndex < pFirstBlock->Count()) )
+ // Item innerhalb des gefundenen Blocks zurueckgeben
+ return pFirstBlock->GetObject( (sal_uInt16)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
diff --git a/tools/inc/impstrg.hxx b/tools/inc/impstrg.hxx
new file mode 100644
index 000000000000..60b25a4c3fd6
--- /dev/null
+++ b/tools/inc/impstrg.hxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/inc/pch/precompiled_tools.cxx b/tools/inc/pch/precompiled_tools.cxx
new file mode 100644
index 000000000000..cafe6444a55d
--- /dev/null
+++ b/tools/inc/pch/precompiled_tools.cxx
@@ -0,0 +1,29 @@
+/*************************************************************************
+ *
+ * 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"
+
diff --git a/tools/inc/pch/precompiled_tools.hxx b/tools/inc/pch/precompiled_tools.hxx
new file mode 100644
index 000000000000..2bc615738a08
--- /dev/null
+++ b/tools/inc/pch/precompiled_tools.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * 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/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 "sys/stat.h"
+#include "sys/types.h"
+
+#include "vos/macros.hxx"
+#include "vos/mutex.hxx"
+#include "vos/process.hxx"
+#include "vos/signal.hxx"
+#include "vos/timer.hxx"
+//---MARKER---
+#endif
diff --git a/tools/inc/poly.h b/tools/inc/poly.h
new file mode 100644
index 000000000000..7876398c1876
--- /dev/null
+++ b/tools/inc/poly.h
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * 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 ((((sal_uInt16)0xFFFF)-32)/sizeof(Point))
+
+// -------------------
+// - ImplPolygonData -
+// -------------------
+
+class ImplPolygonData
+{
+public:
+ Point* mpPointAry;
+ sal_uInt8* mpFlagAry;
+ sal_uInt16 mnPoints;
+ sal_uIntPtr mnRefCount;
+};
+
+// ---------------
+// - ImplPolygon -
+// ---------------
+
+class ImplPolygon : public ImplPolygonData
+{
+public:
+ ImplPolygon( sal_uInt16 nInitSize, sal_Bool bFlags = sal_False );
+ ImplPolygon( sal_uInt16 nPoints, const Point* pPtAry, const sal_uInt8* pInitFlags = NULL );
+ ImplPolygon( const ImplPolygon& rImplPoly );
+ ~ImplPolygon();
+
+ void ImplSetSize( sal_uInt16 nSize, sal_Bool bResize = sal_True );
+ void ImplCreateFlagArray();
+ void ImplSplit( sal_uInt16 nPos, sal_uInt16 nSpace, ImplPolygon* pInitPoly = NULL );
+ void ImplRemove( sal_uInt16 nPos, sal_uInt16 nCount );
+};
+
+// -------------------
+// - ImplPolyPolygon -
+// -------------------
+
+#define MAX_POLYGONS ((sal_uInt16)0x3FF0)
+
+class Polygon;
+typedef Polygon* SVPPOLYGON;
+
+class ImplPolyPolygon
+{
+public:
+ SVPPOLYGON* mpPolyAry;
+ sal_uIntPtr mnRefCount;
+ sal_uInt16 mnCount;
+ sal_uInt16 mnSize;
+ sal_uInt16 mnResize;
+
+ ImplPolyPolygon( sal_uInt16 nInitSize, sal_uInt16 nResize )
+ { mpPolyAry = NULL; mnCount = 0; mnRefCount = 1;
+ mnSize = nInitSize; mnResize = nResize; }
+ ImplPolyPolygon( sal_uInt16 nInitSize );
+ ImplPolyPolygon( const ImplPolyPolygon& rImplPolyPoly );
+ ~ImplPolyPolygon();
+};
+
+#endif // _SV_POLY_H
diff --git a/tools/inc/tools/StringListResource.hxx b/tools/inc/tools/StringListResource.hxx
new file mode 100644
index 000000000000..3f7f6dcc610a
--- /dev/null
+++ b/tools/inc/tools/StringListResource.hxx
@@ -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.
+ *
+ ************************************************************************/
+#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)
+ {
+ sal_uInt16 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
diff --git a/tools/inc/tools/appendunixshellword.hxx b/tools/inc/tools/appendunixshellword.hxx
new file mode 100644
index 000000000000..66b333bb62a5
--- /dev/null
+++ b/tools/inc/tools/appendunixshellword.hxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/inc/tools/b3dtrans.hxx b/tools/inc/tools/b3dtrans.hxx
new file mode 100644
index 000000000000..5b812bde15a2
--- /dev/null
+++ b/tools/inc/tools/b3dtrans.hxx
@@ -0,0 +1,352 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/inc/tools/bigint.hxx b/tools/inc/tools/bigint.hxx
new file mode 100644
index 000000000000..9a5f1e6de886
--- /dev/null
+++ b/tools/inc/tools/bigint.hxx
@@ -0,0 +1,328 @@
+/*************************************************************************
+ *
+ * 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 sal_uInt16() const;
+ operator sal_uIntPtr() 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 sal_uInt16() const
+{
+ if ( !bIsBig && nVal >= 0 && nVal <= USHRT_MAX )
+ return (sal_uInt16)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
diff --git a/tools/inc/tools/cachestr.hxx b/tools/inc/tools/cachestr.hxx
new file mode 100644
index 000000000000..26085fb49e8b
--- /dev/null
+++ b/tools/inc/tools/cachestr.hxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * 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;
+ sal_uIntPtr nMaxSize;
+ int bPersistent;
+
+ SvStream* pSwapStream;
+ SvStream* pCurrentStream;
+ TempFile* pTempFile;
+
+ Link aFilenameLinkHdl;
+
+ TOOLS_DLLPRIVATE virtual sal_uIntPtr GetData( void* pData, sal_uIntPtr nSize );
+ TOOLS_DLLPRIVATE virtual sal_uIntPtr PutData( const void* pData, sal_uIntPtr nSize );
+ TOOLS_DLLPRIVATE virtual sal_uIntPtr SeekPos( sal_uIntPtr nPos );
+ TOOLS_DLLPRIVATE virtual void FlushData();
+ TOOLS_DLLPRIVATE virtual void SetSize( sal_uIntPtr nSize );
+
+public:
+ SvCacheStream( sal_uIntPtr nMaxMemSize = 0 );
+ SvCacheStream( const String &rFileName,
+ sal_uIntPtr nExpectedSize = 0,
+ sal_uIntPtr 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();
+ sal_uIntPtr GetSize();
+
+ sal_Bool IsPersistent() { return bPersistent != 0; }
+ void SetPersistence( sal_Bool b = sal_True ) { bPersistent = b; }
+ void SetSwapStream( SvStream *p )
+ { pSwapStream = p; } // darf nur vom FilenameHdl gerufen werden!
+};
+
+#endif
diff --git a/tools/inc/tools/color.hxx b/tools/inc/tools/color.hxx
new file mode 100644
index 000000000000..ad34f1e9de08
--- /dev/null
+++ b/tools/inc/tools/color.hxx
@@ -0,0 +1,239 @@
+/*************************************************************************
+ *
+ * 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>
+
+#ifndef _BGFX_COLOR_BCOLOR_HXX
+#include <basegfx/color/bcolor.hxx>
+#endif
+
+// --------------------
+// - ColorCount-Types -
+// --------------------
+
+#define COLCOUNT_MONOCHROM ((sal_uIntPtr)2)
+#define COLCOUNT_16 ((sal_uIntPtr)16)
+#define COLCOUNT_256 ((sal_uIntPtr)256)
+#define COLCOUNT_HICOLOR1 (((sal_uIntPtr)0x00007FFF)+1)
+#define COLCOUNT_HICOLOR2 (((sal_uIntPtr)0x0000FFFF)+1)
+#define COLCOUNT_TRUECOLOR (((sal_uIntPtr)0x00FFFFFF)+1)
+
+// ---------------
+// - Color-Types -
+// ---------------
+
+typedef sal_uInt32 ColorData;
+#define RGB_COLORDATA( r,g,b ) ((ColorData)(((sal_uInt32)((sal_uInt8)(b))))|(((sal_uInt32)((sal_uInt8)(g)))<<8)|(((sal_uInt32)((sal_uInt8)(r)))<<16))
+#define TRGB_COLORDATA( t,r,g,b ) ((ColorData)(((sal_uInt32)((sal_uInt8)(b))))|(((sal_uInt32)((sal_uInt8)(g)))<<8)|(((sal_uInt32)((sal_uInt8)(r)))<<16)|(((sal_uInt32)((sal_uInt8)(t)))<<24))
+#define COLORDATA_RED( n ) ((sal_uInt8)((n)>>16))
+#define COLORDATA_GREEN( n ) ((sal_uInt8)(((sal_uInt16)(n)) >> 8))
+#define COLORDATA_BLUE( n ) ((sal_uInt8)(n))
+#define COLORDATA_TRANSPARENCY( n ) ((sal_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 ) \
+ ((sal_uInt8)((((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( sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue )
+ { mnColor = RGB_COLORDATA( nRed, nGreen, nBlue ); }
+ Color( sal_uInt8 nTransparency, sal_uInt8 nRed, sal_uInt8 nGreen, sal_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(
+ sal_uInt8((rBColor.getRed() * 255.0) + 0.5),
+ sal_uInt8((rBColor.getGreen() * 255.0) + 0.5),
+ sal_uInt8((rBColor.getBlue() * 255.0) + 0.5));
+ }
+
+ void SetRed( sal_uInt8 nRed );
+ sal_uInt8 GetRed() const { return COLORDATA_RED( mnColor ); }
+ void SetGreen( sal_uInt8 nGreen );
+ sal_uInt8 GetGreen() const { return COLORDATA_GREEN( mnColor ); }
+ void SetBlue( sal_uInt8 nBlue );
+ sal_uInt8 GetBlue() const { return COLORDATA_BLUE( mnColor ); }
+ void SetTransparency( sal_uInt8 nTransparency );
+ sal_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 ); }
+
+ sal_uInt8 GetColorError( const Color& rCompareColor ) const;
+
+ sal_uInt8 GetLuminance() const;
+ void IncreaseLuminance( sal_uInt8 cLumInc );
+ void DecreaseLuminance( sal_uInt8 cLumDec );
+
+ void IncreaseContrast( sal_uInt8 cContInc );
+ void DecreaseContrast( sal_uInt8 cContDec );
+
+ void Invert();
+
+ void Merge( const Color& rMergeColor, sal_uInt8 cTransparency );
+
+ sal_Bool IsRGBEqual( const Color& rColor ) const;
+
+ // comparison with luminance thresholds
+ sal_Bool IsDark() const;
+ sal_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( sal_uInt16 nHue, sal_uInt16 nSat, sal_uInt16 nBri );
+ void RGBtoHSB( sal_uInt16& nHue, sal_uInt16& nSat, sal_uInt16& nBri ) const;
+
+ sal_Bool operator==( const Color& rColor ) const
+ { return (mnColor == rColor.mnColor); }
+ sal_Bool operator!=( const Color& rColor ) const
+ { return !(Color::operator==( rColor )); }
+
+ SvStream& Read( SvStream& rIStm, sal_Bool bNewFormat = sal_True );
+ SvStream& Write( SvStream& rOStm, sal_Bool bNewFormat = sal_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( sal_uInt8 nRed )
+{
+ mnColor &= 0xFF00FFFF;
+ mnColor |= ((sal_uInt32)nRed)<<16;
+}
+
+inline void Color::SetGreen( sal_uInt8 nGreen )
+{
+ mnColor &= 0xFFFF00FF;
+ mnColor |= ((sal_uInt16)nGreen)<<8;
+}
+
+inline void Color::SetBlue( sal_uInt8 nBlue )
+{
+ mnColor &= 0xFFFFFF00;
+ mnColor |= nBlue;
+}
+
+inline void Color::SetTransparency( sal_uInt8 nTransparency )
+{
+ mnColor &= 0x00FFFFFF;
+ mnColor |= ((sal_uInt32)nTransparency)<<24;
+}
+
+inline sal_Bool Color::IsRGBEqual( const Color& rColor ) const
+{
+ return (COLORDATA_RGB( mnColor ) == COLORDATA_RGB( rColor.mnColor ));
+}
+
+inline sal_uInt8 Color::GetLuminance() const
+{
+ return( (sal_uInt8) ( ( COLORDATA_BLUE( mnColor ) * 28UL +
+ COLORDATA_GREEN( mnColor ) * 151UL +
+ COLORDATA_RED( mnColor ) * 77UL ) >> 8UL ) );
+}
+
+inline void Color::Merge( const Color& rMergeColor, sal_uInt8 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
diff --git a/tools/inc/tools/config.hxx b/tools/inc/tools/config.hxx
new file mode 100644
index 000000000000..d0df492f5488
--- /dev/null
+++ b/tools/inc/tools/config.hxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * 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;
+ sal_uIntPtr mnDataUpdateId;
+ sal_uInt16 mnLockCount;
+ sal_Bool mbPersistence;
+ sal_Bool mbDummy1;
+
+#ifdef _CONFIG_CXX
+ TOOLS_DLLPRIVATE sal_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( sal_uInt16 nGroup ) const;
+ sal_uInt16 GetGroupCount() const;
+ sal_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( sal_uInt16 nKey ) const;
+ ByteString ReadKey( sal_uInt16 nKey ) const;
+ sal_uInt16 GetKeyCount() const;
+
+ void EnterLock();
+ void LeaveLock();
+ sal_Bool IsLocked() const { return (mnLockCount != 0); }
+ sal_Bool Update();
+ void Flush();
+
+ void EnablePersistence( sal_Bool bPersistence = sal_True )
+ { mbPersistence = bPersistence; }
+ sal_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
diff --git a/tools/inc/tools/contnr.hxx b/tools/inc/tools/contnr.hxx
new file mode 100644
index 000000000000..804482afaea5
--- /dev/null
+++ b/tools/inc/tools/contnr.hxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * 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 ((sal_uInt16)0x3FF0)
+
+#define CONTAINER_APPEND ULONG_MAX
+#define CONTAINER_ENTRY_NOTFOUND ULONG_MAX
+
+class TOOLS_DLLPUBLIC Container
+{
+private:
+ CBlock* pFirstBlock;
+ CBlock* pCurBlock;
+ CBlock* pLastBlock;
+ sal_uInt16 nCurIndex;
+ sal_uInt16 nBlockSize;
+ sal_uInt16 nInitSize;
+ sal_uInt16 nReSize;
+ sal_uIntPtr 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, sal_uInt16 nIndex );
+ void* ImpRemove( CBlock* pBlock, sal_uInt16 nIndex );
+ void* ImpGetObject( sal_uIntPtr nIndex ) const;
+ void** ImpGetOnlyNodes() const;
+#endif
+ void** GetObjectPtr( sal_uIntPtr nIndex );
+
+public:
+ Container( sal_uInt16 nBlockSize,
+ sal_uInt16 nInitSize,
+ sal_uInt16 nReSize );
+ Container( sal_uIntPtr nSize );
+ Container( const Container& rContainer );
+ ~Container();
+
+ void Insert( void* p );
+ void Insert( void* p, sal_uIntPtr nIndex );
+ void Insert( void* pNew, void* pOld );
+
+ void* Remove();
+ void* Remove( sal_uIntPtr nIndex );
+ void* Remove( void* p )
+ { return Remove( GetPos( p ) ); }
+
+ void* Replace( void* p );
+ void* Replace( void* p, sal_uIntPtr nIndex );
+ void* Replace( void* pNew, void* pOld )
+ { return Replace( pNew, GetPos( pOld ) ); }
+
+ void SetSize( sal_uIntPtr nNewSize );
+ sal_uIntPtr GetSize() const { return nCount; }
+
+ sal_uIntPtr Count() const { return nCount; }
+ void Clear();
+
+ void* GetCurObject() const;
+ sal_uIntPtr GetCurPos() const;
+ void* GetObject( sal_uIntPtr nIndex ) const;
+ sal_uIntPtr GetPos( const void* p ) const;
+ sal_uIntPtr GetPos( const void* p, sal_uIntPtr nStartIndex,
+ sal_Bool bForward = sal_True ) const;
+
+ void* Seek( sal_uIntPtr nIndex );
+ void* Seek( void* p ) { return Seek( GetPos( p ) ); }
+
+ void* First();
+ void* Last();
+ void* Next();
+ void* Prev();
+
+ Container& operator =( const Container& rContainer );
+
+ sal_Bool operator ==( const Container& rContainer ) const;
+ sal_Bool operator !=( const Container& rContainer ) const
+ { return !(Container::operator==( rContainer )); }
+};
+
+#endif // _CONTNR_HXX
diff --git a/tools/inc/tools/date.hxx b/tools/inc/tools/date.hxx
new file mode 100644
index 000000000000..6e4a2291d954
--- /dev/null
+++ b/tools/inc/tools/date.hxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * 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( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 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( sal_uInt16 nNewDay );
+ void SetMonth( sal_uInt16 nNewMonth );
+ void SetYear( sal_uInt16 nNewYear );
+ sal_uInt16 GetDay() const { return (sal_uInt16)(nDate % 100); }
+ sal_uInt16 GetMonth() const { return (sal_uInt16)((nDate / 100) % 100); }
+ sal_uInt16 GetYear() const { return (sal_uInt16)(nDate / 10000); }
+
+ DayOfWeek GetDayOfWeek() const;
+ sal_uInt16 GetDayOfYear() const;
+ /** nMinimumNumberOfDaysInWeek: how many days of a week must reside in the
+ first week of a year. */
+ sal_uInt16 GetWeekOfYear( DayOfWeek eStartDay = MONDAY,
+ sal_Int16 nMinimumNumberOfDaysInWeek = 4 ) const;
+
+ sal_uInt16 GetDaysInMonth() const;
+ sal_uInt16 GetDaysInYear() const { return (IsLeapYear()) ? 366 : 365; }
+ sal_Bool IsLeapYear() const;
+ sal_Bool IsValid() const;
+
+ sal_Bool IsBetween( const Date& rFrom, const Date& rTo ) const
+ { return ((nDate >= rFrom.nDate) &&
+ (nDate <= rTo.nDate)); }
+
+ sal_Bool operator ==( const Date& rDate ) const
+ { return (nDate == rDate.nDate); }
+ sal_Bool operator !=( const Date& rDate ) const
+ { return (nDate != rDate.nDate); }
+ sal_Bool operator >( const Date& rDate ) const
+ { return (nDate > rDate.nDate); }
+ sal_Bool operator <( const Date& rDate ) const
+ { return (nDate < rDate.nDate); }
+ sal_Bool operator >=( const Date& rDate ) const
+ { return (nDate >= rDate.nDate); }
+ sal_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( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear );
+
+};
+
+#endif // _DATE_HXX
diff --git a/tools/inc/tools/datetime.hxx b/tools/inc/tools/datetime.hxx
new file mode 100644
index 000000000000..c642045c0e76
--- /dev/null
+++ b/tools/inc/tools/datetime.hxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * 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 ) {}
+
+ sal_Bool IsBetween( const DateTime& rFrom,
+ const DateTime& rTo ) const;
+
+ sal_Bool IsEqualIgnore100Sec( const DateTime& rDateTime ) const
+ {
+ if ( Date::operator!=( rDateTime ) )
+ return sal_False;
+ return Time::IsEqualIgnore100Sec( rDateTime );
+ }
+
+ sal_Bool operator ==( const DateTime& rDateTime ) const
+ { return (Date::operator==( rDateTime ) &&
+ Time::operator==( rDateTime )); }
+ sal_Bool operator !=( const DateTime& rDateTime ) const
+ { return (Date::operator!=( rDateTime ) ||
+ Time::operator!=( rDateTime )); }
+ sal_Bool operator >( const DateTime& rDateTime ) const;
+ sal_Bool operator <( const DateTime& rDateTime ) const;
+ sal_Bool operator >=( const DateTime& rDateTime ) const;
+ sal_Bool operator <=( const DateTime& rDateTime ) const;
+
+ long GetSecFromDateTime( const Date& rDate ) const;
+ void MakeDateTimeFromSec( const Date& rDate, sal_uIntPtr 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
diff --git a/tools/inc/tools/debug.hxx b/tools/inc/tools/debug.hxx
new file mode 100644
index 000000000000..63a94555a8c1
--- /dev/null
+++ b/tools/inc/tools/debug.hxx
@@ -0,0 +1,783 @@
+/*************************************************************************
+ *
+ * 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"
+
+#ifndef _SAL_TYPES_H
+#include <sal/types.h>
+#endif
+#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_ABORT 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
+{
+ sal_uIntPtr nTestFlags;
+ sal_uIntPtr bOverwrite;
+ sal_uIntPtr nTraceOut;
+ sal_uIntPtr nWarningOut;
+ sal_uIntPtr nErrorOut;
+ sal_uIntPtr bHookOSLAssert;
+ sal_uInt8 bMemInit;
+ sal_uInt8 bMemBound;
+ sal_uInt8 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
+#define DBG_FUNC_SET_ABORT 20
+
+TOOLS_DLLPUBLIC void* DbgFunc( sal_uInt16 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 );
+}
+
+inline void DbgSetAbort( DbgPrintLine pProc )
+{
+ DbgFunc( DBG_FUNC_SET_ABORT, (void*)(long)pProc );
+}
+
+typedef sal_uInt16 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 sal_Bool DbgFilterMessage( const char* pMsg )
+{
+ return (sal_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 sal_uIntPtr DbgIsTraceOut()
+{
+ DbgData* pData = DbgGetData();
+ if ( pData )
+ return (pData->nTraceOut != DBG_OUT_NULL);
+ else
+ return sal_False;
+}
+
+inline sal_uIntPtr DbgIsWarningOut()
+{
+ DbgData* pData = DbgGetData();
+ if ( pData )
+ return (pData->nWarningOut != DBG_OUT_NULL);
+ else
+ return sal_False;
+}
+
+inline sal_uIntPtr DbgIsErrorOut()
+{
+ DbgData* pData = DbgGetData();
+ if ( pData )
+ return (pData->nErrorOut != DBG_OUT_NULL);
+ else
+ return sal_False;
+}
+
+inline sal_uIntPtr DbgGetErrorOut() // Testtool: test wether to collect OSL_ASSERTions as well
+{
+ DbgData* pData = DbgGetData();
+ if ( pData )
+ return pData->nErrorOut;
+ else
+ return DBG_OUT_NULL;
+}
+
+inline sal_uIntPtr DbgIsAssertWarning()
+{
+ return DbgIsWarningOut();
+}
+
+inline sal_uIntPtr DbgIsAssert()
+{
+ return DbgIsErrorOut();
+}
+
+inline sal_uIntPtr DbgIsResource()
+{
+ DbgData* pData = DbgGetData();
+ if ( pData )
+ return pData->nTestFlags & DBG_TEST_RESOURCE;
+ else
+ return sal_False;
+}
+
+inline sal_uIntPtr DbgIsDialog()
+{
+ DbgData* pData = DbgGetData();
+ if ( pData )
+ return pData->nTestFlags & DBG_TEST_DIALOG;
+ else
+ return sal_False;
+}
+
+inline sal_uIntPtr DbgIsBoldAppFont()
+{
+ DbgData* pData = DbgGetData();
+ if ( pData )
+ return pData->nTestFlags & DBG_TEST_BOLDAPPFONT;
+ else
+ return sal_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( sal_uIntPtr nAlloc = 0 );
+void DbgFreeStackTree( void* p, sal_uIntPtr 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, sal_uInt16 nOutType = DBG_OUT_TRACE,
+ const sal_Char* pFile = NULL, sal_uInt16 nLine = 0 );
+TOOLS_DLLPUBLIC void DbgPrintShell(char const * message);
+TOOLS_DLLPUBLIC void DbgOutTypef( sal_uInt16 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, sal_uInt16 nLine = 0 )
+{
+ DbgOut( pMsg, DBG_OUT_TRACE, pFile, nLine );
+}
+
+inline void DbgWarning( const sal_Char* pMsg,
+ const sal_Char* pFile = NULL, sal_uInt16 nLine = 0 )
+{
+ DbgOut( pMsg, DBG_OUT_WARNING, pFile, nLine );
+}
+
+inline void DbgError( const sal_Char* pMsg,
+ const sal_Char* pFile = NULL, sal_uInt16 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( sal_uInt16 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,
+ sal_uInt16 nAction, const void* pThis, DbgUsr fDbgUsr );
+
+class DbgXtorObj
+{
+private:
+ DbgDataType* pDbgData;
+ const void* pThis;
+ DbgUsr fDbgUsr;
+ sal_uInt16 nAction;
+
+public:
+ DbgXtorObj( DbgDataType* pData,
+ sal_uInt16 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
diff --git a/tools/inc/tools/diagnose_ex.h b/tools/inc/tools/diagnose_ex.h
new file mode 100644
index 000000000000..b244d11dc305
--- /dev/null
+++ b/tools/inc/tools/diagnose_ex.h
@@ -0,0 +1,175 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/inc/tools/dynary.hxx b/tools/inc/tools/dynary.hxx
new file mode 100644
index 000000000000..d7ed083b8e44
--- /dev/null
+++ b/tools/inc/tools/dynary.hxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * 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( sal_uIntPtr nSize = 16 ) : Container( nSize ) {}
+ DynArray( const DynArray& rAry ) : Container( rAry ) {}
+
+ void* Put( sal_uIntPtr nIndex, void* p )
+ { return Container::Replace( p, nIndex ); }
+ void* Get( sal_uIntPtr nIndex ) const
+ { return Container::GetObject( nIndex ); }
+
+ sal_uIntPtr GetIndex( const void* p ) const
+ { return Container::GetPos( p ); }
+ sal_uIntPtr GetIndex( const void* p, sal_uIntPtr nStartIndex,
+ sal_Bool bForward = sal_True ) const
+ { return Container::GetPos( p, nStartIndex, bForward ); }
+
+ DynArray& operator =( const DynArray& rAry )
+ { Container::operator =( rAry ); return *this; }
+
+ sal_Bool operator ==( const DynArray& rAry ) const
+ { return Container::operator ==( rAry ); }
+ sal_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( sal_uIntPtr nSize = 16 ) : \
+ DynArray( nSize ) {} \
+ ClassName( const ClassName& rClassName ) : \
+ DynArray( rClassName ) {} \
+ \
+ Type Put( sal_uIntPtr nIndex, Type p ) \
+ { return (Type)DynArray::Put( nIndex, (void*)p ); } \
+ Type Get( sal_uIntPtr nIndex ) const \
+ { return (Type)DynArray::Get( nIndex ); } \
+ \
+ sal_uIntPtr GetIndex( const Type p ) const \
+ { return DynArray::GetIndex( (const void*)p ); } \
+ sal_uIntPtr GetIndex( const Type p, sal_uIntPtr nStartIndex, \
+ sal_Bool bForward = sal_True ) const \
+ { return DynArray::GetIndex( (const void*)p, \
+ nStartIndex, \
+ bForward ); } \
+ \
+ ClassName& operator =( const ClassName& rClassName ) \
+ { DynArray::operator =( rClassName ); \
+ return *this; } \
+ \
+ sal_Bool operator ==( const ClassName& rAry ) const \
+ { return DynArray::operator ==( rAry ); } \
+ sal_Bool operator !=( const ClassName& rAry ) const \
+ { return DynArray::operator !=( rAry ); } \
+};
+
+#endif // _DYNARY_HXX
diff --git a/tools/inc/tools/errcode.hxx b/tools/inc/tools/errcode.hxx
new file mode 100644
index 000000000000..404ce7bd6e34
--- /dev/null
+++ b/tools/inc/tools/errcode.hxx
@@ -0,0 +1,323 @@
+/*************************************************************************
+ *
+ * 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
+#ifndef _SOLAR_H
+#include <tools/solar.h>
+#endif
+#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 sal_uIntPtr ErrCode;
+
+inline sal_uIntPtr ERRCODE_TOERRID( sal_uIntPtr x )
+{
+ return x & ~ERRCODE_DYNAMIC_MASK;
+}
+
+inline sal_uIntPtr ERRCODE_TOERROR( sal_uIntPtr 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
diff --git a/tools/inc/tools/errinf.hxx b/tools/inc/tools/errinf.hxx
new file mode 100644
index 000000000000..e059a7add067
--- /dev/null
+++ b/tools/inc/tools/errinf.hxx
@@ -0,0 +1,243 @@
+/*************************************************************************
+ *
+ * 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:
+ sal_uIntPtr lUserId;
+
+public:
+ TYPEINFO();
+
+ ErrorInfo( sal_uIntPtr lArgUserId ) :
+ lUserId( lArgUserId ){}
+ virtual ~ErrorInfo(){}
+
+ sal_uIntPtr GetErrorCode() const { return lUserId; }
+
+ static ErrorInfo* GetErrorInfo(sal_uIntPtr);
+};
+
+
+// --------------------
+// - DynamicErrorInfo -
+// --------------------
+
+class TOOLS_DLLPUBLIC DynamicErrorInfo : public ErrorInfo
+{
+ friend class EDcr_Impl;
+
+private:
+ EDcr_Impl* pImpl;
+
+public:
+ TYPEINFO();
+
+ DynamicErrorInfo(sal_uIntPtr lUserId, sal_uInt16 nMask);
+ virtual ~DynamicErrorInfo();
+
+ operator sal_uIntPtr() const;
+ sal_uInt16 GetDialogMask() const;
+};
+
+
+// ---------------------
+// - StandardErrorInfo -
+// ---------------------
+
+class StandardErrorInfo : public DynamicErrorInfo
+{
+private:
+ sal_uIntPtr lExtId;
+
+public:
+ TYPEINFO();
+
+ StandardErrorInfo( sal_uIntPtr lUserId, sal_uIntPtr lExtId,
+ sal_uInt16 nFlags = 0);
+ sal_uIntPtr GetExtendedErrorCode() const { return lExtId; }
+
+};
+
+
+// -------------------
+// - StringErrorInfo -
+// -------------------
+
+class TOOLS_DLLPUBLIC StringErrorInfo : public DynamicErrorInfo
+{
+private:
+ String aString;
+
+public:
+ TYPEINFO();
+
+ StringErrorInfo( sal_uIntPtr lUserId,
+ const String& aStringP,
+ sal_uInt16 nFlags = 0);
+ const String& GetErrorString() const { return aString; }
+};
+
+//=============================================================================
+class TOOLS_DLLPUBLIC TwoStringErrorInfo: public DynamicErrorInfo
+{
+private:
+ String aArg1;
+ String aArg2;
+
+public:
+ TYPEINFO();
+
+ TwoStringErrorInfo(sal_uIntPtr nUserID, const String & rTheArg1,
+ const String & rTheArg2, sal_uInt16 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(sal_uIntPtr UserId, sal_uInt16 nFlags = 0) :
+ DynamicErrorInfo(UserId, nFlags){}
+ MessageInfo(sal_uIntPtr UserId, const String &rArg,
+ sal_uInt16 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 sal_Bool GetString( sal_uIntPtr nErrId, String& rCtxStr ) = 0;
+ Window* GetParent() { return pWin; }
+
+ static ErrorContext* GetContext();
+};
+
+
+// ----------------
+// - ErrorHandler -
+// ----------------
+
+typedef sal_uInt16 WindowDisplayErrorFunc(
+ Window *, sal_uInt16 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 sal_uInt16 HandleError_Impl( sal_uIntPtr lId,
+ sal_uInt16 nFlags,
+ sal_Bool bJustCreateString,
+ String & rError);
+protected:
+ virtual sal_Bool CreateString( const ErrorInfo *,
+ String &, sal_uInt16& nMask ) const = 0;
+ sal_Bool ForwCreateString( const ErrorInfo*,
+ String&, sal_uInt16& nMask ) const;
+
+public:
+ ErrorHandler();
+ virtual ~ErrorHandler();
+
+ static sal_uInt16 HandleError ( sal_uIntPtr lId, sal_uInt16 nMask = USHRT_MAX );
+ static sal_Bool GetErrorString( sal_uIntPtr lId, String& rStr );
+
+ static void RegisterDisplay( BasicDisplayErrorFunc* );
+ static void RegisterDisplay( WindowDisplayErrorFunc* );
+};
+
+
+// ----------------------
+// - SimpleErrorHandler -
+// ----------------------
+
+class TOOLS_DLLPUBLIC SimpleErrorHandler : private ErrorHandler
+{
+protected:
+ virtual sal_Bool CreateString( const ErrorInfo*, String &,
+ sal_uInt16 &nMask ) const;
+
+public:
+ SimpleErrorHandler();
+
+};
+
+#endif
+#endif
diff --git a/tools/inc/tools/extendapplicationenvironment.hxx b/tools/inc/tools/extendapplicationenvironment.hxx
new file mode 100644
index 000000000000..05eac33effba
--- /dev/null
+++ b/tools/inc/tools/extendapplicationenvironment.hxx
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/inc/tools/fldunit.hxx b/tools/inc/tools/fldunit.hxx
new file mode 100644
index 000000000000..0154b4403501
--- /dev/null
+++ b/tools/inc/tools/fldunit.hxx
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * 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 -
+// --------------
+
+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_CUSTOM,
+ FUNIT_PERCENT, FUNIT_100TH_MM };
+
+#endif // _TOOLS_FLDUNIT_HXX
diff --git a/tools/inc/tools/fontenum.hxx b/tools/inc/tools/fontenum.hxx
new file mode 100644
index 000000000000..54611c8f7c25
--- /dev/null
+++ b/tools/inc/tools/fontenum.hxx
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *
+ * 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 sal_uInt16 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
diff --git a/tools/inc/tools/fract.hxx b/tools/inc/tools/fract.hxx
new file mode 100644
index 000000000000..249f1723097b
--- /dev/null
+++ b/tools/inc/tools/fract.hxx
@@ -0,0 +1,165 @@
+/*************************************************************************
+ *
+ * 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 );
+
+ sal_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 sal_Bool operator==( const Fraction& rVal1, const Fraction& rVal2 );
+ friend sal_Bool operator!=( const Fraction& rVal1, const Fraction& rVal2 );
+ friend sal_Bool operator< ( const Fraction& rVal1, const Fraction& rVal2 );
+ friend sal_Bool operator> ( const Fraction& rVal1, const Fraction& rVal2 );
+ friend sal_Bool operator<=( const Fraction& rVal1, const Fraction& rVal2 );
+ friend sal_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 sal_Bool operator==( const Fraction& rVal1, const Fraction& rVal2 );
+ friend inline sal_Bool operator!=( const Fraction& rVal1, const Fraction& rVal2 );
+ TOOLS_DLLPUBLIC friend sal_Bool operator< ( const Fraction& rVal1, const Fraction& rVal2 );
+ TOOLS_DLLPUBLIC friend sal_Bool operator> ( const Fraction& rVal1, const Fraction& rVal2 );
+ friend inline sal_Bool operator<=( const Fraction& rVal1, const Fraction& rVal2 );
+ friend inline sal_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 sal_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 sal_Bool operator !=( const Fraction& rVal1, const Fraction& rVal2 )
+{
+ return !(rVal1 == rVal2);
+}
+
+inline sal_Bool operator <=( const Fraction& rVal1, const Fraction& rVal2 )
+{
+ return !(rVal1 > rVal2);
+}
+
+inline sal_Bool operator >=( const Fraction& rVal1, const Fraction& rVal2 )
+{
+ return !(rVal1 < rVal2);
+}
+
+#endif // _FRACT_HXX
diff --git a/tools/inc/tools/fsys.hxx b/tools/inc/tools/fsys.hxx
new file mode 100644
index 000000000000..9507fdb15faa
--- /dev/null
+++ b/tools/inc/tools/fsys.hxx
@@ -0,0 +1,564 @@
+/*************************************************************************
+ *
+ * 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>
+#ifndef __ERRCODE_HXX
+#include <tools/errcode.hxx>
+#endif
+#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 sal_uIntPtr FSysError;
+
+// FSysExact
+enum FSysExact
+{
+ FSYS_NOTEXACT,
+ FSYS_EXACT
+};
+
+// ------------
+// - Char-Set -
+// ------------
+
+// Was different for WIN, no longer needed...
+#define GUI2FSYS(s) s
+#define FSYS2GUI(s) s
+
+
+// ------------
+// - FileStat -
+// ------------
+
+struct dirent;
+class TOOLS_DLLPUBLIC FileStat
+{
+ friend class CORmFSys;
+ friend class Dir;
+ friend struct DirReader_Impl;
+ friend void ImpInitFileStat( FileStat&, dirent* );
+
+ sal_uIntPtr nError;
+ DirEntryKind nKindFlags;
+ sal_uIntPtr 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 );
+ sal_Bool Update( const DirEntry& rDirEntry,
+ sal_Bool bForceAccess = sal_True );
+
+ sal_uIntPtr GetError() const { return ERRCODE_TOERROR(nError); }
+ sal_uIntPtr GetErrorCode() const { return nError; }
+
+ sal_uIntPtr GetSize() const { return nSize; }
+
+ DirEntryKind GetKind() const { return nKindFlags; }
+ sal_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; }
+ sal_Bool IsYounger( const FileStat& rIsOlder ) const;
+
+#define TF_FSYS_READONLY_FLAG
+ static sal_uIntPtr SetReadOnlyFlag( const DirEntry &rEntry, sal_Bool bRO = sal_True );
+ static sal_Bool GetReadOnlyFlag( const DirEntry &rEntry );
+ static sal_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;
+ sal_uIntPtr nError;
+ DirEntryFlag eFlag;
+
+private:
+ TOOLS_DLLPRIVATE DirEntry( const ByteString& rInitName,
+ DirEntryFlag aDirFlag,
+ FSysPathStyle eStyle );
+
+//#if 0 // _SOLAR__PRIVATE
+
+ 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 sal_uInt16 ImpTryUrl( DirEntryStack& rStack, const String& rPfad, FSysPathStyle eStyle );
+ TOOLS_DLLPRIVATE const DirEntry* ImpGetTopPtr() const;
+ TOOLS_DLLPRIVATE DirEntry* ImpGetTopPtr();
+ TOOLS_DLLPRIVATE DirEntry* ImpGetPreTopPtr();
+ TOOLS_DLLPRIVATE sal_Bool ImpToRel( String aStart );
+
+protected:
+ void ImpTrim( FSysPathStyle eStyle );
+ const ByteString& ImpTheName() const;
+ DirEntryFlag ImpTheFlag() const { return eFlag; };
+ DirEntry* ImpChangeParent( DirEntry* pNewParent, sal_Bool bNormalize = sal_True );
+ DirEntry* ImpGetParent() { return pParent; }
+#ifdef FEAT_FSYS_DOUBLESPEED
+ FileStat* ImpGetStat() const { return pStat; }
+ void ImpSetStat( FileStat *p ) { pStat = p; }
+#endif
+
+//#endif
+
+protected:
+ void SetError( sal_uIntPtr 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();
+
+ sal_Bool IsLongNameOnFAT() const;
+ sal_Bool IsCaseSensitive (FSysPathStyle eFormatter = FSYS_STYLE_HOST) const;
+
+ sal_uIntPtr GetError() const { return nError; }
+ sal_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,
+ sal_Bool bWithDelimiter = sal_False,
+ sal_uInt16 nMaxChars = STRING_MAXLEN ) const;
+
+ DirEntry TempName( DirEntryKind = FSYS_KIND_NONE ) const;
+ static const DirEntry& SetTempNameBase( const String &rBaseName );
+ sal_Bool MakeShortName( const String& rLongName,
+ DirEntryKind eCreateKind = FSYS_KIND_NONE,
+ sal_Bool bUseTilde = sal_True,
+ FSysPathStyle eStyle = FSYS_STYLE_DETECT );
+
+ bool IsAbs() const;
+ sal_Bool ToAbs();
+ sal_Bool Find( const String& rPfad, char cDelim = 0 );
+ sal_Bool ToRel();
+ sal_Bool ToRel( const DirEntry& rRefDir );
+ sal_uInt16 CutRelParents();
+
+ sal_Bool SetCWD( sal_Bool bSloppy = sal_False ) const;
+ sal_Bool MakeDir( sal_Bool bSloppy = sal_False ) const;
+ sal_Bool Exists( FSysAccess nAccess = FSYS_ACCESS_FLOPPY ) const;
+ sal_Bool First();
+
+ sal_uInt16 Level() const;
+ const DirEntry& operator []( sal_uInt16 nParentLevel ) const;
+ sal_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 );
+ sal_Bool operator ==( const DirEntry& rAnotherDir ) const;
+ sal_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 sal_uInt16 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 sal_Bool IsRFSAvailable();
+};
+
+// --------------
+// - FileCopier -
+// --------------
+
+class TOOLS_DLLPUBLIC FileCopier
+{
+ DirEntry aSource;
+ DirEntry aTarget;
+ sal_uIntPtr nBytesTotal;
+ sal_uIntPtr nBytesCopied;
+ Link aProgressLink;
+ sal_uInt16 nBlockSize;
+ FileCopier_Impl* pImp;
+
+private:
+ TOOLS_DLLPRIVATE FSysError DoCopy_Impl(
+ const DirEntry &rSource, const DirEntry &rTarget );
+
+protected:
+ virtual sal_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( sal_uInt16 nBytes ) { nBlockSize = nBytes; }
+ sal_uInt16 GetBlockSize() const { return nBlockSize; }
+
+ sal_uIntPtr GetBytesTotal() const { return nBytesTotal; }
+ sal_uIntPtr 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:
+ sal_Bool ImpInsertPointReached( const DirEntry& rIsSmaller,
+ const FileStat& rNewStat,
+ sal_uIntPtr nCurPos,
+ sal_uIntPtr 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();
+ sal_uInt16 Scan( sal_uInt16 nCount = 5 );
+ sal_uInt16 Count( sal_Bool bUpdated = sal_True ) const;
+ sal_Bool Update();
+
+ Dir& operator +=( const Dir& rDir );
+ DirEntry& operator []( sal_uInt16 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 sal_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 sal_Bool<BR>
+ sal_True, if the path is redirected
+ sal_False, if the path is not redirected (unchanged)
+ */
+ static void DoRedirect( String &rPath );
+};
+
+#endif // BOOTSTRP
+
+//========================================================================
+
+void FSysEnableSysErrorBox( sal_Bool bEnable );
+
+//========================================================================
+
+#if defined(DBG_UTIL)
+void FSysTest();
+#endif
+
+#endif // #ifndef _FSYS_HXX
+
diff --git a/tools/inc/tools/gen.hxx b/tools/inc/tools/gen.hxx
new file mode 100644
index 000000000000..360ecdf98325
--- /dev/null
+++ b/tools/inc/tools/gen.hxx
@@ -0,0 +1,712 @@
+/*************************************************************************
+ *
+ * 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; }
+
+ sal_Bool operator == ( const Pair& rPair ) const;
+ sal_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 sal_Bool Pair::operator == ( const Pair& rPair ) const
+{
+ return ((nA == rPair.nA) && (nB == rPair.nB));
+}
+
+inline sal_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 );
+ sal_Bool IsAbove( const Point& rPoint ) const;
+ sal_Bool IsBelow( const Point& rPoint ) const;
+ sal_Bool IsLeft( const Point& rPoint ) const;
+ sal_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 sal_Bool Point::IsAbove( const Point& rPoint ) const
+{
+ return (nB > rPoint.nB);
+}
+
+inline sal_Bool Point::IsBelow( const Point& rPoint ) const
+{
+ return (nB < rPoint.nB);
+}
+
+inline sal_Bool Point::IsLeft( const Point& rPoint ) const
+{
+ return (nA < rPoint.nA);
+}
+
+inline sal_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; }
+
+ sal_Bool IsInside( long nIs ) const;
+
+ void Justify();
+};
+
+inline Range::Range()
+{
+}
+
+inline Range::Range( long nMin, long nMax ) : Pair( nMin, nMax )
+{
+}
+
+inline sal_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; }
+
+ sal_Bool IsInside( long nIs ) const;
+
+ void Justify();
+
+ sal_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 sal_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();
+
+ sal_Bool IsInside( const Point& rPOINT ) const;
+ sal_Bool IsInside( const Rectangle& rRect ) const;
+ sal_Bool IsOver( const Rectangle& rRect ) const;
+
+ void SetEmpty() { nRight = nBottom = RECT_EMPTY; }
+ sal_Bool IsEmpty() const;
+
+ sal_Bool operator == ( const Rectangle& rRect ) const;
+ sal_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 sal_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 sal_Bool Rectangle::operator == ( const Rectangle& rRect ) const
+{
+ return ((nLeft == rRect.nLeft ) &&
+ (nTop == rRect.nTop ) &&
+ (nRight == rRect.nRight ) &&
+ (nBottom == rRect.nBottom ));
+}
+
+inline sal_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
diff --git a/tools/inc/tools/geninfo.hxx b/tools/inc/tools/geninfo.hxx
new file mode 100644
index 000000000000..889d8c1713cc
--- /dev/null
+++ b/tools/inc/tools/geninfo.hxx
@@ -0,0 +1,230 @@
+/*************************************************************************
+ *
+ * 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, sal_Bool bCopySubs = sal_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
+ sal_Bool InsertSubInfo( GenericInformation *pInfo );
+ // siehe GenericInformationList
+ sal_Bool InsertSubInfo( const ByteString &rPathKey, const ByteString &rValue,
+ sal_Bool bSearchByPath = sal_False, sal_Bool bNewPath = sal_False);
+ void RemoveSubInfo( GenericInformation *pInfo, sal_Bool bDelete = sal_False );
+ // void RemoveSelf( sal_Bool bDelete = sal_False ); // loescht sich selbst aus der Parentliste
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // bei bDelete = sal_True werden auch alle Sublisten UND DIE INFO SELBST geloescht.
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ GenericInformation *GetSubInfo( ByteString &rKey, sal_Bool bSearchByPath = sal_False,
+ sal_Bool bCreatePath = sal_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
+ */
+ sal_Bool SetWriteLock(sal_uInt32 nKey = 0) { return ((read==aLockState) &&
+ (aLockState=writeonly, nLockKey=nKey, sal_True)); }
+ /* Schreibschutz darf nur geloest werden, wenn
+ * der Schreibschutz drin ist, und
+ * entweder der LockKey Null ist(Generalschluessel) oder der Key zum LockKey passt
+ */
+ sal_Bool ReleaseWriteLock(sal_uInt32 nKey = 0) { return ((writeonly==aLockState) &&
+ (!nLockKey||nKey==nLockKey) &&
+ (aLockState=read, nLockKey=0, sal_True)); } // setzt den zustand auf "read"
+ sal_Bool SetReadLock(sal_uInt32 nKey = 0) { return ((read==aLockState) &&
+ (aLockState=readonly, nLockKey=nKey, sal_True)); }
+ sal_Bool ReleaseReadLock(sal_uInt32 nKey = 0) { return ((readonly==aLockState) &&
+ (!nLockKey||nKey==nLockKey) &&
+ (aLockState=read, nLockKey=0, sal_True)); } // setzt den zustand auf "read"
+
+ LockState GetLockState() const { return aLockState; }
+ sal_Bool IsWriteLocked() const { return (writeonly==aLockState); }
+ sal_Bool IsReadLocked() const { return (readonly==aLockState); }
+ sal_Bool IsNotLocked() const { return (read==aLockState); }
+ sal_Bool IsLocker( sal_uInt32 nKey ) { return (nKey==nLockKey || !nLockKey); }
+
+ /* wenn der Schreibschutz aktiviert wurde,
+ * und bei vorhandenem Schreibschutz die Keys stimmen
+ * rufe die Parentmethode auf */
+ sal_Bool InsertSubInfo( GenericInformation *pInfo, sal_uInt32 nKey = 0 ) {
+ return ((writeonly==aLockState) &&
+ (!nLockKey || nKey==nLockKey) &&
+ (GenericInformation::InsertSubInfo( pInfo ), sal_True)); }
+
+ sal_Bool InsertSubInfo( const ByteString &rPathKey, const ByteString &rValue, sal_uInt32 nKey = 0,
+ sal_Bool bSearchByPath = sal_False, sal_Bool bNewPath = sal_False) {
+ return ((writeonly==aLockState) &&
+ (!nLockKey || nKey==nLockKey) &&
+ (GenericInformation::InsertSubInfo( rPathKey, rValue, bSearchByPath, bNewPath ), sal_True)); }
+ /* 29.jan.98: erweiterung um lesemoeglichkeit vom Lockclienten */
+ GenericInformation *GetSubInfo( ByteString &rKey, sal_Bool bSearchByPath = sal_False,
+ sal_Bool bCreatePath = sal_False, sal_uInt32 nKey = 0 ) {
+ if (writeonly==aLockState && nLockKey && nKey!=nLockKey )
+ return NULL;
+ return GenericInformation::GetSubInfo(rKey, bSearchByPath, bCreatePath); }
+
+ // TYPEINFO();
+private:
+
+ LockState aLockState;
+ sal_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
+ sal_uIntPtr InsertSorted( GenericInformation *pInfo, sal_Bool bOverwrite,
+ sal_uIntPtr nStart, sal_uIntPtr nEnd );
+ GenericInformation *Search( sal_uIntPtr &rPos, ByteString sKey,
+ sal_uIntPtr nStart, sal_uIntPtr 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, sal_Bool bSearchByPath = sal_False,
+ sal_Bool bCreatePath = sal_False );
+ /* path can be something like this: src370/drives/o:
+ * bCreatePath will create the neccecary paths to the GI */
+
+ sal_Bool InsertInfo( GenericInformation *pInfo, sal_Bool bOverwrite = sal_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 sal_False zurueck.*/
+ sal_Bool InsertInfo( const ByteString &rPathKey, const ByteString &rValue,
+ sal_Bool bSearchByPath = sal_False, sal_Bool bNewPath = sal_False);
+ void RemoveInfo( GenericInformation *pInfo, sal_Bool bDelete = sal_False );
+
+ GenericInformation* SetOwner( GenericInformation *pNewOwner );
+
+};
+
+#endif
+
diff --git a/tools/inc/tools/getprocessworkingdir.hxx b/tools/inc/tools/getprocessworkingdir.hxx
new file mode 100644
index 000000000000..1b0688379590
--- /dev/null
+++ b/tools/inc/tools/getprocessworkingdir.hxx
@@ -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.
+ *
+ ************************************************************************/
+
+#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
diff --git a/tools/inc/tools/globname.hxx b/tools/inc/tools/globname.hxx
new file mode 100755
index 000000000000..026e4c51b9ac
--- /dev/null
+++ b/tools/inc/tools/globname.hxx
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * 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
+{
+ sal_uInt8 szData[ 16 ];
+ sal_uInt16 nRefCount;
+
+ ImpSvGlobalName()
+ {
+ nRefCount = 0;
+ }
+ ImpSvGlobalName( const ImpSvGlobalName & rObj );
+ ImpSvGlobalName( int );
+
+ sal_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( sal_uInt32 n1, sal_uInt16 n2, sal_uInt16 n3,
+ sal_uInt8 b8, sal_uInt8 b9, sal_uInt8 b10, sal_uInt8 b11,
+ sal_uInt8 b12, sal_uInt8 b13, sal_uInt8 b14, sal_uInt8 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 & );
+
+ sal_Bool operator < ( const SvGlobalName & rObj ) const;
+ SvGlobalName & operator += ( sal_uInt32 );
+ SvGlobalName & operator ++ () { return operator += ( 1 ); }
+
+ sal_Bool operator == ( const SvGlobalName & rObj ) const;
+ sal_Bool operator != ( const SvGlobalName & rObj ) const
+ { return !(*this == rObj); }
+
+ void MakeFromMemory( void * pData );
+ sal_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 sal_uInt8* 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( sal_uLong );
+ sal_Bool IsEntry( const SvGlobalName & rName );
+ sal_uInt32 Count() const { return aList.Count(); }
+private:
+ // nicht erlaubt
+ SvGlobalNameList( const SvGlobalNameList & );
+ SvGlobalNameList & operator = ( const SvGlobalNameList & );
+};
+
+#endif // _GLOBNAME_HXX
+
diff --git a/tools/inc/tools/inetdef.hxx b/tools/inc/tools/inetdef.hxx
new file mode 100644
index 000000000000..7341225912ab
--- /dev/null
+++ b/tools/inc/tools/inetdef.hxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * 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 x86"
+#elif defined NETBSD && defined ARM32
+#define TOOLS_INETDEF_OS "NETBSD ARM32"
+#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 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
+
diff --git a/tools/inc/tools/inetmime.hxx b/tools/inc/tools/inetmime.hxx
new file mode 100755
index 000000000000..2408bf231665
--- /dev/null
+++ b/tools/inc/tools/inetmime.hxx
@@ -0,0 +1,1445 @@
+/*************************************************************************
+ *
+ * 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, sal_uIntPtr nIndex)
+ { List::Insert(pParameter, nIndex); }
+
+ inline const INetContentTypeParameter * GetObject(sal_uIntPtr nIndex) const;
+
+ const INetContentTypeParameter * find(const ByteString & rAttribute)
+ const;
+};
+
+inline const INetContentTypeParameter *
+INetContentTypeParameterList::GetObject(sal_uIntPtr nIndex) const
+{
+ return static_cast< INetContentTypeParameter * >(List::GetObject(nIndex));
+}
+
+#endif // TOOLS_INETMIME_HXX
+
diff --git a/tools/inc/tools/inetmsg.hxx b/tools/inc/tools/inetmsg.hxx
new file mode 100644
index 000000000000..1f14a67b62a7
--- /dev/null
+++ b/tools/inc/tools/inetmsg.hxx
@@ -0,0 +1,623 @@
+/*************************************************************************
+ *
+ * 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>
+
+#ifndef _RTL_TEXTENC_H_
+#include <rtl/textenc.h>
+#endif
+
+#ifndef _TOOLS_INETMIME_HXX
+#include <tools/inetmime.hxx>
+#endif
+#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;
+
+ sal_uIntPtr m_nDocSize;
+ UniString m_aDocName;
+ SvLockBytesRef m_xDocLB;
+
+ void ListCleanup_Impl (void);
+ void ListCopy (const INetMessage& rMsg);
+
+protected:
+ UniString GetHeaderName_Impl (
+ sal_uIntPtr 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 (
+ sal_uIntPtr 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, sal_uIntPtr &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,
+ sal_uIntPtr &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;
+ }
+
+ sal_uIntPtr GetHeaderCount (void) const { return m_aHeaderList.Count(); }
+
+ UniString GetHeaderName (sal_uIntPtr nIndex) const
+ {
+ return GetHeaderName_Impl (nIndex, RTL_TEXTENCODING_ASCII_US);
+ }
+
+ UniString GetHeaderValue (sal_uIntPtr nIndex) const
+ {
+ return GetHeaderValue_Impl (nIndex, INetMIME::HEADER_FIELD_TEXT);
+ }
+
+ INetMessageHeader GetHeaderField (sal_uIntPtr nIndex) const
+ {
+ INetMessageHeader *p =
+ (INetMessageHeader*)(m_aHeaderList.GetObject(nIndex));
+ if (p)
+ return INetMessageHeader(*p);
+ else
+ return INetMessageHeader();
+ }
+
+ sal_uIntPtr SetHeaderField (
+ const UniString& rName,
+ const UniString& rValue,
+ sal_uIntPtr nIndex = LIST_APPEND);
+
+ virtual sal_uIntPtr SetHeaderField (
+ const INetMessageHeader &rField, sal_uIntPtr nIndex = LIST_APPEND);
+
+ sal_uIntPtr GetDocumentSize (void) const { return m_nDocSize; }
+ void SetDocumentSize (sal_uIntPtr 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
+{
+ sal_uIntPtr nValueCount;
+ List aValueList;
+ UniString aEmptyString;
+
+public:
+ INetMessageHeaderIterator (
+ const INetMessage& rMsg, const UniString& rHdrName);
+ virtual ~INetMessageHeaderIterator (void);
+
+ sal_uIntPtr GetValueCount (void) const { return nValueCount; }
+ const UniString& GetValue (sal_uIntPtr 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
+{
+ sal_uIntPtr 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 sal_Bool GenerateDateField (
+ const DateTime& rDateTime, UniString& rDateField);
+ static sal_Bool ParseDateField (
+ const UniString& rDateField, DateTime& rDateTime);
+
+ using INetMessage::SetHeaderField;
+ virtual sal_uIntPtr SetHeaderField (
+ const INetMessageHeader &rHeader, sal_uIntPtr 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
+{
+ sal_uIntPtr m_nIndex[INETMSG_MIME_NUMHDR];
+
+ INetMIMEMessage *pParent;
+ sal_uIntPtr nNumChildren;
+ List aChildren;
+ ByteString m_aBoundary;
+ sal_Bool bHeaderParsed;
+
+ friend class INetMIMEMessageStream;
+
+ void SetChildCount (sal_uIntPtr 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 = sal_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);
+
+ sal_Bool HeaderParsed() const { return bHeaderParsed; }
+
+ virtual INetMIMEMessage* CreateMessage (
+ const INetMIMEMessage& rMsg) const;
+
+ using INetRFC822Message::SetHeaderField;
+ virtual sal_uIntPtr SetHeaderField (
+ const INetMessageHeader &rHeader, sal_uIntPtr 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.
+ */
+ sal_Bool IsContainer (void) const
+ {
+ return (IsMessage() || IsMultipart());
+ }
+ sal_Bool IsMessage (void) const
+ {
+ UniString aType (GetContentType());
+ return (aType.CompareIgnoreCaseToAscii("message/", 8) == 0);
+ }
+ sal_Bool IsMultipart (void) const
+ {
+ UniString aType (GetContentType());
+ return (aType.CompareIgnoreCaseToAscii("multipart/", 10) == 0);
+ }
+
+ sal_uIntPtr GetChildCount (void) const { return nNumChildren; }
+ INetMIMEMessage* GetChild (sal_uIntPtr nIndex) const
+ {
+ return ((INetMIMEMessage *)(aChildren.GetObject (nIndex)));
+ }
+ INetMIMEMessage* GetParent (void) const { return pParent; }
+
+ sal_Bool EnableAttachChild (
+ INetMessageContainerType eType = INETMSG_MULTIPART_MIXED);
+ sal_Bool AttachChild (
+ INetMIMEMessage& rChildMsg, sal_Bool bOwner = sal_True);
+ sal_Bool DetachChild (
+ sal_uIntPtr 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 */
+
diff --git a/tools/inc/tools/inetstrm.hxx b/tools/inc/tools/inetstrm.hxx
new file mode 100644
index 000000000000..b1c01333c63a
--- /dev/null
+++ b/tools/inc/tools/inetstrm.hxx
@@ -0,0 +1,275 @@
+/*************************************************************************
+ *
+ * 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, sal_uIntPtr nSize) = 0;
+
+public:
+ INetIStream ();
+ virtual ~INetIStream (void);
+
+ int Read (sal_Char *pData, sal_uIntPtr 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, sal_uIntPtr nSize) = 0;
+
+public:
+ INetOStream ();
+ virtual ~INetOStream (void);
+
+ int Write (const sal_Char *pData, sal_uIntPtr nSize);
+};
+
+/*
+ * INetIOStream.
+ */
+class INetIOStream : public INetIStream, public INetOStream
+{
+ // Not implemented.
+ INetIOStream (const INetIOStream& rStrm);
+ INetIOStream& operator= (const INetIOStream& rStrm);
+
+public:
+ INetIOStream (sal_uIntPtr nIBufferSize = 0, sal_uIntPtr 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;
+ sal_Bool bHeaderGenerated;
+
+ sal_uIntPtr 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, sal_uIntPtr nSize);
+
+ // Not implemented.
+ INetMessageIStream (const INetMessageIStream& rStrm);
+ INetMessageIStream& operator= (const INetMessageIStream& rStrm);
+
+protected:
+ virtual int GetMsgLine (sal_Char *pData, sal_uIntPtr nSize);
+
+public:
+ INetMessageIStream (sal_uIntPtr nBufferSize = 2048);
+ virtual ~INetMessageIStream (void);
+
+ INetMessage *GetSourceMessage (void) const { return pSourceMsg; }
+ void SetSourceMessage (INetMessage *pMsg) { pSourceMsg = pMsg; }
+
+ void GenerateHeader (sal_Bool bGen = sal_True) { bHeaderGenerated = !bGen; }
+ sal_Bool IsHeaderGenerated (void) const { return bHeaderGenerated; }
+};
+
+/*
+ * INetMessageOStream (Message Parser) Interface.
+ */
+class INetMessageOStream : public INetOStream
+{
+ INetMessage *pTargetMsg;
+ sal_Bool bHeaderParsed;
+
+ INetMessageStreamState eOState;
+
+ SvMemoryStream *pMsgBuffer;
+
+ virtual int PutData (const sal_Char *pData, sal_uIntPtr nSize);
+
+ // Not implemented.
+ INetMessageOStream (const INetMessageOStream& rStrm);
+ INetMessageOStream& operator= (const INetMessageOStream& rStrm);
+
+protected:
+ virtual int PutMsgLine (const sal_Char *pData, sal_uIntPtr nSize);
+
+public:
+ INetMessageOStream (void);
+ virtual ~INetMessageOStream (void);
+
+ INetMessage *GetTargetMessage (void) const { return pTargetMsg; }
+ void SetTargetMessage (INetMessage *pMsg) { pTargetMsg = pMsg; }
+
+ void ParseHeader (sal_Bool bParse = sal_True) { bHeaderParsed = !bParse; }
+ sal_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 (sal_uIntPtr 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;
+
+ sal_uIntPtr 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, sal_uIntPtr nSize);
+ virtual int PutMsgLine (const sal_Char *pData, sal_uIntPtr nSize);
+
+public:
+ INetMIMEMessageStream (sal_uIntPtr 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 */
+
diff --git a/tools/inc/tools/iparser.hxx b/tools/inc/tools/iparser.hxx
new file mode 100644
index 000000000000..c31f6ebd75f7
--- /dev/null
+++ b/tools/inc/tools/iparser.hxx
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * 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 sal_True
+
+class TOOLS_DLLPUBLIC InformationParser
+{
+private:
+ sal_Bool bRecover;
+ ByteString sOldLine;
+
+ ByteString sCurrentComment;
+
+ sal_Bool bReplaceVariables; // meaning %UPD and %VERSION
+ sal_uInt16 nLevel;
+ ByteString sUPD;
+ ByteString sVersion;
+
+ Link aStatusLink;
+ SvStream *pActStream;
+ UniString sStreamName;
+
+ sal_uInt16 nErrorCode;
+ sal_uIntPtr nErrorLine;
+ ByteString sErrorText;
+ sal_uIntPtr nActLine;
+
+ // methods
+ TOOLS_DLLPRIVATE ByteString &ReadLine();
+ TOOLS_DLLPRIVATE GenericInformation *ReadKey( GenericInformationList *pExistingList );
+ inline void Recover();
+
+protected:
+ sal_Bool Save( SvStream &rOutStream,
+ const GenericInformationList *pSaveList, sal_uInt16 nLevel, sal_Bool bStripped );
+ GenericInformationList *Execute( SvStream &rSourceStream,
+ GenericInformationList *pExistingList );
+ virtual void PrintStatus( ByteString &rStatus )
+ { if ( aStatusLink.IsSet()) aStatusLink.Call( &rStatus ); }
+
+public:
+ InformationParser( sal_Bool bReplace = sal_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 sal_False on error
+ sal_Bool Save( SvFileStream &rSourceStream,
+ const GenericInformationList *pSaveList );
+ sal_Bool Save( SvMemoryStream &rSourceStream,
+ const GenericInformationList *pSaveList );
+ sal_Bool Save( const UniString &rSourceFile,
+ const GenericInformationList *pSaveList );
+
+ sal_uInt16 GetErrorCode();
+ ByteString &GetErrorText();
+
+ void SetStatusHdl( const Link &rHdl ) { aStatusLink = rHdl; }
+};
+
+#endif
+
diff --git a/tools/inc/tools/isofallback.hxx b/tools/inc/tools/isofallback.hxx
new file mode 100644
index 000000000000..dcf4bd938376
--- /dev/null
+++ b/tools/inc/tools/isofallback.hxx
@@ -0,0 +1,38 @@
+/*************************************************************************
+ *
+ * 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
+
diff --git a/tools/inc/tools/line.hxx b/tools/inc/tools/line.hxx
new file mode 100644
index 000000000000..32fc157a34a4
--- /dev/null
+++ b/tools/inc/tools/line.hxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * 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;
+
+ sal_Bool Intersection( const Line& rLine, double& rIntersectionX, double& rIntersectionY ) const;
+ sal_Bool Intersection( const Line& rLine, Point& rIntersection ) const;
+ sal_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
diff --git a/tools/inc/tools/link.hxx b/tools/inc/tools/link.hxx
new file mode 100644
index 000000000000..f31fcabc8108
--- /dev/null
+++ b/tools/inc/tools/link.hxx
@@ -0,0 +1,158 @@
+/*************************************************************************
+ *
+ * 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;
+
+ sal_Bool IsSet() const;
+ sal_Bool operator !() const;
+
+ sal_Bool operator==( const Link& rLink ) const;
+ sal_Bool operator!=( const Link& rLink ) const
+ { return !(Link::operator==( rLink )); }
+ sal_Bool operator<( const Link& rLink ) const
+ { return ((sal_uIntPtr)rLink.pFunc < (sal_uIntPtr)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 sal_Bool Link::IsSet() const
+{
+ if ( pFunc )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+inline sal_Bool Link::operator !() const
+{
+ if ( !pFunc )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+#endif // _LINK_HXX
diff --git a/tools/inc/tools/list.hxx b/tools/inc/tools/list.hxx
new file mode 100644
index 000000000000..bb0d8627838c
--- /dev/null
+++ b/tools/inc/tools/list.hxx
@@ -0,0 +1,143 @@
+/*************************************************************************
+ *
+ * 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( sal_uInt16 _nInitSize = 16, sal_uInt16 _nReSize = 16 ) :
+ Container( 1024, _nInitSize, _nReSize ) {}
+ List( sal_uInt16 _nBlockSize, sal_uInt16 _nInitSize, sal_uInt16 _nReSize ) :
+ Container( _nBlockSize, _nInitSize, _nReSize ) {}
+ List( const List& rList ) : Container( rList ) {}
+
+ List& operator =( const List& rList )
+ { Container::operator =( rList ); return *this; }
+
+ sal_Bool operator ==( const List& rList ) const
+ { return Container::operator ==( rList ); }
+ sal_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( sal_uInt16 _nInitSize = 16, \
+ sal_uInt16 _nReSize = 16 ) : \
+ List( _nInitSize, _nReSize ) {} \
+ ClassName( sal_uInt16 _nBlockSize, sal_uInt16 _nInitSize, \
+ sal_uInt16 _nReSize ) : \
+ List( _nBlockSize, _nInitSize, _nReSize ) {} \
+ ClassName( const ClassName& rClassName ) : \
+ List( rClassName ) {} \
+ \
+ void Insert( Type p, sal_uIntPtr 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( sal_uIntPtr 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, sal_uIntPtr 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( sal_uIntPtr nIndex ) const \
+ { return (Type)List::GetObject( nIndex ); } \
+ sal_uIntPtr GetPos( const Type p ) const \
+ { return List::GetPos( (const void*)p ); } \
+ sal_uIntPtr GetPos( const Type p, sal_uIntPtr nStartIndex, \
+ sal_Bool bForward = sal_True ) const \
+ { return List::GetPos( (const void*)p, nStartIndex, \
+ bForward ); } \
+ \
+ Type Seek( sal_uIntPtr 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; } \
+ \
+ sal_Bool operator ==( const ClassName& rList ) const \
+ { return List::operator ==( rList ); } \
+ sal_Bool operator !=( const ClassName& rList ) const \
+ { return List::operator !=( rList ); } \
+};
+
+#endif // _LIST_HXX
diff --git a/tools/inc/tools/mapunit.hxx b/tools/inc/tools/mapunit.hxx
new file mode 100644
index 000000000000..b30d3865d862
--- /dev/null
+++ b/tools/inc/tools/mapunit.hxx
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * 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 -
+// -----------------
+
+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
diff --git a/tools/inc/tools/mempool.hxx b/tools/inc/tools/mempool.hxx
new file mode 100644
index 000000000000..74df068908f7
--- /dev/null
+++ b/tools/inc/tools/mempool.hxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * 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;
+ char const * m_pTypeName;
+
+public:
+ FixedMemPool( char const * pTypeName,
+ sal_uInt16 nTypeSize,
+ sal_uInt16 nInitSize = 512,
+ sal_uInt16 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_STRING(x) IMPL_FIXEDMEMPOOL_MAKESTRING(x)
+#define IMPL_FIXEDMEMPOOL_MAKESTRING(x) #x
+
+#define IMPL_FIXEDMEMPOOL_NEWDEL( Class, InitSize, GrowSize) \
+ FixedMemPool Class::aPool( IMPL_FIXEDMEMPOOL_STRING( Class ), 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( IMPL_FIXEDMEMPOOL_STRING( Class ), 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( IMPL_FIXEDMEMPOOL_STRING( Class ), sizeof( Class ), (InitSize), (GrowSize) )
+
+#endif // _SVMEMPOOL_HXX
diff --git a/tools/inc/tools/multisel.hxx b/tools/inc/tools/multisel.hxx
new file mode 100644
index 000000000000..6544fe771f95
--- /dev/null
+++ b/tools/inc/tools/multisel.hxx
@@ -0,0 +1,216 @@
+/*************************************************************************
+ *
+ * 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
+ sal_uIntPtr nCurSubSel; // index in aSels of current selected index
+ long nCurIndex; // current selected entry
+ sal_uIntPtr nSelCount; // number of selected indexes
+ sal_Bool bInverseCur;// inverse cursor
+ sal_Bool bCurValid; // are nCurIndex and nCurSubSel valid
+ sal_Bool bSelectNew; // auto-select newly inserted indexes
+
+#ifdef _SV_MULTISEL_CXX
+ TOOLS_DLLPRIVATE void ImplClear();
+ TOOLS_DLLPRIVATE sal_uIntPtr ImplFindSubSelection( long nIndex ) const;
+ TOOLS_DLLPRIVATE sal_Bool ImplMergeSubSelections( sal_uIntPtr nPos1, sal_uIntPtr 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 );
+ sal_Bool operator== ( MultiSelection& rOrig );
+ sal_Bool operator!= ( MultiSelection& rOrig )
+ { return !operator==( rOrig ); }
+ sal_Bool operator !() const
+ { return nSelCount == 0; }
+
+ void SelectAll( sal_Bool bSelect = sal_True );
+ sal_Bool Select( long nIndex, sal_Bool bSelect = sal_True );
+ void Select( const Range& rIndexRange, sal_Bool bSelect = sal_True );
+ sal_Bool IsSelected( long nIndex ) const;
+ sal_Bool IsAllSelected() const
+ { return nSelCount == sal_uIntPtr(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; }
+ sal_Bool IsCurValid() const { return bCurValid; }
+ long GetCurSelected() const { return nCurIndex; }
+ long FirstSelected( sal_Bool bInverse = sal_False );
+ long LastSelected();
+ long NextSelected();
+ long PrevSelected();
+
+ sal_uIntPtr GetRangeCount() const { return aSels.Count(); }
+ const Range& GetRange( sal_uIntPtr 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
diff --git a/tools/inc/tools/ownlist.hxx b/tools/inc/tools/ownlist.hxx
new file mode 100644
index 000000000000..78cf5af8e89c
--- /dev/null
+++ b/tools/inc/tools/ownlist.hxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * 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
+
+#ifndef _TOOLS_LIST_HXX //autogen
+#include <tools/list.hxx>
+#endif
+/*************************************************************************
+*************************************************************************/
+
+#define PRV_SV_DECL_OWNER_LIST(ClassName,Type) \
+ List aTypes; \
+public: \
+ ClassName( sal_uInt16 nInitSize = 16, \
+ sal_uInt16 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( sal_uIntPtr nPos ) \
+ { delete (Type *)aTypes.Remove( nPos ); } \
+ Type & Insert( const Type &, sal_uIntPtr nPos ); \
+ Type & Insert( const Type & rType ) \
+ { return Insert( rType, aTypes.GetCurPos() ); } \
+ Type & Append( const Type & rType ) \
+ { return Insert( rType, LIST_APPEND ); } \
+ Type & GetObject( sal_uIntPtr nPos ) const \
+ { return *(Type *)aTypes.GetObject( nPos ); } \
+ Type & operator []( sal_uIntPtr nPos ) const \
+ { return *(Type *)aTypes.GetObject( nPos ); } \
+ sal_uIntPtr Count() const { return aTypes.Count(); }
+
+#define PRV_SV_IMPL_OWNER_LIST(ClassName,Type) \
+ClassName & ClassName::operator = ( const ClassName & rObj ) \
+{ \
+ if( this != &rObj ) \
+ { \
+ Clear(); \
+ for( sal_uIntPtr 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, sal_uIntPtr nPos ) \
+{ \
+ Type * pType = new Type( rType ); \
+ aTypes.Insert( pType, nPos ); \
+ return *pType; \
+}
+
+#endif // _TOOLS_OWNLIST_HXX
diff --git a/tools/inc/tools/pathutils.hxx b/tools/inc/tools/pathutils.hxx
new file mode 100644
index 000000000000..e5c54b09fb4b
--- /dev/null
+++ b/tools/inc/tools/pathutils.hxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/inc/tools/poly.hxx b/tools/inc/tools/poly.hxx
new file mode 100644
index 000000000000..5abcca0c819d
--- /dev/null
+++ b/tools/inc/tools/poly.hxx
@@ -0,0 +1,347 @@
+/*************************************************************************
+ *
+ * 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 { sal_uIntPtr mnAbsolut; sal_uInt16 mnPercent; };
+
+public:
+
+ PolyOptimizeData() : eType( DATA_NONE ) {}
+ PolyOptimizeData( sal_uIntPtr nAbsolut ) : eType( DATA_ABSOLUT ), mnAbsolut( nAbsolut ) {}
+ PolyOptimizeData( sal_uInt16 nPercent ) : eType( DATA_PERCENT ), mnPercent( nPercent ) {}
+
+ sal_uIntPtr GetAbsValue() const { DBG_ASSERT( eType == DATA_ABSOLUT, "Wrong data type" ); return mnAbsolut; }
+ sal_uInt16 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();
+
+//#if 0 // _SOLAR__PRIVATE
+
+public:
+
+ Point* ImplGetPointAry();
+ sal_uInt8* ImplGetFlagAry();
+
+ static void ImplReduceEdges( Polygon& rPoly, const double& rArea, sal_uInt16 nPercent );
+ void ImplRead( SvStream& rIStream );
+ void ImplWrite( SvStream& rOStream ) const;
+
+//#endif // __PRIVATE
+
+public:
+ Polygon();
+ Polygon( sal_uInt16 nSize );
+ Polygon( sal_uInt16 nPoints, const Point* pPtAry,
+ const sal_uInt8* pFlagAry = NULL );
+ Polygon( const Rectangle& rRect );
+ Polygon( const Rectangle& rRect,
+ sal_uIntPtr nHorzRound, sal_uIntPtr nVertRound );
+ Polygon( const Point& rCenter,
+ long nRadX, long nRadY,
+ sal_uInt16 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,
+ sal_uInt16 nPoints = 0 );
+
+ Polygon( const Polygon& rPoly );
+ ~Polygon();
+
+ void SetPoint( const Point& rPt, sal_uInt16 nPos );
+ const Point& GetPoint( sal_uInt16 nPos ) const;
+
+ void SetFlags( sal_uInt16 nPos, PolyFlags eFlags );
+ PolyFlags GetFlags( sal_uInt16 nPos ) const;
+ sal_Bool HasFlags() const;
+
+ sal_Bool IsControl( sal_uInt16 nPos ) const;
+ sal_Bool IsSmooth( sal_uInt16 nPos ) const;
+ sal_Bool IsRect() const;
+
+ void SetSize( sal_uInt16 nNewSize );
+ sal_uInt16 GetSize() const;
+
+ void Clear();
+
+ Rectangle GetBoundRect() const;
+ double GetArea() const;
+ double GetSignedArea() const;
+ sal_Bool IsInside( const Point& rPt ) const;
+ sal_Bool IsRightOrientated() const;
+ double CalcDistance( sal_uInt16 nPt1, sal_uInt16 nPt2 );
+ void Clip( const Rectangle& rRect, sal_Bool bPolygon = sal_True );
+ void Optimize( sal_uIntPtr 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, sal_uInt16 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( sal_uInt16 nPos, const Point& rPt, PolyFlags eFlags = POLY_NORMAL );
+ void Insert( sal_uInt16 nPos, const Polygon& rPoly );
+ void Remove( sal_uInt16 nPos, sal_uInt16 nCount );
+
+ const Point& operator[]( sal_uInt16 nPos ) const { return GetPoint( nPos ); }
+ Point& operator[]( sal_uInt16 nPos );
+
+ Polygon& operator=( const Polygon& rPoly );
+ sal_Bool operator==( const Polygon& rPoly ) const;
+ sal_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 sal_uInt8* 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;
+
+//#if 0 // _SOLAR__PRIVATE
+ TOOLS_DLLPRIVATE void ImplDoOperation( const PolyPolygon& rPolyPoly, PolyPolygon& rResult, sal_uIntPtr nOperation ) const;
+ TOOLS_DLLPRIVATE void *ImplCreateArtVpath() const;
+ TOOLS_DLLPRIVATE void ImplSetFromArtVpath( void *pVpath );
+//#endif // __PRIVATE
+
+public:
+
+ PolyPolygon( sal_uInt16 nInitSize = 16, sal_uInt16 nResize = 16 );
+ PolyPolygon( const Polygon& rPoly );
+ PolyPolygon( sal_uInt16 nPoly, const sal_uInt16* pPointCountAry,
+ const Point* pPtAry );
+ PolyPolygon( const PolyPolygon& rPolyPoly );
+ ~PolyPolygon();
+
+ void Insert( const Polygon& rPoly, sal_uInt16 nPos = POLYPOLY_APPEND );
+ void Remove( sal_uInt16 nPos );
+ void Replace( const Polygon& rPoly, sal_uInt16 nPos );
+ const Polygon& GetObject( sal_uInt16 nPos ) const;
+
+ sal_Bool IsRect() const;
+
+ void Clear();
+
+ sal_uInt16 Count() const;
+ Rectangle GetBoundRect() const;
+ void Clip( const Rectangle& rRect );
+ void Optimize( sal_uIntPtr 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, sal_uInt16 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[]( sal_uInt16 nPos ) const { return GetObject( nPos ); }
+ Polygon& operator[]( sal_uInt16 nPos );
+
+ PolyPolygon& operator=( const PolyPolygon& rPolyPoly );
+ sal_Bool operator==( const PolyPolygon& rPolyPoly ) const;
+ sal_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
diff --git a/tools/inc/tools/postsys.h b/tools/inc/tools/postsys.h
new file mode 100644
index 000000000000..994f86ae35b5
--- /dev/null
+++ b/tools/inc/tools/postsys.h
@@ -0,0 +1,244 @@
+/*************************************************************************
+ *
+ * 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 sal_uInt8
+#undef sal_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"
+{
+ BOOL WINAPI WIN_Rectangle( HDC hDC, int X1, int Y1, int X2, int Y2 );
+ BOOL WINAPI WIN_Polygon( HDC hDC, CONST POINT * ppt, int ncnt );
+ BOOL WINAPI WIN_PolyPolygon( HDC hDC, CONST POINT * ppt, LPINT npcnt, int ncnt );
+}
+
+#endif
+
+// Konfl�kt mit den Tools-Pair vermeiden
+#undef Pair
+
diff --git a/tools/inc/tools/postwin.h b/tools/inc/tools/postwin.h
new file mode 100644
index 000000000000..1e746a941f5c
--- /dev/null
+++ b/tools/inc/tools/postwin.h
@@ -0,0 +1,257 @@
+/*************************************************************************
+ *
+ * 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"
+{
+BOOL WINAPI WIN_Rectangle( HDC hDC, int X1, int Y1, int X2, int Y2 );
+BOOL WINAPI WIN_Polygon( HDC hDC, CONST POINT * ppt, int ncnt );
+BOOL WINAPI WIN_PolyPolygon( HDC hDC, CONST POINT * ppt, LPINT npcnt, int ncnt );
+}
+#endif
+
+// svwin.h nicht mehr includen
+#define _SVWIN_H
diff --git a/tools/inc/tools/postx.h b/tools/inc/tools/postx.h
new file mode 100644
index 000000000000..3e77fde5d14b
--- /dev/null
+++ b/tools/inc/tools/postx.h
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * 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
+
diff --git a/tools/inc/tools/presys.h b/tools/inc/tools/presys.h
new file mode 100644
index 000000000000..7e84a92fb257
--- /dev/null
+++ b/tools/inc/tools/presys.h
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * 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 Rectangle BLA_Rectangle
+#define Polygon BLA_Polygon
+#define PolyPolygon BLA_PolyPolygon
+#define Region WIN_Region
+
+#endif
diff --git a/tools/inc/tools/prewin.h b/tools/inc/tools/prewin.h
new file mode 100644
index 000000000000..86bda268722d
--- /dev/null
+++ b/tools/inc/tools/prewin.h
@@ -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.
+ *
+ ************************************************************************/
+
+/* nicht geschuetzt, darf nur einmal includet werden */
+
+#if defined WNT
+
+#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
diff --git a/tools/inc/tools/prex.h b/tools/inc/tools/prex.h
new file mode 100644
index 000000000000..250a72b2476c
--- /dev/null
+++ b/tools/inc/tools/prex.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * 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 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) // 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
+
diff --git a/tools/inc/tools/pstm.hxx b/tools/inc/tools/pstm.hxx
new file mode 100644
index 000000000000..f149e977f3b3
--- /dev/null
+++ b/tools/inc/tools/pstm.hxx
@@ -0,0 +1,261 @@
+/*************************************************************************
+ *
+ * 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"
+
+#ifndef _TABLE_HXX
+#include <tools/table.hxx>
+#endif
+
+#ifndef _INQIDX_HXX
+#include <tools/unqidx.hxx>
+#endif
+#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< sal_uInt16, SvCreateInstancePersist > Map;
+ Map aAssocTable;
+public:
+ void Register( sal_uInt16 nClassId, SvCreateInstancePersist pFunc );
+ SvCreateInstancePersist Get( sal_uInt16 nClassId );
+};
+
+/************************** S v R t t i B a s e **************************/
+
+class TOOLS_DLLPUBLIC SvRttiBase : public SvRefBase
+{
+public:
+ TYPEINFO();
+};
+SV_DECL_IMPL_REF(SvRttiBase)
+
+/*************************************************************************/
+#define SV_DECL_PERSIST( Class, CLASS_ID ) \
+ TYPEINFO(); \
+ static sal_uInt16 StaticClassId() { return CLASS_ID; } \
+ static void * CreateInstance( SvPersistBase ** ppBase ); \
+ friend SvPersistStream& operator >> ( SvPersistStream & rStm, \
+ Class *& rpObj); \
+ virtual sal_uInt16 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; \
+ } \
+ sal_uInt16 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 sal_uInt16 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(sal_uInt16 nInitSz, sal_uInt16 nResize );
+
+ void WriteObjects( SvPersistStream &, sal_Bool bOnlyStreamedObj = sal_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)
+
+//#if 0 // _SOLAR__PRIVATE
+DECLARE_UNIQUEINDEX( SvPersistUIdx,SvPersistBase *)
+//#else
+//typedef UniqueIndex SvPersistUIdx;
+//#endif
+
+//=========================================================================
+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 sal_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;
+ sal_uIntPtr nStartIdx;
+ const SvPersistStream * pRefStm;
+ sal_uInt32 nFlags;
+
+ virtual sal_uIntPtr GetData( void* pData, sal_uIntPtr nSize );
+ virtual sal_uIntPtr PutData( const void* pData, sal_uIntPtr nSize );
+ virtual sal_uIntPtr SeekPos( sal_uIntPtr nPos );
+ virtual void FlushData();
+protected:
+ sal_uIntPtr GetCurMaxIndex( const SvPersistUIdx & ) const;
+ sal_uIntPtr GetCurMaxIndex() const
+ { return GetCurMaxIndex( aPUIdx ); }
+
+ void WriteObj( sal_uInt8 nHdr, SvPersistBase * pObj );
+ sal_uInt32 ReadObj( SvPersistBase * & rpObj,
+ sal_Bool bRegister );
+public:
+ sal_Bool IsStreamed( SvPersistBase * pObj ) const
+ { return 0 != GetIndex( pObj ); }
+ virtual void ResetError();
+
+ SvPersistStream( SvClassManager &, SvStream * pStream,
+ sal_uInt32 nStartIdx = 1 );
+ SvPersistStream( SvClassManager &, SvStream * pStream,
+ const SvPersistStream & rPersStm );
+ ~SvPersistStream();
+
+ void SetStream( SvStream * pStream );
+ SvStream * GetStream() const { return pStm; }
+ virtual sal_uInt16 IsA() const;
+
+ SvPersistBase * GetObject( sal_uIntPtr nIdx ) const;
+ sal_uIntPtr GetIndex( SvPersistBase * ) const;
+
+ void SetContextFlags( sal_uInt32 n ) { nFlags = n; }
+ sal_uInt32 GetContextFlags() const { return nFlags; }
+
+ static void WriteCompressed( SvStream & rStm, sal_uInt32 nVal );
+ static sal_uInt32 ReadCompressed( SvStream & rStm );
+
+ sal_uInt32 WriteDummyLen();
+ void WriteLen( sal_uInt32 nLenPos );
+ sal_uInt32 ReadLen( sal_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 & );
+ sal_uIntPtr InsertObj( SvPersistBase * );
+ sal_uIntPtr RemoveObj( SvPersistBase * );
+};
+
+#endif // _PSTM_HXX
diff --git a/tools/inc/tools/queue.hxx b/tools/inc/tools/queue.hxx
new file mode 100644
index 000000000000..4df0a60a1618
--- /dev/null
+++ b/tools/inc/tools/queue.hxx
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *
+ * 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( sal_uInt16 _nInitSize = 16, sal_uInt16 _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( (sal_uIntPtr)0 ); }
+
+ Queue& operator =( const Queue& rQueue )
+ { Container::operator =( rQueue ); return *this; }
+
+ sal_Bool operator ==( const Queue& rQueue ) const
+ { return Container::operator ==( rQueue ); }
+ sal_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( sal_uInt16 _nInitSize = 16, \
+ sal_uInt16 _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( sal_uIntPtr nIndex ) const \
+ { return (Type)Queue::GetObject( nIndex ); } \
+ sal_uIntPtr GetPos( const Type p ) const \
+ { return Queue::GetPos( (const void*)p ); } \
+ sal_uIntPtr GetPos( const Type p, sal_uIntPtr nStartIndex, \
+ sal_Bool bForward = sal_True ) const \
+ { return Queue::GetPos( (const void*)p, \
+ nStartIndex, \
+ bForward ); } \
+ \
+ ClassName& operator =( const ClassName& rClassName ) \
+ { Queue::operator =( rClassName ); \
+ return *this; } \
+ \
+ sal_Bool operator ==( const Queue& rQueue ) const \
+ { return Queue::operator ==( rQueue ); } \
+ sal_Bool operator !=( const Queue& rQueue ) const \
+ { return Queue::operator !=( rQueue ); } \
+};
+
+#endif // _QUEUE_HXX
diff --git a/tools/inc/tools/rc.h b/tools/inc/tools/rc.h
new file mode 100644
index 000000000000..e11aed2937fd
--- /dev/null
+++ b/tools/inc/tools/rc.h
@@ -0,0 +1,221 @@
+/*************************************************************************
+ *
+ * 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
+#define WINDOW_HELPID 0x4000
+
+// 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
diff --git a/tools/inc/tools/rc.hxx b/tools/inc/tools/rc.hxx
new file mode 100644
index 000000000000..d8cd73d6dcbc
--- /dev/null
+++ b/tools/inc/tools/rc.hxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * 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
+ sal_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 sal_uInt8* 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(); }
+ // read a byte string from resource data and increment pointer
+ rtl::OString ReadByteStringRes()
+ { return m_pResMgr->ReadByteString(); }
+
+ // 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
diff --git a/tools/inc/tools/rcid.h b/tools/inc/tools/rcid.h
new file mode 100644
index 000000000000..3daf64c547a7
--- /dev/null
+++ b/tools/inc/tools/rcid.h
@@ -0,0 +1,134 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/inc/tools/ref.hxx b/tools/inc/tools/ref.hxx
new file mode 100644
index 000000000000..e2c2c5c893be
--- /dev/null
+++ b/tools/inc/tools/ref.hxx
@@ -0,0 +1,456 @@
+/*************************************************************************
+ *
+ * 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 sal_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( sal_True ), \
+ OwnerLock( sal_True ), OwnerLock( sal_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(sal_uInt16 nInitSz, sal_uInt16 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, sal_uIntPtr 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( sal_uIntPtr nIndex );\
+inline EN Remove( EN p );\
+inline EN Replace( EN p );\
+inline EN Replace( EN p, sal_uIntPtr 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(sal_uInt16 nInitSz, sal_uInt16 nResize )\
+ : CN##List( nInitSz, nResize ){}\
+inline CN##MemberList::CN##MemberList( const CN##MemberList & rRef ) \
+ : CN##List( rRef ) \
+{\
+ sal_uIntPtr 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; \
+ sal_uIntPtr 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( sal_uIntPtr 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, sal_uIntPtr 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( sal_uIntPtr 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(sal_uInt16 nInitSz,sal_uInt16 nResize);\
+inline void Insert( EntryName p ); \
+inline void Insert( EntryName p, sal_uIntPtr nIndex ); \
+inline void Insert( EntryName p, EntryName pOld ); \
+inline void Append( EntryName p ); \
+inline EntryName Remove(); \
+inline EntryName Remove( sal_uIntPtr nIndex ); \
+inline EntryName Remove( EntryName p ); \
+inline EntryName Replace( EntryName p ); \
+inline EntryName Replace( EntryName p, sal_uIntPtr nIndex );\
+inline EntryName Replace( EntryName pNew, EntryName pOld );\
+inline EntryName GetCurObject() const;\
+inline EntryName GetObject( sal_uIntPtr nIndex ) const;\
+inline sal_uIntPtr GetPos( const EntryName ) const;\
+inline sal_uIntPtr GetPos( const EntryName, sal_uIntPtr nStartIndex,\
+ sal_Bool bForward = sal_True ) const;\
+inline EntryName Seek( sal_uIntPtr 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\
+ (sal_uInt16 nInitSz,sal_uInt16 nResize)\
+ : BaseList( nInitSz, nResize ){}\
+inline void ClassName##MemberList::Insert( EntryName p )\
+ {BaseList::Insert(p);}\
+inline void ClassName##MemberList::Insert( EntryName p, sal_uIntPtr 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( sal_uIntPtr 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, sal_uIntPtr 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( sal_uIntPtr nIdx ) const\
+ {return (EntryName)BaseList::GetObject( nIdx );}\
+inline EntryName ClassName##MemberList::Seek( sal_uIntPtr 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 sal_uIntPtr ClassName##MemberList::GetPos( const EntryName p) const\
+ {return BaseList::GetPos( p );}\
+inline sal_uIntPtr ClassName##MemberList::GetPos\
+ ( const EntryName p, sal_uIntPtr nStart, sal_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
+{
+ sal_uIntPtr 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;
+ }
+ sal_uIntPtr AddMulRef( sal_uIntPtr n ) { return nRefCount += n; }
+ sal_uIntPtr AddNextRef() { return ++nRefCount; }
+ sal_uIntPtr AddRef()
+ {
+ if( nRefCount >= SV_NO_DELETE_REFCOUNT )
+ nRefCount -= SV_NO_DELETE_REFCOUNT;
+ return ++nRefCount;
+ }
+ void ReleaseReference()
+ {
+ if( !--nRefCount )
+ QueryDelete();
+ }
+ sal_uIntPtr ReleaseRef()
+ {
+ sal_uIntPtr n = --nRefCount;
+ if( !n )
+ QueryDelete();
+ return n;
+ }
+ sal_uIntPtr GetRefCount() const { return nRefCount; }
+};
+
+//#if 0 // _SOLAR__PRIVATE
+#ifndef EMPTYARG
+#define EMPTYARG
+#endif
+//#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 sal_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
diff --git a/tools/inc/tools/resary.hxx b/tools/inc/tools/resary.hxx
new file mode 100644
index 000000000000..b6cd8f8943c6
--- /dev/null
+++ b/tools/inc/tools/resary.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * 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;
+
+//#if 0 // _SOLAR__PRIVATE
+#ifdef _TOOLS_RESARY_CXX
+ ImplResStringItem( const XubString& rStr ) :
+ maStr( rStr ) {}
+#endif
+//#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
diff --git a/tools/inc/tools/resid.hxx b/tools/inc/tools/resid.hxx
new file mode 100644
index 000000000000..cf3ec3d78ea9
--- /dev/null
+++ b/tools/inc/tools/resid.hxx
@@ -0,0 +1,162 @@
+/*************************************************************************
+ *
+ * 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( sal_uInt16 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(sal_Bool bRelease) const
+ {
+ if( bRelease )
+ m_nResId &= ~RSC_DONTRELEASE;
+ else
+ m_nResId |= RSC_DONTRELEASE;
+ return *this;
+ }
+
+ sal_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
diff --git a/tools/inc/tools/resmgr.hxx b/tools/inc/tools/resmgr.hxx
new file mode 100644
index 000000000000..327eff7a3b80
--- /dev/null
+++ b/tools/inc/tools/resmgr.hxx
@@ -0,0 +1,241 @@
+/*************************************************************************
+ *
+ * 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 sal_uInt8* 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, sal_uInt16 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
+ sal_Bool IsAvailable( const ResId& rId,
+ const Resource* = NULL) const;
+
+ // Resource suchen und laden
+ sal_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() ); }
+
+ // returns a string and its length out of the resource
+ static sal_uInt32 GetString( UniString& rStr, const sal_uInt8* pStr );
+ // returns a byte string and its length out of the resource
+ static sal_uInt32 GetByteString( rtl::OString& rStr, const sal_uInt8* pStr );
+
+ // Groesse eines Strings in der Resource
+ static sal_uInt32 GetStringSize( sal_uInt32 nLen )
+ { nLen++; return (nLen + nLen%2); }
+ static sal_uInt32 GetStringSize( const sal_uInt8* pStr, sal_uInt32& nLen );
+
+ // return a int64
+ static sal_uInt64 GetUInt64( void* pDatum );
+ // Gibt einen long zurueck
+ static sal_Int32 GetLong( void * pLong );
+ // return a short
+ static sal_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;
+
+ sal_Int16 ReadShort();
+ sal_Int32 ReadLong();
+ UniString ReadString();
+ rtl::OString ReadByteString();
+
+ // generate auto help id for current resource stack
+ rtl::OString 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
diff --git a/tools/inc/tools/rtti.hxx b/tools/inc/tools/rtti.hxx
new file mode 100644
index 000000000000..70a9dee7c04d
--- /dev/null
+++ b/tools/inc/tools/rtti.hxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * 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 sal_Bool IsOf( TypeId aSameOrSuperType ); \
+ virtual TypeId Type() const; \
+ virtual sal_Bool IsA( TypeId aSameOrSuperType ) const
+
+#define TYPEINFO_VISIBILITY(visibility) \
+ visibility static void* CreateType(); \
+ visibility static TypeId StaticType(); \
+ visibility static sal_Bool IsOf( TypeId aSameOrSuperType ); \
+ visibility virtual TypeId Type() const; \
+ visibility virtual sal_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; } \
+ sal_Bool sType::IsOf( TypeId aSameOrSuperType ) \
+ { \
+ if ( aSameOrSuperType == StaticType() ) \
+ return sal_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 sal_True
+
+#define TYPEINIT_END(sType) \
+ return sal_False; \
+ } \
+ sal_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 sal_Bool IsOf( TypeId aSameOrSuperType ); \
+ virtual TypeId Type() const; \
+ virtual sal_Bool IsA( TypeId aSameOrSuperType ) const
+
+#define TYPEINIT_ID(sType) \
+ TypeId sType::Type() const { return StaticType(); } \
+ sal_Bool sType::IsOf( TypeId aSameOrSuperType ) \
+ { \
+ if ( aSameOrSuperType == StaticType() ) \
+ return sal_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
diff --git a/tools/inc/tools/shl.hxx b/tools/inc/tools/shl.hxx
new file mode 100644
index 000000000000..73933d91e53b
--- /dev/null
+++ b/tools/inc/tools/shl.hxx
@@ -0,0 +1,114 @@
+/*************************************************************************
+ *
+ * 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( sal_uInt16 nSharedLib );
+
+#endif // _SHL_HXX
diff --git a/tools/inc/tools/simplerm.hxx b/tools/inc/tools/simplerm.hxx
new file mode 100644
index 000000000000..6b8f31147f96
--- /dev/null
+++ b/tools/inc/tools/simplerm.hxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * 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 <vos/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:
+ vos::OMutex 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_
diff --git a/tools/inc/tools/solar.h b/tools/inc/tools/solar.h
new file mode 100644
index 000000000000..1686e82bf52d
--- /dev/null
+++ b/tools/inc/tools/solar.h
@@ -0,0 +1,370 @@
+/*************************************************************************
+ *
+ * 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 ***********************************/
+
+#ifdef _SOLAR__PRIVATE
+#undef _SOLAR__PRIVATE
+#endif
+#define _SOLAR__PRIVATE 1
+#define __REFERENCED 0
+
+/************************************************************
+ Intermediate type to solve type clash with Windows headers.
+ Should be removed as soon as all code parts have been reviewed
+ and the correct type is known. Most of the times ULONG is meant
+ to be a 32-Bit unsigned integer type as sal_uInt32 is often
+ used for data exchange or for similiar method args.
+*************************************************************/
+typedef sal_uIntPtr sal_uLong; /* Replaces type ULONG */
+
+/*** misc. macros to leverage platform and compiler differences ********/
+
+typedef int FASTBOOL;
+#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 sal_uInt8 SVBT8[1];
+typedef sal_uInt8 SVBT16[2];
+typedef sal_uInt8 SVBT32[4];
+typedef sal_uInt8 SVBT64[8];
+
+#ifdef __cplusplus
+
+inline sal_uInt8 SVBT8ToByte ( const SVBT8 p ) { return p[0]; }
+inline sal_uInt16 SVBT16ToShort( const SVBT16 p ) { return (sal_uInt16)p[0]
+ + ((sal_uInt16)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;
+ ((sal_uInt8*)&n)[0] = p[0];
+ ((sal_uInt8*)&n)[1] = p[1];
+ ((sal_uInt8*)&n)[2] = p[2];
+ ((sal_uInt8*)&n)[3] = p[3];
+ ((sal_uInt8*)&n)[4] = p[4];
+ ((sal_uInt8*)&n)[5] = p[5];
+ ((sal_uInt8*)&n)[6] = p[6];
+ ((sal_uInt8*)&n)[7] = p[7];
+ return n; }
+#else
+inline double SVBT64ToDouble( const SVBT64 p ) { double n;
+ ((sal_uInt8*)&n)[0] = p[7];
+ ((sal_uInt8*)&n)[1] = p[6];
+ ((sal_uInt8*)&n)[2] = p[5];
+ ((sal_uInt8*)&n)[3] = p[4];
+ ((sal_uInt8*)&n)[4] = p[3];
+ ((sal_uInt8*)&n)[5] = p[2];
+ ((sal_uInt8*)&n)[6] = p[1];
+ ((sal_uInt8*)&n)[7] = p[0];
+ return n; }
+#endif
+
+inline void ByteToSVBT8 ( sal_uInt8 n, SVBT8 p ) { p[0] = n; }
+inline void ShortToSVBT16( sal_uInt16 n, SVBT16 p ) { p[0] = (sal_uInt8) n;
+ p[1] = (sal_uInt8)(n >> 8); }
+inline void UInt32ToSVBT32 ( sal_uInt32 n, SVBT32 p ) { p[0] = (sal_uInt8) n;
+ p[1] = (sal_uInt8)(n >> 8);
+ p[2] = (sal_uInt8)(n >> 16);
+ p[3] = (sal_uInt8)(n >> 24); }
+#if defined OSL_LITENDIAN
+inline void DoubleToSVBT64( double n, SVBT64 p ) { p[0] = ((sal_uInt8*)&n)[0];
+ p[1] = ((sal_uInt8*)&n)[1];
+ p[2] = ((sal_uInt8*)&n)[2];
+ p[3] = ((sal_uInt8*)&n)[3];
+ p[4] = ((sal_uInt8*)&n)[4];
+ p[5] = ((sal_uInt8*)&n)[5];
+ p[6] = ((sal_uInt8*)&n)[6];
+ p[7] = ((sal_uInt8*)&n)[7]; }
+#else
+inline void DoubleToSVBT64( double n, SVBT64 p ) { p[0] = ((sal_uInt8*)&n)[7];
+ p[1] = ((sal_uInt8*)&n)[6];
+ p[2] = ((sal_uInt8*)&n)[5];
+ p[3] = ((sal_uInt8*)&n)[4];
+ p[4] = ((sal_uInt8*)&n)[3];
+ p[5] = ((sal_uInt8*)&n)[2];
+ p[6] = ((sal_uInt8*)&n)[1];
+ p[7] = ((sal_uInt8*)&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 *******************************************************/
+
+#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 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"
+#else
+ #define __DLLEXTENSION ".so"
+#endif
+#endif
+
+// -----------------------------------------------------------------------
+
+#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 sal_uInt16
+#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 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 */
diff --git a/tools/inc/tools/solarmutex.hxx b/tools/inc/tools/solarmutex.hxx
new file mode 100644
index 000000000000..f8b784c9f9ae
--- /dev/null
+++ b/tools/inc/tools/solarmutex.hxx
@@ -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.
+ *
+ ************************************************************************/
+#ifndef _TOOLS_SOLARMUTEX_HXX
+#define _TOOLS_SOLARMUTEX_HXX
+
+#include "tools/toolsdllapi.h"
+#include <vos/mutex.hxx>
+
+namespace tools
+{
+ class TOOLS_DLLPUBLIC SolarMutex
+ {
+ public:
+ static ::vos::IMutex* GetSolarMutex();
+ static void SetSolarMutex( ::vos::IMutex* pMutex );
+ static bool Acquire();
+ static void Release();
+ };
+}
+
+#endif
diff --git a/tools/inc/tools/stack.hxx b/tools/inc/tools/stack.hxx
new file mode 100644
index 000000000000..6ac6aa2fc586
--- /dev/null
+++ b/tools/inc/tools/stack.hxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * 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( sal_uInt16 _nInitSize = 16, sal_uInt16 _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; }
+
+ sal_Bool operator ==( const Stack& rStack ) const
+ { return Container::operator ==( rStack ); }
+ sal_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( sal_uInt16 _nInitSize = 16, \
+ sal_uInt16 _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( sal_uIntPtr nIndex ) const \
+ { return (Type)Stack::GetObject( nIndex ); } \
+ sal_uIntPtr GetPos( const Type p ) const \
+ { return Stack::GetPos( (const void*)p ); } \
+ sal_uIntPtr GetPos( const Type p, sal_uIntPtr nStartIndex, \
+ sal_Bool bForward = sal_True ) const \
+ { return Stack::GetPos( (const void*)p, \
+ nStartIndex, \
+ bForward ); } \
+ \
+ ClassName& operator =( const ClassName& rClassName ) \
+ { Stack::operator =( rClassName ); \
+ return *this; } \
+ \
+ sal_Bool operator ==( const ClassName& rStack ) const \
+ { return Stack::operator ==( rStack ); } \
+ sal_Bool operator !=( const ClassName& rStack ) const \
+ { return Stack::operator !=( rStack ); } \
+};
+
+#endif // _STACK_HXX
diff --git a/tools/inc/tools/stream.hxx b/tools/inc/tools/stream.hxx
new file mode 100644
index 000000000000..841b364fef6e
--- /dev/null
+++ b/tools/inc/tools/stream.hxx
@@ -0,0 +1,867 @@
+/*************************************************************************
+ *
+ * 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>
+#ifndef _EINF_HXX
+#include <tools/errinf.hxx>
+#endif
+#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(sal_False), m_bSync(sal_False) {}
+
+ SvLockBytes(SvStream * pTheStream, sal_Bool bTheOwner = sal_False):
+ m_pStream(pTheStream), m_bOwner(bTheOwner), m_bSync(sal_False) {}
+
+ virtual ~SvLockBytes() { close(); }
+
+ virtual const SvStream * GetStream() const { return m_pStream; }
+
+ virtual void SetSynchronMode(sal_Bool bTheSync = sal_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, sal_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(sal_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 = sal_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; // sal_True: Stream != Pufferinhalt
+ int bIsConsistent:1;// sal_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();
+
+ /** If eReadBomCharSet==RTL_TEXTENCODING_DONTKNOW: read 16bit,
+ if 0xfeff do nothing (UTF-16), if 0xfffe switch endian
+ swapping (UTF-16), if 0xefbb or 0xbbef read another byte
+ and check for UTF-8. If no UTF-* BOM was detected put all
+ read bytes back. This means that if 2 bytes were read it
+ was an UTF-16 BOM, if 3 bytes were read it was an UTF-8
+ BOM. There is no UTF-7, UTF-32 or UTF-EBCDIC BOM detection!
+
+ If eReadBomCharSet!=RTL_TEXTENCODING_DONTKNOW: only read a
+ BOM of that encoding and switch endian swapping if UTF-16
+ and 0xfffe.
+ */
+ sal_Bool StartReadingUnicodeText( rtl_TextEncoding eReadBomCharSet );
+
+ /// 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 )
+{
+ sal_uIntPtr 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( (sal_uIntPtr)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=sal_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
diff --git a/tools/inc/tools/string.hxx b/tools/inc/tools/string.hxx
new file mode 100755
index 000000000000..510d66937299
--- /dev/null
+++ b/tools/inc/tools/string.hxx
@@ -0,0 +1,691 @@
+/*************************************************************************
+ *
+ * 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>
+#ifndef _RTL_STRING_HXX
+#include <rtl/string.hxx>
+#endif
+#ifndef _RTL_USTRING_HXX
+#include <rtl/ustring.hxx>
+#endif
+#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, sal_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,
+ sal_Bool bReplace = sal_True );
+ static sal_Char Convert( sal_Char c, rtl_TextEncoding eSource,
+ rtl_TextEncoding eTarget,
+ sal_Bool bReplace = sal_True );
+ static sal_Unicode ConvertToUnicode( sal_Char c,
+ rtl_TextEncoding eTextEncoding );
+ static sal_Char ConvertFromUnicode( sal_Unicode c,
+ rtl_TextEncoding eTextEncoding,
+ sal_Bool bReplace = sal_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,
+ sal_Bool bReplace = sal_True );
+ ByteString& ConvertLineEnd( LineEnd eLineEnd );
+ ByteString& ConvertLineEnd()
+ { return ConvertLineEnd( GetSystemLineEnd() ); }
+
+ sal_Bool IsLowerAscii() const;
+ sal_Bool IsUpperAscii() const;
+ sal_Bool IsAlphaAscii() const;
+ sal_Bool IsNumericAscii() const;
+ sal_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;
+ sal_Bool Equals( const ByteString& rStr ) const;
+ sal_Bool Equals( const sal_Char* pCharStr ) const;
+ sal_Bool EqualsIgnoreCaseAscii( const ByteString& rStr ) const;
+ sal_Bool EqualsIgnoreCaseAscii( const sal_Char* pCharStr ) const;
+ sal_Bool Equals( const ByteString& rStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+ sal_Bool Equals( const sal_Char* pCharStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+ sal_Bool EqualsIgnoreCaseAscii( const ByteString& rStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+ sal_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 sal_Bool operator == ( const ByteString& rStr1, const ByteString& rStr2 )
+ { return rStr1.Equals( rStr2 ); }
+ friend sal_Bool operator == ( const ByteString& rStr, const sal_Char* pCharStr )
+ { return rStr.Equals( pCharStr ); }
+ friend sal_Bool operator == ( const sal_Char* pCharStr, const ByteString& rStr )
+ { return rStr.Equals( pCharStr ); }
+ friend sal_Bool operator != ( const ByteString& rStr1, const ByteString& rStr2 )
+ { return !(operator == ( rStr1, rStr2 )); }
+ friend sal_Bool operator != ( const ByteString& rStr, const sal_Char* pCharStr )
+ { return !(operator == ( rStr, pCharStr )); }
+ friend sal_Bool operator != ( const sal_Char* pCharStr, const ByteString& rStr )
+ { return !(operator == ( pCharStr, rStr )); }
+ friend sal_Bool operator < ( const ByteString& rStr1, const ByteString& rStr2 )
+ { return (rStr1.CompareTo( rStr2 ) == COMPARE_LESS); }
+ friend sal_Bool operator < ( const ByteString& rStr, const sal_Char* pCharStr )
+ { return (rStr.CompareTo( pCharStr ) == COMPARE_LESS); }
+ friend sal_Bool operator < ( const sal_Char* pCharStr, const ByteString& rStr )
+ { return (rStr.CompareTo( pCharStr ) >= COMPARE_EQUAL); }
+ friend sal_Bool operator > ( const ByteString& rStr1, const ByteString& rStr2 )
+ { return (rStr1.CompareTo( rStr2 ) == COMPARE_GREATER); }
+ friend sal_Bool operator > ( const ByteString& rStr, const sal_Char* pCharStr )
+ { return (rStr.CompareTo( pCharStr ) == COMPARE_GREATER); }
+ friend sal_Bool operator > ( const sal_Char* pCharStr, const ByteString& rStr )
+ { return (rStr.CompareTo( pCharStr ) <= COMPARE_EQUAL); }
+ friend sal_Bool operator <= ( const ByteString& rStr1, const ByteString& rStr2 )
+ { return !(operator > ( rStr1, rStr2 )); }
+ friend sal_Bool operator <= ( const ByteString& rStr, const sal_Char* pCharStr )
+ { return !(operator > ( rStr, pCharStr )); }
+ friend sal_Bool operator <= ( const sal_Char* pCharStr, const ByteString& rStr )
+ { return !(operator > ( pCharStr, rStr )); }
+ friend sal_Bool operator >= ( const ByteString& rStr1, const ByteString& rStr2 )
+ { return !(operator < ( rStr1, rStr2 )); }
+ friend sal_Bool operator >= ( const ByteString& rStr, const sal_Char* pCharStr )
+ { return !(operator < ( rStr, pCharStr )); }
+ friend sal_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 -
+// -------------
+
+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;
+ sal_Bool Equals( const UniString& rStr ) const;
+ sal_Bool Equals( const sal_Unicode* pCharStr ) const;
+ sal_Bool EqualsAscii( const sal_Char* pAsciiStr ) const;
+ sal_Bool EqualsIgnoreCaseAscii( const UniString& rStr ) const;
+ sal_Bool EqualsIgnoreCaseAscii( const sal_Unicode* pCharStr ) const;
+ sal_Bool EqualsIgnoreCaseAscii( const sal_Char* pAsciiStr ) const;
+ sal_Bool Equals( const UniString& rStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+ sal_Bool Equals( const sal_Unicode* pCharStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+ sal_Bool EqualsAscii( const sal_Char* pAsciiStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+ sal_Bool EqualsIgnoreCaseAscii( const UniString& rStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+ sal_Bool EqualsIgnoreCaseAscii( const sal_Unicode* pCharStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const;
+ sal_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 sal_Bool operator == ( const UniString& rStr1, const UniString& rStr2 )
+ { return rStr1.Equals( rStr2 ); }
+ friend sal_Bool operator != ( const UniString& rStr1, const UniString& rStr2 )
+ { return !(operator == ( rStr1, rStr2 )); }
+ friend sal_Bool operator < ( const UniString& rStr1, const UniString& rStr2 )
+ { return (rStr1.CompareTo( rStr2 ) == COMPARE_LESS); }
+ friend sal_Bool operator > ( const UniString& rStr1, const UniString& rStr2 )
+ { return (rStr1.CompareTo( rStr2 ) == COMPARE_GREATER); }
+ friend sal_Bool operator <= ( const UniString& rStr1, const UniString& rStr2 )
+ { return !(operator > ( rStr1, rStr2 )); }
+ friend sal_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
diff --git a/tools/inc/tools/svborder.hxx b/tools/inc/tools/svborder.hxx
new file mode 100644
index 000000000000..a525618a6c17
--- /dev/null
+++ b/tools/inc/tools/svborder.hxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * 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; }
+ sal_Bool operator == ( const SvBorder & rObj ) const
+ {
+ return nTop == rObj.nTop && nRight == rObj.nRight &&
+ nBottom == rObj.nBottom && nLeft == rObj.nLeft;
+ }
+ sal_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;
+ }
+ sal_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
+
diff --git a/tools/inc/tools/svlibrary.hxx b/tools/inc/tools/svlibrary.hxx
new file mode 100644
index 000000000000..fa8ff7c8068b
--- /dev/null
+++ b/tools/inc/tools/svlibrary.hxx
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * 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
+
diff --git a/tools/inc/tools/svwin.h b/tools/inc/tools/svwin.h
new file mode 100644
index 000000000000..b4ea6fcc3374
--- /dev/null
+++ b/tools/inc/tools/svwin.h
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/inc/tools/table.hxx b/tools/inc/tools/table.hxx
new file mode 100644
index 000000000000..6fff4d7d7f2b
--- /dev/null
+++ b/tools/inc/tools/table.hxx
@@ -0,0 +1,152 @@
+/*************************************************************************
+ *
+ * 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:
+ sal_uIntPtr nCount;
+//#if 0 // _SOLAR__PRIVATE
+ TOOLS_DLLPRIVATE sal_uIntPtr ImplGetIndex( sal_uIntPtr nKey, sal_uIntPtr* pIndex = NULL ) const;
+//#endif
+public:
+ Table( sal_uInt16 nInitSize = 16, sal_uInt16 nReSize = 16 );
+ Table( const Table& rTable ) : Container( rTable )
+ { nCount = rTable.nCount; }
+
+ sal_Bool Insert( sal_uIntPtr nKey, void* p );
+ void* Remove( sal_uIntPtr nKey );
+ void* Replace( sal_uIntPtr nKey, void* p );
+ void* Get( sal_uIntPtr nKey ) const;
+
+ void Clear() { Container::Clear(); nCount = 0; }
+ sal_uIntPtr Count() const { return( nCount ); }
+
+ void* GetCurObject() const;
+ sal_uIntPtr GetCurKey() const { return (sal_uIntPtr)Container::GetCurObject(); }
+ sal_uIntPtr GetKey( const void* p ) const;
+ sal_Bool IsKeyValid( sal_uIntPtr nKey ) const;
+
+ void* GetObject( sal_uIntPtr nPos ) const
+ { return Container::GetObject( (nPos*2)+1 ); }
+ sal_uIntPtr GetObjectKey( sal_uIntPtr nPos ) const
+ { return (sal_uIntPtr)Container::GetObject( nPos*2 ); }
+ sal_uIntPtr GetUniqueKey( sal_uIntPtr nStartKey = 1 ) const;
+ sal_uIntPtr SearchKey( sal_uIntPtr nKey, sal_uIntPtr* pPos = NULL ) const;
+
+ void* Seek( sal_uIntPtr nKey );
+ void* Seek( void* p );
+ void* First();
+ void* Last();
+ void* Next();
+ void* Prev();
+
+ Table& operator =( const Table& rTable );
+
+ sal_Bool operator ==( const Table& rTable ) const
+ { return Container::operator ==( rTable ); }
+ sal_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( sal_uInt16 _nInitSize = 16, \
+ sal_uInt16 _nReSize = 16 ) : \
+ Table( _nInitSize, _nReSize ) {} \
+ ClassName( const ClassName& rClassName ) : \
+ Table( rClassName ) {} \
+ \
+ sal_Bool Insert( sal_uIntPtr nKey, Type p ) \
+ { return Table::Insert( nKey, (void*)p ); } \
+ Type Remove( sal_uIntPtr nKey ) \
+ { return (Type)Table::Remove( nKey ); } \
+ Type Replace( sal_uIntPtr nKey, Type p ) \
+ { return (Type)Table::Replace( nKey, (void*)p ); } \
+ Type Get( sal_uIntPtr nKey ) const \
+ { return (Type)Table::Get( nKey ); } \
+ \
+ Type GetCurObject() const \
+ { return (Type)Table::GetCurObject(); } \
+ sal_uIntPtr GetKey( const Type p ) const \
+ { return Table::GetKey( (const void*)p ); } \
+ \
+ Type GetObject( sal_uIntPtr nPos ) const \
+ { return (Type)Table::GetObject( nPos ); } \
+ \
+ Type Seek( sal_uIntPtr 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; } \
+ \
+ sal_Bool operator ==( const ClassName& rTable ) const \
+ { return Table::operator ==( rTable ); } \
+ sal_Bool operator !=( const ClassName& rTable ) const \
+ { return Table::operator !=( rTable ); } \
+};
+
+#endif // _TOOLS_TABLE_HXX
diff --git a/tools/inc/tools/tempfile.hxx b/tools/inc/tools/tempfile.hxx
new file mode 100644
index 000000000000..896fed5da0cd
--- /dev/null
+++ b/tools/inc/tools/tempfile.hxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/inc/tools/tenccvt.hxx b/tools/inc/tools/tenccvt.hxx
new file mode 100644
index 000000000000..4c9968149291
--- /dev/null
+++ b/tools/inc/tools/tenccvt.hxx
@@ -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.
+ *
+ ************************************************************************/
+#ifndef _TOOLS_TENCCVT_HXX
+#define _TOOLS_TENCCVT_HXX
+
+#include <rtl/textenc.h>
+#ifndef _TOOLS_SOLAR_H
+#include <tools/solar.h>
+#endif
+#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, sal_uInt16 nVersion = SOFFICE_FILEFORMAT_50 );
+TOOLS_DLLPUBLIC rtl_TextEncoding GetSOStoreTextEncoding( rtl_TextEncoding eEncoding, sal_uInt16 nVersion = SOFFICE_FILEFORMAT_50 );
+
+#endif // _TOOLS_TENCCVT_HXX
diff --git a/tools/inc/tools/testtoolloader.hxx b/tools/inc/tools/testtoolloader.hxx
new file mode 100644
index 000000000000..04431d622959
--- /dev/null
+++ b/tools/inc/tools/testtoolloader.hxx
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * 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_
diff --git a/tools/inc/tools/time.hxx b/tools/inc/tools/time.hxx
new file mode 100644
index 000000000000..5b0b508598d8
--- /dev/null
+++ b/tools/inc/tools/time.hxx
@@ -0,0 +1,112 @@
+/*************************************************************************
+ *
+ * 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( sal_uIntPtr nHour, sal_uIntPtr nMin,
+ sal_uIntPtr nSec = 0, sal_uIntPtr n100Sec = 0 );
+
+ void SetTime( sal_Int32 nNewTime ) { nTime = nNewTime; }
+ sal_Int32 GetTime() const { return nTime; }
+
+ void SetHour( sal_uInt16 nNewHour );
+ void SetMin( sal_uInt16 nNewMin );
+ void SetSec( sal_uInt16 nNewSec );
+ void Set100Sec( sal_uInt16 nNew100Sec );
+ sal_uInt16 GetHour() const
+ { sal_uIntPtr nTempTime = (nTime >= 0) ? nTime : nTime*-1;
+ return (sal_uInt16)(nTempTime / 1000000); }
+ sal_uInt16 GetMin() const
+ { sal_uIntPtr nTempTime = (nTime >= 0) ? nTime : nTime*-1;
+ return (sal_uInt16)((nTempTime / 10000) % 100); }
+ sal_uInt16 GetSec() const
+ { sal_uIntPtr nTempTime = (nTime >= 0) ? nTime : nTime*-1;
+ return (sal_uInt16)((nTempTime / 100) % 100); }
+ sal_uInt16 Get100Sec() const
+ { sal_uIntPtr nTempTime = (nTime >= 0) ? nTime : nTime*-1;
+ return (sal_uInt16)(nTempTime % 100); }
+
+ sal_Int32 GetMSFromTime() const;
+ void MakeTimeFromMS( sal_Int32 nMS );
+
+ /// 12 hours == 0.5 days
+ double GetTimeInDays() const;
+
+ sal_Bool IsBetween( const Time& rFrom, const Time& rTo ) const
+ { return ((nTime >= rFrom.nTime) && (nTime <= rTo.nTime)); }
+
+ sal_Bool IsEqualIgnore100Sec( const Time& rTime ) const;
+
+ sal_Bool operator ==( const Time& rTime ) const
+ { return (nTime == rTime.nTime); }
+ sal_Bool operator !=( const Time& rTime ) const
+ { return (nTime != rTime.nTime); }
+ sal_Bool operator >( const Time& rTime ) const
+ { return (nTime > rTime.nTime); }
+ sal_Bool operator <( const Time& rTime ) const
+ { return (nTime < rTime.nTime); }
+ sal_Bool operator >=( const Time& rTime ) const
+ { return (nTime >= rTime.nTime); }
+ sal_Bool operator <=( const Time& rTime ) const
+ { return (nTime <= rTime.nTime); }
+
+ static Time GetUTCOffset();
+ static sal_uIntPtr GetSystemTicks(); // Elapsed time
+ static sal_uIntPtr 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
diff --git a/tools/inc/tools/tools.h b/tools/inc/tools/tools.h
new file mode 100644
index 000000000000..e1ad470cf620
--- /dev/null
+++ b/tools/inc/tools/tools.h
@@ -0,0 +1,38 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/inc/tools/toolsdllapi.h b/tools/inc/tools/toolsdllapi.h
new file mode 100644
index 000000000000..fbd41130a145
--- /dev/null
+++ b/tools/inc/tools/toolsdllapi.h
@@ -0,0 +1,41 @@
+/*************************************************************************
+ *
+ * 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 */
+
diff --git a/tools/inc/tools/unqid.hxx b/tools/inc/tools/unqid.hxx
new file mode 100644
index 000000000000..a8ef2587d486
--- /dev/null
+++ b/tools/inc/tools/unqid.hxx
@@ -0,0 +1,109 @@
+/*************************************************************************
+ *
+ * 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
+{
+ sal_uIntPtr nId;
+ sal_uInt16 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;
+ }
+ sal_uIntPtr GetId() const { return pId ? pId->nId : 0; }
+};
+
+// ---------------------
+// - UniqueIdContainer -
+// ---------------------
+
+class TOOLS_DLLPUBLIC UniqueIdContainer : private UniqueIndex
+{
+ sal_uInt16 nCollectCount;
+
+public: // Irgend etwas mit protected falsch
+ void Clear( sal_Bool bAll );
+ UniqueItemId CreateIdProt( sal_uIntPtr nId );
+
+public:
+ UniqueIdContainer( sal_uIntPtr _nStartIndex,
+ sal_uIntPtr _nInitSize = 16,
+ sal_uIntPtr _nReSize = 16 )
+ : UniqueIndex( _nStartIndex, _nInitSize, _nReSize )
+ , nCollectCount( 0 )
+ {}
+ UniqueIdContainer( const UniqueIdContainer& );
+
+ ~UniqueIdContainer()
+ { Clear( sal_True ); }
+ UniqueIdContainer& operator = ( const UniqueIdContainer & );
+
+ sal_Bool IsIndexValid( sal_uIntPtr nIndex ) const
+ { return UniqueIndex::IsIndexValid( nIndex ); }
+
+ UniqueItemId CreateId();
+ static UniqueItemId CreateFreeId( sal_uIntPtr nId ); // freies Id
+};
+
+#endif // _UNQID_HXX
diff --git a/tools/inc/tools/unqidx.hxx b/tools/inc/tools/unqidx.hxx
new file mode 100644
index 000000000000..6059af077abc
--- /dev/null
+++ b/tools/inc/tools/unqidx.hxx
@@ -0,0 +1,151 @@
+/*************************************************************************
+ *
+ * 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:
+ sal_uIntPtr nReSize;
+ sal_uIntPtr nStartIndex;
+ sal_uIntPtr nUniqIndex;
+ sal_uIntPtr nCount;
+
+public:
+ using Container::GetCurObject;
+
+ UniqueIndex( sal_uIntPtr nStartIndex = 0,
+ sal_uIntPtr nInitSize = 16,
+ sal_uIntPtr nReSize = 16 );
+ UniqueIndex( const UniqueIndex& rIdx );
+
+ sal_uIntPtr Insert( sal_uIntPtr nIndex, void* p );
+ sal_uIntPtr Insert( void* p );
+ void* Remove( sal_uIntPtr nIndex );
+ void* Replace( sal_uIntPtr nIndex, void* p );
+ void* Get( sal_uIntPtr nIndex ) const;
+
+ void Clear();
+ sal_uIntPtr Count() const { return nCount; }
+
+ sal_uIntPtr GetCurIndex() const;
+ sal_uIntPtr GetIndex( const void* p ) const;
+ sal_Bool IsIndexValid( sal_uIntPtr nIndex ) const;
+
+ void* Seek( sal_uIntPtr nIndex );
+ void* Seek( void* p );
+ void* First();
+ void* Last();
+ void* Next();
+ void* Prev();
+
+ sal_uIntPtr GetStartIndex() const { return nStartIndex; }
+ sal_uIntPtr GetCurMaxIndex() const
+ { return (nStartIndex + Container::GetSize()); }
+
+ UniqueIndex& operator =( const UniqueIndex& rIdx );
+
+ sal_Bool operator ==( const UniqueIndex& rIdx ) const;
+ sal_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( sal_uIntPtr _nStartIndex = 0, \
+ sal_uIntPtr _nInitSize = 16, sal_uIntPtr _nReSize = 16 ):\
+ UniqueIndex( _nStartIndex, _nInitSize, _nReSize ) {}\
+ ClassName( const ClassName& rClassName ) : \
+ UniqueIndex( rClassName ) {} \
+ \
+ sal_uIntPtr Insert( sal_uIntPtr nIndex, Type p ) \
+ { return UniqueIndex::Insert( nIndex, (void*)p ); } \
+ sal_uIntPtr Insert( Type p ) \
+ { return UniqueIndex::Insert( (void*)p ); } \
+ Type Remove( sal_uIntPtr nIndex ) \
+ { return (Type)UniqueIndex::Remove( nIndex ); } \
+ Type Replace( sal_uIntPtr nIndex, Type p ) \
+ { return (Type)UniqueIndex::Replace( nIndex, \
+ (void*)p ); } \
+ Type Get( sal_uIntPtr nIndex ) const \
+ { return (Type)UniqueIndex::Get( nIndex ); } \
+ \
+ Type GetCurObject() const \
+ { return (Type)UniqueIndex::GetCurObject(); } \
+ sal_uIntPtr GetIndex( const Type p ) const \
+ { return UniqueIndex::GetIndex( (const void*)p ); } \
+ \
+ Type Seek( sal_uIntPtr 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; } \
+ \
+ sal_Bool operator ==( const ClassName& rIdx ) const \
+ { return UniqueIndex::operator ==( rIdx ); } \
+ sal_Bool operator !=( const ClassName& rIdx ) const \
+ { return UniqueIndex::operator !=( rIdx ); } \
+};
+
+#endif // _UNQIDX_HXX
diff --git a/tools/inc/tools/urlobj.hxx b/tools/inc/tools/urlobj.hxx
new file mode 100644
index 000000000000..cb9c7e407bcc
--- /dev/null
+++ b/tools/inc/tools/urlobj.hxx
@@ -0,0 +1,1922 @@
+/*************************************************************************
+ *
+ * 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 INET_HID_SCHEME "hid:"
+
+#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_HID = 32,
+ INET_PROT_END = 33
+};
+
+//============================================================================
+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
diff --git a/tools/inc/tools/vcompat.hxx b/tools/inc/tools/vcompat.hxx
new file mode 100644
index 000000000000..93517b77053d
--- /dev/null
+++ b/tools/inc/tools/vcompat.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * 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 ) \
+ ((sal_uInt32)((((sal_uInt32)(char)(char1)))| \
+ (((sal_uInt32)(char)(char2))<<8UL)| \
+ (((sal_uInt32)(char)(char3))<<16UL)| \
+ ((sal_uInt32)(char)(char4))<<24UL))
+
+// --------------
+// - ImplCompat -
+// --------------
+
+class SvStream;
+
+class TOOLS_DLLPUBLIC VersionCompat
+{
+ SvStream* mpRWStm;
+ sal_uInt32 mnCompatPos;
+ sal_uInt32 mnTotalSize;
+ sal_uInt16 mnStmMode;
+ sal_uInt16 mnVersion;
+
+ VersionCompat() {}
+ VersionCompat( const VersionCompat& ) {}
+ VersionCompat& operator=( const VersionCompat& ) { return *this; }
+ sal_Bool operator==( const VersionCompat& ) { return sal_False; }
+
+public:
+
+ VersionCompat( SvStream& rStm, sal_uInt16 nStreamMode, sal_uInt16 nVersion = 1 );
+ ~VersionCompat();
+
+ sal_uInt16 GetVersion() const { return mnVersion; }
+};
+
+#endif // _VCOMPAT_HXX
diff --git a/tools/inc/tools/vector2d.hxx b/tools/inc/tools/vector2d.hxx
new file mode 100644
index 000000000000..10c33b57c871
--- /dev/null
+++ b/tools/inc/tools/vector2d.hxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * 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 sal_Bool operator==( const Vector2D& rVec ) const { return( mfX == rVec.mfX && mfY == rVec.mfY ); }
+ inline sal_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 sal_Bool operator==( const Pair& rPair ) const { return( mfX == rPair.nA && mfY == rPair.nB ); }
+ inline sal_Bool operator!=( const Pair& rPair ) const { return !( *this == rPair ); }
+
+ inline sal_Bool IsPositive( Vector2D& rVec ) const { return( ( mfX * rVec.mfY - mfY * rVec.mfX ) >= 0.0 ); }
+ inline sal_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
diff --git a/tools/inc/tools/weakbase.h b/tools/inc/tools/weakbase.h
new file mode 100644
index 000000000000..a66da8c7c33f
--- /dev/null
+++ b/tools/inc/tools/weakbase.h
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * 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_
+
diff --git a/tools/inc/tools/weakbase.hxx b/tools/inc/tools/weakbase.hxx
new file mode 100644
index 000000000000..81f53fb3516b
--- /dev/null
+++ b/tools/inc/tools/weakbase.hxx
@@ -0,0 +1,183 @@
+/*************************************************************************
+ *
+ * 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_
+
diff --git a/tools/inc/tools/wintypes.hxx b/tools/inc/tools/wintypes.hxx
new file mode 100644
index 000000000000..18adfbab37ef
--- /dev/null
+++ b/tools/inc/tools/wintypes.hxx
@@ -0,0 +1,344 @@
+/*************************************************************************
+ *
+ * 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 sal_uInt16 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_RULER (WINDOW_FIRST + 0x52)
+#define WINDOW_LAST (WINDOW_RULER)
+
+
+// ---------------
+// - Window-Bits -
+// ---------------
+
+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_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 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
+
+// For TreeListBox
+#define WB_HASBUTTONS ((WinBits)SAL_CONST_INT64(0x000100000000))
+#define WB_HASLINES ((WinBits)SAL_CONST_INT64(0x000200000000))
+#define WB_HASLINESATROOT ((WinBits)SAL_CONST_INT64(0x000400000000))
+#define WB_HASBUTTONSATROOT ((WinBits)SAL_CONST_INT64(0x000800000000))
+#define WB_NOINITIALSELECTION ((WinBits)SAL_CONST_INT64(0x001000000000))
+#define WB_HIDESELECTION ((WinBits)SAL_CONST_INT64(0x002000000000))
+#define WB_FORCE_MAKEVISIBLE ((WinBits)SAL_CONST_INT64(0x004000000000))
+// DO NOT USE: 0x008000000000, that's WB_SYSTEMCHILDWINDOW
+#define WB_QUICK_SEARCH ((WinBits)SAL_CONST_INT64(0x010000000000))
+
+
+// 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 -
+// ---------------
+
+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 -
+// ------------
+
+enum TriState { STATE_NOCHECK, STATE_CHECK, STATE_DONTKNOW };
+
+
+// ----------------------
+// - ButtonDialog-Types -
+// ----------------------
+
+typedef sal_uInt16 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
+
diff --git a/tools/inc/tools/wldcrd.hxx b/tools/inc/tools/wldcrd.hxx
new file mode 100644
index 000000000000..4938bc212db2
--- /dev/null
+++ b/tools/inc/tools/wldcrd.hxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * 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;
+
+ sal_uInt16 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()); }
+
+ sal_Bool Matches( const String& rStr ) const;
+
+ sal_Bool operator ==( const String& rString ) const
+ { return Matches( rString ); }
+ sal_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
diff --git a/tools/inc/tools/zcodec.hxx b/tools/inc/tools/zcodec.hxx
new file mode 100644
index 000000000000..d42e87f5d4e0
--- /dev/null
+++ b/tools/inc/tools/zcodec.hxx
@@ -0,0 +1,128 @@
+/*************************************************************************
+ *
+ * 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:
+
+ sal_uIntPtr mbInit;
+ sal_Bool mbStatus;
+ sal_Bool mbFinish;
+ sal_uIntPtr mnMemUsage;
+ SvStream* mpIStm;
+ sal_uInt8* mpInBuf;
+ sal_uIntPtr mnInBufSize;
+ sal_uIntPtr mnInToRead;
+ SvStream* mpOStm;
+ sal_uInt8* mpOutBuf;
+ sal_uIntPtr mnOutBufSize;
+
+ sal_uIntPtr mnCRC;
+ sal_uIntPtr mnCompressMethod;
+ void* mpsC_Stream;
+
+ void ImplInitBuf( sal_Bool nIOFlag );
+ void ImplWriteBack( void );
+
+public:
+ ZCodec( sal_uIntPtr nInBuf, sal_uIntPtr nOutBuf, sal_uIntPtr nMemUsage = MAX_MEM_USAGE );
+ ZCodec( void );
+ virtual ~ZCodec();
+
+ virtual void BeginCompression( sal_uIntPtr nCompressMethod = ZCODEC_DEFAULT );
+ virtual long EndCompression();
+ sal_Bool IsFinished () const { return mbFinish; }
+
+ long Compress( SvStream& rIStm, SvStream& rOStm );
+ long Decompress( SvStream& rIStm, SvStream& rOStm );
+
+ long Write( SvStream& rOStm, const sal_uInt8* pData, sal_uIntPtr nSize );
+ long Read( SvStream& rIStm, sal_uInt8* pData, sal_uIntPtr nSize );
+ long ReadAsynchron( SvStream& rIStm, sal_uInt8* pData, sal_uIntPtr nSize );
+
+ void SetBreak( sal_uIntPtr );
+ sal_uIntPtr GetBreak( void );
+ void SetCRC( sal_uIntPtr nCurrentCRC );
+ sal_uIntPtr UpdateCRC( sal_uIntPtr nLatestCRC, sal_uIntPtr nSource );
+ sal_uIntPtr UpdateCRC( sal_uIntPtr nLatestCRC, sal_uInt8* pSource, long nDatSize );
+ sal_uIntPtr GetCRC();
+};
+
+class GZCodec : public ZCodec
+{
+
+public:
+ GZCodec(){};
+ ~GZCodec(){};
+ virtual void BeginCompression( sal_uIntPtr nCompressMethod = ZCODEC_DEFAULT );
+};
+
+#endif // _ZCODEC_HXX
diff --git a/tools/inc/toolsin.hxx b/tools/inc/toolsin.hxx
new file mode 100644
index 000000000000..7259682c9895
--- /dev/null
+++ b/tools/inc/toolsin.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/os2/inc/dll.hxx b/tools/os2/inc/dll.hxx
new file mode 100644
index 000000000000..81a87a03ece7
--- /dev/null
+++ b/tools/os2/inc/dll.hxx
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/os2/source/dll/toolsdll.cxx b/tools/os2/source/dll/toolsdll.cxx
new file mode 100644
index 000000000000..0e0bdec3a9b0
--- /dev/null
+++ b/tools/os2/source/dll/toolsdll.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+#ifndef _SHL_HXX
+#include <tools/shl.hxx>
+#endif
+
+#ifndef _DLL_HXX
+#include <dll.hxx>
+#endif
+
+// =======================================================================
+
+static void* aAppData[SHL_COUNT];
+
+// -----------------------------------------------------------------------
+
+void** GetAppData( USHORT nSharedLib )
+{
+ return &(aAppData[nSharedLib]);
+}
+
+// =======================================================================
+
diff --git a/tools/prj/build.lst b/tools/prj/build.lst
new file mode 100644
index 000000000000..1e5c9135145f
--- /dev/null
+++ b/tools/prj/build.lst
@@ -0,0 +1,2 @@
+tl tools : cppu external offuh vos ZLIB:zlib EXPAT:expat basegfx comphelper i18npool NULL
+tl tools\prj nmake - all tl_prj NULL
diff --git a/tools/prj/d.lst b/tools/prj/d.lst
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/prj/d.lst
diff --git a/tools/prj/makefile.mk b/tools/prj/makefile.mk
new file mode 100644
index 000000000000..e312a7ccab65
--- /dev/null
+++ b/tools/prj/makefile.mk
@@ -0,0 +1,40 @@
+#*************************************************************************
+#
+# 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=prj
+
+.INCLUDE : settings.mk
+
+.IF "$(VERBOSE)"!=""
+VERBOSEFLAG :=
+.ELSE
+VERBOSEFLAG := -s
+.ENDIF
+
+all:
+ cd $(PRJ) && $(GNUMAKE) $(VERBOSEFLAG) -r -j$(MAXPROCESS) $(gb_MAKETARGET) && $(GNUMAKE) $(VERBOSEFLAG) -r deliverlog
diff --git a/tools/qa/test_pathutils.cxx b/tools/qa/test_pathutils.cxx
new file mode 100644
index 000000000000..5966406e150f
--- /dev/null
+++ b/tools/qa/test_pathutils.cxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * 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 "testshl/simpleheader.hxx"
+#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_NAMED_REGISTRATION(Test, "alltests");
+
+}
+
+NOADDITIONAL;
diff --git a/tools/qa/version.map b/tools/qa/version.map
new file mode 100644
index 000000000000..7321bbca16ad
--- /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:
+ registerAllTestFunction;
+
+ local:
+ *;
+};
diff --git a/tools/source/communi/geninfo.cxx b/tools/source/communi/geninfo.cxx
new file mode 100644
index 000000000000..01a325054a69
--- /dev/null
+++ b/tools/source/communi/geninfo.cxx
@@ -0,0 +1,408 @@
+/*************************************************************************
+ *
+ * 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,
+ sal_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 );
+}
+
+/*****************************************************************************/
+sal_Bool GenericInformation::InsertSubInfo( GenericInformation *pInfo )
+/*****************************************************************************/
+{
+ return ( pInfoList && pInfoList->InsertInfo( pInfo ));
+}
+
+/*****************************************************************************/
+sal_Bool GenericInformation::InsertSubInfo( const ByteString &rPathKey, const ByteString &rValue,
+ sal_Bool bSearchByPath, sal_Bool bNewPath )
+/*****************************************************************************/
+{
+ return (pInfoList && pInfoList->InsertInfo( rPathKey, rValue, bSearchByPath, bNewPath ));
+}
+
+/*****************************************************************************/
+void GenericInformation::RemoveSubInfo( GenericInformation *pInfo,
+ sal_Bool bDelete )
+/*****************************************************************************/
+{
+ pInfoList->RemoveInfo( pInfo, bDelete );
+}
+
+/*****************************************************************************/
+//void GenericInformation::RemoveSelf( sal_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,
+ sal_Bool bSearchByPath,
+ sal_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()
+{
+ sal_uInt16 i;
+ GenericInformation* pTemp,*pWork;
+
+ pOwner = pParent;
+
+ for(i=0;i<rList.Count();i++)
+ {
+ pTemp = rList.GetObject(i);
+ pWork = new GenericInformation(*pTemp,sal_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 ( sal_uIntPtr i = 0; i < Count(); i++ ) {
+ GetObject( i )->ListDeleted();
+ delete GetObject( i );
+ Remove( i );*/
+ // Neue Variante:
+ while ( Count() ) {
+ GetObject( 0 )->ListDeleted();
+ delete GetObject( 0 );
+ Remove( (sal_uIntPtr)0 );
+ }
+}
+
+/*****************************************************************************/
+GenericInformation *GenericInformationList::Search( sal_uIntPtr &rPos, ByteString sKey,
+ sal_uIntPtr nStart, sal_uIntPtr 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
+ sal_uIntPtr 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,
+ sal_Bool bSearchByPath,
+ sal_Bool bCreatePath )
+/*****************************************************************************/
+{
+
+ rKey.EraseLeadingChars( '/' );
+ rKey.EraseTrailingChars( '/' );
+
+ ByteString sKey;
+ if ( bSearchByPath )
+ sKey = rKey.GetToken( 0, '/' );
+ else
+ sKey = rKey;
+
+ sal_uIntPtr 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
+ */
+ sal_uInt16 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, sal_True, bCreatePath );
+ }
+ if ( !pReturnInfo && bCreatePath ) {
+ pReturnInfo = new GenericInformation ( sKey, "", this, NULL);
+ }
+
+ return pReturnInfo; // kann durchaus NULL sein.
+}
+
+/*****************************************************************************/
+sal_uIntPtr GenericInformationList::InsertSorted( GenericInformation *pInfo,
+ sal_Bool bOverwrite,
+ sal_uIntPtr nStart, sal_uIntPtr 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, sal_uIntPtr(0)); // ### Laut NF scheint hier ein Memory Leak zu sein
+ return 0;
+ }
+ else if ( sCandidate > sKey ) {
+ Insert( pInfo, sal_uIntPtr(0));
+ return 0;
+ }
+ else {
+ Insert( pInfo, LIST_APPEND );
+ return 1;
+ }
+ }
+// ### GH: /ENDE/ dieser Block schein �berfl�ssig zu sein
+
+ sal_uIntPtr 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 );
+}
+
+/*****************************************************************************/
+sal_Bool GenericInformationList::InsertInfo( GenericInformation *pInfo,
+ sal_Bool bOverwrite )
+/*****************************************************************************/
+{
+ if ( !pInfo->Len())
+ return sal_False;
+
+ InsertSorted( pInfo, bOverwrite, 0, Count() - 1 );
+ return sal_True;
+}
+
+
+/*****************************************************************************/
+sal_Bool GenericInformationList::InsertInfo( const ByteString &rPathKey, const ByteString &rValue,
+ sal_Bool bSearchByPath, sal_Bool bNewPath )
+/*****************************************************************************/
+{
+ GenericInformation *pInfo;
+ ByteString sPathKey ( rPathKey );
+ sPathKey.EraseLeadingChars( '/' );
+ sPathKey.EraseTrailingChars( '/' );
+
+ pInfo = GetInfo( sPathKey, bSearchByPath, bNewPath );
+
+ if ( pInfo ) {
+ pInfo->SetValue( rValue );
+ return sal_True;
+ }
+ return sal_False;
+}
+
+/*****************************************************************************/
+void GenericInformationList::RemoveInfo( GenericInformation *pInfo,
+ sal_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;
+}
+
+
diff --git a/tools/source/communi/parser.cxx b/tools/source/communi/parser.cxx
new file mode 100644
index 000000000000..f3baa37049e2
--- /dev/null
+++ b/tools/source/communi/parser.cxx
@@ -0,0 +1,469 @@
+/*************************************************************************
+ *
+ * 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( sal_Bool bReplace )
+/*****************************************************************************/
+ : bRecover( sal_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 = sal_False;
+ }
+ else {
+ if ( !pActStream->IsEof()) {
+ pActStream->ReadLine( sLine );
+ xub_StrLen nStart = 0;
+ xub_StrLen nEnd = sLine.Len();
+ sal_Bool bCopy = sal_False;
+ while ( nStart < nEnd && ( sLine.GetChar( nStart ) == ' ' || sLine.GetChar( nStart ) == 0x09 ) )
+ {
+ nStart++;
+ bCopy = sal_True;
+ }
+
+ while ( nStart < nEnd && ( sLine.GetChar( nEnd-1 ) == ' ' || sLine.GetChar( nEnd-1 ) == 0x09 ) )
+ {
+ nEnd--;
+ bCopy = sal_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?
+ sal_uInt16 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 = sal_True;
+}
+
+/*****************************************************************************/
+sal_Bool InformationParser::Save( SvStream &rOutStream,
+ const GenericInformationList *pSaveList,
+ sal_uInt16 level, sal_Bool bStripped )
+/*****************************************************************************/
+{
+ sal_uInt16 i;
+ sal_uIntPtr 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 sal_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 sal_False;
+ // recursiv die sublist abarbeiten
+ if ( !Save( rOutStream, pGenericInfoList, level+1, bStripped ) )
+ return sal_False;
+ // schliessende Klammer
+ sTmpStr = "";
+ if ( !bStripped && level )
+ sTmpStr.Append( aKeyLevel.GetBuffer(), level );
+ sTmpStr += '}';
+ if ( !rOutStream.WriteLine( sTmpStr ) )
+ return sal_False;
+ }
+ }
+ return sal_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 ( sal_uInt16 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;
+}
+
+/*****************************************************************************/
+sal_Bool InformationParser::Save( SvFileStream &rSourceStream,
+ const GenericInformationList *pSaveList )
+/*****************************************************************************/
+{
+ if ( !rSourceStream.IsOpen() || !Save( (SvStream &)rSourceStream, pSaveList, 0, sal_False ))
+ {
+ printf( "ERROR saving file \"%s\"\n",ByteString( rSourceStream.GetFileName(), gsl_getSystemTextEncoding()).GetBuffer() );
+ return sal_False;
+ }
+
+ return sal_True;
+}
+
+/*****************************************************************************/
+sal_Bool InformationParser::Save( SvMemoryStream &rSourceStream,
+ const GenericInformationList *pSaveList )
+/*****************************************************************************/
+{
+ Time a;
+ sal_Bool bRet = Save( (SvStream &)rSourceStream, pSaveList, 0, sal_True );
+ Time b;
+ b = b - a;
+ return bRet;
+}
+
+/*****************************************************************************/
+sal_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 sal_False;
+ }
+ delete pOutFile;
+ return sal_True;
+}
+
+/*****************************************************************************/
+sal_uInt16 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;
+}
+
+
diff --git a/tools/source/datetime/datetime.cxx b/tools/source/datetime/datetime.cxx
new file mode 100644
index 000000000000..ffdbd25789ac
--- /dev/null
+++ b/tools/source/datetime/datetime.cxx
@@ -0,0 +1,442 @@
+/*************************************************************************
+ *
+ * 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
+|*
+*************************************************************************/
+
+sal_Bool DateTime::IsBetween( const DateTime& rFrom,
+ const DateTime& rTo ) const
+{
+ if ( (*this >= rFrom) && (*this <= rTo) )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator >()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 18.05.92
+|* Letzte Aenderung TH 18.05.92
+|*
+*************************************************************************/
+
+sal_Bool DateTime::operator >( const DateTime& rDateTime ) const
+{
+ if ( (Date::operator>( rDateTime )) ||
+ (Date::operator==( rDateTime ) && Time::operator>( rDateTime )) )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator <()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 18.05.92
+|* Letzte Aenderung TH 18.05.92
+|*
+*************************************************************************/
+
+sal_Bool DateTime::operator <( const DateTime& rDateTime ) const
+{
+ if ( (Date::operator<( rDateTime )) ||
+ (Date::operator==( rDateTime ) && Time::operator<( rDateTime )) )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator >=()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 18.05.92
+|* Letzte Aenderung TH 18.05.92
+|*
+*************************************************************************/
+
+sal_Bool DateTime::operator >=( const DateTime& rDateTime ) const
+{
+ if ( (Date::operator>( rDateTime )) ||
+ (Date::operator==( rDateTime ) && Time::operator>=( rDateTime )) )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+/*************************************************************************
+|*
+|* DateTime::operator <=()
+|*
+|* Beschreibung DATETIME.SDW
+|* Ersterstellung TH 18.05.92
+|* Letzte Aenderung TH 18.05.92
+|*
+*************************************************************************/
+
+sal_Bool DateTime::operator <=( const DateTime& rDateTime ) const
+{
+ if ( (Date::operator<( rDateTime )) ||
+ (Date::operator==( rDateTime ) && Time::operator<=( rDateTime )) )
+ return sal_True;
+ else
+ return sal_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, sal_uIntPtr nSec )
+{
+ long nDays = nSec / (24UL*60*60);
+ ((Date*)this)->operator=( rDate );
+ nSec -= nDays * (24UL*60*60);
+ sal_uInt16 nMin = (sal_uInt16)(nSec / 60);
+ nSec -= nMin * 60;
+ ((Time*)this)->operator=( Time( 0, nMin, (sal_uInt16)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;
+ sal_uInt16 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;
+ sal_uInt16 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;
+
+ sal_uInt16 nMonths = 0;
+ for( sal_Int64 nDaysCount = nDays; nDaysCount >= 0; )
+ {
+ nDays = nDaysCount;
+ nMonths ++;
+ nDaysCount -= Date(
+ 1, nMonths, sal::static_int_cast< sal_uInt16 >(1601 + nYears) ).
+ GetDaysInMonth();
+ }
+
+ Date _aDate(
+ (sal_uInt16)( nDays + 1 ), nMonths,
+ sal::static_int_cast< sal_uInt16 >(nYears + 1601) );
+ Time _aTime( sal_uIntPtr( ( aTime / ( a100nPerSecond * 60 * 60 ) ) % sal_Int64( 24 ) ),
+ sal_uIntPtr( ( aTime / ( a100nPerSecond * 60 ) ) % sal_Int64( 60 ) ),
+ sal_uIntPtr( ( aTime / ( a100nPerSecond ) ) % sal_Int64( 60 ) ) );
+
+ return DateTime( _aDate, _aTime );
+}
diff --git a/tools/source/datetime/tdate.cxx b/tools/source/datetime/tdate.cxx
new file mode 100644
index 000000000000..2a3c36daf9ed
--- /dev/null
+++ b/tools/source/datetime/tdate.cxx
@@ -0,0 +1,494 @@
+/*************************************************************************
+ *
+ * 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 sal_uInt16 aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30,
+ 31, 31, 30, 31, 30, 31 };
+
+#define MAX_DAYS 3636532
+
+// =======================================================================
+
+inline sal_Bool ImpIsLeapYear( sal_uInt16 nYear )
+{
+ return (
+ ( ((nYear % 4) == 0) && ((nYear % 100) != 0) ) ||
+ ( (nYear % 400) == 0 )
+ );
+}
+
+// -----------------------------------------------------------------------
+
+inline sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16 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( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear )
+{
+ long nDays;
+
+ nDays = ((sal_uIntPtr)nYear-1) * 365;
+ nDays += ((nYear-1) / 4) - ((nYear-1) / 100) + ((nYear-1) / 400);
+ for( sal_uInt16 i = 1; i < nMonth; i++ )
+ nDays += DaysInMonth(i,nYear);
+ nDays += nDay;
+ return nDays;
+}
+
+// -----------------------------------------------------------------------
+
+static void DaysToDate( long nDays,
+ sal_uInt16& rDay, sal_uInt16& rMonth, sal_uInt16& rYear )
+{
+ long nTempDays;
+ long i = 0;
+ sal_Bool bCalc;
+
+ do
+ {
+ nTempDays = (long)nDays;
+ rYear = (sal_uInt16)((nTempDays / 365) - i);
+ nTempDays -= ((sal_uIntPtr)rYear-1) * 365;
+ nTempDays -= ((rYear-1) / 4) - ((rYear-1) / 100) + ((rYear-1) / 400);
+ bCalc = sal_False;
+ if ( nTempDays < 1 )
+ {
+ i++;
+ bCalc = sal_True;
+ }
+ else
+ {
+ if ( nTempDays > 365 )
+ {
+ if ( (nTempDays != 366) || !ImpIsLeapYear( rYear ) )
+ {
+ i--;
+ bCalc = sal_True;
+ }
+ }
+ }
+ }
+ while ( bCalc );
+
+ rMonth = 1;
+ while ( (sal_uIntPtr)nTempDays > DaysInMonth( rMonth, rYear ) )
+ {
+ nTempDays -= DaysInMonth( rMonth, rYear );
+ rMonth++;
+ }
+ rDay = (sal_uInt16)nTempDays;
+}
+
+// =======================================================================
+
+Date::Date()
+{
+#if defined( OS2 )
+ DATETIME aDateTime;
+ DosGetDateTime( &aDateTime );
+
+ // Datum zusammenbauen
+ nDate = ((sal_uIntPtr)aDateTime.day) +
+ (((sal_uIntPtr)aDateTime.month)*100) +
+ (((sal_uIntPtr)aDateTime.year)*10000);
+#elif defined WNT
+ SYSTEMTIME aDateTime;
+ GetLocalTime( &aDateTime );
+
+ // Datum zusammenbauen
+ nDate = ((sal_uIntPtr)aDateTime.wDay) +
+ (((sal_uIntPtr)aDateTime.wMonth)*100) +
+ (((sal_uIntPtr)aDateTime.wYear)*10000);
+#else
+ time_t nTmpTime;
+ struct tm aTime;
+
+ // Zeit ermitteln
+ nTmpTime = time( 0 );
+
+ // Datum zusammenbauen
+ if ( localtime_r( &nTmpTime, &aTime ) )
+ {
+ nDate = ((sal_uIntPtr)aTime.tm_mday) +
+ (((sal_uIntPtr)(aTime.tm_mon+1))*100) +
+ (((sal_uIntPtr)(aTime.tm_year+1900))*10000);
+ }
+ else
+ nDate = 1 + 100 + (((sal_uIntPtr)1900)*10000);
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Date::SetDay( sal_uInt16 nNewDay )
+{
+ sal_uIntPtr nMonth = GetMonth();
+ sal_uIntPtr nYear = GetYear();
+
+ nDate = ((sal_uIntPtr)(nNewDay%100)) + (nMonth*100) + (nYear*10000);
+}
+
+// -----------------------------------------------------------------------
+
+void Date::SetMonth( sal_uInt16 nNewMonth )
+{
+ sal_uIntPtr nDay = GetDay();
+ sal_uIntPtr nYear = GetYear();
+
+ nDate = nDay + (((sal_uIntPtr)(nNewMonth%100))*100) + (nYear*10000);
+}
+
+// -----------------------------------------------------------------------
+
+void Date::SetYear( sal_uInt16 nNewYear )
+{
+ sal_uIntPtr nDay = GetDay();
+ sal_uIntPtr nMonth = GetMonth();
+
+ nDate = nDay + (nMonth*100) + (((sal_uIntPtr)(nNewYear%10000))*10000);
+}
+
+// -----------------------------------------------------------------------
+
+DayOfWeek Date::GetDayOfWeek() const
+{
+ return (DayOfWeek)((sal_uIntPtr)(DateToDays( GetDay(), GetMonth(), GetYear() )-1) % 7);
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 Date::GetDayOfYear() const
+{
+ sal_uInt16 nDay = GetDay();
+ for( sal_uInt16 i = 1; i < GetMonth(); i++ )
+ nDay = nDay + ::DaysInMonth( i, GetYear() ); // += yields a warning on MSVC, so don't use it
+ return nDay;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 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;
+ sal_uInt16 nDay;
+ sal_uInt16 nMonth;
+ sal_uInt16 nYear;
+ DaysToDate( nTempDays, nDay, nMonth, nYear );
+ nWeek = Date( nDay, nMonth, nYear ).GetWeekOfYear( eStartDay, nMinimumNumberOfDaysInWeek );
+ }
+ }
+ }
+
+ return (sal_uInt16)nWeek;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 Date::GetDaysInMonth() const
+{
+ return DaysInMonth( GetMonth(), GetYear() );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Date::IsLeapYear() const
+{
+ sal_uInt16 nYear = GetYear();
+ return ImpIsLeapYear( nYear );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Date::IsValid() const
+{
+ sal_uInt16 nDay = GetDay();
+ sal_uInt16 nMonth = GetMonth();
+ sal_uInt16 nYear = GetYear();
+
+ if ( !nMonth || (nMonth > 12) )
+ return sal_False;
+ if ( !nDay || (nDay > DaysInMonth( nMonth, nYear )) )
+ return sal_False;
+ else if ( nYear <= 1582 )
+ {
+ if ( nYear < 1582 )
+ return sal_False;
+ else if ( nMonth < 10 )
+ return sal_False;
+ else if ( (nMonth == 10) && (nDay < 15) )
+ return sal_False;
+ }
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+Date& Date::operator +=( long nDays )
+{
+ sal_uInt16 nDay;
+ sal_uInt16 nMonth;
+ sal_uInt16 nYear;
+ long nTempDays = DateToDays( GetDay(), GetMonth(), GetYear() );
+
+ nTempDays += nDays;
+ if ( nTempDays > MAX_DAYS )
+ nDate = 31 + (12*100) + (((sal_uIntPtr)9999)*10000);
+ else if ( nTempDays <= 0 )
+ nDate = 1 + 100;
+ else
+ {
+ DaysToDate( nTempDays, nDay, nMonth, nYear );
+ nDate = ((sal_uIntPtr)nDay) + (((sal_uIntPtr)nMonth)*100) + (((sal_uIntPtr)nYear)*10000);
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+Date& Date::operator -=( long nDays )
+{
+ sal_uInt16 nDay;
+ sal_uInt16 nMonth;
+ sal_uInt16 nYear;
+ long nTempDays = DateToDays( GetDay(), GetMonth(), GetYear() );
+
+ nTempDays -= nDays;
+ if ( nTempDays > MAX_DAYS )
+ nDate = 31 + (12*100) + (((sal_uIntPtr)9999)*10000);
+ else if ( nTempDays <= 0 )
+ nDate = 1 + 100;
+ else
+ {
+ DaysToDate( nTempDays, nDay, nMonth, nYear );
+ nDate = ((sal_uIntPtr)nDay) + (((sal_uIntPtr)nMonth)*100) + (((sal_uIntPtr)nYear)*10000);
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+Date& Date::operator ++()
+{
+ sal_uInt16 nDay;
+ sal_uInt16 nMonth;
+ sal_uInt16 nYear;
+ long nTempDays = DateToDays( GetDay(), GetMonth(), GetYear() );
+
+ if ( nTempDays < MAX_DAYS )
+ {
+ nTempDays++;
+ DaysToDate( nTempDays, nDay, nMonth, nYear );
+ nDate = ((sal_uIntPtr)nDay) + (((sal_uIntPtr)nMonth)*100) + (((sal_uIntPtr)nYear)*10000);
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+Date& Date::operator --()
+{
+ sal_uInt16 nDay;
+ sal_uInt16 nMonth;
+ sal_uInt16 nYear;
+ long nTempDays = DateToDays( GetDay(), GetMonth(), GetYear() );
+
+ if ( nTempDays > 1 )
+ {
+ nTempDays--;
+ DaysToDate( nTempDays, nDay, nMonth, nYear );
+ nDate = ((sal_uIntPtr)nDay) + (((sal_uIntPtr)nMonth)*100) + (((sal_uIntPtr)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 )
+{
+ sal_uIntPtr nTempDays1 = Date::DateToDays( rDate1.GetDay(), rDate1.GetMonth(),
+ rDate1.GetYear() );
+ sal_uIntPtr nTempDays2 = Date::DateToDays( rDate2.GetDay(), rDate2.GetMonth(),
+ rDate2.GetYear() );
+ return nTempDays1 - nTempDays2;
+}
diff --git a/tools/source/datetime/ttime.cxx b/tools/source/datetime/ttime.cxx
new file mode 100644
index 000000000000..fee1c159df44
--- /dev/null
+++ b/tools/source/datetime/ttime.cxx
@@ -0,0 +1,445 @@
+/*************************************************************************
+ *
+ * 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( sal_uIntPtr nHour, sal_uIntPtr nMin, sal_uIntPtr nSec, sal_uIntPtr 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( sal_uInt16 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( sal_uInt16 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( sal_uInt16 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( sal_uInt16 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 ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_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, (sal_uInt16)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, (sal_uInt16)Abs( nTempTime ) );
+ if ( nTempTime > 0 )
+ aTime = -aTime;
+ return aTime;
+#else
+ static sal_uIntPtr nCacheTicks = 0;
+ static sal_Int32 nCacheSecOffset = -1;
+ sal_uIntPtr 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, (sal_uInt16)nTempTime );
+ if ( nCacheSecOffset < 0 )
+ aTime = -aTime;
+ return aTime;
+#endif
+}
+
+
+// -----------------------------------------------------------------------
+
+sal_uIntPtr Time::GetSystemTicks()
+{
+#if defined WNT
+ return (sal_uIntPtr)GetTickCount();
+#elif defined( OS2 )
+ sal_uIntPtr nClock;
+ DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &nClock, sizeof( nClock ) );
+ return (sal_uIntPtr)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 sal_uIntPtr(fTicks);
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+sal_uIntPtr Time::GetProcessTicks()
+{
+#if defined WNT
+ return (sal_uIntPtr)GetTickCount();
+#elif defined( OS2 )
+ sal_uIntPtr nClock;
+ DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &nClock, sizeof( nClock ) );
+ return (sal_uIntPtr)nClock;
+#else
+ static sal_uIntPtr nImplTicksPerSecond = 0;
+ static double dImplTicksPerSecond;
+ static double dImplTicksULONGMAX;
+ sal_uIntPtr nTicks = (sal_uIntPtr)clock();
+
+ if ( !nImplTicksPerSecond )
+ {
+ nImplTicksPerSecond = CLOCKS_PER_SEC;
+ dImplTicksPerSecond = nImplTicksPerSecond;
+ dImplTicksULONGMAX = (double)(sal_uIntPtr)ULONG_MAX;
+ }
+
+ double fTicks = nTicks;
+ fTicks *= 1000;
+ fTicks /= dImplTicksPerSecond;
+ fTicks = fmod (fTicks, dImplTicksULONGMAX);
+ return (sal_uIntPtr)fTicks;
+#endif
+}
diff --git a/tools/source/debug/debug.cxx b/tools/source/debug/debug.cxx
new file mode 100644
index 000000000000..bbde4efe6d9e
--- /dev/null
+++ b/tools/source/debug/debug.cxx
@@ -0,0 +1,1826 @@
+/*************************************************************************
+ *
+ * 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 <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];
+ sal_uInt16 nCount;
+ PBlock* pPrev;
+ PBlock* pNext;
+};
+
+class PointerList
+{
+private:
+ PBlock* pFirst;
+ PBlock* pLast;
+ sal_uIntPtr nCount;
+
+public:
+ PointerList() { pFirst = NULL; pLast = NULL; nCount = 0; }
+ ~PointerList();
+
+ void Add( const void* p );
+ sal_Bool Remove( const void* p );
+
+ const void* Get( sal_uIntPtr nPos ) const;
+ sal_Bool IsIn( const void* p ) const;
+ sal_uIntPtr Count() const { return nCount; }
+};
+
+// --- Datentypen ---
+
+#define DBG_MAXNAME 28
+
+struct ProfType
+{
+ sal_uIntPtr nCount;
+ sal_uIntPtr nTime;
+ sal_uIntPtr nMinTime;
+ sal_uIntPtr nMaxTime;
+ sal_uIntPtr nStart;
+ sal_uIntPtr nContinueTime;
+ sal_uIntPtr nContinueStart;
+ sal_Char aName[DBG_MAXNAME+1];
+};
+
+struct XtorType
+{
+ sal_uIntPtr nCtorCalls;
+ sal_uIntPtr nDtorCalls;
+ sal_uIntPtr nMaxCount;
+ sal_uIntPtr nStatics;
+ sal_Char aName[DBG_MAXNAME+1];
+ sal_Bool bTest;
+ PointerList aThisList;
+};
+
+struct DebugData
+{
+ DbgData aDbgData;
+ sal_uInt16 bInit;
+ DbgPrintLine pDbgPrintMsgBox;
+ DbgPrintLine pDbgPrintWindow;
+ DbgPrintLine pDbgPrintTestTool;
+ DbgPrintLine pDbgAbort;
+ ::std::vector< DbgPrintLine >
+ aDbgPrintUserChannels;
+ PointerList* pProfList;
+ PointerList* pXtorList;
+ DbgTestSolarMutexProc pDbgTestSolarMutex;
+ pfunc_osl_printDetailedDebugMessage
+ pOldDebugMessageFunc;
+ bool bOslIsHooked;
+
+ DebugData()
+ :bInit( sal_False )
+ ,pDbgPrintMsgBox( NULL )
+ ,pDbgPrintWindow( NULL )
+ ,pDbgPrintTestTool( NULL )
+ ,pDbgAbort( NULL )
+ ,pProfList( NULL )
+ ,pXtorList( NULL )
+ ,pDbgTestSolarMutex( NULL )
+ ,pOldDebugMessageFunc( NULL )
+ ,bOslIsHooked( false )
+ {
+ aDbgData.nTestFlags = DBG_TEST_RESOURCE | DBG_TEST_MEM_INIT;
+ aDbgData.bOverwrite = sal_True;
+ aDbgData.nTraceOut = DBG_OUT_NULL;
+ aDbgData.nWarningOut = DBG_OUT_NULL;
+ aDbgData.nErrorOut = DBG_OUT_MSGBOX;
+ aDbgData.bMemInit = 0x77;
+ aDbgData.bMemBound = 0x55;
+ aDbgData.bMemFree = 0x33;
+ aDbgData.bHookOSLAssert = sal_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 = sal_False;
+
+// =======================================================================
+
+#if defined( WNT )
+static CRITICAL_SECTION aImplCritDbgSection;
+#elif defined( OS2 )
+static HMTX hImplCritDbgSection = 0;
+#endif
+static sal_Bool bImplCritDbgSectionInit = sal_False;
+
+// -----------------------------------------------------------------------
+
+void ImplDbgInitLock()
+{
+#if defined( WNT )
+ InitializeCriticalSection( &aImplCritDbgSection );
+#elif defined( OS2 )
+ DosCreateMutexSem( NULL, &hImplCritDbgSection, 0, sal_False );
+#endif
+ bImplCritDbgSectionInit = sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDbgDeInitLock()
+{
+#if defined( WNT )
+ DeleteCriticalSection( &aImplCritDbgSection );
+#elif defined( OS2 )
+ DosCloseMutexSem( hImplCritDbgSection );
+#endif
+ bImplCritDbgSectionInit = sal_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 sal_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 sal_True;
+#else
+ (void) pMsg; // avoid warning about unused parameter
+ return sal_False;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static sal_Bool ImplCoreDump()
+{
+#if defined( WNT )
+ DebugBreak();
+#else
+ long* pTemp = 0;
+ *pTemp = 0xCCCC;
+#endif
+ return sal_True;
+}
+
+// =======================================================================
+
+static sal_uIntPtr ImplGetPerfTime()
+{
+#if defined( WNT )
+ return (sal_uIntPtr)GetTickCount();
+#elif defined( OS2 )
+ sal_uIntPtr nClock;
+ DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &nClock, sizeof( nClock ) );
+ return (sal_uIntPtr)nClock;
+#else
+ static sal_uIntPtr nImplTicksPerSecond = 0;
+ static double dImplTicksPerSecond;
+ sal_uIntPtr nTicks = (sal_uIntPtr)clock();
+
+ if ( !nImplTicksPerSecond )
+ {
+ nImplTicksPerSecond = CLOCKS_PER_SEC;
+ dImplTicksPerSecond = nImplTicksPerSecond;
+ }
+
+ double fTicks = nTicks;
+ fTicks *= 1000;
+ fTicks /= dImplTicksPerSecond;
+ return (sal_uIntPtr)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, sal_uIntPtr _nAllFlags, sal_uIntPtr _nCheckFlag )
+ {
+ lcl_writeConfigBoolean( _pFile, _pKeyName, ( _nAllFlags & _nCheckFlag ) != 0 );
+ }
+
+ void lcl_writeConfigOutChannel( FILETYPE _pFile, const sal_Char* _pKeyName, sal_uIntPtr _nValue )
+ {
+ const sal_Char* names[ DBG_OUT_COUNT ] =
+ {
+ "dev/null", "file", "window", "shell", "messagebox", "testtool", "debugger", "abort"
+ };
+ lcl_writeConfigString( _pFile, _pKeyName, names[ _nValue ] );
+ }
+ void lcl_writeHexByte( FILETYPE _pFile, const sal_Char* _pKeyName, sal_uInt8 _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, sal_uIntPtr* _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 ? sal_True : sal_False;
+ }
+ void lcl_matchOutputChannel( sal_Char const * i_buffer, sal_uIntPtr* o_value )
+ {
+ if ( i_buffer == NULL )
+ return;
+ const sal_Char* names[ DBG_OUT_COUNT ] =
+ {
+ "dev/null", "file", "window", "shell", "messagebox", "testtool", "debugger", "abort"
+ };
+ for ( sal_uIntPtr name = 0; name < sizeof( names ) / sizeof( names[0] ); ++name )
+ {
+ if ( strcmp( i_buffer, names[ name ] ) == 0 )
+ {
+ *o_value = name;
+ return;
+ }
+ }
+ }
+ void lcl_tryReadOutputChannel( const sal_Char* _pLine, size_t _nLineLen, const sal_Char* _pKeyName, sal_uIntPtr* _out_pnValue )
+ {
+ sal_Char aBuf[20];
+ size_t nValueLen = lcl_tryReadConfigString( _pLine, _nLineLen, _pKeyName, aBuf, sizeof( aBuf ) );
+ if ( nValueLen )
+ lcl_matchOutputChannel( aBuf, _out_pnValue );
+ }
+ void lcl_tryReadConfigFlag( const sal_Char* _pLine, size_t _nLineLen, const sal_Char* _pKeyName, sal_uIntPtr* _out_pnAllFlags, sal_uIntPtr _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, sal_uInt8* _out_pnValue )
+ {
+ sal_Char aBuf[3];
+ size_t nValueLen = lcl_tryReadConfigString( _pLine, _nLineLen, _pKeyName, aBuf, sizeof( aBuf ) );
+ if ( nValueLen )
+ *_out_pnValue = (sal_uInt8)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;
+ }
+
+ sal_uInt16 i = 0;
+ while ( pBlock->aData[i] )
+ i++;
+
+ pBlock->aData[i] = (void*)p;
+ pBlock->nCount++;
+ nCount++;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool PointerList::Remove( const void* p )
+{
+ if ( !p )
+ return sal_False;
+
+ PBlock* pBlock = pFirst;
+ while ( pBlock )
+ {
+ sal_uInt16 i = 0;
+ while ( i < PBLOCKCOUNT )
+ {
+ if ( ((sal_uIntPtr)p) == ((sal_uIntPtr)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 sal_True;
+ }
+ i++;
+ }
+
+ pBlock = pBlock->pNext;
+ }
+
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------
+
+const void* PointerList::Get( sal_uIntPtr nPos ) const
+{
+ if ( nCount <= nPos )
+ return NULL;
+
+ PBlock* pBlock = pFirst;
+ sal_uIntPtr nStart = 0;
+ while ( pBlock )
+ {
+ sal_uInt16 i = 0;
+ while ( i < PBLOCKCOUNT )
+ {
+ if ( pBlock->aData[i] )
+ {
+ nStart++;
+ if ( (nStart-1) == nPos )
+ return pBlock->aData[i];
+ }
+
+ i++;
+ }
+
+ pBlock = pBlock->pNext;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool PointerList::IsIn( const void* p ) const
+{
+ if ( !p )
+ return sal_False;
+
+ PBlock* pBlock = pFirst;
+ while ( pBlock )
+ {
+ sal_uInt16 i = 0;
+ while ( i < PBLOCKCOUNT )
+ {
+ if ( ((sal_uIntPtr)p) == ((sal_uIntPtr)pBlock->aData[i]) )
+ return sal_True;
+ i++;
+ }
+
+ pBlock = pBlock->pNext;
+ }
+
+ return sal_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 = sal_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 ...
+ sal_uIntPtr 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 );
+ }
+ else
+ {
+ lcl_matchOutputChannel( getenv( "DBGSV_TRACE_OUT" ), &aDebugData.aDbgData.nTraceOut );
+ lcl_matchOutputChannel( getenv( "DBGSV_WARNING_OUT" ), &aDebugData.aDbgData.nWarningOut );
+ lcl_matchOutputChannel( getenv( "DBGSV_ERROR_OUT" ), &aDebugData.aDbgData.nErrorOut );
+
+ }
+
+ 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 sal_Bool bFileInit = sal_False;
+
+ sal_Char aBuf[4096];
+ getcwd( aBuf, sizeof( aBuf ) );
+ chdir( aCurPath );
+
+ DebugData* pData = GetDebugData();
+ FILETYPE pDebugFile;
+
+ if ( !bFileInit )
+ {
+ bFileInit = sal_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 sal_True;
+
+ pTok += nTok+1;
+ nTok = 0;
+ }
+
+ nTok++;
+ }
+
+ if ( nTok && ImplStrSearch( pTok, nTok, pMsg, nMsgLen ) )
+ return sal_True;
+ else
+ return sal_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, (sal_uInt16)nLine );
+}
+
+// -----------------------------------------------------------------------
+
+static void DebugInit()
+{
+ bDbgImplInMain = sal_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();
+ sal_uIntPtr i;
+ sal_uIntPtr nCount;
+ sal_uIntPtr nOldOut;
+
+ if( pData->bOslIsHooked )
+ {
+ osl_setDetailedDebugMessageFunc( pData->pOldDebugMessageFunc );
+ pData->bOslIsHooked = sal_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 sal_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();
+ sal_uIntPtr i;
+ sal_uIntPtr nCount;
+ sal_uIntPtr 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 );
+ sal_uIntPtr 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();
+ sal_uIntPtr i;
+ sal_uIntPtr 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, "" );
+ }
+}
+
+// -----------------------------------------------------------------------
+sal_Bool ImplDbgFilterMessage( const sal_Char* pMsg )
+{
+ DebugData* pData = GetDebugData();
+ if ( !ImplDbgFilter( pData->aDbgData.aInclFilter, pMsg, sal_True ) )
+ return sal_True;
+ if ( ImplDbgFilter( pData->aDbgData.aExclFilter, pMsg, sal_False ) )
+ return sal_True;
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------
+
+void* DbgFunc( sal_uInt16 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_SET_ABORT:
+ pDebugData->pDbgAbort = (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*)(sal_uIntPtr)sal_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 = sal_False;
+ }
+ else if( ! pDebugData->bOslIsHooked && pData->bHookOSLAssert )
+ {
+ pDebugData->pOldDebugMessageFunc = osl_setDetailedDebugMessageFunc( &dbg_printOslDebugMessage );
+ pDebugData->bOslIsHooked = sal_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( sal_uInt16 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;
+ sal_uIntPtr 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, sal_uInt16 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 = sal_True;
+ pData->pXtorList->Add( (void*)pXtorData );
+
+ if ( !ImplDbgFilter( pData->aDbgData.aInclClassFilter, pXtorData->aName, sal_True ) )
+ pXtorData->bTest = sal_False;
+ if ( ImplDbgFilter( pData->aDbgData.aExclClassFilter, pXtorData->aName, sal_False ) )
+ pXtorData->bTest = sal_False;
+ }
+ if ( !pXtorData->bTest )
+ return;
+
+ sal_Char aBuf[DBG_BUF_MAXLEN];
+ sal_uInt16 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, sal_uInt16 nDbgOut, const sal_Char* pFile, sal_uInt16 nLine )
+{
+ static sal_Bool bIn = sal_False;
+ if ( bIn )
+ return;
+ bIn = sal_True;
+
+ DebugData* pData = GetDebugData();
+ sal_Char const * pStr;
+ sal_uIntPtr 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 = sal_False;
+ return;
+ }
+
+ if ( ImplDbgFilterMessage( pMsg ) )
+ {
+ bIn = sal_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];
+ sal_uInt16 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_ABORT )
+ {
+ if ( pData->pDbgAbort != NULL )
+ pData->pDbgAbort( aBufOut );
+ abort();
+ }
+
+ 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 = sal_False;
+}
+
+void DbgPrintShell(char const * message) {
+ fprintf(stderr, "%s\n", message);
+#if defined WNT
+ OutputDebugStringA(message);
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void DbgOutTypef( sal_uInt16 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( sal_uInt16, void* ) { return NULL; }
+
+void DbgProf( sal_uInt16, DbgDataType* ) {}
+void DbgXtor( DbgDataType*, sal_uInt16, const void*, DbgUsr ) {}
+
+void DbgOut( const sal_Char*, sal_uInt16, const sal_Char*, sal_uInt16 ) {}
+void DbgOutTypef( sal_uInt16, const sal_Char*, ... ) {}
+void DbgOutf( const sal_Char*, ... ) {}
+
+#endif
diff --git a/tools/source/debug/stcktree.cxx b/tools/source/debug/stcktree.cxx
new file mode 100644
index 000000000000..34cda7e81119
--- /dev/null
+++ b/tools/source/debug/stcktree.cxx
@@ -0,0 +1,320 @@
+/*************************************************************************
+ *
+ * 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_;
+ sal_uIntPtr nIP_;
+ sal_uIntPtr nBytesLeak_;
+ sal_uIntPtr nBytesPeak_;
+ sal_uIntPtr nBytes_;
+ sal_uIntPtr nCountLeak_;
+ sal_uIntPtr nCountPeak_;
+ sal_uIntPtr nCount_;
+ sal_uIntPtr nMax_;
+ sal_uIntPtr nMin_;
+
+ ImpDbgStackTree( ImpDbgStackTree* pSub, sal_uIntPtr nIP );
+ ~ImpDbgStackTree();
+
+ ImpDbgStackTree* Add( sal_uIntPtr nAlloc, sal_uIntPtr* pBP, sal_uIntPtr nIP );
+ void Print( int nLevel, sal_uIntPtr nCount, sal_uIntPtr nCountLeak );
+ void Print( int nLevel );
+};
+
+static ImpDbgStackTree* pImpDbgStackTreeRoot = NULL;
+static sal_uIntPtr* pImpDbgStackTreeBP = NULL;
+static sal_uIntPtr nImpDbgStackTreeMain = 0;
+static int nImpDbgStackTreeSem = 0;
+
+// -----------------------------------------------------------------------
+
+ImpDbgStackTree::ImpDbgStackTree( ImpDbgStackTree* pSub, sal_uIntPtr 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, sal_uIntPtr nCount, sal_uIntPtr nCountLeak )
+{
+ if ( pLeft_ )
+ pLeft_->Print( nLevel, nCount, nCountLeak );
+
+ if ( nCount_ >= nCount && nCountLeak_ >= nCountLeak )
+ {
+ if ( nMax_ == nMin_ )
+ {
+ sal_uIntPtr 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( sal_uIntPtr nAlloc, sal_uIntPtr *pBP, sal_uIntPtr 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) && (sal_uIntPtr)pBP < pBP[0] && pBP[0] < (sal_uIntPtr)pImpDbgStackTreeBP )
+ {
+ pBP = (sal_uIntPtr*)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 )
+ {
+ sal_uIntPtr* pBP;
+ __asm mov pBP, ebp;
+
+ pImpDbgStackTreeBP = (sal_uIntPtr*)pBP[0];
+ nImpDbgStackTreeMain = pImpDbgStackTreeBP[1];
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void DbgEndStackTree()
+{
+ if ( nImpDbgStackTreeMain )
+ {
+ nImpDbgStackTreeMain = 0;
+ if ( pImpDbgStackTreeRoot )
+ {
+ // Ausgaben ins File umleiten
+ DbgData* pData = DbgGetData();
+ sal_uIntPtr 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( sal_uIntPtr nAlloc )
+{
+ ImpDbgStackTree* pReturn = NULL;
+
+ if ( nImpDbgStackTreeMain && !nImpDbgStackTreeSem )
+ {
+ nImpDbgStackTreeSem++;
+
+ sal_uIntPtr* pBP;
+ __asm mov pBP, ebp;
+
+ sal_uIntPtr nIP = pBP[1];
+ if ( !pImpDbgStackTreeRoot )
+ pImpDbgStackTreeRoot = new ImpDbgStackTree( NULL, nIP );
+ pReturn = pImpDbgStackTreeRoot->Add( nAlloc, pBP, nIP );
+ nImpDbgStackTreeSem--;
+ }
+
+ return pReturn;
+}
+
+// -----------------------------------------------------------------------
+
+void DbgFreeStackTree( void* pVoid, sal_uIntPtr 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();
+ sal_uIntPtr 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( sal_uIntPtr ) { return NULL; }
+void DbgFreeStackTree( void*, sal_uIntPtr ) {}
+void DbgPrintStackTree( void* ) {}
+
+#endif
diff --git a/tools/source/fsys/comdep.cxx b/tools/source/fsys/comdep.cxx
new file mode 100644
index 000000000000..fa1009ad5fd3
--- /dev/null
+++ b/tools/source/fsys/comdep.cxx
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/source/fsys/comdep.hxx b/tools/source/fsys/comdep.hxx
new file mode 100755
index 000000000000..cd6f8db2cd57
--- /dev/null
+++ b/tools/source/fsys/comdep.hxx
@@ -0,0 +1,156 @@
+/*************************************************************************
+ *
+ * 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;
+ sal_Bool bReady;
+ sal_Bool bInUse;
+
+ DirReader_Impl( Dir &rDir )
+ : pDir( &rDir ),
+ pDosEntry( 0 ),
+ pParent( 0 ),
+ aPath( GUI2FSYS(rDir.GetFull()) ),
+ bReady ( sal_False ),
+ bInUse( sal_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
+ sal_uInt16 Init(); // initialisiert, liest ggf. devices
+ sal_uInt16 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
+sal_Bool IsRedirectable_Impl( const ByteString &rPath );
+#else
+#define IsRedirectable_Impl( rPath ) sal_True
+#endif
+
+//--------------------------------------------------------------------
+
+
+#endif
diff --git a/tools/source/fsys/dirent.cxx b/tools/source/fsys/dirent.cxx
new file mode 100755
index 000000000000..0c9e45cb72f2
--- /dev/null
+++ b/tools/source/fsys/dirent.cxx
@@ -0,0 +1,3213 @@
+/*************************************************************************
+ *
+ * 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>
+
+#ifndef _VOS_MUTEX_HXX
+#include <vos/mutex.hxx>
+#endif
+
+#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;
+sal_Bool FSysRedirector::_bEnabled = sal_True;
+#ifdef UNX
+sal_Bool bInRedirection = sal_True;
+#else
+sal_Bool bInRedirection = sal_False;
+#endif
+static vos:: OMutex * pRedirectMutex = 0;
+
+//------------------------------------------------------------------------
+void FSysRedirector::Register( FSysRedirector *pRedirector )
+{
+ if ( pRedirector )
+ pRedirectMutex = new vos:: OMutex ;
+ 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)
+ vos:: OGuard aGuard( pRedirectMutex );
+
+ // if already in redirection, dont redirect
+ if ( bInRedirection )
+ return;
+
+ // dont redirect on nested calls
+ bInRedirection = sal_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 = sal_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, sal_uInt16 nMax, char cAccDel )
+{
+ sal_uInt16 nMaxPathLen = nMax;
+ ByteString aCutPath( rStr );
+ sal_Bool bInsertPrefix = sal_False;
+ sal_uInt16 nBegin = aCutPath.Search( cAccDel );
+
+ if( nBegin == STRING_NOTFOUND )
+ nBegin = 0;
+ else
+ nMaxPathLen += 2; // fuer Prefix <Laufwerk>:
+
+ while( aCutPath.Len() > nMaxPathLen )
+ {
+ sal_uInt16 nEnd = aCutPath.Search( cAccDel, nBegin + 1 );
+ sal_uInt16 nCount;
+
+ if ( nEnd != STRING_NOTFOUND )
+ {
+ nCount = nEnd - nBegin;
+ aCutPath.Erase( nBegin, nCount );
+ bInsertPrefix = sal_True;
+ }
+ else
+ break;
+ }
+
+ if ( aCutPath.Len() > nMaxPathLen )
+ {
+ for ( sal_uInt16 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
+ sal_uInt16 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() );
+
+ sal_uIntPtr 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:
+ {
+ sal_uInt16 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, sal_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
+|*
+*************************************************************************/
+
+sal_Bool DirEntry::Exists( FSysAccess nAccess ) const
+{
+#ifndef BOOTSTRAP
+ static vos::OMutex aLocalMutex;
+ vos::OGuard aGuard( aLocalMutex );
+#endif
+ if ( !IsValid() )
+ return sal_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 sal_True;
+#endif
+
+ FSysFailOnErrorImpl();
+ DirEntryKind eKind = FileStat( *this, nAccess ).GetKind();
+ if ( eKind & ( FSYS_KIND_FILE | FSYS_KIND_DIR ) )
+ {
+ return sal_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
+|*
+*************************************************************************/
+
+sal_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 sal_True;
+ }
+ }
+ closedir( pDir );
+ }
+ return sal_False;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::GetFull()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+String DirEntry::GetFull( FSysPathStyle eStyle, sal_Bool bWithDelimiter,
+ sal_uInt16 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
+|*
+*************************************************************************/
+
+sal_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 sal_True;
+ if ( nError || rEntry.nError ||
+ ( eFlag == FSYS_FLAG_INVALID ) ||
+ ( rEntry.eFlag == FSYS_FLAG_INVALID ) )
+ return sal_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 sal_Bool bTested = sal_False;
+ if ( !bTested )
+ {
+ bTested = sal_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):sal_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
+|*
+*************************************************************************/
+sal_Bool DirEntry::Find( const String& rPfad, char cDelim )
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ if ( ImpGetTopPtr()->eFlag == FSYS_FLAG_ABSROOT )
+ return sal_True;
+
+ sal_Bool bWild = aName.Search( '*' ) != STRING_NOTFOUND ||
+ aName.Search( '?' ) != STRING_NOTFOUND;
+ if ( !cDelim )
+ cDelim = SEARCHDELIM(DEFSTYLE)[0];
+
+ sal_uInt16 nTokenCount = rPfad.GetTokenCount( cDelim );
+ sal_uInt16 nIndex = 0;
+ ByteString aThis = ACCESSDELIM(DEFSTYLE);
+ aThis += ByteString(GetFull(), osl_getThreadTextEncoding());
+ for ( sal_uInt16 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 sal_True;
+ }
+ }
+ }
+ return sal_False;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::ImpToRel()
+|*
+|* Beschreibung
+|* Ersterstellung MI 17.06.93
+|* Letzte Aenderung MI 17.06.93
+|*
+*************************************************************************/
+
+sal_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
+ sal_uInt16 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 sal_True;
+ }
+
+ // Sonderfall, die DirEntries sind total verschieden
+ if ( nPos == 0 )
+ {
+ // dann ist der relativste Pfad absolut
+ *this = aThis;
+ return sal_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 sal_True;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::CutRelParents()
+|*
+|* Beschreibung
+|* Ersterstellung MI 01.08.95
+|* Letzte Aenderung MI 01.08.95
+|*
+*************************************************************************/
+
+sal_uInt16 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
+ sal_uInt16 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
+|*
+*************************************************************************/
+
+sal_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
+|*
+*************************************************************************/
+
+sal_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
+|*
+*************************************************************************/
+
+sal_uInt16 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 sal_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[]( sal_uInt16 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
+ sal_uInt16 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 ( sal_uInt16 n = aHome.Level(); n; --n )
+ aStack.Push( new DirEntry( aHome[ (sal_uInt16) 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;
+}
+
+sal_Bool IsValidEntry_Impl( const DirEntry &rPath,
+ const String &rLongName,
+ DirEntryKind eKind,
+ sal_Bool bIsShortened,
+ sal_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 sal_False;
+ aPath += aName;
+ if ( 1 == aPath.Level() )
+ return sal_False;
+ if ( eStyle == FSYS_STYLE_FAT || eStyle == FSYS_STYLE_NWFS ||
+ eStyle == FSYS_STYLE_UNKNOWN )
+ {
+ DirEntry aDosEntry( rLongName, FSYS_STYLE_FAT );
+ if ( !aDosEntry.IsValid() )
+ return sal_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 sal_False;
+ }
+
+ // MI: Abfrage nach 'CON:' etc. wird jetzt in Exists() mitgemacht
+ if ( aPath.Exists() )
+ return sal_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 "\\/\"':|^<>?*"
+
+sal_Bool DirEntry::MakeShortName( const String& rLongName, DirEntryKind eKind,
+ sal_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
+
+ // HRO: #69627# Weg mit dem Scheiss. Wenn es Client gibt, die so einen
+ // BUG haben, dann muss halt der Client ersetzt werden, aber doch nicht das
+ // Office kastrieren !!!
+
+#if 0
+ if ( FSYS_STYLE_NWFS == GetPathStyle( ImpGetTopPtr()->GetName() ) )
+ {
+ for ( sal_uInt16 n = aLongName.Len(); n; --n )
+ {
+ short nChar = aLongName(n-1);
+ if ( nChar < 32 || nChar >= 127 )
+ aLongName.Erase( n-1, 1 );
+ }
+ }
+#endif
+
+ // 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, sal_False, bUseDelim ) )
+ {
+ operator+=( DirEntry(aLongName) );
+ return sal_True;
+ }
+
+ // max L"angen feststellen
+ sal_uInt16 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 sal_True;
+
+ // kann der gek"urzte Name direkt verwendet werden?
+ if ( !Exists() && (ERRCODE_NONE == CreateEntry_Impl( *this, eKind )) )
+ return sal_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 sal_False;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::CreatePath()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 26.04.91
+|* Letzte Aenderung MA 02.12.91
+|*
+*************************************************************************/
+
+sal_Bool DirEntry::MakeDir( sal_Bool bSloppy ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ // Schnellpruefung, ob vorhanden
+ if ( FileStat( *this ).IsKind( FSYS_KIND_DIR ) )
+ return sal_True;
+ if ( bSloppy && pParent )
+ if ( FileStat( *pParent ).IsKind( FSYS_KIND_DIR ) )
+ return sal_True;
+
+ const DirEntry *pNewDir = bSloppy ? pParent : this;
+ if ( pNewDir )
+ {
+ // den Path zum Dir erzeugen
+ if ( pNewDir->pParent && !pNewDir->pParent->MakeDir(sal_False) )
+ return sal_False;
+
+ // das Dir selbst erzeugen
+ if ( pNewDir->eFlag == FSYS_FLAG_ABSROOT ||
+ pNewDir->eFlag == FSYS_FLAG_ABSROOT ||
+ pNewDir->eFlag == FSYS_FLAG_VOLUME )
+ return sal_True;
+ else
+ {
+ //? nError = ???
+ if ( FileStat( *pNewDir ).IsKind( FSYS_KIND_DIR ) )
+ return sal_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
+ sal_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 sal_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 sal_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
+ sal_Bool isReadOnly = FileStat::GetReadOnlyFlag(*this);
+ if (isReadOnly)
+ {
+ FileStat::SetReadOnlyFlag(*this, sal_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 ( sal_uInt16 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
+|*
+*************************************************************************/
+
+sal_Bool DirEntry::Contains( const DirEntry &rSubEntry ) const
+{
+ DBG_ASSERT( IsAbs() && rSubEntry.IsAbs(), "must be absolute entries" );
+
+ sal_uInt16 nThisLevel = Level();
+ sal_uInt16 nSubLevel = rSubEntry.Level();
+ if ( nThisLevel < nSubLevel )
+ {
+ for ( ; nThisLevel; --nThisLevel, --nSubLevel )
+ if ( (*this)[nThisLevel-1] != rSubEntry[nSubLevel-1] )
+ return sal_False;
+ return sal_True;
+ }
+ return sal_False;
+}
+
+/*************************************************************************
+|*
+|* DirEntry::Level()
+|*
+|* Beschreibung FSYS.SDW
+|* Ersterstellung MI 03.03.92
+|* Letzte Aenderung MI 03.03.92
+|*
+*************************************************************************/
+
+sal_uInt16 DirEntry::Level() const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ sal_uInt16 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
+|*
+*************************************************************************/
+
+sal_Bool DirEntry::IsValid() const
+{
+ return (nError == FSYS_ERR_OK);
+}
+
+/*************************************************************************
+|*
+|* DirEntry::IsRFSAvailable()
+|*
+|* Beschreibung
+|* Ersterstellung TPF 21.10.98
+|* Letzte Aenderung TPF 21.10.98
+|*
+*************************************************************************/
+
+sal_Bool DirEntry::IsRFSAvailable()
+{
+ return sal_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
+|*
+*************************************************************************/
+
+sal_Bool DirEntry::IsLongNameOnFAT() const
+{
+ // FAT-System?
+ DirEntry aTempDirEntry(*this);
+ aTempDirEntry.ToAbs();
+ if (DirEntry::GetPathStyle(aTempDirEntry.GetDevice().GetName().GetChar(0)) != FSYS_STYLE_FAT)
+ {
+ return sal_False; // nein, also false
+ }
+
+ // DirEntry-Kette auf lange Dateinamen pr?fen
+ for( sal_uInt16 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 sal_True;
+ }
+
+ if (aExtension.Len()>3) // Extension > 3?
+ {
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+//========================================================================
+
+#if defined(DBG_UTIL)
+
+void FSysTest()
+{
+}
+
+#endif
+
diff --git a/tools/source/fsys/filecopy.cxx b/tools/source/fsys/filecopy.cxx
new file mode 100755
index 000000000000..e087b6c4a4c3
--- /dev/null
+++ b/tools/source/fsys/filecopy.cxx
@@ -0,0 +1,486 @@
+/*************************************************************************
+ *
+ * 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
+|*
+*************************************************************************/
+
+sal_Bool FileCopier::Progress()
+{
+ if ( !aProgressLink )
+ return sal_True;
+ else
+ {
+ if ( aProgressLink.Call( this ) )
+ return sal_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() );
+ sal_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 ( sal_uInt16 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 );
+}
diff --git a/tools/source/fsys/fstat.cxx b/tools/source/fsys/fstat.cxx
new file mode 100755
index 000000000000..6a32585b2c1e
--- /dev/null
+++ b/tools/source/fsys/fstat.cxx
@@ -0,0 +1,414 @@
+/*************************************************************************
+ *
+ * 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 <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( sal_uIntPtr(0) ),
+ aTimeCreated( sal_uIntPtr(0) ),
+ aDateModified( sal_uIntPtr(0) ),
+ aTimeModified( sal_uIntPtr(0) ),
+ aDateAccessed( sal_uIntPtr(0) ),
+ aTimeAccessed( sal_uIntPtr(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( sal_uIntPtr(0) ),
+ aTimeCreated( sal_uIntPtr(0) ),
+ aDateModified( sal_uIntPtr(0) ),
+ aTimeModified( sal_uIntPtr(0) ),
+ aDateAccessed( sal_uIntPtr(0) ),
+ aTimeAccessed( sal_uIntPtr(0) )
+{
+ sal_Bool bCached = FSYS_ACCESS_CACHED == (nAccess & FSYS_ACCESS_CACHED);
+ sal_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
+|*
+*************************************************************************/
+
+// sal_True wenn die Instanz j"unger als rIsOlder ist.
+// sal_False wenn die Instanz "alter oder gleich alt wie rIsOlder ist.
+
+sal_Bool FileStat::IsYounger( const FileStat& rIsOlder ) const
+{
+ if ( aDateModified > rIsOlder.aDateModified )
+ return sal_True;
+ if ( ( aDateModified == rIsOlder.aDateModified ) &&
+ ( aTimeModified > rIsOlder.aTimeModified ) )
+ return sal_True;
+
+ return sal_False;
+}
+
+/*************************************************************************
+|*
+|* FileStat::IsKind()
+|*
+|* Ersterstellung MA 11.11.91 (?)
+|* Letzte Aenderung KH 16.01.95
+|*
+*************************************************************************/
+
+sal_Bool FileStat::IsKind( DirEntryKind nKind ) const
+{
+ sal_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
+|*
+*************************************************************************/
+
+sal_Bool FileStat::HasReadOnlyFlag()
+{
+#if defined WNT || defined UNX || defined OS2
+ return sal_True;
+#else
+ return sal_False;
+#endif
+}
+
+/*************************************************************************
+|*
+|* FileStat::GetReadOnlyFlag()
+|*
+|* Ersterstellung MI 06.03.97
+|* Letzte Aenderung UT 02.07.98
+|*
+*************************************************************************/
+
+sal_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 sal_False;
+ }
+#elif defined UNX
+ /* could we stat the object? */
+ struct stat aBuf;
+ if (stat(aFPath.GetBuffer(), &aBuf))
+ return sal_False;
+ /* jupp, is writable for user? */
+ return((aBuf.st_mode & S_IWUSR) != S_IWUSR);
+#else
+ return sal_False;
+#endif
+}
+
+/*************************************************************************
+|*
+|* FileStat::SetReadOnlyFlag()
+|*
+|* Ersterstellung MI 06.03.97
+|* Letzte Aenderung UT 01.07.98
+|*
+*************************************************************************/
+
+sal_uIntPtr FileStat::SetReadOnlyFlag( const DirEntry &rEntry, sal_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
diff --git a/tools/source/fsys/os2.cxx b/tools/source/fsys/os2.cxx
new file mode 100644
index 000000000000..03f8f9eb46ce
--- /dev/null
+++ b/tools/source/fsys/os2.cxx
@@ -0,0 +1,1014 @@
+/*************************************************************************
+ *
+ * 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
+#ifndef _VOS_MUTEX_HXX //autogen
+#include <vos/mutex.hxx>
+#endif
+#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
+|*
+*************************************************************************/
+
+#if 0 // YD see dirent.cxx
+BOOL createLongNameEA( const PCSZ pszPath, ULONG ulAttributes, const String& aLongName );
+
+FSysError DirEntry::MoveTo( const DirEntry& rDest ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ DirEntry aTmpDest(rDest);
+ FileStat aTmpStat(aTmpDest);
+ if ( aTmpStat.IsKind(FSYS_KIND_DIR) )
+ aTmpDest += DirEntry( GetName() );
+
+ String aSource( GetFull() );
+ String aDest( aTmpDest.GetFull() );
+ String aShortSource("");
+ String aShortDest("");
+
+ if (Folder::IsAvailable())
+ {
+ if (IsLongNameOnFAT())
+ {
+ // in kurzen Pfad wandeln
+ ItemIDPath aItemIDPath(aSource);
+ aShortSource = aItemIDPath.GetHostNotationPath();
+ }
+ if (rDest.IsLongNameOnFAT())
+ {
+ // in kurzen Pfad wandeln
+ ItemIDPath aItemIDPath(aDest);
+ aShortDest = aItemIDPath.GetHostNotationPath();
+ }
+ }
+
+ APIRET nRet = DosMove( aShortSource.Len()>0?(PSZ)aShortSource.GetStr():(PSZ)aSource.GetStr(),
+ aShortDest.Len()>0?(PSZ)aShortDest.GetStr():(PSZ)aDest.GetStr());
+
+ if ( nRet == ERROR_DIRECTORY_IN_CDS ||
+ nRet == ERROR_CURRENT_DIRECTORY )
+ {
+ // 2nd chance with modified CWD
+ DosSetCurrentDir( (PSZ) "\\" );
+ nRet = DosMove( aShortSource.Len()>0?(PSZ)aShortSource.GetStr():(PSZ)aSource.GetStr(),
+ aShortDest.Len()>0?(PSZ)aShortDest.GetStr():(PSZ)aDest.GetStr());
+ }
+ else if ( nRet == ERROR_NOT_SAME_DEVICE )
+ {
+ // other volume => copy+delete
+ FileCopier aMover( *this, rDest );
+ nRet = aMover.Execute( FSYS_ACTION_MOVE|FSYS_ACTION_RECURSIVE );
+ return nRet;
+ }
+
+ if ( (nRet==NO_ERROR) && aShortDest.Len()>0)
+ {
+ createLongNameEA((const char*)aShortDest, FILE_NORMAL, rDest.GetName());
+ }
+
+ return ApiRet2ToSolarError_Impl( nRet );
+}
+#endif // 0
+
+//-------------------------------------------------------------------------
+
+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() );
+
+#if 0 // YD
+ if (Folder::IsAvailable() && aTempDirEntry.IsLongNameOnFAT())
+ {
+ // in String mit kurzem Pfad wandeln
+ ItemIDPath aItemIDPath(aTempDirEntry.GetFull());
+ aFullName = ByteString( aItemIDPath.GetHostNotationPath(), osl_getThreadTextEncoding() );
+ }
+#endif
+
+ 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;
+}
+
+#if 0
+BOOL IsRedirectable_Impl( const String &rPath )
+{
+ if ( rPath.Len() >= 3 && ':' == rPath.GetStr()[1] )
+ {
+ DriveMapItem &rItem = aDriveMap[toupper(rPath[0]) - 'A'];
+ return FSYS_KIND_FIXED != rItem.nKind;
+ }
+ return FALSE;
+}
+#endif
+
+
+/*************************************************************************
+|*
+|* 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
+
+/*====================================================================
+ * CreateCaseMapImpl()
+ * creates a map of each character to convert to lower
+ *--------------------------------------------------------------------*/
+
+#if 0
+void CreateCaseMapImpl()
+{
+ // build a string starting with code 0 as first character upto 255
+ char sTemp[256];
+ USHORT n;
+
+ for ( n = 0; n < 256; ++n )
+ sTemp[n] = (char) n;
+
+ // convert string to upper case
+ COUNTRYCODE aCountry;
+ aCountry.country = CURRENT_COUNTRY; /* Country code */
+ aCountry.codepage = NLS_CODEPAGE; /* Code page */
+ DosMapCase( 255, &aCountry, sTemp+1 );
+
+ // fill a global buffer starting with code 0 as first character upto 255
+ for ( n = 0; n < 256; ++n )
+ sCaseMap[n] = (char) n;
+
+ // reorder by upper-code and store in a global buffer
+ for ( n = 255; n > 0; --n )
+ // was this character converted?
+ if ( sTemp[n] != (char) n )
+ // we found a convertion from upper to lower
+ sCaseMap[ (unsigned char) sTemp[n] ] = (char) n;
+
+ bCaseMap = TRUE;
+}
+
+String ToLowerImpl( const String& rSource )
+{
+ if ( !bCaseMap )
+ CreateCaseMapImpl();
+
+ // TH sagt: International ist zu langsam, also mit einer eigenen Map
+ ByteString aLower( rSource );
+ for ( USHORT n = 0; n < aLower.Len(); ++n )
+ aLower[n] = sCaseMap[ (unsigned char) aLower[n] ];
+ return aLower;
+}
+#endif // 0
+
+/*====================================================================
+ * 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 );
+}
+
diff --git a/tools/source/fsys/os2.hxx b/tools/source/fsys/os2.hxx
new file mode 100644
index 000000000000..c5e54ba0ad47
--- /dev/null
+++ b/tools/source/fsys/os2.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * 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>
+//#include <datetime.hxx>
+
+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
+
diff --git a/tools/source/fsys/tdir.cxx b/tools/source/fsys/tdir.cxx
new file mode 100755
index 000000000000..c0ebe64114b8
--- /dev/null
+++ b/tools/source/fsys/tdir.cxx
@@ -0,0 +1,768 @@
+/*************************************************************************
+ *
+ * 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>
+
+#ifndef _COMPED_HXX
+#include "comdep.hxx"
+#endif
+#include <tools/fsys.hxx>
+
+
+DBG_NAME( Dir )
+
+DECLARE_LIST( DirEntryList, DirEntry* )
+DECLARE_LIST( FSysSortList, FSysSort* )
+DECLARE_LIST( FileStatList, FileStat* )
+
+#define APPEND (sal_uInt16) 65535
+
+/*************************************************************************
+|*
+|* Dir::InsertPointReached()
+|*
+|* Beschreibung stellt fest, ob eingefuegt werden musz
+|* Ersterstellung MA 05.11.91
+|* Letzte Aenderung MI 05.02.92
+|*
+*************************************************************************/
+
+sal_Bool Dir::ImpInsertPointReached( const DirEntry& rNewEntry,
+ const FileStat& rNewStat,
+ sal_uIntPtr nCurPos, sal_uIntPtr 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 sal_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 sal_True;
+ if ( !(pCurLstObj->aName == rNewEntry.aName) )
+ return sal_False;
+ break;
+ case (FSYS_SORT_NAME | FSYS_SORT_DESCENDING):
+ if ( pCurLstObj->aName < rNewEntry.aName )
+ return sal_True;
+ if ( !(pCurLstObj->aName == rNewEntry.aName) )
+ return sal_False;
+ break;
+
+ case FSYS_SORT_EXT:
+ case (FSYS_SORT_EXT | FSYS_SORT_ASCENDING):
+ {
+ if ( pCurLstObj->GetExtension() > rNewEntry.GetExtension() )
+ return sal_True;
+ if ( !(pCurLstObj->GetExtension() == rNewEntry.GetExtension()) )
+ return sal_False;
+ break;
+ }
+ case (FSYS_SORT_EXT | FSYS_SORT_DESCENDING):
+ {
+ if ( pCurLstObj->GetExtension() < rNewEntry.GetExtension() )
+ return sal_True;
+ if ( !(pCurLstObj->GetExtension() == rNewEntry.GetExtension()) )
+ return sal_False;
+ break;
+ }
+
+ case FSYS_SORT_KIND:
+ case (FSYS_SORT_KIND | FSYS_SORT_ASCENDING ):
+ if ( VALUE(pOldStat->nKindFlags) > VALUE(rNewStat.nKindFlags) )
+ return sal_True;
+ if ( !(VALUE(pOldStat->nKindFlags) == VALUE(rNewStat.nKindFlags)) )
+ return sal_False;
+ break;
+ case (FSYS_SORT_KIND | FSYS_SORT_DESCENDING):
+ if ( VALUE(pOldStat->nKindFlags) < VALUE(rNewStat.nKindFlags) )
+ return sal_True;
+ if ( !(VALUE(pOldStat->nKindFlags) == VALUE(rNewStat.nKindFlags)) )
+ return sal_False;
+ break;
+
+ case FSYS_SORT_SIZE:
+ case (FSYS_SORT_SIZE | FSYS_SORT_ASCENDING):
+ if ( pOldStat->nSize > rNewStat.nSize )
+ return sal_True;
+ if ( !(pOldStat->nSize == rNewStat.nSize) )
+ return sal_False;
+ break;
+ case (FSYS_SORT_SIZE | FSYS_SORT_DESCENDING):
+ if ( pOldStat->nSize < rNewStat.nSize )
+ return sal_True;
+ if ( !(pOldStat->nSize == rNewStat.nSize) )
+ return sal_False;
+ break;
+
+ case FSYS_SORT_MODIFYED:
+ case (FSYS_SORT_MODIFYED | FSYS_SORT_ASCENDING):
+ if ( (pOldStat->aDateModified >= rNewStat.aDateModified) &&
+ (pOldStat->aTimeModified > rNewStat.aTimeModified) )
+ return sal_True;
+ if ( !((pOldStat->aDateModified == rNewStat.aDateModified) &&
+ (pOldStat->aTimeModified == rNewStat.aTimeModified)) )
+ return sal_False;
+ break;
+ case (FSYS_SORT_MODIFYED | FSYS_SORT_DESCENDING):
+ if ( (pOldStat->aDateModified <= rNewStat.aDateModified) &&
+ (pOldStat->aTimeModified < rNewStat.aTimeModified) )
+ return sal_True;
+ if ( !((pOldStat->aDateModified == rNewStat.aDateModified) &&
+ (pOldStat->aTimeModified == rNewStat.aTimeModified)) )
+ return sal_False;
+ break;
+
+ case FSYS_SORT_CREATED:
+ case (FSYS_SORT_CREATED | FSYS_SORT_ASCENDING):
+ if ( (pOldStat->aDateCreated >= rNewStat.aDateCreated) &&
+ (pOldStat->aTimeCreated > rNewStat.aTimeCreated) )
+ return sal_True;
+ if ( !((pOldStat->aDateCreated == rNewStat.aDateCreated) &&
+ (pOldStat->aTimeCreated == rNewStat.aTimeCreated)) )
+ return sal_False;
+ break;
+ case (FSYS_SORT_CREATED | FSYS_SORT_DESCENDING):
+ if ( (pOldStat->aDateCreated <= rNewStat.aDateCreated) &&
+ (pOldStat->aTimeCreated < rNewStat.aTimeCreated) )
+ return sal_True;
+ if ( !((pOldStat->aDateCreated == rNewStat.aDateCreated) &&
+ (pOldStat->aTimeCreated == rNewStat.aTimeCreated)) )
+ return sal_False;
+ break;
+
+ case FSYS_SORT_ACCESSED:
+ case (FSYS_SORT_ACCESSED | FSYS_SORT_ASCENDING):
+ if ( (pOldStat->aDateAccessed >= rNewStat.aDateAccessed) &&
+ (pOldStat->aTimeAccessed > rNewStat.aTimeAccessed) )
+ return sal_True;
+ if ( !((pOldStat->aDateAccessed == rNewStat.aDateAccessed) &&
+ (pOldStat->aTimeAccessed == rNewStat.aTimeAccessed)) )
+ return sal_False;
+ break;
+ case (FSYS_SORT_ACCESSED | FSYS_SORT_DESCENDING):
+ if ( (pOldStat->aDateAccessed <= rNewStat.aDateAccessed) &&
+ (pOldStat->aTimeAccessed < rNewStat.aTimeAccessed) )
+ return sal_True;
+ if ( !((pOldStat->aDateAccessed == rNewStat.aDateAccessed) &&
+ (pOldStat->aTimeAccessed == rNewStat.aTimeAccessed)) )
+ return sal_False;
+ break;
+ default: /* Kann nicht sein */;
+ }
+
+ if ( nSortIndex == ( pSortLst->Count() - 1 ) )
+ return sal_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(),
+ (sal_uIntPtr)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
+|*
+*************************************************************************/
+
+sal_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
+|*
+*************************************************************************/
+
+sal_uInt16 Dir::Scan( sal_uInt16 nCount )
+{
+
+ sal_uInt16 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 = sal_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 )
+{
+ sal_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 & ~(sal_uInt16)FSYS_SORT_ASCENDING
+ & ~(sal_uInt16)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[] ( sal_uInt16 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?
+ sal_Bool bStat = sal_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 = sal_True;
+ } while ( !bStat && pSortLst->Next() );
+ }
+ FileStat * stat = NULL;
+ for ( sal_uInt16 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
+|*
+*************************************************************************/
+
+
+sal_uInt16 Dir::Count( sal_Bool bUpdated ) const
+{
+ // ggf. erst den Rest lesen
+ if ( bUpdated && pReader )
+ ((Dir*)this)->Scan( USHRT_MAX );
+
+ return pLst == NULL ? 0 : (sal_uInt16) pLst->Count();
+}
diff --git a/tools/source/fsys/tempfile.cxx b/tools/source/fsys/tempfile.cxx
new file mode 100644
index 000000000000..b3f53d882467
--- /dev/null
+++ b/tools/source/fsys/tempfile.cxx
@@ -0,0 +1,301 @@
+/*************************************************************************
+ *
+ * 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;
+}
+
diff --git a/tools/source/fsys/unx.cxx b/tools/source/fsys/unx.cxx
new file mode 100644
index 000000000000..94e2ce5950a4
--- /dev/null
+++ b/tools/source/fsys/unx.cxx
@@ -0,0 +1,660 @@
+/*************************************************************************
+ *
+ * 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)
+#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)
+sal_Bool GetMountEntry(dev_t /* dev */, struct mymnttab * /* mytab */ )
+{
+ DBG_WARNING( "Sorry, not implemented: GetMountEntry" );
+ return sal_False;
+}
+
+#elif defined AIX
+sal_Bool GetMountEntry(dev_t dev, struct mymnttab *mytab)
+{
+ int bufsize;
+ if (mntctl (MCTL_QUERY, sizeof bufsize, (char*) &bufsize))
+ return sal_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 sal_True;
+ }
+ }
+ free( buffer );
+ return sal_False;
+}
+
+#else
+
+
+static sal_Bool GetMountEntry(dev_t dev, struct mymnttab *mytab)
+{
+#if defined SOLARIS || defined SINIX
+ FILE *fp = fopen (MNTTAB, "r");
+ if (! fp)
+ return sal_False;
+ struct mnttab mnt[1];
+ while (getmntent (fp, mnt) != -1)
+#elif defined SCO
+ FILE *fp = fopen (MNTTAB, "r");
+ if (! fp)
+ return sal_False;
+ struct mnttab mnt[1];
+ while (fread (&mnt, sizeof mnt, 1, fp) > 0)
+#elif defined DECUNIX || defined AIX
+ FILE *fp = NULL;
+ if (! fp)
+ return sal_False;
+ struct mnttab mnt[1];
+ while ( 0 )
+#else
+ FILE *fp = setmntent (MOUNTED, "r");
+ if (! fp)
+ return sal_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 sal_True;
+ }
+# ifdef LINUX
+ /* #61624# dito */
+ endmntent( fp );
+# else
+ fclose (fp);
+# endif
+ return sal_False;
+}
+
+#endif
+
+/************************************************************************
+|*
+|* DirEntry::IsCaseSensitive()
+|*
+|* Beschreibung
+|* Ersterstellung TPF 25.02.1999
+|* Letzte Aenderung TPF 25.02.1999
+|*
+*************************************************************************/
+
+sal_Bool DirEntry::IsCaseSensitive( FSysPathStyle eFormatter ) const
+{
+
+ if (eFormatter==FSYS_STYLE_HOST)
+ {
+#ifdef NETBSD
+ return sal_True;
+#else
+ struct stat buf;
+ DirEntry aPath(*this);
+ aPath.ToAbs();
+
+ while (stat (ByteString(aPath.GetFull(), osl_getThreadTextEncoding()).GetBuffer(), &buf))
+ {
+ if (aPath.Level() == 1)
+ {
+ return sal_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 sal_False;
+ }
+ else
+ {
+ return sal_True;
+ }
+#endif
+ }
+ else
+ {
+ sal_Bool isCaseSensitive = sal_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 = sal_False;
+ break;
+ }
+ case FSYS_STYLE_SYSV:
+ case FSYS_STYLE_BSD:
+ case FSYS_STYLE_DETECT:
+ {
+ isCaseSensitive = sal_True;
+ break;
+ }
+ default:
+ {
+ isCaseSensitive = sal_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
+|*
+*************************************************************************/
+
+sal_Bool DirEntry::ToAbs()
+{
+ if ( FSYS_FLAG_VOLUME == eFlag )
+ {
+ eFlag = FSYS_FLAG_ABSROOT;
+ return sal_True;
+ }
+
+ if ( IsAbs() )
+ return sal_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
+|*
+*************************************************************************/
+
+sal_Bool DirEntry::SetCWD( sal_Bool bSloppy ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+
+ ByteString aPath( GetFull(), osl_getThreadTextEncoding());
+ if ( !chdir( aPath.GetBuffer() ) )
+ {
+ return sal_True;
+ }
+ else
+ {
+ if ( bSloppy && !chdir(aPath.GetBuffer()) )
+ {
+ return sal_True;
+ }
+ else
+ {
+ return sal_False;
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+
+sal_uInt16 DirReader_Impl::Init()
+{
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+sal_uInt16 DirReader_Impl::Read()
+{
+ if (!pDosDir)
+ {
+ pDosDir = opendir( (char*) ByteString(aPath, osl_getThreadTextEncoding()).GetBuffer() );
+ }
+
+ if (!pDosDir)
+ {
+ bReady = sal_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 ), sal_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 = sal_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
+|*
+*************************************************************************/
+sal_Bool FileStat::Update( const DirEntry& rDirEntry, sal_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 sal_False;
+ }
+
+ // Sonderbehandlung falls es sich um eine Root handelt
+ if ( rDirEntry.eFlag == FSYS_FLAG_ABSROOT )
+ {
+ nKindFlags = FSYS_KIND_DIR;
+ nError = FSYS_ERR_OK;
+ return sal_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 sal_True;
+ }
+
+ nError = FSYS_ERR_NOTEXISTS;
+ return sal_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 sal_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( sal_Bool )
+{
+}
+
diff --git a/tools/source/fsys/unx.hxx b/tools/source/fsys/unx.hxx
new file mode 100644
index 000000000000..b6723e8709a3
--- /dev/null
+++ b/tools/source/fsys/unx.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/source/fsys/urlobj.cxx b/tools/source/fsys/urlobj.cxx
new file mode 100644
index 000000000000..56e6b8ef47cc
--- /dev/null
+++ b/tools/source/fsys/urlobj.cxx
@@ -0,0 +1,5579 @@
+/*************************************************************************
+ *
+ * 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 },
+ { "hid", "hid:", 0, false, false, false, false, false, false,
+ false, 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 },
+ { "hid:", "staroffice.hid:", INET_PROT_HID,
+ PrefixInfo::INTERNAL },
+ { "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.hid:", "hid:", INET_PROT_HID,
+ 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))
+ 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))
+ goto done;
+ break;
+
+ case STATE_LABEL_HYPHEN:
+ if (INetMIME::isAlphanumeric(*p))
+ eState = STATE_LABEL;
+ else if (*p != '-')
+ goto done;
+ break;
+
+ case STATE_LABEL_DOT:
+ if (INetMIME::isAlpha(*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))
+ goto done;
+ break;
+
+ case STATE_TOPLABEL_HYPHEN:
+ if (INetMIME::isAlphanumeric(*p))
+ eState = STATE_TOPLABEL;
+ else if (*p != '-')
+ goto done;
+ break;
+
+ case STATE_TOPLABEL_DOT:
+ if (INetMIME::isAlpha(*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))
+ 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))
+ 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_HID:
+ 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))
+ {
+ ++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))
+ 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))
+ {
+ 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;
+}
diff --git a/tools/source/fsys/wldcrd.cxx b/tools/source/fsys/wldcrd.cxx
new file mode 100755
index 000000000000..16c71cbc51d5
--- /dev/null
+++ b/tools/source/fsys/wldcrd.cxx
@@ -0,0 +1,143 @@
+/*************************************************************************
+ *
+ * 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
+ *
+ */
+
+sal_uInt16 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
+|*
+*************************************************************************/
+
+sal_Bool WildCard::Matches( const String& rString ) const
+{
+ ByteString aTmpWild = aWildString;
+ ByteString aString(rString, osl_getThreadTextEncoding());
+
+ sal_uInt16 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 sal_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 sal_True;
+ else
+ return sal_False;
+}
diff --git a/tools/source/fsys/wntmsc.cxx b/tools/source/fsys/wntmsc.cxx
new file mode 100755
index 000000000000..17421d83feaa
--- /dev/null
+++ b/tools/source/fsys/wntmsc.cxx
@@ -0,0 +1,1081 @@
+/*************************************************************************
+ *
+ * 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 sal_Bool bLastCaseSensitive = sal_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 )
+{
+ sal_Bool bOk = sal_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();
+ sal_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
+|*
+*************************************************************************/
+
+sal_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, sal_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) ? sal_True : sal_False;
+ }
+ else
+ {
+ return sal_False;
+ }
+*/
+ //
+ // guter versuch, aber FS_CASE_SENSITIVE ist D?nnsinn in T?ten:
+ //
+ // sFileSysName FS_CASE_SENSITIVE
+ // FAT sal_False
+ // NTFS sal_True !!!
+ // NWCompat sal_False
+ // Samba sal_False
+ //
+ // NT spricht auch NTFS lediglich case preserving an, also ist unter NT alles case insensitiv
+ //
+
+ return sal_False;
+ }
+ else
+ {
+ sal_Bool isCaseSensitive = sal_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 = sal_False;
+ break;
+ }
+ case FSYS_STYLE_SYSV:
+ case FSYS_STYLE_BSD:
+ {
+ isCaseSensitive = sal_True;
+ break;
+ }
+ default:
+ {
+ isCaseSensitive = sal_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
+|*
+*************************************************************************/
+
+sal_Bool DirEntry::ToAbs()
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ if ( FSYS_FLAG_VOLUME == eFlag )
+ {
+ eFlag = FSYS_FLAG_ABSROOT;
+ return sal_True;
+ }
+
+ if ( IsAbs() )
+ {
+ return sal_True;
+ }
+
+
+ char sBuf[256];
+ char *pOld;
+ ByteString aFullName( GetFull(), osl_getThreadTextEncoding() );
+ FSysFailOnErrorImpl();
+ if ( GetFullPathName((char*)aFullName.GetBuffer(),256,sBuf,&pOld) > 511 )
+ return sal_False;
+
+ *this = DirEntry( String(sBuf, osl_getThreadTextEncoding() ));
+ return sal_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
+|*
+*************************************************************************/
+
+sal_Bool DirEntry::SetCWD( sal_Bool bSloppy ) const
+{
+ DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
+
+ FSysFailOnErrorImpl();
+
+ if ( eFlag == FSYS_FLAG_CURRENT && !aName.Len() )
+ return sal_True;
+
+ if ( SetCurrentDirectory(ByteString(GetFull(), osl_getThreadTextEncoding()).GetBuffer()) )
+ {
+ return sal_True;
+ }
+
+ if ( bSloppy && pParent &&
+ SetCurrentDirectory(ByteString(pParent->GetFull(), osl_getThreadTextEncoding()).GetBuffer()) )
+ {
+ return sal_True;
+ }
+
+ return sal_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
+ sal_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
+ sal_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 ) );
+ sal_Bool bIsHidden = (pDosEntry->d_type & _A_HIDDEN) != 0;
+ sal_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 ), sal_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 = sal_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
+//---------------------------------------------------------------------------
+
+sal_Bool Exists_Impl( const ByteString & crPath )
+{
+ // We do not know if OLE was initialized for this thread
+
+ CoInitialize( NULL );
+
+ sal_Bool bSuccess = SUCCEEDED( SHResolvePath(NULL, crPath.GetBuffer(), NULL) );
+
+ CoUninitialize();
+
+ return bSuccess;
+}
+
+//---------------------------------------------------------------------------
+
+sal_Bool FileStat::Update( const DirEntry& rDirEntry, sal_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 sal_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 sal_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?")
+ sal_Bool bAccess = sal_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 = sal_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 sal_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 sal_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 sal_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 sal_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 sal_True;
+ }
+ else
+ {
+ nKindFlags = FSYS_KIND_UNKNOWN;
+ nError = FSYS_ERR_NOTEXISTS;
+ return sal_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 sal_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;
+
+}
+
+sal_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 sal_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( sal_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 );
+}
+
+
+
diff --git a/tools/source/fsys/wntmsc.hxx b/tools/source/fsys/wntmsc.hxx
new file mode 100755
index 000000000000..d84e5af9680b
--- /dev/null
+++ b/tools/source/fsys/wntmsc.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * 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 sal_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 sal_Bool DRIVE_EXISTS(char c)
+{
+ ByteString aDriveRoot( c );
+ aDriveRoot += ":\\";
+ return GetDriveType( aDriveRoot.GetBuffer() ) > 1;
+}
+
+const char* TempDirImpl( char *pBuf );
+
+#define FSysFailOnErrorImpl()
+
+#endif
diff --git a/tools/source/generic/b3dtrans.cxx b/tools/source/generic/b3dtrans.cxx
new file mode 100644
index 000000000000..9ed887457035
--- /dev/null
+++ b/tools/source/generic/b3dtrans.cxx
@@ -0,0 +1,1014 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/source/generic/bigint.cxx b/tools/source/generic/bigint.cxx
new file mode 100644
index 000000000000..027105767063
--- /dev/null
+++ b/tools/source/generic/bigint.cxx
@@ -0,0 +1,1141 @@
+/*************************************************************************
+ *
+ * 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 sal_uInt16/INT16/sal_uInt32/sal_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 sal_uIntPtr() 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;
+}
diff --git a/tools/source/generic/color.cxx b/tools/source/generic/color.cxx
new file mode 100644
index 000000000000..ec325b9ca3d3
--- /dev/null
+++ b/tools/source/generic/color.cxx
@@ -0,0 +1,510 @@
+/*************************************************************************
+ *
+ * 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 <vos/macros.hxx>
+#include <tools/color.hxx>
+#include <tools/debug.hxx>
+#include <tools/stream.hxx>
+#include <tools/rc.hxx>
+#include <tools/rcid.h>
+#include <tools/resid.hxx>
+#ifndef _SV_RC_H
+#include <tools/rc.h>
+#endif
+
+// -----------
+// - 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
+ sal_uInt16 nRed = pResMgr->ReadShort();
+ sal_uInt16 nGreen = pResMgr->ReadShort();
+ sal_uInt16 nBlue = pResMgr->ReadShort();
+ // one more historical sal_uIntPtr
+ pResMgr->ReadLong();
+
+ // RGB-Farbe
+ mnColor = RGB_COLORDATA( nRed>>8, nGreen>>8, nBlue>>8 );
+ }
+ else
+ {
+ mnColor = RGB_COLORDATA( 0, 0, 0 );
+ }
+}
+sal_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 (sal_uInt8) _FRound( nErrAbs * 0.3333333333 );
+}
+
+// -----------------------------------------------------------------------
+
+void Color::IncreaseLuminance( sal_uInt8 cLumInc )
+{
+ SetRed( (sal_uInt8) VOS_BOUND( (long) COLORDATA_RED( mnColor ) + cLumInc, 0L, 255L ) );
+ SetGreen( (sal_uInt8) VOS_BOUND( (long) COLORDATA_GREEN( mnColor ) + cLumInc, 0L, 255L ) );
+ SetBlue( (sal_uInt8) VOS_BOUND( (long) COLORDATA_BLUE( mnColor ) + cLumInc, 0L, 255L ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Color::DecreaseLuminance( sal_uInt8 cLumDec )
+{
+ SetRed( (sal_uInt8) VOS_BOUND( (long) COLORDATA_RED( mnColor ) - cLumDec, 0L, 255L ) );
+ SetGreen( (sal_uInt8) VOS_BOUND( (long) COLORDATA_GREEN( mnColor ) - cLumDec, 0L, 255L ) );
+ SetBlue( (sal_uInt8) VOS_BOUND( (long) COLORDATA_BLUE( mnColor ) - cLumDec, 0L, 255L ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Color::IncreaseContrast( sal_uInt8 cContInc )
+{
+ if( cContInc)
+ {
+ const double fM = 128.0 / ( 128.0 - 0.4985 * cContInc );
+ const double fOff = 128.0 - fM * 128.0;
+
+ SetRed( (sal_uInt8) VOS_BOUND( _FRound( COLORDATA_RED( mnColor ) * fM + fOff ), 0L, 255L ) );
+ SetGreen( (sal_uInt8) VOS_BOUND( _FRound( COLORDATA_GREEN( mnColor ) * fM + fOff ), 0L, 255L ) );
+ SetBlue( (sal_uInt8) VOS_BOUND( _FRound( COLORDATA_BLUE( mnColor ) * fM + fOff ), 0L, 255L ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Color::DecreaseContrast( sal_uInt8 cContDec )
+{
+ if( cContDec )
+ {
+ const double fM = ( 128.0 - 0.4985 * cContDec ) / 128.0;
+ const double fOff = 128.0 - fM * 128.0;
+
+ SetRed( (sal_uInt8) VOS_BOUND( _FRound( COLORDATA_RED( mnColor ) * fM + fOff ), 0L, 255L ) );
+ SetGreen( (sal_uInt8) VOS_BOUND( _FRound( COLORDATA_GREEN( mnColor ) * fM + fOff ), 0L, 255L ) );
+ SetBlue( (sal_uInt8) VOS_BOUND( _FRound( COLORDATA_BLUE( mnColor ) * fM + fOff ), 0L, 255L ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Color::Invert()
+{
+ SetRed( ~COLORDATA_RED( mnColor ) );
+ SetGreen( ~COLORDATA_GREEN( mnColor ) );
+ SetBlue( ~COLORDATA_BLUE( mnColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Color::IsDark() const
+{
+ return GetLuminance() <= 38;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Color::IsBright() const
+{
+ return GetLuminance() >= 245;
+}
+
+// -----------------------------------------------------------------------
+// color space conversion
+// -----------------------------------------------------------------------
+
+void Color::RGBtoHSB( sal_uInt16& nHue, sal_uInt16& nSat, sal_uInt16& nBri ) const
+{
+ sal_uInt8 c[3];
+ sal_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];
+
+ sal_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 = (sal_uInt16) dHue;
+ }
+}
+
+ColorData Color::HSBtoRGB( sal_uInt16 nHue, sal_uInt16 nSat, sal_uInt16 nBri )
+{
+ sal_uInt8 cR=0,cG=0,cB=0;
+ sal_uInt8 nB = (sal_uInt8) ( nBri * 255 / 100 );
+
+ if( nSat == 0 )
+ {
+ cR = nB;
+ cG = nB;
+ cB = nB;
+ }
+ else
+ {
+ double dH = nHue;
+ double f;
+ sal_uInt16 n;
+ if( dH == 360.0 )
+ dH = 0.0;
+
+ dH /= 60.0;
+ n = (sal_uInt16) dH;
+ f = dH - n;
+
+ sal_uInt8 a = (sal_uInt8) ( nB * ( 100 - nSat ) / 100 );
+ sal_uInt8 b = (sal_uInt8) ( nB * ( 100 - ( (double)nSat * f ) ) / 100 );
+ sal_uInt8 c = (sal_uInt8) ( nB * ( 100 - ( (double)nSat * ( 1.0 - f ) ) ) / 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, sal_Bool bNewFormat )
+{
+ if ( bNewFormat )
+ rIStm >> mnColor;
+ else
+ rIStm >> *this;
+
+ return rIStm;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& Color::Write( SvStream& rOStm, sal_Bool bNewFormat )
+{
+ if ( bNewFormat )
+ rOStm << mnColor;
+ else
+ rOStm << *this;
+
+ return rOStm;
+}
+
+// -----------------------------------------------------------------------
+
+#define COL_NAME_USER ((sal_uInt16)0x8000)
+#define COL_RED_1B ((sal_uInt16)0x0001)
+#define COL_RED_2B ((sal_uInt16)0x0002)
+#define COL_GREEN_1B ((sal_uInt16)0x0010)
+#define COL_GREEN_2B ((sal_uInt16)0x0020)
+#define COL_BLUE_1B ((sal_uInt16)0x0100)
+#define COL_BLUE_2B ((sal_uInt16)0x0200)
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, Color& rColor )
+{
+ DBG_ASSERTWARNING( rIStream.GetVersion(), "Color::>> - Solar-Version not set on rIStream" );
+
+ sal_uInt16 nColorName;
+ sal_uInt16 nRed;
+ sal_uInt16 nGreen;
+ sal_uInt16 nBlue;
+
+ rIStream >> nColorName;
+
+ if ( nColorName & COL_NAME_USER )
+ {
+ if ( rIStream.GetCompressMode() == COMPRESSMODE_FULL )
+ {
+ unsigned char cAry[6];
+ sal_uInt16 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" );
+
+ sal_uInt16 nColorName = COL_NAME_USER;
+ sal_uInt16 nRed = rColor.GetRed();
+ sal_uInt16 nGreen = rColor.GetGreen();
+ sal_uInt16 nBlue = rColor.GetBlue();
+ nRed = (nRed<<8) + nRed;
+ nGreen = (nGreen<<8) + nGreen;
+ nBlue = (nBlue<<8) + nBlue;
+
+ if ( rOStream.GetCompressMode() == COMPRESSMODE_FULL )
+ {
+ unsigned char cAry[6];
+ sal_uInt16 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;
+}
diff --git a/tools/source/generic/config.cxx b/tools/source/generic/config.cxx
new file mode 100644
index 000000000000..ff919fcf2505
--- /dev/null
+++ b/tools/source/generic/config.cxx
@@ -0,0 +1,1304 @@
+/*************************************************************************
+ *
+ * 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;
+ sal_Bool mbIsComment;
+};
+
+struct ImplGroupData
+{
+ ImplGroupData* mpNext;
+ ImplKeyData* mpFirstKey;
+ ByteString maGroupName;
+ sal_uInt16 mnEmptyLines;
+};
+
+struct ImplConfigData
+{
+ ImplGroupData* mpFirstGroup;
+ XubString maFileName;
+ sal_uIntPtr mnDataUpdateId;
+ sal_uIntPtr mnTimeStamp;
+ LineEnd meLineEnd;
+ sal_uInt16 mnRefCount;
+ sal_Bool mbModified;
+ sal_Bool mbRead;
+ sal_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 sal_uIntPtr ImplSysGetConfigTimeStamp( const XubString& rFileName )
+{
+ sal_uIntPtr 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 sal_uInt8* ImplSysReadConfig( const XubString& rFileName,
+ sal_uInt64& rRead, sal_Bool& rbRead, sal_Bool& rbIsUTF8BOM, sal_uIntPtr& rTimeStamp )
+{
+ sal_uInt8* 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 sal_uInt8[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(sal_uInt8)) );
+ rbIsUTF8BOM = sal_True;
+ }
+
+ rTimeStamp = ImplSysGetConfigTimeStamp( rFileName );
+ rbRead = sal_True;
+ rRead = nRead;
+ }
+ else
+ {
+ delete[] pBuf;
+ pBuf = NULL;
+ }
+ }
+ aFile.close();
+ }
+
+ return pBuf;
+}
+
+// -----------------------------------------------------------------------
+
+static sal_Bool ImplSysWriteConfig( const XubString& rFileName,
+ const sal_uInt8* pBuf, sal_uIntPtr nBufLen, sal_Bool rbIsUTF8BOM, sal_uIntPtr& rTimeStamp )
+{
+ sal_Bool bSuccess = sal_False;
+ sal_Bool bUTF8BOMSuccess = sal_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 = sal_True;
+ }
+ }
+
+ if( aFile.write( pBuf, nBufLen, nWritten ) == ::osl::FileBase::E_None && nWritten == nBufLen )
+ {
+ bSuccess = sal_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(sal_uInt8 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 sal_uInt8* 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 sal_uInt8* 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 = sal_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 = sal_True;
+ }
+ else
+ {
+ pKey->mbIsComment = sal_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 sal_uInt8* ImplGetConfigBuffer( const ImplConfigData* pData, sal_uIntPtr& rLen )
+{
+ sal_uInt8* pWriteBuf;
+ sal_uInt8* pBuf;
+ sal_uInt8 aLineEndBuf[2] = {0, 0};
+ ImplKeyData* pKey;
+ ImplGroupData* pGroup;
+ unsigned int nBufLen;
+ sal_uInt16 nValueLen;
+ sal_uInt16 nKeyLen;
+ sal_uInt16 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 sal_uInt8[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 sal_uInt8[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
+ sal_uInt16 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 )
+{
+ sal_uIntPtr nTimeStamp = 0;
+ sal_uInt64 nRead = 0;
+ sal_Bool bRead = sal_False;
+ sal_Bool bIsUTF8BOM =sal_False;
+ sal_uInt8* 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 = sal_False;
+ if ( bRead )
+ pData->mbRead = sal_True;
+ if ( bIsUTF8BOM )
+ pData->mbIsUTF8BOM = sal_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
+ sal_uIntPtr nBufLen;
+ sal_uInt8* pBuf = ImplGetConfigBuffer( pData, nBufLen );
+ if ( pBuf )
+ {
+ if ( ImplSysWriteConfig( pData->maFileName, pBuf, nBufLen, pData->mbIsUTF8BOM, pData->mnTimeStamp ) )
+ pData->mbModified = sal_False;
+ delete[] pBuf;
+ }
+ else
+ pData->mbModified = sal_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 = sal_False;
+ pData->mbIsUTF8BOM = sal_False;
+ ImplReadConfig( pData );
+
+ return pData;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplFreeConfigData( ImplConfigData* pDelData )
+{
+ ImplDeleteConfigData( pDelData );
+ delete pDelData;
+}
+
+// =======================================================================
+
+sal_Bool Config::ImplUpdateConfig() const
+{
+ // Wenn sich TimeStamp unterscheidet, dann Datei neu einlesen
+ if ( mpData->mnTimeStamp != ImplSysGetConfigTimeStamp( maFileName ) )
+ {
+ ImplDeleteConfigData( mpData );
+ ImplReadConfig( mpData );
+ mpData->mnDataUpdateId++;
+ return sal_True;
+ }
+ else
+ return sal_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 = sal_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 = sal_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 = sal_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 = sal_True;
+ }
+
+ // Gruppen auf ungluetig setzen
+ mnDataUpdateId = mpData->mnDataUpdateId;
+ mpData->mnDataUpdateId++;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ByteString Config::GetGroupName( sal_uInt16 nGroup ) const
+{
+ // Config-Daten evt. updaten
+ if ( !mnLockCount )
+ ImplUpdateConfig();
+
+ ImplGroupData* pGroup = mpData->mpFirstGroup;
+ sal_uInt16 nGroupCount = 0;
+ ByteString aGroupName;
+ while ( pGroup )
+ {
+ if ( nGroup == nGroupCount )
+ {
+ aGroupName = pGroup->maGroupName;
+ break;
+ }
+
+ nGroupCount++;
+ pGroup = pGroup->mpNext;
+ }
+
+ return aGroupName;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 Config::GetGroupCount() const
+{
+ // Config-Daten evt. updaten
+ if ( !mnLockCount )
+ ImplUpdateConfig();
+
+ ImplGroupData* pGroup = mpData->mpFirstGroup;
+ sal_uInt16 nGroupCount = 0;
+ while ( pGroup )
+ {
+ nGroupCount++;
+ pGroup = pGroup->mpNext;
+ }
+
+ return nGroupCount;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Config::HasGroup( const ByteString& rGroup ) const
+{
+ // Config-Daten evt. updaten
+ if ( !mnLockCount )
+ ImplUpdateConfig();
+
+ ImplGroupData* pGroup = mpData->mpFirstGroup;
+ sal_Bool bRet = sal_False;
+
+ while( pGroup )
+ {
+ if( pGroup->maGroupName.EqualsIgnoreCaseAscii( rGroup ) )
+ {
+ bRet = sal_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 = sal_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;
+ }
+
+ sal_Bool bNewValue;
+ if ( !pKey )
+ {
+ pKey = new ImplKeyData;
+ pKey->mpNext = NULL;
+ pKey->maKey = rKey;
+ pKey->mbIsComment = sal_False;
+ if ( pPrevKey )
+ pPrevKey->mpNext = pKey;
+ else
+ pGroup->mpFirstKey = pKey;
+ bNewValue = sal_True;
+ }
+ else
+ bNewValue = pKey->maValue != rStr;
+
+ if ( bNewValue )
+ {
+ pKey->maValue = rStr;
+
+ if ( !mnLockCount && mbPersistence )
+ ImplWriteConfig( mpData );
+ else
+ {
+ mpData->mbModified = sal_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 = sal_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 = sal_True;
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 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
+ sal_uInt16 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( sal_uInt16 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( sal_uInt16 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 );
+}
+
+// -----------------------------------------------------------------------
+
+sal_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;
+}
+
diff --git a/tools/source/generic/fract.cxx b/tools/source/generic/fract.cxx
new file mode 100644
index 000000000000..8481fef32e05
--- /dev/null
+++ b/tools/source/generic/fract.cxx
@@ -0,0 +1,736 @@
+/*************************************************************************
+ *
+ * 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 _LIMITS_H
+#include <limits.h>
+#endif
+#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
+|*
+*************************************************************************/
+
+sal_Bool operator == ( const Fraction& rVal1, const Fraction& rVal2 )
+{
+ if ( !rVal1.IsValid() || !rVal2.IsValid() )
+ return sal_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.
+
+sal_Bool operator < ( const Fraction& rVal1, const Fraction& rVal2 )
+{
+ if ( !rVal1.IsValid() || !rVal2.IsValid() )
+ return sal_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.
+
+sal_Bool operator > ( const Fraction& rVal1, const Fraction& rVal2 )
+{
+ if ( !rVal1.IsValid() || !rVal2.IsValid() )
+ return sal_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;
+}
diff --git a/tools/source/generic/gen.cxx b/tools/source/generic/gen.cxx
new file mode 100644
index 000000000000..e4ef3ed58c82
--- /dev/null
+++ b/tools/source/generic/gen.cxx
@@ -0,0 +1,661 @@
+/*************************************************************************
+ *
+ * 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;
+ sal_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 = (sal_Int32)nNum;
+
+ nNum = 0;
+ i = i1+i2;
+ while ( i > i1 )
+ {
+ i--;
+ nNum <<= 8;
+ nNum |= cAry[i];
+ }
+ if ( cId & 0x08 )
+ nNum ^= 0xFFFFFFFF;
+ rPair.nB = (sal_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;
+ sal_uInt32 nNum;
+
+ cAry[0] = 0;
+
+ nNum = (sal_uInt32)(sal_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 = (sal_uInt32)(sal_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
+|*
+*************************************************************************/
+
+sal_Bool Rectangle::IsInside( const Point& rPoint ) const
+{
+ if ( IsEmpty() )
+ return sal_False;
+
+ sal_Bool bRet = sal_True;
+ if ( nLeft <= nRight )
+ {
+ if ( (rPoint.X() < nLeft) || (rPoint.X() > nRight) )
+ bRet = sal_False;
+ }
+ else
+ {
+ if ( (rPoint.X() > nLeft) || (rPoint.X() < nRight) )
+ bRet = sal_False;
+ }
+ if ( nTop <= nBottom )
+ {
+ if ( (rPoint.Y() < nTop) || (rPoint.Y() > nBottom) )
+ bRet = sal_False;
+ }
+ else
+ {
+ if ( (rPoint.Y() > nTop) || (rPoint.Y() < nBottom) )
+ bRet = sal_False;
+ }
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|* Rectangle::IsInside()
+|*
+|* Beschreibung GEN.SDW
+|* Ersterstellung TH 19.03.90
+|* Letzte Aenderung MM 21.04.94
+|*
+*************************************************************************/
+
+sal_Bool Rectangle::IsInside( const Rectangle& rRect ) const
+{
+ if ( IsInside( rRect.TopLeft() ) && IsInside( rRect.BottomRight() ) )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+/*************************************************************************
+|*
+|* Rectangle::IsOver()
+|*
+|* Beschreibung GEN.SDW
+|* Ersterstellung TH 19.03.90
+|* Letzte Aenderung MM 21.04.94
+|*
+*************************************************************************/
+
+sal_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;
+ sal_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 = (sal_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 = (sal_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 = (sal_Int32)nNum;
+
+ nNum = 0;
+ i = iLast+i4;
+ while ( i > iLast )
+ {
+ i--;
+ nNum <<= 8;
+ nNum |= cAry[i];
+ }
+ if ( cIdAry[1] & 0x08 )
+ nNum ^= 0xFFFFFFFF;
+ rRect.nBottom = (sal_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;
+ sal_uInt32 nNum;
+
+ cAry[0] = 0;
+ cAry[1] = 0;
+
+ nNum = (sal_uInt32)(sal_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 = (sal_uInt32)(sal_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 = (sal_uInt32)(sal_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 = (sal_uInt32)(sal_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;
+}
diff --git a/tools/source/generic/line.cxx b/tools/source/generic/line.cxx
new file mode 100644
index 000000000000..ea3b92ad9005
--- /dev/null
+++ b/tools/source/generic/line.cxx
@@ -0,0 +1,363 @@
+/*************************************************************************
+ *
+ * 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() );
+}
+
+// ------------------------------------------------------------------------
+
+sal_Bool Line::Intersection( const Line& rLine, Point& rIntersection ) const
+{
+ double fX, fY;
+ sal_Bool bRet;
+
+ if( Intersection( rLine, fX, fY ) )
+ {
+ rIntersection.X() = FRound( fX );
+ rIntersection.Y() = FRound( fY );
+ bRet = sal_True;
+ }
+ else
+ bRet = sal_False;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+sal_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;
+ sal_Bool bOk = sal_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 sal_Bool bGreater = ( fDen > 0. );
+
+ bOk = sal_True;
+
+ if ( bGreater )
+ {
+ if ( ( fA < 0. ) || ( fA > fDen ) )
+ bOk = sal_False;
+ }
+ else if ( ( fA > 0. ) || ( fA < fDen ) )
+ bOk = sal_False;
+
+ if ( bOk )
+ {
+ const double fB = fAx * fCy - fAy * fCx;
+
+ if ( bGreater )
+ {
+ if ( ( fB < 0. ) || ( fB > fDen ) )
+ bOk = sal_False;
+ }
+ else if ( ( fB > 0. ) || ( fB < fDen ) )
+ bOk = sal_False;
+
+ if( bOk )
+ {
+ const double fAlpha = fA / fDen;
+
+ rIntersectionX = ( maStart.X() + fAlpha * fAx );
+ rIntersectionY = ( maStart.Y() + fAlpha * fAy );
+ }
+ }
+ }
+
+ return bOk;
+}
+
+// ------------------------------------------------------------------------
+
+sal_Bool Line::Intersection( const Rectangle& rRect, Line& rIntersection ) const
+{
+ const sal_Bool bStartInside = rRect.IsInside( maStart );
+ const sal_Bool bEndInside = rRect.IsInside( maEnd );
+ sal_Bool bRet = sal_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 = sal_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 );
+ }
+}
diff --git a/tools/source/generic/link.cxx b/tools/source/generic/link.cxx
new file mode 100644
index 000000000000..2d485a5036c4
--- /dev/null
+++ b/tools/source/generic/link.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// 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
+|*
+*************************************************************************/
+
+sal_Bool Link::operator==( const Link& rLink ) const
+{
+ if ( pFunc == rLink.pFunc )
+ {
+ if ( pFunc )
+ {
+ if ( pInst == rLink.pInst )
+ return sal_True;
+ else
+ return sal_False;
+ }
+ else
+ return sal_True;
+ }
+ else
+ return sal_False;
+}
diff --git a/tools/source/generic/poly.cxx b/tools/source/generic/poly.cxx
new file mode 100644
index 000000000000..73e89c73900f
--- /dev/null
+++ b/tools/source/generic/poly.cxx
@@ -0,0 +1,2380 @@
+/*************************************************************************
+ *
+ * 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>
+#ifndef _VECTOR2D_H
+#include <tools/vector2d.hxx>
+#endif
+#ifndef _POLY_HXX
+#include <tools/poly.hxx>
+#endif
+#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( sal_uInt16 nInitSize, sal_Bool bFlags )
+{
+ if ( nInitSize )
+ {
+ mpPointAry = (Point*)new char[(sal_uIntPtr)nInitSize*sizeof(Point)];
+ memset( mpPointAry, 0, (sal_uIntPtr)nInitSize*sizeof(Point) );
+ }
+ else
+ mpPointAry = NULL;
+
+ if( bFlags )
+ {
+ mpFlagAry = new sal_uInt8[ nInitSize ];
+ memset( mpPointAry, 0, nInitSize );
+ }
+ else
+ mpFlagAry = NULL;
+
+ mnRefCount = 1;
+ mnPoints = nInitSize;
+}
+
+// -----------------------------------------------------------------------
+
+ImplPolygon::ImplPolygon( const ImplPolygon& rImpPoly )
+{
+ if ( rImpPoly.mnPoints )
+ {
+ mpPointAry = (Point*)new char[(sal_uIntPtr)rImpPoly.mnPoints*sizeof(Point)];
+ memcpy( mpPointAry, rImpPoly.mpPointAry, (sal_uIntPtr)rImpPoly.mnPoints*sizeof(Point) );
+
+ if( rImpPoly.mpFlagAry )
+ {
+ mpFlagAry = new sal_uInt8[ rImpPoly.mnPoints ];
+ memcpy( mpFlagAry, rImpPoly.mpFlagAry, rImpPoly.mnPoints );
+ }
+ else
+ mpFlagAry = NULL;
+ }
+ else
+ {
+ mpPointAry = NULL;
+ mpFlagAry = NULL;
+ }
+
+ mnRefCount = 1;
+ mnPoints = rImpPoly.mnPoints;
+}
+
+// -----------------------------------------------------------------------
+
+ImplPolygon::ImplPolygon( sal_uInt16 nInitSize, const Point* pInitAry, const sal_uInt8* pInitFlags )
+{
+ if ( nInitSize )
+ {
+ mpPointAry = (Point*)new char[(sal_uIntPtr)nInitSize*sizeof(Point)];
+ memcpy( mpPointAry, pInitAry, (sal_uIntPtr)nInitSize*sizeof( Point ) );
+
+ if( pInitFlags )
+ {
+ mpFlagAry = new sal_uInt8[ 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( sal_uInt16 nNewSize, sal_Bool bResize )
+{
+ if( mnPoints == nNewSize )
+ return;
+
+ Point* pNewAry;
+
+ if ( nNewSize )
+ {
+ pNewAry = (Point*)new char[(sal_uIntPtr)nNewSize*sizeof(Point)];
+
+ if ( bResize )
+ {
+ // Alte Punkte kopieren
+ if ( mnPoints < nNewSize )
+ {
+ // Neue Punkte mit 0 initialisieren
+ memset( pNewAry+mnPoints, 0, (sal_uIntPtr)(nNewSize-mnPoints)*sizeof(Point) );
+ if ( mpPointAry )
+ memcpy( pNewAry, mpPointAry, mnPoints*sizeof(Point) );
+ }
+ else
+ {
+ if ( mpPointAry )
+ memcpy( pNewAry, mpPointAry, (sal_uIntPtr)nNewSize*sizeof(Point) );
+ }
+ }
+ }
+ else
+ pNewAry = NULL;
+
+ if ( mpPointAry )
+ delete[] (char*) mpPointAry;
+
+ // ggf. FlagArray beruecksichtigen
+ if( mpFlagAry )
+ {
+ sal_uInt8* pNewFlagAry;
+
+ if( nNewSize )
+ {
+ pNewFlagAry = new sal_uInt8[ 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( sal_uInt16 nPos, sal_uInt16 nSpace, ImplPolygon* pInitPoly )
+{
+ const sal_uIntPtr nSpaceSize = nSpace * sizeof( Point );
+
+ //Can't fit this in :-(, throw ?
+ if (mnPoints + nSpace > USHRT_MAX)
+ return;
+
+ const sal_uInt16 nNewSize = mnPoints + nSpace;
+
+ if( nPos >= mnPoints )
+ {
+ // Hinten anhaengen
+ nPos = mnPoints;
+ ImplSetSize( nNewSize, sal_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 sal_uInt16 nSecPos = nPos + nSpace;
+ const sal_uInt16 nRest = mnPoints - nPos;
+
+ Point* pNewAry = (Point*) new char[ (sal_uIntPtr) 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 )
+ {
+ sal_uInt8* pNewFlagAry = new sal_uInt8[ 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( sal_uInt16 nPos, sal_uInt16 nCount )
+{
+ const sal_uInt16 nRemoveCount = Min( (sal_uInt16) ( mnPoints - nPos ), (sal_uInt16) nCount );
+
+ if( nRemoveCount )
+ {
+ const sal_uInt16 nNewSize = mnPoints - nRemoveCount;
+ const sal_uInt16 nSecPos = nPos + nRemoveCount;
+ const sal_uInt16 nRest = mnPoints - nSecPos;
+
+ Point* pNewAry = (Point*) new char[ (sal_uIntPtr) 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 )
+ {
+ sal_uInt8* pNewFlagAry = new sal_uInt8[ 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 sal_uInt8[ 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( sal_uInt16 nSize )
+{
+ DBG_CTOR( Polygon, NULL );
+
+ if ( nSize )
+ mpImplPolygon = new ImplPolygon( nSize );
+ else
+ mpImplPolygon = (ImplPolygon*)(&aStaticImplPolygon);
+}
+
+// -----------------------------------------------------------------------
+
+Polygon::Polygon( sal_uInt16 nPoints, const Point* pPtAry, const sal_uInt8* 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, sal_uIntPtr nHorzRound, sal_uIntPtr nVertRound )
+{
+ DBG_CTOR( Polygon, NULL );
+
+ if ( rRect.IsEmpty() )
+ mpImplPolygon = (ImplPolygon*)(&aStaticImplPolygon);
+ else
+ {
+ Rectangle aRect( rRect );
+ aRect.Justify(); // SJ: i9140
+
+ nHorzRound = Min( nHorzRound, (sal_uIntPtr) labs( aRect.GetWidth() >> 1 ) );
+ nVertRound = Min( nVertRound, (sal_uIntPtr) 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 );
+ sal_uInt16 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, sal_uInt16 nPoints )
+{
+ DBG_CTOR( Polygon, NULL );
+
+ if( nRadX && nRadY )
+ {
+ // Default berechnen (abhaengig von Groesse)
+ if( !nPoints )
+ {
+ nPoints = (sal_uInt16) ( F_PI * ( 1.5 * ( nRadX + nRadY ) -
+ sqrt( (double) labs( nRadX * nRadY ) ) ) );
+
+ nPoints = (sal_uInt16) 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;
+ sal_uInt16 i;
+ sal_uInt16 nPoints2 = nPoints >> 1;
+ sal_uInt16 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();
+ sal_uInt16 nPoints;
+
+ nPoints = (sal_uInt16) ( F_PI * ( 1.5 * ( nRadX + nRadY ) -
+ sqrt( (double) labs( nRadX * nRadY ) ) ) );
+
+ nPoints = (sal_uInt16) 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;
+ sal_uInt16 nStart;
+ sal_uInt16 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( (sal_uInt16) ( ( fDiff * 0.1591549 ) * nPoints ), (sal_uInt16) 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,
+ sal_uInt16 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( sal_uInt16 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;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt8* 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 sal_uInt8* Polygon::GetConstFlagAry() const
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ return mpImplPolygon->mpFlagAry;
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::SetPoint( const Point& rPt, sal_uInt16 nPos )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ DBG_ASSERT( nPos < mpImplPolygon->mnPoints,
+ "Polygon::SetPoint(): nPos >= nPoints" );
+
+ ImplMakeUnique();
+ mpImplPolygon->mpPointAry[nPos] = rPt;
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::SetFlags( sal_uInt16 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 ] = (sal_uInt8) eFlags;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+const Point& Polygon::GetPoint( sal_uInt16 nPos ) const
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ DBG_ASSERT( nPos < mpImplPolygon->mnPoints,
+ "Polygon::GetPoint(): nPos >= nPoints" );
+
+ return mpImplPolygon->mpPointAry[nPos];
+}
+
+// -----------------------------------------------------------------------
+
+PolyFlags Polygon::GetFlags( sal_uInt16 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;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Polygon::IsControl(sal_uInt16 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 );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Polygon::IsSmooth(sal_uInt16 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 ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Polygon::IsRect() const
+{
+ sal_Bool bIsRect = sal_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 = sal_True;
+ }
+ }
+ return bIsRect;
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::SetSize( sal_uInt16 nNewSize )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+
+ if( nNewSize != mpImplPolygon->mnPoints )
+ {
+ ImplMakeUnique();
+ mpImplPolygon->ImplSetSize( nNewSize );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 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( sal_uInt16 nP1, sal_uInt16 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( sal_uIntPtr nOptimizeFlags, const PolyOptimizeData* pData )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ DBG_ASSERT( !mpImplPolygon->mpFlagAry, "Optimizing could fail with beziers!" );
+
+ sal_uInt16 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 sal_uInt16 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 ];
+ sal_uIntPtr 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 )
+ {
+ sal_uInt16 nLast = 0, nNewCount = 1;
+
+ aNewPoly.SetSize( nSize );
+ aNewPoly[ 0 ] = rFirst;
+
+ for( sal_uInt16 i = 1; i < nSize; i++ )
+ {
+ if( ( mpImplPolygon->mpPointAry[ i ] != mpImplPolygon->mpPointAry[ nLast ] ) &&
+ ( !nReduce || ( nReduce < (sal_uIntPtr) 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
+ {
+ sal_uInt16 i;
+ sal_uInt16 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 )
+ {
+ sal_uInt8 P1( mpImplPolygon->mpFlagAry[ i ] );
+ sal_uInt8 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( (sal_uInt16)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, sal_uInt16 nPercent )
+{
+ const double fBound = 2000.0 * ( 100 - nPercent ) * 0.01;
+ sal_uInt16 nNumNoChange = 0, nNumRuns = 0;
+
+ while( nNumNoChange < 2 )
+ {
+ sal_uInt16 nPntCnt = rPoly.GetSize(), nNewPos = 0;
+ Polygon aNewPoly( nPntCnt );
+ sal_Bool bChangeInThisRun = sal_False;
+
+ for( sal_uInt16 n = 0; n < nPntCnt; n++ )
+ {
+ sal_Bool bDeletePoint = sal_False;
+
+ if( ( n + nNumRuns ) % 2 )
+ {
+ sal_uInt16 nIndPrev = !n ? nPntCnt - 1 : n - 1;
+ sal_uInt16 nIndPrevPrev = !nIndPrev ? nPntCnt - 1 : nIndPrev - 1;
+ sal_uInt16 nIndNext = ( n == nPntCnt-1 ) ? 0 : n + 1;
+ sal_uInt16 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 = sal_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 = sal_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( ( (sal_uInt32) ( ( ( fLenFact - 1.0 ) * 1000000.0 ) + 0.5 ) < fBound ) &&
+ ( fabs( fGradB ) <= ( fRelLen * fBound * 0.01 ) ) )
+ {
+ bDeletePoint = sal_True;
+ }
+ }
+ }
+ }
+
+ if( !bDeletePoint )
+ aNewPoly[ nNewPos++ ] = rPoly[ n ];
+ else
+ bChangeInThisRun = sal_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
+ sal_uInt16 nCount = mpImplPolygon->mnPoints;
+ for ( sal_uInt16 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 ( sal_uInt16 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 ( sal_uInt16 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, sal_uInt16 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( sal_uInt16 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( sal_uInt16 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( sal_uInt16 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( sal_uInt16 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
+ sal_uInt16 mnSize;
+
+ ImplPolygonPointFilter( sal_uInt16 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;
+ sal_Bool mbFirst;
+
+public:
+ ImplEdgePointFilter( int nEdge, long nLow, long nHigh,
+ ImplPointFilter& rNextFilter ) :
+ mrNextFilter( rNextFilter ),
+ mnLow( nLow ),
+ mnHigh( nHigh ),
+ mnEdge( nEdge ),
+ mbFirst( sal_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 = sal_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, sal_Bool bPolygon )
+{
+ // #105251# Justify rect befor edge filtering
+ Rectangle aJustifiedRect( rRect );
+ aJustifiedRect.Justify();
+
+ sal_uInt16 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 ( sal_uInt16 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!" );
+
+ sal_uInt16 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 ( sal_uInt16 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 sal_uInt16 nCount1 = mpImplPolygon->mnPoints - 1;
+
+ for( sal_uInt16 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;
+}
+
+// -----------------------------------------------------------------------
+
+sal_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() ) );
+ sal_uInt16 nCount = mpImplPolygon->mnPoints;
+ sal_uInt16 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 ( sal_uInt16 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 );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Polygon::IsRightOrientated() const
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ return GetSignedArea() >= 0.0;
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::Insert( sal_uInt16 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 ] = (sal_uInt8) eFlags;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Polygon::Insert( sal_uInt16 nPos, const Polygon& rPoly )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ const sal_uInt16 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( sal_uInt16 nPos, sal_uInt16 nCount )
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ if( nCount && ( nPos < mpImplPolygon->mnPoints ) )
+ {
+ ImplMakeUnique();
+ mpImplPolygon->ImplRemove( nPos, nCount );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Point& Polygon::operator[]( sal_uInt16 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;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Polygon::operator==( const Polygon& rPoly ) const
+{
+ DBG_CHKTHIS( Polygon, NULL );
+ DBG_CHKOBJ( &rPoly, Polygon, NULL );
+
+ if ( (rPoly.mpImplPolygon == mpImplPolygon) )
+ return sal_True;
+ else
+ return sal_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" );
+
+ sal_uInt16 i;
+ sal_uInt16 nStart;
+ sal_uInt16 nCurPoints;
+ sal_uInt16 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, sal_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;
+ sal_uInt16 nStart;
+ sal_uInt16 i;
+ sal_uInt16 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 = sal_True;
+ else
+ bShort = sal_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 = sal_True;
+ else
+ bCurShort = sal_False;
+
+ // Wenn sich die Werte in einen anderen Bereich begeben,
+ // muessen wir neu rausschreiben
+ if ( bCurShort != bShort )
+ {
+ bShort = bCurShort;
+ break;
+ }
+
+ i++;
+ }
+
+ rOStream << bShort << (sal_uInt16)(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, sal_uInt8 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]);
+ sal_uInt8 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] = (sal_uInt8)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] = (sal_uInt8)POLY_CONTROL;
+ nArrayInsert++;
+
+ mpImplPolygon->mpPointAry[nArrayInsert] = Point(FRound(aBezier.getControlPointB().getX()), FRound(aBezier.getControlPointB().getY()));
+ mpImplPolygon->mpFlagAry[nArrayInsert] = (sal_uInt8)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] = (sal_uInt8)POLY_SMOOTH;
+ }
+ else if(basegfx::CONTINUITY_C2 == eCont)
+ {
+ mpImplPolygon->mpFlagAry[nStartPointIndex] = (sal_uInt8)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] = (sal_uInt8)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] = (sal_uInt8)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
diff --git a/tools/source/generic/poly2.cxx b/tools/source/generic/poly2.cxx
new file mode 100644
index 000000000000..a995c66f9cf0
--- /dev/null
+++ b/tools/source/generic/poly2.cxx
@@ -0,0 +1,891 @@
+/*************************************************************************
+ *
+ * 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( sal_uInt16 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 ( sal_uInt16 i = 0; i < mnCount; i++ )
+ mpPolyAry[i] = new Polygon( *rImplPolyPoly.mpPolyAry[i] );
+ }
+ else
+ mpPolyAry = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ImplPolyPolygon::~ImplPolyPolygon()
+{
+ if ( mpPolyAry )
+ {
+ for ( sal_uInt16 i = 0; i < mnCount; i++ )
+ delete mpPolyAry[i];
+ delete[] mpPolyAry;
+ }
+}
+
+// =======================================================================
+
+PolyPolygon::PolyPolygon( sal_uInt16 nInitSize, sal_uInt16 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( sal_uInt16 nPoly, const sal_uInt16* pPointCountAry,
+ const Point* pPtAry )
+{
+ DBG_CTOR( PolyPolygon, NULL );
+
+ if ( nPoly > MAX_POLYGONS )
+ nPoly = MAX_POLYGONS;
+
+ mpImplPolyPolygon = new ImplPolyPolygon( nPoly );
+ for ( sal_uInt16 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, sal_uInt16 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 )
+ {
+ sal_uInt16 nOldSize = mpImplPolyPolygon->mnSize;
+ sal_uInt16 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( sal_uInt16 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, sal_uInt16 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( sal_uInt16 nPos ) const
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+ DBG_ASSERT( nPos < Count(), "PolyPolygon::GetObject(): nPos >= nSize" );
+
+ return *(mpImplPolyPolygon->mpPolyAry[nPos]);
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool PolyPolygon::IsRect() const
+{
+ sal_Bool bIsRect = sal_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 ( sal_uInt16 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( sal_uIntPtr nOptimizeFlags, const PolyOptimizeData* pData )
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+
+ if( nOptimizeFlags )
+ {
+ double fArea;
+ const sal_Bool bEdges = ( nOptimizeFlags & POLY_OPTIMIZE_EDGES ) == POLY_OPTIMIZE_EDGES;
+ sal_uInt16 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( sal_uInt16 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( sal_uInt16 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, sal_uIntPtr 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 );
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 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
+ sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount;
+ for ( sal_uInt16 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 ( sal_uInt16 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 ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
+ mpImplPolyPolygon->mpPolyAry[ i ]->Scale( fScaleX, fScaleY );
+}
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::Rotate( const Point& rCenter, sal_uInt16 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 ( sal_uInt16 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 ( sal_uInt16 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 ( sal_uInt16 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 ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
+ mpImplPolyPolygon->mpPolyAry[ i ]->Distort( rRefRect, rDistortedRect );
+}
+
+
+// -----------------------------------------------------------------------
+
+void PolyPolygon::Clip( const Rectangle& rRect )
+{
+ // Polygon-Clippen
+ sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount;
+ sal_uInt16 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;
+ sal_Bool bFirst = sal_True;
+ sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount;
+
+ for ( sal_uInt16 n = 0; n < nPolyCount; n++ )
+ {
+ const Polygon* pPoly = mpImplPolyPolygon->mpPolyAry[n];
+ const Point* pAry = pPoly->GetConstPointAry();
+ sal_uInt16 nPointCount = pPoly->GetSize();
+
+ for ( sal_uInt16 i = 0; i < nPointCount; i++ )
+ {
+ const Point* pPt = &pAry[ i ];
+
+ if ( bFirst )
+ {
+ nXMin = nXMax = pPt->X();
+ nYMin = nYMax = pPt->Y();
+ bFirst = sal_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[]( sal_uInt16 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;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool PolyPolygon::operator==( const PolyPolygon& rPolyPoly ) const
+{
+ DBG_CHKTHIS( PolyPolygon, NULL );
+ DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
+
+ if ( rPolyPoly.mpImplPolyPolygon == mpImplPolyPolygon )
+ return sal_True;
+ else
+ return sal_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;
+ sal_uInt16 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 ( sal_uInt16 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
+ sal_uInt16 nPolyCount = rPolyPoly.mpImplPolyPolygon->mnCount;
+ rOStream << nPolyCount;
+
+ // Die einzelnen Polygone ausgeben
+ for ( sal_uInt16 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;
+ sal_uInt16 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 ( sal_uInt16 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
+ sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount;
+ rOStream << nPolyCount;
+
+ // Die einzelnen Polygone ausgeben
+ for ( sal_uInt16 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
diff --git a/tools/source/generic/svborder.cxx b/tools/source/generic/svborder.cxx
new file mode 100644
index 000000000000..fa302384745f
--- /dev/null
+++ b/tools/source/generic/svborder.cxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * 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: sal_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;
+}
+
diff --git a/tools/source/generic/svlibrary.cxx b/tools/source/generic/svlibrary.cxx
new file mode 100644
index 000000000000..6ebfd0086b5c
--- /dev/null
+++ b/tools/source/generic/svlibrary.cxx
@@ -0,0 +1,129 @@
+/*************************************************************************
+ *
+ * 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;
+}
diff --git a/tools/source/generic/toolsin.cxx b/tools/source/generic/toolsin.cxx
new file mode 100644
index 000000000000..50c9c0187b16
--- /dev/null
+++ b/tools/source/generic/toolsin.cxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * 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
+}
diff --git a/tools/source/inet/inetmime.cxx b/tools/source/inet/inetmime.cxx
new file mode 100644
index 000000000000..80b6987d041f
--- /dev/null
+++ b/tools/source/inet/inetmime.cxx
@@ -0,0 +1,4563 @@
+/*************************************************************************
+ *
+ * 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 (sal_uIntPtr i = 0; i < Count(); ++i)
+ {
+ const INetContentTypeParameter * pParameter = GetObject(i);
+ if (pParameter->m_sAttribute.EqualsIgnoreCaseAscii(rAttribute))
+ return pParameter;
+ }
+ return 0;
+}
+
diff --git a/tools/source/inet/inetmsg.cxx b/tools/source/inet/inetmsg.cxx
new file mode 100644
index 000000000000..8432bb52e23d
--- /dev/null
+++ b/tools/source/inet/inetmsg.cxx
@@ -0,0 +1,1653 @@
+/*************************************************************************
+ *
+ * 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>
+#ifndef _TOOLS_INETMIME_HXX
+#include <tools/inetmime.hxx>
+#endif
+#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.
+ sal_uIntPtr 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.
+ sal_uIntPtr 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,
+ sal_uIntPtr &rnIndex)
+{
+ INetMIMEStringOutputSink aSink (0, STRING_MAXLEN);
+ INetMIME::writeHeaderFieldBody (
+ aSink, eType, rValue, gsl_getSystemTextEncoding(), false);
+ SetHeaderField_Impl (
+ INetMessageHeader (rName, aSink.takeBuffer()), rnIndex);
+}
+
+/*
+ * SetHeaderField.
+ */
+sal_uIntPtr INetMessage::SetHeaderField (
+ const UniString& rName, const UniString& rValue, sal_uIntPtr nIndex)
+{
+ sal_uIntPtr nResult = nIndex;
+ SetHeaderField_Impl (
+ INetMIME::HEADER_FIELD_TEXT,
+ ByteString (rName, RTL_TEXTENCODING_ASCII_US), rValue,
+ nResult);
+ return nResult;
+}
+
+/*
+ * SetHeaderField.
+ */
+sal_uIntPtr INetMessage::SetHeaderField (
+ const INetMessageHeader &rHeader, sal_uIntPtr nIndex)
+{
+ sal_uIntPtr 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);
+
+ sal_uIntPtr 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);
+
+ sal_uIntPtr 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)
+{
+ sal_uIntPtr 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)
+{
+ sal_uIntPtr 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 (sal_uInt16 i = 0; i < INETMSG_RFC822_NUMHDR; i++)
+ m_nIndex[i] = LIST_ENTRY_NOTFOUND;
+}
+
+INetRFC822Message::INetRFC822Message (const INetRFC822Message& rMsg)
+ : INetMessage (rMsg)
+{
+ for (sal_uInt16 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 (sal_uInt16 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.
+ */
+sal_Bool INetRFC822Message::GenerateDateField (
+ const DateTime& rDateTime, UniString& rDateFieldW)
+{
+ // Check arguments.
+ if (!rDateTime.IsValid() ||
+ (rDateTime.GetSec() > 59) ||
+ (rDateTime.GetMin() > 59) ||
+ (rDateTime.GetHour() > 23) ) return sal_False;
+
+ // Prepare output string.
+ ByteString rDateField;
+
+ // Insert Date.
+ rDateField += wkdays[(sal_uInt16)(rDateTime.GetDayOfWeek())];
+ rDateField += ", ";
+
+ sal_uInt16 nNum = rDateTime.GetDay();
+ if (nNum < 10) rDateField += '0';
+ rDateField += ByteString::CreateFromInt32(nNum);
+ rDateField += ' ';
+
+ rDateField += months[(sal_uInt16)(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 sal_True;
+}
+
+/*
+ * ParseDateField and local helper functions.
+ */
+static sal_uInt16 ParseNumber (const ByteString& rStr, sal_uInt16& nIndex)
+{
+ sal_uInt16 n = nIndex;
+ while ((n < rStr.Len()) && ascii_isDigit(rStr.GetChar(n))) n++;
+
+ ByteString aNum (rStr.Copy (nIndex, (n - nIndex)));
+ nIndex = n;
+
+ return (sal_uInt16)(aNum.ToInt32());
+}
+
+static sal_uInt16 ParseMonth (const ByteString& rStr, sal_uInt16& nIndex)
+{
+ sal_uInt16 n = nIndex;
+ while ((n < rStr.Len()) && ascii_isLetter(rStr.GetChar(n))) n++;
+
+ ByteString aMonth (rStr.Copy (nIndex, 3));
+ nIndex = n;
+
+ sal_uInt16 i;
+ for (i = 0; i < 12; i++)
+ if (aMonth.CompareIgnoreCaseToAscii (months[i]) == 0) break;
+ return (i + 1);
+}
+
+sal_Bool INetRFC822Message::ParseDateField (
+ const UniString& rDateFieldW, DateTime& rDateTime)
+{
+ ByteString rDateField (rDateFieldW, RTL_TEXTENCODING_ASCII_US);
+ if (rDateField.Len() == 0) return sal_False;
+
+ if (rDateField.Search (':') != STRING_NOTFOUND)
+ {
+ // Some DateTime format.
+ sal_uInt16 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 sal_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);
+
+ sal_uInt16 nYear = ParseNumber (rDateField, nIndex);
+ if (nYear < 100) nYear += 1900;
+ rDateTime.SetYear (nYear);
+ }
+ else
+ {
+ // Format: RFC1036 or RFC1123.
+ if ((rDateField.Len() - nIndex) < 17) return sal_False;
+
+ rDateTime.SetDay (ParseNumber (rDateField, nIndex)); nIndex++;
+ rDateTime.SetMonth (ParseMonth (rDateField, nIndex)); nIndex++;
+
+ sal_uInt16 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".
+ sal_Bool bEast = (rDateField.GetChar(nIndex++) == '+');
+ sal_uInt16 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 sal_False;
+ }
+
+ return (rDateTime.IsValid() &&
+ !((rDateTime.GetSec() > 59) ||
+ (rDateTime.GetMin() > 59) ||
+ (rDateTime.GetHour() > 23) ));
+}
+
+/*
+ * SetHeaderField.
+ * (Header Field Parser).
+ */
+sal_uIntPtr INetRFC822Message::SetHeaderField (
+ const INetMessageHeader &rHeader, sal_uIntPtr nNewIndex)
+{
+ ByteString aName (rHeader.GetName());
+ const sal_Char *pData = aName.GetBuffer();
+ const sal_Char *pStop = pData + aName.Len() + 1;
+ const sal_Char *check = "";
+
+ sal_uIntPtr 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;
+
+#if 0 /* NYI */
+ case 'p':
+ check = "riority";
+ eOkState = INETMSG_RFC822_X_PRIORITY;
+ break;
+#endif /* NYI */
+
+ 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 (sal_uInt16 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 (sal_uInt16 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 (sal_False)
+{
+ for (sal_uInt16 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;
+
+ sal_uInt16 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).
+ */
+sal_uIntPtr INetMIMEMessage::SetHeaderField (
+ const INetMessageHeader &rHeader, sal_uIntPtr nNewIndex)
+{
+ ByteString aName (rHeader.GetName());
+ const sal_Char *pData = aName.GetBuffer();
+ const sal_Char *pStop = pData + aName.Len() + 1;
+ const sal_Char *check = "";
+
+ sal_uIntPtr 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.
+ */
+sal_Bool INetMIMEMessage::EnableAttachChild (INetMessageContainerType eType)
+{
+ // Check context.
+ if (IsContainer())
+ return sal_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 sal_True;
+}
+
+/*
+ * AttachChild.
+ */
+sal_Bool INetMIMEMessage::AttachChild (
+ INetMIMEMessage& rChildMsg, sal_Bool bOwner)
+{
+ if (IsContainer() /*&& rChildMsg.GetContentType().Len() */)
+ {
+ if (bOwner) rChildMsg.pParent = this;
+ aChildren.Insert (&rChildMsg, LIST_APPEND);
+ nNumChildren = aChildren.Count();
+
+ return sal_True;
+ }
+ return sal_False;
+}
+
+/*
+ * DetachChild.
+ */
+sal_Bool INetMIMEMessage::DetachChild (
+ sal_uIntPtr nIndex, INetMIMEMessage& rChildMsg) const
+{
+ if (IsContainer())
+ {
+ // Check document stream.
+ if (GetDocumentLB() == NULL) return sal_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.
+ */
+ sal_uInt16 nLen = (sal_uInt16)(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.
+ sal_uIntPtr 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 sal_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.
+ sal_uIntPtr 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 sal_True;
+ }
+ return sal_False;
+}
+
+/*
+ * operator<<
+ */
+SvStream& INetMIMEMessage::operator<< (SvStream& rStrm) const
+{
+ INetRFC822Message::operator<< (rStrm);
+
+ for (sal_uInt16 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 (sal_uInt16 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;
+}
+
+
diff --git a/tools/source/inet/inetstrm.cxx b/tools/source/inet/inetstrm.cxx
new file mode 100644
index 000000000000..33ed7c8dc41f
--- /dev/null
+++ b/tools/source/inet/inetstrm.cxx
@@ -0,0 +1,1821 @@
+/*************************************************************************
+ *
+ * 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;
+
+ sal_uIntPtr nMsgBufSiz;
+ sal_Char *pMsgBuffer;
+ sal_Char *pMsgRead;
+ sal_Char *pMsgWrite;
+
+ sal_uIntPtr nTokBufSiz;
+ sal_Char *pTokBuffer;
+ sal_Char *pTokRead;
+ sal_Char *pTokWrite;
+
+ INetMessageStreamState eState;
+ sal_Bool bDone;
+
+ virtual int GetMsgLine (sal_Char *pData, sal_uIntPtr nSize);
+
+public:
+ INetMessageEncodeQPStream_Impl (sal_uIntPtr nMsgBufferSize = 1024);
+ virtual ~INetMessageEncodeQPStream_Impl (void);
+};
+
+/*=====================================================================
+ *
+ * INetMessageDecodeQPStream Interface.
+ * (Quoted-Printable Decoding)
+ *
+ *====================================================================*/
+class INetMessageDecodeQPStream_Impl : public INetMessageOStream
+{
+ INetMessageStreamState eState;
+ SvMemoryStream *pMsgBuffer;
+
+ sal_uIntPtr nTokBufLen;
+ sal_Char pTokBuffer[4];
+
+ virtual int PutMsgLine (const sal_Char *pData, sal_uIntPtr nSize);
+
+public:
+ INetMessageDecodeQPStream_Impl (void);
+ virtual ~INetMessageDecodeQPStream_Impl (void);
+};
+
+/*======================================================================
+ *
+ * INetMessageEncode64Stream Interface.
+ * (Base64 Encoding)
+ *
+ *====================================================================*/
+class INetMessageEncode64Stream_Impl : public INetMessageIStream
+{
+ SvStream *pMsgStrm;
+
+ sal_uIntPtr nMsgBufSiz;
+ sal_uInt8 *pMsgBuffer;
+ sal_uInt8 *pMsgRead;
+ sal_uInt8 *pMsgWrite;
+
+ sal_uIntPtr nTokBufSiz;
+ sal_Char *pTokBuffer;
+ sal_Char *pTokRead;
+ sal_Char *pTokWrite;
+
+ sal_Bool bDone;
+
+ virtual int GetMsgLine (sal_Char *pData, sal_uIntPtr nSize);
+
+public:
+ INetMessageEncode64Stream_Impl (sal_uIntPtr nMsgBufferSize = 2048);
+ virtual ~INetMessageEncode64Stream_Impl (void);
+};
+
+/*======================================================================
+ *
+ * INetMessageDecode64Stream Interface.
+ * (Base64 Decoding)
+ *
+ *====================================================================*/
+class INetMessageDecode64Stream_Impl : public INetMessageOStream
+{
+ INetMessageStreamState eState;
+
+ sal_uIntPtr nMsgBufSiz;
+ sal_Char *pMsgBuffer;
+ sal_Char *pMsgRead;
+ sal_Char *pMsgWrite;
+
+ virtual int PutMsgLine (const sal_Char *pData, sal_uIntPtr nSize);
+
+public:
+ INetMessageDecode64Stream_Impl (sal_uIntPtr nMsgBufferSize = 128);
+ virtual ~INetMessageDecode64Stream_Impl (void);
+};
+
+/*=========================================================================
+ *
+ * INetIStream Implementation.
+ *
+ *=======================================================================*/
+/*
+ * INetIStream.
+ */
+INetIStream::INetIStream ()
+{
+}
+
+/*
+ * ~INetIStream.
+ */
+INetIStream::~INetIStream (void)
+{
+}
+
+/*
+ * Read.
+ */
+int INetIStream::Read (sal_Char *pData, sal_uIntPtr nSize)
+{
+ return GetData (pData, nSize);
+}
+
+/*
+ * Decode64.
+ */
+void INetIStream::Decode64 (SvStream& rIn, SvStream& rOut)
+{
+ INetMessage aMsg;
+ aMsg.SetDocumentLB(new SvAsyncLockBytes(&rOut, sal_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, sal_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, sal_uIntPtr nSize)
+{
+ return PutData (pData, nSize);
+}
+
+/*=========================================================================
+ *
+ * INetMessageIStream Implementation.
+ *
+ *=======================================================================*/
+/*
+ * INetMessageIStream.
+ */
+INetMessageIStream::INetMessageIStream (sal_uIntPtr nBufferSize)
+ : pSourceMsg (NULL),
+ bHeaderGenerated (sal_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, sal_uIntPtr 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.
+ sal_uIntPtr n = pRead - pWrite;
+ if (n > 0)
+ {
+ // Bytes still in buffer.
+ sal_uIntPtr m = pWEnd - pWBuf;
+ if (m < n) n = m;
+ for (sal_uIntPtr 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 = sal_True;
+ *pRead++ = '\r';
+ *pRead++ = '\n';
+ }
+ else
+ {
+ // Body generated.
+ return (pWBuf - pData);
+ }
+ }
+ }
+ }
+ return (pWBuf - pData);
+}
+
+/*
+ * GetMsgLine.
+ */
+int INetMessageIStream::GetMsgLine (sal_Char *pData, sal_uIntPtr nSize)
+{
+ if (pSourceMsg == NULL) return INETSTREAM_STATUS_ERROR;
+
+ sal_Char *pWBuf = pData;
+ sal_Char *pWEnd = pData + nSize;
+
+ if (!bHeaderGenerated)
+ {
+ sal_uIntPtr 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());
+
+ sal_uIntPtr nRead = pMsgStrm->Read (pWBuf, (pWEnd - pWBuf));
+ pWBuf += nRead;
+ }
+ }
+ return (pWBuf - pData);
+}
+
+/*=========================================================================
+ *
+ * INetMessageOStream Implementation.
+ *
+ *=======================================================================*/
+/*
+ * INetMessageOStream.
+ */
+INetMessageOStream::INetMessageOStream (void)
+ : pTargetMsg (NULL),
+ bHeaderParsed (sal_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, sal_uIntPtr 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 = sal_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, sal_uIntPtr nSize)
+{
+ // Check for message container.
+ if (pTargetMsg == NULL) return INETSTREAM_STATUS_ERROR;
+
+ // Check for header or body.
+ if (!IsHeaderParsed())
+ {
+ ByteString aField (pData);
+ sal_uInt16 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 (sal_uIntPtr 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 (
+ sal_uIntPtr nMsgBufferSize)
+ : INetMessageIStream (),
+ pMsgStrm (NULL),
+ nMsgBufSiz (nMsgBufferSize),
+ nTokBufSiz (80),
+ eState (INETMSG_EOL_SCR),
+ bDone (sal_False)
+{
+ GenerateHeader (sal_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, sal_uIntPtr 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.
+ sal_uIntPtr 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 = sal_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 (sal_False);
+}
+
+/*
+ * ~INetMessageDecodeQPStream_Impl.
+ */
+INetMessageDecodeQPStream_Impl::~INetMessageDecodeQPStream_Impl (void)
+{
+ delete pMsgBuffer;
+}
+
+/*
+ * PutMsgLine.
+ */
+int INetMessageDecodeQPStream_Impl::PutMsgLine (
+ const sal_Char *pData, sal_uIntPtr 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 (
+ sal_uIntPtr nMsgBufferSize)
+ : INetMessageIStream (),
+ pMsgStrm (NULL),
+ nMsgBufSiz (nMsgBufferSize),
+ nTokBufSiz (80),
+ bDone (sal_False)
+{
+ GenerateHeader (sal_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, sal_uIntPtr 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.
+ sal_uIntPtr 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 = sal_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 = sal_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 (
+ sal_uIntPtr nMsgBufferSize)
+ : INetMessageOStream (),
+ eState (INETMSG_EOL_SCR),
+ nMsgBufSiz (nMsgBufferSize)
+{
+ ParseHeader (sal_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, sal_uIntPtr 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 (sal_uIntPtr 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, sal_uIntPtr 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, sal_uIntPtr 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, sal_False));
+ pMsg->AttachChild( *pNewMessage, sal_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();
+
+ sal_uInt16 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);
+ sal_uIntPtr 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, sal_False));
+
+ pMsg->AttachChild( *pNewMessage, sal_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);
+ }
+ }
+ }
+}
+
+
+
diff --git a/tools/source/memtools/contnr.cxx b/tools/source/memtools/contnr.cxx
new file mode 100755
index 000000000000..63dc74e37441
--- /dev/null
+++ b/tools/source/memtools/contnr.cxx
@@ -0,0 +1,1708 @@
+/*************************************************************************
+ *
+ * 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 _LIMITS_H
+#include <limits.h>
+#endif
+
+#ifndef _STRING_H
+#include <string.h>
+#endif
+
+#ifndef _STDIO_H
+#include <stdio.h>
+#endif
+#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( sal_uInt16 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( sal_uInt16 _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, sal_uInt16 nIndex, sal_uInt16 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, sal_uInt16 nIndex, sal_uInt16 nReSize )
+{
+ DBG_CHKTHIS( CBlock, DbgCheckCBlock );
+
+ sal_uInt16 nNewSize;
+ sal_uInt16 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( sal_uInt16 nIndex, sal_uInt16 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, sal_uInt16 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( sal_uInt16 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( sal_uInt16 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( sal_uInt16 _nBlockSize, sal_uInt16 _nInitSize, sal_uInt16 _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( sal_uIntPtr 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( (sal_uInt16)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( (sal_uInt16)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, sal_uInt16 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, sal_uIntPtr 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, (sal_uInt16)nIndex );
+ }
+}
+
+/*************************************************************************
+|*
+|* Container::Insert()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void Container::Insert( void* pNew, void* pOld )
+{
+ sal_uIntPtr 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, sal_uInt16 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( sal_uIntPtr 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, (sal_uInt16)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, sal_uIntPtr 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, (sal_uInt16)nIndex );
+ }
+}
+
+/*************************************************************************
+|*
+|* Container::SetSize()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void Container::SetSize( sal_uIntPtr nNewSize )
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ if ( nNewSize )
+ {
+ // Unterscheiden sich die Groessen
+ if ( nNewSize != nCount )
+ {
+ CBlock* pTemp;
+ sal_uIntPtr 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
+ sal_Bool bLast = sal_False;
+ CBlock* pDelNext;
+ CBlock* pDelBlock = pTemp->GetNextBlock();
+ while ( pDelBlock )
+ {
+ // Muss CurrentBlock umgesetzt werden
+ if ( pDelBlock == pCurBlock )
+ bLast = sal_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( (sal_uInt16)(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( (sal_uInt16)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( (sal_uInt16)nNewSize, pBlock1 );
+ pBlock1->SetNextBlock( pLastBlock );
+ }
+
+ pCurBlock = pFirstBlock;
+ }
+ // Reicht es, den letzen Puffer in der Groesse anzupassen
+ else if ( (nTemp+pTemp->Count()) <= nBlockSize )
+ pTemp->SetSize( (sal_uInt16)(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( (sal_uInt16)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
+|*
+*************************************************************************/
+
+sal_uIntPtr 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;
+ sal_uIntPtr 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( sal_uIntPtr 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( (sal_uInt16)nIndex );
+ }
+}
+
+/*************************************************************************
+|*
+|* Container::GetObject()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void* Container::GetObject( sal_uIntPtr 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( (sal_uInt16)nIndex );
+ }
+}
+
+/*************************************************************************
+|*
+|* Container::GetPos()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+sal_uIntPtr Container::GetPos( const void* p ) const
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ void** pNodes;
+ CBlock* pTemp;
+ sal_uIntPtr nTemp;
+ sal_uInt16 nBlockCount;
+ sal_uInt16 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
+|*
+*************************************************************************/
+
+sal_uIntPtr Container::GetPos( const void* p, sal_uIntPtr nStartIndex,
+ sal_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;
+ sal_uInt16 nBlockCount;
+ sal_uInt16 i;
+
+ // Block suchen
+ CBlock* pTemp = pFirstBlock;
+ sal_uIntPtr nTemp = 0;
+ while ( nTemp+pTemp->Count() <= nStartIndex )
+ {
+ nTemp += pTemp->Count();
+ pTemp = pTemp->GetNextBlock();
+ }
+
+ // Jetzt den Pointer suchen
+ if ( bForward )
+ {
+ // Alle Bloecke durchrsuchen
+ i = (sal_uInt16)(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 ( sal_True );
+ }
+ else
+ {
+ // Alle Bloecke durchrsuchen
+ i = (sal_uInt16)(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 ( sal_True );
+ }
+ }
+
+ return CONTAINER_ENTRY_NOTFOUND;
+}
+
+/*************************************************************************
+|*
+|* Container::Seek()
+|*
+|* Beschreibung CONTNR.SDW
+|* Ersterstellung TH 17.09.91
+|* Letzte Aenderung TH 17.09.91
+|*
+*************************************************************************/
+
+void* Container::Seek( sal_uIntPtr 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 = (sal_uInt16)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
+|*
+*************************************************************************/
+
+sal_Bool Container::operator ==( const Container& r ) const
+{
+ DBG_CHKTHIS( Container, DbgCheckContainer );
+
+ if ( nCount != r.nCount )
+ return sal_False;
+
+ sal_uIntPtr i = 0;
+ while ( i < nCount )
+ {
+ if ( GetObject( i ) != r.GetObject( i ) )
+ return sal_False;
+ i++;
+ }
+
+ return sal_True;
+}
diff --git a/tools/source/memtools/mempool.cxx b/tools/source/memtools/mempool.cxx
new file mode 100755
index 000000000000..e8be417b15a2
--- /dev/null
+++ b/tools/source/memtools/mempool.cxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * 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 "osl/diagnose.h"
+#include "rtl/alloc.h"
+
+#ifndef INCLUDED_STDIO_H
+#include <stdio.h>
+#endif
+
+/*************************************************************************
+|*
+|* FixedMemPool::FixedMemPool()
+|*
+*************************************************************************/
+
+FixedMemPool::FixedMemPool (
+ char const * pTypeName, sal_uInt16 nTypeSize, sal_uInt16, sal_uInt16)
+ : m_pTypeName (pTypeName)
+{
+ 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);
+ OSL_TRACE("FixedMemPool::ctor(\"%s\"): %p", m_pTypeName, m_pImpl);
+}
+
+/*************************************************************************
+|*
+|* FixedMemPool::~FixedMemPool()
+|*
+*************************************************************************/
+
+FixedMemPool::~FixedMemPool()
+{
+ OSL_TRACE("FixedMemPool::dtor(\"%s\"): %p", m_pTypeName, m_pImpl);
+ rtl_cache_destroy ((rtl_cache_type*)(m_pImpl)), m_pImpl = 0;
+}
+
+/*************************************************************************
+|*
+|* 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);
+}
diff --git a/tools/source/memtools/multisel.cxx b/tools/source/memtools/multisel.cxx
new file mode 100755
index 000000000000..8fd94361d2a3
--- /dev/null
+++ b/tools/source/memtools/multisel.cxx
@@ -0,0 +1,1162 @@
+/*************************************************************************
+ *
+ * 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 ( sal_uIntPtr 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();
+}
+
+// -----------------------------------------------------------------------
+
+sal_uIntPtr MultiSelection::ImplFindSubSelection( long nIndex ) const
+{
+ // iterate through the sub selections
+ sal_uIntPtr n = 0;
+ for ( ;
+ n < aSels.Count() && nIndex > aSels.GetObject(n)->Max();
+ ++n ) {} /* empty loop */
+ return n;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool MultiSelection::ImplMergeSubSelections( sal_uIntPtr nPos1, sal_uIntPtr nPos2 )
+{
+ // didn't a sub selection at nPos2 exist?
+ if ( nPos2 >= aSels.Count() )
+ return sal_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 sal_True;
+ }
+
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------
+
+MultiSelection::MultiSelection():
+ aTotRange( 0, -1 ),
+ nCurSubSel(0),
+ nSelCount(0),
+ bCurValid(sal_False),
+ bSelectNew(sal_False)
+{
+}
+
+// -----------------------------------------------------------------------
+
+MultiSelection::MultiSelection( const UniString& rString, sal_Unicode cRange, sal_Unicode cSep ):
+ aTotRange(0,RANGE_MAX),
+ nCurSubSel(0),
+ nSelCount(0),
+ bCurValid(sal_False),
+ bSelectNew(sal_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;
+ sal_Bool bReady = sal_False;
+ sal_Bool bUntil = sal_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 = sal_False;
+ }
+ *pStr++ = *pOld;
+ nCut++;
+ bUntil = sal_False;
+ break;
+
+ case '-':
+ case ':':
+ case '/':
+ if ( *pOld != cSep )
+ {
+ if ( !bUntil )
+ {
+ *pStr++ = '-';
+ nCut++;
+ bUntil = sal_True;
+ }
+ bReady = sal_False;
+ }
+ else
+ bReady = sal_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 = sal_True;
+ }
+ bReady = sal_False;
+ }
+ else
+ bReady = sal_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 = sal_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 = sal_False;
+ break;
+
+ case '-':
+ nPage = aNumStr.ToInt32();
+ aNumStr.Erase();
+ bUntil = sal_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(sal_False)
+{
+ if ( bCurValid )
+ {
+ nCurSubSel = rOrig.nCurSubSel;
+ nCurIndex = rOrig.nCurIndex;
+ }
+
+ // copy the sub selections
+ for ( sal_uIntPtr 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(sal_False),
+ bSelectNew(sal_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 ( sal_uIntPtr n = 0; n < rOrig.aSels.Count(); ++n )
+ aSels.Insert( new Range( *rOrig.aSels.GetObject(n) ), LIST_APPEND );
+ nSelCount = rOrig.nSelCount;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool MultiSelection::operator== ( MultiSelection& rWith )
+{
+ if ( aTotRange != rWith.aTotRange || nSelCount != rWith.nSelCount ||
+ aSels.Count() != rWith.aSels.Count() )
+ return sal_False;
+
+ // compare the sub seletions
+ for ( sal_uIntPtr n = 0; n < aSels.Count(); ++n )
+ if ( *aSels.GetObject(n) != *rWith.aSels.GetObject(n) )
+ return sal_False;
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+void MultiSelection::SelectAll( sal_Bool bSelect )
+{
+ DBG(DbgOutf( "::SelectAll(%s)\n", bSelect ? "sal_True" : "sal_False" ));
+
+ ImplClear();
+ if ( bSelect )
+ {
+ aSels.Insert( new Range(aTotRange), LIST_APPEND );
+ nSelCount = aTotRange.Len();
+ }
+
+ DBG(Print( this ));
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool MultiSelection::Select( long nIndex, sal_Bool bSelect )
+{
+ DBG_ASSERT( aTotRange.IsInside(nIndex), "selected index out of range" );
+
+ // out of range?
+ if ( !aTotRange.IsInside(nIndex) )
+ return sal_False;
+
+ // find the virtual target position
+ sal_uIntPtr 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 sal_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 sal_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 sal_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 sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+void MultiSelection::Select( const Range& rIndexRange, sal_Bool bSelect )
+{
+ Range* pRange;
+ long nOld;
+
+ sal_uIntPtr nTmpMin = rIndexRange.Min();
+ sal_uIntPtr nTmpMax = rIndexRange.Max();
+ sal_uIntPtr nCurMin = FirstSelected();
+ sal_uIntPtr 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, (sal_uIntPtr)0 );
+ nSelCount += pRange->Len();
+ }
+ else
+ {
+ pRange = aSels.First();
+ nOld = pRange->Min();
+ pRange->Min() = (long)nTmpMin;
+ nSelCount += ( nOld - nTmpMin );
+ }
+ bCurValid = sal_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 = sal_False;
+ }
+ return;
+ }
+
+ //HACK(Hier muss noch optimiert werden)
+ while( nTmpMin <= nTmpMax )
+ {
+ Select( nTmpMin, bSelect );
+ nTmpMin++;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool MultiSelection::IsSelected( long nIndex ) const
+{
+ // find the virtual target position
+ sal_uIntPtr 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
+ sal_uIntPtr 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 ( sal_uIntPtr nPos = nSubSelPos; nPos < aSels.Count(); ++nPos )
+ {
+ aSels.GetObject(nPos)->Min() += nCount;
+ aSels.GetObject(nPos)->Max() += nCount;
+ }
+ }
+
+ bCurValid = sal_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
+ sal_uIntPtr 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 ( sal_uIntPtr nPos = nSubSelPos; nPos < aSels.Count(); ++nPos )
+ {
+ --( aSels.GetObject(nPos)->Min() );
+ --( aSels.GetObject(nPos)->Max() );
+ }
+
+ bCurValid = sal_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( sal_Bool bInverse )
+{
+ bInverseCur = bInverse;
+ nCurSubSel = 0;
+
+ if ( bInverseCur )
+ {
+ bCurValid = nSelCount < sal_uIntPtr(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( (sal_uIntPtr)0 );
+ }
+ else if( pRange->Min() < aTotRange.Min() )
+ {
+ pRange->Min() = aTotRange.Min();
+ break;
+ }
+ else
+ break;
+
+ pRange = aSels.GetObject( 0 );
+ }
+
+ // die obere Bereichsgrenze anpassen
+ sal_uIntPtr nCount = aSels.Count();
+ while( nCount )
+ {
+ pRange = aSels.GetObject( nCount - 1 );
+ if( pRange->Min() > aTotRange.Max() )
+ {
+ delete pRange;
+ aSels.Remove( (sal_uIntPtr)(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 = sal_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;
+}
+
diff --git a/tools/source/memtools/table.cxx b/tools/source/memtools/table.cxx
new file mode 100755
index 000000000000..80b2c9747966
--- /dev/null
+++ b/tools/source/memtools/table.cxx
@@ -0,0 +1,413 @@
+/*************************************************************************
+ *
+ * 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>
+
+// =======================================================================
+
+sal_uIntPtr Table::ImplGetIndex( sal_uIntPtr nKey, sal_uIntPtr* pIndex ) const
+{
+ // Abpruefen, ob der erste Key groesser als der Vergleichskey ist
+ if ( !nCount || (nKey < (sal_uIntPtr)Container::ImpGetObject(0)) )
+ return TABLE_ENTRY_NOTFOUND;
+
+ sal_uIntPtr nLow;
+ sal_uIntPtr nHigh;
+ sal_uIntPtr nMid;
+ sal_uIntPtr nCompareKey;
+ void** pNodes = Container::ImpGetOnlyNodes();
+
+ // Binaeres Suchen
+ nLow = 0;
+ nHigh = nCount-1;
+ if ( pNodes )
+ {
+ do
+ {
+ nMid = (nLow + nHigh) / 2;
+ nCompareKey = (sal_uIntPtr)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 = (sal_uIntPtr)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( sal_uInt16 _nInitSize, sal_uInt16 _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;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Table::Insert( sal_uIntPtr nKey, void* p )
+{
+ // Tabellenelement einsortieren
+ sal_uIntPtr i;
+ if ( nCount )
+ {
+ if ( nCount <= 24 )
+ {
+ sal_uInt16 n = 0;
+ sal_uInt16 nTempCount = (sal_uInt16)nCount * 2;
+ //<!--Modified by PengYunQuan for resolving a NULL pointer access
+
+ if( void** pNodes = Container::ImpGetOnlyNodes() )
+ {
+ sal_uIntPtr nCompareKey = (sal_uIntPtr)(*pNodes);
+ while ( nKey > nCompareKey )
+ {
+ n += 2;
+ pNodes += 2;
+ if ( n < nTempCount )
+ nCompareKey = (sal_uIntPtr)(*pNodes);
+ else
+ {
+ nCompareKey = 0;
+ break;
+ }
+ }
+
+ // Testen, ob sich der Key schon in der Tabelle befindet
+ if ( nKey == nCompareKey )
+ return sal_False;
+
+ i = n;
+ }
+ else
+ {
+ i = 0;
+ if ( ImplGetIndex( nKey, &i ) != TABLE_ENTRY_NOTFOUND )
+ return sal_False;
+ }
+ //-->Modified by PengYunQuan for resolving a NULL pointer access
+ }
+ else
+ {
+ i = 0;
+ if ( ImplGetIndex( nKey, &i ) != TABLE_ENTRY_NOTFOUND )
+ return sal_False;
+ }
+ }
+ else
+ i = 0;
+
+ // Eintrag einfuegen (Key vor Pointer)
+ Container::Insert( (void*)nKey, i );
+ Container::Insert( p, i+1 );
+
+ // Ein neuer Eintrag
+ nCount++;
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+void* Table::Remove( sal_uIntPtr nKey )
+{
+ // Index besorgen
+ sal_uIntPtr 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( sal_uIntPtr nKey, void* p )
+{
+ // Index abfragen
+ sal_uIntPtr 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( sal_uIntPtr nKey ) const
+{
+ // Index besorgen
+ sal_uIntPtr 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 );
+}
+
+// -----------------------------------------------------------------------
+
+sal_uIntPtr Table::GetKey( const void* p ) const
+{
+ sal_uIntPtr 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 (sal_uIntPtr)Container::ImpGetObject( nIndex*2 );
+
+ nIndex++;
+ }
+
+ return TABLE_ENTRY_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Table::IsKeyValid( sal_uIntPtr nKey ) const
+{
+ return (ImplGetIndex( nKey ) != TABLE_ENTRY_NOTFOUND) ? sal_True : sal_False;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uIntPtr Table::GetUniqueKey( sal_uIntPtr nStartKey ) const
+{
+ DBG_ASSERT( (nStartKey > 1) && (nStartKey < 0xFFFFFFFF),
+ "Table::GetUniqueKey() - nStartKey == 0 or nStartKey >= 0xFFFFFFFF" );
+
+ if ( !nCount )
+ return nStartKey;
+
+ sal_uIntPtr nLastKey = (sal_uIntPtr)Container::GetObject( (nCount*2)-2 );
+ if ( nLastKey < nStartKey )
+ return nStartKey;
+ else
+ {
+ if ( nLastKey < 0xFFFFFFFE )
+ return nLastKey+1;
+ else
+ {
+ sal_uIntPtr nPos;
+ sal_uIntPtr nTempPos = ImplGetIndex( nStartKey, &nPos );
+ if ( nTempPos != TABLE_ENTRY_NOTFOUND )
+ nPos = nTempPos;
+ nLastKey = (sal_uIntPtr)Container::GetObject( nPos );
+ if ( nStartKey < nLastKey )
+ return nStartKey;
+ while ( nLastKey < 0xFFFFFFFE )
+ {
+ nPos += 2;
+ nLastKey++;
+ if ( nLastKey != (sal_uIntPtr)Container::GetObject( nPos ) )
+ return nLastKey;
+ }
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uIntPtr Table::SearchKey( sal_uIntPtr nKey, sal_uIntPtr* pPos ) const
+{
+ *pPos = 0;
+ sal_uIntPtr nPos = ImplGetIndex( nKey, pPos );
+ if ( nPos != TABLE_ENTRY_NOTFOUND )
+ {
+ nPos /= 2;
+ *pPos = nPos;
+ }
+ else
+ *pPos /= 2;
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+void* Table::Seek( sal_uIntPtr nKey )
+{
+ // Testen, ob ein Eintrag vorhanden ist
+ if ( nCount )
+ {
+ sal_uIntPtr 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 )
+{
+ sal_uIntPtr 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;
+}
diff --git a/tools/source/memtools/unqidx.cxx b/tools/source/memtools/unqidx.cxx
new file mode 100755
index 000000000000..020ae64dde95
--- /dev/null
+++ b/tools/source/memtools/unqidx.cxx
@@ -0,0 +1,601 @@
+/*************************************************************************
+ *
+ * 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( sal_uIntPtr _nStartIndex,
+ sal_uIntPtr _nInitSize, sal_uIntPtr _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
+|*
+*************************************************************************/
+
+sal_uIntPtr 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
+|*
+*************************************************************************/
+
+sal_uIntPtr UniqueIndex::Insert( sal_uIntPtr nIndex, void* p )
+{
+ // NULL-Pointer ist nicht erlaubt
+ if ( !p )
+ return UNIQUEINDEX_ENTRY_NOTFOUND;
+
+ sal_uIntPtr 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( sal_uIntPtr 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( sal_uIntPtr 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( sal_uIntPtr 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
+|*
+*************************************************************************/
+
+sal_uIntPtr UniqueIndex::GetCurIndex() const
+{
+ sal_uIntPtr 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
+|*
+*************************************************************************/
+
+sal_uIntPtr UniqueIndex::GetIndex( const void* p ) const
+{
+ // Wird ein NULL-Pointer uebergeben, dann wurde Pointer nicht gefunden
+ if ( !p )
+ return UNIQUEINDEX_ENTRY_NOTFOUND;
+
+ sal_uIntPtr 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
+|*
+*************************************************************************/
+
+sal_Bool UniqueIndex::IsIndexValid( sal_uIntPtr 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 sal_True;
+ else
+ return sal_False;
+ }
+ else
+ return sal_False;
+}
+
+/*************************************************************************
+|*
+|* UniqueIndex::Seek()
+|*
+|* Beschreibung UNQIDX.SDW
+|* Ersterstellung TH 24.09.91
+|* Letzte Aenderung TH 24.09.91
+|*
+*************************************************************************/
+
+void* UniqueIndex::Seek( sal_uIntPtr 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;
+
+ sal_uIntPtr 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
+|*
+*************************************************************************/
+
+sal_Bool UniqueIndex::operator ==( const UniqueIndex& rIdx ) const
+{
+ // Neue Werte zuweisen
+ if ( (nStartIndex == rIdx.nStartIndex) &&
+ (nCount == rIdx.nCount) &&
+ (Container::operator ==( rIdx )) )
+ return sal_True;
+ else
+ return sal_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 )
+{
+ sal_uIntPtr 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;
+
+ sal_uIntPtr 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( sal_Bool bAll )
+{
+ sal_uInt16 nFree = bAll ? 0xFFFF : 1;
+
+ ImpUniqueId* pId = (ImpUniqueId*)Last();
+ sal_Bool bLast = sal_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 = sal_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( sal_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( sal_uIntPtr 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( sal_uIntPtr 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 );
+}
diff --git a/tools/source/misc/appendunixshellword.cxx b/tools/source/misc/appendunixshellword.cxx
new file mode 100644
index 000000000000..af2a05b00716
--- /dev/null
+++ b/tools/source/misc/appendunixshellword.cxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/source/misc/extendapplicationenvironment.cxx b/tools/source/misc/extendapplicationenvironment.cxx
new file mode 100644
index 000000000000..440f5a5cb207
--- /dev/null
+++ b/tools/source/misc/extendapplicationenvironment.cxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * 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();
+ }
+}
+
+}
diff --git a/tools/source/misc/getprocessworkingdir.cxx b/tools/source/misc/getprocessworkingdir.cxx
new file mode 100644
index 000000000000..8cad594befca
--- /dev/null
+++ b/tools/source/misc/getprocessworkingdir.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+#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;
+}
+
+}
diff --git a/tools/source/misc/pathutils.cxx b/tools/source/misc/pathutils.cxx
new file mode 100644
index 000000000000..4685f96ca187
--- /dev/null
+++ b/tools/source/misc/pathutils.cxx
@@ -0,0 +1,218 @@
+/*************************************************************************
+ *
+ * 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 "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
diff --git a/tools/source/misc/solarmutex.cxx b/tools/source/misc/solarmutex.cxx
new file mode 100644
index 000000000000..5abdfef5e37f
--- /dev/null
+++ b/tools/source/misc/solarmutex.cxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * 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 ::vos::IMutex* pSolarMutex = 0;
+
+ ::vos::IMutex* SolarMutex::GetSolarMutex()
+ {
+ return pSolarMutex;
+ }
+
+ void SolarMutex::SetSolarMutex( ::vos::IMutex* pMutex )
+ {
+ pSolarMutex = pMutex;
+ }
+
+ bool SolarMutex::Acquire()
+ {
+ if ( pSolarMutex )
+ pSolarMutex->acquire();
+ else
+ return false;
+ return true;
+ }
+
+ void SolarMutex::Release()
+ {
+ if ( pSolarMutex )
+ pSolarMutex->release();
+ }
+}
diff --git a/tools/source/rc/isofallback.cxx b/tools/source/rc/isofallback.cxx
new file mode 100644
index 000000000000..002a90f580aa
--- /dev/null
+++ b/tools/source/rc/isofallback.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// 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;
+}
+
diff --git a/tools/source/rc/rc.cxx b/tools/source/rc/rc.cxx
new file mode 100644
index 000000000000..f9a08a5525e6
--- /dev/null
+++ b/tools/source/rc/rc.cxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * 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 );
+
+ sal_uIntPtr nObjMask = (sal_uInt16)pResMgr->ReadLong();
+
+ if ( 0x01 & nObjMask )
+ SetHour( (sal_uInt16)pResMgr->ReadShort() );
+ if ( 0x02 & nObjMask )
+ SetMin( (sal_uInt16)pResMgr->ReadShort() );
+ if ( 0x04 & nObjMask )
+ SetSec( (sal_uInt16)pResMgr->ReadShort() );
+ if ( 0x08 & nObjMask )
+ Set100Sec( (sal_uInt16)pResMgr->ReadShort() );
+}
+
+// =======================================================================
+
+Date::Date( const ResId& rResId ) : nDate(0)
+{
+ rResId.SetRT( RSC_DATE );
+ ResMgr* pResMgr = NULL;
+
+ ResMgr::GetResourceSkipHeader( rResId, &pResMgr );
+
+ sal_uIntPtr nObjMask = (sal_uInt16)pResMgr->ReadLong();
+
+ if ( 0x01 & nObjMask )
+ SetYear( (sal_uInt16)pResMgr->ReadShort() );
+ if ( 0x02 & nObjMask )
+ SetMonth( (sal_uInt16)pResMgr->ReadShort() );
+ if ( 0x04 & nObjMask )
+ SetDay( (sal_uInt16)pResMgr->ReadShort() );
+}
diff --git a/tools/source/rc/resary.cxx b/tools/source/rc/resary.cxx
new file mode 100644
index 000000000000..a55a4f644a9f
--- /dev/null
+++ b/tools/source/rc/resary.cxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * 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;
+}
diff --git a/tools/source/rc/resmgr.cxx b/tools/source/rc/resmgr.cxx
new file mode 100644
index 000000000000..4ddb753a0df3
--- /dev/null
+++ b/tools/source/rc/resmgr.cxx
@@ -0,0 +1,2120 @@
+/*************************************************************************
+ *
+ * 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 <vos/signal.hxx>
+#include <tools/debug.hxx>
+#ifndef _TABLE_HXX
+#include <tools/table.hxx>
+#endif
+#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 <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.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;
+ sal_uInt32 nOffCorrection;
+ sal_uInt8 * pStringBlock;
+ SvStream * pStm;
+ sal_Bool bEqual2Content;
+ sal_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();
+ sal_Bool Create();
+
+ sal_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( sal_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;
+}
+
+// -----------------------------------------------------------------------
+
+
+sal_Bool InternalResMgr::Create()
+{
+ ResMgrContainer::get();
+ sal_Bool bDone = sal_False;
+
+ pStm = new SvFileStream( aFileName, (STREAM_READ | STREAM_SHARE_DENYWRITE | STREAM_NOCREATE) );
+ if( pStm->GetError() == 0 )
+ {
+ sal_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)
+ sal_uInt8* pContentBuf = (sal_uInt8*)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 = (sal_uInt32)lContLen / 12;
+ bEqual2Content = sal_True; // Die Daten der Resourcen liegen
+ // genauso wie das Inhaltsverzeichnis
+ sal_Bool bSorted = sal_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 = sal_False;
+ if( (pContent[i].nTypeAndId & 0xFFFFFFFF00000000LL) == (pContent[j].nTypeAndId & 0xFFFFFFFF00000000LL)
+ && pContent[i].nOffset >= pContent[j].nOffset )
+ bEqual2Content = sal_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 = sal_True;
+ }
+
+ return bDone;
+}
+
+// -----------------------------------------------------------------------
+
+sal_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;
+ sal_uInt32 nSize;
+ --pLast;
+ pStm->Seek( pLast->nOffset );
+ RSHEADER_TYPE aHdr;
+ pStm->Read( &aHdr, sizeof( aHdr ) );
+ nSize = pLast->nOffset + aHdr.GetGlobOff() - nOffCorrection;
+ pStringBlock = (sal_uInt8*)rtl_allocateMemory( nSize );
+ pStm->Seek( pFirst->nOffset );
+ pStm->Read( pStringBlock, nSize );
+ }
+ *pResHandle = pStringBlock;
+ return (sal_uInt8*)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( (sal_uInt8*)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 = sal_False;
+ UniString aTypStr( UniString::CreateFromInt32( rTypeId.GetId() ) );
+
+ if ( !bInUse )
+ {
+ bInUse = sal_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 = sal_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 ( vos::OSignalHandler::raise( OSL_SIGNAL_USER_RESOURCEFAILURE, (void*)"" ) )
+ {
+ case vos::OSignalHandler::TAction_CallNextHandler:
+ abort();
+
+ case vos::OSignalHandler::TAction_Ignore:
+ return;
+
+ case vos::OSignalHandler::TAction_AbortApplication:
+ abort();
+
+ case vos::OSignalHandler::TAction_KillApplication:
+ 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*)
+ ((sal_uInt8*)pStack->pResource + pStack->pResource->GetLocalOff());
+ pEnd = (RSHEADER_TYPE*)
+ ((sal_uInt8*)pStack->pResource + pStack->pResource->GetGlobOff());
+ while ( pTmp != pEnd )
+ {
+ if ( pTmp->GetRT() == nRTType && pTmp->GetId() == nId )
+ return pTmp;
+ pTmp = (RSHEADER_TYPE*)((sal_uInt8*)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
+
+// -----------------------------------------------------------------------
+sal_Bool ResMgr::IsAvailable( const ResId& rId, const Resource* pResObj ) const
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ sal_Bool bAvailable = sal_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 = sal_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;
+}
+
+// -----------------------------------------------------------------------
+
+sal_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 sal_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 sal_False;
+ }
+ }
+ }
+
+ return sal_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 = (sal_uInt8*)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;
+}
+
+// ------------------------------------------------------------------
+
+sal_Int16 ResMgr::GetShort( void * pShort )
+{
+ return ((*((sal_uInt8*)pShort + 0) << 8) |
+ (*((sal_uInt8*)pShort + 1) << 0) );
+}
+
+// ------------------------------------------------------------------
+
+sal_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 sal_uInt8* pStr )
+{
+ sal_uInt32 nLen=0;
+ sal_uInt32 nRet = GetStringSize( pStr, nLen );
+ 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 sal_uInt8* pStr )
+{
+ UniString aString;
+ sal_uInt32 nRet = GetStringWithoutHook( aString, pStr );
+ if ( pImplResHookProc )
+ pImplResHookProc( aString );
+ rStr = aString;
+ return nRet;
+}
+
+sal_uInt32 ResMgr::GetByteString( rtl::OString& rStr, const sal_uInt8* pStr )
+{
+ sal_uInt32 nLen=0;
+ sal_uInt32 nRet = GetStringSize( pStr, nLen );
+ rStr = rtl::OString( (const sal_Char*)pStr, nLen );
+ return nRet;
+}
+
+// ------------------------------------------------------------------
+
+sal_uInt32 ResMgr::GetStringSize( const sal_uInt8* pStr, sal_uInt32& nLen )
+{
+ nLen = static_cast< sal_uInt32 >( strlen( (const char*)pStr ) );
+ return GetStringSize( nLen );
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt32 ResMgr::GetRemainSize()
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if( pFallbackResMgr )
+ return pFallbackResMgr->GetRemainSize();
+
+ const ImpRCStack& rTop = aStack[nCurStack];
+ return (sal_uInt32)((long)(sal_uInt8 *)rTop.pResource +
+ rTop.pResource->GetLocalOff() -
+ (long)(sal_uInt8 *)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;
+
+ sal_uInt8* pClassRes = (sal_uInt8*)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, sal_uInt16 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;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int16 ResMgr::ReadShort()
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if( pFallbackResMgr )
+ return pFallbackResMgr->ReadShort();
+
+ sal_Int16 n = GetShort( GetClass() );
+ Increment( sizeof( sal_Int16 ) );
+ return n;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int32 ResMgr::ReadLong()
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if( pFallbackResMgr )
+ return pFallbackResMgr->ReadLong();
+
+ sal_Int32 n = GetLong( GetClass() );
+ Increment( sizeof( sal_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 sal_uInt8*)GetClass() ) );
+
+ return aRet;
+}
+
+UniString ResMgr::ReadString()
+{
+ UniString aRet = ReadStringWithoutHook();
+ if ( pImplResHookProc )
+ pImplResHookProc( aRet );
+ return aRet;
+}
+
+rtl::OString ResMgr::ReadByteString()
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if( pFallbackResMgr )
+ return pFallbackResMgr->ReadByteString();
+
+ rtl::OString aRet;
+
+ const ImpRCStack& rTop = aStack[nCurStack];
+ if( (rTop.Flags & RC_NOTFOUND) )
+ {
+ #if OSL_DEBUG_LEVEL > 0
+ aRet = OString( "<resource not found>" );
+ #endif
+ }
+ else
+ Increment( GetByteString( aRet, (const sal_uInt8*)GetClass() ) );
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------
+
+rtl::OString ResMgr::GetAutoHelpId()
+{
+ osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
+
+ if( pFallbackResMgr )
+ return pFallbackResMgr->GetAutoHelpId();
+
+ OSL_ENSURE( nCurStack, "resource stack empty in Auto help id generation" );
+ if( nCurStack < 1 || nCurStack > 2 )
+ return rtl::OString();
+
+ // prepare HID, start with resource prefix
+ rtl::OStringBuffer aHID( 32 );
+ aHID.append( rtl::OUStringToOString( pImpRes->aPrefix, RTL_TEXTENCODING_UTF8 ) );
+ aHID.append( '.' );
+
+ // append type
+ const ImpRCStack *pRC = StackTop();
+ OSL_ENSURE( pRC, "missing resource stack level" );
+
+ if ( nCurStack == 1 )
+ {
+ // auto help ids for top level windows
+ switch( pRC->pResource->GetRT() ) {
+ case RSC_DOCKINGWINDOW: aHID.append( "DockingWindow" ); break;
+ case RSC_WORKWIN: aHID.append( "WorkWindow" ); break;
+ case RSC_MODELESSDIALOG: aHID.append( "ModelessDialog" ); break;
+ case RSC_FLOATINGWINDOW: aHID.append( "FloatingWindow" ); break;
+ case RSC_MODALDIALOG: aHID.append( "ModalDialog" ); break;
+ case RSC_TABPAGE: aHID.append( "TabPage" ); break;
+ default: return rtl::OString();
+ }
+ }
+ else
+ {
+ // only controls with the following parents get auto help ids
+ const ImpRCStack *pRC1 = StackTop(1);
+ switch( pRC1->pResource->GetRT() ) {
+ case RSC_DOCKINGWINDOW:
+ case RSC_WORKWIN:
+ case RSC_MODELESSDIALOG:
+ case RSC_FLOATINGWINDOW:
+ case RSC_MODALDIALOG:
+ case RSC_TABPAGE:
+ // intentionally no breaks!
+ // auto help ids for controls
+ switch( pRC->pResource->GetRT() ) {
+ case RSC_TABCONTROL: aHID.append( "TabControl" ); break;
+ case RSC_RADIOBUTTON: aHID.append( "RadioButton" ); break;
+ case RSC_CHECKBOX: aHID.append( "CheckBox" ); break;
+ case RSC_TRISTATEBOX: aHID.append( "TriStateBox" ); break;
+ case RSC_EDIT: aHID.append( "Edit" ); break;
+ case RSC_MULTILINEEDIT: aHID.append( "MultiLineEdit" ); break;
+ case RSC_MULTILISTBOX: aHID.append( "MultiListBox" ); break;
+ case RSC_LISTBOX: aHID.append( "ListBox" ); break;
+ case RSC_COMBOBOX: aHID.append( "ComboBox" ); break;
+ case RSC_PUSHBUTTON: aHID.append( "PushButton" ); break;
+ case RSC_SPINFIELD: aHID.append( "SpinField" ); break;
+ case RSC_PATTERNFIELD: aHID.append( "PatternField" ); break;
+ case RSC_NUMERICFIELD: aHID.append( "NumericField" ); break;
+ case RSC_METRICFIELD: aHID.append( "MetricField" ); break;
+ case RSC_CURRENCYFIELD: aHID.append( "CurrencyField" ); break;
+ case RSC_DATEFIELD: aHID.append( "DateField" ); break;
+ case RSC_TIMEFIELD: aHID.append( "TimeField" ); break;
+ case RSC_IMAGERADIOBUTTON: aHID.append( "ImageRadioButton" ); break;
+ case RSC_NUMERICBOX: aHID.append( "NumericBox" ); break;
+ case RSC_METRICBOX: aHID.append( "MetricBox" ); break;
+ case RSC_CURRENCYBOX: aHID.append( "CurrencyBox" ); break;
+ case RSC_DATEBOX: aHID.append( "DateBox" ); break;
+ case RSC_TIMEBOX: aHID.append( "TimeBox" ); break;
+ case RSC_IMAGEBUTTON: aHID.append( "ImageButton" ); break;
+ case RSC_MENUBUTTON: aHID.append( "MenuButton" ); break;
+ case RSC_MOREBUTTON: aHID.append( "MoreButton" ); break;
+ default:
+ // no type, no auto HID
+ return rtl::OString();
+ }
+ break;
+ default:
+ return rtl::OString();
+ }
+ }
+
+ // append resource id hierarchy
+ for( int nOff = nCurStack-1; nOff >= 0; nOff-- )
+ {
+ aHID.append( '.' );
+ pRC = StackTop( nOff );
+
+ OSL_ENSURE( pRC->pResource, "missing resource in resource stack level !" );
+ if( pRC->pResource )
+ aHID.append( sal_Int32( pRC->pResource->GetId() ) );
+ }
+
+ return aHID.makeStringAndClear();
+}
+
+// -----------------------------------------------------------------------
+
+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 )
+{
+ vos::OGuard 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 )
+{
+ vos::OGuard 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;
+ }
+
+ // sal_uIntPtr nLen = pResHeader->GetLocalOff() - sizeof(RSHEADER_TYPE);
+ ResMgr::GetString( sReturn, (const sal_uInt8*)(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 )
+{
+ vos::OGuard 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*)(((sal_uInt8*)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*)(((sal_uInt8*)pBuffer) - sizeof(RSHEADER_TYPE));
+ rtl_freeMemory(pCompleteBuffer);
+}
diff --git a/tools/source/ref/errinf.cxx b/tools/source/ref/errinf.cxx
new file mode 100644
index 000000000000..1587f7324556
--- /dev/null
+++ b/tools/source/ref/errinf.cxx
@@ -0,0 +1,462 @@
+/*************************************************************************
+ *
+ * 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;
+ sal_Bool bIsWindowDsp;
+
+
+ DynamicErrorInfo *ppDcr[ERRCODE_DYNAMIC_COUNT];
+ sal_uInt16 nNextDcr;
+ EDcrData();
+
+static EDcrData *GetData();
+
+};
+
+class EDcr_Impl
+{
+ sal_uIntPtr lErrId;
+ sal_uInt16 nMask;
+
+ void RegisterEDcr(DynamicErrorInfo *);
+ void UnRegisterEDcr(DynamicErrorInfo *);
+ static ErrorInfo *GetDynamicErrorInfo(sal_uIntPtr lId);
+
+friend class DynamicErrorInfo;
+friend class ErrorInfo;
+};
+
+
+EDcrData::EDcrData()
+{
+ for(sal_uInt16 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= (((sal_uIntPtr)pData->nNextDcr + 1) << ERRCODE_DYNAMIC_SHIFT) +
+ pDcr->GetErrorCode();
+ DynamicErrorInfo **ppDcr=pData->ppDcr;
+ sal_uInt16 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;
+ sal_uIntPtr lIdx=(
+ ((sal_uIntPtr)(*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(sal_uIntPtr lId)
+{
+ if(lId & ERRCODE_DYNAMIC_MASK)
+ return EDcr_Impl::GetDynamicErrorInfo(lId);
+ else
+ return new ErrorInfo(lId);
+}
+
+DynamicErrorInfo::operator sal_uIntPtr() const
+{
+ return pImpl->lErrId;
+}
+
+DynamicErrorInfo::DynamicErrorInfo(sal_uIntPtr lArgUserId, sal_uInt16 nMask)
+: ErrorInfo(lArgUserId)
+{
+ pImpl=new EDcr_Impl;
+ pImpl->RegisterEDcr(this);
+ pImpl->nMask=nMask;
+}
+
+DynamicErrorInfo::~DynamicErrorInfo()
+{
+ pImpl->UnRegisterEDcr(this);
+ delete pImpl;
+}
+
+ErrorInfo* EDcr_Impl::GetDynamicErrorInfo(sal_uIntPtr lId)
+{
+ sal_uIntPtr lIdx=((lId & ERRCODE_DYNAMIC_MASK)>>ERRCODE_DYNAMIC_SHIFT)-1;
+ DynamicErrorInfo* pDcr=EDcrData::GetData()->ppDcr[lIdx];
+ if(pDcr && (sal_uIntPtr)(*pDcr)==lId)
+ return pDcr;
+ else
+ return new ErrorInfo(lId & ~ERRCODE_DYNAMIC_MASK);
+}
+
+
+sal_uInt16 DynamicErrorInfo::GetDialogMask() const
+{
+ return pImpl->nMask;
+}
+
+
+StandardErrorInfo::StandardErrorInfo(
+ sal_uIntPtr UserId, sal_uIntPtr lArgExtId, sal_uInt16 nFlags)
+: DynamicErrorInfo(UserId, nFlags), lExtId(lArgExtId)
+{
+}
+
+
+StringErrorInfo::StringErrorInfo(
+ sal_uIntPtr UserId, const String& aStringP, sal_uInt16 nFlags)
+: DynamicErrorInfo(UserId, nFlags), aString(aStringP)
+{
+}
+
+
+class ErrHdl_Impl
+{
+ public:
+
+ ErrorHandler *pNext;
+ static sal_Bool CreateString(const ErrorHandler *pStart,
+ const ErrorInfo*, String&, sal_uInt16&);
+};
+
+
+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=sal_True;
+ pData->pDsp = reinterpret_cast< DisplayFnPtr >(aDsp);
+}
+
+void ErrorHandler::RegisterDisplay(BasicDisplayErrorFunc *aDsp)
+{
+ EDcrData *pData=EDcrData::GetData();
+ pData->bIsWindowDsp=sal_False;
+ pData->pDsp = reinterpret_cast< DisplayFnPtr >(aDsp);
+}
+
+sal_uInt16 ErrorHandler::HandleError_Impl(
+ sal_uIntPtr lId, sal_uInt16 nFlags, sal_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;
+ }
+
+ sal_Bool bWarning = ((lId & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK);
+ sal_uInt16 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)
+ {
+ sal_uInt16 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
+sal_Bool ErrorHandler::GetErrorString(sal_uIntPtr lId, String& rStr)
+{
+ return (sal_Bool)HandleError_Impl( lId, USHRT_MAX, sal_True, rStr );
+}
+
+sal_uInt16 ErrorHandler::HandleError(sal_uIntPtr lId, sal_uInt16 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, sal_False, aDummy );
+}
+
+sal_Bool ErrorHandler::ForwCreateString(const ErrorInfo* pInfo, String& rStr, sal_uInt16 &rFlags) const
+{
+ return ErrHdl_Impl::CreateString(this->pImpl->pNext, pInfo, rStr, rFlags);
+}
+
+sal_Bool ErrHdl_Impl::CreateString( const ErrorHandler *pStart,
+ const ErrorInfo* pInfo, String& pStr,
+ sal_uInt16 &rFlags)
+{
+ for(const ErrorHandler *pHdl=pStart;pHdl;pHdl=pHdl->pImpl->pNext)
+ {
+ if(pHdl->CreateString( pInfo, pStr, rFlags))
+ return sal_True;
+ }
+ return sal_False;
+}
+
+sal_Bool SimpleErrorHandler::CreateString(
+ const ErrorInfo *pInfo, String &rStr, sal_uInt16 &) const
+{
+ sal_uIntPtr 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((sal_uIntPtr)*pDyn);
+ }
+ StandardErrorInfo *pStd=PTR_CAST(StandardErrorInfo,pInfo);
+ if(pStd)
+ {
+ aStr+="\nXId ";
+ aStr+=ByteString::CreateFromInt32(pStd->GetExtendedErrorCode());
+ }
+ rStr = String( aStr, RTL_TEXTENCODING_ASCII_US );
+ return sal_True;
+}
+
+SimpleErrorHandler::SimpleErrorHandler()
+ : ErrorHandler()
+{
+}
+
diff --git a/tools/source/ref/globname.cxx b/tools/source/ref/globname.cxx
new file mode 100755
index 000000000000..0228aeef9e81
--- /dev/null
+++ b/tools/source/ref/globname.cxx
@@ -0,0 +1,453 @@
+/*************************************************************************
+ *
+ * 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 ==()
+*************************************************************************/
+sal_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
+{
+ sal_uInt32 Data1;
+ sal_uInt16 Data2;
+ sal_uInt16 Data3;
+ sal_uInt8 Data4[8];
+};
+SvGlobalName::SvGlobalName( const CLSID & rId )
+{
+ pImp = new ImpSvGlobalName();
+ pImp->nRefCount++;
+ memcpy( pImp->szData, &rId, sizeof( pImp->szData ) );
+}
+
+SvGlobalName::SvGlobalName( sal_uInt32 n1, sal_uInt16 n2, sal_uInt16 n3,
+ sal_uInt8 b8, sal_uInt8 b9, sal_uInt8 b10, sal_uInt8 b11,
+ sal_uInt8 b12, sal_uInt8 b13, sal_uInt8 b14, sal_uInt8 b15 )
+{
+ pImp = new ImpSvGlobalName();
+ pImp->nRefCount++;
+
+ *(sal_uInt32 *)pImp->szData = n1;
+ *(sal_uInt16 *)&pImp->szData[ 4 ] = n2;
+ *(sal_uInt16 *)&pImp->szData[ 6 ] = 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 )
+{
+ rOStr << *(sal_uInt32 *)rObj.pImp->szData;
+ rOStr << *(sal_uInt16 *)&rObj.pImp->szData[ 4 ];
+ rOStr << *(sal_uInt16 *)&rObj.pImp->szData[ 6 ];
+ rOStr.Write( (sal_Char *)&rObj.pImp->szData[ 8 ], 8 );
+ return rOStr;
+}
+
+SvStream& operator >> ( SvStream& rStr, SvGlobalName & rObj )
+{
+ rObj.NewImp(); // kopieren, falls noetig
+ rStr >> *(sal_uInt32 *)rObj.pImp->szData;
+ rStr >> *(sal_uInt16 *)&rObj.pImp->szData[ 4 ];
+ rStr >> *(sal_uInt16 *)&rObj.pImp->szData[ 6 ];
+ rStr.Read( (sal_Char *)&rObj.pImp->szData[ 8 ], 8 );
+ return rStr;
+}
+
+
+/*************************************************************************
+|* SvGlobalName::operator < ()
+*************************************************************************/
+sal_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 sal_True;
+ else if( n > 0 )
+ return sal_False;
+ else if( *(sal_uInt16 *)&pImp->szData[ 4 ] < *(sal_uInt16 *)&rObj.pImp->szData[ 4 ] )
+ return sal_True;
+ else if( *(sal_uInt16 *)&pImp->szData[ 4 ] == *(sal_uInt16 *)&rObj.pImp->szData[ 4 ] )
+ return *(sal_uInt32 *)pImp->szData < *(sal_uInt32 *)rObj.pImp->szData;
+ else
+ return sal_False;
+
+}
+
+/*************************************************************************
+|* SvGlobalName::operator +=()
+*************************************************************************/
+SvGlobalName & SvGlobalName::operator += ( sal_uInt32 n )
+{
+ NewImp();
+ sal_uInt32 nOld = (*(sal_uInt32 *)pImp->szData);
+ (*(sal_uInt32 *)pImp->szData) += n;
+ if( nOld > *(sal_uInt32 *)pImp->szData )
+ // ueberlauf
+ (*(sal_uInt16 *)&pImp->szData[ 4 ])++;
+ return *this;
+}
+
+/*************************************************************************
+|* SvGlobalName::operator ==()
+*************************************************************************/
+sal_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()
+*************************************************************************/
+sal_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 ] )
+ {
+ sal_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 sal_False;
+ pStr++;
+ }
+
+ sal_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 + (sal_uInt16)(toupper( *pStr ) - 'A' + 10 );
+ else
+ return sal_False;
+ pStr++;
+ }
+
+ sal_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 + (sal_uInt16)(toupper( *pStr ) - 'A' + 10 );
+ else
+ return sal_False;
+ pStr++;
+ }
+
+ sal_Int8 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 + (sal_Int8)(toupper( *pStr ) - 'A' + 10 );
+ else
+ return sal_False;
+ pStr++;
+ if( i == 3 )
+ pStr++;
+ }
+
+ NewImp();
+ *(sal_uInt32 *)pImp->szData = nFirst;
+ *(sal_uInt16 *)&pImp->szData[ 4 ] = nSec;
+ *(sal_uInt16 *)&pImp->szData[ 6 ] = nThird;
+ memcpy( &pImp->szData[ 8 ], szRemain, 8 );
+ return sal_True;
+ }
+ return sal_False;
+}
+
+/*************************************************************************
+|* SvGlobalName::GetctorName()
+*************************************************************************/
+String SvGlobalName::GetctorName() const
+{
+ ByteString aRet;
+
+ sal_Char buf[ 20 ];
+ sprintf( buf, "0x%8.8lX", (sal_uIntPtr)*(sal_uInt32 *)pImp->szData );
+ aRet += buf;
+ sal_uInt16 i;
+ for( i = 4; i < 8; i += 2 )
+ {
+ aRet += ',';
+ sprintf( buf, "0x%4.4X", *(sal_uInt16 *)&pImp->szData[ i ] );
+ 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 ];
+ sprintf( buf, "%8.8lX", (sal_uIntPtr)*(sal_uInt32 *)pImp->szData );
+ aRet += buf;
+ aRet += '-';
+ sal_uInt16 i ;
+ for( i = 4; i < 8; i += 2 )
+ {
+ sprintf( buf, "%4.4X", *(sal_uInt16 *)&pImp->szData[ i ] );
+ 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( sal_uIntPtr 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( sal_uLong nPos )
+{
+ return SvGlobalName( (ImpSvGlobalName *)aList.GetObject( nPos ) );
+}
+
+/*************************************************************************
+|* SvGlobalNameList::IsEntry()
+*************************************************************************/
+sal_Bool SvGlobalNameList::IsEntry( const SvGlobalName & rName )
+{
+ for( sal_uIntPtr i = Count(); i > 0; i-- )
+ {
+ if( *rName.pImp == *(ImpSvGlobalName *)aList.GetObject( i -1 ) )
+ return sal_True;
+ }
+ return sal_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 );
+
+ aResult[0] = (sal_Int8) (*(sal_uInt32 *)pImp->szData >> 24);
+ aResult[1] = (sal_Int8) ((*(sal_uInt32 *)pImp->szData << 8 ) >> 24);
+ aResult[2] = (sal_Int8) ((*(sal_uInt32 *)pImp->szData << 16 ) >> 24);
+ aResult[3] = (sal_Int8) ((*(sal_uInt32 *)pImp->szData << 24 ) >> 24);
+ aResult[4] = (sal_Int8) (*(sal_uInt16 *)&pImp->szData[ 4 ] >> 8);
+ aResult[5] = (sal_Int8) ((*(sal_uInt16 *)&pImp->szData[ 4 ] << 8 ) >> 8);
+ aResult[6] = (sal_Int8) (*(sal_uInt16 *)&pImp->szData[ 6 ] >> 8);
+ aResult[7] = (sal_Int8) ((*(sal_uInt16 *)&pImp->szData[ 6 ] << 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 ) );
+}
diff --git a/tools/source/ref/pstm.cxx b/tools/source/ref/pstm.cxx
new file mode 100644
index 000000000000..b2a5600075cc
--- /dev/null
+++ b/tools/source/ref/pstm.cxx
@@ -0,0 +1,915 @@
+/*************************************************************************
+ *
+ * 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( sal_uInt16 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( sal_uInt16 nClassId )
+{
+ Map::const_iterator i(aAssocTable.find(nClassId));
+ return i == aAssocTable.end() ? 0 : i->second;
+}
+
+/****************** SvRttiBase *******************************************/
+TYPEINIT0( SvRttiBase );
+
+/****************** SvPersistBaseMemberList ******************************/
+
+SvPersistBaseMemberList::SvPersistBaseMemberList(){}
+SvPersistBaseMemberList::SvPersistBaseMemberList(
+ sal_uInt16 nInitSz, sal_uInt16 nResize )
+ : SuperSvPersistBaseMemberList( nInitSz, nResize ){}
+
+#define PERSIST_LIST_VER (sal_uInt8)0
+#define PERSIST_LIST_DBGUTIL (sal_uInt8)0x80
+
+/************************************************************************
+|* SvPersistBaseMemberList::WriteOnlyStreamedObjects()
+*************************************************************************/
+void SvPersistBaseMemberList::WriteObjects( SvPersistStream & rStm,
+ sal_Bool bOnlyStreamed ) const
+{
+#ifdef STOR_NO_OPTIMIZE
+ rStm << (sal_uInt8)(PERSIST_LIST_VER | PERSIST_LIST_DBGUTIL);
+ sal_uInt32 nObjPos = rStm.WriteDummyLen();
+#else
+ sal_uInt8 bTmp = PERSIST_LIST_VER;
+ rStm << bTmp;
+#endif
+ sal_uInt32 nCountMember = Count();
+ sal_uIntPtr nCountPos = rStm.Tell();
+ sal_uInt32 nWriteCount = 0;
+ rStm << nCountMember;
+ //bloss die Liste nicht veraendern,
+ //wegen Seiteneffekten beim Save
+ for( sal_uIntPtr 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
+ sal_uIntPtr 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 )
+{
+ sal_uInt8 nVer;
+ rStm >> nVer;
+
+ if( (nVer & ~PERSIST_LIST_DBGUTIL) != PERSIST_LIST_VER )
+ {
+ rStm.SetError( SVSTREAM_GENERALERROR );
+ DBG_ERROR( "persist list, false version" );
+ }
+
+ sal_uInt32 nObjLen(0), nObjPos(0);
+ if( nVer & PERSIST_LIST_DBGUTIL )
+ nObjLen = rStm.ReadLen( &nObjPos );
+
+ sal_uInt32 nCount;
+ rStm >> nCount;
+ for( sal_uIntPtr 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 */
+ sal_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 = sal_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 = sal_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() );
+ }
+}
+
+//=========================================================================
+sal_uInt16 SvPersistStream::IsA() const
+/* [Beschreibung]
+
+ Gibt den Identifier dieses Streamklasse zur"uck.
+
+ [R"uckgabewert]
+
+ sal_uInt16 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()
+*************************************************************************/
+sal_uIntPtr SvPersistStream::GetData( void* pData, sal_uIntPtr nSize )
+{
+ DBG_ASSERT( pStm, "stream not set" );
+ sal_uIntPtr nRet = pStm->Read( pData, nSize );
+ SetError( pStm->GetError() );
+ return nRet;
+}
+
+/*************************************************************************
+|* SvPersistStream::PutData()
+*************************************************************************/
+sal_uIntPtr SvPersistStream::PutData( const void* pData, sal_uIntPtr nSize )
+{
+ DBG_ASSERT( pStm, "stream not set" );
+ sal_uIntPtr nRet = pStm->Write( pData, nSize );
+ SetError( pStm->GetError() );
+ return nRet;
+}
+
+/*************************************************************************
+|* SvPersistStream::Seek()
+*************************************************************************/
+sal_uIntPtr SvPersistStream::SeekPos( sal_uIntPtr nPos )
+{
+ DBG_ASSERT( pStm, "stream not set" );
+ sal_uIntPtr nRet = pStm->Seek( nPos );
+ SetError( pStm->GetError() );
+ return nRet;
+}
+
+/*************************************************************************
+|* SvPersistStream::FlushData()
+*************************************************************************/
+void SvPersistStream::FlushData()
+{
+}
+
+/*************************************************************************
+|* SvPersistStream::GetCurMaxIndex()
+*************************************************************************/
+sal_uIntPtr SvPersistStream::GetCurMaxIndex( const SvPersistUIdx & rIdx ) const
+{
+ // const bekomme ich nicht den hoechsten Index
+ SvPersistUIdx * p = (SvPersistUIdx *)&rIdx;
+ // alten merken
+ sal_uIntPtr nCurIdx = p->GetCurIndex();
+ p->Last();
+ // Bereiche nicht ueberschneiden, deshalb nur groessere Indexe
+ sal_uIntPtr nMaxIdx = p->GetCurIndex();
+ // wieder herstellen
+ p->Seek( nCurIdx );
+ return nMaxIdx;
+}
+
+/*************************************************************************
+|* SvPersistStream::GetIndex()
+*************************************************************************/
+sal_uIntPtr SvPersistStream::GetIndex( SvPersistBase * pObj ) const
+{
+ sal_uIntPtr nId = (sal_uIntPtr)aPTable.Get( (sal_uIntPtr)pObj );
+ if( !nId && pRefStm )
+ return pRefStm->GetIndex( pObj );
+ return nId;
+}
+
+/*************************************************************************
+|* SvPersistStream::GetObject)
+*************************************************************************/
+SvPersistBase * SvPersistStream::GetObject( sal_uIntPtr 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
+sal_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]
+
+ sal_uInt32 Das nicht komprimierte Wort wird zur"uckgegeben.
+
+ [Querverweise]
+
+*/
+{
+ sal_uInt32 nRet(0);
+ sal_uInt8 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;
+ sal_uInt16 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 */
+ sal_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 << (sal_uInt8)(LEN_1 | nVal);
+ else if( nVal < 0x4000 )
+ {
+ rStm << (sal_uInt8)(LEN_2 | (nVal >> 8));
+ rStm << (sal_uInt8)nVal;
+ }
+ else if( nVal < 0x20000000 )
+ {
+ // hoechstes sal_uInt8
+ rStm << (sal_uInt8)(LEN_4 | (nVal >> 24));
+ // 2. hoechstes sal_uInt8
+ rStm << (sal_uInt8)(nVal >> 16);
+ rStm << (sal_uInt16)(nVal);
+ }
+ else
+#endif
+ {
+ rStm << (sal_uInt8)LEN_5;
+ rStm << nVal;
+ }
+}
+
+//=========================================================================
+sal_uInt32 SvPersistStream::WriteDummyLen()
+/* [Beschreibung]
+
+ Die Methode schreibt 4 Byte in den Stream und gibt die Streamposition
+ zur"uck.
+
+ [R"uckgabewert]
+
+ sal_uInt32 Die Position hinter der L"angenangabe wird zur"uckgegeben.
+
+ [Beispiel]
+
+ sal_uInt32 nObjPos = rStm.WriteDummyLen();
+ ...
+ // Daten schreiben
+ ...
+ rStm.WriteLen( nObjPos );
+
+ [Querverweise]
+
+ <SvPersistStream::ReadLen>, <SvPersistStream::WriteLen>
+
+*/
+{
+#ifdef DBG_UTIL
+ sal_uInt32 nPos = Tell();
+#endif
+ sal_uInt32 n0 = 0;
+ *this << n0; // wegen Sun sp
+ // keine Assertion bei Streamfehler
+ DBG_ASSERT( GetError() != SVSTREAM_OK
+ || (sizeof( sal_uInt32 ) == Tell() -nPos),
+ "keine 4-Byte fuer Langenangabe" );
+ return Tell();
+}
+
+//=========================================================================
+void SvPersistStream::WriteLen
+(
+ sal_uInt32 nObjPos /* die Position + 4, an der die L"ange geschrieben
+ wird. */
+)
+/* [Beschreibung]
+
+ Die Methode schreibt die Differenz zwischen der aktuellen und
+ nObjPos als sal_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.
+
+ sal_uInt32 nObjPos = rStm.WriteDummyLen();
+ ...
+ // Daten schreiben
+ ...
+ rStm.WriteLen( nObjPos );
+ // weitere Daten schreiben
+
+ [Querverweise]
+
+ <SvPersistStream::ReadLen>, <SvPersistStream::WriteDummyLen>
+*/
+{
+ sal_uInt32 nPos = Tell();
+ sal_uInt32 nLen = nPos - nObjPos;
+ // die Laenge mu� im stream 4-Byte betragen
+ Seek( nObjPos - sizeof( sal_uInt32 ) );
+ // Laenge schreiben
+ *this << nLen;
+ Seek( nPos );
+}
+
+//=========================================================================
+sal_uInt32 SvPersistStream::ReadLen
+(
+ sal_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.
+*/
+{
+ sal_uInt32 nLen;
+ *this >> nLen;
+ if( pTestPos )
+ *pTestPos = Tell();
+ return nLen;
+}
+
+//=========================================================================
+// Dateirormat abw"arts kompatibel
+#ifdef STOR_NO_OPTIMIZE
+#define P_VER (sal_uInt8)0x00
+#else
+#define P_VER (sal_uInt8)0x01
+#endif
+#define P_VER_MASK (sal_uInt8)0x0F
+#define P_ID_0 (sal_uInt8)0x80
+#define P_OBJ (sal_uInt8)0x40
+#define P_DBGUTIL (sal_uInt8)0x20
+#define P_ID (sal_uInt8)0x10
+#ifdef STOR_NO_OPTIMIZE
+#define P_STD P_DBGUTIL
+#else
+#define P_STD 0
+#endif
+
+static void WriteId
+(
+ SvStream & rStm,
+ sal_uInt8 nHdr,
+ sal_uInt32 nId,
+ sal_uInt16 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 << (sal_uInt8)(nHdr);
+ SvPersistStream::WriteCompressed( rStm, nId );
+ }
+ else
+ { // NULL Pointer
+ rStm << (sal_uInt8)(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,
+ sal_uInt8 & nHdr,
+ sal_uInt32 & nId,
+ sal_uInt16 & 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 = (sal_uInt16)SvPersistStream::ReadCompressed( rStm );
+ }
+}
+
+//=========================================================================
+void SvPersistStream::WriteObj
+(
+ sal_uInt8 nHdr,
+ SvPersistBase * pObj
+)
+{
+#ifdef STOR_NO_OPTIMIZE
+ sal_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
+)
+{
+ sal_uInt8 nP = P_STD;
+
+ if( pObj )
+ {
+ sal_uIntPtr nId = GetIndex( pObj );
+ if( nId )
+ nP |= P_ID;
+ else
+ {
+ nId = aPUIdx.Insert( pObj );
+ aPTable.Insert( (sal_uIntPtr)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;
+}
+
+//=========================================================================
+sal_uInt32 SvPersistStream::ReadObj
+(
+ SvPersistBase * & rpObj,
+ sal_Bool bRegister
+)
+{
+ sal_uInt8 nHdr;
+ sal_uInt32 nId = 0;
+ sal_uInt16 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 );
+
+ sal_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
+ sal_uIntPtr nNewId = aPUIdx.Insert( rpObj );
+ // um den gleichen Zustand, wie nach dem Speichern herzustellen
+ aPTable.Insert( (sal_uIntPtr)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, sal_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 );
+
+ sal_uInt8 bTmp = 0;
+ rThis << bTmp; // Version
+ sal_uInt32 nCount = (sal_uInt32)rThis.aPUIdx.Count();
+ rThis << nCount;
+ SvPersistBase * pEle = rThis.aPUIdx.First();
+ for( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ sal_uInt8 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 );
+
+ sal_uInt8 nVers;
+ rThis >> nVers; // Version
+ if( 0 == nVers )
+ {
+ sal_uInt32 nCount = 0;
+ rThis >> nCount;
+ for( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ SvPersistBase * pEle;
+ // Lesen, ohne in die Tabellen einzutragen
+ sal_uInt32 nId = rThis.ReadObj( pEle, sal_False );
+ if( rThis.GetError() )
+ break;
+
+ // Die Id eines Objektes wird nie modifiziert
+ rThis.aPUIdx.Insert( nId, pEle );
+ rThis.aPTable.Insert( (sal_uIntPtr)pEle, (void *)nId );
+ }
+ }
+ else
+ rThis.SetError( SVSTREAM_FILEFORMAT_ERROR );
+
+ rThis.SetStream( pOldStm );
+ return rStm;
+}
+
+//=========================================================================
+sal_uIntPtr SvPersistStream::InsertObj( SvPersistBase * pObj )
+{
+ sal_uIntPtr nId = aPUIdx.Insert( pObj );
+ aPTable.Insert( (sal_uIntPtr)pObj, (void *)nId );
+ return nId;
+}
+
+//=========================================================================
+sal_uIntPtr SvPersistStream::RemoveObj( SvPersistBase * pObj )
+{
+ sal_uIntPtr nIdx = GetIndex( pObj );
+ aPUIdx.Remove( nIdx );
+ aPTable.Remove( (sal_uIntPtr)pObj );
+ return nIdx;
+}
+
diff --git a/tools/source/ref/ref.cxx b/tools/source/ref/ref.cxx
new file mode 100644
index 000000000000..eeee931f9182
--- /dev/null
+++ b/tools/source/ref/ref.cxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * 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;
+}
+
diff --git a/tools/source/stream/cachestr.cxx b/tools/source/stream/cachestr.cxx
new file mode 100644
index 000000000000..17270048fcf4
--- /dev/null
+++ b/tools/source/stream/cachestr.cxx
@@ -0,0 +1,290 @@
+/*************************************************************************
+ *
+ * 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( sal_uIntPtr nMaxMemSize )
+{
+ if( !nMaxMemSize )
+ nMaxMemSize = 20480;
+ SvStream::bIsWritable = sal_True;
+ nMaxSize = nMaxMemSize;
+ bPersistent = sal_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,
+ sal_uIntPtr nExpectedSize,
+ sal_uIntPtr nMaxMemSize )
+{
+ if( !nMaxMemSize )
+ nMaxMemSize = 20480;
+
+ if( nExpectedSize > nMaxMemSize )
+ nExpectedSize = nMaxMemSize; // oder gleich in File schreiben
+ else if( !nExpectedSize )
+ nExpectedSize = 4096;
+
+ SvStream::bIsWritable = sal_True;
+ nMaxSize = nMaxMemSize;
+ bPersistent = sal_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( sal_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();
+ }
+ }
+
+ sal_uIntPtr 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
+|*
+*************************************************************************/
+
+sal_uIntPtr SvCacheStream::GetData( void* pData, sal_uIntPtr nSize )
+{
+ return pCurrentStream->Read( pData, nSize );
+}
+
+/*************************************************************************
+|*
+|* SvCacheStream::PutData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 27.09.94
+|* Letzte Aenderung OV 27.09.94
+|*
+*************************************************************************/
+
+sal_uIntPtr SvCacheStream::PutData( const void* pData, sal_uIntPtr 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
+|*
+*************************************************************************/
+
+sal_uIntPtr SvCacheStream::SeekPos( sal_uIntPtr 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( sal_uIntPtr nSize )
+{
+ pCurrentStream->SetStreamSize( nSize );
+}
+
+/*************************************************************************
+|*
+|* SvCacheStream::GetSize()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 27.09.94
+|* Letzte Aenderung OV 27.09.94
+|*
+*************************************************************************/
+
+sal_uIntPtr SvCacheStream::GetSize()
+{
+ // ACHTUNG: SvMemoryStream::GetSize() gibt Groesse
+ // des allozierten Buffers zurueck
+ Flush();
+ sal_uIntPtr nTemp = Tell();
+ sal_uIntPtr 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;
+}
diff --git a/tools/source/stream/stream.cxx b/tools/source/stream/stream.cxx
new file mode 100755
index 000000000000..5d0da0f3e29d
--- /dev/null
+++ b/tools/source/stream/stream.cxx
@@ -0,0 +1,2879 @@
+/*************************************************************************
+ *
+ * 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 )
+ {
+ *((sal_uInt32*)(void*)&r) = SWAPLONG( *((sal_uInt32*)(void*)&r) );
+ }
+inline static void SwapDouble( double& r )
+ {
+ if( sizeof(double) != 8 )
+ {
+ DBG_ASSERT( sal_False, "Can only swap 8-Byte-doubles\n" );
+ }
+ else
+ {
+ sal_uInt32* c = (sal_uInt32*)(void*)&r;
+ c[0] ^= c[1]; // zwei 32-Bit-Werte in situ vertauschen
+ c[1] ^= c[0];
+ c[0] ^= c[1];
+ c[0] = SWAPLONG(c[0]); // und die beiden 32-Bit-Werte selbst in situ drehen
+ c[1] = SWAPLONG(c[1]);
+ }
+ }
+#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 = sal_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 = sal_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 = sal_False;
+ bIsConsistent = sal_True;
+ bIsWritable = sal_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 = sal_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 = sal_False;
+#ifdef OSL_BIGENDIAN
+ if( nNumberFormatInt == NUMBERFORMAT_INT_LITTLEENDIAN )
+ bSwap = sal_True;
+#else
+ if( nNumberFormatInt == NUMBERFORMAT_INT_BIGENDIAN )
+ bSwap = sal_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 sal_uInt8[ nBufSize ];
+ bIsConsistent = sal_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 = sal_False;
+ bIsConsistent = sal_True;
+ eIOMode = STREAM_IO_DONTKNOW;
+
+ bIsEof = sal_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 = sal_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 = sal_True;
+ return sal_False;
+ }
+ else
+ break;
+ }
+
+ sal_uInt16 j, n;
+ for( j = n = 0; j < nLen ; ++j )
+ {
+ c = buf[j];
+ if ( c == '\n' || c == '\r' )
+ {
+ bEnd = sal_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 = sal_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 = sal_False;
+ return bEnd;
+}
+
+sal_Bool SvStream::ReadUniStringLine( String& rStr )
+{
+ sal_Unicode buf[256+1];
+ sal_Bool bEnd = sal_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 = sal_True;
+ return sal_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 = sal_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 = sal_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 = sal_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 = sal_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( sal_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( rtl_TextEncoding eReadBomCharSet )
+{
+ if (!( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
+ eReadBomCharSet == RTL_TEXTENCODING_UNICODE ||
+ eReadBomCharSet == RTL_TEXTENCODING_UTF8))
+ return sal_True; // nothing to read
+
+ bool bTryUtf8 = false;
+ sal_uInt16 nFlag;
+ sal_sSize nBack = sizeof(nFlag);
+ *this >> nFlag;
+ switch ( nFlag )
+ {
+ case 0xfeff :
+ // native UTF-16
+ if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
+ eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
+ nBack = 0;
+ break;
+ case 0xfffe :
+ // swapped UTF-16
+ if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
+ eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
+ {
+ SetEndianSwap( !bSwap );
+ nBack = 0;
+ }
+ break;
+ case 0xefbb :
+ if (nNumberFormatInt == NUMBERFORMAT_INT_BIGENDIAN &&
+ (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
+ eReadBomCharSet == RTL_TEXTENCODING_UTF8))
+ bTryUtf8 = true;
+ break;
+ case 0xbbef :
+ if (nNumberFormatInt == NUMBERFORMAT_INT_LITTLEENDIAN &&
+ (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
+ eReadBomCharSet == RTL_TEXTENCODING_UTF8))
+ bTryUtf8 = true;
+ break;
+ default:
+ ; // nothing
+ }
+ if (bTryUtf8)
+ {
+ sal_uChar nChar;
+ nBack += sizeof(nChar);
+ *this >> nChar;
+ if (nChar == 0xbf)
+ nBack = 0; // it is UTF-8
+ }
+ if (nBack)
+ SeekRel( -nBack ); // 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 = sal_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 = sal_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 = sal_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 = sal_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 = sal_False;
+ nBufFree = nBufActualLen - nBufActualPos;
+ if( nCount != nSaveCount && nError != ERRCODE_IO_PENDING )
+ bIsEof = sal_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 = sal_True;
+ }
+ else
+ {
+ // Flushen ?
+ if( bIsDirty )
+ {
+ SeekPos( nBufFilePos );
+ if( nCryptMask )
+ CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
+ else
+ PutData( pRWBuf, nBufActualLen );
+ bIsDirty = sal_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 = sal_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 = sal_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 = sal_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 = sal_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 = sal_False;
+ }
+ bIsConsistent = sal_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 = sal_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 = sal_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 = sal_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 = sal_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 = sal_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 = sal_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 sal_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 = sal_True;
+ else
+ bIsWritable = sal_False;
+ nEndOfData = bufSize;
+ bOwnsData = sal_False;
+ pBuf = (sal_uInt8 *) 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 = sal_True;
+ bOwnsData = sal_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 = (sal_uInt8 *) 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 sal_uInt8[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 = sal_False;
+ long nTemp = (long)nSize;
+ nTemp += nDiff;
+ sal_Size nNewSize = (sal_Size)nTemp;
+
+ if( nNewSize )
+ {
+ sal_uInt8* pNewBuf = new sal_uInt8[nNewSize];
+
+ if( pNewBuf )
+ {
+ bRetVal = sal_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 = sal_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& )
+{
+}
diff --git a/tools/source/stream/strmos2.cxx b/tools/source/stream/strmos2.cxx
new file mode 100644
index 000000000000..bfe1f9750f4d
--- /dev/null
+++ b/tools/source/stream/strmos2.cxx
@@ -0,0 +1,758 @@
+/*************************************************************************
+ *
+ * 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
+#ifndef _OSL_FILE_HXX_
+#include <osl/file.hxx>
+#endif
+
+using namespace osl;
+
+// -----------------------------------------------------------------------
+
+// --------------
+// - StreamData -
+// --------------
+
+class StreamData
+{
+public:
+ HFILE hFile;
+ sal_Bool bIsEof;
+
+ StreamData()
+ {
+ hFile = 0;
+ bIsEof = sal_True;
+ }
+};
+
+// -----------------------------------------------------------------------
+
+sal_uIntPtr GetSvError( APIRET nPMError )
+{
+ static struct { APIRET pm; sal_uIntPtr 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 }
+ };
+
+ sal_uIntPtr 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 = sal_False;
+ nLockCounter = 0;
+ bIsWritable = sal_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 = sal_False;
+ nLockCounter = 0;
+ bIsWritable = sal_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
+|*
+*************************************************************************/
+
+sal_uIntPtr SvFileStream::GetFileHandle() const
+{
+ return (sal_uIntPtr)pInstanceData->hFile;
+}
+
+/*************************************************************************
+|*
+|* 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, Prueft nicht Eof; IsEof danach rufbar
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+sal_uIntPtr SvFileStream::GetData( void* pData, sal_uIntPtr 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
+
+ sal_uIntPtr 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
+|*
+*************************************************************************/
+
+sal_uIntPtr SvFileStream::PutData( const void* pData, sal_uIntPtr 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
+
+ sal_uIntPtr 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
+|*
+*************************************************************************/
+
+sal_uIntPtr SvFileStream::SeekPos( sal_uIntPtr nPos )
+{
+ sal_uIntPtr 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
+|*
+*************************************************************************/
+/*
+sal_uIntPtr SvFileStream::Tell()
+{
+ sal_uIntPtr 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( sal_uIntPtr nByteOffset, sal_uIntPtr nBytes )
+{
+ sal_Bool bRetVal = sal_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 = sal_True;
+ }
+ return bRetVal;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::UnlockRange()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvFileStream::UnlockRange( sal_uIntPtr nByteOffset, sal_uIntPtr nBytes )
+{
+ sal_Bool bRetVal = sal_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 = sal_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 = sal_False;
+ if( !nLockCounter )
+ {
+ if( LockRange( 0L, LONG_MAX ) )
+ {
+ nLockCounter = 1;
+ bRetVal = sal_True;
+ }
+ }
+ else
+ {
+ nLockCounter++;
+ bRetVal = sal_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 = sal_False;
+ if( nLockCounter > 0)
+ {
+ if( nLockCounter == 1)
+ {
+ if( UnlockRange( 0L, LONG_MAX ) )
+ {
+ nLockCounter = 0;
+ bRetVal = sal_True;
+ }
+ }
+ else
+ {
+ nLockCounter--;
+ bRetVal = sal_True;
+ }
+ }
+ return bRetVal;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::Open()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+
+#if 0
+sal_Bool createLongNameEA ( const PCSZ pszPath, sal_uIntPtr ulAttributes, const String& aLongName );
+#endif
+
+void SvFileStream::Open( const String& rFilename, StreamMode nOpenMode )
+{
+ String aParsedFilename;
+
+#if 0
+ if ( Folder::IsAvailable() && (rFilename.Search('{') < 9) )
+ {
+ String aVirtualPart;
+ String aRealPart;
+ String aVirtualPath;
+ ItemIDPath aVirtualURL;
+ sal_uIntPtr nDivider = 0;
+
+ String aVirtualString(rFilename);
+
+ for (int x=aVirtualString.Len(); x>0; x--)
+ {
+ if (aVirtualString.Copy(x,1).Compare("}")==COMPARE_EQUAL)
+ {
+ nDivider = x;
+ break;
+ }
+ }
+
+ aVirtualPart = aVirtualString.Copy(0,nDivider+1);
+ aRealPart = aVirtualString.Copy(nDivider+2);
+
+ aVirtualURL = aVirtualPart;
+ aVirtualPath = aVirtualURL.GetHostNotationPath();
+
+ DirEntry aTempDirEntry(aVirtualPath);
+
+ aTempDirEntry += aRealPart;
+
+ aParsedFilename = aTempDirEntry.GetFull();
+ }
+ else
+#endif // 0
+ {
+ aParsedFilename = rFilename;
+ }
+
+ Close();
+ SvStream::ClearBuffer();
+
+ sal_uIntPtr nActionTaken;
+ sal_uIntPtr nOpenAction = 0L;
+ sal_uIntPtr nShareBits = 0L;
+ sal_uIntPtr 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;
+ }
+
+#if 0 // YD
+ //
+ // resolves long FAT names used by OS2
+ //
+ sal_Bool bIsLongOS2=sal_False;
+ if (Folder::IsAvailable())
+ {
+ DirEntry aDirEntry(rFilename);
+ if (aDirEntry.IsLongNameOnFAT())
+ {
+ // in kurzen Pfad wandeln
+ ItemIDPath aItemIDPath(rFilename);
+ aParsedFilename = aItemIDPath.GetHostNotationPath();
+ bIsLongOS2 = sal_True;
+ }
+ }
+#endif
+
+ 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;
+ sal_uIntPtr 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 = sal_False;
+ SetError(::GetSvError(nRet) );
+ }
+ else
+ {
+ bIsOpen = sal_True;
+ pInstanceData->bIsEof = sal_False;
+ if( nReadWriteBits != OPEN_ACCESS_READONLY )
+ bIsWritable = sal_True;
+ }
+
+#if 0
+ if (bIsOpen && bIsLongOS2)
+ {
+ //file schließen, da sonst createLongName u.U. nicht möglich
+ Close();
+
+ // erzeugtem File langen Namen geben
+ DirEntry aDirEntry(rFilename);
+ createLongNameEA(aFileNameA.GetBuffer(), FILE_NORMAL, aDirEntry.GetName());
+
+ // und wieder oeffnen
+ ReOpen();
+ }
+#endif
+
+}
+
+/*************************************************************************
+|*
+|* 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 = sal_False;
+ nLockCounter= 0;
+ bIsWritable = sal_False;
+ pInstanceData->bIsEof = sal_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( sal_uIntPtr nSize )
+{
+ if( IsOpen() )
+ {
+ APIRET nRet = DosSetFileSize( pInstanceData->hFile, nSize );
+ if( nRet )
+ SetError( ::GetSvError( nRet ) );
+ }
+}
diff --git a/tools/source/stream/strmsys.cxx b/tools/source/stream/strmsys.cxx
new file mode 100644
index 000000000000..a373ad985214
--- /dev/null
+++ b/tools/source/stream/strmsys.cxx
@@ -0,0 +1,37 @@
+/*************************************************************************
+ *
+ * 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
diff --git a/tools/source/stream/strmunx.cxx b/tools/source/stream/strmunx.cxx
new file mode 100644
index 000000000000..87e3cea4c0c7
--- /dev/null
+++ b/tools/source/stream/strmunx.cxx
@@ -0,0 +1,920 @@
+/*************************************************************************
+ *
+ * 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 <vos/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< vos::OMutex, 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
+ vos:: OGuard 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( sal_uIntPtr 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
+ vos:: OGuard aGuard( LockMutex::get() );
+#endif
+ InternalStreamLock* pLock = NULL;
+ InternalStreamLockList &rLockList = LockList::get();
+ if( nStart == 0 && nEnd == 0 )
+ {
+ for( sal_uIntPtr i = 0; i < rLockList.Count(); ++i )
+ {
+ if( ( pLock = rLockList.GetObject( i ) )->m_pStream == pStream )
+ {
+ delete pLock;
+ i--;
+ }
+ }
+ return;
+ }
+ for( sal_uIntPtr 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(__FreeBSD_kernel__)
+ { 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(__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;
+ }
+ }
+ }
+}
+
+
diff --git a/tools/source/stream/strmwnt.cxx b/tools/source/stream/strmwnt.cxx
new file mode 100644
index 000000000000..20443e268964
--- /dev/null
+++ b/tools/source/stream/strmwnt.cxx
@@ -0,0 +1,689 @@
+/*************************************************************************
+ *
+ * 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 sal_uIntPtr GetSvError( DWORD nWntError )
+{
+ static struct { DWORD wnt; sal_uIntPtr 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 }
+ };
+
+ sal_uIntPtr 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 = sal_False;
+ nLockCounter = 0;
+ bIsWritable = sal_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 = sal_False;
+ nLockCounter = 0;
+ bIsWritable = sal_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
+|*
+*************************************************************************/
+
+sal_uIntPtr SvFileStream::GetFileHandle() const
+{
+ return (sal_uIntPtr)pInstanceData->hFile;
+}
+
+/*************************************************************************
+|*
+|* 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, Prueft nicht Eof; IsEof danach rufbar
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung TPF 15.07.98
+|*
+*************************************************************************/
+
+sal_uIntPtr SvFileStream::GetData( void* pData, sal_uIntPtr nSize )
+{
+ DWORD nCount = 0;
+ if( IsOpen() )
+ {
+ bool bResult = ReadFile(pInstanceData->hFile,(LPVOID)pData,nSize,&nCount,NULL);
+ if( !bResult )
+ {
+ sal_uIntPtr nTestError = GetLastError();
+ SetError(::GetSvError( nTestError ) );
+ }
+ }
+ return (DWORD)nCount;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::PutData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung TPF 15.07.98
+|*
+*************************************************************************/
+
+sal_uIntPtr SvFileStream::PutData( const void* pData, sal_uIntPtr 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
+|*
+*************************************************************************/
+
+sal_uIntPtr SvFileStream::SeekPos( sal_uIntPtr 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 (sal_uIntPtr)nNewPos;
+}
+
+/*************************************************************************
+|*
+|* SvFileStream::Tell()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 15.06.94
+|* Letzte Aenderung OV 15.06.94
+|*
+*************************************************************************/
+/*
+sal_uIntPtr SvFileStream::Tell()
+{
+ sal_uIntPtr 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
+|*
+*************************************************************************/
+
+sal_Bool SvFileStream::LockRange( sal_uIntPtr nByteOffset, sal_uIntPtr 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
+|*
+*************************************************************************/
+
+sal_Bool SvFileStream::UnlockRange( sal_uIntPtr nByteOffset, sal_uIntPtr 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
+|*
+*************************************************************************/
+
+sal_Bool SvFileStream::LockFile()
+{
+ sal_Bool bRetVal = sal_False;
+ if( !nLockCounter )
+ {
+ if( LockRange( 0L, LONG_MAX ) )
+ {
+ nLockCounter = 1;
+ bRetVal = sal_True;
+ }
+ }
+ else
+ {
+ nLockCounter++;
+ bRetVal = sal_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 = sal_False;
+ if( nLockCounter > 0)
+ {
+ if( nLockCounter == 1)
+ {
+ if( UnlockRange( 0L, LONG_MAX ) )
+ {
+ nLockCounter = 0;
+ bRetVal = sal_True;
+ }
+ }
+ else
+ {
+ nLockCounter--;
+ bRetVal = sal_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))
+ {
+ sal_uIntPtr 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 = sal_False;
+ SetError(::GetSvError( GetLastError() ) );
+ }
+ else
+ {
+ bIsOpen = sal_True;
+ // pInstanceData->bIsEof = sal_False;
+ if( nAccessMode & GENERIC_WRITE )
+ bIsWritable = sal_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 = sal_False;
+ nLockCounter= 0;
+ 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 19.10.95
+|* Letzte Aenderung TPF 15.07.98
+|*
+*************************************************************************/
+
+void SvFileStream::SetSize( sal_uIntPtr nSize )
+{
+
+ if( IsOpen() )
+ {
+ int bError = sal_False;
+ HANDLE hFile = pInstanceData->hFile;
+ sal_uIntPtr 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 = sal_True;
+ }
+ if( SetFilePointer( hFile,nOld,NULL,FILE_BEGIN ) == 0xffffffff)
+ bError = sal_True;
+ }
+ if( bError )
+ SetError(::GetSvError( GetLastError() ) );
+ }
+}
+
diff --git a/tools/source/stream/vcompat.cxx b/tools/source/stream/vcompat.cxx
new file mode 100644
index 000000000000..fcbab9b98826
--- /dev/null
+++ b/tools/source/stream/vcompat.cxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * 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, sal_uInt16 nStreamMode, sal_uInt16 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 sal_uInt32 nEndPos = mpRWStm->Tell();
+
+ mpRWStm->Seek( mnCompatPos );
+ *mpRWStm << ( nEndPos - mnTotalSize );
+ mpRWStm->Seek( nEndPos );
+ }
+ else
+ {
+ const sal_uInt32 nReadSize = mpRWStm->Tell() - mnCompatPos;
+
+ if( mnTotalSize > nReadSize )
+ mpRWStm->SeekRel( mnTotalSize - nReadSize );
+ }
+}
diff --git a/tools/source/string/debugprint.cxx b/tools/source/string/debugprint.cxx
new file mode 100644
index 000000000000..7acff963b1b9
--- /dev/null
+++ b/tools/source/string/debugprint.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// 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));
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/tools/source/string/strascii.cxx b/tools/source/string/strascii.cxx
new file mode 100644
index 000000000000..e47517d93412
--- /dev/null
+++ b/tools/source/string/strascii.cxx
@@ -0,0 +1,637 @@
+#/*************************************************************************
+ *
+ * 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 sal_Bool ImplDbgCheckAsciiStr( const sal_Char* pAsciiStr, sal_Int32 nLen )
+{
+ while ( nLen && *pAsciiStr )
+ {
+ if ( ((unsigned char)*pAsciiStr) > 127 )
+ return sal_False;
+ ++pAsciiStr,
+ --nLen;
+ }
+
+ return sal_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;
+}
+
+// -----------------------------------------------------------------------
+
+sal_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);
+}
+
+// -----------------------------------------------------------------------
+
+sal_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);
+}
+
+// -----------------------------------------------------------------------
+
+sal_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);
+}
+
+// -----------------------------------------------------------------------
+
+sal_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 );
+ }
+}
diff --git a/tools/source/string/strcvt.cxx b/tools/source/string/strcvt.cxx
new file mode 100644
index 000000000000..ce5c7ecdcad0
--- /dev/null
+++ b/tools/source/string/strcvt.cxx
@@ -0,0 +1,613 @@
+/*************************************************************************
+ *
+ * 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,
+ sal_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, sal_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, sal_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,
+ sal_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, sal_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,
+ sal_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;
+}
diff --git a/tools/source/string/strimp.cxx b/tools/source/string/strimp.cxx
new file mode 100644
index 000000000000..8712733c0851
--- /dev/null
+++ b/tools/source/string/strimp.cxx
@@ -0,0 +1,2115 @@
+/*************************************************************************
+ *
+ * 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
+ sal_Bool bConvert = sal_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 = sal_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;
+}
+
+// -----------------------------------------------------------------------
+
+sal_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 sal_True;
+
+ // Gleiche Laenge
+ if ( mpData->mnLen != rStr.mpData->mnLen )
+ return sal_False;
+
+ // String vergleichen
+ return (ImplStringCompareWithoutZero( mpData->maStr, rStr.mpData->maStr, mpData->mnLen ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool STRING::Equals( const STRCODE* pCharStr ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ return (ImplStringCompare( mpData->maStr, pCharStr ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+sal_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 sal_True;
+
+ // Gleiche Laenge
+ if ( mpData->mnLen != rStr.mpData->mnLen )
+ return sal_False;
+
+ // String vergleichen
+ return (ImplStringICompareWithoutZero( mpData->maStr, rStr.mpData->maStr, mpData->mnLen ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool STRING::EqualsIgnoreCaseAscii( const STRCODE* pCharStr ) const
+{
+ DBG_CHKTHIS( STRING, DBGCHECKSTRING );
+
+ return (ImplStringICompare( mpData->maStr, pCharStr ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+sal_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 sal_False;
+ nLen = static_cast< xub_StrLen >(nMaxLen);
+ }
+
+ // String vergleichen
+ return (ImplStringCompareWithoutZero( mpData->maStr+nIndex, rStr.mpData->maStr, nLen ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+sal_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);
+}
+
+// -----------------------------------------------------------------------
+
+sal_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 sal_False;
+ nLen = static_cast< xub_StrLen >(nMaxLen);
+ }
+
+ // String vergleichen
+ return (ImplStringICompareWithoutZero( mpData->maStr+nIndex, rStr.mpData->maStr, nLen ) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+sal_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;
+}
diff --git a/tools/source/string/strucvt.cxx b/tools/source/string/strucvt.cxx
new file mode 100644
index 000000000000..9c9ef1dc4b5a
--- /dev/null
+++ b/tools/source/string/strucvt.cxx
@@ -0,0 +1,213 @@
+/*************************************************************************
+ *
+ * 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 );
+}
+
diff --git a/tools/source/string/tenccvt.cxx b/tools/source/string/tenccvt.cxx
new file mode 100644
index 000000000000..f1f023a90502
--- /dev/null
+++ b/tools/source/string/tenccvt.cxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * 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, sal_uInt16 /* nVersion = SOFFICE_FILEFORMAT_50 */ )
+{
+ return GetExtendedCompatibilityTextEncoding( GetOneByteTextEncoding( eEncoding ) );
+}
+
+// -----------------------------------------------------------------------
+
+rtl_TextEncoding GetSOStoreTextEncoding( rtl_TextEncoding eEncoding, sal_uInt16 /* nVersion = SOFFICE_FILEFORMAT_50 */ )
+{
+ return GetExtendedTextEncoding( GetOneByteTextEncoding( eEncoding ) );
+}
diff --git a/tools/source/string/tstring.cxx b/tools/source/string/tstring.cxx
new file mode 100644
index 000000000000..734e729ceccb
--- /dev/null
+++ b/tools/source/string/tstring.cxx
@@ -0,0 +1,295 @@
+/*************************************************************************
+ *
+ * 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"
+#ifndef _OSL_INTERLCK_H
+#include <osl/interlck.h>
+#endif
+#ifndef _RTL_ALLOC_H
+#include <rtl/alloc.h>
+#endif
+#ifndef _RTL_MEMORY_H
+#include <rtl/memory.h>
+#endif
+#include <rtl/tencinfo.h>
+#include <rtl/instance.hxx>
+
+#include <tools/string.hxx>
+#include <impstrg.hxx>
+
+// For shared byte convert tables
+#ifndef _TOOLS_TOOLSIN_HXX
+#include <toolsin.hxx>
+#endif
+
+#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;
+}
+
+// -----------------------------------------------------------------------
+
+sal_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 sal_False;
+
+ ++pStr,
+ ++nIndex;
+ }
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+sal_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 sal_False;
+
+ ++pStr,
+ ++nIndex;
+ }
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+sal_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 sal_False;
+
+ ++pStr,
+ ++nIndex;
+ }
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+sal_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 sal_False;
+
+ ++pStr,
+ ++nIndex;
+ }
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+sal_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 sal_False;
+
+ ++pStr,
+ ++nIndex;
+ }
+
+ return sal_True;
+}
diff --git a/tools/source/string/tustring.cxx b/tools/source/string/tustring.cxx
new file mode 100644
index 000000000000..27dab841124d
--- /dev/null
+++ b/tools/source/string/tustring.cxx
@@ -0,0 +1,162 @@
+/*************************************************************************
+ *
+ * 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"
+
+#ifndef _OSL_INTERLCK_H
+#include <osl/interlck.h>
+#endif
+#ifndef _RTL_ALLOC_H
+#include <rtl/alloc.h>
+#endif
+#ifndef _RTL_MEMORY_H
+#include <rtl/memory.h>
+#endif
+#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 );
+}
+
diff --git a/tools/source/testtoolloader/testtoolloader.cxx b/tools/source/testtoolloader/testtoolloader.cxx
new file mode 100644
index 000000000000..59be94a02f4c
--- /dev/null
+++ b/tools/source/testtoolloader/testtoolloader.cxx
@@ -0,0 +1,185 @@
+/*************************************************************************
+ *
+ * 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 <vos/process.hxx>
+#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()
+{
+ vos:: OStartupInfo aStartInfo;
+ return aStartInfo.getCommandArgCount();
+}
+
+String GetCommandLineParam( sal_uInt32 nParam )
+{
+ vos:: OStartupInfo aStartInfo;
+ ::rtl::OUString aParam;
+ vos:: OStartupInfo ::TStartupError eError = aStartInfo.getCommandArg( nParam, aParam );
+ if ( eError == vos:: OStartupInfo ::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 = sal_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 = sal_False;
+ }
+ }
+
+ osl_unloadModule( aTestToolModule );
+ }
+}
+
+} // namespace tools
diff --git a/tools/source/zcodec/zcodec.cxx b/tools/source/zcodec/zcodec.cxx
new file mode 100644
index 000000000000..cf62c02e0c29
--- /dev/null
+++ b/tools/source/zcodec/zcodec.cxx
@@ -0,0 +1,488 @@
+/*************************************************************************
+ *
+ * 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( sal_uIntPtr nInBufSize, sal_uIntPtr nOutBufSize, sal_uIntPtr 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( sal_uIntPtr nCompressMethod )
+{
+ mbInit = 0;
+ mbStatus = sal_True;
+ mbFinish = sal_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( sal_False );
+ mpInBuf = new sal_uInt8[ 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 = sal_False;
+ break;
+ }
+ };
+ return ( mbStatus ) ? (long)(PZSTREAM->total_in - nOldTotal_In) : -1;
+}
+
+// ------------------------------------------------------------------------
+
+long ZCodec::Decompress( SvStream& rIStm, SvStream& rOStm )
+{
+ int err;
+ sal_uIntPtr nInToRead;
+ long nOldTotal_Out = PZSTREAM->total_out;
+
+ if ( mbFinish )
+ return PZSTREAM->total_out - nOldTotal_Out;
+
+ if ( mbInit == 0 )
+ {
+ mpIStm = &rIStm;
+ mpOStm = &rOStm;
+ ImplInitBuf( sal_True );
+ PZSTREAM->next_out = mpOutBuf = new sal_uInt8[ 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 = sal_False;
+ break;
+ }
+
+ }
+ while ( ( err != Z_STREAM_END) && ( PZSTREAM->avail_in || mnInToRead ) );
+ ImplWriteBack();
+
+ if ( err == Z_STREAM_END )
+ mbFinish = sal_True;
+ return ( mbStatus ) ? (long)(PZSTREAM->total_out - nOldTotal_Out) : -1;
+}
+
+// ------------------------------------------------------------------------
+
+long ZCodec::Write( SvStream& rOStm, const sal_uInt8* pData, sal_uIntPtr nSize )
+{
+ if ( mbInit == 0 )
+ {
+ mpOStm = &rOStm;
+ ImplInitBuf( sal_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 = sal_False;
+ break;
+ }
+ }
+ return ( mbStatus ) ? (long)nSize : -1;
+}
+
+// ------------------------------------------------------------------------
+
+long ZCodec::Read( SvStream& rIStm, sal_uInt8* pData, sal_uIntPtr nSize )
+{
+ int err;
+ sal_uIntPtr nInToRead;
+
+ if ( mbFinish )
+ return 0; // PZSTREAM->total_out;
+
+ mpIStm = &rIStm;
+ if ( mbInit == 0 )
+ {
+ ImplInitBuf( sal_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 = sal_True;
+
+ return (mbStatus ? (long)(nSize - PZSTREAM->avail_out) : -1);
+}
+
+// ------------------------------------------------------------------------
+
+long ZCodec::ReadAsynchron( SvStream& rIStm, sal_uInt8* pData, sal_uIntPtr nSize )
+{
+ int err = 0;
+ sal_uIntPtr nInToRead;
+
+ if ( mbFinish )
+ return 0; // PZSTREAM->total_out;
+
+ if ( mbInit == 0 )
+ {
+ mpIStm = &rIStm;
+ ImplInitBuf( sal_True );
+ }
+ PZSTREAM->avail_out = nSize;
+ PZSTREAM->next_out = pData;
+ do
+ {
+ if ( PZSTREAM->avail_in == 0 && mnInToRead )
+ {
+ nInToRead = (mnInBufSize > mnInToRead) ? mnInToRead : mnInBufSize;
+
+ sal_uIntPtr nStreamPos = rIStm.Tell();
+ rIStm.Seek( STREAM_SEEK_TO_END );
+ sal_uIntPtr 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 = sal_True;
+
+ return (mbStatus ? (long)(nSize - PZSTREAM->avail_out) : -1);
+}
+
+// ------------------------------------------------------------------------
+
+void ZCodec::ImplWriteBack()
+{
+ sal_uIntPtr 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( sal_uIntPtr nInToRead )
+{
+ mnInToRead = nInToRead;
+}
+
+// ------------------------------------------------------------------------
+
+sal_uIntPtr ZCodec::GetBreak( void )
+{
+ return ( mnInToRead + PZSTREAM->avail_in );
+}
+
+// ------------------------------------------------------------------------
+
+void ZCodec::SetCRC( sal_uIntPtr nCRC )
+{
+ mnCRC = nCRC;
+}
+
+// ------------------------------------------------------------------------
+
+sal_uIntPtr ZCodec::GetCRC()
+{
+ return mnCRC;
+}
+
+// ------------------------------------------------------------------------
+
+void ZCodec::ImplInitBuf ( sal_Bool nIOFlag )
+{
+ if ( mbInit == 0 )
+ {
+ if ( nIOFlag )
+ {
+ mbInit = 1;
+ if ( mbStatus && ( mnCompressMethod & ZCODEC_GZ_LIB ) )
+ {
+ sal_uInt8 n1, n2, j, nMethod, nFlags;
+ for ( int i = 0; i < 2; i++ ) // gz - magic number
+ {
+ *mpIStm >> j;
+ if ( j != gz_magic[ i ] )
+ mbStatus = sal_False;
+ }
+ *mpIStm >> nMethod;
+ *mpIStm >> nFlags;
+ if ( nMethod != Z_DEFLATED )
+ mbStatus = sal_False;
+ if ( ( nFlags & GZ_RESERVED ) != 0 )
+ mbStatus = sal_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 ) ? sal_False : sal_True;
+ }
+ else
+ {
+ mbStatus = ( inflateInit( PZSTREAM ) >= 0 );
+ }
+ mpInBuf = new sal_uInt8[ 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 sal_uInt8[ PZSTREAM->avail_out = mnOutBufSize ];
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+sal_uIntPtr ZCodec::UpdateCRC ( sal_uIntPtr nLatestCRC, sal_uIntPtr nNumber )
+{
+
+#ifdef OSL_LITENDIAN
+ nNumber = SWAPLONG( nNumber );
+#endif
+ return rtl_crc32( nLatestCRC, &nNumber, 4 );
+}
+
+// ------------------------------------------------------------------------
+
+sal_uIntPtr ZCodec::UpdateCRC ( sal_uIntPtr nLatestCRC, sal_uInt8* pSource, long nDatSize)
+{
+ return rtl_crc32( nLatestCRC, pSource, nDatSize );
+}
+
+// ------------------------------------------------------------------------
+
+void GZCodec::BeginCompression( sal_uIntPtr nCompressMethod )
+{
+ ZCodec::BeginCompression( nCompressMethod | ZCODEC_GZ_LIB );
+};
+
+
diff --git a/tools/test/export.map b/tools/test/export.map
new file mode 100644
index 000000000000..7321bbca16ad
--- /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:
+ registerAllTestFunction;
+
+ local:
+ *;
+};
diff --git a/tools/test/tests.cxx b/tools/test/tests.cxx
new file mode 100644
index 000000000000..5a1e21f172a4
--- /dev/null
+++ b/tools/test/tests.cxx
@@ -0,0 +1,126 @@
+/*************************************************************************
+ *
+ * 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 <testshl/simpleheader.hxx>
+#include <rtl/math.hxx>
+#include <tools/fract.hxx>
+
+#include <stdio.h>
+
+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_NAMED_REGISTRATION(tools::FractionTest, "FractionTest");
+} // namespace tools
+
+
+// -----------------------------------------------------------------------------
+
+// this macro creates an empty function, which will called by the RegisterAllFunctions()
+// to let the user the possibility to also register some functions by hand.
+NOADDITIONAL;
+
diff --git a/tools/unx/source/dll/toolsdll.cxx b/tools/unx/source/dll/toolsdll.cxx
new file mode 100644
index 000000000000..c008cbbc001c
--- /dev/null
+++ b/tools/unx/source/dll/toolsdll.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// 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( sal_uInt16 nSharedLib )
+{
+ return &(aAppData[nSharedLib]);
+}
diff --git a/tools/win/inc/dll.hxx b/tools/win/inc/dll.hxx
new file mode 100644
index 000000000000..f28b07974c61
--- /dev/null
+++ b/tools/win/inc/dll.hxx
@@ -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.
+ *
+ ************************************************************************/
+
+#ifndef _DLL_HXX
+#define _DLL_HXX
+
+// Um Resourcen wieder freizugeben
+inline void ImpDeInitWinTools() {}
+
+#endif /* _DLL_HXX */
diff --git a/tools/win/source/dll/toolsdll.cxx b/tools/win/source/dll/toolsdll.cxx
new file mode 100644
index 000000000000..3d934edfe71d
--- /dev/null
+++ b/tools/win/source/dll/toolsdll.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+#include <tools/svwin.h>
+#include <dll.hxx>
+#include <tools/shl.hxx>
+
+// =======================================================================
+
+#ifdef WNT
+
+static void* aAppData[SHL_COUNT];
+
+// -----------------------------------------------------------------------
+
+void** GetAppData( USHORT nSharedLib )
+{
+ return &(aAppData[nSharedLib]);
+}
+
+#endif
diff --git a/tools/workben/fstest.cxx b/tools/workben/fstest.cxx
new file mode 100644
index 000000000000..8048f2c166b0
--- /dev/null
+++ b/tools/workben/fstest.cxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * 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;
+}
+
diff --git a/tools/workben/hashtbl.cxx b/tools/workben/hashtbl.cxx
new file mode 100644
index 000000000000..bcd9f903ab64
--- /dev/null
+++ b/tools/workben/hashtbl.cxx
@@ -0,0 +1,515 @@
+/*************************************************************************
+ *
+ * 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;
+}
diff --git a/tools/workben/hashtbl.hxx b/tools/workben/hashtbl.hxx
new file mode 100644
index 000000000000..f4593b8148cf
--- /dev/null
+++ b/tools/workben/hashtbl.hxx
@@ -0,0 +1,203 @@
+/*************************************************************************
+ *
+ * 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
+
diff --git a/tools/workben/helloworld.c b/tools/workben/helloworld.c
new file mode 100644
index 000000000000..5d86cf2db21b
--- /dev/null
+++ b/tools/workben/helloworld.c
@@ -0,0 +1,33 @@
+/*************************************************************************
+ *
+ * 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");
+}
diff --git a/tools/workben/inetmimetest.cxx b/tools/workben/inetmimetest.cxx
new file mode 100644
index 000000000000..e380fb7f6fbe
--- /dev/null
+++ b/tools/workben/inetmimetest.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// 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;
+}
diff --git a/tools/workben/makefile.mk b/tools/workben/makefile.mk
new file mode 100644
index 000000000000..d97156c7f66c
--- /dev/null
+++ b/tools/workben/makefile.mk
@@ -0,0 +1,68 @@
+#*************************************************************************
+#
+# 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 = workben
+LIBTARGET = NO
+TARGETTYPE = CUI
+ENABLE_EXCEPTIONS=TRUE
+
+.INCLUDE: settings.mk
+
+OBJFILES = \
+ $(OBJ)$/solar.obj \
+ $(OBJ)$/urltest.obj \
+ $(OBJ)$/inetmimetest.obj \
+ $(OBJ)$/mempooltest.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) $(VOSLIB) $(SALLIB) $(CPPULIB) $(CPPUHELPERLIB)
+.ELSE
+APP2STDLIBS = $(LB)$/itools.lib $(VOSLIB) $(SALLIB) $(CPPULIB) $(CPPUHELPERLIB)
+.ENDIF
+
+APP3TARGET = inetmimetest
+APP3OBJS = $(OBJ)$/inetmimetest.obj
+APP3STDLIBS = $(SALLIB) $(TOOLSLIB)
+
+APP4TARGET = mempooltest
+APP4OBJS = $(OBJ)$/mempooltest.obj
+APP4STDLIBS = $(TOOLSLIB)
+APP4RPATH = UREBIN
+
+.INCLUDE: target.mk
diff --git a/tools/workben/mempooltest.cxx b/tools/workben/mempooltest.cxx
new file mode 100644
index 000000000000..bf00343bc9d6
--- /dev/null
+++ b/tools/workben/mempooltest.cxx
@@ -0,0 +1,18 @@
+#include "tools/mempool.hxx"
+
+struct MempoolTest
+{
+ int m_int;
+
+ DECL_FIXEDMEMPOOL_NEWDEL(MempoolTest);
+};
+
+IMPL_FIXEDMEMPOOL_NEWDEL(MempoolTest, 0, 0);
+
+int main()
+{
+ MempoolTest * p = new MempoolTest();
+ if (p != 0)
+ delete p;
+ return 1;
+}
diff --git a/tools/workben/solar.c b/tools/workben/solar.c
new file mode 100644
index 000000000000..06c4a787ec72
--- /dev/null
+++ b/tools/workben/solar.c
@@ -0,0 +1,427 @@
+/*************************************************************************
+ *
+ * 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;
+}
diff --git a/tools/workben/tldem.cxx b/tools/workben/tldem.cxx
new file mode 100644
index 000000000000..9571d3ff9b94
--- /dev/null
+++ b/tools/workben/tldem.cxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * 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;
+}
+
+
diff --git a/tools/workben/urltest.cxx b/tools/workben/urltest.cxx
new file mode 100644
index 000000000000..0930dfcc5239
--- /dev/null
+++ b/tools/workben/urltest.cxx
@@ -0,0 +1,1906 @@
+/*************************************************************************
+ *
+ * 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 <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 < sizeof aTest / sizeof aTest[0]; ++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 < sizeof aTest / sizeof aTest[0]; ++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 < sizeof aTest / sizeof aTest[0]; ++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 < sizeof aTest / sizeof aTest[0]; ++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 < sizeof aTest / sizeof aTest[0]; ++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 < sizeof aTest / sizeof aTest[0]; ++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 < sizeof aTest / sizeof aTest[0]; ++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;
+}