summaryrefslogtreecommitdiffstats
path: root/debian/wv2/wv2-0.4.2.dfsg.2
diff options
context:
space:
mode:
Diffstat (limited to 'debian/wv2/wv2-0.4.2.dfsg.2')
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/AUTHORS4
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/CMakeLists.txt199
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/COPYING.LIB482
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/ChangeLog202
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/INSTALL112
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/README15
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/RELEASE18
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/THANKS14
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/TODO31
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/cmake/FindGLIB2.cmake50
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/cmake/FindIconv.cmake57
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/cmake/FindLIBGSF.cmake57
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/cmake/MacroCreateLibtoolFile.cmake53
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/cmake/TestModernIconv.c41
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/cmake/TestModernZlib.c24
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/cmake/generate_converter.cmake7
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/cmake/generate_scanner.cmake15
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/config.h.cmake113
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/README.Debian13
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/changelog299
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/compat1
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/control29
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/copyright91
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-4.install1
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-4.shlibs1
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-dev.docs0
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-dev.install3
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-dev.manpages1
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/avoid-writing-after-structures.patch1421
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/buffer-overflow.patch25
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/fix-ftbfs-with-gold.patch20
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/fix-handling-empty-associatedstrings.patch48
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/fix-nan-and-inf-for-mips.patch23
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/fix-tests.patch20
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/glib-2.32-compat.patch20
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/series8
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/support-endnotes.patch17
-rwxr-xr-xdebian/wv2/wv2-0.4.2.dfsg.2/debian/rules36
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/source/format1
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/source/options3
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/debian/wv2-config.155
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/.cvsignore6
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/CMakeLists.txt107
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/associatedstrings.cpp91
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/associatedstrings.h91
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/convert.cpp1007
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/convert.h75
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/crc32.c244
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/crc32.h29
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/dllmagic.h28
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/fields.cpp197
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/fields.h97
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/fonts.cpp82
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/fonts.h69
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/footnotes97.cpp131
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/footnotes97.h89
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/functor.cpp30
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/functor.h69
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/functordata.cpp43
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/functordata.h103
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/generator/.cvsignore6
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/generator/CMakeLists.txt20
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/generator/Makefile.am18
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/generator/converter.pl721
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/generator/generate.pl1829
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/generator/spec_defects30
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-Word95.cpp48
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-Word95.h47
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-Word97.cpp147
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-Word97.h223
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-conv.cpp91
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-conv.h52
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/global.cpp66
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/global.h165
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/graphics.cpp321
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/graphics.h184
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/handlers.cpp214
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/handlers.h388
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/headers.cpp64
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/headers.h62
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/headers95.cpp56
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/headers95.h56
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/headers97.cpp51
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/headers97.h49
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/lists.cpp944
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/lists.h252
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/olestorage.cpp330
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/olestorage.h193
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/olestream.cpp414
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/olestream.h307
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/paragraphproperties.cpp65
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/paragraphproperties.h67
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/parser.cpp88
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/parser.h170
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/parser95.cpp44
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/parser95.h46
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/parser97.cpp43
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/parser97.h46
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/parser9x.cpp1209
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/parser9x.h324
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/parserfactory.cpp136
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/parserfactory.h56
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/properties97.cpp392
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/properties97.h98
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/sharedptr.h144
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/styles.cpp763
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/styles.h288
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/textconverter.cpp340
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/textconverter.h132
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/ustring.cpp638
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/ustring.h396
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/utilities.cpp38
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/utilities.h37
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/word95_generated.cpp6995
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/word95_generated.h6638
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/word95_helper.cpp453
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/word95_helper.h39
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/word97_generated.cpp8546
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/word97_generated.h8740
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/word97_helper.cpp2344
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/word97_helper.h49
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/word_helper.cpp319
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/word_helper.h745
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/wv2version.cpp45
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/wv2version.h69
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/wvlog.cpp24
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/wvlog.h117
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/zcodec.cxx573
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/src/zcodec.hxx151
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/tests/.cvsignore15
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/tests/CMakeLists.txt48
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/tests/handlertest.cpp404
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/tests/helpertest.cpp151
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/tests/iconvtest.cpp111
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/tests/oletest.cpp290
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/tests/parsertest.cpp49
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/tests/parsertest_mem.cpp66
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/tests/regression171
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/tests/sharedptrtest.cpp58
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/tests/test.h46
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/tests/testole.docbin0 -> 45056 bytes
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/tests/ustringtest.cpp91
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/tests/word95_test.cpp1167
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/tests/word97_test.cpp1462
-rw-r--r--debian/wv2/wv2-0.4.2.dfsg.2/wv2-config.cmake103
145 files changed, 59205 insertions, 0 deletions
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/AUTHORS b/debian/wv2/wv2-0.4.2.dfsg.2/AUTHORS
new file mode 100644
index 00000000..3f6c4260
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/AUTHORS
@@ -0,0 +1,4 @@
+Shaheed Haque <[email protected]>
+Werner Trobin <[email protected]>
+David Faure <[email protected]>
+Benjamin Cail <[email protected]>
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/CMakeLists.txt b/debian/wv2/wv2-0.4.2.dfsg.2/CMakeLists.txt
new file mode 100644
index 00000000..8f24660b
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/CMakeLists.txt
@@ -0,0 +1,199 @@
+PROJECT( wvWare )
+
+cmake_minimum_required(VERSION 2.6)
+
+# wv2 versioning
+SET( WV2_MAJOR_VERSION 0 )
+SET( WV2_MINOR_VERSION 4 )
+SET( WV2_MICRO_VERSION 2 )
+SET( WV2_VERSION ${WV2_MAJOR_VERSION}.${WV2_MINOR_VERSION}.${WV2_MICRO_VERSION} )
+
+# libtool versioning
+SET( LT_VERSION_CURRENT 4 )
+SET( LT_VERSION_REVISION 1 )
+SET( LT_VERSION_AGE 0 )
+
+# For automake. Is this required in CMake? (I don't think so)
+SET( VERSION ${WV2_VERSION} )
+SET( PACKAGE wv2 )
+
+SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${wvWare_SOURCE_DIR}/cmake )
+
+FIND_PACKAGE( GLIB2 REQUIRED )
+
+FIND_PACKAGE( LIBGSF REQUIRED )
+
+FIND_PACKAGE( Iconv REQUIRED )
+IF( ICONV_FOUND )
+ SET( HAVE_ICONV_H 1 )
+ SET( ICONV_REQUIRES_CONST ${ICONV_SECOND_ARGUMENT_IS_CONST} )
+ENDIF( ICONV_FOUND )
+
+OPTION( WITH_ZLIB "Build wv2 with zlib (with compression features)" ON )
+IF( WITH_ZLIB )
+ FIND_PACKAGE( ZLIB REQUIRED )
+ENDIF( WITH_ZLIB )
+
+INCLUDE_DIRECTORIES( ${GLIB2_INCLUDE_DIR} ${LIBGSF_INCLUDE_DIR} ${ICONV_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} )
+
+#
+# Iconv checks
+#
+
+INCLUDE( CheckIncludeFile )
+
+CHECK_INCLUDE_FILE( sys/iconv.h HAVE_SYS_ICONV_H )
+
+# Add "COMPILE_DEFINITIONS definitions" to TRY_RUN only if we have compile definitions
+
+# Make sure ICONV_COMPILE_DEFINITIONS will never be empty (in case we define neither HAVE_ICONV_H nor HAVE_SYS_ICONV_H),
+# otherwise TRY_RUN will fail due to COMPILE_DEFINITIONS being followed by nothing
+
+SET( ICONV_COMPILE_DEFINITIONS "-DBLAH" )
+
+IF( HAVE_ICONV_H )
+ SET( ICONV_COMPILE_DEFINITIONS ${ICONV_COMPILE_DEFINITIONS} "-DHAVE_ICONV_H" )
+ENDIF( HAVE_ICONV_H )
+
+IF( HAVE_SYS_ICONV_H )
+ SET( ICONV_COMPILE_DEFINITIONS ${ICONV_COMPILE_DEFINITIONS} "-DHAVE_SYS_ICONV_H" )
+ENDIF( HAVE_SYS_ICONV_H )
+
+TRY_RUN( MODERN_ICONV_RUN MODERN_ICONV_COMPILE ${wvWare_BINARY_DIR}/CMakeTmp ${wvWare_SOURCE_DIR}/cmake/TestModernIconv.c COMPILE_DEFINITIONS ${ICONV_COMPILE_DEFINITIONS} )
+
+IF( MODERN_ICONV_RUN GREATER 0 OR NOT MODERN_ICONV_COMPILE )
+ MESSAGE( STATUS "wv2 depends on a modern iconv installation, supporting UNICODELITTLE and" )
+ MESSAGE( STATUS "UNICODEBIG. The detected iconv version doesn't support these conversions." )
+ MESSAGE( STATUS "" )
+ MESSAGE( STATUS "Please get a new libiconv from http://www.gnu.org/software/libiconv/" )
+ MESSAGE( STATUS "You might want to install the library to some alternative directory, in" )
+ MESSAGE( STATUS "order not to overwrite your current installation. Please use the options" )
+ MESSAGE( STATUS "-DICONV_INCLUDE_DIR=DIR and -DICONV_LIBRARIES=DIR to specify the location." )
+ MESSAGE( STATUS "" )
+ MESSAGE( FATAL_ERROR "* * * No iconv support - unable to continue. * * *" )
+ENDIF( MODERN_ICONV_RUN GREATER 0 OR NOT MODERN_ICONV_COMPILE )
+
+#
+# Various checks
+#
+
+INCLUDE( TestBigEndian )
+TEST_BIG_ENDIAN( WORDS_BIGENDIAN )
+
+CHECK_INCLUDE_FILE( dlfcn.h HAVE_DLFCN_H )
+CHECK_INCLUDE_FILE( strings.h HAVE_STRINGS_H )
+CHECK_INCLUDE_FILE( string.h HAVE_STRING_H )
+CHECK_INCLUDE_FILE( math.h HAVE_MATH_H )
+CHECK_INCLUDE_FILE( float.h HAVE_FLOAT_H )
+CHECK_INCLUDE_FILE( ieeefp.h HAVE_IEEEFP_H )
+CHECK_INCLUDE_FILE( errno.h HAVE_ERRNO_H )
+CHECK_INCLUDE_FILE( inttypes.h HAVE_INTTYPES_H )
+CHECK_INCLUDE_FILE( memory.h HAVE_MEMORY_H )
+CHECK_INCLUDE_FILE( stdlib.h HAVE_STDLIB_H )
+CHECK_INCLUDE_FILE( unistd.h HAVE_UNISTD_H )
+CHECK_INCLUDE_FILE( stdint.h HAVE_STDINT_H ) # Not really needed because CHECK_TYPE_SIZE already performs this test
+CHECK_INCLUDE_FILE( stdint.h HAVE_STDINT_H ) # Not really needed because CHECK_TYPE_SIZE already performs this test
+CHECK_INCLUDE_FILE( sys/types.h HAVE_SYS_TYPES_H ) # Not really needed because CHECK_TYPE_SIZE already performs this test
+CHECK_INCLUDE_FILE( sys/stat.h HAVE_SYS_STAT_H )
+
+INCLUDE( CheckTypeSize )
+CHECK_TYPE_SIZE( char SIZEOF_CHAR )
+CHECK_TYPE_SIZE( short SIZEOF_SHORT )
+CHECK_TYPE_SIZE( long SIZEOF_LONG )
+CHECK_TYPE_SIZE( int SIZEOF_INT )
+CHECK_TYPE_SIZE( "void *" SIZEOF_VOID_P )
+
+INCLUDE( CheckFunctionExists )
+IF( NOT MSVC )
+ # libm does not exist on MSVC
+ SET( CMAKE_REQUIRED_LIBRARIES m )
+ SET( CMAKE_REQUIRED_INCLUDES math.h )
+ENDIF( NOT MSVC )
+
+CHECK_FUNCTION_EXISTS( isinf HAVE_FUNC_ISINF )
+CHECK_FUNCTION_EXISTS( isnan HAVE_FUNC_ISNAN )
+CHECK_FUNCTION_EXISTS( finite HAVE_FUNC_FINITE )
+CHECK_FUNCTION_EXISTS( _finite HAVE_FUNC__FINITE )
+
+#
+# Check zlib is modern enough
+#
+
+SET( NEON_ZLIB 0 ) # By default, we are not modern enough
+SET( CMAKE_REQUIRED_LIBRARIES ${ZLIB_LIBRARIES} )
+SET( CMAKE_REQUIRED_INCLUDES zlib.h )
+
+CHECK_FUNCTION_EXISTS( inflate ZLIB_HAS_INFLATE )
+
+IF( ZLIB_HAS_INFLATE )
+ TRY_RUN( MODERN_ZLIB_RUN MODERN_ZLIB_COMPILE ${wvWare_BINARY_DIR}/CMakeTmp ${wvWare_SOURCE_DIR}/cmake/TestModernZlib.c )
+ENDIF( ZLIB_HAS_INFLATE )
+
+IF( MODERN_ZLIB_RUN GREATER 0 AND WITH_ZLIB )
+ MESSAGE( FATAL_ERROR "Your version of zlib is too old for wv2" )
+ENDIF( MODERN_ZLIB_RUN GREATER 0 AND WITH_ZLIB )
+
+#
+# Set cflags and ldflags
+#
+
+IF( ZLIB_FOUND )
+ SET( _WV2_LDFLAGS ${_WV2_LDFLAGS} ${ZLIB_LIBRARIES} )
+ SET( _WV2_CFLAGS ${_WV2_CFLAGS} ${ZLIB_INCLUDE_DIR} )
+ENDIF( ZLIB_FOUND )
+
+IF( LIBGSF_FOUND )
+ SET( _WV2_LDFLAGS ${_WV2_LDFLAGS} ${LIBGSF_LIBRARIES} )
+ SET( _WV2_CFLAGS ${_WV2_CFLAGS} ${LIBGSF_INCLUDE_DIR} )
+ENDIF( LIBGSF_FOUND )
+
+IF( ICONV_FOUND )
+ SET( _WV2_LDFLAGS ${_WV2_LDFLAGS} ${ICONV_LIBRARIES} )
+ SET( _WV2_CFLAGS ${_WV2_CFLAGS} ${ICONV_INCLUDE_DIR} )
+ENDIF( ICONV_FOUND )
+
+IF( GLIB2_FOUND )
+ SET( _WV2_LDFLAGS ${_WV2_LDFLAGS} ${GLIB2_LIBRARIES} )
+ SET( _WV2_CFLAGS ${_WV2_CFLAGS} ${GLIB2_INCLUDE_DIR} )
+ENDIF( GLIB2_FOUND )
+
+#
+# Clean and prepare
+#
+LIST( REMOVE_DUPLICATES _WV2_LDFLAGS )
+LIST( REMOVE_DUPLICATES _WV2_CFLAGS )
+
+FOREACH( _lib ${_WV2_LDFLAGS} )
+ # Remove path to the library and suffixes. Transformation example: libglib-2.0.so => glib-2.0
+ STRING( REGEX REPLACE "[\\\\ _\\/\\.a-zA-Z0-9\\-]*\\/lib([_\\.a-zA-Z0-9\\-]*)\\.[_a-zA-Z0-9\\-\\.]*" \\1 _lib_no_path ${_lib} )
+ SET( WV2_LDFLAGS "${WV2_LDFLAGS} ${CMAKE_LINK_LIBRARY_FLAG}${_lib_no_path}" )
+ENDFOREACH( _lib )
+
+FOREACH( _inc ${_WV2_CFLAGS} )
+ SET( WV2_CFLAGS "${WV2_CFLAGS} -I${_inc}" )
+ENDFOREACH( _inc )
+
+# Generate configuration files
+CONFIGURE_FILE( config.h.cmake ${wvWare_BINARY_DIR}/config.h )
+CONFIGURE_FILE( wv2-config.cmake ${wvWare_BINARY_DIR}/wv2-config @ONLY )
+
+# Source directories
+ADD_SUBDIRECTORY( src )
+ADD_SUBDIRECTORY( src/generator )
+ADD_SUBDIRECTORY( tests )
+
+# Installation (more in src/CMakeLists.txt)
+
+INSTALL( FILES ${wvWare_BINARY_DIR}/wv2-config
+ DESTINATION bin
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+ )
+
+# "make dist"
+
+SET(ARCHIVE_NAME ${PACKAGE}-${WV2_VERSION})
+ADD_CUSTOM_TARGET(dist
+ COMMAND svn export ${wvWare_SOURCE_DIR} ${wvWare_BINARY_DIR}/${ARCHIVE_NAME}
+ COMMAND tar -C ${wvWare_BINARY_DIR} -c -v -z -f ${ARCHIVE_NAME}.tar.gz ${ARCHIVE_NAME}
+ COMMAND ${CMAKE_COMMAND} -E remove_directory ${wvWare_BINARY_DIR}/${ARCHIVE_NAME}
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/COPYING.LIB b/debian/wv2/wv2-0.4.2.dfsg.2/COPYING.LIB
new file mode 100644
index 00000000..bf50f20d
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/COPYING.LIB
@@ -0,0 +1,482 @@
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/ChangeLog b/debian/wv2/wv2-0.4.2.dfsg.2/ChangeLog
new file mode 100644
index 00000000..492844d0
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/ChangeLog
@@ -0,0 +1,202 @@
+2009-10-30 Benjamin Cail <[email protected]>
+
+ * Release wv2-0.4.2 with a couple updates.
+
+2009-10-08 Benjamin Cail <[email protected]>
+
+ * Release wv2-0.4.1 with a few updates.
+
+2009-08-26 Benjamin Cail <[email protected]>
+
+ * Release wv2-0.4.0 with cmake build system from Pau Garcia i
+ Quiles and some table border/shading improvements from
+ boemann.
+
+2009-03-05 Benjamin Cail <[email protected]>
+
+ * Released wv2-0.3.1 with a few bugfixes for image handling.
+
+2009-02-16 Benjamin Cail <[email protected]>
+
+ * Released wv2-0.3.0 with basic for images, both metafile and
+ bitmap.
+
+2006-06-12 Werner Trobin <[email protected]>
+
+ * Applied security fix to HEAD
+
+2004-09-14 Werner Trobin <[email protected]>
+
+ * Applied a patch by Friedemann Kleint (Fa. metis) <[email protected]>
+ with fixes for Solaris / Sun C++ 5.5 Patch 113817-02 2003/08/29.
+ Additionally fixes some tab-related bugs (unique and erase stuff)
+
+2004-05-10 Werner Trobin <[email protected]>
+
+ * Ported the gcc 3.4 fixes to HEAD
+
+2004-05-09 Werner Trobin <[email protected]>
+
+ * Released wv2-0.2.2 (WV2_0_2_1_BRANCH)
+
+ * Fixed compilation with gcc 3.4
+
+2003-11-08 Werner Trobin <[email protected]>
+
+ * Cleaned up the configure.in script and the Makefiles a bit.
+ Let's hope this still works everywhere and doesn't barf on the
+ iconv test on Cygwin...
+
+2003-11-06 Werner Trobin <[email protected]>
+
+ * Safer version of the wvlog.h fix. Backported to the branch.
+
+ * Added a version header surprisingly similar to kdeversion.h to
+ make it easier for the KOffice part of the filter.
+
+2003-11-05 Werner Trobin <[email protected]>
+
+ * Released wv2-0.2.1
+
+ * Fixed a very stupid bug: it didn't compile on gcc 2.95.x ... doh!
+
+ * Bumped the CVS version 0.2.5 and the library version to 2.0.0.
+ The goal is to have at least basic image support for the 0.3
+ release. Depending on the quality of the 0.2 release there might
+ be one or more bugfix releases (0.2.1, 0.2.2,...).
+
+ * Released wv2-0.2
+
+ * Merged some fixes from HEAD to the WV2_0_1_9_BRANCH
+
+2003-10-23 Werner Trobin <[email protected]>
+
+ * Fixed a tricky list bug. When a compat list was converted to Word 8
+ format it worked for the first time. From the second time on the
+ index into the pllfo was off-by-one. This triggered a crash in case
+ the first list in the pllfo was a compat one (i.e. there are *just*
+ compat lists in a document).
+
+2003-09-11 Werner Trobin <[email protected]>
+
+ * More image stuff. I had to split some interfaces, let's see if it's
+ cleaner that way.
+
+2003-09-08 Werner Trobin <[email protected]>
+
+ * Started to implement image support for Word 6 style inline images.
+
+2003-09-01 Werner Trobin <[email protected]>
+
+ * Released wv2-0.1.9
+
+2003-08-30 Werner Trobin <[email protected]>
+
+ * Implemented a different logging mechanism to support a really
+ quiet wv2 for users. :-)
+ Packagers will have to use --disable-debug
+
+2003-08-29 Werner Trobin <[email protected]>
+
+ * Okay, as it turned out there was still a problem with lists and
+ restarting counters yesterday. Now all my test documents work
+ as expected, though.
+
+2003-08-28 Werner Trobin <[email protected]>
+
+ * Fixed the handling of startAt in list level overrides and
+ some related list bugs. Looks pretty okay now...
+
+2003-08-26 Werner Trobin <[email protected]>
+
+ * Fixed list handling for Word 6 files.
+
+2003-08-25 Werner Trobin <[email protected]>
+
+ * Added a public domain implementation of CRC32 written by
+ Ross Williams. We need that to calculate unique list ids.
+
+2003-08-23 Werner Trobin <[email protected]>
+
+ * Added some ideas about image handling in wv2 to the design document.
+ Moved some variables in Parser9x to the private section.
+
+2003-08-13 Werner Trobin <[email protected]>
+
+ * Fixed the problem of lost text in some Word 95 documents.
+ Unfortunately MS uses CP1252 characters marked as UNDEFINED
+ in the specification. iconv doesn't really like that.
+ The filter now tries to recover as much text as possible.
+
+2003-08-09 Werner Trobin <[email protected]>
+
+ * Rewrote parts of the design document to reflect the recent changes.
+
+2003-08-07 Werner Trobin <[email protected]>
+
+ * Removed the "any later version" clause from the license headers.
+
+ * Released wv2-0.1.8
+
+ * Fixed a bug in the lid handling
+
+2003-08-01 Werner Trobin <[email protected]>
+
+ * Fixed some SPRMs (Word 6 vs. Word 8)
+
+2003-07-31 Werner Trobin <[email protected]>
+
+ * Released wv2-0.1.7
+
+ * Word 6/7 support should work now. Well, at least none of the test
+ documents crashes and headers/footers also seem to work. Now I'd
+ need some more test documents (including screenshots).
+
+2003-07-23 Werner Trobin <[email protected]>
+
+ * Started to implement Word 6/7 support by moving code around. This
+ stuff is quite tricky. Basically I'm trying to unify the code and
+ move it to the common base class Parser9x, which Parser95 and
+ Parser97 inherit.
+
+2003-06-08 Werner Trobin <[email protected]>
+
+ * Applied a patch from Ben Burton <[email protected]> to make wv2 work
+ with libgsf-1.8.x and libgsf-1.7.2.
+
+ * Released wv2-0.1
+
+2003-04-26 Werner Trobin <[email protected]>
+
+ * Got rid of the acconfig.h file, as autoconf 2.57 issued warnings.
+
+2003-04-08 Werner Trobin <[email protected]>
+
+ * Applied a patch from Adrian Schroeter <[email protected]>, fixing the
+ build system. (e.g. CFLAGS -> AM_CFLAGS,...)
+
+ * Fixed the libtool versioning
+
+ * Released wv2-0.0.9
+
+2003-03-21 Werner Trobin <[email protected]>
+
+ * Worked around another bug in list handling (05_...). Unfortunately
+ I have no idea how to fix that "the right way" as some information
+ is just missing and I see no way to recover it (having only one
+ test document with that oddity). Maybe I can recognize a pattern
+ when I get some more flaky list documents.
+
+ * Fixed a bug in list handling, avoids crashes on flaky documents.
+
+2003-03-16 Werner Trobin <[email protected]>
+
+ * Removed the "/wv2" after the include path, to avoid header
+ clashes when #including e.g. parser.h (libxml2 also has a
+ header named parser.h)
+
+2003-03-09 Werner Trobin <[email protected]>
+
+ * Released wv2-0.0.8 (and decided to start writing a ChangeLog :-)
+
+ * Registered the project at freshmeat.net
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/INSTALL b/debian/wv2/wv2-0.4.2.dfsg.2/INSTALL
new file mode 100644
index 00000000..c169cdd7
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/INSTALL
@@ -0,0 +1,112 @@
+Basic installation instructions
+===============================
+
+These are instructions to build wv2 with the CMake build system on any
+platform, including cross-compilation. If you are intested in building
+wv2 with autotools, please read INSTALL instead.
+
+
+Configuring and building
+========================
+
+1. Download CMake from http://www.cmake.org or install it by other means (apt,
+ yum, zypper, the KDE on Windows installer, etc)
+
+2. The following third party dependencies must be available:
+
+ * GNOME Structured File Library
+ http://ftp.gnome.org/pub/gnome/sources/libgsf/
+
+ * glib 2.0
+ http://www.gtk.org
+
+ * iconv
+ http://www.gnu.org/software/libiconv/
+
+ * zlib
+ http://www.zlib.net/
+
+ By default, Zlib is also required, although it is possible to build wv2
+ without zlib by using setting the WITHOUT_ZLIB CMake option to ON.
+
+3. Open the CMake GUI and select the source directory (where the CMakeLists.txt
+ file is) and the build directory (where you want to build wv2).
+
+ Building in the source directory (i.e. build directory = source directory )
+ is possible but ill-advised.
+
+ If you want to build without zlib, change the value of WITHOUT_ZLIB to ON.
+
+4. Click the 'Configure' button.
+
+ If the build directory does not exist, CMake will ask for your permission to
+ create it.
+
+5. CMake will also ask you what build system you want to build with, i. e. Unix
+ makefiles, Visual Studio solutions, Eclipse project, Borland makefiles, etc.
+ Depending on what platform you are, you will be offered different build
+ systems (known as "generators" in CMake slang).
+
+6. CMake will now look for the third party dependencies.
+
+ On Linux/Unix (including Mac), if third party libraries were installed in
+ the default locations they will be found automatically.
+
+ On Windows, if you are cross-compiling or if third party libraries are
+ installed to non-default locations, you will need to browse for the
+ libraries (on windows, the .lib files) and include directories. Make
+ sure CMake GUI is in the "Advanced view" mode or you may not see all
+ missing dependencies.
+
+7. Once you are done with dependencies, click the 'Generate' button
+
+8. An appropriate build system will be available in your build directory.
+ Use it with your toolchain, i.e.
+ - Go to the build directory and invoke "make" or "nmake", if using makefiles
+ - Open the Visual Studio solution, if using Visual C++
+ - Open the Eclipse project if using Eclipse
+ etc
+
+Alternatively to steps 3-7, you may invoke CMake from the command line:
+ $ cmake /path/to/wv2/sources
+ or, to build without zlib:
+ $ cmake -DWITHOUT_ZLIB=ON
+
+
+Building the tests
+==================
+
+By default, only the wv2 library will be built. If you want to compile the tests,
+build the "test" target ("make test").
+
+
+Installing
+==========
+
+Build the "install" target ("make install").
+
+On Linux/Unix, the default installation prefix is /usr/local. On Windows, the
+default installation prefix is C:\Program Files. To change this, modify the
+value of the CMAKE_INSTALL_PREFIX variable in the CMake GUI.
+
+You can also install to a different location by using the DESTDIR environment
+variable ("make install DESTDIR=/opt/mine/wv2") but then wv2-config will
+report wrong paths.
+
+
+Regenerating the scanner and converter code
+===========================================
+
+Build the 'scanner' and 'converter' targets. The 'generated' target is provided
+as a convenience and will build both 'scanner' and 'converter'.
+
+Please note the generated sources are currently generated in the SOURCE
+directory, not in the build directory.
+
+
+Generating a distributable source package
+=========================================
+
+Use "make dist" to create a tarball from a Subversion working tree. In the future,
+other options (NSIS installer for Windows, .dmg for Mac, Debian and RPM packages
+for Linux, etc) may be available.
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/README b/debian/wv2/wv2-0.4.2.dfsg.2/README
new file mode 100644
index 00000000..caca79e9
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/README
@@ -0,0 +1,15 @@
+This library depends on libgsf >= 1.7.2, but it doesn't need the GNOME part
+of it, so it's probably a good idea to configure libgsf with the
+--without-gnome option (then you don't have to install bonobo et al.)
+For newer libgsf versions this is detected automatically, so you don't have
+to specify that anymore.
+
+You can download libgsf at: ftp://ftp.gnome.org/pub/GNOME/sources/libgsf
+
+libgsf depends on glib2 (www.gtk.org) and libxml2 (www.xmlsoft.org), in case
+you use the --without-gnome option.
+
+Additionally you need pkg-config (www.freedesktop.org/software/pkgconfig/)
+
+In case you want to package wv2, please use the --disable-debug flag to get
+rid of the debug output.
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/RELEASE b/debian/wv2/wv2-0.4.2.dfsg.2/RELEASE
new file mode 100644
index 00000000..9147bf32
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/RELEASE
@@ -0,0 +1,18 @@
+A small listing for me as I keep forgetting important steps like tagging...
+
+- Bump the version numbers in:
+ * CMakeLists.txt: WV_MAJOR/MINOR/MICRO_VERSION and LT_CURRENT/REVISION/AGE
+ * wv2version.h: WV2_VERSION_MAJOR/MINOR/RELEASE, WV2_VERSION_STRING
+- Add a ChangeLog entry for the release
+- branch svn if needed
+- copy branch out to wv2-x.y.z & remove .svn directories
+- tar -jcvf wv2-x.y.z.tar.bz2 wv2-x.y.z/
+- use that tarball, install it, and run tests with that version of library
+- svn copy https://wvware.svn.sourceforge.net/svnroot/wvware/branches/wv2-0.x https://wvware.s
+vn.sourceforge.net/svnroot/wvware/tags/wv2-0.x.y -m "tag wv2-0.x.y"
+- gpg --detach-sign --armor -u "user" wv2-0.x.y.tar.bz2
+- gpg --verify wv2-x.y.z.tar.bz2.asc
+- upload files to sourceforge
+- download & gpg verify again
+- announce on koffice-devel
+
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/THANKS b/debian/wv2/wv2-0.4.2.dfsg.2/THANKS
new file mode 100644
index 00000000..5800f6ea
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/THANKS
@@ -0,0 +1,14 @@
+We would like to thank the following people for their help:
+
+Harri Porten <[email protected]> - for the UString class
+Karl-Heinz Zimmer <[email protected]> - for hints about bits and pieces of the Word
+ oddities
+F J Franklin <[email protected]> - for the build system, all the
+ libtool/autofoo magic
+Jeremy White, CEO of CodeWeavers, Inc. - for donating a CrossOver Office
+ license
+Stephan Kulow <[email protected]> - for all the code we stole^H^H^Hborrowed from
+ the KDE build system
+Duncan Wilcox <[email protected]> - for porting wv2 to Visual C++,
+ for adding "OLE from memory" support,
+ and for sending good bug reports
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/TODO b/debian/wv2/wv2-0.4.2.dfsg.2/TODO
new file mode 100644
index 00000000..943a0391
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/TODO
@@ -0,0 +1,31 @@
+This file contains the next few features I'd like to implement (in no
+particular order):
+
+* SPRM related:
+ - Try to implement some more of the known SPRMs and merge the information
+ about the non-documented sprms from OOo
+ - Try to find out what the sprms 0xD632 and 0xD634 mean and how to interpret
+ them (OOo). Some spacing related thing. Check all other sprms found in
+ C.U.5.doc. It seems that some previously undocumented sprms like 0xD620
+ are known in OOo now.
+
+* Image reading:
+ - Try to write some image reading code, OOo has some nice comments in the
+ ww8graf* files.
+ - Find out how drawings are anchored, tell David
+ - Try to import textboxes / header-textboxes. Note: Internally they are
+ represented like drawings
+
+* Performance:
+ - Run cachegrind on the parsertest and check for bottlenecks
+
+* Bugs:
+ - The parser has problems with Informatikmanagement.doc (header)
+ - The generated testcases have alignment problems on Solaris
+ - The helpertest fails on Solaris with some backtrace ending in UString. Weird
+ - Fields don't really work in the KOffice part of the filter... (e.g. page
+ numbers in the footer)
+
+* Build system:
+ - Fix the iconv test (cygwin link line problem)
+ - Make sure to create some test system with gcc 2.95.x...
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/cmake/FindGLIB2.cmake b/debian/wv2/wv2-0.4.2.dfsg.2/cmake/FindGLIB2.cmake
new file mode 100644
index 00000000..431f2e5e
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/cmake/FindGLIB2.cmake
@@ -0,0 +1,50 @@
+# - Try to find the GLIB2 libraries
+# Once done this will define
+#
+# GLIB2_FOUND - system has glib2
+# GLIB2_INCLUDE_DIR - the glib2 include directory
+# GLIB2_LIBRARIES - glib2 library
+
+# Copyright (c) 2008 Laurent Montel, <[email protected]>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+if(GLIB2_INCLUDE_DIR AND GLIB2_LIBRARIES)
+ # Already in cache, be silent
+ set(GLIB2_FIND_QUIETLY TRUE)
+endif(GLIB2_INCLUDE_DIR AND GLIB2_LIBRARIES)
+
+if (NOT WIN32)
+ include(UsePkgConfig)
+ pkgconfig(glib-2.0 _LibGLIB2IncDir _LibGLIB2LinkDir _LibGLIB2LinkFlags _LibGLIB2Cflags)
+endif(NOT WIN32)
+
+find_path(GLIB2_MAIN_INCLUDE_DIR glib.h
+ PATH_SUFFIXES glib-2.0
+ PATHS ${_LibGLIB2IncDir} )
+
+# search the glibconfig.h include dir under the same root where the library is found
+find_library(GLIB2_LIBRARIES
+ NAMES glib-2.0
+ PATHS ${_LibGLIB2LinkDir} )
+
+get_filename_component(glib2LibDir "${GLIB2_LIBRARIES}" PATH)
+
+find_path(GLIB2_INTERNAL_INCLUDE_DIR glibconfig.h
+ PATH_SUFFIXES glib-2.0/include
+ PATHS ${_LibGLIB2IncDir} "${glib2LibDir}" ${CMAKE_SYSTEM_LIBRARY_PATH})
+
+set(GLIB2_INCLUDE_DIR "${GLIB2_MAIN_INCLUDE_DIR}")
+
+# not sure if this include dir is optional or required
+# for now it is optional
+if(GLIB2_INTERNAL_INCLUDE_DIR)
+ set(GLIB2_INCLUDE_DIR ${GLIB2_INCLUDE_DIR} "${GLIB2_INTERNAL_INCLUDE_DIR}")
+endif(GLIB2_INTERNAL_INCLUDE_DIR)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(GLIB2 DEFAULT_MSG GLIB2_LIBRARIES GLIB2_MAIN_INCLUDE_DIR)
+
+mark_as_advanced(GLIB2_INCLUDE_DIR GLIB2_LIBRARIES)
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/cmake/FindIconv.cmake b/debian/wv2/wv2-0.4.2.dfsg.2/cmake/FindIconv.cmake
new file mode 100644
index 00000000..ce40ab26
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/cmake/FindIconv.cmake
@@ -0,0 +1,57 @@
+# - Try to find Iconv
+# Once done this will define
+#
+# ICONV_FOUND - system has Iconv
+# ICONV_INCLUDE_DIR - the Iconv include directory
+# ICONV_LIBRARIES - Link these to use Iconv
+# ICONV_SECOND_ARGUMENT_IS_CONST - the second argument for iconv() is const
+#
+include(CheckCXXSourceCompiles)
+
+IF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
+ # Already in cache, be silent
+ SET(ICONV_FIND_QUIETLY TRUE)
+ENDIF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
+
+FIND_PATH(ICONV_INCLUDE_DIR iconv.h)
+
+FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2 c)
+
+IF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
+ SET(ICONV_FOUND TRUE)
+ENDIF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
+
+set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
+set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARIES})
+IF(ICONV_FOUND)
+ check_cxx_source_compiles("
+ #include <iconv.h>
+ int main(){
+ iconv_t conv = 0;
+ const char* in = 0;
+ size_t ilen = 0;
+ char* out = 0;
+ size_t olen = 0;
+ iconv(conv, &in, &ilen, &out, &olen);
+ return 0;
+ }
+" ICONV_SECOND_ARGUMENT_IS_CONST )
+ENDIF(ICONV_FOUND)
+set(CMAKE_REQUIRED_INCLUDES)
+set(CMAKE_REQUIRED_LIBRARIES)
+
+IF(ICONV_FOUND)
+ IF(NOT ICONV_FIND_QUIETLY)
+ MESSAGE(STATUS "Found Iconv: ${ICONV_LIBRARIES}")
+ ENDIF(NOT ICONV_FIND_QUIETLY)
+ELSE(ICONV_FOUND)
+ IF(Iconv_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find Iconv")
+ ENDIF(Iconv_FIND_REQUIRED)
+ENDIF(ICONV_FOUND)
+
+MARK_AS_ADVANCED(
+ ICONV_INCLUDE_DIR
+ ICONV_LIBRARIES
+ ICONV_SECOND_ARGUMENT_IS_CONST
+)
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/cmake/FindLIBGSF.cmake b/debian/wv2/wv2-0.4.2.dfsg.2/cmake/FindLIBGSF.cmake
new file mode 100644
index 00000000..8d749a87
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/cmake/FindLIBGSF.cmake
@@ -0,0 +1,57 @@
+# - Try to find libGSF
+#
+# Once done this will define
+#
+# LIBGSF_FOUND - System has LibGSF
+# LIBGSF_INCLUDE_DIR - The LibGSF include directory
+# LIBGSF_LIBRARIES - The libraries needed to use LibGSF
+# LIBGSF_DEFINITIONS - Compiler switches required for using LibGSF
+# LIBGSF_GSF_EXECUTABLE - The archive utility
+# LIBGSF_GSFOFFICETHUMBNAILER_EXECUTABLE - The office files thumbnailer for the GNOME desktop
+# LIBGSF_GSFVBADUMP_EXECUTABLE - The utility to extract Visual Basic for Applications macros
+
+# Copyright (c) 2009, Pau Garcia i Quiles <[email protected]>
+# Based off FindLibXml2.cmake from CMake 2.6.4 by Alexander Neundorf <[email protected]>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+IF (LIBGSF_INCLUDE_DIR AND LIBGSF_LIBRARIES)
+ # in cache already
+ SET(LIBGSF_FIND_QUIETLY TRUE)
+ENDIF (LIBGSF_INCLUDE_DIR AND LIBGSF_LIBRARIES)
+
+IF (NOT WIN32)
+ # use pkg-config to get the directories and then use these values
+ # in the FIND_PATH() and FIND_LIBRARY() calls
+ FIND_PACKAGE(PkgConfig)
+ PKG_CHECK_MODULES(PC_LIBGSF libgsf-1)
+ SET(LIBGSF_DEFINITIONS ${PC_LIBGSF_CFLAGS_OTHER})
+ENDIF (NOT WIN32)
+
+FIND_PATH(LIBGSF_INCLUDE_DIR gsf/gsf.h
+ HINTS
+ ${PC_LIBGSF_INCLUDEDIR}
+ ${PC_LIBGSF_INCLUDE_DIRS}
+ PATH_SUFFIXES libgsf-1
+ )
+
+FIND_LIBRARY(LIBGSF_LIBRARIES NAMES gsf-1 libgsf-1
+ HINTS
+ ${PC_LIBGSF_LIBDIR}
+ ${PC_LIBGSF_LIBRARY_DIRS}
+ )
+
+FIND_PROGRAM(LIBGSF_GSF_EXECUTABLE gsf)
+FIND_PROGRAM(LIBGSF_GSFOFFICETHUMBNAILER_EXECUTABLE gsf-office-thumbnailer)
+FIND_PROGRAM(LIBGSF_GSFVBADUMP_EXECUTABLE gsf-vba-dump)
+
+INCLUDE(FindPackageHandleStandardArgs)
+
+# handle the QUIETLY and REQUIRED arguments and set LIBGSF_FOUND to TRUE if
+# all listed variables are TRUE
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBGSF DEFAULT_MSG LIBGSF_LIBRARIES LIBGSF_INCLUDE_DIR)
+
+MARK_AS_ADVANCED(LIBGSF_INCLUDE_DIR LIBGSF_LIBRARIES LIBGSF_GSF_EXECUTABLE LIBGSF_GSFOFFICETHUMBNAILER_EXECUTABLE LIBGSF_GSFVBADUMP_EXECUTABLE )
+
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/cmake/MacroCreateLibtoolFile.cmake b/debian/wv2/wv2-0.4.2.dfsg.2/cmake/MacroCreateLibtoolFile.cmake
new file mode 100644
index 00000000..73f52f37
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/cmake/MacroCreateLibtoolFile.cmake
@@ -0,0 +1,53 @@
+# MacroCreateLibtoolFile.cmake
+# http://www.cmake.org/Wiki/CMakeMacroLibtoolFile
+
+MACRO(GET_TARGET_PROPERTY_WITH_DEFAULT _variable _target _property _default_value)
+ GET_TARGET_PROPERTY (${_variable} ${_target} ${_property})
+ IF (${_variable} MATCHES NOTFOUND)
+ SET (${_variable} ${_default_value})
+ ENDIF (${_variable} MATCHES NOTFOUND)
+ENDMACRO (GET_TARGET_PROPERTY_WITH_DEFAULT)
+
+MACRO(CREATE_LIBTOOL_FILE _target _install_DIR)
+ GET_TARGET_PROPERTY(_target_location ${_target} LOCATION)
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_static_lib ${_target} STATIC_LIB "")
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_dependency_libs ${_target} LT_DEPENDENCY_LIBS "")
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_current ${_target} LT_VERSION_CURRENT 0)
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_age ${_target} LT_VERSION_AGE 0)
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_revision ${_target} LT_VERSION_REVISION 0)
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_installed ${_target} LT_INSTALLED yes)
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_shouldnotlink ${_target} LT_SHOULDNOTLINK yes)
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_dlopen ${_target} LT_DLOPEN "")
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_dlpreopen ${_target} LT_DLPREOPEN "")
+ GET_FILENAME_COMPONENT(_laname ${_target_location} NAME_WE)
+ GET_FILENAME_COMPONENT(_soname ${_target_location} NAME)
+ SET(_laname ${PROJECT_BINARY_DIR}/${_laname}.la)
+ FILE(WRITE ${_laname} "# ${_laname} - a libtool library file\n")
+ FILE(WRITE ${_laname} "# Generated by CMake ${CMAKE_VERSION} (like GNU libtool)\n")
+ FILE(WRITE ${_laname} "\n# Please DO NOT delete this file!\n# It is necessary for linking the library with libtool.\n\n" )
+ FILE(APPEND ${_laname} "# The name that we can dlopen(3).\n")
+ FILE(APPEND ${_laname} "dlname='${_soname}'\n\n")
+ FILE(APPEND ${_laname} "# Names of this library.\n")
+ FILE(APPEND ${_laname} "library_names='${_soname}.${_target_current}.${_target_age}.${_target_revision} ${_soname}.${_target_current} ${_soname}'\n\n")
+ FILE(APPEND ${_laname} "# The name of the static archive.\n")
+ FILE(APPEND ${_laname} "old_library='${_target_static_lib}'\n\n")
+ FILE(APPEND ${_laname} "# Libraries that this one depends upon.\n")
+ FILE(APPEND ${_laname} "dependency_libs='${_target_dependency_libs}'\n\n")
+ FILE(APPEND ${_laname} "# Names of additional weak libraries provided by this library\n")
+ FILE(APPEND ${_laname} "weak_library_names=''\n\n")
+ FILE(APPEND ${_laname} "# Version information for ${_laname}.\n")
+ FILE(APPEND ${_laname} "current=${_target_current}\n")
+ FILE(APPEND ${_laname} "age=${_target_age}\n")
+ FILE(APPEND ${_laname} "revision=${_target_revision}\n\n")
+ FILE(APPEND ${_laname} "# Is this an already installed library?\n")
+ FILE(APPEND ${_laname} "installed=${_target_installed}\n\n")
+ FILE(APPEND ${_laname} "# Should we warn about portability when linking against -modules?\n")
+ FILE(APPEND ${_laname} "shouldnotlink=${_target_shouldnotlink}\n\n")
+ FILE(APPEND ${_laname} "# Files to dlopen/dlpreopen\n")
+ FILE(APPEND ${_laname} "dlopen='${_target_dlopen}'\n")
+ FILE(APPEND ${_laname} "dlpreopen='${_target_dlpreopen}'\n\n")
+ FILE(APPEND ${_laname} "# Directory that this library needs to be installed in:\n")
+ FILE(APPEND ${_laname} "libdir='${CMAKE_INSTALL_PREFIX}${_install_DIR}'\n")
+# INSTALL( FILES ${_laname} ${_soname} DESTINATION ${CMAKE_INSTALL_PREFIX}${_install_DIR})
+ INSTALL( FILES ${_laname} DESTINATION ${CMAKE_INSTALL_PREFIX}${_install_DIR})
+ENDMACRO(CREATE_LIBTOOL_FILE)
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/cmake/TestModernIconv.c b/debian/wv2/wv2-0.4.2.dfsg.2/cmake/TestModernIconv.c
new file mode 100644
index 00000000..26b7e962
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/cmake/TestModernIconv.c
@@ -0,0 +1,41 @@
+#ifdef HAVE_ICONV_H
+#include <iconv.h>
+#endif
+#ifdef HAVE_SYS_ICONV_H
+#include <sys/iconv.h>
+#endif
+#include <stdlib.h>
+
+int check( const char* from, const char* to )
+{
+ iconv_t myConverter = iconv_open( to, from );
+
+ if ( myConverter != (iconv_t)-1 ) {
+ iconv_close( myConverter );
+ return 0;
+ }
+ else
+ return 1;
+}
+
+int main(int argc, char** argv)
+{
+ const char* from[] = { "CP874", "CP932", "CP936", "CP949",
+ "CP950", "CP1250", "CP1251", "CP1252",
+ "CP1253", "CP1254", "CP1255", "CP1256",
+ "CP1257", "koi8-r", 0 };
+ const char* to[] = { "UNICODELITTLE", "UNICODEBIG", 0 };
+ int fromIndex = 0;
+ int toIndex = 0;
+
+ while ( to[ toIndex ] != 0 ) {
+ while( from[ fromIndex ] != 0 ) {
+ if ( check( from[ fromIndex ], to[ toIndex ] ) != 0 )
+ exit( 1 );
+ fromIndex = fromIndex + 1;
+ }
+ toIndex = toIndex + 1;
+ fromIndex = 0;
+ }
+ exit( 0 );
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/cmake/TestModernZlib.c b/debian/wv2/wv2-0.4.2.dfsg.2/cmake/TestModernZlib.c
new file mode 100644
index 00000000..f7c6a042
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/cmake/TestModernZlib.c
@@ -0,0 +1,24 @@
+#include <string.h>
+#include <zlib.h>
+
+int version[3] = {0,0,0};
+
+static void decode(char *str)
+{
+ int n;
+ for (n = 0; n < 3 && str; n++) {
+ char *pnt = strchr(str, '.');
+ if (pnt) *pnt++ = '\0';
+ version[n] = atoi(str);
+ str = pnt;
+ }
+}
+
+int main(void) {
+ decode(strdup(zlibVersion()));
+ return
+ (version[0] < 1 ||
+ (version[0] == 1 &&
+ (version[1] < 1 ||
+ (version[1] == 1 && version[2] < 4))));
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/cmake/generate_converter.cmake b/debian/wv2/wv2-0.4.2.dfsg.2/cmake/generate_converter.cmake
new file mode 100644
index 00000000..7e00454f
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/cmake/generate_converter.cmake
@@ -0,0 +1,7 @@
+EXECUTE_PROCESS( COMMAND perl converter.pl generator_wword6.htm generator_wword8.htm
+ WORKING_DIRECTORY ${GENERATOR_DIR} )
+
+SET( generated_files convert.cpp convert.h )
+FOREACH( F ${generated_files} )
+ EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E copy_if_different ${F} ../${F} WORKING_DIRECTORY ${GENERATOR_DIR} )
+ENDFOREACH( F )
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/cmake/generate_scanner.cmake b/debian/wv2/wv2-0.4.2.dfsg.2/cmake/generate_scanner.cmake
new file mode 100644
index 00000000..bdf00037
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/cmake/generate_scanner.cmake
@@ -0,0 +1,15 @@
+EXECUTE_PROCESS( COMMAND perl generate.pl generator_wword6.htm Word95
+ WORKING_DIRECTORY ${GENERATOR_DIR} )
+
+EXECUTE_PROCESS( COMMAND perl generate.pl generator_wword8.htm Word97
+ WORKING_DIRECTORY ${GENERATOR_DIR} )
+
+SET( generated_files word95_generated.h word95_generated.cpp word97_generated.h word97_generated.cpp )
+FOREACH( F ${generated_files} )
+ EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E copy_if_different ${F} ../${F} WORKING_DIRECTORY ${GENERATOR_DIR} )
+ENDFOREACH( F )
+
+SET( generated_tests word95_test.cpp word97_test.cpp )
+FOREACH( T ${generated_tests} )
+ EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E copy_if_different ${T} ../../tests/${T} WORKING_DIRECTORY ${GENERATOR_DIR} )
+ENDFOREACH( T )
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/config.h.cmake b/debian/wv2/wv2-0.4.2.dfsg.2/config.h.cmake
new file mode 100644
index 00000000..d31cf65a
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/config.h.cmake
@@ -0,0 +1,113 @@
+/* config.h Generated from config.h.cmake by CMake */
+
+#ifndef LIBWV2_CONFIG_H
+#define LIBWV2_CONFIG_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#cmakedefine HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#cmakedefine HAVE_ERRNO_H
+
+/* Define to 1 if you have the <float.h> header file. */
+#cmakedefine HAVE_FLOAT_H 1
+
+/* Define if you have finite */
+#cmakedefine HAVE_FUNC_FINITE
+
+/* Define if you have isinf */
+#cmakedefine HAVE_FUNC_ISINF
+
+/* Define if you have isnan */
+#cmakedefine HAVE_FUNC_ISNAN
+
+/* Define if you have _finite */
+#cmakedefine HAVE_FUNC__FINITE
+
+/* Define to 1 if you have the <iconv.h> header file. */
+#cmakedefine HAVE_ICONV_H 1
+
+/* Define to 1 if you have the <ieeefp.h> header file. */
+#cmakedefine HAVE_IEEEFP_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#cmakedefine HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <math.h> header file. */
+#cmakedefine HAVE_MATH_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#cmakedefine HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#cmakedefine HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#cmakedefine HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#cmakedefine HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#cmakedefine HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/iconv.h> header file. */
+#cmakedefine HAVE_SYS_ICONV_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#cmakedefine HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#cmakedefine HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#cmakedefine HAVE_UNISTD_H 1
+
+/* Define to 1 if iconv requires const var in argument 2 */
+#cmakedefine ICONV_REQUIRES_CONST 1
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LT_OBJDIR
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* The size of `char', as computed by sizeof. */
+#cmakedefine SIZEOF_CHAR @SIZEOF_CHAR@
+
+/* The size of `int', as computed by sizeof. */
+#cmakedefine SIZEOF_INT @SIZEOF_INT@
+
+/* The size of `long', as computed by sizeof. */
+#cmakedefine SIZEOF_LONG @SIZEOF_LONG@
+
+/* The size of `short', as computed by sizeof. */
+#cmakedefine SIZEOF_SHORT @SIZEOF_SHORT@
+
+/* The size of `void *', as computed by sizeof. */
+#cmakedefine SIZEOF_VOID_P @SIZEOF_VOID_P@
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#cmakedefine WORDS_BIGENDIAN 1
+
+#ifdef ICONV_REQUIRES_CONST
+#define ICONV_CONST const
+#else
+#define ICONV_CONST
+#endif
+
+#endif /* ! LIBWV2_CONFIG_H */
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/README.Debian b/debian/wv2/wv2-0.4.2.dfsg.2/debian/README.Debian
new file mode 100644
index 00000000..daefcf24
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/README.Debian
@@ -0,0 +1,13 @@
+The wv2 source tarball has been repacked to remove the following
+documentation files for which the licence is unknown:
+
+ * The doc/ subdirectory
+ * src/generator/generator_wword6.htm
+ * src/generator/generator_wword8.htm
+
+You can find these files in the original source tarball, which you
+can download from here:
+
+http://sourceforge.net/projects/wvware/files/
+
+ -- Olly Betts <[email protected]> Thu, 30 May 2013 10:49:39 +0000
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/changelog b/debian/wv2/wv2-0.4.2.dfsg.2/debian/changelog
new file mode 100644
index 00000000..6a491b0e
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/changelog
@@ -0,0 +1,299 @@
+wv2 (0.4.2.dfsg.2-2debian11.0.0+1~a) bullseye; urgency=low
+
+ * Replace python dependency with python-all.
+
+ -- Slávek Banko <[email protected]> Tue, 07 Apr 2020 20:57:23 +0200
+
+wv2 (0.4.2.dfsg.2-2ubuntu20.04.0+0~a) focal; urgency=low
+
+ * Run "make test" directly to avoid differences between when dh_auto_test
+ thinks the testsuite should be run and when we do. (Closes: #718141)
+ * Enable LFS so that we can read files of CIFS shares.
+ * debian/rules: Simplify - dh compat 9 handles passing CPPFLAGS under
+ cmake.
+ * Support parsing end notes (new patch support-endnotes.patch from upstream
+ SVN).
+
+ -- Olly Betts <[email protected]> Thu, 29 Aug 2013 10:38:30 +1200
+
+wv2 (0.4.2.dfsg.2-1) unstable; urgency=low
+
+ * Repack to remove src/generator/generator_wword{6,8}.htm, which are
+ based on documents from Microsoft. These two files were documented as
+ removed in README.Debian, but actually still present.
+ * Improve wording in README.Debian.
+ * "Standards-Version: 3.9.4": No changes required.
+
+ -- Olly Betts <[email protected]> Thu, 30 May 2013 11:21:57 +0000
+
+wv2 (0.4.2.dfsg.1-10) unstable; urgency=low
+
+ * Fix to use -I options from libgsf's pkg-config so libxml headers are
+ found. (Closes: #707417)
+ * Honour DEB_BUILD_OPTIONS nocheck in debian/rules. (Closes: #685920)
+ * Fix double "-l" in output from wv2-config --libs. (LP: #1017413)
+
+ -- Olly Betts <[email protected]> Fri, 10 May 2013 12:06:41 +1200
+
+wv2 (0.4.2.dfsg.1-9.1) unstable; urgency=low
+
+ * Non-maintainer upload.
+ * [SECURITY] Fix "Buffer overflow":
+ add patch buffer-overflow.patch, taken from calligra git.
+ (Closes: #684078)
+
+ -- gregor herrmann <[email protected]> Sun, 26 Aug 2012 15:20:51 +0200
+
+wv2 (0.4.2.dfsg.1-9) unstable; urgency=low
+
+ * Apply hardening to CFLAGS too (patch from Simon Ruderich in private mail).
+ * Fix compatibility with glib 2.32 (Closes: #665626)
+
+ -- Olly Betts <[email protected]> Sun, 25 Mar 2012 04:04:44 +0000
+
+wv2 (0.4.2.dfsg.1-8) unstable; urgency=low
+
+ * "Standards-Version: 3.9.3": No changes required.
+ * Ensure hardening LDFLAGS are used by updating to debhelper compat level 9.
+ (Closes: #662009)
+
+ -- Olly Betts <[email protected]> Fri, 23 Mar 2012 09:30:09 +0000
+
+wv2 (0.4.2.dfsg.1-7) unstable; urgency=low
+
+ * The mips/mipsel issue appears to be due to the wv2 code assuming it knows
+ the bit pattern for NaN and Inf, so revert the change to disable
+ optimisation (which didn't actually work anyway) and add new patch
+ fix-nan-and-inf-for-mips.patch.
+
+ -- Olly Betts <[email protected]> Thu, 05 Jan 2012 05:14:37 +0000
+
+wv2 (0.4.2.dfsg.1-6) unstable; urgency=low
+
+ * Enabling hardening build flags also turned on optimisation, which results
+ in a bus error in handlertest on mips and mipsel. The backtrace is useless
+ so just disable optimisation again for these two archs.
+
+ -- Olly Betts <[email protected]> Sun, 01 Jan 2012 11:15:19 +0000
+
+wv2 (0.4.2.dfsg.1-5) unstable; urgency=low
+
+ * Enable hardened build flags.
+
+ -- Olly Betts <[email protected]> Wed, 28 Dec 2011 23:24:21 +0000
+
+wv2 (0.4.2.dfsg.1-4) unstable; urgency=low
+
+ * Fix avoid-writing-after-structures.patch to actually work.
+
+ -- Olly Betts <[email protected]> Thu, 01 Dec 2011 05:12:36 +0000
+
+wv2 (0.4.2.dfsg.1-3) unstable; urgency=low
+
+ * New patch avoid-writing-after-structures.patch to fix word95test and
+ word97test not to write after the end of word-aligned structures, fixing
+ FTBFS on sparc.
+
+ -- Olly Betts <[email protected]> Wed, 30 Nov 2011 14:23:07 +0000
+
+wv2 (0.4.2.dfsg.1-2) unstable; urgency=low
+
+ * New maintainer.
+
+ -- Olly Betts <[email protected]> Wed, 30 Nov 2011 13:01:02 +0000
+
+wv2 (0.4.2.dfsg.1-1.1) unstable; urgency=low
+
+ * Non-maintainer upload.
+ * Add patch fix-ftbfs-with-gold.patch to fix FTBFS with binutils-gold.
+ (Closes: #556686)
+ * Add patch fix-handling-empty-associatedstrings.patch to fix handling of
+ .doc files with an empty associated strings section. (Closes: #603868)
+ * Build with debugging messages disabled. (Closes: #603871)
+ * Drop leading article from short description.
+ * Actually run the testsuite, don't just build it (needs new patch
+ fix-tests.patch)
+ * "Standards-Version: 3.9.2":
+ + Include the BSD licence in debian/copyright rather than referring to
+ /usr/share/common-licenses/BSD.
+
+ -- Olly Betts <[email protected]> Wed, 30 Nov 2011 12:04:22 +0000
+
+wv2 (0.4.2.dfsg.1-1) unstable; urgency=low
+
+ * New upstream release.
+ * Switch to 3.0 (quilt) source format. No changes required further adding
+ debian/source/format.
+
+ -- Ana Beatriz Guerrero Lopez <[email protected]> Sat, 14 Nov 2009 00:28:32 +0100
+
+wv2 (0.4.1.dfsg-1) unstable; urgency=low
+
+ * New upstream release. "Another release, another bump soname".
+ * Update from upstream to build with GCC 4.4. (Closes: #548708)
+ * Bump soname fom libwv2-3 to libwv2-4, make changes accordingly.
+
+ -- Ana Beatriz Guerrero Lopez <[email protected]> Sat, 10 Oct 2009 18:10:30 +0200
+
+wv2 (0.4.0.dfsg-1) unstable; urgency=low
+
+ * New upstream release.
+
+ +++ Changes by Pino Toscano:
+
+ * Bump SONAME.
+ * Switch to dh, and bump debhelper requirements & compatibility to 7.
+ * wv2's build system is cmake now, so build-depend on it.
+ * Add dependency on ${misc:Depends}, given debhelper is used.
+ * Bump Standards-Version to 3.8.3, no changes required.
+ * Remove duplicate section from binary libwv2-3 in control.
+ * Update copyright.
+
+ -- Debian Qt/KDE Maintainers <[email protected]> Fri, 18 Sep 2009 17:59:51 +0200
+
+wv2 (0.3.1.dfsg-1) unstable; urgency=low
+
+ * Repack tarball and remove unlicesed documentation. Document this in
+ Debian.README.
+ * Update debian/copyright.
+
+ -- Ana Beatriz Guerrero Lopez <[email protected]> Fri, 07 Aug 2009 16:32:59 +0200
+
+wv2 (0.3.1-1) unstable; urgency=low
+
+ * New upstream release.
+ * Remove patches:
+ - gcc_4.3_fixes, merged upstream.
+ - 05_relibtoolize.dpatch, 50_autogen.dpatch, 10_wv2-config_static.dpatch,
+ obsolete.
+ - remove quilt patching stuff.
+ * Remove deprecated libstdc++-dev, it is being updated in build-essential.
+ * Rename libwv2-1c2 -> libwv2-2.
+ * Update to debhelper 6.
+ * Add Homepage field.
+ * Update debian/copyright.
+ * Update to Standards-Version: 3.8.2, no changes required.
+ * Update uploaders, remove Isaac.
+
+ -- Ana Beatriz Guerrero Lopez <[email protected]> Fri, 07 Aug 2009 00:31:33 +0200
+
+wv2 (0.2.3-2) unstable; urgency=low
+
+ * Update Standards-Version to 3.7.3.
+ * Update uploaders.
+ * Move patch system to quilt.
+ * Add gcc_4.3_fixes to fix problems with GCC 4.3. This patch adds a missing
+ include and hack away the #warning stuff. (Closes: #441614)
+ * Replace ${source:Version}) with (= ${binary:Version}) to make package
+ binNMUable.
+
+ -- Ana Beatriz Guerrero Lopez <[email protected]> Wed, 26 Dec 2007 08:32:36 +0100
+
+wv2 (0.2.3-1) unstable; urgency=low
+
+ * New upstream release.
+
+ +++ Changes by Christopher Martin:
+
+ * Drop the libwv2.la file from libwv2-dev, at the request of
+ J.H.M. Dassen (Ray). (Closes: #374332)
+
+ -- Debian Qt/KDE Maintainers <[email protected]> Sun, 18 Jun 2006 15:28:58 -0400
+
+wv2 (0.2.2-6) unstable; urgency=medium
+
+ +++ Changes by Christopher Martin:
+
+ * Add a patch which fixes CVE-2006-2197, missing boundary checks which could
+ allow the execution of arbitrary code. Urgency medium.
+
+ * Revamp patch system; should make further updates easier.
+
+ * Set Uploaders to the standard Qt/KDE team list.
+
+ +++ Changes by Pierre Habouzit:
+
+ * Add -DNDEBUG in the CFLAGS (no more horribly verbose debug output on
+ stderr; see wvlog.h). (Closes: #329109)
+
+ -- Debian Qt/KDE Maintainers <[email protected]> Sat, 17 Jun 2006 19:00:35 -0400
+
+wv2 (0.2.2-5) unstable; urgency=low
+
+ * wv2-config: introduce a "--static" option to provide options suitable
+ for static linking and have "--libs" output just "-lwv2", closes: #342889
+ * Update libtool (required to fix FTBFS in GNU/k*BSD), closes: #311988
+
+ -- Isaac Clerencia <[email protected]> Mon, 12 Dec 2005 08:36:00 +0100
+
+wv2 (0.2.2-4) unstable; urgency=low
+
+ +++ Changes by Isaac Clerencia:
+
+ * Rebuild against new libgsf-1-dev, making libwv2-1c2 installable in sid
+ again, closes: #338712
+
+ -- Debian Qt/KDE Maintainers <[email protected]> Sat, 12 Nov 2005 11:27:27 +0100
+
+wv2 (0.2.2-3) unstable; urgency=low
+
+ * Changed maintainer to the Debian Qt/KDE group (in coordination with
+ koffice, which has also changed maintainer to the Debian Qt/KDE group).
+
+ -- Ben Burton <[email protected]> Sun, 16 Oct 2005 02:07:54 +1000
+
+wv2 (0.2.2-2) unstable; urgency=low
+
+ * C++ ABI transition (g++-3.3 -> g++-4.0).
+ * Library package renamed from libwv2-1 to libwv2-1c2.
+ * Build-depends on c++abi2-dev, since the binaries do not depend on libstdc++.
+ * Made libwv2-dev depend on libstdc++-dev since it imports libstdc++ headers.
+ * Removed -pedantic from compilation flags to avoid HUGE_VAL error (#319553).
+ * Bumped standards-version to 3.6.2.1 (no changes required).
+
+ -- Ben Burton <[email protected]> Sat, 23 Jul 2005 10:20:38 +1000
+
+wv2 (0.2.2-1) unstable; urgency=low
+
+ * New upstream bugfix release.
+ * Builds under gcc 3.4 (closes: #274051).
+
+ -- Ben Burton <[email protected]> Thu, 14 Oct 2004 19:08:15 +1000
+
+wv2 (0.2.1-2) unstable; urgency=low
+
+ * Build-depends on zlib1g-dev, which no longer seems to be provided by
+ libxml2-dev (closes: #242971).
+
+ -- Ben Burton <[email protected]> Sun, 11 Apr 2004 07:36:57 +1000
+
+wv2 (0.2.1-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Ben Burton <[email protected]> Sun, 7 Dec 2003 20:37:52 +1100
+
+wv2 (0.1.9-1) unstable; urgency=low
+
+ * New upstream release.
+ * Bumped standards-version to 3.6.1.
+
+ -- Ben Burton <[email protected]> Mon, 29 Sep 2003 10:57:45 +1000
+
+wv2 (0.1.8-1) unstable; urgency=low
+
+ * New upstream release.
+ * Bumped standards-version to 3.6.0.
+
+ -- Ben Burton <[email protected]> Fri, 8 Aug 2003 08:58:07 +1000
+
+wv2 (0.0.9-1) unstable; urgency=low
+
+ * Initial Release (closes: #196455).
+ * Patched olestorage.cpp for type correctness with newer versions of
+ libgfs-1.
+ * Using AM_MAINTAINER_MODE.
+ * Updated config.{sub,guess}.
+
+ -- Ben Burton <[email protected]> Sat, 7 Jun 2003 15:30:53 +1000
+
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/compat b/debian/wv2/wv2-0.4.2.dfsg.2/debian/compat
new file mode 100644
index 00000000..ec635144
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/control b/debian/wv2/wv2-0.4.2.dfsg.2/debian/control
new file mode 100644
index 00000000..d2d0dda0
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/control
@@ -0,0 +1,29 @@
+Source: wv2
+Section: deps-r14/libs
+Priority: optional
+Maintainer: Olly Betts <[email protected]>
+Build-Depends: debhelper (>= 9), cmake, libglib2.0-dev, libgsf-1-dev (>= 1.14.0), libxml2-dev, zlib1g-dev, pkg-config, python-all
+Standards-Version: 3.9.4
+Homepage: http://wvware.sourceforge.net
+
+Package: libwv2-4
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Conflicts: libwv2-1
+Replaces: libwv2-1
+Description: library for accessing Microsoft Word documents
+ The wv2 library allows access to Microsoft Word documents, for the
+ purpose of converting them to other formats. This library is intended
+ as an eventual replacement for the wv library, used in the package wv.
+
+Package: libwv2-dev
+Architecture: any
+Section: deps-r14/libdevel
+Depends: libwv2-4 (= ${binary:Version}), libglib2.0-dev, libgsf-1-dev (>= 1.14.0), libxml2-dev, ${misc:Depends}
+Description: development files for Microsoft Word access library
+ The wv2 library allows access to Microsoft Word documents, for the
+ purpose of converting them to other formats. This library is intended
+ as an eventual replacement for the wv library, used in the package wv.
+ .
+ This package contains development files for using libwv2 within your own
+ projects.
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/copyright b/debian/wv2/wv2-0.4.2.dfsg.2/debian/copyright
new file mode 100644
index 00000000..d5c5e1eb
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/copyright
@@ -0,0 +1,91 @@
+This package was debianized by Ben Burton <[email protected]> on
+Sat, 7 Jun 2003 15:30:53 +1000.
+
+It was downloaded from: http://wvware.sourceforge.net
+
+Upstream Authors and copyright holders:
+
+Copyright: © 2001-2003 Werner Trobin <[email protected]>
+Copyright: © 1998-10-14 Eric Durbin
+Copyright: © 1999-2000 Harri Porten <[email protected]>
+Copyright: © 2003 KOffice Team
+Copyright: © 2001 S.R.Haque <[email protected]>
+Copyright: © 1999 Waldo Bastian <[email protected]>
+Copyright: © 2009 Benjamin Cail <[email protected]>
+Copyright: © 2008 Laurent Montel <[email protected]>
+Copyright: © 2009 Pau Garcia i Quiles <[email protected]>
+
+License (see below for exceptions)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ version 2 of the License.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+
+
+On Debian systems, the complete text of the GNU Lesser General Public
+License 2 can be found in the file /usr/share/common-licenses/LGPL-2
+
+
+Exceptions:
+
+src/crc32.{c,h} are under the public domain.
+
+src/zcodec.* are under the LGPL2.1, header says:
+
+
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+
+On Debian systems, the complete text of the GNU Lesser General Public
+License 2.1 can be found in the file /usr/share/common-licenses/LGPL-2-1.
+
+cmake/Find{GLIB2,LIBGSF}.cmake are under the BSD license:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-4.install b/debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-4.install
new file mode 100644
index 00000000..b6a6d0f7
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-4.install
@@ -0,0 +1 @@
+usr/lib/libwv2.so.*
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-4.shlibs b/debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-4.shlibs
new file mode 100644
index 00000000..363ce0f2
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-4.shlibs
@@ -0,0 +1 @@
+libwv2 4 libwv2-4
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-dev.docs b/debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-dev.docs
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-dev.docs
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-dev.install b/debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-dev.install
new file mode 100644
index 00000000..c4844e76
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-dev.install
@@ -0,0 +1,3 @@
+usr/bin/wv2-config
+usr/include/wv2
+usr/lib/libwv2.so
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-dev.manpages b/debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-dev.manpages
new file mode 100644
index 00000000..5e652484
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/libwv2-dev.manpages
@@ -0,0 +1 @@
+debian/wv2-config.1
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/avoid-writing-after-structures.patch b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/avoid-writing-after-structures.patch
new file mode 100644
index 00000000..38cf9bbe
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/avoid-writing-after-structures.patch
@@ -0,0 +1,1421 @@
+Description: Avoid writing after word-aligned structures
+ Fixes FTBFS on sparc.
+Author: Olly Betts <[email protected]>
+
+---
+Origin: debian
+Forwarded: no
+Last-Update: 2011-12-01
+
+--- wv2-0.4.2.dfsg.1.orig/tests/word95_test.cpp
++++ wv2-0.4.2.dfsg.1/tests/word95_test.cpp
+@@ -32,18 +32,18 @@ int main(int, char**) {
+ srand( time( 0 ) );
+
+ // Some "global" variables...
+- int *ptr=0; // used to "initialize" the structs
++ char *ptr=0; // used to "initialize" the structs
+ int tmp;
+ std::cout << "Testing the Word95 structures..." << std::endl;
+ // Begin of writing test for DTTM
+ std::cout << "Testing writing for DTTM: ";
+ DTTM dttm1;
+- // Initilaize the struct with random data
+- tmp=sizeof(DTTM)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &dttm1 );
++ // Initialize the struct with random data
++ tmp=sizeof(DTTM);
++ ptr=reinterpret_cast<char*>( &dttm1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DTTM) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(dttm1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -55,12 +55,12 @@ int main(int, char**) {
+ // Begin of writing test for PRM2
+ std::cout << "Testing writing for PRM2: ";
+ PRM2 prm21;
+- // Initilaize the struct with random data
+- tmp=sizeof(PRM2)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &prm21 );
++ // Initialize the struct with random data
++ tmp=sizeof(PRM2);
++ ptr=reinterpret_cast<char*>( &prm21 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PRM2) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(prm21.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -71,12 +71,12 @@ int main(int, char**) {
+ // Begin of writing test for PRM
+ std::cout << "Testing writing for PRM: ";
+ PRM prm1;
+- // Initilaize the struct with random data
+- tmp=sizeof(PRM)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &prm1 );
++ // Initialize the struct with random data
++ tmp=sizeof(PRM);
++ ptr=reinterpret_cast<char*>( &prm1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PRM) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(prm1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -87,12 +87,12 @@ int main(int, char**) {
+ // Begin of writing test for SHD
+ std::cout << "Testing writing for SHD: ";
+ SHD shd1;
+- // Initilaize the struct with random data
+- tmp=sizeof(SHD)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &shd1 );
++ // Initialize the struct with random data
++ tmp=sizeof(SHD);
++ ptr=reinterpret_cast<char*>( &shd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(SHD) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(shd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -104,12 +104,12 @@ int main(int, char**) {
+ // Begin of writing test for PHE
+ std::cout << "Testing writing for PHE: ";
+ PHE phe1;
+- // Initilaize the struct with random data
+- tmp=sizeof(PHE)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &phe1 );
++ // Initialize the struct with random data
++ tmp=sizeof(PHE);
++ ptr=reinterpret_cast<char*>( &phe1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PHE) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(phe1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -121,12 +121,12 @@ int main(int, char**) {
+ // Begin of writing test for BRC
+ std::cout << "Testing writing for BRC: ";
+ BRC brc1;
+- // Initilaize the struct with random data
+- tmp=sizeof(BRC)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &brc1 );
++ // Initialize the struct with random data
++ tmp=sizeof(BRC);
++ ptr=reinterpret_cast<char*>( &brc1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BRC) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(brc1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -138,12 +138,12 @@ int main(int, char**) {
+ // Begin of writing test for TLP
+ std::cout << "Testing writing for TLP: ";
+ TLP tlp1;
+- // Initilaize the struct with random data
+- tmp=sizeof(TLP)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &tlp1 );
++ // Initialize the struct with random data
++ tmp=sizeof(TLP);
++ ptr=reinterpret_cast<char*>( &tlp1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(TLP) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(tlp1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -155,12 +155,12 @@ int main(int, char**) {
+ // Begin of writing test for TC
+ std::cout << "Testing writing for TC: ";
+ TC tc1;
+- // Initilaize the struct with random data
+- tmp=sizeof(TC)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &tc1 );
++ // Initialize the struct with random data
++ tmp=sizeof(TC);
++ ptr=reinterpret_cast<char*>( &tc1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(TC) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(tc1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -172,12 +172,12 @@ int main(int, char**) {
+ // Begin of writing test for DPHEAD
+ std::cout << "Testing writing for DPHEAD: ";
+ DPHEAD dphead1;
+- // Initilaize the struct with random data
+- tmp=sizeof(DPHEAD)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &dphead1 );
++ // Initialize the struct with random data
++ tmp=sizeof(DPHEAD);
++ ptr=reinterpret_cast<char*>( &dphead1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DPHEAD) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(dphead1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -188,12 +188,12 @@ int main(int, char**) {
+ // Begin of writing test for DPTXBX
+ std::cout << "Testing writing for DPTXBX: ";
+ DPTXBX dptxbx1;
+- // Initilaize the struct with random data
+- tmp=sizeof(DPTXBX)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &dptxbx1 );
++ // Initialize the struct with random data
++ tmp=sizeof(DPTXBX);
++ ptr=reinterpret_cast<char*>( &dptxbx1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DPTXBX) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(dptxbx1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -207,12 +207,12 @@ int main(int, char**) {
+ // Begin of writing test for ANLD
+ std::cout << "Testing writing for ANLD: ";
+ ANLD anld1;
+- // Initilaize the struct with random data
+- tmp=sizeof(ANLD)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &anld1 );
++ // Initialize the struct with random data
++ tmp=sizeof(ANLD);
++ ptr=reinterpret_cast<char*>( &anld1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(ANLD) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(anld1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -224,12 +224,12 @@ int main(int, char**) {
+ // Begin of writing test for ANLV
+ std::cout << "Testing writing for ANLV: ";
+ ANLV anlv1;
+- // Initilaize the struct with random data
+- tmp=sizeof(ANLV)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &anlv1 );
++ // Initialize the struct with random data
++ tmp=sizeof(ANLV);
++ ptr=reinterpret_cast<char*>( &anlv1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(ANLV) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(anlv1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -241,12 +241,12 @@ int main(int, char**) {
+ // Begin of writing test for BKF
+ std::cout << "Testing writing for BKF: ";
+ BKF bkf1;
+- // Initilaize the struct with random data
+- tmp=sizeof(BKF)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &bkf1 );
++ // Initialize the struct with random data
++ tmp=sizeof(BKF);
++ ptr=reinterpret_cast<char*>( &bkf1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BKF) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(bkf1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -257,12 +257,12 @@ int main(int, char**) {
+ // Begin of writing test for BKL
+ std::cout << "Testing writing for BKL: ";
+ BKL bkl1;
+- // Initilaize the struct with random data
+- tmp=sizeof(BKL)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &bkl1 );
++ // Initialize the struct with random data
++ tmp=sizeof(BKL);
++ ptr=reinterpret_cast<char*>( &bkl1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BKL) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(bkl1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -273,12 +273,12 @@ int main(int, char**) {
+ // Begin of writing test for BRC10
+ std::cout << "Testing writing for BRC10: ";
+ BRC10 brc101;
+- // Initilaize the struct with random data
+- tmp=sizeof(BRC10)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &brc101 );
++ // Initialize the struct with random data
++ tmp=sizeof(BRC10);
++ ptr=reinterpret_cast<char*>( &brc101 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BRC10) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(brc101.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -289,12 +289,12 @@ int main(int, char**) {
+ // Begin of writing test for BTE
+ std::cout << "Testing writing for BTE: ";
+ BTE bte1;
+- // Initilaize the struct with random data
+- tmp=sizeof(BTE)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &bte1 );
++ // Initialize the struct with random data
++ tmp=sizeof(BTE);
++ ptr=reinterpret_cast<char*>( &bte1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BTE) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(bte1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -305,12 +305,12 @@ int main(int, char**) {
+ // Begin of writing test for CHP
+ std::cout << "Testing writing for CHP: ";
+ CHP chp1;
+- // Initilaize the struct with random data
+- tmp=sizeof(CHP)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &chp1 );
++ // Initialize the struct with random data
++ tmp=sizeof(CHP);
++ ptr=reinterpret_cast<char*>( &chp1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(CHP) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(chp1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -322,12 +322,12 @@ int main(int, char**) {
+ // Begin of writing test for DCS
+ std::cout << "Testing writing for DCS: ";
+ DCS dcs1;
+- // Initilaize the struct with random data
+- tmp=sizeof(DCS)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &dcs1 );
++ // Initialize the struct with random data
++ tmp=sizeof(DCS);
++ ptr=reinterpret_cast<char*>( &dcs1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DCS) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(dcs1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -339,12 +339,12 @@ int main(int, char**) {
+ // Begin of writing test for DO
+ std::cout << "Testing writing for DO: ";
+ DO do1;
+- // Initilaize the struct with random data
+- tmp=sizeof(DO)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &do1 );
++ // Initialize the struct with random data
++ tmp=sizeof(DO);
++ ptr=reinterpret_cast<char*>( &do1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DO) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(do1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -355,12 +355,12 @@ int main(int, char**) {
+ // Begin of writing test for DOP
+ std::cout << "Testing writing for DOP: ";
+ DOP dop1;
+- // Initilaize the struct with random data
+- tmp=sizeof(DOP)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &dop1 );
++ // Initialize the struct with random data
++ tmp=sizeof(DOP);
++ ptr=reinterpret_cast<char*>( &dop1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DOP) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(dop1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -371,12 +371,12 @@ int main(int, char**) {
+ // Begin of writing test for DPARC
+ std::cout << "Testing writing for DPARC: ";
+ DPARC dparc1;
+- // Initilaize the struct with random data
+- tmp=sizeof(DPARC)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &dparc1 );
++ // Initialize the struct with random data
++ tmp=sizeof(DPARC);
++ ptr=reinterpret_cast<char*>( &dparc1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DPARC) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(dparc1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -387,12 +387,12 @@ int main(int, char**) {
+ // Begin of writing test for DPELLIPSE
+ std::cout << "Testing writing for DPELLIPSE: ";
+ DPELLIPSE dpellipse1;
+- // Initilaize the struct with random data
+- tmp=sizeof(DPELLIPSE)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &dpellipse1 );
++ // Initialize the struct with random data
++ tmp=sizeof(DPELLIPSE);
++ ptr=reinterpret_cast<char*>( &dpellipse1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DPELLIPSE) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(dpellipse1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -403,12 +403,12 @@ int main(int, char**) {
+ // Begin of writing test for DPLINE
+ std::cout << "Testing writing for DPLINE: ";
+ DPLINE dpline1;
+- // Initilaize the struct with random data
+- tmp=sizeof(DPLINE)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &dpline1 );
++ // Initialize the struct with random data
++ tmp=sizeof(DPLINE);
++ ptr=reinterpret_cast<char*>( &dpline1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DPLINE) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(dpline1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -419,12 +419,12 @@ int main(int, char**) {
+ // Begin of writing test for DPRECT
+ std::cout << "Testing writing for DPRECT: ";
+ DPRECT dprect1;
+- // Initilaize the struct with random data
+- tmp=sizeof(DPRECT)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &dprect1 );
++ // Initialize the struct with random data
++ tmp=sizeof(DPRECT);
++ ptr=reinterpret_cast<char*>( &dprect1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DPRECT) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(dprect1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -435,12 +435,12 @@ int main(int, char**) {
+ // Begin of writing test for DPSAMPLE
+ std::cout << "Testing writing for DPSAMPLE: ";
+ DPSAMPLE dpsample1;
+- // Initilaize the struct with random data
+- tmp=sizeof(DPSAMPLE)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &dpsample1 );
++ // Initialize the struct with random data
++ tmp=sizeof(DPSAMPLE);
++ ptr=reinterpret_cast<char*>( &dpsample1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DPSAMPLE) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(dpsample1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -451,12 +451,12 @@ int main(int, char**) {
+ // Begin of writing test for FDOA
+ std::cout << "Testing writing for FDOA: ";
+ FDOA fdoa1;
+- // Initilaize the struct with random data
+- tmp=sizeof(FDOA)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &fdoa1 );
++ // Initialize the struct with random data
++ tmp=sizeof(FDOA);
++ ptr=reinterpret_cast<char*>( &fdoa1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(FDOA) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(fdoa1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -467,12 +467,12 @@ int main(int, char**) {
+ // Begin of writing test for FIB
+ std::cout << "Testing writing for FIB: ";
+ FIB fib1;
+- // Initilaize the struct with random data
+- tmp=sizeof(FIB)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &fib1 );
++ // Initialize the struct with random data
++ tmp=sizeof(FIB);
++ ptr=reinterpret_cast<char*>( &fib1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(FIB) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(fib1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -483,12 +483,12 @@ int main(int, char**) {
+ // Begin of writing test for LSPD
+ std::cout << "Testing writing for LSPD: ";
+ LSPD lspd1;
+- // Initilaize the struct with random data
+- tmp=sizeof(LSPD)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &lspd1 );
++ // Initialize the struct with random data
++ tmp=sizeof(LSPD);
++ ptr=reinterpret_cast<char*>( &lspd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(LSPD) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(lspd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -500,12 +500,12 @@ int main(int, char**) {
+ // Begin of writing test for METAFILEPICT
+ std::cout << "Testing writing for METAFILEPICT: ";
+ METAFILEPICT metafilepict1;
+- // Initilaize the struct with random data
+- tmp=sizeof(METAFILEPICT)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &metafilepict1 );
++ // Initialize the struct with random data
++ tmp=sizeof(METAFILEPICT);
++ ptr=reinterpret_cast<char*>( &metafilepict1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(METAFILEPICT) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(metafilepict1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -517,12 +517,12 @@ int main(int, char**) {
+ // Begin of writing test for OBJHEADER
+ std::cout << "Testing writing for OBJHEADER: ";
+ OBJHEADER objheader1;
+- // Initilaize the struct with random data
+- tmp=sizeof(OBJHEADER)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &objheader1 );
++ // Initialize the struct with random data
++ tmp=sizeof(OBJHEADER);
++ ptr=reinterpret_cast<char*>( &objheader1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(OBJHEADER) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(objheader1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -533,12 +533,12 @@ int main(int, char**) {
+ // Begin of writing test for OLST
+ std::cout << "Testing writing for OLST: ";
+ OLST olst1;
+- // Initilaize the struct with random data
+- tmp=sizeof(OLST)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &olst1 );
++ // Initialize the struct with random data
++ tmp=sizeof(OLST);
++ ptr=reinterpret_cast<char*>( &olst1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(OLST) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(olst1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -550,12 +550,12 @@ int main(int, char**) {
+ // Begin of writing test for PCD
+ std::cout << "Testing writing for PCD: ";
+ PCD pcd1;
+- // Initilaize the struct with random data
+- tmp=sizeof(PCD)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &pcd1 );
++ // Initialize the struct with random data
++ tmp=sizeof(PCD);
++ ptr=reinterpret_cast<char*>( &pcd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PCD) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(pcd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -566,12 +566,12 @@ int main(int, char**) {
+ // Begin of writing test for PGD
+ std::cout << "Testing writing for PGD: ";
+ PGD pgd1;
+- // Initilaize the struct with random data
+- tmp=sizeof(PGD)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &pgd1 );
++ // Initialize the struct with random data
++ tmp=sizeof(PGD);
++ ptr=reinterpret_cast<char*>( &pgd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PGD) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(pgd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -582,12 +582,12 @@ int main(int, char**) {
+ // Begin of writing test for PICF
+ std::cout << "Testing writing for PICF: ";
+ PICF picf1;
+- // Initilaize the struct with random data
+- tmp=sizeof(PICF)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &picf1 );
++ // Initialize the struct with random data
++ tmp=sizeof(PICF);
++ ptr=reinterpret_cast<char*>( &picf1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PICF) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(picf1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -599,12 +599,12 @@ int main(int, char**) {
+ // Begin of writing test for SED
+ std::cout << "Testing writing for SED: ";
+ SED sed1;
+- // Initilaize the struct with random data
+- tmp=sizeof(SED)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &sed1 );
++ // Initialize the struct with random data
++ tmp=sizeof(SED);
++ ptr=reinterpret_cast<char*>( &sed1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(SED) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(sed1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -618,12 +618,12 @@ int main(int, char**) {
+ // Begin of writing test for STSHI
+ std::cout << "Testing writing for STSHI: ";
+ STSHI stshi1;
+- // Initilaize the struct with random data
+- tmp=sizeof(STSHI)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &stshi1 );
++ // Initialize the struct with random data
++ tmp=sizeof(STSHI);
++ ptr=reinterpret_cast<char*>( &stshi1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(STSHI) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(stshi1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+--- wv2-0.4.2.dfsg.1.orig/tests/word97_test.cpp
++++ wv2-0.4.2.dfsg.1/tests/word97_test.cpp
+@@ -32,18 +32,18 @@
+ srand( time( 0 ) );
+
+ // Some "global" variables...
+- int *ptr=0; // used to "initialize" the structs
++ char *ptr=0; // used to "initialize" the structs
+ int tmp;
+ std::cout << "Testing the Word97 structures..." << std::endl;
+ // Begin of writing test for DTTM
+ std::cout << "Testing writing for DTTM: ";
+ DTTM dttm1;
+- // Initilaize the struct with random data
+- tmp=sizeof(DTTM)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &dttm1 );
++ // Initialize the struct with random data
++ tmp=sizeof(DTTM);
++ ptr=reinterpret_cast<char*>( &dttm1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DTTM) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(dttm1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -55,12 +55,12 @@ int main(int, char**) {
+ // Begin of writing test for DOPTYPOGRAPHY
+ std::cout << "Testing writing for DOPTYPOGRAPHY: ";
+ DOPTYPOGRAPHY doptypography1;
+- // Initilaize the struct with random data
+- tmp=sizeof(DOPTYPOGRAPHY)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &doptypography1 );
++ // Initialize the struct with random data
++ tmp=sizeof(DOPTYPOGRAPHY);
++ ptr=reinterpret_cast<char*>( &doptypography1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DOPTYPOGRAPHY) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(doptypography1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -71,12 +71,12 @@ int main(int, char**) {
+ // Begin of writing test for PRM2
+ std::cout << "Testing writing for PRM2: ";
+ PRM2 prm21;
+- // Initilaize the struct with random data
+- tmp=sizeof(PRM2)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &prm21 );
++ // Initialize the struct with random data
++ tmp=sizeof(PRM2);
++ ptr=reinterpret_cast<char*>( &prm21 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PRM2) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(prm21.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -87,12 +87,12 @@ int main(int, char**) {
+ // Begin of writing test for PRM
+ std::cout << "Testing writing for PRM: ";
+ PRM prm1;
+- // Initilaize the struct with random data
+- tmp=sizeof(PRM)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &prm1 );
++ // Initialize the struct with random data
++ tmp=sizeof(PRM);
++ ptr=reinterpret_cast<char*>( &prm1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PRM) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(prm1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -103,12 +103,12 @@ int main(int, char**) {
+ // Begin of writing test for SHD
+ std::cout << "Testing writing for SHD: ";
+ SHD shd1;
+- // Initilaize the struct with random data
+- tmp=sizeof(SHD)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &shd1 );
++ // Initialize the struct with random data
++ tmp=sizeof(SHD);
++ ptr=reinterpret_cast<char*>( &shd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(SHD) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(shd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -120,12 +120,12 @@ int main(int, char**) {
+ // Begin of writing test for PHE
+ std::cout << "Testing writing for PHE: ";
+ PHE phe1;
+- // Initilaize the struct with random data
+- tmp=sizeof(PHE)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &phe1 );
++ // Initialize the struct with random data
++ tmp=sizeof(PHE);
++ ptr=reinterpret_cast<char*>( &phe1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PHE) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(phe1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -137,12 +137,12 @@ int main(int, char**) {
+ // Begin of writing test for BRC
+ std::cout << "Testing writing for BRC: ";
+ BRC brc1;
+- // Initilaize the struct with random data
+- tmp=sizeof(BRC)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &brc1 );
++ // Initialize the struct with random data
++ tmp=sizeof(BRC);
++ ptr=reinterpret_cast<char*>( &brc1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BRC) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(brc1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -154,12 +154,12 @@ int main(int, char**) {
+ // Begin of writing test for TLP
+ std::cout << "Testing writing for TLP: ";
+ TLP tlp1;
+- // Initilaize the struct with random data
+- tmp=sizeof(TLP)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &tlp1 );
++ // Initialize the struct with random data
++ tmp=sizeof(TLP);
++ ptr=reinterpret_cast<char*>( &tlp1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(TLP) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(tlp1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -171,12 +171,12 @@ int main(int, char**) {
+ // Begin of writing test for TC
+ std::cout << "Testing writing for TC: ";
+ TC tc1;
+- // Initilaize the struct with random data
+- tmp=sizeof(TC)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &tc1 );
++ // Initialize the struct with random data
++ tmp=sizeof(TC);
++ ptr=reinterpret_cast<char*>( &tc1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(TC) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(tc1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -188,12 +188,12 @@ int main(int, char**) {
+ // Begin of writing test for ANLD
+ std::cout << "Testing writing for ANLD: ";
+ ANLD anld1;
+- // Initilaize the struct with random data
+- tmp=sizeof(ANLD)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &anld1 );
++ // Initialize the struct with random data
++ tmp=sizeof(ANLD);
++ ptr=reinterpret_cast<char*>( &anld1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(ANLD) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(anld1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -205,12 +205,12 @@ int main(int, char**) {
+ // Begin of writing test for ANLV
+ std::cout << "Testing writing for ANLV: ";
+ ANLV anlv1;
+- // Initilaize the struct with random data
+- tmp=sizeof(ANLV)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &anlv1 );
++ // Initialize the struct with random data
++ tmp=sizeof(ANLV);
++ ptr=reinterpret_cast<char*>( &anlv1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(ANLV) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(anlv1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -222,12 +222,12 @@ int main(int, char**) {
+ // Begin of writing test for ASUMY
+ std::cout << "Testing writing for ASUMY: ";
+ ASUMY asumy1;
+- // Initilaize the struct with random data
+- tmp=sizeof(ASUMY)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &asumy1 );
++ // Initialize the struct with random data
++ tmp=sizeof(ASUMY);
++ ptr=reinterpret_cast<char*>( &asumy1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(ASUMY) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(asumy1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -238,12 +238,12 @@ int main(int, char**) {
+ // Begin of writing test for ASUMYI
+ std::cout << "Testing writing for ASUMYI: ";
+ ASUMYI asumyi1;
+- // Initilaize the struct with random data
+- tmp=sizeof(ASUMYI)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &asumyi1 );
++ // Initialize the struct with random data
++ tmp=sizeof(ASUMYI);
++ ptr=reinterpret_cast<char*>( &asumyi1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(ASUMYI) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(asumyi1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -254,12 +254,12 @@ int main(int, char**) {
+ // Begin of writing test for ATRD
+ std::cout << "Testing writing for ATRD: ";
+ ATRD atrd1;
+- // Initilaize the struct with random data
+- tmp=sizeof(ATRD)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &atrd1 );
++ // Initialize the struct with random data
++ tmp=sizeof(ATRD);
++ ptr=reinterpret_cast<char*>( &atrd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(ATRD) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(atrd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -270,12 +270,12 @@ int main(int, char**) {
+ // Begin of writing test for BKD
+ std::cout << "Testing writing for BKD: ";
+ BKD bkd1;
+- // Initilaize the struct with random data
+- tmp=sizeof(BKD)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &bkd1 );
++ // Initialize the struct with random data
++ tmp=sizeof(BKD);
++ ptr=reinterpret_cast<char*>( &bkd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BKD) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(bkd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -286,12 +286,12 @@ int main(int, char**) {
+ // Begin of writing test for BKF
+ std::cout << "Testing writing for BKF: ";
+ BKF bkf1;
+- // Initilaize the struct with random data
+- tmp=sizeof(BKF)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &bkf1 );
++ // Initialize the struct with random data
++ tmp=sizeof(BKF);
++ ptr=reinterpret_cast<char*>( &bkf1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BKF) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(bkf1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -302,12 +302,12 @@ int main(int, char**) {
+ // Begin of writing test for BKL
+ std::cout << "Testing writing for BKL: ";
+ BKL bkl1;
+- // Initilaize the struct with random data
+- tmp=sizeof(BKL)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &bkl1 );
++ // Initialize the struct with random data
++ tmp=sizeof(BKL);
++ ptr=reinterpret_cast<char*>( &bkl1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BKL) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(bkl1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -318,12 +318,12 @@ int main(int, char**) {
+ // Begin of writing test for BRC10
+ std::cout << "Testing writing for BRC10: ";
+ BRC10 brc101;
+- // Initilaize the struct with random data
+- tmp=sizeof(BRC10)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &brc101 );
++ // Initialize the struct with random data
++ tmp=sizeof(BRC10);
++ ptr=reinterpret_cast<char*>( &brc101 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BRC10) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(brc101.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -334,12 +334,12 @@ int main(int, char**) {
+ // Begin of writing test for BTE
+ std::cout << "Testing writing for BTE: ";
+ BTE bte1;
+- // Initilaize the struct with random data
+- tmp=sizeof(BTE)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &bte1 );
++ // Initialize the struct with random data
++ tmp=sizeof(BTE);
++ ptr=reinterpret_cast<char*>( &bte1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BTE) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(bte1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -350,12 +350,12 @@ int main(int, char**) {
+ // Begin of writing test for CHP
+ std::cout << "Testing writing for CHP: ";
+ CHP chp1;
+- // Initilaize the struct with random data
+- tmp=sizeof(CHP)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &chp1 );
++ // Initialize the struct with random data
++ tmp=sizeof(CHP);
++ ptr=reinterpret_cast<char*>( &chp1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(CHP) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(chp1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -367,12 +367,12 @@ int main(int, char**) {
+ // Begin of writing test for DCS
+ std::cout << "Testing writing for DCS: ";
+ DCS dcs1;
+- // Initilaize the struct with random data
+- tmp=sizeof(DCS)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &dcs1 );
++ // Initialize the struct with random data
++ tmp=sizeof(DCS);
++ ptr=reinterpret_cast<char*>( &dcs1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DCS) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(dcs1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -384,12 +384,12 @@ int main(int, char**) {
+ // Begin of writing test for DOGRID
+ std::cout << "Testing writing for DOGRID: ";
+ DOGRID dogrid1;
+- // Initilaize the struct with random data
+- tmp=sizeof(DOGRID)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &dogrid1 );
++ // Initialize the struct with random data
++ tmp=sizeof(DOGRID);
++ ptr=reinterpret_cast<char*>( &dogrid1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DOGRID) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(dogrid1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -400,12 +400,12 @@ int main(int, char**) {
+ // Begin of writing test for DOP
+ std::cout << "Testing writing for DOP: ";
+ DOP dop1;
+- // Initilaize the struct with random data
+- tmp=sizeof(DOP)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &dop1 );
++ // Initialize the struct with random data
++ tmp=sizeof(DOP);
++ ptr=reinterpret_cast<char*>( &dop1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DOP) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(dop1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -416,12 +416,12 @@ int main(int, char**) {
+ // Begin of writing test for FIB
+ std::cout << "Testing writing for FIB: ";
+ FIB fib1;
+- // Initilaize the struct with random data
+- tmp=sizeof(FIB)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &fib1 );
++ // Initialize the struct with random data
++ tmp=sizeof(FIB);
++ ptr=reinterpret_cast<char*>( &fib1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(FIB) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(fib1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -432,12 +432,12 @@ int main(int, char**) {
+ // Begin of writing test for FIBFCLCB
+ std::cout << "Testing writing for FIBFCLCB: ";
+ FIBFCLCB fibfclcb1;
+- // Initilaize the struct with random data
+- tmp=sizeof(FIBFCLCB)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &fibfclcb1 );
++ // Initialize the struct with random data
++ tmp=sizeof(FIBFCLCB);
++ ptr=reinterpret_cast<char*>( &fibfclcb1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(FIBFCLCB) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(fibfclcb1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -448,12 +448,12 @@ int main(int, char**) {
+ // Begin of writing test for FRD
+ std::cout << "Testing writing for FRD: ";
+ FRD frd1;
+- // Initilaize the struct with random data
+- tmp=sizeof(FRD)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &frd1 );
++ // Initialize the struct with random data
++ tmp=sizeof(FRD);
++ ptr=reinterpret_cast<char*>( &frd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(FRD) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(frd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -464,12 +464,12 @@ int main(int, char**) {
+ // Begin of writing test for FSPA
+ std::cout << "Testing writing for FSPA: ";
+ FSPA fspa1;
+- // Initilaize the struct with random data
+- tmp=sizeof(FSPA)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &fspa1 );
++ // Initialize the struct with random data
++ tmp=sizeof(FSPA);
++ ptr=reinterpret_cast<char*>( &fspa1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(FSPA) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(fspa1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -480,12 +480,12 @@ int main(int, char**) {
+ // Begin of writing test for FTXBXS
+ std::cout << "Testing writing for FTXBXS: ";
+ FTXBXS ftxbxs1;
+- // Initilaize the struct with random data
+- tmp=sizeof(FTXBXS)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &ftxbxs1 );
++ // Initialize the struct with random data
++ tmp=sizeof(FTXBXS);
++ ptr=reinterpret_cast<char*>( &ftxbxs1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(FTXBXS) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(ftxbxs1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -496,12 +496,12 @@ int main(int, char**) {
+ // Begin of writing test for LFO
+ std::cout << "Testing writing for LFO: ";
+ LFO lfo1;
+- // Initilaize the struct with random data
+- tmp=sizeof(LFO)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &lfo1 );
++ // Initialize the struct with random data
++ tmp=sizeof(LFO);
++ ptr=reinterpret_cast<char*>( &lfo1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(LFO) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(lfo1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -512,12 +512,12 @@ int main(int, char**) {
+ // Begin of writing test for LFOLVL
+ std::cout << "Testing writing for LFOLVL: ";
+ LFOLVL lfolvl1;
+- // Initilaize the struct with random data
+- tmp=sizeof(LFOLVL)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &lfolvl1 );
++ // Initialize the struct with random data
++ tmp=sizeof(LFOLVL);
++ ptr=reinterpret_cast<char*>( &lfolvl1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(LFOLVL) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(lfolvl1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -528,12 +528,12 @@ int main(int, char**) {
+ // Begin of writing test for LSPD
+ std::cout << "Testing writing for LSPD: ";
+ LSPD lspd1;
+- // Initilaize the struct with random data
+- tmp=sizeof(LSPD)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &lspd1 );
++ // Initialize the struct with random data
++ tmp=sizeof(LSPD);
++ ptr=reinterpret_cast<char*>( &lspd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(LSPD) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(lspd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -545,12 +545,12 @@ int main(int, char**) {
+ // Begin of writing test for LSTF
+ std::cout << "Testing writing for LSTF: ";
+ LSTF lstf1;
+- // Initilaize the struct with random data
+- tmp=sizeof(LSTF)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &lstf1 );
++ // Initialize the struct with random data
++ tmp=sizeof(LSTF);
++ ptr=reinterpret_cast<char*>( &lstf1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(LSTF) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(lstf1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -561,12 +561,12 @@ int main(int, char**) {
+ // Begin of writing test for LVLF
+ std::cout << "Testing writing for LVLF: ";
+ LVLF lvlf1;
+- // Initilaize the struct with random data
+- tmp=sizeof(LVLF)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &lvlf1 );
++ // Initialize the struct with random data
++ tmp=sizeof(LVLF);
++ ptr=reinterpret_cast<char*>( &lvlf1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(LVLF) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(lvlf1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -577,12 +577,12 @@ int main(int, char**) {
+ // Begin of writing test for METAFILEPICT
+ std::cout << "Testing writing for METAFILEPICT: ";
+ METAFILEPICT metafilepict1;
+- // Initilaize the struct with random data
+- tmp=sizeof(METAFILEPICT)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &metafilepict1 );
++ // Initialize the struct with random data
++ tmp=sizeof(METAFILEPICT);
++ ptr=reinterpret_cast<char*>( &metafilepict1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(METAFILEPICT) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(metafilepict1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -594,12 +594,12 @@ int main(int, char**) {
+ // Begin of writing test for NUMRM
+ std::cout << "Testing writing for NUMRM: ";
+ NUMRM numrm1;
+- // Initilaize the struct with random data
+- tmp=sizeof(NUMRM)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &numrm1 );
++ // Initialize the struct with random data
++ tmp=sizeof(NUMRM);
++ ptr=reinterpret_cast<char*>( &numrm1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(NUMRM) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(numrm1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -611,12 +611,12 @@ int main(int, char**) {
+ // Begin of writing test for OBJHEADER
+ std::cout << "Testing writing for OBJHEADER: ";
+ OBJHEADER objheader1;
+- // Initilaize the struct with random data
+- tmp=sizeof(OBJHEADER)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &objheader1 );
++ // Initialize the struct with random data
++ tmp=sizeof(OBJHEADER);
++ ptr=reinterpret_cast<char*>( &objheader1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(OBJHEADER) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(objheader1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -627,12 +627,12 @@ int main(int, char**) {
+ // Begin of writing test for OLST
+ std::cout << "Testing writing for OLST: ";
+ OLST olst1;
+- // Initilaize the struct with random data
+- tmp=sizeof(OLST)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &olst1 );
++ // Initialize the struct with random data
++ tmp=sizeof(OLST);
++ ptr=reinterpret_cast<char*>( &olst1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(OLST) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(olst1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -644,12 +644,12 @@ int main(int, char**) {
+ // Begin of writing test for PCD
+ std::cout << "Testing writing for PCD: ";
+ PCD pcd1;
+- // Initilaize the struct with random data
+- tmp=sizeof(PCD)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &pcd1 );
++ // Initialize the struct with random data
++ tmp=sizeof(PCD);
++ ptr=reinterpret_cast<char*>( &pcd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PCD) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(pcd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -660,12 +660,12 @@ int main(int, char**) {
+ // Begin of writing test for PGD
+ std::cout << "Testing writing for PGD: ";
+ PGD pgd1;
+- // Initilaize the struct with random data
+- tmp=sizeof(PGD)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &pgd1 );
++ // Initialize the struct with random data
++ tmp=sizeof(PGD);
++ ptr=reinterpret_cast<char*>( &pgd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PGD) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(pgd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -676,12 +676,12 @@ int main(int, char**) {
+ // Begin of writing test for PHE2
+ std::cout << "Testing writing for PHE2: ";
+ PHE2 phe21;
+- // Initilaize the struct with random data
+- tmp=sizeof(PHE2)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &phe21 );
++ // Initialize the struct with random data
++ tmp=sizeof(PHE2);
++ ptr=reinterpret_cast<char*>( &phe21 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PHE2) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(phe21.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -692,12 +692,12 @@ int main(int, char**) {
+ // Begin of writing test for PICF
+ std::cout << "Testing writing for PICF: ";
+ PICF picf1;
+- // Initilaize the struct with random data
+- tmp=sizeof(PICF)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &picf1 );
++ // Initialize the struct with random data
++ tmp=sizeof(PICF);
++ ptr=reinterpret_cast<char*>( &picf1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PICF) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(picf1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -709,12 +709,12 @@ int main(int, char**) {
+ // Begin of writing test for RR
+ std::cout << "Testing writing for RR: ";
+ RR rr1;
+- // Initilaize the struct with random data
+- tmp=sizeof(RR)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &rr1 );
++ // Initialize the struct with random data
++ tmp=sizeof(RR);
++ ptr=reinterpret_cast<char*>( &rr1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(RR) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(rr1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -725,12 +725,12 @@ int main(int, char**) {
+ // Begin of writing test for RS
+ std::cout << "Testing writing for RS: ";
+ RS rs1;
+- // Initilaize the struct with random data
+- tmp=sizeof(RS)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &rs1 );
++ // Initialize the struct with random data
++ tmp=sizeof(RS);
++ ptr=reinterpret_cast<char*>( &rs1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(RS) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(rs1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -741,12 +741,12 @@ int main(int, char**) {
+ // Begin of writing test for SED
+ std::cout << "Testing writing for SED: ";
+ SED sed1;
+- // Initilaize the struct with random data
+- tmp=sizeof(SED)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &sed1 );
++ // Initialize the struct with random data
++ tmp=sizeof(SED);
++ ptr=reinterpret_cast<char*>( &sed1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(SED) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(sed1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -760,12 +760,12 @@ int main(int, char**) {
+ // Begin of writing test for STSHI
+ std::cout << "Testing writing for STSHI: ";
+ STSHI stshi1;
+- // Initilaize the struct with random data
+- tmp=sizeof(STSHI)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &stshi1 );
++ // Initialize the struct with random data
++ tmp=sizeof(STSHI);
++ ptr=reinterpret_cast<char*>( &stshi1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(STSHI) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(stshi1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+@@ -776,12 +776,12 @@ int main(int, char**) {
+ // Begin of writing test for WKB
+ std::cout << "Testing writing for WKB: ";
+ WKB wkb1;
+- // Initilaize the struct with random data
+- tmp=sizeof(WKB)/sizeof(int);
+- ptr=reinterpret_cast<int*>( &wkb1 );
++ // Initialize the struct with random data
++ tmp=sizeof(WKB);
++ ptr=reinterpret_cast<char*>( &wkb1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+- *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(WKB) % sizeof(int)))*8)); // yay! :)
++
+ // and write it out...
+ if(wkb1.write(writer, false))
+ std::cout << "Passed." << std::endl;
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/buffer-overflow.patch b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/buffer-overflow.patch
new file mode 100644
index 00000000..139e81c5
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/buffer-overflow.patch
@@ -0,0 +1,25 @@
+Description: Make sure not to write behind the allocated memory
+ Validate the input data to not write behind the allocated memory. This
+ fixes a buffer overflow found by Charlie Miller.
+Origin: https://projects.kde.org/projects/calligra/repository/revisions/8652ab672eaaa145dfb3782f5011de58aa4cc046
+Author: Thorsten Zachmann
+Comment: change to original patch:
+ s/endl/std::endl/
+Bug-Debian: http://bugs.debian.org/684078
+Reviewed-by: gregor herrmann <[email protected]>
+Last-Update: 2012-08-26
+
+--- a/src/styles.cpp
++++ b/src/styles.cpp
+@@ -188,6 +188,11 @@ bool STD::read( U16 baseSize, U16 totalS
+ #ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "cbUPX: " << cbUPX << std::endl;
+ #endif
++ // do not overflow the allocated buffer grupx
++ if (offset + cbUPX > grupxLen) {
++ wvlog << "====> Error: grupx would overflow!" << std::endl;
++ return false;
++ }
+ for ( U16 j = 0; j < cbUPX; ++j ) {
+ grupx[ offset + j ] = stream->readU8(); // read the whole UPX
+ #ifdef WV2_DEBUG_STYLESHEET
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/fix-ftbfs-with-gold.patch b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/fix-ftbfs-with-gold.patch
new file mode 100644
index 00000000..7272aee1
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/fix-ftbfs-with-gold.patch
@@ -0,0 +1,20 @@
+Description: Fix FTBFS with binutils-gold
+Author: Olly Betts <[email protected]>
+
+---
+Origin: debian
+Bug-Debian: http://bugs.debian.org/556686
+Forwarded: no
+Last-Update: 2013-05-10
+
+diff -ru wv2-0.4.2.dfsg.1.orig/CMakeLists.txt wv2-0.4.2.dfsg.1/CMakeLists.txt
+--- wv2-0.4.2.dfsg.1.orig/CMakeLists.txt 2009-11-01 07:22:43.000000000 +1300
++++ wv2-0.4.2.dfsg.1/CMakeLists.txt 2011-11-30 23:49:51.000000000 +1300
+@@ -153,6 +153,7 @@
+ ENDIF( ICONV_FOUND )
+
+ IF( GLIB2_FOUND )
++ SET( GLIB2_LIBRARIES ${GLIB2_LIBRARIES} gobject-2.0 )
+ SET( _WV2_LDFLAGS ${_WV2_LDFLAGS} ${GLIB2_LIBRARIES} )
+ SET( _WV2_CFLAGS ${_WV2_CFLAGS} ${GLIB2_INCLUDE_DIR} )
+ ENDIF( GLIB2_FOUND )
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/fix-handling-empty-associatedstrings.patch b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/fix-handling-empty-associatedstrings.patch
new file mode 100644
index 00000000..33b8d119
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/fix-handling-empty-associatedstrings.patch
@@ -0,0 +1,48 @@
+Description: Fix to handle empty associated strings
+Author: Olly Betts <[email protected]>
+
+---
+Origin: debian
+Bug-Debian: http://bugs.debian.org/603868
+Forwarded: https://sourceforge.net/tracker/?func=detail&aid=3128662&group_id=10501&atid=110501
+Last-Update: 2010-11-17
+
+diff -ru wv2-0.4.2.dfsg.1/src/associatedstrings.cpp wv2-0.4.2.dfsg.1-tweaked/src/associatedstrings.cpp
+--- wv2-0.4.2.dfsg.1/src/associatedstrings.cpp 2009-11-01 04:52:43.000000000 +1030
++++ wv2-0.4.2.dfsg.1-tweaked/src/associatedstrings.cpp 2010-11-17 22:28:50.263808931 +1030
+@@ -27,6 +27,10 @@
+ AssociatedStrings::AssociatedStrings( U32 fcSttbfAssoc, U32 lcbSttbfAssoc, U16 lid, OLEStreamReader* tableStream ) :
+ m_sttbf( 0 )
+ {
++ if ( lcbSttbfAssoc == 0 ) {
++ m_sttbf = new STTBF();
++ return;
++ }
+ tableStream->push();
+ tableStream->seek( fcSttbfAssoc );
+ m_sttbf = new STTBF( lid, tableStream );
+diff -ru wv2-0.4.2.dfsg.1/src/word_helper.cpp wv2-0.4.2.dfsg.1-tweaked/src/word_helper.cpp
+--- wv2-0.4.2.dfsg.1/src/word_helper.cpp 2009-11-01 04:52:43.000000000 +1030
++++ wv2-0.4.2.dfsg.1-tweaked/src/word_helper.cpp 2010-11-17 22:27:14.126649654 +1030
+@@ -24,6 +24,10 @@
+ namespace wvWare
+ {
+
++ STTBF::STTBF() : m_extraDataLength( 0 )
++ {
++ }
++
+ STTBF::STTBF( U16 lid, OLEStreamReader* reader, bool preservePos )
+ {
+ if ( preservePos )
+diff -ru wv2-0.4.2.dfsg.1/src/word_helper.h wv2-0.4.2.dfsg.1-tweaked/src/word_helper.h
+--- wv2-0.4.2.dfsg.1/src/word_helper.h 2009-11-01 04:52:43.000000000 +1030
++++ wv2-0.4.2.dfsg.1-tweaked/src/word_helper.h 2010-11-17 22:25:41.591053581 +1030
+@@ -44,6 +44,7 @@
+ class STTBF
+ {
+ public:
++ STTBF();
+ STTBF( U16 lid, OLEStreamReader* reader, bool preservePos = false );
+ STTBF( U16 lid, const U8* ptr );
+ STTBF( const STTBF& rhs );
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/fix-nan-and-inf-for-mips.patch b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/fix-nan-and-inf-for-mips.patch
new file mode 100644
index 00000000..c25ac328
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/fix-nan-and-inf-for-mips.patch
@@ -0,0 +1,23 @@
+The bit patterns used are wrong for mips and mipsel and cause a bus error
+when this code is compiled with optimisation. They may also be wrong
+on other archs, but without causing a crash...
+
+--- wv2-0.4.2.dfsg.1/src/ustring.cpp Sun Nov 1 07:22:43 2009
++++ wv2-0.4.2.dfsg.1/src/ustring.cpp Thu Jan 5 18:09:31 2012
+@@ -57,8 +57,16 @@
+ unsigned char Inf_Bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
+ #endif
+
++#ifdef NAN
++ const double NaN = NAN;
++#else
+ const double NaN = *( reinterpret_cast<const double*>( NaN_Bytes ) );
++#endif
++#ifdef INFINITY
++ const double Inf = INFINITY;
++#else
+ const double Inf = *( reinterpret_cast<const double*>( Inf_Bytes ) );
++#endif
+ }
+
+ using namespace wvWare;
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/fix-tests.patch b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/fix-tests.patch
new file mode 100644
index 00000000..ba154491
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/fix-tests.patch
@@ -0,0 +1,20 @@
+Description: Fix testsuite not to try encoding libiconv doesn't know
+Author: Olly Betts <[email protected]>
+
+---
+Origin: debian
+Last-Update: 2010-11-30
+
+--- wv2-0.4.2.dfsg.1.orig/tests/iconvtest.cpp
++++ wv2-0.4.2.dfsg.1/tests/iconvtest.cpp
+@@ -59,7 +59,9 @@ int main( int, char** )
+ status += cp_test( "CP1256" );
+ status += cp_test( "CP1257" );
+ status += cp_test( "UCS-2" );
+- status += cp_test( "UCS-2-INTERNAL" );
++ // Not supported by iconv(3) on Debian. Isn't used by libwv though, so
++ // that's not a problem.
++ //status += cp_test( "UCS-2-INTERNAL" );
+ status += cp_test( "UNICODEBIG" );
+ status += cp_test( "UNICODELITTLE" );
+ status += cp_test( "UTF-8" );
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/glib-2.32-compat.patch b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/glib-2.32-compat.patch
new file mode 100644
index 00000000..cab53b13
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/glib-2.32-compat.patch
@@ -0,0 +1,20 @@
+Description: Fix compatibility with glib 2.32 and later
+ Starting with glib 2.32 it is now mandatory to include glib.h instead
+ of individual headers, or the compiler will generate an error:
+ http://git.gnome.org/browse/glib/commit/?id=7455dd370eb37ce3b0b409ff6120501f37b50569
+Author: Olly Betts <[email protected]>
+Bug-Debian: http://bugs.debian.org/665626
+Forwarded: no
+Last-Update: 2012-03-25
+
+--- wv2-0.4.2.dfsg.1.orig/src/olestream.h
++++ wv2-0.4.2.dfsg.1/src/olestream.h
+@@ -23,7 +23,7 @@
+ #include "global.h" // U8,... typedefs
+ #include <stack>
+
+-#include <glib/giochannel.h> // GSeekType
++#include <glib.h> // GSeekType
+
+ namespace wvWare {
+
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/series b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/series
new file mode 100644
index 00000000..1b6787c3
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/series
@@ -0,0 +1,8 @@
+fix-ftbfs-with-gold.patch
+fix-handling-empty-associatedstrings.patch
+fix-tests.patch
+avoid-writing-after-structures.patch
+fix-nan-and-inf-for-mips.patch
+glib-2.32-compat.patch
+buffer-overflow.patch
+support-endnotes.patch
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/support-endnotes.patch b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/support-endnotes.patch
new file mode 100644
index 00000000..b44a392e
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/patches/support-endnotes.patch
@@ -0,0 +1,17 @@
+Description: Parse endnotes
+Author: manikandaprasad.chandrasekar
+Origin: upstream
+Forwarded: http://sourceforge.net/p/wvware/svn/45/tree//wv2-trunk/src/parser9x.cpp?diff=51ae0a3b2718464e814d6236:44
+Last-Update: 2009-12-17
+
+--- wv2-0.4.2.dfsg.2.orig/src/parser9x.cpp
++++ wv2-0.4.2.dfsg.2/src/parser9x.cpp
+@@ -310,7 +310,7 @@ void Parser9x::init()
+ m_fields = new Fields( m_table, m_fib );
+ m_drawings = new Drawings( m_table, m_fib );
+
+- if ( m_fib.ccpFtn != 0 )
++ if (( m_fib.ccpFtn != 0 ) || ( m_fib.ccpEdn != 0 ))
+ m_footnotes = new Footnotes97( m_table, m_fib );
+ }
+
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/rules b/debian/wv2/wv2-0.4.2.dfsg.2/debian/rules
new file mode 100755
index 00000000..090672ca
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/rules
@@ -0,0 +1,36 @@
+#!/usr/bin/make -f
+
+# Upstream build system seems to just ignore these, and as a result, libgsf
+# fails to find libxml headers (see #707417).
+CPPFLAGS += $(shell pkg-config libgsf-1 --cflags)
+
+# Files on CIFS shares can have 64 bit inode numbers, which means we need LFS
+# enabled to read them (which is something which a library which reads Word
+# documents really should support).
+CPPFLAGS += -D_FILE_OFFSET_BITS=64
+
+# Disable debug output, which is very noisy.
+# (#329109 and (after upstream moved to cmake and the fix was lost) #603871)
+CXXFLAGS += -DNDEBUG
+
+%:
+ dh $@
+
+override_dh_auto_configure:
+ dh_auto_configure
+
+override_dh_auto_test:
+ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
+ifeq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE))
+ $(MAKE) -C obj-* test
+ cp tests/*.doc obj-*/tests
+ cd obj-*/tests ; for t in *test ; do \
+ echo "Running test $$t" ;\
+ if [ $$t = handlertest ]; then \
+ set -e ; ./$$t testole.doc ;\
+ else \
+ set -e ; ./$$t ;\
+ fi \
+ done
+endif
+endif
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/source/format b/debian/wv2/wv2-0.4.2.dfsg.2/debian/source/format
new file mode 100644
index 00000000..163aaf8d
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/source/options b/debian/wv2/wv2-0.4.2.dfsg.2/debian/source/options
new file mode 100644
index 00000000..d71748bb
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/source/options
@@ -0,0 +1,3 @@
+# Use xz instead of gzip
+compression = "xz"
+compression-level = 9
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/debian/wv2-config.1 b/debian/wv2/wv2-0.4.2.dfsg.2/debian/wv2-config.1
new file mode 100644
index 00000000..8bef3ac8
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/debian/wv2-config.1
@@ -0,0 +1,55 @@
+.TH WV2-CONFIG 1 "June 2003"
+.SH NAME
+wv2-config - script to get information about the installed version of wv2
+.SH SYNOPSIS
+.B wv2-config
+[\fB\-\-prefix\fP[=\fIDIR\fP]]
+[\fB\-\-exec\-prefix\fP[=\fIDIR\fP]]
+[\fB\-\-version\fP]
+[\fB\-\-libs\fP]
+[\fB\-\-cflags\fP]
+.SH DESCRIPTION
+.PP
+\fIwv2-config\fP is used to determine
+the compiler and linker flags that should be used to compile
+and link programs that use \fIwv2\fP.
+.SH OPTIONS
+\fIwv2-config\fP accepts the following options.
+.TP
+\fB\-\-prefix\fP=\fIDIR\fP
+If specified, use DIR instead of the installation prefix that \fIwv2\fP
+was built with when computing the output for the \-\-cflags and
+\-\-libs options. This option is also used for the exec prefix
+if \-\-exec\-prefix is not specified. This option must be specified
+before any \-\-libs or \-\-cflags options.
+If no DIR is specified then the current installation prefix will be
+written to standard output.
+.TP
+\fB\-\-exec\-prefix\fP=\fIDIR\fP
+If specified, use DIR instead of the installation exec prefix that
+\fIwv2\fP was built with when computing the output for the \-\-cflags
+and \-\-libs options. This option must be specified before any
+\-\-libs or \-\-cflags options.
+If no DIR is specified then the current installation exec prefix will be
+written to standard output.
+.TP
+.B \-\-version
+Print the currently installed version of \fIwv2\fP on standard output.
+.TP
+.B \-\-libs
+Print the linker flags that are necessary to link a program against
+\fIwv2\fP.
+.TP
+.B \-\-cflags
+Print the compiler flags that are necessary to compile a program that
+uses \fIwv2\fP.
+.SH SEE ALSO
+Some documentation regarding the design of the \fIwv2\fP library is available
+in \fI/usr/share/doc/libwv2-dev/design/\fP .
+.SH AUTHOR
+The \fIwv2\fP library was written by
+Shaheed Haque <[email protected]>, Werner Trobin <[email protected]> and
+David Faure <[email protected]>.
+.br
+This manual page was prepared by Ben Burton <[email protected]> for the
+Debian GNU/Linux system, but may be used by others.
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/.cvsignore b/debian/wv2/wv2-0.4.2.dfsg.2/src/.cvsignore
new file mode 100644
index 00000000..45edc33f
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/.cvsignore
@@ -0,0 +1,6 @@
+Makefile
+Makefile.in
+.deps
+.libs
+*.lo
+libwv2.la
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/CMakeLists.txt b/debian/wv2/wv2-0.4.2.dfsg.2/src/CMakeLists.txt
new file mode 100644
index 00000000..f001384a
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/CMakeLists.txt
@@ -0,0 +1,107 @@
+INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ${wvWare_BINARY_DIR} )
+
+# I'd say the 'if' is unneeded because we always CONFIGURE_FILE
+IF( EXISTS ${wvWare_BINARY_DIR}/config.h )
+ ADD_DEFINITIONS( -DHAVE_CONFIG_H )
+ENDIF( EXISTS ${wvWare_BINARY_DIR}/config.h )
+
+SET( wv2_SOURCES
+ olestorage.cpp
+ olestream.cpp
+ word97_generated.cpp
+ word97_helper.cpp
+ word95_helper.cpp
+ word_helper.cpp
+ word95_generated.cpp
+ convert.cpp
+ global.cpp
+ parser.cpp
+ parser9x.cpp
+ parser95.cpp
+ parser97.cpp
+ parserfactory.cpp
+ ustring.cpp
+ textconverter.cpp
+ styles.cpp
+ handlers.cpp
+ properties97.cpp
+ fonts.cpp
+ lists.cpp
+ paragraphproperties.cpp
+ headers.cpp
+ headers95.cpp
+ headers97.cpp
+ footnotes97.cpp
+ functor.cpp
+ functordata.cpp
+ associatedstrings.cpp
+ fields.cpp
+ utilities.cpp
+ crc32.c
+ wvlog.cpp
+ graphics.cpp
+ wv2version.cpp
+ zcodec.cxx
+ )
+
+SET( wv2_HEADERS
+ olestorage.h
+ olestream.h
+ word95_generated.h
+ word97_generated.h
+ word_helper.h
+ parser.h
+ parserfactory.h
+ ustring.h
+ textconverter.h
+ styles.h
+ sharedptr.h
+ convert.h
+ global.h
+ handlers.h
+ fonts.h
+ lists.h
+ utilities.h
+ paragraphproperties.h
+ functor.h
+ functordata.h
+ associatedstrings.h
+ fields.h
+ dllmagic.h
+ wvlog.h
+ wv2version.h
+ zcodec.hxx
+ )
+
+ADD_LIBRARY( wv2 SHARED ${wv2_SOURCES} ${wv2_HEADERS} )
+TARGET_LINK_LIBRARIES( wv2 ${ZLIB_LIBRARIES} ${LIBGSF_LIBRARIES} ${ICONV_LIBRARIES} ${GLIB2_LIBRARIES} )
+SET_TARGET_PROPERTIES( wv2 PROPERTIES
+ SOVERSION ${LT_VERSION_CURRENT}
+ VERSION ${LT_VERSION_CURRENT}.${LT_VERSION_AGE}.${LT_VERSION_REVISION}
+ LT_VERSION_CURRENT ${LT_VERSION_CURRENT}
+ LT_VERSION_AGE ${LT_VERSION_AGE}
+ LT_VERSION_REVISION ${LT_VERSION_REVISION}
+ LT_DEPENDENCY_LIBS ${WV2_LDFLAGS}
+ )
+IF( WIN32 )
+ SET_TARGET_PROPERTIES( wv2 PROPERTIES DEFINE_SYMBOL WV2_DLL )
+ENDIF( WIN32 )
+
+INSTALL( TARGETS wv2
+ EXPORT wvWare
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib${LIB_SUFFIX}
+ ARCHIVE DESTINATION lib${LIB_SUFFIX}/static
+)
+
+INSTALL( EXPORT wvWare DESTINATION lib${LIB_SUFFIX}/wvWare FILE wv2.cmake )
+
+INSTALL( FILES ${wv2_HEADERS}
+ DESTINATION include/wv2
+)
+
+# libtool files are useless for Visual C++ and Borland C++
+IF( NOT MSVC AND NOT BORLAND )
+ INCLUDE( ${wvWare_SOURCE_DIR}/cmake/MacroCreateLibtoolFile.cmake )
+ CREATE_LIBTOOL_FILE( wv2 /lib${LIB_SUFFIX} )
+ENDIF( NOT MSVC AND NOT BORLAND )
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/associatedstrings.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/associatedstrings.cpp
new file mode 100644
index 00000000..bb3136f3
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/associatedstrings.cpp
@@ -0,0 +1,91 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002, 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "associatedstrings.h"
+#include "ustring.h"
+#include "olestream.h"
+#include "word_helper.h"
+#include "wvlog.h"
+
+using namespace wvWare;
+
+AssociatedStrings::AssociatedStrings( U32 fcSttbfAssoc, U32 lcbSttbfAssoc, U16 lid, OLEStreamReader* tableStream ) :
+ m_sttbf( 0 )
+{
+ tableStream->push();
+ tableStream->seek( fcSttbfAssoc );
+ m_sttbf = new STTBF( lid, tableStream );
+ if ( tableStream->tell() - fcSttbfAssoc != lcbSttbfAssoc )
+ wvlog << "Warning: Associated strings have a different size than expected!" << std::endl;
+ tableStream->pop();
+}
+
+AssociatedStrings::AssociatedStrings( const AssociatedStrings& rhs ) :
+ m_sttbf( new STTBF( *rhs.m_sttbf ) )
+{
+}
+
+AssociatedStrings::~AssociatedStrings()
+{
+ delete m_sttbf;
+}
+
+UString AssociatedStrings::associatedTemplate() const
+{
+ return m_sttbf->stringAt( 1 );
+}
+
+UString AssociatedStrings::title() const
+{
+ return m_sttbf->stringAt( 2 );
+}
+
+UString AssociatedStrings::subject() const
+{
+ return m_sttbf->stringAt( 3 );
+}
+
+UString AssociatedStrings::keywords() const
+{
+ return m_sttbf->stringAt( 4 );
+}
+
+UString AssociatedStrings::comments() const
+{
+ return m_sttbf->stringAt( 5 );
+}
+
+UString AssociatedStrings::author() const
+{
+ return m_sttbf->stringAt( 6 );
+}
+
+UString AssociatedStrings::lastRevBy() const
+{
+ return m_sttbf->stringAt( 7 );
+}
+
+UString AssociatedStrings::dataDocument() const
+{
+ return m_sttbf->stringAt( 8 );
+}
+
+UString AssociatedStrings::headerDocument() const
+{
+ return m_sttbf->stringAt( 9 );
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/associatedstrings.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/associatedstrings.h
new file mode 100644
index 00000000..b072668a
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/associatedstrings.h
@@ -0,0 +1,91 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002, 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef ASSOCSTRINGS_H
+#define ASSOCSTRINGS_H
+
+#include "global.h"
+
+namespace wvWare
+{
+ class OLEStreamReader;
+ class STTBF;
+ class UString;
+
+ /**
+ * AssociatedStrings provides a confortable way to access Word's STTBFASSOC,
+ * the table of associated strings. This table holds information about the
+ * author of the document, the tile, keywords, and so on.
+ */
+ class AssociatedStrings
+ {
+ public:
+ /**
+ * You shouldn't have to create such an object yourself, the Parser provides
+ * it.
+ */
+ AssociatedStrings( U32 fcSttbfAssoc, U32 lcbSttbfAssoc, U16 lid, OLEStreamReader* tableStream );
+ AssociatedStrings( const AssociatedStrings& rhs );
+ ~AssociatedStrings();
+
+ /**
+ * Provides access to the string described as ibstAssocDot
+ */
+ UString associatedTemplate() const;
+ /**
+ * Provides access to the string described as ibstAssocTitle
+ */
+ UString title() const;
+ /**
+ * Provides access to the string described as ibstAssocSubject
+ */
+ UString subject() const;
+ /**
+ * Provides access to the string described as ibstAssocKeyWords
+ */
+ UString keywords() const;
+ /**
+ * Provides access to the string described as ibstAssocComments
+ */
+ UString comments() const;
+ /**
+ * Provides access to the string described as ibstAssocAuthor
+ */
+ UString author() const;
+ /**
+ * Provides access to the string described as ibstAssocLastRevBy
+ */
+ UString lastRevBy() const;
+ /**
+ * Provides access to the string described as ibstAssocDataDoc
+ */
+ UString dataDocument() const;
+ /**
+ * Provides access to the string described as ibstAssocHeaderDoc
+ */
+ UString headerDocument() const;
+
+ private:
+ AssociatedStrings& operator=( const AssociatedStrings& rhs );
+
+ STTBF* m_sttbf;
+ };
+
+} // namespace wvWare
+
+#endif // ASSOCSTRINGS_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/convert.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/convert.cpp
new file mode 100644
index 00000000..7468ea8b
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/convert.cpp
@@ -0,0 +1,1007 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+// This code is generated from the Microsoft HTML specification of the
+// WinWord format. Do NOT edit this code, but fix the spec or the script
+// generating the sources. If you want to add some additional code, some
+// includes or any other stuff, please add it to the template file!
+// For information about the script and the "hidden features" please read
+// the comments at the begin of the script.
+
+// If you find bugs or strange behavior please contact Werner Trobin
+
+#include <convert.h>
+
+namespace wvWare {
+
+namespace Word95 {
+
+// This has been added to the template file, as the mapping is
+// non-trivial. Shaheed: Please check the implementation
+Word97::BRC toWord97(const Word95::BRC &s) {
+
+ Word97::BRC ret;
+
+ // Check the BRC documentation
+ if ( s.dxpLineWidth < 6 ) {
+ ret.dptLineWidth = s.dxpLineWidth * 6;
+ ret.brcType = s.brcType;
+ }
+ else if ( s.dxpLineWidth == 6 ) {
+ ret.dptLineWidth = 6; // what's the default?
+ ret.brcType = 6; // dotted
+ }
+ else { // s.dxpLineWidth == 7
+ ret.dptLineWidth = 6; // what's the default?
+ ret.brcType = 7;
+ }
+ ret.fShadow = s.fShadow;
+ ret.cv = Word97::icoToRGB(s.ico);
+ ret.dptSpace = s.dxpSpace;
+ return ret;
+}
+
+Word97::STSHI toWord97(const Word95::STSHI &s)
+{
+ Word97::STSHI ret;
+
+ ret.cstd=s.cstd;
+ ret.cbSTDBaseInFile=s.cbSTDBaseInFile;
+ ret.fStdStylenamesWritten=s.fStdStylenamesWritten;
+ ret.unused4_2=s.unused4_2;
+ ret.stiMaxWhenSaved=s.stiMaxWhenSaved;
+ ret.istdMaxFixedWhenSaved=s.istdMaxFixedWhenSaved;
+ ret.nVerBuiltInNamesWhenSaved=s.nVerBuiltInNamesWhenSaved;
+ ret.rgftcStandardChpStsh[0]=s.ftcStandardChpStsh;
+ ret.rgftcStandardChpStsh[1]=s.ftcStandardChpStsh; // fake them
+ ret.rgftcStandardChpStsh[2]=s.ftcStandardChpStsh; // fake them
+
+ return ret;
+}
+
+Word97::ANLD toWord97(const Word95::ANLD &s) {
+
+ Word97::ANLD ret;
+
+ ret.nfc=s.nfc;
+ ret.cxchTextBefore=s.cxchTextBefore;
+ ret.cxchTextAfter=s.cxchTextAfter;
+ ret.jc=s.jc;
+ ret.fPrev=s.fPrev;
+ ret.fHang=s.fHang;
+ ret.fSetBold=s.fSetBold;
+ ret.fSetItalic=s.fSetItalic;
+ ret.fSetSmallCaps=s.fSetSmallCaps;
+ ret.fSetCaps=s.fSetCaps;
+ ret.fSetStrike=s.fSetStrike;
+ ret.fSetKul=s.fSetKul;
+ ret.fPrevSpace=s.fPrevSpace;
+ ret.fBold=s.fBold;
+ ret.fItalic=s.fItalic;
+ ret.fSmallCaps=s.fSmallCaps;
+ ret.fCaps=s.fCaps;
+ ret.fStrike=s.fStrike;
+ ret.kul=s.kul;
+ ret.ico=s.ico;
+ ret.ftc=s.ftc;
+ ret.hps=s.hps;
+ ret.iStartAt=s.iStartAt;
+ ret.dxaIndent=s.dxaIndent;
+ ret.dxaSpace=s.dxaSpace;
+ ret.fNumber1=s.fNumber1;
+ ret.fNumberAcross=s.fNumberAcross;
+ ret.fRestartHdn=s.fRestartHdn;
+ ret.fSpareX=s.fSpareX;
+ for(int i=0;i<(32);++i)
+ ret.rgxch[i]=s.rgchAnld[i];
+
+ return ret;
+}
+
+Word97::ANLV toWord97(const Word95::ANLV &s) {
+
+ Word97::ANLV ret;
+
+ ret.nfc=s.nfc;
+ ret.cxchTextBefore=s.cxchTextBefore;
+ ret.cxchTextAfter=s.cxchTextAfter;
+ ret.jc=s.jc;
+ ret.fPrev=s.fPrev;
+ ret.fHang=s.fHang;
+ ret.fSetBold=s.fSetBold;
+ ret.fSetItalic=s.fSetItalic;
+ ret.fSetSmallCaps=s.fSetSmallCaps;
+ ret.fSetCaps=s.fSetCaps;
+ ret.fSetStrike=s.fSetStrike;
+ ret.fSetKul=s.fSetKul;
+ ret.fPrevSpace=s.fPrevSpace;
+ ret.fBold=s.fBold;
+ ret.fItalic=s.fItalic;
+ ret.fSmallCaps=s.fSmallCaps;
+ ret.fCaps=s.fCaps;
+ ret.fStrike=s.fStrike;
+ ret.kul=s.kul;
+ ret.ico=s.ico;
+ ret.ftc=s.ftc;
+ ret.hps=s.hps;
+ ret.iStartAt=s.iStartAt;
+ ret.dxaIndent=s.dxaIndent;
+ ret.dxaSpace=s.dxaSpace;
+
+ return ret;
+}
+
+Word97::BKF toWord97(const Word95::BKF &s) {
+
+ Word97::BKF ret;
+
+ ret.ibkl=s.ibkl;
+ ret.itcFirst=s.itcFirst;
+ ret.fPub=s.fPub;
+ ret.itcLim=s.itcLim;
+ ret.fCol=s.fCol;
+
+ return ret;
+}
+
+Word97::BKL toWord97(const Word95::BKL &s) {
+
+ Word97::BKL ret;
+
+ ret.ibkf=s.ibkf;
+
+ return ret;
+}
+
+/* Please check...
+Word97::BRC toWord97(const Word95::BRC &s) {
+
+ Word97::BRC ret;
+
+ ret.brcType=s.brcType;
+ ret.fShadow=s.fShadow;
+ ret.ico=s.ico;
+
+ return ret;
+} */
+
+Word97::BRC10 toWord97(const Word95::BRC10 &s) {
+
+ Word97::BRC10 ret;
+
+ ret.dxpLine2Width=s.dxpLine2Width;
+ ret.dxpSpaceBetween=s.dxpSpaceBetween;
+ ret.dxpLine1Width=s.dxpLine1Width;
+ ret.dxpSpace=s.dxpSpace;
+ ret.fShadow=s.fShadow;
+ ret.fSpare=s.fSpare;
+
+ return ret;
+}
+
+Word97::BTE toWord97(const Word95::BTE &s) {
+
+ Word97::BTE ret;
+
+ ret.pn=s.pn;
+
+ return ret;
+}
+
+Word97::CHP toWord97(const Word95::CHP &s) {
+
+ Word97::CHP ret;
+
+ ret.fBold=s.fBold;
+ ret.fItalic=s.fItalic;
+ ret.fRMarkDel=s.fRMarkDel;
+ ret.fOutline=s.fOutline;
+ ret.fFldVanish=s.fFldVanish;
+ ret.fSmallCaps=s.fSmallCaps;
+ ret.fCaps=s.fCaps;
+ ret.fVanish=s.fVanish;
+ ret.fRMark=s.fRMark;
+ ret.fSpec=s.fSpec;
+ ret.fStrike=s.fStrike;
+ ret.fObj=s.fObj;
+ ret.fShadow=s.fShadow;
+ ret.fLowerCase=s.fLowerCase;
+ ret.fData=s.fData;
+ ret.fOle2=s.fOle2;
+ ret.ftcAscii=s.ftc;
+ ret.hps=s.hps;
+ ret.dxaSpace=s.dxaSpace;
+ ret.iss=s.iss;
+ ret.fSysVanish=s.fSysVanish;
+ ret.cv= Word97::icoToRGB(s.ico);
+ ret.kul=s.kul;
+ ret.hpsPos=s.hpsPos;
+ ret.lid=s.lid;
+ ret.fcPic_fcObj_lTagObj=s.fcPic_fcObj_lTagObj;
+ ret.ibstRMark=s.ibstRMark;
+ ret.dttmRMark=toWord97(s.dttmRMark);
+ ret.istd=s.istd;
+ ret.ftcSym=s.ftcSym;
+ ret.xchSym=s.chSym;
+ ret.fChsDiff=s.fChsDiff;
+ ret.idslRMReason=s.idslRMReason;
+ ret.ysr=s.ysr;
+ ret.chYsr=s.chYsr;
+ ret.chse=s.chse;
+ ret.hpsKern=s.hpsKern;
+
+ return ret;
+}
+
+/* Please check...
+Word97::CHPX toWord97(const Word95::CHPX &s) {
+
+ Word97::CHPX ret;
+
+ ret.cb=s.cb;
+ ret.grpprl=s.grpprl;
+
+ return ret;
+} */
+
+/* Please check...
+Word97::CHPXFKP toWord97(const Word95::CHPXFKP &s) {
+
+ Word97::CHPXFKP ret;
+
+ ret.rgb=s.rgb;
+ ret.unusedSpace=s.unusedSpace;
+ ret.grpchpx=s.grpchpx;
+ ret.crun=s.crun;
+
+ return ret;
+} */
+
+Word97::DCS toWord97(const Word95::DCS &s) {
+
+ Word97::DCS ret;
+
+ ret.fdct=s.fdct;
+ ret.lines=s.lines;
+ ret.unused1=s.unused1;
+
+ return ret;
+}
+
+Word97::DOP toWord97(const Word95::DOP &s) {
+
+ Word97::DOP ret;
+
+ ret.fFacingPages=s.fFacingPages;
+ ret.fWidowControl=s.fWidowControl;
+ ret.fPMHMainDoc=s.fPMHMainDoc;
+ ret.grfSuppression=s.grfSuppression;
+ ret.fpc=s.fpc;
+ ret.unused0_7=s.unused0_7;
+ ret.grpfIhdt=s.grpfIhdt;
+ ret.rncFtn=s.rncFtn;
+ ret.nFtn=s.nFtn;
+ ret.fOutlineDirtySave=s.fOutlineDirtySave;
+ ret.unused4_1=s.unused4_1;
+ ret.fOnlyMacPics=s.fOnlyMacPics;
+ ret.fOnlyWinPics=s.fOnlyWinPics;
+ ret.fLabelDoc=s.fLabelDoc;
+ ret.fHyphCapitals=s.fHyphCapitals;
+ ret.fAutoHyphen=s.fAutoHyphen;
+ ret.fFormNoFields=s.fFormNoFields;
+ ret.fLinkStyles=s.fLinkStyles;
+ ret.fRevMarking=s.fRevMarking;
+ ret.fBackup=s.fBackup;
+ ret.fExactCWords=s.fExactCWords;
+ ret.fPagHidden=s.fPagHidden;
+ ret.fPagResults=s.fPagResults;
+ ret.fLockAtn=s.fLockAtn;
+ ret.fMirrorMargins=s.fMirrorMargins;
+ ret.fDfltTrueType=s.fDfltTrueType;
+ ret.fPagSuppressTopSpacing=s.fPagSuppressTopSpacing;
+ ret.fProtEnabled=s.fProtEnabled;
+ ret.fDispFormFldSel=s.fDispFormFldSel;
+ ret.fRMView=s.fRMView;
+ ret.fRMPrint=s.fRMPrint;
+ ret.fLockRev=s.fLockRev;
+ ret.fEmbedFonts=s.fEmbedFonts;
+ ret.copts_fNoTabForInd=s.copts_fNoTabForInd;
+ ret.copts_fNoSpaceRaiseLower=s.copts_fNoSpaceRaiseLower;
+ ret.copts_fSuppressSpbfAfterPageBreak=s.copts_fSuppressSpbfAfterPageBreak;
+ ret.copts_fWrapTrailSpaces=s.copts_fWrapTrailSpaces;
+ ret.copts_fMapPrintTextColor=s.copts_fMapPrintTextColor;
+ ret.copts_fNoColumnBalance=s.copts_fNoColumnBalance;
+ ret.copts_fConvMailMergeEsc=s.copts_fConvMailMergeEsc;
+ ret.copts_fSupressTopSpacing=s.copts_fSupressTopSpacing;
+ ret.copts_fOrigWordTableRules=s.copts_fOrigWordTableRules;
+ ret.copts_fTransparentMetafiles=s.copts_fTransparentMetafiles;
+ ret.copts_fShowBreaksInFrames=s.copts_fShowBreaksInFrames;
+ ret.copts_fSwapBordersFacingPgs=s.copts_fSwapBordersFacingPgs;
+ ret.unused8_12=s.unused8_12;
+ ret.dxaTab=s.dxaTab;
+ ret.wSpare=s.wSpare;
+ ret.dxaHotZ=s.dxaHotZ;
+ ret.cConsecHypLim=s.cConsecHypLim;
+ ret.wSpare2=s.wSpare2;
+ ret.dttmCreated=toWord97(s.dttmCreated);
+ ret.dttmRevised=toWord97(s.dttmRevised);
+ ret.dttmLastPrint=toWord97(s.dttmLastPrint);
+ ret.nRevision=s.nRevision;
+ ret.tmEdited=s.tmEdited;
+ ret.cWords=s.cWords;
+ ret.cCh=s.cCh;
+ ret.cPg=s.cPg;
+ ret.cParas=s.cParas;
+ ret.rncEdn=s.rncEdn;
+ ret.nEdn=s.nEdn;
+ ret.epc=s.epc;
+ ret.nfcFtnRef2=s.nfcFtnRef;
+ ret.nfcEdnRef2=s.nfcEdnRef;
+ ret.fPrintFormData=s.fPrintFormData;
+ ret.fSaveFormData=s.fSaveFormData;
+ ret.fShadeFormData=s.fShadeFormData;
+ ret.unused54_13=s.unused54_13;
+ ret.fWCFtnEdn=s.fWCFtnEdn;
+ ret.cLines=s.cLines;
+ ret.cWordsFtnEnd=s.cWordsFtnEnd;
+ ret.cChFtnEdn=s.cChFtnEdn;
+ ret.cPgFtnEdn=s.cPgFtnEdn;
+ ret.cParasFtnEdn=s.cParasFtnEdn;
+ ret.cLinesFtnEdn=s.cLinesFtnEdn;
+ ret.lKeyProtDoc=s.lKeyProtDoc;
+ ret.wvkSaved=s.wvkSaved;
+ ret.wScaleSaved=s.wScaleSaved;
+ ret.zkSaved=s.zkSaved;
+
+ return ret;
+}
+
+Word97::DTTM toWord97(const Word95::DTTM &s) {
+
+ Word97::DTTM ret;
+
+ ret.mint=s.mint;
+ ret.hr=s.hr;
+ ret.dom=s.dom;
+ ret.mon=s.mon;
+ ret.yr=s.yr;
+ ret.wdy=s.wdy;
+
+ return ret;
+}
+
+/* Please check...
+Word97::FFN toWord97(const Word95::FFN &s) {
+
+ Word97::FFN ret;
+
+ ret.cbFfnM1=s.cbFfnM1;
+ ret.prq=s.prq;
+ ret.fTrueType=s.fTrueType;
+ ret.unused1_3=s.unused1_3;
+ ret.ff=s.ff;
+ ret.unused1_7=s.unused1_7;
+ ret.wWeight=s.wWeight;
+ ret.chs=s.chs;
+ ret.ixchSzAlt=s.ibszAlt;
+ ret.xszFfn=s.szFfn;
+
+ return ret;
+} */
+
+Word97::FIB toWord97(const Word95::FIB &s) {
+
+ Word97::FIB ret;
+
+ ret.wIdent=s.wIdent;
+ ret.nFib=s.nFib;
+ ret.nProduct=s.nProduct;
+ ret.lid=s.lid;
+ ret.pnNext=s.pnNext;
+ ret.fDot=s.fDot;
+ ret.fGlsy=s.fGlsy;
+ ret.fComplex=s.fComplex;
+ ret.fHasPic=s.fHasPic;
+ ret.cQuickSaves=s.cQuickSaves;
+ ret.fEncrypted=s.fEncrypted;
+ ret.fReadOnlyRecommended=s.fReadOnlyRecommended;
+ ret.fWriteReservation=s.fWriteReservation;
+ ret.fExtChar=s.fExtChar;
+ ret.nFibBack=s.nFibBack;
+ ret.lKey=s.lKey;
+ ret.envr=s.envr;
+ ret.chs=s.chse;
+ ret.chsTables=s.chseTables;
+ ret.fcMin=s.fcMin;
+ ret.fcMac=s.fcMac;
+ ret.cbMac=s.cbMac;
+ ret.ccpText=s.ccpText;
+ ret.ccpFtn=s.ccpFtn;
+ ret.ccpHdd=s.ccpHdd;
+ ret.ccpMcr=s.ccpMcr;
+ ret.ccpAtn=s.ccpAtn;
+ ret.ccpEdn=s.ccpEdn;
+ ret.ccpTxbx=s.ccpTxbx;
+ ret.ccpHdrTxbx=s.ccpHdrTxbx;
+ ret.fcStshfOrig=s.fcStshfOrig;
+ ret.lcbStshfOrig=s.lcbStshfOrig;
+ ret.fcStshf=s.fcStshf;
+ ret.lcbStshf=s.lcbStshf;
+ ret.fcPlcffndRef=s.fcPlcffndRef;
+ ret.lcbPlcffndRef=s.lcbPlcffndRef;
+ ret.fcPlcffndTxt=s.fcPlcffndTxt;
+ ret.lcbPlcffndTxt=s.lcbPlcffndTxt;
+ ret.fcPlcfandRef=s.fcPlcfandRef;
+ ret.lcbPlcfandRef=s.lcbPlcfandRef;
+ ret.fcPlcfandTxt=s.fcPlcfandTxt;
+ ret.lcbPlcfandTxt=s.lcbPlcfandTxt;
+ ret.fcPlcfsed=s.fcPlcfsed;
+ ret.lcbPlcfsed=s.lcbPlcfsed;
+ ret.fcPlcfpad=s.fcPlcfpad;
+ ret.lcbPlcfpad=s.lcbPlcfpad;
+ ret.fcPlcfphe=s.fcPlcfphe;
+ ret.lcbPlcfphe=s.lcbPlcfphe;
+ ret.fcSttbfglsy=s.fcSttbfglsy;
+ ret.lcbSttbfglsy=s.lcbSttbfglsy;
+ ret.fcPlcfglsy=s.fcPlcfglsy;
+ ret.lcbPlcfglsy=s.lcbPlcfglsy;
+ ret.fcPlcfhdd=s.fcPlcfhdd;
+ ret.lcbPlcfhdd=s.lcbPlcfhdd;
+ ret.fcPlcfbteChpx=s.fcPlcfbteChpx;
+ ret.lcbPlcfbteChpx=s.lcbPlcfbteChpx;
+ ret.fcPlcfbtePapx=s.fcPlcfbtePapx;
+ ret.lcbPlcfbtePapx=s.lcbPlcfbtePapx;
+ ret.fcPlcfsea=s.fcPlcfsea;
+ ret.lcbPlcfsea=s.lcbPlcfsea;
+ ret.fcSttbfffn=s.fcSttbfffn;
+ ret.lcbSttbfffn=s.lcbSttbfffn;
+ ret.fcPlcffldMom=s.fcPlcffldMom;
+ ret.lcbPlcffldMom=s.lcbPlcffldMom;
+ ret.fcPlcffldHdr=s.fcPlcffldHdr;
+ ret.lcbPlcffldHdr=s.lcbPlcffldHdr;
+ ret.fcPlcffldFtn=s.fcPlcffldFtn;
+ ret.lcbPlcffldFtn=s.lcbPlcffldFtn;
+ ret.fcPlcffldAtn=s.fcPlcffldAtn;
+ ret.lcbPlcffldAtn=s.lcbPlcffldAtn;
+ ret.fcPlcffldMcr=s.fcPlcffldMcr;
+ ret.lcbPlcffldMcr=s.lcbPlcffldMcr;
+ ret.fcSttbfbkmk=s.fcSttbfbkmk;
+ ret.lcbSttbfbkmk=s.lcbSttbfbkmk;
+ ret.fcPlcfbkf=s.fcPlcfbkf;
+ ret.lcbPlcfbkf=s.lcbPlcfbkf;
+ ret.fcPlcfbkl=s.fcPlcfbkl;
+ ret.lcbPlcfbkl=s.lcbPlcfbkl;
+ ret.fcCmds=s.fcCmds;
+ ret.lcbCmds=s.lcbCmds;
+ ret.fcPlcmcr=s.fcPlcmcr;
+ ret.lcbPlcmcr=s.lcbPlcmcr;
+ ret.fcSttbfmcr=s.fcSttbfmcr;
+ ret.lcbSttbfmcr=s.lcbSttbfmcr;
+ ret.fcPrDrvr=s.fcPrDrvr;
+ ret.lcbPrDrvr=s.lcbPrDrvr;
+ ret.fcPrEnvPort=s.fcPrEnvPort;
+ ret.lcbPrEnvPort=s.lcbPrEnvPort;
+ ret.fcPrEnvLand=s.fcPrEnvLand;
+ ret.lcbPrEnvLand=s.lcbPrEnvLand;
+ ret.fcWss=s.fcWss;
+ ret.lcbWss=s.lcbWss;
+ ret.fcDop=s.fcDop;
+ ret.lcbDop=s.lcbDop;
+ ret.fcSttbfAssoc=s.fcSttbfAssoc;
+ ret.lcbSttbfAssoc=s.lcbSttbfAssoc;
+ ret.fcClx=s.fcClx;
+ ret.lcbClx=s.lcbClx;
+ ret.fcPlcfpgdFtn=s.fcPlcfpgdFtn;
+ ret.lcbPlcfpgdFtn=s.lcbPlcfpgdFtn;
+ ret.fcAutosaveSource=s.fcAutosaveSource;
+ ret.lcbAutosaveSource=s.lcbAutosaveSource;
+ ret.fcGrpXstAtnOwners=s.fcGrpStAtnOwners;
+ ret.lcbGrpXstAtnOwners=s.lcbGrpStAtnOwners;
+ ret.fcSttbfAtnbkmk=s.fcSttbfAtnbkmk;
+ ret.lcbSttbfAtnbkmk=s.lcbSttbfAtnbkmk;
+ ret.pnChpFirst=s.pnChpFirst;
+ ret.pnPapFirst=s.pnPapFirst;
+ ret.cpnBteChp=s.cpnBteChp;
+ ret.cpnBtePap=s.cpnBtePap;
+ ret.fcPlcdoaMom=s.fcPlcfdoaMom;
+ ret.lcbPlcdoaMom=s.lcbPlcfdoaMom;
+ ret.fcPlcdoaHdr=s.fcPlcfdoaHdr;
+ ret.lcbPlcdoaHdr=s.lcbPlcfdoaHdr;
+ ret.fcPlcfAtnbkf=s.fcPlcfAtnbkf;
+ ret.lcbPlcfAtnbkf=s.lcbPlcfAtnbkf;
+ ret.fcPlcfAtnbkl=s.fcPlcfAtnbkl;
+ ret.lcbPlcfAtnbkl=s.lcbPlcfAtnbkl;
+ ret.fcPms=s.fcPms;
+ ret.lcbPms=s.lcbPms;
+ ret.fcFormFldSttbf=s.fcFormFldSttbf;
+ ret.lcbFormFldSttbf=s.lcbFormFldSttbf;
+ ret.fcPlcfendRef=s.fcPlcfendRef;
+ ret.lcbPlcfendRef=s.lcbPlcfendRef;
+ ret.fcPlcfendTxt=s.fcPlcfendTxt;
+ ret.lcbPlcfendTxt=s.lcbPlcfendTxt;
+ ret.fcPlcffldEdn=s.fcPlcffldEdn;
+ ret.lcbPlcffldEdn=s.lcbPlcffldEdn;
+ ret.fcPlcfpgdEdn=s.fcPlcfpgdEdn;
+ ret.lcbPlcfpgdEdn=s.lcbPlcfpgdEdn;
+ ret.fcSttbfRMark=s.fcSttbfRMark;
+ ret.lcbSttbfRMark=s.lcbSttbfRMark;
+ ret.fcSttbfCaption=s.fcSttbfCaption;
+ ret.lcbSttbfCaption=s.lcbSttbfCaption;
+ ret.fcSttbfAutoCaption=s.fcSttbfAutoCaption;
+ ret.lcbSttbfAutoCaption=s.lcbSttbfAutoCaption;
+ ret.fcPlcfwkb=s.fcPlcfwkb;
+ ret.lcbPlcfwkb=s.lcbPlcfwkb;
+ ret.fcPlcftxbxTxt=s.fcPlcftxbxTxt;
+ ret.lcbPlcftxbxTxt=s.lcbPlcftxbxTxt;
+ ret.fcPlcffldTxbx=s.fcPlcffldTxbx;
+ ret.lcbPlcffldTxbx=s.lcbPlcffldTxbx;
+ ret.fcPlcfHdrtxbxTxt=s.fcPlcfHdrtxbxTxt;
+ ret.lcbPlcfHdrtxbxTxt=s.lcbPlcfHdrtxbxTxt;
+ ret.fcPlcffldHdrTxbx=s.fcPlcffldHdrTxbx;
+ ret.lcbPlcffldHdrTxbx=s.lcbPlcffldHdrTxbx;
+ ret.fcStwUser=s.fcStwUser;
+ ret.lcbStwUser=s.lcbStwUser;
+ ret.fcSttbttmbd=s.fcSttbttmbd;
+ ret.lcbSttbttmbd=s.lcbSttbttmbd;
+ ret.fcUnused=s.fcUnused;
+ ret.lcbUnused=s.lcbUnused;
+ ret.fcPgdMother=s.fcPgdMother;
+ ret.lcbPgdMother=s.lcbPgdMother;
+ ret.fcBkdMother=s.fcBkdMother;
+ ret.lcbBkdMother=s.lcbBkdMother;
+ ret.fcPgdFtn=s.fcPgdFtn;
+ ret.lcbPgdFtn=s.lcbPgdFtn;
+ ret.fcBkdFtn=s.fcBkdFtn;
+ ret.lcbBkdFtn=s.lcbBkdFtn;
+ ret.fcPgdEdn=s.fcPgdEdn;
+ ret.lcbPgdEdn=s.lcbPgdEdn;
+ ret.fcBkdEdn=s.fcBkdEdn;
+ ret.lcbBkdEdn=s.lcbBkdEdn;
+ ret.fcSttbfIntlFld=s.fcSttbfIntlFld;
+ ret.lcbSttbfIntlFld=s.lcbSttbfIntlFld;
+ ret.fcRouteSlip=s.fcRouteSlip;
+ ret.lcbRouteSlip=s.lcbRouteSlip;
+ ret.fcSttbSavedBy=s.fcSttbSavedBy;
+ ret.lcbSttbSavedBy=s.lcbSttbSavedBy;
+ ret.fcSttbFnm=s.fcSttbFnm;
+ ret.lcbSttbFnm=s.lcbSttbFnm;
+
+ return ret;
+}
+
+/* Please check...
+Word97::FLD toWord97(const Word95::FLD &s) {
+
+ Word97::FLD ret;
+
+ ret.ch=s.ch;
+
+ return ret;
+} */
+
+Word97::LSPD toWord97(const Word95::LSPD &s) {
+
+ Word97::LSPD ret;
+
+ ret.dyaLine=s.dyaLine;
+ ret.fMultLinespace=s.fMultLinespace;
+
+ return ret;
+}
+
+Word97::METAFILEPICT toWord97(const Word95::METAFILEPICT &s) {
+
+ Word97::METAFILEPICT ret;
+
+ ret.mm=s.mm;
+ ret.xExt=s.xExt;
+ ret.yExt=s.yExt;
+ ret.hMF=s.hMF;
+
+ return ret;
+}
+
+Word97::OBJHEADER toWord97(const Word95::OBJHEADER &s) {
+
+ Word97::OBJHEADER ret;
+
+ ret.lcb=s.lcb;
+ ret.cbHeader=s.cbHeader;
+ ret.icf=s.icf;
+
+ return ret;
+}
+
+Word97::OLST toWord97(const Word95::OLST &s) {
+
+ Word97::OLST ret;
+
+ for(int i=0;i<(9);++i)
+ ret.rganlv[i]=toWord97(s.rganlv[i]);
+ ret.fRestartHdr=s.fRestartHdr;
+ ret.fSpareOlst2=s.fSpareOlst2;
+ ret.fSpareOlst3=s.fSpareOlst3;
+ ret.fSpareOlst4=s.fSpareOlst4;
+ for(int i=0;i<(32);++i)
+ ret.rgxch[i]=s.rgch[i];
+
+ return ret;
+}
+
+Word97::PAP toWord97(const Word95::PAP &s) {
+
+ Word97::PAP ret;
+
+ ret.istd=s.istd;
+ ret.jc=s.jc;
+ ret.fKeep=s.fKeep;
+ ret.fKeepFollow=s.fKeepFollow;
+ ret.fPageBreakBefore=s.fPageBreakBefore;
+ ret.fBrLnAbove=s.fBrLnAbove;
+ ret.fBrLnBelow=s.fBrLnBelow;
+ ret.fUnused=s.fUnused;
+ ret.pcVert=s.pcVert;
+ ret.pcHorz=s.pcHorz;
+ ret.brcp=s.brcp;
+ ret.brcl=s.brcl;
+ ret.unused9=s.unused9;
+ ret.nLvlAnm=s.nLvlAnm;
+ ret.fNoLnn=s.fNoLnn;
+ ret.fSideBySide=s.fSideBySide;
+ ret.dxaRight=s.dxaRight;
+ ret.dxaLeft=s.dxaLeft;
+ ret.dxaLeft1=s.dxaLeft1;
+ ret.lspd=toWord97(s.lspd);
+ ret.dyaBefore=s.dyaBefore;
+ ret.dyaAfter=s.dyaAfter;
+ ret.phe=toWord97(s.phe);
+ ret.fWidowControl=s.fWidowControl;
+ ret.fInTable=s.fInTable;
+ ret.fTtp=s.fTtp;
+ ret.ptap=s.ptap;
+ ret.dxaAbs=s.dxaAbs;
+ ret.dyaAbs=s.dyaAbs;
+ ret.dxaWidth=s.dxaWidth;
+ ret.brcTop=toWord97(s.brcTop);
+ ret.brcLeft=toWord97(s.brcLeft);
+ ret.brcBottom=toWord97(s.brcBottom);
+ ret.brcRight=toWord97(s.brcRight);
+ ret.brcBetween=toWord97(s.brcBetween);
+ ret.brcBar=toWord97(s.brcBar);
+ ret.dxaFromText=s.dxaFromText;
+ ret.dyaFromText=s.dyaFromText;
+ ret.wr=s.wr;
+ ret.fLocked=s.fLocked;
+ ret.dyaHeight=s.dyaHeight;
+ ret.fMinHeight=s.fMinHeight;
+ ret.shd=toWord97(s.shd);
+ ret.dcs=toWord97(s.dcs);
+ ret.anld=toWord97(s.anld);
+ ret.itbdMac=s.itbdMac;
+
+ return ret;
+}
+
+/* Please check...
+Word97::PAPX toWord97(const Word95::PAPX &s) {
+
+ Word97::PAPX ret;
+
+ ret.cw=s.cw;
+ ret.cb=s.cb;
+
+ return ret;
+} */
+
+/* Please check...
+Word97::PAPXFKP toWord97(const Word95::PAPXFKP &s) {
+
+ Word97::PAPXFKP ret;
+
+ ret.rgfc=s.rgfc;
+ ret.rgbx=s.rgbx;
+ ret.grppapx=s.grppapx;
+ ret.crun=s.crun;
+
+ return ret;
+} */
+
+Word97::PCD toWord97(const Word95::PCD &s) {
+
+ Word97::PCD ret;
+
+ ret.fNoParaLast=s.fNoParaLast;
+ ret.fPaphNil=s.fPaphNil;
+ ret.fCopied=s.fCopied;
+ ret.unused0_3=s.unused0_3;
+ ret.fn=s.fn;
+ ret.fc=s.fc;
+ ret.prm=toWord97(s.prm);
+
+ return ret;
+}
+
+/* Please check...
+Word97::PGD toWord97(const Word95::PGD &s) {
+
+ Word97::PGD ret;
+
+ ret.fContinue=s.fContinue;
+ ret.fUnk=s.fUnk;
+ ret.fRight=s.fRight;
+ ret.fPgnRestart=s.fPgnRestart;
+ ret.fEmptyPage=s.fEmptyPage;
+ ret.fAllFtn=s.fAllFtn;
+ ret.fTableBreaks=s.fTableBreaks;
+ ret.fMarked=s.fMarked;
+ ret.fColumnBreaks=s.fColumnBreaks;
+ ret.fTableHeader=s.fTableHeader;
+ ret.fNewPage=s.fNewPage;
+ ret.bkc=s.bkc;
+ ret.lnn=s.lnn;
+ ret.pgn=s.pgn;
+
+ return ret;
+} */
+
+Word97::PHE toWord97(const Word95::PHE &s) {
+
+ Word97::PHE ret;
+
+ ret.fSpare=s.fSpare;
+ ret.fUnk=s.fUnk;
+ ret.fDiffLines=s.fDiffLines;
+ ret.unused0_3=s.unused0_3;
+ ret.clMac=s.clMac;
+ ret.dxaCol=s.dxaCol;
+ ret.dym=s.dylLine_dylHeight;
+
+ return ret;
+}
+
+Word97::PICF toWord97(const Word95::PICF &s) {
+
+ Word97::PICF ret;
+
+ ret.lcb=s.lcb;
+ ret.cbHeader=s.cbHeader;
+ ret.mfp=toWord97(s.mfp);
+ for(int i=0;i<(14);++i)
+ ret.bm_rcWinMF[i]=s.bm_rcWinMF[i];
+ ret.dxaGoal=s.dxaGoal;
+ ret.dyaGoal=s.dyaGoal;
+ ret.mx=s.mx;
+ ret.my=s.my;
+ ret.dxaCropLeft=s.dxaCropLeft;
+ ret.dyaCropTop=s.dyaCropTop;
+ ret.dxaCropRight=s.dxaCropRight;
+ ret.dyaCropBottom=s.dyaCropBottom;
+ ret.brcl=s.brcl;
+ ret.fFrameEmpty=s.fFrameEmpty;
+ ret.fBitmap=s.fBitmap;
+ ret.fDrawHatch=s.fDrawHatch;
+ ret.fError=s.fError;
+ ret.bpp=s.bpp;
+ ret.brcTop=toWord97(s.brcTop);
+ ret.brcLeft=toWord97(s.brcLeft);
+ ret.brcBottom=toWord97(s.brcBottom);
+ ret.brcRight=toWord97(s.brcRight);
+ ret.dxaOrigin=s.dxaOrigin;
+ ret.dyaOrigin=s.dyaOrigin;
+
+ return ret;
+}
+
+/* Please check...
+Word97::PLCF toWord97(const Word95::PLCF &s) {
+
+ Word97::PLCF ret;
+
+ ret.rgfc=s.rgfc;
+
+ return ret;
+} */
+
+Word97::PRM toWord97(const Word95::PRM &s) {
+
+ Word97::PRM ret;
+
+ ret.fComplex=s.fComplex;
+ ret.isprm=s.sprm;
+ ret.val=s.val;
+
+ return ret;
+}
+
+Word97::PRM2 toWord97(const Word95::PRM2 &s) {
+
+ Word97::PRM2 ret;
+
+ ret.fComplex=s.fComplex;
+ ret.igrpprl=s.igrpprl;
+
+ return ret;
+}
+
+Word97::SED toWord97(const Word95::SED &s) {
+
+ Word97::SED ret;
+
+ ret.fcSepx=s.fcSepx;
+ ret.fnMpr=s.fnMpr;
+ ret.fcMpr=s.fcMpr;
+
+ return ret;
+}
+
+Word97::SEP toWord97(const Word95::SEP &s) {
+
+ Word97::SEP ret;
+
+ ret.bkc=s.bkc;
+ ret.fTitlePage=s.fTitlePage;
+ ret.ccolM1=s.ccolM1;
+ ret.dxaColumns=s.dxaColumns;
+ ret.fAutoPgn=s.fAutoPgn;
+ ret.nfcPgn=s.nfcPgn;
+ ret.pgnStart=s.pgnStart;
+ ret.fUnlocked=s.fUnlocked;
+ ret.cnsPgn=s.cnsPgn;
+ ret.fPgnRestart=s.fPgnRestart;
+ ret.fEndNote=s.fEndNote;
+ ret.lnc=s.lnc;
+ ret.grpfIhdt=s.grpfIhdt;
+ ret.nLnnMod=s.nLnnMod;
+ ret.dxaLnn=s.dxaLnn;
+ ret.dyaHdrTop=s.dyaHdrTop;
+ ret.dyaHdrBottom=s.dyaHdrBottom;
+ ret.dxaPgn=s.dxaPgn;
+ ret.dyaPgn=s.dyaPgn;
+ ret.fLBetween=s.fLBetween;
+ ret.vjc=s.vjc;
+ ret.lnnMin=s.lnnMin;
+ ret.dmOrientPage=s.dmOrientPage;
+ ret.iHeadingPgn=s.iHeadingPgn;
+ ret.xaPage=s.xaPage;
+ ret.yaPage=s.yaPage;
+ ret.dxaLeft=s.dxaLeft;
+ ret.dxaRight=s.dxaRight;
+ ret.dyaTop=s.dyaTop;
+ ret.dyaBottom=s.dyaBottom;
+ ret.dzaGutter=s.dzaGutter;
+ ret.dmBinFirst=s.dmBinFirst;
+ ret.dmBinOther=s.dmBinOther;
+ ret.dmPaperReq=s.dmPaperReq;
+ ret.fEvenlySpaced=s.fEvenlySpaced;
+ ret.dxaColumnWidth=s.dxaColumnWidth;
+ for(int i=0;i<(89);++i)
+ ret.rgdxaColumnWidthSpacing[i]=s.rgdxaColumnWidthSpacing[i];
+ ret.olstAnm=toWord97(s.olstAnm);
+
+ return ret;
+}
+
+/* Please check...
+Word97::SEPX toWord97(const Word95::SEPX &s) {
+
+ Word97::SEPX ret;
+
+ ret.grpprl=s.grpprl;
+
+ return ret;
+} */
+
+Word97::SHD toWord97(const Word95::SHD &s) {
+
+ Word97::SHD ret;
+
+ ret.cvFore=Word97::icoToRGB(s.icoFore);
+ ret.cvBack=Word97::icoToRGB(s.icoBack);
+ ret.ipat=s.ipat;
+
+ return ret;
+}
+
+/* Please check...
+Word97::STSHI toWord97(const Word95::STSHI &s) {
+
+ Word97::STSHI ret;
+
+ ret.cstd=s.cstd;
+ ret.cbSTDBaseInFile=s.cbSTDBaseInFile;
+ ret.fStdStylenamesWritten=s.fStdStylenamesWritten;
+ ret.unused4_2=s.unused4_2;
+ ret.stiMaxWhenSaved=s.stiMaxWhenSaved;
+ ret.istdMaxFixedWhenSaved=s.istdMaxFixedWhenSaved;
+ ret.nVerBuiltInNamesWhenSaved=s.nVerBuiltInNamesWhenSaved;
+
+ return ret;
+} */
+
+Word97::TAP toWord97(const Word95::TAP &s) {
+
+ Word97::TAP ret;
+
+ ret.jc=s.jc;
+ ret.dxaGapHalf=s.dxaGapHalf;
+ ret.dyaRowHeight=s.dyaRowHeight;
+ ret.fCantSplit=s.fCantSplit;
+ ret.fTableHeader=s.fTableHeader;
+ ret.tlp=toWord97(s.tlp);
+ ret.fCaFull=s.fCaFull;
+ ret.fFirstRow=s.fFirstRow;
+ ret.fLastRow=s.fLastRow;
+ ret.fOutline=s.fOutline;
+ ret.itcMac=s.itcMac;
+ ret.dxaAdjust=s.dxaAdjust;
+ for(int i=0;i<(6);++i)
+ ret.rgbrcTable[i]=toWord97(s.rgbrcTable[i]);
+
+ return ret;
+}
+
+/* Please check...
+Word97::TBD toWord97(const Word95::TBD &s) {
+
+ Word97::TBD ret;
+
+ ret.jc=s.jc;
+ ret.tlc=s.tlc;
+ ret.unused0_6=s.unused0_6;
+
+ return ret;
+} */
+
+Word97::TC toWord97(const Word95::TC &s) {
+
+ Word97::TC ret;
+
+ ret.fFirstMerged=s.fFirstMerged;
+ ret.fMerged=s.fMerged;
+ ret.fUnused=s.fUnused;
+ ret.brcTop=toWord97(s.brcTop);
+ ret.brcLeft=toWord97(s.brcLeft);
+ ret.brcBottom=toWord97(s.brcBottom);
+ ret.brcRight=toWord97(s.brcRight);
+
+ return ret;
+}
+
+Word97::TLP toWord97(const Word95::TLP &s) {
+
+ Word97::TLP ret;
+
+ ret.itl=s.itl;
+ ret.fBorders=s.fBorders;
+ ret.fShading=s.fShading;
+ ret.fFont=s.fFont;
+ ret.fColor=s.fColor;
+ ret.fBestFit=s.fBestFit;
+ ret.fHdrRows=s.fHdrRows;
+ ret.fLastRow=s.fLastRow;
+ ret.fHdrCols=s.fHdrCols;
+ ret.fLastCol=s.fLastCol;
+ ret.unused2_9=s.unused2_9;
+
+ return ret;
+}
+
+} // namespace Word95
+
+} // namespace wvWare
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/convert.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/convert.h
new file mode 100644
index 00000000..75239932
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/convert.h
@@ -0,0 +1,75 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+// This code is generated from the Microsoft HTML specification of the
+// WinWord format. Do NOT edit this code, but fix the spec or the script
+// generating the sources.
+// For information about the script and the "hidden features" please read
+// the comments at the begin of the script.
+
+// If you find bugs or strange behavior please contact Werner Trobin
+
+#ifndef CONVERT_H
+#define CONVERT_H
+
+#include <word95_generated.h>
+#include <word97_generated.h>
+
+namespace wvWare {
+
+namespace Word95 {
+
+// This has been added to the template file, as the mapping is
+// non-trivial. Shaheed: Please check the implementation
+Word97::BRC toWord97(const Word95::BRC &s);
+Word97::STSHI toWord97(const Word95::STSHI &s);
+
+Word97::ANLD toWord97(const Word95::ANLD &s);
+Word97::ANLV toWord97(const Word95::ANLV &s);
+Word97::BKF toWord97(const Word95::BKF &s);
+Word97::BKL toWord97(const Word95::BKL &s);
+Word97::BRC10 toWord97(const Word95::BRC10 &s);
+Word97::BTE toWord97(const Word95::BTE &s);
+Word97::CHP toWord97(const Word95::CHP &s);
+Word97::DCS toWord97(const Word95::DCS &s);
+Word97::DOP toWord97(const Word95::DOP &s);
+Word97::DTTM toWord97(const Word95::DTTM &s);
+Word97::FIB toWord97(const Word95::FIB &s);
+Word97::LSPD toWord97(const Word95::LSPD &s);
+Word97::METAFILEPICT toWord97(const Word95::METAFILEPICT &s);
+Word97::OBJHEADER toWord97(const Word95::OBJHEADER &s);
+Word97::OLST toWord97(const Word95::OLST &s);
+Word97::PAP toWord97(const Word95::PAP &s);
+Word97::PCD toWord97(const Word95::PCD &s);
+Word97::PHE toWord97(const Word95::PHE &s);
+Word97::PICF toWord97(const Word95::PICF &s);
+Word97::PRM toWord97(const Word95::PRM &s);
+Word97::PRM2 toWord97(const Word95::PRM2 &s);
+Word97::SED toWord97(const Word95::SED &s);
+Word97::SEP toWord97(const Word95::SEP &s);
+Word97::SHD toWord97(const Word95::SHD &s);
+Word97::TAP toWord97(const Word95::TAP &s);
+Word97::TC toWord97(const Word95::TC &s);
+Word97::TLP toWord97(const Word95::TLP &s);
+
+} // namespace Word95
+
+} // namespace wvWare
+
+#endif // CONVERT_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/crc32.c b/debian/wv2/wv2-0.4.2.dfsg.2/src/crc32.c
new file mode 100644
index 00000000..7628b824
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/crc32.c
@@ -0,0 +1,244 @@
+/* crc32.c
+
+ C implementation of CRC-32 checksums for NAACCR records. Code is based
+ upon and utilizes algorithm published by Ross Williams.
+
+ This file contains:
+ CRC lookup table
+ function CalcCRC32 for calculating CRC-32 checksum
+ function AssignCRC32 for assigning CRC-32 in NAACCR record
+ function CheckCRC32 for checking CRC-32 in NAACCR record
+
+ Provided by:
+ Eric Durbin
+ Kentucky Cancer Registry
+ University of Kentucky
+ October 14, 1998
+
+ Status:
+ Public Domain
+*/
+#include "crc32.h"
+
+/*****************************************************************/
+/* */
+/* CRC LOOKUP TABLE */
+/* ================ */
+/* The following CRC lookup table was generated automagically */
+/* by the Rocksoft^tm Model CRC Algorithm Table Generation */
+/* Program V1.0 using the following model parameters: */
+/* */
+/* Width : 4 bytes. */
+/* Poly : 0x04C11DB7L */
+/* Reverse : TRUE. */
+/* */
+/* For more information on the Rocksoft^tm Model CRC Algorithm, */
+/* see the document titled "A Painless Guide to CRC Error */
+/* Detection Algorithms" by Ross Williams */
+/* ([email protected].). This document is likely to be */
+/* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". */
+/* */
+/*****************************************************************/
+
+unsigned long crctable[256] =
+{
+ 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
+ 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
+ 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
+ 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
+ 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
+ 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
+ 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
+ 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
+ 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
+ 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
+ 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
+ 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
+ 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
+ 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
+ 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
+ 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
+ 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
+ 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
+ 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
+ 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
+ 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
+ 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
+ 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
+ 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
+ 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
+ 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
+ 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
+ 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
+ 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
+ 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
+ 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
+ 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
+ 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
+ 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
+ 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
+ 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
+ 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
+ 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
+ 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
+ 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
+ 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
+ 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
+ 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
+ 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
+ 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
+ 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
+ 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
+ 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
+ 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
+ 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
+ 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
+ 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
+ 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
+ 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
+ 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
+ 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
+ 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
+ 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
+ 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
+ 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
+ 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
+ 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
+ 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
+ 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
+};
+
+/*****************************************************************/
+/* End of CRC Lookup Table */
+/*****************************************************************/
+
+/* Calculate CRC-32 Checksum for NAACCR Record,
+ skipping area of record containing checksum field.
+
+ Uses reflected table driven method documented by Ross Williams.
+
+ PARAMETERS:
+ unsigned char *p NAACCR Record Buffer
+ unsigned long reclen NAACCR Record Length
+ unsigned long checksumpos Position of CHECKSUM (as in Data Dictionary)
+ unsigned long checksumlen Length of checksum Field
+
+ RETURNS:
+ checksum value
+
+ Author:
+ Eric Durbin 1998-10-14
+
+ Status:
+ Public Domain
+*/
+unsigned long CalcCRC32(unsigned char *p, unsigned long reclen, unsigned long checksumpos, unsigned long checksumlen)
+{
+ unsigned long j;
+
+ /* initialize value */
+ unsigned long crc = CRC32_XINIT;
+
+ /* process each byte prior to checksum field */
+ for (j = 1; j < checksumpos; j++) {
+ crc = crctable[(crc ^ *p++) & 0xFFL] ^ (crc >> 8);
+ }
+
+ /* skip checksum position */
+ j += checksumlen;
+ p += checksumlen;
+
+ /* process remaining bytes in record */
+ while (j <= reclen) {
+ crc = crctable[(crc ^ *p++) & 0xFFL] ^ (crc >> 8);
+ j++;
+ }
+
+ /* return XOR out value */
+ return crc ^ CRC32_XOROT;
+}
+
+/* Assign CRC-32 checksum for NAACCR record passed in buffer p of length
+ reclen with checksum occupying position checksumpos of length checksumlen.
+
+ PARAMETERS:
+ unsigned char *p NAACCR Record Buffer
+ unsigned long reclen NAACCR Record Length
+ unsigned long checksumpos Position of CHECKSUM (as in Data Dictionary)
+ unsigned long checksumlen Length of checksum Field
+
+ RETURNS:
+ 0 Checksum successfully placed in checksum field
+ -1 Checksum length too short
+ -2 Checksum length too long
+ -3 Checksum position exceeds record length
+
+ Author:
+ Eric Durbin 1998-10-14
+
+ Status:
+ Public Domain
+*/
+int AssignCRC32(unsigned char *p, unsigned long reclen, unsigned long checksumpos, unsigned long checksumlen)
+{
+ unsigned long CRCValue; /* value of CRC checksum for record */
+ unsigned long Mask = 0x0000000FL; /* Mask for converting hex string */
+ char *HexString ="0123456789ABCDEF"; /* hex string characters */
+ unsigned char *s; /* string pointer */
+
+ /* validate checksum length */
+ if (checksumlen < MINIMUM_CHECKSUM_LEN)
+ return -1;
+ if (checksumlen > MAXIMUM_CHECKSUM_LEN)
+ return -2;
+ if (checksumpos > reclen)
+ return -3;
+
+ CRCValue = CalcCRC32(p, reclen, checksumpos, checksumlen);
+
+ /* convert CRC Value to ASCII Hex String */
+ s = p+checksumpos-1;
+ while (checksumlen--) {
+ *(s+checksumlen) = *(HexString + (CRCValue & Mask));
+ CRCValue >>= 4; /* right shift 4 bits */
+ }
+ return 0;
+}
+
+/* compare CRC-32 checksum in NAACCR record
+
+ PARAMETERS:
+ unsigned char *p NAACCR Record Buffer
+ unsigned long reclen NAACCR Record Length
+ unsigned long checksumpos Position of CHECKSUM (as in Data Dictionary)
+ unsigned long checksumlen Length of checksum Field
+
+ RETURNS:
+ 0 Checksum matches
+ -1 Checksum mismatch
+
+ Author:
+ Eric Durbin 1998-10-14
+
+ Status:
+ Public Domain
+*/
+int CompareCRC32(unsigned char *p, unsigned long reclen, unsigned long checksumpos, unsigned long checksumlen)
+{
+ unsigned long RecordCRCValue = 0L; /* initialize record's CRC Value */
+ unsigned long CalcCRCValue;
+ unsigned char *s = p+checksumpos-1;/* incoming checksum string */
+
+ CalcCRCValue = CalcCRC32(p, reclen, checksumpos, checksumlen);
+
+ /* extract records hexadecimal checksum value */
+ while (checksumlen--) {
+ RecordCRCValue <<= 4; /* left shift 4 bits */
+ RecordCRCValue += (*s>'9') ? *s++-'A'+10 : *s++-'0';
+ }
+
+ /* compare values */
+ if (RecordCRCValue != CalcCRCValue)
+ return -1;
+ return 0;
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/crc32.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/crc32.h
new file mode 100644
index 00000000..d51bb131
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/crc32.h
@@ -0,0 +1,29 @@
+/* crc32.h
+
+ header file for crc32 checksum
+*/
+
+#define CRC32_XINIT 0xFFFFFFFFL /* initial value */
+#define CRC32_XOROT 0xFFFFFFFFL /* final xor value */
+
+#define MINIMUM_CHECKSUM_LEN 8
+#define MAXIMUM_CHECKSUM_LEN 99
+
+/* NAACCR 6.0 Specifications */
+#define NAACCR_60_CHECKSUM_POS 942
+#define NAACCR_60_CHECKSUM_LEN 10
+
+/* function prototypes */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+unsigned long CalcCRC32(unsigned char *, unsigned long, unsigned long, unsigned long);
+int AssignCRC32(unsigned char *, unsigned long, unsigned long, unsigned long);
+int CompareCRC32(unsigned char *, unsigned long, unsigned long, unsigned long);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/dllmagic.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/dllmagic.h
new file mode 100644
index 00000000..f9322237
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/dllmagic.h
@@ -0,0 +1,28 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef DLLMAGIC_H
+#define DLLMAGIC_H
+
+#ifdef WV2_DLL
+# define WV2_DLLEXPORT __declspec(dllexport)
+#else
+# define WV2_DLLEXPORT
+#endif
+
+#endif // DLLMAGIC_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/fields.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/fields.cpp
new file mode 100644
index 00000000..de4c3edf
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/fields.cpp
@@ -0,0 +1,197 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "fields.h"
+#include "olestream.h"
+#include "word_helper.h"
+#include "word97_generated.h"
+
+#include "wvlog.h"
+
+namespace wvWare
+{
+ FLD::FLD() : ch( 0 ), flt( 0 )
+ {
+ }
+
+ FLD::FLD( OLEStreamReader* stream, bool preservePos ) : ch( 0 ), flt( 0 )
+ {
+ read( stream, preservePos );
+ }
+
+ FLD::FLD( const U8* ptr ) : ch( 0 ), flt( 0 )
+ {
+ readPtr( ptr );
+ }
+
+ bool FLD::read( OLEStreamReader* stream, bool preservePos )
+ {
+ if ( preservePos )
+ stream->push();
+
+ ch = stream->readU8();
+ flt = stream->readU8();
+
+ if ( preservePos )
+ stream->pop();
+ return true;
+ }
+
+ bool FLD::readPtr( const U8* ptr )
+ {
+ ch = *ptr++;
+ flt = *ptr;
+ return true;
+ }
+
+ void FLD::clear()
+ {
+ ch = 0;
+ flt = 0;
+ }
+
+ const unsigned int FLD::sizeOf = 2;
+
+ bool operator==( const FLD &lhs, const FLD &rhs )
+ {
+ return lhs.ch == rhs.ch &&
+ lhs.flt == rhs.flt;
+ }
+
+ bool operator!=( const FLD &lhs, const FLD &rhs )
+ {
+ return !( lhs == rhs );
+ }
+} // namespace wvWare
+
+using namespace wvWare;
+
+
+Fields::Fields( OLEStreamReader* tableStream, const Word97::FIB& fib ) :
+ m_main( 0 ), m_header( 0 ), m_footnote( 0 ), m_annotation( 0 ),
+ m_endnote( 0 ), m_textbox( 0 ), m_headerTextbox( 0 )
+{
+ tableStream->push();
+
+#ifdef WV2_DEBUG_FIELDS
+ wvlog << "Fields --------------" << std::endl
+ << " main: fc=" << fib.fcPlcffldMom << " lcb=" << fib.lcbPlcffldMom << std::endl
+ << " header: fc=" << fib.fcPlcffldHdr << " lcb=" << fib.lcbPlcffldHdr << std::endl
+ << " footnote: fc=" << fib.fcPlcffldFtn << " lcb=" << fib.lcbPlcffldFtn << std::endl
+ << " annotation: fc=" << fib.fcPlcffldAtn << " lcb=" << fib.lcbPlcffldAtn << std::endl
+ << " endnote: fc=" << fib.fcPlcffldEdn << " lcb=" << fib.lcbPlcffldEdn << std::endl
+ << " textbox: fc=" << fib.fcPlcffldTxbx << " lcb=" << fib.lcbPlcffldTxbx << std::endl
+ << " headertextbox: fc=" << fib.fcPlcffldHdrTxbx << " lcb=" << fib.lcbPlcffldHdrTxbx << std::endl;
+#endif
+
+ tableStream->seek( fib.fcPlcffldMom, G_SEEK_SET ); // to make the sanity check work
+ read( fib.fcPlcffldMom, fib.lcbPlcffldMom, tableStream, &m_main );
+
+ sanityCheck( tableStream, fib.fcPlcffldHdr, fib.lcbPlcffldHdr );
+ read( fib.fcPlcffldHdr, fib.lcbPlcffldHdr, tableStream, &m_header );
+
+ sanityCheck( tableStream, fib.fcPlcffldFtn, fib.lcbPlcffldFtn );
+ read( fib.fcPlcffldFtn, fib.lcbPlcffldFtn, tableStream, &m_footnote );
+
+ sanityCheck( tableStream, fib.fcPlcffldAtn, fib.lcbPlcffldAtn );
+ read( fib.fcPlcffldAtn, fib.lcbPlcffldAtn, tableStream, &m_annotation );
+
+ sanityCheck( tableStream, fib.fcPlcffldEdn, fib.lcbPlcffldEdn );
+ read( fib.fcPlcffldEdn, fib.lcbPlcffldEdn, tableStream, &m_endnote );
+
+ sanityCheck( tableStream, fib.fcPlcffldTxbx, fib.lcbPlcffldTxbx );
+ read( fib.fcPlcffldTxbx, fib.lcbPlcffldTxbx, tableStream, &m_textbox );
+
+ // No sanity check here, plcOcx might be in between
+ read( fib.fcPlcffldHdrTxbx, fib.lcbPlcffldHdrTxbx, tableStream, &m_headerTextbox );
+
+ tableStream->pop();
+}
+
+Fields::~Fields()
+{
+ delete m_headerTextbox;
+ delete m_textbox;
+ delete m_endnote;
+ delete m_annotation;
+ delete m_footnote;
+ delete m_header;
+ delete m_main;
+}
+
+const FLD* Fields::fldForCP( Parser::SubDocument subDocument, U32 cp ) const
+{
+ switch( subDocument ) {
+ case Parser::None:
+ wvlog << "Error: The state of the parser is invalid!" << std::endl;
+ return 0;
+ break;
+ case Parser::Main:
+ return fldForCP( m_main, cp );
+ break;
+ case Parser::Footnote:
+ return fldForCP( m_footnote, cp );
+ break;
+ case Parser::Header:
+ return fldForCP( m_header, cp );
+ break;
+ case Parser::Macro:
+ wvlog << "Warning: There shouldn't be any fields in macro text" << std::endl;
+ return 0;
+ break;
+ case Parser::Annotation:
+ return fldForCP( m_annotation, cp );
+ break;
+ case Parser::Endnote:
+ return fldForCP( m_endnote, cp );
+ break;
+ case Parser::TextBox:
+ return fldForCP( m_textbox, cp );
+ break;
+ case Parser::HeaderTextBox:
+ return fldForCP( m_headerTextbox, cp );
+ break;
+ }
+ return 0; // make the compiler happy, never reached
+}
+
+void Fields::read( U32 fc, U32 lcb, OLEStreamReader* tableStream, PLCF<FLD>** plcf )
+{
+ if ( lcb == 0 )
+ return;
+ tableStream->seek( fc, G_SEEK_SET );
+ *plcf = new PLCF<FLD>( lcb, tableStream );
+}
+
+void Fields::sanityCheck( const OLEStreamReader* tableStream, U32 nextFC, U32 lcb ) const
+{
+ if ( lcb != 0 && static_cast<U32>( tableStream->tell() ) != nextFC )
+ wvlog << "Warning: Detected a hole within the table stream (next fc=" << nextFC << ")" << std::endl;
+}
+
+const FLD* Fields::fldForCP( const PLCF<FLD>* plcf, U32 cp ) const
+{
+ if ( !plcf )
+ return 0;
+
+ PLCFIterator<FLD> it( *plcf );
+ for ( ; it.current(); ++it )
+ if ( it.currentStart() == cp )
+ return it.current();
+ return 0;
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/fields.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/fields.h
new file mode 100644
index 00000000..8a8ef1e8
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/fields.h
@@ -0,0 +1,97 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef FIELDS_H
+#define FIELDS_H
+
+#include "parser.h"
+
+namespace wvWare
+{
+ namespace Word97
+ {
+ struct FIB;
+ }
+ template<class T> class PLCF;
+ class OLEStreamReader;
+
+ struct FLD
+ {
+ FLD();
+ FLD( OLEStreamReader* stream, bool preservePos = false );
+ FLD( const U8* ptr );
+
+ bool read( OLEStreamReader* stream, bool preservePos = false );
+ bool readPtr( const U8* ptr );
+
+ void clear();
+
+ // Data
+ U8 ch;
+ union
+ {
+ U8 flt;
+ struct
+ {
+ U8 fDiffer:1;
+ U8 fZomieEmbed:1;
+ U8 fResultDirty:1;
+ U8 fResultEdited:1;
+ U8 fLocked:1;
+ U8 fPrivateResult:1;
+ U8 fNested:1;
+ U8 fHasSep:1;
+ } flags;
+ };
+
+ // Size of the structure (needed for the PLCF template)
+ static const unsigned int sizeOf;
+ };
+
+ bool operator==( const FLD &lhs, const FLD &rhs );
+ bool operator!=( const FLD &lhs, const FLD &rhs );
+
+
+ class Fields
+ {
+ public:
+ Fields( OLEStreamReader* tableStream, const Word97::FIB& fib );
+ ~Fields();
+
+ const FLD* fldForCP( Parser::SubDocument subDocument, U32 cp ) const;
+
+ private:
+ Fields( const Fields& rhs );
+ Fields& operator=( const Fields& rhs );
+
+ void read( U32 fc, U32 lcb, OLEStreamReader* tableStream, PLCF<FLD>** plcf );
+ void sanityCheck( const OLEStreamReader* tableStream, U32 nextFC, U32 lcb ) const;
+ const FLD* fldForCP( const PLCF<FLD>* plcf, U32 cp ) const;
+
+ PLCF<FLD>* m_main;
+ PLCF<FLD>* m_header;
+ PLCF<FLD>* m_footnote;
+ PLCF<FLD>* m_annotation;
+ PLCF<FLD>* m_endnote;
+ PLCF<FLD>* m_textbox;
+ PLCF<FLD>* m_headerTextbox;
+ };
+
+} // namespace wvWare
+
+#endif // FIELDS_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/fonts.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/fonts.cpp
new file mode 100644
index 00000000..1aba1232
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/fonts.cpp
@@ -0,0 +1,82 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "fonts.h"
+#include "olestream.h"
+#include "word97_generated.h"
+#include "utilities.h"
+
+#include "wvlog.h"
+
+using namespace wvWare;
+
+FontCollection::FontCollection( OLEStreamReader* reader, const Word97::FIB& fib )
+{
+ m_fallbackFont = new Word97::FFN();
+ m_fallbackFont->xszFfn = "Helvetica";
+
+ reader->push();
+ reader->seek( fib.fcSttbfffn );
+
+ if ( fib.nFib < Word8nFib ) { // older than Word97
+ int bytesLeft = reader->readU16() - 2;
+ while ( bytesLeft > 0 ) {
+ Word97::FFN* ffn = new Word97::FFN( reader, Word97::FFN::Word95, false );
+ m_fonts.push_back( ffn );
+ bytesLeft -= ffn->cbFfnM1 + 1;
+ }
+ }
+ else { // Word97 or newer
+ const U16 count = reader->readU16();
+ const U16 extraData = reader->readU16();
+ if ( extraData != 0 )
+ wvlog << "Huh?? Found STTBF extra data within the STTBF of FFNs" << std::endl;
+
+ for ( int i = 0; i < count; ++i )
+ m_fonts.push_back( new Word97::FFN( reader, Word97::FFN::Word97, false ) );
+ }
+
+ if ( reader->tell() - fib.fcSttbfffn != fib.lcbSttbfffn )
+ wvlog << "Warning: Didn't read lcbSttbfffn bytes: read=" << reader->tell() - fib.fcSttbfffn
+ << " lcbSttbfffn=" << fib.lcbSttbfffn << std::endl;
+ reader->pop();
+}
+
+FontCollection::~FontCollection()
+{
+ std::for_each( m_fonts.begin(), m_fonts.end(), Delete<Word97::FFN>() );
+ delete m_fallbackFont;
+}
+
+const Word97::FFN& FontCollection::font( S16 ftc ) const
+{
+ if ( ftc >= 0 && static_cast<U16>( ftc ) < m_fonts.size() )
+ return *m_fonts[ ftc ];
+ return *m_fallbackFont;
+}
+
+void FontCollection::dump() const
+{
+ std::vector<Word97::FFN*>::const_iterator it = m_fonts.begin();
+ std::vector<Word97::FFN*>::const_iterator end = m_fonts.end();
+ for ( ; it != end; ++it ) {
+ wvlog << "Font: xszFfn='" << ( *it )->xszFfn.ascii() << "'" << std::endl;
+ if ( !( *it )->xszFfnAlt.isEmpty() )
+ wvlog << " xszFfnAlt='" << ( *it )->xszFfnAlt.ascii() << "'" << std::endl;
+ }
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/fonts.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/fonts.h
new file mode 100644
index 00000000..bbbfc715
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/fonts.h
@@ -0,0 +1,69 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef FONTS_H
+#define FONTS_H
+
+#include "global.h"
+#include <vector>
+
+namespace wvWare
+{
+ class OLEStreamReader;
+ namespace Word97
+ {
+ struct FIB;
+ struct FFN;
+ }
+
+ /**
+ * The FontCollection can be used to map ftc (font code) values to font names.
+ */
+ class FontCollection
+ {
+ public:
+ /**
+ * You shouldn't construct such objects yourself, the Parser interface
+ * provides accesst to the internal font collection.
+ * @param reader is either a table or a document stream (97+ / older versions)
+ */
+ FontCollection( OLEStreamReader* reader, const Word97::FIB& fib );
+ ~FontCollection();
+
+ /**
+ * Returns the matching FFN structure for the given font code. If no matching
+ * FFN is found, a fallback defaulting to "Helvetica" is returned.
+ */
+ const Word97::FFN& font( S16 ftc ) const;
+
+ /**
+ * Dump all the font information, used for debugging.
+ */
+ void dump() const;
+
+ private:
+ FontCollection( const FontCollection& rhs );
+ FontCollection& operator=( const FontCollection& rhs );
+
+ std::vector<Word97::FFN*> m_fonts;
+ Word97::FFN* m_fallbackFont;
+ };
+
+} // namespace wvWare
+
+#endif // FONTS_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/footnotes97.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/footnotes97.cpp
new file mode 100644
index 00000000..3dbe9bd9
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/footnotes97.cpp
@@ -0,0 +1,131 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "footnotes97.h"
+#include "word_helper.h"
+#include "word97_generated.h"
+#include "olestream.h"
+
+#include "wvlog.h"
+
+using namespace wvWare;
+
+Footnotes97::Footnotes97( OLEStreamReader* tableStream, const Word97::FIB& fib ) :
+ m_footnoteRef( 0 ), m_footnoteRefIt( 0 ), m_endnoteRef( 0 ), m_endnoteRefIt( 0 )
+{
+#ifdef WV2_DEBUG_FOOTNOTES
+ wvlog << "Footnotes97::Footnotes97()" << std::endl
+ << " fcPlcffndRef=" << fib.fcPlcffndRef << " lcbPlcffndRef=" << fib.lcbPlcffndRef << std::endl
+ << " fcPlcffndTxt=" << fib.fcPlcffndTxt << " lcbPlcffndTxt=" << fib.lcbPlcffndTxt << std::endl
+ << " fcPlcfendRef=" << fib.fcPlcfendRef << " lcbPlcfendRef=" << fib.lcbPlcfendRef << std::endl
+ << " fcPlcfendTxt=" << fib.fcPlcfendTxt << " lcbPlcfendTxt=" << fib.lcbPlcfendTxt << std::endl;
+#endif
+ tableStream->push();
+ // Footnotes
+ init( fib.fcPlcffndRef, fib.lcbPlcffndRef, fib.fcPlcffndTxt, fib.lcbPlcffndTxt,
+ tableStream, &m_footnoteRef, &m_footnoteRefIt, m_footnoteTxt, m_footnoteTxtIt );
+ // Endnotes
+ init( fib.fcPlcfendRef, fib.lcbPlcfendRef, fib.fcPlcfendTxt, fib.lcbPlcfendTxt,
+ tableStream, &m_endnoteRef, &m_endnoteRefIt, m_endnoteTxt, m_endnoteTxtIt );
+ tableStream->pop();
+}
+
+Footnotes97::~Footnotes97()
+{
+ delete m_endnoteRefIt;
+ delete m_endnoteRef;
+ delete m_footnoteRefIt;
+ delete m_footnoteRef;
+}
+
+FootnoteData Footnotes97::footnote( U32 globalCP, bool& ok )
+{
+#ifdef WV2_DEBUG_FOOTNOTES
+ wvlog << "Footnotes97::footnote(): globalCP=" << globalCP << std::endl;
+#endif
+ ok = true; // let's assume we will find it
+ if ( m_footnoteRefIt && m_footnoteRefIt->currentStart() == globalCP &&
+ m_footnoteTxtIt != m_footnoteTxt.end() ) {
+ bool fAuto = m_footnoteRefIt->current()->nAuto;
+ ++( *m_footnoteRefIt ); // yay, but it is hard to make that more elegant
+
+ U32 start = *m_footnoteTxtIt;
+ ++m_footnoteTxtIt;
+ return FootnoteData( FootnoteData::Footnote, fAuto, start, *m_footnoteTxtIt );
+ }
+
+ if ( m_endnoteRefIt && m_endnoteRefIt->currentStart() == globalCP &&
+ m_endnoteTxtIt != m_endnoteTxt.end() ) {
+ bool fAuto = m_endnoteRefIt->current()->nAuto;
+ ++( *m_endnoteRefIt ); // yay, but it is hard to make that more elegant
+
+ U32 start = *m_endnoteTxtIt;
+ ++m_endnoteTxtIt;
+ return FootnoteData( FootnoteData::Endnote, fAuto, start, *m_endnoteTxtIt );
+ }
+
+ wvlog << "Bug: There is no footnote or endnote with the CP " << globalCP << std::endl;
+ ok = false;
+ return FootnoteData( FootnoteData::Footnote, false, 0, 0 );
+}
+
+U32 Footnotes97::nextFootnote() const
+{
+ return m_footnoteRefIt && m_footnoteRefIt->current() ? m_footnoteRefIt->currentStart() : 0xffffffff;
+}
+
+U32 Footnotes97::nextEndnote() const
+{
+ return m_endnoteRefIt && m_endnoteRefIt->current() ? m_endnoteRefIt->currentStart() : 0xffffffff;
+}
+
+void Footnotes97::init( U32 fcRef, U32 lcbRef, U32 fcTxt, U32 lcbTxt, OLEStreamReader* tableStream,
+ PLCF<Word97::FRD>** ref, PLCFIterator<Word97::FRD>** refIt,
+ std::vector<U32>& txt, std::vector<U32>::const_iterator& txtIt )
+{
+ if ( lcbRef == 0 )
+ return;
+
+ tableStream->seek( fcRef, G_SEEK_SET );
+ *ref = new PLCF<Word97::FRD>( lcbRef, tableStream );
+ *refIt = new PLCFIterator<Word97::FRD>( **ref );
+
+#ifdef WV2_DEBUG_FOOTNOTES
+ wvlog << "Footnotes97::init()" << std::endl;
+ ( *ref )->dumpCPs();
+#endif
+
+ if ( lcbTxt == 0 )
+ wvlog << "Bug: lcbTxt == 0 but lcbRef != 0" << std::endl;
+ else {
+ if ( static_cast<U32>( tableStream->tell() ) != fcTxt ) {
+ wvlog << "Warning: Found a hole in the table stream" << std::endl;
+ tableStream->seek( fcTxt, G_SEEK_SET );
+ }
+ for ( U32 i = 0; i < lcbTxt; i += sizeof( U32 ) ) {
+ txt.push_back( tableStream->readU32() );
+#ifdef WV2_DEBUG_FOOTNOTES
+ wvlog << "read: " << txt.back() << std::endl;
+#endif
+ }
+ txtIt = txt.begin();
+ }
+#ifdef WV2_DEBUG_FOOTNOTES
+ wvlog << "Footnotes97::init() done" << std::endl;
+#endif
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/footnotes97.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/footnotes97.h
new file mode 100644
index 00000000..ae30e969
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/footnotes97.h
@@ -0,0 +1,89 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef FOOTNOTES97_H
+#define FOOTNOTES97_H
+
+#include "global.h"
+#include "functordata.h"
+
+#include <vector>
+
+namespace wvWare
+{
+ namespace Word97
+ {
+ struct FIB;
+ struct FRD;
+ }
+ template<class T> class PLCF;
+ template<class T> class PLCFIterator;
+ class OLEStreamReader;
+ struct FootnoteData;
+
+ /**
+ * @internal
+ */
+ class Footnotes97
+ {
+ public:
+ Footnotes97( OLEStreamReader* tableStream, const Word97::FIB& fib );
+ ~Footnotes97();
+
+ /**
+ * Get the FootnoteData for the footnote/endnote at @param globalCP.
+ * The @param ok flag is true if a footnote/endnote has been found.
+ * If @�aram ok is false no footnote/endnote has been found and the
+ * returned FootnoteData structure is invalid.
+ */
+ FootnoteData footnote( U32 globalCP, bool& ok );
+
+ /**
+ * Returns the global CP of the next footnote reference,
+ * 0xffffffff if none exists.
+ */
+ U32 nextFootnote() const;
+ /**
+ * Returns the global CP of the next endnote reference,
+ * 0xffffffff if none exists.
+ */
+ U32 nextEndnote() const;
+
+ private:
+ Footnotes97( const Footnotes97& rhs );
+ Footnotes97& operator=( const Footnotes97& rhs );
+
+ // Ugly, but helps to avoid code duplication
+ void init( U32 fcRef, U32 lcbRef, U32 fcTxt, U32 lcbTxt, OLEStreamReader* tableStream,
+ PLCF<Word97::FRD>** ref, PLCFIterator<Word97::FRD>** refIt,
+ std::vector<U32>& txt, std::vector<U32>::const_iterator& txtIt );
+
+ PLCF<Word97::FRD>* m_footnoteRef;
+ PLCFIterator<Word97::FRD>* m_footnoteRefIt;
+ std::vector<U32> m_footnoteTxt;
+ std::vector<U32>::const_iterator m_footnoteTxtIt;
+
+ PLCF<Word97::FRD>* m_endnoteRef;
+ PLCFIterator<Word97::FRD>* m_endnoteRefIt;
+ std::vector<U32> m_endnoteTxt;
+ std::vector<U32>::const_iterator m_endnoteTxtIt;
+ };
+
+} // namespace wvWare
+
+#endif // FOOTNOTES97_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/functor.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/functor.cpp
new file mode 100644
index 00000000..2512ca92
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/functor.cpp
@@ -0,0 +1,30 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "functor.h"
+
+using namespace wvWare;
+
+FunctorBase::~FunctorBase()
+{
+}
+
+void FunctorBase::operator()() const
+{
+}
+
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/functor.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/functor.h
new file mode 100644
index 00000000..f65c4201
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/functor.h
@@ -0,0 +1,69 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef FUNCTOR_H
+#define FUNCTOR_H
+
+namespace wvWare
+{
+ /**
+ * FunctorBase is provided to allow polymorphic handling of different
+ * types of functors. Use it like the real functor.
+ */
+ class FunctorBase
+ {
+ public:
+ virtual ~FunctorBase() = 0;
+ virtual void operator()() const;
+ };
+
+ /**
+ * The Functor class is used to pass on callback information to the
+ * consumer filter. You may copy and assign it, to invoke it just
+ * call operator().
+ */
+ template<class ParserT, typename Data>
+ class Functor : public FunctorBase
+ {
+ public:
+ typedef void (ParserT::*F)( const Data& );
+
+ Functor( ParserT& parser, F f, const Data& data )
+ : m_parser( &parser ), f_( f ), m_data( data ) {}
+ virtual void operator()() const { (m_parser->*f_)( m_data ); }
+
+ private:
+ ParserT* m_parser;
+ F f_;
+ Data m_data;
+ };
+
+ /**
+ * A small helper function to avoid unnecessary uglyness in the template
+ * creation code. The function figures out the types and we don't have to
+ * specify them explicitly every time we create a functor.
+ */
+ template<class ParserT, typename Data>
+ Functor<ParserT, Data> make_functor( ParserT& parser, void (ParserT::*f) ( const Data& ), const Data& data )
+ {
+ return Functor<ParserT, Data>( parser, f, data );
+ }
+
+} // namespace wvWare
+
+#endif // FUNCTOR_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/functordata.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/functordata.cpp
new file mode 100644
index 00000000..1d670802
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/functordata.cpp
@@ -0,0 +1,43 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "functordata.h"
+#include "word97_generated.h"
+
+using namespace wvWare;
+
+
+TableRowData::TableRowData( unsigned int sp, unsigned int so, unsigned int len,
+ int subDoc, SharedPtr<const Word97::TAP> sharedTap ) :
+ startPiece( sp ), startOffset( so ), length( len ), subDocument( subDoc ), tap( sharedTap )
+{
+}
+
+TableRowData::~TableRowData()
+{
+}
+
+
+PictureData::PictureData( U32 fc, SharedPtr<const Word97::PICF> sharedPicf ) :
+ fcPic( fc ), picf( sharedPicf )
+{
+}
+
+PictureData::~PictureData()
+{
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/functordata.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/functordata.h
new file mode 100644
index 00000000..47994145
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/functordata.h
@@ -0,0 +1,103 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef FUNCTORDATA_H
+#define FUNCTORDATA_H
+
+#include "sharedptr.h"
+
+namespace wvWare
+{
+ /**
+ * @internal
+ * Holds all the necessary information for asynchronous header/footer parsing.
+ * The sectionNumber is a 0-based index, the headerMask holds bits of
+ * the Type enum ORed together.
+ */
+ struct HeaderData
+ {
+ enum Type { HeaderEven = 0x01, HeaderOdd = 0x02, FooterEven = 0x04,
+ FooterOdd = 0x08, HeaderFirst = 0x10, FooterFirst = 0x20 };
+
+ HeaderData( int sectionNum ) : sectionNumber( sectionNum ),
+ headerMask( HeaderOdd | FooterOdd ) {}
+
+ int sectionNumber;
+ unsigned char headerMask;
+ };
+
+
+ /**
+ * @internal
+ * Holds all necessary information for delayed footnote/endnote parsing.
+ */
+ struct FootnoteData
+ {
+ enum Type { Footnote, Endnote };
+
+ FootnoteData( Type t, bool autoNum, unsigned int start, unsigned int lim ) :
+ type( t ), autoNumbered( autoNum ), startCP( start ), limCP( lim ) {}
+
+ Type type;
+ bool autoNumbered;
+ unsigned int startCP;
+ unsigned int limCP;
+ };
+
+
+ namespace Word97
+ {
+ struct TAP;
+ struct PICF;
+ }
+
+ /**
+ * @internal
+ * Keeps track of the table (row) information. Tables are parsed
+ * row by row.
+ */
+ struct TableRowData
+ {
+ TableRowData( unsigned int sp, unsigned int so, unsigned int len,
+ int subDoc, SharedPtr<const Word97::TAP> sharedTap );
+ ~TableRowData();
+
+ unsigned int startPiece;
+ unsigned int startOffset;
+ unsigned int length;
+ int subDocument; // int to avoid #including <parser.h> here
+ SharedPtr<const Word97::TAP> tap;
+ };
+
+
+ /**
+ * @internal
+ * Holds the information about pictures inside the functor.
+ */
+ struct PictureData
+ {
+ PictureData( unsigned int fc, SharedPtr<const Word97::PICF> sharedPicf );
+ ~PictureData();
+
+ unsigned int fcPic;
+ SharedPtr<const Word97::PICF> picf;
+ };
+
+} // namespace wvWare
+
+#endif // FUNCTORDATA_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/.cvsignore b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/.cvsignore
new file mode 100644
index 00000000..44653e57
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/.cvsignore
@@ -0,0 +1,6 @@
+*_generated.*
+*_test.cpp
+convert.h
+convert.cpp
+Makefile
+Makefile.in
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/CMakeLists.txt b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/CMakeLists.txt
new file mode 100644
index 00000000..b6c86297
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/CMakeLists.txt
@@ -0,0 +1,20 @@
+# The generated files will be in the source directory ( src )
+# IMHO polluting the source directory is a bad idea UNLESS the only
+# point of the "make generated" target is to create word9{5,7}_generated.{h,cpp}
+# for "make dist" (i. e. for a tarball)
+# - Pau
+
+ADD_CUSTOM_TARGET( scanner
+ ${CMAKE_COMMAND}
+ -DGENERATOR_DIR:PATH=${wvWare_SOURCE_DIR}/src/generator
+ -P ${wvWare_SOURCE_DIR}/cmake/generate_scanner.cmake
+ )
+
+ADD_CUSTOM_TARGET( converter
+ ${CMAKE_COMMAND}
+ -DGENERATOR_DIR:PATH=${wvWare_SOURCE_DIR}/src/generator
+ -P ${wvWare_SOURCE_DIR}/cmake/generate_converter.cmake
+ )
+
+
+ADD_CUSTOM_TARGET( generated DEPENDS scanner converter )
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/Makefile.am b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/Makefile.am
new file mode 100644
index 00000000..3d28aae0
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/Makefile.am
@@ -0,0 +1,18 @@
+# Some convenience stuff for the code generator...
+
+generated: scanner converter
+
+scanner:
+ @cd $(srcdir) && perl generate.pl generator_wword6.htm Word95 ;\
+ perl generate.pl generator_wword8.htm Word97 ;\
+ cmp -s word95_generated.h ../word95_generated.h || cp word95_generated.h .. ;\
+ cmp -s word95_generated.cpp ../word95_generated.cpp || cp word95_generated.cpp .. ;\
+ cmp -s word97_generated.h ../word97_generated.h || cp word97_generated.h .. ;\
+ cmp -s word97_generated.cpp ../word97_generated.cpp || cp word97_generated.cpp .. ;\
+ cmp -s word95_test.cpp ../../tests/word95_test.cpp || cp word95_test.cpp ../../tests ;\
+ cmp -s word97_test.cpp ../../tests/word97_test.cpp || cp word97_test.cpp ../../tests
+
+converter:
+ @cd $(srcdir) && perl converter.pl generator_wword6.htm generator_wword8.htm ;\
+ cmp -s convert.cpp ../convert.cpp || cp convert.cpp .. ;\
+ cmp -s convert.h ../convert.h || cp convert.h ..
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/converter.pl b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/converter.pl
new file mode 100644
index 00000000..0d6959dd
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/converter.pl
@@ -0,0 +1,721 @@
+#!/usr/local/bin/perl -w
+use strict; # we at least try to ;)
+use Class::Struct;
+
+# This file is part of the wvWare 2 project
+# Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License version 2 as published by the Free Software Foundation.
+
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU Library General Public License
+# along with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# A script to generate code which converts Word95 structures to Word97 ones
+# as good as possible.
+# If you add a convert comment to the Word 6 HTML you can "losen" the
+# restrictions a bit:
+# - convert="string(fieldname)" converts between U8[] and XCHAR[]
+# In case you want to limit the string size just write
+# "string(fieldname:XY)" where XY is the length to copy.
+# - convert="type" losens the type restrictions and simply tries to assign
+# even if the types are not exactly the same (U32 <- U16,...)
+# - convert="(fieldname)" relates the fieldnames and losens the type
+# restrictions
+# - convert="unused" skips this field
+
+###############################################################################
+# To discuss with Shaheed:
+# - CHP::chse - I think we should map that to the Word97 CHP::fMacChs (70)
+# - I disabled (unused) DOP::fReadOnlyRecommended and DOP::fWriteReservation
+# as this should normally go into the Word97 FIB, but well, I doubt we need
+# that flags.
+# - I mapped the things like cpnBtePap to the "active" Word97 structures
+# instead of mapping it to the blah_W6 compatibility ones.
+# - PAP::fAutoHyph -> ? Maybe it's Word97::PAP::fAutoWrap?
+# - PAP::rgdxaTab, PAP::rgtbd?
+# - PGD: We should create a PGD2 structure for the 2nd table and have
+# conversion function like for PRM -> PRM2. The we can map Word95::PGD to
+# the Word97::PGD2. For now I disabled the structure.
+# - PHE: What to do with the Height/Line field? Have a union for them?
+###############################################################################
+
+# This structure holds one "variable"
+struct Item => {
+ name => '$', # The name of this variable
+ type => '$', # The type (e.g. U16, S32[42],...)
+ bits => '$', # The amount of bits (e.g. 3), if any
+ comment => '$', # The comment for this variable
+ initial => '$', # The initial value of this field, if any
+ len => '$', # If the item is a dynamic array we store its length
+ # here. length can be a plain C++ expression.
+ compareSizeLHS => '$', # If the item is a dynamic array we need to compare the
+ # left-hand-side (lhs) and the rhs in their size. This
+ # is a plain C++ expression returning the size of the LHS.
+ compareSizeRHS => '$', # If the item is a dynamic array we need to compare the
+ # left-hand-side (lhs) and the rhs in their size. This
+ # is a plain C++ expression returning the size of the RHS.
+ startNew => '$', # This field is used for debugging purposes. It
+ # is set to 1 if this variable should start a new
+ # bitfield (and close the last one). We simply
+ # check whether we filled the last field completely here
+ matched => '$', # This field is used to indicate that this item already was "matched"
+ convert => '$', # The conversion options - if any
+};
+
+struct Structure => {
+ name => '$', # The name of the structure
+ comment => '$', # The comment for this struct
+ items => '@', # All the data members
+ hidden => '$', # Set to "//" if we want to comment that structure out
+ dynamic => '$', # Do we have dynamic memory? Then we need a Copy CTOR,
+ # DTOR, assignment op, op==,...
+};
+
+
+# This array of strings contains the whole HTML
+# documentation file. It's used twice when reading the spec in
+# All the parsing subs will read/modify that global array
+# Note: All the tags we use are already converted to
+# uppercase.
+my @document;
+
+# The current index in the document-array (used during parsing)
+my $i;
+
+# These arrays hold all the structures we want to write out
+my @structs95;
+my @structs97;
+
+# The current struct we're working on (only used during parsing)
+my $struct;
+# The current item we're working on (only used during parsing)
+my $item;
+
+# Parses all the structures
+sub parseStructures {
+ my ($doc)=@_;
+ my ($tmp);
+
+ print "Parsing $doc...\n";
+ $i=0;
+ while($i<=$#document) {
+ if($document[$i] =~ m,\</H3\>,) {
+ if($document[$i-1] =~ m/\<H3\>/) { # Safe, as </H3> can't be in the first line
+ # looks okay
+ $struct=Structure->new(); # create a new structure element
+ $document[$i] =~ m,^(.*)\</H3\>,;
+ $struct->comment($1);
+ }
+ elsif($document[$i] =~ m/\<H3\>/) {
+ # looks okay, too
+ $struct=Structure->new(); # create a new structure element
+ $document[$i] =~ m,\<H3\>(.*)\</H3\>,;
+ $struct->comment($1);
+ }
+ else {
+ if($document[$i-1] !~ m/Algorithm/) {
+ # huh? Shouldn't happen at all
+ print "####### ERROR #######\n";
+ print $document[$i-1], "\n", $document[$i], "\n";
+ }
+ $i++; # don't forget that one here :))
+ next;
+ }
+ $struct->comment =~ m,.*\((.*)\),; # get the name of the structure
+ $tmp=$1; # store it in a $tmp var as I'm too clueless :)
+ $tmp =~ s/\s/_/; # replace the spaces with underscores
+ $struct->name($tmp); # ...and set it as name
+ #print "found: name: '", $struct->name, "' comment: '", $struct->comment, "'\n";
+ $struct->hidden(""); # initialize that with a sane value
+
+ #print "Checking for a <TABLE> ";
+ while($document[$i] !~ m,\<TABLE ,) {
+ $i++;
+ #print ".";
+ }
+ #print " found\n";
+ # parse the <TABLE> we found
+ if(parseStructure()) {
+ if($doc eq "Word95") {
+ push(@structs95, $struct); # append the new structure
+ }
+ elsif($doc eq "Word97") {
+ push(@structs97, $struct);
+ }
+ else {
+ print "Error: Word95 or Word97?\n";
+ }
+ }
+ else {
+ print "####### ERROR #######\n";
+ print " name: '", $struct->name, "' comment: '", $struct->comment, "'\n";
+ }
+ }
+ $i++;
+ }
+ print "Done.\n";
+}
+
+# Parses one structure (<table>...</table>)
+sub parseStructure {
+
+ # eat the first row (headline)
+ while($document[$i] !~ m,^\<TR\>$,) {
+ $i++;
+ }
+ while($document[$i] !~ m,^\</TR\>$,) {
+ $i++;
+ }
+
+ # parse all the variables till we encounter </TABLE>
+ while($document[$i] !~ m,^\</TABLE\>$,) {
+ if(parseItem()) {
+ push(@{$struct->items}, $item);
+ $i++;
+ }
+ else {
+ print "####### ERROR #######\n";
+ print " Error while parsing an item!\n";
+ return 0; # uh-oh :}
+ }
+ }
+ #print "count: ", $#{$struct->items}+1, "\n";
+ return 1; # success
+}
+
+# Parses one row of the table (<tr> ... </tr>) to get one
+# data item out of it. Does some trivial error checking
+sub parseItem {
+ my ($myState, $tmp);
+
+ $myState=0;
+ while($document[$i] !~ m,^\<TR\>$,) {
+ $i++;
+ }
+ $item=Item->new();
+ while($document[$i] !~ m,^\</TR\>$,) {
+ if($document[$i] =~ m,^\<TD\>(.*)\</TD\>$,) {
+ if($myState==0) { # this is used for debugging/sanity checking
+ $item->startNew($1);
+ #print " startNew: ", $1, "\n";
+ }
+ # yes, I left out $myState==1 on purpose
+ elsif($myState==2) {
+ $item->name($1);
+ #print " name: ", $1, "\n";
+ }
+ elsif($myState==3) {
+ $item->type($1);
+ #print " type: ", $1, "\n";
+ }
+ elsif($myState==4) {
+ $tmp=$1;
+ if($tmp =~ m/^:(.*)/) {
+ $item->bits($1);
+ #print " bits: ", $1, "\n";
+ }
+ else {
+ #print " no bits but a plain size attribute!\n";
+ }
+ }
+ # yes, I left out $myState==5 on purpose
+ elsif($myState==6) {
+ $item->comment($1);
+ #print " (short) comment: ", $1, "\n";
+ }
+ $myState++;
+ }
+ # The comment can expand across several lines
+ elsif($document[$i] =~ m,^\<TD\>(.*)$, && $myState==6) {
+ $tmp=$1;
+ # Insert a <BR> for "newlines" (consistency)
+ if($document[$i+1] !~ m,\<BR\>,) {
+ $tmp .= "<BR>";
+ }
+ $i++;
+ while($document[$i] !~ m,(.*)\</TD\>$,) {
+ $tmp .= $document[$i];
+ # Insert a <BR> for "newlines" (consistency)
+ if($document[$i+1] !~ m,\<BR\>,) {
+ $tmp .= "<BR>";
+ }
+ $i++;
+ }
+ $document[$i] =~ m,(.*)\</TD\>$,;
+ $tmp .= $1;
+ $item->comment($tmp);
+ #print " (long) comment: ", $tmp, "\n";
+ $myState++;
+ }
+ elsif($document[$i] =~ m,\<\!--\s*initial=\"(.*?)\"\s*--\>,) {
+ #print "initial found: ", $document[$i], " filtered: ", $1, "\n";
+ $item->initial($1);
+ }
+ elsif($document[$i] =~ m,\<\!--\s+compareSizeLHS=\"(.*?)\"\s+compareSizeRHS=\"(.*?)\"\s+--\>,) {
+ #print "compareSize found: ", $document[$i], " filtered: ", $1, ", ", $2, "\n";
+ $item->compareSizeLHS($1);
+ $item->compareSizeRHS($2);
+ }
+ elsif($document[$i] =~ m,\<\!--\s*convert=\"(.*?)\"\s*--\>,) {
+ #print "convert found: ", $document[$i], " filtered: ", $1, "\n";
+ $item->convert($1);
+ }
+ elsif($document[$i] =~ m,^\</TABLE\>$,) {
+ print "Error: Found a table end where I didn't expect it!\n";
+ return 0;
+ }
+ $i++;
+ }
+ #print "$myState==7 ? ", $myState==7, "\n";
+ return $myState==7;
+}
+
+# Parse the template file
+sub parseTemplate {
+ my($name) = @_; # name of the template
+ my($license, $includes, $before, $after, $myState);
+
+ open(TEMPLATE, "<$name") or die "Couldn't open the template: " . $!;
+ # initialize all the template vars
+ $myState=0;
+ $license="";
+ $includes="";
+ $before="";
+ $after="";
+ # read in the information...
+ while(<TEMPLATE>) {
+ if(m/^\#\#\#/) { # ignore comments
+ next;
+ }
+ if(m/^\@\@license-start\@\@$/) { # license section
+ $myState=1;
+ next;
+ }
+ if(m/^\@\@license-end\@\@$/) { # end of license sect.
+ $myState=0;
+ next;
+ }
+ if(m/^\@\@includes-start\@\@$/) { # includes section
+ $myState=2;
+ next;
+ }
+ if(m/^\@\@includes-end\@\@$/) { # end of includes sect.
+ $myState=0;
+ next;
+ }
+ if(m/^\@\@namespace-start\@\@$/) { # namespace (before)
+ $myState=3;
+ next;
+ }
+ if(m/^\@\@generated-code\@\@$/) { # namespace (after)
+ $myState=4;
+ next;
+ }
+ if(m/^\@\@namespace-end\@\@$/) { # end of namespace
+ $myState=0;
+ next;
+ }
+
+ if($myState==1) {
+ $license .= $_;
+ }
+ elsif($myState==2) {
+ $includes .= $_;
+ }
+ elsif($myState==3) {
+ $before .= $_;
+ }
+ elsif($myState==4) {
+ $after .= $_;
+ }
+ }
+ close(TEMPLATE) or die $!;
+ return ($license, $includes, $before, $after);
+}
+
+# Removes some structures we can't generate easily.
+# Note: We write out the struct in the header and just
+# comment it out (that you can copy it for a proper impl.).
+sub cleanStructures {
+ my($index, @clean, $done);
+
+ print "Cleaning up...\n";
+ # Feel free to add your "favorites" here
+ # The goal, however, should be to have as much as possible
+ # generated, so try to fix the HTML ;)
+ @clean=("PAPXFKP", "CHPXFKP",
+ "PAPX", "CHPX", "FLD", "PLCF", "STD", "BRC", "PGD", "SEPX",
+ "FFN", "STSHI", "TBD");
+ foreach (@clean) {
+ $index=0;
+ $done=0;
+ while($index<=$#structs95 && $done==0) {
+ if($structs95[$index]->name eq $_) {
+ print "Removing: ", $structs95[$index]->name, "\n";
+ # Better not really remove, just comment it out by setting "hidden"
+ # That way you can copy the declaration for a real implementation
+ #splice @structs95,$index,1;
+ $structs95[$index]->hidden("//");
+ $done=1;
+ }
+ $index++;
+ }
+ }
+ print "Done.\n";
+}
+
+# Generates the conversion header. trivial code, as we just create declarations
+# like Word97::FOO toWord97(const Word95::FOO &s), where FOO is some struct
+sub generateHeader {
+ my($license, $includes, $before, $after, $myState);
+
+ print "Generating the header file...\n";
+ open(HEADER, ">convert.h") or die "Couldn't open the header for writing: " . $!;
+
+ ($license, $includes, $before, $after) = parseTemplate("template-conv.h");
+
+ # license section...
+ print HEADER $license;
+ print HEADER "\n#ifndef CONVERT_H\n#define CONVERT_H\n\n";
+ # include section...
+ print HEADER "#include <word95_generated.h>\n";
+ print HEADER "#include <word97_generated.h>\n";
+ print HEADER $includes;
+ print HEADER "\nnamespace wvWare {\n\n";
+ print HEADER "namespace Word95 {\n";
+
+ # pre
+ print HEADER $before . "\n";
+ # Fill the empty template
+ print HEADER generateDeclarations();
+ # post
+ print HEADER $after;
+
+ print HEADER "\n} // namespace Word95\n\n";
+ print HEADER "} // namespace wvWare\n\n";
+ print HEADER "#endif // CONVERT_H\n";
+ close(HEADER) or die $!;
+ print "Done.\n";
+}
+
+# This method is used to actually generate the methods with the pattern
+# Word97::FOO toWord97(const Word95::FOO &s), where FOO is some struct
+sub generateDeclarations {
+ my($index, $string, $n, $tmp);
+
+ for($index=0; $index<=$#structs95; $index++) {
+ $n=$structs95[$index]->name;
+ if($structs95[$index]->hidden ne "//") {
+ for($tmp=0; $tmp<=$#structs97; $tmp++) {
+ if($n eq $structs97[$tmp]->name) {
+ $string .= "Word97::$n toWord97(const Word95::$n &s);\n";
+ last;
+ }
+ }
+ }
+ }
+ return $string;
+}
+
+# This is the tricky part. It first adds all the template stuff and calls the
+# generator method to fill the void ;)
+sub generateImplementation {
+ my($tmp, $license, $includes, $before, $after);
+
+ print "Generating the source file...\n";
+ open(SOURCE, ">convert.cpp") or die "Couldn't open the file for writing: " . $!;
+
+ ($license, $includes, $before, $after) = parseTemplate("template-conv.cpp");
+
+ # license section...
+ print SOURCE $license . "\n";
+ # include section...
+ print SOURCE "#include <convert.h>\n";
+ print SOURCE $includes;
+ print SOURCE "\nnamespace wvWare {\n";
+ print SOURCE "\nnamespace Word95 {\n";
+
+ # pre
+ print SOURCE $before . "\n";
+ # Fill the empty template
+ print SOURCE generateFunctions();
+ # post
+ print SOURCE $after;
+
+ print SOURCE "} // namespace Word95\n";
+ print SOURCE "\n} // namespace wvWare\n";
+ close(SOURCE) or die $!;
+ print "Done.\n";
+
+}
+
+# Creates the empty template for every conversion function
+sub generateFunctions {
+ my($index95, $index97, $string, $n, $h);
+
+ for($index95=0; $index95<=$#structs95; $index95++) {
+ $n=$structs95[$index95]->name;
+ $h=$structs95[$index95]->hidden;
+ for($index97=0; $index97<=$#structs97; $index97++) {
+ if($n eq $structs97[$index97]->name) {
+ if($h eq "//") {
+ $string .= "/* Please check...\n";
+ }
+ $string .= "Word97::$n toWord97(const Word95::$n &s) {\n\n";
+ $string .= " Word97::$n ret;\n\n";
+ $string .= generateConversion($index95, $index97);
+ $string .= "\n return ret;\n";
+ if($h eq "//") {
+ $string .= "} */\n\n";
+ }
+ else {
+ $string .= "}\n\n";
+ }
+ last;
+ }
+ }
+ }
+ return $string;
+}
+
+# This method tries to match fields inside structures, using some basic heuristics
+# and hints inside the .html files. Check the documentation at the top of that file
+# for further information about the hints and how to use them
+sub generateConversion {
+ my($index95, $index97)=@_;
+ my($i, $j, @items95, @items97, %result, $tmp1, $tmp2, $string);
+
+ print "Trying to match the fields for " . $structs95[$index95]->name . "\n";
+ if($structs95[$index95]->hidden eq "//") {
+ print " Note: Hidden structure, implementation will be commented out\n";
+ }
+ @items95=@{$structs95[$index95]->items};
+ @items97=@{$structs97[$index97]->items};
+ # First try to find all "direct" matches (type, name, position)
+ for($i=0; $i<=$#items95 && $i<=$#items97; $i++) {
+ if($items95[$i]->name eq $items97[$i]->name &&
+ $items95[$i]->type eq $items97[$i]->type &&
+ ((defined($items95[$i]->bits) && defined($items97[$i]->bits) &&
+ $items95[$i]->bits eq $items97[$i]->bits) ||
+ (not(defined($items95[$i]->bits)) && not(defined($items97[$i]->bits))))) {
+ #print " Direct match for " . $items95[$i]->name . "\n";
+ $items95[$i]->matched(1);
+ $items97[$i]->matched(1);
+ $result{$items95[$i]->name}=$i;
+ }
+ }
+ # Then try to check if we find the same name/type at some other position
+ for($i=0; $i<=$#items95; $i++) {
+ if(not(defined($items95[$i]->matched))) {
+ for($j=0; $j<=$#items97; $j++) {
+ if(not(defined($items97[$j]->matched)) &&
+ $items95[$i]->name eq $items97[$j]->name &&
+ $items95[$i]->type eq $items97[$j]->type) {
+ #print " Indirect match for " . $items95[$i]->name . "\n";
+ $items95[$i]->matched(1);
+ $items97[$j]->matched(1);
+ $result{$items95[$i]->name}=$j;
+ }
+ }
+ }
+ }
+ # Did the "user" add some hints for us?
+ for($i=0; $i<=$#items95; $i++) {
+ if(defined($items95[$i]->convert)) {
+ if($items95[$i]->convert =~ m/^string\((.*)\)$/) {
+ #print " Hint: string($1)\n";
+ $tmp1=$1;
+ if($tmp1 =~ m/(.*):(\d+)/) {
+ #print " Additional length hint: " . $2 . "\n";
+ $tmp1=$1;
+ $tmp2=$2;
+ if($items95[$i]->type =~ m/(.*)\[(.*)\]/) {
+ #print " Old type: " . $items95[$i]->type . "\n";
+ $items95[$i]->type($1 . "[" . $tmp2 . "]");
+ #print " New type: " . $items95[$i]->type . "\n";
+ }
+ }
+ for($j=0; $j<=$#items97; $j++) {
+ if(not(defined($items97[$j]->matched)) &&
+ $tmp1 eq $items97[$j]->name) {
+ #print " Matched due to string hint: " . $items95[$i]->name . " -> " . $1 . "\n";
+ $items95[$i]->matched(1);
+ $items97[$j]->matched(1);
+ $result{$items95[$i]->name}=$j;
+ }
+ }
+ }
+ elsif($items95[$i]->convert =~ m/^type$/) {
+ #print " Hint: type\n";
+ for($j=0; $j<=$#items97; $j++) {
+ if(not(defined($items97[$j]->matched)) &&
+ $items95[$i]->name eq $items97[$j]->name) {
+ #print " Matched due to type hint: " . $items95[$i]->name . "\n";
+ $items95[$i]->matched(1);
+ $items97[$j]->matched(1);
+ $result{$items95[$i]->name}=$j;
+ }
+ }
+ }
+ elsif($items95[$i]->convert =~ m/^\((.*)\)$/) {
+ #print " Hint: ($1)\n";
+ for($j=0; $j<=$#items97; $j++) {
+ if(not(defined($items97[$j]->matched)) &&
+ $1 eq $items97[$j]->name) {
+ #print " Matched due to mapping hint: " . $items95[$i]->name . " -> " . $1 . "\n";
+ $items95[$i]->matched(1);
+ $items97[$j]->matched(1);
+ $result{$items95[$i]->name}=$j;
+ }
+ }
+ }
+ elsif($items95[$i]->convert =~ m/^unused$/) {
+ #print " Hint: unused\n";
+ $items95[$i]->matched(1);
+ $result{$items95[$i]->name}=-42; # unused
+ }
+ else {
+ print " Hint: Didn't understand this hint.\n";
+ }
+ }
+ }
+ # What's still missing? (Information)
+ foreach(@items95) {
+ if(not(defined($_->matched))) {
+ print " -> No match for " . $_->name . "\n";
+ }
+ }
+
+ # Now that we have a complete map (hopefully ;) let's generate the code
+ $string="";
+ foreach(@items95) {
+ $i=$result{$_->name};
+ if(not(defined($i)) || $i == -42) {
+ #print " Skipping item " . $_->name . "\n";
+ next;
+ }
+ $string .= generateMapping($_, $items97[$i]);
+ }
+ return $string;
+}
+
+# Create "one line" of the conversion function. Depending on the type
+# this method has to generate a proper assignment operation.
+sub generateMapping {
+ my($item95, $item97)=@_;
+ my($ret, $tmp);
+
+ # is it a dyn. array we know the size of?
+ if(defined($item95->len) && $item95->len ne "") {
+ $item95->type =~ m/(.*)\[.*\]/;
+ $ret .= " ret." . $item97->name . "=new " . $1 . "[" . $item95->len . "];\n";
+ $ret .= " memcpy(rhs." . $item97->name . ", s." . $item95->name . ", sizeof($1)*(" . $item95->len . "));\n";
+ }
+ elsif($item95->type =~ m/(.*)\[(\d+)\]/) {
+ $ret .= " for(int i=0;i<($2);++i)\n";
+ if(knownType($1)) {
+ $ret .= " ret." . $item97->name . "[i]=toWord97(s." . $item95->name . "[i]);\n";
+ }
+ else {
+ $ret .= " ret." . $item97->name . "[i]=s." . $item95->name . "[i];\n";
+ }
+ }
+ elsif(knownType($item95->type)) {
+ $ret .= " ret." . $item97->name . "=toWord97(s." . $item95->name . ");\n";
+ }
+ else {
+ # "plain" members, no problem here
+ $ret .= " ret." . $item97->name . "=s." . $item95->name . ";\n";
+ }
+ return $ret;
+}
+
+# Helper method to detect known Word95 structs
+sub knownType {
+ my($name)=@_;
+
+ foreach (@structs95) {
+ if($_->name eq $name) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+# Read the whole .html file into an array, line by line
+sub readDocument {
+ my($name)=@_;
+ my $ignore=1;
+
+ open(INPUT, "<$name") or die $!;
+
+ while(<INPUT>) {
+ # Detection of start for Word9x
+ if(m,^Structure Definitions\</h[12]\>$,) {
+ $ignore=0;
+ }
+ # Detection of end for Word97
+ elsif(m,^Appendix A - Reading a Macintosh PICT Graphic\</h2\>$,) {
+ $ignore=1;
+ }
+ # Detection of end for Word95
+ elsif(m,^Appendix A - Changes from version 1\.x to 2\.0\</h1\>$,) {
+ $ignore=1;
+ }
+
+ if(!$ignore) {
+ chomp;
+ # convert the important tags we use to uppercase on the fly
+ s,\<tr\>,\<TR\>,;
+ s,\</tr\>,\</TR\>,;
+ s,\<td\>,\<TD\>,;
+ s,\</td\>,\</TD\>,;
+ s,\<table ,\<TABLE ,;
+ s,\</table\>,\</TABLE\>,;
+ s,\<br\>,\<BR\>,;
+ s,\<h3\>,\<H3\>,;
+ s,\</h3\>,\</H3\>,;
+ # get rid of that ugly &nbsp; thingies
+ s/&nbsp;//g;
+
+ push(@document, $_);
+ }
+ }
+ close(INPUT) or die $!;
+}
+
+# Reads the HTML files and converts the "interesting" tags
+# to uppercase. It also cuts of areas we're not interested in
+# from the begin and the end of the file.
+sub main {
+
+ readDocument($ARGV[0]);
+ parseStructures("Word95");
+ $#document=0;
+ readDocument($ARGV[1]);
+ parseStructures("Word97");
+ $#document=0;
+ cleanStructures(); # get rid of stuff we don't want to use
+
+ generateHeader(); # generate the header file
+ generateImplementation(); # generate the source
+}
+
+# We start execution here
+if($#ARGV != 1) {
+ print "Script to generate C++ code to convert Word95 to Word97 structures";
+ print "\nfrom the HTML specs.\n";
+ print "Usage: perl converter.pl spec95.html spec97.html\n";
+ exit(1);
+}
+
+main();
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/generate.pl b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/generate.pl
new file mode 100644
index 00000000..006fa762
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/generate.pl
@@ -0,0 +1,1829 @@
+#!/usr/local/bin/perl -w
+use strict; # we at least try to ;)
+use Class::Struct;
+
+# This file is part of the wvWare 2 project
+# Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License version 2 as published by the Free Software Foundation.
+
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU Library General Public License
+# along with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+
+# A small utility to generate the basic classes needed to
+# read an write primitive Word structures.
+# Usage: perl generate.pl input_file.html Word97
+# The input_file.html is the document we want to process,
+# 'Word97' is used for various things:
+# - The namespace is called Word97 and all the generated
+# code lives in there
+# - word97_generated.cpp and word97_generated.h are the
+# filenames (note the case)
+
+# A few notes about the form of the HTML document:
+# 1) We expect all seven fields in the tables:
+# b10, b16, field, type, size, bitfield, comment
+# If any of them is absent just add empty ones (<td></td>)
+# 2) If you want to set an initial value for a (plain!) variable
+# you can add a <!-- initial="50" --> HTML comment to the
+# "entry" (preferably after the "field" tag).
+# Note: It has to be on a separate line, else it won't get
+# picked up!
+# Note 2: We don't check the value, we just assign it, so make
+# sure that this is legal C++ (e.g. inital="true", initial="42+42")!
+# Note 3: Everything else will be set to 0
+# 3) In some cases the </table> tag has to be right after the
+# last </tr> tag, so better do that everywhere :)
+# 4) An array with a dynamic size can easily be created by editing
+# the "type field." If you add, say "U8[foo]" then this means:
+# - we create a dynamic array of size "foo", where "foo" is
+# some variable of that structure we have already read.
+# Note: We don't do any error checking here, so be careful
+# not to use uninitialized values we didn't read at
+# the time we create the array!
+# Note2: You can even put plain expressions there, or a
+# call to a function you include in the template!
+# Just make sure that it's legal C++ and that it
+# doesn't contain any '[' or ']' as it will probably
+# confuse the parser.
+# - if foo=="", i.e. if you just have "U32[]" then we will
+# just create a plain pointer for you and initialize it with 0.
+# Note: Plain destruction will work as we just delete [] it.
+# Attention: Copy CTOR and assignment operator won't work!!!!
+# (as we can't know the length) What we do is what
+# C++ does by default - copy the pointer :}
+# To allow proper comparsions (operator==) we have to know the length
+# of the dynamich structure. Therefore you should add a HTML comment
+# to such items, specifying a way to perform that check.
+# (e.g. <!-- compareSizeLHS="lhs.cb" compareSizeRHS="rhs.cb" -->)
+# Everything between the quotes will be copied verbatim to an if statement
+# (e.g. if((lhs.cb)!=(rhs.cb)) ).
+# If you decide to call a function please ensure it returns something
+# useful we can compare :)
+# 5) For all structures which need a way to "apply" a grpprl (e.g. PAP, CHP)
+# we provide a special method you can reimplement if you want to. In the
+# header we simply add a declaration.
+# 6) If you need the possibility to share a structure (e.g. SEP, PAP, CHP,...)
+# you can add it to the list in sub selectShared()
+# 7) In case you want to use the structure in any of the PL(C)F templates
+# you have to add the "sizeof" comment to the .htm file between the name of
+# the structure and the <table> (like for the DTTM struct)
+
+# If you want to ignore certain structures, please add them to
+# the 'cleanStructures' sub.
+# If you need the possibility to read a structure from a plain
+# pointer, too, please add it to the if statement in parseStructures
+
+# This structure holds one "variable"
+struct Item => {
+ name => '$', # The name of this variable
+ type => '$', # The type (e.g. U16, S32[42],...)
+ bits => '$', # The amount of bits (e.g. 3), if any
+ comment => '$', # The comment for this variable
+ initial => '$', # The initial value of this field, if any
+ len => '$', # If the item is a dynamic array we store its length
+ # here. length can be a plain C++ expression.
+ compareSizeLHS => '$', # If the item is a dynamic array we need to compare the
+ # left-hand-side (lhs) and the rhs in their size. This
+ # is a plain C++ expression returning the size of the LHS.
+ compareSizeRHS => '$', # If the item is a dynamic array we need to compare the
+ # left-hand-side (lhs) and the rhs in their size. This
+ # is a plain C++ expression returning the size of the RHS.
+ startNew => '$', # This field is used for debugging purposes. It
+ # is set to 1 if this variable should start a new
+ # bitfield (and close the last one). We simply
+ # check whether we filled the last field completely here
+};
+
+struct Structure => {
+ name => '$', # The name of the structure
+ comment => '$', # The comment for this struct
+ items => '@', # All the data members
+ hidden => '$', # Set to "//" if we want to comment that structure out
+ dynamic => '$', # Do we have dynamic memory? Then we need a Copy CTOR,
+ # DTOR, assignment op, op==,...
+ readPtr => '$', # Do we want to be able to construct/read from a pointer?
+ shared => '$', # Whether this structure should be derived from wvWare::Shared'
+ sizeOf => '$', # The size of the structure (not padded, as in the file!)
+ dumpCode => '$', # Whether dumping code should be generated
+};
+
+
+# This array of strings contains the whole HTML
+# documentation file.
+# All the parsing subs will read/modify that global array
+# Note: All the tags we use are already converted to
+# uppercase.
+my @document;
+
+# The current index in the document-array (used during parsing)
+my $i;
+
+# This string holds the name of the namespace to create
+my $namespace;
+
+# This array holds all the structures we want to write out
+# It's filled during parsing and used heavily afterwards
+my @structs;
+
+# The current struct we're working on (only used during parsing)
+my $struct;
+# The current item we're working on (only used during parsing)
+my $item;
+
+# Parses all the structures
+sub parseStructures {
+ my ($tmp);
+
+ print "Parsing...\n";
+ $i=0;
+ while($i<=$#document) {
+ if($document[$i] =~ m,\</H3\>,) {
+ if($document[$i-1] =~ m/\<H3\>/) { # Safe, as </H3> can't be in the first line
+ # looks okay
+ $struct=Structure->new(); # create a new structure element
+ $document[$i] =~ m,^(.*)\</H3\>,;
+ $struct->comment($1);
+ }
+ elsif($document[$i] =~ m/\<H3\>/) {
+ # looks okay, too
+ $struct=Structure->new(); # create a new structure element
+ $document[$i] =~ m,\<H3\>(.*)\</H3\>,;
+ $struct->comment($1);
+ }
+ else {
+ if($document[$i-1] !~ m/Algorithm/) {
+ # huh? Shouldn't happen at all
+ print "####### ERROR #######\n";
+ print $document[$i-1], "\n", $document[$i], "\n";
+ }
+ $i++; # don't forget that one here :))
+ next;
+ }
+ $struct->comment =~ m,.*\((.*)\),; # get the name of the structure
+ $tmp=$1; # store it in a $tmp var as I'm too clueless :)
+ $tmp =~ s/\s/_/; # replace the spaces with underscores
+ $struct->name($tmp); # ...and set it as name
+ #print "found: name: '", $struct->name, "' comment: '", $struct->comment, "'\n";
+ $struct->hidden(""); # initialize that with a sane value
+
+ # We want that readPtr function :)
+ if($struct->name eq "BRC" || $struct->name eq "SHD" || $struct->name eq "DCS"
+ || $struct->name eq "DTTM" || $struct->name eq "PHE" || $struct->name eq "TLP"
+ || $struct->name eq "ANLD" || $struct->name eq "ANLV" || $struct->name eq "OLST"
+ || $struct->name eq "TC" || $struct->name eq "PCD" || $struct->name eq "PRM"
+ || $struct->name eq "NUMRM") {
+ $struct->readPtr(1);
+ }
+
+ #print "Checking for a <TABLE> ";
+ while($document[$i] !~ m,\<TABLE ,) {
+ if($document[$i] =~ m,\<\!--\s*sizeOf\s*=\s*\"(.*?)\"\s*--\>,) {
+ #print "found a sizeOf tag for structure " . $struct->name . ": " . $1 . "\n";
+ $struct->sizeOf($1);
+ }
+ $i++;
+ #print ".";
+ }
+ #print " found\n";
+ # parse the <TABLE> we found
+ if(parseStructure()) {
+ push(@structs, $struct); # append the new structure
+ }
+ else {
+ print "####### ERROR #######\n";
+ print " name: '", $struct->name, "' comment: '", $struct->comment, "'\n";
+ }
+ }
+ $i++;
+ }
+ # print "Number of structures: ", $#structs+1, "\n";
+ print "Done.\n";
+}
+
+# Parses one structure (<table>...</table>)
+sub parseStructure {
+
+ # eat the first row (headline)
+ while($document[$i] !~ m,^\<TR\>$,) {
+ $i++;
+ }
+ while($document[$i] !~ m,^\</TR\>$,) {
+ $i++;
+ }
+
+ # parse all the variables till we encounter </TABLE>
+ while($document[$i] !~ m,^\</TABLE\>$,) {
+ if(parseItem()) {
+ push(@{$struct->items}, $item);
+ $i++;
+ }
+ else {
+ print "####### ERROR #######\n";
+ print " Error while parsing an item!\n";
+ return 0; # uh-oh :}
+ }
+ }
+ #print "count: ", $#{$struct->items}+1, "\n";
+ return 1; # success
+}
+
+# Parses one row of the table (<tr> ... </tr>) to get one
+# data item out of it. Does some trivial error checking
+sub parseItem {
+ my ($myState, $tmp);
+
+ $myState=0;
+ while($document[$i] !~ m,^\<TR\>$,) {
+ $i++;
+ }
+ $item=Item->new();
+ while($document[$i] !~ m,^\</TR\>$,) {
+ if($document[$i] =~ m,^\<TD\>(.*)\</TD\>$,) {
+ if($myState==0) { # this is used for debugging/sanity checking
+ $item->startNew($1);
+ #print " startNew: ", $1, "\n";
+ }
+ # yes, I left out $myState==1 on purpose
+ elsif($myState==2) {
+ $item->name($1);
+ #print " name: ", $1, "\n";
+ }
+ elsif($myState==3) {
+ $item->type($1);
+ #print " type: ", $1, "\n";
+ }
+ elsif($myState==4) {
+ $tmp=$1;
+ if($tmp =~ m/^:(.*)/) {
+ $item->bits($1);
+ #print " bits: ", $1, "\n";
+ }
+ else {
+ #print " no bits but a plain size attribute!\n";
+ }
+ }
+ # yes, I left out $myState==5 on purpose
+ elsif($myState==6) {
+ $item->comment($1);
+ #print " (short) comment: ", $1, "\n";
+ }
+ $myState++;
+ }
+ # The comment can expand across several lines
+ elsif($document[$i] =~ m,^\<TD\>(.*)$, && $myState==6) {
+ $tmp=$1;
+ # Insert a <BR> for "newlines" (consistency)
+ if($document[$i+1] !~ m,\<BR\>,) {
+ $tmp .= "<BR>";
+ }
+ $i++;
+ while($document[$i] !~ m,(.*)\</TD\>$,) {
+ $tmp .= $document[$i];
+ # Insert a <BR> for "newlines" (consistency)
+ if($document[$i+1] !~ m,\<BR\>,) {
+ $tmp .= "<BR>";
+ }
+ $i++;
+ }
+ $document[$i] =~ m,(.*)\</TD\>$,;
+ $tmp .= $1;
+ $item->comment($tmp);
+ #print " (long) comment: ", $tmp, "\n";
+ $myState++;
+ }
+ elsif($document[$i] =~ m,\<\!--\s*initial=\"(.*?)\"\s*--\>,) {
+ #print "initial found: ", $document[$i], " filtered: ", $1, "\n";
+ $item->initial($1);
+ }
+ elsif($document[$i] =~ m,\<\!--\s+compareSizeLHS=\"(.*?)\"\s+compareSizeRHS=\"(.*?)\"\s+--\>,) {
+ #print "compareSize found: ", $document[$i], " filtered: ", $1, ", ", $2, "\n";
+ $item->compareSizeLHS($1);
+ $item->compareSizeRHS($2);
+ }
+ elsif($document[$i] =~ m,^\</TABLE\>$,) {
+ print "Error: Found a table end where I didn't expect it!\n";
+ return 0;
+ }
+ $i++;
+ }
+ #print "$myState==7 ? ", $myState==7, "\n";
+ return $myState==7;
+}
+
+# Removes some structures we can't generate easily.
+# Note: We write out the struct in the header and just
+# comment it out (that you can copy it for a proper impl.).
+sub cleanStructures {
+ my($index, @clean, $done);
+
+ print "Cleaning up...\n";
+ # Feel free to add your "favorites" here
+ # The goal, however, should be to have as much as possible
+ # generated, so try to fix the HTML ;)
+ @clean=("PAPXFKP", "CHPXFKP",
+ "PAPX", "CHPX", "FLD", "PLCF", "STD", "FFN", "TBD");
+ foreach (@clean) {
+ $index=0;
+ $done=0;
+ while($index<=$#structs && $done==0) {
+ if($structs[$index]->name eq $_) {
+ print "Removing: ", $structs[$index]->name, "\n";
+ # Better not really remove, just comment it out by setting "hidden"
+ # That way you can copy the declaration for a real implementation
+ #splice @structs,$index,1;
+ $structs[$index]->hidden("//");
+ $done=1;
+ }
+ $index++;
+ }
+ }
+ print "Done.\n";
+}
+
+# Moves around some structures to resolve forward references
+# in the generated sources
+sub hoistStructures {
+ my($index, @hoist, $done);
+
+ print "Resolving forward references...\n";
+ # Feel free to add your "favorites" here
+ # Note: LIFO, at least kind of (the last element here is first afterwards)
+ @hoist=("TBD", "TAP", "DPPOLYLINE", "DPTXBX", "DPHEAD", "TC", "TLP", "BRC", "PHE",
+ "SHD", "PRM", "PRM2", "DOPTYPOGRAPHY", "DTTM");
+ foreach (@hoist) {
+ $index=0;
+ $done=0;
+ while($index<=$#structs && $done==0) {
+ if($structs[$index]->name eq $_) {
+ print "Moving: ", $structs[$index]->name, "\n";
+ #print "before: ", $#structs, "\n";
+ unshift @structs, $structs[$index];
+ $index++;
+ #print "afterwards: ", $#structs, "\n";
+ #print "delete: ", $structs[$index]->name, "\n";
+ splice @structs,$index,1;
+ #print "test: ", $structs[0]->name, "\n";
+ $done=1;
+ }
+ $index++;
+ }
+ }
+ print "Done.\n";
+}
+
+# Selects the structures we want to derive from wvWare::Shared.
+sub selectShared {
+ my($index, @shared, $done);
+
+ print "Selecting shared structures...\n";
+ @shared=("SEP", "TAP", "PAP", "CHP", "PICF");
+ foreach (@shared) {
+ $index=0;
+ $done=0;
+ while($index<=$#structs && $done==0) {
+ if($structs[$index]->name eq $_) {
+ print "Sharing: ", $structs[$index]->name, "\n";
+ $structs[$index]->shared(1);
+ $done=1;
+ }
+ $index++;
+ }
+ }
+ print "Done.\n";
+}
+
+# Selects the structures which should contain a dump() method
+sub selectDumped {
+ my($index, @dumped, $done);
+
+ print "Selecting structures with a dump() method...\n";
+ @dumped=("SEP", "TAP", "PAP", "CHP", "OLST", "BRC", "TLP",
+ "SHD", "DTTM", "PHE", "TC", "ANLV", "LSPD", "DCS",
+ "NUMRM", "ANLD", "PICF", "METAFILEPICT");
+ foreach (@dumped) {
+ $index=0;
+ $done=0;
+ while($index<=$#structs && $done==0) {
+ if($structs[$index]->name eq $_) {
+ print "Adding dump() to: ", $structs[$index]->name, "\n";
+ $structs[$index]->dumpCode(1);
+ $done=1;
+ }
+ $index++;
+ }
+ }
+ print "Done.\n";
+}
+
+# The "main" generator function for headers.
+sub generateHeader {
+ my($tmp, $license, $includes, $before, $after, $myState);
+
+ print "Generating the header file...\n";
+ $tmp=lc($namespace);
+ $tmp .= "_generated.h";
+ open(HEADER, ">$tmp") or die "Couldn't open the header for writing: " . $!;
+
+ ($license, $includes, $before, $after) = parseTemplate("template-$namespace.h");
+
+ $tmp =~ s/.h/_h/;
+ $tmp=uc($tmp);
+ # license section...
+ print HEADER $license;
+ print HEADER "\n#ifndef $tmp\n#define $tmp\n\n";
+ # include section...
+ print HEADER "#include \"global.h\"\n";
+ print HEADER "#include \"sharedptr.h\"\n";
+ print HEADER "#include \"utilities.h\"\n";
+ print HEADER $includes;
+ print HEADER "\nnamespace wvWare {\n\n";
+ print HEADER "class OLEStreamReader;\n";
+ print HEADER "class OLEStreamWriter;\n";
+ print HEADER "class StyleSheet;\n";
+ print HEADER "class Style;\n\n";
+
+ print HEADER "namespace $namespace {\n\n";
+
+ # pre
+ print HEADER $before . "\n";
+ # Fill the empty template
+ print HEADER generateHeaderStructs();
+ # post
+ print HEADER $after;
+
+ print HEADER "\n} // namespace $namespace\n\n";
+ print HEADER "} // namespace wvWare\n\n";
+ print HEADER "#endif // $tmp\n";
+ close(HEADER) or die $!;
+ print "Done.\n";
+}
+
+# This subroutine generates the header file's structures
+sub generateHeaderStructs {
+ my($index, $string, $n, $h, $tmp);
+
+ for($index=0; $index<=$#structs; $index++) {
+ $n=$structs[$index]->name;
+ $h=$structs[$index]->hidden;
+ $string .= "/**\n * " . $structs[$index]->comment . "\n */\n";
+ if($h ne "") {
+ $string .= "/* This structure has been commented out because we can't handle it correctly\n";
+ $string .= " * Please don't try to fix it here in this file, but rather copy this broken\n";
+ $string .= " * structure definition and fix it in some auxilliary file. If you want to\n";
+ $string .= " * include that aux. file here, please change the template file.\n */\n";
+ }
+ $string .= $h . "struct $n ";
+ if(defined($structs[$index]->shared)) {
+ $string .= ": public Shared ";
+ }
+ $string .= "{\n";
+ $string .= $h . " /**\n";
+ $string .= $h . " * Creates an empty $n structure and sets the defaults\n";
+ $string .= $h . " */\n";
+ $string .= $h . " $n();\n";
+ $string .= $h . " /**\n";
+ $string .= $h . " * Simply calls read(...)\n";
+ $string .= $h . " */\n";
+ $string .= $h . " $n(OLEStreamReader *stream, bool preservePos=false);\n";
+ if(defined($structs[$index]->readPtr)) {
+ $string .= $h . " /**\n";
+ $string .= $h . " * Simply calls readPtr(...)\n";
+ $string .= $h . " */\n";
+ $string .= $h . " $n(const U8 *ptr);\n";
+ }
+
+ # From here on we first put the text into a temporary variable, as
+ # we might have to insert some code at this place. The reason is
+ # that we need DTOR, Copy CTOR,... if we have pointers in our struct.
+ # Unfortunately we find that out in generateHeaderData and don't know
+ # it here.
+ $tmp = "\n" . $h . " /**\n";
+ $tmp .= $h . " * This method reads the $n structure from the stream.\n";
+ $tmp .= $h . " * If preservePos is true we push/pop the position of\n";
+ $tmp .= $h . " * the stream to save the state. If it's false the state\n";
+ $tmp .= $h . " * of stream will be changed!\n";
+ $tmp .= $h . " */\n";
+ $tmp .= $h . " bool read(OLEStreamReader *stream, bool preservePos=false);\n\n";
+ # Special readPtr() method for all the "ultra primitive" structs
+ # we sometimes have to read from memory (SPRM parameter,...)
+ if(defined($structs[$index]->readPtr)) {
+ $tmp .= $h . " /**\n";
+ $tmp .= $h . " * This method reads the struct from a pointer\n";
+ $tmp .= $h . " */\n";
+ $tmp .= $h . " void readPtr(const U8 *ptr);\n\n";
+ }
+ $tmp .= $h . " /**\n";
+ $tmp .= $h . " * Same as reading :)\n";
+ $tmp .= $h . " */\n";
+ $tmp .= $h . " bool write(OLEStreamWriter *stream, bool preservePos=false) const;\n\n";
+ $tmp .= $h . " /**\n";
+ $tmp .= $h . " * Set all the fields to the inital value (default is 0)\n";
+ $tmp .= $h . " */\n";
+ $tmp .= $h . " void clear();\n\n";
+
+ # Special apply() method for all the PAP, CHP,... structs
+ # Implement that in an auxilliary file
+ if(lc($namespace) eq "word97" && ($n eq "PAP" || $n eq "CHP" || $n eq "TAP" || $n eq "SEP" || $n eq "PICF")) {
+ $tmp .= $h . " /**\n";
+ $tmp .= $h . " * This method applies a grpprl with \@param count elements\n";
+ $tmp .= $h . " */\n";
+ $tmp .= $h . " void apply(const U8 *grpprl, U16 count, const Style* style, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version);\n\n";
+ $tmp .= $h . " /**\n";
+ $tmp .= $h . " * This method applies a whole " . $n . "X to the structure.\n";
+ $tmp .= $h . " * The reason that we only pass a pointer to the start of the exception\n";
+ $tmp .= $h . " * structure is, that we don't know the type in the FKP template :}\n";
+ $tmp .= $h . " */\n";
+ if($n eq "CHP") { # More than just CHP?
+ $tmp .= $h . " void applyExceptions(const U8* exceptions, const Style* paragraphStyle, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version);\n\n";
+ }
+ else {
+ $tmp .= $h . " void applyExceptions(const U8 *exceptions, const StyleSheet *styleSheet, OLEStreamReader* dataStream, WordVersion version);\n\n";
+ }
+ $tmp .= $h . " /**\n";
+ $tmp .= $h . " * This method applies one single SPRM. It returns -1 if it wasn't\n";
+ $tmp .= $h . " * a " . $n . " SPRM and it returns the length of the applied SPRM\n";
+ $tmp .= $h . " * if it was successful.\n";
+ $tmp .= $h . " */\n";
+ $tmp .= $h . " S16 apply" . $n . "SPRM(const U8* ptr, const Style* style, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version);\n\n";
+ }
+
+ # Special toPRM2 method for the PRM struct, implemented in word97_helper.cpp
+ # This method is neccessary as we don't want to rely on a "packed" layout of
+ # the structure so we can't just do evil casting ;)
+ if($n eq "PRM") {
+ $tmp .= $h . " /**\n";
+ $tmp .= $h . " * This method returns a PRM2 created from the current PRM\n";
+ $tmp .= $h . " */\n";
+ $tmp .= $h . " PRM2 toPRM2() const;\n\n";
+ }
+
+ if(defined($structs[$index]->dumpCode)) {
+ $tmp .= $h . " /**\n";
+ $tmp .= $h . " * Dumps all fields of this structure (for debugging)\n";
+ $tmp .= $h . " */\n";
+ $tmp .= $h . " void dump() const;\n\n";
+
+ $tmp .= $h . " /**\n";
+ $tmp .= $h . " * Converts the data structure to a string (for debugging)\n";
+ $tmp .= $h . " */\n";
+ $tmp .= $h . " std::string toString() const;\n\n";
+ }
+
+ if(defined($structs[$index]->sizeOf)) {
+ $tmp .= $h . " // Size of the structure\n";
+ $tmp .= $h . " static const unsigned int sizeOf;\n\n";
+ }
+
+ $tmp .= $h . " // Data\n";
+ $tmp .= generateHeaderData($index);
+
+ if(defined($structs[$index]->dynamic)) {
+ # okay, now we already know what we need, so let's
+ # add that stuff (to $string, of course ;)
+ $string .= $h . " /**\n";
+ $string .= $h . " * Attention: This struct allocates memory on the heap\n";
+ $string .= $h . " */\n";
+ $string .= $h . " $n(const $n &rhs);\n";
+ $string .= $h . " ~" . $n . "();\n\n";
+ $string .= $h . " " . $n . " &operator=(const $n &rhs);\n";
+ }
+ # insert the stuff from above
+ $string .= $tmp;
+
+ # If we have dynamic structures we have to be careful
+ # with clear()! We simply define that clear() also
+ # delete []s all the arrays and clearInternal() just sets
+ # everything to 0
+ if(defined($structs[$index]->dynamic)) {
+ $string .= $h . "private:\n";
+ $string .= $h . " void clearInternal();\n\n";
+ }
+ $string .= $h . "}; // $n\n";
+
+ # ...and add some more code "outside"
+ $string .= "\n" . $h . "bool operator==(const $n &lhs, const $n &rhs);\n";
+ $string .= $h . "bool operator!=(const $n &lhs, const $n &rhs);\n\n\n";
+ }
+ return $string;
+}
+
+# Takes one structure and generates all the fields for it.
+# Checks the bit-fields for missing bits and tries to detect
+# arrays with non-static size. We use that information all
+# over the place :)
+sub generateHeaderData {
+ my ($index)=@_;
+ my ($string, $tmp, $tmp2, $sum, $bits, $h);
+
+ $sum=0; # no bits counted up to now :)
+ $bits=0; # make the first check work
+
+ # write out all the data
+ foreach (@{$structs[$index]->items}) {
+ $h=$structs[$index]->hidden;
+ $string .= prepareComment($_->comment, $h);
+ # Check the completeness of the bitfields...
+ if($_->startNew ne "") {
+ if($bits != $sum) {
+ print " ERROR: Last bitfield incomplete. Current position: ";
+ print $structs[$index]->name . " - " . $_->name . "\n";
+ }
+ # set up a new check (sloppy, only for U8, U16, and U32 bitfields)
+ if($_->type =~ m/U(\d+)/ && defined($_->bits)) {
+ #print "bitfield..." . $_->name . "\n";
+ $bits=$1;
+ }
+ else {
+ $bits=0;
+ }
+ $sum=0;
+ }
+ # Handle XCHAR[32] by splitting it up properly
+ if($_->type =~ m/(.*)(\[.*\])/) {
+ $tmp = " " . $1 . " " . $_->name . $2;
+ #print "Array: '" . $tmp . "'\n";
+ # Is it a fixed size array or not?
+ if($tmp !~ m/.*\[\d+\]/) {
+ $tmp =~ m/ (.+)\[(.*)\]/;
+ $tmp2=$1;
+ # get the "length" (or the C++ expression ;)
+ $_->len($2);
+ $tmp2 =~ s/ / \*/;
+ $tmp = " " . $tmp2 . "; //" . $tmp;
+ #print " --- Result: " . $tmp . "\n";
+ # okay, we found a dynamic array, so we need some additional
+ # code for that struct (Copy CTOR, DTOR,...)
+ $structs[$index]->dynamic(1);
+ #if(defined($_->len)) {
+ # print "Dynamic: " . $structs[$index]->name . ", length: " . $_->len . "\n";
+ #}
+ }
+ $string .= $h . $tmp;
+ }
+ else {
+ $string .= $h . " " . $_->type . " " . $_->name;
+ }
+ if(defined($_->bits)) {
+ $string .= ":" . $_->bits;
+ $sum += $_->bits;
+ }
+ $string .= ";\n\n";
+ }
+ return $string;
+}
+
+# This meathod gets a looong comment string. It takes the
+# string and splits it at the <BR>s and creates a nice
+# comment out of it (not longer than, say 90 cols, as found in
+# the HTML spec)
+sub prepareComment {
+ my($comment, $h)=@_;
+ my($string, @tmp);
+
+ if($comment eq "") {
+ return "";
+ }
+
+ $string = $h . " /**\n";
+ # "unfold" the <BR>'ed comments
+ @tmp=split(/\<BR\>/, $comment);
+ foreach (@tmp) {
+ $string .= $h . " * $_\n";
+ }
+ $string .= $h . " */\n";
+ return $string;
+}
+
+# Parse the template file
+sub parseTemplate {
+ my($name) = @_; # name of the template
+ my($license, $includes, $before, $after, $myState);
+
+ open(TEMPLATE, "<$name") or die "Couldn't open the template: " . $!;
+ # initialize all the template vars
+ $myState=0;
+ $license="";
+ $includes="";
+ $before="";
+ $after="";
+ # read in the information...
+ while(<TEMPLATE>) {
+ if(m/^\#\#\#/) { # ignore comments
+ next;
+ }
+ if(m/^\@\@license-start\@\@$/) { # license section
+ $myState=1;
+ next;
+ }
+ if(m/^\@\@license-end\@\@$/) { # end of license sect.
+ $myState=0;
+ next;
+ }
+ if(m/^\@\@includes-start\@\@$/) { # includes section
+ $myState=2;
+ next;
+ }
+ if(m/^\@\@includes-end\@\@$/) { # end of includes sect.
+ $myState=0;
+ next;
+ }
+ if(m/^\@\@namespace-start\@\@$/) { # namespace (before)
+ $myState=3;
+ next;
+ }
+ if(m/^\@\@generated-code\@\@$/) { # namespace (after)
+ $myState=4;
+ next;
+ }
+ if(m/^\@\@namespace-end\@\@$/) { # end of namespace
+ $myState=0;
+ next;
+ }
+
+ if($myState==1) {
+ $license .= $_;
+ }
+ elsif($myState==2) {
+ $includes .= $_;
+ }
+ elsif($myState==3) {
+ $before .= $_;
+ }
+ elsif($myState==4) {
+ $after .= $_;
+ }
+ }
+ close(TEMPLATE) or die $!;
+ return ($license, $includes, $before, $after);
+}
+
+# generate the source file
+sub generateImplementation {
+ my($tmp, $license, $includes, $before, $after, $myState);
+
+ print "Generating the source file...\n";
+ $tmp=lc($namespace);
+ $tmp .= "_generated.cpp";
+ open(SOURCE, ">$tmp") or die "Couldn't open the file for writing: " . $!;
+
+ ($license, $includes, $before, $after) = parseTemplate("template-$namespace.cpp");
+
+ # license section...
+ print SOURCE $license . "\n";
+ # include section...
+ $tmp =~ s/\.cpp/\.h/;
+ print SOURCE "#include <$tmp>\n";
+ print SOURCE "#include <olestream.h>\n";
+ print SOURCE "#include <string.h> // memset(), memcpy()\n";
+ print SOURCE "#include \"wvlog.h\"\n";
+ print SOURCE $includes;
+ print SOURCE "\nnamespace wvWare {\n";
+ print SOURCE "\nnamespace $namespace {\n\n";
+
+ # pre
+ print SOURCE $before . "\n";
+ # Fill the empty template
+ print SOURCE generateImplStructs();
+ # post
+ print SOURCE $after;
+
+ print SOURCE "\n} // namespace $namespace\n";
+ print SOURCE "\n} // namespace wvWare\n";
+ close(SOURCE) or die $!;
+ print "Done.\n";
+}
+
+# Iterare over all structs and generte the necessary code
+sub generateImplStructs {
+ my($index, $string, $n);
+
+ for($index=0; $index<=$#structs; $index++) {
+ if($structs[$index]->hidden ne "") {
+ next; # Don't generate useless code
+ }
+ $n=$structs[$index]->name;
+ $string .= "// $n implementation\n\n";
+
+ # Size (if specified)
+ if(defined($structs[$index]->sizeOf)) {
+ $string .= "const unsigned int " . $n . "::sizeOf = " . $structs[$index]->sizeOf . ";\n\n";
+ }
+
+ # default CTOR
+ $string .= $n . "::" . $n . "() ";
+ if(defined($structs[$index]->shared)) {
+ $string .= ": Shared() ";
+ }
+ $string .= "{\n";
+ if(defined($structs[$index]->dynamic)) {
+ $string .= " clearInternal();\n";
+ }
+ else {
+ $string .= " clear();\n";
+ }
+ $string .= "}\n\n";
+ # stream CTOR
+ $string .= $n . "::" . $n . "(OLEStreamReader *stream, bool preservePos) ";
+ if(defined($structs[$index]->shared)) {
+ $string .= ": Shared() ";
+ }
+ $string .= "{\n";
+ if(defined($structs[$index]->dynamic)) {
+ $string .= " clearInternal();\n";
+ }
+ else {
+ $string .= " clear();\n";
+ }
+ $string .= " read(stream, preservePos);\n";
+ $string .= "}\n\n";
+ # readPtr CTOR
+ if(defined($structs[$index]->readPtr)) {
+ $string .= $n . "::" . $n . "(const U8 *ptr) ";
+ if(defined($structs[$index]->shared)) {
+ $string .= ": Shared() ";
+ }
+ $string .= "{\n";
+ if(defined($structs[$index]->dynamic)) {
+ $string .= " clearInternal();\n";
+ }
+ else {
+ $string .= " clear();\n";
+ }
+ $string .= " readPtr(ptr);\n";
+ $string .= "}\n\n";
+ }
+ if(defined($structs[$index]->dynamic)) {
+ # Copy CTOR
+ $string .= $n . "::" . $n . "(const $n &rhs) ";
+ if(defined($structs[$index]->shared)) {
+ $string .= ": Shared() ";
+ }
+ $string .= "{\n";
+ $string .= generateCopyCTOR($index);
+ $string .= "}\n\n";
+ # DTOR
+ $string .= $n . "::~" . $n . "() {\n";
+ $string .= generateDTOR($index);
+ $string .= "}\n\n";
+ # assignement operator
+ $string .= $n . " &" . $n . "::operator=(const $n &rhs) {\n";
+ $string .= generateAssignment($index);
+ $string .= "}\n\n";
+ }
+ # read()
+ $string .= "bool " . $n . "::read(OLEStreamReader *stream, bool preservePos) {\n";
+ $string .= generateRead($index);
+ $string .= "}\n\n";
+ # readPtr()?
+ if(defined($structs[$index]->readPtr)) {
+ $string .= "void " . $n . "::readPtr(const U8 *ptr) {\n";
+ $string .= generateReadPtr($index);
+ $string .= "}\n\n";
+ }
+ # write()
+ $string .= "bool " . $n . "::write(OLEStreamWriter *stream, bool preservePos) const {\n";
+ $string .= generateWrite($index);
+ $string .= "}\n\n";
+ # clear()
+ $string .= "void " . $n . "::clear() {\n";
+ $string .= generateClear($index);
+ $string .= "}\n\n";
+
+ if(defined($structs[$index]->dumpCode)) {
+ $string .= "void " . $n . "::dump() const\n{\n";
+ $string .= generateDump($index);
+ $string .= "}\n\n";
+
+ $string .= "std::string " . $n . "::toString() const\n{\n";
+ $string .= generateToString($index);
+ $string .= "}\n\n";
+ }
+
+ if(defined($structs[$index]->dynamic)) {
+ $string .= "void " . $n . "::clearInternal() {\n";
+ $string .= generateClearInternal($index);
+ $string .= "}\n\n";
+ }
+
+ # It's okay to initialize the const variable in the header
+ #if(defined($structs[$index]->sizeOf)) {
+ # $string .= "const unsigned int " . $n . "::sizeOf = " . $structs[$index]->sizeOf . ";\n\n";
+ #}
+
+ # operator== and op!=
+ $string .= "bool operator==(const $n &lhs, const $n &rhs) {\n";
+ $string .= generateEqualityOp($index);
+ $string .= "}\n\n";
+ $string .= "bool operator!=(const $n &lhs, const $n &rhs) {\n";
+ $string .= " return !(lhs==rhs);\n";
+ $string .= "}\n\n\n";
+ }
+ return $string;
+}
+
+# Generates a Copy Constructor
+sub generateCopyCTOR {
+ my($index)=@_;
+ my($string);
+
+ foreach (@{$structs[$index]->items}) {
+ # is it a dyn. array we know the size of?
+ if(defined($_->len) && $_->len ne "") {
+ $_->type =~ m/(.*)\[.*\]/;
+ $string .= " " . $_->name . "=new " . $1 . "[" . $_->len . "];\n";
+ $string .= " memcpy(" . $_->name . ", rhs." . $_->name . ", sizeof($1)*(" . $_->len . "));\n";
+ }
+ elsif($_->type =~ m/.*\[\d+\]/) {
+ $string .= " memcpy(&" . $_->name . ", &rhs." . $_->name . ", sizeof(" . $_->name . "));\n";
+ }
+ else {
+ # "plain" members, no problem here
+ $string .= " " . $_->name . "=rhs." . $_->name . ";\n";
+ }
+ }
+ return $string;
+}
+
+
+# Generates a Destructor
+sub generateDTOR {
+ my($index)=@_;
+ my($string);
+
+ foreach (@{$structs[$index]->items}) {
+ # is it a dyn. array (regardless whether we know the size!) ?
+ if(defined($_->len)) {
+ $string .= " delete [] " . $_->name . ";\n";
+ }
+ }
+ return $string;
+}
+
+# Generates an assignment operator
+sub generateAssignment {
+ my($index)=@_;
+ my($string);
+
+ $string = "\n // Check for assignment to self\n";
+ $string .= " if(this==&rhs)\n";
+ $string .= " return *this;\n\n";
+
+ foreach (@{$structs[$index]->items}) {
+ # is it a dyn. array we know the size of?
+ if(defined($_->len) && $_->len ne "") {
+ $string .= " delete [] " . $_->name . ";\n";
+ $_->type =~ m/(.*)\[.*\]/;
+ $string .= " " . $_->name . "=new " . $1 . "[" . $_->len . "];\n";
+ $string .= " memcpy(" . $_->name . ", rhs." . $_->name . ", sizeof($1)*(" . $_->len . "));\n";
+ }
+ elsif($_->type =~ m/.*\[\d+\]/) {
+ $string .= " memcpy(&" . $_->name . ", &rhs." . $_->name . ", sizeof(" . $_->name . "));\n";
+ }
+ else {
+ # "plain" members, no problem here
+ $string .= " " . $_->name . "=rhs." . $_->name . ";\n";
+ }
+ }
+ $string .= "\n return *this;\n";
+ return $string;
+}
+
+# Generates the code to read from the stream
+sub generateRead {
+ my($index)=@_;
+ my($needU8, $needU16, $needU32, $string, $sum, $limit, $vars);
+
+ $needU8=0;
+ $needU16=0;
+ $needU32=0;
+
+ $string = " if(preservePos)\n";
+ $string .= " stream->push();\n\n";
+
+ foreach (@{$structs[$index]->items}) {
+ if(defined($_->bits)) {
+ if($_->type eq "U8") {
+ $needU8=1;
+ $limit=8;
+ }
+ elsif($_->type eq "U16") {
+ $needU16=1;
+ $limit=16;
+ }
+ elsif($_->type eq "U32") {
+ $needU32=1;
+ $limit=32;
+ }
+ else {
+ print " ERROR: Don't know how to handle a '" . $_->type . "' bitfield\n";
+ }
+ # first bit of a bitfield?
+ if($_->startNew ne "") {
+ $string .= " shifter" . $_->type . "=stream->read" . $_->type . "();\n";
+ $sum=0;
+ }
+ $string .= " " . $_->name . "=shifter" . $_->type . ";\n";
+ $sum+=$_->bits;
+ if($sum<$limit) {
+ $string .= " shifter" . $_->type . ">>=" . $_->bits . ";\n";
+ }
+ }
+ # okay, no bitfields from here on
+ else {
+ # Array?
+ if($_->type =~ m/(.*)\[(.*)\]/) {
+ #print "Array: " . $_->name . " -- type: " . $_->type . "\n";
+ #print " 1: " . $1 . ", 2: " . $2 . "\n";
+ if($2 eq "") {
+ #print " empty! -> warning\n";
+ $string .= " // Attention: I don't know how to read " . $_->name . " - " . $_->type . "\n";
+ $string .= "#ifdef __GNUC__\n";
+ $string .= "#warning \"Couldn't generate reading code for " . $structs[$index]->name . "::" . $_->name . "\"\n";
+ $string .= "#endif\n";
+ }
+ else {
+ # Do we have to allocate the memory first?
+ if(defined($_->len) && $_->len ne "") {
+ #print " allocating...\n";
+ $_->type =~ m/(.*)\[.*\]/;
+ $string .= " " . $_->name . "=new " . $1 . "[" . $_->len . "];\n";
+ }
+ $string .= " for(int _i=0; _i<(" . $2 . "); ++_i)\n";
+ $string .= " " . readVariable($_->name . "[_i]", $1);
+ }
+ }
+ else {
+ $string .= readVariable($_->name, $_->type);
+ }
+ }
+ }
+
+ $vars="\n";
+ if($needU8) {
+ $vars .= " U8 shifterU8;\n";
+ }
+ if($needU16) {
+ $vars .= " U16 shifterU16;\n";
+ }
+ if($needU32) {
+ $vars .= " U32 shifterU32;\n";
+ }
+
+ # looks better IMVHO :)
+ if($vars ne "\n") {
+ $vars .= "\n";
+ }
+
+ $string .= "\n if(preservePos)\n";
+ $string .= " stream->pop();\n";
+ $string .= " return true;\n";
+
+ return $vars . $string;
+}
+
+# Generates the code to read from a pointer
+sub generateReadPtr {
+ my($index)=@_;
+ my($needU8, $needU16, $needU32, $string, $sum, $limit, $vars);
+
+ $needU8=0;
+ $needU16=0;
+ $needU32=0;
+
+ foreach (@{$structs[$index]->items}) {
+ if(defined($_->bits)) {
+ if($_->type eq "U8") {
+ $needU8=1;
+ $limit=8;
+ }
+ elsif($_->type eq "U16") {
+ $needU16=1;
+ $limit=16;
+ }
+ elsif($_->type eq "U32") {
+ $needU32=1;
+ $limit=32;
+ }
+ else {
+ print " ERROR: Don't know how to handle a '" . $_->type . "' bitfield\n";
+ }
+ # first bit of a bitfield?
+ if($_->startNew ne "") {
+ $string .= " shifter" . $_->type . "=read" . $_->type . "(ptr);\n";
+ $string .= " ptr+=sizeof(" . $_->type . ");\n";
+ $sum=0;
+ }
+ $string .= " " . $_->name . "=shifter" . $_->type . ";\n";
+ $sum+=$_->bits;
+ if($sum<$limit) {
+ $string .= " shifter" . $_->type . ">>=" . $_->bits . ";\n";
+ }
+ }
+ # okay, no bitfields from here on
+ else {
+ # Array?
+ if($_->type =~ m/(.*)\[(.*)\]/) {
+ #print "Array: " . $_->name . " -- type: " . $_->type . "\n";
+ #print " 1: " . $1 . ", 2: " . $2 . "\n";
+ if($2 eq "") {
+ #print " empty! -> warning\n";
+ $string .= " // Attention: I don't know how to read " . $_->name . " - " . $_->type . "\n";
+ $string .= "#ifdef __GNUC__\n";
+ $string .= "#warning \"Couldn't generate reading code for " . $structs[$index]->name . "::" . $_->name . "\"\n";
+ $string .= "#endif\n";
+ }
+ else {
+ # Do we have to allocate the memory first?
+ if(defined($_->len) && $_->len ne "") {
+ #print " allocating...\n";
+ $_->type =~ m/(.*)\[.*\]/;
+ $string .= " " . $_->name . "=new " . $1 . "[" . $_->len . "];\n";
+ }
+ $string .= " for(int _i=0; _i<(" . $2 . "); ++_i) {\n";
+ $string .= readVariablePtr($_->name . "[_i]", $1, " ");
+ $string .= " }\n";
+ }
+ }
+ else {
+ $string .= readVariablePtr($_->name, $_->type, " ");
+ }
+ }
+ }
+
+ $vars="\n";
+ if($needU8) {
+ $vars .= " U8 shifterU8;\n";
+ }
+ if($needU16) {
+ $vars .= " U16 shifterU16;\n";
+ }
+ if($needU32) {
+ $vars .= " U32 shifterU32;\n";
+ }
+
+ # looks better IMVHO :)
+ if($vars ne "\n") {
+ $vars .= "\n";
+ }
+ return $vars . $string;
+}
+
+# Is the passed name a known structure? (needed for read())
+sub knownType {
+ my($name)=@_;
+
+ foreach (@structs) {
+ if($_->name eq $name) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+# Generates code to read one plain variable (no arrays!)
+sub readVariable {
+ my($name, $type)=@_;
+ my($string);
+
+ if($type =~ m/^[US]\d+$/) {
+ $string = " " . $name . "=stream->read" . $type . "();\n";
+ }
+ elsif($type eq "FC") {
+ $string = " " . $name . "=stream->readU32();\n";
+ }
+ elsif($type eq "XCHAR") {
+ $string = " " . $name . "=stream->readU16();\n";
+ }
+ elsif(knownType($type)) {
+ #print "Known: " . $type . "\n";
+ $string = " " . $name . ".read(stream, false);\n";
+ }
+ elsif($type =~ m/std::vector/ ) {
+ print "Found a std::vector, skipping it for reading. I hope you know what you're doing\n";
+ $string = " // skipping the std::vector " . $name . "\n";
+ }
+ else {
+ print "Error: Can't read " . $name . ", " . $type . "\n";
+ $string=""; # initialize
+ }
+ return $string;
+}
+
+# Generates code to read one plain variable (no arrays!) from memory
+sub readVariablePtr {
+ my($name, $type, $indent)=@_;
+ my($string);
+
+ if($type =~ m/^[US]\d+$/) {
+ $string = $indent . $name . "=read" . $type . "(ptr);\n";
+ $string .= $indent . "ptr+=sizeof(" . $type . ");\n";
+ }
+ elsif($type eq "FC") {
+ $string = $indent . $name . "=readU32(ptr);\n";
+ $string .= $indent . "ptr+=sizeof(U32);\n";
+ }
+ elsif($type eq "XCHAR") {
+ $string = $indent . $name . "=readU16(ptr);\n";
+ $string .= $indent . "ptr+=sizeof(U16);\n";
+ }
+ elsif(knownType($type)) {
+ #print "Known: " . $type . "\n";
+ $string = $indent . $name . ".readPtr(ptr);\n";
+ $string .= $indent . "ptr+=" . $type . "::sizeOf;\n";
+ }
+ elsif($type =~ m/std::vector/ ) {
+ print "Found a std::vector, skipping it for reading. I hope you know what you're doing\n";
+ $string = " // skipping the std::vector " . $name . "\n";
+ }
+ else {
+ print "Error: Can't read " . $name . ", " . $type . "\n";
+ $string=""; # initialize
+ }
+ return $string;
+}
+
+# Generates code to add one plain variable (no arrays!) to the string
+sub variableToString {
+ my($name, $type)=@_;
+ my($string, $output);
+
+ if($name =~ m/(.+)\[(.+)\]/) {
+ $output = $1 . "[\" + int2string( " . $2 . " ) + \"]";
+ }
+ else {
+ $output = $name;
+ }
+
+ $string = " s += \"\\n" . $output . "=\";\n";
+ if($type =~ m/^U\d+$/ || $type eq "FC" || $type eq "XCHAR") {
+ $string .= " s += uint2string( " . $name . " );\n";
+ }
+ elsif($type =~ m/^S\d+$/) {
+ $string .= " s += int2string( " . $name . " );\n";
+ }
+ elsif(knownType($type)) {
+ #print "Known: " . $type . "\n";
+ $string .= " s += \"\\n{\" + " . $name . ".toString() + \"}\\n\";\n";
+ }
+ elsif($type =~ m/std::vector/ ) {
+ print "Found a std::vector, skipping it for reading. I hope you know what you're doing\n";
+ $string .= " // skipping the std::vector " . $name . "\n";
+ }
+ else {
+ print "Error: Can't dump " . $name . ", " . $type . "\n";
+ }
+ return $string;
+}
+
+# Generates the code to write to the stream
+sub generateWrite {
+ my($index)=@_;
+ my($needU8, $needU16, $needU32, $string, $position, $limit, $vars);
+
+ $needU8=0;
+ $needU16=0;
+ $needU32=0;
+ $position=0;
+
+ $string = " if(preservePos)\n";
+ $string .= " stream->push();\n\n";
+
+ foreach (@{$structs[$index]->items}) {
+ if(defined($_->bits)) {
+ if($_->type eq "U8") {
+ $needU8=1;
+ $limit=8;
+ }
+ elsif($_->type eq "U16") {
+ $needU16=1;
+ $limit=16;
+ }
+ elsif($_->type eq "U32") {
+ $needU32=1;
+ $limit=32;
+ }
+ else {
+ print " ERROR: Don't know how to handle a '" . $_->type . "' bitfield\n";
+ }
+ # first bit of a bitfield?
+ if($_->startNew ne "") {
+ # Do we have to write out the last bitfield?
+ if($position != 0) {
+ $string .= " stream->write(shifter" . $_->type . ");\n";
+ $position=0;
+ }
+ $string .= " shifter" . $_->type . "=" . $_->name . ";\n";
+ }
+ else {
+ $string .= " shifter" . $_->type . "|=" . $_->name . " << " . $position . ";\n";
+ }
+ $position+=$_->bits;
+ }
+ # Do we have to write out the last bitfield?
+ if(defined($limit) && $position == $limit) {
+ #print "reached the limit...\n";
+ $string .= " stream->write(shifter" . $_->type . ");\n";
+ $position=0;
+ undef($limit);
+ }
+ # okay, no bitfields from here on
+ if(!defined($_->bits)) {
+ # Array?
+ if($_->type =~ m/(.*)\[(.*)\]/) {
+ #print "Array: " . $_->name . " -- type: " . $_->type . "\n";
+ #print " 1: " . $1 . ", 2: " . $2 . "\n";
+ if($2 eq "") {
+ #print " empty! -> warning\n";
+ $string .= " // Attention: I don't know how to write " . $_->name . " - " . $_->type . "\n";
+ $string .= "#ifdef __GNUC__\n";
+ $string .= "#warning \"Couldn't generate writing code for " . $structs[$index]->name . "::" . $_->name . "\"\n";
+ $string .= "#endif\n";
+ }
+ else {
+ $string .= " for(int _i=0; _i<(" . $2 . "); ++_i)\n";
+ $string .= " " . writeVariable($_->name . "[_i]", $1);
+ }
+ }
+ else {
+ $string .= writeVariable($_->name, $_->type);
+ }
+ }
+ }
+
+ $vars="\n";
+ if($needU8) {
+ $vars .= " U8 shifterU8;\n";
+ }
+ if($needU16) {
+ $vars .= " U16 shifterU16;\n";
+ }
+ if($needU32) {
+ $vars .= " U32 shifterU32;\n";
+ }
+
+ # looks better IMVHO :)
+ if($vars ne "\n") {
+ $vars .= "\n";
+ }
+
+ $string .= "\n if(preservePos)\n";
+ $string .= " stream->pop();\n";
+ $string .= " return true;\n";
+
+ return $vars . $string;
+}
+
+# Generates code to write one plain variable (no arrays!)
+sub writeVariable {
+ my($name, $type)=@_;
+ my($string);
+
+ if($type =~ m/^[US]\d+$/ || $type eq "FC" || $type eq "XCHAR") {
+ $string = " stream->write(" . $name . ");\n";
+ }
+ elsif(knownType($type)) {
+ #print "Known: " . $type . "\n";
+ $string = " " . $name . ".write(stream, false);\n";
+ }
+ elsif($type =~ m/std::vector/ ) {
+ print "Found a std::vector, skipping it for writing. I hope you know what you're doing\n";
+ $string = " // skipping the std::vector " . $name . "\n";
+ }
+ else {
+ print "Error: Can't write " . $name . ", " . $type . "\n";
+ $string=""; # initialize
+ }
+ return $string;
+}
+
+# Generates the code to compare structs with dynamic members
+sub generateEqualityOp {
+ my($index)=@_;
+ my($string, $first, $tmp);
+
+ # first check the arrays
+ # Note: We don't check the 0-sized ones!
+ foreach (@{$structs[$index]->items}) {
+ if($_->type =~ m/.*\[(.*)\]/) {
+ $tmp=$1;
+ if($tmp eq "") {
+ #print " empty! -> warning\n";
+ $string .= " // Attention: I don't know how to compare " . $_->name . " - " . $_->type . "\n";
+ $string .= "#ifdef __GNUC__\n";
+ $string .= "#warning \"Can't compare " . $structs[$index]->name . "::" . $_->name . " items\"\n";
+ $string .= "#endif\n";
+ next;
+ }
+ # okay, not a plain array, so we have to compare the size, too :}
+ if($_->type !~ m/.*\[(\d+)\]/) {
+ if(defined($_->compareSizeLHS) && defined($_->compareSizeRHS)) {
+ #print " ---> compareSize: " . $_->compareSizeLHS . ", " . $_->compareSizeRHS . "\n";
+ $string .= "\n if((" . $_->compareSizeLHS . ")!=(" . $_->compareSizeRHS . "))\n";
+ $string .= " return false;\n";
+ $string .= " for(int _i=0; _i<(" . $_->compareSizeLHS . "); ++_i) {\n";
+ $string .= " if(lhs." . $_->name . "[_i]!=rhs." . $_->name . "[_i])\n";
+ $string .= " return false;\n";
+ $string .= " }\n";
+ }
+ else {
+ $string .= "#ifdef __GNUC__\n";
+ $string .= "#warning \"Please provide a compareSize* comment for " . $structs[$index]->name . "::" . $_->name . "\"\n";
+ $string .= "#endif\n";
+ }
+ }
+ else {
+ $string .= "\n for(int _i=0; _i<(" . $tmp . "); ++_i) {\n";
+ $string .= " if(lhs." . $_->name . "[_i]!=rhs." . $_->name . "[_i])\n";
+ $string .= " return false;\n";
+ $string .= " }\n";
+ }
+ }
+ }
+ # ... then create a nice return statement ;)
+ $string .= "\n return";
+ $first=1; # first line?
+ foreach (@{$structs[$index]->items}) {
+ # don't forget to exclude the arrays!
+ if($_->type !~ m/.*\[.*\]/) {
+ # special case: first line
+ if($first==1) {
+ $string .= " lhs." . $_->name . "==rhs." . $_->name;
+ $first=0;
+ }
+ else {
+ $string .= " &&\n lhs." . $_->name . "==rhs." . $_->name;
+ }
+ }
+ }
+ $string .= ";\n";
+ return $string;
+}
+
+# Generates a proper clear() method depending whether we have
+# dynamic members of not
+sub generateClear {
+ my($index)=@_;
+ my($string);
+
+ if(defined($structs[$index]->dynamic)) {
+ # delete [] the dynamic memory!
+ foreach (@{$structs[$index]->items}) {
+ if(defined($_->len)) {
+ $string .= " delete [] " . $_->name . ";\n";
+ }
+ }
+ $string .= " clearInternal();\n";
+ }
+ else {
+ $string=generateClearInternal($index);
+ }
+ return $string;
+}
+
+# Generates the code to dump a structure
+sub generateDump {
+ my($index, $tmp) = @_;
+ my($string);
+
+ $string .= " wvlog << \"Dumping " . $structs[$index]->name . ":\" << std::endl;\n";
+ $string .= " wvlog << toString().c_str() << std::endl;\n";
+ $string .= " wvlog << \"\\nDumping " . $structs[$index]->name . " done.\" << std::endl;\n";
+ return $string;
+}
+
+# Generates the code to convert a structure to a string
+sub generateToString {
+ my($index, $tmp) = @_;
+ my($string);
+
+ $string .= " std::string s( \"" . $structs[$index]->name . ":\" );\n";
+ foreach (@{$structs[$index]->items}) {
+ # Array?
+ if($_->type =~ m/(.*)\[(.*)\]/) {
+ #print "Array: " . $_->name . " -- type: " . $_->type . "\n";
+ #print " 1: " . $1 . ", 2: " . $2 . "\n";
+ if($2 eq "") {
+ #print " empty! -> warning\n";
+ $string .= " // Attention: I don't know how to turn " . $_->name . " - " . $_->type . " to a string\n";
+ $string .= "#ifdef __GNUC__\n";
+ $string .= "#warning \"Couldn't generate toString code for " . $structs[$index]->name . "::" . $_->name . "\"\n";
+ $string .= "#endif\n";
+ }
+ else {
+ $string .= " for(int _i=0; _i<(" . $2 . "); ++_i) {\n";
+ $string .= " " . variableToString($_->name . "[_i]", $1);
+ $string .= " }\n";
+ }
+ }
+ else {
+ $string .= variableToString($_->name, $_->type);
+ }
+ }
+ $string .= " s += \"\\n" . $structs[$index]->name . " Done.\";\n";
+ $string .= " return s;\n";
+ return $string;
+}
+
+# Generates the code to initialize all fields
+sub generateClearInternal {
+ my($index, $tmp) = @_;
+ my($string);
+
+ foreach (@{$structs[$index]->items}) {
+ if($_->type =~ m/.*\[(.*)\]/) {
+ $tmp=$1;
+ # fine, just a pointer
+ if($tmp eq "") {
+ $string .= " " . $_->name . "=0;\n";
+ next;
+ }
+ # okay, also a pointer
+ if($_->type !~ m/.*\[(\d+)\]/) {
+ $string .= " " . $_->name . "=0;\n";
+ }
+ else {
+ $string .= " for(int _i=0; _i<(" . $tmp . "); ++_i)\n";
+ $_->type =~ m/(.*)\[.*\]/;
+ $string .= " " . $_->name . "[_i]" . initValue($_, $1) . ";\n";
+ }
+ }
+ else {
+ $string .= " " . $_->name . initValue($_, $_->type) . ";\n";
+ }
+ }
+ return $string;
+}
+
+sub initValue {
+ my($item, $type)=@_;
+ my($string);
+
+ if(defined($item->initial)) {
+ $string = "=" . $item->initial;
+ }
+ else {
+ if($type =~ m/^[US]\d+$/ || $type eq "FC" || $type eq "XCHAR") {
+ $string = "=0";
+ }
+ elsif(knownType($type)) {
+ #print "Known: " . $type . "\n";
+ $string = ".clear()";
+ }
+ elsif($type =~ m/std::vector/ ) {
+ $string = ".clear()";
+ }
+ else {
+ print "Error: Can't initialize " . $item->name . ", " . $type . "\n";
+ $string=""; # initialize
+ }
+ }
+ return $string;
+}
+
+# Generates some testcases
+sub generateTest {
+ my($tmp);
+
+ print "Generating the testcases...\n";
+ $tmp=lc($namespace);
+ open(TEST, ">$tmp" . "_test.cpp") or die "Couldn't open the file for writing: " . $!;
+
+ print TEST "// This file contains generated testing code. We do some basic tests\n";
+ print TEST "// like writing and reading from/to streams. Of course these tests are\n";
+ print TEST "// neither complete nor very advanced, so watch out :)\n\n";
+ print TEST "#include <" . $tmp . "_generated.h>\n";
+ print TEST "#include <olestream.h>\n";
+ print TEST "#include <iostream>\n";
+ print TEST "#include <stdlib.h> // rand(), srand()\n\n";
+ print TEST "#include <time.h> // time()\n\n";
+
+ print TEST "using namespace wvWare;\n";
+ print TEST "using namespace " . $namespace .";\n\n";
+
+ print TEST "int main(int, char**) {\n\n";
+ print TEST " // First we have to create some infrastructure\n";
+ print TEST " system(\"rm " . $tmp . "_test.doc &> /dev/null\");\n";
+ print TEST " OLEStorage storage(\"" . $tmp . "_test.doc\");\n";
+ print TEST " if(!storage.open(OLEStorage::WriteOnly)) {\n";
+ print TEST " std::cout << \"Error: Couldn't open the storage!\" << std::endl;\n";
+ print TEST " ::exit(1);\n";
+ print TEST " }\n\n";
+ print TEST " OLEStreamWriter *writer=storage.createStreamWriter(\"TestStream\");\n";
+ print TEST " if(!writer || !writer->isValid()) {\n";
+ print TEST " std::cout << \"Error: Couldn't open a stream for writing!\" << std::endl;\n";
+ print TEST " ::exit(1);\n";
+ print TEST " }\n\n";
+ print TEST " // Initialize the random number generator\n";
+ print TEST " srand( time( 0 ) );\n\n";
+
+ print TEST " // Some \"global\" variables...\n";
+ print TEST " int *ptr=0; // used to \"initialize\" the structs\n";
+ print TEST " int tmp;\n";
+
+ print TEST " std::cout << \"Testing the $namespace structures...\" << std::endl;\n";
+
+ print TEST generateTestStructures();
+
+ print TEST " std::cout << \"Done.\" << std::endl;\n";
+ print TEST " // Clean up\n";
+ print TEST " storage.close();\n";
+ print TEST "}\n";
+
+ close(TEST) or die $!;
+ print "Done.\n";
+}
+
+# Generates all the tests for every single structure
+sub generateTestStructures {
+ my($string, $index, $n);
+
+ # writing
+ for($index=0; $index<=$#structs; $index++) {
+ if($structs[$index]->hidden ||
+ $structs[$index]->name eq "DPCALLOUT" || # DPCALLOUT depends on DPPOLY -> dynamic
+ $structs[$index]->name eq "PAP" || # PAP uses std::vector<Foo>
+ $structs[$index]->name eq "SEP" || # SEP uses std::vector<Foo>
+ $structs[$index]->name eq "TAP") { # TAP uses std::vector<Foo>
+ next;
+ }
+ $n=$structs[$index]->name;
+ if($structs[$index]->dynamic) {
+ $string .= " std::cout << \"Testing writing for $n:\" << std::endl;\n";
+ $string .= " std::cout << \" Sorry, testing dynamic structures isn't implemented,\"\n";
+ $string .= " << \" yet.\" << std::endl;\n";
+ }
+ else {
+ $string .= " // Begin of writing test for $n\n";
+ $string .= " std::cout << \"Testing writing for $n: \";\n";
+ $string .= generateWritingTest($index);
+ $string .= " // End of writing test for $n\n\n";
+ }
+ }
+
+ # mess with the streams...
+ $string .= "\n // Okay, close the stream writer and open it for reading...\n";
+ $string .= " int position=writer->tell(); // store the position for a check\n";
+ $string .= " delete writer;\n";
+ $string .= " storage.close();\n";
+ $string .= " if(!storage.open(OLEStorage::ReadOnly)) {\n";
+ $string .= " std::cout << \"Error: Couldn't open the storage!\" << std::endl;\n";
+ $string .= " ::exit(1);\n";
+ $string .= " }\n";
+ $string .= " OLEStreamReader *reader=storage.createStreamReader(\"TestStream\");\n";
+ $string .= " if(!reader || !reader->isValid()) {\n";
+ $string .= " std::cout << \"Error: Couldn't open a stream for reading!\" << std::endl;\n";
+ $string .= " ::exit(1);\n";
+ $string .= " }\n\n";
+
+ # reading
+ for($index=0; $index<=$#structs; $index++) {
+ if($structs[$index]->hidden ||
+ $structs[$index]->name eq "DPCALLOUT" || # DPCALLOUT depends on DPPOLY -> dynamic
+ $structs[$index]->name eq "PAP" || # PAP uses std::vector<Foo>
+ $structs[$index]->name eq "SEP" || # SEP uses std::vector<Foo>
+ $structs[$index]->name eq "TAP") { # TAP uses std::vector<Foo>
+ next;
+ }
+ $n=$structs[$index]->name;
+ if($structs[$index]->dynamic) {
+ $string .= " std::cout << \"Testing reading for $n:\" << std::endl;\n";
+ $string .= " std::cout << \" Sorry, testing dynamic structures isn't implemented,\"\n";
+ $string .= " << \" yet.\" << std::endl;\n";
+ }
+ else {
+ $string .= " // Begin of reading test for $n\n";
+ $string .= " std::cout << \"Testing reading for $n: \";\n";
+ $string .= generateReadingTest($index);
+ $string .= " // End of reading test for $n\n\n";
+ }
+ }
+
+ # check the position in the stream
+ $string .= "\n if(position!=reader->tell())\n";
+ $string .= " std::cout << \"Error: Different amount of bytes read/written!\" << std::endl;\n";
+ $string .= " delete reader;\n\n";
+ return $string;
+}
+
+# Generates some code to initialize a struct and write it out.
+sub generateWritingTest {
+ my($index)=@_;
+ my($string, $n, $var);
+
+ $n=$structs[$index]->name;
+ $var=lc($n) . "1";
+ $string .= " $n " . $var . ";\n";
+ $string .= " // Initilaize the struct with random data\n";
+ $string .= " tmp=sizeof($n)/sizeof(int);\n";
+ $string .= " ptr=reinterpret_cast<int*>( &" . $var . " );\n";
+ $string .= " for(int _i=0; _i<tmp; ++_i)\n";
+ $string .= " *ptr++=rand();\n";
+ $string .= " *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof($n) % sizeof(int)))*8)); // yay! :)\n";
+ $string .= " // and write it out...\n";
+ $string .= " if($var.write(writer, false))\n";
+ $string .= " std::cout << \"Passed.\" << std::endl;\n";
+ $string .= " else\n";
+ $string .= " std::cout << \"Failed.\" << std::endl;\n";
+ if(defined($structs[$index]->dumpCode)) {
+ $string .= " " . $var . ".dump();\n";
+ }
+ return $string;
+}
+
+sub generateReadingTest {
+ my($index)=@_;
+ my($string, $n, $var2, $var3);
+
+ $n=$structs[$index]->name;
+ $var2=lc($n) . "2";
+ $string .= " $n " . $var2 . ";\n";
+ $string .= " // Read the data from the stream\n";
+ $string .= " if(!$var2.read(reader, false))\n";
+ $string .= " std::cout << \"Failed. \" << std::endl;\n";
+ $string .= " // Test the copy CTOR\n";
+ $var3=lc($n) . "3";
+ $string .= " $n " . $var3 . "($var2);\n";
+ $string .= " if(" . lc($n) . "1==$var2 && $var2==$var3)\n";
+ $string .= " std::cout << \"Passed.\" << std::endl;\n";
+ $string .= " else\n";
+ $string .= " std::cout << \"Failed.\" << std::endl;\n";
+
+ return $string;
+}
+
+# Reads the HTML file and converts the "interesting" tags
+# to uppercase. It also cuts of areas we're not interested in
+# from the begin and the end of the file.
+sub main {
+ # A flag which tells us what part of the HTML to ignore
+ my $ignore=1;
+
+ open(INPUT, "<$ARGV[0]") or die $!;
+ $namespace=$ARGV[1];
+
+ while(<INPUT>) {
+
+ # Detection of start for Word9x
+ if(m,^Structure Definitions\</h[12]\>$,) {
+ $ignore=0;
+ }
+ # Detection of end for Word97
+ elsif(m,^Appendix A - Reading a Macintosh PICT Graphic\</h2\>$,) {
+ $ignore=1;
+ }
+ # Detection of end for Word95
+ elsif(m,^Appendix A - Changes from version 1\.x to 2\.0\</h1\>$,) {
+ $ignore=1;
+ }
+
+ if(!$ignore) {
+ chomp;
+ # convert the important tags we use to uppercase on the fly
+ s,\<tr\>,\<TR\>,;
+ s,\</tr\>,\</TR\>,;
+ s,\<td\>,\<TD\>,;
+ s,\</td\>,\</TD\>,;
+ s,\<table ,\<TABLE ,;
+ s,\</table\>,\</TABLE\>,;
+ s,\<br\>,\<BR\>,;
+ s,\<h3\>,\<H3\>,;
+ s,\</h3\>,\</H3\>,;
+ # get rid of that ugly &nbsp; thingies
+ s/&nbsp;//g;
+
+ push(@document, $_);
+ }
+ }
+ close(INPUT) or die $!;
+ # print "Size of the array: ", $#document+1, "\n";
+
+ parseStructures(); # parse the document
+ cleanStructures(); # get rid of stuff we don't want to use
+ hoistStructures(); # resolve forward references
+ selectShared(); # select the structures we wanted to share
+ selectDumped(); # select the structures which should contain a dump() method
+
+ generateHeader(); # generate the header file
+ generateImplementation(); # generate the source
+ generateTest(); # generate the sythetic test cases
+}
+
+# We start execution here
+if($#ARGV != 1) {
+ print "Script to generate C++ code to read Word structures from the HTML\n";
+ print "documentation. Usage: perl generate.pl input_file.html Word9x\n";
+ exit(1);
+}
+
+main();
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/spec_defects b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/spec_defects
new file mode 100644
index 00000000..77eac7c3
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/spec_defects
@@ -0,0 +1,30 @@
+This file lists a few known defects in the Word specs:
+- Word6 spec:
+
+
+
+- Word8 spec:
+ + The LSTF structures are stored as strange PLF (with a short count instead of
+ the integer count known from plain PLFs) and it's labeled plcflst. Normally
+ a PLCF also contains an array of CPs or FCs, so this is a clear error in the
+ spec.
+ + The name of a style (STD::xstzName) is stored as pascal string. According to
+ the spec it's preceded by a length byte, to me it looks like a length short.
+ In Shaheed's code it looks like older versions (baseSize < 10) don't store it
+ as Unicode string. The whole style docu looks like Word6 documentation to me.
+ + The PAP spec suggests that fMultLineSpace and dyaLine should be set to some
+ default values. I think they mean fMinHeight and dyaHeight, but we don't need
+ that stuff, do we?
+ + It looks like sprmCHpsKern has a two byte data field, but I found a document
+ where it's only one byte long. Any special case we're missing?
+ + I added a few sprms as sprmUnknown1,2,... to the jump tables, to avoid warnings
+ we can't do anything about. I also added sprmPJcFE (0x2461) with the same
+ behavior as plain old sprmPJc (as seen in OOo).
+ + sprmPIncLvl talks about an stc, but it's istd now in Word97 (check wv/sprm.c)
+ + The header/footer documentation is crap, look at the code
+ + The footnote/endnote documentation is crap too
+
+- Word 2000:
+ + OOo reverse-engineered a field of the FIB they called fcMagicTable. A PLCF
+ with information about table cell start CPs in the file. For now I decided
+ not to use this information, as Word 8 doesn't have it anyway.
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-Word95.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-Word95.cpp
new file mode 100644
index 00000000..d813700c
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-Word95.cpp
@@ -0,0 +1,48 @@
+### As you recognized already, "###" at the begin of a line
+### marks a comment.
+
+### Everything between start and end will be put into the file
+@@license-start@@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+// This code is generated from the Microsoft HTML specification of the
+// WinWord format. Do NOT edit this code, but fix the spec or the script
+// generating the sources. If you want to add some additional code, some
+// includes or any other stuff, please add it to the template file!
+// For information about the script and the "hidden features" please read
+// the comments at the begin of the script.
+
+// If you find bugs or strange behavior please contact Werner Trobin
+@@license-end@@
+
+### Everything between @@includes-start@@ and -end will be added to
+### the generated includes (e.g. "#include <string>")
+@@includes-start@@
+####include <string> // test
+@@includes-end@@
+
+### These are the "borders" of the namespace (e.g. namespace Word97 { .. })
+### Everything you add in here will be added to the generated code
+@@namespace-start@@
+### nothing
+### This tag "expands" to all the structs :)
+@@generated-code@@
+### nothing
+@@namespace-end@@
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-Word95.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-Word95.h
new file mode 100644
index 00000000..ee453a8a
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-Word95.h
@@ -0,0 +1,47 @@
+### As you recognized already, "###" at the begin of a line
+### marks a comment.
+
+### Everything between start and end will be put into the file
+@@license-start@@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+// This code is generated from the Microsoft HTML specification of the
+// WinWord format. Do NOT edit this code, but fix the spec or the script
+// generating the sources.
+// For information about the script and the "hidden features" please read
+// the comments at the begin of the script.
+
+// If you find bugs or strange behavior please contact Werner Trobin
+@@license-end@@
+
+### Everything between @@includes-start@@ and -end will be added to
+### the generated includes (e.g. "#include <string>")
+@@includes-start@@
+####include <string> // test
+@@includes-end@@
+
+### These are the "borders" of the namespace (e.g. namespace Word97 { .. })
+### Everything you add in here will be added to the generated code
+@@namespace-start@@
+### nothing
+### This tag "expands" to all the structs :)
+@@generated-code@@
+### nothing
+@@namespace-end@@
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-Word97.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-Word97.cpp
new file mode 100644
index 00000000..acb93883
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-Word97.cpp
@@ -0,0 +1,147 @@
+### As you recognized already, "###" at the begin of a line
+### marks a comment.
+
+### Everything between start and end will be put into the file
+@@license-start@@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+// This code is generated from the Microsoft HTML specification of the
+// WinWord format. Do NOT edit this code, but fix the spec or the script
+// generating the sources. If you want to add some additional code, some
+// includes or any other stuff, please add it to the template file!
+// For information about the script and the "hidden features" please read
+// the comments at the begin of the script.
+
+// If you find bugs or strange behavior please contact Werner Trobin
+@@license-end@@
+
+### Everything between @@includes-start@@ and -end will be added to
+### the generated includes (e.g. "#include <string>")
+@@includes-start@@
+####include <string> // test
+@@includes-end@@
+
+### These are the "borders" of the namespace (e.g. namespace Word97 { .. })
+### Everything you add in here will be added to the generated code
+@@namespace-start@@
+// FFN implementation, located in template-Word97.cpp
+FFN::FFN() {
+ clearInternal();
+}
+
+FFN::FFN(OLEStreamReader *stream, Version version, bool preservePos) {
+ clearInternal();
+ read(stream, version, preservePos);
+}
+
+bool FFN::read(OLEStreamReader *stream, Version version, bool preservePos) {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ cbFfnM1=stream->readU8();
+ shifterU8=stream->readU8();
+ prq=shifterU8;
+ shifterU8>>=2;
+ fTrueType=shifterU8;
+ shifterU8>>=1;
+ unused1_3=shifterU8;
+ shifterU8>>=1;
+ ff=shifterU8;
+ shifterU8>>=3;
+ unused1_7=shifterU8;
+ wWeight=stream->readS16();
+ chs=stream->readU8();
+ ixchSzAlt=stream->readU8();
+
+ U8 remainingSize = cbFfnM1 - 5;
+
+ if ( version == Word97 ) {
+ for(int _i=0; _i<(10); ++_i)
+ panose[_i]=stream->readU8();
+ for(int _i=0; _i<(24); ++_i)
+ fs[_i]=stream->readU8();
+ remainingSize -= 34;
+
+ // Remaining size in bytes -> shorts
+ remainingSize /= 2;
+ XCHAR* string = new XCHAR[ remainingSize ];
+ for ( int i = 0; i < remainingSize; ++i )
+ string[ i ] = stream->readU16();
+ if ( ixchSzAlt == 0 )
+ xszFfn = UString( reinterpret_cast<const wvWare::UChar *>( string ), remainingSize - 1 );
+ else {
+ xszFfn = UString( reinterpret_cast<const wvWare::UChar *>( string ), ixchSzAlt - 1 );
+ xszFfnAlt = UString( reinterpret_cast<const wvWare::UChar *>( &string[ ixchSzAlt ] ), remainingSize - 1 - ixchSzAlt );
+ }
+ delete [] string;
+ }
+ else {
+ U8* string = new U8[ remainingSize ];
+ stream->read( string, remainingSize );
+ // ###### Assume plain latin1 strings, maybe we'll have to use a textconverter here...
+ if ( ixchSzAlt == 0 )
+ xszFfn = UString( reinterpret_cast<char*>( string ) );
+ else {
+ xszFfn = UString( reinterpret_cast<char*>( string ) ); // The strings are 0-terminated, according to the SPEC
+ xszFfnAlt = UString( reinterpret_cast<char*>( &string[ ixchSzAlt ] ) );
+ }
+ delete [] string;
+ }
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void FFN::clear() {
+ clearInternal();
+}
+
+void FFN::clearInternal() {
+ cbFfnM1=0;
+ prq=0;
+ fTrueType=0;
+ unused1_3=0;
+ ff=0;
+ unused1_7=0;
+ wWeight=0;
+ chs=0;
+ ixchSzAlt=0;
+ for(int _i=0; _i<(10); ++_i)
+ panose[_i]=0;
+ for(int _i=0; _i<(24); ++_i)
+ fs[_i]=0;
+ xszFfn = UString::null;
+ xszFfnAlt = UString::null;
+}
+
+// There can be only one tab at a given position, no matter what the other options are
+bool operator==( const TabDescriptor& lhs, const TabDescriptor& rhs ) { return lhs.dxaTab == rhs.dxaTab; }
+bool operator!=( const TabDescriptor& lhs, const TabDescriptor& rhs ) { return lhs.dxaTab != rhs.dxaTab; }
+bool operator<( const TabDescriptor& lhs, const TabDescriptor& rhs ) { return lhs.dxaTab < rhs.dxaTab; }
+bool operator>( const TabDescriptor& lhs, const TabDescriptor& rhs ) { return lhs.dxaTab > rhs.dxaTab; }
+
+### This tag "expands" to all the structs :)
+@@generated-code@@
+### nothing
+@@namespace-end@@
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-Word97.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-Word97.h
new file mode 100644
index 00000000..6fac3cf6
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-Word97.h
@@ -0,0 +1,223 @@
+### As you recognized already, "###" at the begin of a line
+### marks a comment.
+
+### Everything between start and end will be put into the file
+@@license-start@@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+// This code is generated from the Microsoft HTML specification of the
+// WinWord format. Do NOT edit this code, but fix the spec or the script
+// generating the sources.
+// For information about the script and the "hidden features" please read
+// the comments at the begin of the script.
+
+// If you find bugs or strange behavior please contact Werner Trobin
+@@license-end@@
+
+### Everything between @@includes-start@@ and -end will be added to
+### the generated includes (e.g. "#include <string>")
+@@includes-start@@
+#include "ustring.h"
+#include <vector> // for Word97::PAP
+@@includes-end@@
+
+### These are the "borders" of the namespace (e.g. namespace Word97 { .. })
+### Everything you add in here will be added to the generated code
+@@namespace-start@@
+/**
+ * Font Family Name (FFN), this code is located in the template-Word97.h
+ */
+struct FFN {
+ enum Version { Word95, Word97 };
+ /**
+ * Creates an empty FFN structure and sets the defaults
+ */
+ FFN();
+ /**
+ * Simply calls read(...)
+ */
+ FFN(OLEStreamReader *stream, Version version, bool preservePos=false);
+
+ /**
+ * This method reads the FFN structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, Version version, bool preservePos=false);
+
+ /**
+ * Same as reading, not implemented yet
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * total length of FFN - 1.
+ */
+ U8 cbFfnM1;
+
+ /**
+ * pitch request
+ */
+ U8 prq:2;
+
+ /**
+ * when 1, font is a TrueType font
+ */
+ U8 fTrueType:1;
+
+ /**
+ * reserved
+ */
+ U8 unused1_3:1;
+
+ /**
+ * font family id
+ */
+ U8 ff:3;
+
+ /**
+ * reserved
+ */
+ U8 unused1_7:1;
+
+ /**
+ * base weight of font
+ */
+ S16 wWeight;
+
+ /**
+ * character set identifier
+ */
+ U8 chs;
+
+ /**
+ * index into ffn.szFfn to the name of the alternate font
+ */
+ U8 ixchSzAlt;
+
+ /**
+ * ? This is supposed to be of type PANOSE.
+ */
+ U8 panose[10];
+
+ /**
+ * ? This is supposed to be of type FONTSIGNATURE.
+ */
+ U8 fs[24];
+
+ /**
+ * zero terminated string that records name of font. Possibly followed
+ * by a second xsz which records the name of an alternate font to use if the
+ * first named font does not exist on this system. Maximal size of xszFfn
+ * is 65 characters.
+ */
+ //U8 *xszFfn; // U8 xszFfn[];
+ /**
+ * We are using two UStrings here, the alternative string (xszFfnAlt) will
+ * contain the alternative font name in case ixchSzAlt is != 0
+ */
+ UString xszFfn;
+ UString xszFfnAlt;
+
+private:
+ FFN(const FFN &rhs);
+ FFN &operator=(const FFN &rhs);
+
+ void clearInternal();
+}; // FFN
+
+/**
+ * Tab Descriptor (TBD)
+ */
+struct TBD
+{
+ TBD() : jc( 0 ), tlc( 0 ), unused0_6( 0 ) {}
+ TBD( U8 tbd )
+ {
+ jc = tbd;
+ tbd >>= 3;
+ tlc = tbd;
+ tbd >>= 3;
+ unused0_6 = tbd;
+ }
+
+ /**
+ * justification code
+ * 0 left tab
+ * 1 centered tab
+ * 2 right tab
+ * 3 decimal tab
+ * 4 bar
+ */
+ U8 jc:3;
+
+ /**
+ * tab leader code
+ * 0 no leader
+ * 1 dotted leader
+ * 2 hyphenated leader
+ * 3 single line leader
+ * 4 heavy line leader
+ */
+ U8 tlc:3;
+
+ /**
+ * reserved
+ */
+ U8 unused0_6:2;
+};
+
+/**
+ * Convenient structure for describing tabs
+ * It's difficult to sort two arrays in parallel, so instead of rgdxaTab[] and rgtbd[]
+ * we combine all the data for one tab into this struct, and the PAP has
+ * a vector<TabDescriptor>
+ */
+struct TabDescriptor
+{
+ /**
+ * Position of the tab
+ */
+ S16 dxaTab;
+ /**
+ * Options (justification and tab-leading code)
+ */
+ Word97::TBD tbd;
+
+}; // TabDescriptor
+
+// There can be only one tab at a given position, no matter what the other options are
+bool operator==( const TabDescriptor& lhs, const TabDescriptor& rhs );
+bool operator!=( const TabDescriptor& lhs, const TabDescriptor& rhs );
+bool operator<( const TabDescriptor& lhs, const TabDescriptor& rhs );
+bool operator>( const TabDescriptor& lhs, const TabDescriptor& rhs );
+
+### This tag "expands" to all the structs :)
+@@generated-code@@
+
+### nothing
+@@namespace-end@@
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-conv.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-conv.cpp
new file mode 100644
index 00000000..9ce4b789
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-conv.cpp
@@ -0,0 +1,91 @@
+### As you recognized already, "###" at the begin of a line
+### marks a comment.
+
+### Everything between start and end will be put into the file
+@@license-start@@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+// This code is generated from the Microsoft HTML specification of the
+// WinWord format. Do NOT edit this code, but fix the spec or the script
+// generating the sources. If you want to add some additional code, some
+// includes or any other stuff, please add it to the template file!
+// For information about the script and the "hidden features" please read
+// the comments at the begin of the script.
+
+// If you find bugs or strange behavior please contact Werner Trobin
+@@license-end@@
+
+### Everything between @@includes-start@@ and -end will be added to
+### the generated includes (e.g. "#include <string>")
+@@includes-start@@
+####include <string> // test
+@@includes-end@@
+
+### These are the "borders" of the namespace (e.g. namespace Word97 { .. })
+### Everything you add in here will be added to the generated code
+@@namespace-start@@
+### nothing
+
+// This has been added to the template file, as the mapping is
+// non-trivial. Shaheed: Please check the implementation
+Word97::BRC toWord97(const Word95::BRC &s) {
+
+ Word97::BRC ret;
+
+ // Check the BRC documentation
+ if ( s.dxpLineWidth < 6 ) {
+ ret.dptLineWidth = s.dxpLineWidth * 6;
+ ret.brcType = s.brcType;
+ }
+ else if ( s.dxpLineWidth == 6 ) {
+ ret.dptLineWidth = 6; // what's the default?
+ ret.brcType = 6; // dotted
+ }
+ else { // s.dxpLineWidth == 7
+ ret.dptLineWidth = 6; // what's the default?
+ ret.brcType = 7;
+ }
+ ret.fShadow = s.fShadow;
+ ret.ico = s.ico;
+ ret.dptSpace = s.dxpSpace;
+ return ret;
+}
+
+Word97::STSHI toWord97(const Word95::STSHI &s)
+{
+ Word97::STSHI ret;
+
+ ret.cstd=s.cstd;
+ ret.cbSTDBaseInFile=s.cbSTDBaseInFile;
+ ret.fStdStylenamesWritten=s.fStdStylenamesWritten;
+ ret.unused4_2=s.unused4_2;
+ ret.stiMaxWhenSaved=s.stiMaxWhenSaved;
+ ret.istdMaxFixedWhenSaved=s.istdMaxFixedWhenSaved;
+ ret.nVerBuiltInNamesWhenSaved=s.nVerBuiltInNamesWhenSaved;
+ ret.rgftcStandardChpStsh[0]=s.ftcStandardChpStsh;
+ ret.rgftcStandardChpStsh[1]=s.ftcStandardChpStsh; // fake them
+ ret.rgftcStandardChpStsh[2]=s.ftcStandardChpStsh; // fake them
+
+ return ret;
+}
+### This tag "expands" to all the structs :)
+@@generated-code@@
+### nothing
+@@namespace-end@@
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-conv.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-conv.h
new file mode 100644
index 00000000..2f6a4fb8
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/generator/template-conv.h
@@ -0,0 +1,52 @@
+### As you recognized already, "###" at the begin of a line
+### marks a comment.
+
+### Everything between start and end will be put into the file
+@@license-start@@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+// This code is generated from the Microsoft HTML specification of the
+// WinWord format. Do NOT edit this code, but fix the spec or the script
+// generating the sources.
+// For information about the script and the "hidden features" please read
+// the comments at the begin of the script.
+
+// If you find bugs or strange behavior please contact Werner Trobin
+@@license-end@@
+
+### Everything between @@includes-start@@ and -end will be added to
+### the generated includes (e.g. "#include <string>")
+@@includes-start@@
+####include <string> // test
+@@includes-end@@
+
+### These are the "borders" of the namespace (e.g. namespace Word97 { .. })
+### Everything you add in here will be added to the generated code
+@@namespace-start@@
+### nothing
+
+// This has been added to the template file, as the mapping is
+// non-trivial. Shaheed: Please check the implementation
+Word97::BRC toWord97(const Word95::BRC &s);
+Word97::STSHI toWord97(const Word95::STSHI &s);
+### This tag "expands" to all the structs :)
+@@generated-code@@
+### nothing
+@@namespace-end@@
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/global.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/global.cpp
new file mode 100644
index 00000000..59751508
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/global.cpp
@@ -0,0 +1,66 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "global.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+namespace wvWare {
+
+// Endianness fun
+U16 toLittleEndian( U16 data )
+{
+#if defined(WORDS_BIGENDIAN)
+ return ( ( data & 0x00ffU ) << 8 ) | ( ( data & 0xff00U ) >> 8 );
+#else
+ return data;
+#endif
+}
+
+U16 toBigEndian( U16 data )
+{
+#if defined(WORDS_BIGENDIAN)
+ return data;
+#else
+ return ( ( data & 0x00ffU ) << 8 ) | ( ( data & 0xff00U ) >> 8 );
+#endif
+}
+
+U32 toLittleEndian( U32 data )
+{
+#if defined(WORDS_BIGENDIAN)
+ return ( ( data & 0x000000ffU ) << 24 ) | ( ( data & 0x0000ff00U ) << 8 ) |
+ ( ( data & 0x00ff0000U ) >> 8 ) | ( ( data & 0xff000000U ) >> 24 );
+#else
+ return data;
+#endif
+}
+
+U32 toBigEndian( U32 data )
+{
+#if defined(WORDS_BIGENDIAN)
+ return data;
+#else
+ return ( ( data & 0x000000ffU ) << 24 ) | ( ( data & 0x0000ff00U ) << 8 ) |
+ ( ( data & 0x00ff0000U ) >> 8 ) | ( ( data & 0xff000000U ) >> 24 );
+#endif
+}
+
+} // namespace wvWare
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/global.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/global.h
new file mode 100644
index 00000000..c4c71f68
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/global.h
@@ -0,0 +1,165 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#include "dllmagic.h"
+#include "wv2version.h" // ###### WV2 0.3: Remove this #include
+
+/** @file
+ * We use this typedefs to be compatible with the types from
+ * the MS HTML specifications.
+ */
+
+// A few defines used for "inline" debugging
+#define WV2_DUMP_PIECE_TABLE 0 // has to be defined as we just #if it
+//#define WV2_DUMP_FIB 1
+
+#define WV2_DEBUG_STYLESHEET 1
+#define WV2_DEBUG_SPRMS 1
+
+//#define WV2_DEBUG_LIST_READING 1
+//#define WV2_DEBUG_LIST_PROCESSING 1
+
+//#define WV2_DEBUG_FIELDS 1
+
+//#define WV2_DEBUG_FOOTNOTES 1
+
+//#define WV2_DEBUG_HEADERS 1
+
+//#define WV2_DEBUG_TABLES 1
+
+//#define WV2_DEBUG_PICTURES 1
+
+// This define should only be commented out for releases (if at all)
+#define WV2_CHECKING 1
+
+namespace wvWare
+{
+
+typedef signed char S8;
+typedef unsigned char U8;
+typedef signed short S16;
+typedef unsigned short U16;
+typedef signed int S32;
+typedef unsigned int U32;
+typedef U16 XCHAR;
+typedef U32 FC;
+
+/**
+ * This enum tells the apply* methods in the PAP/CHP/... structs what grpprls to
+ * expect. Unfortunately the size of the SPRMs changed for Word 8.
+ */
+enum WordVersion { Word67, Word8 };
+const int Word8nFib = 193;
+
+inline U8 readU8( const U8* in )
+{
+ return *in;
+}
+
+inline S8 readS8( const U8* in )
+{
+ return static_cast<S8>( *in );
+}
+
+// reads a U16/S16 or U32/S32 from a little-endian byte
+// "array" in an endian-correct way
+inline U16 readU16( const U8* in )
+{
+ return static_cast<U16>( in[0] ) | ( static_cast<U16>( in[1] ) << 8 );
+}
+
+inline S16 readS16( const U8* in )
+{
+ return static_cast<S16>( readU16( in ) );
+}
+
+// writes a U16 to a little-endian byte "array" in an endian-correct way
+inline void write( U8* out, U16 data )
+{
+ out[ 0 ] = data & 0x00ff;
+ out[ 1 ] = data >> 8;
+}
+
+inline U32 readU32( const U8* in )
+{
+ return static_cast<U32>( in[0] ) | ( static_cast<U32>( in[1] ) << 8 ) |
+ ( static_cast<U32>( in[2] ) << 16 ) | ( static_cast<U32>( in[3] ) << 24 );
+}
+
+inline S32 readS32(const U8* in)
+{
+ return static_cast<S32>( readU32( in ) );
+}
+
+// Endianness fun
+U16 toLittleEndian( U16 data );
+
+inline S16 toLittleEndian( S16 data )
+{
+ return static_cast<S16>( toLittleEndian( static_cast<U16>( data ) ) );
+}
+
+U16 toBigEndian( U16 data );
+
+inline S16 toBigEndian( S16 data )
+{
+ return static_cast<S16>( toBigEndian( static_cast<U16>( data ) ) );
+}
+
+inline U16 swapEndianness( U16 data )
+{
+ return ( ( data & 0x00ffU ) << 8 ) | ( ( data & 0xff00U ) >> 8 );
+}
+
+inline S16 swapEndianness( S16 data )
+{
+ return ( ( data & 0x00ffU ) << 8 ) | ( ( data & 0xff00U ) >> 8 );
+}
+
+U32 toLittleEndian( U32 data );
+
+inline S32 toLittleEndian( S32 data )
+{
+ return static_cast<S32>( toLittleEndian( static_cast<U32>( data ) ) );
+}
+
+U32 toBigEndian( U32 data );
+
+inline S32 toBigEndian( S32 data )
+{
+ return static_cast<S32>( toBigEndian( static_cast<U32>( data ) ) );
+}
+
+inline U32 swapEndianness( U32 data )
+{
+ return ( ( data & 0x000000ffU ) << 24 ) | ( ( data & 0x0000ff00U ) << 8 ) |
+ ( ( data & 0x00ff0000U ) >> 8 ) | ( ( data & 0xff000000U ) >> 24 );
+}
+
+inline S32 swapEndianness( S32 data )
+{
+ return ( ( data & 0x000000ffU ) << 24 ) | ( ( data & 0x0000ff00U ) << 8 ) |
+ ( ( data & 0x00ff0000U ) >> 8 ) | ( ( data & 0xff000000U ) >> 24 );
+}
+
+} // namespace wvWare
+
+#endif // GLOBAL_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/graphics.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/graphics.cpp
new file mode 100644
index 00000000..9c527f22
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/graphics.cpp
@@ -0,0 +1,321 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "graphics.h"
+#include "word97_generated.h"
+
+using namespace wvWare;
+
+Drawings::Drawings( OLEStreamReader* table, const Word97::FIB &fib ) :
+ m_plcfspaMom( 0 ), m_plcfspaHdr( 0 ), m_plcftxbxTxt( 0 ), m_plcfHdrtxbxTxt( 0 ),
+ m_plcftxbxBkd( 0 ), m_plcfHdrtxbxBkd( 0 )
+{
+ table->push();
+
+ // Don't try to read that. It will cause eye-cancer!
+ if ( fib.lcbPlcspaMom != 0 && table->seek( fib.fcPlcspaMom, G_SEEK_SET ) )
+ m_plcfspaMom = new PLCF<Word97::FSPA>( fib.lcbPlcspaMom, table, false );
+ if ( fib.lcbPlcspaHdr != 0 && table->seek( fib.fcPlcspaHdr, G_SEEK_SET ) )
+ m_plcfspaHdr = new PLCF<Word97::FSPA>( fib.lcbPlcspaHdr, table, false );
+
+ if ( fib.lcbPlcftxbxTxt != 0 && table->seek( fib.fcPlcftxbxTxt, G_SEEK_SET ) )
+ m_plcftxbxTxt = new PLCF<Word97::FTXBXS>( fib.lcbPlcftxbxTxt, table, false );
+ if ( fib.lcbPlcfHdrtxbxTxt != 0 && table->seek( fib.fcPlcfHdrtxbxTxt, G_SEEK_SET ) )
+ m_plcfHdrtxbxTxt = new PLCF<Word97::FTXBXS>( fib.lcbPlcfHdrtxbxTxt, table, false );
+
+ if ( fib.lcbPlcftxbxBkd != 0 && table->seek( fib.fcPlcftxbxBkd, G_SEEK_SET ) )
+ m_plcftxbxBkd = new PLCF<Word97::BKD>( fib.lcbPlcftxbxBkd, table, false );
+ if ( fib.lcbPlcftxbxHdrBkd != 0 && table->seek( fib.fcPlcftxbxHdrBkd, G_SEEK_SET ) )
+ m_plcfHdrtxbxBkd = new PLCF<Word97::BKD>( fib.lcbPlcftxbxHdrBkd, table, false );
+
+ table->pop();
+}
+
+Drawings::~Drawings()
+{
+ delete m_plcfHdrtxbxBkd;
+ delete m_plcftxbxBkd;
+ delete m_plcfHdrtxbxTxt;
+ delete m_plcftxbxTxt;
+ delete m_plcfspaHdr;
+ delete m_plcfspaMom;
+}
+
+EscherHeader::EscherHeader( OLEStreamReader* stream )
+{
+ //read first 32 bits
+ U32 shifterU32;
+ shifterU32 = stream->readU32();
+ ver = shifterU32;
+ shifterU32>>=4;
+ inst = shifterU32;
+ shifterU32>>=12;
+ fbt = shifterU32;
+ //read second 32 bits
+ cbLength = stream->readU32();
+}
+
+EscherHeader::~EscherHeader()
+{
+}
+
+bool EscherHeader::isAtom()
+{
+ //0xF in ver means it's a container
+ if( ver == 0xF )
+ return false;
+ else
+ return true;
+}
+
+string EscherHeader::getRecordType()
+{
+ string s;
+ switch( fbt ) {
+ case 0xF000:
+ s = "msofbtDggContainer";
+ break;
+ case 0xF001:
+ s = "msofbtBstoreContainer";
+ break;
+ case 0xF002:
+ s = "msofbtDgContainer";
+ break;
+ case 0xF004:
+ s = "msofbtSpContainer";
+ break;
+ case 0xF006:
+ s = "msofbtDgg";
+ break;
+ case 0xF007:
+ s = "msofbtBSE";
+ break;
+ case 0xF008:
+ s = "msofbtDg";
+ break;
+ case 0xF00A:
+ s = "msofbtSp";
+ break;
+ case 0xF00B:
+ s = "msofbtOPT";
+ break;
+ case 0xF010:
+ s = "msofbtClientAnchor";
+ break;
+ case 0xF016:
+ s = "msofbtCLSID";
+ break;
+ case 0xF01A:
+ s = "EMF";
+ break;
+ case 0xF01B:
+ s = "WMF";
+ break;
+ case 0xF01C:
+ s = "PICT";
+ break;
+ case 0xF01D:
+ s = "JPEG";
+ break;
+ case 0xF01E:
+ s = "PNG";
+ break;
+ case 0xF01F:
+ s = "DIB";
+ break;
+ case 0xF11A:
+ s = "msofbtColorMRU";
+ break;
+ case 0xF11E:
+ s = "msofbtSplitMenuColors";
+ break;
+ case 0xF118:
+ s = "msofbtRegroupItems";
+ break;
+ default:
+ s = "unknown";
+ }
+ return s;
+}
+
+//returns size of the record NOT COUNTING the header
+int EscherHeader::recordSize()
+{
+ return static_cast<int> (cbLength);
+}
+
+void EscherHeader::dump()
+{
+ wvlog << "Dumping Escher header:" << std::endl;
+ wvlog << " ver = " << ver << std::endl;
+ wvlog << " inst = " << inst << std::endl;
+ wvlog << " fbt = " << fbt << std::endl;
+ wvlog << " cbLength = " << cbLength << std::endl;
+ wvlog << "Finished dumping Escher header." << std::endl;
+}
+
+FBSE::FBSE( OLEStreamReader* stream )
+{
+ btWin32 = static_cast<MSOBLIPTYPE> (stream->readU8());
+ btMacOS = static_cast<MSOBLIPTYPE> (stream->readU8());
+ stream->read( rgbUid, 16 );
+ tag = stream->readU16();
+ size = stream->readU32();
+ cRef = stream->readU32();
+ foDelay = stream->readU32();
+ usage = static_cast<MSOBLIPUSAGE> (stream->readU8());
+ cbName = stream->readU8();
+ unused2 = stream->readU8();
+ unused3 = stream->readU8();
+}
+
+FBSE::~FBSE()
+{
+}
+
+void FBSE::dump()
+{
+ wvlog << "Dumping FBSE:" << std::endl;
+ wvlog << "\tbtWin32 = " << btWin32 << std::endl;
+ wvlog << "\tbtMacOS = " << btMacOS << std::endl;
+ wvlog << "\trgbUid = " << rgbUid << std::endl;
+ wvlog << "\ttag = " << tag << std::endl;
+ wvlog << "\tsize = " << size << std::endl;
+ wvlog << "\tcRef = " << cRef << std::endl;
+ wvlog << "\tfoDelay = " << foDelay << std::endl;
+ wvlog << "\tusage = " << static_cast<int> (usage) << std::endl;
+ wvlog << "\tcbName = " << static_cast<unsigned int> (cbName) << std::endl;
+ wvlog << "\tunused2 = " << static_cast<unsigned int> (unused2) << std::endl;
+ wvlog << "\tunused3 = " << static_cast<unsigned int> (unused3) << std::endl;
+ wvlog << "Finished dumping FBSE." << std::endl;
+}
+
+int FBSE::recordSize()
+{
+ //just add up the sizes of btWin32 + btMacOS + rgUid[16] + ...
+ return 36;
+}
+
+int FBSE::getBlipType()
+{
+ //cast enum to int
+ return static_cast<int> (btWin32);
+}
+
+int FBSE::getStreamOffset()
+{
+ //cast U32 to unsigned int
+ return static_cast<unsigned int> (foDelay);
+}
+
+int FBSE::getNameLength()
+{
+ //cast U8 to unsigned int
+ return static_cast<unsigned int> (cbName);
+}
+
+Blip::Blip( OLEStreamReader* stream, string blipType )
+{
+ m_size = 0; //just an initial value
+ m_blipType = blipType;
+ m_isMetafileBlip = false;
+ if( blipType.compare("JPEG") == 0 || blipType.compare("PNG") == 0
+ || blipType.compare("DIB") == 0 )
+ {
+ stream->read( m_rgbUid, 16 ); //data UID
+ m_bTag = stream->readU8();
+ m_size = 17;
+ //initialize other variables just to 0
+ m_cb = 0;
+ m_rcBounds = 0;
+ m_ptSize = 0;
+ m_cbSave = 0;
+ m_fCompression = 255; //test value, so we'll just initialize to this
+ m_fFilter = 255; //test value, so we'll just initialize to this
+ }
+ else if( blipType.compare("EMF") == 0 || blipType.compare("WMF") == 0
+ || blipType.compare("PICT") == 0 )
+ {
+ stream->read( m_rgbUid, 16 ); //data UID
+ stream->read( m_rgbUidPrimary, 16 ); //primary Uid
+ m_cb = stream->readU32(); //cache of metafile size
+ m_rcBounds = stream->readU32(); //boundary of metafile drawing commands
+ m_ptSize = stream->readU32(); //size of metafile in EMU's
+ m_cbSave = stream->readU32(); //cache of saved size (size of m_pvBits)
+ m_fCompression = stream->readU8(); //compression
+ m_fFilter = stream->readU8(); //always msofilterNone = 254
+ m_isMetafileBlip = true;
+ m_size = 46;
+ }
+}
+
+Blip::~Blip()
+{
+}
+
+bool Blip::isMetafileBlip()
+{
+ return m_isMetafileBlip;
+}
+
+bool Blip::isCompressed()
+{
+ //only metafile blips can be compressed
+ //and the flag has to be set
+ if( isMetafileBlip() && m_fCompression == 0 )
+ return true;
+ else
+ return false;
+}
+
+int Blip::recordSize()
+{
+ return m_size;
+}
+
+int Blip::imageSize()
+{
+ return static_cast<unsigned int> (m_cb);
+}
+
+int Blip::compressedImageSize()
+{
+ return static_cast<unsigned int> (m_cbSave);
+}
+
+void Blip::dump()
+{
+ if( !isCompressed() )
+ {
+ wvlog << " bitmap blip:" << std::endl;
+ wvlog << " m_rgbUid = " << m_rgbUid << std::endl;
+ wvlog << " m_bTag = " << static_cast<unsigned int> (m_bTag) << std::endl;
+ }
+ else
+ {
+ wvlog << " metafile blip:" << std::endl;
+ wvlog << " m_rgbUid = " << m_rgbUid << std::endl;
+ wvlog << " m_cb = " << m_cb << std::endl;
+ wvlog << " m_rcBounds = " << m_rcBounds << std::endl;
+ wvlog << " m_ptSize = " << m_ptSize << std::endl;
+ wvlog << " m_cbSave = " << m_cbSave << std::endl;
+ wvlog << " m_fCompression = " << static_cast<unsigned int> (m_fCompression) << std::endl;
+ wvlog << " m_fFilter = " << static_cast<unsigned int> (m_fFilter) << std::endl;
+ }
+}
+
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/graphics.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/graphics.h
new file mode 100644
index 00000000..1aa93665
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/graphics.h
@@ -0,0 +1,184 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef GRAPHICS_H
+#define GRAPHICS_H
+
+#include <string>
+
+#include "word_helper.h"
+
+using std::string;
+
+namespace wvWare
+{
+ class OLEStreamReader;
+ namespace Word97
+ {
+ struct FSPA;
+ struct FIB;
+ struct FTXBXS;
+ struct BKD;
+ }
+
+ class Drawings
+ {
+ public:
+ Drawings( OLEStreamReader* table, const Word97::FIB &fib );
+ ~Drawings();
+
+ private:
+ Drawings( const Drawings& rhs );
+ Drawings& operator=( const Drawings& rhs );
+
+ PLCF<Word97::FSPA>* m_plcfspaMom;
+ PLCF<Word97::FSPA>* m_plcfspaHdr;
+
+ PLCF<Word97::FTXBXS>* m_plcftxbxTxt;
+ PLCF<Word97::FTXBXS>* m_plcfHdrtxbxTxt;
+
+ PLCF<Word97::BKD>* m_plcftxbxBkd;
+ PLCF<Word97::BKD>* m_plcfHdrtxbxBkd;
+ };
+
+ class Pictures
+ {
+ };
+
+ typedef enum
+ {
+ msoblipUsageDefault, // All non-texture fill blips get this.
+ msoblipUsageTexture,
+ msoblipUsageMax = 255 // Since this is stored in a byte
+ } MSOBLIPUSAGE;
+
+ typedef enum
+ { // GEL provided types...
+ msoblipERROR = 0, // An error occured during loading
+ msoblipUNKNOWN, // An unknown blip type
+ msoblipEMF, // Windows Enhanced Metafile
+ msoblipWMF, // Windows Metafile
+ msoblipPICT, // Macintosh PICT
+ msoblipJPEG, // JFIF
+ msoblipPNG, // PNG
+ msoblipDIB, // Windows DIB
+ msoblipFirstClient = 32, // First client defined blip type
+ msoblipLastClient = 255 // Last client defined blip type
+ } MSOBLIPTYPE;
+
+ typedef enum
+ {
+ msobiUNKNOWN = 0,
+ msobiWMF = 0x216, // Metafile header then compressed WMF
+ msobiEMF = 0x3D4, // Metafile header then compressed EMF
+ msobiPICT = 0x542, // Metafile header then compressed PICT
+ msobiPNG = 0x6E0, // One byte tag then PNG data
+ msobiJFIF = 0x46A, // One byte tag then JFIF data
+ msobiJPEG = msobiJFIF,
+ msobiDIB = 0x7A8, // One byte tag then DIB data
+ msobiClient=0x800 // Clients should set this bit
+ } MSOBI; // Blip signature as encoded in the MSOFBH.inst
+
+ //this is a common header that every record
+ //in Escher streams share
+ class EscherHeader
+ {
+ public:
+ EscherHeader( OLEStreamReader* stream );
+ ~EscherHeader();
+
+ bool isAtom();
+ int recordSize();
+ string getRecordType();
+ void dump();
+
+ private:
+ U32 ver:4; //4 bits
+ U32 inst:12; //12 bits
+ U32 fbt:16; //16 bits
+ U32 cbLength; //4 bytes
+ }; //EscherHeader
+
+ //msofbtSpContainer
+ //msofbtSp
+ //msofbtOPT
+ //msoftbClientAnchor
+
+ //this is a structure inside the msofbtBSE
+ //record
+ class FBSE
+ {
+ public:
+ FBSE( OLEStreamReader* stream );
+ ~FBSE();
+
+ int recordSize();//size of the record without the Escher header
+ //(does NOT include actual picture data, either, which is in a
+ //new record)
+ int getBlipType();
+ int getStreamOffset();
+ int getNameLength();
+ void dump();
+
+ private:
+ MSOBLIPTYPE btWin32; //required type on Win32
+ MSOBLIPTYPE btMacOS; //required type on Mac
+ U8 rgbUid[ 16 ]; //identifier of the blip
+ U16 tag; //unused
+ U32 size; //blip size in the stream
+ U32 cRef; //reference count on the blip
+ U32 foDelay; //file offset in the delay stream
+ MSOBLIPUSAGE usage; //how this blip is used
+ U8 cbName; //length of blip name
+ U8 unused2; //unused
+ U8 unused3; //unused
+ }; //FBSE
+
+ //this is a structure that actually contains the
+ //image data (it follows the FBSE in a new record)
+ class Blip
+ {
+ public:
+ Blip( OLEStreamReader* stream, string blipType );
+ ~Blip();
+
+ bool isMetafileBlip(); //is this an EMF, WMF, or PICT?
+ bool isCompressed(); //is this blip compressed? (only applied to metafile blips)
+ int recordSize(); //size of the record *without* the actual picture data
+ int imageSize(); //size of the *uncompressed* image
+ int compressedImageSize(); //size of the *compressed* image
+ void dump();
+ private:
+ U8 m_rgbUid[16];
+ U8 m_bTag;
+ U8 m_rgbUidPrimary[16]; //not always present!
+ U32 m_cb;
+ U32 m_rcBounds;
+ U32 m_ptSize;
+ U32 m_cbSave;
+ U8 m_fCompression;
+ U8 m_fFilter;
+ string m_blipType;
+ unsigned int m_size; //store size of record (without actual picture data)
+ //this is set in the constructor when the data is read in
+ bool m_isMetafileBlip; //flag for remembering whether it's metafile or bitmap
+ }; //Blip
+
+} // namespace wvWare
+
+#endif // GRAPHICS_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/handlers.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/handlers.cpp
new file mode 100644
index 00000000..49cebe02
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/handlers.cpp
@@ -0,0 +1,214 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "handlers.h"
+#include "parser9x.h"
+#include "paragraphproperties.h"
+#include "functor.h"
+
+using namespace wvWare;
+
+InlineReplacementHandler::~InlineReplacementHandler()
+{
+}
+
+U8 InlineReplacementHandler::tab()
+{
+ return TAB;
+}
+
+U8 InlineReplacementHandler::hardLineBreak()
+{
+ return HARD_LINE_BREAK;
+}
+
+U8 InlineReplacementHandler::columnBreak()
+{
+ return COLUMN_BREAK;
+}
+
+U8 InlineReplacementHandler::nonBreakingHyphen()
+{
+ return NON_BREAKING_HYPHEN;
+}
+
+U8 InlineReplacementHandler::nonRequiredHyphen()
+{
+ return NON_REQUIRED_HYPHEN;
+}
+
+U8 InlineReplacementHandler::nonBreakingSpace()
+{
+ return NON_BREAKING_SPACE;
+}
+
+
+SubDocumentHandler::~SubDocumentHandler()
+{
+}
+
+void SubDocumentHandler::bodyStart()
+{
+}
+
+void SubDocumentHandler::bodyEnd()
+{
+}
+
+void SubDocumentHandler::footnoteStart()
+{
+}
+
+void SubDocumentHandler::footnoteEnd()
+{
+}
+
+void SubDocumentHandler::headersStart()
+{
+}
+
+void SubDocumentHandler::headersEnd()
+{
+}
+
+void SubDocumentHandler::headerStart( HeaderData::Type /*type*/ )
+{
+}
+
+void SubDocumentHandler::headerEnd()
+{
+}
+
+
+TableHandler::~TableHandler()
+{
+}
+
+void TableHandler::tableRowStart( SharedPtr<const Word97::TAP> /*tap*/ )
+{
+}
+
+void TableHandler::tableRowEnd()
+{
+}
+
+void TableHandler::tableCellStart()
+{
+}
+
+void TableHandler::tableCellEnd()
+{
+}
+
+
+PictureHandler::~PictureHandler()
+{
+}
+
+void PictureHandler::bitmapData( OLEImageReader& /*reader*/, SharedPtr<const Word97::PICF> /*picf*/ )
+{
+}
+
+void PictureHandler::escherData( OLEImageReader& /*reader*/, SharedPtr<const Word97::PICF> /*picf*/, int type )
+{
+}
+
+void PictureHandler::escherData( std::vector<U8>, SharedPtr<const Word97::PICF> /*picf*/, int type )
+{
+}
+
+void PictureHandler::wmfData( OLEImageReader& /*reader*/, SharedPtr<const Word97::PICF> /*picf*/ )
+{
+}
+
+void PictureHandler::externalImage( const UString& /*name*/, SharedPtr<const Word97::PICF> /*picf*/ )
+{
+}
+
+
+TextHandler::~TextHandler()
+{
+}
+
+void TextHandler::sectionStart( SharedPtr<const Word97::SEP> /*sep*/ )
+{
+}
+
+void TextHandler::sectionEnd()
+{
+}
+
+void TextHandler::pageBreak()
+{
+}
+
+void TextHandler::headersFound( const HeaderFunctor& parseHeaders )
+{
+ parseHeaders();
+}
+
+void TextHandler::paragraphStart( SharedPtr<const ParagraphProperties> /*paragraphProperties*/ )
+{
+}
+
+void TextHandler::paragraphEnd()
+{
+}
+
+void TextHandler::runOfText( const UString& /*text*/, SharedPtr<const Word97::CHP> /*chp*/ )
+{
+}
+
+void TextHandler::specialCharacter( SpecialCharacter /*character*/, SharedPtr<const Word97::CHP> /*chp*/ )
+{
+}
+
+void TextHandler::footnoteFound( FootnoteData::Type /*type*/, UChar character,
+ SharedPtr<const Word97::CHP> chp, const FootnoteFunctor& parseFootnote )
+{
+ if ( character.unicode() != 2 )
+ runOfText( UString( character ), chp ); // The character shouldn't get lost unless it's the auto-number
+ parseFootnote();
+}
+
+void TextHandler::footnoteAutoNumber( SharedPtr<const Word97::CHP> /*chp*/ )
+{
+}
+
+void TextHandler::fieldStart( const FLD* /*fld*/, SharedPtr<const Word97::CHP> /*chp*/ )
+{
+}
+
+void TextHandler::fieldSeparator( const FLD* /*fld*/, SharedPtr<const Word97::CHP> /*chp*/ )
+{
+}
+
+void TextHandler::fieldEnd( const FLD* /*fld*/, SharedPtr<const Word97::CHP> /*chp*/ )
+{
+}
+
+void TextHandler::tableRowFound( const TableRowFunctor& tableRow, SharedPtr<const Word97::TAP> /*tap*/ )
+{
+ tableRow();
+}
+
+void TextHandler::pictureFound( const PictureFunctor& picture, SharedPtr<const Word97::PICF> /*picf*/,
+ SharedPtr<const Word97::CHP> /*chp*/ )
+{
+ picture();
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/handlers.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/handlers.h
new file mode 100644
index 00000000..c244364f
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/handlers.h
@@ -0,0 +1,388 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef HANDLERS_H
+#define HANDLERS_H
+
+#include <vector>
+
+#include "global.h"
+#include "sharedptr.h"
+#include "functordata.h"
+
+namespace wvWare {
+
+ class Parser9x;
+ struct UChar;
+ class UString;
+ template<class ParserT, typename Data> class Functor;
+ typedef Functor<Parser9x, HeaderData> HeaderFunctor;
+ typedef Functor<Parser9x, TableRowData> TableRowFunctor;
+ typedef Functor<Parser9x, FootnoteData> FootnoteFunctor;
+ typedef Functor<Parser9x, PictureData> PictureFunctor;
+
+ /**
+ * This class allows to replace the character values of some
+ * characters in a Word document, like non-breaking hyphens,...
+ * during the processing. As we have to look at every single
+ * character anyway, we can as well do single-character replacement
+ * in case it's necessary. That way you don't have to scan all the
+ * text again in the consumer filter.
+ *
+ * We use U8 instead of U16 as all interesting Word characters are
+ * within 7bit ASCII range, the names of the methods should be
+ * descriptive enough.
+ */
+ class InlineReplacementHandler
+ {
+ public:
+ virtual ~InlineReplacementHandler();
+
+ virtual U8 tab();
+ virtual U8 hardLineBreak();
+ virtual U8 columnBreak();
+ virtual U8 nonBreakingHyphen();
+ virtual U8 nonRequiredHyphen();
+ virtual U8 nonBreakingSpace();
+ };
+
+
+ /**
+ * The SubDocumentHandler is more or less a state-callback class. It informs
+ * the consumer filter about changes of subdocuments like body, header,
+ * footnote,...
+ * This class is needed as we reuse one @ref TextHandler object for all the
+ * text we find, no matter whether it's inside the main body or within a textbox.
+ */
+ class WV2_DLLEXPORT SubDocumentHandler
+ {
+ public:
+ virtual ~SubDocumentHandler();
+
+ /**
+ * This method is called as soon as you call @ref Parser::parse. It indicates
+ * the start of the body text (the main document text-flow).
+ */
+ virtual void bodyStart();
+ /**
+ * This method is called when all characters of the main body text
+ * are processed.
+ */
+ virtual void bodyEnd();
+
+ /**
+ * Every time you invoke a @ref FoonoteFunctor this method will be called.
+ * Note that @ref FoonoteFunctor is also emitted when we find endnotes.
+ */
+ virtual void footnoteStart();
+ /**
+ * Once the footnote characters are processed this method is called.
+ */
+ virtual void footnoteEnd();
+
+ /**
+ * For every section in a Word document a @ref HeaderFunctor is emitted.
+ * Invoking the functor triggers the parsing of all headers inside the
+ * section, this method is called to indicate that.
+ */
+ virtual void headersStart();
+ /**
+ * This method is called once all headers and footers of the current
+ * section are processed.
+ */
+ virtual void headersEnd();
+ /**
+ * There are up to 6 headers/footers for every section. This method informs
+ * you about the begin of a new header or footer of the given type.
+ *
+ * The default header/footer is the *Odd one. If you also get any *Even
+ * header or footer the document's left and right pages have different
+ * headers/footers. In case you get a *First header or footer the first
+ * page of this section has a different header or footer.
+ *
+ * @param type The type of the header or footer. Always emitted in
+ * the order of definition in the enum
+ */
+ virtual void headerStart( HeaderData::Type type );
+ /**
+ * The end of the current header or footer.
+ */
+ virtual void headerEnd();
+ };
+
+
+ namespace Word97
+ {
+ struct TAP;
+ }
+
+ /**
+ * The TableHandler class is the interface for all table related callbacks.
+ * It informs about about starts and ends of table cells and rows.
+ * Only invoking a table row functor triggers the parsing of the given table
+ * row, and results in table(Row|Cell)(Start|End) callbacks.
+ *
+ * Word doesn't store information about table boundaries internally, but
+ * it's quite easy to find out the start/end of a table, as all table
+ * row functors are emitted in a row (pun intended). This means that if
+ * you get a sequence of table row functors and then suddenly a
+ * paragraphStart callback, you know that the table has ended.
+ */
+ class WV2_DLLEXPORT TableHandler
+ {
+ public:
+ virtual ~TableHandler();
+
+ /**
+ * Indicates the start of a table row with the passed properties.
+ */
+ virtual void tableRowStart( SharedPtr<const Word97::TAP> tap );
+ /**
+ * Indicates the end of a table row.
+ */
+ virtual void tableRowEnd();
+ /**
+ * This method is invoked every time we start processing a new cell.
+ */
+ virtual void tableCellStart();
+ /**
+ * This method is invoked every time we reach a cell end.
+ */
+ virtual void tableCellEnd();
+ };
+
+
+ class OLEImageReader;
+
+ /**
+ * The PictureHandler class is the interface for all image related
+ * callbacks. All the image data is passed to the consumer via this
+ * interface.
+ */
+ class WV2_DLLEXPORT PictureHandler
+ {
+ public:
+ /**
+ * A small helper struct to express the dimensions of the passed
+ * .wmf. A dimension of 0 indicates an invalid dimension.
+ */
+ // ###### FIXME: Do we really need that?
+ /*
+ struct WMFDimensions
+ {
+ WMFDimensions( const U8* rcWinMF )
+ {
+ left = readS16( rcWinMF );
+ top = readS16( rcWinMF + 2 );
+ width = readU16( rcWinMF + 4 );
+ height = readU16( rcWinMF + 6 );
+ }
+ S16 left;
+ S16 top;
+ U16 width;
+ U16 height;
+ };
+ */
+
+ virtual ~PictureHandler();
+
+ /**
+ * This method is called when you invoke a PictureFunctor and the embedded
+ * image is a bitmap. The bitmap data can be accessed using the OLEImageReader.
+ * Note: The reader will only be valid until you return form that method, and
+ * don't forget that you're directly accessing little-endian image data!
+ */
+ virtual void bitmapData( OLEImageReader& reader, SharedPtr<const Word97::PICF> picf );
+ /**
+ * This method is called when the image is escher data.
+ */
+ virtual void escherData( OLEImageReader& reader, SharedPtr<const Word97::PICF> picf, int type );
+ virtual void escherData( std::vector<U8> data, SharedPtr<const Word97::PICF> picf, int type );
+ /**
+ * This method is called when you invoke a PictureFunctor and the embedded
+ * image is a .wmf file. The data can be accessed using the OLEImageReader.
+ * Note: The reader will only be valid until you return form that method, and
+ * don't forget that you're directly accessing little-endian data!
+ */
+ virtual void wmfData( OLEImageReader& reader, SharedPtr<const Word97::PICF> picf );
+ /**
+ * Word allows to store .tif, .bmp, or .gif images externally.
+ */
+ virtual void externalImage( const UString& name, SharedPtr<const Word97::PICF> picf );
+ };
+
+
+ class ParagraphProperties;
+ struct FLD;
+ namespace Word97
+ {
+ struct CHP;
+ struct SEP;
+ }
+
+ /**
+ * The TextHandler class is the main worker in this filter. It tells you
+ * about sections, paragraphs, and characters inside the document. If
+ * you want to have a fast filter, try to make those methods fast, they
+ * will get called very oftern.
+ */
+ class WV2_DLLEXPORT TextHandler
+ {
+ public:
+ virtual ~TextHandler();
+
+ //////////////////////////////////////////////////////////////////////
+ // Section related callbacks...
+ /**
+ * Denotes the start of a section.
+ * The section properties are passed in the @p sep argument.
+ */
+ virtual void sectionStart( SharedPtr<const Word97::SEP> sep );
+ virtual void sectionEnd();
+ /**
+ * A page break within a section.
+ */
+ virtual void pageBreak();
+ /**
+ * Emitted when we found headers or footers. The default implementation
+ * simply invokes the functor. This function is called right after the
+ * start of a new section.
+ */
+ virtual void headersFound( const HeaderFunctor& parseHeaders );
+
+ //////////////////////////////////////////////////////////////////////
+ // Paragraph related callbacks...
+ /**
+ * Denotes the start of a paragraph.
+ * The paragraph properties are passed in the @p paragraphProperties argument.
+ */
+ virtual void paragraphStart( SharedPtr<const ParagraphProperties> paragraphProperties );
+ virtual void paragraphEnd();
+
+ /**
+ * runOfText is the main worker in this API. It provides a chunk of text with
+ * the properties passed. A run of text inside a Word document may encompass
+ * an entire document, but in our implementation we chop those runs of text into
+ * smaller pieces.
+ * A run of text will never cross paragraph boundaries, even if the paragraph
+ * properties of the two or more containing paragraphs are the same. It would
+ * probably be slightly faster to do that, but IMHO it's just not worth the
+ * pain this would cause.
+ * @param text The text of this run, UString holds it as UCS-2 host order string.
+ * @param chp The character properties attached to this run of text
+ */
+ virtual void runOfText( const UString& text, SharedPtr<const Word97::CHP> chp );
+
+ //////////////////////////////////////////////////////////////////////
+ // Special characters...
+ /**
+ * The enum only contains characters which are "easy" to handle (as they don't
+ * need any further information). All the other fSpec characters are/will be
+ * handled via functors. The values match the ones found in the specification.
+ *
+ * The current list is just a first draft, I have no idea how many of them will
+ * be moved out because they're more complex as expected.
+ */
+ enum SpecialCharacter { CurrentPageNumber = 0, LineNumber = 6,
+ AbbreviatedDate = 10, TimeHMS = 11,
+ CurrentSectionNumber = 12, AbbreviatedDayOfWeek = 14,
+ DayOfWeek = 15, DayShort = 16, HourCurrentTime = 22,
+ HourCurrentTimeTwoDigits = 23, MinuteCurrentTime = 24,
+ MinuteCurrentTimeTwoDigits = 25, SecondsCurrentTime = 26,
+ AMPMCurrentTime = 27, CurrentTimeHMSOld = 28,
+ DateM = 29, DateShort = 30, MonthShort = 33,
+ YearLong = 34, YearShort = 35,
+ AbbreviatedMonth = 36, MonthLong = 37,
+ CurrentTimeHMS = 38, DateLong = 39 };
+
+ /**
+ * Very special characters (bad, bad name) are the ones which need additional
+ * information from the file (i.e. the plain "put the current date there" isn't sufficent).
+ */
+ enum VerySpecialCharacter { Picture = 1, FootnoteAuto = 2, DrawnObject = 8, FieldBegin = 19,
+ FieldSeparator = 20, FieldEnd = 21, FieldEscapeChar = 92 };
+
+ /**
+ * This method passes the simple cases of special characters we find. More complex ones
+ * will get their own callback.
+ */
+ virtual void specialCharacter( SpecialCharacter character, SharedPtr<const Word97::CHP> chp );
+
+ /**
+ * The parser found a footnote. The passed functor will trigger the parsing of this
+ * footnote/endnote, the default implementation just emits the passed character
+ * (unless it's an auto-numbered footnote, we won't emit ASCII 2 by default) with
+ * runOfText (that it doesn't get lost if someone doesn't override this method) and
+ * invokes the functor.
+ */
+ virtual void footnoteFound( FootnoteData::Type type, UChar character,
+ SharedPtr<const Word97::CHP> chp, const FootnoteFunctor& parseFootnote );
+ /**
+ * This callback will get triggered when parsing a auto-numbered footnote.
+ * The passed CHP is the character formatting information provided for the
+ * "number"
+ */
+ virtual void footnoteAutoNumber( SharedPtr<const Word97::CHP> chp );
+
+ /**
+ * This callback indicates the start of a field. Fields consist of two parts, separated
+ * by a field separator.
+ * @param fld Describes the type of the field for live fields. May be 0!
+ * @param chp The character properties of the field start (ASCII 19)
+ */
+ virtual void fieldStart( const FLD* fld, SharedPtr<const Word97::CHP> chp );
+ /**
+ * This callback separates the two parts of a field. The first part contains control
+ * codes and keywords, the second part is the field result.
+ * @param fld Describes the type of the field for live fields. May be 0!
+ * @param chp The character properties of the field separator (ASCII 20)
+ */
+ virtual void fieldSeparator( const FLD* fld, SharedPtr<const Word97::CHP> chp );
+ /**
+ * The end of the field result is indicated by this callback, fields may be nested up
+ * to 20 levels, so take care :-)
+ * @param fld Describes the type of the field for live fields. May be 0!
+ * @param chp The character properties of the field end (ASCII 21)
+ */
+ virtual void fieldEnd( const FLD* fld, SharedPtr<const Word97::CHP> chp );
+
+ /**
+ * This method is called every time we find a table row. The default
+ * implementation invokes the functor, which triggers the parsing
+ * process for the given table row.
+ * @param tap the table row properties. Those are the same as the
+ * ones you'll get when invoking the functor, but by having them here,
+ * you can do some preprocessing on the whole table first.
+ */
+ virtual void tableRowFound( const TableRowFunctor& tableRow, SharedPtr<const Word97::TAP> tap );
+
+ /**
+ * This method is called every time we find a picture. The default
+ * implementation invokes the functor, which triggers the parsing
+ * process for the given picture.
+ * @param picf the picture properties. Those are the same as the
+ * ones you'll get when invoking the functor, but by having them here,
+ * you can do some preprocessing.
+ */
+ virtual void pictureFound( const PictureFunctor& picture, SharedPtr<const Word97::PICF> picf,
+ SharedPtr<const Word97::CHP> chp );
+ };
+
+} // namespace wvWare
+
+#endif // HANDLERS_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/headers.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/headers.cpp
new file mode 100644
index 00000000..2eb00e68
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/headers.cpp
@@ -0,0 +1,64 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "headers.h"
+#include "olestream.h"
+#include "wvlog.h"
+
+using namespace wvWare;
+
+const int Headers::headerTypes = 6;
+
+Headers::Headers( U32 fcPlcfhdd, U32 lcbPlcfhdd, OLEStreamReader* tableStream, WordVersion version )
+{
+ if ( lcbPlcfhdd == 0 )
+ return;
+
+ tableStream->push();
+#ifdef WV2_DEBUG_HEADERS
+ wvlog << "Headers::Headers(): fc=" << fcPlcfhdd << " lcb=" << lcbPlcfhdd << std::endl;
+ if ( version == Word8 )
+ wvlog << " there is/are " << lcbPlcfhdd / 4 - 2 << " header(s)" << std::endl;
+#endif
+
+ // remove later (do we want asserts in here???)
+ if ( lcbPlcfhdd % 4 )
+ wvlog << "Bug: m_fib.lcbPlcfhdd % 4 != 0!" << std::endl;
+ else if ( version == Word8 && ( lcbPlcfhdd / 4 - 2 ) % headerTypes )
+ wvlog << "Bug: #headers % " << headerTypes << " != 0!" << std::endl;
+
+ tableStream->seek( fcPlcfhdd, G_SEEK_SET );
+
+ U32 i = 0;
+ if ( version == Word8 )
+ for ( ; i < headerTypes * sizeof( U32 ); i += sizeof( U32 ) )
+ if ( tableStream->readU32() )
+ wvlog << "Bug: Read a value != 0 where I expected a 0!" << std::endl;
+ for ( ; i < lcbPlcfhdd; i += sizeof( U32 ) )
+ m_headers.push_back( tableStream->readU32() );
+
+ tableStream->pop();
+}
+
+Headers::~Headers()
+{
+}
+
+void Headers::headerMask( U8 /*sep_grpfIhdt*/ )
+{
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/headers.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/headers.h
new file mode 100644
index 00000000..578d43e9
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/headers.h
@@ -0,0 +1,62 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef HEADERS_H
+#define HEADERS_H
+
+#include "global.h"
+#include <utility>
+#include <vector>
+
+namespace wvWare
+{
+
+ class OLEStreamReader;
+
+ /**
+ * @internal
+ * A tiny helper class to move some header/footer code out of the parser.
+ * Might not be ultra-elegant, but I don't like it if the parser code
+ * grows too much.
+ * Abstract base class for the Word 6/7 and Word 8 variants.
+ */
+ class Headers
+ {
+ public:
+ Headers( U32 fcPlcfhdd, U32 lcbPlcfhdd, OLEStreamReader* tableStream, WordVersion version );
+ virtual ~Headers();
+
+ /**
+ * Returns the header if there is any for the given mask. If we didn't find
+ * any header the pair's values are 0, 0.
+ */
+ virtual std::pair<U32, U32> findHeader( int sectionNumber, unsigned char mask ) const = 0;
+
+ /**
+ * A helper method to implement Word 6 support.
+ */
+ virtual void headerMask( U8 sep_grpfIhdt );
+
+ protected:
+ std::vector<U32> m_headers;
+ static const int headerTypes;
+ };
+
+} // namespace wvWare
+
+#endif // HEADERS_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/headers95.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/headers95.cpp
new file mode 100644
index 00000000..5b6f8632
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/headers95.cpp
@@ -0,0 +1,56 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "headers95.h"
+#include "wvlog.h"
+
+using namespace wvWare;
+
+Headers95::Headers95( U32 fcPlcfhdd, U32 lcbPlcfhdd, OLEStreamReader* tableStream, U8 dop_grpfIhdt ) :
+ Headers( fcPlcfhdd, lcbPlcfhdd, tableStream, Word67 ), ihddOffset( countOnes( dop_grpfIhdt, 0x40 ) )
+{
+ m_headerCount.push_back( 0 );
+}
+
+std::pair<U32, U32> Headers95::findHeader( int sectionNumber, unsigned char mask ) const
+{
+ if ( m_grpfIhdt.size() <= static_cast<std::vector<U32>::size_type>( sectionNumber ) ) {
+ wvlog << "Warning: You are trying to access a section that has not been registered yet!" << std::endl;
+ return std::make_pair( 0u, 0u );
+ }
+
+ // The offset to the begin of the section + offset due to mask/grpfIhdt
+ const int ihdd = ihddOffset + m_headerCount[ sectionNumber ] +
+ countOnes( m_grpfIhdt[ sectionNumber ], mask );
+ return std::make_pair( m_headers[ ihdd ], m_headers[ ihdd + 1 ] );
+}
+
+void Headers95::headerMask( U8 sep_grpfIhdt )
+{
+ m_grpfIhdt.push_back( sep_grpfIhdt );
+ m_headerCount.push_back( countOnes( sep_grpfIhdt, 0x40 ) + m_headerCount.back() );
+}
+
+int Headers95::countOnes( U8 mask, U8 limit ) const
+{
+ int count = 0;
+ for ( U8 m = 1; m < limit; m <<= 1 )
+ if ( m & mask )
+ ++count;
+ return count;
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/headers95.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/headers95.h
new file mode 100644
index 00000000..4cd2b8fa
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/headers95.h
@@ -0,0 +1,56 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef HEADERS95_H
+#define HEADERS95_H
+
+#include "headers.h"
+
+namespace wvWare
+{
+ /**
+ * @internal
+ * A tiny helper class to move some header/footer code out of the parser.
+ * Might not be ultra-elegant, but I don't like it if the parser code
+ * grows too much.
+ */
+ class Headers95 : public Headers
+ {
+ public:
+ Headers95( U32 fcPlcfhdd, U32 lcbPlcfhdd, OLEStreamReader* tableStream, U8 dop_grpfIhdt );
+
+ /**
+ * Returns the header if there is any for the given mask. If we didn't find
+ * any header the pair's values are 0, 0.
+ */
+ virtual std::pair<U32, U32> findHeader( int sectionNumber, unsigned char mask ) const;
+
+ virtual void headerMask( U8 sep_grpfIhdt );
+
+ private:
+ // Counts the '1' bits in <mask> from the lsb up to <limit> (exclusively)
+ int countOnes( U8 mask, U8 limit ) const;
+
+ const int ihddOffset;
+ std::vector<U32> m_headerCount;
+ std::vector<U8> m_grpfIhdt;
+ };
+
+} // namespace wvWare
+
+#endif // HEADERS95_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/headers97.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/headers97.cpp
new file mode 100644
index 00000000..28de548d
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/headers97.cpp
@@ -0,0 +1,51 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "headers97.h"
+
+using namespace wvWare;
+
+Headers97::Headers97( U32 fcPlcfhdd, U32 lcbPlcfhdd, OLEStreamReader* tableStream ) :
+ Headers( fcPlcfhdd, lcbPlcfhdd, tableStream, Word8 )
+{
+}
+
+std::pair<U32, U32> Headers97::findHeader( int sectionNumber, unsigned char mask ) const
+{
+ U32 start = 0;
+ U32 lim = 0;
+ const int offset = maskToOffset( mask );
+ do {
+ const int tmp = sectionNumber * headerTypes + offset;
+ start = m_headers[ tmp ];
+ lim = m_headers[ tmp + 1 ];
+ --sectionNumber;
+ } while ( start == lim && sectionNumber >= 0 );
+
+ return std::make_pair( start, lim );
+}
+
+int Headers97::maskToOffset( unsigned char mask ) const
+{
+ int offset = 0;
+ while ( mask != 0 && ( mask & 1 ) == 0 ) {
+ ++offset;
+ mask >>= 1;
+ }
+ return offset;
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/headers97.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/headers97.h
new file mode 100644
index 00000000..fe7383e3
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/headers97.h
@@ -0,0 +1,49 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef HEADERS97_H
+#define HEADERS97_H
+
+#include "headers.h"
+
+namespace wvWare
+{
+ /**
+ * @internal
+ * A tiny helper class to move some header/footer code out of the parser.
+ * Might not be ultra-elegant, but I don't like it if the parser code
+ * grows too much.
+ */
+ class Headers97 : public Headers
+ {
+ public:
+ Headers97( U32 fcPlcfhdd, U32 lcbPlcfhdd, OLEStreamReader* tableStream );
+
+ /**
+ * Returns the header if there is any for the given mask. If we didn't find
+ * any header the pair's values are 0, 0.
+ */
+ virtual std::pair<U32, U32> findHeader( int sectionNumber, unsigned char mask ) const;
+
+ private:
+ int maskToOffset( unsigned char mask ) const;
+ };
+
+} // namespace wvWare
+
+#endif // HEADERS97_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/lists.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/lists.cpp
new file mode 100644
index 00000000..30a08068
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/lists.cpp
@@ -0,0 +1,944 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "lists.h"
+#include "olestream.h"
+#include "word97_generated.h"
+#include "word_helper.h"
+#include "utilities.h"
+#include "styles.h"
+#include "crc32.h"
+
+#include "wvlog.h"
+#include <algorithm>
+
+// Private API
+// This might look a bit over-the-top at a first glance, but the reason
+// that I put all that stuff in separate classes is that Word 6 has a
+// completely different list info implementation, and I somehow have to
+// hide that fact.
+namespace wvWare
+{
+ namespace Word97
+ {
+ struct LSTF;
+ struct LVLF;
+ }
+ namespace
+ {
+ const int maxListLevels = 9;
+ const int oldStyleIlfo = 2047;
+ const U16 usLid = 0x409; // The list names in the STTBF are always Unicode, the lid doesn't matter
+ const U16 istdNil = 4095; // default style
+
+ // some sprms we need here
+ const U16 sprmCFBold = 0x0835;
+ const U16 sprmCFItalic = 0x0836;
+ const U16 sprmCFSmallCaps = 0x083A;
+ const U16 sprmCFCaps = 0x083B;
+ const U16 sprmCFStrike = 0x0837;
+ const U16 sprmCKul = 0x2A3E;
+ const U16 sprmCIco = 0x2A42;
+ const U16 sprmCRgFtc0 = 0x4A4F;
+ const U16 sprmCHps = 0x4A43;
+
+ unsigned int createFakeLSID( const Word97::ANLD& anld )
+ {
+ // As our structure contains padding bytes we have to use
+ // an array which is guaranteed not to have "holes" for the
+ // CRC32 sum...
+ unsigned char buffer[102];
+ buffer[0] = anld.nfc;
+ buffer[1] = anld.cxchTextBefore;
+ buffer[2] = anld.cxchTextAfter;
+ buffer[3] = anld.jc;
+ buffer[4] = anld.fPrev;
+ buffer[5] = anld.fHang;
+ buffer[6] = anld.fSetBold;
+ buffer[7] = anld.fSetItalic;
+ buffer[8] = anld.fSetSmallCaps;
+ buffer[9] = anld.fSetCaps;
+ buffer[10] = anld.fSetStrike;
+ buffer[11] = anld.fSetKul;
+ buffer[12] = anld.fPrevSpace;
+ buffer[13] = anld.fBold;
+ buffer[14] = anld.fItalic;
+ buffer[15] = anld.fSmallCaps;
+ buffer[16] = anld.fCaps;
+ buffer[17] = anld.fStrike;
+ buffer[18] = anld.kul;
+ buffer[19] = anld.ico;
+ unsigned short* tmp = reinterpret_cast<unsigned short*>( buffer ) + 10;
+ *tmp++ = anld.ftc;
+ *tmp++ = anld.hps;
+ *tmp++ = anld.iStartAt;
+ *tmp++ = anld.dxaIndent;
+ *tmp++ = anld.dxaSpace;
+ buffer[30] = anld.fNumber1;
+ buffer[31] = anld.fNumberAcross;
+ buffer[32] = anld.fRestartHdn;
+ buffer[33] = anld.fSpareX;
+ tmp += 2;
+ for ( int i = 0; i < 32; ++i )
+ *tmp++ = anld.rgxch[i];
+ // 98 bytes up to this point + 4 for the CRC32 sum
+ buffer[98] = 0;
+ buffer[99] = 0;
+ buffer[100] = 0;
+ buffer[101] = 0;
+ return CalcCRC32( buffer, 102, 98, 4 );
+ }
+ }
+
+ class ListLevel
+ {
+ public:
+ explicit ListLevel( OLEStreamReader* tableStream );
+ explicit ListLevel( const Word97::ANLD& anld );
+ ~ListLevel();
+
+ S32 startAt() const;
+ U8 numberFormat() const;
+ U8 alignment() const;
+ bool isLegal() const;
+ bool notRestarted() const;
+ bool prev() const;
+ bool prevSpace() const;
+ bool isWord6() const; // ###### Do we want to have that?
+ UString text() const;
+ U8 followingChar() const;
+
+ void applyGrpprlPapx( Word97::PAP* pap, const StyleSheet* styleSheet ) const;
+ void applyGrpprlChpx( Word97::CHP* chp, const Style* style, const StyleSheet* styleSheet ) const;
+
+ private:
+ ListLevel( const ListLevel& rhs );
+ ListLevel& operator=( const ListLevel& rhs );
+
+ int writeCharProperty( U16 sprm, U8 value, U8** grpprl );
+ int writeCharProperty( U16 sprm, U16 value, U8** grpprl );
+
+ Word97::LVLF m_lvlf;
+ U8* m_grpprlPapx;
+ U8* m_grpprlChpx;
+ UString m_numberText;
+ };
+
+
+ class ListData
+ {
+ public:
+ explicit ListData( OLEStreamReader* tableStream );
+ ListData( S32 lsid, bool fRestartHdn );
+ ~ListData();
+
+ S32 lsid() const;
+ U16 istdForLevel( U8 level ) const;
+ bool isSimpleList() const;
+ bool restartingCounter() const;
+
+ // The ownership is transferred to us
+ void appendListLevel( ListLevel* listLevel );
+ const ListLevel* listLevel( U8 level ) const;
+
+ void applyGrpprlPapx( Word97::PAP* pap, const StyleSheet* styleSheet ) const;
+
+ private:
+ ListData( const ListData& rhs );
+ ListData& operator=( const ListData& rhs );
+
+ Word97::LSTF m_lstf;
+ std::vector<ListLevel*> m_listLevels;
+ };
+
+
+ class ListFormatOverrideLVL
+ {
+ public:
+ ListFormatOverrideLVL( OLEStreamReader* tableStream );
+ ~ListFormatOverrideLVL();
+
+ S32 startAt() const;
+ U8 level() const;
+
+ bool overridesStartAt() const;
+ void resetStartAtFlag();
+ bool overridesFormat() const;
+
+ const ListLevel* listLevel() const;
+
+ void dump() const;
+ private:
+ ListFormatOverrideLVL( const ListFormatOverrideLVL& rhs );
+ ListFormatOverrideLVL& operator=( const ListFormatOverrideLVL& rhs );
+
+ Word97::LFOLVL m_lfolvl;
+ ListLevel* m_level;
+ };
+
+
+ class ListFormatOverride
+ {
+ public:
+ explicit ListFormatOverride( OLEStreamReader* tableStream );
+ explicit ListFormatOverride( S32 lsid );
+ ~ListFormatOverride();
+
+ S32 lsid() const;
+ U8 countOfLevels() const;
+ const ListFormatOverrideLVL* overrideLVL( U8 level ) const;
+
+ // The ownership is transferred to us
+ void appendListFormatOverrideLVL( ListFormatOverrideLVL* listFormatOverrideLVL );
+
+ private:
+ ListFormatOverride( const ListFormatOverride& rhs );
+ ListFormatOverride& operator=( const ListFormatOverride& rhs );
+
+ Word97::LFO m_lfo;
+ std::vector<ListFormatOverrideLVL*> m_lfoLevels;
+ };
+
+ // Compares the lisd variables, needed to generate a new unique ID
+ // for converted ANLDs
+ bool operator<( const ListFormatOverride& lhs, const ListFormatOverride& rhs )
+ {
+ return lhs.lsid() < rhs.lsid();
+ }
+
+} // namespace wvWare
+
+using namespace wvWare;
+
+ListLevel::ListLevel( OLEStreamReader* tableStream ) :
+ m_lvlf( tableStream, false ), m_grpprlPapx( 0 ), m_grpprlChpx( 0 )
+{
+#ifdef WV2_DEBUG_LIST_READING
+ wvlog << " ListLevel::ListLevel() ######" << std::endl
+ << " iStartAt=" << static_cast<int>( m_lvlf.iStartAt ) << " nfc=" << static_cast<int>( m_lvlf.nfc )
+ << " jc=" << static_cast<int>( m_lvlf.jc ) << std::endl << " fLegal=" << static_cast<int>( m_lvlf.fLegal )
+ << " fNoRestart=" << static_cast<int>( m_lvlf.fNoRestart ) << " fPrev=" << static_cast<int>( m_lvlf.fPrev )
+ << std::endl << " fPrevSpace=" << static_cast<int>( m_lvlf.fPrevSpace ) << " fWord6="
+ << static_cast<int>( m_lvlf.fWord6 ) << std::endl << " cbGrpprlPapx=" << static_cast<int>( m_lvlf.cbGrpprlPapx )
+ << " cbGrpprlChpx=" << static_cast<int>( m_lvlf.cbGrpprlChpx ) << std::endl;
+#endif
+
+ if ( m_lvlf.cbGrpprlPapx != 0 ) {
+ m_grpprlPapx = new U8[ m_lvlf.cbGrpprlPapx ];
+ tableStream->read( m_grpprlPapx, m_lvlf.cbGrpprlPapx );
+ }
+ if ( m_lvlf.cbGrpprlChpx != 0 ) {
+ m_grpprlChpx = new U8[ m_lvlf.cbGrpprlChpx ];
+ tableStream->read( m_grpprlChpx, m_lvlf.cbGrpprlChpx );
+ }
+
+ U16 len = tableStream->readU16();
+ if ( len != 0 ) {
+ XCHAR* string = new XCHAR[ len ];
+ for ( int i = 0; i < len; ++i )
+ string[ i ] = tableStream->readU16();
+ // The UString takes ownership, don't delete[] string!
+ m_numberText = UString( reinterpret_cast<UChar*>( string ), len, false );
+ }
+}
+
+ListLevel::ListLevel( const Word97::ANLD& anld ) : m_grpprlPapx( 0 ), m_grpprlChpx( 0 )
+{
+ m_lvlf.iStartAt = anld.iStartAt;
+ m_lvlf.nfc = anld.nfc;
+ m_lvlf.jc = anld.jc;
+ m_lvlf.fPrev = anld.fPrev;
+ m_lvlf.fPrevSpace = anld.fPrevSpace;
+ m_lvlf.fWord6 = true;
+ m_lvlf.dxaSpace = anld.dxaSpace;
+ m_lvlf.dxaIndent = anld.dxaIndent;
+
+ // number text
+#ifdef WV2_DEBUG_LIST_PROCESSING
+ wvlog << "cxchTextBefore=" << static_cast<int>( anld.cxchTextBefore ) << " cxchTextAfter="
+ << static_cast<int>( anld.cxchTextAfter ) << std::endl;
+#endif
+ if ( anld.cxchTextBefore > 0 && anld.cxchTextBefore <= 32 ) {
+ m_numberText = UString( reinterpret_cast<const UChar*>( &anld.rgxch[ 0 ] ), anld.cxchTextBefore );
+#ifdef WV2_DEBUG_LIST_PROCESSING
+ wvlog << "String (before): '" << m_numberText.ascii() << "'" << std::endl;
+#endif
+ }
+ m_numberText += UString( static_cast<char>( 0 ) ); // we are faking list level 0, so we have
+ // to insert the "variable"
+ if ( anld.cxchTextAfter > 0 && anld.cxchTextAfter <= 32 ) {
+ int start = anld.cxchTextAfter > anld.cxchTextBefore ? anld.cxchTextBefore : 0;
+ m_numberText += UString( reinterpret_cast<const UChar*>( &anld.rgxch[ start ] ), anld.cxchTextAfter - start );
+#ifdef WV2_DEBUG_LIST_PROCESSING
+ wvlog << "String (after): '" << UString( reinterpret_cast<const UChar*>( &anld.rgxch[ start ] ), anld.cxchTextAfter - start ).ascii() << "'" << std::endl;
+#endif
+ }
+
+ // grpprls
+ // ###### TODO: PAPX
+ m_lvlf.cbGrpprlPapx = 0;
+
+ // Allocate enough for all sprms and set the cb as limit
+ m_grpprlChpx = new U8[ 29 ];
+ U8* grpprl = m_grpprlChpx;
+ m_lvlf.cbGrpprlChpx = 0;
+
+ if ( anld.fSetBold )
+ m_lvlf.cbGrpprlChpx += writeCharProperty( sprmCFBold, anld.fBold, &grpprl );
+ if ( anld.fSetItalic )
+ m_lvlf.cbGrpprlChpx += writeCharProperty( sprmCFItalic, anld.fItalic, &grpprl );
+ if ( anld.fSetSmallCaps )
+ m_lvlf.cbGrpprlChpx += writeCharProperty( sprmCFSmallCaps, anld.fSmallCaps, &grpprl );
+ if ( anld.fSetCaps )
+ m_lvlf.cbGrpprlChpx += writeCharProperty( sprmCFCaps, anld.fCaps, &grpprl );
+ if ( anld.fSetStrike )
+ m_lvlf.cbGrpprlChpx += writeCharProperty( sprmCFStrike, anld.fStrike, &grpprl );
+ if ( anld.fSetKul )
+ m_lvlf.cbGrpprlChpx += writeCharProperty( sprmCKul, anld.kul, &grpprl );
+
+ m_lvlf.cbGrpprlChpx += writeCharProperty( sprmCIco, anld.ico, &grpprl );
+ m_lvlf.cbGrpprlChpx += writeCharProperty( sprmCRgFtc0, static_cast<U16>( anld.ftc ), &grpprl );
+ m_lvlf.cbGrpprlChpx += writeCharProperty( sprmCHps, anld.hps, &grpprl );
+
+#ifdef WV2_DEBUG_LIST_PROCESSING
+ wvlog << "The CHPX is " << static_cast<int>( m_lvlf.cbGrpprlChpx ) << " bytes long" << std::endl;
+#endif
+}
+
+ListLevel::~ListLevel()
+{
+ delete [] m_grpprlChpx;
+ delete [] m_grpprlPapx;
+}
+
+S32 ListLevel::startAt() const
+{
+ return m_lvlf.iStartAt;
+}
+
+U8 ListLevel::numberFormat() const
+{
+ return m_lvlf.nfc;
+}
+
+U8 ListLevel::alignment() const
+{
+ return m_lvlf.jc;
+}
+
+bool ListLevel::isLegal() const
+{
+ return m_lvlf.fLegal;
+}
+
+bool ListLevel::notRestarted() const
+{
+ return m_lvlf.fNoRestart;
+}
+
+bool ListLevel::prev() const
+{
+ return m_lvlf.fPrev;
+}
+
+bool ListLevel::prevSpace() const
+{
+ return m_lvlf.fPrevSpace;
+}
+
+bool ListLevel::isWord6() const
+{
+ return m_lvlf.fWord6;
+}
+
+UString ListLevel::text() const
+{
+ return m_numberText;
+}
+
+U8 ListLevel::followingChar() const
+{
+ return m_lvlf.ixchFollow;
+}
+
+void ListLevel::applyGrpprlPapx( Word97::PAP* pap, const StyleSheet* styleSheet ) const
+{
+#ifdef WV2_DEBUG_LIST_PROCESSING
+ wvlog << " ListLevel::applyGrpprlPapx: cbGrpprlPapx=" << static_cast<int>( m_lvlf.cbGrpprlPapx ) << std::endl;
+#endif
+ if ( m_grpprlPapx )
+ pap->apply( m_grpprlPapx, m_lvlf.cbGrpprlPapx, 0, styleSheet, 0, Word8 );
+}
+
+void ListLevel::applyGrpprlChpx( Word97::CHP* chp, const Style* style, const StyleSheet* styleSheet ) const
+{
+#ifdef WV2_DEBUG_LIST_PROCESSING
+ wvlog << " ListLevel::applyGrpprlChpx: cbGrpprlChpx=" << static_cast<int>( m_lvlf.cbGrpprlChpx ) << std::endl;
+#endif
+ if ( m_grpprlChpx )
+ chp->apply( m_grpprlChpx, m_lvlf.cbGrpprlChpx, style, styleSheet, 0, Word8 );
+}
+
+int ListLevel::writeCharProperty( U16 sprm, U8 value, U8** grpprl )
+{
+ write( *grpprl, sprm );
+ *grpprl += sizeof( U16 );
+ **grpprl = value;
+ ++( *grpprl );
+ return 3;
+}
+
+int ListLevel::writeCharProperty( U16 sprm, U16 value, U8** grpprl )
+{
+ write( *grpprl, sprm );
+ *grpprl += sizeof( U16 );
+ write( *grpprl, value );
+ *grpprl += sizeof( U16 );
+ return 4;
+}
+
+ListData::ListData( OLEStreamReader* tableStream ) : m_lstf( tableStream, false )
+{
+#ifdef WV2_DEBUG_LIST_READING
+ wvlog << " ListData::ListData() ######" << std::endl
+ << " lsid=" << m_lstf.lsid << " fSimpleList=" << static_cast<int>( m_lstf.fSimpleList )
+ << " tlpc=" << m_lstf.tplc << std::endl;
+#endif
+}
+
+ListData::ListData( S32 lsid, bool fRestartHdn )
+{
+ m_lstf.lsid = lsid;
+ m_lstf.fSimpleList = true;
+ for ( int i = 0; i < 9; ++i )
+ m_lstf.rgistd[ i ] = istdNil;
+ m_lstf.fRestartHdn = fRestartHdn;
+}
+
+ListData::~ListData()
+{
+ std::for_each( m_listLevels.begin(), m_listLevels.end(), Delete<ListLevel>() );
+}
+
+S32 ListData::lsid() const
+{
+ return m_lstf.lsid;
+}
+
+U16 ListData::istdForLevel( U8 level ) const
+{
+ return m_lstf.rgistd[ level ];
+}
+
+bool ListData::isSimpleList() const
+{
+ return m_lstf.fSimpleList;
+}
+
+bool ListData::restartingCounter() const
+{
+ return m_lstf.fRestartHdn;
+}
+
+void ListData::appendListLevel( ListLevel* listLevel )
+{
+#ifdef WV2_DEBUG_LIST_READING
+ wvlog << " ListData::appendListLevel() this=" << std::hex << reinterpret_cast<int>( this ) << std::dec << std::endl;
+#endif
+ m_listLevels.push_back( listLevel );
+}
+
+const ListLevel* ListData::listLevel( U8 level ) const
+{
+ if ( level < m_listLevels.size() )
+ return m_listLevels[ level ];
+ return 0;
+}
+
+void ListData::applyGrpprlPapx( Word97::PAP* pap, const StyleSheet* styleSheet ) const
+{
+#ifdef WV2_DEBUG_LIST_PROCESSING
+ wvlog << " ListData::applyGrpprlPapx(): level=" << static_cast<int>( pap->ilvl ) << std::endl;
+#endif
+
+ if ( !pap || pap->ilvl >= maxListLevels || ( m_lstf.fSimpleList && pap->ilvl != 0 ) )
+ return;
+ ListLevel* lvl = m_listLevels[ pap->ilvl ];
+ if ( lvl )
+ lvl->applyGrpprlPapx( pap, styleSheet );
+ else
+ wvlog << "Bug: Didn't find the level " << pap->ilvl << " in the LSTF!" << std::endl;
+}
+
+
+ListFormatOverrideLVL::ListFormatOverrideLVL( OLEStreamReader* tableStream ) :
+ m_lfolvl( tableStream, false ), m_level( 0 )
+{
+ if ( m_lfolvl.fFormatting )
+ m_level = new ListLevel( tableStream );
+}
+
+ListFormatOverrideLVL::~ListFormatOverrideLVL()
+{
+ delete m_level;
+}
+
+S32 ListFormatOverrideLVL::startAt() const
+{
+ return m_lfolvl.iStartAt;
+}
+
+U8 ListFormatOverrideLVL::level() const
+{
+ return m_lfolvl.ilvl;
+}
+
+bool ListFormatOverrideLVL::overridesStartAt() const
+{
+ return m_lfolvl.fStartAt;
+}
+
+void ListFormatOverrideLVL::resetStartAtFlag()
+{
+ m_lfolvl.fStartAt = false;
+}
+
+bool ListFormatOverrideLVL::overridesFormat() const
+{
+ return m_lfolvl.fFormatting;
+}
+
+const ListLevel* ListFormatOverrideLVL::listLevel() const
+{
+ return m_level;
+}
+
+void ListFormatOverrideLVL::dump() const
+{
+ wvlog << " ListFormatOverrideLVL::dump() ------------" << std::endl
+ << " iStartAt=" << m_lfolvl.iStartAt << " ilvl=" << static_cast<int>( m_lfolvl.ilvl ) << std::endl
+ << " fStartAt=" << static_cast<int>( m_lfolvl.fStartAt ) << " fFormatting="
+ << static_cast<int>( m_lfolvl.fFormatting ) << std::endl
+ << " ListFormatOverrideLVL::dump() done" << std::endl;
+}
+
+
+ListFormatOverride::ListFormatOverride( OLEStreamReader* tableStream ) : m_lfo( tableStream, false )
+{
+#ifdef WV2_DEBUG_LIST_READING
+ wvlog << " ListFormatOverride:ListFormatOverride() ######" << std::endl
+ << " lsid=" << m_lfo.lsid << " clfolvl=" << static_cast<int>( m_lfo.clfolvl ) << std::endl;
+#endif
+}
+
+ListFormatOverride::ListFormatOverride( S32 lsid )
+{
+ m_lfo.lsid = lsid;
+}
+
+ListFormatOverride::~ListFormatOverride()
+{
+ std::for_each( m_lfoLevels.begin(), m_lfoLevels.end(), Delete<ListFormatOverrideLVL>() );
+}
+
+S32 ListFormatOverride::lsid() const
+{
+ return m_lfo.lsid;
+}
+
+U8 ListFormatOverride::countOfLevels() const
+{
+ return m_lfo.clfolvl;
+}
+
+const ListFormatOverrideLVL* ListFormatOverride::overrideLVL( U8 level ) const
+{
+ std::vector<ListFormatOverrideLVL*>::const_iterator it = m_lfoLevels.begin();
+ std::vector<ListFormatOverrideLVL*>::const_iterator end = m_lfoLevels.end();
+ for ( ; it != end; ++it )
+ if ( ( *it )->level() == level )
+ return *it;
+ return 0;
+}
+
+void ListFormatOverride::appendListFormatOverrideLVL( ListFormatOverrideLVL* listFormatOverrideLVL )
+{
+ m_lfoLevels.push_back( listFormatOverrideLVL );
+}
+
+
+ListText::ListText() : chp( 0 )
+{
+}
+
+ListText::~ListText()
+{
+}
+
+
+ListInfo::ListInfo( Word97::PAP& pap, ListInfoProvider& listInfoProvider ) :
+ m_linkedIstd( istdNil ), m_restartingCounter( false ), m_numberFormat( 0 ),
+ m_alignment( 0 ), m_isLegal( false ), m_notRestarted( false ), m_prev( false ),
+ m_prevSpace( false ), m_isWord6( false ), m_followingChar( 0 ), m_lsid( 0 )
+{
+ if ( !listInfoProvider.setPAP( &pap ) )
+ return;
+ const ListLevel* const level = listInfoProvider.formattingListLevel();
+ const ListData* const listData = listInfoProvider.m_currentLst;
+
+ if ( listData ) {
+ m_linkedIstd = listData->istdForLevel( pap.ilvl );
+ m_restartingCounter = listData->restartingCounter();
+ m_lsid = listData->lsid();
+ }
+ else
+ wvlog << "Bug: The ListData is 0!!" << std::endl;
+
+ m_startAt = listInfoProvider.startAt();
+
+ if ( level ) {
+ m_numberFormat = level->numberFormat();
+ m_alignment = level->alignment();
+ m_isLegal = level->isLegal();
+ m_notRestarted = level->notRestarted();
+ m_prev = level->prev();
+ m_prevSpace = level->prevSpace();
+ m_isWord6 = level->isWord6();
+ m_text = listInfoProvider.text();
+ m_followingChar = level->followingChar();
+ }
+ else
+ wvlog << "Bug: The ListLevel is 0!!" << std::endl;
+}
+
+void ListInfo::dump() const
+{
+ wvlog << "ListInfo::dump() ------------------------------" << std::endl;
+ wvlog << " linkedIstd=" << m_linkedIstd << std::endl
+ << " restartingCounter=" << m_restartingCounter << " startAt=" << m_startAt.first << std::endl
+ << " startAtOverridden=" << m_startAt.second << std::endl
+ << " numberFormat=" << static_cast<int>( m_numberFormat ) << " alignment="
+ << static_cast<int>( m_alignment ) << std::endl << " isLegal=" << m_isLegal
+ << " notRestarted=" << m_notRestarted << std::endl << " prev=" << m_prev
+ << " prevSpace=" << m_prevSpace << std::endl << " isWord6=" << m_isWord6
+ << " text= '";
+ for ( int i = 0; i < m_text.text.length(); ++i )
+ wvlog << "<" << static_cast<char>( m_text.text[ i ].low() ) << "/" << m_text.text[ i ].unicode() << ">";
+ wvlog << "'" << std::endl
+ << " followingChar=" << static_cast<int>( m_followingChar ) << std::endl
+ << "ListInfo::dump() done -------------------------" << std::endl;
+}
+
+
+ListInfoProvider::ListInfoProvider( const StyleSheet* styleSheet )
+ : m_listNames( 0 ), m_pap( 0 ), m_styleSheet( styleSheet ), m_currentLfoLVL( 0 ),
+ m_currentLst( 0 ), m_version( Word67 )
+{
+#ifdef WV2_DEBUG_LIST_READING
+ wvlog << "ListInfoProvider::ListInfoProvider() ################################" << std::endl
+ << " ---> pre-Word 8" << std::endl;
+#endif
+}
+
+ListInfoProvider::ListInfoProvider( OLEStreamReader* tableStream, const Word97::FIB& fib, const StyleSheet* styleSheet ) :
+ m_listNames( 0 ), m_pap( 0 ), m_styleSheet( styleSheet ), m_currentLfoLVL( 0 ), m_currentLst( 0 ), m_version( Word8 )
+{
+#ifdef WV2_DEBUG_LIST_READING
+ wvlog << "ListInfoProvider::ListInfoProvider() ################################" << std::endl
+ << " fcPlcfLst=" << fib.fcPlcfLst << " lcbPlcfLst=" << fib.lcbPlcfLst << std::endl
+ << " fcPlfLfo=" << fib.fcPlfLfo << " lcbPlfLfo=" << fib.lcbPlfLfo << std::endl
+ << " fcSttbListNames=" << fib.fcSttbListNames << " lcbSttbListNames=" << fib.lcbSttbListNames << std::endl;
+#endif
+
+ tableStream->push();
+ if ( fib.lcbPlcfLst != 0 ) {
+ tableStream->seek( fib.fcPlcfLst, G_SEEK_SET );
+ readListData( tableStream, fib.fcPlcfLst + fib.lcbPlcfLst );
+ }
+ if ( fib.lcbPlfLfo != 0 ) {
+ if ( static_cast<U32>( tableStream->tell() ) != fib.fcPlfLfo ) {
+ wvlog << "Found a \"hole\" within the table stream (list data): current="
+ << tableStream->tell() << " expected=" << fib.fcPlfLfo << std::endl;
+ tableStream->seek( fib.fcPlfLfo, G_SEEK_SET );
+ }
+ readListFormatOverride( tableStream );
+ }
+ if ( fib.lcbSttbListNames != 0 ) {
+ // Get rid of leading garbage. Take care, though, as the STTBF most likely starts
+ // with 0xffff (extended character STTBF)
+ while ( static_cast<U32>( tableStream->tell() ) < fib.fcSttbListNames &&
+ tableStream->readU8() == 0xff ); // the ; is intended!
+
+ // Check the position and warn about corrupt files
+ if ( static_cast<U32>( tableStream->tell() ) != fib.fcSttbListNames ) {
+ wvlog << "Found a \"hole\" within the table stream (list format override): current="
+ << tableStream->tell() << " expected=" << fib.fcSttbListNames << std::endl;
+ tableStream->seek( fib.fcSttbListNames, G_SEEK_SET );
+ }
+ readListNames( tableStream );
+ }
+ tableStream->pop();
+
+#ifdef WV2_DEBUG_LIST_READING
+ wvlog << "ListInfoProvider::ListInfoProvider() done ###########################" << std::endl;
+#endif
+}
+
+ListInfoProvider::~ListInfoProvider()
+{
+ delete m_listNames;
+ std::for_each( m_listFormatOverride.begin(), m_listFormatOverride.end(), Delete<ListFormatOverride>() );
+ std::for_each( m_listData.begin(), m_listData.end(), Delete<ListData>() );
+}
+
+bool ListInfoProvider::isValid( S16 ilfo, U8 nLvlAnm ) const
+{
+ if ( m_version == Word67 )
+ return nLvlAnm != 0;
+ else
+ return ilfo == oldStyleIlfo || ( ilfo > 0 && ilfo <= static_cast<int>( m_listFormatOverride.size() ) );
+}
+
+bool ListInfoProvider::setPAP( Word97::PAP* pap )
+{
+#ifdef WV2_DEBUG_LIST_PROCESSING
+ wvlog << "ListInfoProvider::setPAP(): nLvlAnm = " << static_cast<int>( pap->nLvlAnm )
+ << " ilfo = " << pap->ilfo << std::endl;
+#endif
+ // Is it a list paragraph at all?
+ if ( ( m_version == Word67 ? static_cast<S16>( pap->nLvlAnm ) : pap->ilfo ) < 1 ) {
+ m_pap = 0;
+ m_currentLfoLVL = 0;
+ m_currentLst = 0;
+ return false;
+ }
+
+ m_pap = pap; // Don't we all love dangling pointers?
+ if ( m_version == Word67 )
+ convertCompatANLD();
+ else {
+ if ( m_listFormatOverride.size() < static_cast<unsigned int>( pap->ilfo ) ) { // 1-based index!
+ // This might be an old-style pap, where a pap->ilfo of 2047 suggests to look at
+ // the ANLD of that paragaph and to convert it
+ if ( pap->ilfo == oldStyleIlfo )
+ convertCompatANLD();
+ else {
+ wvlog << "Bug: ListInfoProvider::setWord97StylePAP -- out of bounds access (ilfo=" << pap->ilfo << ")" << std::endl;
+ m_pap = 0;
+ m_currentLfoLVL = 0;
+ m_currentLst = 0;
+ return false;
+ }
+ }
+ }
+ processOverride( m_listFormatOverride[ pap->ilfo - 1 ] );
+ return true;
+}
+
+void ListInfoProvider::readListData( OLEStreamReader* tableStream, const U32 endOfLSTF )
+{
+ const U16 count = tableStream->readU16();
+#ifdef WV2_DEBUG_LIST_READING
+ wvlog << "ListInfoProvider::readListData(): count=" << count << std::endl;
+#endif
+ for ( int i = 0; i < count; ++i )
+ m_listData.push_back( new ListData( tableStream ) );
+
+ // Note that this is a bug in the spec, but it at least seems to be a "stable" bug ;)
+ if ( static_cast<U32>( tableStream->tell() ) != endOfLSTF )
+ wvlog << "Expected a different size of this plcflst! (expected: "
+ << endOfLSTF << " position: " << tableStream->tell() << ")" << std::endl;
+
+#ifdef WV2_DEBUG_LIST_READING
+ wvlog << "ListInfoProvider::readListData(): 2nd step -- reading the LVLFs" << std::endl;
+#endif
+ // Now read in the ListLevels for each ListData
+ // If fSimpleList is true we only have one level, else there are nine
+ std::vector<ListData*>::const_iterator it = m_listData.begin();
+ std::vector<ListData*>::const_iterator end = m_listData.end();
+ for ( ; it != end; ++it ) {
+ if ( ( *it )->isSimpleList() )
+ ( *it )->appendListLevel( new ListLevel( tableStream ) );
+ else
+ for ( int i = 0; i < maxListLevels; ++i )
+ ( *it )->appendListLevel( new ListLevel( tableStream ) );
+ }
+}
+
+void ListInfoProvider::readListFormatOverride( OLEStreamReader* tableStream )
+{
+ const U32 count = tableStream->readU32();
+#ifdef WV2_DEBUG_LIST_READING
+ wvlog << "ListInfoProvider::readListFormatOverride(): count=" << count << std::endl;
+#endif
+ for ( U32 i = 0; i < count; ++i )
+ m_listFormatOverride.push_back( new ListFormatOverride( tableStream ) );
+
+ std::vector<ListFormatOverride*>::const_iterator it = m_listFormatOverride.begin();
+ std::vector<ListFormatOverride*>::const_iterator end = m_listFormatOverride.end();
+ for ( ; it != end; ++it ) {
+ const U8 levelCount = ( *it )->countOfLevels();
+ for ( int i = 0; i < levelCount; ++i ) {
+ // Word seems to write 0xff pagging-bytes between LFO and LFOLVLs, also
+ // between different LFOLVLs, get rid of it (Werner)
+ eatLeading0xff( tableStream );
+ ( *it )->appendListFormatOverrideLVL( new ListFormatOverrideLVL( tableStream ) );
+ }
+ }
+}
+
+void ListInfoProvider::readListNames( OLEStreamReader* tableStream )
+{
+#ifdef WV2_DEBUG_LIST_READING
+ wvlog << "ListInfoProvider::readListNames()" << std::endl;
+#endif
+ m_listNames = new STTBF( usLid, tableStream, false );
+#ifdef WV2_DEBUG_LIST_READING
+ m_listNames->dumpStrings();
+#endif
+}
+
+void ListInfoProvider::eatLeading0xff( OLEStreamReader* tableStream )
+{
+ while ( tableStream->readU8() == 0xff ); // semicolon intended ;)
+ tableStream->seek( -1, G_SEEK_CUR ); // rewind the stream
+}
+
+void ListInfoProvider::processOverride( ListFormatOverride* lfo )
+{
+#ifdef WV2_DEBUG_LIST_PROCESSING
+ wvlog << " ListInfoProvider::processOverride()" << std::endl;
+#endif
+ bool appliedPapx = false;
+ // It turns out we need a non-const pointer, as we have to reset the
+ // startAt flag after the first paragraph
+ m_currentLfoLVL = const_cast<ListFormatOverrideLVL*>( lfo->overrideLVL( m_pap->ilvl ) );
+
+ if ( m_currentLfoLVL ) {
+#ifdef WV2_DEBUG_LIST_PROCESSING
+ wvlog << " Level " << static_cast<int>( m_pap->ilvl ) << " found:" << std::endl;
+ m_currentLfoLVL->dump();
+#endif
+ if ( m_currentLfoLVL->overridesFormat() && m_currentLfoLVL->listLevel() ) {
+ m_currentLfoLVL->listLevel()->applyGrpprlPapx( m_pap, m_styleSheet );
+ appliedPapx = true;
+ }
+ }
+ m_currentLst = findLST( lfo->lsid() );
+
+ if ( m_currentLst && !appliedPapx )
+ m_currentLst->applyGrpprlPapx( m_pap, m_styleSheet );
+}
+
+void ListInfoProvider::convertCompatANLD()
+{
+ // We are creating a fake "unique" list ID via a CRC32 sum.
+ // It should be rather unlikely that two different ANLDs
+ // have the same lsid. In the case that the lsid is already
+ // there we assume that we already hit that ANLD before and
+ // just use its formatting information right away.
+ // There's one problem with that approach: If you have a Word 97
+ // document using some compat-lists and the lsid the CRC algorithm
+ // creates is already there, we end up using the wrong formatting
+ // information. I'm sure it's more likely to win in the lottery
+ // than facing that situation, though :-)
+ // Note that compat lists are always simple lists. (ilvl == 0)
+ const S32 lsid = createFakeLSID( m_pap->anld );
+ m_pap->ilvl = 0;
+#ifdef WV2_DEBUG_LIST_PROCESSING
+ wvlog << " ListInfoProvider::convertCompatANLD" << std::endl
+ << " generated a unique lsid: " << lsid << std::endl;
+#endif
+
+ // Does it already exist?
+ std::vector<ListData*>::const_iterator it = m_listData.begin();
+ std::vector<ListData*>::const_iterator end = m_listData.end();
+ for ( int i = 1; it != end; ++it, ++i ) // 1-based index!
+ if ( ( *it )->lsid() == lsid ) {
+ m_pap->ilfo = i;
+ return;
+ }
+
+ // It's not there yet...
+ // Fake a LFO structure (with 0 overridden levels and the lsid we generated)
+ m_listFormatOverride.push_back( new ListFormatOverride( lsid ) );
+ m_pap->ilfo = m_listFormatOverride.size();
+
+ // And another fake, the LSTF
+ ListData* listData = new ListData( lsid, m_pap->anld.fRestartHdn );
+ listData->appendListLevel( new ListLevel( m_pap->anld ) );
+ m_listData.push_back( listData );
+}
+
+ListData* ListInfoProvider::findLST( S32 lsid )
+{
+#ifdef WV2_DEBUG_LIST_PROCESSING
+ wvlog << " ListInfoProvider::findLST: lsid=" << lsid << std::endl;
+#endif
+ std::vector<ListData*>::const_iterator it = m_listData.begin();
+ std::vector<ListData*>::const_iterator end = m_listData.end();
+ for ( ; it != end; ++it )
+ if ( ( *it )->lsid() == lsid )
+ return *it;
+ return 0;
+}
+
+const ListLevel* ListInfoProvider::formattingListLevel() const
+{
+ if ( m_currentLfoLVL && m_currentLfoLVL->overridesFormat() && m_currentLfoLVL->listLevel() )
+ return m_currentLfoLVL->listLevel();
+ return m_currentLst ? m_currentLst->listLevel( m_pap->ilvl ) : 0;
+}
+
+std::pair<S32, bool> ListInfoProvider::startAt()
+{
+ std::pair<S32, bool> start( 1, false );
+ if ( m_currentLfoLVL && m_currentLfoLVL->overridesStartAt() ) {
+ start.second = true;
+ if ( m_currentLfoLVL->overridesFormat() && m_currentLfoLVL->listLevel() )
+ start.first = m_currentLfoLVL->listLevel()->startAt();
+ else
+ start.first = m_currentLfoLVL->startAt();
+ // Reset the startAt flag after the first paragraph (Word 97 spec, LFO parag.)
+ m_currentLfoLVL->resetStartAtFlag();
+ }
+ else {
+ const ListLevel* level = m_currentLst ? m_currentLst->listLevel( m_pap->ilvl ) : 0;
+ if ( level )
+ start.first = level->startAt();
+ }
+ return start;
+}
+
+ListText ListInfoProvider::text() const
+{
+ ListText ret;
+ ret.text = formattingListLevel()->text();
+
+ // Get the appropriate style for this paragraph
+ const Style* style = m_styleSheet->styleByIndex( m_pap->istd );
+ if ( !style ) {
+ wvlog << "Bug: Huh, really obscure error, couldn't find the Style for the current PAP" << std::endl;
+ ret.chp = new Word97::CHP;
+ }
+ else
+ ret.chp = new Word97::CHP( style->chp() );
+
+ formattingListLevel()->applyGrpprlChpx( ret.chp, style, m_styleSheet );
+ return ret;
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/lists.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/lists.h
new file mode 100644
index 00000000..4b108e87
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/lists.h
@@ -0,0 +1,252 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef LISTS_H
+#define LISTS_H
+
+#include <vector>
+#include <utility>
+#include "global.h"
+#include "ustring.h"
+#include "sharedptr.h"
+
+namespace wvWare
+{
+ class STTBF;
+ class OLEStreamReader;
+ class StyleSheet;
+ class ListLevel;
+ class ListData;
+ class ListFormatOverride;
+ class ListFormatOverrideLVL;
+ class ListInfoProvider;
+ namespace Word97
+ {
+ struct FIB;
+ struct PAP;
+ struct CHP;
+ }
+
+ /**
+ * Please refer to the documentation of the ListInfo::text method.
+ */
+ struct ListText
+ {
+ ListText();
+ ~ListText();
+
+ UString text;
+ SharedPtr<Word97::CHP> chp;
+ };
+
+
+ /**
+ * This class provides an abstraction for the list information in
+ * Word6 and Word97 (they are totally different).
+ *
+ * I'm providing a slim API here and there would be some more information
+ * inside the internal structures. Please speak up if you're missing
+ * something, don't try to hack around this artificial limitation (Werner)
+ */
+ class ListInfo
+ {
+ public:
+ ListInfo( Word97::PAP& pap, ListInfoProvider& listInfoProvider );
+
+ /**
+ * The istd linked to the current list/level, istdNil (4095) if none (LSFT::rgistd)
+ */
+ U16 linkedIstd() const { return m_linkedIstd; }
+ /**
+ * Returns whether the list counter should be restarted in new sections. (LSFT::fRestartHdn)
+ */
+ bool restartingCounter() const { return m_restartingCounter; }
+
+ /**
+ * The list starts at this value at the current level (LVLF::iStartAt)
+ */
+ S32 startAt() const { return m_startAt.first; }
+ /**
+ * This flag tells you whether some list format override set a new start value.
+ * If this method returns true you have to restart the counter (initialized
+ * with the startAt value)
+ */
+ bool startAtOverridden() const { return m_startAt.second; }
+ /**
+ * Number format code (see ANLD) (LVLF::nfc)
+ */
+ U8 numberFormat() const { return m_numberFormat; }
+ /**
+ * Alignment of the list number (LVLF::jc)
+ */
+ U8 alignment() const { return m_alignment; }
+ /**
+ * (LVLF::fLegal)
+ */
+ bool isLegal() const { return m_isLegal; }
+ /**
+ * (LVLF::fNoRestart)
+ */
+ bool notRestarted() const { return m_notRestarted; }
+ /**
+ * (LVLF::fPrev)
+ */
+ bool prev() const { return m_prev; }
+ /**
+ * (LVLF::fPrevSpace)
+ */
+ bool prevSpace() const { return m_prevSpace; }
+ /**
+ * (LVLF::fWord6)
+ */
+ bool isWord6() const { return m_isWord6; }
+
+ /**
+ * The most important method, returning the text template and the
+ * corresponding CHP.
+ *
+ * The returned string contains place holders for the real list
+ * counter text. The place holders are the values 0...8, representing
+ * the corresponding list levels (pap->ilvl). To illustrate that,
+ * consider the following example (<0>, <1>,... represent the ASCII
+ * values 0, 1,...):
+ * "<0>.<1>.<2>)"
+ * The <0> should be replaced with the current counter value of level 0,
+ * then we should display a '.', <1> should be the counter value of level 1,
+ * and so forth.
+ *
+ * The CHP provides the character formatting properties; information about
+ * the alignment and optional spaces/tabs after the counter text is
+ * also available here (alignment, followingChar,...)
+ */
+ const ListText& text() const { return m_text; }
+
+ /**
+ * The character following the list number (LVLF::ixchFollow)
+ */
+ U8 followingChar() const { return m_followingChar; }
+
+ /**
+ * In order to help users to detect when a new list starts
+ * we also provide access to the (internal) unique ID of a list.
+ * Returns 0 if it hasn't been initailized.
+ */
+ S32 lsid() const { return m_lsid; }
+
+ /**
+ * Debugging...
+ */
+ void dump() const;
+
+ private:
+ ListInfo& operator=( const ListInfo& rhs );
+
+ U16 m_linkedIstd;
+ bool m_restartingCounter;
+ std::pair<S32, bool> m_startAt;
+ U8 m_numberFormat;
+ U8 m_alignment;
+ bool m_isLegal;
+ bool m_notRestarted;
+ bool m_prev;
+ bool m_prevSpace;
+ bool m_isWord6;
+ ListText m_text;
+ U8 m_followingChar;
+ S32 m_lsid;
+ };
+
+
+ /**
+ * An internal class managing the list information read from the file.
+ * Word versions before 8 don't have any explicit list information in
+ * the table stream, it's just a part of the PAP (and it's way less
+ * powerful). An object of this class will act as proxy for that
+ * information in this case.
+ */
+ class ListInfoProvider
+ {
+ friend class ListInfo;
+ public:
+ /**
+ * This constructor assumes that this is a list info provider
+ * for a Word 6 document. It will just act as a proxy for the information
+ * inside pap.anld. To make that work you have to set the ANLD structure
+ * every time the PAP changes, using setWord6StylePAP()
+ */
+ ListInfoProvider( const StyleSheet* styleSheet );
+ /**
+ * This constructor reads the structures from the table stream of a
+ * Word 97 document.
+ */
+ ListInfoProvider( OLEStreamReader* tableStream, const Word97::FIB& fib, const StyleSheet* styleSheet );
+ ~ListInfoProvider();
+
+ /**
+ * Returns true if the passed ilfo is in a valid range.
+ */
+ bool isValid( S16 ilfo, U8 nLvlAnm ) const;
+
+ private:
+ ListInfoProvider( const ListInfoProvider& rhs );
+ ListInfoProvider& operator=( const ListInfoProvider& rhs );
+
+ /**
+ * @internal
+ * This function tries to get the list information (if any) from the
+ * given PAP. As the list info handling is completely different in Word6
+ * and in Word97 we have one additional level of indirection here (to
+ * keep the user of the library from fighting multiple versions).
+ * In case there's no list information for that paragraph it returns
+ * false.
+ *
+ * Take care, these methods modify the passed PAP structure!!
+ */
+ bool setPAP( Word97::PAP* pap );
+
+ void readListData( OLEStreamReader* tableStream, const U32 endOfLSTF );
+ void readListFormatOverride( OLEStreamReader* tableStream );
+ void readListNames( OLEStreamReader* tableStream );
+ void eatLeading0xff( OLEStreamReader* tableStream );
+
+ void processOverride( ListFormatOverride* lfo );
+ void convertCompatANLD();
+ ListData* findLST( S32 lsid );
+
+ const ListLevel* formattingListLevel() const;
+ std::pair<S32, bool> startAt();
+ ListText text() const;
+
+ std::vector<ListData*> m_listData;
+ std::vector<ListFormatOverride*> m_listFormatOverride;
+ STTBF* m_listNames;
+
+ Word97::PAP* m_pap; // we don't own that one!
+ const StyleSheet* const m_styleSheet; // needed to determine the CHP
+
+ ListFormatOverrideLVL* m_currentLfoLVL;
+ const ListData* m_currentLst;
+
+ // We have to keep track of the version, as Word radically changed
+ // it's way to handle lists from version 7 to 8.
+ const WordVersion m_version;
+ };
+
+} // namespace wvWare
+
+#endif // LISTS_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/olestorage.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/olestorage.cpp
new file mode 100644
index 00000000..48dfdc86
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/olestorage.cpp
@@ -0,0 +1,330 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "olestorage.h"
+#include "olestream.h"
+#include "wvlog.h"
+
+#include <gsf/gsf-input-memory.h>
+#include <gsf/gsf-infile.h>
+#include <gsf/gsf-infile-msole.h>
+#include <gsf/gsf-output-stdio.h>
+#include <gsf/gsf-outfile.h>
+#include <gsf/gsf-outfile-msole.h>
+#include <gsf/gsf-utils.h>
+
+using namespace wvWare;
+
+OLEStorage::OLEStorage() : m_inputFile( 0 ), m_outputFile( 0 ),
+ m_fileName( "" ), m_buffer( 0 ), m_buflen( 0 )
+{
+ // According to Dom it's no problem to call that function multiple times
+ gsf_init();
+}
+
+OLEStorage::OLEStorage( const std::string& fileName ) : m_inputFile( 0 ),
+ m_outputFile( 0 ), m_fileName( fileName ), m_buffer( 0 ), m_buflen( 0 )
+{
+ // According to Dom it's no problem to call that function multiple times
+ gsf_init();
+}
+
+OLEStorage::OLEStorage( const unsigned char* buffer, size_t buflen ) :
+ m_inputFile( 0 ), m_outputFile( 0 ), m_fileName( "" ), m_buffer( buffer ), m_buflen( buflen )
+{
+ // According to Dom it's no problem to call that function multiple times
+ gsf_init();
+}
+
+OLEStorage::~OLEStorage()
+{
+ close(); // just in case
+ // According to Dom it's no problem to call that function multiple times
+ gsf_shutdown();
+}
+
+void OLEStorage::setName( const std::string& fileName )
+{
+ // Don't set a new name if we already have an open storage or a buffer
+ if ( m_inputFile || m_outputFile || m_buffer )
+ return;
+ m_fileName = fileName;
+}
+
+void OLEStorage::setBuffer( const unsigned char* buffer, size_t buflen )
+{
+ // Don't set a new buffer if we already have an open storage or a filename
+ if ( m_inputFile || m_outputFile || !m_fileName.empty() )
+ return;
+ m_buffer = buffer;
+ m_buflen = buflen;
+}
+
+bool OLEStorage::open( Mode mode )
+{
+ // We already have an open storage, return as appropriate
+ if ( m_inputFile && mode == ReadOnly )
+ return true;
+ else if ( m_outputFile && mode == WriteOnly )
+ return true;
+ else if ( m_inputFile || m_outputFile )
+ return false;
+
+ if ( m_fileName.empty() && ( mode == WriteOnly || !m_buffer ) )
+ return false;
+
+ GError* err = 0;
+
+ if ( mode == ReadOnly ) {
+ GsfInput* input;
+ if ( m_buffer )
+ input = GSF_INPUT( gsf_input_memory_new( m_buffer, m_buflen, false ) );
+ else
+ input = GSF_INPUT( gsf_input_mmap_new( m_fileName.c_str(), &err ) );
+
+ if ( !input ) {
+ if ( !err )
+ return false;
+ wvlog << m_fileName << " error: " << err->message << std::endl;
+ g_error_free( err );
+ return false;
+ }
+
+ m_inputFile = GSF_INFILE( gsf_infile_msole_new( input, &err ) );
+ g_object_unref( G_OBJECT( input ) );
+ if ( !m_inputFile ) {
+ if ( !err )
+ return false;
+ wvlog << m_fileName << " Not an OLE file: " << err->message << std::endl;
+ g_error_free( err );
+ return false;
+ }
+ }
+ else {
+ GsfOutput* output = GSF_OUTPUT( gsf_output_stdio_new( m_fileName.c_str(), &err ) );
+ if ( !output ) {
+ if ( !err )
+ return false;
+ wvlog << m_fileName << " error: " << err->message << std::endl;
+ g_error_free( err );
+ return false;
+ }
+
+ m_outputFile = GSF_OUTFILE( gsf_outfile_msole_new( output ) );
+ g_object_unref( G_OBJECT(output) );
+ }
+ return true;
+}
+
+void OLEStorage::close()
+{
+ // check if we still have some open streams and close them properly
+ std::list<OLEStream*>::const_iterator it = m_streams.begin();
+ std::list<OLEStream*>::const_iterator end = m_streams.end();
+ while ( it != end ) {
+ OLEStream* stream( *it );
+ ++it; // first advance the iterator, as the stream will remove itself from the list
+ delete stream;
+ wvlog << "Warning: Closing a stream you didn't delete." << std::endl;
+ }
+ m_streams.clear(); // should be a no-op
+
+ if ( m_inputFile ) {
+ g_object_unref( G_OBJECT( m_inputFile ) );
+ m_inputFile = 0;
+ }
+
+ if ( m_outputFile ) {
+ gsf_output_close( reinterpret_cast<GsfOutput*>( m_outputFile ) );
+ g_object_unref( G_OBJECT( m_outputFile ) );
+ m_outputFile = 0;
+ }
+}
+
+bool OLEStorage::isValid() const
+{
+ return m_inputFile || m_outputFile;
+}
+
+std::list<std::string> OLEStorage::listDirectory()
+{
+ std::list<std::string> ret;
+
+ if ( m_outputFile || !m_inputFile ) // outfiles don't seem to support that feature :-(
+ return ret;
+
+ GsfInfile* currentDir( m_inputFile );
+ if ( !m_path.empty() )
+ currentDir = m_path.back().infile;
+
+ int numChildren = gsf_infile_num_children( currentDir );
+ for ( int i = 0; i < numChildren; ++i ) {
+ GsfInput* entry( gsf_infile_child_by_index( currentDir, i ) );
+ const char* name( gsf_input_name( entry ) );
+ ret.push_back( name != 0 ? name : "[unnamed]" );
+ g_object_unref( G_OBJECT( entry ) );
+ }
+ return ret;
+}
+
+bool OLEStorage::enterDirectory( const std::string& directory )
+{
+ if ( m_inputFile ) {
+ GsfInfile* currentDir( m_inputFile );
+ if ( !m_path.empty() )
+ currentDir = m_path.back().infile;
+
+ GsfInput* dir( gsf_infile_child_by_name( currentDir, directory.c_str() ) );
+
+ if ( dir && GSF_IS_INFILE( dir ) &&
+ gsf_infile_num_children( GSF_INFILE( dir ) ) >= 0 ) {
+ m_path.push_back( GSF_INFILE( dir ) );
+ return true;
+ }
+ }
+ else if ( m_outputFile ) {
+ GsfOutfile* currentDir( m_outputFile );
+ if ( !m_path.empty() )
+ currentDir = m_path.back().outfile;
+
+ GsfOutput* newDir( gsf_outfile_new_child( currentDir, directory.c_str(), TRUE ) );
+ if ( newDir ) {
+ m_path.push_back( GSF_OUTFILE( newDir ) );
+ return true;
+ }
+ }
+ return false; // no file opened
+}
+
+void OLEStorage::leaveDirectory()
+{
+ if ( !m_path.empty() ) {
+ if ( m_inputFile )
+ g_object_unref( G_OBJECT( m_path.back().infile ) );
+ else if ( m_outputFile ) {
+ gsf_output_close( reinterpret_cast<GsfOutput*>( m_path.back().outfile ) );
+ g_object_unref( G_OBJECT( m_path.back().outfile ) );
+ }
+ m_path.pop_back();
+ }
+}
+
+bool OLEStorage::setPath( const std::string& path )
+{
+ // Save the old path
+ std::deque<Directory> oldPath;
+ oldPath.swap( m_path );
+
+ std::string tmp;
+ std::string::size_type start = 1, end = 0;
+ bool success = true;
+
+ if ( path[ 0 ] != '/' )
+ start = 0;
+
+ while ( start < path.length() && success ) {
+ end = path.find_first_of( '/', start );
+ if ( end != std::string::npos ) {
+ tmp = path.substr( start, end - start );
+ start = end + 1;
+ }
+ else {
+ tmp = path.substr( start );
+ start = std::string::npos;
+ }
+ if ( !enterDirectory( tmp ) )
+ success = false;
+ }
+
+ // If we were successful, we save the current m_path in
+ // the oldPath, and free m_path using leaveDirectory
+ if ( success )
+ oldPath.swap( m_path );
+ while ( !m_path.empty() )
+ leaveDirectory();
+
+ // Now restore the correct path in m_path
+ oldPath.swap( m_path );
+ return success;
+}
+
+std::string OLEStorage::path() const
+{
+ std::deque<Directory>::const_iterator it( m_path.begin() );
+ std::deque<Directory>::const_iterator end( m_path.end() );
+ std::string p( "/" );
+ for ( ; it != end; ++it ) {
+ const char* name = 0;
+ if ( m_inputFile )
+ name = gsf_input_name( GSF_INPUT( ( *it ).infile ) ); // it->infile doesn't work with gcc 2.95.2
+ else if ( m_outputFile )
+ name = gsf_output_name( GSF_OUTPUT( ( *it ).outfile ) ); // it->outfile doesn't work with gcc 2.95.2
+
+ if ( name ) {
+ p.append( name );
+ p.push_back( '/' );
+ }
+ }
+ return p;
+}
+
+OLEStreamReader* OLEStorage::createStreamReader( const std::string& stream )
+{
+ if ( !m_inputFile )
+ return 0;
+
+ GsfInfile* currentDir( m_inputFile );
+ if ( !m_path.empty() )
+ currentDir = m_path.back().infile;
+ GsfInput* input( gsf_infile_child_by_name( currentDir, stream.c_str() ) );
+
+ if ( !input )
+ return 0;
+
+ OLEStreamReader* reader( new OLEStreamReader( input, this ) );
+ m_streams.push_back( reader );
+ return reader;
+}
+
+OLEStreamWriter* OLEStorage::createStreamWriter( const std::string& stream )
+{
+ if ( !m_outputFile )
+ return 0;
+ // Don't try to confuse our highly intelligent path system :p
+ if ( stream.find('/') != std::string::npos ) {
+ wvlog << "Warning: You tried to create a stream with a '/' in its name." << std::endl;
+ return 0;
+ }
+
+ GsfOutfile* currentDir( m_outputFile );
+ if ( !m_path.empty() )
+ currentDir = m_path.back().outfile;
+ GsfOutput* output( gsf_outfile_new_child( currentDir, stream.c_str(), FALSE ) );
+
+ if ( !output )
+ return 0;
+
+ OLEStreamWriter* writer( new OLEStreamWriter( output, this ) );
+ m_streams.push_back( writer );
+ return writer;
+}
+
+void OLEStorage::streamDestroyed( OLEStream* stream )
+{
+ m_streams.remove( stream );
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/olestorage.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/olestorage.h
new file mode 100644
index 00000000..d268a52d
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/olestorage.h
@@ -0,0 +1,193 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef OLESTORAGE_H
+#define OLESTORAGE_H
+
+#include <string>
+#include <list>
+#include <deque>
+
+#include <gsf/gsf.h>
+
+namespace wvWare
+{
+
+class OLEStream;
+class OLEStreamReader;
+class OLEStreamWriter;
+
+class OLEStorage
+{
+ friend class OLEStream;
+public:
+ /**
+ * The mode of the storage. libgsf doesn't support storages opened
+ * for reading and writing like libole2 did.
+ */
+ enum Mode { ReadOnly, WriteOnly };
+
+ /**
+ * Create an "empty" storage
+ */
+ OLEStorage();
+ /**
+ * Specify a name for the storage. Note: It will *not* be opened
+ * right now, call @see open() to do that
+ */
+ OLEStorage( const std::string& fileName );
+ /**
+ * Specify a buffer for the storage. The OLE storage will be read
+ * from that buffer. We don't take ownership of the buffer.
+ * Note: Only for ReadOnly mode!
+ */
+ OLEStorage( const unsigned char* buffer, size_t buflen );
+ /**
+ * Destroy the current storage. Open streams on it will
+ * be synced and written back.
+ */
+ ~OLEStorage();
+
+ /**
+ * Specify a name for the storage (file)
+ * This is a no-op if a storage is already open!
+ */
+ void setName( const std::string& fileName );
+ /**
+ * Get the name of the OLE storage file
+ */
+ std::string name() const { return m_fileName; }
+
+ /**
+ * Specify a buffer for the storage. The OLE storage will be read
+ * from that buffer. We don't take ownership of the buffer.
+ * Note: Only for ReadOnly mode!
+ */
+ void setBuffer( const unsigned char* buffer, size_t buflen );
+
+ /**
+ * Open the specified storage for reading or writing.
+ * Opening a storage twice won't do any harm.
+ * @return true if opening was successful
+ */
+ bool open( Mode mode );
+
+ /**
+ * Closes the current storage (no-op if we don't have one ;)
+ * This method also tries to close/sync all the open streams.
+ * Closing a storage twice won't do any harm.
+ */
+ void close();
+
+ /**
+ * Any problems with the current storage?
+ */
+ bool isValid() const;
+
+ /**
+ * Returns a list containing all the files and dirs at the
+ * current position in the VFS. The std::strings are UTF-8
+ * encoded.
+ * Only works in ReadOnly mode, gsf doesn't support reading
+ * the directory structure of WriteOnly storages.
+ */
+ std::list<std::string> listDirectory();
+
+ /**
+ * Enters a specific subdirectory. If the specified directory
+ * doesn't exist this method returns false. The passed string
+ * has to be UTF-8 encoded.
+ */
+ bool enterDirectory( const std::string& directory );
+ /**
+ * One level up (cd ..)
+ */
+ void leaveDirectory();
+
+ /**
+ * Manipulate the path directly. If the operation fails at some
+ * point the path will be set back to the previous location.
+ */
+ bool setPath( const std::string& path );
+ /**
+ * Get the current path (UTF-8 encoded)
+ */
+ std::string path() const;
+
+ /**
+ * Opens the specified stream for reading and passes the
+ * opened stream reader back. Returns 0 if it didn't work,
+ * e.g. if the storage is opened in WriteOnly mode.
+ * Note: The ownership is transferred to you!
+ */
+ OLEStreamReader* createStreamReader( const std::string& stream );
+
+ /**
+ * Opens a stream for writing (you get 0 if it failed, e.g. if
+ * the storage is in ReadOnly mode).
+ * Note: The ownership is transferred to you!
+ * Note2: Don't try to pass names with a '/' in it :)
+ */
+ OLEStreamWriter* createStreamWriter( const std::string& stream );
+
+private:
+ /**
+ * we don't want to allow copying
+ */
+ OLEStorage( const OLEStorage& rhs );
+ /**
+ * we don't want to allow assigning
+ */
+ OLEStorage& operator=( const OLEStorage& rhs );
+
+ /**
+ * This method is called from the stream's DTOR
+ */
+ void streamDestroyed( OLEStream* stream );
+
+ // One of those members will be 0, we only use one of them,
+ // due to the libgsf design...
+ GsfInfile* m_inputFile;
+ GsfOutfile* m_outputFile;
+
+ std::string m_fileName;
+
+ const unsigned char* m_buffer;
+ size_t m_buflen;
+
+ union Directory
+ {
+ Directory( GsfInfile* in ) : infile( in ) {}
+ Directory( GsfOutfile* out ) : outfile( out ) {}
+
+ GsfInfile* infile;
+ GsfOutfile* outfile;
+ };
+ std::deque<Directory> m_path;
+
+ /**
+ * We're not the owner, but we still keep track of all
+ * the streams for bookkeeping issues. If the user forgets
+ * to delete the OLEStreams we do it on closing.
+ */
+ std::list<OLEStream*> m_streams;
+};
+
+} // namespace wvWare
+
+#endif // OLESTORAGE_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/olestream.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/olestream.cpp
new file mode 100644
index 00000000..8f8f03fd
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/olestream.cpp
@@ -0,0 +1,414 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "olestream.h"
+#include "wvlog.h"
+
+#include <stdio.h> // FILE,...
+
+#include <gsf/gsf-input.h>
+#include <gsf/gsf-output.h>
+#include <gsf/gsf-input-memory.h>
+#include <gsf/gsf-msole-utils.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+using namespace wvWare;
+
+OLEStream::OLEStream( OLEStorage* storage ) : m_storage( storage )
+{
+}
+
+OLEStream::~OLEStream()
+{
+ if ( m_storage )
+ m_storage->streamDestroyed( this );
+}
+
+void OLEStream::push()
+{
+ m_positions.push( tell() );
+}
+
+bool OLEStream::pop()
+{
+ if ( m_positions.empty() )
+ return false;
+ seek( m_positions.top(), G_SEEK_SET );
+ m_positions.pop();
+ return true;
+}
+
+
+OLEStreamReader::OLEStreamReader( GsfInput* stream, OLEStorage* storage ) :
+ OLEStream( storage ), m_stream( stream )
+{
+}
+
+OLEStreamReader::~OLEStreamReader()
+{
+ if ( m_stream )
+ g_object_unref( G_OBJECT( m_stream ) );
+}
+
+bool OLEStreamReader::isValid() const
+{
+ return m_stream;
+}
+
+bool OLEStreamReader::seek( int offset, GSeekType whence )
+{
+ return gsf_input_seek( m_stream, offset, whence ) == 0;
+}
+
+int OLEStreamReader::tell() const
+{
+#ifdef WV2_CHECKING
+ if ( !m_stream )
+ return -1;
+#endif
+ return gsf_input_tell( m_stream );
+}
+
+size_t OLEStreamReader::size() const
+{
+#ifdef WV2_CHECKING
+ if ( !m_stream )
+ return 0;
+#endif
+ return gsf_input_size( m_stream );
+}
+
+OLEStreamReader* OLEStreamReader::inflate( int offset ) const
+{
+ //call the inflate function
+ wvlog << "calling gsf_msole_inflate with offset of ... " << offset;
+ GByteArray* gbArray = gsf_msole_inflate( m_stream, offset );
+ wvlog << " got " << gbArray->len << " decompressed bytes." << std::endl;
+ //transform it to an unsigned char* buffer (better way to do this?)
+ unsigned char* buffer = new unsigned char [gbArray->len];
+ for ( int i = 0; i < gbArray->len; i++ ) {
+ wvlog << (unsigned int) gbArray->data[i];
+ buffer[i] = (unsigned char) gbArray->data[i];
+ }
+ //create storage
+ /*OLEStorage store( buffer, gbArray->len );
+ if ( !store.open( OLEStorage::ReadOnly ) )
+ wvlog << "Couldn't open OLEStorage." << std::endl;
+ //now get a stream reader
+ OLEStreamReader* reader = store.createStreamReader("");
+ */
+ //create gsfinput
+ GsfInput* input = GSF_INPUT( gsf_input_memory_new( buffer, gbArray->len, false ) );
+ //create an OLEStreamReader from that
+ OLEStreamReader* reader = new OLEStreamReader( input, 0 );
+ //free memory
+ g_byte_array_free (gbArray, TRUE);
+ delete[] buffer;
+ //store.close();
+
+ //return the OLEStreamReader
+ return reader;
+}
+
+U8 OLEStreamReader::readU8()
+{
+#ifdef WV2_CHECKING
+ if ( !m_stream )
+ return 0;
+#endif
+
+ U8 ret;
+ gsf_input_read( m_stream, sizeof( ret ), static_cast<guint8*>( &ret ) );
+ return ret;
+}
+
+S8 OLEStreamReader::readS8()
+{
+ return static_cast<S8>( readU8() );
+}
+
+U16 OLEStreamReader::readU16()
+{
+#ifdef WV2_CHECKING
+ if ( !m_stream )
+ return 0;
+#endif
+
+#if defined(WORDS_BIGENDIAN)
+ // Please take care when "optimizing" that and read
+ // http://gcc.gnu.org/ml/gcc-bugs/2000-12/msg00429.html
+ // and http://www.eskimo.com/~scs/C-faq/q3.8.html
+ U16 tmp1 = readU8();
+ U16 tmp2 = readU8();
+ return ( tmp2 << 8 ) | tmp1;
+#else
+ U16 ret;
+ gsf_input_read( m_stream, sizeof( ret ), reinterpret_cast<guint8*>( &ret ) );
+ return ret;
+#endif
+}
+
+S16 OLEStreamReader::readS16()
+{
+ return static_cast<S16>( readU16() );
+}
+
+U32 OLEStreamReader::readU32()
+{
+#ifdef WV2_CHECKING
+ if ( !m_stream )
+ return 0;
+#endif
+
+#if defined(WORDS_BIGENDIAN)
+ // Please take care when "optimizing" that and read
+ // http://gcc.gnu.org/ml/gcc-bugs/2000-12/msg00429.html
+ // and http://www.eskimo.com/~scs/C-faq/q3.8.html
+ U32 tmp1 = readU16();
+ U32 tmp2 = readU16();
+ return ( tmp2 << 16 ) | tmp1;
+#else
+ U32 ret;
+ gsf_input_read( m_stream, sizeof( ret ), reinterpret_cast<guint8*>( &ret ) );
+ return ret;
+#endif
+}
+
+S32 OLEStreamReader::readS32()
+{
+ return static_cast<S32>( readU32() );
+}
+
+bool OLEStreamReader::read( U8 *buffer, size_t length )
+{
+#ifdef WV2_CHECKING
+ if ( !m_stream )
+ return false;
+#endif
+ return gsf_input_read( m_stream, length, buffer ) != 0;
+}
+
+void OLEStreamReader::dumpStream( const std::string& fileName )
+{
+ push();
+ seek( 0, G_SEEK_SET );
+
+ FILE* myFile = fopen( fileName.c_str(), "w" );
+ if ( !myFile ) {
+ pop();
+ return;
+ }
+
+ const size_t buflen = 1024;
+ char buffer[ buflen ];
+ size_t remaining = size();
+ size_t length;
+
+ while ( remaining ) {
+ length = remaining > buflen ? buflen : remaining;
+ remaining -= length;
+ if ( gsf_input_read( m_stream, length, reinterpret_cast<guint8*>( buffer ) ) )
+ fwrite( buffer, 1, length, myFile );
+ }
+
+ fclose( myFile );
+ pop();
+}
+
+
+OLEImageReader::OLEImageReader( OLEStreamReader& reader, unsigned int start, unsigned int limit ) :
+ m_reader( reader ), m_start( start ), m_limit( limit ), m_position( start )
+{
+ if ( limit <= start )
+ wvlog << "Error: The passed region is empty." << std::endl;
+}
+
+OLEImageReader::OLEImageReader( const OLEImageReader& rhs ) : m_reader( rhs.m_reader ), m_start( rhs.m_start ),
+ m_limit( rhs.m_limit ), m_position( rhs.m_position )
+{
+}
+
+OLEImageReader::~OLEImageReader()
+{
+ // nothing to do
+}
+
+bool OLEImageReader::isValid() const
+{
+ return m_reader.isValid() && m_position >= m_start && m_position < m_limit;
+}
+
+bool OLEImageReader::seek( int offset, GSeekType whence )
+{
+ switch( whence ) {
+ case G_SEEK_CUR:
+ return updatePosition( m_position + offset );
+ case G_SEEK_SET:
+ return updatePosition( offset );
+ case G_SEEK_END:
+ return updatePosition( m_limit - 1 + offset );
+ default:
+ wvlog << "Error: Unknown GSeekType!" << std::endl;
+ return false;
+ }
+}
+
+int OLEImageReader::tell() const
+{
+ return static_cast<int>( m_position );
+}
+
+size_t OLEImageReader::size() const
+{
+ return m_limit - m_start;
+}
+
+size_t OLEImageReader::read( U8 *buffer, size_t length )
+{
+ m_reader.push();
+ if ( !m_reader.seek( m_position, G_SEEK_SET ) ) {
+ m_reader.pop();
+ return 0;
+ }
+
+ size_t bytesRead = ( m_limit - m_position ) < length ? m_limit - m_position : length;
+ if ( !m_reader.read( buffer, bytesRead ) ) {
+ m_reader.pop();
+ return 0;
+ }
+ //have to update our position in the stream
+ unsigned int newpos = m_position + (unsigned int) bytesRead;
+ wvlog << "new position is " << newpos << std::endl;
+ if ( !updatePosition( newpos ) )
+ wvlog << "error updating position in stream" << std::endl;
+ m_reader.pop();
+ return bytesRead;
+}
+
+bool OLEImageReader::updatePosition( unsigned int position )
+{
+ if ( m_start <= position && position < m_limit ) {
+ m_position = position;
+ return true;
+ }
+ return false;
+}
+
+
+OLEStreamWriter::OLEStreamWriter( GsfOutput* stream, OLEStorage* storage ) :
+ OLEStream( storage ), m_stream( stream )
+{
+}
+
+OLEStreamWriter::~OLEStreamWriter()
+{
+ if ( m_stream ) {
+ gsf_output_close( m_stream );
+ g_object_unref( G_OBJECT( m_stream ) );
+ }
+}
+
+bool OLEStreamWriter::isValid() const
+{
+ return m_stream;
+}
+
+bool OLEStreamWriter::seek( int offset, GSeekType whence )
+{
+ return gsf_output_seek( m_stream, offset, whence ) == 0;
+}
+
+int OLEStreamWriter::tell() const
+{
+#ifdef WV2_CHECKING
+ if ( !m_stream )
+ return -1;
+#endif
+ return gsf_output_tell( m_stream );
+}
+
+size_t OLEStreamWriter::size() const
+{
+#ifdef WV2_CHECKING
+ if ( !m_stream )
+ return 0;
+#endif
+ return gsf_output_size( m_stream );
+}
+
+void OLEStreamWriter::write( U8 data )
+{
+#ifdef WV2_CHECKING
+ if ( !m_stream )
+ return;
+#endif
+ gsf_output_write( m_stream, sizeof( data ), &data );
+}
+
+void OLEStreamWriter::write( S8 data )
+{
+ write( static_cast<U8>( data ) );
+}
+
+void OLEStreamWriter::write( U16 data )
+{
+#ifdef WV2_CHECKING
+ if ( !m_stream )
+ return;
+#endif
+ U16 copy = toLittleEndian( data );
+ gsf_output_write( m_stream, sizeof( copy ), reinterpret_cast<guint8 *>( &copy ) );
+}
+
+void OLEStreamWriter::write( S16 data )
+{
+ write( static_cast<U16>( data ) );
+}
+
+void OLEStreamWriter::write( U32 data )
+{
+#ifdef WV2_CHECKING
+ if ( !m_stream )
+ return;
+#endif
+ U32 copy = toLittleEndian( data );
+ gsf_output_write( m_stream, sizeof( copy ), reinterpret_cast<guint8 *>( &copy ) );
+}
+
+void OLEStreamWriter::write( S32 data )
+{
+ write( static_cast<U32>( data ) );
+}
+
+void OLEStreamWriter::write( U8* data, size_t length )
+{
+#ifdef WV2_CHECKING
+ if ( !m_stream )
+ return;
+#endif
+ gsf_output_write( m_stream, length, data );
+}
+
+GsfOutput* OLEStreamWriter::getGsfStream()
+{
+ return m_stream;
+}
+
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/olestream.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/olestream.h
new file mode 100644
index 00000000..559288b9
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/olestream.h
@@ -0,0 +1,307 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef OLESTREAM_H
+#define OLESTREAM_H
+
+#include "olestorage.h"
+#include "global.h" // U8,... typedefs
+#include <stack>
+
+#include <glib/giochannel.h> // GSeekType
+
+namespace wvWare {
+
+class OLEStream
+{
+public:
+ /**
+ * Create an OLE stream
+ */
+ OLEStream( OLEStorage* storage );
+ virtual ~OLEStream();
+
+ /**
+ * Is this still a valid stream?
+ */
+ virtual bool isValid() const = 0;
+
+ /**
+ * works like plain fseek
+ */
+ virtual bool seek( int offset, GSeekType whence = G_SEEK_SET ) = 0;
+ /**
+ * works like plain ftell
+ */
+ virtual int tell() const = 0;
+ /**
+ * The size of the stream
+ */
+ virtual size_t size() const = 0;
+
+ /**
+ * Push the current offset on the stack
+ */
+ void push();
+ /**
+ * Pop the topmost position (false if the stack was empty)
+ */
+ bool pop();
+
+private:
+ /**
+ * we don't want to allow copying and assigning streams
+ */
+ OLEStream( const OLEStream& rhs );
+ /**
+ * we don't want to allow copying and assigning streams
+ */
+ OLEStream& operator=( const OLEStream& rhs );
+
+ std::stack<int> m_positions;
+ /**
+ * for bookkeeping :}
+ */
+ OLEStorage *m_storage;
+};
+
+
+class OLEStreamReader : public OLEStream
+{
+public:
+ OLEStreamReader( GsfInput* stream, OLEStorage* storage );
+ virtual ~OLEStreamReader();
+
+ /**
+ * Is this still a valid stream?
+ */
+ virtual bool isValid() const;
+
+ /**
+ * works like plain fseek
+ */
+ virtual bool seek( int offset, GSeekType whence = G_SEEK_SET );
+ /**
+ * works like plain ftell
+ */
+ virtual int tell() const;
+ /**
+ * The size of the stream
+ */
+ virtual size_t size() const;
+ /**
+ * decompress LZ compress bits in a stream
+ * and return a new OLEStreamReader with the data
+ */
+ virtual OLEStreamReader* inflate( int offset ) const;
+
+ /**
+ * Reading from the current position
+ * Note: Modifies the current position!
+ * All the read methods are endian-aware and convert
+ * the contents from the file if necessary
+ */
+ U8 readU8();
+ /**
+ * @see readU8()
+ */
+ S8 readS8();
+ /**
+ * @see readU8()
+ */
+ U16 readU16();
+ /**
+ * @see readU8()
+ */
+ S16 readS16();
+ /**
+ * @see readU8()
+ */
+ U32 readU32();
+ /**
+ * @see readU8()
+ */
+ S32 readS32();
+
+ /**
+ * Reads a bunch of bytes w/o endian conversion to the
+ * given buffer, at most length bytes.
+ * Returns true on success
+ */
+ bool read( U8 *buffer, size_t length );
+
+ /**
+ * For debugging
+ */
+ void dumpStream( const std::string& fileName );
+
+private:
+ // we don't want to allow copying and assigning streams
+ OLEStreamReader( const OLEStreamReader& rhs );
+ OLEStreamReader& operator=( const OLEStreamReader& rhs );
+
+ GsfInput* m_stream;
+};
+
+
+/**
+ * OLEImageReader provides bounds-checked access to a stream.
+ * Objects of this class are used to safely provide image data to
+ * the consumer.
+ * It doesn't actually own an OLE stream, it just wraps the access
+ * to the real data stream. In that wrapper code it also performs
+ * the bounds checking.
+ * Note that this stream class, unlike the other two classes, doesn't
+ * fix the endianness of the data!
+ */
+class OLEImageReader
+{
+public:
+ /**
+ * Constructs a limited reader which is only allowed to read the passed
+ * OLEStreamReader from start up to, but not including, limit.
+ */
+ OLEImageReader( OLEStreamReader& reader, unsigned int start, unsigned int limit );
+ OLEImageReader( const OLEImageReader& rhs );
+
+ ~OLEImageReader();
+
+ /**
+ * Is this still a valid stream?
+ */
+ bool isValid() const;
+
+ /**
+ * Works like plain fseek, with the limitation of the defined region.
+ */
+ bool seek( int offset, GSeekType whence = G_SEEK_SET );
+ /**
+ * Works like plain ftell
+ */
+ int tell() const;
+ /**
+ * The size of the region that's available to the user of this class.
+ */
+ size_t size() const;
+
+ /**
+ * Reads a bunch of bytes w/o endian conversion to the
+ * given buffer, at most length bytes. The position in the stream
+ * is changed, too.
+ * Returns the number of bytes read.
+ */
+ size_t read( U8 *buffer, size_t length );
+
+private:
+ // It doesn't make sense to assign them (copying is fine, though)
+ OLEImageReader& operator=( const OLEImageReader& rhs );
+
+ // Updates the position, if it's valid. Returns false if the passed
+ // position is out of the range.
+ bool updatePosition( unsigned int position );
+
+ OLEStreamReader& m_reader;
+ const unsigned int m_start;
+ const unsigned int m_limit;
+
+ // Keeps track of the "virtual" position. We aren't allowed
+ // to change the state of the real stream, so we have to push/pop
+ // the real position every time one of the OLEImageReader methods
+ // is called. We want to fake a consistent internal state, though,
+ // so we have to remember the "virtual" position here.
+ // Initialized with the m_start value.
+ unsigned int m_position;
+};
+
+
+class OLEStreamWriter : public OLEStream
+{
+public:
+ OLEStreamWriter( GsfOutput* stream, OLEStorage* storage );
+ virtual ~OLEStreamWriter();
+
+ /**
+ * Is this still a valid stream?
+ */
+ virtual bool isValid() const;
+
+ /**
+ * works like plain fseek
+ */
+ virtual bool seek( int offset, GSeekType whence = G_SEEK_SET );
+ /**
+ * works like plain ftell
+ */
+ virtual int tell() const;
+ /**
+ * The size of the stream
+ */
+ virtual size_t size() const;
+
+ /**
+ * Writing to the current position
+ * Note: Modifies the current position!
+ * These write methods are endian-aware
+ * and convert the contents to be LE in the file
+ */
+ void write( U8 data );
+ /**
+ * @see write(U8 data)
+ */
+ void write( S8 data );
+ /**
+ * @see write(U8 data)
+ */
+ void write( U16 data );
+ /**
+ * @see write(U8 data)
+ */
+ void write( S16 data );
+ /**
+ * @see write(U8 data)
+ */
+ void write( U32 data );
+ /**
+ * @see write(U8 data)
+ */
+ void write( S32 data );
+
+ /**
+ * Attention: This write method just writes out the
+ * contents of the memory directly (w/o converting
+ * to little-endian first!)
+ */
+ void write( U8* data, size_t length );
+
+ /**
+ * give access to GSF stream
+ * probably should find another way of doing this
+ */
+ GsfOutput* getGsfStream();
+
+private:
+ // we don't want to allow copying and assigning streams
+ OLEStreamWriter( const OLEStreamWriter& rhs );
+ OLEStreamWriter& operator=( const OLEStreamWriter& rhs );
+
+ GsfOutput* m_stream;
+};
+
+} // namespace wvWare
+
+#endif // OLESTREAM_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/paragraphproperties.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/paragraphproperties.cpp
new file mode 100644
index 00000000..9c68094b
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/paragraphproperties.cpp
@@ -0,0 +1,65 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "paragraphproperties.h"
+#include "lists.h"
+
+using namespace wvWare;
+
+ParagraphProperties::ParagraphProperties() : m_listInfo( 0 )
+{
+}
+
+ParagraphProperties::ParagraphProperties( const Word97::PAP& pap ) :
+ m_pap( pap ), m_listInfo( 0 )
+{
+}
+
+ParagraphProperties::ParagraphProperties( const ParagraphProperties& rhs ) :
+ Shared( rhs ), m_pap( rhs.pap() ), m_listInfo( 0 )
+{
+ if ( rhs.listInfo() )
+ m_listInfo = new ListInfo( *rhs.listInfo() );
+}
+
+ParagraphProperties::~ParagraphProperties()
+{
+ delete m_listInfo;
+}
+
+Word97::PAP& ParagraphProperties::pap()
+{
+ return m_pap;
+}
+
+const Word97::PAP& ParagraphProperties::pap() const
+{
+ return m_pap;
+}
+
+const ListInfo* ParagraphProperties::listInfo() const
+{
+ return m_listInfo;
+}
+
+void ParagraphProperties::createListInfo( ListInfoProvider& listInfoProvider )
+{
+ if ( m_listInfo || !listInfoProvider.isValid( m_pap.ilfo, m_pap.nLvlAnm ) )
+ return;
+ m_listInfo = new ListInfo( m_pap, listInfoProvider );
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/paragraphproperties.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/paragraphproperties.h
new file mode 100644
index 00000000..3ff2d7bf
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/paragraphproperties.h
@@ -0,0 +1,67 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef PARAGRAPHPROPERTIES_H
+#define PARAGRAPHPROPERTIES_H
+
+#include "word97_generated.h"
+
+namespace wvWare
+{
+
+ class ListInfo;
+ class ListInfoProvider;
+
+ /**
+ * A tiny helper class to wrap the PAP and any additional information
+ * we want to pass to the consumer. Right now we have a ListInfo object
+ * if the paragraph belongs to some list.
+ */
+ class ParagraphProperties : public Shared
+ {
+ public:
+ ParagraphProperties();
+ explicit ParagraphProperties( const Word97::PAP& pap );
+ ParagraphProperties( const ParagraphProperties& rhs );
+ ~ParagraphProperties();
+
+ Word97::PAP& pap();
+ const Word97::PAP& pap() const;
+ /**
+ * If this paragraph belongs to a list, the ListInfo object will be
+ * valid and contain useful information about the formatting of the
+ * list counter. If the paragraph is not inside a list, this method
+ * will return 0.
+ */
+ const ListInfo* listInfo() const;
+
+ /**
+ * @internal
+ */
+ void createListInfo( ListInfoProvider& listInfoProvider );
+
+ private:
+ ParagraphProperties& operator=( const ParagraphProperties& rhs );
+
+ Word97::PAP m_pap;
+ ListInfo* m_listInfo;
+ };
+
+} // namespace wvWare
+
+#endif // PARAGRAPHPROPERTIES_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/parser.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/parser.cpp
new file mode 100644
index 00000000..863ba743
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/parser.cpp
@@ -0,0 +1,88 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "parser.h"
+#include "olestream.h"
+#include "handlers.h"
+
+using namespace wvWare;
+
+Parser::Parser( OLEStorage* storage, OLEStreamReader* wordDocument ) :
+ m_inlineHandler( new InlineReplacementHandler ), m_subDocumentHandler( new SubDocumentHandler ),
+ m_tableHandler( new TableHandler ), m_pictureHandler( new PictureHandler ),
+ m_textHandler( new TextHandler ), m_ourInlineHandler( true ), m_ourSubDocumentHandler( true ),
+ m_ourTableHandler( true ), m_ourPictureHandler( true ), m_ourTextHandler( true ),
+ m_storage( storage ), m_wordDocument( wordDocument ), m_okay( true )
+{
+ if ( !storage || !wordDocument ) {
+ m_okay = false;
+ return;
+ }
+
+ // Let the "real" constructor find out which additional
+ // streams it needs, as only it knows the FIB!
+}
+
+Parser::~Parser()
+{
+ // In case we're still using the default handlers we have
+ // to clean them up. Messy, but we shouldn't use some smart
+ // pointer here, as it's very restrictive for the user of
+ // this library (std::auto_ptr would make it impossible to
+ // use MI, SharedPtr would potentially lead to circular references).
+ if ( m_ourInlineHandler )
+ delete m_inlineHandler;
+ if ( m_ourSubDocumentHandler )
+ delete m_subDocumentHandler;
+ if ( m_ourTableHandler )
+ delete m_tableHandler;
+ if ( m_ourPictureHandler )
+ delete m_pictureHandler;
+ if ( m_ourTextHandler )
+ delete m_textHandler;
+
+ // Don't forget to close everything properly here
+ delete m_wordDocument;
+ m_storage->close();
+ delete m_storage;
+}
+
+void Parser::setInlineReplacementHandler( InlineReplacementHandler* handler )
+{
+ setHandler<InlineReplacementHandler>( handler, &m_inlineHandler, m_ourInlineHandler );
+}
+
+void Parser::setSubDocumentHandler( SubDocumentHandler* handler )
+{
+ setHandler<SubDocumentHandler>( handler, &m_subDocumentHandler, m_ourSubDocumentHandler );
+}
+
+void Parser::setTableHandler( TableHandler* handler )
+{
+ setHandler<TableHandler>( handler, &m_tableHandler, m_ourTableHandler );
+}
+
+void Parser::setPictureHandler( PictureHandler* handler )
+{
+ setHandler<PictureHandler>( handler, &m_pictureHandler, m_ourPictureHandler );
+}
+
+void Parser::setTextHandler( TextHandler* handler )
+{
+ setHandler<TextHandler>( handler, &m_textHandler, m_ourTextHandler );
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/parser.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/parser.h
new file mode 100644
index 00000000..9e87aa1e
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/parser.h
@@ -0,0 +1,170 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef PARSER_H
+#define PARSER_H
+
+#include "sharedptr.h"
+#include "global.h"
+
+namespace wvWare
+{
+
+// This ensures that we return the correct FIB :)
+// Note: The guy implementing Word95 support also has to return such
+// a Word97 FIB (as for most of the other important structures)!
+// We will create the conversion code with a script (at least those
+// parts of it which are easy to map)
+namespace Word97
+{
+struct FIB;
+struct DOP;
+struct SEP;
+struct FFN;
+struct STTBF;
+}
+
+class InlineReplacementHandler;
+class SubDocumentHandler;
+class TableHandler;
+class PictureHandler;
+class TextHandler;
+class OLEStorage;
+class OLEStreamReader;
+class StyleSheet;
+class AssociatedStrings;
+
+class WV2_DLLEXPORT Parser : public Shared
+{
+public:
+ /**
+ * This enum is needed to keep track of the parsing state. We e.g. have to
+ * handle footnote references differently while parsing footnotes. It's a bit
+ * hacky, but needed.
+ */
+ enum SubDocument { None, Main, Footnote, Header, Macro, Annotation, Endnote, TextBox, HeaderTextBox };
+
+ /**
+ * Construct a parser. The reason that we get the "open" storage
+ * and the document reader passed (ugly :}) is that "someone" has
+ * to determine the nFib to select the proper parser... oh well
+ * At least we take ownership ;)
+ */
+ Parser( OLEStorage* storage, OLEStreamReader* wordDocument );
+ virtual ~Parser(); // Don't forget to close everything properly here
+
+ /**
+ * Is everything allright?
+ */
+ bool isOk() const { return m_okay; }
+
+ /**
+ * Invokes the parsing process.
+ */
+ virtual bool parse() = 0;
+
+ /**
+ * Get the FIB (read only!)
+ */
+ virtual const Word97::FIB& fib() const = 0;
+ /**
+ * Get the DOP (read only!)
+ */
+ virtual const Word97::DOP& dop() const = 0;
+
+ /**
+ * Get the font family name structure for a given ftc.
+ */
+ virtual const Word97::FFN& font( S16 ftc ) const = 0;
+
+ /**
+ * Get the associated strings (author, title,...).
+ * Not cached, so don't use it like:
+ * parser->associatedStrings().author(); parser->associatedStrings().title()...
+ */
+ virtual AssociatedStrings associatedStrings() = 0;
+
+ /**
+ * This stylesheet holds all the styles inside the Word file
+ */
+ virtual const StyleSheet& styleSheet() const = 0;
+
+ /**
+ * The inline replacement handler is used to replace certain characters on the fly.
+ * We don't take ownership of the handler!
+ */
+ void setInlineReplacementHandler( InlineReplacementHandler* handler );
+ /**
+ * The sub-document handler gets all callbacks related to the document structure.
+ * We don't take ownership of the handler!
+ */
+ void setSubDocumentHandler( SubDocumentHandler* handler );
+ /**
+ * The table handler is used to tell the consumer about table structures.
+ * We don't take ownership of the handler!
+ */
+ void setTableHandler( TableHandler* handler );
+ /**
+ * The picture handler passes the image/drawing data to the consumer.
+ * We don't take ownership of the handler!
+ */
+ void setPictureHandler( PictureHandler* handler );
+ /**
+ * The text handler is the main worker among all handlers. It's used to forward
+ * the formatted text to the document, make sure that it's fast.
+ * We don't take ownership of the handler!
+ */
+ void setTextHandler( TextHandler* handler );
+
+ // Do we need public access to parts of the OLEStorage interface?
+ // If we add public accessors we should make m_storage private.
+
+protected:
+ InlineReplacementHandler* m_inlineHandler;
+ SubDocumentHandler* m_subDocumentHandler;
+ TableHandler* m_tableHandler;
+ PictureHandler* m_pictureHandler;
+ TextHandler* m_textHandler;
+ bool m_ourInlineHandler;
+ bool m_ourSubDocumentHandler;
+ bool m_ourTableHandler;
+ bool m_ourPictureHandler;
+ bool m_ourTextHandler;
+
+ OLEStorage* m_storage; // The storage representing the file
+ OLEStreamReader* m_wordDocument; // document stream ('WordDocument')
+
+ bool m_okay; // Still allright?
+
+private:
+ Parser( const Parser& rhs );
+ Parser& operator=( const Parser& rhs );
+
+ template<typename Handler> void setHandler( Handler* newHandler, Handler** handler, bool& ourHandler )
+ {
+ if ( ourHandler ) {
+ ourHandler = false;
+ delete *handler;
+ }
+ *handler = newHandler;
+ }
+};
+
+} // namespace wvWare
+
+#endif // PARSER_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/parser95.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/parser95.cpp
new file mode 100644
index 00000000..f02ecb50
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/parser95.cpp
@@ -0,0 +1,44 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "parser95.h"
+#include "convert.h"
+#include "headers95.h"
+#include "properties97.h"
+
+using namespace wvWare;
+
+Parser95::Parser95( OLEStorage* storage, OLEStreamReader* wordDocument ) :
+ Parser9x( storage, wordDocument, Word95::toWord97( Word95::FIB( wordDocument, true ) ) )
+{
+ if ( !isOk() )
+ return;
+
+ // Initialize the remaining data structures
+ init();
+}
+
+Parser95::~Parser95()
+{
+}
+
+void Parser95::init()
+{
+ if ( m_fib.ccpHdd != 0 )
+ m_headers = new Headers95( m_fib.fcPlcfhdd, m_fib.lcbPlcfhdd, m_table, m_properties->dop().grpfIhdt );
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/parser95.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/parser95.h
new file mode 100644
index 00000000..e3fe3502
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/parser95.h
@@ -0,0 +1,46 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef PARSER95_H
+#define PARSER95_H
+
+#include "parser9x.h"
+
+namespace wvWare
+{
+
+/**
+ * This class is the main parser class for Word95 documents.
+ */
+class Parser95 : public Parser9x
+{
+public:
+ Parser95( OLEStorage* storage, OLEStreamReader* wordDocument );
+ virtual ~Parser95();
+
+private:
+ // don't copy or assing us
+ Parser95( const Parser95& rhs );
+ Parser95& operator=( const Parser95& rhs );
+
+ void init();
+};
+
+} // namespace wvWare
+
+#endif // PARSER95_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/parser97.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/parser97.cpp
new file mode 100644
index 00000000..2d849681
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/parser97.cpp
@@ -0,0 +1,43 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "parser97.h"
+#include "headers97.h"
+
+using namespace wvWare;
+
+
+Parser97::Parser97( OLEStorage* storage, OLEStreamReader* wordDocument ) :
+ Parser9x( storage, wordDocument, Word97::FIB( wordDocument, true ) )
+{
+ if ( !isOk() )
+ return;
+
+ // Initialize the remaining data structures
+ init();
+}
+
+Parser97::~Parser97()
+{
+}
+
+void Parser97::init()
+{
+ if ( m_fib.ccpHdd != 0 )
+ m_headers = new Headers97( m_fib.fcPlcfhdd, m_fib.lcbPlcfhdd, m_table );
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/parser97.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/parser97.h
new file mode 100644
index 00000000..dd92a939
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/parser97.h
@@ -0,0 +1,46 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef PARSER97_H
+#define PARSER97_H
+
+#include "parser9x.h"
+
+namespace wvWare
+{
+
+/**
+ * This class is the main parser class for Word97 documents.
+ */
+class Parser97 : public Parser9x
+{
+public:
+ Parser97( OLEStorage* storage, OLEStreamReader* wordDocument );
+ virtual ~Parser97();
+
+private:
+ // Don't copy or assign us
+ Parser97( const Parser97& rhs );
+ Parser97& operator=( const Parser97& rhs );
+
+ void init();
+};
+
+} // namespace wvWare
+
+#endif // PARSER97_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/parser9x.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/parser9x.cpp
new file mode 100644
index 00000000..25e60d02
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/parser9x.cpp
@@ -0,0 +1,1209 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "parser9x.h"
+#include "properties97.h"
+#include "styles.h"
+#include "word97_helper.h"
+#include "lists.h"
+#include "handlers.h"
+#include "footnotes97.h"
+#include "headers.h"
+#include "fonts.h"
+#include "textconverter.h"
+#include "olestream.h"
+#include "fields.h"
+#include "graphics.h"
+#include "associatedstrings.h"
+#include "paragraphproperties.h"
+#include "functor.h"
+#include "functordata.h"
+#include "word95_generated.h"
+#include "convert.h"
+#include "zcodec.hxx"
+#include "wvlog.h"
+
+#include <gsf/gsf-input.h>
+#include <gsf/gsf-output.h>
+#include <gsf/gsf-input-memory.h>
+#include <gsf/gsf-output-memory.h>
+
+#include <numeric>
+#include <string.h>
+
+using namespace wvWare;
+
+
+Parser9x::Position::Position( U32 cp, const PLCF<Word97::PCD>* plcfpcd ) :
+ piece( 0 ), offset( cp )
+{
+ PLCFIterator<Word97::PCD> it( *plcfpcd );
+ for ( ; it.current(); ++it, ++piece ) {
+ if ( it.currentLim() > cp && it.currentStart() <= cp )
+ break;
+ offset -= it.currentRun();
+ }
+}
+
+
+Parser9x::Parser9x( OLEStorage* storage, OLEStreamReader* wordDocument, const Word97::FIB& fib ) :
+ Parser( storage, wordDocument ), m_fib( fib ), m_table( 0 ), m_data( 0 ), m_properties( 0 ),
+ m_headers( 0 ), m_lists( 0 ), m_textconverter( 0 ), m_fields( 0 ), m_footnotes( 0 ),
+ m_fonts( 0 ), m_drawings( 0 ), m_plcfpcd( 0 ), m_tableRowStart( 0 ), m_tableRowLength( 0 ),
+ m_cellMarkFound( false ), m_remainingCells( 0 ), m_currentParagraph( new Paragraph ),
+ m_remainingChars( 0 ), m_sectionNumber( 0 ), m_subDocument( None ), m_parsingMode( Default )
+{
+ if ( !isOk() )
+ return;
+
+ m_table = storage->createStreamReader( tableStream() );
+ if ( !m_table || !m_table->isValid() ) {
+ wvlog << "Error: Couldn't open the table stream (i.e. [0|1]Table or WordDocument)" << std::endl;
+ m_okay = false;
+ return;
+ }
+
+ m_data = storage->createStreamReader( "Data" );
+ if ( !m_data || !m_data->isValid() ) {
+ wvlog << "Information: Couldn't open the Data stream, no big deal" << std::endl;
+ delete m_data;
+ m_data = 0;
+ }
+
+#ifdef WV2_DUMP_FIB
+ wvlog << "Dumping some parts of the FIB: " << std::endl;
+ wvlog << " wIdent=" << m_fib.wIdent << std::endl;
+ wvlog << " nFib=" << m_fib.nFib << std::endl;
+ wvlog << " nFibBack=" << m_fib.nFibBack << std::endl;
+ wvlog << " lid=0x" << std::hex << m_fib.lid << std::dec << std::endl;
+ wvlog << " lidFE=0x" << std::hex << m_fib.lidFE << std::dec << std::endl;
+ wvlog << " fEncrypted=" << m_fib.fEncrypted << std::endl;
+ wvlog << " chs=" << m_fib.chs << std::endl;
+ wvlog << " fcMin=" << m_fib.fcMin << std::endl;
+ wvlog << " fcMac=" << m_fib.fcMac << std::endl;
+ wvlog << " ccpText=" << m_fib.ccpText << std::endl;
+ wvlog << " ccpFtn=" << m_fib.ccpFtn << std::endl;
+ wvlog << " ccpHdd=" << m_fib.ccpHdd << std::endl;
+ wvlog << " ccpMcr=" << m_fib.ccpMcr << std::endl;
+ wvlog << " ccpAtn=" << m_fib.ccpAtn << std::endl;
+ wvlog << " ccpEdn=" << m_fib.ccpEdn << std::endl;
+ wvlog << " ccpTxbx=" << m_fib.ccpTxbx << std::endl;
+ wvlog << " ccpHdrTxbx=" << m_fib.ccpHdrTxbx << std::endl;
+ wvlog << " pnFbpChpFirst=" << m_fib.pnFbpChpFirst << std::endl;
+ wvlog << " pnChpFirst=" << m_fib.pnChpFirst << std::endl;
+ wvlog << " cpnBteChp=" << m_fib.cpnBteChp << std::endl;
+ wvlog << " pnFbpPapFirst=" << m_fib.pnFbpPapFirst << std::endl;
+ wvlog << " pnPapFirst=" << m_fib.pnPapFirst << std::endl;
+ wvlog << " cpnBtePap=" << m_fib.cpnBtePap << std::endl;
+#endif
+
+ // Initialize all the cached data structures like stylesheets, fonts,
+ // textconverter,...
+ init();
+}
+
+Parser9x::~Parser9x()
+{
+ // Sanity check
+ if ( !oldParsingStates.empty() || m_subDocument != None )
+ wvlog << "Bug: Someone messed up the save/restore stack!" << std::endl;
+
+ delete m_currentParagraph;
+ delete m_tableRowStart;
+ delete m_drawings;
+ delete m_fonts;
+ delete m_plcfpcd;
+ delete m_headers;
+ delete m_footnotes;
+ delete m_fields;
+ delete m_textconverter;
+ delete m_properties;
+ delete m_lists;
+ delete m_data;
+ delete m_table;
+}
+
+bool Parser9x::parse()
+{
+ if ( !isOk() )
+ return false;
+
+ if ( m_fib.fEncrypted ) {
+ // There is some code out there to break this "encryption", do we want
+ // to implement that?
+ // We could either ask for a password or cheat a bit :-)
+ wvlog << "Error: The document is encrypted." << std::endl;
+ return false;
+ }
+
+ if ( m_fib.lcbClx == 0 )
+ fakePieceTable();
+ else {
+ // Get the piece table
+ if ( !readPieceTable() )
+ return false;
+ }
+
+ // start parsing the body
+ if ( !parseBody() )
+ return false;
+ return true;
+}
+
+const Word97::FIB& Parser9x::fib() const
+{
+ return m_fib;
+}
+
+const Word97::DOP& Parser9x::dop() const
+{
+ return m_properties->dop();
+}
+
+const Word97::FFN& Parser9x::font( S16 ftc ) const
+{
+ return m_fonts->font( ftc );
+}
+
+AssociatedStrings Parser9x::associatedStrings()
+{
+ return AssociatedStrings( m_fib.fcSttbfAssoc, m_fib.lcbSttbfAssoc,
+ m_fib.fFarEast ? m_fib.lidFE : m_fib.lid, m_table );
+}
+
+const StyleSheet& Parser9x::styleSheet() const
+{
+ return m_properties->styleSheet();
+}
+
+void Parser9x::parseHeaders( const HeaderData& data )
+{
+ m_subDocumentHandler->headersStart();
+ for ( unsigned char mask = HeaderData::HeaderEven; mask <= HeaderData::FooterFirst; mask <<= 1 )
+ if ( mask & data.headerMask )
+ parseHeader( data, mask );
+ m_subDocumentHandler->headersEnd();
+}
+
+void Parser9x::parseFootnote( const FootnoteData& data )
+{
+#ifdef WV2_DEBUG_FOOTNOTES
+ wvlog << "Parser9x::parseFootnote() #####################" << std::endl;
+#endif
+ if ( data.limCP - data.startCP == 0 ) // shouldn't happen, but well...
+ return;
+
+ saveState( data.limCP - data.startCP, data.type == FootnoteData::Footnote ? Footnote : Endnote );
+ m_subDocumentHandler->footnoteStart();
+
+ U32 offset = m_fib.ccpText + data.startCP;
+ if ( data.type == FootnoteData::Endnote )
+ offset += m_fib.ccpFtn + m_fib.ccpHdd + m_fib.ccpMcr + m_fib.ccpAtn;
+ parseHelper( Position( offset, m_plcfpcd ) );
+
+ m_subDocumentHandler->footnoteEnd();
+ restoreState();
+#ifdef WV2_DEBUG_FOOTNOTES
+ wvlog << "Parser9x::parseFootnote() done ################" << std::endl;
+#endif
+}
+
+void Parser9x::parseTableRow( const TableRowData& data )
+{
+#ifdef WV2_DEBUG_TABLES
+ wvlog << "Parser9x::parseTableRow(): startPiece=" << data.startPiece << " startOffset="
+ << data.startOffset << " length=" << data.length << std::endl;
+#endif
+
+ if ( data.length == 0 ) // idiot safe ;-)
+ return;
+
+ saveState( data.length, static_cast<SubDocument>( data.subDocument ), Table );
+ m_remainingCells = data.tap->itcMac;
+ m_tableHandler->tableRowStart( data.tap );
+ m_tableHandler->tableCellStart();
+
+ parseHelper( Position( data.startPiece, data.startOffset ) );
+
+ m_tableHandler->tableRowEnd();
+ restoreState();
+
+#ifdef WV2_DEBUG_TABLES
+ wvlog << "Parser9x::parseTableRow() done #####################" << std::endl;
+#endif
+}
+
+void Parser9x::parsePicture( const PictureData& data )
+{
+ wvlog << "Parser9x::parsePicture" << std::endl;
+ OLEStreamReader* stream = m_fib.nFib < Word8nFib ? m_wordDocument : m_data;
+ stream->push(); // saveState would be overkill
+
+ //go to the position in the stream after the PICF, where the actual picture data/escher is
+ if ( !stream->seek( data.fcPic + data.picf->cbHeader, G_SEEK_SET ) ) {
+ wvlog << "Error: Parser9x::parsePicture couldn't seek properly" << std::endl;
+ stream->pop();
+ return;
+ }
+
+ if ( data.picf->mfp.mm == 0x64 || data.picf->mfp.mm == 0x66 ) {
+ wvlog << "Linked graphic in Escher object" << std::endl;
+ parsePictureEscher( data, stream, data.picf->lcb, data.fcPic );
+ }
+ else {
+ switch ( data.picf->mfp.mm ) {
+ case 94: // A .bmp or a .gif name is stored after the PICF
+ case 98: // The .tiff name is stored after the PICF
+ parsePictureExternalHelper( data, stream );
+ break;
+ case 99: // A full bmp is stored after the PICF -- not handled in OOo??
+ parsePictureBitmapHelper( data, stream );
+ break;
+ default: // It has to be a .wmf or .emf file (right after the PICF)
+ wvlog << "assuming WMF/EMF file... not sure this is correct" << std::endl;
+ parsePictureWmfHelper( data, stream );
+ break;
+ }
+ }
+ stream->pop();
+}
+
+std::string Parser9x::tableStream() const
+{
+ if ( m_fib.nFib < Word8nFib )
+ return "WordDocument"; // Word 6 or Word 7 (==95)
+ else
+ return m_fib.fWhichTblStm ? "1Table" : "0Table"; // Word 8 (==97) or newer
+}
+
+void Parser9x::init()
+{
+ if ( m_fib.fFarEast )
+ m_textconverter = new TextConverter( m_fib.lidFE );
+ else
+ m_textconverter = new TextConverter( m_fib.lid );
+
+ // Get hold of all the SEP/PAP/CHP related structures and the StyleSheet
+ m_properties = new Properties97( m_wordDocument, m_table, m_fib );
+
+ if ( m_fib.nFib < Word8nFib ) // Word67
+ m_lists = new ListInfoProvider( &styleSheet() );
+ else
+ m_lists = new ListInfoProvider( m_table, m_fib, &m_properties->styleSheet() );
+
+ m_fonts = new FontCollection( m_table, m_fib );
+ m_fields = new Fields( m_table, m_fib );
+ m_drawings = new Drawings( m_table, m_fib );
+
+ if ( m_fib.ccpFtn != 0 )
+ m_footnotes = new Footnotes97( m_table, m_fib );
+}
+
+bool Parser9x::readPieceTable()
+{
+ m_table->seek( m_fib.fcClx );
+ // first skip the leading grpprl blocks, we'll re-read them
+ // if we need them later (no caching here)
+ U8 blockType = m_table->readU8();
+ while ( blockType == wvWare::clxtGrpprl ) {
+ U16 size = m_table->readU16();
+#if WV2_DUMP_PIECE_TABLE > 0
+ wvlog << "Found a clxtGrpprl (size=" << size << ")" << std::endl;
+#endif
+ m_table->seek( size, G_SEEK_CUR );
+ blockType = m_table->readU8();
+ }
+ if ( blockType == wvWare::clxtPlcfpcd ) {
+ U32 size = m_table->readU32();
+#if WV2_DUMP_PIECE_TABLE > 0
+ wvlog << "Found the clxtPlcfpcd (size=" << size << ")" << std::endl;
+#endif
+ m_plcfpcd = new PLCF<Word97::PCD>( size, m_table, false );
+
+#if WV2_DUMP_PIECE_TABLE > 1
+ PLCFIterator<Word97::PCD> it( *m_plcfpcd );
+ for ( int i = 0; it.current(); ++it, ++i ) {
+ wvlog << "Piece Table Entry(" << i << "): " << std::endl;
+ wvlog << " start: " << it.currentStart() << std::endl;
+ wvlog << " lim: " << it.currentLim() << std::endl;
+ wvlog << " complex: " << it.current()->prm.fComplex << std::endl;
+ if ( it.current()->prm.fComplex )
+ wvlog << " igrpprl: " << it.current()->prm.toPRM2().igrpprl << std::endl;
+ else
+ wvlog << " isprm: " << it.current()->prm.isprm << std::endl;
+
+ U32 fc = it.current()->fc;
+ U32 limit = it.currentRun() << 1;
+ wvlog << " value: " << fc << std::endl;
+ if ( fc & 0x40000000 ) {
+ fc = ( fc & 0xbfffffff ) >> 1;
+ limit >>= 1;
+ wvlog << " value (cleared 2nd MSB, div. by 2): " << fc << std::endl;
+ }
+ m_wordDocument->seek( fc );
+ wvlog << " position: " << m_wordDocument->tell() << ", limit: " << limit << std::endl;
+ for ( unsigned int j = 0; j < limit; ++j ) {
+ U8 foo = m_wordDocument->readU8();
+ if ( foo > 31 )
+ wvlog << static_cast<char>( foo );
+ else if ( foo == PARAGRAPH_MARK )
+ wvlog << std::endl;
+ else if ( foo > 0 )
+ wvlog << "{" << static_cast<int>( foo ) << "}";
+ else
+ wvlog << "_";
+ }
+ wvlog << std::endl << " position: " << m_wordDocument->tell() << ", limit: " << limit << std::endl;
+ }
+#endif
+ }
+ else {
+ wvlog << "Oooops, couldn't find the piece table." << std::endl;
+ return false;
+ }
+ return true;
+}
+
+void Parser9x::fakePieceTable()
+{
+ U32 fakePlcfPCD[ 4 ];
+ // The first CP is 0 (endianness doesn't matter :-)
+ fakePlcfPCD[ 0 ] = 0;
+ // The second CP corresponds to the length of the document
+ fakePlcfPCD[ 1 ] = toLittleEndian( m_fib.ccpText + m_fib.ccpFtn + m_fib.ccpHdd + m_fib.ccpMcr +
+ m_fib.ccpAtn + m_fib.ccpEdn + m_fib.ccpTxbx + m_fib.ccpHdrTxbx );
+
+ // Now fake a matching PCD
+ U8* tmp( reinterpret_cast<U8*>( &fakePlcfPCD[0] ) );
+ tmp += 8;
+ *tmp++ = 0; // first the bitfields (unused)
+ *tmp++ = 0;
+ U32 fcMin = m_fib.fcMin << 1;
+ fcMin |= 0x40000000;
+ *tmp++ = static_cast<U8>( fcMin & 0x000000ff );
+ *tmp++ = static_cast<U8>( ( fcMin & 0x0000ff00 ) >> 8 ); // then store the
+ *tmp++ = static_cast<U8>( ( fcMin & 0x00ff0000 ) >> 16 ); // fc in little
+ *tmp++ = static_cast<U8>( ( fcMin & 0xff000000 ) >> 24 ); // endian style
+ *tmp++ = 0; // then an empty PRM
+ *tmp++ = 0;
+
+ tmp = reinterpret_cast<U8*>( &fakePlcfPCD[0] );
+ m_plcfpcd = new PLCF<Word97::PCD>( 16, tmp );
+}
+
+bool Parser9x::parseBody()
+{
+ saveState( m_fib.ccpText, Main );
+ m_subDocumentHandler->bodyStart();
+
+ SharedPtr<const Word97::SEP> sep( m_properties->sepForCP( 0 ) );
+ if ( !sep )
+ sep = new Word97::SEP(); // don't pass 0 pointers in any case
+ m_textHandler->sectionStart( sep ); // First section, starting at CP 0
+ emitHeaderData( sep );
+ sep = 0; // get rid of the huge SEP
+
+ // Process all the pieces belonging to the main document text
+ parseHelper( Position( 0, static_cast<U32>( 0 ) ) );
+
+ // Implicit end of the section
+ m_textHandler->sectionEnd();
+ m_subDocumentHandler->bodyEnd();
+ restoreState();
+ return true;
+}
+
+void Parser9x::parseHelper( Position startPos )
+{
+ PLCFIterator<Word97::PCD> it( m_plcfpcd->at( startPos.piece ) );
+
+ while ( m_remainingChars > 0 && it.current() ) {
+ U32 fc = it.current()->fc; // Start FC of this piece
+ bool unicode;
+ realFC( fc, unicode );
+
+ U32 limit = it.currentRun(); // Number of characters in this piece
+
+ // Check whether the text starts somewhere within the piece, reset at the end of the loop body
+ if ( startPos.offset != 0 ) {
+ fc += unicode ? startPos.offset * 2 : startPos.offset;
+ limit -= startPos.offset;
+ }
+
+ limit = limit > m_remainingChars ? m_remainingChars : limit;
+ m_wordDocument->seek( fc );
+
+ if ( unicode ) {
+ XCHAR* string = new XCHAR[ limit ];
+ // First read the whole piece
+ for ( unsigned int j = 0; j < limit; ++j ) {
+ string[ j ] = m_wordDocument->readU16();
+ if ( ( string[ j ] & 0xff00 ) == 0xf000 ) {
+ // Microsoft uses a Private Unicode Area (PUA) to store the characters of the
+ // Symbol and the Wingdings font. We simply clear these bits to shift the
+ // characters to 0x00XX and hope the correct font is installed. If the font
+ // isn't there, the user will get some ASCII text instead of symbols :}
+ //wvlog << "private unicode area detected -- cropping" << std::endl;
+ string[ j ] &= 0x00ff;
+ }
+ }
+ processPiece<XCHAR>( string, fc, limit, startPos ); // also takes care to delete [] string
+ }
+ else {
+ U8* string = new U8[ limit ];
+ m_wordDocument->read( string, limit );
+ processPiece<U8>( string, fc, limit, startPos ); // also takes care to delete [] string
+ }
+ m_remainingChars -= limit;
+ ++it;
+ ++startPos.piece;
+ startPos.offset = 0; // just in case it was != 0 in the first iteration
+ }
+}
+
+template<typename String>
+void Parser9x::processPiece( String* string, U32 fc, U32 limit, const Position& position )
+{
+ // Take a closer look at the piece we just read. "start" and "index" are
+ // counted in character positions (take care!)
+ unsigned int start = 0;
+ unsigned int index = 0;
+ while ( index < limit ) {
+ switch( string[ index ] ) {
+ case SECTION_MARK:
+ {
+ if ( !m_currentParagraph->empty() || start != index ) {
+ // No "index - start + 1" here, as we don't want to copy the section mark!
+ UString ustring( processPieceStringHelper( string, start, index ) );
+ m_currentParagraph->push_back( Chunk( ustring, Position( position.piece, position.offset + start ),
+ fc + start * sizeof( String ), sizeof( String ) == sizeof( XCHAR ) ) );
+ processParagraph( fc + index * sizeof( String ) );
+ }
+ start = ++index;
+
+ SharedPtr<const Word97::SEP> sep( m_properties->sepForCP( m_fib.ccpText - m_remainingChars + index ) );
+ if ( sep ) {
+ // It's not only a page break, it's a new section
+ m_textHandler->sectionEnd();
+ m_textHandler->sectionStart( sep );
+ emitHeaderData( sep );
+ }
+ else
+ m_textHandler->pageBreak();
+ break;
+ }
+ case CELL_MARK: // same ASCII code as a ROW_MARK
+ m_cellMarkFound = true;
+ // Fall-through intended. A row/cell end is also a paragraph end.
+ case PARAGRAPH_MARK:
+ {
+ // No "index - start + 1" here, as we don't want to copy the paragraph mark!
+ UString ustring( processPieceStringHelper( string, start, index ) );
+ m_currentParagraph->push_back( Chunk( ustring, Position( position.piece, position.offset + start ),
+ fc + start * sizeof( String ), sizeof( String ) == sizeof( XCHAR ) ) );
+ processParagraph( fc + index * sizeof( String ) );
+ m_cellMarkFound = false;
+ start = ++index;
+ break;
+ }
+ // "Special" characters
+ case TAB:
+ string[ index ] = m_inlineHandler->tab();
+ ++index;
+ break;
+ case HARD_LINE_BREAK:
+ string[ index ] = m_inlineHandler->hardLineBreak();
+ ++index;
+ break;
+ case COLUMN_BREAK:
+ string[ index ] = m_inlineHandler->columnBreak();
+ ++index;
+ break;
+ case NON_BREAKING_HYPHEN:
+ string[ index ] = m_inlineHandler->nonBreakingHyphen();
+ ++index;
+ break;
+ case NON_REQUIRED_HYPHEN:
+ string[ index ] = m_inlineHandler->nonRequiredHyphen();
+ ++index;
+ break;
+ case NON_BREAKING_SPACE:
+ string[ index ] = m_inlineHandler->nonBreakingSpace();
+ ++index;
+ break;
+ default:
+ ++index;
+ break;
+ }
+ }
+ if ( start < limit ) {
+ // Finally we have to add the remaining text to the current paragaph (if there is any)
+ UString ustring( processPieceStringHelper( string, start, limit ) );
+ m_currentParagraph->push_back( Chunk( ustring, Position( position.piece, position.offset + start ),
+ fc + start * sizeof( String ), sizeof( String ) == sizeof( XCHAR ) ) );
+ }
+ delete [] string;
+}
+
+UString Parser9x::processPieceStringHelper( XCHAR* string, unsigned int start, unsigned int index ) const
+{
+ return UString( reinterpret_cast<const wvWare::UChar *>( &string[ start ] ), index - start );
+}
+
+UString Parser9x::processPieceStringHelper( U8* string, unsigned int start, unsigned int index ) const
+{
+ return m_textconverter->convert( reinterpret_cast<char*>( &string[ start ] ), index - start );
+}
+
+void Parser9x::processParagraph( U32 fc )
+{
+ // Get the PAP structure as it was at the last full-save
+ ParagraphProperties* props( m_properties->fullSavedPap( fc, m_data ) );
+ // ...and apply the latest changes, then the PAP is completely restored
+ m_properties->applyClxGrpprl( m_plcfpcd->at( m_currentParagraph->back().m_position.piece ).current(), m_fib.fcClx, props );
+
+ // Skim the tables first, as soon as the functor is invoked we have to
+ // parse them and emit the text
+ if ( m_parsingMode == Default && props->pap().fInTable ) {
+ if ( !m_tableRowStart ) {
+ m_tableRowStart = new Position( m_currentParagraph->front().m_position );
+ m_tableRowLength = 0;
+#ifdef WV2_DEBUG_TABLES
+ wvlog << "Start of a table row: piece=" << m_tableRowStart->piece << " offset="
+ << m_tableRowStart->offset << std::endl;
+#endif
+ }
+ m_tableRowLength += std::accumulate( m_currentParagraph->begin(), m_currentParagraph->end(),
+ 1, &Parser9x::accumulativeLength ); // init == 1 because of the parag. mark!
+ if ( props->pap().fTtp ) {
+ // Restore the table properties of this row
+ Word97::TAP* tap = m_properties->fullSavedTap( fc, m_data );
+ m_properties->applyClxGrpprl( m_plcfpcd->at( m_currentParagraph->back().m_position.piece ).current(),
+ m_fib.fcClx, tap, m_properties->styleByIndex( props->pap().istd ) );
+
+ SharedPtr<const Word97::TAP> sharedTap( tap );
+ // We decrement the length by 1 that the trailing row mark doesn't emit
+ // one empty paragraph during parsing.
+ m_textHandler->tableRowFound( make_functor( *this, &Parser9x::parseTableRow,
+ TableRowData( m_tableRowStart->piece, m_tableRowStart->offset,
+ m_tableRowLength - 1, static_cast<int>( m_subDocument ),
+ sharedTap ) ),
+ sharedTap );
+ delete m_tableRowStart;
+ m_tableRowStart = 0;
+ }
+ delete props;
+ }
+ else {
+ // Now that we have the complete PAP, let's see if this paragraph belongs to a list
+ props->createListInfo( *m_lists );
+
+ SharedPtr<const ParagraphProperties> sharedProps( props ); // keep it that way, else the ParagraphProperties get deleted!
+ m_textHandler->paragraphStart( sharedProps );
+
+ // Get the appropriate style for this paragraph
+ const Style* style = m_properties->styleByIndex( props->pap().istd );
+ if ( !style ) {
+ wvlog << "Warning: Huh, really obscure error, couldn't find the Style for the current PAP -- skipping" << std::endl;
+ return;
+ }
+
+ // Now walk the paragraph, chunk for chunk
+ std::list<Chunk>::const_iterator it = m_currentParagraph->begin();
+ std::list<Chunk>::const_iterator end = m_currentParagraph->end();
+ for ( ; it != end; ++it ) {
+ U32 index = 0;
+ const U32 limit = ( *it ).m_text.length();
+ const PLCFIterator<Word97::PCD> pcdIt( m_plcfpcd->at( ( *it ).m_position.piece ) );
+
+ while ( index < limit ) {
+ Word97::CHP* chp = new Word97::CHP( style->chp() );
+ U32 length = m_properties->fullSavedChp( ( *it ).m_startFC + index * ( ( *it ).m_isUnicode ? 2 : 1 ), chp, style );
+ if ( ( *it ).m_isUnicode )
+ length >>= 1;
+ length = length > limit - index ? limit - index : length;
+
+ m_properties->applyClxGrpprl( pcdIt.current(), m_fib.fcClx, chp, style );
+ SharedPtr<const Word97::CHP> sharedChp( chp ); // keep it that way, else the CHP gets deleted!
+ processChunk( *it, chp, length, index, pcdIt.currentStart() );
+ index += length;
+ }
+ }
+ m_textHandler->paragraphEnd();
+
+ if ( m_cellMarkFound ) {
+ m_tableHandler->tableCellEnd();
+ if ( --m_remainingCells )
+ m_tableHandler->tableCellStart();
+ }
+ }
+ m_currentParagraph->clear();
+}
+
+void Parser9x::processChunk( const Chunk& chunk, SharedPtr<const Word97::CHP> chp,
+ U32 length, U32 index, U32 currentStart )
+{
+ // Some characters have a special meaning (e.g. a footnote is anchored at some
+ // position inside the text) and they *don't* have the fSpec flag set. This means
+ // that we have to watch out for such characters even in plain text. Slooow :}
+ //
+ // For now we only have to handle footnote and endnote references that way. Due to that
+ // the code below is a bit simpler right now, but I fear we have to extend that later on.
+ // (We will have to keep track of the type of disruption, footnote() takes care of all now)
+ //
+ // A precondition for the footnote/endnote implementation below is, that footnote and
+ // endnote references only occur in the main body text. The reason is that we only check
+ // for the next footnote inside the PLCF and don't take subdocuments into account. If
+ // it turns out that this precondition is not satisfied we would have to change the
+ // O(1) nextFootnote() call to something like an O(n) containsFootnote( start, lim )
+ // Up to now Word 97, 2000, and 2002 seem to be bug compatible and fullfill that precondition.
+ //
+ while ( length > 0 ) {
+ U32 disruption = 0xffffffff; // "infinity"
+ if ( m_footnotes ) {
+ U32 nextFtn = m_footnotes->nextFootnote();
+ U32 nextEnd = m_footnotes->nextEndnote();
+ disruption = nextFtn < nextEnd ? nextFtn : nextEnd;
+#ifdef WV2_DEBUG_FOOTNOTES
+ wvlog << "nextFtn=" << nextFtn << " nextEnd=" << nextEnd << " disruption="
+ << disruption << " length=" << length << std::endl;
+#endif
+ }
+ U32 startCP = currentStart + chunk.m_position.offset + index;
+
+ if ( disruption >= startCP && disruption < startCP + length ) {
+#ifdef WV2_DEBUG_FOOTNOTES
+ wvlog << "startCP=" << startCP << " len=" << length << " disruption=" << disruption << std::endl;
+#endif
+ U32 disLen = disruption - startCP;
+ if ( disLen != 0 )
+ processRun( chunk, chp, disLen, index, currentStart );
+ length -= disLen;
+ index += disLen;
+ processFootnote( chunk.m_text[ index ], disruption, chp );
+ --length;
+ ++index;
+ }
+ else {
+ // common case, no disruption at all (or the end of a disrupted chunk)
+ processRun( chunk, chp, length, index, currentStart );
+ break; // should be faster than messing with length...
+ }
+ }
+}
+
+void Parser9x::processRun( const Chunk& chunk, SharedPtr<const Word97::CHP> chp,
+ U32 length, U32 index, U32 currentStart )
+{
+ if ( chp->fSpec ) {
+ U32 i = 0;
+ while ( i < length ) {
+ processSpecialCharacter( chunk.m_text[ index + i ], currentStart + chunk.m_position.offset + index + i, chp );
+ ++i;
+ }
+ }
+ else {
+ UConstString str( const_cast<UChar*>( chunk.m_text.data() ) + index, length );
+ m_textHandler->runOfText( str.string(), chp );
+ }
+}
+
+void Parser9x::processSpecialCharacter( UChar character, U32 globalCP, SharedPtr<const Word97::CHP> chp )
+{
+ switch( character.unicode() ) {
+ // Is it one of the "simple" special characters?
+ case TextHandler::CurrentPageNumber:
+ case TextHandler::LineNumber:
+ case TextHandler::AbbreviatedDate:
+ case TextHandler::TimeHMS:
+ case TextHandler::CurrentSectionNumber:
+ case TextHandler::AbbreviatedDayOfWeek:
+ case TextHandler::DayOfWeek:
+ case TextHandler::DayShort:
+ case TextHandler::HourCurrentTime:
+ case TextHandler::HourCurrentTimeTwoDigits:
+ case TextHandler::MinuteCurrentTime:
+ case TextHandler::MinuteCurrentTimeTwoDigits:
+ case TextHandler::SecondsCurrentTime:
+ case TextHandler::AMPMCurrentTime:
+ case TextHandler::CurrentTimeHMSOld:
+ case TextHandler::DateM:
+ case TextHandler::DateShort:
+ case TextHandler::MonthShort:
+ case TextHandler::YearLong:
+ case TextHandler::YearShort:
+ case TextHandler::AbbreviatedMonth:
+ case TextHandler::MonthLong:
+ case TextHandler::CurrentTimeHMS:
+ case TextHandler::DateLong:
+ m_textHandler->specialCharacter( static_cast<TextHandler::SpecialCharacter>( character.unicode() ), chp );
+ break;
+
+ // It has to be one of the very special characters...
+ case TextHandler::Picture:
+ emitPictureData( chp );
+ break;
+ case TextHandler::DrawnObject:
+ emitDrawnObject( chp );
+ break;
+ case TextHandler::FootnoteAuto:
+ if ( m_subDocument == Footnote || m_subDocument == Endnote )
+ m_textHandler->footnoteAutoNumber( chp );
+ else
+ processFootnote( character, globalCP, chp );
+ break;
+ case TextHandler::FieldBegin:
+ {
+ const FLD* fld( m_fields->fldForCP( m_subDocument, toLocalCP( globalCP ) ) );
+ if ( fld )
+ m_textHandler->fieldStart( fld, chp );
+ break;
+ }
+ case TextHandler::FieldSeparator:
+ {
+ const FLD* fld( m_fields->fldForCP( m_subDocument, toLocalCP( globalCP ) ) );
+ if ( fld )
+ m_textHandler->fieldSeparator( fld, chp );
+ break;
+ }
+ case TextHandler::FieldEnd:
+ {
+ const FLD* fld( m_fields->fldForCP( m_subDocument, toLocalCP( globalCP ) ) );
+ if ( fld )
+ m_textHandler->fieldEnd( fld, chp );
+ break;
+ }
+ case TextHandler::FieldEscapeChar:
+ wvlog << "Found an escape character ++++++++++++++++++++?" << std::endl;
+ break;
+ default:
+ wvlog << "Parser9x::processSpecialCharacter(): Support for character " << character.unicode()
+ << " not implemented yet." << std::endl;
+ break;
+ }
+}
+
+void Parser9x::processFootnote( UChar character, U32 globalCP, SharedPtr<const Word97::CHP> chp )
+{
+ if ( !m_footnotes ) {
+ wvlog << "Bug: Found a footnote, but m_footnotes == 0!" << std::endl;
+ return;
+ }
+#ifdef WV2_DEBUG_FOOTNOTES
+ wvlog << "######### Footnote found: CP=" << globalCP << std::endl;
+#endif
+ bool ok;
+ FootnoteData data( m_footnotes->footnote( globalCP, ok ) );
+ if ( ok )
+ m_textHandler->footnoteFound( data.type, character, chp, make_functor( *this, &Parser9x::parseFootnote, data ) );
+}
+
+void Parser9x::emitHeaderData( SharedPtr<const Word97::SEP> sep )
+{
+ // We don't care about non-existant headers
+ if ( !m_headers )
+ return;
+
+ // MS Word stores headers in a very strange way, so we have to keep track
+ // of the section numbers. We use a 0-based index for convenience inside
+ // the header reading code. (Werner)
+ //
+ // Of course the file format has changed between Word 6/7 and Word 8, so
+ // I had to add a workaround... oh well.
+ HeaderData data( m_sectionNumber++ );
+
+ if ( m_fib.nFib < Word8nFib ) {
+ data.headerMask = sep->grpfIhdt;
+ m_headers->headerMask( sep->grpfIhdt );
+ }
+ else {
+ if ( sep->fTitlePage )
+ data.headerMask |= HeaderData::HeaderFirst | HeaderData::FooterFirst;
+ if ( dop().fFacingPages )
+ data.headerMask |= HeaderData::HeaderEven | HeaderData::FooterEven;
+ }
+ m_textHandler->headersFound( make_functor( *this, &Parser9x::parseHeaders, data ) );
+}
+
+void Parser9x::emitDrawnObject( SharedPtr<const Word97::CHP> chp )
+{
+#ifdef WV2_DEBUG_PICTURES
+ wvlog << "TODO: process 'Drawn object': " << static_cast<int> (chp->fSpec) << " "
+ << static_cast<int> (chp->fObj) << " " << static_cast<int> (chp->fOle2) << " "
+ << chp->fcPic_fcObj_lTagObj << std::endl;
+#endif
+
+}
+
+void Parser9x::emitPictureData( SharedPtr<const Word97::CHP> chp )
+{
+#ifdef WV2_DEBUG_PICTURES
+ wvlog << "Found a picture; the fcPic is " << chp->fcPic_fcObj_lTagObj << std::endl;
+#endif
+
+ OLEStreamReader* stream( m_fib.nFib < Word8nFib ? m_wordDocument : m_data );
+ if ( !stream || static_cast<unsigned int>( chp->fcPic_fcObj_lTagObj ) >= stream->size() ) {
+ wvlog << "Error: Severe problems when trying to read an image. Skipping." << std::endl;
+ return;
+ }
+ stream->push();
+ stream->seek( chp->fcPic_fcObj_lTagObj, G_SEEK_SET );
+
+ Word97::PICF* picf( 0 );
+ if ( m_fib.nFib < Word8nFib )
+ picf = new Word97::PICF( Word95::toWord97( Word95::PICF( stream, false ) ) );
+ else
+ picf = new Word97::PICF( stream, false );
+ stream->pop();
+
+ if ( picf->cbHeader < 58 ) {
+ wvlog << "Error: Found an image with a PICF smaller than 58 bytes! Skipping the image." << std::endl;
+ delete picf;
+ return;
+ }
+ if ( picf->fError ) {
+ wvlog << "Information: Skipping the image, fError is set" << std::endl;
+ delete picf;
+ return;
+ }
+
+#ifdef WV2_DEBUG_PICTURES
+ wvlog << "picf:" << std::endl << " lcb=" << picf->lcb << " cbHeader=" << picf->cbHeader
+ << std::endl << " mfp.mm=" << picf->mfp.mm << " mfp.xExt=" << picf->mfp.xExt
+ << " mfp.yExt=" << picf->mfp.yExt << " mfp.hMF=" << picf->mfp.hMF << std::endl
+ << " dxaGoal=" << picf->dxaGoal << " dyaGoal=" << picf->dyaGoal << " mx="
+ << picf->mx << " my=" << picf->my << std::endl << " dxaCropLeft=" << picf->dxaCropLeft
+ << " dyaCropTop=" << picf->dyaCropTop << " dxaCropRight=" << picf->dxaCropRight
+ << " dyaCropBottom=" << picf->dyaCropBottom << std::endl << " fFrameEmpty="
+ << picf->fFrameEmpty << " fBitmap=" << picf->fBitmap << " fDrawHatch="
+ << picf->fDrawHatch << " fError=" << picf->fError << " bpp=" << picf->bpp
+ << std::endl << " dxaOrigin=" << picf->dxaOrigin << " dyaOrigin="
+ << picf->dyaOrigin << std::endl;
+#endif
+
+ SharedPtr<const Word97::PICF> sharedPicf( picf );
+ m_textHandler->pictureFound( make_functor( *this, &Parser9x::parsePicture,
+ PictureData( static_cast<U32>( chp->fcPic_fcObj_lTagObj ), sharedPicf ) ),
+ sharedPicf, chp );
+}
+
+void Parser9x::parseHeader( const HeaderData& data, unsigned char mask )
+{
+#ifdef WV2_DEBUG_HEADERS
+ wvlog << "parsing one header for section " << data.sectionNumber << ": mask=0x"
+ << std::hex << static_cast<int>( mask ) << std::dec << std::endl;
+#endif
+
+ // First we have to determine the CP start/lim for the header text. From what I
+ // found out Word 8 does it that way:
+ // - At the begin of the plcfhdd there are always 6 "0 fields" (stoppers)
+ // - The number of headers modulo 6 is always 0
+ // Word 6 does it completely different, of course :-}
+ std::pair<U32, U32> range( m_headers->findHeader( data.sectionNumber, mask ) );
+
+ int length = range.second - range.first;
+#ifdef WV2_DEBUG_HEADERS
+ wvlog << "found a range: start=" << range.first << " lim=" << range.second << std::endl
+ << "length: " << length << std::endl;
+#endif
+ if ( length < 1 ) {
+#ifdef WV2_DEBUG_HEADERS
+ wvlog << "Warning: Didn't find a valid CPs for this header -- faking it" << std::endl;
+#endif
+ m_subDocumentHandler->headerStart( static_cast<HeaderData::Type>( mask ) );
+ SharedPtr<const ParagraphProperties> sharedProps( new ParagraphProperties );
+ m_textHandler->paragraphStart( sharedProps );
+ m_textHandler->paragraphEnd();
+ m_subDocumentHandler->headerEnd();
+ return;
+ }
+ else if ( length > 1 )
+ --length; // get rid of the trailing "end of header/footer" character
+
+ saveState( length, Header );
+
+ m_subDocumentHandler->headerStart( static_cast<HeaderData::Type>( mask ) );
+ parseHelper( Position( m_fib.ccpText + m_fib.ccpFtn + range.first, m_plcfpcd ) );
+ m_subDocumentHandler->headerEnd();
+
+ restoreState();
+}
+
+void Parser9x::parsePictureEscher( const PictureData& data, OLEStreamReader* stream,
+ int totalPicfSize, int picfStartPos )
+{
+ int endOfPicf = picfStartPos + totalPicfSize;
+#ifdef WV2_DEBUG_PICTURES
+ wvlog << "Parser9x::parsePictureEscher:\n Total PICF size = " << totalPicfSize
+ << "\n PICF start position = " << picfStartPos
+ << "\n current stream position = " << stream->tell()
+ << "\n endOfPicf = " << endOfPicf << std::endl;
+#endif
+
+ //from OOo code, looks like we have to process this type differently
+ // read a byte in, and that's an offset before reading the image
+ if ( data.picf->mfp.mm == 102 )
+ {
+ U8 byte = stream->readU8();
+ int offset = static_cast<unsigned int> (byte);
+ wvlog << " 0x66 offset is " << offset << std::endl;
+ stream->seek( offset, G_SEEK_CUR );
+ }
+
+ //now we do a big loop, just reading each record until we get to the end of the picf
+ do
+ {
+ //read header
+ EscherHeader header( stream );
+#ifdef WV2_DEBUG_PICTURES
+ wvlog << "Starting new outer record: " << std::endl;
+ header.dump();
+#endif
+ //process record
+ wvlog << header.getRecordType() << std::endl;
+ if( !header.isAtom() )
+ {
+ wvlog << "Reading container..." << std::endl;
+ //same process again with container
+ int endOfContainer = stream->tell() + header.recordSize();
+ do
+ {
+ //read header
+ EscherHeader h( stream );
+#ifdef WV2_DEBUG_PICTURES
+ wvlog << " starting new inner record: " << std::endl;
+ h.dump();
+ wvlog << h.getRecordType() << std::endl;
+#endif
+ //process record
+ if( h.isAtom() )
+ {
+ U8* s = new U8[ h.recordSize() ];
+ stream->read( s, h.recordSize() );
+ //clean up memory
+ delete [] s;
+ }
+ else
+ wvlog << " Error - container inside a container!" << std::endl;
+ } while (stream->tell() != endOfContainer);
+ wvlog << "End of container." << std::endl;
+ } //finished processing a container
+ else
+ {
+ wvlog << "Reading atom" << std::endl;
+ if( header.getRecordType() == "msofbtBSE" )
+ {
+ //process image
+ FBSE fbse( stream );
+#ifdef WV2_DEBUG_PICTURES
+ fbse.dump();
+ wvlog << "name length is " << fbse.getNameLength() << std::endl;
+#endif
+ //the data is actually in a new record!
+ EscherHeader h( stream );
+#ifdef WV2_DEBUG_PICTURES
+ wvlog << " reading data record after fbse record" << std::endl;
+ h.dump();
+#endif
+ string blipType = h.getRecordType();
+ Blip blip( stream, blipType );
+#ifdef WV2_DEBUG_PICTURES
+ wvlog << " Blip record dump:" << std::endl;
+ blip.dump();
+#endif
+ //if Blip is compressed, we have to process differently
+ if( blip.isCompressed() )
+ {
+ wvlog << "Decompressing image data at " << stream->tell() << "..." << std::endl;
+ ZCodec z( 0x8000, 0x8000 );
+ z.BeginCompression();
+ z.SetBreak(blip.compressedImageSize());
+ std::vector<U8> outBuffer;
+ int err = z.Decompress( *stream, &outBuffer );
+#ifdef WV2_DEBUG_PICTURES
+ wvlog << " err=" << err << std::endl;
+ wvlog << " outBuffer size = " << outBuffer.size() << std::endl;
+#endif
+ z.EndCompression(&outBuffer);
+ //pass vector to escherData instead of OLEImageReader
+ m_pictureHandler->escherData(outBuffer, data.picf, fbse.getBlipType());
+ }
+ //normal data, just create an OLEImageReader to be read
+ else
+ {
+ int start = stream->tell();
+ int limit = endOfPicf; //TODO is it possible that it wouldn't go all the way to the end?
+ OLEImageReader reader( *stream, start, limit);
+ m_pictureHandler->escherData(reader, data.picf, fbse.getBlipType());
+ //we've read the data in OLEImageReader, so advance stream to the
+ //end of OLEImageReader
+ stream->seek( endOfPicf, G_SEEK_SET );
+ }
+ }
+ else
+ {
+ //we can't really process this atom, because we don't recognize the type
+ //so just skip to the end of this picf
+ wvlog << " unrecognized atom, so we'll skip this image" << std::endl;
+ stream->seek( endOfPicf );
+ //U8* string = new U8[ header.recordSize() ];
+ //stream->read( string, header.recordSize() );
+ //clean up memory
+ //delete [] string;
+ }
+ wvlog << "End of atom." << std::endl;
+ } //finished processing an atom record
+ wvlog << "current position: " << stream->tell() << ", endOfPicf:" << endOfPicf << std::endl;
+ if( stream->tell() > endOfPicf )
+ wvlog << "Error! We read past the end of the picture!" << std::endl;
+ } while (stream->tell() != endOfPicf); //end of record
+}
+
+void Parser9x::parsePictureExternalHelper( const PictureData& data, OLEStreamReader* stream )
+{
+#ifdef WV2_DEBUG_PICTURES
+ wvlog << "Parser9x::parsePictureExternalHelper" << std::endl;
+#endif
+
+ // Guessing... some testing would be nice
+ const U8 length( stream->readU8() );
+ U8* string = new U8[ length ];
+ stream->read( string, length );
+ // Do we have to use the textconverter here?
+ UString ustring( m_textconverter->convert( reinterpret_cast<char*>( string ),
+ static_cast<unsigned int>( length ) ) );
+ delete [] string;
+
+ m_pictureHandler->externalImage( ustring, data.picf );
+}
+
+void Parser9x::parsePictureBitmapHelper( const PictureData& data, OLEStreamReader* stream )
+{
+#ifdef WV2_DEBUG_PICTURES
+ wvlog << "Parser9x::parsePictureBitmapHelper" << std::endl;
+#endif
+ OLEImageReader reader( *stream, data.fcPic + data.picf->cbHeader, data.fcPic + data.picf->lcb );
+ m_pictureHandler->bitmapData( reader, data.picf );
+}
+
+void Parser9x::parsePictureWmfHelper( const PictureData& data, OLEStreamReader* stream )
+{
+#ifdef WV2_DEBUG_PICTURES
+ wvlog << "Parser9x::parsePictureWmfHelper" << std::endl;
+#endif
+ // ###### TODO: Handle the Mac case (x-wmf + PICT)
+ // ###### CHECK: Do we want to do anything about .emf files?
+ OLEImageReader reader( *stream, data.fcPic + data.picf->cbHeader, data.fcPic + data.picf->lcb );
+ m_pictureHandler->wmfData( reader, data.picf );
+}
+
+void Parser9x::saveState( U32 newRemainingChars, SubDocument newSubDocument, ParsingMode newParsingMode )
+{
+ oldParsingStates.push( ParsingState( m_tableRowStart, m_tableRowLength, m_cellMarkFound, m_remainingCells,
+ m_currentParagraph, m_remainingChars, m_sectionNumber, m_subDocument,
+ m_parsingMode ) );
+ m_tableRowStart = 0;
+ m_cellMarkFound = false;
+ m_currentParagraph = new Paragraph;
+ m_remainingChars = newRemainingChars;
+ m_subDocument = newSubDocument;
+ m_parsingMode = newParsingMode;
+
+ m_wordDocument->push();
+ if ( m_data )
+ m_data->push();
+}
+
+void Parser9x::restoreState()
+{
+ if ( oldParsingStates.empty() ) {
+ wvlog << "Bug: You messed up the save/restore stack! The stack is empty" << std::endl;
+ return;
+ }
+
+ if ( m_data )
+ m_data->pop();
+ m_wordDocument->pop();
+
+ ParsingState ps( oldParsingStates.top() );
+ oldParsingStates.pop();
+
+ if ( m_tableRowStart )
+ wvlog << "Bug: We still have to process the table row." << std::endl;
+ delete m_tableRowStart; // Should be a no-op, but I hate mem-leaks even for buggy code ;-)
+ m_tableRowStart = ps.tableRowStart;
+ m_tableRowLength = ps.tableRowLength;
+ m_cellMarkFound = ps.cellMarkFound;
+ m_remainingCells = ps.remainingCells;
+
+ if ( !m_currentParagraph->empty() )
+ wvlog << "Bug: The current paragraph isn't empty." << std::endl;
+ delete m_currentParagraph;
+ m_currentParagraph = ps.paragraph;
+
+ if ( m_remainingChars != 0 )
+ wvlog << "Bug: Still got " << m_remainingChars << " remaining chars." << std::endl;
+ m_remainingChars = ps.remainingChars;
+ m_sectionNumber = ps.sectionNumber;
+
+ m_subDocument = ps.subDocument;
+ m_parsingMode = ps.parsingMode;
+}
+
+U32 Parser9x::toLocalCP( U32 globalCP ) const
+{
+ if ( globalCP < m_fib.ccpText )
+ return globalCP;
+ globalCP -= m_fib.ccpText;
+
+ if ( globalCP < m_fib.ccpFtn )
+ return globalCP;
+ globalCP -= m_fib.ccpFtn;
+
+ if ( globalCP < m_fib.ccpHdd )
+ return globalCP;
+ globalCP -= m_fib.ccpHdd;
+
+ if ( globalCP < m_fib.ccpMcr )
+ return globalCP;
+ globalCP -= m_fib.ccpMcr;
+
+ if ( globalCP < m_fib.ccpAtn )
+ return globalCP;
+ globalCP -= m_fib.ccpAtn;
+
+ if ( globalCP < m_fib.ccpEdn )
+ return globalCP;
+ globalCP -= m_fib.ccpEdn;
+
+ if ( globalCP < m_fib.ccpTxbx )
+ return globalCP;
+ globalCP -= m_fib.ccpTxbx;
+
+ if ( globalCP < m_fib.ccpHdrTxbx )
+ return globalCP;
+ globalCP -= m_fib.ccpHdrTxbx;
+
+ wvlog << "Warning: You aimed " << globalCP << " characters past the end of the text!" << std::endl;
+ return globalCP;
+}
+
+int Parser9x::accumulativeLength( int len, const Parser9x::Chunk& chunk )
+{
+ return len + chunk.m_text.length();
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/parser9x.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/parser9x.h
new file mode 100644
index 00000000..ea323ea1
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/parser9x.h
@@ -0,0 +1,324 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef PARSER9X_H
+#define PARSER9X_H
+
+#include "parser.h"
+#include "word97_generated.h"
+
+#include <string>
+#include <list>
+#include <stack>
+
+namespace wvWare
+{
+
+ // Word97 so far. Is that different in Word95?
+ const unsigned char CELL_MARK = 7;
+ const unsigned char ROW_MARK = 7;
+ const unsigned char TAB = 9;
+ const unsigned char HARD_LINE_BREAK = 11;
+ const unsigned char PAGE_BREAK = 12;
+ const unsigned char SECTION_MARK = 12;
+ const unsigned char PARAGRAPH_MARK = 13;
+ const unsigned char COLUMN_BREAK = 14;
+ const unsigned char FIELD_BEGIN_MARK = 19;
+ const unsigned char FIELD_SEPARATOR = 20;
+ const unsigned char FIELD_END_MARK = 21;
+ const unsigned char NON_BREAKING_HYPHEN = 30;
+ const unsigned char NON_REQUIRED_HYPHEN = 31;
+ const unsigned char SPACE = 32;
+ const unsigned char BREAKING_HYPHEN = 45;
+ const unsigned char NON_BREAKING_SPACE = 160;
+ const unsigned char FIELD_ESCAPE_CHAR = '\\';
+ const unsigned char FORMULA_MARK = '\\';
+
+ // Special chars (fSpec==1)
+ const unsigned char SPEC_CURRENT_PAGE_NUMBER = 0;
+ const unsigned char SPEC_PICTURE = 1;
+ const unsigned char SPEC_AUTONUM_FOOTNOTE_REF = 2;
+ const unsigned char SPEC_FOOTNOTE_SEPARATOR = 3;
+ const unsigned char SPEC_FOOTNOTE_CONTINUATION = 4;
+ const unsigned char SPEC_ANNOTATION_REF = 5;
+ const unsigned char SPEC_LINE_NUMBER = 6;
+ const unsigned char SPEC_HAND_ANNOTATION_PIC = 7;
+ const unsigned char SPEC_DRAWN_OBJECT = 8;
+ const unsigned char SPEC_ABBREV_DATE = 10;
+ const unsigned char SPEC_TIME_HMS = 11;
+ const unsigned char SPEC_CURRENT_SECTION_NUMBER = 12;
+ const unsigned char SPEC_ABBREV_WEEKDAY = 14;
+ const unsigned char SPEC_WEEKDAY = 15;
+ const unsigned char SPEC_DAY_SHORT = 16;
+ const unsigned char SPEC_CURRENT_HOUR = 22;
+ const unsigned char SPEC_CURRENT_HOUR_TWODIG = 23;
+ const unsigned char SPEC_CURRENT_MINUTE = 24;
+ const unsigned char SPEC_CURRENT_MINUTE_TWODIG = 25;
+ const unsigned char SPEC_CURRENT_SECONDS = 26;
+ const unsigned char SPEC_CURRENT_AMPM = 27;
+ const unsigned char SPEC_CURRENT_TIME_HMS = 28;
+ const unsigned char SPEC_DATE_M = 29;
+ const unsigned char SPEC_DATE_SHORT = 30;
+ const unsigned char SPEC_MONTH_SHORT = 33;
+ const unsigned char SPEC_YEAR_LONG = 34;
+ const unsigned char SPEC_YEAR_SHORT = 35;
+ const unsigned char SPEC_MONTH_ABBREV = 36;
+ const unsigned char SPEC_MONTH_LONG = 37;
+ const unsigned char SPEC_CURRENT_TIME_HM = 38;
+ const unsigned char SPEC_DATE_LONG = 39;
+ const unsigned char SPEC_MERGE_HELPER = 41;
+
+
+ class Properties97;
+ class ListInfoProvider;
+ class FontCollection;
+ class TextConverter;
+ class Fields;
+ class Headers;
+ class Footnotes97;
+ class Drawings;
+ template<class T> class PLCF;
+
+ // Helper structures for the Functor-based approach
+ struct HeaderData;
+ struct FootnoteData;
+ struct TableRowData;
+ struct PictureData;
+
+ /**
+ * This class should contain all the common functionality shared
+ * among the Word9[5|7] parsers.
+ */
+ class Parser9x : public Parser
+ {
+ public:
+ Parser9x( OLEStorage* storage, OLEStreamReader* wordDocument, const Word97::FIB& fib );
+ virtual ~Parser9x();
+
+ /**
+ * The main parsing method
+ */
+ virtual bool parse();
+
+ virtual const Word97::FIB& fib() const;
+ virtual const Word97::DOP& dop() const;
+
+ /**
+ * Get the font family name structure for a given ftc.
+ */
+ virtual const Word97::FFN& font( S16 ftc ) const;
+
+ /**
+ * Get the associated strings (author, title,...).
+ * Not cached.
+ */
+ virtual AssociatedStrings associatedStrings();
+
+ virtual const StyleSheet& styleSheet() const;
+
+ // This part of the public API is only visible to the Functor classes,
+ // as the "outside world" only sees the public API of Parser. The Functors
+ // allow to delay the parsing of certain text inside the file (e.g. headers)
+ // and trigger parsing at any point (as long as the parser exists).
+ //
+ // In case you want to add a new method here, please obey the following guidelines:
+ // - Executing the method mustn't change the state of the parser (i.e. save and
+ // restore the state!)
+ // - Be very careful, these calls can possibly be triggered at any time
+ void parseHeaders( const HeaderData& data );
+ void parseFootnote( const FootnoteData& data );
+ void parseTableRow( const TableRowData& data );
+ void parsePicture( const PictureData& data );
+
+ protected:
+ // First all variables which don't change their state during
+ // the parsing process. We don't have to save and restore those.
+ const Word97::FIB m_fib;
+
+ OLEStreamReader* m_table; // table stream ('WordDocument' for Word 6+95 and
+ // the real table stream for Word 97+)
+ OLEStreamReader* m_data; // data stream (if any, most of the time 0)
+
+ Properties97* m_properties;
+ Headers* m_headers;
+
+ // From here on we have all variables which change their state depending
+ // on the parsed content. These variables have to be saved and restored
+ // to make the parsing code reentrant.
+
+ private:
+ // Don't copy or assign us
+ Parser9x( const Parser9x& rhs );
+ Parser9x& operator=( const Parser9x& rhs );
+
+ // Uniquely represents a position inside a complex file. Used to map a CP to a Position
+ struct Position
+ {
+ // Start position
+ Position( U32 p, U32 o ) : piece( p ), offset( o ) {}
+ // Constructs a Position from a CP
+ Position( U32 cp, const PLCF<Word97::PCD>* plcfpcd );
+
+ U32 piece; // The piece number (0-based index)
+ U32 offset; // The CP offset within the piece
+ };
+
+ // Represents a chunk of text. This is a part of a (or a whole) paragraph
+ // contained in one text piece. A paragraph consists of at least one Chunk.
+ // We don't store the paragraph/section mark, and in case only the paragraph
+ // mark sits in a different piece than the rest of the paragraph we just store
+ // an empty string for this chunk.
+ struct Chunk
+ {
+ Chunk( const UString& text, const Position& position, U32 startFC, bool isUnicode ) :
+ m_text( text ), m_position( position ), m_startFC( startFC ), m_isUnicode( isUnicode ) {}
+
+ UString m_text;
+ Position m_position;
+ U32 m_startFC;
+ bool m_isUnicode;
+ };
+ // Represents a paragraph consisting of at least one Chunk. Right now it's only
+ // a typedef, maybe we need more than that later on
+ typedef std::list<Chunk> Paragraph;
+
+ // We have to keep track of the current parsing mode (e.g. are we skimming tables
+ // or are we parsing them?)
+ enum ParsingMode { Default, Table };
+
+ // "Callbacks" for the 95/97 parsers
+ // ##### TODO
+
+ // Private helper methods
+ std::string tableStream() const;
+ void init();
+ bool readPieceTable();
+ void fakePieceTable();
+
+ bool parseBody();
+
+ // Expects m_remainingChars to be set correctly, changes the state of m_wordDocument,...
+ void parseHelper( Position startPos );
+ template<typename String> void processPiece( String* string, U32 fc, U32 limit, const Position& position );
+ // These helper methods are a cheap trick to "configure" parts of the template code by
+ // plain old overloading. It's just a matter of compressed vs. real unicode (1 vs. 2 bytes)
+ UString processPieceStringHelper( XCHAR* string, unsigned int start, unsigned int index ) const;
+ UString processPieceStringHelper( U8* string, unsigned int start, unsigned int index ) const;
+ // Processes the current contents of the Paragraph structure and clears it when it's done
+ void processParagraph( U32 fc );
+ void processChunk( const Chunk& chunk, SharedPtr<const Word97::CHP> chp,
+ U32 length, U32 index, U32 currentStart );
+ void processRun( const Chunk& chunk, SharedPtr<const Word97::CHP> chp,
+ U32 length, U32 index, U32 currentStart );
+
+ void processSpecialCharacter( UChar character, U32 globalCP, SharedPtr<const Word97::CHP> chp );
+ void processFootnote( UChar character, U32 globalCP, SharedPtr<const Word97::CHP> chp );
+
+ // Helper methods to gather and emit the information needed for the functors
+ void emitHeaderData( SharedPtr<const Word97::SEP> sep );
+ void emitPictureData( SharedPtr<const Word97::CHP> chp );
+ void emitDrawnObject( SharedPtr<const Word97::CHP> chp );
+
+ void parseHeader( const HeaderData& data, unsigned char mask );
+
+ void parsePictureEscher( const PictureData& data, OLEStreamReader* stream,
+ int totalPicfSize, int picfStartPos );
+ void parsePictureExternalHelper( const PictureData& data, OLEStreamReader* stream );
+ void parsePictureBitmapHelper( const PictureData& data, OLEStreamReader* stream );
+ void parsePictureWmfHelper( const PictureData& data, OLEStreamReader* stream );
+
+ void saveState( U32 newRemainingChars, SubDocument newSubDocument, ParsingMode newParsingMode = Default );
+ void restoreState();
+
+ // Maps the global CP (as found in the piece table) to the local CP
+ // coordinate space of the corresponding sub document
+ U32 toLocalCP( U32 globalCP ) const;
+ // Calculates the real FC and tells us whether it was unicode or not
+ inline void realFC( U32& fc, bool& unicode ) const;
+ // Helper method to use std::accumulate in the table handling code
+ static int accumulativeLength( int len, const Chunk& chunk );
+
+ // Private variables, no access needed in 95/97 code
+ // First all variables which don't change their state during
+ // the parsing process. We don't have to save and restore those.
+ ListInfoProvider* m_lists;
+ TextConverter* m_textconverter;
+ Fields* m_fields;
+ Footnotes97* m_footnotes;
+ FontCollection* m_fonts;
+ Drawings* m_drawings;
+
+ PLCF<Word97::PCD>* m_plcfpcd; // piece table
+
+ // From here on we have all variables which change their state depending
+ // on the parsed content. These variables have to be saved and restored
+ // to make the parsing code reentrant.
+ Position* m_tableRowStart; // If != 0 this represents the start of a table row
+ U32 m_tableRowLength; // Lenght of the table row (in characters). Only valid
+ bool m_cellMarkFound; // if m_tableRowStart != 0
+ int m_remainingCells; // The number of remaining cells for the processed row
+
+ Paragraph* m_currentParagraph;
+
+ U32 m_remainingChars;
+ U32 m_sectionNumber;
+
+ // Keeps track of the current sub document
+ SubDocument m_subDocument;
+
+ // We have to behave differently, depending whether we are parsing
+ // a table or the "main" text, as we skim the table first
+ ParsingMode m_parsingMode;
+
+ // Needed to have reentrant parsing methods (to make the functor approach work)
+ struct ParsingState
+ {
+ ParsingState( Position* tableRowS, U32 tableRowL, bool cMarkFound,
+ int remCells, Paragraph* parag, U32 remChars, U32 sectionNum,
+ SubDocument subD, ParsingMode mode ) :
+ tableRowStart( tableRowS ), tableRowLength( tableRowL ), cellMarkFound( cMarkFound),
+ remainingCells( remCells ), paragraph( parag ), remainingChars( remChars ),
+ sectionNumber( sectionNum ), subDocument( subD ), parsingMode( mode ) {}
+
+ Position* tableRowStart;
+ U32 tableRowLength;
+ bool cellMarkFound;
+ int remainingCells;
+ Paragraph* paragraph;
+ U32 remainingChars;
+ U32 sectionNumber; // not strictly necessary, but doesn't hurt
+ SubDocument subDocument;
+ ParsingMode parsingMode;
+ };
+
+ std::stack<ParsingState> oldParsingStates;
+ };
+
+ inline void Parser9x::realFC( U32& fc, bool& unicode ) const
+ {
+ if ( fc & 0x40000000 ) {
+ fc = ( fc & 0xbfffffff ) >> 1;
+ unicode = false;
+ }
+ else
+ unicode = m_fib.nFib >= Word8nFib;
+ }
+
+} // namespace wvWare
+
+#endif // PARSER9X_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/parserfactory.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/parserfactory.cpp
new file mode 100644
index 00000000..66518b2f
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/parserfactory.cpp
@@ -0,0 +1,136 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "parserfactory.h"
+#include "parser95.h"
+#include "parser97.h"
+#include "olestream.h"
+#include <iostream>
+#include "wvlog.h"
+#include <stdio.h>
+
+using namespace wvWare;
+
+namespace
+{
+ void diagnose( const unsigned char* const buffer )
+ {
+ // Check if it's a Word 3, 4, or 5 file
+ if ( buffer[0] == 0x31 && buffer[1] == 0xbe &&
+ buffer[2] == 0x00 && buffer[3] == 0x00 )
+ std::cerr << "This is a Word 3, 4, or 5 file. Right now we don't handle these versions.\n"
+ << "Please send us the file, maybe we will implement it later on." << std::endl;
+ else if ( buffer[0] == 0xdb && buffer[1] == 0xa5 &&
+ buffer[2] == 0x2d && buffer[3] == 0x00 )
+ std::cerr << "This is a Word 2 document. Right now we don't handle this version." << std::endl
+ << "Please send us the file, maybe we will implement it later on." << std::endl;
+ else
+ std::cerr << "That doesn't seem to be a Word document." << std::endl;
+ }
+
+ SharedPtr<Parser> setupParser( OLEStorage* storage )
+ {
+ // Is it called WordDocument in all versions?
+ OLEStreamReader* wordDocument = storage->createStreamReader( "WordDocument" );
+ if ( !wordDocument || !wordDocument->isValid() ) {
+ std::cerr << "Error: No 'WordDocument' stream found. Are you sure this is a Word document?" << std::endl;
+ delete wordDocument;
+ delete storage;
+ return 0;
+ }
+
+ U16 magic = wordDocument->readU16();
+ if ( magic != 0xa5ec && magic != 0xa5dc )
+ wvlog << "+++ Attention: Strange magic number: " << magic << std::endl;
+
+ U16 nFib = wordDocument->readU16();
+ wvlog << "nFib=" << nFib << std::endl;
+ wordDocument->seek( 0 ); // rewind the stream
+
+ if ( nFib < 101 ) {
+ std::cerr << "+++ Don't know how to handle nFib=" << nFib << std::endl;
+ delete wordDocument;
+ delete storage;
+ return 0;
+ }
+ else if ( nFib == 101 ) {
+ wvlog << "Word 6 document found" << std::endl;
+ return new Parser95( storage, wordDocument );
+ }
+ else if ( nFib == 103 || nFib == 104 ) {
+ wvlog << "Word 7 (aka Word 95) document found" << std::endl;
+ return new Parser95( storage, wordDocument );
+ }
+ else if ( nFib == Word8nFib ) { // Word8nFib == 193
+ wvlog << "Word 8 (aka Word 97) document found" << std::endl;
+ return new Parser97( storage, wordDocument );
+ }
+ else {
+ if ( nFib == 217 ) {
+ wvlog << "Looks like document was created with Word 9/Office 2000"
+ << ", trying with the Word 8 parser." << std::endl;
+ }
+ else if ( nFib == 257 ) {
+ wvlog << "Looks like document was created with Word 10/Office XP"
+ << ", trying with the Word 8 parser." << std::endl;
+ }
+ else if ( nFib == 268 ) {
+ wvlog << "Looks like document was created with Word 11/Office 2003"
+ << ", trying with the Word 8 parser." << std::endl;
+ }
+ else {
+ wvlog << "A document newer than Word 8 found"
+ << ", trying with the Word 8 parser" << std::endl;
+ }
+ return new Parser97( storage, wordDocument );
+ }
+ }
+}
+
+SharedPtr<Parser> ParserFactory::createParser( const std::string& fileName )
+{
+ OLEStorage* storage( new OLEStorage( fileName ) );
+ if ( !storage->open( OLEStorage::ReadOnly ) || !storage->isValid() ) {
+ delete storage;
+
+ FILE* file = fopen( fileName.c_str(), "r" );
+ if ( !file ) {
+ std::cerr << "Couldn't open " << fileName.c_str() << " for reading." << std::endl;
+ return 0;
+ }
+ unsigned char buffer[4];
+ fread( buffer, 1, 4, file );
+ diagnose( buffer );
+ fclose( file );
+ return 0;
+ }
+
+ return setupParser( storage );
+}
+
+SharedPtr<Parser> ParserFactory::createParser( const unsigned char* buffer, size_t buflen )
+{
+ OLEStorage* storage( new OLEStorage( buffer, buflen ) );
+ if ( !storage->open( OLEStorage::ReadOnly ) || !storage->isValid() ) {
+ delete storage;
+ if ( buflen >= 4 )
+ diagnose( buffer );
+ return 0;
+ }
+ return setupParser( storage );
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/parserfactory.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/parserfactory.h
new file mode 100644
index 00000000..8650877e
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/parserfactory.h
@@ -0,0 +1,56 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef PARSERFACTORY_H
+#define PARSERFACTORY_H
+
+#include <string>
+#include "sharedptr.h"
+
+namespace wvWare
+{
+
+class Parser;
+class OLEStorage;
+
+class WV2_DLLEXPORT ParserFactory
+{
+public:
+ /**
+ * This method opens a storage on the file, determines the nFib,
+ * and creates a proper parser for it.
+ * All you have to do with that parser is to call parse() on it
+ * and it will start firing callbacks.
+ * This method will return 0 if it wasn't successful (e.g unknown
+ * version, corrupted file,...).
+ */
+ static SharedPtr<Parser> createParser( const std::string& fileName );
+ /**
+ * This method opens a storage on a buffer in memory, determines the nFib,
+ * and creates a proper parser for it.
+ * All you have to do with that parser is to call parse() on it
+ * and it will start firing callbacks.
+ * This method will return 0 if it wasn't successful (e.g unknown
+ * version, corrupted file,...).
+ */
+ static SharedPtr<Parser> createParser( const unsigned char* buffer, size_t buflen );
+};
+
+} // namespace wvWare
+
+#endif // PARSERFACTORY_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/properties97.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/properties97.cpp
new file mode 100644
index 00000000..35965df2
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/properties97.cpp
@@ -0,0 +1,392 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "properties97.h"
+#include "word97_helper.h"
+#include "word95_generated.h"
+#include "convert.h"
+#include "styles.h"
+#include "paragraphproperties.h"
+
+
+namespace wvWare
+{
+ FKP< BX<Word97::PHE> >* convertFKP( const FKP< BX<Word95::PHE> >& old )
+ {
+ FKP< BX<Word97::PHE> >* ret( new FKP< BX<Word97::PHE> > );
+ // The unchanged fields first...
+ ret->m_crun = old.m_crun;
+ ret->m_rgfc = new U32[ old.m_crun + 1 ];
+ memcpy( ret->m_rgfc, old.m_rgfc, ( old.m_crun + 1 ) * sizeof( U32 ) );
+ ret->m_internalOffset = old.m_internalOffset;
+ const U16 length = 511 - old.m_internalOffset;
+ ret->m_fkp = new U8[ length ];
+ memcpy( ret->m_fkp, old.m_fkp, length );
+
+ // Convert the Offset array
+ ret->m_rgb = new BX<Word97::PHE>[ old.m_crun ];
+ for ( int i = 0; i < old.m_crun; ++i ) {
+ ret->m_rgb[ i ].offset = old.m_rgb[ i ].offset;
+ ret->m_rgb[ i ].phe = Word95::toWord97( old.m_rgb[ i ].phe );
+ }
+ return ret;
+ }
+} // namespace
+
+using namespace wvWare;
+
+
+Properties97::Properties97( OLEStreamReader* wordDocument, OLEStreamReader* table, const Word97::FIB &fib ) :
+ m_version( fib.nFib < Word8nFib ? Word67 : Word8 ), m_wordDocument( wordDocument ), m_table( table ),
+ m_stylesheet( 0 ), m_plcfsed( 0 ), m_plcfbtePapx( 0 ), m_plcfbteChpx( 0 ), m_papxFkp( 0 ), m_chpxFkp( 0 )
+{
+ // First create the whole stylesheet information.
+ m_stylesheet = new StyleSheet( m_table, fib.fcStshf, fib.lcbStshf );
+
+ // Read the DOP
+ m_table->seek( fib.fcDop );
+ if ( m_version == Word8 )
+ m_dop.read( m_table, false );
+ else
+ m_dop = Word95::toWord97( Word95::DOP( m_table, false ) );
+
+ if ( m_table->tell() != static_cast<S32>( fib.fcDop + fib.lcbDop ) )
+ wvlog << "Warning: DOP has a different size than expected." << std::endl;
+
+ // Read the PLCF SED. The Word95::SED is different, but the differing
+ // fields are unused and of the same size, so what :-)
+ m_table->seek( fib.fcPlcfsed );
+ m_plcfsed = new PLCF<Word97::SED>( fib.lcbPlcfsed, m_table );
+
+ if ( fib.lcbClx != 0 ) {
+ // Read the PAPX and CHPX BTE PLCFs (to locate the appropriate FKPs)
+ m_table->seek( fib.fcPlcfbtePapx );
+ if ( m_version == Word8 )
+ m_plcfbtePapx = new PLCF<Word97::BTE>( fib.lcbPlcfbtePapx, m_table );
+ else
+ m_plcfbtePapx = convertPLCF<Word95::BTE, Word97::BTE>( PLCF<Word95::BTE>( fib.lcbPlcfbtePapx, m_table ) );
+ if ( fib.cpnBtePap != 0 && fib.cpnBtePap != m_plcfbtePapx->count() )
+ wvlog << "Error: The PAP piece table is incomplete! (Should be " << fib.cpnBtePap << ")" << std::endl;
+
+ m_table->seek( fib.fcPlcfbteChpx );
+ if ( m_version == Word8 )
+ m_plcfbteChpx = new PLCF<Word97::BTE>( fib.lcbPlcfbteChpx, m_table );
+ else
+ m_plcfbteChpx = convertPLCF<Word95::BTE, Word97::BTE>( PLCF<Word95::BTE>( fib.lcbPlcfbteChpx, m_table ) );
+ if ( fib.cpnBteChp != 0 && fib.cpnBteChp != m_plcfbteChpx->count() )
+ wvlog << "Error: The CHP piece table is incomplete! (Should be " << fib.cpnBteChp << ")" << std::endl;
+ }
+ else {
+ // Read the PAPX and CHPX BTE PLCFs (to locate the appropriate FKPs) from a non-complex file
+ m_table->seek( fib.fcPlcfbtePapx );
+ m_plcfbtePapx = convertPLCF<Word95::BTE, Word97::BTE>( PLCF<Word95::BTE>( fib.lcbPlcfbtePapx, m_table ) );
+ if ( fib.cpnBtePap != m_plcfbtePapx->count() )
+ fillBinTable( m_plcfbtePapx, fib.cpnBtePap );
+
+ m_table->seek( fib.fcPlcfbteChpx );
+ m_plcfbteChpx = convertPLCF<Word95::BTE, Word97::BTE>( PLCF<Word95::BTE>( fib.lcbPlcfbteChpx, m_table ) );
+ if ( fib.cpnBteChp != m_plcfbteChpx->count() )
+ fillBinTable( m_plcfbteChpx, fib.cpnBteChp );
+ }
+
+
+}
+
+Properties97::~Properties97()
+{
+ delete m_chpxFkp;
+ delete m_papxFkp;
+ delete m_plcfbteChpx;
+ delete m_plcfbtePapx;
+ delete m_plcfsed;
+ delete m_stylesheet;
+}
+
+const Style* Properties97::styleByIndex( U16 istd ) const
+{
+ return m_stylesheet->styleByIndex( istd );
+}
+
+StyleSheet& Properties97::styleSheet() const
+{
+ return *m_stylesheet;
+}
+
+const Word97::DOP& Properties97::dop() const
+{
+ return m_dop;
+}
+
+SharedPtr<const Word97::SEP> Properties97::sepForCP( U32 cp ) const
+{
+ // Did we find a page break? If we don't have any PLCFSED entries it has to be one
+ if ( m_plcfsed->isEmpty() )
+ return SharedPtr<const Word97::SEP>( 0 );
+
+ // The documentation says that it's a page break if this PLCF doesn't have an entry
+ // for this CP -- at least I read it that way
+ PLCFIterator<Word97::SED> it( *m_plcfsed );
+ while ( it.current() && it.currentLim() <= cp )
+ ++it;
+
+ if ( it.currentStart() == cp ) {
+ Word97::SED* sed = it.current();
+ Word97::SEP* sep = new Word97::SEP;
+
+ if ( !sed || sed->fcSepx == 0xffffffff )
+ return SharedPtr<const Word97::SEP>( sep );
+
+ m_wordDocument->push();
+ m_wordDocument->seek( sed->fcSepx );
+ const U16 count = m_wordDocument->readU16();
+ U8* grpprl = new U8[ count ];
+ m_wordDocument->read( grpprl, count );
+
+ sep->apply( grpprl, count, 0, m_stylesheet, 0, m_version );
+
+ delete [] grpprl;
+ m_wordDocument->pop();
+ return SharedPtr<const Word97::SEP>( sep );
+ }
+ return SharedPtr<const Word97::SEP>( 0 );
+}
+
+ParagraphProperties* Properties97::fullSavedPap( U32 fc, OLEStreamReader* dataStream )
+{
+ // Step 1: Search the correct FKP entry in the PLCFBTE
+ PLCFIterator<Word97::BTE> it( *m_plcfbtePapx );
+ while ( it.current() && it.currentLim() <= fc )
+ ++it;
+
+ if ( !it.current() ) {
+ wvlog << "Bug: PAPX BTE screwed" << std::endl;
+ return new ParagraphProperties;
+ }
+
+ // Step 2: Check the cache if we already have the correct FKP
+ if ( m_papxFkp ) {
+ PAPXFKPIterator fkpit( *m_papxFkp );
+ if ( fkpit.currentStart() != it.currentStart() ) {
+ delete m_papxFkp;
+ m_papxFkp = 0;
+ }
+ }
+
+ // Step 3: Get the new FKP, if necessary
+ if ( !m_papxFkp ) {
+ m_wordDocument->push();
+ m_wordDocument->seek( it.current()->pn << 9, G_SEEK_SET ); // 512 byte pages ( << 9 )
+ if ( m_version == Word8 )
+ m_papxFkp = new PAPXFKP_t( m_wordDocument, false );
+ else
+ m_papxFkp = convertFKP( PAPXFKP95_t( m_wordDocument, false ) );
+ m_wordDocument->pop();
+ }
+
+ // Step 4: Get the right entry within our FKP
+ PAPXFKPIterator fkpit( *m_papxFkp );
+ while ( !fkpit.atEnd() && fkpit.currentLim() <= fc )
+ ++fkpit;
+
+ // Step 5: Now that we are at the correct place let's apply the PAPX grpprl
+ ParagraphProperties *properties = Word97::initPAPFromStyle( fkpit.current(), m_stylesheet, dataStream, m_version );
+
+ // Step 6: Copy the PHE from the BX in the FKP to restore the state of the PAP during
+ // the last full-save of the document
+ properties->pap().phe = fkpit.currentOffset().phe;
+
+ return properties;
+}
+
+void Properties97::applyClxGrpprl( const Word97::PCD* pcd, U32 fcClx, ParagraphProperties* properties )
+{
+ applyClxGrpprlImpl<Word97::PAP>( pcd, fcClx, &properties->pap(), m_stylesheet->styleByIndex( properties->pap().istd ) );
+}
+
+Word97::TAP* Properties97::fullSavedTap( U32 fc, OLEStreamReader* dataStream )
+{
+ // This method is quite similar to fullSavedPap, but a template solution would suck :}
+ // Maybe I'll clean that up later
+
+ // Step 1: Search the correct FKP entry in the PLCFBTE
+ PLCFIterator<Word97::BTE> it( *m_plcfbtePapx );
+ while ( it.current() && it.currentLim() <= fc )
+ ++it;
+
+ if ( !it.current() ) {
+ wvlog << "Bug: TAPX BTE screwed" << std::endl;
+ return new Word97::TAP;
+ }
+
+ // Step 2: Check the cache if we already have the correct FKP
+ if ( m_papxFkp ) {
+ PAPXFKPIterator fkpit( *m_papxFkp );
+ if ( fkpit.currentStart() != it.currentStart() ) {
+ delete m_papxFkp;
+ m_papxFkp = 0;
+ }
+ }
+
+ // Step 3: Get the new FKP, if necessary
+ if ( !m_papxFkp ) {
+ m_wordDocument->push();
+ m_wordDocument->seek( it.current()->pn << 9, G_SEEK_SET ); // 512 byte pages ( << 9 )
+ if ( m_version == Word8 )
+ m_papxFkp = new PAPXFKP_t( m_wordDocument, false );
+ else
+ m_papxFkp = convertFKP( PAPXFKP95_t( m_wordDocument, false ) );
+ m_wordDocument->pop();
+ }
+
+ // Step 4: Get the right entry within our FKP
+ PAPXFKPIterator fkpit( *m_papxFkp );
+ while ( !fkpit.atEnd() && fkpit.currentLim() <= fc )
+ ++fkpit;
+
+ // Step 5: Now that we are at the correct place let's apply the PAPX grpprl
+ // to our TAP
+ return Word97::initTAP( fkpit.current(), dataStream, m_version );
+}
+
+void Properties97::applyClxGrpprl( const Word97::PCD* pcd, U32 fcClx, Word97::TAP* tap, const Style* style )
+{
+ applyClxGrpprlImpl<Word97::TAP>( pcd, fcClx, tap, style );
+}
+
+U32 Properties97::fullSavedChp( const U32 fc, Word97::CHP* chp, const Style* paragraphStyle )
+{
+ // Before we start with the plain FKP algorithm like above we have to apply any
+ // CHPX found in the style entry for the CHP, unless it's istdNormalChar (10)
+ if ( chp->istd != 10 ) {
+ const Style* style = m_stylesheet->styleByIndex( chp->istd );
+ if ( style && style->type() == Style::sgcChp ) {
+ const UPECHPX& upechpx( style->upechpx() );
+ chp->apply( upechpx.grpprl, upechpx.cb, paragraphStyle, m_stylesheet, 0, m_version );
+ }
+ else
+ wvlog << "Couldn't find the character style with istd " << chp->istd << std::endl;
+ }
+
+ // Step 1: Search the correct FKP entry in the PLCFBTE
+ PLCFIterator<Word97::BTE> it( *m_plcfbteChpx );
+ while ( it.current() && it.currentLim() <= fc )
+ ++it;
+
+ if ( !it.current() ) {
+ wvlog << "Bug: CHPX BTE screwed (backing out by faking properties)" << std::endl;
+ it.toFirst();
+ }
+
+ // Step 2: Check the cache if we already have the correct FKP
+ if ( m_chpxFkp ) {
+ CHPXFKPIterator fkpit( *m_chpxFkp );
+ if ( fkpit.currentStart() != it.currentStart() ) {
+ delete m_chpxFkp;
+ m_chpxFkp = 0;
+ }
+ }
+
+ // Step 3: Get the new FKP, if necessary
+ if ( !m_chpxFkp ) {
+ m_wordDocument->push();
+ m_wordDocument->seek( it.current()->pn << 9, G_SEEK_SET ); // 512 byte pages ( << 9 )
+ m_chpxFkp = new CHPXFKP_t( m_wordDocument, false );
+ m_wordDocument->pop();
+ }
+
+ // Step 4: Get the right entry within our FKP
+ CHPXFKPIterator fkpit( *m_chpxFkp );
+ while ( !fkpit.atEnd() && fkpit.currentLim() <= fc )
+ ++fkpit;
+
+ // Step 5: Now that we are at the correct place let's apply the CHPX grpprl
+ chp->applyExceptions( fkpit.current(), paragraphStyle, m_stylesheet, 0, m_version );
+ return fkpit.currentLim() - fc;
+}
+
+void Properties97::applyClxGrpprl( const Word97::PCD* pcd, U32 fcClx, Word97::CHP* chp, const Style* style )
+{
+ applyClxGrpprlImpl<Word97::CHP>( pcd, fcClx, chp, style );
+}
+
+template<class P>
+void Properties97::applyClxGrpprlImpl( const Word97::PCD* pcd, U32 fcClx, P* properties, const Style* style )
+{
+ if ( !pcd ) {
+ wvlog << "Huh? This can't have happended, right?" << std::endl;
+ return;
+ }
+
+ if ( pcd->prm.fComplex != 0 ) {
+ U16 igrpprl = pcd->prm.toPRM2().igrpprl;
+ //wvlog << "############# igrpprl: " << igrpprl << std::endl;
+ m_table->push();
+ m_table->seek( fcClx );
+ U8 blockType = m_table->readU8();
+
+ while ( blockType == wvWare::clxtGrpprl && igrpprl > 0 ) {
+ U16 size = m_table->readU16();
+ //wvlog << "Skipping a clxtGrpprl (size=" << size << ")" << std::endl;
+ m_table->seek( size, G_SEEK_CUR );
+ blockType = m_table->readU8();
+ --igrpprl;
+ }
+
+ if ( blockType == wvWare::clxtGrpprl ) {
+ U16 size = m_table->readU16();
+ //wvlog << "Found the right clxtGrpprl (size=" << size << ")" << std::endl;
+ U8 *grpprl = new U8[ size ];
+ m_table->read( grpprl, size );
+ properties->apply( grpprl, size, style, m_stylesheet, 0, m_version ); // dataStream shouldn't be necessary in a clx
+ delete [] grpprl;
+ }
+ m_table->pop();
+ }
+ else {
+ U16 sprm = toLittleEndian( Word97::SPRM::unzippedOpCode( pcd->prm.isprm ) ); // force LE order
+ if ( sprm != 0 ) {
+ //wvlog << "CHPX/PAPX/TAPX ###### compressed: " << pcd->prm.isprm << " Uncompressed sprm: " << sprm
+ // << " data: " << ( int )pcd->prm.val << std::endl;
+ U8 grpprl[ 3 ];
+ grpprl[ 0 ] = static_cast<U8>( sprm & 0x00ff );
+ grpprl[ 1 ] = static_cast<U8>( ( sprm & 0xff00 ) >> 8 );
+ grpprl[ 2 ] = pcd->prm.val;
+ properties->apply( grpprl, 3, style, m_stylesheet, 0, Word8 ); // dataStream shouldn't be necessary in a clx
+ }
+ }
+}
+
+void Properties97::fillBinTable( PLCF<Word97::BTE>* bte, U16 cpnBte )
+{
+ U16 pnLast = 0;
+ PLCFIterator<Word97::BTE> it( *bte );
+ for ( ; it.current(); ++it )
+ if ( it.current()->pn > pnLast )
+ pnLast = it.current()->pn;
+
+ m_wordDocument->push();
+ cpnBte -= bte->count();
+ while ( cpnBte > 0 ) {
+ Word97::BTE* tmp( new Word97::BTE );
+ tmp->pn = ++pnLast;
+ m_wordDocument->seek( pnLast << 9, G_SEEK_SET );
+ bte->insert( m_wordDocument->readU32(), tmp );
+ --cpnBte;
+ }
+ m_wordDocument->pop();
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/properties97.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/properties97.h
new file mode 100644
index 00000000..ecf2b753
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/properties97.h
@@ -0,0 +1,98 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef PROPERTIES97_H
+#define PROPERTIES97_H
+
+#include "sharedptr.h"
+#include "word_helper.h"
+#include "word97_generated.h"
+
+namespace wvWare
+{
+ class ParagraphProperties;
+ namespace Word95
+ {
+ class PHE;
+ }
+
+ class Properties97
+ {
+ public:
+ Properties97( OLEStreamReader* wordDocument, OLEStreamReader* table, const Word97::FIB &fib );
+ ~Properties97();
+
+ // StyleSheet ---------
+ const Style* styleByIndex( U16 istd ) const;
+ StyleSheet& styleSheet() const;
+
+ // Document properties ---------
+ const Word97::DOP& dop() const;
+
+ // Section properties ---------
+ SharedPtr<const Word97::SEP> sepForCP( U32 cp ) const;
+
+ // Paragraph properties ---------
+ // Determines the PAP state from the last full-save (ownership is transferred)
+ ParagraphProperties* fullSavedPap( U32 fc, OLEStreamReader* dataStream );
+ // Apply the latest changes recorded in the clxGrppl section of the piece table
+ void applyClxGrpprl( const Word97::PCD* pcd, U32 fcClx, ParagraphProperties* properties );
+
+ // Table properties ---------
+ // Determines the TAP state from the last full-save (ownership is transferred)
+ Word97::TAP* fullSavedTap( U32 fc, OLEStreamReader* dataStream );
+ void applyClxGrpprl( const Word97::PCD* pcd, U32 fcClx, Word97::TAP* tap, const Style* style );
+
+ // Character properties ---------
+ // Determines the CHP state from the last full-save (ownership is transferred)
+ U32 fullSavedChp( const U32 fc, Word97::CHP* chp, const Style* paragraphStyle );
+ // Apply the latest changes recorded in the clxGrppl section of the piece table
+ void applyClxGrpprl( const Word97::PCD* pcd, U32 fcClx, Word97::CHP* chp, const Style* style );
+
+ private:
+ Properties97( const Properties97& rhs );
+ Properties97& operator=( const Properties97& rhs );
+
+ // This should have been called "applyClxGrpprl" too, but VC7 doesn't like that
+ template<class P> void applyClxGrpprlImpl( const Word97::PCD* pcd, U32 fcClx, P* properties, const Style* style );
+
+ void fillBinTable( PLCF<Word97::BTE>* bte, U16 cpnBte );
+
+ const WordVersion m_version;
+ OLEStreamReader* m_wordDocument; // doesn't belong to us, be careful
+ OLEStreamReader* m_table; // doesn't belong to us, be careful
+
+ StyleSheet* m_stylesheet;
+ Word97::DOP m_dop;
+ PLCF<Word97::SED>* m_plcfsed; // section descr. table
+ PLCF<Word97::BTE>* m_plcfbtePapx; // PAPX FKP page numbers
+ PLCF<Word97::BTE>* m_plcfbteChpx; // CHPX FKP page numbers
+
+ typedef FKP< BX<Word97::PHE> > PAPXFKP_t;
+ typedef FKP< BX<Word95::PHE> > PAPXFKP95_t;
+ typedef FKPIterator< BX<Word97::PHE> > PAPXFKPIterator;
+ PAPXFKP_t* m_papxFkp; // Currently cached PAPX FKP
+
+ typedef FKP<CHPFKP_BX> CHPXFKP_t;
+ typedef FKPIterator<CHPFKP_BX> CHPXFKPIterator;
+ CHPXFKP_t* m_chpxFkp; // Currently cached CHPX FKP
+};
+
+} // namespace wvWare
+
+#endif // PROPERTIES97_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/sharedptr.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/sharedptr.h
new file mode 100644
index 00000000..f968bc1b
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/sharedptr.h
@@ -0,0 +1,144 @@
+/* This file is part of the KDE libraries
+ Copyright (c) 1999 Waldo Bastian <[email protected]>
+ Copyright (c) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+#ifndef SharedPTR_H
+#define SharedPTR_H
+
+#include "dllmagic.h"
+
+namespace wvWare {
+
+/**
+ * Reference counting for shared objects. If you derive your object
+ * from this class, then you may use it in conjunction with
+ * @ref SharedPtr to control the lifetime of your object.
+ *
+ * Specifically, all classes that derive from Shared have an internal
+ * counter keeping track of how many other objects have a reference to
+ * their object. If used with @ref SharedPtr, then your object will
+ * not be deleted until all references to the object have been
+ * released.
+ *
+ * You should probably not ever use any of the methods in this class
+ * directly -- let the @ref SharedPtr take care of that. Just derive
+ * your class from Shared and forget about it.
+ *
+ * @author Waldo Bastian <[email protected]>
+ */
+class WV2_DLLEXPORT Shared {
+public:
+ /**
+ * Standard constructor. This will initialize the reference count
+ * on this object to 0
+ */
+ Shared() : count( 0 ) { }
+
+ /**
+ * Copy constructor. This will @em not actually copy the objects
+ * but it will initialize the reference count on this object to 0
+ */
+ Shared( const Shared & ) : count( 0 ) { }
+
+ /**
+ * Overloaded assignment operator
+ */
+ Shared &operator=( const Shared & ) { return *this; }
+
+ /**
+ * Increases the reference count by one
+ */
+ void _Shared_ref() const { count++; }
+
+ /**
+ * Releases a reference (decreases the reference count by one). If
+ * the count goes to 0, this object will delete itself
+ */
+ void _Shared_deref() const { if (!--count) delete this; }
+
+ /**
+ * Return the current number of references held
+ *
+ * @return Number of references
+ */
+ int _Shared_count() const { return count; }
+
+protected:
+ virtual ~Shared() { }
+private:
+ mutable int count;
+};
+
+/**
+ * Can be used to control the lifetime of an object that has derived
+ * @ref Shared. As long a someone holds a SharedPtr on some Shared
+ * object it won't become deleted but is deleted once its reference
+ * count is 0. This struct emulates C++ pointers perfectly. So just
+ * use it like a simple C++ pointer.
+ *
+ * @author Waldo Bastian <[email protected]>
+ */
+template< class T >
+struct SharedPtr
+{
+public:
+ SharedPtr()
+ : ptr(0) { }
+ SharedPtr( T* t )
+ : ptr(t) { if ( ptr ) ptr->_Shared_ref(); }
+ SharedPtr( const SharedPtr& p )
+ : ptr(p.ptr) { if ( ptr ) ptr->_Shared_ref(); }
+
+ ~SharedPtr() { if ( ptr ) ptr->_Shared_deref(); }
+
+ SharedPtr<T>& operator= ( const SharedPtr<T>& p ) {
+ if ( ptr == p.ptr ) return *this;
+ if ( ptr ) ptr->_Shared_deref();
+ ptr = p.ptr;
+ if ( ptr ) ptr->_Shared_ref();
+ return *this;
+ }
+ SharedPtr<T>& operator= ( T* p ) {
+ if ( ptr == p ) return *this;
+ if ( ptr ) ptr->_Shared_deref();
+ ptr = p;
+ if ( ptr ) ptr->_Shared_ref();
+ return *this;
+ }
+ bool operator== ( const SharedPtr<T>& p ) const { return ( ptr == p.ptr ); }
+ bool operator!= ( const SharedPtr<T>& p ) const { return ( ptr != p.ptr ); }
+ bool operator== ( const T* p ) const { return ( ptr == p ); }
+ bool operator!= ( const T* p ) const { return ( ptr != p ); }
+ bool operator!() const { return ( ptr == 0 ); }
+ operator T*() const { return ptr; }
+
+ T* data() { return ptr; }
+ const T* data() const { return ptr; }
+
+ const T& operator*() const { return *ptr; }
+ T& operator*() { return *ptr; }
+ const T* operator->() const { return ptr; }
+ T* operator->() { return ptr; }
+
+ int count() const { return ptr->_Shared_count(); } // for debugging purposes
+private:
+ T* ptr;
+};
+
+} // namespace wvWare
+
+#endif
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/styles.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/styles.cpp
new file mode 100644
index 00000000..f603e56d
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/styles.cpp
@@ -0,0 +1,763 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "styles.h"
+#include "olestream.h"
+#include "word97_helper.h"
+#include "convert.h"
+#include "paragraphproperties.h"
+
+#include "wvlog.h"
+#include <algorithm>
+#include <string.h>
+
+namespace wvWare
+{
+
+namespace Word97
+{
+
+// STD implementation
+STD::STD()
+{
+ clearInternal();
+}
+
+STD::STD( U16 baseSize, U16 totalSize, OLEStreamReader* stream, bool preservePos )
+{
+ clearInternal();
+ read( baseSize, totalSize, stream, preservePos );
+}
+
+STD::STD( const STD& rhs ) : xstzName( rhs.xstzName )
+{
+ sti = rhs.sti;
+ fScratch = rhs.fScratch;
+ fInvalHeight = rhs.fInvalHeight;
+ fHasUpe = rhs.fHasUpe;
+ fMassCopy = rhs.fMassCopy;
+ sgc = rhs.sgc;
+ istdBase = rhs.istdBase;
+ cupx = rhs.cupx;
+ istdNext = rhs.istdNext;
+ bchUpe = rhs.bchUpe;
+ fAutoRedef = rhs.fAutoRedef;
+ fHidden = rhs.fHidden;
+ unused8_3 = rhs.unused8_3;
+ grupxLen = rhs.grupxLen;
+
+ // ...and the UPXes
+ grupx = new U8[ grupxLen ];
+ memcpy( grupx, rhs.grupx, grupxLen );
+}
+
+STD::~STD()
+{
+ delete [] grupx;
+}
+
+STD& STD::operator=( const STD& rhs )
+{
+ // Check for assignment to self
+ if ( this == &rhs )
+ return *this;
+
+ sti = rhs.sti;
+ fScratch = rhs.fScratch;
+ fInvalHeight = rhs.fInvalHeight;
+ fHasUpe = rhs.fHasUpe;
+ fMassCopy = rhs.fMassCopy;
+ sgc = rhs.sgc;
+ istdBase = rhs.istdBase;
+ cupx = rhs.cupx;
+ istdNext = rhs.istdNext;
+ bchUpe = rhs.bchUpe;
+ fAutoRedef = rhs.fAutoRedef;
+ fHidden = rhs.fHidden;
+ unused8_3 = rhs.unused8_3;
+ grupxLen = rhs.grupxLen;
+
+ // assign the name
+ xstzName = rhs.xstzName;
+
+ // ...and the UPXes
+ delete [] grupx;
+ grupx = new U8[ grupxLen ];
+ memcpy( grupx, rhs.grupx, grupxLen );
+
+ return *this;
+}
+
+bool STD::read( U16 baseSize, U16 totalSize, OLEStreamReader* stream, bool preservePos )
+{
+ U16 shifterU16;
+ S32 startOffset=stream->tell(); // address where the STD starts
+
+ if (preservePos)
+ stream->push();
+
+ shifterU16 = stream->readU16();
+ sti = shifterU16;
+ shifterU16 >>= 12;
+ fScratch = shifterU16;
+ shifterU16 >>= 1;
+ fInvalHeight = shifterU16;
+ shifterU16 >>= 1;
+ fHasUpe = shifterU16;
+ shifterU16 >>= 1;
+ fMassCopy = shifterU16;
+ shifterU16 = stream->readU16();
+ sgc = shifterU16;
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "##### sgc: " << static_cast<int>( sgc ) << std::endl;
+#endif
+ shifterU16 >>= 4;
+ istdBase = shifterU16;
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << " istdBase: " << istdBase << std::endl;
+#endif
+ shifterU16 = stream->readU16();
+ cupx = shifterU16;
+ shifterU16 >>= 4;
+ istdNext = shifterU16;
+ bchUpe = stream->readU16();
+
+ // Skip the end of the Word97::STD in older documents with baseSize <= 8
+ if ( baseSize > 8 ) {
+ shifterU16 = stream->readU16();
+ fAutoRedef = shifterU16;
+ shifterU16 >>= 1;
+ fHidden = shifterU16;
+ shifterU16 >>= 1;
+ unused8_3 = shifterU16;
+ }
+
+ // read the name of the style.
+ // Note: Starts at an even address within the STD after the
+ // stshi.cbSTDBaseInFile part.
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "baseSize: " << baseSize << std::endl;
+ wvlog << "start offset: " << startOffset << std::endl;
+ wvlog << "curr. position: " << stream->tell() << std::endl;
+#endif
+ baseSize += ( baseSize & 0x0001 ) ? 1 : 0; // next even address
+ stream->seek( startOffset + baseSize, G_SEEK_SET );
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "new position: " << stream->tell() << std::endl;
+#endif
+
+ readStyleName( baseSize, stream );
+
+ // even byte address within the STD?
+ if ( ( stream->tell() - startOffset ) & 1 ) {
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "Adjusting the position... from " << stream->tell() - startOffset;
+#endif
+ stream->seek( 1, G_SEEK_CUR );
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << " to " << stream->tell() - startOffset << std::endl;
+#endif
+ }
+
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "cupx: " << static_cast<int>( cupx ) << std::endl;
+ wvlog << "size: " << totalSize - ( stream->tell() - startOffset ) << std::endl;
+#endif
+ grupxLen = totalSize - ( stream->tell() - startOffset );
+ grupx = new U8[ grupxLen ];
+ int offset = 0;
+ for ( U8 i = 0; i < cupx; ++i) {
+ U16 cbUPX = stream->readU16(); // size of the next UPX
+ stream->seek( -2, G_SEEK_CUR ); // rewind the "lookahead"
+ cbUPX += 2; // ...and correct the size
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "cbUPX: " << cbUPX << std::endl;
+#endif
+ for ( U16 j = 0; j < cbUPX; ++j ) {
+ grupx[ offset + j ] = stream->readU8(); // read the whole UPX
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << " read: " << static_cast<int>( grupx[ offset + j ] ) << std::endl;
+#endif
+ }
+ offset += cbUPX; // adjust the offset in the grupx array
+ // Don't forget to adjust the position
+ if ( ( stream->tell() - startOffset ) & 1 ) {
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "Adjusting the UPX position... from " << stream->tell() - startOffset;
+#endif
+ stream->seek( 1, G_SEEK_CUR );
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << " to " << stream->tell() - startOffset << std::endl;
+#endif
+ }
+ }
+
+ if ( preservePos )
+ stream->pop();
+ return true;
+}
+
+bool STD::write( U16 /*baseSize*/, OLEStreamWriter* stream, bool preservePos ) const
+{
+ // FIXME: don't ignore baseSize and add writing code for the STD
+ U16 shifterU16;
+
+ if ( preservePos )
+ stream->push();
+
+ shifterU16 = sti;
+ shifterU16 |= fScratch << 12;
+ shifterU16 |= fInvalHeight << 13;
+ shifterU16 |= fHasUpe << 14;
+ shifterU16 |= fMassCopy << 15;
+ stream->write( shifterU16 );
+ shifterU16 = sgc;
+ shifterU16 |= istdBase << 4;
+ stream->write( shifterU16 );
+ shifterU16 = cupx;
+ shifterU16 |= istdNext << 4;
+ stream->write( shifterU16 );
+ stream->write( bchUpe );
+ shifterU16 = fAutoRedef;
+ shifterU16 |= fHidden << 1;
+ shifterU16 |= unused8_3 << 2;
+ stream->write( shifterU16 );
+ // Attention: I don't know how to write xstzName - XCHAR[]
+#ifdef __GNUC__
+#warning "Couldn't generate writing code for STD::xstzName"
+#endif
+ // Attention: I don't know how to write grupx - U8[]
+#ifdef __GNUC__
+#warning "Couldn't generate writing code for STD::grupx"
+#endif
+
+ if ( preservePos )
+ stream->pop();
+ return true;
+}
+
+void STD::clear()
+{
+ delete [] grupx;
+ clearInternal();
+}
+
+void STD::clearInternal()
+{
+ sti = 0; fScratch = 0; fInvalHeight = 0;
+ fHasUpe = 0; fMassCopy = 0; sgc = 0;
+ istdBase = 0; cupx = 0; istdNext = 0;
+ bchUpe = 0; fAutoRedef = 0; fHidden = 0;
+ unused8_3 = 0; grupx = 0; grupxLen = 0;
+}
+
+void STD::readStyleName( U16 baseSize, OLEStreamReader* stream )
+{
+ // Read the length of the string. It seems that the spec is
+ // buggy and the "length byte" is actually a short in Word97+
+ if ( baseSize > 8 ) {
+ U16 length = stream->readU16();
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "len: " << length << std::endl;
+#endif
+ // question: Is the \0 included in the length spec?
+ XCHAR *name = new XCHAR[ length + 1 ];
+ for ( U16 i = 0; i < length + 1; ++i ) {
+ name[ i ] = stream->readU16();
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "xstzName[" << static_cast<int>( i ) << "]: " << name[i] << std::endl;
+#endif
+ }
+ if ( name[ length ] != 0 )
+ wvlog << "Warning: Illegal trailing character: " << static_cast<int>( name[ length ] ) << std::endl;
+
+ xstzName = UString( reinterpret_cast<const wvWare::UChar *>( name ), length );
+ delete [] name;
+ }
+ else {
+ // Word versions older than Word97 have a plain lenght byte and
+ // a char* string as name
+ U8 length = stream->readU8();
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "len: " << static_cast<int>( length ) << std::endl;
+#endif
+ // question: Is the \0 included in the length spec?
+ U8 *name = new U8[ length + 1 ];
+ stream->read( name, length + 1 );
+#ifdef WV2_DEBUG_STYLESHEET
+ for ( U16 i = 0; i < length + 1; ++i )
+ wvlog << "xstzName[" << static_cast<int>( i ) << "]: " << static_cast<int>( name[i] ) << std::endl;
+#endif
+ if ( name[ length ] != 0 ) {
+ wvlog << "Warning: Illegal trailing character: " << static_cast<int>( name[ length ] ) << std::endl;
+ name[ length ] = 0;
+ }
+
+ xstzName = UString( reinterpret_cast<const char *>( name ) );
+ delete [] name;
+ }
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "ASCII Name: '" << xstzName.ascii() << "'" << std::endl;
+#endif
+}
+
+bool operator==( const STD& lhs, const STD& rhs )
+{
+ if ( lhs.grupxLen != rhs.grupxLen )
+ return false;
+ for ( U8 i = 0; i < lhs.grupxLen; ++i ) {
+ if ( lhs.grupx[ i ] != rhs.grupx[ i ] )
+ return false;
+ }
+
+ return lhs.xstzName == rhs.xstzName &&
+ lhs.sti == rhs.sti &&
+ lhs.fScratch == rhs.fScratch &&
+ lhs.fInvalHeight == rhs.fInvalHeight &&
+ lhs.fHasUpe == rhs.fHasUpe &&
+ lhs.fMassCopy == rhs.fMassCopy &&
+ lhs.sgc == rhs.sgc &&
+ lhs.istdBase == rhs.istdBase &&
+ lhs.cupx == rhs.cupx &&
+ lhs.istdNext == rhs.istdNext &&
+ lhs.bchUpe == rhs.bchUpe &&
+ lhs.fAutoRedef == rhs.fAutoRedef &&
+ lhs.fHidden == rhs.fHidden &&
+ lhs.unused8_3 == rhs.unused8_3;
+}
+
+bool operator!=( const STD& lhs, const STD& rhs )
+{
+ return !( lhs == rhs );
+}
+
+} // namespace Word97
+} // namespace wvWare
+
+
+using namespace wvWare;
+
+Style::Style( U16 baseSize, OLEStreamReader* tableStream, U16* ftc ) : m_isEmpty( false ),
+ m_isWrapped( true ), m_std( 0 ), m_properties( 0 ), m_chp( 0 ), m_upechpx( 0 )
+{
+ // size of the STD
+ U16 cb = tableStream->readU16();
+ if ( cb == 0 ) { // empty slot
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "Empty style found: " << tableStream->tell() << std::endl;
+#endif
+ m_isEmpty = true;
+ m_isWrapped = false;
+ return;
+ }
+ S32 offset = tableStream->tell();
+ m_std = new Word97::STD( baseSize, cb, tableStream, false );
+ if ( tableStream->tell() != offset + cb ) {
+ wvlog << "Warning: Found a \"hole\"" << std::endl;
+ tableStream->seek( cb, G_SEEK_CUR ); // correct the offset
+ }
+
+ if ( m_std->sgc == sgcPara ) {
+ m_chp = new Word97::CHP();
+ m_properties = new ParagraphProperties();
+ m_chp->ftc = *ftc; // Same value for ftc and ftcAscii
+ m_chp->ftcAscii = *ftc++;
+ m_chp->ftcFE = *ftc++;
+ m_chp->ftcOther = *ftc;
+ }
+ else if ( m_std->sgc == sgcChp )
+ m_upechpx = new UPECHPX();
+ else
+ wvlog << "Attention: New kind of style in the stylesheet" << std::endl;
+}
+
+Style::~Style()
+{
+ delete m_std;
+ delete m_properties;
+ delete m_chp;
+ delete m_upechpx;
+}
+
+void Style::unwrapStyle( const StyleSheet& stylesheet, WordVersion version )
+{
+ if ( !m_isWrapped || !m_std )
+ return;
+
+ if ( m_std->sgc == sgcPara ) {
+ const Style* parentStyle = 0;
+ // only try to unwrap the "parent" if the style isn't the Nil style
+ if ( m_std->istdBase != 0x0fff ) {
+ parentStyle = stylesheet.styleByIndex( m_std->istdBase );
+ if ( parentStyle ) {
+ const_cast<Style*>( parentStyle )->unwrapStyle( stylesheet, version );
+ m_properties->pap() = parentStyle->paragraphProperties().pap();
+ *m_chp = parentStyle->chp();
+ }
+ }
+
+ U8 *data = m_std->grupx;
+
+ // paragraph
+ U16 cbUPX = readU16( data );
+ data += 2;
+ m_properties->pap().istd = readU16( data );
+ data += 2;
+ cbUPX -= 2;
+#ifdef WV2_DEBUG_SPRMS
+ wvlog << "############# Applying paragraph exceptions: " << cbUPX << std::endl;
+#endif
+ m_properties->pap().apply( data, cbUPX, parentStyle, &stylesheet, 0, version ); // try without data stream for now
+ data += cbUPX;
+#ifdef WV2_DEBUG_SPRMS
+ wvlog << "############# done" << std::endl;
+#endif
+
+ // character
+ cbUPX = readU16( data );
+ data += 2;
+#ifdef WV2_DEBUG_SPRMS
+ wvlog << "############# Applying character exceptions: " << cbUPX << std::endl;
+#endif
+ m_chp->apply( data, cbUPX, parentStyle, &stylesheet, 0, version ); // try without data stream for now
+#ifdef WV2_DEBUG_SPRMS
+ wvlog << "############# done" << std::endl;
+#endif
+ }
+ else if ( m_std->sgc == sgcChp ) {
+ const Style* parentStyle = 0;
+ // only try to unwrap the "parent" if the style isn't the Nil style
+ if ( m_std->istdBase != 0x0fff ) {
+ parentStyle = stylesheet.styleByIndex( m_std->istdBase );
+ if ( parentStyle ) {
+ wvlog << "##### in here, parent style = " << parentStyle->sti() << std::endl;
+ const_cast<Style*>( parentStyle )->unwrapStyle( stylesheet, version );
+ bool ok;
+ m_upechpx->istd = stylesheet.indexByID( m_std->sti, ok );
+ wvlog << "our istd = " << m_upechpx->istd << " sti = " << m_std->sti << std::endl;
+ mergeUpechpx( parentStyle, version );
+
+ // Normally we don't need the full CHP, but sprms like sprmCFBold are nasty and
+ // need that information (sometimes).
+ m_chp = new Word97::CHP();
+ m_chp->apply( m_upechpx->grpprl, m_upechpx->cb, parentStyle, &stylesheet, 0, version );
+ wvlog << "-------> fStrike = " << static_cast<int>( m_chp->fStrike ) << std::endl;
+ }
+ else
+ wvlog << "################# NO parent style for this character style found" << std::endl;
+ }
+ else
+ m_chp = new Word97::CHP(); // initialize stiNormalChar
+ }
+ else
+ wvlog << "Warning: Unknown style type code detected" << std::endl;
+ m_isWrapped = false;
+}
+
+U16 Style::sti() const
+{
+ if ( m_std )
+ return static_cast<U16>( m_std->sti );
+ return 0x0fff; // stiNil
+}
+
+UString Style::name() const
+{
+ if ( m_std )
+ return m_std->xstzName;
+ return UString::null;
+}
+
+U16 Style::followingStyle() const
+{
+ return m_std ? m_std->istdNext : 0x0fff;
+}
+
+Style::StyleType Style::type() const
+{
+ if ( m_std ) {
+ if ( m_std->sgc == sgcPara )
+ return sgcPara;
+ else if ( m_std->sgc == sgcChp )
+ return sgcChp;
+ }
+ return sgcUnknown;
+}
+
+const ParagraphProperties& Style::paragraphProperties() const
+{
+ if ( !m_properties ) {
+ wvlog << "You requested the PAP of a character style? Hmm..." << std::endl;
+ m_properties = new ParagraphProperties(); // let's return a default PAP, better than crashing
+ }
+ return *m_properties;
+}
+
+const Word97::CHP& Style::chp() const
+{
+ if ( !m_chp ) {
+ wvlog << "You requested the CHP of an unknown style type? Hmm..." << std::endl;
+ wvlog << "sti == " << m_std->sti << std::endl;
+ m_chp = new Word97::CHP(); // let's return a default CHP, better than crashing
+ }
+ return *m_chp;
+}
+
+const UPECHPX& Style::upechpx() const
+{
+ if ( !m_upechpx ) {
+ wvlog << "You requested the CHPX of a paragraph style? Hmm..." << std::endl;
+ m_upechpx = new UPECHPX(); // let's return a default UPECHPX, better than crashing
+ }
+ return *m_upechpx;
+}
+
+// Some code to assist in merging CHPXes
+namespace {
+ struct SprmEntry
+ {
+ SprmEntry( U16 sp, U16 offs ) : sprm( sp ), offset( offs ) {}
+ U16 sprm;
+ U16 offset;
+ };
+
+ bool operator<( const SprmEntry& rhs, const SprmEntry& lhs )
+ {
+ return rhs.sprm < lhs.sprm;
+ }
+
+ bool operator==( const SprmEntry& rhs, const SprmEntry& lhs )
+ {
+ return rhs.sprm == lhs.sprm;
+ }
+
+ void analyzeGrpprl( U8* grpprl, U16 count, std::vector<SprmEntry>& entries, WordVersion version )
+ {
+ U16 offset = 0;
+ while ( offset < count ) {
+ U16 sprm;
+ if ( version == Word8 ) {
+ sprm = readU16( grpprl );
+#ifdef WV2_DEBUG_SPRMS
+ wvlog << "####### offset: " << offset << " sprm: 0x" << std::hex << sprm << std::dec << std::endl;
+#endif
+ grpprl += sizeof( U16 );
+ }
+ else {
+ sprm = *grpprl++;
+#ifdef WV2_DEBUG_SPRMS
+ wvlog << "####### offset: " << offset << " sprm (Word6/7): " << sprm << std::endl;
+#endif
+ }
+ entries.push_back( SprmEntry( sprm, offset ) );
+ const U16 len = wvWare::Word97::SPRM::determineParameterLength( sprm, grpprl, version );
+ grpprl += len;
+ offset += len + ( version == Word8 ? 2 : 1 );
+ }
+ }
+
+ U16 copySprm( U8* destGrpprl, U8* srcGrpprl, const SprmEntry& entry, WordVersion version )
+ {
+ srcGrpprl += entry.offset;
+
+ U16 sprm;
+ if ( version == Word8 ) {
+ sprm = readU16( srcGrpprl );
+#ifdef WV2_DEBUG_SPRMS
+ wvlog << "####### Copying sprm 0x" << std::hex << sprm << std::dec << std::endl;
+#endif
+ srcGrpprl += sizeof( U16 );
+ }
+ else {
+ sprm = *srcGrpprl++;
+#ifdef WV2_DEBUG_SPRMS
+ wvlog << "####### Copying sprm (Word6/7) " << sprm << std::endl;
+#endif
+ }
+
+ if ( sprm != entry.sprm )
+ wvlog << "Ooops, we messed up the CHPX merging!" << std::endl;
+ const U16 len = wvWare::Word97::SPRM::determineParameterLength( sprm, srcGrpprl, version ) + ( version == Word8 ? 2 : 1 );
+ srcGrpprl -= version == Word8 ? 2 : 1; // back to the start
+ memcpy( destGrpprl, srcGrpprl, len );
+ return len;
+ }
+}
+
+void Style::mergeUpechpx( const Style* parentStyle, WordVersion version )
+{
+ // Analyze the source and the base grpprls
+ U8* srcGrpprl = m_std->grupx;
+ U16 cbUPX = readU16( srcGrpprl );
+ srcGrpprl += 2;
+ std::vector<SprmEntry> source;
+ analyzeGrpprl( srcGrpprl, cbUPX, source, version );
+
+ U8* baseGrpprl = parentStyle->m_upechpx->grpprl;
+ std::vector<SprmEntry> base;
+ analyzeGrpprl( baseGrpprl, parentStyle->m_upechpx->cb, base, version );
+
+ // Sort the created vectors
+ std::sort( source.begin(), source.end() );
+ std::sort( base.begin(), base.end() );
+
+ // Get enough room for the sprms of both chpxes
+ m_upechpx->grpprl = new U8[ parentStyle->m_upechpx->cb + cbUPX ];
+ U16 destCount = 0;
+
+ std::vector<SprmEntry>::const_iterator sourceIt = source.begin();
+ std::vector<SprmEntry>::const_iterator sourceEnd = source.end();
+ std::vector<SprmEntry>::const_iterator baseIt = base.begin();
+ std::vector<SprmEntry>::const_iterator baseEnd = base.end();
+ // First merge till one array is empty.
+ while ( sourceIt != sourceEnd && baseIt != baseEnd ) {
+ if ( *sourceIt < *baseIt ) {
+ destCount += copySprm( &m_upechpx->grpprl[ destCount ], srcGrpprl, *sourceIt, version );
+ ++sourceIt;
+ }
+ else if ( *sourceIt == *baseIt ) { // prefer the "new" entry
+ destCount += copySprm( &m_upechpx->grpprl[ destCount ], srcGrpprl, *sourceIt, version );
+ ++sourceIt;
+ ++baseIt;
+ }
+ else {
+ destCount += copySprm( &m_upechpx->grpprl[ destCount ], baseGrpprl, *baseIt, version );
+ ++baseIt;
+ }
+ }
+
+ // Then copy the rest of the longer grpprl
+ while ( sourceIt != sourceEnd ) {
+ destCount += copySprm( &m_upechpx->grpprl[ destCount ], srcGrpprl, *sourceIt, version );
+ ++sourceIt;
+ }
+ while ( baseIt != baseEnd ) {
+ destCount += copySprm( &m_upechpx->grpprl[ destCount ], baseGrpprl, *baseIt, version );
+ ++baseIt;
+ }
+ m_upechpx->cb = destCount;
+}
+
+
+StyleSheet::StyleSheet( OLEStreamReader* tableStream, U32 fcStshf, U32 lcbStshf )
+{
+ WordVersion version = Word8;
+
+ tableStream->push();
+ tableStream->seek( fcStshf, G_SEEK_SET );
+
+ const U16 cbStshi = tableStream->readU16();
+
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "StyleSheet::StyleSheet(): fcStshf=" << fcStshf << " lcbStshf=" << lcbStshf
+ << " cbStshi=" << cbStshi << std::endl;
+#endif
+
+ // First read the STSHI
+ if ( cbStshi == Word95::STSHI::sizeOf ) {
+ Word95::STSHI stsh( tableStream, false );
+ m_stsh = Word95::toWord97( stsh );
+ version = Word67; // okay, it's Word 6/7 after all
+ }
+ else if ( cbStshi == Word97::STSHI::sizeOf )
+ m_stsh.read( tableStream, false );
+ else {
+ wvlog << "Detected a different STSHI, check this (trying to read Word97 one)" << std::endl;
+ m_stsh.read( tableStream, false );
+ }
+
+ if ( tableStream->tell() != static_cast<int>( fcStshf + cbStshi + 2 ) ) {
+ wvlog << "Warning: STSHI too big? New version?"
+ << " Expected: " << cbStshi + 2 << " Read: " << tableStream->tell() - fcStshf << std::endl;
+ tableStream->seek( fcStshf + 2 + cbStshi, G_SEEK_SET );
+ }
+
+ // read all the styles
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "Reading in " << m_stsh.cstd << " styles." << std::endl;
+#endif
+ for( U16 i = 0; i < m_stsh.cstd; ++i )
+ m_styles.push_back( new Style( m_stsh.cbSTDBaseInFile,
+ tableStream,
+ m_stsh.rgftcStandardChpStsh ) );
+
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "Done reading the styles: " << tableStream->tell()
+ << " expected: " << fcStshf + lcbStshf << std::endl;
+#endif
+ if ( tableStream->tell() < static_cast<int>( fcStshf + lcbStshf ) )
+ wvlog << "Warning: Didn't read all bytes of the stylesheet..." << std::endl;
+ else if ( tableStream->tell() > static_cast<int>( fcStshf + lcbStshf ) )
+ wvlog << "BUG: Read past the stylesheet area!" << std::endl;
+
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "##### Starting to unwrap the styles" << std::endl;
+ int i = 0;
+#endif
+ // "unzip" them and build up the PAPs and CHPs
+ for ( std::vector<Style*>::iterator it = m_styles.begin(); it != m_styles.end(); ++it ) {
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "Unwrapping style: " << i << std::endl;
+ ++i;
+#endif
+ (*it)->unwrapStyle( *this, version );
+ }
+#ifdef WV2_DEBUG_STYLESHEET
+ wvlog << "##### Styles unwrapped" << std::endl;
+#endif
+ tableStream->pop();
+}
+
+StyleSheet::~StyleSheet()
+{
+ for ( std::vector<Style*>::iterator it = m_styles.begin(); it != m_styles.end(); ++it )
+ delete *it;
+}
+
+unsigned int StyleSheet::size() const
+{
+ return m_styles.size();
+}
+
+const Style* StyleSheet::styleByIndex( U16 istd ) const
+{
+ if ( istd < m_styles.size() )
+ return m_styles[ istd ];
+ return 0;
+}
+
+const Style* StyleSheet::styleByID( U16 sti ) const
+{
+ for ( std::vector<Style*>::const_iterator it = m_styles.begin(); it != m_styles.end(); ++it ) {
+ if ( (*it)->sti() == sti )
+ return *it;
+ }
+ return 0;
+}
+
+U16 StyleSheet::indexByID( U16 sti, bool& ok ) const
+{
+ ok = true;
+ U16 istd = 0;
+ for ( std::vector<Style*>::const_iterator it = m_styles.begin(); it != m_styles.end(); ++it, ++istd ) {
+ if ( (*it)->sti() == sti )
+ return istd;
+ }
+ ok = false;
+ return 0;
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/styles.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/styles.h
new file mode 100644
index 00000000..16710079
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/styles.h
@@ -0,0 +1,288 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef STYLES_H
+#define STYLES_H
+
+#include "word97_generated.h"
+
+namespace wvWare
+{
+
+class OLEStreamReader;
+class OLEStreamWriter;
+
+namespace Word97
+{
+
+/**
+ * STyle Definition (STD)
+ */
+struct STD
+{
+ /**
+ * Creates an empty STD structure and sets the defaults
+ */
+ STD();
+ /**
+ * Simply calls read(...)
+ */
+ STD( U16 baseSize, U16 totalSize, OLEStreamReader* stream, bool preservePos = false );
+ /**
+ * Attention: This struct allocates memory on the heap
+ */
+ STD( const STD& rhs );
+ ~STD();
+
+ STD& operator=( const STD& rhs );
+
+ /**
+ * This method reads the STD structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read( U16 baseSize, U16 totalSize, OLEStreamReader* stream, bool preservePos = false );
+
+ /**
+ * Same as reading :)
+ */
+ bool write( U16 baseSize, OLEStreamWriter* stream, bool preservePos = false ) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * invariant style identifier
+ */
+ U16 sti:12;
+
+ /**
+ * spare field for any temporary use, always reset back to zero!
+ */
+ U16 fScratch:1;
+
+ /**
+ * PHEs of all text with this style are wrong
+ */
+ U16 fInvalHeight:1;
+
+ /**
+ * UPEs have been generated
+ */
+ U16 fHasUpe:1;
+
+ /**
+ * std has been mass-copied; if unused at save time, style should be deleted
+ */
+ U16 fMassCopy:1;
+
+ /**
+ * style type code
+ */
+ U16 sgc:4;
+
+ /**
+ * base style
+ */
+ U16 istdBase:12;
+
+ /**
+ * # of UPXs (and UPEs)
+ */
+ U16 cupx:4;
+
+ /**
+ * next style
+ */
+ U16 istdNext:12;
+
+ /**
+ * offset to end of upx's, start of upe's
+ */
+ U16 bchUpe;
+
+ /**
+ * auto redefine style when appropriate
+ */
+ U16 fAutoRedef:1;
+
+ /**
+ * hidden from UI?
+ */
+ U16 fHidden:1;
+
+ /**
+ * unused bits
+ */
+ U16 unused8_3:14;
+
+ /**
+ * sub-names are separated by chDelimStyle
+ */
+ UString xstzName;
+
+ U8* grupx;
+
+ // Internal, for bookkeeping
+ U16 grupxLen;
+
+private:
+ void clearInternal();
+ void readStyleName( U16 baseSize, OLEStreamReader* stream );
+}; // STD
+
+bool operator==( const STD& lhs, const STD& rhs );
+bool operator!=( const STD& lhs, const STD& rhs );
+
+} // namespace Word97
+
+
+class StyleSheet;
+class ParagraphProperties;
+class ListInfoProvider;
+
+// The structure to hold the UPE for character styles.
+struct UPECHPX
+{
+ UPECHPX() : istd( 0 ), cb( 0 ), grpprl( 0 ) {}
+ ~UPECHPX() { delete [] grpprl; }
+
+ U16 istd;
+ U8 cb;
+ U8* grpprl;
+
+private:
+ UPECHPX( const UPECHPX& rhs );
+ UPECHPX& operator=( const UPECHPX& rhs );
+};
+
+/**
+ * This class represents one single style.
+ */
+// It would maybe be worth to optimize the construction a bit, like creating
+// the PAP and the CHP on copying from the base style, and not before (TODO)
+class Style
+{
+public:
+ enum StyleType { sgcUnknown = 0, sgcPara = 1, sgcChp = 2 };
+
+ Style( U16 baseSize, OLEStreamReader* tableStream, U16* ftc );
+ ~Style();
+
+ /**
+ * The stylesheet can have "empty" slots
+ */
+ bool isEmpty() const { return m_isEmpty; }
+ /**
+ * Did we already unwrap the style?
+ */
+ bool isWrapped() const { return m_isWrapped; }
+
+ /**
+ * Unwrap the style and create a valid PAP/CHP
+ */
+ void unwrapStyle( const StyleSheet& stylesheet, WordVersion version );
+
+ /**
+ * Get the (unique?) sti of that style
+ */
+ U16 sti() const;
+
+ /**
+ * Get the type of the style (paragraph/character style)
+ */
+ StyleType type() const;
+
+ /**
+ * Style name
+ */
+ UString name() const;
+
+ /**
+ * Id of following style
+ */
+ U16 followingStyle() const;
+
+ /*
+ * For paragraph styles only
+ */
+ const ParagraphProperties& paragraphProperties() const;
+ /*
+ * For paragraph styles only
+ */
+ const Word97::CHP& chp() const;
+ /*
+ * For character styles only
+ */
+ const UPECHPX& upechpx() const;
+
+private:
+ Style( const Style& rhs );
+ Style& operator=( const Style& rhs );
+
+ // This helper method merges two CHPX structures to one
+ // (needed for character styles)
+ void mergeUpechpx( const Style* parentStyle, WordVersion version );
+
+ bool m_isEmpty;
+ bool m_isWrapped;
+public:
+ Word97::STD* m_std;
+private:
+
+ mutable ParagraphProperties *m_properties; // "mutable" in case someone goes mad
+ mutable Word97::CHP *m_chp; // with the styles. We have to create a default style
+ mutable UPECHPX *m_upechpx; // to avoid crashes and still have to keep ownership!
+};
+
+
+/**
+ * This class holds all the styles this Word document
+ * defines. You can query styles by ID (sti) or index (istd)
+ */
+class StyleSheet
+{
+public:
+ StyleSheet( OLEStreamReader* tableStream, U32 fcStshf, U32 lcbStshf );
+ ~StyleSheet();
+
+ /**
+ * Return the number of styles.
+ */
+ unsigned int size() const;
+ const Style* styleByIndex( U16 istd ) const;
+
+ const Style* styleByID( U16 sti ) const;
+
+ U16 indexByID( U16 sti, bool& ok ) const;
+
+private:
+ StyleSheet( const StyleSheet& rhs );
+ StyleSheet& operator=( const StyleSheet& rhs );
+
+ Word97::STSHI m_stsh;
+ std::vector<Style*> m_styles;
+};
+
+} // namespace wvWare
+
+#endif // STYLES_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/textconverter.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/textconverter.cpp
new file mode 100644
index 00000000..af370a2d
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/textconverter.cpp
@@ -0,0 +1,340 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "textconverter.h"
+#include "ustring.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_ICONV_H
+#include <iconv.h>
+#endif
+#ifdef HAVE_SYS_ICONV_H
+#include <sys/iconv.h>
+#endif
+
+#include "wvlog.h"
+#include <errno.h>
+
+using namespace wvWare;
+
+class TextConverter::Private
+{
+public:
+ Private( const std::string& toCode, const std::string& fromCode ) :
+ m_toCode( toCode ), m_fromCode( fromCode ), m_iconv( reinterpret_cast<iconv_t>( -1 ) ) {}
+
+ Private( const std::string& fromCode ) :
+#ifdef WORDS_BIGENDIAN
+ m_toCode( "UNICODEBIG" ),
+#else
+ m_toCode( "UNICODELITTLE" ),
+#endif
+ m_fromCode( fromCode ), m_iconv( reinterpret_cast<iconv_t>( -1 ) ) {}
+
+ Private( U16 lid ) :
+#ifdef WORDS_BIGENDIAN
+ m_toCode( "UNICODEBIG" ),
+#else
+ m_toCode( "UNICODELITTLE" ),
+#endif
+ m_fromCode( TextConverter::LID2Codepage( lid ) ),
+ m_iconv( reinterpret_cast<iconv_t>( -1 ) ) {}
+
+
+ std::string m_toCode, m_fromCode;
+ iconv_t m_iconv;
+ bool m_swap;
+};
+
+TextConverter::TextConverter( const std::string& toCode, const std::string& fromCode ) :
+ d( new Private( toCode, fromCode ) )
+{
+ open();
+}
+
+TextConverter::TextConverter( const std::string& fromCode ) : d( new Private( fromCode ) )
+{
+ open();
+}
+
+TextConverter::TextConverter( U16 lid ) : d( new Private( lid ) )
+{
+ open();
+}
+
+TextConverter::~TextConverter()
+{
+ close();
+ delete d;
+}
+
+bool TextConverter::isOk() const
+{
+ return d->m_iconv != reinterpret_cast<iconv_t>( -1 );
+}
+
+void TextConverter::setToCode( const std::string& toCode )
+{
+ d->m_toCode = toCode;
+ close();
+ open();
+}
+
+std::string TextConverter::toCode() const
+{
+ return d->m_toCode;
+}
+
+void TextConverter::setFromCode( const std::string& fromCode )
+{
+ d->m_fromCode = fromCode;
+ close();
+ open();
+}
+
+std::string TextConverter::fromCode() const
+{
+ return d->m_fromCode;
+}
+
+UString TextConverter::convert( const std::string& input ) const
+{
+ return convert( input.c_str(), input.size() );
+}
+
+UString TextConverter::convert( const char* input, unsigned int length ) const
+{
+ if ( !isOk() ) {
+ wvlog << "Error: I don't have any open converter." << std::endl;
+ return UString();
+ }
+
+ // WinWord doesn't have multi-byte characters encoded in compressed-unicode
+ // sections, right?
+ UChar *output = new UChar[ length ];
+ char *p_output = reinterpret_cast<char*>( output );
+ size_t outputLen = length << 1;
+
+ const char* p_input = input;
+ size_t inputLen = length;
+
+ if ( static_cast<size_t>( -1 ) == iconv( d->m_iconv, const_cast<ICONV_CONST char**>( &p_input ), &inputLen, &p_output, &outputLen ) ) {
+ delete [] output;
+ // If we got more than one character, try to return as much text as possible...
+ // To convert the text with as few iconv calls as possible we are using a divide
+ // and conquer approach.
+ if ( length > 1 ) {
+ UString ustring( convert( input, length / 2 ) );
+ ustring += convert( input + length / 2, ( length + 1 ) / 2 );
+ return ustring;
+ }
+ else {
+ wvlog << "Error: The conversion was not successful: " << errno << std::endl;
+ return UString();
+ }
+ }
+
+ if ( outputLen != 0 || ( outputLen & 0x00000001 ) == 1 )
+ wvlog << "Strange, got an outputLen of " << outputLen << std::endl;
+
+ UString ustring( output, length - ( outputLen >> 1 ), true );
+ delete [] output;
+ return ustring;
+}
+
+U16 TextConverter::locale2LID( U8 nLocale )
+{
+ switch ( nLocale ) {
+ case 134: // Chinese Simplified
+ return 0x804;
+ case 136: // Chinese Traditional
+ return 0x404;
+ // Add Japanese, Korean and whatever nLocale you see fit.
+ default:
+ return 0x0;
+ }
+}
+
+const char* TextConverter::LID2lang( U16 lid )
+{
+ switch ( lid ) {
+ case 0x0405:
+ return "cs-CZ";
+ case 0x0406:
+ return "da-DK";
+ case 0x0807: /* swiss german */
+ case 0x0407: /* german */
+ return "de-DE";
+ case 0x0809: /* british english */
+ return "en-GB";
+ case 0x0c09:
+ return "en-AU";
+ case 0x0413: /* dutch */
+ return "da-NL"; /* netherlands */
+ case 0x040a: /* castillian */
+ case 0x080a: /* mexican */
+ return "es-ES";
+ case 0x040b:
+ return "fi-FI";
+ case 0x040c:
+ return "fr-FR";
+ case 0x0410:
+ return "it-IT";
+ case 0x040d: /* hebrew */
+ return "iw-IL";
+ case 0x0416: /* brazilian */
+ case 0x0816: /* portugese */
+ return "pt-PT";
+ case 0x0419:
+ return "ru-RU";
+ case 0x041d:
+ return "sv-SE";
+ case 0x0400:
+ return "-none-";
+ case 0x0409:
+ default:
+ return "en-US";
+ }
+}
+
+const char* TextConverter::LID2Codepage( U16 lid )
+{
+ static const char *cp874 = "CP874";
+ static const char *cp932 = "CP932";
+ static const char *cp936 = "CP936";
+ static const char *cp949 = "CP949";
+ static const char *cp950 = "CP950";
+ static const char *cp1250 = "CP1250";
+ static const char *cp1251 = "CP1251";
+ static const char *cp1252 = "CP1252";
+ static const char *cp1253 = "CP1253";
+ static const char *cp1254 = "CP1254";
+ static const char *cp1255 = "CP1255";
+ static const char *cp1256 = "CP1256";
+ static const char *cp1257 = "CP1257";
+ static const char *unknown = "not known";
+
+ // Work around spec bugs. Thomas Zander's documents had very
+ // weird lid codes. Mac Word?
+ if ( lid < 999 )
+ lid = fixLID( lid );
+
+ switch ( lid ) {
+ case 0x0401: /*Arabic*/ return cp1256;
+ case 0x0402: /*Bulgarian*/ return cp1251;
+ case 0x0403: /*Catalan*/ return cp1252;
+ case 0x0404: /*Traditional Chinese*/ return cp950;
+ case 0x0804: /*Simplified Chinese*/ return cp936;
+ case 0x0405: /*Czech*/ return cp1250;
+ case 0x0406: /*Danish*/ return cp1252;
+ case 0x0407: /*German*/ return cp1252;
+ case 0x0807: /*Swiss German*/ return cp1252;
+ case 0x0408: /*Greek*/ return cp1253;
+ case 0x0409: /*U.S. English*/ return cp1252;
+ case 0x0809: /*U.K. English*/ return cp1252;
+ case 0x0c09: /*Australian English*/ return cp1252;
+ case 0x040a: /*Castilian Spanish*/ return cp1252;
+ case 0x080a: /*Mexican Spanish*/ return cp1252;
+ case 0x0c0a: /*Traditional Spanish*/ return cp1252; // TBD: Undocumented!
+ case 0x040b: /*Finnish*/ return cp1252;
+ case 0x040c: /*French*/ return cp1252;
+ case 0x080c: /*Belgian French*/ return cp1252;
+ case 0x0c0c: /*Canadian French*/ return cp1252;
+ case 0x100c: /*Swiss French*/ return cp1252;
+ case 0x040d: /*Hebrew*/ return cp1255;
+ case 0x040e: /*Hungarian*/ return cp1250;
+ case 0x040f: /*Icelandic*/ return cp1252;
+ case 0x0410: /*Italian*/ return cp1252;
+ case 0x0810: /*Swiss Italian*/ return cp1252;
+ case 0x0411: /*Japanese*/ return cp932;
+ case 0x0412: /*Korean*/ return cp949;
+ case 0x0413: /*Dutch*/ return cp1252;
+ case 0x0813: /*Belgian Dutch*/ return cp1252;
+ case 0x0414: /*Norwegian - Bokmal*/ return cp1252;
+ case 0x0814: /*Norwegian - Nynorsk*/ return cp1252;
+ case 0x0415: /*Polish*/ return cp1250;
+ case 0x0416: /*Brazilian Portuguese*/ return cp1252;
+ case 0x0816: /*Portuguese*/ return cp1252;
+ case 0x0417: /*Rhaeto-Romanic*/ return cp1252;
+ case 0x0418: /*Romanian*/ return cp1252;
+ case 0x0419: /*Russian*/ return cp1251;
+ case 0x041a: /*Croato-Serbian (Latin)*/ return cp1250;
+ case 0x081a: /*Serbo-Croatian (Cyrillic) */ return cp1252;
+ case 0x041b: /*Slovak*/ return cp1250;
+ case 0x041c: /*Albanian*/ return cp1251;
+ case 0x041d: /*Swedish*/ return cp1252;
+ case 0x041e: /*Thai*/ return cp874;
+ case 0x041f: /*Turkish*/ return cp1254;
+ case 0x0420: /*Urdu*/ return cp1256;
+ case 0x0421: /*Bahasa*/ return cp1256;
+ case 0x0422: /*Ukrainian*/ return cp1251;
+ case 0x0423: /*Byelorussian*/ return cp1251;
+ case 0x0424: /*Slovenian*/ return cp1250;
+ case 0x0425: /*Estonian*/ return cp1257;
+ case 0x0426: /*Latvian*/ return cp1257;
+ case 0x0427: /*Lithuanian*/ return cp1257;
+ case 0x0429: /*Farsi*/ return cp1256;
+ case 0x042D: /*Basque*/ return cp1252;
+ case 0x042F: /*Macedonian*/ return cp1251;
+ case 0x0436: /*Afrikaans*/ return cp1252;
+ case 0x043E: /*Malaysian*/ return cp1251;
+ default: return unknown;
+ }
+}
+
+void TextConverter::close()
+{
+ if ( d->m_iconv != reinterpret_cast<iconv_t>( -1 ) )
+ iconv_close( d->m_iconv );
+ d->m_iconv = reinterpret_cast<iconv_t>( -1 );
+}
+
+void TextConverter::open()
+{
+ if ( d->m_iconv != reinterpret_cast<iconv_t>( -1 ) ) {
+ wvlog << "Warning: Do you really want to get rid of the current converter?" << std::endl;
+ close();
+ }
+#ifdef WORDS_BIGENDIAN
+ if ( d->m_toCode != "UNICODEBIG" )
+ wvlog << "Warning: Do you really want to do convert to something else than UNICODEBIG?" << std::endl;
+#else
+ if ( d->m_toCode != "UNICODELITTLE" )
+ wvlog << "Warning: Do you really want to do convert to something else than UNICODELITTLE?" << std::endl;
+#endif
+ if ( d->m_fromCode == "not known" )
+ wvlog << "Warning: We don't know the current charset you want to convert from!" << std::endl;
+
+ if ( !d->m_toCode.empty() && !d->m_fromCode.empty() )
+ d->m_iconv = iconv_open( d->m_toCode.c_str(), d->m_fromCode.c_str() );
+}
+
+U16 TextConverter::fixLID( U16 nLocale )
+{
+ // I have no idea which code these nLocale numbers are, but the
+ // files in ftp://dkuug.dk/i18n/charmaps look promising. If another
+ // one of those files turns out to be right I'll add the remaining
+ // mappings.
+ switch( nLocale ) {
+ case 0x13: /* Dutch */ return 0x0413;
+ default: return nLocale;
+ }
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/textconverter.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/textconverter.h
new file mode 100644
index 00000000..443966c6
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/textconverter.h
@@ -0,0 +1,132 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef TEXTCONVERTER_H
+#define TEXTCONVERTER_H
+
+#include "global.h"
+#include <string>
+
+namespace wvWare
+{
+
+class UString;
+
+/**
+ * A small tool class to provide a convenient interface to iconv.
+ */
+class TextConverter
+{
+public:
+ /**
+ * Construct a TextConverter
+ */
+ TextConverter( const std::string& toCode, const std::string& fromCode );
+ /**
+ * Constructs a TextConverter which converts to UCS-2
+ */
+ TextConverter( const std::string& fromCode );
+ /**
+ * Constructs a TextConverter which converts from the proper
+ * codepage for the given lid to UCS-2. This is probably what
+ * you want to use.
+ */
+ TextConverter( U16 lid );
+
+ /**
+ * Properly cleans up
+ */
+ ~TextConverter();
+
+ /**
+ * Is the converter okay?
+ */
+ bool isOk() const;
+
+ /**
+ * Change the converter to convert to that code
+ */
+ void setToCode( const std::string& toCode );
+ std::string toCode() const;
+
+ /**
+ * Change the converter to convert from that code
+ */
+ void setFromCode( const std::string& fromCode );
+ std::string fromCode() const;
+
+ /**
+ * Convert the string to the specified encoding (most likely UCS-2).
+ * Note: No other conversions are really supported, as we don't
+ * need them anyway.
+ */
+ UString convert( const std::string& input ) const;
+
+ /**
+ * Convert the string to the specified encoding (most likely UCS-2).
+ * Note: No other conversions are really supported, as we don't
+ * need them anyway.
+ */
+ UString convert( const char* input, unsigned int length ) const;
+
+ /**
+ * "stolen" from wvWare, guesses a lid for some locales.
+ */
+ static U16 locale2LID( U8 nLocale );
+
+ /**
+ * "stolen" from the wvWare, guesses a lang for some lids.
+ */
+ static const char* LID2lang( U16 lid );
+
+ /**
+ * returns the appropriate codepage for the given lid.
+ */
+ static const char* LID2Codepage( U16 lid );
+
+private:
+ /**
+ * Don't copy us
+ */
+ TextConverter( const TextConverter& rhs );
+ /**
+ * Don't assign us
+ */
+ TextConverter& operator=( const TextConverter& rhs );
+
+ /**
+ * Closes the old converter
+ */
+ void close();
+
+ /**
+ * Opens a converter
+ */
+ void open();
+
+ static U16 fixLID( U16 nLocale );
+
+ // We need this private impl. to hide the iconv_t in the source file. The
+ // reason is that we can't #include <config.h> in the header file!
+ class Private;
+ Private* d;
+};
+
+} // namespace wvWare
+
+#endif // TEXTCONVERTER_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/ustring.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/ustring.cpp
new file mode 100644
index 00000000..ce270913
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/ustring.cpp
@@ -0,0 +1,638 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 1999-2000 Harri Porten ([email protected])
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ustring.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif
+#ifdef HAVE_FLOAT_H
+#include <float.h>
+#endif
+#ifdef HAVE_IEEEFP_H
+#include <ieeefp.h>
+#endif
+
+namespace wvWare {
+#ifdef WORDS_BIGENDIAN
+ unsigned char NaN_Bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 };
+ unsigned char Inf_Bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 };
+#elif defined(arm)
+ unsigned char NaN_Bytes[] = { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 };
+ unsigned char Inf_Bytes[] = { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 };
+#else
+ unsigned char NaN_Bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f };
+ unsigned char Inf_Bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
+#endif
+
+ const double NaN = *( reinterpret_cast<const double*>( NaN_Bytes ) );
+ const double Inf = *( reinterpret_cast<const double*>( Inf_Bytes ) );
+}
+
+using namespace wvWare;
+
+bool wvWare::isNaN(double d)
+{
+#ifdef HAVE_FUNC_ISNAN
+ return isnan(d);
+#elif defined HAVE_FLOAT_H
+ return _isnan(d) != 0;
+#else
+ return !(d == d);
+#endif
+}
+
+bool wvWare::isPosInf(double d)
+{
+#if defined(HAVE_FUNC_ISINF)
+ return (isinf(d) == 1);
+#elif defined(HAVE_FUNC_FINITE)
+ return finite(d) == 0 && d == d; // ### can we distinguish between + and - ?
+#elif defined(HAVE_FUNC__FINITE)
+ return _finite(d) == 0 && d == d; // ###
+#else
+ return false;
+#endif
+}
+
+bool wvWare::isNegInf(double d)
+{
+#if defined(HAVE_FUNC_ISINF)
+ return (isinf(d) == -1);
+#elif defined(HAVE_FUNC_FINITE)
+ return finite(d) == 0 && d == d; // ###
+#elif defined(HAVE_FUNC__FINITE)
+ return _finite(d) == 0 && d == d; // ###
+#else
+ return false;
+#endif
+}
+
+CString::CString(const char *c)
+{
+ data = new char[strlen(c)+1];
+ strcpy(data, c);
+}
+
+CString::CString(const CString &b)
+{
+ data = new char[b.length()+1];
+ strcpy(data, b.c_str());
+}
+
+CString::~CString()
+{
+ delete [] data;
+}
+
+CString &CString::append(const CString &t)
+{
+ char *n;
+ if (data) {
+ n = new char[strlen(data)+t.length()+1];
+ strcpy(n, data);
+ } else {
+ n = new char[t.length()+1];
+ n[0] = '\0';
+ }
+ strcat(n, t.c_str());
+
+ delete [] data;
+ data = n;
+
+ return *this;
+}
+
+CString &CString::operator=(const char *c)
+{
+ if (data)
+ delete [] data;
+ data = new char[strlen(c)+1];
+ strcpy(data, c);
+
+ return *this;
+}
+
+CString &CString::operator=(const CString &str)
+{
+ if (this == &str)
+ return *this;
+
+ if (data)
+ delete [] data;
+ data = new char[str.length()+1];
+ strcpy(data, str.c_str());
+
+ return *this;
+}
+
+CString &CString::operator+=(const CString &str)
+{
+ return append(CString(str.c_str()));
+}
+
+int CString::length() const
+{
+ return strlen(data);
+}
+
+bool wvWare::operator==(const wvWare::CString& c1, const wvWare::CString& c2)
+{
+ return (strcmp(c1.c_str(), c2.c_str()) == 0);
+}
+
+UChar UChar::null;
+UString::Rep UString::Rep::null = { 0, 0, 1 };
+UString UString::null;
+static char *statBuffer = 0L;
+
+UChar::UChar(const UCharReference &c)
+ : uc( c.unicode() )
+{
+}
+
+UChar UChar::toLower() const
+{
+ // ### properly support unicode tolower
+ if (uc >= 256 || islower(uc))
+ return *this;
+
+ return UChar(tolower(uc));
+}
+
+UChar UChar::toUpper() const
+{
+ if (uc >= 256 || isupper(uc))
+ return *this;
+
+ return UChar(toupper(uc));
+}
+
+UCharReference& UCharReference::operator=(UChar c)
+{
+ str->detach();
+ if (offset < str->rep->len)
+ *(str->rep->dat + offset) = c;
+ /* TODO: lengthen string ? */
+ return *this;
+}
+
+UChar& UCharReference::ref() const
+{
+ if (offset < str->rep->len)
+ return *(str->rep->dat + offset);
+ else
+ return UChar::null;
+}
+
+namespace {
+ // return an uninitialized UChar array of size s
+ static inline UChar* allocateChars(int s)
+ {
+ // work around default UChar constructor code
+ return reinterpret_cast<UChar*>(new short[s]);
+ }
+}
+
+UString::Rep *UString::Rep::create(UChar *d, int l)
+{
+ Rep *r = new Rep;
+ r->dat = d;
+ r->len = l;
+ r->rc = 1;
+
+ return r;
+}
+
+UString::UString()
+{
+ null.rep = &Rep::null;
+ attach(&Rep::null);
+}
+
+UString::UString(char c)
+{
+ UChar *d = allocateChars( 1 );
+ d[0] = UChar(0, c);
+ rep = Rep::create(d, 1);
+}
+
+UString::UString(UChar c)
+{
+ UChar *d = allocateChars( 1 );
+ d[0] = c;
+ rep = Rep::create(d, 1);
+}
+
+UString::UString(const char *c)
+{
+ attach(&Rep::null);
+ operator=(c);
+}
+
+UString::UString(const UChar *c, int length)
+{
+ UChar *d = allocateChars( length );
+ memcpy(d, c, length * sizeof(UChar));
+ rep = Rep::create(d, length);
+}
+
+UString::UString(UChar *c, int length, bool copy)
+{
+ UChar *d;
+ if (copy) {
+ d = allocateChars( length );
+ memcpy(d, c, length * sizeof(UChar));
+ } else
+ d = c;
+ rep = Rep::create(d, length);
+}
+
+UString::UString(const UString &b)
+{
+ attach(b.rep);
+}
+
+UString::~UString()
+{
+ release();
+}
+
+UString UString::from(int i)
+{
+ char buf[40];
+ sprintf(buf, "%d", i);
+
+ return UString(buf);
+}
+
+UString UString::from(unsigned int u)
+{
+ char buf[40];
+ sprintf(buf, "%u", u);
+
+ return UString(buf);
+}
+
+UString UString::from(double d)
+{
+ char buf[40];
+
+ if (d == -0)
+ strcpy(buf,"0");
+ else if (isNaN(d))
+ strcpy(buf,"NaN");
+ else if (isPosInf(d))
+ strcpy(buf,"Infinity");
+ else if (isNegInf(d))
+ strcpy(buf,"-Infinity");
+ else
+ sprintf(buf, "%.16g", d); // does the right thing
+
+ // ECMA 3rd ed. 9.8.1 9 e: "with no leading zeros"
+ int buflen = strlen(buf);
+ if (buflen >= 4 && buf[buflen-4] == 'e' && buf[buflen-2] == '0') {
+ buf[buflen-2] = buf[buflen-1];
+ buf[buflen-1] = 0;
+ }
+
+ return UString(buf);
+}
+
+UString &UString::append(const UString &t)
+{
+ int l = length();
+ UChar *n = allocateChars( l+t.length() );
+ memcpy(n, data(), l * sizeof(UChar));
+ memcpy(n+l, t.data(), t.length() * sizeof(UChar));
+ release();
+ rep = Rep::create(n, l + t.length());
+
+ return *this;
+}
+
+CString UString::cstring() const
+{
+ return CString(ascii());
+}
+
+char *UString::ascii() const
+{
+ if (statBuffer)
+ delete [] statBuffer;
+
+ statBuffer = new char[length()+1];
+ for(int i = 0; i < length(); i++)
+ statBuffer[i] = data()[i].low();
+ statBuffer[length()] = '\0';
+
+ return statBuffer;
+}
+
+UString &UString::operator=(const char *c)
+{
+ release();
+ int l = c ? strlen(c) : 0;
+ UChar *d = allocateChars( l );
+ for (int i = 0; i < l; i++)
+ d[i].uc = static_cast<unsigned char>( c[i] );
+ rep = Rep::create(d, l);
+
+ return *this;
+}
+
+UString &UString::operator=(const UString &str)
+{
+ str.rep->ref();
+ release();
+ rep=str.rep;
+
+ return *this;
+}
+
+UString &UString::operator+=(const UString &s)
+{
+ return append(s);
+}
+
+bool UString::is8Bit() const
+{
+ const UChar *u = data();
+ for(int i = 0; i < length(); i++, u++)
+ if (u->uc > 0xFF)
+ return false;
+
+ return true;
+}
+
+UChar UString::operator[](int pos) const
+{
+ if (pos >= length())
+ return UChar::null;
+
+ return static_cast<const UChar *>( data() )[pos];
+}
+
+UCharReference UString::operator[](int pos)
+{
+ /* TODO: boundary check */
+ return UCharReference(this, pos);
+}
+
+double UString::toDouble( bool tolerant ) const
+{
+ double d;
+
+ if (!is8Bit())
+ return NaN;
+
+ CString str = cstring();
+ const char *c = str.c_str();
+
+ // skip leading white space
+ while (isspace(*c))
+ c++;
+
+ // empty string ?
+ if (*c == '\0')
+ return tolerant ? NaN : 0.0;
+
+ // hex number ?
+ if (*c == '0' && (*(c+1) == 'x' || *(c+1) == 'X')) {
+ c++;
+ d = 0.0;
+ while (*(++c)) {
+ if (*c >= '0' && *c <= '9')
+ d = d * 16.0 + *c - '0';
+ else if ((*c >= 'A' && *c <= 'F') || (*c >= 'a' && *c <= 'f'))
+ d = d * 16.0 + (*c & 0xdf) - 'A' + 10.0;
+ else
+ break;
+ }
+ } else {
+ // regular number ?
+ char *end;
+ d = strtod(c, &end);
+ if ((d != 0.0 || end != c) && d != HUGE_VAL && d != -HUGE_VAL) {
+ c = end;
+ } else {
+ // infinity ?
+ d = 1.0;
+ if (*c == '+')
+ c++;
+ else if (*c == '-') {
+ d = -1.0;
+ c++;
+ }
+ if (strncmp(c, "Infinity", 8) != 0)
+ return NaN;
+ d = d * Inf;
+ c += 8;
+ }
+ }
+
+ // allow trailing white space
+ while (isspace(*c))
+ c++;
+ // don't allow anything after - unless tolerant=true
+ if ( !tolerant && *c != '\0')
+ d = NaN;
+
+ return d;
+}
+
+unsigned long UString::toULong(bool *ok) const
+{
+ double d = toDouble();
+ bool b = true;
+
+ if (isNaN(d) || d != static_cast<unsigned long>(d)) {
+ b = false;
+ d = 0;
+ }
+
+ if (ok)
+ *ok = b;
+
+ return static_cast<unsigned long>(d);
+}
+
+int UString::find(const UString &f, int pos) const
+{
+ if (isNull())
+ return -1;
+ long fsize = f.length() * sizeof(UChar);
+ if (pos < 0)
+ pos = 0;
+ const UChar *end = data() + length() - f.length();
+ for (const UChar *c = data() + pos; c <= end; c++)
+ if (!memcmp(c, f.data(), fsize))
+ return (c-data());
+
+ return -1;
+}
+
+int UString::rfind(const UString &f, int pos) const
+{
+ if (isNull())
+ return -1;
+ if (pos + f.length() >= length())
+ pos = length() - f.length();
+ long fsize = f.length() * sizeof(UChar);
+ for (const UChar *c = data() + pos; c >= data(); c--) {
+ if (!memcmp(c, f.data(), fsize))
+ return (c-data());
+ }
+
+ return -1;
+}
+
+UString UString::substr(int pos, int len) const
+{
+ if (isNull())
+ return UString();
+ if (pos < 0)
+ pos = 0;
+ else if (pos >= static_cast<int>( length() ))
+ pos = length();
+ if (len < 0)
+ len = length();
+ if (pos + len >= static_cast<int>( length() ))
+ len = length() - pos;
+
+ UChar *tmp = allocateChars( len );
+ memcpy(tmp, data()+pos, len * sizeof(UChar));
+ UString result(tmp, len);
+ delete [] tmp;
+
+ return result;
+}
+
+void UString::attach(Rep *r)
+{
+ rep = r;
+ rep->ref();
+}
+
+void UString::detach()
+{
+ if (rep->rc > 1) {
+ int l = length();
+ UChar *n = allocateChars( l );
+ memcpy(n, data(), l * sizeof(UChar));
+ release();
+ rep = Rep::create(n, l);
+ }
+}
+
+void UString::release()
+{
+ if (!rep->deref()) {
+ delete [] rep->dat;
+ delete rep;
+ }
+}
+
+bool wvWare::operator==(const UString& s1, const UString& s2)
+{
+ if (s1.rep->len != s2.rep->len)
+ return false;
+
+ return (memcmp(s1.rep->dat, s2.rep->dat,
+ s1.rep->len * sizeof(UChar)) == 0);
+}
+
+bool wvWare::operator==(const UString& s1, const char *s2)
+{
+ if (s2 == 0L && s1.isNull())
+ return true;
+
+ if (s1.length() != static_cast<int>( strlen(s2) ))
+ return false;
+
+ const UChar *u = s1.data();
+ while (*s2) {
+ if (u->uc != *s2 )
+ return false;
+ s2++;
+ u++;
+ }
+
+ return true;
+}
+
+bool wvWare::operator<(const UString& s1, const UString& s2)
+{
+ const int l1 = s1.length();
+ const int l2 = s2.length();
+ const int lmin = l1 < l2 ? l1 : l2;
+ const UChar *c1 = s1.data();
+ const UChar *c2 = s2.data();
+ int l = 0;
+ while (l < lmin && *c1 == *c2) {
+ c1++;
+ c2++;
+ l++;
+ }
+ if (l < lmin)
+ return (c1->unicode() < c2->unicode());
+
+ return (l1 < l2);
+}
+
+UString wvWare::operator+(const UString& s1, const UString& s2)
+{
+ UString tmp(s1);
+ tmp.append(s2);
+
+ return tmp;
+}
+
+
+UConstString::UConstString( UChar* data, unsigned int length ) : UString( data, length, false )
+{
+}
+
+UConstString::~UConstString()
+{
+ if ( rep->rc > 1 ) {
+ int l = length();
+ UChar* n = allocateChars( l );
+ memcpy( n, data(), l * sizeof( UChar ) );
+ rep->dat = n;
+ }
+ else
+ rep->dat = 0;
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/ustring.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/ustring.h
new file mode 100644
index 00000000..e4eaec4f
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/ustring.h
@@ -0,0 +1,396 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 1999-2000 Harri Porten ([email protected])
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _KJS_USTRING_H_
+#define _KJS_USTRING_H_
+
+#include "dllmagic.h"
+
+namespace wvWare {
+
+ /**
+ * @return True if d is not a number (platform support required).
+ */
+ bool isNaN(double d);
+
+ bool isPosInf(double d);
+ bool isNegInf(double d);
+
+ class UCharReference;
+ class UString;
+ class UConstString;
+
+ /**
+ * @short Unicode character.
+ *
+ * UChar represents a 16 bit Unicode character. It's internal data
+ * representation is compatible to XChar2b and QChar. It's therefore
+ * possible to exchange data with X and Qt with shallow copies.
+ */
+ struct UChar {
+ /**
+ * Construct a character with value 0.
+ */
+ UChar();
+ /**
+ * Construct a character with the value denoted by the arguments.
+ * @param h higher byte
+ * @param l lower byte
+ */
+ UChar(unsigned char h , unsigned char l);
+ /**
+ * Construct a character with the given value.
+ * @param u 16 bit Unicode value
+ */
+ UChar(unsigned short u);
+ UChar(const UCharReference &c);
+ /**
+ * @return The higher byte of the character.
+ */
+ unsigned char high() const { return uc >> 8; }
+ /**
+ * @return The lower byte of the character.
+ */
+ unsigned char low() const { return uc & 0xFF; }
+ /**
+ * @return the 16 bit Unicode value of the character
+ */
+ unsigned short unicode() const { return uc; }
+ public:
+ /**
+ * @return The character converted to lower case.
+ */
+ UChar toLower() const;
+ /**
+ * @return The character converted to upper case.
+ */
+ UChar toUpper() const;
+ /**
+ * A static instance of UChar(0).
+ */
+ static UChar null;
+ private:
+ friend class UCharReference;
+ friend class UString;
+ friend bool operator==(const UChar &c1, const UChar &c2);
+ friend bool operator==(const UString& s1, const char *s2);
+ friend bool operator<(const UString& s1, const UString& s2);
+
+ unsigned short uc;
+ };
+
+ inline UChar::UChar() : uc(0) { }
+ inline UChar::UChar(unsigned char h , unsigned char l) : uc(h << 8 | l) { }
+ inline UChar::UChar(unsigned short u) : uc(u) { }
+
+ /**
+ * @short Dynamic reference to a string character.
+ *
+ * UCharReference is the dynamic counterpart of @ref UChar. It's used when
+ * characters retrieved via index from a @ref UString are used in an
+ * assignment expression (and therefore can't be treated as being const):
+ * <pre>
+ * UString s("hello world");
+ * s[0] = 'H';
+ * </pre>
+ *
+ * If that sounds confusing your best bet is to simply forget about the
+ * existance of this class and treat is as being identical to @ref UChar.
+ */
+ class UCharReference {
+ friend class UString;
+ UCharReference(UString *s, unsigned int off) : str(s), offset(off) { }
+ public:
+ /**
+ * Set the referenced character to c.
+ */
+ UCharReference& operator=(UChar c);
+ /**
+ * Same operator as above except the argument that it takes.
+ */
+ UCharReference& operator=(char c) { return operator=(UChar(c)); }
+ /**
+ * @return Unicode value.
+ */
+ unsigned short unicode() const { return ref().unicode(); }
+ /**
+ * @return Lower byte.
+ */
+ unsigned char low() const { return ref().uc & 0xFF; }
+ /**
+ * @return Higher byte.
+ */
+ unsigned char high() const { return ref().uc >> 8; }
+ /**
+ * @return Character converted to lower case.
+ */
+ UChar toLower() const { return ref().toLower(); }
+ /**
+ * @return Character converted to upper case.
+ */
+ UChar toUpper() const { return ref().toUpper(); }
+ private:
+ // not implemented, can only be constructed from UString
+ UCharReference();
+
+ UChar& ref() const;
+ UString *str;
+ int offset;
+ };
+
+ /**
+ * @short 8 bit char based string class
+ */
+ class CString {
+ public:
+ CString() : data(0L) { }
+ explicit CString(const char *c);
+ CString(const CString &);
+
+ ~CString();
+
+ CString &append(const CString &);
+ CString &operator=(const char *c);
+ CString &operator=(const CString &);
+ CString &operator+=(const CString &);
+
+ int length() const;
+ const char *c_str() const { return data; }
+ private:
+ char *data;
+ };
+
+ /**
+ * @short Unicode string class
+ */
+ class WV2_DLLEXPORT UString {
+ friend bool operator==(const UString&, const UString&);
+ friend class UCharReference;
+ friend class UConstString;
+ /**
+ * @internal
+ */
+ struct Rep {
+ friend class UString;
+ friend bool operator==(const UString&, const UString&);
+ static Rep *create(UChar *d, int l);
+ inline UChar *data() const { return dat; }
+ inline int length() const { return len; }
+
+ inline void ref() { rc++; }
+ inline int deref() { return --rc; }
+
+ UChar *dat;
+ int len;
+ int rc;
+ static Rep null;
+ };
+
+ public:
+ /**
+ * Constructs a null string.
+ */
+ UString();
+ /**
+ * Constructs a string from the single character c.
+ */
+ explicit UString(char c);
+ /**
+ * Constructs a string from the single character c.
+ */
+ explicit UString(UChar c);
+ /**
+ * Constructs a string from a classical zero determined char string.
+ */
+ explicit UString(const char *c);
+ /**
+ * Constructs a string from an array of Unicode characters of the specified
+ * length.
+ */
+ UString(const UChar *c, int length);
+ /**
+ * If copy is false a shallow copy of the string will be created. That
+ * means that the data will NOT be copied and you'll have to guarantee that
+ * it doesn't get deleted during the lifetime of the UString object.
+ */
+ UString(UChar *c, int length, bool copy);
+ /**
+ * Copy constructor. Makes a shallow copy only.
+ */
+ UString(const UString &);
+ /**
+ * Destructor. If this handle was the only one holding a reference to the
+ * string the data will be freed.
+ */
+ ~UString();
+
+ /**
+ * Constructs a string from an int.
+ */
+ static UString from(int i);
+ /**
+ * Constructs a string from an unsigned int.
+ */
+ static UString from(unsigned int u);
+ /**
+ * Constructs a string from a double.
+ */
+ static UString from(double d);
+
+ /**
+ * Append another string.
+ */
+ UString &append(const UString &);
+
+ /**
+ * @return The string converted to the 8-bit string type @ref CString().
+ */
+ CString cstring() const;
+ /**
+ * Convert the Unicode string to plain ASCII chars chopping of any higher
+ * bytes. This method should only be used for *debugging* purposes as it
+ * is neither Unicode safe nor free from side effects. In order not to
+ * waste any memory the char buffer is static and *shared* by all UString
+ * instances.
+ */
+ char *ascii() const;
+
+ /**
+ * Assignment operator.
+ */
+ UString &operator=(const char *c);
+ /**
+ * Assignment operator.
+ */
+ UString &operator=(const UString &);
+ /**
+ * Appends the specified string.
+ */
+ UString &operator+=(const UString &s);
+
+ /**
+ * @return A pointer to the internal Unicode data.
+ */
+ const UChar* data() const { return rep->data(); }
+ /**
+ * @return True if null.
+ */
+ bool isNull() const { return (rep == &Rep::null); }
+ /**
+ * @return True if null or zero length.
+ */
+ bool isEmpty() const { return (!rep->len); }
+ /**
+ * Use this if you want to make sure that this string is a plain ASCII
+ * string. For example, if you don't want to lose any information when
+ * using @ref cstring() or @ref ascii().
+ *
+ * @return True if the string doesn't contain any non-ASCII characters.
+ */
+ bool is8Bit() const;
+ /**
+ * @return The length of the string.
+ */
+ int length() const { return rep->length(); }
+ /**
+ * Const character at specified position.
+ */
+ UChar operator[](int pos) const;
+ /**
+ * Writable reference to character at specified position.
+ */
+ UCharReference operator[](int pos);
+
+ /**
+ * Attempts an conversion to a number. Apart from floating point numbers,
+ * the algorithm will recognize hexadecimal representations (as
+ * indicated by a 0x or 0X prefix) and +/- Infinity.
+ * Returns NaN if the conversion failed.
+ * @param tolerant if true, toDouble can tolerate garbage after the number.
+ */
+ double toDouble(bool tolerant=false) const;
+ /**
+ * Attempts an conversion to an unsigned long integer. ok will be set
+ * according to the success.
+ */
+ unsigned long toULong(bool *ok = 0L) const;
+ /**
+ * @return Position of first occurence of f starting at position pos.
+ * -1 if the search was not successful.
+ */
+ int find(const UString &f, int pos = 0) const;
+ /**
+ * @return Position of first occurence of f searching backwards from
+ * position pos.
+ * -1 if the search was not successful.
+ */
+ int rfind(const UString &f, int pos) const;
+ /**
+ * @return The sub string starting at position pos and length len.
+ */
+ UString substr(int pos = 0, int len = -1) const;
+ /**
+ * Static instance of a null string.
+ */
+ static UString null;
+ private:
+ void attach(Rep *r);
+ void detach();
+ void release();
+ Rep *rep;
+ };
+
+ inline bool operator==(const UChar &c1, const UChar &c2) {
+ return (c1.uc == c2.uc);
+ }
+ inline bool operator!=(const UChar &c1, const UChar &c2) {
+ return !(c1 == c2);
+ }
+ bool operator==(const UString& s1, const UString& s2);
+ inline bool operator!=(const UString& s1, const UString& s2) {
+ return !wvWare::operator==(s1, s2);
+ }
+ bool operator<(const UString& s1, const UString& s2);
+ bool operator==(const UString& s1, const char *s2);
+ inline bool operator!=(const UString& s1, const char *s2) {
+ return !wvWare::operator==(s1, s2);
+ }
+ inline bool operator==(const char *s1, const UString& s2) {
+ return operator==(s2, s1);
+ }
+ inline bool operator!=(const char *s1, const UString& s2) {
+ return !wvWare::operator==(s1, s2);
+ }
+ bool operator==(const CString& s1, const CString& s2);
+ UString operator+(const UString& s1, const UString& s2);
+
+
+ class UConstString : private UString {
+ public:
+ UConstString( UChar* data, unsigned int length );
+ ~UConstString();
+
+ const UString& string() const { return *this; }
+ };
+
+} // namespace
+
+#endif
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/utilities.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/utilities.cpp
new file mode 100644
index 00000000..6d29cb37
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/utilities.cpp
@@ -0,0 +1,38 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "utilities.h"
+#include <stdio.h>
+
+namespace wvWare
+{
+
+ std::string int2string( int i )
+ {
+ char buf[ 40 ];
+ snprintf( buf, 40, "%d", i );
+ return std::string( buf );
+ }
+
+ std::string uint2string( unsigned int i )
+ {
+ char buf[ 40 ];
+ snprintf( buf, 40, "%u", i );
+ return std::string( buf );
+ }
+} // namespace wvWare
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/utilities.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/utilities.h
new file mode 100644
index 00000000..1c25f320
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/utilities.h
@@ -0,0 +1,37 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef UTILITIES_H
+#define UTILITIES_H
+
+#include <algorithm>
+#include <functional> // std::unary_function is in this header with gcc 2.9x
+#include <string>
+
+namespace wvWare
+{
+ template<class T> struct Delete : public std::unary_function<T*, void>
+ {
+ void operator() (T* t) const { delete t; }
+ };
+
+ std::string int2string( int i );
+ std::string uint2string( unsigned int i );
+}
+
+#endif // UTILITIES_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/word95_generated.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/word95_generated.cpp
new file mode 100644
index 00000000..9fcd6b47
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/word95_generated.cpp
@@ -0,0 +1,6995 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+// This code is generated from the Microsoft HTML specification of the
+// WinWord format. Do NOT edit this code, but fix the spec or the script
+// generating the sources. If you want to add some additional code, some
+// includes or any other stuff, please add it to the template file!
+// For information about the script and the "hidden features" please read
+// the comments at the begin of the script.
+
+// If you find bugs or strange behavior please contact Werner Trobin
+
+#include <word95_generated.h>
+#include <olestream.h>
+#include <string.h> // memset(), memcpy()
+#include "wvlog.h"
+
+namespace wvWare {
+
+namespace Word95 {
+
+
+// DTTM implementation
+
+DTTM::DTTM() {
+ clear();
+}
+
+DTTM::DTTM(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+DTTM::DTTM(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool DTTM::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ mint=shifterU16;
+ shifterU16>>=6;
+ hr=shifterU16;
+ shifterU16>>=5;
+ dom=shifterU16;
+ shifterU16=stream->readU16();
+ mon=shifterU16;
+ shifterU16>>=4;
+ yr=shifterU16;
+ shifterU16>>=9;
+ wdy=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DTTM::readPtr(const U8 *ptr) {
+
+ U16 shifterU16;
+
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ mint=shifterU16;
+ shifterU16>>=6;
+ hr=shifterU16;
+ shifterU16>>=5;
+ dom=shifterU16;
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ mon=shifterU16;
+ shifterU16>>=4;
+ yr=shifterU16;
+ shifterU16>>=9;
+ wdy=shifterU16;
+}
+
+bool DTTM::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=mint;
+ shifterU16|=hr << 6;
+ shifterU16|=dom << 11;
+ stream->write(shifterU16);
+ shifterU16=mon;
+ shifterU16|=yr << 4;
+ shifterU16|=wdy << 13;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DTTM::clear() {
+ mint=0;
+ hr=0;
+ dom=0;
+ mon=0;
+ yr=0;
+ wdy=0;
+}
+
+void DTTM::dump() const
+{
+ wvlog << "Dumping DTTM:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping DTTM done." << std::endl;
+}
+
+std::string DTTM::toString() const
+{
+ std::string s( "DTTM:" );
+ s += "\nmint=";
+ s += uint2string( mint );
+ s += "\nhr=";
+ s += uint2string( hr );
+ s += "\ndom=";
+ s += uint2string( dom );
+ s += "\nmon=";
+ s += uint2string( mon );
+ s += "\nyr=";
+ s += uint2string( yr );
+ s += "\nwdy=";
+ s += uint2string( wdy );
+ s += "\nDTTM Done.";
+ return s;
+}
+
+bool operator==(const DTTM &lhs, const DTTM &rhs) {
+
+ return lhs.mint==rhs.mint &&
+ lhs.hr==rhs.hr &&
+ lhs.dom==rhs.dom &&
+ lhs.mon==rhs.mon &&
+ lhs.yr==rhs.yr &&
+ lhs.wdy==rhs.wdy;
+}
+
+bool operator!=(const DTTM &lhs, const DTTM &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// PRM2 implementation
+
+PRM2::PRM2() {
+ clear();
+}
+
+PRM2::PRM2(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool PRM2::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ fComplex=shifterU16;
+ shifterU16>>=1;
+ igrpprl=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool PRM2::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=fComplex;
+ shifterU16|=igrpprl << 1;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PRM2::clear() {
+ fComplex=0;
+ igrpprl=0;
+}
+
+bool operator==(const PRM2 &lhs, const PRM2 &rhs) {
+
+ return lhs.fComplex==rhs.fComplex &&
+ lhs.igrpprl==rhs.igrpprl;
+}
+
+bool operator!=(const PRM2 &lhs, const PRM2 &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// PRM implementation
+
+const unsigned int PRM::sizeOf = 2;
+
+PRM::PRM() {
+ clear();
+}
+
+PRM::PRM(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+PRM::PRM(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool PRM::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU8=stream->readU8();
+ fComplex=shifterU8;
+ shifterU8>>=1;
+ sprm=shifterU8;
+ val=stream->readU8();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PRM::readPtr(const U8 *ptr) {
+
+ U8 shifterU8;
+
+ shifterU8=readU8(ptr);
+ ptr+=sizeof(U8);
+ fComplex=shifterU8;
+ shifterU8>>=1;
+ sprm=shifterU8;
+ val=readU8(ptr);
+ ptr+=sizeof(U8);
+}
+
+bool PRM::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU8=fComplex;
+ shifterU8|=sprm << 1;
+ stream->write(shifterU8);
+ stream->write(val);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PRM::clear() {
+ fComplex=0;
+ sprm=0;
+ val=0;
+}
+
+bool operator==(const PRM &lhs, const PRM &rhs) {
+
+ return lhs.fComplex==rhs.fComplex &&
+ lhs.sprm==rhs.sprm &&
+ lhs.val==rhs.val;
+}
+
+bool operator!=(const PRM &lhs, const PRM &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// SHD implementation
+
+SHD::SHD() {
+ clear();
+}
+
+SHD::SHD(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+SHD::SHD(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool SHD::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ icoFore=shifterU16;
+ shifterU16>>=5;
+ icoBack=shifterU16;
+ shifterU16>>=5;
+ ipat=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void SHD::readPtr(const U8 *ptr) {
+
+ U16 shifterU16;
+
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ icoFore=shifterU16;
+ shifterU16>>=5;
+ icoBack=shifterU16;
+ shifterU16>>=5;
+ ipat=shifterU16;
+}
+
+bool SHD::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=icoFore;
+ shifterU16|=icoBack << 5;
+ shifterU16|=ipat << 10;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void SHD::clear() {
+ icoFore=0;
+ icoBack=0;
+ ipat=0;
+}
+
+void SHD::dump() const
+{
+ wvlog << "Dumping SHD:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping SHD done." << std::endl;
+}
+
+std::string SHD::toString() const
+{
+ std::string s( "SHD:" );
+ s += "\nicoFore=";
+ s += uint2string( icoFore );
+ s += "\nicoBack=";
+ s += uint2string( icoBack );
+ s += "\nipat=";
+ s += uint2string( ipat );
+ s += "\nSHD Done.";
+ return s;
+}
+
+bool operator==(const SHD &lhs, const SHD &rhs) {
+
+ return lhs.icoFore==rhs.icoFore &&
+ lhs.icoBack==rhs.icoBack &&
+ lhs.ipat==rhs.ipat;
+}
+
+bool operator!=(const SHD &lhs, const SHD &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// PHE implementation
+
+const unsigned int PHE::sizeOf = 6;
+
+PHE::PHE() {
+ clear();
+}
+
+PHE::PHE(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+PHE::PHE(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool PHE::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ fSpare=shifterU16;
+ shifterU16>>=1;
+ fUnk=shifterU16;
+ shifterU16>>=1;
+ fDiffLines=shifterU16;
+ shifterU16>>=1;
+ unused0_3=shifterU16;
+ shifterU16>>=5;
+ clMac=shifterU16;
+ dxaCol=stream->readU16();
+ dylLine_dylHeight=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PHE::readPtr(const U8 *ptr) {
+
+ U16 shifterU16;
+
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ fSpare=shifterU16;
+ shifterU16>>=1;
+ fUnk=shifterU16;
+ shifterU16>>=1;
+ fDiffLines=shifterU16;
+ shifterU16>>=1;
+ unused0_3=shifterU16;
+ shifterU16>>=5;
+ clMac=shifterU16;
+ dxaCol=readU16(ptr);
+ ptr+=sizeof(U16);
+ dylLine_dylHeight=readU16(ptr);
+ ptr+=sizeof(U16);
+}
+
+bool PHE::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=fSpare;
+ shifterU16|=fUnk << 1;
+ shifterU16|=fDiffLines << 2;
+ shifterU16|=unused0_3 << 3;
+ shifterU16|=clMac << 8;
+ stream->write(shifterU16);
+ stream->write(dxaCol);
+ stream->write(dylLine_dylHeight);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PHE::clear() {
+ fSpare=0;
+ fUnk=0;
+ fDiffLines=0;
+ unused0_3=0;
+ clMac=0;
+ dxaCol=0;
+ dylLine_dylHeight=0;
+}
+
+void PHE::dump() const
+{
+ wvlog << "Dumping PHE:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping PHE done." << std::endl;
+}
+
+std::string PHE::toString() const
+{
+ std::string s( "PHE:" );
+ s += "\nfSpare=";
+ s += uint2string( fSpare );
+ s += "\nfUnk=";
+ s += uint2string( fUnk );
+ s += "\nfDiffLines=";
+ s += uint2string( fDiffLines );
+ s += "\nunused0_3=";
+ s += uint2string( unused0_3 );
+ s += "\nclMac=";
+ s += uint2string( clMac );
+ s += "\ndxaCol=";
+ s += uint2string( dxaCol );
+ s += "\ndylLine_dylHeight=";
+ s += uint2string( dylLine_dylHeight );
+ s += "\nPHE Done.";
+ return s;
+}
+
+bool operator==(const PHE &lhs, const PHE &rhs) {
+
+ return lhs.fSpare==rhs.fSpare &&
+ lhs.fUnk==rhs.fUnk &&
+ lhs.fDiffLines==rhs.fDiffLines &&
+ lhs.unused0_3==rhs.unused0_3 &&
+ lhs.clMac==rhs.clMac &&
+ lhs.dxaCol==rhs.dxaCol &&
+ lhs.dylLine_dylHeight==rhs.dylLine_dylHeight;
+}
+
+bool operator!=(const PHE &lhs, const PHE &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// BRC implementation
+
+const unsigned int BRC::sizeOf = 2;
+
+BRC::BRC() {
+ clear();
+}
+
+BRC::BRC(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+BRC::BRC(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool BRC::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ dxpLineWidth=shifterU16;
+ shifterU16>>=3;
+ brcType=shifterU16;
+ shifterU16>>=2;
+ fShadow=shifterU16;
+ shifterU16>>=1;
+ ico=shifterU16;
+ shifterU16>>=5;
+ dxpSpace=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void BRC::readPtr(const U8 *ptr) {
+
+ U16 shifterU16;
+
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ dxpLineWidth=shifterU16;
+ shifterU16>>=3;
+ brcType=shifterU16;
+ shifterU16>>=2;
+ fShadow=shifterU16;
+ shifterU16>>=1;
+ ico=shifterU16;
+ shifterU16>>=5;
+ dxpSpace=shifterU16;
+}
+
+bool BRC::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=dxpLineWidth;
+ shifterU16|=brcType << 3;
+ shifterU16|=fShadow << 5;
+ shifterU16|=ico << 6;
+ shifterU16|=dxpSpace << 11;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void BRC::clear() {
+ dxpLineWidth=0;
+ brcType=0;
+ fShadow=0;
+ ico=0;
+ dxpSpace=0;
+}
+
+void BRC::dump() const
+{
+ wvlog << "Dumping BRC:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping BRC done." << std::endl;
+}
+
+std::string BRC::toString() const
+{
+ std::string s( "BRC:" );
+ s += "\ndxpLineWidth=";
+ s += uint2string( dxpLineWidth );
+ s += "\nbrcType=";
+ s += uint2string( brcType );
+ s += "\nfShadow=";
+ s += uint2string( fShadow );
+ s += "\nico=";
+ s += uint2string( ico );
+ s += "\ndxpSpace=";
+ s += uint2string( dxpSpace );
+ s += "\nBRC Done.";
+ return s;
+}
+
+bool operator==(const BRC &lhs, const BRC &rhs) {
+
+ return lhs.dxpLineWidth==rhs.dxpLineWidth &&
+ lhs.brcType==rhs.brcType &&
+ lhs.fShadow==rhs.fShadow &&
+ lhs.ico==rhs.ico &&
+ lhs.dxpSpace==rhs.dxpSpace;
+}
+
+bool operator!=(const BRC &lhs, const BRC &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// TLP implementation
+
+TLP::TLP() {
+ clear();
+}
+
+TLP::TLP(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+TLP::TLP(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool TLP::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ itl=stream->readU16();
+ shifterU16=stream->readU16();
+ fBorders=shifterU16;
+ shifterU16>>=1;
+ fShading=shifterU16;
+ shifterU16>>=1;
+ fFont=shifterU16;
+ shifterU16>>=1;
+ fColor=shifterU16;
+ shifterU16>>=1;
+ fBestFit=shifterU16;
+ shifterU16>>=1;
+ fHdrRows=shifterU16;
+ shifterU16>>=1;
+ fLastRow=shifterU16;
+ shifterU16>>=1;
+ fHdrCols=shifterU16;
+ shifterU16>>=1;
+ fLastCol=shifterU16;
+ shifterU16>>=1;
+ unused2_9=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void TLP::readPtr(const U8 *ptr) {
+
+ U16 shifterU16;
+
+ itl=readU16(ptr);
+ ptr+=sizeof(U16);
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ fBorders=shifterU16;
+ shifterU16>>=1;
+ fShading=shifterU16;
+ shifterU16>>=1;
+ fFont=shifterU16;
+ shifterU16>>=1;
+ fColor=shifterU16;
+ shifterU16>>=1;
+ fBestFit=shifterU16;
+ shifterU16>>=1;
+ fHdrRows=shifterU16;
+ shifterU16>>=1;
+ fLastRow=shifterU16;
+ shifterU16>>=1;
+ fHdrCols=shifterU16;
+ shifterU16>>=1;
+ fLastCol=shifterU16;
+ shifterU16>>=1;
+ unused2_9=shifterU16;
+}
+
+bool TLP::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(itl);
+ shifterU16=fBorders;
+ shifterU16|=fShading << 1;
+ shifterU16|=fFont << 2;
+ shifterU16|=fColor << 3;
+ shifterU16|=fBestFit << 4;
+ shifterU16|=fHdrRows << 5;
+ shifterU16|=fLastRow << 6;
+ shifterU16|=fHdrCols << 7;
+ shifterU16|=fLastCol << 8;
+ shifterU16|=unused2_9 << 9;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void TLP::clear() {
+ itl=0;
+ fBorders=0;
+ fShading=0;
+ fFont=0;
+ fColor=0;
+ fBestFit=0;
+ fHdrRows=0;
+ fLastRow=0;
+ fHdrCols=0;
+ fLastCol=0;
+ unused2_9=0;
+}
+
+void TLP::dump() const
+{
+ wvlog << "Dumping TLP:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping TLP done." << std::endl;
+}
+
+std::string TLP::toString() const
+{
+ std::string s( "TLP:" );
+ s += "\nitl=";
+ s += uint2string( itl );
+ s += "\nfBorders=";
+ s += uint2string( fBorders );
+ s += "\nfShading=";
+ s += uint2string( fShading );
+ s += "\nfFont=";
+ s += uint2string( fFont );
+ s += "\nfColor=";
+ s += uint2string( fColor );
+ s += "\nfBestFit=";
+ s += uint2string( fBestFit );
+ s += "\nfHdrRows=";
+ s += uint2string( fHdrRows );
+ s += "\nfLastRow=";
+ s += uint2string( fLastRow );
+ s += "\nfHdrCols=";
+ s += uint2string( fHdrCols );
+ s += "\nfLastCol=";
+ s += uint2string( fLastCol );
+ s += "\nunused2_9=";
+ s += uint2string( unused2_9 );
+ s += "\nTLP Done.";
+ return s;
+}
+
+bool operator==(const TLP &lhs, const TLP &rhs) {
+
+ return lhs.itl==rhs.itl &&
+ lhs.fBorders==rhs.fBorders &&
+ lhs.fShading==rhs.fShading &&
+ lhs.fFont==rhs.fFont &&
+ lhs.fColor==rhs.fColor &&
+ lhs.fBestFit==rhs.fBestFit &&
+ lhs.fHdrRows==rhs.fHdrRows &&
+ lhs.fLastRow==rhs.fLastRow &&
+ lhs.fHdrCols==rhs.fHdrCols &&
+ lhs.fLastCol==rhs.fLastCol &&
+ lhs.unused2_9==rhs.unused2_9;
+}
+
+bool operator!=(const TLP &lhs, const TLP &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// TC implementation
+
+const unsigned int TC::sizeOf = 10;
+
+TC::TC() {
+ clear();
+}
+
+TC::TC(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+TC::TC(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool TC::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ fFirstMerged=shifterU16;
+ shifterU16>>=1;
+ fMerged=shifterU16;
+ shifterU16>>=1;
+ fUnused=shifterU16;
+ brcTop.read(stream, false);
+ brcLeft.read(stream, false);
+ brcBottom.read(stream, false);
+ brcRight.read(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void TC::readPtr(const U8 *ptr) {
+
+ U16 shifterU16;
+
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ fFirstMerged=shifterU16;
+ shifterU16>>=1;
+ fMerged=shifterU16;
+ shifterU16>>=1;
+ fUnused=shifterU16;
+ brcTop.readPtr(ptr);
+ ptr+=BRC::sizeOf;
+ brcLeft.readPtr(ptr);
+ ptr+=BRC::sizeOf;
+ brcBottom.readPtr(ptr);
+ ptr+=BRC::sizeOf;
+ brcRight.readPtr(ptr);
+ ptr+=BRC::sizeOf;
+}
+
+bool TC::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=fFirstMerged;
+ shifterU16|=fMerged << 1;
+ shifterU16|=fUnused << 2;
+ stream->write(shifterU16);
+ brcTop.write(stream, false);
+ brcLeft.write(stream, false);
+ brcBottom.write(stream, false);
+ brcRight.write(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void TC::clear() {
+ fFirstMerged=0;
+ fMerged=0;
+ fUnused=0;
+ brcTop.clear();
+ brcLeft.clear();
+ brcBottom.clear();
+ brcRight.clear();
+}
+
+void TC::dump() const
+{
+ wvlog << "Dumping TC:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping TC done." << std::endl;
+}
+
+std::string TC::toString() const
+{
+ std::string s( "TC:" );
+ s += "\nfFirstMerged=";
+ s += uint2string( fFirstMerged );
+ s += "\nfMerged=";
+ s += uint2string( fMerged );
+ s += "\nfUnused=";
+ s += uint2string( fUnused );
+ s += "\nbrcTop=";
+ s += "\n{" + brcTop.toString() + "}\n";
+ s += "\nbrcLeft=";
+ s += "\n{" + brcLeft.toString() + "}\n";
+ s += "\nbrcBottom=";
+ s += "\n{" + brcBottom.toString() + "}\n";
+ s += "\nbrcRight=";
+ s += "\n{" + brcRight.toString() + "}\n";
+ s += "\nTC Done.";
+ return s;
+}
+
+bool operator==(const TC &lhs, const TC &rhs) {
+
+ return lhs.fFirstMerged==rhs.fFirstMerged &&
+ lhs.fMerged==rhs.fMerged &&
+ lhs.fUnused==rhs.fUnused &&
+ lhs.brcTop==rhs.brcTop &&
+ lhs.brcLeft==rhs.brcLeft &&
+ lhs.brcBottom==rhs.brcBottom &&
+ lhs.brcRight==rhs.brcRight;
+}
+
+bool operator!=(const TC &lhs, const TC &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// DPHEAD implementation
+
+DPHEAD::DPHEAD() {
+ clear();
+}
+
+DPHEAD::DPHEAD(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool DPHEAD::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ dpk=stream->readU16();
+ cb=stream->readU16();
+ xa=stream->readU16();
+ ya=stream->readU16();
+ dxa=stream->readU16();
+ dya=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool DPHEAD::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(dpk);
+ stream->write(cb);
+ stream->write(xa);
+ stream->write(ya);
+ stream->write(dxa);
+ stream->write(dya);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DPHEAD::clear() {
+ dpk=0;
+ cb=0;
+ xa=0;
+ ya=0;
+ dxa=0;
+ dya=0;
+}
+
+bool operator==(const DPHEAD &lhs, const DPHEAD &rhs) {
+
+ return lhs.dpk==rhs.dpk &&
+ lhs.cb==rhs.cb &&
+ lhs.xa==rhs.xa &&
+ lhs.ya==rhs.ya &&
+ lhs.dxa==rhs.dxa &&
+ lhs.dya==rhs.dya;
+}
+
+bool operator!=(const DPHEAD &lhs, const DPHEAD &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// DPTXBX implementation
+
+DPTXBX::DPTXBX() {
+ clear();
+}
+
+DPTXBX::DPTXBX(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool DPTXBX::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ dphead.read(stream, false);
+ lnpc=stream->readU32();
+ lnpw=stream->readU16();
+ lnps=stream->readU16();
+ dlpcFg=stream->readU32();
+ dlpcBg=stream->readU32();
+ flpp=stream->readU16();
+ shdwpi=stream->readU16();
+ xaOffset=stream->readU16();
+ yaOffset=stream->readU16();
+ shifterU16=stream->readU16();
+ fRoundCorners=shifterU16;
+ shifterU16>>=1;
+ zaShape=shifterU16;
+ dzaInternalMargin=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool DPTXBX::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ dphead.write(stream, false);
+ stream->write(lnpc);
+ stream->write(lnpw);
+ stream->write(lnps);
+ stream->write(dlpcFg);
+ stream->write(dlpcBg);
+ stream->write(flpp);
+ stream->write(shdwpi);
+ stream->write(xaOffset);
+ stream->write(yaOffset);
+ shifterU16=fRoundCorners;
+ shifterU16|=zaShape << 1;
+ stream->write(shifterU16);
+ stream->write(dzaInternalMargin);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DPTXBX::clear() {
+ dphead.clear();
+ lnpc=0;
+ lnpw=0;
+ lnps=0;
+ dlpcFg=0;
+ dlpcBg=0;
+ flpp=0;
+ shdwpi=0;
+ xaOffset=0;
+ yaOffset=0;
+ fRoundCorners=0;
+ zaShape=0;
+ dzaInternalMargin=0;
+}
+
+bool operator==(const DPTXBX &lhs, const DPTXBX &rhs) {
+
+ return lhs.dphead==rhs.dphead &&
+ lhs.lnpc==rhs.lnpc &&
+ lhs.lnpw==rhs.lnpw &&
+ lhs.lnps==rhs.lnps &&
+ lhs.dlpcFg==rhs.dlpcFg &&
+ lhs.dlpcBg==rhs.dlpcBg &&
+ lhs.flpp==rhs.flpp &&
+ lhs.shdwpi==rhs.shdwpi &&
+ lhs.xaOffset==rhs.xaOffset &&
+ lhs.yaOffset==rhs.yaOffset &&
+ lhs.fRoundCorners==rhs.fRoundCorners &&
+ lhs.zaShape==rhs.zaShape &&
+ lhs.dzaInternalMargin==rhs.dzaInternalMargin;
+}
+
+bool operator!=(const DPTXBX &lhs, const DPTXBX &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// DPPOLYLINE implementation
+
+DPPOLYLINE::DPPOLYLINE() {
+ clearInternal();
+}
+
+DPPOLYLINE::DPPOLYLINE(OLEStreamReader *stream, bool preservePos) {
+ clearInternal();
+ read(stream, preservePos);
+}
+
+DPPOLYLINE::DPPOLYLINE(const DPPOLYLINE &rhs) {
+ dphead=rhs.dphead;
+ lnpc=rhs.lnpc;
+ lnpw=rhs.lnpw;
+ lnps=rhs.lnps;
+ dlpcFg=rhs.dlpcFg;
+ dlpcBg=rhs.dlpcBg;
+ flpp=rhs.flpp;
+ eppsStart=rhs.eppsStart;
+ eppwStart=rhs.eppwStart;
+ epplStart=rhs.epplStart;
+ unused30_6=rhs.unused30_6;
+ eppsEnd=rhs.eppsEnd;
+ eppwEnd=rhs.eppwEnd;
+ epplEnd=rhs.epplEnd;
+ unused32_6=rhs.unused32_6;
+ shdwpi=rhs.shdwpi;
+ xaOffset=rhs.xaOffset;
+ yaOffset=rhs.yaOffset;
+ fPolygon=rhs.fPolygon;
+ cpt=rhs.cpt;
+ xaFirst=rhs.xaFirst;
+ yaFirst=rhs.yaFirst;
+ xaEnd=rhs.xaEnd;
+ yaEnd=rhs.yaEnd;
+ rgpta=rhs.rgpta;
+}
+
+DPPOLYLINE::~DPPOLYLINE() {
+ delete [] rgpta;
+}
+
+DPPOLYLINE &DPPOLYLINE::operator=(const DPPOLYLINE &rhs) {
+
+ // Check for assignment to self
+ if(this==&rhs)
+ return *this;
+
+ dphead=rhs.dphead;
+ lnpc=rhs.lnpc;
+ lnpw=rhs.lnpw;
+ lnps=rhs.lnps;
+ dlpcFg=rhs.dlpcFg;
+ dlpcBg=rhs.dlpcBg;
+ flpp=rhs.flpp;
+ eppsStart=rhs.eppsStart;
+ eppwStart=rhs.eppwStart;
+ epplStart=rhs.epplStart;
+ unused30_6=rhs.unused30_6;
+ eppsEnd=rhs.eppsEnd;
+ eppwEnd=rhs.eppwEnd;
+ epplEnd=rhs.epplEnd;
+ unused32_6=rhs.unused32_6;
+ shdwpi=rhs.shdwpi;
+ xaOffset=rhs.xaOffset;
+ yaOffset=rhs.yaOffset;
+ fPolygon=rhs.fPolygon;
+ cpt=rhs.cpt;
+ xaFirst=rhs.xaFirst;
+ yaFirst=rhs.yaFirst;
+ xaEnd=rhs.xaEnd;
+ yaEnd=rhs.yaEnd;
+ rgpta=rhs.rgpta;
+
+ return *this;
+}
+
+bool DPPOLYLINE::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ dphead.read(stream, false);
+ lnpc=stream->readU32();
+ lnpw=stream->readU16();
+ lnps=stream->readU16();
+ dlpcFg=stream->readU32();
+ dlpcBg=stream->readU32();
+ flpp=stream->readU16();
+ shifterU16=stream->readU16();
+ eppsStart=shifterU16;
+ shifterU16>>=2;
+ eppwStart=shifterU16;
+ shifterU16>>=2;
+ epplStart=shifterU16;
+ shifterU16>>=2;
+ unused30_6=shifterU16;
+ shifterU16=stream->readU16();
+ eppsEnd=shifterU16;
+ shifterU16>>=2;
+ eppwEnd=shifterU16;
+ shifterU16>>=2;
+ epplEnd=shifterU16;
+ shifterU16>>=2;
+ unused32_6=shifterU16;
+ shdwpi=stream->readU16();
+ xaOffset=stream->readU16();
+ yaOffset=stream->readU16();
+ shifterU16=stream->readU16();
+ fPolygon=shifterU16;
+ shifterU16>>=1;
+ cpt=shifterU16;
+ xaFirst=stream->readU16();
+ yaFirst=stream->readU16();
+ xaEnd=stream->readU16();
+ yaEnd=stream->readU16();
+ // Attention: I don't know how to read rgpta - U16[]
+#ifdef __GNUC__
+#warning "Couldn't generate reading code for DPPOLYLINE::rgpta"
+#endif
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool DPPOLYLINE::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ dphead.write(stream, false);
+ stream->write(lnpc);
+ stream->write(lnpw);
+ stream->write(lnps);
+ stream->write(dlpcFg);
+ stream->write(dlpcBg);
+ stream->write(flpp);
+ shifterU16=eppsStart;
+ shifterU16|=eppwStart << 2;
+ shifterU16|=epplStart << 4;
+ shifterU16|=unused30_6 << 6;
+ stream->write(shifterU16);
+ shifterU16=eppsEnd;
+ shifterU16|=eppwEnd << 2;
+ shifterU16|=epplEnd << 4;
+ shifterU16|=unused32_6 << 6;
+ stream->write(shifterU16);
+ stream->write(shdwpi);
+ stream->write(xaOffset);
+ stream->write(yaOffset);
+ shifterU16=fPolygon;
+ shifterU16|=cpt << 1;
+ stream->write(shifterU16);
+ stream->write(xaFirst);
+ stream->write(yaFirst);
+ stream->write(xaEnd);
+ stream->write(yaEnd);
+ // Attention: I don't know how to write rgpta - U16[]
+#ifdef __GNUC__
+#warning "Couldn't generate writing code for DPPOLYLINE::rgpta"
+#endif
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DPPOLYLINE::clear() {
+ delete [] rgpta;
+ clearInternal();
+}
+
+void DPPOLYLINE::clearInternal() {
+ dphead.clear();
+ lnpc=0;
+ lnpw=0;
+ lnps=0;
+ dlpcFg=0;
+ dlpcBg=0;
+ flpp=0;
+ eppsStart=0;
+ eppwStart=0;
+ epplStart=0;
+ unused30_6=0;
+ eppsEnd=0;
+ eppwEnd=0;
+ epplEnd=0;
+ unused32_6=0;
+ shdwpi=0;
+ xaOffset=0;
+ yaOffset=0;
+ fPolygon=0;
+ cpt=0;
+ xaFirst=0;
+ yaFirst=0;
+ xaEnd=0;
+ yaEnd=0;
+ rgpta=0;
+}
+
+bool operator==(const DPPOLYLINE &lhs, const DPPOLYLINE &rhs) {
+ // Attention: I don't know how to compare rgpta - U16[]
+#ifdef __GNUC__
+#warning "Can't compare DPPOLYLINE::rgpta items"
+#endif
+
+ return lhs.dphead==rhs.dphead &&
+ lhs.lnpc==rhs.lnpc &&
+ lhs.lnpw==rhs.lnpw &&
+ lhs.lnps==rhs.lnps &&
+ lhs.dlpcFg==rhs.dlpcFg &&
+ lhs.dlpcBg==rhs.dlpcBg &&
+ lhs.flpp==rhs.flpp &&
+ lhs.eppsStart==rhs.eppsStart &&
+ lhs.eppwStart==rhs.eppwStart &&
+ lhs.epplStart==rhs.epplStart &&
+ lhs.unused30_6==rhs.unused30_6 &&
+ lhs.eppsEnd==rhs.eppsEnd &&
+ lhs.eppwEnd==rhs.eppwEnd &&
+ lhs.epplEnd==rhs.epplEnd &&
+ lhs.unused32_6==rhs.unused32_6 &&
+ lhs.shdwpi==rhs.shdwpi &&
+ lhs.xaOffset==rhs.xaOffset &&
+ lhs.yaOffset==rhs.yaOffset &&
+ lhs.fPolygon==rhs.fPolygon &&
+ lhs.cpt==rhs.cpt &&
+ lhs.xaFirst==rhs.xaFirst &&
+ lhs.yaFirst==rhs.yaFirst &&
+ lhs.xaEnd==rhs.xaEnd &&
+ lhs.yaEnd==rhs.yaEnd;
+}
+
+bool operator!=(const DPPOLYLINE &lhs, const DPPOLYLINE &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// TAP implementation
+
+TAP::TAP() : Shared() {
+ clearInternal();
+}
+
+TAP::TAP(OLEStreamReader *stream, bool preservePos) : Shared() {
+ clearInternal();
+ read(stream, preservePos);
+}
+
+TAP::TAP(const TAP &rhs) : Shared() {
+ jc=rhs.jc;
+ dxaGapHalf=rhs.dxaGapHalf;
+ dyaRowHeight=rhs.dyaRowHeight;
+ fCantSplit=rhs.fCantSplit;
+ fTableHeader=rhs.fTableHeader;
+ tlp=rhs.tlp;
+ fCaFull=rhs.fCaFull;
+ fFirstRow=rhs.fFirstRow;
+ fLastRow=rhs.fLastRow;
+ fOutline=rhs.fOutline;
+ unused12_4=rhs.unused12_4;
+ itcMac=rhs.itcMac;
+ dxaAdjust=rhs.dxaAdjust;
+ rgdxaCenter=new U16[itcMac + 1];
+ memcpy(rgdxaCenter, rhs.rgdxaCenter, sizeof(U16)*(itcMac + 1));
+ rgtc=new TC[itcMac];
+ memcpy(rgtc, rhs.rgtc, sizeof(TC)*(itcMac));
+ rgshd=new SHD[itcMac];
+ memcpy(rgshd, rhs.rgshd, sizeof(SHD)*(itcMac));
+ memcpy(&rgbrcTable, &rhs.rgbrcTable, sizeof(rgbrcTable));
+}
+
+TAP::~TAP() {
+ delete [] rgdxaCenter;
+ delete [] rgtc;
+ delete [] rgshd;
+}
+
+TAP &TAP::operator=(const TAP &rhs) {
+
+ // Check for assignment to self
+ if(this==&rhs)
+ return *this;
+
+ jc=rhs.jc;
+ dxaGapHalf=rhs.dxaGapHalf;
+ dyaRowHeight=rhs.dyaRowHeight;
+ fCantSplit=rhs.fCantSplit;
+ fTableHeader=rhs.fTableHeader;
+ tlp=rhs.tlp;
+ fCaFull=rhs.fCaFull;
+ fFirstRow=rhs.fFirstRow;
+ fLastRow=rhs.fLastRow;
+ fOutline=rhs.fOutline;
+ unused12_4=rhs.unused12_4;
+ itcMac=rhs.itcMac;
+ dxaAdjust=rhs.dxaAdjust;
+ delete [] rgdxaCenter;
+ rgdxaCenter=new U16[itcMac + 1];
+ memcpy(rgdxaCenter, rhs.rgdxaCenter, sizeof(U16)*(itcMac + 1));
+ delete [] rgtc;
+ rgtc=new TC[itcMac];
+ memcpy(rgtc, rhs.rgtc, sizeof(TC)*(itcMac));
+ delete [] rgshd;
+ rgshd=new SHD[itcMac];
+ memcpy(rgshd, rhs.rgshd, sizeof(SHD)*(itcMac));
+ memcpy(&rgbrcTable, &rhs.rgbrcTable, sizeof(rgbrcTable));
+
+ return *this;
+}
+
+bool TAP::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ jc=stream->readU16();
+ dxaGapHalf=stream->readU16();
+ dyaRowHeight=stream->readU16();
+ fCantSplit=stream->readU8();
+ fTableHeader=stream->readU8();
+ tlp.read(stream, false);
+ shifterU16=stream->readU16();
+ fCaFull=shifterU16;
+ shifterU16>>=1;
+ fFirstRow=shifterU16;
+ shifterU16>>=1;
+ fLastRow=shifterU16;
+ shifterU16>>=1;
+ fOutline=shifterU16;
+ shifterU16>>=1;
+ unused12_4=shifterU16;
+ itcMac=stream->readU16();
+ dxaAdjust=stream->readU16();
+ rgdxaCenter=new U16[itcMac + 1];
+ for(int _i=0; _i<(itcMac + 1); ++_i)
+ rgdxaCenter[_i]=stream->readU16();
+ rgtc=new TC[itcMac];
+ for(int _i=0; _i<(itcMac); ++_i)
+ rgtc[_i].read(stream, false);
+ rgshd=new SHD[itcMac];
+ for(int _i=0; _i<(itcMac); ++_i)
+ rgshd[_i].read(stream, false);
+ for(int _i=0; _i<(6); ++_i)
+ rgbrcTable[_i].read(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool TAP::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(jc);
+ stream->write(dxaGapHalf);
+ stream->write(dyaRowHeight);
+ stream->write(fCantSplit);
+ stream->write(fTableHeader);
+ tlp.write(stream, false);
+ shifterU16=fCaFull;
+ shifterU16|=fFirstRow << 1;
+ shifterU16|=fLastRow << 2;
+ shifterU16|=fOutline << 3;
+ shifterU16|=unused12_4 << 4;
+ stream->write(shifterU16);
+ stream->write(itcMac);
+ stream->write(dxaAdjust);
+ for(int _i=0; _i<(itcMac + 1); ++_i)
+ stream->write(rgdxaCenter[_i]);
+ for(int _i=0; _i<(itcMac); ++_i)
+ rgtc[_i].write(stream, false);
+ for(int _i=0; _i<(itcMac); ++_i)
+ rgshd[_i].write(stream, false);
+ for(int _i=0; _i<(6); ++_i)
+ rgbrcTable[_i].write(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void TAP::clear() {
+ delete [] rgdxaCenter;
+ delete [] rgtc;
+ delete [] rgshd;
+ clearInternal();
+}
+
+void TAP::dump() const
+{
+ wvlog << "Dumping TAP:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping TAP done." << std::endl;
+}
+
+std::string TAP::toString() const
+{
+ std::string s( "TAP:" );
+ s += "\njc=";
+ s += uint2string( jc );
+ s += "\ndxaGapHalf=";
+ s += uint2string( dxaGapHalf );
+ s += "\ndyaRowHeight=";
+ s += uint2string( dyaRowHeight );
+ s += "\nfCantSplit=";
+ s += uint2string( fCantSplit );
+ s += "\nfTableHeader=";
+ s += uint2string( fTableHeader );
+ s += "\ntlp=";
+ s += "\n{" + tlp.toString() + "}\n";
+ s += "\nfCaFull=";
+ s += uint2string( fCaFull );
+ s += "\nfFirstRow=";
+ s += uint2string( fFirstRow );
+ s += "\nfLastRow=";
+ s += uint2string( fLastRow );
+ s += "\nfOutline=";
+ s += uint2string( fOutline );
+ s += "\nunused12_4=";
+ s += uint2string( unused12_4 );
+ s += "\nitcMac=";
+ s += uint2string( itcMac );
+ s += "\ndxaAdjust=";
+ s += uint2string( dxaAdjust );
+ for(int _i=0; _i<(itcMac + 1); ++_i) {
+ s += "\nrgdxaCenter[" + int2string( _i ) + "]=";
+ s += uint2string( rgdxaCenter[_i] );
+ }
+ for(int _i=0; _i<(itcMac); ++_i) {
+ s += "\nrgtc[" + int2string( _i ) + "]=";
+ s += "\n{" + rgtc[_i].toString() + "}\n";
+ }
+ for(int _i=0; _i<(itcMac); ++_i) {
+ s += "\nrgshd[" + int2string( _i ) + "]=";
+ s += "\n{" + rgshd[_i].toString() + "}\n";
+ }
+ for(int _i=0; _i<(6); ++_i) {
+ s += "\nrgbrcTable[" + int2string( _i ) + "]=";
+ s += "\n{" + rgbrcTable[_i].toString() + "}\n";
+ }
+ s += "\nTAP Done.";
+ return s;
+}
+
+void TAP::clearInternal() {
+ jc=0;
+ dxaGapHalf=0;
+ dyaRowHeight=0;
+ fCantSplit=0;
+ fTableHeader=0;
+ tlp.clear();
+ fCaFull=0;
+ fFirstRow=0;
+ fLastRow=0;
+ fOutline=0;
+ unused12_4=0;
+ itcMac=0;
+ dxaAdjust=0;
+ rgdxaCenter=0;
+ rgtc=0;
+ rgshd=0;
+ for(int _i=0; _i<(6); ++_i)
+ rgbrcTable[_i].clear();
+}
+
+bool operator==(const TAP &lhs, const TAP &rhs) {
+
+ if((lhs.itcMac)!=(rhs.itcMac))
+ return false;
+ for(int _i=0; _i<(lhs.itcMac); ++_i) {
+ if(lhs.rgdxaCenter[_i]!=rhs.rgdxaCenter[_i])
+ return false;
+ }
+
+ if((lhs.itcMac)!=(rhs.itcMac))
+ return false;
+ for(int _i=0; _i<(lhs.itcMac); ++_i) {
+ if(lhs.rgtc[_i]!=rhs.rgtc[_i])
+ return false;
+ }
+
+ if((lhs.itcMac)!=(rhs.itcMac))
+ return false;
+ for(int _i=0; _i<(lhs.itcMac); ++_i) {
+ if(lhs.rgshd[_i]!=rhs.rgshd[_i])
+ return false;
+ }
+
+ for(int _i=0; _i<(6); ++_i) {
+ if(lhs.rgbrcTable[_i]!=rhs.rgbrcTable[_i])
+ return false;
+ }
+
+ return lhs.jc==rhs.jc &&
+ lhs.dxaGapHalf==rhs.dxaGapHalf &&
+ lhs.dyaRowHeight==rhs.dyaRowHeight &&
+ lhs.fCantSplit==rhs.fCantSplit &&
+ lhs.fTableHeader==rhs.fTableHeader &&
+ lhs.tlp==rhs.tlp &&
+ lhs.fCaFull==rhs.fCaFull &&
+ lhs.fFirstRow==rhs.fFirstRow &&
+ lhs.fLastRow==rhs.fLastRow &&
+ lhs.fOutline==rhs.fOutline &&
+ lhs.unused12_4==rhs.unused12_4 &&
+ lhs.itcMac==rhs.itcMac &&
+ lhs.dxaAdjust==rhs.dxaAdjust;
+}
+
+bool operator!=(const TAP &lhs, const TAP &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// ANLD implementation
+
+ANLD::ANLD() {
+ clear();
+}
+
+ANLD::ANLD(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+ANLD::ANLD(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool ANLD::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ nfc=stream->readU8();
+ cxchTextBefore=stream->readU8();
+ cxchTextAfter=stream->readU8();
+ shifterU8=stream->readU8();
+ jc=shifterU8;
+ shifterU8>>=2;
+ fPrev=shifterU8;
+ shifterU8>>=1;
+ fHang=shifterU8;
+ shifterU8>>=1;
+ fSetBold=shifterU8;
+ shifterU8>>=1;
+ fSetItalic=shifterU8;
+ shifterU8>>=1;
+ fSetSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fSetCaps=shifterU8;
+ shifterU8=stream->readU8();
+ fSetStrike=shifterU8;
+ shifterU8>>=1;
+ fSetKul=shifterU8;
+ shifterU8>>=1;
+ fPrevSpace=shifterU8;
+ shifterU8>>=1;
+ fBold=shifterU8;
+ shifterU8>>=1;
+ fItalic=shifterU8;
+ shifterU8>>=1;
+ fSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fCaps=shifterU8;
+ shifterU8>>=1;
+ fStrike=shifterU8;
+ shifterU8=stream->readU8();
+ kul=shifterU8;
+ shifterU8>>=3;
+ ico=shifterU8;
+ ftc=stream->readS16();
+ hps=stream->readU16();
+ iStartAt=stream->readU16();
+ dxaIndent=stream->readU16();
+ dxaSpace=stream->readU16();
+ fNumber1=stream->readU8();
+ fNumberAcross=stream->readU8();
+ fRestartHdn=stream->readU8();
+ fSpareX=stream->readU8();
+ for(int _i=0; _i<(32); ++_i)
+ rgchAnld[_i]=stream->readU8();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void ANLD::readPtr(const U8 *ptr) {
+
+ U8 shifterU8;
+
+ nfc=readU8(ptr);
+ ptr+=sizeof(U8);
+ cxchTextBefore=readU8(ptr);
+ ptr+=sizeof(U8);
+ cxchTextAfter=readU8(ptr);
+ ptr+=sizeof(U8);
+ shifterU8=readU8(ptr);
+ ptr+=sizeof(U8);
+ jc=shifterU8;
+ shifterU8>>=2;
+ fPrev=shifterU8;
+ shifterU8>>=1;
+ fHang=shifterU8;
+ shifterU8>>=1;
+ fSetBold=shifterU8;
+ shifterU8>>=1;
+ fSetItalic=shifterU8;
+ shifterU8>>=1;
+ fSetSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fSetCaps=shifterU8;
+ shifterU8=readU8(ptr);
+ ptr+=sizeof(U8);
+ fSetStrike=shifterU8;
+ shifterU8>>=1;
+ fSetKul=shifterU8;
+ shifterU8>>=1;
+ fPrevSpace=shifterU8;
+ shifterU8>>=1;
+ fBold=shifterU8;
+ shifterU8>>=1;
+ fItalic=shifterU8;
+ shifterU8>>=1;
+ fSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fCaps=shifterU8;
+ shifterU8>>=1;
+ fStrike=shifterU8;
+ shifterU8=readU8(ptr);
+ ptr+=sizeof(U8);
+ kul=shifterU8;
+ shifterU8>>=3;
+ ico=shifterU8;
+ ftc=readS16(ptr);
+ ptr+=sizeof(S16);
+ hps=readU16(ptr);
+ ptr+=sizeof(U16);
+ iStartAt=readU16(ptr);
+ ptr+=sizeof(U16);
+ dxaIndent=readU16(ptr);
+ ptr+=sizeof(U16);
+ dxaSpace=readU16(ptr);
+ ptr+=sizeof(U16);
+ fNumber1=readU8(ptr);
+ ptr+=sizeof(U8);
+ fNumberAcross=readU8(ptr);
+ ptr+=sizeof(U8);
+ fRestartHdn=readU8(ptr);
+ ptr+=sizeof(U8);
+ fSpareX=readU8(ptr);
+ ptr+=sizeof(U8);
+ for(int _i=0; _i<(32); ++_i) {
+ rgchAnld[_i]=readU8(ptr);
+ ptr+=sizeof(U8);
+ }
+}
+
+bool ANLD::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(nfc);
+ stream->write(cxchTextBefore);
+ stream->write(cxchTextAfter);
+ shifterU8=jc;
+ shifterU8|=fPrev << 2;
+ shifterU8|=fHang << 3;
+ shifterU8|=fSetBold << 4;
+ shifterU8|=fSetItalic << 5;
+ shifterU8|=fSetSmallCaps << 6;
+ shifterU8|=fSetCaps << 7;
+ stream->write(shifterU8);
+ shifterU8=fSetStrike;
+ shifterU8|=fSetKul << 1;
+ shifterU8|=fPrevSpace << 2;
+ shifterU8|=fBold << 3;
+ shifterU8|=fItalic << 4;
+ shifterU8|=fSmallCaps << 5;
+ shifterU8|=fCaps << 6;
+ shifterU8|=fStrike << 7;
+ stream->write(shifterU8);
+ shifterU8=kul;
+ shifterU8|=ico << 3;
+ stream->write(shifterU8);
+ stream->write(ftc);
+ stream->write(hps);
+ stream->write(iStartAt);
+ stream->write(dxaIndent);
+ stream->write(dxaSpace);
+ stream->write(fNumber1);
+ stream->write(fNumberAcross);
+ stream->write(fRestartHdn);
+ stream->write(fSpareX);
+ for(int _i=0; _i<(32); ++_i)
+ stream->write(rgchAnld[_i]);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void ANLD::clear() {
+ nfc=0;
+ cxchTextBefore=0;
+ cxchTextAfter=0;
+ jc=0;
+ fPrev=0;
+ fHang=0;
+ fSetBold=0;
+ fSetItalic=0;
+ fSetSmallCaps=0;
+ fSetCaps=0;
+ fSetStrike=0;
+ fSetKul=0;
+ fPrevSpace=0;
+ fBold=0;
+ fItalic=0;
+ fSmallCaps=0;
+ fCaps=0;
+ fStrike=0;
+ kul=0;
+ ico=0;
+ ftc=0;
+ hps=0;
+ iStartAt=0;
+ dxaIndent=0;
+ dxaSpace=0;
+ fNumber1=0;
+ fNumberAcross=0;
+ fRestartHdn=0;
+ fSpareX=0;
+ for(int _i=0; _i<(32); ++_i)
+ rgchAnld[_i]=0;
+}
+
+void ANLD::dump() const
+{
+ wvlog << "Dumping ANLD:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping ANLD done." << std::endl;
+}
+
+std::string ANLD::toString() const
+{
+ std::string s( "ANLD:" );
+ s += "\nnfc=";
+ s += uint2string( nfc );
+ s += "\ncxchTextBefore=";
+ s += uint2string( cxchTextBefore );
+ s += "\ncxchTextAfter=";
+ s += uint2string( cxchTextAfter );
+ s += "\njc=";
+ s += uint2string( jc );
+ s += "\nfPrev=";
+ s += uint2string( fPrev );
+ s += "\nfHang=";
+ s += uint2string( fHang );
+ s += "\nfSetBold=";
+ s += uint2string( fSetBold );
+ s += "\nfSetItalic=";
+ s += uint2string( fSetItalic );
+ s += "\nfSetSmallCaps=";
+ s += uint2string( fSetSmallCaps );
+ s += "\nfSetCaps=";
+ s += uint2string( fSetCaps );
+ s += "\nfSetStrike=";
+ s += uint2string( fSetStrike );
+ s += "\nfSetKul=";
+ s += uint2string( fSetKul );
+ s += "\nfPrevSpace=";
+ s += uint2string( fPrevSpace );
+ s += "\nfBold=";
+ s += uint2string( fBold );
+ s += "\nfItalic=";
+ s += uint2string( fItalic );
+ s += "\nfSmallCaps=";
+ s += uint2string( fSmallCaps );
+ s += "\nfCaps=";
+ s += uint2string( fCaps );
+ s += "\nfStrike=";
+ s += uint2string( fStrike );
+ s += "\nkul=";
+ s += uint2string( kul );
+ s += "\nico=";
+ s += uint2string( ico );
+ s += "\nftc=";
+ s += int2string( ftc );
+ s += "\nhps=";
+ s += uint2string( hps );
+ s += "\niStartAt=";
+ s += uint2string( iStartAt );
+ s += "\ndxaIndent=";
+ s += uint2string( dxaIndent );
+ s += "\ndxaSpace=";
+ s += uint2string( dxaSpace );
+ s += "\nfNumber1=";
+ s += uint2string( fNumber1 );
+ s += "\nfNumberAcross=";
+ s += uint2string( fNumberAcross );
+ s += "\nfRestartHdn=";
+ s += uint2string( fRestartHdn );
+ s += "\nfSpareX=";
+ s += uint2string( fSpareX );
+ for(int _i=0; _i<(32); ++_i) {
+ s += "\nrgchAnld[" + int2string( _i ) + "]=";
+ s += uint2string( rgchAnld[_i] );
+ }
+ s += "\nANLD Done.";
+ return s;
+}
+
+bool operator==(const ANLD &lhs, const ANLD &rhs) {
+
+ for(int _i=0; _i<(32); ++_i) {
+ if(lhs.rgchAnld[_i]!=rhs.rgchAnld[_i])
+ return false;
+ }
+
+ return lhs.nfc==rhs.nfc &&
+ lhs.cxchTextBefore==rhs.cxchTextBefore &&
+ lhs.cxchTextAfter==rhs.cxchTextAfter &&
+ lhs.jc==rhs.jc &&
+ lhs.fPrev==rhs.fPrev &&
+ lhs.fHang==rhs.fHang &&
+ lhs.fSetBold==rhs.fSetBold &&
+ lhs.fSetItalic==rhs.fSetItalic &&
+ lhs.fSetSmallCaps==rhs.fSetSmallCaps &&
+ lhs.fSetCaps==rhs.fSetCaps &&
+ lhs.fSetStrike==rhs.fSetStrike &&
+ lhs.fSetKul==rhs.fSetKul &&
+ lhs.fPrevSpace==rhs.fPrevSpace &&
+ lhs.fBold==rhs.fBold &&
+ lhs.fItalic==rhs.fItalic &&
+ lhs.fSmallCaps==rhs.fSmallCaps &&
+ lhs.fCaps==rhs.fCaps &&
+ lhs.fStrike==rhs.fStrike &&
+ lhs.kul==rhs.kul &&
+ lhs.ico==rhs.ico &&
+ lhs.ftc==rhs.ftc &&
+ lhs.hps==rhs.hps &&
+ lhs.iStartAt==rhs.iStartAt &&
+ lhs.dxaIndent==rhs.dxaIndent &&
+ lhs.dxaSpace==rhs.dxaSpace &&
+ lhs.fNumber1==rhs.fNumber1 &&
+ lhs.fNumberAcross==rhs.fNumberAcross &&
+ lhs.fRestartHdn==rhs.fRestartHdn &&
+ lhs.fSpareX==rhs.fSpareX;
+}
+
+bool operator!=(const ANLD &lhs, const ANLD &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// ANLV implementation
+
+const unsigned int ANLV::sizeOf = 16;
+
+ANLV::ANLV() {
+ clear();
+}
+
+ANLV::ANLV(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+ANLV::ANLV(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool ANLV::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ nfc=stream->readU8();
+ cxchTextBefore=stream->readU8();
+ cxchTextAfter=stream->readU8();
+ shifterU8=stream->readU8();
+ jc=shifterU8;
+ shifterU8>>=2;
+ fPrev=shifterU8;
+ shifterU8>>=1;
+ fHang=shifterU8;
+ shifterU8>>=1;
+ fSetBold=shifterU8;
+ shifterU8>>=1;
+ fSetItalic=shifterU8;
+ shifterU8>>=1;
+ fSetSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fSetCaps=shifterU8;
+ shifterU8=stream->readU8();
+ fSetStrike=shifterU8;
+ shifterU8>>=1;
+ fSetKul=shifterU8;
+ shifterU8>>=1;
+ fPrevSpace=shifterU8;
+ shifterU8>>=1;
+ fBold=shifterU8;
+ shifterU8>>=1;
+ fItalic=shifterU8;
+ shifterU8>>=1;
+ fSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fCaps=shifterU8;
+ shifterU8>>=1;
+ fStrike=shifterU8;
+ shifterU8=stream->readU8();
+ kul=shifterU8;
+ shifterU8>>=3;
+ ico=shifterU8;
+ ftc=stream->readS16();
+ hps=stream->readU16();
+ iStartAt=stream->readU16();
+ dxaIndent=stream->readU16();
+ dxaSpace=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void ANLV::readPtr(const U8 *ptr) {
+
+ U8 shifterU8;
+
+ nfc=readU8(ptr);
+ ptr+=sizeof(U8);
+ cxchTextBefore=readU8(ptr);
+ ptr+=sizeof(U8);
+ cxchTextAfter=readU8(ptr);
+ ptr+=sizeof(U8);
+ shifterU8=readU8(ptr);
+ ptr+=sizeof(U8);
+ jc=shifterU8;
+ shifterU8>>=2;
+ fPrev=shifterU8;
+ shifterU8>>=1;
+ fHang=shifterU8;
+ shifterU8>>=1;
+ fSetBold=shifterU8;
+ shifterU8>>=1;
+ fSetItalic=shifterU8;
+ shifterU8>>=1;
+ fSetSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fSetCaps=shifterU8;
+ shifterU8=readU8(ptr);
+ ptr+=sizeof(U8);
+ fSetStrike=shifterU8;
+ shifterU8>>=1;
+ fSetKul=shifterU8;
+ shifterU8>>=1;
+ fPrevSpace=shifterU8;
+ shifterU8>>=1;
+ fBold=shifterU8;
+ shifterU8>>=1;
+ fItalic=shifterU8;
+ shifterU8>>=1;
+ fSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fCaps=shifterU8;
+ shifterU8>>=1;
+ fStrike=shifterU8;
+ shifterU8=readU8(ptr);
+ ptr+=sizeof(U8);
+ kul=shifterU8;
+ shifterU8>>=3;
+ ico=shifterU8;
+ ftc=readS16(ptr);
+ ptr+=sizeof(S16);
+ hps=readU16(ptr);
+ ptr+=sizeof(U16);
+ iStartAt=readU16(ptr);
+ ptr+=sizeof(U16);
+ dxaIndent=readU16(ptr);
+ ptr+=sizeof(U16);
+ dxaSpace=readU16(ptr);
+ ptr+=sizeof(U16);
+}
+
+bool ANLV::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(nfc);
+ stream->write(cxchTextBefore);
+ stream->write(cxchTextAfter);
+ shifterU8=jc;
+ shifterU8|=fPrev << 2;
+ shifterU8|=fHang << 3;
+ shifterU8|=fSetBold << 4;
+ shifterU8|=fSetItalic << 5;
+ shifterU8|=fSetSmallCaps << 6;
+ shifterU8|=fSetCaps << 7;
+ stream->write(shifterU8);
+ shifterU8=fSetStrike;
+ shifterU8|=fSetKul << 1;
+ shifterU8|=fPrevSpace << 2;
+ shifterU8|=fBold << 3;
+ shifterU8|=fItalic << 4;
+ shifterU8|=fSmallCaps << 5;
+ shifterU8|=fCaps << 6;
+ shifterU8|=fStrike << 7;
+ stream->write(shifterU8);
+ shifterU8=kul;
+ shifterU8|=ico << 3;
+ stream->write(shifterU8);
+ stream->write(ftc);
+ stream->write(hps);
+ stream->write(iStartAt);
+ stream->write(dxaIndent);
+ stream->write(dxaSpace);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void ANLV::clear() {
+ nfc=0;
+ cxchTextBefore=0;
+ cxchTextAfter=0;
+ jc=0;
+ fPrev=0;
+ fHang=0;
+ fSetBold=0;
+ fSetItalic=0;
+ fSetSmallCaps=0;
+ fSetCaps=0;
+ fSetStrike=0;
+ fSetKul=0;
+ fPrevSpace=0;
+ fBold=0;
+ fItalic=0;
+ fSmallCaps=0;
+ fCaps=0;
+ fStrike=0;
+ kul=0;
+ ico=0;
+ ftc=0;
+ hps=0;
+ iStartAt=0;
+ dxaIndent=0;
+ dxaSpace=0;
+}
+
+void ANLV::dump() const
+{
+ wvlog << "Dumping ANLV:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping ANLV done." << std::endl;
+}
+
+std::string ANLV::toString() const
+{
+ std::string s( "ANLV:" );
+ s += "\nnfc=";
+ s += uint2string( nfc );
+ s += "\ncxchTextBefore=";
+ s += uint2string( cxchTextBefore );
+ s += "\ncxchTextAfter=";
+ s += uint2string( cxchTextAfter );
+ s += "\njc=";
+ s += uint2string( jc );
+ s += "\nfPrev=";
+ s += uint2string( fPrev );
+ s += "\nfHang=";
+ s += uint2string( fHang );
+ s += "\nfSetBold=";
+ s += uint2string( fSetBold );
+ s += "\nfSetItalic=";
+ s += uint2string( fSetItalic );
+ s += "\nfSetSmallCaps=";
+ s += uint2string( fSetSmallCaps );
+ s += "\nfSetCaps=";
+ s += uint2string( fSetCaps );
+ s += "\nfSetStrike=";
+ s += uint2string( fSetStrike );
+ s += "\nfSetKul=";
+ s += uint2string( fSetKul );
+ s += "\nfPrevSpace=";
+ s += uint2string( fPrevSpace );
+ s += "\nfBold=";
+ s += uint2string( fBold );
+ s += "\nfItalic=";
+ s += uint2string( fItalic );
+ s += "\nfSmallCaps=";
+ s += uint2string( fSmallCaps );
+ s += "\nfCaps=";
+ s += uint2string( fCaps );
+ s += "\nfStrike=";
+ s += uint2string( fStrike );
+ s += "\nkul=";
+ s += uint2string( kul );
+ s += "\nico=";
+ s += uint2string( ico );
+ s += "\nftc=";
+ s += int2string( ftc );
+ s += "\nhps=";
+ s += uint2string( hps );
+ s += "\niStartAt=";
+ s += uint2string( iStartAt );
+ s += "\ndxaIndent=";
+ s += uint2string( dxaIndent );
+ s += "\ndxaSpace=";
+ s += uint2string( dxaSpace );
+ s += "\nANLV Done.";
+ return s;
+}
+
+bool operator==(const ANLV &lhs, const ANLV &rhs) {
+
+ return lhs.nfc==rhs.nfc &&
+ lhs.cxchTextBefore==rhs.cxchTextBefore &&
+ lhs.cxchTextAfter==rhs.cxchTextAfter &&
+ lhs.jc==rhs.jc &&
+ lhs.fPrev==rhs.fPrev &&
+ lhs.fHang==rhs.fHang &&
+ lhs.fSetBold==rhs.fSetBold &&
+ lhs.fSetItalic==rhs.fSetItalic &&
+ lhs.fSetSmallCaps==rhs.fSetSmallCaps &&
+ lhs.fSetCaps==rhs.fSetCaps &&
+ lhs.fSetStrike==rhs.fSetStrike &&
+ lhs.fSetKul==rhs.fSetKul &&
+ lhs.fPrevSpace==rhs.fPrevSpace &&
+ lhs.fBold==rhs.fBold &&
+ lhs.fItalic==rhs.fItalic &&
+ lhs.fSmallCaps==rhs.fSmallCaps &&
+ lhs.fCaps==rhs.fCaps &&
+ lhs.fStrike==rhs.fStrike &&
+ lhs.kul==rhs.kul &&
+ lhs.ico==rhs.ico &&
+ lhs.ftc==rhs.ftc &&
+ lhs.hps==rhs.hps &&
+ lhs.iStartAt==rhs.iStartAt &&
+ lhs.dxaIndent==rhs.dxaIndent &&
+ lhs.dxaSpace==rhs.dxaSpace;
+}
+
+bool operator!=(const ANLV &lhs, const ANLV &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// BKF implementation
+
+BKF::BKF() {
+ clear();
+}
+
+BKF::BKF(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool BKF::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ ibkl=stream->readS16();
+ shifterU16=stream->readU16();
+ itcFirst=shifterU16;
+ shifterU16>>=7;
+ fPub=shifterU16;
+ shifterU16>>=1;
+ itcLim=shifterU16;
+ shifterU16>>=7;
+ fCol=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool BKF::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(ibkl);
+ shifterU16=itcFirst;
+ shifterU16|=fPub << 7;
+ shifterU16|=itcLim << 8;
+ shifterU16|=fCol << 15;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void BKF::clear() {
+ ibkl=0;
+ itcFirst=0;
+ fPub=0;
+ itcLim=0;
+ fCol=0;
+}
+
+bool operator==(const BKF &lhs, const BKF &rhs) {
+
+ return lhs.ibkl==rhs.ibkl &&
+ lhs.itcFirst==rhs.itcFirst &&
+ lhs.fPub==rhs.fPub &&
+ lhs.itcLim==rhs.itcLim &&
+ lhs.fCol==rhs.fCol;
+}
+
+bool operator!=(const BKF &lhs, const BKF &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// BKL implementation
+
+BKL::BKL() {
+ clear();
+}
+
+BKL::BKL(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool BKL::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ ibkf=stream->readS16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool BKL::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(ibkf);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void BKL::clear() {
+ ibkf=0;
+}
+
+bool operator==(const BKL &lhs, const BKL &rhs) {
+
+ return lhs.ibkf==rhs.ibkf;
+}
+
+bool operator!=(const BKL &lhs, const BKL &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// BRC10 implementation
+
+BRC10::BRC10() {
+ clear();
+}
+
+BRC10::BRC10(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool BRC10::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ dxpLine2Width=shifterU16;
+ shifterU16>>=3;
+ dxpSpaceBetween=shifterU16;
+ shifterU16>>=3;
+ dxpLine1Width=shifterU16;
+ shifterU16>>=3;
+ dxpSpace=shifterU16;
+ shifterU16>>=5;
+ fShadow=shifterU16;
+ shifterU16>>=1;
+ fSpare=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool BRC10::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=dxpLine2Width;
+ shifterU16|=dxpSpaceBetween << 3;
+ shifterU16|=dxpLine1Width << 6;
+ shifterU16|=dxpSpace << 9;
+ shifterU16|=fShadow << 14;
+ shifterU16|=fSpare << 15;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void BRC10::clear() {
+ dxpLine2Width=0;
+ dxpSpaceBetween=0;
+ dxpLine1Width=0;
+ dxpSpace=0;
+ fShadow=0;
+ fSpare=0;
+}
+
+bool operator==(const BRC10 &lhs, const BRC10 &rhs) {
+
+ return lhs.dxpLine2Width==rhs.dxpLine2Width &&
+ lhs.dxpSpaceBetween==rhs.dxpSpaceBetween &&
+ lhs.dxpLine1Width==rhs.dxpLine1Width &&
+ lhs.dxpSpace==rhs.dxpSpace &&
+ lhs.fShadow==rhs.fShadow &&
+ lhs.fSpare==rhs.fSpare;
+}
+
+bool operator!=(const BRC10 &lhs, const BRC10 &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// BTE implementation
+
+const unsigned int BTE::sizeOf = 2;
+
+BTE::BTE() {
+ clear();
+}
+
+BTE::BTE(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool BTE::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ pn=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool BTE::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(pn);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void BTE::clear() {
+ pn=0;
+}
+
+bool operator==(const BTE &lhs, const BTE &rhs) {
+
+ return lhs.pn==rhs.pn;
+}
+
+bool operator!=(const BTE &lhs, const BTE &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// CHP implementation
+
+CHP::CHP() : Shared() {
+ clear();
+}
+
+CHP::CHP(OLEStreamReader *stream, bool preservePos) : Shared() {
+ clear();
+ read(stream, preservePos);
+}
+
+bool CHP::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU8=stream->readU8();
+ fBold=shifterU8;
+ shifterU8>>=1;
+ fItalic=shifterU8;
+ shifterU8>>=1;
+ fRMarkDel=shifterU8;
+ shifterU8>>=1;
+ fOutline=shifterU8;
+ shifterU8>>=1;
+ fFldVanish=shifterU8;
+ shifterU8>>=1;
+ fSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fCaps=shifterU8;
+ shifterU8>>=1;
+ fVanish=shifterU8;
+ shifterU8=stream->readU8();
+ fRMark=shifterU8;
+ shifterU8>>=1;
+ fSpec=shifterU8;
+ shifterU8>>=1;
+ fStrike=shifterU8;
+ shifterU8>>=1;
+ fObj=shifterU8;
+ shifterU8>>=1;
+ fShadow=shifterU8;
+ shifterU8>>=1;
+ fLowerCase=shifterU8;
+ shifterU8>>=1;
+ fData=shifterU8;
+ shifterU8>>=1;
+ fOle2=shifterU8;
+ unused2=stream->readU16();
+ ftc=stream->readU16();
+ hps=stream->readU16();
+ dxaSpace=stream->readU16();
+ shifterU8=stream->readU8();
+ iss=shifterU8;
+ shifterU8>>=3;
+ unused10_3=shifterU8;
+ shifterU8>>=3;
+ fSysVanish=shifterU8;
+ shifterU8>>=1;
+ unused10_7=shifterU8;
+ shifterU8=stream->readU8();
+ ico=shifterU8;
+ shifterU8>>=5;
+ kul=shifterU8;
+ hpsPos=stream->readS16();
+ lid=stream->readU16();
+ fcPic_fcObj_lTagObj=stream->readU32();
+ ibstRMark=stream->readU16();
+ dttmRMark.read(stream, false);
+ unused26=stream->readU16();
+ istd=stream->readU16();
+ ftcSym=stream->readU16();
+ chSym=stream->readU8();
+ fChsDiff=stream->readU8();
+ idslRMReason=stream->readU16();
+ ysr=stream->readU8();
+ chYsr=stream->readU8();
+ chse=stream->readU16();
+ hpsKern=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool CHP::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU8=fBold;
+ shifterU8|=fItalic << 1;
+ shifterU8|=fRMarkDel << 2;
+ shifterU8|=fOutline << 3;
+ shifterU8|=fFldVanish << 4;
+ shifterU8|=fSmallCaps << 5;
+ shifterU8|=fCaps << 6;
+ shifterU8|=fVanish << 7;
+ stream->write(shifterU8);
+ shifterU8=fRMark;
+ shifterU8|=fSpec << 1;
+ shifterU8|=fStrike << 2;
+ shifterU8|=fObj << 3;
+ shifterU8|=fShadow << 4;
+ shifterU8|=fLowerCase << 5;
+ shifterU8|=fData << 6;
+ shifterU8|=fOle2 << 7;
+ stream->write(shifterU8);
+ stream->write(unused2);
+ stream->write(ftc);
+ stream->write(hps);
+ stream->write(dxaSpace);
+ shifterU8=iss;
+ shifterU8|=unused10_3 << 3;
+ shifterU8|=fSysVanish << 6;
+ shifterU8|=unused10_7 << 7;
+ stream->write(shifterU8);
+ shifterU8=ico;
+ shifterU8|=kul << 5;
+ stream->write(shifterU8);
+ stream->write(hpsPos);
+ stream->write(lid);
+ stream->write(fcPic_fcObj_lTagObj);
+ stream->write(ibstRMark);
+ dttmRMark.write(stream, false);
+ stream->write(unused26);
+ stream->write(istd);
+ stream->write(ftcSym);
+ stream->write(chSym);
+ stream->write(fChsDiff);
+ stream->write(idslRMReason);
+ stream->write(ysr);
+ stream->write(chYsr);
+ stream->write(chse);
+ stream->write(hpsKern);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void CHP::clear() {
+ fBold=0;
+ fItalic=0;
+ fRMarkDel=0;
+ fOutline=0;
+ fFldVanish=0;
+ fSmallCaps=0;
+ fCaps=0;
+ fVanish=0;
+ fRMark=0;
+ fSpec=0;
+ fStrike=0;
+ fObj=0;
+ fShadow=0;
+ fLowerCase=0;
+ fData=0;
+ fOle2=0;
+ unused2=0;
+ ftc=0;
+ hps=0;
+ dxaSpace=0;
+ iss=0;
+ unused10_3=0;
+ fSysVanish=0;
+ unused10_7=0;
+ ico=0;
+ kul=0;
+ hpsPos=0;
+ lid=0;
+ fcPic_fcObj_lTagObj=0;
+ ibstRMark=0;
+ dttmRMark.clear();
+ unused26=0;
+ istd=0;
+ ftcSym=0;
+ chSym=0;
+ fChsDiff=0;
+ idslRMReason=0;
+ ysr=0;
+ chYsr=0;
+ chse=0;
+ hpsKern=0;
+}
+
+void CHP::dump() const
+{
+ wvlog << "Dumping CHP:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping CHP done." << std::endl;
+}
+
+std::string CHP::toString() const
+{
+ std::string s( "CHP:" );
+ s += "\nfBold=";
+ s += uint2string( fBold );
+ s += "\nfItalic=";
+ s += uint2string( fItalic );
+ s += "\nfRMarkDel=";
+ s += uint2string( fRMarkDel );
+ s += "\nfOutline=";
+ s += uint2string( fOutline );
+ s += "\nfFldVanish=";
+ s += uint2string( fFldVanish );
+ s += "\nfSmallCaps=";
+ s += uint2string( fSmallCaps );
+ s += "\nfCaps=";
+ s += uint2string( fCaps );
+ s += "\nfVanish=";
+ s += uint2string( fVanish );
+ s += "\nfRMark=";
+ s += uint2string( fRMark );
+ s += "\nfSpec=";
+ s += uint2string( fSpec );
+ s += "\nfStrike=";
+ s += uint2string( fStrike );
+ s += "\nfObj=";
+ s += uint2string( fObj );
+ s += "\nfShadow=";
+ s += uint2string( fShadow );
+ s += "\nfLowerCase=";
+ s += uint2string( fLowerCase );
+ s += "\nfData=";
+ s += uint2string( fData );
+ s += "\nfOle2=";
+ s += uint2string( fOle2 );
+ s += "\nunused2=";
+ s += uint2string( unused2 );
+ s += "\nftc=";
+ s += uint2string( ftc );
+ s += "\nhps=";
+ s += uint2string( hps );
+ s += "\ndxaSpace=";
+ s += uint2string( dxaSpace );
+ s += "\niss=";
+ s += uint2string( iss );
+ s += "\nunused10_3=";
+ s += uint2string( unused10_3 );
+ s += "\nfSysVanish=";
+ s += uint2string( fSysVanish );
+ s += "\nunused10_7=";
+ s += uint2string( unused10_7 );
+ s += "\nico=";
+ s += uint2string( ico );
+ s += "\nkul=";
+ s += uint2string( kul );
+ s += "\nhpsPos=";
+ s += int2string( hpsPos );
+ s += "\nlid=";
+ s += uint2string( lid );
+ s += "\nfcPic_fcObj_lTagObj=";
+ s += uint2string( fcPic_fcObj_lTagObj );
+ s += "\nibstRMark=";
+ s += uint2string( ibstRMark );
+ s += "\ndttmRMark=";
+ s += "\n{" + dttmRMark.toString() + "}\n";
+ s += "\nunused26=";
+ s += uint2string( unused26 );
+ s += "\nistd=";
+ s += uint2string( istd );
+ s += "\nftcSym=";
+ s += uint2string( ftcSym );
+ s += "\nchSym=";
+ s += uint2string( chSym );
+ s += "\nfChsDiff=";
+ s += uint2string( fChsDiff );
+ s += "\nidslRMReason=";
+ s += uint2string( idslRMReason );
+ s += "\nysr=";
+ s += uint2string( ysr );
+ s += "\nchYsr=";
+ s += uint2string( chYsr );
+ s += "\nchse=";
+ s += uint2string( chse );
+ s += "\nhpsKern=";
+ s += uint2string( hpsKern );
+ s += "\nCHP Done.";
+ return s;
+}
+
+bool operator==(const CHP &lhs, const CHP &rhs) {
+
+ return lhs.fBold==rhs.fBold &&
+ lhs.fItalic==rhs.fItalic &&
+ lhs.fRMarkDel==rhs.fRMarkDel &&
+ lhs.fOutline==rhs.fOutline &&
+ lhs.fFldVanish==rhs.fFldVanish &&
+ lhs.fSmallCaps==rhs.fSmallCaps &&
+ lhs.fCaps==rhs.fCaps &&
+ lhs.fVanish==rhs.fVanish &&
+ lhs.fRMark==rhs.fRMark &&
+ lhs.fSpec==rhs.fSpec &&
+ lhs.fStrike==rhs.fStrike &&
+ lhs.fObj==rhs.fObj &&
+ lhs.fShadow==rhs.fShadow &&
+ lhs.fLowerCase==rhs.fLowerCase &&
+ lhs.fData==rhs.fData &&
+ lhs.fOle2==rhs.fOle2 &&
+ lhs.unused2==rhs.unused2 &&
+ lhs.ftc==rhs.ftc &&
+ lhs.hps==rhs.hps &&
+ lhs.dxaSpace==rhs.dxaSpace &&
+ lhs.iss==rhs.iss &&
+ lhs.unused10_3==rhs.unused10_3 &&
+ lhs.fSysVanish==rhs.fSysVanish &&
+ lhs.unused10_7==rhs.unused10_7 &&
+ lhs.ico==rhs.ico &&
+ lhs.kul==rhs.kul &&
+ lhs.hpsPos==rhs.hpsPos &&
+ lhs.lid==rhs.lid &&
+ lhs.fcPic_fcObj_lTagObj==rhs.fcPic_fcObj_lTagObj &&
+ lhs.ibstRMark==rhs.ibstRMark &&
+ lhs.dttmRMark==rhs.dttmRMark &&
+ lhs.unused26==rhs.unused26 &&
+ lhs.istd==rhs.istd &&
+ lhs.ftcSym==rhs.ftcSym &&
+ lhs.chSym==rhs.chSym &&
+ lhs.fChsDiff==rhs.fChsDiff &&
+ lhs.idslRMReason==rhs.idslRMReason &&
+ lhs.ysr==rhs.ysr &&
+ lhs.chYsr==rhs.chYsr &&
+ lhs.chse==rhs.chse &&
+ lhs.hpsKern==rhs.hpsKern;
+}
+
+bool operator!=(const CHP &lhs, const CHP &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// DCS implementation
+
+DCS::DCS() {
+ clear();
+}
+
+DCS::DCS(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+DCS::DCS(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool DCS::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU8=stream->readU8();
+ fdct=shifterU8;
+ shifterU8>>=3;
+ lines=shifterU8;
+ unused1=stream->readU8();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DCS::readPtr(const U8 *ptr) {
+
+ U8 shifterU8;
+
+ shifterU8=readU8(ptr);
+ ptr+=sizeof(U8);
+ fdct=shifterU8;
+ shifterU8>>=3;
+ lines=shifterU8;
+ unused1=readU8(ptr);
+ ptr+=sizeof(U8);
+}
+
+bool DCS::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU8=fdct;
+ shifterU8|=lines << 3;
+ stream->write(shifterU8);
+ stream->write(unused1);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DCS::clear() {
+ fdct=0;
+ lines=0;
+ unused1=0;
+}
+
+void DCS::dump() const
+{
+ wvlog << "Dumping DCS:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping DCS done." << std::endl;
+}
+
+std::string DCS::toString() const
+{
+ std::string s( "DCS:" );
+ s += "\nfdct=";
+ s += uint2string( fdct );
+ s += "\nlines=";
+ s += uint2string( lines );
+ s += "\nunused1=";
+ s += uint2string( unused1 );
+ s += "\nDCS Done.";
+ return s;
+}
+
+bool operator==(const DCS &lhs, const DCS &rhs) {
+
+ return lhs.fdct==rhs.fdct &&
+ lhs.lines==rhs.lines &&
+ lhs.unused1==rhs.unused1;
+}
+
+bool operator!=(const DCS &lhs, const DCS &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// DO implementation
+
+DO::DO() {
+ clear();
+}
+
+DO::DO(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool DO::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ fc=stream->readU32();
+ dok=stream->readU16();
+ cb=stream->readU16();
+ bx=stream->readU8();
+ by=stream->readU8();
+ dhgt=stream->readU16();
+ shifterU16=stream->readU16();
+ fAnchorLock=shifterU16;
+ shifterU16>>=1;
+ unused8=shifterU16;
+ rgdp=stream->readU8();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool DO::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(fc);
+ stream->write(dok);
+ stream->write(cb);
+ stream->write(bx);
+ stream->write(by);
+ stream->write(dhgt);
+ shifterU16=fAnchorLock;
+ shifterU16|=unused8 << 1;
+ stream->write(shifterU16);
+ stream->write(rgdp);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DO::clear() {
+ fc=0;
+ dok=0;
+ cb=0;
+ bx=0;
+ by=0;
+ dhgt=0;
+ fAnchorLock=0;
+ unused8=0;
+ rgdp=0;
+}
+
+bool operator==(const DO &lhs, const DO &rhs) {
+
+ return lhs.fc==rhs.fc &&
+ lhs.dok==rhs.dok &&
+ lhs.cb==rhs.cb &&
+ lhs.bx==rhs.bx &&
+ lhs.by==rhs.by &&
+ lhs.dhgt==rhs.dhgt &&
+ lhs.fAnchorLock==rhs.fAnchorLock &&
+ lhs.unused8==rhs.unused8 &&
+ lhs.rgdp==rhs.rgdp;
+}
+
+bool operator!=(const DO &lhs, const DO &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// DOP implementation
+
+DOP::DOP() {
+ clear();
+}
+
+DOP::DOP(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool DOP::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ fFacingPages=shifterU16;
+ shifterU16>>=1;
+ fWidowControl=shifterU16;
+ shifterU16>>=1;
+ fPMHMainDoc=shifterU16;
+ shifterU16>>=1;
+ grfSuppression=shifterU16;
+ shifterU16>>=2;
+ fpc=shifterU16;
+ shifterU16>>=2;
+ unused0_7=shifterU16;
+ shifterU16>>=1;
+ grpfIhdt=shifterU16;
+ shifterU16=stream->readU16();
+ rncFtn=shifterU16;
+ shifterU16>>=2;
+ nFtn=shifterU16;
+ shifterU8=stream->readU8();
+ fOutlineDirtySave=shifterU8;
+ shifterU8>>=1;
+ unused4_1=shifterU8;
+ shifterU8=stream->readU8();
+ fOnlyMacPics=shifterU8;
+ shifterU8>>=1;
+ fOnlyWinPics=shifterU8;
+ shifterU8>>=1;
+ fLabelDoc=shifterU8;
+ shifterU8>>=1;
+ fHyphCapitals=shifterU8;
+ shifterU8>>=1;
+ fAutoHyphen=shifterU8;
+ shifterU8>>=1;
+ fFormNoFields=shifterU8;
+ shifterU8>>=1;
+ fLinkStyles=shifterU8;
+ shifterU8>>=1;
+ fRevMarking=shifterU8;
+ shifterU8=stream->readU8();
+ fBackup=shifterU8;
+ shifterU8>>=1;
+ fExactCWords=shifterU8;
+ shifterU8>>=1;
+ fPagHidden=shifterU8;
+ shifterU8>>=1;
+ fPagResults=shifterU8;
+ shifterU8>>=1;
+ fLockAtn=shifterU8;
+ shifterU8>>=1;
+ fMirrorMargins=shifterU8;
+ shifterU8>>=1;
+ fReadOnlyRecommended=shifterU8;
+ shifterU8>>=1;
+ fDfltTrueType=shifterU8;
+ shifterU8=stream->readU8();
+ fPagSuppressTopSpacing=shifterU8;
+ shifterU8>>=1;
+ fProtEnabled=shifterU8;
+ shifterU8>>=1;
+ fDispFormFldSel=shifterU8;
+ shifterU8>>=1;
+ fRMView=shifterU8;
+ shifterU8>>=1;
+ fRMPrint=shifterU8;
+ shifterU8>>=1;
+ fWriteReservation=shifterU8;
+ shifterU8>>=1;
+ fLockRev=shifterU8;
+ shifterU8>>=1;
+ fEmbedFonts=shifterU8;
+ shifterU16=stream->readU16();
+ copts_fNoTabForInd=shifterU16;
+ shifterU16>>=1;
+ copts_fNoSpaceRaiseLower=shifterU16;
+ shifterU16>>=1;
+ copts_fSuppressSpbfAfterPageBreak=shifterU16;
+ shifterU16>>=1;
+ copts_fWrapTrailSpaces=shifterU16;
+ shifterU16>>=1;
+ copts_fMapPrintTextColor=shifterU16;
+ shifterU16>>=1;
+ copts_fNoColumnBalance=shifterU16;
+ shifterU16>>=1;
+ copts_fConvMailMergeEsc=shifterU16;
+ shifterU16>>=1;
+ copts_fSupressTopSpacing=shifterU16;
+ shifterU16>>=1;
+ copts_fOrigWordTableRules=shifterU16;
+ shifterU16>>=1;
+ copts_fTransparentMetafiles=shifterU16;
+ shifterU16>>=1;
+ copts_fShowBreaksInFrames=shifterU16;
+ shifterU16>>=1;
+ copts_fSwapBordersFacingPgs=shifterU16;
+ shifterU16>>=1;
+ unused8_12=shifterU16;
+ dxaTab=stream->readU16();
+ wSpare=stream->readU16();
+ dxaHotZ=stream->readU16();
+ cConsecHypLim=stream->readU16();
+ wSpare2=stream->readU16();
+ dttmCreated.read(stream, false);
+ dttmRevised.read(stream, false);
+ dttmLastPrint.read(stream, false);
+ nRevision=stream->readU16();
+ tmEdited=stream->readU32();
+ cWords=stream->readU32();
+ cCh=stream->readU32();
+ cPg=stream->readU16();
+ cParas=stream->readU32();
+ shifterU16=stream->readU16();
+ rncEdn=shifterU16;
+ shifterU16>>=2;
+ nEdn=shifterU16;
+ shifterU16=stream->readU16();
+ epc=shifterU16;
+ shifterU16>>=2;
+ nfcFtnRef=shifterU16;
+ shifterU16>>=4;
+ nfcEdnRef=shifterU16;
+ shifterU16>>=4;
+ fPrintFormData=shifterU16;
+ shifterU16>>=1;
+ fSaveFormData=shifterU16;
+ shifterU16>>=1;
+ fShadeFormData=shifterU16;
+ shifterU16>>=1;
+ unused54_13=shifterU16;
+ shifterU16>>=2;
+ fWCFtnEdn=shifterU16;
+ cLines=stream->readU32();
+ cWordsFtnEnd=stream->readU32();
+ cChFtnEdn=stream->readU32();
+ cPgFtnEdn=stream->readU16();
+ cParasFtnEdn=stream->readU32();
+ cLinesFtnEdn=stream->readU32();
+ lKeyProtDoc=stream->readU32();
+ shifterU16=stream->readU16();
+ wvkSaved=shifterU16;
+ shifterU16>>=3;
+ wScaleSaved=shifterU16;
+ shifterU16>>=9;
+ zkSaved=shifterU16;
+ shifterU16>>=2;
+ unused82_14=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool DOP::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=fFacingPages;
+ shifterU16|=fWidowControl << 1;
+ shifterU16|=fPMHMainDoc << 2;
+ shifterU16|=grfSuppression << 3;
+ shifterU16|=fpc << 5;
+ shifterU16|=unused0_7 << 7;
+ shifterU16|=grpfIhdt << 8;
+ stream->write(shifterU16);
+ shifterU16=rncFtn;
+ shifterU16|=nFtn << 2;
+ stream->write(shifterU16);
+ shifterU8=fOutlineDirtySave;
+ shifterU8|=unused4_1 << 1;
+ stream->write(shifterU8);
+ shifterU8=fOnlyMacPics;
+ shifterU8|=fOnlyWinPics << 1;
+ shifterU8|=fLabelDoc << 2;
+ shifterU8|=fHyphCapitals << 3;
+ shifterU8|=fAutoHyphen << 4;
+ shifterU8|=fFormNoFields << 5;
+ shifterU8|=fLinkStyles << 6;
+ shifterU8|=fRevMarking << 7;
+ stream->write(shifterU8);
+ shifterU8=fBackup;
+ shifterU8|=fExactCWords << 1;
+ shifterU8|=fPagHidden << 2;
+ shifterU8|=fPagResults << 3;
+ shifterU8|=fLockAtn << 4;
+ shifterU8|=fMirrorMargins << 5;
+ shifterU8|=fReadOnlyRecommended << 6;
+ shifterU8|=fDfltTrueType << 7;
+ stream->write(shifterU8);
+ shifterU8=fPagSuppressTopSpacing;
+ shifterU8|=fProtEnabled << 1;
+ shifterU8|=fDispFormFldSel << 2;
+ shifterU8|=fRMView << 3;
+ shifterU8|=fRMPrint << 4;
+ shifterU8|=fWriteReservation << 5;
+ shifterU8|=fLockRev << 6;
+ shifterU8|=fEmbedFonts << 7;
+ stream->write(shifterU8);
+ shifterU16=copts_fNoTabForInd;
+ shifterU16|=copts_fNoSpaceRaiseLower << 1;
+ shifterU16|=copts_fSuppressSpbfAfterPageBreak << 2;
+ shifterU16|=copts_fWrapTrailSpaces << 3;
+ shifterU16|=copts_fMapPrintTextColor << 4;
+ shifterU16|=copts_fNoColumnBalance << 5;
+ shifterU16|=copts_fConvMailMergeEsc << 6;
+ shifterU16|=copts_fSupressTopSpacing << 7;
+ shifterU16|=copts_fOrigWordTableRules << 8;
+ shifterU16|=copts_fTransparentMetafiles << 9;
+ shifterU16|=copts_fShowBreaksInFrames << 10;
+ shifterU16|=copts_fSwapBordersFacingPgs << 11;
+ shifterU16|=unused8_12 << 12;
+ stream->write(shifterU16);
+ stream->write(dxaTab);
+ stream->write(wSpare);
+ stream->write(dxaHotZ);
+ stream->write(cConsecHypLim);
+ stream->write(wSpare2);
+ dttmCreated.write(stream, false);
+ dttmRevised.write(stream, false);
+ dttmLastPrint.write(stream, false);
+ stream->write(nRevision);
+ stream->write(tmEdited);
+ stream->write(cWords);
+ stream->write(cCh);
+ stream->write(cPg);
+ stream->write(cParas);
+ shifterU16=rncEdn;
+ shifterU16|=nEdn << 2;
+ stream->write(shifterU16);
+ shifterU16=epc;
+ shifterU16|=nfcFtnRef << 2;
+ shifterU16|=nfcEdnRef << 6;
+ shifterU16|=fPrintFormData << 10;
+ shifterU16|=fSaveFormData << 11;
+ shifterU16|=fShadeFormData << 12;
+ shifterU16|=unused54_13 << 13;
+ shifterU16|=fWCFtnEdn << 15;
+ stream->write(shifterU16);
+ stream->write(cLines);
+ stream->write(cWordsFtnEnd);
+ stream->write(cChFtnEdn);
+ stream->write(cPgFtnEdn);
+ stream->write(cParasFtnEdn);
+ stream->write(cLinesFtnEdn);
+ stream->write(lKeyProtDoc);
+ shifterU16=wvkSaved;
+ shifterU16|=wScaleSaved << 3;
+ shifterU16|=zkSaved << 12;
+ shifterU16|=unused82_14 << 14;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DOP::clear() {
+ fFacingPages=0;
+ fWidowControl=0;
+ fPMHMainDoc=0;
+ grfSuppression=0;
+ fpc=0;
+ unused0_7=0;
+ grpfIhdt=0;
+ rncFtn=0;
+ nFtn=0;
+ fOutlineDirtySave=0;
+ unused4_1=0;
+ fOnlyMacPics=0;
+ fOnlyWinPics=0;
+ fLabelDoc=0;
+ fHyphCapitals=0;
+ fAutoHyphen=0;
+ fFormNoFields=0;
+ fLinkStyles=0;
+ fRevMarking=0;
+ fBackup=0;
+ fExactCWords=0;
+ fPagHidden=0;
+ fPagResults=0;
+ fLockAtn=0;
+ fMirrorMargins=0;
+ fReadOnlyRecommended=0;
+ fDfltTrueType=0;
+ fPagSuppressTopSpacing=0;
+ fProtEnabled=0;
+ fDispFormFldSel=0;
+ fRMView=0;
+ fRMPrint=0;
+ fWriteReservation=0;
+ fLockRev=0;
+ fEmbedFonts=0;
+ copts_fNoTabForInd=0;
+ copts_fNoSpaceRaiseLower=0;
+ copts_fSuppressSpbfAfterPageBreak=0;
+ copts_fWrapTrailSpaces=0;
+ copts_fMapPrintTextColor=0;
+ copts_fNoColumnBalance=0;
+ copts_fConvMailMergeEsc=0;
+ copts_fSupressTopSpacing=0;
+ copts_fOrigWordTableRules=0;
+ copts_fTransparentMetafiles=0;
+ copts_fShowBreaksInFrames=0;
+ copts_fSwapBordersFacingPgs=0;
+ unused8_12=0;
+ dxaTab=0;
+ wSpare=0;
+ dxaHotZ=0;
+ cConsecHypLim=0;
+ wSpare2=0;
+ dttmCreated.clear();
+ dttmRevised.clear();
+ dttmLastPrint.clear();
+ nRevision=0;
+ tmEdited=0;
+ cWords=0;
+ cCh=0;
+ cPg=0;
+ cParas=0;
+ rncEdn=0;
+ nEdn=0;
+ epc=0;
+ nfcFtnRef=0;
+ nfcEdnRef=0;
+ fPrintFormData=0;
+ fSaveFormData=0;
+ fShadeFormData=0;
+ unused54_13=0;
+ fWCFtnEdn=0;
+ cLines=0;
+ cWordsFtnEnd=0;
+ cChFtnEdn=0;
+ cPgFtnEdn=0;
+ cParasFtnEdn=0;
+ cLinesFtnEdn=0;
+ lKeyProtDoc=0;
+ wvkSaved=0;
+ wScaleSaved=0;
+ zkSaved=0;
+ unused82_14=0;
+}
+
+bool operator==(const DOP &lhs, const DOP &rhs) {
+
+ return lhs.fFacingPages==rhs.fFacingPages &&
+ lhs.fWidowControl==rhs.fWidowControl &&
+ lhs.fPMHMainDoc==rhs.fPMHMainDoc &&
+ lhs.grfSuppression==rhs.grfSuppression &&
+ lhs.fpc==rhs.fpc &&
+ lhs.unused0_7==rhs.unused0_7 &&
+ lhs.grpfIhdt==rhs.grpfIhdt &&
+ lhs.rncFtn==rhs.rncFtn &&
+ lhs.nFtn==rhs.nFtn &&
+ lhs.fOutlineDirtySave==rhs.fOutlineDirtySave &&
+ lhs.unused4_1==rhs.unused4_1 &&
+ lhs.fOnlyMacPics==rhs.fOnlyMacPics &&
+ lhs.fOnlyWinPics==rhs.fOnlyWinPics &&
+ lhs.fLabelDoc==rhs.fLabelDoc &&
+ lhs.fHyphCapitals==rhs.fHyphCapitals &&
+ lhs.fAutoHyphen==rhs.fAutoHyphen &&
+ lhs.fFormNoFields==rhs.fFormNoFields &&
+ lhs.fLinkStyles==rhs.fLinkStyles &&
+ lhs.fRevMarking==rhs.fRevMarking &&
+ lhs.fBackup==rhs.fBackup &&
+ lhs.fExactCWords==rhs.fExactCWords &&
+ lhs.fPagHidden==rhs.fPagHidden &&
+ lhs.fPagResults==rhs.fPagResults &&
+ lhs.fLockAtn==rhs.fLockAtn &&
+ lhs.fMirrorMargins==rhs.fMirrorMargins &&
+ lhs.fReadOnlyRecommended==rhs.fReadOnlyRecommended &&
+ lhs.fDfltTrueType==rhs.fDfltTrueType &&
+ lhs.fPagSuppressTopSpacing==rhs.fPagSuppressTopSpacing &&
+ lhs.fProtEnabled==rhs.fProtEnabled &&
+ lhs.fDispFormFldSel==rhs.fDispFormFldSel &&
+ lhs.fRMView==rhs.fRMView &&
+ lhs.fRMPrint==rhs.fRMPrint &&
+ lhs.fWriteReservation==rhs.fWriteReservation &&
+ lhs.fLockRev==rhs.fLockRev &&
+ lhs.fEmbedFonts==rhs.fEmbedFonts &&
+ lhs.copts_fNoTabForInd==rhs.copts_fNoTabForInd &&
+ lhs.copts_fNoSpaceRaiseLower==rhs.copts_fNoSpaceRaiseLower &&
+ lhs.copts_fSuppressSpbfAfterPageBreak==rhs.copts_fSuppressSpbfAfterPageBreak &&
+ lhs.copts_fWrapTrailSpaces==rhs.copts_fWrapTrailSpaces &&
+ lhs.copts_fMapPrintTextColor==rhs.copts_fMapPrintTextColor &&
+ lhs.copts_fNoColumnBalance==rhs.copts_fNoColumnBalance &&
+ lhs.copts_fConvMailMergeEsc==rhs.copts_fConvMailMergeEsc &&
+ lhs.copts_fSupressTopSpacing==rhs.copts_fSupressTopSpacing &&
+ lhs.copts_fOrigWordTableRules==rhs.copts_fOrigWordTableRules &&
+ lhs.copts_fTransparentMetafiles==rhs.copts_fTransparentMetafiles &&
+ lhs.copts_fShowBreaksInFrames==rhs.copts_fShowBreaksInFrames &&
+ lhs.copts_fSwapBordersFacingPgs==rhs.copts_fSwapBordersFacingPgs &&
+ lhs.unused8_12==rhs.unused8_12 &&
+ lhs.dxaTab==rhs.dxaTab &&
+ lhs.wSpare==rhs.wSpare &&
+ lhs.dxaHotZ==rhs.dxaHotZ &&
+ lhs.cConsecHypLim==rhs.cConsecHypLim &&
+ lhs.wSpare2==rhs.wSpare2 &&
+ lhs.dttmCreated==rhs.dttmCreated &&
+ lhs.dttmRevised==rhs.dttmRevised &&
+ lhs.dttmLastPrint==rhs.dttmLastPrint &&
+ lhs.nRevision==rhs.nRevision &&
+ lhs.tmEdited==rhs.tmEdited &&
+ lhs.cWords==rhs.cWords &&
+ lhs.cCh==rhs.cCh &&
+ lhs.cPg==rhs.cPg &&
+ lhs.cParas==rhs.cParas &&
+ lhs.rncEdn==rhs.rncEdn &&
+ lhs.nEdn==rhs.nEdn &&
+ lhs.epc==rhs.epc &&
+ lhs.nfcFtnRef==rhs.nfcFtnRef &&
+ lhs.nfcEdnRef==rhs.nfcEdnRef &&
+ lhs.fPrintFormData==rhs.fPrintFormData &&
+ lhs.fSaveFormData==rhs.fSaveFormData &&
+ lhs.fShadeFormData==rhs.fShadeFormData &&
+ lhs.unused54_13==rhs.unused54_13 &&
+ lhs.fWCFtnEdn==rhs.fWCFtnEdn &&
+ lhs.cLines==rhs.cLines &&
+ lhs.cWordsFtnEnd==rhs.cWordsFtnEnd &&
+ lhs.cChFtnEdn==rhs.cChFtnEdn &&
+ lhs.cPgFtnEdn==rhs.cPgFtnEdn &&
+ lhs.cParasFtnEdn==rhs.cParasFtnEdn &&
+ lhs.cLinesFtnEdn==rhs.cLinesFtnEdn &&
+ lhs.lKeyProtDoc==rhs.lKeyProtDoc &&
+ lhs.wvkSaved==rhs.wvkSaved &&
+ lhs.wScaleSaved==rhs.wScaleSaved &&
+ lhs.zkSaved==rhs.zkSaved &&
+ lhs.unused82_14==rhs.unused82_14;
+}
+
+bool operator!=(const DOP &lhs, const DOP &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// DPARC implementation
+
+DPARC::DPARC() {
+ clear();
+}
+
+DPARC::DPARC(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool DPARC::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ dphead.read(stream, false);
+ lnpc=stream->readU32();
+ lnpw=stream->readU16();
+ lnps=stream->readU16();
+ dlpcFg=stream->readU32();
+ dlpcBg=stream->readU32();
+ flpp=stream->readU16();
+ shdwpi=stream->readU16();
+ xaOffset=stream->readU16();
+ yaOffset=stream->readU16();
+ shifterU16=stream->readU16();
+ fLeft=shifterU16;
+ shifterU16>>=8;
+ fUp=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool DPARC::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ dphead.write(stream, false);
+ stream->write(lnpc);
+ stream->write(lnpw);
+ stream->write(lnps);
+ stream->write(dlpcFg);
+ stream->write(dlpcBg);
+ stream->write(flpp);
+ stream->write(shdwpi);
+ stream->write(xaOffset);
+ stream->write(yaOffset);
+ shifterU16=fLeft;
+ shifterU16|=fUp << 8;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DPARC::clear() {
+ dphead.clear();
+ lnpc=0;
+ lnpw=0;
+ lnps=0;
+ dlpcFg=0;
+ dlpcBg=0;
+ flpp=0;
+ shdwpi=0;
+ xaOffset=0;
+ yaOffset=0;
+ fLeft=0;
+ fUp=0;
+}
+
+bool operator==(const DPARC &lhs, const DPARC &rhs) {
+
+ return lhs.dphead==rhs.dphead &&
+ lhs.lnpc==rhs.lnpc &&
+ lhs.lnpw==rhs.lnpw &&
+ lhs.lnps==rhs.lnps &&
+ lhs.dlpcFg==rhs.dlpcFg &&
+ lhs.dlpcBg==rhs.dlpcBg &&
+ lhs.flpp==rhs.flpp &&
+ lhs.shdwpi==rhs.shdwpi &&
+ lhs.xaOffset==rhs.xaOffset &&
+ lhs.yaOffset==rhs.yaOffset &&
+ lhs.fLeft==rhs.fLeft &&
+ lhs.fUp==rhs.fUp;
+}
+
+bool operator!=(const DPARC &lhs, const DPARC &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// DPCALLOUT implementation
+
+DPCALLOUT::DPCALLOUT() {
+ clear();
+}
+
+DPCALLOUT::DPCALLOUT(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool DPCALLOUT::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ dphead.read(stream, false);
+ unused12=stream->readU16();
+ dzaOffset=stream->readU16();
+ dzaDescent=stream->readU16();
+ dzaLength=stream->readU16();
+ dptxbx.read(stream, false);
+ dpPolyLine.read(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool DPCALLOUT::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ dphead.write(stream, false);
+ stream->write(unused12);
+ stream->write(dzaOffset);
+ stream->write(dzaDescent);
+ stream->write(dzaLength);
+ dptxbx.write(stream, false);
+ dpPolyLine.write(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DPCALLOUT::clear() {
+ dphead.clear();
+ unused12=0;
+ dzaOffset=0;
+ dzaDescent=0;
+ dzaLength=0;
+ dptxbx.clear();
+ dpPolyLine.clear();
+}
+
+bool operator==(const DPCALLOUT &lhs, const DPCALLOUT &rhs) {
+
+ return lhs.dphead==rhs.dphead &&
+ lhs.unused12==rhs.unused12 &&
+ lhs.dzaOffset==rhs.dzaOffset &&
+ lhs.dzaDescent==rhs.dzaDescent &&
+ lhs.dzaLength==rhs.dzaLength &&
+ lhs.dptxbx==rhs.dptxbx &&
+ lhs.dpPolyLine==rhs.dpPolyLine;
+}
+
+bool operator!=(const DPCALLOUT &lhs, const DPCALLOUT &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// DPELLIPSE implementation
+
+DPELLIPSE::DPELLIPSE() {
+ clear();
+}
+
+DPELLIPSE::DPELLIPSE(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool DPELLIPSE::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ dphead.read(stream, false);
+ lnpc=stream->readU32();
+ lnpw=stream->readU16();
+ lnps=stream->readU16();
+ dlpcFg=stream->readU32();
+ dlpcBg=stream->readU32();
+ flpp=stream->readU16();
+ shdwpi=stream->readU16();
+ xaOffset=stream->readU16();
+ yaOffset=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool DPELLIPSE::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ dphead.write(stream, false);
+ stream->write(lnpc);
+ stream->write(lnpw);
+ stream->write(lnps);
+ stream->write(dlpcFg);
+ stream->write(dlpcBg);
+ stream->write(flpp);
+ stream->write(shdwpi);
+ stream->write(xaOffset);
+ stream->write(yaOffset);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DPELLIPSE::clear() {
+ dphead.clear();
+ lnpc=0;
+ lnpw=0;
+ lnps=0;
+ dlpcFg=0;
+ dlpcBg=0;
+ flpp=0;
+ shdwpi=0;
+ xaOffset=0;
+ yaOffset=0;
+}
+
+bool operator==(const DPELLIPSE &lhs, const DPELLIPSE &rhs) {
+
+ return lhs.dphead==rhs.dphead &&
+ lhs.lnpc==rhs.lnpc &&
+ lhs.lnpw==rhs.lnpw &&
+ lhs.lnps==rhs.lnps &&
+ lhs.dlpcFg==rhs.dlpcFg &&
+ lhs.dlpcBg==rhs.dlpcBg &&
+ lhs.flpp==rhs.flpp &&
+ lhs.shdwpi==rhs.shdwpi &&
+ lhs.xaOffset==rhs.xaOffset &&
+ lhs.yaOffset==rhs.yaOffset;
+}
+
+bool operator!=(const DPELLIPSE &lhs, const DPELLIPSE &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// DPLINE implementation
+
+DPLINE::DPLINE() {
+ clear();
+}
+
+DPLINE::DPLINE(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool DPLINE::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ dphead.read(stream, false);
+ xaStart=stream->readU16();
+ yaStart=stream->readU16();
+ xaEnd=stream->readU16();
+ yaEnd=stream->readU16();
+ lnpc=stream->readU32();
+ lnpw=stream->readU16();
+ lnps=stream->readU16();
+ shifterU16=stream->readU16();
+ eppsStart=shifterU16;
+ shifterU16>>=2;
+ eppwStart=shifterU16;
+ shifterU16>>=2;
+ epplStart=shifterU16;
+ shifterU16>>=2;
+ unused24_6=shifterU16;
+ shifterU16=stream->readU16();
+ eppsEnd=shifterU16;
+ shifterU16>>=2;
+ eppwEnd=shifterU16;
+ shifterU16>>=2;
+ epplEnd=shifterU16;
+ shifterU16>>=2;
+ unused26_6=shifterU16;
+ shdwpi=stream->readU16();
+ xaOffset=stream->readU16();
+ yaOffset=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool DPLINE::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ dphead.write(stream, false);
+ stream->write(xaStart);
+ stream->write(yaStart);
+ stream->write(xaEnd);
+ stream->write(yaEnd);
+ stream->write(lnpc);
+ stream->write(lnpw);
+ stream->write(lnps);
+ shifterU16=eppsStart;
+ shifterU16|=eppwStart << 2;
+ shifterU16|=epplStart << 4;
+ shifterU16|=unused24_6 << 6;
+ stream->write(shifterU16);
+ shifterU16=eppsEnd;
+ shifterU16|=eppwEnd << 2;
+ shifterU16|=epplEnd << 4;
+ shifterU16|=unused26_6 << 6;
+ stream->write(shifterU16);
+ stream->write(shdwpi);
+ stream->write(xaOffset);
+ stream->write(yaOffset);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DPLINE::clear() {
+ dphead.clear();
+ xaStart=0;
+ yaStart=0;
+ xaEnd=0;
+ yaEnd=0;
+ lnpc=0;
+ lnpw=0;
+ lnps=0;
+ eppsStart=0;
+ eppwStart=0;
+ epplStart=0;
+ unused24_6=0;
+ eppsEnd=0;
+ eppwEnd=0;
+ epplEnd=0;
+ unused26_6=0;
+ shdwpi=0;
+ xaOffset=0;
+ yaOffset=0;
+}
+
+bool operator==(const DPLINE &lhs, const DPLINE &rhs) {
+
+ return lhs.dphead==rhs.dphead &&
+ lhs.xaStart==rhs.xaStart &&
+ lhs.yaStart==rhs.yaStart &&
+ lhs.xaEnd==rhs.xaEnd &&
+ lhs.yaEnd==rhs.yaEnd &&
+ lhs.lnpc==rhs.lnpc &&
+ lhs.lnpw==rhs.lnpw &&
+ lhs.lnps==rhs.lnps &&
+ lhs.eppsStart==rhs.eppsStart &&
+ lhs.eppwStart==rhs.eppwStart &&
+ lhs.epplStart==rhs.epplStart &&
+ lhs.unused24_6==rhs.unused24_6 &&
+ lhs.eppsEnd==rhs.eppsEnd &&
+ lhs.eppwEnd==rhs.eppwEnd &&
+ lhs.epplEnd==rhs.epplEnd &&
+ lhs.unused26_6==rhs.unused26_6 &&
+ lhs.shdwpi==rhs.shdwpi &&
+ lhs.xaOffset==rhs.xaOffset &&
+ lhs.yaOffset==rhs.yaOffset;
+}
+
+bool operator!=(const DPLINE &lhs, const DPLINE &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// DPRECT implementation
+
+DPRECT::DPRECT() {
+ clear();
+}
+
+DPRECT::DPRECT(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool DPRECT::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ dphead.read(stream, false);
+ lnpc=stream->readU32();
+ lnpw=stream->readU16();
+ lnps=stream->readU16();
+ dlpcFg=stream->readU32();
+ dlpcBg=stream->readU32();
+ flpp=stream->readU16();
+ shdwpi=stream->readU16();
+ xaOffset=stream->readU16();
+ yaOffset=stream->readU16();
+ shifterU16=stream->readU16();
+ fRoundCorners=shifterU16;
+ shifterU16>>=1;
+ zaShape=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool DPRECT::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ dphead.write(stream, false);
+ stream->write(lnpc);
+ stream->write(lnpw);
+ stream->write(lnps);
+ stream->write(dlpcFg);
+ stream->write(dlpcBg);
+ stream->write(flpp);
+ stream->write(shdwpi);
+ stream->write(xaOffset);
+ stream->write(yaOffset);
+ shifterU16=fRoundCorners;
+ shifterU16|=zaShape << 1;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DPRECT::clear() {
+ dphead.clear();
+ lnpc=0;
+ lnpw=0;
+ lnps=0;
+ dlpcFg=0;
+ dlpcBg=0;
+ flpp=0;
+ shdwpi=0;
+ xaOffset=0;
+ yaOffset=0;
+ fRoundCorners=0;
+ zaShape=0;
+}
+
+bool operator==(const DPRECT &lhs, const DPRECT &rhs) {
+
+ return lhs.dphead==rhs.dphead &&
+ lhs.lnpc==rhs.lnpc &&
+ lhs.lnpw==rhs.lnpw &&
+ lhs.lnps==rhs.lnps &&
+ lhs.dlpcFg==rhs.dlpcFg &&
+ lhs.dlpcBg==rhs.dlpcBg &&
+ lhs.flpp==rhs.flpp &&
+ lhs.shdwpi==rhs.shdwpi &&
+ lhs.xaOffset==rhs.xaOffset &&
+ lhs.yaOffset==rhs.yaOffset &&
+ lhs.fRoundCorners==rhs.fRoundCorners &&
+ lhs.zaShape==rhs.zaShape;
+}
+
+bool operator!=(const DPRECT &lhs, const DPRECT &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// DPSAMPLE implementation
+
+DPSAMPLE::DPSAMPLE() {
+ clear();
+}
+
+DPSAMPLE::DPSAMPLE(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool DPSAMPLE::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ dphead.read(stream, false);
+ lnpc=stream->readU32();
+ lnpw=stream->readU16();
+ lnps=stream->readU16();
+ dlpcFg=stream->readU32();
+ dlpcBg=stream->readU32();
+ flpp=stream->readU16();
+ shifterU16=stream->readU16();
+ eppsStart=shifterU16;
+ shifterU16>>=2;
+ eppwStart=shifterU16;
+ shifterU16>>=2;
+ epplStart=shifterU16;
+ shifterU16>>=2;
+ unused30_6=shifterU16;
+ shifterU16=stream->readU16();
+ eppsEnd=shifterU16;
+ shifterU16>>=2;
+ eppwEnd=shifterU16;
+ shifterU16>>=2;
+ epplEnd=shifterU16;
+ shifterU16>>=2;
+ unused32_6=shifterU16;
+ shdwpi=stream->readU16();
+ xaOffset=stream->readU16();
+ yaOffset=stream->readU16();
+ unused40=stream->readU16();
+ dzaOffset=stream->readU16();
+ dzaDescent=stream->readU16();
+ dzaLength=stream->readU16();
+ shifterU16=stream->readU16();
+ fRoundCorners=shifterU16;
+ shifterU16>>=1;
+ zaShape=shifterU16;
+ dzaInternalMargin=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool DPSAMPLE::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ dphead.write(stream, false);
+ stream->write(lnpc);
+ stream->write(lnpw);
+ stream->write(lnps);
+ stream->write(dlpcFg);
+ stream->write(dlpcBg);
+ stream->write(flpp);
+ shifterU16=eppsStart;
+ shifterU16|=eppwStart << 2;
+ shifterU16|=epplStart << 4;
+ shifterU16|=unused30_6 << 6;
+ stream->write(shifterU16);
+ shifterU16=eppsEnd;
+ shifterU16|=eppwEnd << 2;
+ shifterU16|=epplEnd << 4;
+ shifterU16|=unused32_6 << 6;
+ stream->write(shifterU16);
+ stream->write(shdwpi);
+ stream->write(xaOffset);
+ stream->write(yaOffset);
+ stream->write(unused40);
+ stream->write(dzaOffset);
+ stream->write(dzaDescent);
+ stream->write(dzaLength);
+ shifterU16=fRoundCorners;
+ shifterU16|=zaShape << 1;
+ stream->write(shifterU16);
+ stream->write(dzaInternalMargin);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DPSAMPLE::clear() {
+ dphead.clear();
+ lnpc=0;
+ lnpw=0;
+ lnps=0;
+ dlpcFg=0;
+ dlpcBg=0;
+ flpp=0;
+ eppsStart=0;
+ eppwStart=0;
+ epplStart=0;
+ unused30_6=0;
+ eppsEnd=0;
+ eppwEnd=0;
+ epplEnd=0;
+ unused32_6=0;
+ shdwpi=0;
+ xaOffset=0;
+ yaOffset=0;
+ unused40=0;
+ dzaOffset=0;
+ dzaDescent=0;
+ dzaLength=0;
+ fRoundCorners=0;
+ zaShape=0;
+ dzaInternalMargin=0;
+}
+
+bool operator==(const DPSAMPLE &lhs, const DPSAMPLE &rhs) {
+
+ return lhs.dphead==rhs.dphead &&
+ lhs.lnpc==rhs.lnpc &&
+ lhs.lnpw==rhs.lnpw &&
+ lhs.lnps==rhs.lnps &&
+ lhs.dlpcFg==rhs.dlpcFg &&
+ lhs.dlpcBg==rhs.dlpcBg &&
+ lhs.flpp==rhs.flpp &&
+ lhs.eppsStart==rhs.eppsStart &&
+ lhs.eppwStart==rhs.eppwStart &&
+ lhs.epplStart==rhs.epplStart &&
+ lhs.unused30_6==rhs.unused30_6 &&
+ lhs.eppsEnd==rhs.eppsEnd &&
+ lhs.eppwEnd==rhs.eppwEnd &&
+ lhs.epplEnd==rhs.epplEnd &&
+ lhs.unused32_6==rhs.unused32_6 &&
+ lhs.shdwpi==rhs.shdwpi &&
+ lhs.xaOffset==rhs.xaOffset &&
+ lhs.yaOffset==rhs.yaOffset &&
+ lhs.unused40==rhs.unused40 &&
+ lhs.dzaOffset==rhs.dzaOffset &&
+ lhs.dzaDescent==rhs.dzaDescent &&
+ lhs.dzaLength==rhs.dzaLength &&
+ lhs.fRoundCorners==rhs.fRoundCorners &&
+ lhs.zaShape==rhs.zaShape &&
+ lhs.dzaInternalMargin==rhs.dzaInternalMargin;
+}
+
+bool operator!=(const DPSAMPLE &lhs, const DPSAMPLE &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// FDOA implementation
+
+FDOA::FDOA() {
+ clear();
+}
+
+FDOA::FDOA(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool FDOA::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ fc=stream->readU32();
+ ctxbx=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool FDOA::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(fc);
+ stream->write(ctxbx);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void FDOA::clear() {
+ fc=0;
+ ctxbx=0;
+}
+
+bool operator==(const FDOA &lhs, const FDOA &rhs) {
+
+ return lhs.fc==rhs.fc &&
+ lhs.ctxbx==rhs.ctxbx;
+}
+
+bool operator!=(const FDOA &lhs, const FDOA &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// FIB implementation
+
+FIB::FIB() {
+ clear();
+}
+
+FIB::FIB(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool FIB::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ wIdent=stream->readU16();
+ nFib=stream->readU16();
+ nProduct=stream->readU16();
+ lid=stream->readU16();
+ pnNext=stream->readU16();
+ shifterU16=stream->readU16();
+ fDot=shifterU16;
+ shifterU16>>=1;
+ fGlsy=shifterU16;
+ shifterU16>>=1;
+ fComplex=shifterU16;
+ shifterU16>>=1;
+ fHasPic=shifterU16;
+ shifterU16>>=1;
+ cQuickSaves=shifterU16;
+ shifterU16>>=4;
+ fEncrypted=shifterU16;
+ shifterU16>>=1;
+ unused10_9=shifterU16;
+ shifterU16>>=1;
+ fReadOnlyRecommended=shifterU16;
+ shifterU16>>=1;
+ fWriteReservation=shifterU16;
+ shifterU16>>=1;
+ fExtChar=shifterU16;
+ shifterU16>>=1;
+ unused10_13=shifterU16;
+ nFibBack=stream->readU16();
+ lKey=stream->readU32();
+ envr=stream->readU8();
+ unused19=stream->readU8();
+ chse=stream->readU16();
+ chseTables=stream->readU16();
+ fcMin=stream->readU32();
+ fcMac=stream->readU32();
+ cbMac=stream->readU32();
+ fcSpare0=stream->readU32();
+ fcSpare1=stream->readU32();
+ fcSpare2=stream->readU32();
+ fcSpare3=stream->readU32();
+ ccpText=stream->readU32();
+ ccpFtn=stream->readU32();
+ ccpHdd=stream->readU32();
+ ccpMcr=stream->readU32();
+ ccpAtn=stream->readU32();
+ ccpEdn=stream->readU32();
+ ccpTxbx=stream->readU32();
+ ccpHdrTxbx=stream->readU32();
+ ccpSpare2=stream->readU32();
+ fcStshfOrig=stream->readU32();
+ lcbStshfOrig=stream->readU32();
+ fcStshf=stream->readU32();
+ lcbStshf=stream->readU32();
+ fcPlcffndRef=stream->readU32();
+ lcbPlcffndRef=stream->readU32();
+ fcPlcffndTxt=stream->readU32();
+ lcbPlcffndTxt=stream->readU32();
+ fcPlcfandRef=stream->readU32();
+ lcbPlcfandRef=stream->readU32();
+ fcPlcfandTxt=stream->readU32();
+ lcbPlcfandTxt=stream->readU32();
+ fcPlcfsed=stream->readU32();
+ lcbPlcfsed=stream->readU32();
+ fcPlcfpad=stream->readU32();
+ lcbPlcfpad=stream->readU32();
+ fcPlcfphe=stream->readU32();
+ lcbPlcfphe=stream->readU32();
+ fcSttbfglsy=stream->readU32();
+ lcbSttbfglsy=stream->readU32();
+ fcPlcfglsy=stream->readU32();
+ lcbPlcfglsy=stream->readU32();
+ fcPlcfhdd=stream->readU32();
+ lcbPlcfhdd=stream->readU32();
+ fcPlcfbteChpx=stream->readU32();
+ lcbPlcfbteChpx=stream->readU32();
+ fcPlcfbtePapx=stream->readU32();
+ lcbPlcfbtePapx=stream->readU32();
+ fcPlcfsea=stream->readU32();
+ lcbPlcfsea=stream->readU32();
+ fcSttbfffn=stream->readU32();
+ lcbSttbfffn=stream->readU32();
+ fcPlcffldMom=stream->readU32();
+ lcbPlcffldMom=stream->readU32();
+ fcPlcffldHdr=stream->readU32();
+ lcbPlcffldHdr=stream->readU32();
+ fcPlcffldFtn=stream->readU32();
+ lcbPlcffldFtn=stream->readU32();
+ fcPlcffldAtn=stream->readU32();
+ lcbPlcffldAtn=stream->readU32();
+ fcPlcffldMcr=stream->readU32();
+ lcbPlcffldMcr=stream->readU32();
+ fcSttbfbkmk=stream->readU32();
+ lcbSttbfbkmk=stream->readU32();
+ fcPlcfbkf=stream->readU32();
+ lcbPlcfbkf=stream->readU32();
+ fcPlcfbkl=stream->readU32();
+ lcbPlcfbkl=stream->readU32();
+ fcCmds=stream->readU32();
+ lcbCmds=stream->readU32();
+ fcPlcmcr=stream->readU32();
+ lcbPlcmcr=stream->readU32();
+ fcSttbfmcr=stream->readU32();
+ lcbSttbfmcr=stream->readU32();
+ fcPrDrvr=stream->readU32();
+ lcbPrDrvr=stream->readU32();
+ fcPrEnvPort=stream->readU32();
+ lcbPrEnvPort=stream->readU32();
+ fcPrEnvLand=stream->readU32();
+ lcbPrEnvLand=stream->readU32();
+ fcWss=stream->readU32();
+ lcbWss=stream->readU32();
+ fcDop=stream->readU32();
+ lcbDop=stream->readU32();
+ fcSttbfAssoc=stream->readU32();
+ lcbSttbfAssoc=stream->readU32();
+ fcClx=stream->readU32();
+ lcbClx=stream->readU32();
+ fcPlcfpgdFtn=stream->readU32();
+ lcbPlcfpgdFtn=stream->readU32();
+ fcAutosaveSource=stream->readU32();
+ lcbAutosaveSource=stream->readU32();
+ fcGrpStAtnOwners=stream->readU32();
+ lcbGrpStAtnOwners=stream->readU32();
+ fcSttbfAtnbkmk=stream->readU32();
+ lcbSttbfAtnbkmk=stream->readU32();
+ wSpare4Fib=stream->readU16();
+ pnChpFirst=stream->readU16();
+ pnPapFirst=stream->readU16();
+ cpnBteChp=stream->readU16();
+ cpnBtePap=stream->readU16();
+ fcPlcfdoaMom=stream->readU32();
+ lcbPlcfdoaMom=stream->readU32();
+ fcPlcfdoaHdr=stream->readU32();
+ lcbPlcfdoaHdr=stream->readU32();
+ fcUnused1=stream->readU32();
+ lcbUnused1=stream->readU32();
+ fcUnused2=stream->readU32();
+ lcbUnused2=stream->readU32();
+ fcPlcfAtnbkf=stream->readU32();
+ lcbPlcfAtnbkf=stream->readU32();
+ fcPlcfAtnbkl=stream->readU32();
+ lcbPlcfAtnbkl=stream->readU32();
+ fcPms=stream->readU32();
+ lcbPms=stream->readU32();
+ fcFormFldSttbf=stream->readU32();
+ lcbFormFldSttbf=stream->readU32();
+ fcPlcfendRef=stream->readU32();
+ lcbPlcfendRef=stream->readU32();
+ fcPlcfendTxt=stream->readU32();
+ lcbPlcfendTxt=stream->readU32();
+ fcPlcffldEdn=stream->readU32();
+ lcbPlcffldEdn=stream->readU32();
+ fcPlcfpgdEdn=stream->readU32();
+ lcbPlcfpgdEdn=stream->readU32();
+ fcUnused3=stream->readU32();
+ lcbUnused3=stream->readU32();
+ fcSttbfRMark=stream->readU32();
+ lcbSttbfRMark=stream->readU32();
+ fcSttbfCaption=stream->readU32();
+ lcbSttbfCaption=stream->readU32();
+ fcSttbfAutoCaption=stream->readU32();
+ lcbSttbfAutoCaption=stream->readU32();
+ fcPlcfwkb=stream->readU32();
+ lcbPlcfwkb=stream->readU32();
+ fcUnused4=stream->readU32();
+ lcbUnused4=stream->readU32();
+ fcPlcftxbxTxt=stream->readU32();
+ lcbPlcftxbxTxt=stream->readU32();
+ fcPlcffldTxbx=stream->readU32();
+ lcbPlcffldTxbx=stream->readU32();
+ fcPlcfHdrtxbxTxt=stream->readU32();
+ lcbPlcfHdrtxbxTxt=stream->readU32();
+ fcPlcffldHdrTxbx=stream->readU32();
+ lcbPlcffldHdrTxbx=stream->readU32();
+ fcStwUser=stream->readU32();
+ lcbStwUser=stream->readU32();
+ fcSttbttmbd=stream->readU32();
+ lcbSttbttmbd=stream->readU32();
+ fcUnused=stream->readU32();
+ lcbUnused=stream->readU32();
+ fcPgdMother=stream->readU32();
+ lcbPgdMother=stream->readU32();
+ fcBkdMother=stream->readU32();
+ lcbBkdMother=stream->readU32();
+ fcPgdFtn=stream->readU32();
+ lcbPgdFtn=stream->readU32();
+ fcBkdFtn=stream->readU32();
+ lcbBkdFtn=stream->readU32();
+ fcPgdEdn=stream->readU32();
+ lcbPgdEdn=stream->readU32();
+ fcBkdEdn=stream->readU32();
+ lcbBkdEdn=stream->readU32();
+ fcSttbfIntlFld=stream->readU32();
+ lcbSttbfIntlFld=stream->readU32();
+ fcRouteSlip=stream->readU32();
+ lcbRouteSlip=stream->readU32();
+ fcSttbSavedBy=stream->readU32();
+ lcbSttbSavedBy=stream->readU32();
+ fcSttbFnm=stream->readU32();
+ lcbSttbFnm=stream->readU32();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool FIB::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(wIdent);
+ stream->write(nFib);
+ stream->write(nProduct);
+ stream->write(lid);
+ stream->write(pnNext);
+ shifterU16=fDot;
+ shifterU16|=fGlsy << 1;
+ shifterU16|=fComplex << 2;
+ shifterU16|=fHasPic << 3;
+ shifterU16|=cQuickSaves << 4;
+ shifterU16|=fEncrypted << 8;
+ shifterU16|=unused10_9 << 9;
+ shifterU16|=fReadOnlyRecommended << 10;
+ shifterU16|=fWriteReservation << 11;
+ shifterU16|=fExtChar << 12;
+ shifterU16|=unused10_13 << 13;
+ stream->write(shifterU16);
+ stream->write(nFibBack);
+ stream->write(lKey);
+ stream->write(envr);
+ stream->write(unused19);
+ stream->write(chse);
+ stream->write(chseTables);
+ stream->write(fcMin);
+ stream->write(fcMac);
+ stream->write(cbMac);
+ stream->write(fcSpare0);
+ stream->write(fcSpare1);
+ stream->write(fcSpare2);
+ stream->write(fcSpare3);
+ stream->write(ccpText);
+ stream->write(ccpFtn);
+ stream->write(ccpHdd);
+ stream->write(ccpMcr);
+ stream->write(ccpAtn);
+ stream->write(ccpEdn);
+ stream->write(ccpTxbx);
+ stream->write(ccpHdrTxbx);
+ stream->write(ccpSpare2);
+ stream->write(fcStshfOrig);
+ stream->write(lcbStshfOrig);
+ stream->write(fcStshf);
+ stream->write(lcbStshf);
+ stream->write(fcPlcffndRef);
+ stream->write(lcbPlcffndRef);
+ stream->write(fcPlcffndTxt);
+ stream->write(lcbPlcffndTxt);
+ stream->write(fcPlcfandRef);
+ stream->write(lcbPlcfandRef);
+ stream->write(fcPlcfandTxt);
+ stream->write(lcbPlcfandTxt);
+ stream->write(fcPlcfsed);
+ stream->write(lcbPlcfsed);
+ stream->write(fcPlcfpad);
+ stream->write(lcbPlcfpad);
+ stream->write(fcPlcfphe);
+ stream->write(lcbPlcfphe);
+ stream->write(fcSttbfglsy);
+ stream->write(lcbSttbfglsy);
+ stream->write(fcPlcfglsy);
+ stream->write(lcbPlcfglsy);
+ stream->write(fcPlcfhdd);
+ stream->write(lcbPlcfhdd);
+ stream->write(fcPlcfbteChpx);
+ stream->write(lcbPlcfbteChpx);
+ stream->write(fcPlcfbtePapx);
+ stream->write(lcbPlcfbtePapx);
+ stream->write(fcPlcfsea);
+ stream->write(lcbPlcfsea);
+ stream->write(fcSttbfffn);
+ stream->write(lcbSttbfffn);
+ stream->write(fcPlcffldMom);
+ stream->write(lcbPlcffldMom);
+ stream->write(fcPlcffldHdr);
+ stream->write(lcbPlcffldHdr);
+ stream->write(fcPlcffldFtn);
+ stream->write(lcbPlcffldFtn);
+ stream->write(fcPlcffldAtn);
+ stream->write(lcbPlcffldAtn);
+ stream->write(fcPlcffldMcr);
+ stream->write(lcbPlcffldMcr);
+ stream->write(fcSttbfbkmk);
+ stream->write(lcbSttbfbkmk);
+ stream->write(fcPlcfbkf);
+ stream->write(lcbPlcfbkf);
+ stream->write(fcPlcfbkl);
+ stream->write(lcbPlcfbkl);
+ stream->write(fcCmds);
+ stream->write(lcbCmds);
+ stream->write(fcPlcmcr);
+ stream->write(lcbPlcmcr);
+ stream->write(fcSttbfmcr);
+ stream->write(lcbSttbfmcr);
+ stream->write(fcPrDrvr);
+ stream->write(lcbPrDrvr);
+ stream->write(fcPrEnvPort);
+ stream->write(lcbPrEnvPort);
+ stream->write(fcPrEnvLand);
+ stream->write(lcbPrEnvLand);
+ stream->write(fcWss);
+ stream->write(lcbWss);
+ stream->write(fcDop);
+ stream->write(lcbDop);
+ stream->write(fcSttbfAssoc);
+ stream->write(lcbSttbfAssoc);
+ stream->write(fcClx);
+ stream->write(lcbClx);
+ stream->write(fcPlcfpgdFtn);
+ stream->write(lcbPlcfpgdFtn);
+ stream->write(fcAutosaveSource);
+ stream->write(lcbAutosaveSource);
+ stream->write(fcGrpStAtnOwners);
+ stream->write(lcbGrpStAtnOwners);
+ stream->write(fcSttbfAtnbkmk);
+ stream->write(lcbSttbfAtnbkmk);
+ stream->write(wSpare4Fib);
+ stream->write(pnChpFirst);
+ stream->write(pnPapFirst);
+ stream->write(cpnBteChp);
+ stream->write(cpnBtePap);
+ stream->write(fcPlcfdoaMom);
+ stream->write(lcbPlcfdoaMom);
+ stream->write(fcPlcfdoaHdr);
+ stream->write(lcbPlcfdoaHdr);
+ stream->write(fcUnused1);
+ stream->write(lcbUnused1);
+ stream->write(fcUnused2);
+ stream->write(lcbUnused2);
+ stream->write(fcPlcfAtnbkf);
+ stream->write(lcbPlcfAtnbkf);
+ stream->write(fcPlcfAtnbkl);
+ stream->write(lcbPlcfAtnbkl);
+ stream->write(fcPms);
+ stream->write(lcbPms);
+ stream->write(fcFormFldSttbf);
+ stream->write(lcbFormFldSttbf);
+ stream->write(fcPlcfendRef);
+ stream->write(lcbPlcfendRef);
+ stream->write(fcPlcfendTxt);
+ stream->write(lcbPlcfendTxt);
+ stream->write(fcPlcffldEdn);
+ stream->write(lcbPlcffldEdn);
+ stream->write(fcPlcfpgdEdn);
+ stream->write(lcbPlcfpgdEdn);
+ stream->write(fcUnused3);
+ stream->write(lcbUnused3);
+ stream->write(fcSttbfRMark);
+ stream->write(lcbSttbfRMark);
+ stream->write(fcSttbfCaption);
+ stream->write(lcbSttbfCaption);
+ stream->write(fcSttbfAutoCaption);
+ stream->write(lcbSttbfAutoCaption);
+ stream->write(fcPlcfwkb);
+ stream->write(lcbPlcfwkb);
+ stream->write(fcUnused4);
+ stream->write(lcbUnused4);
+ stream->write(fcPlcftxbxTxt);
+ stream->write(lcbPlcftxbxTxt);
+ stream->write(fcPlcffldTxbx);
+ stream->write(lcbPlcffldTxbx);
+ stream->write(fcPlcfHdrtxbxTxt);
+ stream->write(lcbPlcfHdrtxbxTxt);
+ stream->write(fcPlcffldHdrTxbx);
+ stream->write(lcbPlcffldHdrTxbx);
+ stream->write(fcStwUser);
+ stream->write(lcbStwUser);
+ stream->write(fcSttbttmbd);
+ stream->write(lcbSttbttmbd);
+ stream->write(fcUnused);
+ stream->write(lcbUnused);
+ stream->write(fcPgdMother);
+ stream->write(lcbPgdMother);
+ stream->write(fcBkdMother);
+ stream->write(lcbBkdMother);
+ stream->write(fcPgdFtn);
+ stream->write(lcbPgdFtn);
+ stream->write(fcBkdFtn);
+ stream->write(lcbBkdFtn);
+ stream->write(fcPgdEdn);
+ stream->write(lcbPgdEdn);
+ stream->write(fcBkdEdn);
+ stream->write(lcbBkdEdn);
+ stream->write(fcSttbfIntlFld);
+ stream->write(lcbSttbfIntlFld);
+ stream->write(fcRouteSlip);
+ stream->write(lcbRouteSlip);
+ stream->write(fcSttbSavedBy);
+ stream->write(lcbSttbSavedBy);
+ stream->write(fcSttbFnm);
+ stream->write(lcbSttbFnm);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void FIB::clear() {
+ wIdent=0;
+ nFib=0;
+ nProduct=0;
+ lid=0;
+ pnNext=0;
+ fDot=0;
+ fGlsy=0;
+ fComplex=0;
+ fHasPic=0;
+ cQuickSaves=0;
+ fEncrypted=0;
+ unused10_9=0;
+ fReadOnlyRecommended=0;
+ fWriteReservation=0;
+ fExtChar=0;
+ unused10_13=0;
+ nFibBack=0;
+ lKey=0;
+ envr=0;
+ unused19=0;
+ chse=0;
+ chseTables=0;
+ fcMin=0;
+ fcMac=0;
+ cbMac=0;
+ fcSpare0=0;
+ fcSpare1=0;
+ fcSpare2=0;
+ fcSpare3=0;
+ ccpText=0;
+ ccpFtn=0;
+ ccpHdd=0;
+ ccpMcr=0;
+ ccpAtn=0;
+ ccpEdn=0;
+ ccpTxbx=0;
+ ccpHdrTxbx=0;
+ ccpSpare2=0;
+ fcStshfOrig=0;
+ lcbStshfOrig=0;
+ fcStshf=0;
+ lcbStshf=0;
+ fcPlcffndRef=0;
+ lcbPlcffndRef=0;
+ fcPlcffndTxt=0;
+ lcbPlcffndTxt=0;
+ fcPlcfandRef=0;
+ lcbPlcfandRef=0;
+ fcPlcfandTxt=0;
+ lcbPlcfandTxt=0;
+ fcPlcfsed=0;
+ lcbPlcfsed=0;
+ fcPlcfpad=0;
+ lcbPlcfpad=0;
+ fcPlcfphe=0;
+ lcbPlcfphe=0;
+ fcSttbfglsy=0;
+ lcbSttbfglsy=0;
+ fcPlcfglsy=0;
+ lcbPlcfglsy=0;
+ fcPlcfhdd=0;
+ lcbPlcfhdd=0;
+ fcPlcfbteChpx=0;
+ lcbPlcfbteChpx=0;
+ fcPlcfbtePapx=0;
+ lcbPlcfbtePapx=0;
+ fcPlcfsea=0;
+ lcbPlcfsea=0;
+ fcSttbfffn=0;
+ lcbSttbfffn=0;
+ fcPlcffldMom=0;
+ lcbPlcffldMom=0;
+ fcPlcffldHdr=0;
+ lcbPlcffldHdr=0;
+ fcPlcffldFtn=0;
+ lcbPlcffldFtn=0;
+ fcPlcffldAtn=0;
+ lcbPlcffldAtn=0;
+ fcPlcffldMcr=0;
+ lcbPlcffldMcr=0;
+ fcSttbfbkmk=0;
+ lcbSttbfbkmk=0;
+ fcPlcfbkf=0;
+ lcbPlcfbkf=0;
+ fcPlcfbkl=0;
+ lcbPlcfbkl=0;
+ fcCmds=0;
+ lcbCmds=0;
+ fcPlcmcr=0;
+ lcbPlcmcr=0;
+ fcSttbfmcr=0;
+ lcbSttbfmcr=0;
+ fcPrDrvr=0;
+ lcbPrDrvr=0;
+ fcPrEnvPort=0;
+ lcbPrEnvPort=0;
+ fcPrEnvLand=0;
+ lcbPrEnvLand=0;
+ fcWss=0;
+ lcbWss=0;
+ fcDop=0;
+ lcbDop=0;
+ fcSttbfAssoc=0;
+ lcbSttbfAssoc=0;
+ fcClx=0;
+ lcbClx=0;
+ fcPlcfpgdFtn=0;
+ lcbPlcfpgdFtn=0;
+ fcAutosaveSource=0;
+ lcbAutosaveSource=0;
+ fcGrpStAtnOwners=0;
+ lcbGrpStAtnOwners=0;
+ fcSttbfAtnbkmk=0;
+ lcbSttbfAtnbkmk=0;
+ wSpare4Fib=0;
+ pnChpFirst=0;
+ pnPapFirst=0;
+ cpnBteChp=0;
+ cpnBtePap=0;
+ fcPlcfdoaMom=0;
+ lcbPlcfdoaMom=0;
+ fcPlcfdoaHdr=0;
+ lcbPlcfdoaHdr=0;
+ fcUnused1=0;
+ lcbUnused1=0;
+ fcUnused2=0;
+ lcbUnused2=0;
+ fcPlcfAtnbkf=0;
+ lcbPlcfAtnbkf=0;
+ fcPlcfAtnbkl=0;
+ lcbPlcfAtnbkl=0;
+ fcPms=0;
+ lcbPms=0;
+ fcFormFldSttbf=0;
+ lcbFormFldSttbf=0;
+ fcPlcfendRef=0;
+ lcbPlcfendRef=0;
+ fcPlcfendTxt=0;
+ lcbPlcfendTxt=0;
+ fcPlcffldEdn=0;
+ lcbPlcffldEdn=0;
+ fcPlcfpgdEdn=0;
+ lcbPlcfpgdEdn=0;
+ fcUnused3=0;
+ lcbUnused3=0;
+ fcSttbfRMark=0;
+ lcbSttbfRMark=0;
+ fcSttbfCaption=0;
+ lcbSttbfCaption=0;
+ fcSttbfAutoCaption=0;
+ lcbSttbfAutoCaption=0;
+ fcPlcfwkb=0;
+ lcbPlcfwkb=0;
+ fcUnused4=0;
+ lcbUnused4=0;
+ fcPlcftxbxTxt=0;
+ lcbPlcftxbxTxt=0;
+ fcPlcffldTxbx=0;
+ lcbPlcffldTxbx=0;
+ fcPlcfHdrtxbxTxt=0;
+ lcbPlcfHdrtxbxTxt=0;
+ fcPlcffldHdrTxbx=0;
+ lcbPlcffldHdrTxbx=0;
+ fcStwUser=0;
+ lcbStwUser=0;
+ fcSttbttmbd=0;
+ lcbSttbttmbd=0;
+ fcUnused=0;
+ lcbUnused=0;
+ fcPgdMother=0;
+ lcbPgdMother=0;
+ fcBkdMother=0;
+ lcbBkdMother=0;
+ fcPgdFtn=0;
+ lcbPgdFtn=0;
+ fcBkdFtn=0;
+ lcbBkdFtn=0;
+ fcPgdEdn=0;
+ lcbPgdEdn=0;
+ fcBkdEdn=0;
+ lcbBkdEdn=0;
+ fcSttbfIntlFld=0;
+ lcbSttbfIntlFld=0;
+ fcRouteSlip=0;
+ lcbRouteSlip=0;
+ fcSttbSavedBy=0;
+ lcbSttbSavedBy=0;
+ fcSttbFnm=0;
+ lcbSttbFnm=0;
+}
+
+bool operator==(const FIB &lhs, const FIB &rhs) {
+
+ return lhs.wIdent==rhs.wIdent &&
+ lhs.nFib==rhs.nFib &&
+ lhs.nProduct==rhs.nProduct &&
+ lhs.lid==rhs.lid &&
+ lhs.pnNext==rhs.pnNext &&
+ lhs.fDot==rhs.fDot &&
+ lhs.fGlsy==rhs.fGlsy &&
+ lhs.fComplex==rhs.fComplex &&
+ lhs.fHasPic==rhs.fHasPic &&
+ lhs.cQuickSaves==rhs.cQuickSaves &&
+ lhs.fEncrypted==rhs.fEncrypted &&
+ lhs.unused10_9==rhs.unused10_9 &&
+ lhs.fReadOnlyRecommended==rhs.fReadOnlyRecommended &&
+ lhs.fWriteReservation==rhs.fWriteReservation &&
+ lhs.fExtChar==rhs.fExtChar &&
+ lhs.unused10_13==rhs.unused10_13 &&
+ lhs.nFibBack==rhs.nFibBack &&
+ lhs.lKey==rhs.lKey &&
+ lhs.envr==rhs.envr &&
+ lhs.unused19==rhs.unused19 &&
+ lhs.chse==rhs.chse &&
+ lhs.chseTables==rhs.chseTables &&
+ lhs.fcMin==rhs.fcMin &&
+ lhs.fcMac==rhs.fcMac &&
+ lhs.cbMac==rhs.cbMac &&
+ lhs.fcSpare0==rhs.fcSpare0 &&
+ lhs.fcSpare1==rhs.fcSpare1 &&
+ lhs.fcSpare2==rhs.fcSpare2 &&
+ lhs.fcSpare3==rhs.fcSpare3 &&
+ lhs.ccpText==rhs.ccpText &&
+ lhs.ccpFtn==rhs.ccpFtn &&
+ lhs.ccpHdd==rhs.ccpHdd &&
+ lhs.ccpMcr==rhs.ccpMcr &&
+ lhs.ccpAtn==rhs.ccpAtn &&
+ lhs.ccpEdn==rhs.ccpEdn &&
+ lhs.ccpTxbx==rhs.ccpTxbx &&
+ lhs.ccpHdrTxbx==rhs.ccpHdrTxbx &&
+ lhs.ccpSpare2==rhs.ccpSpare2 &&
+ lhs.fcStshfOrig==rhs.fcStshfOrig &&
+ lhs.lcbStshfOrig==rhs.lcbStshfOrig &&
+ lhs.fcStshf==rhs.fcStshf &&
+ lhs.lcbStshf==rhs.lcbStshf &&
+ lhs.fcPlcffndRef==rhs.fcPlcffndRef &&
+ lhs.lcbPlcffndRef==rhs.lcbPlcffndRef &&
+ lhs.fcPlcffndTxt==rhs.fcPlcffndTxt &&
+ lhs.lcbPlcffndTxt==rhs.lcbPlcffndTxt &&
+ lhs.fcPlcfandRef==rhs.fcPlcfandRef &&
+ lhs.lcbPlcfandRef==rhs.lcbPlcfandRef &&
+ lhs.fcPlcfandTxt==rhs.fcPlcfandTxt &&
+ lhs.lcbPlcfandTxt==rhs.lcbPlcfandTxt &&
+ lhs.fcPlcfsed==rhs.fcPlcfsed &&
+ lhs.lcbPlcfsed==rhs.lcbPlcfsed &&
+ lhs.fcPlcfpad==rhs.fcPlcfpad &&
+ lhs.lcbPlcfpad==rhs.lcbPlcfpad &&
+ lhs.fcPlcfphe==rhs.fcPlcfphe &&
+ lhs.lcbPlcfphe==rhs.lcbPlcfphe &&
+ lhs.fcSttbfglsy==rhs.fcSttbfglsy &&
+ lhs.lcbSttbfglsy==rhs.lcbSttbfglsy &&
+ lhs.fcPlcfglsy==rhs.fcPlcfglsy &&
+ lhs.lcbPlcfglsy==rhs.lcbPlcfglsy &&
+ lhs.fcPlcfhdd==rhs.fcPlcfhdd &&
+ lhs.lcbPlcfhdd==rhs.lcbPlcfhdd &&
+ lhs.fcPlcfbteChpx==rhs.fcPlcfbteChpx &&
+ lhs.lcbPlcfbteChpx==rhs.lcbPlcfbteChpx &&
+ lhs.fcPlcfbtePapx==rhs.fcPlcfbtePapx &&
+ lhs.lcbPlcfbtePapx==rhs.lcbPlcfbtePapx &&
+ lhs.fcPlcfsea==rhs.fcPlcfsea &&
+ lhs.lcbPlcfsea==rhs.lcbPlcfsea &&
+ lhs.fcSttbfffn==rhs.fcSttbfffn &&
+ lhs.lcbSttbfffn==rhs.lcbSttbfffn &&
+ lhs.fcPlcffldMom==rhs.fcPlcffldMom &&
+ lhs.lcbPlcffldMom==rhs.lcbPlcffldMom &&
+ lhs.fcPlcffldHdr==rhs.fcPlcffldHdr &&
+ lhs.lcbPlcffldHdr==rhs.lcbPlcffldHdr &&
+ lhs.fcPlcffldFtn==rhs.fcPlcffldFtn &&
+ lhs.lcbPlcffldFtn==rhs.lcbPlcffldFtn &&
+ lhs.fcPlcffldAtn==rhs.fcPlcffldAtn &&
+ lhs.lcbPlcffldAtn==rhs.lcbPlcffldAtn &&
+ lhs.fcPlcffldMcr==rhs.fcPlcffldMcr &&
+ lhs.lcbPlcffldMcr==rhs.lcbPlcffldMcr &&
+ lhs.fcSttbfbkmk==rhs.fcSttbfbkmk &&
+ lhs.lcbSttbfbkmk==rhs.lcbSttbfbkmk &&
+ lhs.fcPlcfbkf==rhs.fcPlcfbkf &&
+ lhs.lcbPlcfbkf==rhs.lcbPlcfbkf &&
+ lhs.fcPlcfbkl==rhs.fcPlcfbkl &&
+ lhs.lcbPlcfbkl==rhs.lcbPlcfbkl &&
+ lhs.fcCmds==rhs.fcCmds &&
+ lhs.lcbCmds==rhs.lcbCmds &&
+ lhs.fcPlcmcr==rhs.fcPlcmcr &&
+ lhs.lcbPlcmcr==rhs.lcbPlcmcr &&
+ lhs.fcSttbfmcr==rhs.fcSttbfmcr &&
+ lhs.lcbSttbfmcr==rhs.lcbSttbfmcr &&
+ lhs.fcPrDrvr==rhs.fcPrDrvr &&
+ lhs.lcbPrDrvr==rhs.lcbPrDrvr &&
+ lhs.fcPrEnvPort==rhs.fcPrEnvPort &&
+ lhs.lcbPrEnvPort==rhs.lcbPrEnvPort &&
+ lhs.fcPrEnvLand==rhs.fcPrEnvLand &&
+ lhs.lcbPrEnvLand==rhs.lcbPrEnvLand &&
+ lhs.fcWss==rhs.fcWss &&
+ lhs.lcbWss==rhs.lcbWss &&
+ lhs.fcDop==rhs.fcDop &&
+ lhs.lcbDop==rhs.lcbDop &&
+ lhs.fcSttbfAssoc==rhs.fcSttbfAssoc &&
+ lhs.lcbSttbfAssoc==rhs.lcbSttbfAssoc &&
+ lhs.fcClx==rhs.fcClx &&
+ lhs.lcbClx==rhs.lcbClx &&
+ lhs.fcPlcfpgdFtn==rhs.fcPlcfpgdFtn &&
+ lhs.lcbPlcfpgdFtn==rhs.lcbPlcfpgdFtn &&
+ lhs.fcAutosaveSource==rhs.fcAutosaveSource &&
+ lhs.lcbAutosaveSource==rhs.lcbAutosaveSource &&
+ lhs.fcGrpStAtnOwners==rhs.fcGrpStAtnOwners &&
+ lhs.lcbGrpStAtnOwners==rhs.lcbGrpStAtnOwners &&
+ lhs.fcSttbfAtnbkmk==rhs.fcSttbfAtnbkmk &&
+ lhs.lcbSttbfAtnbkmk==rhs.lcbSttbfAtnbkmk &&
+ lhs.wSpare4Fib==rhs.wSpare4Fib &&
+ lhs.pnChpFirst==rhs.pnChpFirst &&
+ lhs.pnPapFirst==rhs.pnPapFirst &&
+ lhs.cpnBteChp==rhs.cpnBteChp &&
+ lhs.cpnBtePap==rhs.cpnBtePap &&
+ lhs.fcPlcfdoaMom==rhs.fcPlcfdoaMom &&
+ lhs.lcbPlcfdoaMom==rhs.lcbPlcfdoaMom &&
+ lhs.fcPlcfdoaHdr==rhs.fcPlcfdoaHdr &&
+ lhs.lcbPlcfdoaHdr==rhs.lcbPlcfdoaHdr &&
+ lhs.fcUnused1==rhs.fcUnused1 &&
+ lhs.lcbUnused1==rhs.lcbUnused1 &&
+ lhs.fcUnused2==rhs.fcUnused2 &&
+ lhs.lcbUnused2==rhs.lcbUnused2 &&
+ lhs.fcPlcfAtnbkf==rhs.fcPlcfAtnbkf &&
+ lhs.lcbPlcfAtnbkf==rhs.lcbPlcfAtnbkf &&
+ lhs.fcPlcfAtnbkl==rhs.fcPlcfAtnbkl &&
+ lhs.lcbPlcfAtnbkl==rhs.lcbPlcfAtnbkl &&
+ lhs.fcPms==rhs.fcPms &&
+ lhs.lcbPms==rhs.lcbPms &&
+ lhs.fcFormFldSttbf==rhs.fcFormFldSttbf &&
+ lhs.lcbFormFldSttbf==rhs.lcbFormFldSttbf &&
+ lhs.fcPlcfendRef==rhs.fcPlcfendRef &&
+ lhs.lcbPlcfendRef==rhs.lcbPlcfendRef &&
+ lhs.fcPlcfendTxt==rhs.fcPlcfendTxt &&
+ lhs.lcbPlcfendTxt==rhs.lcbPlcfendTxt &&
+ lhs.fcPlcffldEdn==rhs.fcPlcffldEdn &&
+ lhs.lcbPlcffldEdn==rhs.lcbPlcffldEdn &&
+ lhs.fcPlcfpgdEdn==rhs.fcPlcfpgdEdn &&
+ lhs.lcbPlcfpgdEdn==rhs.lcbPlcfpgdEdn &&
+ lhs.fcUnused3==rhs.fcUnused3 &&
+ lhs.lcbUnused3==rhs.lcbUnused3 &&
+ lhs.fcSttbfRMark==rhs.fcSttbfRMark &&
+ lhs.lcbSttbfRMark==rhs.lcbSttbfRMark &&
+ lhs.fcSttbfCaption==rhs.fcSttbfCaption &&
+ lhs.lcbSttbfCaption==rhs.lcbSttbfCaption &&
+ lhs.fcSttbfAutoCaption==rhs.fcSttbfAutoCaption &&
+ lhs.lcbSttbfAutoCaption==rhs.lcbSttbfAutoCaption &&
+ lhs.fcPlcfwkb==rhs.fcPlcfwkb &&
+ lhs.lcbPlcfwkb==rhs.lcbPlcfwkb &&
+ lhs.fcUnused4==rhs.fcUnused4 &&
+ lhs.lcbUnused4==rhs.lcbUnused4 &&
+ lhs.fcPlcftxbxTxt==rhs.fcPlcftxbxTxt &&
+ lhs.lcbPlcftxbxTxt==rhs.lcbPlcftxbxTxt &&
+ lhs.fcPlcffldTxbx==rhs.fcPlcffldTxbx &&
+ lhs.lcbPlcffldTxbx==rhs.lcbPlcffldTxbx &&
+ lhs.fcPlcfHdrtxbxTxt==rhs.fcPlcfHdrtxbxTxt &&
+ lhs.lcbPlcfHdrtxbxTxt==rhs.lcbPlcfHdrtxbxTxt &&
+ lhs.fcPlcffldHdrTxbx==rhs.fcPlcffldHdrTxbx &&
+ lhs.lcbPlcffldHdrTxbx==rhs.lcbPlcffldHdrTxbx &&
+ lhs.fcStwUser==rhs.fcStwUser &&
+ lhs.lcbStwUser==rhs.lcbStwUser &&
+ lhs.fcSttbttmbd==rhs.fcSttbttmbd &&
+ lhs.lcbSttbttmbd==rhs.lcbSttbttmbd &&
+ lhs.fcUnused==rhs.fcUnused &&
+ lhs.lcbUnused==rhs.lcbUnused &&
+ lhs.fcPgdMother==rhs.fcPgdMother &&
+ lhs.lcbPgdMother==rhs.lcbPgdMother &&
+ lhs.fcBkdMother==rhs.fcBkdMother &&
+ lhs.lcbBkdMother==rhs.lcbBkdMother &&
+ lhs.fcPgdFtn==rhs.fcPgdFtn &&
+ lhs.lcbPgdFtn==rhs.lcbPgdFtn &&
+ lhs.fcBkdFtn==rhs.fcBkdFtn &&
+ lhs.lcbBkdFtn==rhs.lcbBkdFtn &&
+ lhs.fcPgdEdn==rhs.fcPgdEdn &&
+ lhs.lcbPgdEdn==rhs.lcbPgdEdn &&
+ lhs.fcBkdEdn==rhs.fcBkdEdn &&
+ lhs.lcbBkdEdn==rhs.lcbBkdEdn &&
+ lhs.fcSttbfIntlFld==rhs.fcSttbfIntlFld &&
+ lhs.lcbSttbfIntlFld==rhs.lcbSttbfIntlFld &&
+ lhs.fcRouteSlip==rhs.fcRouteSlip &&
+ lhs.lcbRouteSlip==rhs.lcbRouteSlip &&
+ lhs.fcSttbSavedBy==rhs.fcSttbSavedBy &&
+ lhs.lcbSttbSavedBy==rhs.lcbSttbSavedBy &&
+ lhs.fcSttbFnm==rhs.fcSttbFnm &&
+ lhs.lcbSttbFnm==rhs.lcbSttbFnm;
+}
+
+bool operator!=(const FIB &lhs, const FIB &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// LSPD implementation
+
+LSPD::LSPD() {
+ clear();
+}
+
+LSPD::LSPD(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool LSPD::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ dyaLine=stream->readU16();
+ fMultLinespace=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool LSPD::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(dyaLine);
+ stream->write(fMultLinespace);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void LSPD::clear() {
+ dyaLine=0;
+ fMultLinespace=0;
+}
+
+void LSPD::dump() const
+{
+ wvlog << "Dumping LSPD:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping LSPD done." << std::endl;
+}
+
+std::string LSPD::toString() const
+{
+ std::string s( "LSPD:" );
+ s += "\ndyaLine=";
+ s += uint2string( dyaLine );
+ s += "\nfMultLinespace=";
+ s += uint2string( fMultLinespace );
+ s += "\nLSPD Done.";
+ return s;
+}
+
+bool operator==(const LSPD &lhs, const LSPD &rhs) {
+
+ return lhs.dyaLine==rhs.dyaLine &&
+ lhs.fMultLinespace==rhs.fMultLinespace;
+}
+
+bool operator!=(const LSPD &lhs, const LSPD &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// METAFILEPICT implementation
+
+METAFILEPICT::METAFILEPICT() {
+ clear();
+}
+
+METAFILEPICT::METAFILEPICT(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool METAFILEPICT::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ mm=stream->readU16();
+ xExt=stream->readU16();
+ yExt=stream->readU16();
+ hMF=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool METAFILEPICT::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(mm);
+ stream->write(xExt);
+ stream->write(yExt);
+ stream->write(hMF);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void METAFILEPICT::clear() {
+ mm=0;
+ xExt=0;
+ yExt=0;
+ hMF=0;
+}
+
+void METAFILEPICT::dump() const
+{
+ wvlog << "Dumping METAFILEPICT:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping METAFILEPICT done." << std::endl;
+}
+
+std::string METAFILEPICT::toString() const
+{
+ std::string s( "METAFILEPICT:" );
+ s += "\nmm=";
+ s += uint2string( mm );
+ s += "\nxExt=";
+ s += uint2string( xExt );
+ s += "\nyExt=";
+ s += uint2string( yExt );
+ s += "\nhMF=";
+ s += uint2string( hMF );
+ s += "\nMETAFILEPICT Done.";
+ return s;
+}
+
+bool operator==(const METAFILEPICT &lhs, const METAFILEPICT &rhs) {
+
+ return lhs.mm==rhs.mm &&
+ lhs.xExt==rhs.xExt &&
+ lhs.yExt==rhs.yExt &&
+ lhs.hMF==rhs.hMF;
+}
+
+bool operator!=(const METAFILEPICT &lhs, const METAFILEPICT &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// OBJHEADER implementation
+
+OBJHEADER::OBJHEADER() {
+ clear();
+}
+
+OBJHEADER::OBJHEADER(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool OBJHEADER::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ lcb=stream->readU32();
+ cbHeader=stream->readU16();
+ icf=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool OBJHEADER::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(lcb);
+ stream->write(cbHeader);
+ stream->write(icf);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void OBJHEADER::clear() {
+ lcb=0;
+ cbHeader=0;
+ icf=0;
+}
+
+bool operator==(const OBJHEADER &lhs, const OBJHEADER &rhs) {
+
+ return lhs.lcb==rhs.lcb &&
+ lhs.cbHeader==rhs.cbHeader &&
+ lhs.icf==rhs.icf;
+}
+
+bool operator!=(const OBJHEADER &lhs, const OBJHEADER &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// OLST implementation
+
+const unsigned int OLST::sizeOf = 212;
+
+OLST::OLST() {
+ clear();
+}
+
+OLST::OLST(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+OLST::OLST(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool OLST::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ for(int _i=0; _i<(9); ++_i)
+ rganlv[_i].read(stream, false);
+ fRestartHdr=stream->readU8();
+ fSpareOlst2=stream->readU8();
+ fSpareOlst3=stream->readU8();
+ fSpareOlst4=stream->readU8();
+ for(int _i=0; _i<(64); ++_i)
+ rgch[_i]=stream->readU8();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void OLST::readPtr(const U8 *ptr) {
+
+ for(int _i=0; _i<(9); ++_i) {
+ rganlv[_i].readPtr(ptr);
+ ptr+=ANLV::sizeOf;
+ }
+ fRestartHdr=readU8(ptr);
+ ptr+=sizeof(U8);
+ fSpareOlst2=readU8(ptr);
+ ptr+=sizeof(U8);
+ fSpareOlst3=readU8(ptr);
+ ptr+=sizeof(U8);
+ fSpareOlst4=readU8(ptr);
+ ptr+=sizeof(U8);
+ for(int _i=0; _i<(64); ++_i) {
+ rgch[_i]=readU8(ptr);
+ ptr+=sizeof(U8);
+ }
+}
+
+bool OLST::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ for(int _i=0; _i<(9); ++_i)
+ rganlv[_i].write(stream, false);
+ stream->write(fRestartHdr);
+ stream->write(fSpareOlst2);
+ stream->write(fSpareOlst3);
+ stream->write(fSpareOlst4);
+ for(int _i=0; _i<(64); ++_i)
+ stream->write(rgch[_i]);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void OLST::clear() {
+ for(int _i=0; _i<(9); ++_i)
+ rganlv[_i].clear();
+ fRestartHdr=0;
+ fSpareOlst2=0;
+ fSpareOlst3=0;
+ fSpareOlst4=0;
+ for(int _i=0; _i<(64); ++_i)
+ rgch[_i]=0;
+}
+
+void OLST::dump() const
+{
+ wvlog << "Dumping OLST:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping OLST done." << std::endl;
+}
+
+std::string OLST::toString() const
+{
+ std::string s( "OLST:" );
+ for(int _i=0; _i<(9); ++_i) {
+ s += "\nrganlv[" + int2string( _i ) + "]=";
+ s += "\n{" + rganlv[_i].toString() + "}\n";
+ }
+ s += "\nfRestartHdr=";
+ s += uint2string( fRestartHdr );
+ s += "\nfSpareOlst2=";
+ s += uint2string( fSpareOlst2 );
+ s += "\nfSpareOlst3=";
+ s += uint2string( fSpareOlst3 );
+ s += "\nfSpareOlst4=";
+ s += uint2string( fSpareOlst4 );
+ for(int _i=0; _i<(64); ++_i) {
+ s += "\nrgch[" + int2string( _i ) + "]=";
+ s += uint2string( rgch[_i] );
+ }
+ s += "\nOLST Done.";
+ return s;
+}
+
+bool operator==(const OLST &lhs, const OLST &rhs) {
+
+ for(int _i=0; _i<(9); ++_i) {
+ if(lhs.rganlv[_i]!=rhs.rganlv[_i])
+ return false;
+ }
+
+ for(int _i=0; _i<(64); ++_i) {
+ if(lhs.rgch[_i]!=rhs.rgch[_i])
+ return false;
+ }
+
+ return lhs.fRestartHdr==rhs.fRestartHdr &&
+ lhs.fSpareOlst2==rhs.fSpareOlst2 &&
+ lhs.fSpareOlst3==rhs.fSpareOlst3 &&
+ lhs.fSpareOlst4==rhs.fSpareOlst4;
+}
+
+bool operator!=(const OLST &lhs, const OLST &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// PAP implementation
+
+PAP::PAP() : Shared() {
+ clearInternal();
+}
+
+PAP::PAP(OLEStreamReader *stream, bool preservePos) : Shared() {
+ clearInternal();
+ read(stream, preservePos);
+}
+
+PAP::PAP(const PAP &rhs) : Shared() {
+ istd=rhs.istd;
+ jc=rhs.jc;
+ fKeep=rhs.fKeep;
+ fKeepFollow=rhs.fKeepFollow;
+ fPageBreakBefore=rhs.fPageBreakBefore;
+ fBrLnAbove=rhs.fBrLnAbove;
+ fBrLnBelow=rhs.fBrLnBelow;
+ fUnused=rhs.fUnused;
+ pcVert=rhs.pcVert;
+ pcHorz=rhs.pcHorz;
+ brcp=rhs.brcp;
+ brcl=rhs.brcl;
+ unused9=rhs.unused9;
+ nLvlAnm=rhs.nLvlAnm;
+ fNoLnn=rhs.fNoLnn;
+ fSideBySide=rhs.fSideBySide;
+ dxaRight=rhs.dxaRight;
+ dxaLeft=rhs.dxaLeft;
+ dxaLeft1=rhs.dxaLeft1;
+ lspd=rhs.lspd;
+ dyaBefore=rhs.dyaBefore;
+ dyaAfter=rhs.dyaAfter;
+ phe=rhs.phe;
+ fAutoHyph=rhs.fAutoHyph;
+ fWidowControl=rhs.fWidowControl;
+ fInTable=rhs.fInTable;
+ fTtp=rhs.fTtp;
+ ptap=rhs.ptap;
+ dxaAbs=rhs.dxaAbs;
+ dyaAbs=rhs.dyaAbs;
+ dxaWidth=rhs.dxaWidth;
+ brcTop=rhs.brcTop;
+ brcLeft=rhs.brcLeft;
+ brcBottom=rhs.brcBottom;
+ brcRight=rhs.brcRight;
+ brcBetween=rhs.brcBetween;
+ brcBar=rhs.brcBar;
+ dxaFromText=rhs.dxaFromText;
+ dyaFromText=rhs.dyaFromText;
+ wr=rhs.wr;
+ fLocked=rhs.fLocked;
+ dyaHeight=rhs.dyaHeight;
+ fMinHeight=rhs.fMinHeight;
+ shd=rhs.shd;
+ dcs=rhs.dcs;
+ anld=rhs.anld;
+ itbdMac=rhs.itbdMac;
+ rgdxaTab=new U16[itbdMac];
+ memcpy(rgdxaTab, rhs.rgdxaTab, sizeof(U16)*(itbdMac));
+ rgtbd=new U8[itbdMac];
+ memcpy(rgtbd, rhs.rgtbd, sizeof(U8)*(itbdMac));
+}
+
+PAP::~PAP() {
+ delete [] rgdxaTab;
+ delete [] rgtbd;
+}
+
+PAP &PAP::operator=(const PAP &rhs) {
+
+ // Check for assignment to self
+ if(this==&rhs)
+ return *this;
+
+ istd=rhs.istd;
+ jc=rhs.jc;
+ fKeep=rhs.fKeep;
+ fKeepFollow=rhs.fKeepFollow;
+ fPageBreakBefore=rhs.fPageBreakBefore;
+ fBrLnAbove=rhs.fBrLnAbove;
+ fBrLnBelow=rhs.fBrLnBelow;
+ fUnused=rhs.fUnused;
+ pcVert=rhs.pcVert;
+ pcHorz=rhs.pcHorz;
+ brcp=rhs.brcp;
+ brcl=rhs.brcl;
+ unused9=rhs.unused9;
+ nLvlAnm=rhs.nLvlAnm;
+ fNoLnn=rhs.fNoLnn;
+ fSideBySide=rhs.fSideBySide;
+ dxaRight=rhs.dxaRight;
+ dxaLeft=rhs.dxaLeft;
+ dxaLeft1=rhs.dxaLeft1;
+ lspd=rhs.lspd;
+ dyaBefore=rhs.dyaBefore;
+ dyaAfter=rhs.dyaAfter;
+ phe=rhs.phe;
+ fAutoHyph=rhs.fAutoHyph;
+ fWidowControl=rhs.fWidowControl;
+ fInTable=rhs.fInTable;
+ fTtp=rhs.fTtp;
+ ptap=rhs.ptap;
+ dxaAbs=rhs.dxaAbs;
+ dyaAbs=rhs.dyaAbs;
+ dxaWidth=rhs.dxaWidth;
+ brcTop=rhs.brcTop;
+ brcLeft=rhs.brcLeft;
+ brcBottom=rhs.brcBottom;
+ brcRight=rhs.brcRight;
+ brcBetween=rhs.brcBetween;
+ brcBar=rhs.brcBar;
+ dxaFromText=rhs.dxaFromText;
+ dyaFromText=rhs.dyaFromText;
+ wr=rhs.wr;
+ fLocked=rhs.fLocked;
+ dyaHeight=rhs.dyaHeight;
+ fMinHeight=rhs.fMinHeight;
+ shd=rhs.shd;
+ dcs=rhs.dcs;
+ anld=rhs.anld;
+ itbdMac=rhs.itbdMac;
+ delete [] rgdxaTab;
+ rgdxaTab=new U16[itbdMac];
+ memcpy(rgdxaTab, rhs.rgdxaTab, sizeof(U16)*(itbdMac));
+ delete [] rgtbd;
+ rgtbd=new U8[itbdMac];
+ memcpy(rgtbd, rhs.rgtbd, sizeof(U8)*(itbdMac));
+
+ return *this;
+}
+
+bool PAP::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ istd=stream->readU16();
+ jc=stream->readU8();
+ fKeep=stream->readU8();
+ fKeepFollow=stream->readU8();
+ fPageBreakBefore=stream->readU8();
+ shifterU8=stream->readU8();
+ fBrLnAbove=shifterU8;
+ shifterU8>>=1;
+ fBrLnBelow=shifterU8;
+ shifterU8>>=1;
+ fUnused=shifterU8;
+ shifterU8>>=2;
+ pcVert=shifterU8;
+ shifterU8>>=2;
+ pcHorz=shifterU8;
+ brcp=stream->readU8();
+ brcl=stream->readU8();
+ unused9=stream->readU8();
+ nLvlAnm=stream->readU8();
+ fNoLnn=stream->readU8();
+ fSideBySide=stream->readU8();
+ dxaRight=stream->readS16();
+ dxaLeft=stream->readS16();
+ dxaLeft1=stream->readS16();
+ lspd.read(stream, false);
+ dyaBefore=stream->readU16();
+ dyaAfter=stream->readU16();
+ phe.read(stream, false);
+ fAutoHyph=stream->readU8();
+ fWidowControl=stream->readU8();
+ fInTable=stream->readU8();
+ fTtp=stream->readU8();
+ ptap=stream->readU16();
+ dxaAbs=stream->readS16();
+ dyaAbs=stream->readS16();
+ dxaWidth=stream->readU16();
+ brcTop.read(stream, false);
+ brcLeft.read(stream, false);
+ brcBottom.read(stream, false);
+ brcRight.read(stream, false);
+ brcBetween.read(stream, false);
+ brcBar.read(stream, false);
+ dxaFromText=stream->readU16();
+ dyaFromText=stream->readU16();
+ wr=stream->readU8();
+ fLocked=stream->readU8();
+ shifterU16=stream->readU16();
+ dyaHeight=shifterU16;
+ shifterU16>>=15;
+ fMinHeight=shifterU16;
+ shd.read(stream, false);
+ dcs.read(stream, false);
+ anld.read(stream, false);
+ itbdMac=stream->readU16();
+ rgdxaTab=new U16[itbdMac];
+ for(int _i=0; _i<(itbdMac); ++_i)
+ rgdxaTab[_i]=stream->readU16();
+ rgtbd=new U8[itbdMac];
+ for(int _i=0; _i<(itbdMac); ++_i)
+ rgtbd[_i]=stream->readU8();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool PAP::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(istd);
+ stream->write(jc);
+ stream->write(fKeep);
+ stream->write(fKeepFollow);
+ stream->write(fPageBreakBefore);
+ shifterU8=fBrLnAbove;
+ shifterU8|=fBrLnBelow << 1;
+ shifterU8|=fUnused << 2;
+ shifterU8|=pcVert << 4;
+ shifterU8|=pcHorz << 6;
+ stream->write(shifterU8);
+ stream->write(brcp);
+ stream->write(brcl);
+ stream->write(unused9);
+ stream->write(nLvlAnm);
+ stream->write(fNoLnn);
+ stream->write(fSideBySide);
+ stream->write(dxaRight);
+ stream->write(dxaLeft);
+ stream->write(dxaLeft1);
+ lspd.write(stream, false);
+ stream->write(dyaBefore);
+ stream->write(dyaAfter);
+ phe.write(stream, false);
+ stream->write(fAutoHyph);
+ stream->write(fWidowControl);
+ stream->write(fInTable);
+ stream->write(fTtp);
+ stream->write(ptap);
+ stream->write(dxaAbs);
+ stream->write(dyaAbs);
+ stream->write(dxaWidth);
+ brcTop.write(stream, false);
+ brcLeft.write(stream, false);
+ brcBottom.write(stream, false);
+ brcRight.write(stream, false);
+ brcBetween.write(stream, false);
+ brcBar.write(stream, false);
+ stream->write(dxaFromText);
+ stream->write(dyaFromText);
+ stream->write(wr);
+ stream->write(fLocked);
+ shifterU16=dyaHeight;
+ shifterU16|=fMinHeight << 15;
+ stream->write(shifterU16);
+ shd.write(stream, false);
+ dcs.write(stream, false);
+ anld.write(stream, false);
+ stream->write(itbdMac);
+ for(int _i=0; _i<(itbdMac); ++_i)
+ stream->write(rgdxaTab[_i]);
+ for(int _i=0; _i<(itbdMac); ++_i)
+ stream->write(rgtbd[_i]);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PAP::clear() {
+ delete [] rgdxaTab;
+ delete [] rgtbd;
+ clearInternal();
+}
+
+void PAP::dump() const
+{
+ wvlog << "Dumping PAP:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping PAP done." << std::endl;
+}
+
+std::string PAP::toString() const
+{
+ std::string s( "PAP:" );
+ s += "\nistd=";
+ s += uint2string( istd );
+ s += "\njc=";
+ s += uint2string( jc );
+ s += "\nfKeep=";
+ s += uint2string( fKeep );
+ s += "\nfKeepFollow=";
+ s += uint2string( fKeepFollow );
+ s += "\nfPageBreakBefore=";
+ s += uint2string( fPageBreakBefore );
+ s += "\nfBrLnAbove=";
+ s += uint2string( fBrLnAbove );
+ s += "\nfBrLnBelow=";
+ s += uint2string( fBrLnBelow );
+ s += "\nfUnused=";
+ s += uint2string( fUnused );
+ s += "\npcVert=";
+ s += uint2string( pcVert );
+ s += "\npcHorz=";
+ s += uint2string( pcHorz );
+ s += "\nbrcp=";
+ s += uint2string( brcp );
+ s += "\nbrcl=";
+ s += uint2string( brcl );
+ s += "\nunused9=";
+ s += uint2string( unused9 );
+ s += "\nnLvlAnm=";
+ s += uint2string( nLvlAnm );
+ s += "\nfNoLnn=";
+ s += uint2string( fNoLnn );
+ s += "\nfSideBySide=";
+ s += uint2string( fSideBySide );
+ s += "\ndxaRight=";
+ s += int2string( dxaRight );
+ s += "\ndxaLeft=";
+ s += int2string( dxaLeft );
+ s += "\ndxaLeft1=";
+ s += int2string( dxaLeft1 );
+ s += "\nlspd=";
+ s += "\n{" + lspd.toString() + "}\n";
+ s += "\ndyaBefore=";
+ s += uint2string( dyaBefore );
+ s += "\ndyaAfter=";
+ s += uint2string( dyaAfter );
+ s += "\nphe=";
+ s += "\n{" + phe.toString() + "}\n";
+ s += "\nfAutoHyph=";
+ s += uint2string( fAutoHyph );
+ s += "\nfWidowControl=";
+ s += uint2string( fWidowControl );
+ s += "\nfInTable=";
+ s += uint2string( fInTable );
+ s += "\nfTtp=";
+ s += uint2string( fTtp );
+ s += "\nptap=";
+ s += uint2string( ptap );
+ s += "\ndxaAbs=";
+ s += int2string( dxaAbs );
+ s += "\ndyaAbs=";
+ s += int2string( dyaAbs );
+ s += "\ndxaWidth=";
+ s += uint2string( dxaWidth );
+ s += "\nbrcTop=";
+ s += "\n{" + brcTop.toString() + "}\n";
+ s += "\nbrcLeft=";
+ s += "\n{" + brcLeft.toString() + "}\n";
+ s += "\nbrcBottom=";
+ s += "\n{" + brcBottom.toString() + "}\n";
+ s += "\nbrcRight=";
+ s += "\n{" + brcRight.toString() + "}\n";
+ s += "\nbrcBetween=";
+ s += "\n{" + brcBetween.toString() + "}\n";
+ s += "\nbrcBar=";
+ s += "\n{" + brcBar.toString() + "}\n";
+ s += "\ndxaFromText=";
+ s += uint2string( dxaFromText );
+ s += "\ndyaFromText=";
+ s += uint2string( dyaFromText );
+ s += "\nwr=";
+ s += uint2string( wr );
+ s += "\nfLocked=";
+ s += uint2string( fLocked );
+ s += "\ndyaHeight=";
+ s += uint2string( dyaHeight );
+ s += "\nfMinHeight=";
+ s += uint2string( fMinHeight );
+ s += "\nshd=";
+ s += "\n{" + shd.toString() + "}\n";
+ s += "\ndcs=";
+ s += "\n{" + dcs.toString() + "}\n";
+ s += "\nanld=";
+ s += "\n{" + anld.toString() + "}\n";
+ s += "\nitbdMac=";
+ s += uint2string( itbdMac );
+ for(int _i=0; _i<(itbdMac); ++_i) {
+ s += "\nrgdxaTab[" + int2string( _i ) + "]=";
+ s += uint2string( rgdxaTab[_i] );
+ }
+ for(int _i=0; _i<(itbdMac); ++_i) {
+ s += "\nrgtbd[" + int2string( _i ) + "]=";
+ s += uint2string( rgtbd[_i] );
+ }
+ s += "\nPAP Done.";
+ return s;
+}
+
+void PAP::clearInternal() {
+ istd=0;
+ jc=0;
+ fKeep=0;
+ fKeepFollow=0;
+ fPageBreakBefore=0;
+ fBrLnAbove=0;
+ fBrLnBelow=0;
+ fUnused=0;
+ pcVert=0;
+ pcHorz=0;
+ brcp=0;
+ brcl=0;
+ unused9=0;
+ nLvlAnm=0;
+ fNoLnn=0;
+ fSideBySide=0;
+ dxaRight=0;
+ dxaLeft=0;
+ dxaLeft1=0;
+ lspd.clear();
+ dyaBefore=0;
+ dyaAfter=0;
+ phe.clear();
+ fAutoHyph=0;
+ fWidowControl=0;
+ fInTable=0;
+ fTtp=0;
+ ptap=0;
+ dxaAbs=0;
+ dyaAbs=0;
+ dxaWidth=0;
+ brcTop.clear();
+ brcLeft.clear();
+ brcBottom.clear();
+ brcRight.clear();
+ brcBetween.clear();
+ brcBar.clear();
+ dxaFromText=0;
+ dyaFromText=0;
+ wr=0;
+ fLocked=0;
+ dyaHeight=0;
+ fMinHeight=0;
+ shd.clear();
+ dcs.clear();
+ anld.clear();
+ itbdMac=0;
+ rgdxaTab=0;
+ rgtbd=0;
+}
+
+bool operator==(const PAP &lhs, const PAP &rhs) {
+
+ if((lhs.itbdMac)!=(rhs.itbdMac))
+ return false;
+ for(int _i=0; _i<(lhs.itbdMac); ++_i) {
+ if(lhs.rgdxaTab[_i]!=rhs.rgdxaTab[_i])
+ return false;
+ }
+
+ if((lhs.itbdMac)!=(rhs.itbdMac))
+ return false;
+ for(int _i=0; _i<(lhs.itbdMac); ++_i) {
+ if(lhs.rgtbd[_i]!=rhs.rgtbd[_i])
+ return false;
+ }
+
+ return lhs.istd==rhs.istd &&
+ lhs.jc==rhs.jc &&
+ lhs.fKeep==rhs.fKeep &&
+ lhs.fKeepFollow==rhs.fKeepFollow &&
+ lhs.fPageBreakBefore==rhs.fPageBreakBefore &&
+ lhs.fBrLnAbove==rhs.fBrLnAbove &&
+ lhs.fBrLnBelow==rhs.fBrLnBelow &&
+ lhs.fUnused==rhs.fUnused &&
+ lhs.pcVert==rhs.pcVert &&
+ lhs.pcHorz==rhs.pcHorz &&
+ lhs.brcp==rhs.brcp &&
+ lhs.brcl==rhs.brcl &&
+ lhs.unused9==rhs.unused9 &&
+ lhs.nLvlAnm==rhs.nLvlAnm &&
+ lhs.fNoLnn==rhs.fNoLnn &&
+ lhs.fSideBySide==rhs.fSideBySide &&
+ lhs.dxaRight==rhs.dxaRight &&
+ lhs.dxaLeft==rhs.dxaLeft &&
+ lhs.dxaLeft1==rhs.dxaLeft1 &&
+ lhs.lspd==rhs.lspd &&
+ lhs.dyaBefore==rhs.dyaBefore &&
+ lhs.dyaAfter==rhs.dyaAfter &&
+ lhs.phe==rhs.phe &&
+ lhs.fAutoHyph==rhs.fAutoHyph &&
+ lhs.fWidowControl==rhs.fWidowControl &&
+ lhs.fInTable==rhs.fInTable &&
+ lhs.fTtp==rhs.fTtp &&
+ lhs.ptap==rhs.ptap &&
+ lhs.dxaAbs==rhs.dxaAbs &&
+ lhs.dyaAbs==rhs.dyaAbs &&
+ lhs.dxaWidth==rhs.dxaWidth &&
+ lhs.brcTop==rhs.brcTop &&
+ lhs.brcLeft==rhs.brcLeft &&
+ lhs.brcBottom==rhs.brcBottom &&
+ lhs.brcRight==rhs.brcRight &&
+ lhs.brcBetween==rhs.brcBetween &&
+ lhs.brcBar==rhs.brcBar &&
+ lhs.dxaFromText==rhs.dxaFromText &&
+ lhs.dyaFromText==rhs.dyaFromText &&
+ lhs.wr==rhs.wr &&
+ lhs.fLocked==rhs.fLocked &&
+ lhs.dyaHeight==rhs.dyaHeight &&
+ lhs.fMinHeight==rhs.fMinHeight &&
+ lhs.shd==rhs.shd &&
+ lhs.dcs==rhs.dcs &&
+ lhs.anld==rhs.anld &&
+ lhs.itbdMac==rhs.itbdMac;
+}
+
+bool operator!=(const PAP &lhs, const PAP &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// PCD implementation
+
+const unsigned int PCD::sizeOf = 8;
+
+PCD::PCD() {
+ clear();
+}
+
+PCD::PCD(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+PCD::PCD(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool PCD::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ fNoParaLast=shifterU16;
+ shifterU16>>=1;
+ fPaphNil=shifterU16;
+ shifterU16>>=1;
+ fCopied=shifterU16;
+ shifterU16>>=1;
+ unused0_3=shifterU16;
+ shifterU16>>=5;
+ fn=shifterU16;
+ fc=stream->readU32();
+ prm.read(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PCD::readPtr(const U8 *ptr) {
+
+ U16 shifterU16;
+
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ fNoParaLast=shifterU16;
+ shifterU16>>=1;
+ fPaphNil=shifterU16;
+ shifterU16>>=1;
+ fCopied=shifterU16;
+ shifterU16>>=1;
+ unused0_3=shifterU16;
+ shifterU16>>=5;
+ fn=shifterU16;
+ fc=readU32(ptr);
+ ptr+=sizeof(U32);
+ prm.readPtr(ptr);
+ ptr+=PRM::sizeOf;
+}
+
+bool PCD::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=fNoParaLast;
+ shifterU16|=fPaphNil << 1;
+ shifterU16|=fCopied << 2;
+ shifterU16|=unused0_3 << 3;
+ shifterU16|=fn << 8;
+ stream->write(shifterU16);
+ stream->write(fc);
+ prm.write(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PCD::clear() {
+ fNoParaLast=0;
+ fPaphNil=0;
+ fCopied=0;
+ unused0_3=0;
+ fn=0;
+ fc=0;
+ prm.clear();
+}
+
+bool operator==(const PCD &lhs, const PCD &rhs) {
+
+ return lhs.fNoParaLast==rhs.fNoParaLast &&
+ lhs.fPaphNil==rhs.fPaphNil &&
+ lhs.fCopied==rhs.fCopied &&
+ lhs.unused0_3==rhs.unused0_3 &&
+ lhs.fn==rhs.fn &&
+ lhs.fc==rhs.fc &&
+ lhs.prm==rhs.prm;
+}
+
+bool operator!=(const PCD &lhs, const PCD &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// PGD implementation
+
+PGD::PGD() {
+ clear();
+}
+
+PGD::PGD(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool PGD::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ unused0_0=shifterU16;
+ shifterU16>>=5;
+ fGhost=shifterU16;
+ shifterU16>>=2;
+ unused0_7=shifterU16;
+ shifterU16=stream->readU16();
+ fContinue=shifterU16;
+ shifterU16>>=1;
+ fUnk=shifterU16;
+ shifterU16>>=1;
+ fRight=shifterU16;
+ shifterU16>>=1;
+ fPgnRestart=shifterU16;
+ shifterU16>>=1;
+ fEmptyPage=shifterU16;
+ shifterU16>>=1;
+ fAllFtn=shifterU16;
+ shifterU16>>=1;
+ fColOnly=shifterU16;
+ shifterU16>>=1;
+ fTableBreaks=shifterU16;
+ shifterU16>>=1;
+ fMarked=shifterU16;
+ shifterU16>>=1;
+ fColumnBreaks=shifterU16;
+ shifterU16>>=1;
+ fTableHeader=shifterU16;
+ shifterU16>>=1;
+ fNewPage=shifterU16;
+ shifterU16>>=1;
+ bkc=shifterU16;
+ lnn=stream->readU16();
+ pgn=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool PGD::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=unused0_0;
+ shifterU16|=fGhost << 5;
+ shifterU16|=unused0_7 << 7;
+ stream->write(shifterU16);
+ shifterU16=fContinue;
+ shifterU16|=fUnk << 1;
+ shifterU16|=fRight << 2;
+ shifterU16|=fPgnRestart << 3;
+ shifterU16|=fEmptyPage << 4;
+ shifterU16|=fAllFtn << 5;
+ shifterU16|=fColOnly << 6;
+ shifterU16|=fTableBreaks << 7;
+ shifterU16|=fMarked << 8;
+ shifterU16|=fColumnBreaks << 9;
+ shifterU16|=fTableHeader << 10;
+ shifterU16|=fNewPage << 11;
+ shifterU16|=bkc << 12;
+ stream->write(shifterU16);
+ stream->write(lnn);
+ stream->write(pgn);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PGD::clear() {
+ unused0_0=0;
+ fGhost=0;
+ unused0_7=0;
+ fContinue=0;
+ fUnk=0;
+ fRight=0;
+ fPgnRestart=0;
+ fEmptyPage=0;
+ fAllFtn=0;
+ fColOnly=0;
+ fTableBreaks=0;
+ fMarked=0;
+ fColumnBreaks=0;
+ fTableHeader=0;
+ fNewPage=0;
+ bkc=0;
+ lnn=0;
+ pgn=0;
+}
+
+bool operator==(const PGD &lhs, const PGD &rhs) {
+
+ return lhs.unused0_0==rhs.unused0_0 &&
+ lhs.fGhost==rhs.fGhost &&
+ lhs.unused0_7==rhs.unused0_7 &&
+ lhs.fContinue==rhs.fContinue &&
+ lhs.fUnk==rhs.fUnk &&
+ lhs.fRight==rhs.fRight &&
+ lhs.fPgnRestart==rhs.fPgnRestart &&
+ lhs.fEmptyPage==rhs.fEmptyPage &&
+ lhs.fAllFtn==rhs.fAllFtn &&
+ lhs.fColOnly==rhs.fColOnly &&
+ lhs.fTableBreaks==rhs.fTableBreaks &&
+ lhs.fMarked==rhs.fMarked &&
+ lhs.fColumnBreaks==rhs.fColumnBreaks &&
+ lhs.fTableHeader==rhs.fTableHeader &&
+ lhs.fNewPage==rhs.fNewPage &&
+ lhs.bkc==rhs.bkc &&
+ lhs.lnn==rhs.lnn &&
+ lhs.pgn==rhs.pgn;
+}
+
+bool operator!=(const PGD &lhs, const PGD &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// PICF implementation
+
+PICF::PICF() : Shared() {
+ clear();
+}
+
+PICF::PICF(OLEStreamReader *stream, bool preservePos) : Shared() {
+ clear();
+ read(stream, preservePos);
+}
+
+bool PICF::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ lcb=stream->readU32();
+ cbHeader=stream->readU16();
+ mfp.read(stream, false);
+ for(int _i=0; _i<(14); ++_i)
+ bm_rcWinMF[_i]=stream->readU8();
+ dxaGoal=stream->readU16();
+ dyaGoal=stream->readU16();
+ mx=stream->readU16();
+ my=stream->readU16();
+ dxaCropLeft=stream->readU16();
+ dyaCropTop=stream->readU16();
+ dxaCropRight=stream->readU16();
+ dyaCropBottom=stream->readU16();
+ shifterU16=stream->readU16();
+ brcl=shifterU16;
+ shifterU16>>=4;
+ fFrameEmpty=shifterU16;
+ shifterU16>>=1;
+ fBitmap=shifterU16;
+ shifterU16>>=1;
+ fDrawHatch=shifterU16;
+ shifterU16>>=1;
+ fError=shifterU16;
+ shifterU16>>=1;
+ bpp=shifterU16;
+ brcTop.read(stream, false);
+ brcLeft.read(stream, false);
+ brcBottom.read(stream, false);
+ brcRight.read(stream, false);
+ dxaOrigin=stream->readU16();
+ dyaOrigin=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool PICF::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(lcb);
+ stream->write(cbHeader);
+ mfp.write(stream, false);
+ for(int _i=0; _i<(14); ++_i)
+ stream->write(bm_rcWinMF[_i]);
+ stream->write(dxaGoal);
+ stream->write(dyaGoal);
+ stream->write(mx);
+ stream->write(my);
+ stream->write(dxaCropLeft);
+ stream->write(dyaCropTop);
+ stream->write(dxaCropRight);
+ stream->write(dyaCropBottom);
+ shifterU16=brcl;
+ shifterU16|=fFrameEmpty << 4;
+ shifterU16|=fBitmap << 5;
+ shifterU16|=fDrawHatch << 6;
+ shifterU16|=fError << 7;
+ shifterU16|=bpp << 8;
+ stream->write(shifterU16);
+ brcTop.write(stream, false);
+ brcLeft.write(stream, false);
+ brcBottom.write(stream, false);
+ brcRight.write(stream, false);
+ stream->write(dxaOrigin);
+ stream->write(dyaOrigin);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PICF::clear() {
+ lcb=0;
+ cbHeader=0;
+ mfp.clear();
+ for(int _i=0; _i<(14); ++_i)
+ bm_rcWinMF[_i]=0;
+ dxaGoal=0;
+ dyaGoal=0;
+ mx=0;
+ my=0;
+ dxaCropLeft=0;
+ dyaCropTop=0;
+ dxaCropRight=0;
+ dyaCropBottom=0;
+ brcl=0;
+ fFrameEmpty=0;
+ fBitmap=0;
+ fDrawHatch=0;
+ fError=0;
+ bpp=0;
+ brcTop.clear();
+ brcLeft.clear();
+ brcBottom.clear();
+ brcRight.clear();
+ dxaOrigin=0;
+ dyaOrigin=0;
+}
+
+void PICF::dump() const
+{
+ wvlog << "Dumping PICF:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping PICF done." << std::endl;
+}
+
+std::string PICF::toString() const
+{
+ std::string s( "PICF:" );
+ s += "\nlcb=";
+ s += uint2string( lcb );
+ s += "\ncbHeader=";
+ s += uint2string( cbHeader );
+ s += "\nmfp=";
+ s += "\n{" + mfp.toString() + "}\n";
+ for(int _i=0; _i<(14); ++_i) {
+ s += "\nbm_rcWinMF[" + int2string( _i ) + "]=";
+ s += uint2string( bm_rcWinMF[_i] );
+ }
+ s += "\ndxaGoal=";
+ s += uint2string( dxaGoal );
+ s += "\ndyaGoal=";
+ s += uint2string( dyaGoal );
+ s += "\nmx=";
+ s += uint2string( mx );
+ s += "\nmy=";
+ s += uint2string( my );
+ s += "\ndxaCropLeft=";
+ s += uint2string( dxaCropLeft );
+ s += "\ndyaCropTop=";
+ s += uint2string( dyaCropTop );
+ s += "\ndxaCropRight=";
+ s += uint2string( dxaCropRight );
+ s += "\ndyaCropBottom=";
+ s += uint2string( dyaCropBottom );
+ s += "\nbrcl=";
+ s += uint2string( brcl );
+ s += "\nfFrameEmpty=";
+ s += uint2string( fFrameEmpty );
+ s += "\nfBitmap=";
+ s += uint2string( fBitmap );
+ s += "\nfDrawHatch=";
+ s += uint2string( fDrawHatch );
+ s += "\nfError=";
+ s += uint2string( fError );
+ s += "\nbpp=";
+ s += uint2string( bpp );
+ s += "\nbrcTop=";
+ s += "\n{" + brcTop.toString() + "}\n";
+ s += "\nbrcLeft=";
+ s += "\n{" + brcLeft.toString() + "}\n";
+ s += "\nbrcBottom=";
+ s += "\n{" + brcBottom.toString() + "}\n";
+ s += "\nbrcRight=";
+ s += "\n{" + brcRight.toString() + "}\n";
+ s += "\ndxaOrigin=";
+ s += uint2string( dxaOrigin );
+ s += "\ndyaOrigin=";
+ s += uint2string( dyaOrigin );
+ s += "\nPICF Done.";
+ return s;
+}
+
+bool operator==(const PICF &lhs, const PICF &rhs) {
+
+ for(int _i=0; _i<(14); ++_i) {
+ if(lhs.bm_rcWinMF[_i]!=rhs.bm_rcWinMF[_i])
+ return false;
+ }
+
+ return lhs.lcb==rhs.lcb &&
+ lhs.cbHeader==rhs.cbHeader &&
+ lhs.mfp==rhs.mfp &&
+ lhs.dxaGoal==rhs.dxaGoal &&
+ lhs.dyaGoal==rhs.dyaGoal &&
+ lhs.mx==rhs.mx &&
+ lhs.my==rhs.my &&
+ lhs.dxaCropLeft==rhs.dxaCropLeft &&
+ lhs.dyaCropTop==rhs.dyaCropTop &&
+ lhs.dxaCropRight==rhs.dxaCropRight &&
+ lhs.dyaCropBottom==rhs.dyaCropBottom &&
+ lhs.brcl==rhs.brcl &&
+ lhs.fFrameEmpty==rhs.fFrameEmpty &&
+ lhs.fBitmap==rhs.fBitmap &&
+ lhs.fDrawHatch==rhs.fDrawHatch &&
+ lhs.fError==rhs.fError &&
+ lhs.bpp==rhs.bpp &&
+ lhs.brcTop==rhs.brcTop &&
+ lhs.brcLeft==rhs.brcLeft &&
+ lhs.brcBottom==rhs.brcBottom &&
+ lhs.brcRight==rhs.brcRight &&
+ lhs.dxaOrigin==rhs.dxaOrigin &&
+ lhs.dyaOrigin==rhs.dyaOrigin;
+}
+
+bool operator!=(const PICF &lhs, const PICF &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// SED implementation
+
+const unsigned int SED::sizeOf = 12;
+
+SED::SED() {
+ clear();
+}
+
+SED::SED(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool SED::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ fSwap=shifterU16;
+ shifterU16>>=1;
+ fUnk=shifterU16;
+ shifterU16>>=1;
+ fn=shifterU16;
+ fcSepx=stream->readU32();
+ fnMpr=stream->readU16();
+ fcMpr=stream->readU32();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool SED::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=fSwap;
+ shifterU16|=fUnk << 1;
+ shifterU16|=fn << 2;
+ stream->write(shifterU16);
+ stream->write(fcSepx);
+ stream->write(fnMpr);
+ stream->write(fcMpr);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void SED::clear() {
+ fSwap=0;
+ fUnk=0;
+ fn=0;
+ fcSepx=0;
+ fnMpr=0;
+ fcMpr=0;
+}
+
+bool operator==(const SED &lhs, const SED &rhs) {
+
+ return lhs.fSwap==rhs.fSwap &&
+ lhs.fUnk==rhs.fUnk &&
+ lhs.fn==rhs.fn &&
+ lhs.fcSepx==rhs.fcSepx &&
+ lhs.fnMpr==rhs.fnMpr &&
+ lhs.fcMpr==rhs.fcMpr;
+}
+
+bool operator!=(const SED &lhs, const SED &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// SEP implementation
+
+SEP::SEP() : Shared() {
+ clear();
+}
+
+SEP::SEP(OLEStreamReader *stream, bool preservePos) : Shared() {
+ clear();
+ read(stream, preservePos);
+}
+
+bool SEP::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ bkc=stream->readU8();
+ fTitlePage=stream->readU8();
+ ccolM1=stream->readU16();
+ dxaColumns=stream->readU16();
+ fAutoPgn=stream->readU8();
+ nfcPgn=stream->readU8();
+ pgnStart=stream->readU16();
+ fUnlocked=stream->readU8();
+ cnsPgn=stream->readU8();
+ fPgnRestart=stream->readU8();
+ fEndNote=stream->readU8();
+ lnc=stream->readU8();
+ grpfIhdt=stream->readU8();
+ nLnnMod=stream->readU16();
+ dxaLnn=stream->readU16();
+ dyaHdrTop=stream->readU16();
+ dyaHdrBottom=stream->readU16();
+ dxaPgn=stream->readU16();
+ dyaPgn=stream->readU16();
+ fLBetween=stream->readU8();
+ vjc=stream->readU8();
+ lnnMin=stream->readU16();
+ dmOrientPage=stream->readU8();
+ iHeadingPgn=stream->readU8();
+ xaPage=stream->readU16();
+ yaPage=stream->readU16();
+ dxaLeft=stream->readU16();
+ dxaRight=stream->readU16();
+ dyaTop=stream->readU16();
+ dyaBottom=stream->readU16();
+ dzaGutter=stream->readU16();
+ dmBinFirst=stream->readU16();
+ dmBinOther=stream->readU16();
+ dmPaperReq=stream->readU16();
+ fEvenlySpaced=stream->readU8();
+ unused55=stream->readU8();
+ dxaColumnWidth=stream->readU16();
+ for(int _i=0; _i<(89); ++_i)
+ rgdxaColumnWidthSpacing[_i]=stream->readU16();
+ olstAnm.read(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool SEP::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(bkc);
+ stream->write(fTitlePage);
+ stream->write(ccolM1);
+ stream->write(dxaColumns);
+ stream->write(fAutoPgn);
+ stream->write(nfcPgn);
+ stream->write(pgnStart);
+ stream->write(fUnlocked);
+ stream->write(cnsPgn);
+ stream->write(fPgnRestart);
+ stream->write(fEndNote);
+ stream->write(lnc);
+ stream->write(grpfIhdt);
+ stream->write(nLnnMod);
+ stream->write(dxaLnn);
+ stream->write(dyaHdrTop);
+ stream->write(dyaHdrBottom);
+ stream->write(dxaPgn);
+ stream->write(dyaPgn);
+ stream->write(fLBetween);
+ stream->write(vjc);
+ stream->write(lnnMin);
+ stream->write(dmOrientPage);
+ stream->write(iHeadingPgn);
+ stream->write(xaPage);
+ stream->write(yaPage);
+ stream->write(dxaLeft);
+ stream->write(dxaRight);
+ stream->write(dyaTop);
+ stream->write(dyaBottom);
+ stream->write(dzaGutter);
+ stream->write(dmBinFirst);
+ stream->write(dmBinOther);
+ stream->write(dmPaperReq);
+ stream->write(fEvenlySpaced);
+ stream->write(unused55);
+ stream->write(dxaColumnWidth);
+ for(int _i=0; _i<(89); ++_i)
+ stream->write(rgdxaColumnWidthSpacing[_i]);
+ olstAnm.write(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void SEP::clear() {
+ bkc=2;
+ fTitlePage=0;
+ ccolM1=0;
+ dxaColumns=0;
+ fAutoPgn=0;
+ nfcPgn=0;
+ pgnStart=0;
+ fUnlocked=0;
+ cnsPgn=0;
+ fPgnRestart=0;
+ fEndNote=true;
+ lnc=0;
+ grpfIhdt=0;
+ nLnnMod=0;
+ dxaLnn=0;
+ dyaHdrTop=720;
+ dyaHdrBottom=720;
+ dxaPgn=720;
+ dyaPgn=720;
+ fLBetween=0;
+ vjc=0;
+ lnnMin=0;
+ dmOrientPage=1;
+ iHeadingPgn=0;
+ xaPage=12240;
+ yaPage=15840;
+ dxaLeft=0;
+ dxaRight=0;
+ dyaTop=0;
+ dyaBottom=0;
+ dzaGutter=0;
+ dmBinFirst=0;
+ dmBinOther=0;
+ dmPaperReq=0;
+ fEvenlySpaced=true;
+ unused55=0;
+ dxaColumnWidth=0;
+ for(int _i=0; _i<(89); ++_i)
+ rgdxaColumnWidthSpacing[_i]=0;
+ olstAnm.clear();
+}
+
+void SEP::dump() const
+{
+ wvlog << "Dumping SEP:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping SEP done." << std::endl;
+}
+
+std::string SEP::toString() const
+{
+ std::string s( "SEP:" );
+ s += "\nbkc=";
+ s += uint2string( bkc );
+ s += "\nfTitlePage=";
+ s += uint2string( fTitlePage );
+ s += "\nccolM1=";
+ s += uint2string( ccolM1 );
+ s += "\ndxaColumns=";
+ s += uint2string( dxaColumns );
+ s += "\nfAutoPgn=";
+ s += uint2string( fAutoPgn );
+ s += "\nnfcPgn=";
+ s += uint2string( nfcPgn );
+ s += "\npgnStart=";
+ s += uint2string( pgnStart );
+ s += "\nfUnlocked=";
+ s += uint2string( fUnlocked );
+ s += "\ncnsPgn=";
+ s += uint2string( cnsPgn );
+ s += "\nfPgnRestart=";
+ s += uint2string( fPgnRestart );
+ s += "\nfEndNote=";
+ s += uint2string( fEndNote );
+ s += "\nlnc=";
+ s += uint2string( lnc );
+ s += "\ngrpfIhdt=";
+ s += uint2string( grpfIhdt );
+ s += "\nnLnnMod=";
+ s += uint2string( nLnnMod );
+ s += "\ndxaLnn=";
+ s += uint2string( dxaLnn );
+ s += "\ndyaHdrTop=";
+ s += uint2string( dyaHdrTop );
+ s += "\ndyaHdrBottom=";
+ s += uint2string( dyaHdrBottom );
+ s += "\ndxaPgn=";
+ s += uint2string( dxaPgn );
+ s += "\ndyaPgn=";
+ s += uint2string( dyaPgn );
+ s += "\nfLBetween=";
+ s += uint2string( fLBetween );
+ s += "\nvjc=";
+ s += uint2string( vjc );
+ s += "\nlnnMin=";
+ s += uint2string( lnnMin );
+ s += "\ndmOrientPage=";
+ s += uint2string( dmOrientPage );
+ s += "\niHeadingPgn=";
+ s += uint2string( iHeadingPgn );
+ s += "\nxaPage=";
+ s += uint2string( xaPage );
+ s += "\nyaPage=";
+ s += uint2string( yaPage );
+ s += "\ndxaLeft=";
+ s += uint2string( dxaLeft );
+ s += "\ndxaRight=";
+ s += uint2string( dxaRight );
+ s += "\ndyaTop=";
+ s += uint2string( dyaTop );
+ s += "\ndyaBottom=";
+ s += uint2string( dyaBottom );
+ s += "\ndzaGutter=";
+ s += uint2string( dzaGutter );
+ s += "\ndmBinFirst=";
+ s += uint2string( dmBinFirst );
+ s += "\ndmBinOther=";
+ s += uint2string( dmBinOther );
+ s += "\ndmPaperReq=";
+ s += uint2string( dmPaperReq );
+ s += "\nfEvenlySpaced=";
+ s += uint2string( fEvenlySpaced );
+ s += "\nunused55=";
+ s += uint2string( unused55 );
+ s += "\ndxaColumnWidth=";
+ s += uint2string( dxaColumnWidth );
+ for(int _i=0; _i<(89); ++_i) {
+ s += "\nrgdxaColumnWidthSpacing[" + int2string( _i ) + "]=";
+ s += uint2string( rgdxaColumnWidthSpacing[_i] );
+ }
+ s += "\nolstAnm=";
+ s += "\n{" + olstAnm.toString() + "}\n";
+ s += "\nSEP Done.";
+ return s;
+}
+
+bool operator==(const SEP &lhs, const SEP &rhs) {
+
+ for(int _i=0; _i<(89); ++_i) {
+ if(lhs.rgdxaColumnWidthSpacing[_i]!=rhs.rgdxaColumnWidthSpacing[_i])
+ return false;
+ }
+
+ return lhs.bkc==rhs.bkc &&
+ lhs.fTitlePage==rhs.fTitlePage &&
+ lhs.ccolM1==rhs.ccolM1 &&
+ lhs.dxaColumns==rhs.dxaColumns &&
+ lhs.fAutoPgn==rhs.fAutoPgn &&
+ lhs.nfcPgn==rhs.nfcPgn &&
+ lhs.pgnStart==rhs.pgnStart &&
+ lhs.fUnlocked==rhs.fUnlocked &&
+ lhs.cnsPgn==rhs.cnsPgn &&
+ lhs.fPgnRestart==rhs.fPgnRestart &&
+ lhs.fEndNote==rhs.fEndNote &&
+ lhs.lnc==rhs.lnc &&
+ lhs.grpfIhdt==rhs.grpfIhdt &&
+ lhs.nLnnMod==rhs.nLnnMod &&
+ lhs.dxaLnn==rhs.dxaLnn &&
+ lhs.dyaHdrTop==rhs.dyaHdrTop &&
+ lhs.dyaHdrBottom==rhs.dyaHdrBottom &&
+ lhs.dxaPgn==rhs.dxaPgn &&
+ lhs.dyaPgn==rhs.dyaPgn &&
+ lhs.fLBetween==rhs.fLBetween &&
+ lhs.vjc==rhs.vjc &&
+ lhs.lnnMin==rhs.lnnMin &&
+ lhs.dmOrientPage==rhs.dmOrientPage &&
+ lhs.iHeadingPgn==rhs.iHeadingPgn &&
+ lhs.xaPage==rhs.xaPage &&
+ lhs.yaPage==rhs.yaPage &&
+ lhs.dxaLeft==rhs.dxaLeft &&
+ lhs.dxaRight==rhs.dxaRight &&
+ lhs.dyaTop==rhs.dyaTop &&
+ lhs.dyaBottom==rhs.dyaBottom &&
+ lhs.dzaGutter==rhs.dzaGutter &&
+ lhs.dmBinFirst==rhs.dmBinFirst &&
+ lhs.dmBinOther==rhs.dmBinOther &&
+ lhs.dmPaperReq==rhs.dmPaperReq &&
+ lhs.fEvenlySpaced==rhs.fEvenlySpaced &&
+ lhs.unused55==rhs.unused55 &&
+ lhs.dxaColumnWidth==rhs.dxaColumnWidth &&
+ lhs.olstAnm==rhs.olstAnm;
+}
+
+bool operator!=(const SEP &lhs, const SEP &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// SEPX implementation
+
+SEPX::SEPX() {
+ clearInternal();
+}
+
+SEPX::SEPX(OLEStreamReader *stream, bool preservePos) {
+ clearInternal();
+ read(stream, preservePos);
+}
+
+SEPX::SEPX(const SEPX &rhs) {
+ cb=rhs.cb;
+ grpprl=rhs.grpprl;
+}
+
+SEPX::~SEPX() {
+ delete [] grpprl;
+}
+
+SEPX &SEPX::operator=(const SEPX &rhs) {
+
+ // Check for assignment to self
+ if(this==&rhs)
+ return *this;
+
+ cb=rhs.cb;
+ grpprl=rhs.grpprl;
+
+ return *this;
+}
+
+bool SEPX::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ cb=stream->readU8();
+ // Attention: I don't know how to read grpprl - U8[]
+#ifdef __GNUC__
+#warning "Couldn't generate reading code for SEPX::grpprl"
+#endif
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool SEPX::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(cb);
+ // Attention: I don't know how to write grpprl - U8[]
+#ifdef __GNUC__
+#warning "Couldn't generate writing code for SEPX::grpprl"
+#endif
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void SEPX::clear() {
+ delete [] grpprl;
+ clearInternal();
+}
+
+void SEPX::clearInternal() {
+ cb=0;
+ grpprl=0;
+}
+
+bool operator==(const SEPX &lhs, const SEPX &rhs) {
+ // Attention: I don't know how to compare grpprl - U8[]
+#ifdef __GNUC__
+#warning "Can't compare SEPX::grpprl items"
+#endif
+
+ return lhs.cb==rhs.cb;
+}
+
+bool operator!=(const SEPX &lhs, const SEPX &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// STSHI implementation
+
+const unsigned int STSHI::sizeOf = 14;
+
+STSHI::STSHI() {
+ clear();
+}
+
+STSHI::STSHI(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool STSHI::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ cstd=stream->readU16();
+ cbSTDBaseInFile=stream->readU16();
+ shifterU16=stream->readU16();
+ fStdStylenamesWritten=shifterU16;
+ shifterU16>>=1;
+ unused4_2=shifterU16;
+ stiMaxWhenSaved=stream->readU16();
+ istdMaxFixedWhenSaved=stream->readU16();
+ nVerBuiltInNamesWhenSaved=stream->readU16();
+ ftcStandardChpStsh=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool STSHI::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(cstd);
+ stream->write(cbSTDBaseInFile);
+ shifterU16=fStdStylenamesWritten;
+ shifterU16|=unused4_2 << 1;
+ stream->write(shifterU16);
+ stream->write(stiMaxWhenSaved);
+ stream->write(istdMaxFixedWhenSaved);
+ stream->write(nVerBuiltInNamesWhenSaved);
+ stream->write(ftcStandardChpStsh);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void STSHI::clear() {
+ cstd=0;
+ cbSTDBaseInFile=0;
+ fStdStylenamesWritten=0;
+ unused4_2=0;
+ stiMaxWhenSaved=0;
+ istdMaxFixedWhenSaved=0;
+ nVerBuiltInNamesWhenSaved=0;
+ ftcStandardChpStsh=0;
+}
+
+bool operator==(const STSHI &lhs, const STSHI &rhs) {
+
+ return lhs.cstd==rhs.cstd &&
+ lhs.cbSTDBaseInFile==rhs.cbSTDBaseInFile &&
+ lhs.fStdStylenamesWritten==rhs.fStdStylenamesWritten &&
+ lhs.unused4_2==rhs.unused4_2 &&
+ lhs.stiMaxWhenSaved==rhs.stiMaxWhenSaved &&
+ lhs.istdMaxFixedWhenSaved==rhs.istdMaxFixedWhenSaved &&
+ lhs.nVerBuiltInNamesWhenSaved==rhs.nVerBuiltInNamesWhenSaved &&
+ lhs.ftcStandardChpStsh==rhs.ftcStandardChpStsh;
+}
+
+bool operator!=(const STSHI &lhs, const STSHI &rhs) {
+ return !(lhs==rhs);
+}
+
+
+
+} // namespace Word95
+
+} // namespace wvWare
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/word95_generated.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/word95_generated.h
new file mode 100644
index 00000000..07136019
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/word95_generated.h
@@ -0,0 +1,6638 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+// This code is generated from the Microsoft HTML specification of the
+// WinWord format. Do NOT edit this code, but fix the spec or the script
+// generating the sources.
+// For information about the script and the "hidden features" please read
+// the comments at the begin of the script.
+
+// If you find bugs or strange behavior please contact Werner Trobin
+
+#ifndef WORD95_GENERATED_H
+#define WORD95_GENERATED_H
+
+#include "global.h"
+#include "sharedptr.h"
+#include "utilities.h"
+
+namespace wvWare {
+
+class OLEStreamReader;
+class OLEStreamWriter;
+class StyleSheet;
+class Style;
+
+namespace Word95 {
+
+
+/**
+ * Date and Time (internal date format) (DTTM)
+ */
+struct DTTM {
+ /**
+ * Creates an empty DTTM structure and sets the defaults
+ */
+ DTTM();
+ /**
+ * Simply calls read(...)
+ */
+ DTTM(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ DTTM(const U8 *ptr);
+
+ /**
+ * This method reads the DTTM structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * minutes (0-59)
+ */
+ U16 mint:6;
+
+ /**
+ * hours (0-23)
+ */
+ U16 hr:5;
+
+ /**
+ * days of month (1-31)
+ */
+ U16 dom:5;
+
+ /**
+ * months (1-12)
+ */
+ U16 mon:4;
+
+ /**
+ * years (1900-2411)-1900
+ */
+ U16 yr:9;
+
+ /**
+ * weekday
+ * Sunday=0
+ * Monday=1
+ * Tuesday=2
+ * Wednesday=3
+ * Thursday=4
+ * Friday=5
+ * Saturday=6
+ */
+ U16 wdy:3;
+
+}; // DTTM
+
+bool operator==(const DTTM &lhs, const DTTM &rhs);
+bool operator!=(const DTTM &lhs, const DTTM &rhs);
+
+
+/**
+ * Property Modifier(variant 2) (PRM2)
+ */
+struct PRM2 {
+ /**
+ * Creates an empty PRM2 structure and sets the defaults
+ */
+ PRM2();
+ /**
+ * Simply calls read(...)
+ */
+ PRM2(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the PRM2 structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * set to 1 for variant 2
+ */
+ U16 fComplex:1;
+
+ /**
+ * index to a grpprl stored in CLX portion of file.
+ */
+ U16 igrpprl:15;
+
+}; // PRM2
+
+bool operator==(const PRM2 &lhs, const PRM2 &rhs);
+bool operator!=(const PRM2 &lhs, const PRM2 &rhs);
+
+
+/**
+ * Property Modifier(variant 1) (PRM)
+ */
+struct PRM {
+ /**
+ * Creates an empty PRM structure and sets the defaults
+ */
+ PRM();
+ /**
+ * Simply calls read(...)
+ */
+ PRM(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ PRM(const U8 *ptr);
+
+ /**
+ * This method reads the PRM structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * This method returns a PRM2 created from the current PRM
+ */
+ PRM2 toPRM2() const;
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * set to 0 for variant 1
+ */
+ U8 fComplex:1;
+
+ /**
+ * sprm opcode
+ */
+ U8 sprm:7;
+
+ /**
+ * sprm's second byte if necessary
+ */
+ U8 val;
+
+}; // PRM
+
+bool operator==(const PRM &lhs, const PRM &rhs);
+bool operator!=(const PRM &lhs, const PRM &rhs);
+
+
+/**
+ * Shading Descriptor (SHD)
+ */
+struct SHD {
+ /**
+ * Creates an empty SHD structure and sets the defaults
+ */
+ SHD();
+ /**
+ * Simply calls read(...)
+ */
+ SHD(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ SHD(const U8 *ptr);
+
+ /**
+ * This method reads the SHD structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * foreground color (see chp.ico)
+ */
+ U16 icoFore:5;
+
+ /**
+ * background color (see chp.ico)
+ */
+ U16 icoBack:5;
+
+ /**
+ * shading pattern (see ipat table below)
+ * 0 Automatic
+ * 1 Solid
+ * 2 5 Percent
+ * 3 10 Percent
+ * 4 20 Percent
+ * 5 25 Percent
+ * 6 30 Percent
+ * 7 40 Percent
+ * 8 50 Percent
+ * 9 60 Percent
+ * 10 70 Percent
+ * 11 75 Percent
+ * 12 80 Percent
+ * 13 90 Percent
+ * 14 Dark Horizontal
+ * 15 Dark Vertical
+ * 16 Dark Forward Diagonal
+ * 17 Dark Backward Diagonal
+ * 18 Dark Cross
+ * 19 Dark Diagonal Cross
+ * 20 Horizontal
+ * 21 Vertical
+ * 22 Forward Diagonal
+ * 23 Backward Diagonal
+ * 24 Cross
+ * 25 Diagonal Cross
+ * 35 2.5 Percent
+ * 36 7.5 Percent
+ * 37 12.5 Percent
+ * 38 15 Percent
+ * 39 17.5 Percent
+ * 40 22.5 Percent
+ * 41 27.5 Percent
+ * 42 32.5 Percent
+ * 43 35 Percent
+ * 44 37.5 Percent
+ * 45 42.5 Percent
+ * 46 45 Percent
+ * 47 47.5 Percent
+ * 48 52.5 Percent
+ * 49 55 Percent
+ * 50 57.5 Percent
+ * 51 62.5 Percent
+ * 52 65 Percent
+ * 53 67.5 Percent
+ * 54 72.5 Percent
+ * 55 77.5 Percent
+ * 56 82.5 Percent
+ * 57 85 Percent
+ * 58 87.5 Percent
+ * 59 92.5 Percent
+ * 60 95 Percent
+ * 61 97.5 Percent
+ * 62 97 Percent
+ */
+ U16 ipat:6;
+
+}; // SHD
+
+bool operator==(const SHD &lhs, const SHD &rhs);
+bool operator!=(const SHD &lhs, const SHD &rhs);
+
+
+/**
+ * Paragraph Height (PHE)
+ */
+struct PHE {
+ /**
+ * Creates an empty PHE structure and sets the defaults
+ */
+ PHE();
+ /**
+ * Simply calls read(...)
+ */
+ PHE(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ PHE(const U8 *ptr);
+
+ /**
+ * This method reads the PHE structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * reserved
+ */
+ U16 fSpare:1;
+
+ /**
+ * phe entry is invalid when == 1
+ */
+ U16 fUnk:1;
+
+ /**
+ * when 1, total height of paragraph is known but lines in paragraph have
+ * different heights.
+ */
+ U16 fDiffLines:1;
+
+ /**
+ * reserved
+ */
+ U16 unused0_3:5;
+
+ /**
+ * when fDiffLines is 0 is number of lines in paragraph
+ */
+ U16 clMac:8;
+
+ /**
+ * width of lines in paragraph
+ */
+ U16 dxaCol;
+
+ /**
+ * When fDiffLines is 0, this is the height of every line in paragraph.in pixels (dylLine).
+ * When fDiffLines is 1, this is the total height in pixels of the paragraph (dylHeight).
+ * dylHeight and dylLine overlap (shaheed).
+ */
+ U16 dylLine_dylHeight;
+
+}; // PHE
+
+bool operator==(const PHE &lhs, const PHE &rhs);
+bool operator!=(const PHE &lhs, const PHE &rhs);
+
+
+/**
+ * Border Code (BRC)
+ */
+struct BRC {
+ /**
+ * Creates an empty BRC structure and sets the defaults
+ */
+ BRC();
+ /**
+ * Simply calls read(...)
+ */
+ BRC(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ BRC(const U8 *ptr);
+
+ /**
+ * This method reads the BRC structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * When dxpLineWidth is 0, 1, 2, 3, 4, or 5, this field is the width of
+ * a single line of border in units of 0.75 points.Each line in the border
+ * is this wide (e.g. a double border is three lines).Must be nonzero when
+ * brcType is nonzero.When dxpLineWidth is 6, it means that the border line
+ * is dotted.When dxpLineWidth is 7, it means the border line is dashed.
+ */
+ U16 dxpLineWidth:3;
+
+ /**
+ * border type code
+ * 0 none
+ * 1 single
+ * 2 thick
+ * 3 double
+ */
+ U16 brcType:2;
+
+ /**
+ * when 1, border is drawn with shadow. Must be 0 when BRC is a substructure
+ * of the TC
+ */
+ U16 fShadow:1;
+
+ /**
+ * color code (see chp.ico)
+ */
+ U16 ico:5;
+
+ /**
+ * width of space to maintain between border and text within border. Must
+ * be 0 when BRC is a substructure of the TC.Stored in points for Windows.
+ */
+ U16 dxpSpace:5;
+
+}; // BRC
+
+bool operator==(const BRC &lhs, const BRC &rhs);
+bool operator!=(const BRC &lhs, const BRC &rhs);
+
+
+/**
+ * Table Autoformat Look sPecifier (TLP)
+ */
+struct TLP {
+ /**
+ * Creates an empty TLP structure and sets the defaults
+ */
+ TLP();
+ /**
+ * Simply calls read(...)
+ */
+ TLP(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ TLP(const U8 *ptr);
+
+ /**
+ * This method reads the TLP structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * index to Word's table of table looks
+ */
+ U16 itl;
+
+ /**
+ * when ==1, use the border properties from the selected table look
+ */
+ U16 fBorders:1;
+
+ /**
+ * when ==1, use the shading properties from the selected table look
+ */
+ U16 fShading:1;
+
+ /**
+ * when ==1, use the font from the selected table look
+ */
+ U16 fFont:1;
+
+ /**
+ * when ==1, use the color from the selected table look
+ */
+ U16 fColor:1;
+
+ /**
+ * when ==1, do best fit from the selected table look
+ */
+ U16 fBestFit:1;
+
+ /**
+ * when ==1, apply properties from the selected table look to the header
+ * rows in the table
+ */
+ U16 fHdrRows:1;
+
+ /**
+ * when ==1, apply properties from the selected table look to the last
+ * row in the table
+ */
+ U16 fLastRow:1;
+
+ /**
+ * when ==1, apply properties from the selected table look to the header
+ * columns ofthe table
+ */
+ U16 fHdrCols:1;
+
+ /**
+ * when ==1, apply properties from the selected table look to the last
+ * column ofthe table
+ */
+ U16 fLastCol:1;
+
+ /**
+ * unused
+ */
+ U16 unused2_9:7;
+
+}; // TLP
+
+bool operator==(const TLP &lhs, const TLP &rhs);
+bool operator!=(const TLP &lhs, const TLP &rhs);
+
+
+/**
+ * Table Cell Descriptors (TC)
+ */
+struct TC {
+ /**
+ * Creates an empty TC structure and sets the defaults
+ */
+ TC();
+ /**
+ * Simply calls read(...)
+ */
+ TC(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ TC(const U8 *ptr);
+
+ /**
+ * This method reads the TC structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * set to 1 when cell is first cell of a range of cells that have been
+ * merged. When a cell is merged, the display areas of the merged cells are
+ * consolidated and the text within the cells is interpreted as belonging
+ * to one text stream for purposes of calculating line breaks.
+ */
+ U16 fFirstMerged:1;
+
+ /**
+ * set to 1 when cell has been merged with preceding cell.
+ */
+ U16 fMerged:1;
+
+ /**
+ * reserved
+ */
+ U16 fUnused:14;
+
+ /**
+ * specification of the top border of a table cell
+ */
+ BRC brcTop;
+
+ /**
+ * specification of left border of table row
+ */
+ BRC brcLeft;
+
+ /**
+ * specification of bottom border of table row
+ */
+ BRC brcBottom;
+
+ /**
+ * specification f right border of table row.
+ */
+ BRC brcRight;
+
+}; // TC
+
+bool operator==(const TC &lhs, const TC &rhs);
+bool operator!=(const TC &lhs, const TC &rhs);
+
+
+/**
+ * Drawing Primitive Header (Word) (DPHEAD)
+ */
+struct DPHEAD {
+ /**
+ * Creates an empty DPHEAD structure and sets the defaults
+ */
+ DPHEAD();
+ /**
+ * Simply calls read(...)
+ */
+ DPHEAD(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the DPHEAD structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * Drawn Primitive KindREVIEW davebu
+ * 0x0000 = start of grouping of primitives (DO)
+ * 0x0001 = line (DPLINE)
+ * 0x0002 = textbox (DPTXBX)
+ * 0x0003 = rectangle (DPRECT)
+ * 0x0004 = arc (DPARC)
+ * 0x0005 = ellipse (DPELLIPSE)
+ * 0x0006 = polyline (DPPOLYLINE)
+ * 0x0007 = callout textbox (DPCALLOUT)
+ * 0x0008 = end of grouping of primitives
+ * 0x0009 = sample primitve holding default values (DPSAMPLE)
+ */
+ U16 dpk;
+
+ /**
+ * size (count of bytes) of this DP
+ */
+ U16 cb;
+
+ /**
+ * These 2 points describe the rectangle enclosing this DP relative to
+ * the origin of the DO
+ */
+ U16 xa;
+
+ U16 ya;
+
+ U16 dxa;
+
+ U16 dya;
+
+}; // DPHEAD
+
+bool operator==(const DPHEAD &lhs, const DPHEAD &rhs);
+bool operator!=(const DPHEAD &lhs, const DPHEAD &rhs);
+
+
+/**
+ * DP data for a textbox (DPTXBX)
+ */
+struct DPTXBX {
+ /**
+ * Creates an empty DPTXBX structure and sets the defaults
+ */
+ DPTXBX();
+ /**
+ * Simply calls read(...)
+ */
+ DPTXBX(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the DPTXBX structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * Common header for a drawing primitive
+ */
+ DPHEAD dphead;
+
+ /**
+ * LiNe Property Color -- RGB color value
+ */
+ U32 lnpc;
+
+ /**
+ * line property weight in twips
+ */
+ U16 lnpw;
+
+ /**
+ * line property style. See description in DPLINE.
+ */
+ U16 lnps;
+
+ /**
+ * FiLl Property Color ForeGround -- RGB color value
+ */
+ U32 dlpcFg;
+
+ /**
+ * FiLl Property Color BackGround -- RGB color value
+ */
+ U32 dlpcBg;
+
+ /**
+ * FiLl Property Pattern. REVIEW davebu
+ */
+ U16 flpp;
+
+ /**
+ * Shadow Property Intensity
+ */
+ U16 shdwpi;
+
+ /**
+ * x offset of shadow
+ */
+ U16 xaOffset;
+
+ /**
+ * y offset of shadow
+ */
+ U16 yaOffset;
+
+ /**
+ * 1 if the textbox has rounded corners
+ */
+ U16 fRoundCorners:1;
+
+ /**
+ * REVIEW davebu
+ */
+ U16 zaShape:15;
+
+ /**
+ * REVIEW davebu
+ */
+ U16 dzaInternalMargin;
+
+}; // DPTXBX
+
+bool operator==(const DPTXBX &lhs, const DPTXBX &rhs);
+bool operator!=(const DPTXBX &lhs, const DPTXBX &rhs);
+
+
+/**
+ * DP data for a polyline (DPPOLYLINE)
+ */
+struct DPPOLYLINE {
+ /**
+ * Creates an empty DPPOLYLINE structure and sets the defaults
+ */
+ DPPOLYLINE();
+ /**
+ * Simply calls read(...)
+ */
+ DPPOLYLINE(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Attention: This struct allocates memory on the heap
+ */
+ DPPOLYLINE(const DPPOLYLINE &rhs);
+ ~DPPOLYLINE();
+
+ DPPOLYLINE &operator=(const DPPOLYLINE &rhs);
+
+ /**
+ * This method reads the DPPOLYLINE structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * Common header for a drawing primitive
+ */
+ DPHEAD dphead;
+
+ /**
+ * LiNe Property Color -- RGB color value
+ */
+ U32 lnpc;
+
+ /**
+ * line property weight in twips
+ */
+ U16 lnpw;
+
+ /**
+ * line property style. See description in DPLINE.
+ */
+ U16 lnps;
+
+ /**
+ * FiLl Property Color ForeGround -- RGB color value
+ */
+ U32 dlpcFg;
+
+ /**
+ * FiLl Property Color BackGround -- RGB color value
+ */
+ U32 dlpcBg;
+
+ /**
+ * FiLl Property Pattern. REVIEW davebu
+ */
+ U16 flpp;
+
+ /**
+ * Start EndPoint Property Style
+ * 0 None
+ * 1 Hollow
+ * 2 Filled
+ */
+ U16 eppsStart:2;
+
+ /**
+ * Start EndPoint Property Weight
+ */
+ U16 eppwStart:2;
+
+ /**
+ * Start EndPoint Property length
+ */
+ U16 epplStart:2;
+
+ U16 unused30_6:10;
+
+ /**
+ * End EndPoint Property Style
+ */
+ U16 eppsEnd:2;
+
+ /**
+ * End EndPoint Property Weight
+ */
+ U16 eppwEnd:2;
+
+ /**
+ * End EndPoint Property length
+ */
+ U16 epplEnd:2;
+
+ U16 unused32_6:10;
+
+ /**
+ * Shadow Property Intensity
+ */
+ U16 shdwpi;
+
+ /**
+ * x offset of shadow
+ */
+ U16 xaOffset;
+
+ /**
+ * y offset of shadow
+ */
+ U16 yaOffset;
+
+ /**
+ * 1 if this is a polygon
+ */
+ U16 fPolygon:1;
+
+ /**
+ * count of points
+ */
+ U16 cpt:15;
+
+ /**
+ * These are the endpoints of the first line.
+ */
+ U16 xaFirst;
+
+ U16 yaFirst;
+
+ U16 xaEnd;
+
+ U16 yaEnd;
+
+ /**
+ * An array of xa,ya pairs for the remaining points
+ */
+ U16 *rgpta; // U16 rgpta[];
+
+private:
+ void clearInternal();
+
+}; // DPPOLYLINE
+
+bool operator==(const DPPOLYLINE &lhs, const DPPOLYLINE &rhs);
+bool operator!=(const DPPOLYLINE &lhs, const DPPOLYLINE &rhs);
+
+
+/**
+ * Table Properties (TAP)
+ */
+struct TAP : public Shared {
+ /**
+ * Creates an empty TAP structure and sets the defaults
+ */
+ TAP();
+ /**
+ * Simply calls read(...)
+ */
+ TAP(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Attention: This struct allocates memory on the heap
+ */
+ TAP(const TAP &rhs);
+ ~TAP();
+
+ TAP &operator=(const TAP &rhs);
+
+ /**
+ * This method reads the TAP structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * justification code. specifies how table row should be justified within
+ * its column.
+ * 0 left justify
+ * 1center
+ * 2right justify
+ * 3left and right justify
+ */
+ U16 jc;
+
+ /**
+ * measures half of the white space that will be maintained between textin
+ * adjacent columns of a table row. A dxaGapHalf width of white space will
+ * be maintained on both sides of a column boundary.
+ */
+ U16 dxaGapHalf;
+
+ /**
+ * when greater than 0. guarantees that the height of the table will be
+ * at least dyaRowHeight high. When less than 0, guarantees that the height
+ * of the table will be exactly absolute value of dyaRowHeight high.When 0,table
+ * will be given a height large enough to representall of the text in all
+ * of the cells of the table.
+ */
+ U16 dyaRowHeight;
+
+ /**
+ * when 1, table row may not be split across page bounds
+ */
+ U8 fCantSplit;
+
+ /**
+ * when 1, table row is to be used as the header of the table
+ */
+ U8 fTableHeader;
+
+ /**
+ * table look specifier (see TLP definition)
+ */
+ TLP tlp;
+
+ /**
+ * used internally by Word
+ */
+ U16 fCaFull:1;
+
+ /**
+ * used internally by Word
+ */
+ U16 fFirstRow:1;
+
+ /**
+ * used internally by Word
+ */
+ U16 fLastRow:1;
+
+ /**
+ * used internally by Word
+ */
+ U16 fOutline:1;
+
+ /**
+ * reserved
+ */
+ U16 unused12_4:12;
+
+ /**
+ * count of cells defined for this row. ItcMac must be >= 0 and less than
+ * or equal to 32.
+ */
+ U16 itcMac;
+
+ /**
+ * used internally by Word
+ */
+ U16 dxaAdjust;
+
+ /**
+ * rgdxaCenter[0] is the left boundary of cell 0 measured relative to
+ * margin.. rgdxaCenter[tap.itcMac - 1] is left boundary of last cell. rgdxaCenter[tap.itcMac]
+ * is right boundary of last cell.
+ */
+ U16 *rgdxaCenter; // U16 rgdxaCenter[itcMac + 1];
+
+ /**
+ * array of table cell descriptors
+ */
+ TC *rgtc; // TC rgtc[itcMac];
+
+ /**
+ * array of cell shades
+ */
+ SHD *rgshd; // SHD rgshd[itcMac];
+
+ /**
+ * array of border defaults for cells
+ */
+ BRC rgbrcTable[6];
+
+private:
+ void clearInternal();
+
+}; // TAP
+
+bool operator==(const TAP &lhs, const TAP &rhs);
+bool operator!=(const TAP &lhs, const TAP &rhs);
+
+
+/**
+ * Tab Descriptor (TBD)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct TBD {
+// /**
+// * Creates an empty TBD structure and sets the defaults
+// */
+// TBD();
+// /**
+// * Simply calls read(...)
+// */
+// TBD(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * This method reads the TBD structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * justification code
+// * 0 left tab
+// * 1 centered tab
+// * 2 right tab
+// * 3 decimal tab
+// * 4 bar
+// */
+// U8 jc:3;
+
+// /**
+// * tab leader code
+// * 0 no leader
+// * 1 dotted leader
+// * 2 hyphenated leader
+// * 3 single line leader
+// * 4 heavy line leader
+// */
+// U8 tlc:3;
+
+// /**
+// * reserved
+// */
+// U8 unused0_6:2;
+
+//}; // TBD
+
+//bool operator==(const TBD &lhs, const TBD &rhs);
+//bool operator!=(const TBD &lhs, const TBD &rhs);
+
+
+/**
+ * Autonumbered List Data Descriptor (ANLD)
+ */
+struct ANLD {
+ /**
+ * Creates an empty ANLD structure and sets the defaults
+ */
+ ANLD();
+ /**
+ * Simply calls read(...)
+ */
+ ANLD(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ ANLD(const U8 *ptr);
+
+ /**
+ * This method reads the ANLD structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * number format code
+ * 0 Arabic numbering
+ * 1 Upper case Roman
+ * 2 Lower case Roman
+ * 3 Upper case Letter
+ * 4 Lower case letter
+ * 5 Ordinal
+ */
+ U8 nfc;
+
+ /**
+ * offset into anld.rgch that is the limit of the text that will be displayed
+ * as the prefix of the autonumber text
+ */
+ U8 cxchTextBefore;
+
+ /**
+ * anld.cxchTextBefore will be the beginning offset of the text in the
+ * anld.rgchthat will be displayed as the suffix of an autonumber. The sum
+ * of anld.cxchTextBefore + anld.cxchTextAfter will be the limit of the autonumber
+ * suffix in anld.rgch
+ */
+ U8 cxchTextAfter;
+
+ /**
+ * justification code
+ * 0 left justify
+ * 1 center
+ * 2 right justify
+ * 3 left and right justify
+ */
+ U8 jc:2;
+
+ /**
+ * when ==1, number generated will include previous levels (used for legal
+ * numbering)
+ */
+ U8 fPrev:1;
+
+ /**
+ * when ==1, number will be displayed using a hanging indent
+ */
+ U8 fHang:1;
+
+ /**
+ * when ==1, boldness of number will be determined by anld.fBold.
+ */
+ U8 fSetBold:1;
+
+ /**
+ * when ==1, italicness of number will be determined by anld.fItalic
+ */
+ U8 fSetItalic:1;
+
+ /**
+ * when ==1, anld.fSmallCaps will determine whether number will be displayed
+ * in small caps or not.
+ */
+ U8 fSetSmallCaps:1;
+
+ /**
+ * when ==1, anld.fCaps will determine whether number will be displayed
+ * capitalized or not
+ */
+ U8 fSetCaps:1;
+
+ /**
+ * when ==1, anld.fStrike will determine whether the number will be displayed
+ * using strikethrough or not.
+ */
+ U8 fSetStrike:1;
+
+ /**
+ * when ==1, anld.kul will determine the underlining state of the autonumber.
+ */
+ U8 fSetKul:1;
+
+ /**
+ * when ==1, autonumber will be displayed with a single prefixing space
+ * character
+ */
+ U8 fPrevSpace:1;
+
+ /**
+ * determines boldness of autonumber when anld.fSetBold == 1.
+ */
+ U8 fBold:1;
+
+ /**
+ * determines italicness of autonumber when anld.fSetItalic == 1.
+ */
+ U8 fItalic:1;
+
+ /**
+ * determines whether autonumber will be displayed using small caps when
+ * anld.fSetSmallCaps == 1.
+ */
+ U8 fSmallCaps:1;
+
+ /**
+ * determines whether autonumber will be displayed using caps when anld.fSetCaps
+ * == 1.
+ */
+ U8 fCaps:1;
+
+ /**
+ * determines whether autonumber will be displayed using caps when anld.fSetStrike
+ * == 1.
+ */
+ U8 fStrike:1;
+
+ /**
+ * determines whether autonumber will be displayed with underlining when
+ * anld.fSetKul == 1.
+ */
+ U8 kul:3;
+
+ /**
+ * color of autonumber
+ */
+ U8 ico:5;
+
+ /**
+ * font code of autonumber
+ */
+ S16 ftc;
+
+ /**
+ * font half point size (or 0=auto)
+ */
+ U16 hps;
+
+ /**
+ * starting value (0 to 65535)
+ */
+ U16 iStartAt;
+
+ /**
+ * width of prefix text (same as indent)
+ */
+ U16 dxaIndent;
+
+ /**
+ * minimum space between number and paragraph
+ */
+ U16 dxaSpace;
+
+ /**
+ * number only 1 item per table cell
+ */
+ U8 fNumber1;
+
+ /**
+ * number across cells in table rows(instead of down)
+ */
+ U8 fNumberAcross;
+
+ /**
+ * restart heading number on section boundary
+ */
+ U8 fRestartHdn;
+
+ /**
+ * unused( should be 0)
+ */
+ U8 fSpareX;
+
+ /**
+ * characters displayed before/after autonumber
+ */
+ U8 rgchAnld[32];
+
+}; // ANLD
+
+bool operator==(const ANLD &lhs, const ANLD &rhs);
+bool operator!=(const ANLD &lhs, const ANLD &rhs);
+
+
+/**
+ * Autonumber Level Descriptor (ANLV)
+ */
+struct ANLV {
+ /**
+ * Creates an empty ANLV structure and sets the defaults
+ */
+ ANLV();
+ /**
+ * Simply calls read(...)
+ */
+ ANLV(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ ANLV(const U8 *ptr);
+
+ /**
+ * This method reads the ANLV structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * number format code
+ * 0 Arabic numbering
+ * 1 Upper case Roman
+ * 2 Lower case Roman
+ * 3 Upper case Letter
+ * 4 Lower case letter
+ * 5 Ordinal
+ */
+ U8 nfc;
+
+ /**
+ * offset into anld.rgch that is the limit of the text that will be displayed
+ * as the prefix of the autonumber text
+ */
+ U8 cxchTextBefore;
+
+ /**
+ * anld.cxchTextBefore will be the beginning offset of the text in the
+ * anld.rgch that will be displayed as the suffix of an autonumber. The sum
+ * of anld.cxchTextBefore + anld.cxchTextAfter will be the limit of the autonumber
+ * suffix in anld.rgch
+ */
+ U8 cxchTextAfter;
+
+ /**
+ * justification code
+ * 0 left justify
+ * 1 center
+ * 2 right justify
+ * 3 left and right justify
+ */
+ U8 jc:2;
+
+ /**
+ * when ==1, number generated will include previous levels (used for legal
+ * numbering)
+ */
+ U8 fPrev:1;
+
+ /**
+ * when ==1, number will be displayed using a hanging indent
+ */
+ U8 fHang:1;
+
+ /**
+ * when ==1, boldness of number will be determined by anld.fBold.
+ */
+ U8 fSetBold:1;
+
+ /**
+ * when ==1, italicness of number will be determined by anld.fItalic
+ */
+ U8 fSetItalic:1;
+
+ /**
+ * when ==1, anld.fSmallCaps will determine whether number will be displayed
+ * in small caps or not.
+ */
+ U8 fSetSmallCaps:1;
+
+ /**
+ * when ==1, anld.fCaps will determine whether number will be displayed
+ * capitalized or not
+ */
+ U8 fSetCaps:1;
+
+ /**
+ * when ==1, anld.fStrike will determine whether the number will be displayed
+ * using strikethrough or not.
+ */
+ U8 fSetStrike:1;
+
+ /**
+ * when ==1, anld.kul will determine the underlining state of the autonumber.
+ */
+ U8 fSetKul:1;
+
+ /**
+ * when ==1, autonumber will be displayed with a single prefixing space
+ * character
+ */
+ U8 fPrevSpace:1;
+
+ /**
+ * determines boldness of autonumber when anld.fSetBold == 1.
+ */
+ U8 fBold:1;
+
+ /**
+ * determines italicness of autonumber when anld.fSetItalic == 1.
+ */
+ U8 fItalic:1;
+
+ /**
+ * determines whether autonumber will be displayed using small caps when
+ * anld.fSetSmallCaps == 1.
+ */
+ U8 fSmallCaps:1;
+
+ /**
+ * determines whether autonumber will be displayed using caps when anld.fSetCaps
+ * == 1.
+ */
+ U8 fCaps:1;
+
+ /**
+ * determines whether autonumber will be displayed using caps when anld.fSetStrike
+ * == 1.
+ */
+ U8 fStrike:1;
+
+ /**
+ * determines whetherautonumber will be displayed with underlining when
+ * anld.fSetKul == 1.
+ */
+ U8 kul:3;
+
+ /**
+ * color of autonumber
+ */
+ U8 ico:5;
+
+ /**
+ * font code of autonumber
+ */
+ S16 ftc;
+
+ /**
+ * font half point size (or 0=auto)
+ */
+ U16 hps;
+
+ /**
+ * starting value (0 to 65535)
+ */
+ U16 iStartAt;
+
+ /**
+ * width of prefix text (same as indent)
+ */
+ U16 dxaIndent;
+
+ /**
+ * minimum space between number and paragraph
+ */
+ U16 dxaSpace;
+
+}; // ANLV
+
+bool operator==(const ANLV &lhs, const ANLV &rhs);
+bool operator!=(const ANLV &lhs, const ANLV &rhs);
+
+
+/**
+ * BooKmark First descriptor (BKF)
+ */
+struct BKF {
+ /**
+ * Creates an empty BKF structure and sets the defaults
+ */
+ BKF();
+ /**
+ * Simply calls read(...)
+ */
+ BKF(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the BKF structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * index to BKL entry in plcfbkl that describes the ending position of
+ * this bookmark in the CP stream.
+ */
+ S16 ibkl;
+
+ /**
+ * when bkf.fCol is 1, this is the index to the first column of a table
+ * column bookmark.
+ */
+ U16 itcFirst:7;
+
+ /**
+ * when 1, this indicates that this bookmark is marking the range of a
+ * Macintosh Publisher section.
+ */
+ U16 fPub:1;
+
+ /**
+ * when bkf.fCol is 1, this is the index to limit column of a table column
+ * bookmark.
+ */
+ U16 itcLim:7;
+
+ /**
+ * when 1, this bookmark marks a range of columns in a table specified
+ * by [bkf.itcFirst, bkf.itcLim).
+ */
+ U16 fCol:1;
+
+}; // BKF
+
+bool operator==(const BKF &lhs, const BKF &rhs);
+bool operator!=(const BKF &lhs, const BKF &rhs);
+
+
+/**
+ * BooKmark Lim descriptor (BKL)
+ */
+struct BKL {
+ /**
+ * Creates an empty BKL structure and sets the defaults
+ */
+ BKL();
+ /**
+ * Simply calls read(...)
+ */
+ BKL(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the BKL structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * index to BKF entry in plcfbkf that
+ */
+ S16 ibkf;
+
+}; // BKL
+
+bool operator==(const BKL &lhs, const BKL &rhs);
+bool operator!=(const BKL &lhs, const BKL &rhs);
+
+
+/**
+ * Border Code for Windows Word 1.0 (BRC10)
+ */
+struct BRC10 {
+ /**
+ * Creates an empty BRC10 structure and sets the defaults
+ */
+ BRC10();
+ /**
+ * Simply calls read(...)
+ */
+ BRC10(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the BRC10 structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * width of second line of border in pixels
+ */
+ U16 dxpLine2Width:3;
+
+ /**
+ * distance to maintain between both lines of borderin pixels
+ */
+ U16 dxpSpaceBetween:3;
+
+ /**
+ * width of first border line in pixels
+ */
+ U16 dxpLine1Width:3;
+
+ /**
+ * width of space to maintain between border and text within border. Must
+ * be 0 when BRC is a substructure of the TC.
+ */
+ U16 dxpSpace:5;
+
+ /**
+ * when 1, border is drawn with shadow. Must be 0 when BRC10 is a substructure
+ * of the TC.
+ */
+ U16 fShadow:1;
+
+ /**
+ * reserved
+ */
+ U16 fSpare:1;
+
+}; // BRC10
+
+bool operator==(const BRC10 &lhs, const BRC10 &rhs);
+bool operator!=(const BRC10 &lhs, const BRC10 &rhs);
+
+
+/**
+ * Bin Table Entry (BTE)
+ */
+struct BTE {
+ /**
+ * Creates an empty BTE structure and sets the defaults
+ */
+ BTE();
+ /**
+ * Simply calls read(...)
+ */
+ BTE(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the BTE structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * Page Number for FKP
+ */
+ U16 pn;
+
+}; // BTE
+
+bool operator==(const BTE &lhs, const BTE &rhs);
+bool operator!=(const BTE &lhs, const BTE &rhs);
+
+
+/**
+ * Character Properties (CHP)
+ */
+struct CHP : public Shared {
+ /**
+ * Creates an empty CHP structure and sets the defaults
+ */
+ CHP();
+ /**
+ * Simply calls read(...)
+ */
+ CHP(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the CHP structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * text is bold when 1 , and not bold when 0.
+ */
+ U8 fBold:1;
+
+ /**
+ * italic when 1, not italic when 0
+ */
+ U8 fItalic:1;
+
+ /**
+ * when 1, text has been deleted and will be displayed with strikethrus
+ * when revision marked text is to displayed
+ */
+ U8 fRMarkDel:1;
+
+ /**
+ * outlined when 1, not outlined when 0
+ */
+ U8 fOutline:1;
+
+ /**
+ * &lt;needs work>
+ */
+ U8 fFldVanish:1;
+
+ /**
+ * displayed with small caps when 1, no small caps when 0
+ */
+ U8 fSmallCaps:1;
+
+ /**
+ * displayed with caps when 1, no caps when 0
+ */
+ U8 fCaps:1;
+
+ U8 fVanish:1;
+
+ /**
+ * when 1, text is newly typed since the last time revision marks have
+ * been accepted and will be displayed with an underline when revision marked
+ * text is to be displayed
+ */
+ U8 fRMark:1;
+
+ /**
+ * character is a Word special character when 1, not a special character
+ * when 0
+ */
+ U8 fSpec:1;
+
+ /**
+ * displayed with strikethrough when 1, no strikethroughwhen 0
+ */
+ U8 fStrike:1;
+
+ /**
+ * embedded object when 1, not an embedded object when 0
+ */
+ U8 fObj:1;
+
+ /**
+ * character is drawn with a shdow when 1; drawn without shadow when 0
+ */
+ U8 fShadow:1;
+
+ /**
+ * character is displayed in lower case when 1. No case transformation
+ * is performed when 0. This field may be set to 1 only when chp.fSmallCaps
+ * is 1.
+ */
+ U8 fLowerCase:1;
+
+ /**
+ * when 1, chp.fcPic points to an FFDATA the data structure binary data
+ * used by Word to describe a form field. chp.fData may only be 1 when chp.fSpec
+ * is also 1 and the special character in the document stream that has this
+ * property is a chPicture (0x01).
+ */
+ U8 fData:1;
+
+ /**
+ * when 1, chp.lTagObj specifies a particular object in the object stream
+ * that specifies the particular OLE object in the stream that should be displayed
+ * when the chPicture fSpec character that is tagged with the fOle2 is encountered.
+ * chp.fOle2 may only be 1 when chp.fSpec is also 1 and the special character
+ * in the document stream that has this property is a chPicture (0x01).
+ */
+ U8 fOle2:1;
+
+ /**
+ * Reserved
+ */
+ U16 unused2;
+
+ /**
+ * font code. The ftc is an index into the rgffn structure. The rgffn
+ * entry indexed by ftc describes the font that will be used to display the
+ * run of text described by the CHP.
+ */
+ U16 ftc;
+
+ /**
+ * font size in half points
+ */
+ U16 hps;
+
+ /**
+ * space following each character in the run expressed in twip units.
+ */
+ U16 dxaSpace;
+
+ /**
+ * superscript/subscript indices
+ * 0 means no super/subscripting
+ * 1 means text in run is superscrpted
+ * 2 means text in run is subscripted
+ */
+ U8 iss:3;
+
+ /**
+ * reserved
+ */
+ U8 unused10_3:3;
+
+ /**
+ * used by Word internally, not stored in file
+ */
+ U8 fSysVanish:1;
+
+ /**
+ * reserved
+ */
+ U8 unused10_7:1;
+
+ /**
+ * color of text:
+ * 0 Auto
+ * 1 Black
+ * 2 Blue
+ * 3 Cyan
+ * 4 Green
+ * 5 Magenta
+ * 6 Red
+ * 7 Yellow
+ * 8 White
+ * 9 DkBlue
+ * 10 DkCyan
+ * 11 DkGreen
+ * 12 DkMagenta
+ * 13 DkRed
+ * 14 DkYellow
+ * 15 DkGray
+ * 16 LtGray
+ */
+ U8 ico:5;
+
+ /**
+ * underline code:
+ * 0 none
+ * 1 single
+ * 2 by word
+ * 3 double
+ * 4 dotted
+ * 5 hidden
+ */
+ U8 kul:3;
+
+ /**
+ * super/subscript position in half points; positive means text is raised;
+ * negative means text is lowered.
+ */
+ S16 hpsPos;
+
+ /**
+ * Language Name Language ID
+ * 0x0401 Arabic
+ * 0x0402 Bulgarian
+ * 0x0403 Catalan
+ * 0x0404 Traditional Chinese
+ * 0x0804 Simplified Chinese
+ * 0x0405 Czech
+ * 0x0406 Danish
+ * 0x0407 German
+ * 0x0807 Swiss German
+ * 0x0408 Greek
+ * 0x0409 U.S. English
+ * 0x0809 U.K. English
+ * 0x0c09 Australian English
+ * 0x040a Castilian Spanish
+ * 0x080a Mexican Spanish
+ * 0x040b Finnish
+ * 0x040c French
+ * 0x080c Belgian French
+ * 0x0c0c Canadian French
+ * 0x100c Swiss French
+ * 0x040d Hebrew
+ * 0x040e Hungarian
+ * 0x040f Icelandic
+ * 0x0410 Italian
+ * 0x0810 Swiss Italian
+ * 0x0411 Japanese
+ * 0x0412 Korean
+ * 0x0413 Dutch
+ * 0x0813 Belgian Dutch
+ * 0x0414 Norwegian - Bokmal
+ * 0x0814 Norwegian - Nynorsk
+ * 0x0415 Polish
+ * 0x0416 Brazilian Portuguese
+ * 0x0816 Portuguese
+ * 0x0417 Rhaeto-Romanic
+ * 0x0418 Romanian
+ * 0x0419 Russian
+ * 0x041a Croato-Serbian (Latin)
+ * 0x081a Serbo-Croatian (Cyrillic)
+ * 0x041b Slovak
+ * 0x041c Albanian
+ * 0x041d Swedish
+ * 0x041e Thai
+ * 0x041f Turkish
+ * 0x0420 Urdu
+ * 0x0421 Bahasa
+ */
+ U16 lid;
+
+ /**
+ * offset in document stream pointing to beginning of a picture when character
+ * is a picture character (character is 0x01 and chp.fSpec is 1)
+ * offset in document stream pointing to beginning of a picture when character
+ * is an OLE1 object character (character is 0x20 and chp.fSpec is 1, chp.fOle2
+ * is 0)
+ * long word tag that identifies an OLE2 object in the object stream when
+ * the character is an OLE2 object character. (character is 0x01 and chp.fSpec
+ * is 1, chp.fOle2 is 1)
+ */
+ U32 fcPic_fcObj_lTagObj;
+
+ /**
+ * index to author IDs stored in hsttbfRMark. used when text in run was
+ * newly typed or deleted when revision marking was enabled
+ */
+ U16 ibstRMark;
+
+ /**
+ * Date/time at which this run of text was entered/modified by the author.
+ * (Only recorded whenrevision marking is on.)
+ */
+ DTTM dttmRMark;
+
+ /**
+ * reserved
+ */
+ U16 unused26;
+
+ /**
+ * index to character style descriptor in the stylesheet that tags this
+ * run of text When istd is istdNormalChar (10 decimal), characters in run
+ * are not affected by a character style. If chp.istd contains any other value,
+ * chpx of the specified character style are applied to CHP for this run before
+ * any other exceptional properties are applied.
+ */
+ U16 istd;
+
+ /**
+ * when chp.fSpec is 1 and the character recorded for the run in the document
+ * stream is chSymbol (0x28), chp.ftcSym identifies the font code of the symbol
+ * font that will be used to display the symbol character recorded in chp.chSym.
+ * Just like chp.ftc, chp.ftcSym is an index into the rgffn structure.
+ */
+ U16 ftcSym;
+
+ /**
+ * when chp.fSpec is 1 and the character recorded for the run in the document
+ * stream is chSymbol (0x28), the character stored chp.chSym will be displayed
+ * using the font specified in chp.ftcSym.
+ */
+ U8 chSym;
+
+ /**
+ * when 1, the character set used to interpret the characters recorded
+ * in the run identified by chp.chse is different from the native character
+ * set for this document which is stored in fib.chse.
+ */
+ U8 fChsDiff;
+
+ /**
+ * an index to strings displayed as reasons for actions taken by Word?s
+ * AutoFormat code
+ */
+ U16 idslRMReason;
+
+ /**
+ * hyphenation rule
+ * 0 No hyphenation
+ * 1Normal hyphenation
+ * 2Add letter before hyphen
+ * 3Change letter before hyphen
+ * 4Delete letter before hyphen
+ * 5Change letter after hyphen
+ * 6Delete letter before the hyphen and change the letter preceding the
+ * deleted character
+ */
+ U8 ysr;
+
+ /**
+ * the character that will be used to add or changea letter when chp.ysr
+ * is 2,3, 5 or 6
+ */
+ U8 chYsr;
+
+ /**
+ * extended character set id
+ * 0 characters in run should be interpreted using the ANSI set used by
+ * Windows
+ * 256 characters in run should be interpreted using the Macintosh character
+ * set.
+ */
+ U16 chse;
+
+ /**
+ * kerning distance for characters in run recorded in half points
+ */
+ U16 hpsKern;
+
+}; // CHP
+
+bool operator==(const CHP &lhs, const CHP &rhs);
+bool operator!=(const CHP &lhs, const CHP &rhs);
+
+
+/**
+ * Character Property Exceptions (CHPX)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct CHPX {
+// /**
+// * Creates an empty CHPX structure and sets the defaults
+// */
+// CHPX();
+// /**
+// * Simply calls read(...)
+// */
+// CHPX(OLEStreamReader *stream, bool preservePos=false);
+// /**
+// * Attention: This struct allocates memory on the heap
+// */
+// CHPX(const CHPX &rhs);
+// ~CHPX();
+
+// CHPX &operator=(const CHPX &rhs);
+
+// /**
+// * This method reads the CHPX structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * count of bytes of following data in CHPX.
+// */
+// U8 cb;
+
+// /**
+// * a list of the sprms that encode the differences between CHP for a run
+// * of text and the CHP generated by the paragraph and character styles that
+// * tag the run.
+// */
+// U8 *grpprl; // U8 grpprl[cb];
+
+//private:
+// void clearInternal();
+
+//}; // CHPX
+
+//bool operator==(const CHPX &lhs, const CHPX &rhs);
+//bool operator!=(const CHPX &lhs, const CHPX &rhs);
+
+
+/**
+ * Formatted Disk Page for CHPXs (CHPXFKP)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct CHPXFKP {
+// /**
+// * Creates an empty CHPXFKP structure and sets the defaults
+// */
+// CHPXFKP();
+// /**
+// * Simply calls read(...)
+// */
+// CHPXFKP(OLEStreamReader *stream, bool preservePos=false);
+// /**
+// * Attention: This struct allocates memory on the heap
+// */
+// CHPXFKP(const CHPXFKP &rhs);
+// ~CHPXFKP();
+
+// CHPXFKP &operator=(const CHPXFKP &rhs);
+
+// /**
+// * This method reads the CHPXFKP structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * Array of FCs. Each FC is the limit FC of a run of exception text.
+// */
+// U32 *rgfc; // U32 rgfc[];
+
+// /**
+// * an array of bytes where each byte is the word offset of aCHPX. If the
+// * byte stored is 0,there is no difference between run's character properties
+// * and the style's character properties
+// */
+// U8 *rgb; // U8 rgb[];
+
+// /**
+// * As new runs/paragraphs are recorded in the FKP,unused space is reduced
+// * by 5 if CHPX is already recorded and is reduced by5+sizeof(CHPX) if property
+// * is not already recorded.
+// */
+// U8 *unusedSpace; // U8 unusedSpace[];
+
+// /**
+// * grpchpx consists of all of the CHPXs stored in FKP concatenated end
+// * to end. Each CHPXis prefixed with a count of bytes which records its length.
+// */
+// U8 *grpchpx; // U8 grpchpx[];
+
+// /**
+// * count of runs for CHPX FKP,
+// */
+// U8 crun;
+
+//private:
+// void clearInternal();
+
+//}; // CHPXFKP
+
+//bool operator==(const CHPXFKP &lhs, const CHPXFKP &rhs);
+//bool operator!=(const CHPXFKP &lhs, const CHPXFKP &rhs);
+
+
+/**
+ * Drop Cap Specifier (DCS)
+ */
+struct DCS {
+ /**
+ * Creates an empty DCS structure and sets the defaults
+ */
+ DCS();
+ /**
+ * Simply calls read(...)
+ */
+ DCS(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ DCS(const U8 *ptr);
+
+ /**
+ * This method reads the DCS structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * default value 0
+ * drop cap type
+ * 0 no drop cap
+ * 1 normal drop cap
+ * 2 drop cap in margin
+ */
+ U8 fdct:3;
+
+ /**
+ * count of lines to drop
+ */
+ U8 lines:5;
+
+ /**
+ * reserved
+ */
+ U8 unused1;
+
+}; // DCS
+
+bool operator==(const DCS &lhs, const DCS &rhs);
+bool operator!=(const DCS &lhs, const DCS &rhs);
+
+
+/**
+ * Drawing Object (Word) (DO)
+ */
+struct DO {
+ /**
+ * Creates an empty DO structure and sets the defaults
+ */
+ DO();
+ /**
+ * Simply calls read(...)
+ */
+ DO(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the DO structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * FC pointing to drawing object data
+ */
+ U32 fc;
+
+ /**
+ * Drawn Object Kind, currently this is always 0
+ */
+ U16 dok;
+
+ /**
+ * size (count of bytes) of the entire DO
+ */
+ U16 cb;
+
+ /**
+ * x position relative to anchor CP
+ */
+ U8 bx;
+
+ /**
+ * y position relative to anchor CP
+ */
+ U8 by;
+
+ /**
+ * height of DO
+ */
+ U16 dhgt;
+
+ /**
+ * 1 if the DO anchor is locked
+ */
+ U16 fAnchorLock:1;
+
+ U16 unused8:15;
+
+ /**
+ * variable length array of drawing primitives
+ */
+ U8 rgdp;
+
+}; // DO
+
+bool operator==(const DO &lhs, const DO &rhs);
+bool operator!=(const DO &lhs, const DO &rhs);
+
+
+/**
+ * Document Properties (DOP)
+ */
+struct DOP {
+ /**
+ * Creates an empty DOP structure and sets the defaults
+ */
+ DOP();
+ /**
+ * Simply calls read(...)
+ */
+ DOP(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the DOP structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * 1 when facing pages should be printed (default 0)
+ */
+ U16 fFacingPages:1;
+
+ /**
+ * 1 when widow control is in effect. 0 when widow control disabled. (default
+ * 1)
+ */
+ U16 fWidowControl:1;
+
+ /**
+ * 1 when doc is a main doc for Print Merge Helper, 0 when not; default=0
+ */
+ U16 fPMHMainDoc:1;
+
+ /**
+ * Default line suppression storage
+ * 0= form letter line suppression
+ * 1= no line suppression
+ * default=0
+ */
+ U16 grfSuppression:2;
+
+ /**
+ * footnote position code
+ * 0 print as endnotes
+ * 1 print at bottom of page
+ * 2 print immediately beneath text
+ * (default 1)
+ */
+ U16 fpc:2;
+
+ /**
+ * unused (default 0)
+ */
+ U16 unused0_7:1;
+
+ /**
+ * specification of document headers and footers. See explanation under
+ * Headers and Footers topic. (default 0)
+ */
+ U16 grpfIhdt:8;
+
+ /**
+ * restart index for footnote
+ * 0 don't restart note numbering
+ * 1 restart for each section
+ * 2 restart for each page
+ * (default 0)
+ */
+ U16 rncFtn:2;
+
+ /**
+ * initial footnote number for document (default 1)
+ */
+ U16 nFtn:14;
+
+ /**
+ * when 1, indicates that information in the hplcpad should be refreshed
+ * since outline has been dirtied
+ */
+ U8 fOutlineDirtySave:1;
+
+ /**
+ * reserved
+ */
+ U8 unused4_1:7;
+
+ /**
+ * when 1, Word believes all pictures recorded in the document were created
+ * on a Macintosh
+ */
+ U8 fOnlyMacPics:1;
+
+ /**
+ * when 1, Word believes all pictures recorded in the document were created
+ * in Windows
+ */
+ U8 fOnlyWinPics:1;
+
+ /**
+ * when 1, document was created as a print merge labels document
+ */
+ U8 fLabelDoc:1;
+
+ /**
+ * when 1, Word is allowed to hyphenate words that are capitalized. When
+ * 0, capitalized may not be hyphenated
+ */
+ U8 fHyphCapitals:1;
+
+ /**
+ * when 1, Word will hyphenate newly typed text as a background task
+ */
+ U8 fAutoHyphen:1;
+
+ U8 fFormNoFields:1;
+
+ /**
+ * when 1, Word will merge styles from its template
+ */
+ U8 fLinkStyles:1;
+
+ /**
+ * when 1, Word will mark revisions as the document is edited
+ */
+ U8 fRevMarking:1;
+
+ /**
+ * always make backup when document saved when 1.
+ */
+ U8 fBackup:1;
+
+ U8 fExactCWords:1;
+
+ U8 fPagHidden:1;
+
+ U8 fPagResults:1;
+
+ /**
+ * when 1, annotations are locked for editing
+ */
+ U8 fLockAtn:1;
+
+ /**
+ * swap margins on left/right pages when 1.
+ */
+ U8 fMirrorMargins:1;
+
+ /**
+ * user has recommended that this doc be opened read-only when 1
+ */
+ U8 fReadOnlyRecommended:1;
+
+ /**
+ * when 1, use TrueType fonts by default (flag obeyed only when doc was
+ * created by WinWord 2.x)
+ */
+ U8 fDfltTrueType:1;
+
+ /**
+ * when 1, file created with SUPPRESSTOPSPACING=YES in win.ini. (flag
+ * obeyed only when doc was created by WinWord 2.x).
+ */
+ U8 fPagSuppressTopSpacing:1;
+
+ /**
+ * when 1, document is protected from edit operations
+ */
+ U8 fProtEnabled:1;
+
+ /**
+ * when 1, restrict selections to occur only within form fields
+ */
+ U8 fDispFormFldSel:1;
+
+ /**
+ * when 1, show revision markings on screen
+ */
+ U8 fRMView:1;
+
+ /**
+ * when 1, print revision marks when document is printed
+ */
+ U8 fRMPrint:1;
+
+ U8 fWriteReservation:1;
+
+ /**
+ * when 1, the current revision marking state is locked
+ */
+ U8 fLockRev:1;
+
+ /**
+ * when 1, document contains embedded True Type fonts
+ */
+ U8 fEmbedFonts:1;
+
+ /**
+ * compatability option: when 1, don?t add automatic tab stops for hanging
+ * indent
+ */
+ U16 copts_fNoTabForInd:1;
+
+ /**
+ * compatability option: when 1, don?t add extra space for raised or lowered
+ * characters
+ */
+ U16 copts_fNoSpaceRaiseLower:1;
+
+ /**
+ * compatability option: when 1, supress the paragraph Space Before and
+ * Space After options after a page break
+ */
+ U16 copts_fSuppressSpbfAfterPageBreak:1;
+
+ /**
+ * compatability option: when 1, wrap trailing spaces at the end of a
+ * line to the next line
+ */
+ U16 copts_fWrapTrailSpaces:1;
+
+ /**
+ * compatability option: when 1, print colors as black on non-color printers
+ */
+ U16 copts_fMapPrintTextColor:1;
+
+ /**
+ * compatability option: when 1, don?t balance columns for Continuous
+ * Section starts
+ */
+ U16 copts_fNoColumnBalance:1;
+
+ U16 copts_fConvMailMergeEsc:1;
+
+ /**
+ * compatability option: when 1, supress extra line spacing at top of
+ * page
+ */
+ U16 copts_fSupressTopSpacing:1;
+
+ /**
+ * compatability option: when 1, combine table borders like Word 5.x for
+ * the Macintosh
+ */
+ U16 copts_fOrigWordTableRules:1;
+
+ /**
+ * compatability option: when 1, don?t blank area between metafile pictures
+ */
+ U16 copts_fTransparentMetafiles:1;
+
+ /**
+ * compatability option: when 1, show hard page or column breaks in frames
+ */
+ U16 copts_fShowBreaksInFrames:1;
+
+ /**
+ * compatability option: when 1, swap left and right pages on odd facing
+ * pages
+ */
+ U16 copts_fSwapBordersFacingPgs:1;
+
+ /**
+ * reserved
+ */
+ U16 unused8_12:4;
+
+ /**
+ * (default 720 twips) default tab width
+ */
+ U16 dxaTab;
+
+ U16 wSpare;
+
+ /**
+ * width of hyphenation hot zone measured in twips
+ */
+ U16 dxaHotZ;
+
+ /**
+ * number of lines allowed to have consecutive hyphens
+ */
+ U16 cConsecHypLim;
+
+ /**
+ * reserved
+ */
+ U16 wSpare2;
+
+ /**
+ * date and time document was created
+ */
+ DTTM dttmCreated;
+
+ /**
+ * date and time document was last revised
+ */
+ DTTM dttmRevised;
+
+ /**
+ * date and time document was last printed
+ */
+ DTTM dttmLastPrint;
+
+ /**
+ * number of times document has been revised since its creation
+ */
+ U16 nRevision;
+
+ /**
+ * time document was last edited
+ */
+ U32 tmEdited;
+
+ /**
+ * count of words tallied by last Word Count execution
+ */
+ U32 cWords;
+
+ /**
+ * count of characters tallied by last Word Count execution
+ */
+ U32 cCh;
+
+ /**
+ * count of pages tallied by last Word Count execution
+ */
+ U16 cPg;
+
+ /**
+ * count of paragraphs tallied by last Word Count execution
+ */
+ U32 cParas;
+
+ /**
+ * restart endnote number code
+ * 0 don't restart endnote numbering
+ * 1 restart for each section
+ * 2 restart for each page
+ */
+ U16 rncEdn:2;
+
+ /**
+ * beginning endnote number
+ */
+ U16 nEdn:14;
+
+ /**
+ * endnote position code
+ * 0 display endnotes at end of section
+ * 3 display endnotes at end of document
+ */
+ U16 epc:2;
+
+ /**
+ * number format code for auto footnotes
+ * 0 Arabic numbering
+ * 1 Upper case Roman
+ * 2 Lower case Roman
+ * 3 Upper case Letter
+ * 4 Lower case letter
+ * 5 Ordinal
+ */
+ U16 nfcFtnRef:4;
+
+ /**
+ * number format code for auto endnotes
+ * 0 Arabic numbering
+ * 1 Upper case Roman
+ * 2 Lower case Roman
+ * 3 Upper case Letter
+ * 4 Lower case letter
+ * 5 Ordinal
+ */
+ U16 nfcEdnRef:4;
+
+ /**
+ * only print data inside of form fields
+ */
+ U16 fPrintFormData:1;
+
+ /**
+ * only save document data that is inside of a form field.
+ */
+ U16 fSaveFormData:1;
+
+ /**
+ * shade form fields
+ */
+ U16 fShadeFormData:1;
+
+ /**
+ * reserved
+ */
+ U16 unused54_13:2;
+
+ /**
+ * when 1, include footnotes and endnotes in word count
+ */
+ U16 fWCFtnEdn:1;
+
+ /**
+ * count of lines tallied by last Word Count operation
+ */
+ U32 cLines;
+
+ /**
+ * count of words in footnotes and endnotes tallied by last Word Count
+ * operation
+ */
+ U32 cWordsFtnEnd;
+
+ /**
+ * count of characters in footnotes and endnotes tallied by last Word
+ * Count operation
+ */
+ U32 cChFtnEdn;
+
+ /**
+ * count of pages in footnotes and endnotes tallied by last Word Count
+ * operation
+ */
+ U16 cPgFtnEdn;
+
+ /**
+ * count of paragraphs in footnotes and endnotes tallied by last Word
+ * Count operation
+ */
+ U32 cParasFtnEdn;
+
+ /**
+ * count of paragraphs in footnotes and endnotes tallied by last Word
+ * Count operation
+ */
+ U32 cLinesFtnEdn;
+
+ /**
+ * document protection password key, only valid if dop.fProtEnabled, dop.fLockAtn
+ * or dop.fLockRev are 1.
+ */
+ U32 lKeyProtDoc;
+
+ /**
+ * document view kind
+ * 0 Normal view
+ * 1 Outline view
+ * 2 Page View
+ */
+ U16 wvkSaved:3;
+
+ U16 wScaleSaved:9;
+
+ U16 zkSaved:2;
+
+ U16 unused82_14:2;
+
+}; // DOP
+
+bool operator==(const DOP &lhs, const DOP &rhs);
+bool operator!=(const DOP &lhs, const DOP &rhs);
+
+
+/**
+ * DP data for an arc (DPARC)
+ */
+struct DPARC {
+ /**
+ * Creates an empty DPARC structure and sets the defaults
+ */
+ DPARC();
+ /**
+ * Simply calls read(...)
+ */
+ DPARC(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the DPARC structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * Common header for a drawing primitive
+ */
+ DPHEAD dphead;
+
+ /**
+ * LiNe Property Color -- RGB color value
+ */
+ U32 lnpc;
+
+ /**
+ * line property weight in twips
+ */
+ U16 lnpw;
+
+ /**
+ * line property style. See description in DPLINE.
+ */
+ U16 lnps;
+
+ /**
+ * FiLl Property Color ForeGround -- RGB color value
+ */
+ U32 dlpcFg;
+
+ /**
+ * FiLl Property Color BackGround -- RGB color value
+ */
+ U32 dlpcBg;
+
+ /**
+ * FiLl Property Pattern. REVIEW davebu
+ */
+ U16 flpp;
+
+ /**
+ * Shadow Property Intensity
+ */
+ U16 shdwpi;
+
+ /**
+ * x offset of shadow
+ */
+ U16 xaOffset;
+
+ /**
+ * y offset of shadow
+ */
+ U16 yaOffset;
+
+ /**
+ * REVIEW davebu
+ */
+ U16 fLeft:8;
+
+ /**
+ * REVIEW davebu
+ */
+ U16 fUp:8;
+
+}; // DPARC
+
+bool operator==(const DPARC &lhs, const DPARC &rhs);
+bool operator!=(const DPARC &lhs, const DPARC &rhs);
+
+
+/**
+ * DP data for a callout textbox (DPCALLOUT)
+ */
+struct DPCALLOUT {
+ /**
+ * Creates an empty DPCALLOUT structure and sets the defaults
+ */
+ DPCALLOUT();
+ /**
+ * Simply calls read(...)
+ */
+ DPCALLOUT(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the DPCALLOUT structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * Common header for a drawing primitive
+ */
+ DPHEAD dphead;
+
+ /**
+ * REVIEW davebu flags
+ */
+ U16 unused12;
+
+ /**
+ * REVIEW davebu
+ */
+ U16 dzaOffset;
+
+ /**
+ * REVIEW davebu
+ */
+ U16 dzaDescent;
+
+ /**
+ * REVIEW davebu
+ */
+ U16 dzaLength;
+
+ /**
+ * DP for a textbox
+ */
+ DPTXBX dptxbx;
+
+ /**
+ * DP for a polyline
+ */
+ DPPOLYLINE dpPolyLine;
+
+}; // DPCALLOUT
+
+bool operator==(const DPCALLOUT &lhs, const DPCALLOUT &rhs);
+bool operator!=(const DPCALLOUT &lhs, const DPCALLOUT &rhs);
+
+
+/**
+ * DP data for an ellipse (DPELLIPSE)
+ */
+struct DPELLIPSE {
+ /**
+ * Creates an empty DPELLIPSE structure and sets the defaults
+ */
+ DPELLIPSE();
+ /**
+ * Simply calls read(...)
+ */
+ DPELLIPSE(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the DPELLIPSE structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * Common header for a drawing primitive
+ */
+ DPHEAD dphead;
+
+ /**
+ * LiNe Property Color -- RGB color value
+ */
+ U32 lnpc;
+
+ /**
+ * line property weight in twips
+ */
+ U16 lnpw;
+
+ /**
+ * line property style. See description in DPLINE.
+ */
+ U16 lnps;
+
+ /**
+ * FiLl Property Color ForeGround -- RGB color value
+ */
+ U32 dlpcFg;
+
+ /**
+ * FiLl Property Color BackGround -- RGB color value
+ */
+ U32 dlpcBg;
+
+ /**
+ * FiLl Property Pattern. REVIEW davebu
+ */
+ U16 flpp;
+
+ /**
+ * Shadow Property Intensity
+ */
+ U16 shdwpi;
+
+ /**
+ * x offset of shadow
+ */
+ U16 xaOffset;
+
+ /**
+ * y offset of shadow
+ */
+ U16 yaOffset;
+
+}; // DPELLIPSE
+
+bool operator==(const DPELLIPSE &lhs, const DPELLIPSE &rhs);
+bool operator!=(const DPELLIPSE &lhs, const DPELLIPSE &rhs);
+
+
+/**
+ * DP data for a line (DPLINE)
+ */
+struct DPLINE {
+ /**
+ * Creates an empty DPLINE structure and sets the defaults
+ */
+ DPLINE();
+ /**
+ * Simply calls read(...)
+ */
+ DPLINE(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the DPLINE structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * Common header for a drawing primitive
+ */
+ DPHEAD dphead;
+
+ /**
+ * starting point for line
+ */
+ U16 xaStart;
+
+ U16 yaStart;
+
+ /**
+ * ending point for line
+ */
+ U16 xaEnd;
+
+ U16 yaEnd;
+
+ /**
+ * LiNe Property Color -- RGB color value
+ */
+ U32 lnpc;
+
+ /**
+ * line property weight in twips
+ */
+ U16 lnpw;
+
+ /**
+ * line property style
+ * 0 Solid
+ * 1 Dashed
+ * 2 Dotted
+ * 3 Dash Dot
+ * 4 Dash Dot Dot
+ * 5 Hollow
+ */
+ U16 lnps;
+
+ /**
+ * Start EndPoint Property Style 0 None
+ * 1 Hollow
+ * 2 Filled
+ */
+ U16 eppsStart:2;
+
+ /**
+ * Start EndPoint Property Weight
+ */
+ U16 eppwStart:2;
+
+ /**
+ * Start EndPoint Property length
+ */
+ U16 epplStart:2;
+
+ U16 unused24_6:10;
+
+ /**
+ * End EndPoint Property Style
+ */
+ U16 eppsEnd:2;
+
+ /**
+ * End EndPoint Property Weight
+ */
+ U16 eppwEnd:2;
+
+ /**
+ * End EndPoint Property length
+ */
+ U16 epplEnd:2;
+
+ U16 unused26_6:10;
+
+ /**
+ * Shadow Property Intensity REVIEW davebu
+ */
+ U16 shdwpi;
+
+ /**
+ * x offset of shadow
+ */
+ U16 xaOffset;
+
+ /**
+ * y offset of shadow
+ */
+ U16 yaOffset;
+
+}; // DPLINE
+
+bool operator==(const DPLINE &lhs, const DPLINE &rhs);
+bool operator!=(const DPLINE &lhs, const DPLINE &rhs);
+
+
+/**
+ * DP data for a rectangle (DPRECT)
+ */
+struct DPRECT {
+ /**
+ * Creates an empty DPRECT structure and sets the defaults
+ */
+ DPRECT();
+ /**
+ * Simply calls read(...)
+ */
+ DPRECT(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the DPRECT structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * Common header for a drawing primitive
+ */
+ DPHEAD dphead;
+
+ /**
+ * LiNe Property Color -- RGB color value
+ */
+ U32 lnpc;
+
+ /**
+ * line property weight in twips
+ */
+ U16 lnpw;
+
+ /**
+ * line property style. See description in DPLINE.
+ */
+ U16 lnps;
+
+ /**
+ * FiLl Property Color ForeGround -- RGB color value
+ */
+ U32 dlpcFg;
+
+ /**
+ * FiLl Property Color BackGround -- RGB color value
+ */
+ U32 dlpcBg;
+
+ /**
+ * FiLl Property Pattern. REVIEW davebu
+ */
+ U16 flpp;
+
+ /**
+ * Shadow Property Intensity
+ */
+ U16 shdwpi;
+
+ /**
+ * x offset of shadow
+ */
+ U16 xaOffset;
+
+ /**
+ * y offset of shadow
+ */
+ U16 yaOffset;
+
+ /**
+ * 1 if the textbox has rounded corners
+ */
+ U16 fRoundCorners:1;
+
+ /**
+ * REVIEW davebu
+ */
+ U16 zaShape:15;
+
+}; // DPRECT
+
+bool operator==(const DPRECT &lhs, const DPRECT &rhs);
+bool operator!=(const DPRECT &lhs, const DPRECT &rhs);
+
+
+/**
+ * DP data for a sample primitive holding default values (DPSAMPLE)
+ */
+struct DPSAMPLE {
+ /**
+ * Creates an empty DPSAMPLE structure and sets the defaults
+ */
+ DPSAMPLE();
+ /**
+ * Simply calls read(...)
+ */
+ DPSAMPLE(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the DPSAMPLE structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * Common header for a drawing primitive
+ */
+ DPHEAD dphead;
+
+ /**
+ * LiNe Property Color -- RGB color value
+ */
+ U32 lnpc;
+
+ /**
+ * line property weight in twips
+ */
+ U16 lnpw;
+
+ /**
+ * line property style. See description in DPLINE.
+ */
+ U16 lnps;
+
+ /**
+ * FiLl Property Color ForeGround -- RGB color value
+ */
+ U32 dlpcFg;
+
+ /**
+ * FiLl Property Color BackGround -- RGB color value
+ */
+ U32 dlpcBg;
+
+ /**
+ * FiLl Property Pattern. REVIEW davebu
+ */
+ U16 flpp;
+
+ /**
+ * Start EndPoint Property Style
+ * 0 None
+ * 1 Hollow
+ * 2 Filled
+ */
+ U16 eppsStart:2;
+
+ /**
+ * Start EndPoint Property Weight
+ */
+ U16 eppwStart:2;
+
+ /**
+ * Start EndPoint Property length
+ */
+ U16 epplStart:2;
+
+ U16 unused30_6:10;
+
+ /**
+ * End EndPoint Property Style
+ */
+ U16 eppsEnd:2;
+
+ /**
+ * End EndPoint Property Weight
+ */
+ U16 eppwEnd:2;
+
+ /**
+ * End EndPoint Property length
+ */
+ U16 epplEnd:2;
+
+ U16 unused32_6:10;
+
+ /**
+ * Shadow Property Intensity
+ */
+ U16 shdwpi;
+
+ /**
+ * x offset of shadow
+ */
+ U16 xaOffset;
+
+ /**
+ * y offset of shadow
+ */
+ U16 yaOffset;
+
+ U16 unused40;
+
+ /**
+ * REVIEW davebu
+ */
+ U16 dzaOffset;
+
+ /**
+ * REVIEW davebu
+ */
+ U16 dzaDescent;
+
+ /**
+ * REVIEW davebu
+ */
+ U16 dzaLength;
+
+ /**
+ * 1 if the textbox has rounded corners
+ */
+ U16 fRoundCorners:1;
+
+ /**
+ * REVIEW davebu
+ */
+ U16 zaShape:15;
+
+ /**
+ * REVIEW davebu
+ */
+ U16 dzaInternalMargin;
+
+}; // DPSAMPLE
+
+bool operator==(const DPSAMPLE &lhs, const DPSAMPLE &rhs);
+bool operator!=(const DPSAMPLE &lhs, const DPSAMPLE &rhs);
+
+
+/**
+ * File Drawn Object Address (Word) (FDOA)
+ */
+struct FDOA {
+ /**
+ * Creates an empty FDOA structure and sets the defaults
+ */
+ FDOA();
+ /**
+ * Simply calls read(...)
+ */
+ FDOA(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the FDOA structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * FC pointing to drawing object data
+ */
+ U32 fc;
+
+ /**
+ * count of textboxes in the drawing object
+ */
+ U16 ctxbx;
+
+}; // FDOA
+
+bool operator==(const FDOA &lhs, const FDOA &rhs);
+bool operator!=(const FDOA &lhs, const FDOA &rhs);
+
+
+/**
+ * Font Family Name (FFN)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct FFN {
+// /**
+// * Creates an empty FFN structure and sets the defaults
+// */
+// FFN();
+// /**
+// * Simply calls read(...)
+// */
+// FFN(OLEStreamReader *stream, bool preservePos=false);
+// /**
+// * Attention: This struct allocates memory on the heap
+// */
+// FFN(const FFN &rhs);
+// ~FFN();
+
+// FFN &operator=(const FFN &rhs);
+
+// /**
+// * This method reads the FFN structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * total length of FFN - 1.
+// */
+// U8 cbFfnM1;
+
+// /**
+// * pitch request
+// */
+// U8 prq:2;
+
+// /**
+// * when 1, font is a TrueType font
+// */
+// U8 fTrueType:1;
+
+// /**
+// * reserved
+// */
+// U8 unused1_3:1;
+
+// /**
+// * font family id
+// */
+// U8 ff:3;
+
+// /**
+// * reserved
+// */
+// U8 unused1_7:1;
+
+// /**
+// * base weight of font
+// */
+// U16 wWeight;
+
+// /**
+// * character set identifier
+// */
+// U8 chs;
+
+// /**
+// * index into ffn.szFfn to the name of the alternate font
+// */
+// U8 ibszAlt;
+
+// /**
+// * zero terminated string that records name of font. Possibly followed
+// * by a second sz which records the name of an alternate font to use if the
+// * first named font does not exist on this system. Maximal size of szFfn is
+// * 65 characters.
+// */
+// U8 *szFfn; // U8 szFfn[];
+
+//private:
+// void clearInternal();
+
+//}; // FFN
+
+//bool operator==(const FFN &lhs, const FFN &rhs);
+//bool operator!=(const FFN &lhs, const FFN &rhs);
+
+
+/**
+ * File Information Block (Windows Word) (FIB)
+ */
+struct FIB {
+ /**
+ * Creates an empty FIB structure and sets the defaults
+ */
+ FIB();
+ /**
+ * Simply calls read(...)
+ */
+ FIB(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the FIB structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * magic number
+ */
+ U16 wIdent;
+
+ /**
+ * FIB version written
+ */
+ U16 nFib;
+
+ /**
+ * product version written by
+ */
+ U16 nProduct;
+
+ /**
+ * language stamp---localized version;
+ * <p>In pre-WinWord2.0 files this value was the nLocale.If value is &lt;
+ * 999, then it is the nLocale, otherwise it is the lid.
+ */
+ U16 lid;
+
+ U16 pnNext;
+
+ U16 fDot:1;
+
+ U16 fGlsy:1;
+
+ /**
+ * when 1, file is in complex, fast-saved format.
+ */
+ U16 fComplex:1;
+
+ /**
+ * file contains 1 or more pictures
+ */
+ U16 fHasPic:1;
+
+ /**
+ * count of times file was quicksaved
+ */
+ U16 cQuickSaves:4;
+
+ /**
+ * 1 if file is encrypted, 0 if not
+ */
+ U16 fEncrypted:1;
+
+ /**
+ * reserved
+ */
+ U16 unused10_9:1;
+
+ /**
+ * =1 when user has recommended that file be read read-only
+ */
+ U16 fReadOnlyRecommended:1;
+
+ /**
+ * =1, when file owner has made the file write reserved
+ */
+ U16 fWriteReservation:1;
+
+ /**
+ * =1, when using extended character set in file
+ */
+ U16 fExtChar:1;
+
+ /**
+ * unused
+ */
+ U16 unused10_13:3;
+
+ U16 nFibBack;
+
+ /**
+ * file encrypted key, only valid if fEncrypted.
+ */
+ U32 lKey;
+
+ /**
+ * environment in which file was created
+ * 0 created by Win Word
+ * 1 created by Mac Word
+ */
+ U8 envr;
+
+ /**
+ * reserved
+ */
+ U8 unused19;
+
+ /**
+ * default extended character set id for text in document stream. (overidden
+ * by chp.chse)
+ * 0 by default characters in doc stream should be interpreted using the
+ * ANSI character set used by Windows
+ * 256 characters in doc stream should be interpreted using the Macintosh
+ * character set.
+ */
+ U16 chse;
+
+ /**
+ * default extended character set id for text in internal data structures
+ * 0 by default characters in doc stream should be interpreted using the
+ * ANSI character set used by Windows
+ * 256 characters in doc stream should be interpreted using the Macintosh
+ * character set.
+ */
+ U16 chseTables;
+
+ /**
+ * file offset of first character of text. In non-complexfiles a CP can
+ * be transformed into an FC by the following transformation: fc = cp + fib.fcMin.
+ */
+ U32 fcMin;
+
+ /**
+ * file offset of last character of text in document text stream+ 1
+ */
+ U32 fcMac;
+
+ /**
+ * file offset of last byte written to file + 1.
+ */
+ U32 cbMac;
+
+ /**
+ * reserved
+ */
+ U32 fcSpare0;
+
+ /**
+ * reserved
+ */
+ U32 fcSpare1;
+
+ /**
+ * reserved
+ */
+ U32 fcSpare2;
+
+ /**
+ * reserved
+ */
+ U32 fcSpare3;
+
+ /**
+ * length of main document text stream
+ */
+ U32 ccpText;
+
+ /**
+ * length of footnote subdocument text stream
+ */
+ U32 ccpFtn;
+
+ /**
+ * length of header subdocument text stream
+ */
+ U32 ccpHdd;
+
+ /**
+ * length of macro subdocument text stream
+ */
+ U32 ccpMcr;
+
+ /**
+ * length of annotation subdocument text stream
+ */
+ U32 ccpAtn;
+
+ /**
+ * length of endnote subdocument text stream
+ */
+ U32 ccpEdn;
+
+ /**
+ * length of textbox subdocument text stream
+ */
+ U32 ccpTxbx;
+
+ /**
+ * length of header textbox subdocument text stream
+ * <p>Note: when ccpFtn == 0 and ccpHdr == 0 and ccpMcr== 0 and ccpAtn ==
+ * 0 and ccpEdn ==0 and ccpTxbx == 0 and ccpHdrTxbx == 0, then fib.fcMac =
+ * fib.fcMin+ fib.ccpText. If either ccpFtn != 0 or ccpHdd != 0or ccpMcr !=
+ * 0or ccpAtn != 0 or ccpEdn !=0 or ccpTxbx != 0 or ccpHdrTxbx == 0, then
+ * fib.fcMac = fib.fcMin + fib.ccpText + fib.ccpFtn + fib.ccpHdd+ fib.ccpMcr+
+ * fib.ccpAtn + fib.ccpEdn + fib.ccpTxbx + fib.ccpHdrTxbx + 1. The single
+ * characterstored beginning at file position fib.fcMac - 1 must always be
+ * a CRcharacter (ASCII 13).
+ */
+ U32 ccpHdrTxbx;
+
+ /**
+ * reserved
+ */
+ U32 ccpSpare2;
+
+ /**
+ * file offset of original allocation for STSH in file. During fast save
+ * Word will attempt to reuse this allocation if STSH is small enough to fit.
+ */
+ U32 fcStshfOrig;
+
+ /**
+ * count of bytes of original STSH allocation
+ */
+ U32 lcbStshfOrig;
+
+ /**
+ * file offset of STSH in file.
+ */
+ U32 fcStshf;
+
+ /**
+ * count of bytes of current STSH allocation
+ */
+ U32 lcbStshf;
+
+ /**
+ * file offset of footnote reference PLC. CPs in PLC are relative to main
+ * document text stream and give location of footnote references. The structure
+ * stored in this plc, called the FRD (footnote reference descriptor) is two
+ * byte long.
+ */
+ U32 fcPlcffndRef;
+
+ /**
+ * count of bytes of footnote reference PLC. == 0 if no footnotes defined
+ * in document.
+ */
+ U32 lcbPlcffndRef;
+
+ /**
+ * file offset of footnote text PLC. CPs in PLC are relative to footnote
+ * subdocument text stream and give location of beginnings of footnote text
+ * for correspondings references recorded in plcffndRef. No structure is stored
+ * in this plc. There will just be n+1 FC entries in this PLC when there are
+ * n footnotes
+ */
+ U32 fcPlcffndTxt;
+
+ /**
+ * count of bytes of footnote text PLC. == 0 if no footnotes defined in
+ * document
+ */
+ U32 lcbPlcffndTxt;
+
+ /**
+ * file offset of annotation reference PLC. The CPs recorded in this PLC
+ * give the offset of annotation references in the main document.
+ */
+ U32 fcPlcfandRef;
+
+ /**
+ * count of bytes of annotation reference PLC.
+ */
+ U32 lcbPlcfandRef;
+
+ /**
+ * file offset of annotation text PLC. The Cps recorded in this PLC give
+ * the offset of the annotation text in the annotation sub document corresponding
+ * to the references stored in the plcfandRef. There is a 1 to 1 correspondence
+ * between entries recorded in the plcfandTxt and the plcfandRef.
+ */
+ U32 fcPlcfandTxt;
+
+ /**
+ * count of bytes of the annotation text PLC
+ */
+ U32 lcbPlcfandTxt;
+
+ /**
+ * file offset of section descriptor PLC. CPs in PLC are relative to main
+ * document. The length of the SED is 12 bytes.
+ */
+ U32 fcPlcfsed;
+
+ /**
+ * count of bytes of section descriptor PLC.
+ */
+ U32 lcbPlcfsed;
+
+ /**
+ * file offset of paragraph descriptor PLCfor main document which is used
+ * by Word's Outline view. CPs in PLC are relative to main document. The length
+ * of the PGD is 8 bytes.
+ */
+ U32 fcPlcfpad;
+
+ /**
+ * count of bytes of paragraph descriptor PLC. ==0 if file was never viewed
+ * in Outline view. Should not be written by third party creators of Word
+ * files.
+ */
+ U32 lcbPlcfpad;
+
+ /**
+ * file offset of PLC of paragraph heights. CPs in PLC are relative to
+ * main document text stream. Only written for fies in complex format. Should
+ * not be written by third party creators of Word files. The PHE is 6 bytes
+ * long.
+ */
+ U32 fcPlcfphe;
+
+ /**
+ * count of bytes of paragraph height PLC. ==0 when file is non-complex.
+ */
+ U32 lcbPlcfphe;
+
+ /**
+ * file offset of glossary string table. This table consists of pascal
+ * style strings (strings stored prefixed with a length byte) concatenated
+ * one after another.
+ */
+ U32 fcSttbfglsy;
+
+ /**
+ * count of bytes of glossary string table.
+ * == 0 for non-glossary documents.
+ * !=0 for glossary documents.
+ */
+ U32 lcbSttbfglsy;
+
+ /**
+ * file offset of glossary PLC. CPs in PLC are relative to main document
+ * and mark the beginnings of glossary entries and are in 1-1 correspondence
+ * with entries of sttbfglsy. No structure is stored in this PLC. There will
+ * be n+1 FC entries in this PLC when there are n glossary entries.
+ */
+ U32 fcPlcfglsy;
+
+ /**
+ * count of bytes of glossary PLC.
+ * == 0 for non-glossary documents.
+ * !=0 for glossary documents.
+ */
+ U32 lcbPlcfglsy;
+
+ /**
+ * byte offset of header PLC. CPs are relative to header subdocument and
+ * mark the beginnings of individual headers in the header subdoc. No structure
+ * is stored in this PLC. There will be n+1 FC entries in this PLC when there
+ * are n headers stored for the document.
+ */
+ U32 fcPlcfhdd;
+
+ /**
+ * count of bytes of header PLC. == 0 if document contains no headers
+ */
+ U32 lcbPlcfhdd;
+
+ /**
+ * file offset of character property bin table.PLC. FCs in PLC are file
+ * offsets. Describes text of main document and all subdocuments. The BTE
+ * is 2 bytes long.
+ */
+ U32 fcPlcfbteChpx;
+
+ /**
+ * count of bytes of character property bin table PLC.
+ */
+ U32 lcbPlcfbteChpx;
+
+ /**
+ * file offset of paragraph property bin table.PLC. FCs in PLC are file
+ * offsets. Describes text of main document and all subdocuments. The BTE
+ * is 2 bytes long.
+ */
+ U32 fcPlcfbtePapx;
+
+ /**
+ * count of bytes of paragraph property bin table PLC.
+ */
+ U32 lcbPlcfbtePapx;
+
+ /**
+ * file offset of PLC reserved for private use. The SEA is 6 bytes long.
+ */
+ U32 fcPlcfsea;
+
+ /**
+ * count of bytes of private use PLC.
+ */
+ U32 lcbPlcfsea;
+
+ /**
+ * file offset of font information STTBF. The nth entry in the STTBF describes
+ * the font that will be displayed when the chp.ftc for text is equal to n.
+ * See the FFN file structure definition.
+ */
+ U32 fcSttbfffn;
+
+ /**
+ * count of bytes in sttbfffn.
+ */
+ U32 lcbSttbfffn;
+
+ /**
+ * offset in doc stream to the PLC of field positions in the main document.
+ * The Cps point to the beginning CP of a field, the CP offield separator
+ * character inside a field and the ending CP of the field. A field may be
+ * nested within another field. 20 levels of field nesting are allowed.
+ */
+ U32 fcPlcffldMom;
+
+ U32 lcbPlcffldMom;
+
+ /**
+ * offset in doc stream to the PLC of field positions in the header subdocument.
+ */
+ U32 fcPlcffldHdr;
+
+ U32 lcbPlcffldHdr;
+
+ /**
+ * offset in doc stream to the PLC of field positions in the footnote
+ * subdocument.
+ */
+ U32 fcPlcffldFtn;
+
+ U32 lcbPlcffldFtn;
+
+ /**
+ * offset in doc stream to the PLC of field positions in the annotation
+ * subdocument.
+ */
+ U32 fcPlcffldAtn;
+
+ U32 lcbPlcffldAtn;
+
+ /**
+ * offset in doc stream to the PLC of field positions in the macro subdocument.
+ */
+ U32 fcPlcffldMcr;
+
+ U32 lcbPlcffldMcr;
+
+ /**
+ * offset in document stream of the STTBF that records bookmark names
+ * in the main document
+ */
+ U32 fcSttbfbkmk;
+
+ U32 lcbSttbfbkmk;
+
+ /**
+ * offset in document stream of the PLCF that records the beginning CP
+ * offsets of bookmarks in the main document. See BKF structure definition
+ */
+ U32 fcPlcfbkf;
+
+ U32 lcbPlcfbkf;
+
+ /**
+ * offset in document stream of the PLCF that records the ending CP offsets
+ * of bookmarks recorded in the main document. See the BKL structure definition.
+ */
+ U32 fcPlcfbkl;
+
+ U32 lcbPlcfbkl;
+
+ U32 fcCmds;
+
+ U32 lcbCmds;
+
+ U32 fcPlcmcr;
+
+ U32 lcbPlcmcr;
+
+ U32 fcSttbfmcr;
+
+ U32 lcbSttbfmcr;
+
+ /**
+ * file offset of the printer driver information (names of drivers, port
+ * etc...)
+ */
+ U32 fcPrDrvr;
+
+ /**
+ * count of bytes of the printer driver information (names of drivers,
+ * port etc...)
+ */
+ U32 lcbPrDrvr;
+
+ /**
+ * file offset of the print environment in portrait mode.
+ */
+ U32 fcPrEnvPort;
+
+ /**
+ * count of bytes of the print environment in portrait mode.
+ */
+ U32 lcbPrEnvPort;
+
+ /**
+ * file offset of the print environment in landscape mode.
+ */
+ U32 fcPrEnvLand;
+
+ /**
+ * count of bytes of the print environment in landscape mode.
+ */
+ U32 lcbPrEnvLand;
+
+ /**
+ * file offset of Window Save State data structure. WSS contains dimensions
+ * of document's main text window and the last selection made by Word user.
+ */
+ U32 fcWss;
+
+ /**
+ * count of bytes of WSS. ==0 if unable to store the window state. Should
+ * not be written by third party creators of Word files.
+ */
+ U32 lcbWss;
+
+ /**
+ * file offset of document property data structure.
+ */
+ U32 fcDop;
+
+ /**
+ * count of bytes of document properties.
+ */
+ U32 lcbDop;
+
+ /**
+ * offset to STTBF of associated strings. The strings in this table specify
+ * document summary info and the paths to special documents related to this
+ * document. See documentation of the STTBFASSOC.
+ */
+ U32 fcSttbfAssoc;
+
+ U32 lcbSttbfAssoc;
+
+ /**
+ * file of offset of beginning of information for complex files. Consists
+ * of an encoding of all of the prms quoted by the document followed by the
+ * plcpcd (piece table) for the document.
+ */
+ U32 fcClx;
+
+ /**
+ * count of bytes of complex file information. == 0 if file is non-complex.
+ */
+ U32 lcbClx;
+
+ /**
+ * file offset of page descriptor PLC for footnote subdocument. CPs in
+ * PLC are relative to footnote subdocument. Should not be written by third
+ * party creators of Word files.
+ */
+ U32 fcPlcfpgdFtn;
+
+ /**
+ * count of bytes of page descriptor PLC for footnote subdocument. ==0
+ * if document has not been paginated. The length of the PGD is 8 bytes.
+ */
+ U32 lcbPlcfpgdFtn;
+
+ /**
+ * file offset of the name of the original file.fcAutosaveSource and cbAutosaveSource
+ * should both be 0 if autosave is off.
+ */
+ U32 fcAutosaveSource;
+
+ /**
+ * count of bytes of the name of the original file.
+ */
+ U32 lcbAutosaveSource;
+
+ /**
+ * group of strings recording the names of the owners of annotations stored
+ * in the document
+ */
+ U32 fcGrpStAtnOwners;
+
+ /**
+ * count of bytes of the group of strings
+ */
+ U32 lcbGrpStAtnOwners;
+
+ /**
+ * file offset of the sttbf that records names of bookmarks in the annotation
+ * subdocument
+ */
+ U32 fcSttbfAtnbkmk;
+
+ /**
+ * length in bytes of the sttbf that records names of bookmarks in the
+ * annotation subdocument
+ */
+ U32 lcbSttbfAtnbkmk;
+
+ U16 wSpare4Fib;
+
+ /**
+ * the page number of the lowest numbered page in the document that records
+ * CHPX FKP information
+ */
+ U16 pnChpFirst;
+
+ /**
+ * the page number of the lowest numbered page in the document that records
+ * PAPX FKP information
+ */
+ U16 pnPapFirst;
+
+ /**
+ * count of CHPX FKPs recorded in file. In non-complexfiles if the number
+ * of entries in the plcfbteChpxis less than this, the plcfbteChpxis incomplete.
+ */
+ U16 cpnBteChp;
+
+ /**
+ * count of PAPX FKPs recorded in file. In non-complexfiles if the number
+ * of entries in the plcfbtePapxis less than this, the plcfbtePapxis incomplete.
+ */
+ U16 cpnBtePap;
+
+ /**
+ * file offset of theFDOA (drawn object) PLC for main document. ==0 if
+ * document has no drawn objects. The length of the FDOA is 6 bytes.
+ */
+ U32 fcPlcfdoaMom;
+
+ /**
+ * length in bytes of the FDOA PLC of the main document
+ */
+ U32 lcbPlcfdoaMom;
+
+ /**
+ * file offset of theFDOA (drawn object) PLC for the header document.
+ * ==0 if document has no drawn objects. The length of the FDOA is 6 bytes.
+ */
+ U32 fcPlcfdoaHdr;
+
+ /**
+ * length in bytes of the FDOA PLC of the header document
+ */
+ U32 lcbPlcfdoaHdr;
+
+ U32 fcUnused1;
+
+ U32 lcbUnused1;
+
+ U32 fcUnused2;
+
+ U32 lcbUnused2;
+
+ /**
+ * file offset of BKF (bookmark first) PLC of the annotation subdocument
+ */
+ U32 fcPlcfAtnbkf;
+
+ /**
+ * length in bytes of BKF (bookmark first) PLC of the annotation subdocument
+ */
+ U32 lcbPlcfAtnbkf;
+
+ /**
+ * file offset of BKL (bookmark last) PLC of the annotation subdocument
+ */
+ U32 fcPlcfAtnbkl;
+
+ /**
+ * length in bytes of BKL (bookmark first) PLC of the annotation subdocument
+ */
+ U32 lcbPlcfAtnbkl;
+
+ /**
+ * file offset of PMS (Print Merge State) information block
+ */
+ U32 fcPms;
+
+ /**
+ * length in bytes of PMS
+ */
+ U32 lcbPms;
+
+ /**
+ * file offset of form field Sttbf which contains strings used in form
+ * field dropdown controls
+ */
+ U32 fcFormFldSttbf;
+
+ /**
+ * length in bytes of form field Sttbf
+ */
+ U32 lcbFormFldSttbf;
+
+ /**
+ * file offset of PlcfendRef which points to endnote references in the
+ * main document stream
+ */
+ U32 fcPlcfendRef;
+
+ U32 lcbPlcfendRef;
+
+ /**
+ * file offset of PlcfendRef which points to endnote textin the endnote
+ * document stream which corresponds with the plcfendRef
+ */
+ U32 fcPlcfendTxt;
+
+ U32 lcbPlcfendTxt;
+
+ /**
+ * offset to PLCF of field positions in the endnote subdoc
+ */
+ U32 fcPlcffldEdn;
+
+ U32 lcbPlcffldEdn;
+
+ /**
+ * offset to PLCF of page boundaries in the endnote subdoc.
+ */
+ U32 fcPlcfpgdEdn;
+
+ U32 lcbPlcfpgdEdn;
+
+ U32 fcUnused3;
+
+ U32 lcbUnused3;
+
+ /**
+ * offset to STTBF that records the author abbreviations for authors who
+ * have made revisions in the document.
+ */
+ U32 fcSttbfRMark;
+
+ U32 lcbSttbfRMark;
+
+ /**
+ * offset to STTBF that records caption titles used in the document.
+ */
+ U32 fcSttbfCaption;
+
+ U32 lcbSttbfCaption;
+
+ U32 fcSttbfAutoCaption;
+
+ U32 lcbSttbfAutoCaption;
+
+ /**
+ * offset to PLCF that describes the boundaries of contributing documents
+ * in a master document
+ */
+ U32 fcPlcfwkb;
+
+ U32 lcbPlcfwkb;
+
+ U32 fcUnused4;
+
+ U32 lcbUnused4;
+
+ /**
+ * offset in doc stream of PLCF that records the beginning CP in the text
+ * box subdoc of the text of individual text box entries
+ */
+ U32 fcPlcftxbxTxt;
+
+ U32 lcbPlcftxbxTxt;
+
+ /**
+ * offset in doc stream of the PLCF that records field boundaries recorded
+ * in the textbox subdoc.
+ */
+ U32 fcPlcffldTxbx;
+
+ U32 lcbPlcffldTxbx;
+
+ /**
+ * offset in doc stream of PLCF that records the beginning CP in the header
+ * text box subdoc of the text of individual header text box entries
+ */
+ U32 fcPlcfHdrtxbxTxt;
+
+ U32 lcbPlcfHdrtxbxTxt;
+
+ /**
+ * offset in doc stream of the PLCF that records field boundaries recorded
+ * in the header textbox subdoc.
+ */
+ U32 fcPlcffldHdrTxbx;
+
+ U32 lcbPlcffldHdrTxbx;
+
+ /**
+ * Macro User storage
+ */
+ U32 fcStwUser;
+
+ U32 lcbStwUser;
+
+ U32 fcSttbttmbd;
+
+ U32 lcbSttbttmbd;
+
+ U32 fcUnused;
+
+ U32 lcbUnused;
+
+ U32 fcPgdMother;
+
+ U32 lcbPgdMother;
+
+ U32 fcBkdMother;
+
+ U32 lcbBkdMother;
+
+ U32 fcPgdFtn;
+
+ U32 lcbPgdFtn;
+
+ U32 fcBkdFtn;
+
+ U32 lcbBkdFtn;
+
+ U32 fcPgdEdn;
+
+ U32 lcbPgdEdn;
+
+ U32 fcBkdEdn;
+
+ U32 lcbBkdEdn;
+
+ U32 fcSttbfIntlFld;
+
+ U32 lcbSttbfIntlFld;
+
+ U32 fcRouteSlip;
+
+ U32 lcbRouteSlip;
+
+ U32 fcSttbSavedBy;
+
+ U32 lcbSttbSavedBy;
+
+ U32 fcSttbFnm;
+
+ U32 lcbSttbFnm;
+
+}; // FIB
+
+bool operator==(const FIB &lhs, const FIB &rhs);
+bool operator!=(const FIB &lhs, const FIB &rhs);
+
+
+/**
+ * Field Descriptor (FLD)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct FLD {
+// /**
+// * Creates an empty FLD structure and sets the defaults
+// */
+// FLD();
+// /**
+// * Simply calls read(...)
+// */
+// FLD(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * This method reads the FLD structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * type of field boundary the FLD describes.
+// * 19 field begin mark
+// * 20 field separator
+// * 21 field end mark
+// */
+// U8 ch;
+
+//}; // FLD
+
+//bool operator==(const FLD &lhs, const FLD &rhs);
+//bool operator!=(const FLD &lhs, const FLD &rhs);
+
+
+/**
+ * Line Spacing Descriptor (LSPD)
+ */
+struct LSPD {
+ /**
+ * Creates an empty LSPD structure and sets the defaults
+ */
+ LSPD();
+ /**
+ * Simply calls read(...)
+ */
+ LSPD(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the LSPD structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * see description of sprmPDyaLine in the Sprm Definitions sectionfor
+ * description of the meaning of dyaLine and fMultLinespace fields
+ */
+ U16 dyaLine;
+
+ U16 fMultLinespace;
+
+}; // LSPD
+
+bool operator==(const LSPD &lhs, const LSPD &rhs);
+bool operator!=(const LSPD &lhs, const LSPD &rhs);
+
+
+/**
+ * Window's (METAFILEPICT)
+ */
+struct METAFILEPICT {
+ /**
+ * Creates an empty METAFILEPICT structure and sets the defaults
+ */
+ METAFILEPICT();
+ /**
+ * Simply calls read(...)
+ */
+ METAFILEPICT(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the METAFILEPICT structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * Specifies the mapping mode in which the picture is drawn.
+ */
+ U16 mm;
+
+ /**
+ * Specifies the size of the metafile picture for all modes except the
+ * MM_ISOTROPIC and MM_ANISOTROPIC modes. (For more information about these
+ * modes, see the yExt member.) The x-extent specifies the width of the rectangle
+ * within which the picture is drawn. The coordinates are in units that correspond
+ * to the mapping mode.
+ */
+ U16 xExt;
+
+ /**
+ * Specifies the size of the metafile picture for all modes except the
+ * MM_ISOTROPIC and MM_ANISOTROPIC modes. The y-extent specifies the height
+ * of the rectangle within which the picture is drawn. The coordinates are
+ * in units that correspond to the mapping mode.
+ * <p>For MM_ISOTROPIC and MM_ANISOTROPIC modes, which can be scaled, the
+ * xExt and yExt members contain an optional suggested size in MM_HIMETRIC
+ * units.
+ * <p>For MM_ANISOTROPIC pictures, xExt and yExt can be zero when no suggested
+ * size is supplied. For MM_ISOTROPIC pictures, an aspect ratio must be supplied
+ * even when no suggested size is given. (If a suggested size is given, the
+ * aspect ratio is implied by the size.) To give an aspect ratio without implying
+ * a suggested size, set xExt and yExt to negative values whose ratio is the
+ * appropriate aspect ratio. The magnitude of the negative xExt and yExt values
+ * is ignored; only the ratio is used.
+ */
+ U16 yExt;
+
+ /**
+ * Identifies a memory metafile.
+ */
+ U16 hMF;
+
+}; // METAFILEPICT
+
+bool operator==(const METAFILEPICT &lhs, const METAFILEPICT &rhs);
+bool operator!=(const METAFILEPICT &lhs, const METAFILEPICT &rhs);
+
+
+/**
+ * Embedded Object Properties (OBJHEADER)
+ */
+struct OBJHEADER {
+ /**
+ * Creates an empty OBJHEADER structure and sets the defaults
+ */
+ OBJHEADER();
+ /**
+ * Simply calls read(...)
+ */
+ OBJHEADER(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the OBJHEADER structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * length of object (including this header)
+ */
+ U32 lcb;
+
+ /**
+ * length of this header (for future use)
+ */
+ U16 cbHeader;
+
+ /**
+ * index to clipboard format of object
+ */
+ U16 icf;
+
+}; // OBJHEADER
+
+bool operator==(const OBJHEADER &lhs, const OBJHEADER &rhs);
+bool operator!=(const OBJHEADER &lhs, const OBJHEADER &rhs);
+
+
+/**
+ * Outline LiST Data (OLST)
+ */
+struct OLST {
+ /**
+ * Creates an empty OLST structure and sets the defaults
+ */
+ OLST();
+ /**
+ * Simply calls read(...)
+ */
+ OLST(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ OLST(const U8 *ptr);
+
+ /**
+ * This method reads the OLST structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * an array of 9 ANLV structures describing how heading numbers should
+ * be displayed for each of Word?s 9 outline heading levels
+ */
+ ANLV rganlv[9];
+
+ /**
+ * when ==1, restart heading on section break
+ */
+ U8 fRestartHdr;
+
+ /**
+ * reserved
+ */
+ U8 fSpareOlst2;
+
+ /**
+ * reserved
+ */
+ U8 fSpareOlst3;
+
+ /**
+ * reserved
+ */
+ U8 fSpareOlst4;
+
+ /**
+ * text before/after number
+ */
+ U8 rgch[64];
+
+}; // OLST
+
+bool operator==(const OLST &lhs, const OLST &rhs);
+bool operator!=(const OLST &lhs, const OLST &rhs);
+
+
+/**
+ * Paragraph Properties (PAP)
+ */
+struct PAP : public Shared {
+ /**
+ * Creates an empty PAP structure and sets the defaults
+ */
+ PAP();
+ /**
+ * Simply calls read(...)
+ */
+ PAP(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Attention: This struct allocates memory on the heap
+ */
+ PAP(const PAP &rhs);
+ ~PAP();
+
+ PAP &operator=(const PAP &rhs);
+
+ /**
+ * This method reads the PAP structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * index to style descriptor . This is an index to an STD in the STSH
+ * structure
+ */
+ U16 istd;
+
+ /**
+ * justification code 0left justify
+ * 1center
+ * 2right justify
+ * 3left and right justify
+ */
+ U8 jc;
+
+ /**
+ * keep entire paragraph on one page if possible
+ */
+ U8 fKeep;
+
+ /**
+ * keep paragraph on same page with next paragraph if possible
+ */
+ U8 fKeepFollow;
+
+ /**
+ * start this paragraph on new page
+ */
+ U8 fPageBreakBefore;
+
+ U8 fBrLnAbove:1;
+
+ U8 fBrLnBelow:1;
+
+ /**
+ * reserved
+ */
+ U8 fUnused:2;
+
+ /**
+ * vertical position code. Specifies coordinate frame to use when paragraphs
+ * are absolutely positioned.
+ * 0 vertical position coordinates are relative to margin
+ * 1 coordinates are relative to page
+ * 2 coordinates are relative to text.This means: relative to where the
+ * next non-APO text would have been placed if this APO did not exist.
+ */
+ U8 pcVert:2;
+
+ /**
+ * horizontal position code. Specifies coordinate frame to use when paragraphs
+ * are absolutely positioned.
+ * 0 horiz. position coordinates are relative to column.
+ * 1 coordinates are relative to margin
+ * 2 coordinates are relative to page
+ */
+ U8 pcHorz:2;
+
+ /**
+ * rectangle border codes (the brcp and brcl fields have been superceded
+ * by the newly defined brcLeft, brcTop, etc. fields. They remain in the PAP
+ * for compatibility with MacWord 3.0)
+ * 0 none
+ * 1 border above
+ * 2 border below
+ * 15 box around
+ * 16 bar to left of paragraph
+ */
+ U8 brcp;
+
+ /**
+ * border line style
+ * 0 single
+ * 1 thick
+ * 2 double
+ * 3 shadow
+ */
+ U8 brcl;
+
+ /**
+ * reserved
+ */
+ U8 unused9;
+
+ /**
+ * auto list numbering level (0 = nothing)
+ */
+ U8 nLvlAnm;
+
+ /**
+ * no line numbering for this para. (makes this an exception to the section
+ * property of line numbering)
+ */
+ U8 fNoLnn;
+
+ /**
+ * when 1, paragraph is a side by side paragraph
+ */
+ U8 fSideBySide;
+
+ /**
+ * indent from right margin (signed).
+ */
+ S16 dxaRight;
+
+ /**
+ * indent from left margin (signed)
+ */
+ S16 dxaLeft;
+
+ /**
+ * first line indent; signed number relative to dxaLeft
+ */
+ S16 dxaLeft1;
+
+ /**
+ * line spacing descriptor
+ */
+ LSPD lspd;
+
+ /**
+ * vertical spacing before paragraph (unsigned)
+ */
+ U16 dyaBefore;
+
+ /**
+ * vertical spacing after paragraph (unsigned)
+ */
+ U16 dyaAfter;
+
+ /**
+ * height of current paragraph.
+ */
+ PHE phe;
+
+ /**
+ * when 1, text in paragraph may be auto hyphenated
+ */
+ U8 fAutoHyph;
+
+ /**
+ * when 1, Word will prevent widowed lines in this paragraph from being
+ * placed at the beginning of a page
+ */
+ U8 fWidowControl;
+
+ /**
+ * when 1, paragraph is contained in a table row
+ */
+ U8 fInTable;
+
+ /**
+ * when 1, paragraph consists only of the row mark special character and
+ * marks the end of a table row.
+ */
+ U8 fTtp;
+
+ /**
+ * used internally by Word
+ */
+ U16 ptap;
+
+ /**
+ * when positive, is the horizontal distance from the reference frame
+ * specified by pap.pcHorz. 0 means paragraph is positioned at the left with
+ * respect to the refence frame specified by pcHorz. Certain negative values
+ * have special meaning:
+ * -4 paragraph centered horizontally within reference frame
+ * -8 paragraph adjusted right within reference frame
+ * -12 paragraph placed immediately inside of reference frame
+ * -16 paragraph placed immediately outside of reference frame
+ */
+ S16 dxaAbs;
+
+ /**
+ * when positive, is the vertical distance from the reference frame specified
+ * by pap.pcVert. 0 means paragraph's y-position is unconstrained. . Certain
+ * negative values have special meaning:
+ * -4 paragraph is placed at top of reference frame
+ * -8 paragraph is centered vertically within reference frame
+ * -12 paragraph is placed at bottom of reference frame.
+ */
+ S16 dyaAbs;
+
+ /**
+ * when not == 0, paragraph is constrained to be dxaWidth wide, independent
+ * of current margin or column setings.
+ */
+ U16 dxaWidth;
+
+ /**
+ * specification for border above paragraph
+ */
+ BRC brcTop;
+
+ /**
+ * specification for border to the left of paragraph
+ */
+ BRC brcLeft;
+
+ /**
+ * specification for border below paragraph
+ */
+ BRC brcBottom;
+
+ /**
+ * specification for border to the right of paragraph
+ */
+ BRC brcRight;
+
+ /**
+ * specification of border to place between conforming paragraphs. Two
+ * paragraphs conform when both have borders, their brcLeft and brcRight matches,
+ * their widths are the same, theyboth belong to tables or both do not, and
+ * have the same absolute positioning props.
+ */
+ BRC brcBetween;
+
+ /**
+ * specification of border to place on outside of text when facing pages
+ * are to be displayed.
+ */
+ BRC brcBar;
+
+ /**
+ * horizontal distance to be maintained between an absolutely positioned
+ * paragraph and any non-absolute positioned text
+ */
+ U16 dxaFromText;
+
+ /**
+ * vertical distance to be maintained between an absolutely positioned
+ * paragraph and any non-absolute positioned text
+ */
+ U16 dyaFromText;
+
+ /**
+ * Wrap Code for absolute objects
+ */
+ U8 wr;
+
+ /**
+ * when 1, paragraph may not be editted
+ */
+ U8 fLocked;
+
+ /**
+ * height of abs obj; 0 == Auto
+ */
+ U16 dyaHeight:15;
+
+ /**
+ * 0 = Exact, 1 = At Least
+ */
+ U16 fMinHeight:1;
+
+ /**
+ * shading
+ */
+ SHD shd;
+
+ /**
+ * drop cap specifier (see DCS definition)
+ */
+ DCS dcs;
+
+ /**
+ * autonumber list descriptor (see ANLD definition)
+ */
+ ANLD anld;
+
+ /**
+ * number of tabs stops defined for paragraph. Must be >= 0 and &lt;=
+ * 50.
+ */
+ U16 itbdMac;
+
+ /**
+ * array of positions of itbdMac tab stops. itbdMax == 50
+ */
+ U16 *rgdxaTab; // U16 rgdxaTab[itbdMac];
+
+ /**
+ * array of itbdMac tab descriptors
+ */
+ U8 *rgtbd; // U8 rgtbd[itbdMac];
+
+private:
+ void clearInternal();
+
+}; // PAP
+
+bool operator==(const PAP &lhs, const PAP &rhs);
+bool operator!=(const PAP &lhs, const PAP &rhs);
+
+
+/**
+ * Paragraph Property Exceptions (PAPX)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct PAPX {
+// /**
+// * Creates an empty PAPX structure and sets the defaults
+// */
+// PAPX();
+// /**
+// * Simply calls read(...)
+// */
+// PAPX(OLEStreamReader *stream, bool preservePos=false);
+// /**
+// * Attention: This struct allocates memory on the heap
+// */
+// PAPX(const PAPX &rhs);
+// ~PAPX();
+
+// PAPX &operator=(const PAPX &rhs);
+
+// /**
+// * This method reads the PAPX structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * count of words of following data in PAPX. The first byte of a PAPX
+// * is a count of words when PAPX is stored in an FKP. Count of words is used
+// * because PAPX in an FKP can contain paragraph and table sprms.
+// */
+// U8 cw;
+
+// /**
+// * count of bytes of following data in PAPX. The first byte of a PAPX
+// * is a count of bytes when a PAPX is stored in a STSH. Count of bytes is
+// * used because only paragraph sprms are stored in a STSH PAPX.
+// */
+// U8 cb;
+
+// /**
+// * index to style descriiptor of the style from which the paragraph inherits
+// * its paragraph and character properties
+// */
+// U8 istd;
+
+// /**
+// * a list of the sprms that encode the differences between PAP for a paragraph
+// * and the PAP for the style used. When a paragraph bound is also the end
+// * of a table row, the PAPX also contains a list of table sprms which express
+// * the difference of table row's TAP from an empty TAP that has been cleared
+// * to zeros. The table sprms are recorded in the list after all of the paragraph
+// * sprms.See Sprms definitions for list of sprms that are used in PAPXs.
+// */
+// U8 *grpprl; // U8 grpprl[];
+
+//private:
+// void clearInternal();
+
+//}; // PAPX
+
+//bool operator==(const PAPX &lhs, const PAPX &rhs);
+//bool operator!=(const PAPX &lhs, const PAPX &rhs);
+
+
+/**
+ * Formatted Disk Page for PAPXs (PAPXFKP)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct PAPXFKP {
+// /**
+// * Creates an empty PAPXFKP structure and sets the defaults
+// */
+// PAPXFKP();
+// /**
+// * Simply calls read(...)
+// */
+// PAPXFKP(OLEStreamReader *stream, bool preservePos=false);
+// /**
+// * Attention: This struct allocates memory on the heap
+// */
+// PAPXFKP(const PAPXFKP &rhs);
+// ~PAPXFKP();
+
+// PAPXFKP &operator=(const PAPXFKP &rhs);
+
+// /**
+// * This method reads the PAPXFKP structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * Each FC is the limit FC of a paragraph (ie. points to the next character
+// * past an end of paragraph mark). There will be fkp.crun+1 recorded in the
+// * FKP.
+// */
+// FC *rgfc; // FC rgfc[fkp.crun+1];
+
+// /**
+// * an array of the BX data structure. The ith BX entry in the array describes
+// * the paragraph beginning at fkp.rgfc[i]. The BX is a seven byte data structure.
+// * The first byte of each BX is the word offset of thePAPX recorded for the
+// * paragraph corresponding to this BX. ..If the byte stored is 0, this represents
+// * a 1 line paragraph 15 pixels high with Normal style (stc == 0) whose column
+// * width is 7980 dxas.
+// * <p>The last six bytes of the BX is a PHE structure which stores the current
+// * paragraph height for the paragraph corresponding to the BX. If a plcfphe
+// * has an entry that maps to the FC for this paragraph, that entry?s PHE overides
+// * the PHE stored in the FKP.
+// */
+// BX *rgbx; // BX rgbx[fkp.crun];
+
+// /**
+// * As new runs/paragraphs are recorded in the FKP,unused space is reduced
+// * by 11 if CHPX/PAPX is already recorded and is reduced by11+sizeof(PAPX)
+// * if property is not already recorded.
+// */
+// U8 *unusedSpace; // U8 unusedSpace[];
+
+// /**
+// * grppapx consists of all of the PAPXs stored in FKP concatenated end
+// * to end. Each PAPX begins with a count of words which records its length
+// * padded to a word boundary.
+// */
+// U8 *grppapx; // U8 grppapx[];
+
+// /**
+// * count of paragraphs for PAPX FKP.
+// */
+// U8 crun;
+
+//private:
+// void clearInternal();
+
+//}; // PAPXFKP
+
+//bool operator==(const PAPXFKP &lhs, const PAPXFKP &rhs);
+//bool operator!=(const PAPXFKP &lhs, const PAPXFKP &rhs);
+
+
+/**
+ * Piece Descriptor (PCD)
+ */
+struct PCD {
+ /**
+ * Creates an empty PCD structure and sets the defaults
+ */
+ PCD();
+ /**
+ * Simply calls read(...)
+ */
+ PCD(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ PCD(const U8 *ptr);
+
+ /**
+ * This method reads the PCD structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * when 1, means that piece contains no end of paragraph marks.
+ */
+ U16 fNoParaLast:1;
+
+ /**
+ * used internally by Word
+ */
+ U16 fPaphNil:1;
+
+ /**
+ * used internally by Word
+ */
+ U16 fCopied:1;
+
+ U16 unused0_3:5;
+
+ /**
+ * used internally by Word
+ */
+ U16 fn:8;
+
+ /**
+ * file offset of beginning of piece. The size of the ithpiece can be
+ * determined by subtracting rgcp[i] of the containing plcfpcd from its rgcp[i+1].
+ */
+ U32 fc;
+
+ /**
+ * contains either a single sprm or else an index number of the grpprl
+ * which contains the sprms that modify the properties of the piece.
+ */
+ PRM prm;
+
+}; // PCD
+
+bool operator==(const PCD &lhs, const PCD &rhs);
+bool operator!=(const PCD &lhs, const PCD &rhs);
+
+
+/**
+ * Page Descriptor (PGD)
+ */
+struct PGD {
+ /**
+ * Creates an empty PGD structure and sets the defaults
+ */
+ PGD();
+ /**
+ * Simply calls read(...)
+ */
+ PGD(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the PGD structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ U16 unused0_0:5;
+
+ /**
+ * redefine fEmptyPage and fAllFtn. true when blank page or footnote only
+ * page
+ */
+ U16 fGhost:2;
+
+ U16 unused0_7:9;
+
+ /**
+ * 1 only when footnote is continued from previous page
+ */
+ U16 fContinue:1;
+
+ /**
+ * 1 when page is dirty (ie. pagination cannot be trusted)
+ */
+ U16 fUnk:1;
+
+ /**
+ * 1 when right hand side page
+ */
+ U16 fRight:1;
+
+ /**
+ * 1 when page number must be reset to 1.
+ */
+ U16 fPgnRestart:1;
+
+ /**
+ * 1 when section break forced page to be empty.
+ */
+ U16 fEmptyPage:1;
+
+ /**
+ * 1 when page contains nothing but footnotes
+ */
+ U16 fAllFtn:1;
+
+ U16 fColOnly:1;
+
+ U16 fTableBreaks:1;
+
+ U16 fMarked:1;
+
+ U16 fColumnBreaks:1;
+
+ U16 fTableHeader:1;
+
+ U16 fNewPage:1;
+
+ /**
+ * section break code
+ */
+ U16 bkc:4;
+
+ /**
+ * line number of first line, -1 if no line numbering
+ */
+ U16 lnn;
+
+ /**
+ * page number as printed
+ */
+ U16 pgn;
+
+}; // PGD
+
+bool operator==(const PGD &lhs, const PGD &rhs);
+bool operator!=(const PGD &lhs, const PGD &rhs);
+
+
+/**
+ * Picture Descriptor (PICF)
+ */
+struct PICF : public Shared {
+ /**
+ * Creates an empty PICF structure and sets the defaults
+ */
+ PICF();
+ /**
+ * Simply calls read(...)
+ */
+ PICF(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the PICF structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * number of bytes in the PIC structure plus size of following picture
+ * data which may be a Window's metafile, a bitmap, or the filename of a TIFF
+ * file.
+ */
+ U32 lcb;
+
+ /**
+ * number of bytes in the PIC (to allow for future expansion).
+ */
+ U16 cbHeader;
+
+ /**
+ * If a Windows metafiles is stored immediatelly followingthe PIC structure,
+ * the mfp is a Window's METAFILEPICT structure. When the data immediately
+ * following the PIC is aTIFF filename, mfp.mm == 98. If a bitmap is stored
+ * after the pic,mfp.mm == 99
+ * When the PIC describes a bitmap, mfp.xExt is the width of the bitmap
+ * in pixels and mfp.yExt is the height of the bitmap in pixels..
+ */
+ METAFILEPICT mfp;
+
+ /**
+ * Window's bitmap structure when PIC describes a BITMAP. rect for window
+ * origin and extents whenmetafile is stored -- ignored if 0
+ */
+ U8 bm_rcWinMF[14];
+
+ /**
+ * horizontalmeasurement in twips of therectangle the picture should be
+ * imaged within.
+ */
+ U16 dxaGoal;
+
+ /**
+ * verticalmeasurement in twips of therectangle the picture should be
+ * imaged within. when scaling bitmaps, dxaGoal and dyaGoal may be ignored
+ * if the operation would cause the bitmap to shrink or grow by anon -power-of-two
+ * factor
+ */
+ U16 dyaGoal;
+
+ /**
+ * horizontal scaling factor supplied by user expressedin .001% units.
+ */
+ U16 mx;
+
+ /**
+ * vertical scaling factor supplied by user expressed in .001% units.
+ * for all of the Crop values, a positive measurement means the specified
+ * border has been moved inward from its original setting and a negative measurement
+ * means the borderhas been moved outward from its original setting.
+ */
+ U16 my;
+
+ /**
+ * the amount the picture has been cropped on the left in twips.
+ */
+ U16 dxaCropLeft;
+
+ /**
+ * the amount the picture has been cropped on the top in twips.
+ */
+ U16 dyaCropTop;
+
+ /**
+ * the amount the picture has been cropped on the right in twips.
+ */
+ U16 dxaCropRight;
+
+ /**
+ * the amount the picture has been cropped on the bottom in twips.
+ */
+ U16 dyaCropBottom;
+
+ /**
+ * Obsolete, superseded by brcTop, etc.In WinWord 1.x, it was the type
+ * of border to place around picture
+ * 0 single
+ * 1 thick
+ * 2 double
+ * 3 shadow
+ */
+ U16 brcl:4;
+
+ /**
+ * picture consists of a single frame
+ */
+ U16 fFrameEmpty:1;
+
+ /**
+ * ==1, when picture is just a bitmap
+ */
+ U16 fBitmap:1;
+
+ /**
+ * ==1, when picture is an active OLE object
+ */
+ U16 fDrawHatch:1;
+
+ /**
+ * ==1, when picture is just an error message
+ */
+ U16 fError:1;
+
+ /**
+ * bits per pixel
+ * 0 unknown
+ * 1 monochrome
+ * 4
+ */
+ U16 bpp:8;
+
+ /**
+ * specification for border above picture
+ */
+ BRC brcTop;
+
+ /**
+ * specification for border to the left of picture
+ */
+ BRC brcLeft;
+
+ /**
+ * specification for border below picture
+ */
+ BRC brcBottom;
+
+ /**
+ * specification for border to the right of picture
+ */
+ BRC brcRight;
+
+ /**
+ * horizontal offset of hand annotation origin
+ */
+ U16 dxaOrigin;
+
+ /**
+ * vertical offset of hand annotation origin
+ */
+ U16 dyaOrigin;
+
+}; // PICF
+
+bool operator==(const PICF &lhs, const PICF &rhs);
+bool operator!=(const PICF &lhs, const PICF &rhs);
+
+
+/**
+ * Plex of CPs stored in File (PLCF)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct PLCF {
+// /**
+// * Creates an empty PLCF structure and sets the defaults
+// */
+// PLCF();
+// /**
+// * Simply calls read(...)
+// */
+// PLCF(OLEStreamReader *stream, bool preservePos=false);
+// /**
+// * Attention: This struct allocates memory on the heap
+// */
+// PLCF(const PLCF &rhs);
+// ~PLCF();
+
+// PLCF &operator=(const PLCF &rhs);
+
+// /**
+// * This method reads the PLCF structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * given that the size of PLCF is cb and the size of the structure stored
+// * in plc is cbStruct, then the number of structure instances stored in PLCF,
+// * iMac is given by (cb -4)/(4 + cbStruct) The number of FCs stored in the
+// * PLCF will be iMac + 1.
+// */
+// FC *rgfc; // FC rgfc[];
+
+// struct *rgstruct; // struct rgstruct[];
+
+//private:
+// void clearInternal();
+
+//}; // PLCF
+
+//bool operator==(const PLCF &lhs, const PLCF &rhs);
+//bool operator!=(const PLCF &lhs, const PLCF &rhs);
+
+
+/**
+ * Section Descriptor (SED)
+ */
+struct SED {
+ /**
+ * Creates an empty SED structure and sets the defaults
+ */
+ SED();
+ /**
+ * Simply calls read(...)
+ */
+ SED(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the SED structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * runtime flag, indicates whether orientation should be changed before
+ * printing. 0 indicates no change, 1 indicates orientation change.
+ */
+ U16 fSwap:1;
+
+ /**
+ * used internally by Windows Word
+ */
+ U16 fUnk:1;
+
+ /**
+ * used internally by Windows Word
+ */
+ U16 fn:14;
+
+ /**
+ * file offset to beginning of SEPX stored for section. If sed.fcSepx==
+ * 0xFFFFFFFF, the section properties for the section are equal to the standard
+ * SEP (see SEP definition).
+ */
+ U32 fcSepx;
+
+ /**
+ * used internally by Windows Word
+ */
+ U16 fnMpr;
+
+ /**
+ * points to offset in FC space where the Macintosh Print Record for a
+ * document created on a Mac will be stored
+ */
+ U32 fcMpr;
+
+}; // SED
+
+bool operator==(const SED &lhs, const SED &rhs);
+bool operator!=(const SED &lhs, const SED &rhs);
+
+
+/**
+ * Section Properties (SEP)
+ */
+struct SEP : public Shared {
+ /**
+ * Creates an empty SEP structure and sets the defaults
+ */
+ SEP();
+ /**
+ * Simply calls read(...)
+ */
+ SEP(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the SEP structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * break code:
+ * 0 No break
+ * 1 New column
+ * 2 New page
+ * 3 Even page
+ * 4 Odd page
+ */
+ U8 bkc;
+
+ /**
+ * set to 1 when a title page is to be displayed
+ */
+ U8 fTitlePage;
+
+ /**
+ * number of columns in section - 1.
+ */
+ U16 ccolM1;
+
+ /**
+ * distance that will be maintained between columns
+ */
+ U16 dxaColumns;
+
+ /**
+ * only for Mac compatability, used only during open, when 1, sep.dxaPgn
+ * and sep.dyaPgn are valid page number locations
+ */
+ U8 fAutoPgn;
+
+ /**
+ * page number format code:
+ * 0Arabic numbering
+ * 1 Upper case Roman
+ * 2 Lower case Roman
+ * 3 Upper case Letter
+ * 4 Lower case letter
+ * 5 Ordinal
+ */
+ U8 nfcPgn;
+
+ /**
+ * user specified starting page number.
+ */
+ U16 pgnStart;
+
+ /**
+ * set to 1, when a section in a locked document is unlocked
+ */
+ U8 fUnlocked;
+
+ /**
+ * chapter number separator for page numbers
+ */
+ U8 cnsPgn;
+
+ /**
+ * set to 1 when page numbering should be restarted at the beginning of
+ * this section
+ */
+ U8 fPgnRestart;
+
+ /**
+ * when 1, footnotes placed at end of section. When 0, footnotes are placed
+ * at bottom of page.
+ */
+ U8 fEndNote;
+
+ /**
+ * line numbering code:
+ * 0 Per page
+ * 1 Restart
+ * 2 Continue
+ */
+ U8 lnc;
+
+ /**
+ * specification of which headers and footers are included in this section.
+ * See explanation inHeaders and Footers topic.
+ */
+ U8 grpfIhdt;
+
+ /**
+ * if 0, no line numbering, otherwise this is the line number modulus
+ * (e.g. if nLnnMod is 5, line numbers appear on line 5, 10, etc.)
+ */
+ U16 nLnnMod;
+
+ /**
+ * distance of
+ */
+ U16 dxaLnn;
+
+ /**
+ * y position of top header measured from top edge of page.
+ */
+ U16 dyaHdrTop;
+
+ /**
+ * y position of top header measured from top edge of page.
+ */
+ U16 dyaHdrBottom;
+
+ /**
+ * when fAutoPgn ==1, gives the x position of auto page number on page
+ * in twips (for Mac compatabilty only)
+ */
+ U16 dxaPgn;
+
+ /**
+ * when fAutoPgn ==1, gives the y position of auto page number on page
+ * in twips (for Mac compatabilty only)
+ */
+ U16 dyaPgn;
+
+ /**
+ * when ==1, draw vertical lines between columns
+ */
+ U8 fLBetween;
+
+ /**
+ * vertical justification code
+ * 0 top justified
+ * 1 centered
+ * 2 fully justified vertically
+ * 3 bottom justified
+ */
+ U8 vjc;
+
+ /**
+ * beginning line number for section
+ */
+ U16 lnnMin;
+
+ /**
+ * orientation of pages in that section.set to 0 when portrait, 1 when
+ * landscape
+ */
+ U8 dmOrientPage;
+
+ /**
+ * heading number level for page number
+ */
+ U8 iHeadingPgn;
+
+ /**
+ * width of page default value is 12240 twips
+ */
+ U16 xaPage;
+
+ /**
+ * height of page default value is 15840 twips
+ */
+ U16 yaPage;
+
+ /**
+ * left margin default value is 1800 twips
+ */
+ U16 dxaLeft;
+
+ /**
+ * right margin default value is 1800 twips
+ */
+ U16 dxaRight;
+
+ /**
+ * top margin default value is 1440 twips
+ */
+ U16 dyaTop;
+
+ /**
+ * bottom margin default value is 1440 twips
+ */
+ U16 dyaBottom;
+
+ /**
+ * gutter width default value is 0 twips
+ */
+ U16 dzaGutter;
+
+ /**
+ * bin number supplied from windows printer driver indicating which bin
+ * the first page of section will be printed.
+ */
+ U16 dmBinFirst;
+
+ /**
+ * bin number supplied from windows printer driver indicating which bin
+ * the pages other than the first page of section will be printed.
+ */
+ U16 dmBinOther;
+
+ /**
+ * dmPaper code for form selected by user
+ */
+ U16 dmPaperReq;
+
+ /**
+ * when == 1, columns are evenly spaced. Default value is 1.
+ */
+ U8 fEvenlySpaced;
+
+ /**
+ * reserved
+ */
+ U8 unused55;
+
+ /**
+ * used internally by Word
+ */
+ U16 dxaColumnWidth;
+
+ /**
+ * array of 89 Xas that determine bounds of irregular width columns
+ */
+ U16 rgdxaColumnWidthSpacing[89];
+
+ /**
+ * multilevel autonumbering list data (see OLST definition)
+ */
+ OLST olstAnm;
+
+}; // SEP
+
+bool operator==(const SEP &lhs, const SEP &rhs);
+bool operator!=(const SEP &lhs, const SEP &rhs);
+
+
+/**
+ * Section Property Exceptions (SEPX)
+ */
+struct SEPX {
+ /**
+ * Creates an empty SEPX structure and sets the defaults
+ */
+ SEPX();
+ /**
+ * Simply calls read(...)
+ */
+ SEPX(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Attention: This struct allocates memory on the heap
+ */
+ SEPX(const SEPX &rhs);
+ ~SEPX();
+
+ SEPX &operator=(const SEPX &rhs);
+
+ /**
+ * This method reads the SEPX structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * count of bytes in remainder of SEPX.
+ */
+ U8 cb;
+
+ /**
+ * list of sprms that encodes the differences between the properties of
+ * a section and Word's default section properties.
+ */
+ U8 *grpprl; // U8 grpprl[];
+
+private:
+ void clearInternal();
+
+}; // SEPX
+
+bool operator==(const SEPX &lhs, const SEPX &rhs);
+bool operator!=(const SEPX &lhs, const SEPX &rhs);
+
+
+/**
+ * STyleSHeet Information (STSHI)
+ */
+struct STSHI {
+ /**
+ * Creates an empty STSHI structure and sets the defaults
+ */
+ STSHI();
+ /**
+ * Simply calls read(...)
+ */
+ STSHI(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the STSHI structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * Count of styles in stylesheet
+ */
+ U16 cstd;
+
+ /**
+ * Length of STD Base as stored in a file
+ */
+ U16 cbSTDBaseInFile;
+
+ /**
+ * Are built-in stylenames stored?
+ */
+ U16 fStdStylenamesWritten:1;
+
+ /**
+ * Spare flags
+ */
+ U16 unused4_2:15;
+
+ /**
+ * Max sti known when this file was written
+ */
+ U16 stiMaxWhenSaved;
+
+ /**
+ * How many fixed-index istds are there?
+ */
+ U16 istdMaxFixedWhenSaved;
+
+ /**
+ * Current version of built-in stylenames
+ */
+ U16 nVerBuiltInNamesWhenSaved;
+
+ /**
+ * ftc used by StandardChpStsh for this document
+ */
+ U16 ftcStandardChpStsh;
+
+}; // STSHI
+
+bool operator==(const STSHI &lhs, const STSHI &rhs);
+bool operator!=(const STSHI &lhs, const STSHI &rhs);
+
+
+
+} // namespace Word95
+
+} // namespace wvWare
+
+#endif // WORD95_GENERATED_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/word95_helper.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/word95_helper.cpp
new file mode 100644
index 00000000..5f094821
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/word95_helper.cpp
@@ -0,0 +1,453 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001 S.R.Haque <[email protected]>
+ Copyright (C) 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "word95_helper.h"
+#include "word95_generated.h"
+#include "olestream.h"
+#include "styles.h"
+
+#include "wvlog.h"
+
+namespace wvWare
+{
+
+namespace Word95
+{
+
+namespace SPRM
+{
+
+typedef enum {
+ sprmNoop = 0,
+ sprmPIstd = 2,
+ sprmPIstdPermute = 3,
+ sprmPIncLvl = 4,
+ sprmPJc = 5,
+ sprmPFSideBySide = 6,
+ sprmPFKeep = 7,
+ sprmPFKeepFollow = 8,
+ sprmPFPageBreakBefore = 9,
+ sprmPBrcl = 10,
+ sprmPBrcp = 11,
+ sprmPAnld = 12,
+ sprmPNLvlAnm = 13,
+ sprmPFNoLineNumb = 14,
+ sprmPChgTabsPapx = 15,
+ sprmPDxaRight = 16,
+ sprmPDxaLeft = 17,
+ sprmPNest = 18,
+ sprmPDxaLeft1 = 19,
+ sprmPDyaLine = 20,
+ sprmPDyaBefore = 21,
+ sprmPDyaAfter = 22,
+ sprmPChgTabs = 23,
+ sprmPFInTable = 24,
+ sprmPFTtp = 25,
+ sprmPDxaAbs = 26,
+ sprmPDyaAbs = 27,
+ sprmPDxaWidth = 28,
+ sprmPPc = 29,
+ sprmPBrcTop10 = 30,
+ sprmPBrcLeft10 = 31,
+ sprmPBrcBottom10 = 32,
+ sprmPBrcRight10 = 33,
+ sprmPBrcBetween10 = 34,
+ sprmPBrcBar10 = 35,
+ sprmPFromText10 = 36,
+ sprmPWr = 37,
+ sprmPBrcTop = 38,
+ sprmPBrcLeft = 39,
+ sprmPBrcBottom = 40,
+ sprmPBrcRight = 41,
+ sprmPBrcBetween = 42,
+ sprmPBrcBar = 43,
+ sprmPFNoAutoHyph = 44,
+ sprmPWHeightAbs = 45,
+ sprmPDcs = 46,
+ sprmPShd = 47,
+ sprmPDyaFromText = 48,
+ sprmPDxaFromText = 49,
+ sprmPFLocked = 50,
+ sprmPFWidowControl = 51,
+ sprmPRuler = 52,
+ sprmCFStrikeRM = 65,
+ sprmCFRMark = 66,
+ sprmCFFldVanish = 67,
+ sprmCPicLocation = 68,
+ sprmCIbstRMark = 69,
+ sprmCDttmRMark = 70,
+ sprmCFData = 71,
+ sprmCRMReason = 72,
+ sprmCChse = 73,
+ sprmCSymbol = 74,
+ sprmCFOle2 = 75,
+ sprmCIstd = 80,
+ sprmCIstdPermute = 81,
+ sprmCDefault = 82,
+ sprmCPlain = 83,
+ sprmCFBold = 85,
+ sprmCFItalic = 86,
+ sprmCFStrike = 87,
+ sprmCFOutline = 88,
+ sprmCFShadow = 89,
+ sprmCFSmallCaps = 90,
+ sprmCFCaps = 91,
+ sprmCFVanish = 92,
+ sprmCFtc = 93,
+ sprmCKul = 94,
+ sprmCSizePos = 95,
+ sprmCDxaSpace = 96,
+ sprmCLid = 97,
+ sprmCIco = 98,
+ sprmCHps = 99,
+ sprmCHpsInc = 100,
+ sprmCHpsPos = 101,
+ sprmCHpsPosAdj = 102,
+ sprmCMajority = 103,
+ sprmCIss = 104,
+ sprmCHpsNew50 = 105,
+ sprmCHpsInc1 = 106,
+ sprmCHpsKern = 107,
+ sprmCMajority50 = 108,
+ sprmCHpsMul = 109,
+ sprmCCondHyhen = 110,
+ sprmCFSpec = 117,
+ sprmCFObj = 118,
+ sprmPicBrcl = 119,
+ sprmPicScale = 120,
+ sprmPicBrcTop = 121,
+ sprmPicBrcLeft = 122,
+ sprmPicBrcBottom = 123,
+ sprmPicBrcRight = 124,
+ sprmSScnsPgn = 131,
+ sprmSiHeadingPgn = 132,
+ sprmSOlstAnm = 133,
+ sprmSDxaColWidth = 136,
+ sprmSDxaColSpacing = 137,
+ sprmSFEvenlySpaced = 138,
+ sprmSFProtected = 139,
+ sprmSDmBinFirst = 140,
+ sprmSDmBinOther = 141,
+ sprmSBkc = 142,
+ sprmSFTitlePage = 143,
+ sprmSCcolumns = 144,
+ sprmSDxaColumns = 145,
+ sprmSFAutoPgn = 146,
+ sprmSNfcPgn = 147,
+ sprmSDyaPgn = 148,
+ sprmSDxaPgn = 149,
+ sprmSFPgnRestart = 150,
+ sprmSFEndnote = 151,
+ sprmSLnc = 152,
+ sprmSGprfIhdt = 153,
+ sprmSNLnnMod = 154,
+ sprmSDxaLnn = 155,
+ sprmSDyaHdrTop = 156,
+ sprmSDyaHdrBottom = 157,
+ sprmSLBetween = 158,
+ sprmSVjc = 159,
+ sprmSLnnMin = 160,
+ sprmSPgnStart = 161,
+ sprmSBOrientation = 162,
+ sprmSBCustomize = 163,
+ sprmSXaPage = 164,
+ sprmSYaPage = 165,
+ sprmSDxaLeft = 166,
+ sprmSDxaRight = 167,
+ sprmSDyaTop = 168,
+ sprmSDyaBottom = 169,
+ sprmSDzaGutter = 170,
+ sprmSDMPaperReq = 171,
+ sprmTJc = 182,
+ sprmTDxaLeft = 183,
+ sprmTDxaGapHalf = 184,
+ sprmTFCantSplit = 185,
+ sprmTTableHeader = 186,
+ sprmTTableBorders = 187,
+ sprmTDefTable10 = 188,
+ sprmTDyaRowHeight = 189,
+ sprmTDefTable = 190,
+ sprmTDefTableShd = 191,
+ sprmTTlp = 192,
+ sprmTSetBrc = 193,
+ sprmTInsert = 194,
+ sprmTDelete = 195,
+ sprmTDxaCol = 196,
+ sprmTMerge = 197,
+ sprmTSplit = 198,
+ sprmTSetBrc10 = 199,
+ sprmTSetShd = 200
+} opcodes;
+
+// The length of the SPRM parameter
+U16 determineParameterLength( U8 sprm, const U8* in )
+{
+ switch ( sprm ) {
+ case SPRM::sprmNoop:
+ return 0;
+ case SPRM::sprmPIstd:
+ return 2;
+ case SPRM::sprmPIstdPermute:
+ break; // Variable.
+ case SPRM::sprmPIncLvl:
+ case SPRM::sprmPJc:
+ case SPRM::sprmPFSideBySide:
+ case SPRM::sprmPFKeep:
+ case SPRM::sprmPFKeepFollow:
+ case SPRM::sprmPFPageBreakBefore:
+ case SPRM::sprmPBrcl:
+ case SPRM::sprmPBrcp:
+ return 1;
+ case SPRM::sprmPAnld:
+ break; // Variable.
+ case SPRM::sprmPNLvlAnm:
+ case SPRM::sprmPFNoLineNumb:
+ return 1;
+ case SPRM::sprmPChgTabsPapx:
+ break; // Variable.
+ case SPRM::sprmPDxaRight:
+ return 2;
+ case SPRM::sprmPDxaLeft:
+ case SPRM::sprmPNest:
+ case SPRM::sprmPDxaLeft1:
+ return 2;
+ case SPRM::sprmPDyaLine:
+ return 4;
+ case SPRM::sprmPDyaBefore:
+ case SPRM::sprmPDyaAfter:
+ return 2;
+ case SPRM::sprmPChgTabs:
+ if ( *in == 255 ) {
+ U8 itbdDelMax = in[1];
+ U8 itbdAddMax = in[1 + itbdDelMax * 4];
+ return 1 + itbdDelMax * 4 + itbdAddMax * 3;
+ }
+ else
+ return *in + 1;
+ case SPRM::sprmPFInTable:
+ case SPRM::sprmPFTtp:
+ return 1;
+ case SPRM::sprmPDxaAbs:
+ case SPRM::sprmPDyaAbs:
+ case SPRM::sprmPDxaWidth:
+ return 2;
+ case SPRM::sprmPPc:
+ return 1;
+ case SPRM::sprmPBrcTop10:
+ case SPRM::sprmPBrcLeft10:
+ case SPRM::sprmPBrcBottom10:
+ case SPRM::sprmPBrcRight10:
+ case SPRM::sprmPBrcBetween10:
+ case SPRM::sprmPBrcBar10:
+ case SPRM::sprmPFromText10:
+ return 2;
+ case SPRM::sprmPWr:
+ return 1;
+ case SPRM::sprmPBrcTop:
+ case SPRM::sprmPBrcLeft:
+ case SPRM::sprmPBrcBottom:
+ case SPRM::sprmPBrcRight:
+ case SPRM::sprmPBrcBetween:
+ case SPRM::sprmPBrcBar:
+ return 2;
+ case SPRM::sprmPFNoAutoHyph:
+ return 1;
+ case SPRM::sprmPWHeightAbs:
+ case SPRM::sprmPDcs:
+ case SPRM::sprmPShd:
+ case SPRM::sprmPDyaFromText:
+ case SPRM::sprmPDxaFromText:
+ return 2;
+ case SPRM::sprmPFLocked:
+ case SPRM::sprmPFWidowControl:
+ return 1;
+ case SPRM::sprmPRuler:
+ break; // Variable.
+ case SPRM::sprmCFStrikeRM:
+ case SPRM::sprmCFRMark:
+ case SPRM::sprmCFFldVanish:
+ return 1;
+ case SPRM::sprmCPicLocation:
+ break; // Variable.
+ case SPRM::sprmCIbstRMark:
+ return 2;
+ case SPRM::sprmCDttmRMark:
+ return 4;
+ case SPRM::sprmCFData:
+ return 1;
+ case SPRM::sprmCRMReason:
+ return 2;
+ case SPRM::sprmCChse:
+ return 3;
+ case SPRM::sprmCSymbol:
+ break; // Variable.
+ case SPRM::sprmCFOle2:
+ return 1;
+ case SPRM::sprmCIstd:
+ return 2;
+ case SPRM::sprmCIstdPermute:
+ case SPRM::sprmCDefault:
+ break; // Variable.
+ case SPRM::sprmCPlain:
+ return 0;
+ case SPRM::sprmCFBold:
+ case SPRM::sprmCFItalic:
+ case SPRM::sprmCFStrike:
+ case SPRM::sprmCFOutline:
+ case SPRM::sprmCFShadow:
+ case SPRM::sprmCFSmallCaps:
+ case SPRM::sprmCFCaps:
+ case SPRM::sprmCFVanish:
+ return 1;
+ case SPRM::sprmCFtc:
+ return 2;
+ case SPRM::sprmCKul:
+ return 1;
+ case SPRM::sprmCSizePos:
+ return 3;
+ case SPRM::sprmCDxaSpace:
+ case SPRM::sprmCLid:
+ return 2;
+ case SPRM::sprmCIco:
+ case SPRM::sprmCHps:
+ case SPRM::sprmCHpsInc:
+ case SPRM::sprmCHpsPos:
+ case SPRM::sprmCHpsPosAdj:
+ return 1;
+ case SPRM::sprmCMajority:
+ break; // Variable.
+ case SPRM::sprmCIss:
+ return 1;
+ case SPRM::sprmCHpsNew50:
+ case SPRM::sprmCHpsInc1:
+ break; // Variable.
+ case SPRM::sprmCHpsKern:
+ return 2;
+ case SPRM::sprmCMajority50:
+ break; // Variable.
+ case SPRM::sprmCHpsMul:
+ case SPRM::sprmCCondHyhen:
+ return 2;
+ case SPRM::sprmCFSpec:
+ case SPRM::sprmCFObj:
+ case SPRM::sprmPicBrcl:
+ return 1;
+ case SPRM::sprmPicScale:
+ break; // Variable.
+ case SPRM::sprmPicBrcTop:
+ case SPRM::sprmPicBrcLeft:
+ case SPRM::sprmPicBrcBottom:
+ case SPRM::sprmPicBrcRight:
+ return 2;
+ case SPRM::sprmSScnsPgn:
+ case SPRM::sprmSiHeadingPgn:
+ return 1;
+ case SPRM::sprmSOlstAnm:
+ break; // Variable.
+ case SPRM::sprmSDxaColWidth:
+ case SPRM::sprmSDxaColSpacing:
+ return 3;
+ case SPRM::sprmSFEvenlySpaced:
+ case SPRM::sprmSFProtected:
+ return 1;
+ case SPRM::sprmSDmBinFirst:
+ case SPRM::sprmSDmBinOther:
+ return 2;
+ case SPRM::sprmSBkc:
+ case SPRM::sprmSFTitlePage:
+ return 1;
+ case SPRM::sprmSCcolumns:
+ case SPRM::sprmSDxaColumns:
+ return 2;
+ case SPRM::sprmSFAutoPgn:
+ case SPRM::sprmSNfcPgn:
+ return 1;
+ case SPRM::sprmSDyaPgn:
+ case SPRM::sprmSDxaPgn:
+ return 2;
+ case SPRM::sprmSFPgnRestart:
+ case SPRM::sprmSFEndnote:
+ case SPRM::sprmSLnc:
+ case SPRM::sprmSGprfIhdt:
+ return 1;
+ case SPRM::sprmSNLnnMod:
+ case SPRM::sprmSDxaLnn:
+ case SPRM::sprmSDyaHdrTop:
+ case SPRM::sprmSDyaHdrBottom:
+ return 2;
+ case SPRM::sprmSLBetween:
+ case SPRM::sprmSVjc:
+ return 1;
+ case SPRM::sprmSLnnMin:
+ case SPRM::sprmSPgnStart:
+ return 2;
+ case SPRM::sprmSBOrientation:
+ case SPRM::sprmSBCustomize:
+ return 1;
+ case SPRM::sprmSXaPage:
+ case SPRM::sprmSYaPage:
+ case SPRM::sprmSDxaLeft:
+ case SPRM::sprmSDxaRight:
+ case SPRM::sprmSDyaTop:
+ case SPRM::sprmSDyaBottom:
+ case SPRM::sprmSDzaGutter:
+ case SPRM::sprmSDMPaperReq:
+ case SPRM::sprmTJc:
+ case SPRM::sprmTDxaLeft:
+ case SPRM::sprmTDxaGapHalf:
+ return 2;
+ case SPRM::sprmTFCantSplit:
+ case SPRM::sprmTTableHeader:
+ return 1;
+ case SPRM::sprmTTableBorders:
+ return 12;
+ case SPRM::sprmTDefTable10:
+ return readU16(in) + 1;
+ case SPRM::sprmTDyaRowHeight:
+ return 2;
+ case SPRM::sprmTDefTable:
+ return readU16(in) + 1;
+ case SPRM::sprmTDefTableShd:
+ break; // Variable.
+ case SPRM::sprmTTlp:
+ return 4;
+ case SPRM::sprmTSetBrc:
+ return 5;
+ case SPRM::sprmTInsert:
+ return 4;
+ case SPRM::sprmTDelete:
+ return 2;
+ case SPRM::sprmTDxaCol:
+ return 4;
+ case SPRM::sprmTMerge:
+ case SPRM::sprmTSplit:
+ return 2;
+ case SPRM::sprmTSetBrc10:
+ return 5;
+ case SPRM::sprmTSetShd:
+ return 4;
+ }
+
+ // Get length of variable size operand.
+ return *in + 1;
+}
+
+} // namespace SPRM
+} // namespace Word95
+} // namespace wvWare
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/word95_helper.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/word95_helper.h
new file mode 100644
index 00000000..3a3e416e
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/word95_helper.h
@@ -0,0 +1,39 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001 S.R.Haque <[email protected]>
+ Copyright (C) 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef WORD95_HELPER_H
+#define WORD95_HELPER_H
+
+#include "global.h"
+
+
+namespace wvWare
+{
+ namespace Word95
+ {
+ namespace SPRM
+ {
+
+ U16 determineParameterLength( U8 sprm, const U8* in );
+
+ } // namespace SPRM
+ } // namespace Word95
+} // namespace wvWare
+
+#endif // WORD95_HELPER_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/word97_generated.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/word97_generated.cpp
new file mode 100644
index 00000000..f1a87564
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/word97_generated.cpp
@@ -0,0 +1,8546 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+// This code is generated from the Microsoft HTML specification of the
+// WinWord format. Do NOT edit this code, but fix the spec or the script
+// generating the sources. If you want to add some additional code, some
+// includes or any other stuff, please add it to the template file!
+// For information about the script and the "hidden features" please read
+// the comments at the begin of the script.
+
+// If you find bugs or strange behavior please contact Werner Trobin
+
+#include <word97_generated.h>
+#include <olestream.h>
+#include <string.h> // memset(), memcpy()
+#include "wvlog.h"
+
+namespace wvWare {
+
+namespace Word97 {
+
+// FFN implementation, located in template-Word97.cpp
+FFN::FFN() {
+ clearInternal();
+}
+
+FFN::FFN(OLEStreamReader *stream, Version version, bool preservePos) {
+ clearInternal();
+ read(stream, version, preservePos);
+}
+
+bool FFN::read(OLEStreamReader *stream, Version version, bool preservePos) {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ cbFfnM1=stream->readU8();
+ shifterU8=stream->readU8();
+ prq=shifterU8;
+ shifterU8>>=2;
+ fTrueType=shifterU8;
+ shifterU8>>=1;
+ unused1_3=shifterU8;
+ shifterU8>>=1;
+ ff=shifterU8;
+ shifterU8>>=3;
+ unused1_7=shifterU8;
+ wWeight=stream->readS16();
+ chs=stream->readU8();
+ ixchSzAlt=stream->readU8();
+
+ U8 remainingSize = cbFfnM1 - 5;
+
+ if ( version == Word97 ) {
+ for(int _i=0; _i<(10); ++_i)
+ panose[_i]=stream->readU8();
+ for(int _i=0; _i<(24); ++_i)
+ fs[_i]=stream->readU8();
+ remainingSize -= 34;
+
+ // Remaining size in bytes -> shorts
+ remainingSize /= 2;
+ XCHAR* string = new XCHAR[ remainingSize ];
+ for ( int i = 0; i < remainingSize; ++i )
+ string[ i ] = stream->readU16();
+ if ( ixchSzAlt == 0 )
+ xszFfn = UString( reinterpret_cast<const wvWare::UChar *>( string ), remainingSize - 1 );
+ else {
+ xszFfn = UString( reinterpret_cast<const wvWare::UChar *>( string ), ixchSzAlt - 1 );
+ xszFfnAlt = UString( reinterpret_cast<const wvWare::UChar *>( &string[ ixchSzAlt ] ), remainingSize - 1 - ixchSzAlt );
+ }
+ delete [] string;
+ }
+ else {
+ U8* string = new U8[ remainingSize ];
+ stream->read( string, remainingSize );
+ // ###### Assume plain latin1 strings, maybe we'll have to use a textconverter here...
+ if ( ixchSzAlt == 0 )
+ xszFfn = UString( reinterpret_cast<char*>( string ) );
+ else {
+ xszFfn = UString( reinterpret_cast<char*>( string ) ); // The strings are 0-terminated, according to the SPEC
+ xszFfnAlt = UString( reinterpret_cast<char*>( &string[ ixchSzAlt ] ) );
+ }
+ delete [] string;
+ }
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void FFN::clear() {
+ clearInternal();
+}
+
+void FFN::clearInternal() {
+ cbFfnM1=0;
+ prq=0;
+ fTrueType=0;
+ unused1_3=0;
+ ff=0;
+ unused1_7=0;
+ wWeight=0;
+ chs=0;
+ ixchSzAlt=0;
+ for(int _i=0; _i<(10); ++_i)
+ panose[_i]=0;
+ for(int _i=0; _i<(24); ++_i)
+ fs[_i]=0;
+ xszFfn = UString::null;
+ xszFfnAlt = UString::null;
+}
+
+// There can be only one tab at a given position, no matter what the other options are
+bool operator==( const TabDescriptor& lhs, const TabDescriptor& rhs ) { return lhs.dxaTab == rhs.dxaTab; }
+bool operator!=( const TabDescriptor& lhs, const TabDescriptor& rhs ) { return lhs.dxaTab != rhs.dxaTab; }
+bool operator<( const TabDescriptor& lhs, const TabDescriptor& rhs ) { return lhs.dxaTab < rhs.dxaTab; }
+bool operator>( const TabDescriptor& lhs, const TabDescriptor& rhs ) { return lhs.dxaTab > rhs.dxaTab; }
+
+
+// DTTM implementation
+
+const unsigned int DTTM::sizeOf = 4;
+
+DTTM::DTTM() {
+ clear();
+}
+
+DTTM::DTTM(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+DTTM::DTTM(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool DTTM::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ mint=shifterU16;
+ shifterU16>>=6;
+ hr=shifterU16;
+ shifterU16>>=5;
+ dom=shifterU16;
+ shifterU16=stream->readU16();
+ mon=shifterU16;
+ shifterU16>>=4;
+ yr=shifterU16;
+ shifterU16>>=9;
+ wdy=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DTTM::readPtr(const U8 *ptr) {
+
+ U16 shifterU16;
+
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ mint=shifterU16;
+ shifterU16>>=6;
+ hr=shifterU16;
+ shifterU16>>=5;
+ dom=shifterU16;
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ mon=shifterU16;
+ shifterU16>>=4;
+ yr=shifterU16;
+ shifterU16>>=9;
+ wdy=shifterU16;
+}
+
+bool DTTM::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=mint;
+ shifterU16|=hr << 6;
+ shifterU16|=dom << 11;
+ stream->write(shifterU16);
+ shifterU16=mon;
+ shifterU16|=yr << 4;
+ shifterU16|=wdy << 13;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DTTM::clear() {
+ mint=0;
+ hr=0;
+ dom=0;
+ mon=0;
+ yr=0;
+ wdy=0;
+}
+
+void DTTM::dump() const
+{
+ wvlog << "Dumping DTTM:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping DTTM done." << std::endl;
+}
+
+std::string DTTM::toString() const
+{
+ std::string s( "DTTM:" );
+ s += "\nmint=";
+ s += uint2string( mint );
+ s += "\nhr=";
+ s += uint2string( hr );
+ s += "\ndom=";
+ s += uint2string( dom );
+ s += "\nmon=";
+ s += uint2string( mon );
+ s += "\nyr=";
+ s += uint2string( yr );
+ s += "\nwdy=";
+ s += uint2string( wdy );
+ s += "\nDTTM Done.";
+ return s;
+}
+
+bool operator==(const DTTM &lhs, const DTTM &rhs) {
+
+ return lhs.mint==rhs.mint &&
+ lhs.hr==rhs.hr &&
+ lhs.dom==rhs.dom &&
+ lhs.mon==rhs.mon &&
+ lhs.yr==rhs.yr &&
+ lhs.wdy==rhs.wdy;
+}
+
+bool operator!=(const DTTM &lhs, const DTTM &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// DOPTYPOGRAPHY implementation
+
+DOPTYPOGRAPHY::DOPTYPOGRAPHY() {
+ clear();
+}
+
+DOPTYPOGRAPHY::DOPTYPOGRAPHY(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool DOPTYPOGRAPHY::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ fKerningPunct=shifterU16;
+ shifterU16>>=1;
+ iJustification=shifterU16;
+ shifterU16>>=2;
+ iLevelOfKinsoku=shifterU16;
+ shifterU16>>=2;
+ f2on1=shifterU16;
+ shifterU16>>=1;
+ unused0_6=shifterU16;
+ cchFollowingPunct=stream->readS16();
+ cchLeadingPunct=stream->readS16();
+ for(int _i=0; _i<(101); ++_i)
+ rgxchFPunct[_i]=stream->readU16();
+ for(int _i=0; _i<(51); ++_i)
+ rgxchLPunct[_i]=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool DOPTYPOGRAPHY::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=fKerningPunct;
+ shifterU16|=iJustification << 1;
+ shifterU16|=iLevelOfKinsoku << 3;
+ shifterU16|=f2on1 << 5;
+ shifterU16|=unused0_6 << 6;
+ stream->write(shifterU16);
+ stream->write(cchFollowingPunct);
+ stream->write(cchLeadingPunct);
+ for(int _i=0; _i<(101); ++_i)
+ stream->write(rgxchFPunct[_i]);
+ for(int _i=0; _i<(51); ++_i)
+ stream->write(rgxchLPunct[_i]);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DOPTYPOGRAPHY::clear() {
+ fKerningPunct=0;
+ iJustification=0;
+ iLevelOfKinsoku=0;
+ f2on1=0;
+ unused0_6=0;
+ cchFollowingPunct=0;
+ cchLeadingPunct=0;
+ for(int _i=0; _i<(101); ++_i)
+ rgxchFPunct[_i]=0;
+ for(int _i=0; _i<(51); ++_i)
+ rgxchLPunct[_i]=0;
+}
+
+bool operator==(const DOPTYPOGRAPHY &lhs, const DOPTYPOGRAPHY &rhs) {
+
+ for(int _i=0; _i<(101); ++_i) {
+ if(lhs.rgxchFPunct[_i]!=rhs.rgxchFPunct[_i])
+ return false;
+ }
+
+ for(int _i=0; _i<(51); ++_i) {
+ if(lhs.rgxchLPunct[_i]!=rhs.rgxchLPunct[_i])
+ return false;
+ }
+
+ return lhs.fKerningPunct==rhs.fKerningPunct &&
+ lhs.iJustification==rhs.iJustification &&
+ lhs.iLevelOfKinsoku==rhs.iLevelOfKinsoku &&
+ lhs.f2on1==rhs.f2on1 &&
+ lhs.unused0_6==rhs.unused0_6 &&
+ lhs.cchFollowingPunct==rhs.cchFollowingPunct &&
+ lhs.cchLeadingPunct==rhs.cchLeadingPunct;
+}
+
+bool operator!=(const DOPTYPOGRAPHY &lhs, const DOPTYPOGRAPHY &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// PRM2 implementation
+
+PRM2::PRM2() {
+ clear();
+}
+
+PRM2::PRM2(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool PRM2::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ fComplex=shifterU16;
+ shifterU16>>=1;
+ igrpprl=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool PRM2::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=fComplex;
+ shifterU16|=igrpprl << 1;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PRM2::clear() {
+ fComplex=0;
+ igrpprl=0;
+}
+
+bool operator==(const PRM2 &lhs, const PRM2 &rhs) {
+
+ return lhs.fComplex==rhs.fComplex &&
+ lhs.igrpprl==rhs.igrpprl;
+}
+
+bool operator!=(const PRM2 &lhs, const PRM2 &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// PRM implementation
+
+const unsigned int PRM::sizeOf = 2;
+
+PRM::PRM() {
+ clear();
+}
+
+PRM::PRM(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+PRM::PRM(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool PRM::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ fComplex=shifterU16;
+ shifterU16>>=1;
+ isprm=shifterU16;
+ shifterU16>>=7;
+ val=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PRM::readPtr(const U8 *ptr) {
+
+ U16 shifterU16;
+
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ fComplex=shifterU16;
+ shifterU16>>=1;
+ isprm=shifterU16;
+ shifterU16>>=7;
+ val=shifterU16;
+}
+
+bool PRM::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=fComplex;
+ shifterU16|=isprm << 1;
+ shifterU16|=val << 8;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PRM::clear() {
+ fComplex=0;
+ isprm=0;
+ val=0;
+}
+
+bool operator==(const PRM &lhs, const PRM &rhs) {
+
+ return lhs.fComplex==rhs.fComplex &&
+ lhs.isprm==rhs.isprm &&
+ lhs.val==rhs.val;
+}
+
+bool operator!=(const PRM &lhs, const PRM &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// SHD implementation
+
+const unsigned int SHD::sizeOf = 10;
+
+SHD::SHD() {
+ clear();
+}
+
+SHD::SHD(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+SHD::SHD(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool SHD::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+ U16 ico;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ ico=shifterU16;
+ cvFore=Word97::icoToRGB(ico);
+ shifterU16>>=5;
+ ico=shifterU16;
+ cvBack=Word97::icoToRGB(ico);
+ shifterU16>>=5;
+ ipat=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void SHD::readPtr(const U8 *ptr) {
+
+ U16 shifterU16;
+ U16 ico;
+
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ ico=shifterU16 & 0x1F;
+ cvFore=Word97::icoToRGB(ico);
+ shifterU16>>=5;
+ ico=shifterU16 & 0x1F;
+ cvBack=Word97::icoToRGB(ico);
+ shifterU16>>=5;
+ ipat=shifterU16;
+}
+
+void SHD::read90Ptr(const U8 *ptr) {
+
+ U16 shifterU16;
+ U8 r,g,b,cvauto;
+
+ r=readU8(ptr);
+ ptr+=sizeof(U8);
+ g=readU8(ptr);
+ ptr+=sizeof(U8);
+ b=readU8(ptr);
+ ptr+=sizeof(U8);
+ cvauto=readU8(ptr);
+ ptr+=sizeof(U8);
+ cvFore=(cvauto<<24)|(r<<16)|(g<<8)|(b);
+ r=readU8(ptr);
+ ptr+=sizeof(U8);
+ g=readU8(ptr);
+ ptr+=sizeof(U8);
+ b=readU8(ptr);
+ ptr+=sizeof(U8);
+ cvauto=readU8(ptr);
+ ptr+=sizeof(U8);
+ cvBack=(cvauto<<24)|(r<<16)|(g<<8)|(b);
+ shifterU16=readU16(ptr);
+ ipat=shifterU16;
+}
+
+bool SHD::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ //shifterU16=icoFore;
+ //shifterU16|=icoBack << 5;
+ shifterU16|=ipat << 10;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void SHD::clear() {
+ cvFore=0xff000000;
+ cvBack=0xff000000;
+ ipat=0;
+}
+
+void SHD::dump() const
+{
+ wvlog << "Dumping SHD:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping SHD done." << std::endl;
+}
+
+std::string SHD::toString() const
+{
+ std::string s( "SHD:" );
+ s += "\ncvFore=";
+ s += uint2string( cvFore );
+ s += "\nicvBack=";
+ s += uint2string( cvBack );
+ s += "\nipat=";
+ s += uint2string( ipat );
+ s += "\nSHD Done.";
+ return s;
+}
+
+bool operator==(const SHD &lhs, const SHD &rhs) {
+
+ return lhs.cvFore==rhs.cvFore &&
+ lhs.cvBack==rhs.cvBack &&
+ lhs.ipat==rhs.ipat;
+}
+
+bool operator!=(const SHD &lhs, const SHD &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// PHE implementation
+
+const unsigned int PHE::sizeOf = 12;
+
+PHE::PHE() {
+ clear();
+}
+
+PHE::PHE(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+PHE::PHE(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool PHE::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ fSpare=shifterU16;
+ shifterU16>>=1;
+ fUnk=shifterU16;
+ shifterU16>>=1;
+ fDiffLines=shifterU16;
+ shifterU16>>=1;
+ unused0_3=shifterU16;
+ shifterU16>>=5;
+ clMac=shifterU16;
+ unused2=stream->readU16();
+ dxaCol=stream->readS32();
+ dym=stream->readS32();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PHE::readPtr(const U8 *ptr) {
+
+ U16 shifterU16;
+
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ fSpare=shifterU16;
+ shifterU16>>=1;
+ fUnk=shifterU16;
+ shifterU16>>=1;
+ fDiffLines=shifterU16;
+ shifterU16>>=1;
+ unused0_3=shifterU16;
+ shifterU16>>=5;
+ clMac=shifterU16;
+ unused2=readU16(ptr);
+ ptr+=sizeof(U16);
+ dxaCol=readS32(ptr);
+ ptr+=sizeof(S32);
+ dym=readS32(ptr);
+ ptr+=sizeof(S32);
+}
+
+bool PHE::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=fSpare;
+ shifterU16|=fUnk << 1;
+ shifterU16|=fDiffLines << 2;
+ shifterU16|=unused0_3 << 3;
+ shifterU16|=clMac << 8;
+ stream->write(shifterU16);
+ stream->write(unused2);
+ stream->write(dxaCol);
+ stream->write(dym);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PHE::clear() {
+ fSpare=0;
+ fUnk=0;
+ fDiffLines=0;
+ unused0_3=0;
+ clMac=0;
+ unused2=0;
+ dxaCol=0;
+ dym=0;
+}
+
+void PHE::dump() const
+{
+ wvlog << "Dumping PHE:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping PHE done." << std::endl;
+}
+
+std::string PHE::toString() const
+{
+ std::string s( "PHE:" );
+ s += "\nfSpare=";
+ s += uint2string( fSpare );
+ s += "\nfUnk=";
+ s += uint2string( fUnk );
+ s += "\nfDiffLines=";
+ s += uint2string( fDiffLines );
+ s += "\nunused0_3=";
+ s += uint2string( unused0_3 );
+ s += "\nclMac=";
+ s += uint2string( clMac );
+ s += "\nunused2=";
+ s += uint2string( unused2 );
+ s += "\ndxaCol=";
+ s += int2string( dxaCol );
+ s += "\ndym=";
+ s += int2string( dym );
+ s += "\nPHE Done.";
+ return s;
+}
+
+bool operator==(const PHE &lhs, const PHE &rhs) {
+
+ return lhs.fSpare==rhs.fSpare &&
+ lhs.fUnk==rhs.fUnk &&
+ lhs.fDiffLines==rhs.fDiffLines &&
+ lhs.unused0_3==rhs.unused0_3 &&
+ lhs.clMac==rhs.clMac &&
+ lhs.unused2==rhs.unused2 &&
+ lhs.dxaCol==rhs.dxaCol &&
+ lhs.dym==rhs.dym;
+}
+
+bool operator!=(const PHE &lhs, const PHE &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// BRC implementation
+
+const unsigned int BRC::sizeOf = 8;
+const unsigned int BRC::sizeOf97 = 4;
+
+BRC::BRC() {
+ clear();
+}
+
+BRC::BRC(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+BRC::BRC(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool BRC::read(OLEStreamReader *stream, bool preservePos) {
+ U16 shifterU16;
+ U16 ico;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ dptLineWidth=shifterU16;
+ shifterU16>>=8;
+ brcType=shifterU16;
+ shifterU16=stream->readU16();
+ ico=shifterU16;
+ cv=Word97::icoToRGB(ico);
+ shifterU16>>=8;
+ dptSpace=shifterU16;
+ shifterU16>>=5;
+ fShadow=shifterU16;
+ shifterU16>>=1;
+ fFrame=shifterU16;
+ shifterU16>>=1;
+ unused2_15=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void BRC::readPtr(const U8 *ptr) {
+ U16 shifterU16;
+ U16 ico;
+
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ dptLineWidth=shifterU16;
+ shifterU16>>=8;
+ brcType=shifterU16;
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ ico=shifterU16;
+ cv=Word97::icoToRGB(ico);
+ shifterU16>>=8;
+ dptSpace=shifterU16;
+ shifterU16>>=5;
+ fShadow=shifterU16;
+ shifterU16>>=1;
+ fFrame=shifterU16;
+ shifterU16>>=1;
+ unused2_15=shifterU16;
+}
+
+void BRC::read90Ptr(const U8 *ptr) {
+ U16 shifterU16;
+ U8 r,g,b,cvauto;
+
+ r=readU8(ptr);
+ ptr+=sizeof(U8);
+ g=readU8(ptr);
+ ptr+=sizeof(U8);
+ b=readU8(ptr);
+ ptr+=sizeof(U8);
+ cvauto=readU8(ptr);
+ ptr+=sizeof(U8);
+ cv=(cvauto<<24)|(r<<16)|(g<<8)|(b);
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ dptLineWidth=shifterU16;
+ shifterU16>>=8;
+ brcType=shifterU16;
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ dptSpace=shifterU16;
+ shifterU16>>=5;
+ fShadow=shifterU16;
+ shifterU16>>=1;
+ fFrame=shifterU16;
+ shifterU16>>=1;
+ unused2_15=shifterU16;
+}
+
+bool BRC::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=dptLineWidth;
+ shifterU16|=brcType << 8;
+ stream->write(shifterU16);
+ shifterU16=1; // FIXME used to be ico - we should possibly convert cv to ico
+ shifterU16|=dptSpace << 8;
+ shifterU16|=fShadow << 13;
+ shifterU16|=fFrame << 14;
+ shifterU16|=unused2_15 << 15;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void BRC::clear() {
+ dptLineWidth=0;
+ brcType=0;
+ cv=0;
+ dptSpace=0;
+ fShadow=0;
+ fFrame=0;
+ unused2_15=0;
+}
+
+void BRC::dump() const
+{
+ wvlog << "Dumping BRC:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping BRC done." << std::endl;
+}
+
+std::string BRC::toString() const
+{
+ std::string s( "BRC:" );
+ s += "\ndptLineWidth=";
+ s += uint2string( dptLineWidth );
+ s += "\nbrcType=";
+ s += uint2string( brcType );
+ s += "\ncv=";
+ s += uint2string( cv );
+ s += "\ndptSpace=";
+ s += uint2string( dptSpace );
+ s += "\nfShadow=";
+ s += uint2string( fShadow );
+ s += "\nfFrame=";
+ s += uint2string( fFrame );
+ s += "\nunused2_15=";
+ s += uint2string( unused2_15 );
+ s += "\nBRC Done.";
+ return s;
+}
+
+bool operator==(const BRC &lhs, const BRC &rhs) {
+
+ return lhs.dptLineWidth==rhs.dptLineWidth &&
+ lhs.brcType==rhs.brcType &&
+ lhs.cv==rhs.cv &&
+ lhs.dptSpace==rhs.dptSpace &&
+ lhs.fShadow==rhs.fShadow &&
+ lhs.fFrame==rhs.fFrame &&
+ lhs.unused2_15==rhs.unused2_15;
+}
+
+bool operator!=(const BRC &lhs, const BRC &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// TLP implementation
+
+TLP::TLP() {
+ clear();
+}
+
+TLP::TLP(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+TLP::TLP(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool TLP::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ itl=stream->readS16();
+ shifterU16=stream->readU16();
+ fBorders=shifterU16;
+ shifterU16>>=1;
+ fShading=shifterU16;
+ shifterU16>>=1;
+ fFont=shifterU16;
+ shifterU16>>=1;
+ fColor=shifterU16;
+ shifterU16>>=1;
+ fBestFit=shifterU16;
+ shifterU16>>=1;
+ fHdrRows=shifterU16;
+ shifterU16>>=1;
+ fLastRow=shifterU16;
+ shifterU16>>=1;
+ fHdrCols=shifterU16;
+ shifterU16>>=1;
+ fLastCol=shifterU16;
+ shifterU16>>=1;
+ unused2_9=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void TLP::readPtr(const U8 *ptr) {
+
+ U16 shifterU16;
+
+ itl=readS16(ptr);
+ ptr+=sizeof(S16);
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ fBorders=shifterU16;
+ shifterU16>>=1;
+ fShading=shifterU16;
+ shifterU16>>=1;
+ fFont=shifterU16;
+ shifterU16>>=1;
+ fColor=shifterU16;
+ shifterU16>>=1;
+ fBestFit=shifterU16;
+ shifterU16>>=1;
+ fHdrRows=shifterU16;
+ shifterU16>>=1;
+ fLastRow=shifterU16;
+ shifterU16>>=1;
+ fHdrCols=shifterU16;
+ shifterU16>>=1;
+ fLastCol=shifterU16;
+ shifterU16>>=1;
+ unused2_9=shifterU16;
+}
+
+bool TLP::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(itl);
+ shifterU16=fBorders;
+ shifterU16|=fShading << 1;
+ shifterU16|=fFont << 2;
+ shifterU16|=fColor << 3;
+ shifterU16|=fBestFit << 4;
+ shifterU16|=fHdrRows << 5;
+ shifterU16|=fLastRow << 6;
+ shifterU16|=fHdrCols << 7;
+ shifterU16|=fLastCol << 8;
+ shifterU16|=unused2_9 << 9;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void TLP::clear() {
+ itl=0;
+ fBorders=0;
+ fShading=0;
+ fFont=0;
+ fColor=0;
+ fBestFit=0;
+ fHdrRows=0;
+ fLastRow=0;
+ fHdrCols=0;
+ fLastCol=0;
+ unused2_9=0;
+}
+
+void TLP::dump() const
+{
+ wvlog << "Dumping TLP:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping TLP done." << std::endl;
+}
+
+std::string TLP::toString() const
+{
+ std::string s( "TLP:" );
+ s += "\nitl=";
+ s += int2string( itl );
+ s += "\nfBorders=";
+ s += uint2string( fBorders );
+ s += "\nfShading=";
+ s += uint2string( fShading );
+ s += "\nfFont=";
+ s += uint2string( fFont );
+ s += "\nfColor=";
+ s += uint2string( fColor );
+ s += "\nfBestFit=";
+ s += uint2string( fBestFit );
+ s += "\nfHdrRows=";
+ s += uint2string( fHdrRows );
+ s += "\nfLastRow=";
+ s += uint2string( fLastRow );
+ s += "\nfHdrCols=";
+ s += uint2string( fHdrCols );
+ s += "\nfLastCol=";
+ s += uint2string( fLastCol );
+ s += "\nunused2_9=";
+ s += uint2string( unused2_9 );
+ s += "\nTLP Done.";
+ return s;
+}
+
+bool operator==(const TLP &lhs, const TLP &rhs) {
+
+ return lhs.itl==rhs.itl &&
+ lhs.fBorders==rhs.fBorders &&
+ lhs.fShading==rhs.fShading &&
+ lhs.fFont==rhs.fFont &&
+ lhs.fColor==rhs.fColor &&
+ lhs.fBestFit==rhs.fBestFit &&
+ lhs.fHdrRows==rhs.fHdrRows &&
+ lhs.fLastRow==rhs.fLastRow &&
+ lhs.fHdrCols==rhs.fHdrCols &&
+ lhs.fLastCol==rhs.fLastCol &&
+ lhs.unused2_9==rhs.unused2_9;
+}
+
+bool operator!=(const TLP &lhs, const TLP &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// TC implementation
+
+const unsigned int TC::sizeOf = 20;
+
+TC::TC() {
+ clear();
+}
+
+TC::TC(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+TC::TC(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool TC::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ fFirstMerged=shifterU16;
+ shifterU16>>=1;
+ fMerged=shifterU16;
+ shifterU16>>=1;
+ fVertical=shifterU16;
+ shifterU16>>=1;
+ fBackward=shifterU16;
+ shifterU16>>=1;
+ fRotateFont=shifterU16;
+ shifterU16>>=1;
+ fVertMerge=shifterU16;
+ shifterU16>>=1;
+ fVertRestart=shifterU16;
+ shifterU16>>=1;
+ vertAlign=shifterU16;
+ shifterU16>>=2;
+ fUnused=shifterU16;
+ wUnused=stream->readU16();
+ brcTop.read(stream, false);
+ brcLeft.read(stream, false);
+ brcBottom.read(stream, false);
+ brcRight.read(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void TC::readPtr(const U8 *ptr) {
+
+ U16 shifterU16;
+
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ fFirstMerged=shifterU16;
+ shifterU16>>=1;
+ fMerged=shifterU16;
+ shifterU16>>=1;
+ fVertical=shifterU16;
+ shifterU16>>=1;
+ fBackward=shifterU16;
+ shifterU16>>=1;
+ fRotateFont=shifterU16;
+ shifterU16>>=1;
+ fVertMerge=shifterU16;
+ shifterU16>>=1;
+ fVertRestart=shifterU16;
+ shifterU16>>=1;
+ vertAlign=shifterU16;
+ shifterU16>>=2;
+ fUnused=shifterU16;
+ wUnused=readU16(ptr);
+ ptr+=sizeof(U16);
+ wvlog << std::endl;
+ brcTop.readPtr(ptr);
+ ptr+=BRC::sizeOf97;
+ brcLeft.readPtr(ptr);
+ ptr+=BRC::sizeOf97;
+ brcBottom.readPtr(ptr);
+ ptr+=BRC::sizeOf97;
+ brcRight.readPtr(ptr);
+ ptr+=BRC::sizeOf;
+}
+
+bool TC::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=fFirstMerged;
+ shifterU16|=fMerged << 1;
+ shifterU16|=fVertical << 2;
+ shifterU16|=fBackward << 3;
+ shifterU16|=fRotateFont << 4;
+ shifterU16|=fVertMerge << 5;
+ shifterU16|=fVertRestart << 6;
+ shifterU16|=vertAlign << 7;
+ shifterU16|=fUnused << 9;
+ stream->write(shifterU16);
+ stream->write(wUnused);
+ brcTop.write(stream, false);
+ brcLeft.write(stream, false);
+ brcBottom.write(stream, false);
+ brcRight.write(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void TC::clear() {
+ fFirstMerged=0;
+ fMerged=0;
+ fVertical=0;
+ fBackward=0;
+ fRotateFont=0;
+ fVertMerge=0;
+ fVertRestart=0;
+ vertAlign=0;
+ fUnused=0;
+ wUnused=0;
+ brcTop.clear();
+ brcLeft.clear();
+ brcBottom.clear();
+ brcRight.clear();
+}
+
+void TC::dump() const
+{
+ wvlog << "Dumping TC:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping TC done." << std::endl;
+}
+
+std::string TC::toString() const
+{
+ std::string s( "TC:" );
+ s += "\nfFirstMerged=";
+ s += uint2string( fFirstMerged );
+ s += "\nfMerged=";
+ s += uint2string( fMerged );
+ s += "\nfVertical=";
+ s += uint2string( fVertical );
+ s += "\nfBackward=";
+ s += uint2string( fBackward );
+ s += "\nfRotateFont=";
+ s += uint2string( fRotateFont );
+ s += "\nfVertMerge=";
+ s += uint2string( fVertMerge );
+ s += "\nfVertRestart=";
+ s += uint2string( fVertRestart );
+ s += "\nvertAlign=";
+ s += uint2string( vertAlign );
+ s += "\nfUnused=";
+ s += uint2string( fUnused );
+ s += "\nwUnused=";
+ s += uint2string( wUnused );
+ s += "\nbrcTop=";
+ s += "\n{" + brcTop.toString() + "}\n";
+ s += "\nbrcLeft=";
+ s += "\n{" + brcLeft.toString() + "}\n";
+ s += "\nbrcBottom=";
+ s += "\n{" + brcBottom.toString() + "}\n";
+ s += "\nbrcRight=";
+ s += "\n{" + brcRight.toString() + "}\n";
+ s += "\nTC Done.";
+ return s;
+}
+
+bool operator==(const TC &lhs, const TC &rhs) {
+
+ return lhs.fFirstMerged==rhs.fFirstMerged &&
+ lhs.fMerged==rhs.fMerged &&
+ lhs.fVertical==rhs.fVertical &&
+ lhs.fBackward==rhs.fBackward &&
+ lhs.fRotateFont==rhs.fRotateFont &&
+ lhs.fVertMerge==rhs.fVertMerge &&
+ lhs.fVertRestart==rhs.fVertRestart &&
+ lhs.vertAlign==rhs.vertAlign &&
+ lhs.fUnused==rhs.fUnused &&
+ lhs.wUnused==rhs.wUnused &&
+ lhs.brcTop==rhs.brcTop &&
+ lhs.brcLeft==rhs.brcLeft &&
+ lhs.brcBottom==rhs.brcBottom &&
+ lhs.brcRight==rhs.brcRight;
+}
+
+bool operator!=(const TC &lhs, const TC &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// TAP implementation
+
+TAP::TAP() : Shared() {
+ clear();
+}
+
+TAP::TAP(OLEStreamReader *stream, bool preservePos) : Shared() {
+ clear();
+ read(stream, preservePos);
+}
+
+bool TAP::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ jc=stream->readS16();
+ dxaGapHalf=stream->readS32();
+ dyaRowHeight=stream->readS32();
+ fCantSplit=stream->readU8();
+ fTableHeader=stream->readU8();
+ tlp.read(stream, false);
+ lwHTMLProps=stream->readS32();
+ shifterU16=stream->readU16();
+ fCaFull=shifterU16;
+ shifterU16>>=1;
+ fFirstRow=shifterU16;
+ shifterU16>>=1;
+ fLastRow=shifterU16;
+ shifterU16>>=1;
+ fOutline=shifterU16;
+ shifterU16>>=1;
+ unused20_12=shifterU16;
+ itcMac=stream->readS16();
+ dxaAdjust=stream->readS32();
+ dxaScale=stream->readS32();
+ dxsInch=stream->readS32();
+ // skipping the std::vector rgdxaCenter
+ // skipping the std::vector rgdxaCenterPrint
+ // skipping the std::vector rgtc
+ // skipping the std::vector rgshd
+ for(int _i=0; _i<(6); ++_i)
+ rgbrcTable[_i].read(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool TAP::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(jc);
+ stream->write(dxaGapHalf);
+ stream->write(dyaRowHeight);
+ stream->write(fCantSplit);
+ stream->write(fTableHeader);
+ tlp.write(stream, false);
+ stream->write(lwHTMLProps);
+ shifterU16=fCaFull;
+ shifterU16|=fFirstRow << 1;
+ shifterU16|=fLastRow << 2;
+ shifterU16|=fOutline << 3;
+ shifterU16|=unused20_12 << 4;
+ stream->write(shifterU16);
+ stream->write(itcMac);
+ stream->write(dxaAdjust);
+ stream->write(dxaScale);
+ stream->write(dxsInch);
+ // skipping the std::vector rgdxaCenter
+ // skipping the std::vector rgdxaCenterPrint
+ // skipping the std::vector rgtc
+ // skipping the std::vector rgshd
+ for(int _i=0; _i<(6); ++_i)
+ rgbrcTable[_i].write(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void TAP::clear() {
+ jc=0;
+ dxaGapHalf=0;
+ dyaRowHeight=0;
+ fCantSplit=0;
+ fTableHeader=0;
+ tlp.clear();
+ lwHTMLProps=0;
+ fCaFull=0;
+ fFirstRow=0;
+ fLastRow=0;
+ fOutline=0;
+ unused20_12=0;
+ itcMac=0;
+ dxaAdjust=0;
+ dxaScale=0;
+ dxsInch=0;
+ rgdxaCenter.clear();
+ rgdxaCenterPrint.clear();
+ rgtc.clear();
+ rgshd.clear();
+ for(int _i=0; _i<(6); ++_i)
+ rgbrcTable[_i].clear();
+}
+
+void TAP::dump() const
+{
+ wvlog << "Dumping TAP:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping TAP done." << std::endl;
+}
+
+std::string TAP::toString() const
+{
+ std::string s( "TAP:" );
+ s += "\njc=";
+ s += int2string( jc );
+ s += "\ndxaGapHalf=";
+ s += int2string( dxaGapHalf );
+ s += "\ndyaRowHeight=";
+ s += int2string( dyaRowHeight );
+ s += "\nfCantSplit=";
+ s += uint2string( fCantSplit );
+ s += "\nfTableHeader=";
+ s += uint2string( fTableHeader );
+ s += "\ntlp=";
+ s += "\n{" + tlp.toString() + "}\n";
+ s += "\nlwHTMLProps=";
+ s += int2string( lwHTMLProps );
+ s += "\nfCaFull=";
+ s += uint2string( fCaFull );
+ s += "\nfFirstRow=";
+ s += uint2string( fFirstRow );
+ s += "\nfLastRow=";
+ s += uint2string( fLastRow );
+ s += "\nfOutline=";
+ s += uint2string( fOutline );
+ s += "\nunused20_12=";
+ s += uint2string( unused20_12 );
+ s += "\nitcMac=";
+ s += int2string( itcMac );
+ s += "\ndxaAdjust=";
+ s += int2string( dxaAdjust );
+ s += "\ndxaScale=";
+ s += int2string( dxaScale );
+ s += "\ndxsInch=";
+ s += int2string( dxsInch );
+ s += "\nrgdxaCenter=";
+ // skipping the std::vector rgdxaCenter
+ s += "\nrgdxaCenterPrint=";
+ // skipping the std::vector rgdxaCenterPrint
+ s += "\nrgtc=";
+ // skipping the std::vector rgtc
+ s += "\nrgshd=";
+ // skipping the std::vector rgshd
+ for(int _i=0; _i<(6); ++_i) {
+ s += "\nrgbrcTable[" + int2string( _i ) + "]=";
+ s += "\n{" + rgbrcTable[_i].toString() + "}\n";
+ }
+ s += "\nTAP Done.";
+ return s;
+}
+
+bool operator==(const TAP &lhs, const TAP &rhs) {
+
+ for(int _i=0; _i<(6); ++_i) {
+ if(lhs.rgbrcTable[_i]!=rhs.rgbrcTable[_i])
+ return false;
+ }
+
+ return lhs.jc==rhs.jc &&
+ lhs.dxaGapHalf==rhs.dxaGapHalf &&
+ lhs.dyaRowHeight==rhs.dyaRowHeight &&
+ lhs.fCantSplit==rhs.fCantSplit &&
+ lhs.fTableHeader==rhs.fTableHeader &&
+ lhs.tlp==rhs.tlp &&
+ lhs.lwHTMLProps==rhs.lwHTMLProps &&
+ lhs.fCaFull==rhs.fCaFull &&
+ lhs.fFirstRow==rhs.fFirstRow &&
+ lhs.fLastRow==rhs.fLastRow &&
+ lhs.fOutline==rhs.fOutline &&
+ lhs.unused20_12==rhs.unused20_12 &&
+ lhs.itcMac==rhs.itcMac &&
+ lhs.dxaAdjust==rhs.dxaAdjust &&
+ lhs.dxaScale==rhs.dxaScale &&
+ lhs.dxsInch==rhs.dxsInch &&
+ lhs.rgdxaCenter==rhs.rgdxaCenter &&
+ lhs.rgdxaCenterPrint==rhs.rgdxaCenterPrint &&
+ lhs.rgtc==rhs.rgtc &&
+ lhs.rgshd==rhs.rgshd;
+}
+
+bool operator!=(const TAP &lhs, const TAP &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// ANLD implementation
+
+ANLD::ANLD() {
+ clear();
+}
+
+ANLD::ANLD(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+ANLD::ANLD(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool ANLD::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ nfc=stream->readU8();
+ cxchTextBefore=stream->readU8();
+ cxchTextAfter=stream->readU8();
+ shifterU8=stream->readU8();
+ jc=shifterU8;
+ shifterU8>>=2;
+ fPrev=shifterU8;
+ shifterU8>>=1;
+ fHang=shifterU8;
+ shifterU8>>=1;
+ fSetBold=shifterU8;
+ shifterU8>>=1;
+ fSetItalic=shifterU8;
+ shifterU8>>=1;
+ fSetSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fSetCaps=shifterU8;
+ shifterU8=stream->readU8();
+ fSetStrike=shifterU8;
+ shifterU8>>=1;
+ fSetKul=shifterU8;
+ shifterU8>>=1;
+ fPrevSpace=shifterU8;
+ shifterU8>>=1;
+ fBold=shifterU8;
+ shifterU8>>=1;
+ fItalic=shifterU8;
+ shifterU8>>=1;
+ fSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fCaps=shifterU8;
+ shifterU8>>=1;
+ fStrike=shifterU8;
+ shifterU8=stream->readU8();
+ kul=shifterU8;
+ shifterU8>>=3;
+ ico=shifterU8;
+ ftc=stream->readS16();
+ hps=stream->readU16();
+ iStartAt=stream->readU16();
+ dxaIndent=stream->readU16();
+ dxaSpace=stream->readU16();
+ fNumber1=stream->readU8();
+ fNumberAcross=stream->readU8();
+ fRestartHdn=stream->readU8();
+ fSpareX=stream->readU8();
+ for(int _i=0; _i<(32); ++_i)
+ rgxch[_i]=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void ANLD::readPtr(const U8 *ptr) {
+
+ U8 shifterU8;
+
+ nfc=readU8(ptr);
+ ptr+=sizeof(U8);
+ cxchTextBefore=readU8(ptr);
+ ptr+=sizeof(U8);
+ cxchTextAfter=readU8(ptr);
+ ptr+=sizeof(U8);
+ shifterU8=readU8(ptr);
+ ptr+=sizeof(U8);
+ jc=shifterU8;
+ shifterU8>>=2;
+ fPrev=shifterU8;
+ shifterU8>>=1;
+ fHang=shifterU8;
+ shifterU8>>=1;
+ fSetBold=shifterU8;
+ shifterU8>>=1;
+ fSetItalic=shifterU8;
+ shifterU8>>=1;
+ fSetSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fSetCaps=shifterU8;
+ shifterU8=readU8(ptr);
+ ptr+=sizeof(U8);
+ fSetStrike=shifterU8;
+ shifterU8>>=1;
+ fSetKul=shifterU8;
+ shifterU8>>=1;
+ fPrevSpace=shifterU8;
+ shifterU8>>=1;
+ fBold=shifterU8;
+ shifterU8>>=1;
+ fItalic=shifterU8;
+ shifterU8>>=1;
+ fSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fCaps=shifterU8;
+ shifterU8>>=1;
+ fStrike=shifterU8;
+ shifterU8=readU8(ptr);
+ ptr+=sizeof(U8);
+ kul=shifterU8;
+ shifterU8>>=3;
+ ico=shifterU8;
+ ftc=readS16(ptr);
+ ptr+=sizeof(S16);
+ hps=readU16(ptr);
+ ptr+=sizeof(U16);
+ iStartAt=readU16(ptr);
+ ptr+=sizeof(U16);
+ dxaIndent=readU16(ptr);
+ ptr+=sizeof(U16);
+ dxaSpace=readU16(ptr);
+ ptr+=sizeof(U16);
+ fNumber1=readU8(ptr);
+ ptr+=sizeof(U8);
+ fNumberAcross=readU8(ptr);
+ ptr+=sizeof(U8);
+ fRestartHdn=readU8(ptr);
+ ptr+=sizeof(U8);
+ fSpareX=readU8(ptr);
+ ptr+=sizeof(U8);
+ for(int _i=0; _i<(32); ++_i) {
+ rgxch[_i]=readU16(ptr);
+ ptr+=sizeof(U16);
+ }
+}
+
+bool ANLD::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(nfc);
+ stream->write(cxchTextBefore);
+ stream->write(cxchTextAfter);
+ shifterU8=jc;
+ shifterU8|=fPrev << 2;
+ shifterU8|=fHang << 3;
+ shifterU8|=fSetBold << 4;
+ shifterU8|=fSetItalic << 5;
+ shifterU8|=fSetSmallCaps << 6;
+ shifterU8|=fSetCaps << 7;
+ stream->write(shifterU8);
+ shifterU8=fSetStrike;
+ shifterU8|=fSetKul << 1;
+ shifterU8|=fPrevSpace << 2;
+ shifterU8|=fBold << 3;
+ shifterU8|=fItalic << 4;
+ shifterU8|=fSmallCaps << 5;
+ shifterU8|=fCaps << 6;
+ shifterU8|=fStrike << 7;
+ stream->write(shifterU8);
+ shifterU8=kul;
+ shifterU8|=ico << 3;
+ stream->write(shifterU8);
+ stream->write(ftc);
+ stream->write(hps);
+ stream->write(iStartAt);
+ stream->write(dxaIndent);
+ stream->write(dxaSpace);
+ stream->write(fNumber1);
+ stream->write(fNumberAcross);
+ stream->write(fRestartHdn);
+ stream->write(fSpareX);
+ for(int _i=0; _i<(32); ++_i)
+ stream->write(rgxch[_i]);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void ANLD::clear() {
+ nfc=0;
+ cxchTextBefore=0;
+ cxchTextAfter=0;
+ jc=0;
+ fPrev=0;
+ fHang=0;
+ fSetBold=0;
+ fSetItalic=0;
+ fSetSmallCaps=0;
+ fSetCaps=0;
+ fSetStrike=0;
+ fSetKul=0;
+ fPrevSpace=0;
+ fBold=0;
+ fItalic=0;
+ fSmallCaps=0;
+ fCaps=0;
+ fStrike=0;
+ kul=0;
+ ico=0;
+ ftc=0;
+ hps=0;
+ iStartAt=0;
+ dxaIndent=0;
+ dxaSpace=0;
+ fNumber1=0;
+ fNumberAcross=0;
+ fRestartHdn=0;
+ fSpareX=0;
+ for(int _i=0; _i<(32); ++_i)
+ rgxch[_i]=0;
+}
+
+void ANLD::dump() const
+{
+ wvlog << "Dumping ANLD:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping ANLD done." << std::endl;
+}
+
+std::string ANLD::toString() const
+{
+ std::string s( "ANLD:" );
+ s += "\nnfc=";
+ s += uint2string( nfc );
+ s += "\ncxchTextBefore=";
+ s += uint2string( cxchTextBefore );
+ s += "\ncxchTextAfter=";
+ s += uint2string( cxchTextAfter );
+ s += "\njc=";
+ s += uint2string( jc );
+ s += "\nfPrev=";
+ s += uint2string( fPrev );
+ s += "\nfHang=";
+ s += uint2string( fHang );
+ s += "\nfSetBold=";
+ s += uint2string( fSetBold );
+ s += "\nfSetItalic=";
+ s += uint2string( fSetItalic );
+ s += "\nfSetSmallCaps=";
+ s += uint2string( fSetSmallCaps );
+ s += "\nfSetCaps=";
+ s += uint2string( fSetCaps );
+ s += "\nfSetStrike=";
+ s += uint2string( fSetStrike );
+ s += "\nfSetKul=";
+ s += uint2string( fSetKul );
+ s += "\nfPrevSpace=";
+ s += uint2string( fPrevSpace );
+ s += "\nfBold=";
+ s += uint2string( fBold );
+ s += "\nfItalic=";
+ s += uint2string( fItalic );
+ s += "\nfSmallCaps=";
+ s += uint2string( fSmallCaps );
+ s += "\nfCaps=";
+ s += uint2string( fCaps );
+ s += "\nfStrike=";
+ s += uint2string( fStrike );
+ s += "\nkul=";
+ s += uint2string( kul );
+ s += "\nico=";
+ s += uint2string( ico );
+ s += "\nftc=";
+ s += int2string( ftc );
+ s += "\nhps=";
+ s += uint2string( hps );
+ s += "\niStartAt=";
+ s += uint2string( iStartAt );
+ s += "\ndxaIndent=";
+ s += uint2string( dxaIndent );
+ s += "\ndxaSpace=";
+ s += uint2string( dxaSpace );
+ s += "\nfNumber1=";
+ s += uint2string( fNumber1 );
+ s += "\nfNumberAcross=";
+ s += uint2string( fNumberAcross );
+ s += "\nfRestartHdn=";
+ s += uint2string( fRestartHdn );
+ s += "\nfSpareX=";
+ s += uint2string( fSpareX );
+ for(int _i=0; _i<(32); ++_i) {
+ s += "\nrgxch[" + int2string( _i ) + "]=";
+ s += uint2string( rgxch[_i] );
+ }
+ s += "\nANLD Done.";
+ return s;
+}
+
+bool operator==(const ANLD &lhs, const ANLD &rhs) {
+
+ for(int _i=0; _i<(32); ++_i) {
+ if(lhs.rgxch[_i]!=rhs.rgxch[_i])
+ return false;
+ }
+
+ return lhs.nfc==rhs.nfc &&
+ lhs.cxchTextBefore==rhs.cxchTextBefore &&
+ lhs.cxchTextAfter==rhs.cxchTextAfter &&
+ lhs.jc==rhs.jc &&
+ lhs.fPrev==rhs.fPrev &&
+ lhs.fHang==rhs.fHang &&
+ lhs.fSetBold==rhs.fSetBold &&
+ lhs.fSetItalic==rhs.fSetItalic &&
+ lhs.fSetSmallCaps==rhs.fSetSmallCaps &&
+ lhs.fSetCaps==rhs.fSetCaps &&
+ lhs.fSetStrike==rhs.fSetStrike &&
+ lhs.fSetKul==rhs.fSetKul &&
+ lhs.fPrevSpace==rhs.fPrevSpace &&
+ lhs.fBold==rhs.fBold &&
+ lhs.fItalic==rhs.fItalic &&
+ lhs.fSmallCaps==rhs.fSmallCaps &&
+ lhs.fCaps==rhs.fCaps &&
+ lhs.fStrike==rhs.fStrike &&
+ lhs.kul==rhs.kul &&
+ lhs.ico==rhs.ico &&
+ lhs.ftc==rhs.ftc &&
+ lhs.hps==rhs.hps &&
+ lhs.iStartAt==rhs.iStartAt &&
+ lhs.dxaIndent==rhs.dxaIndent &&
+ lhs.dxaSpace==rhs.dxaSpace &&
+ lhs.fNumber1==rhs.fNumber1 &&
+ lhs.fNumberAcross==rhs.fNumberAcross &&
+ lhs.fRestartHdn==rhs.fRestartHdn &&
+ lhs.fSpareX==rhs.fSpareX;
+}
+
+bool operator!=(const ANLD &lhs, const ANLD &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// ANLV implementation
+
+const unsigned int ANLV::sizeOf = 16;
+
+ANLV::ANLV() {
+ clear();
+}
+
+ANLV::ANLV(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+ANLV::ANLV(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool ANLV::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ nfc=stream->readU8();
+ cxchTextBefore=stream->readU8();
+ cxchTextAfter=stream->readU8();
+ shifterU8=stream->readU8();
+ jc=shifterU8;
+ shifterU8>>=2;
+ fPrev=shifterU8;
+ shifterU8>>=1;
+ fHang=shifterU8;
+ shifterU8>>=1;
+ fSetBold=shifterU8;
+ shifterU8>>=1;
+ fSetItalic=shifterU8;
+ shifterU8>>=1;
+ fSetSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fSetCaps=shifterU8;
+ shifterU8=stream->readU8();
+ fSetStrike=shifterU8;
+ shifterU8>>=1;
+ fSetKul=shifterU8;
+ shifterU8>>=1;
+ fPrevSpace=shifterU8;
+ shifterU8>>=1;
+ fBold=shifterU8;
+ shifterU8>>=1;
+ fItalic=shifterU8;
+ shifterU8>>=1;
+ fSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fCaps=shifterU8;
+ shifterU8>>=1;
+ fStrike=shifterU8;
+ shifterU8=stream->readU8();
+ kul=shifterU8;
+ shifterU8>>=3;
+ ico=shifterU8;
+ ftc=stream->readS16();
+ hps=stream->readU16();
+ iStartAt=stream->readU16();
+ dxaIndent=stream->readU16();
+ dxaSpace=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void ANLV::readPtr(const U8 *ptr) {
+
+ U8 shifterU8;
+
+ nfc=readU8(ptr);
+ ptr+=sizeof(U8);
+ cxchTextBefore=readU8(ptr);
+ ptr+=sizeof(U8);
+ cxchTextAfter=readU8(ptr);
+ ptr+=sizeof(U8);
+ shifterU8=readU8(ptr);
+ ptr+=sizeof(U8);
+ jc=shifterU8;
+ shifterU8>>=2;
+ fPrev=shifterU8;
+ shifterU8>>=1;
+ fHang=shifterU8;
+ shifterU8>>=1;
+ fSetBold=shifterU8;
+ shifterU8>>=1;
+ fSetItalic=shifterU8;
+ shifterU8>>=1;
+ fSetSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fSetCaps=shifterU8;
+ shifterU8=readU8(ptr);
+ ptr+=sizeof(U8);
+ fSetStrike=shifterU8;
+ shifterU8>>=1;
+ fSetKul=shifterU8;
+ shifterU8>>=1;
+ fPrevSpace=shifterU8;
+ shifterU8>>=1;
+ fBold=shifterU8;
+ shifterU8>>=1;
+ fItalic=shifterU8;
+ shifterU8>>=1;
+ fSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fCaps=shifterU8;
+ shifterU8>>=1;
+ fStrike=shifterU8;
+ shifterU8=readU8(ptr);
+ ptr+=sizeof(U8);
+ kul=shifterU8;
+ shifterU8>>=3;
+ ico=shifterU8;
+ ftc=readS16(ptr);
+ ptr+=sizeof(S16);
+ hps=readU16(ptr);
+ ptr+=sizeof(U16);
+ iStartAt=readU16(ptr);
+ ptr+=sizeof(U16);
+ dxaIndent=readU16(ptr);
+ ptr+=sizeof(U16);
+ dxaSpace=readU16(ptr);
+ ptr+=sizeof(U16);
+}
+
+bool ANLV::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(nfc);
+ stream->write(cxchTextBefore);
+ stream->write(cxchTextAfter);
+ shifterU8=jc;
+ shifterU8|=fPrev << 2;
+ shifterU8|=fHang << 3;
+ shifterU8|=fSetBold << 4;
+ shifterU8|=fSetItalic << 5;
+ shifterU8|=fSetSmallCaps << 6;
+ shifterU8|=fSetCaps << 7;
+ stream->write(shifterU8);
+ shifterU8=fSetStrike;
+ shifterU8|=fSetKul << 1;
+ shifterU8|=fPrevSpace << 2;
+ shifterU8|=fBold << 3;
+ shifterU8|=fItalic << 4;
+ shifterU8|=fSmallCaps << 5;
+ shifterU8|=fCaps << 6;
+ shifterU8|=fStrike << 7;
+ stream->write(shifterU8);
+ shifterU8=kul;
+ shifterU8|=ico << 3;
+ stream->write(shifterU8);
+ stream->write(ftc);
+ stream->write(hps);
+ stream->write(iStartAt);
+ stream->write(dxaIndent);
+ stream->write(dxaSpace);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void ANLV::clear() {
+ nfc=0;
+ cxchTextBefore=0;
+ cxchTextAfter=0;
+ jc=0;
+ fPrev=0;
+ fHang=0;
+ fSetBold=0;
+ fSetItalic=0;
+ fSetSmallCaps=0;
+ fSetCaps=0;
+ fSetStrike=0;
+ fSetKul=0;
+ fPrevSpace=0;
+ fBold=0;
+ fItalic=0;
+ fSmallCaps=0;
+ fCaps=0;
+ fStrike=0;
+ kul=0;
+ ico=0;
+ ftc=0;
+ hps=0;
+ iStartAt=0;
+ dxaIndent=0;
+ dxaSpace=0;
+}
+
+void ANLV::dump() const
+{
+ wvlog << "Dumping ANLV:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping ANLV done." << std::endl;
+}
+
+std::string ANLV::toString() const
+{
+ std::string s( "ANLV:" );
+ s += "\nnfc=";
+ s += uint2string( nfc );
+ s += "\ncxchTextBefore=";
+ s += uint2string( cxchTextBefore );
+ s += "\ncxchTextAfter=";
+ s += uint2string( cxchTextAfter );
+ s += "\njc=";
+ s += uint2string( jc );
+ s += "\nfPrev=";
+ s += uint2string( fPrev );
+ s += "\nfHang=";
+ s += uint2string( fHang );
+ s += "\nfSetBold=";
+ s += uint2string( fSetBold );
+ s += "\nfSetItalic=";
+ s += uint2string( fSetItalic );
+ s += "\nfSetSmallCaps=";
+ s += uint2string( fSetSmallCaps );
+ s += "\nfSetCaps=";
+ s += uint2string( fSetCaps );
+ s += "\nfSetStrike=";
+ s += uint2string( fSetStrike );
+ s += "\nfSetKul=";
+ s += uint2string( fSetKul );
+ s += "\nfPrevSpace=";
+ s += uint2string( fPrevSpace );
+ s += "\nfBold=";
+ s += uint2string( fBold );
+ s += "\nfItalic=";
+ s += uint2string( fItalic );
+ s += "\nfSmallCaps=";
+ s += uint2string( fSmallCaps );
+ s += "\nfCaps=";
+ s += uint2string( fCaps );
+ s += "\nfStrike=";
+ s += uint2string( fStrike );
+ s += "\nkul=";
+ s += uint2string( kul );
+ s += "\nico=";
+ s += uint2string( ico );
+ s += "\nftc=";
+ s += int2string( ftc );
+ s += "\nhps=";
+ s += uint2string( hps );
+ s += "\niStartAt=";
+ s += uint2string( iStartAt );
+ s += "\ndxaIndent=";
+ s += uint2string( dxaIndent );
+ s += "\ndxaSpace=";
+ s += uint2string( dxaSpace );
+ s += "\nANLV Done.";
+ return s;
+}
+
+bool operator==(const ANLV &lhs, const ANLV &rhs) {
+
+ return lhs.nfc==rhs.nfc &&
+ lhs.cxchTextBefore==rhs.cxchTextBefore &&
+ lhs.cxchTextAfter==rhs.cxchTextAfter &&
+ lhs.jc==rhs.jc &&
+ lhs.fPrev==rhs.fPrev &&
+ lhs.fHang==rhs.fHang &&
+ lhs.fSetBold==rhs.fSetBold &&
+ lhs.fSetItalic==rhs.fSetItalic &&
+ lhs.fSetSmallCaps==rhs.fSetSmallCaps &&
+ lhs.fSetCaps==rhs.fSetCaps &&
+ lhs.fSetStrike==rhs.fSetStrike &&
+ lhs.fSetKul==rhs.fSetKul &&
+ lhs.fPrevSpace==rhs.fPrevSpace &&
+ lhs.fBold==rhs.fBold &&
+ lhs.fItalic==rhs.fItalic &&
+ lhs.fSmallCaps==rhs.fSmallCaps &&
+ lhs.fCaps==rhs.fCaps &&
+ lhs.fStrike==rhs.fStrike &&
+ lhs.kul==rhs.kul &&
+ lhs.ico==rhs.ico &&
+ lhs.ftc==rhs.ftc &&
+ lhs.hps==rhs.hps &&
+ lhs.iStartAt==rhs.iStartAt &&
+ lhs.dxaIndent==rhs.dxaIndent &&
+ lhs.dxaSpace==rhs.dxaSpace;
+}
+
+bool operator!=(const ANLV &lhs, const ANLV &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// ASUMY implementation
+
+ASUMY::ASUMY() {
+ clear();
+}
+
+ASUMY::ASUMY(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool ASUMY::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ lLevel=stream->readS32();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool ASUMY::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(lLevel);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void ASUMY::clear() {
+ lLevel=0;
+}
+
+bool operator==(const ASUMY &lhs, const ASUMY &rhs) {
+
+ return lhs.lLevel==rhs.lLevel;
+}
+
+bool operator!=(const ASUMY &lhs, const ASUMY &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// ASUMYI implementation
+
+ASUMYI::ASUMYI() {
+ clear();
+}
+
+ASUMYI::ASUMYI(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool ASUMYI::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ fValid=shifterU16;
+ shifterU16>>=1;
+ fView=shifterU16;
+ shifterU16>>=1;
+ iViewBy=shifterU16;
+ shifterU16>>=2;
+ fUpdateProps=shifterU16;
+ shifterU16>>=1;
+ unused0_5=shifterU16;
+ wDlgLevel=stream->readS16();
+ lHighestLevel=stream->readS32();
+ lCurrentLevel=stream->readS32();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool ASUMYI::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=fValid;
+ shifterU16|=fView << 1;
+ shifterU16|=iViewBy << 2;
+ shifterU16|=fUpdateProps << 4;
+ shifterU16|=unused0_5 << 5;
+ stream->write(shifterU16);
+ stream->write(wDlgLevel);
+ stream->write(lHighestLevel);
+ stream->write(lCurrentLevel);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void ASUMYI::clear() {
+ fValid=0;
+ fView=0;
+ iViewBy=0;
+ fUpdateProps=0;
+ unused0_5=0;
+ wDlgLevel=0;
+ lHighestLevel=0;
+ lCurrentLevel=0;
+}
+
+bool operator==(const ASUMYI &lhs, const ASUMYI &rhs) {
+
+ return lhs.fValid==rhs.fValid &&
+ lhs.fView==rhs.fView &&
+ lhs.iViewBy==rhs.iViewBy &&
+ lhs.fUpdateProps==rhs.fUpdateProps &&
+ lhs.unused0_5==rhs.unused0_5 &&
+ lhs.wDlgLevel==rhs.wDlgLevel &&
+ lhs.lHighestLevel==rhs.lHighestLevel &&
+ lhs.lCurrentLevel==rhs.lCurrentLevel;
+}
+
+bool operator!=(const ASUMYI &lhs, const ASUMYI &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// ATRD implementation
+
+ATRD::ATRD() {
+ clear();
+}
+
+ATRD::ATRD(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool ATRD::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ for(int _i=0; _i<(10); ++_i)
+ xstUsrInitl[_i]=stream->readU16();
+ ibst=stream->readS16();
+ shifterU16=stream->readU16();
+ ak=shifterU16;
+ shifterU16>>=2;
+ unused22_2=shifterU16;
+ grfbmc=stream->readU16();
+ lTagBkmk=stream->readS32();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool ATRD::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ for(int _i=0; _i<(10); ++_i)
+ stream->write(xstUsrInitl[_i]);
+ stream->write(ibst);
+ shifterU16=ak;
+ shifterU16|=unused22_2 << 2;
+ stream->write(shifterU16);
+ stream->write(grfbmc);
+ stream->write(lTagBkmk);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void ATRD::clear() {
+ for(int _i=0; _i<(10); ++_i)
+ xstUsrInitl[_i]=0;
+ ibst=0;
+ ak=0;
+ unused22_2=0;
+ grfbmc=0;
+ lTagBkmk=0;
+}
+
+bool operator==(const ATRD &lhs, const ATRD &rhs) {
+
+ for(int _i=0; _i<(10); ++_i) {
+ if(lhs.xstUsrInitl[_i]!=rhs.xstUsrInitl[_i])
+ return false;
+ }
+
+ return lhs.ibst==rhs.ibst &&
+ lhs.ak==rhs.ak &&
+ lhs.unused22_2==rhs.unused22_2 &&
+ lhs.grfbmc==rhs.grfbmc &&
+ lhs.lTagBkmk==rhs.lTagBkmk;
+}
+
+bool operator!=(const ATRD &lhs, const ATRD &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// BKD implementation
+
+const unsigned int BKD::sizeOf = 6;
+
+BKD::BKD() {
+ clear();
+}
+
+BKD::BKD(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool BKD::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ ipgd_itxbxs=stream->readS16();
+ dcpDepend=stream->readS16();
+ shifterU16=stream->readU16();
+ icol=shifterU16;
+ shifterU16>>=8;
+ fTableBreak=shifterU16;
+ shifterU16>>=1;
+ fColumnBreak=shifterU16;
+ shifterU16>>=1;
+ fMarked=shifterU16;
+ shifterU16>>=1;
+ fUnk=shifterU16;
+ shifterU16>>=1;
+ fTextOverflow=shifterU16;
+ shifterU16>>=1;
+ unused4_13=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool BKD::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(ipgd_itxbxs);
+ stream->write(dcpDepend);
+ shifterU16=icol;
+ shifterU16|=fTableBreak << 8;
+ shifterU16|=fColumnBreak << 9;
+ shifterU16|=fMarked << 10;
+ shifterU16|=fUnk << 11;
+ shifterU16|=fTextOverflow << 12;
+ shifterU16|=unused4_13 << 13;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void BKD::clear() {
+ ipgd_itxbxs=0;
+ dcpDepend=0;
+ icol=0;
+ fTableBreak=0;
+ fColumnBreak=0;
+ fMarked=0;
+ fUnk=0;
+ fTextOverflow=0;
+ unused4_13=0;
+}
+
+bool operator==(const BKD &lhs, const BKD &rhs) {
+
+ return lhs.ipgd_itxbxs==rhs.ipgd_itxbxs &&
+ lhs.dcpDepend==rhs.dcpDepend &&
+ lhs.icol==rhs.icol &&
+ lhs.fTableBreak==rhs.fTableBreak &&
+ lhs.fColumnBreak==rhs.fColumnBreak &&
+ lhs.fMarked==rhs.fMarked &&
+ lhs.fUnk==rhs.fUnk &&
+ lhs.fTextOverflow==rhs.fTextOverflow &&
+ lhs.unused4_13==rhs.unused4_13;
+}
+
+bool operator!=(const BKD &lhs, const BKD &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// BKF implementation
+
+BKF::BKF() {
+ clear();
+}
+
+BKF::BKF(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool BKF::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ ibkl=stream->readS16();
+ shifterU16=stream->readU16();
+ itcFirst=shifterU16;
+ shifterU16>>=7;
+ fPub=shifterU16;
+ shifterU16>>=1;
+ itcLim=shifterU16;
+ shifterU16>>=7;
+ fCol=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool BKF::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(ibkl);
+ shifterU16=itcFirst;
+ shifterU16|=fPub << 7;
+ shifterU16|=itcLim << 8;
+ shifterU16|=fCol << 15;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void BKF::clear() {
+ ibkl=0;
+ itcFirst=0;
+ fPub=0;
+ itcLim=0;
+ fCol=0;
+}
+
+bool operator==(const BKF &lhs, const BKF &rhs) {
+
+ return lhs.ibkl==rhs.ibkl &&
+ lhs.itcFirst==rhs.itcFirst &&
+ lhs.fPub==rhs.fPub &&
+ lhs.itcLim==rhs.itcLim &&
+ lhs.fCol==rhs.fCol;
+}
+
+bool operator!=(const BKF &lhs, const BKF &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// BKL implementation
+
+BKL::BKL() {
+ clear();
+}
+
+BKL::BKL(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool BKL::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ ibkf=stream->readS16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool BKL::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(ibkf);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void BKL::clear() {
+ ibkf=0;
+}
+
+bool operator==(const BKL &lhs, const BKL &rhs) {
+
+ return lhs.ibkf==rhs.ibkf;
+}
+
+bool operator!=(const BKL &lhs, const BKL &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// BRC10 implementation
+
+BRC10::BRC10() {
+ clear();
+}
+
+BRC10::BRC10(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool BRC10::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ dxpLine2Width=shifterU16;
+ shifterU16>>=3;
+ dxpSpaceBetween=shifterU16;
+ shifterU16>>=3;
+ dxpLine1Width=shifterU16;
+ shifterU16>>=3;
+ dxpSpace=shifterU16;
+ shifterU16>>=5;
+ fShadow=shifterU16;
+ shifterU16>>=1;
+ fSpare=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool BRC10::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=dxpLine2Width;
+ shifterU16|=dxpSpaceBetween << 3;
+ shifterU16|=dxpLine1Width << 6;
+ shifterU16|=dxpSpace << 9;
+ shifterU16|=fShadow << 14;
+ shifterU16|=fSpare << 15;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void BRC10::clear() {
+ dxpLine2Width=0;
+ dxpSpaceBetween=0;
+ dxpLine1Width=0;
+ dxpSpace=0;
+ fShadow=0;
+ fSpare=0;
+}
+
+bool operator==(const BRC10 &lhs, const BRC10 &rhs) {
+
+ return lhs.dxpLine2Width==rhs.dxpLine2Width &&
+ lhs.dxpSpaceBetween==rhs.dxpSpaceBetween &&
+ lhs.dxpLine1Width==rhs.dxpLine1Width &&
+ lhs.dxpSpace==rhs.dxpSpace &&
+ lhs.fShadow==rhs.fShadow &&
+ lhs.fSpare==rhs.fSpare;
+}
+
+bool operator!=(const BRC10 &lhs, const BRC10 &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// BTE implementation
+
+const unsigned int BTE::sizeOf = 4;
+
+BTE::BTE() {
+ clear();
+}
+
+BTE::BTE(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool BTE::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ pn=stream->readU32();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool BTE::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(pn);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void BTE::clear() {
+ pn=0;
+}
+
+bool operator==(const BTE &lhs, const BTE &rhs) {
+
+ return lhs.pn==rhs.pn;
+}
+
+bool operator!=(const BTE &lhs, const BTE &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// CHP implementation
+
+CHP::CHP() : Shared() {
+ clear();
+}
+
+CHP::CHP(OLEStreamReader *stream, bool preservePos) : Shared() {
+ clear();
+ read(stream, preservePos);
+}
+
+bool CHP::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU8=stream->readU8();
+ fBold=shifterU8;
+ shifterU8>>=1;
+ fItalic=shifterU8;
+ shifterU8>>=1;
+ fRMarkDel=shifterU8;
+ shifterU8>>=1;
+ fOutline=shifterU8;
+ shifterU8>>=1;
+ fFldVanish=shifterU8;
+ shifterU8>>=1;
+ fSmallCaps=shifterU8;
+ shifterU8>>=1;
+ fCaps=shifterU8;
+ shifterU8>>=1;
+ fVanish=shifterU8;
+ shifterU8=stream->readU8();
+ fRMark=shifterU8;
+ shifterU8>>=1;
+ fSpec=shifterU8;
+ shifterU8>>=1;
+ fStrike=shifterU8;
+ shifterU8>>=1;
+ fObj=shifterU8;
+ shifterU8>>=1;
+ fShadow=shifterU8;
+ shifterU8>>=1;
+ fLowerCase=shifterU8;
+ shifterU8>>=1;
+ fData=shifterU8;
+ shifterU8>>=1;
+ fOle2=shifterU8;
+ shifterU16=stream->readU16();
+ fEmboss=shifterU16;
+ shifterU16>>=1;
+ fImprint=shifterU16;
+ shifterU16>>=1;
+ fDStrike=shifterU16;
+ shifterU16>>=1;
+ fUsePgsuSettings=shifterU16;
+ shifterU16>>=1;
+ unused2_4=shifterU16;
+ unused4=stream->readS32();
+ ftc=stream->readS16();
+ ftcAscii=stream->readS16();
+ ftcFE=stream->readS16();
+ ftcOther=stream->readS16();
+ hps=stream->readU16();
+ dxaSpace=stream->readS32();
+ shifterU8=stream->readU8();
+ iss=shifterU8;
+ shifterU8>>=3;
+ kul=shifterU8;
+ shifterU8>>=4;
+ fSpecSymbol=shifterU8;
+ shifterU8=stream->readU8();
+ //ico=shifterU8;
+ shifterU8>>=5;
+ unused23_5=shifterU8;
+ shifterU8>>=1;
+ fSysVanish=shifterU8;
+ shifterU8>>=1;
+ hpScript=shifterU8;
+ hpsPos=stream->readS16();
+ lid=stream->readU16();
+ lidDefault=stream->readU16();
+ lidFE=stream->readU16();
+ idct=stream->readU8();
+ idctHint=stream->readU8();
+ wCharScale=stream->readU16();
+ fcPic_fcObj_lTagObj=stream->readS32();
+ ibstRMark=stream->readS16();
+ ibstRMarkDel=stream->readS16();
+ dttmRMark.read(stream, false);
+ dttmRMarkDel.read(stream, false);
+ unused52=stream->readS16();
+ istd=stream->readU16();
+ ftcSym=stream->readS16();
+ xchSym=stream->readU16();
+ idslRMReason=stream->readS16();
+ idslRMReasonDel=stream->readS16();
+ ysr=stream->readU8();
+ chYsr=stream->readU8();
+ chse=stream->readU16();
+ hpsKern=stream->readU16();
+ shifterU16=stream->readU16();
+ icoHighlight=shifterU16;
+ shifterU16>>=5;
+ fHighlight=shifterU16;
+ shifterU16>>=1;
+ kcd=shifterU16;
+ shifterU16>>=3;
+ fNavHighlight=shifterU16;
+ shifterU16>>=1;
+ fChsDiff=shifterU16;
+ shifterU16>>=1;
+ fMacChs=shifterU16;
+ shifterU16>>=1;
+ fFtcAsciSym=shifterU16;
+ shifterU16>>=1;
+ reserved_3=shifterU16;
+ fPropMark=stream->readU16();
+ ibstPropRMark=stream->readS16();
+ dttmPropRMark.read(stream, false);
+ sfxtText=stream->readU8();
+ unused81=stream->readU8();
+ unused82=stream->readU8();
+ unused83=stream->readU16();
+ unused85=stream->readS16();
+ unused87=stream->readU32();
+ fDispFldRMark=stream->readS8();
+ ibstDispFldRMark=stream->readS16();
+ dttmDispFldRMark=stream->readU32();
+ for(int _i=0; _i<(16); ++_i)
+ xstDispFldRMark[_i]=stream->readU16();
+ shd.read(stream, false);
+ brc.read(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool CHP::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU8=fBold;
+ shifterU8|=fItalic << 1;
+ shifterU8|=fRMarkDel << 2;
+ shifterU8|=fOutline << 3;
+ shifterU8|=fFldVanish << 4;
+ shifterU8|=fSmallCaps << 5;
+ shifterU8|=fCaps << 6;
+ shifterU8|=fVanish << 7;
+ stream->write(shifterU8);
+ shifterU8=fRMark;
+ shifterU8|=fSpec << 1;
+ shifterU8|=fStrike << 2;
+ shifterU8|=fObj << 3;
+ shifterU8|=fShadow << 4;
+ shifterU8|=fLowerCase << 5;
+ shifterU8|=fData << 6;
+ shifterU8|=fOle2 << 7;
+ stream->write(shifterU8);
+ shifterU16=fEmboss;
+ shifterU16|=fImprint << 1;
+ shifterU16|=fDStrike << 2;
+ shifterU16|=fUsePgsuSettings << 3;
+ shifterU16|=unused2_4 << 4;
+ stream->write(shifterU16);
+ stream->write(unused4);
+ stream->write(ftc);
+ stream->write(ftcAscii);
+ stream->write(ftcFE);
+ stream->write(ftcOther);
+ stream->write(hps);
+ stream->write(dxaSpace);
+ shifterU8=iss;
+ shifterU8|=kul << 3;
+ shifterU8|=fSpecSymbol << 7;
+ stream->write(shifterU8);
+ shifterU8=0; //Was ico
+ shifterU8|=unused23_5 << 5;
+ shifterU8|=fSysVanish << 6;
+ shifterU8|=hpScript << 7;
+ stream->write(shifterU8);
+ stream->write(hpsPos);
+ stream->write(lid);
+ stream->write(lidDefault);
+ stream->write(lidFE);
+ stream->write(idct);
+ stream->write(idctHint);
+ stream->write(wCharScale);
+ stream->write(fcPic_fcObj_lTagObj);
+ stream->write(ibstRMark);
+ stream->write(ibstRMarkDel);
+ dttmRMark.write(stream, false);
+ dttmRMarkDel.write(stream, false);
+ stream->write(unused52);
+ stream->write(istd);
+ stream->write(ftcSym);
+ stream->write(xchSym);
+ stream->write(idslRMReason);
+ stream->write(idslRMReasonDel);
+ stream->write(ysr);
+ stream->write(chYsr);
+ stream->write(chse);
+ stream->write(hpsKern);
+ shifterU16=icoHighlight;
+ shifterU16|=fHighlight << 5;
+ shifterU16|=kcd << 6;
+ shifterU16|=fNavHighlight << 9;
+ shifterU16|=fChsDiff << 10;
+ shifterU16|=fMacChs << 11;
+ shifterU16|=fFtcAsciSym << 12;
+ shifterU16|=reserved_3 << 13;
+ stream->write(shifterU16);
+ stream->write(fPropMark);
+ stream->write(ibstPropRMark);
+ dttmPropRMark.write(stream, false);
+ stream->write(sfxtText);
+ stream->write(unused81);
+ stream->write(unused82);
+ stream->write(unused83);
+ stream->write(unused85);
+ stream->write(unused87);
+ stream->write(fDispFldRMark);
+ stream->write(ibstDispFldRMark);
+ stream->write(dttmDispFldRMark);
+ for(int _i=0; _i<(16); ++_i)
+ stream->write(xstDispFldRMark[_i]);
+ shd.write(stream, false);
+ brc.write(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void CHP::clear() {
+ fBold=0;
+ fItalic=0;
+ fRMarkDel=0;
+ fOutline=0;
+ fFldVanish=0;
+ fSmallCaps=0;
+ fCaps=0;
+ fVanish=0;
+ fRMark=0;
+ fSpec=0;
+ fStrike=0;
+ fObj=0;
+ fShadow=0;
+ fLowerCase=0;
+ fData=0;
+ fOle2=0;
+ fEmboss=0;
+ fImprint=0;
+ fDStrike=0;
+ fUsePgsuSettings=0;
+ unused2_4=0;
+ unused4=0;
+ ftc=0;
+ ftcAscii=0;
+ ftcFE=0;
+ ftcOther=0;
+ hps=20;
+ dxaSpace=0;
+ iss=0;
+ kul=0;
+ fSpecSymbol=0;
+ unused23_5=0;
+ fSysVanish=0;
+ hpScript=0;
+ hpsPos=0;
+ lid=0x0400;
+ lidDefault=0x0400;
+ lidFE=0x0400;
+ idct=0;
+ idctHint=0;
+ wCharScale=100;
+ fcPic_fcObj_lTagObj=-1;
+ ibstRMark=0;
+ ibstRMarkDel=0;
+ dttmRMark.clear();
+ dttmRMarkDel.clear();
+ unused52=0;
+ istd=10;
+ ftcSym=0;
+ xchSym=0;
+ idslRMReason=0;
+ idslRMReasonDel=0;
+ ysr=0;
+ chYsr=0;
+ chse=0;
+ hpsKern=0;
+ icoHighlight=0;
+ fHighlight=0;
+ kcd=0;
+ fNavHighlight=0;
+ fChsDiff=0;
+ fMacChs=0;
+ fFtcAsciSym=0;
+ reserved_3=0;
+ fPropMark=0;
+ ibstPropRMark=0;
+ dttmPropRMark.clear();
+ sfxtText=0;
+ unused81=0;
+ unused82=0;
+ unused83=0;
+ unused85=0;
+ unused87=0;
+ fDispFldRMark=0;
+ ibstDispFldRMark=0;
+ dttmDispFldRMark=0;
+ for(int _i=0; _i<(16); ++_i)
+ xstDispFldRMark[_i]=0;
+ shd.clear();
+ brc.clear();
+ cv=0;
+}
+
+void CHP::dump() const
+{
+ wvlog << "Dumping CHP:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping CHP done." << std::endl;
+}
+
+std::string CHP::toString() const
+{
+ std::string s( "CHP:" );
+ s += "\nfBold=";
+ s += uint2string( fBold );
+ s += "\nfItalic=";
+ s += uint2string( fItalic );
+ s += "\nfRMarkDel=";
+ s += uint2string( fRMarkDel );
+ s += "\nfOutline=";
+ s += uint2string( fOutline );
+ s += "\nfFldVanish=";
+ s += uint2string( fFldVanish );
+ s += "\nfSmallCaps=";
+ s += uint2string( fSmallCaps );
+ s += "\nfCaps=";
+ s += uint2string( fCaps );
+ s += "\nfVanish=";
+ s += uint2string( fVanish );
+ s += "\nfRMark=";
+ s += uint2string( fRMark );
+ s += "\nfSpec=";
+ s += uint2string( fSpec );
+ s += "\nfStrike=";
+ s += uint2string( fStrike );
+ s += "\nfObj=";
+ s += uint2string( fObj );
+ s += "\nfShadow=";
+ s += uint2string( fShadow );
+ s += "\nfLowerCase=";
+ s += uint2string( fLowerCase );
+ s += "\nfData=";
+ s += uint2string( fData );
+ s += "\nfOle2=";
+ s += uint2string( fOle2 );
+ s += "\nfEmboss=";
+ s += uint2string( fEmboss );
+ s += "\nfImprint=";
+ s += uint2string( fImprint );
+ s += "\nfDStrike=";
+ s += uint2string( fDStrike );
+ s += "\nfUsePgsuSettings=";
+ s += uint2string( fUsePgsuSettings );
+ s += "\nunused2_4=";
+ s += uint2string( unused2_4 );
+ s += "\nunused4=";
+ s += int2string( unused4 );
+ s += "\nftc=";
+ s += int2string( ftc );
+ s += "\nftcAscii=";
+ s += int2string( ftcAscii );
+ s += "\nftcFE=";
+ s += int2string( ftcFE );
+ s += "\nftcOther=";
+ s += int2string( ftcOther );
+ s += "\nhps=";
+ s += uint2string( hps );
+ s += "\ndxaSpace=";
+ s += int2string( dxaSpace );
+ s += "\niss=";
+ s += uint2string( iss );
+ s += "\nkul=";
+ s += uint2string( kul );
+ s += "\nfSpecSymbol=";
+ s += uint2string( fSpecSymbol );
+ s += "\nunused23_5=";
+ s += uint2string( unused23_5 );
+ s += "\nfSysVanish=";
+ s += uint2string( fSysVanish );
+ s += "\nhpScript=";
+ s += uint2string( hpScript );
+ s += "\nhpsPos=";
+ s += int2string( hpsPos );
+ s += "\nlid=";
+ s += uint2string( lid );
+ s += "\nlidDefault=";
+ s += uint2string( lidDefault );
+ s += "\nlidFE=";
+ s += uint2string( lidFE );
+ s += "\nidct=";
+ s += uint2string( idct );
+ s += "\nidctHint=";
+ s += uint2string( idctHint );
+ s += "\nwCharScale=";
+ s += uint2string( wCharScale );
+ s += "\nfcPic_fcObj_lTagObj=";
+ s += int2string( fcPic_fcObj_lTagObj );
+ s += "\nibstRMark=";
+ s += int2string( ibstRMark );
+ s += "\nibstRMarkDel=";
+ s += int2string( ibstRMarkDel );
+ s += "\ndttmRMark=";
+ s += "\n{" + dttmRMark.toString() + "}\n";
+ s += "\ndttmRMarkDel=";
+ s += "\n{" + dttmRMarkDel.toString() + "}\n";
+ s += "\nunused52=";
+ s += int2string( unused52 );
+ s += "\nistd=";
+ s += uint2string( istd );
+ s += "\nftcSym=";
+ s += int2string( ftcSym );
+ s += "\nxchSym=";
+ s += uint2string( xchSym );
+ s += "\nidslRMReason=";
+ s += int2string( idslRMReason );
+ s += "\nidslRMReasonDel=";
+ s += int2string( idslRMReasonDel );
+ s += "\nysr=";
+ s += uint2string( ysr );
+ s += "\nchYsr=";
+ s += uint2string( chYsr );
+ s += "\nchse=";
+ s += uint2string( chse );
+ s += "\nhpsKern=";
+ s += uint2string( hpsKern );
+ s += "\nicoHighlight=";
+ s += uint2string( icoHighlight );
+ s += "\nfHighlight=";
+ s += uint2string( fHighlight );
+ s += "\nkcd=";
+ s += uint2string( kcd );
+ s += "\nfNavHighlight=";
+ s += uint2string( fNavHighlight );
+ s += "\nfChsDiff=";
+ s += uint2string( fChsDiff );
+ s += "\nfMacChs=";
+ s += uint2string( fMacChs );
+ s += "\nfFtcAsciSym=";
+ s += uint2string( fFtcAsciSym );
+ s += "\nreserved_3=";
+ s += uint2string( reserved_3 );
+ s += "\nfPropMark=";
+ s += uint2string( fPropMark );
+ s += "\nibstPropRMark=";
+ s += int2string( ibstPropRMark );
+ s += "\ndttmPropRMark=";
+ s += "\n{" + dttmPropRMark.toString() + "}\n";
+ s += "\nsfxtText=";
+ s += uint2string( sfxtText );
+ s += "\nunused81=";
+ s += uint2string( unused81 );
+ s += "\nunused82=";
+ s += uint2string( unused82 );
+ s += "\nunused83=";
+ s += uint2string( unused83 );
+ s += "\nunused85=";
+ s += int2string( unused85 );
+ s += "\nunused87=";
+ s += uint2string( unused87 );
+ s += "\nfDispFldRMark=";
+ s += int2string( fDispFldRMark );
+ s += "\nibstDispFldRMark=";
+ s += int2string( ibstDispFldRMark );
+ s += "\ndttmDispFldRMark=";
+ s += uint2string( dttmDispFldRMark );
+ for(int _i=0; _i<(16); ++_i) {
+ s += "\nxstDispFldRMark[" + int2string( _i ) + "]=";
+ s += uint2string( xstDispFldRMark[_i] );
+ }
+ s += "\nshd=";
+ s += "\n{" + shd.toString() + "}\n";
+ s += "\nbrc=";
+ s += "\n{" + brc.toString() + "}\n";
+ s += "\nCHP Done.";
+ return s;
+}
+
+bool operator==(const CHP &lhs, const CHP &rhs) {
+
+ for(int _i=0; _i<(16); ++_i) {
+ if(lhs.xstDispFldRMark[_i]!=rhs.xstDispFldRMark[_i])
+ return false;
+ }
+
+ return lhs.fBold==rhs.fBold &&
+ lhs.fItalic==rhs.fItalic &&
+ lhs.fRMarkDel==rhs.fRMarkDel &&
+ lhs.fOutline==rhs.fOutline &&
+ lhs.fFldVanish==rhs.fFldVanish &&
+ lhs.fSmallCaps==rhs.fSmallCaps &&
+ lhs.fCaps==rhs.fCaps &&
+ lhs.fVanish==rhs.fVanish &&
+ lhs.fRMark==rhs.fRMark &&
+ lhs.fSpec==rhs.fSpec &&
+ lhs.fStrike==rhs.fStrike &&
+ lhs.fObj==rhs.fObj &&
+ lhs.fShadow==rhs.fShadow &&
+ lhs.fLowerCase==rhs.fLowerCase &&
+ lhs.fData==rhs.fData &&
+ lhs.fOle2==rhs.fOle2 &&
+ lhs.fEmboss==rhs.fEmboss &&
+ lhs.fImprint==rhs.fImprint &&
+ lhs.fDStrike==rhs.fDStrike &&
+ lhs.fUsePgsuSettings==rhs.fUsePgsuSettings &&
+ lhs.unused2_4==rhs.unused2_4 &&
+ lhs.unused4==rhs.unused4 &&
+ lhs.ftc==rhs.ftc &&
+ lhs.ftcAscii==rhs.ftcAscii &&
+ lhs.ftcFE==rhs.ftcFE &&
+ lhs.ftcOther==rhs.ftcOther &&
+ lhs.hps==rhs.hps &&
+ lhs.dxaSpace==rhs.dxaSpace &&
+ lhs.iss==rhs.iss &&
+ lhs.kul==rhs.kul &&
+ lhs.fSpecSymbol==rhs.fSpecSymbol &&
+ lhs.cv==rhs.cv &&
+ lhs.unused23_5==rhs.unused23_5 &&
+ lhs.fSysVanish==rhs.fSysVanish &&
+ lhs.hpScript==rhs.hpScript &&
+ lhs.hpsPos==rhs.hpsPos &&
+ lhs.lid==rhs.lid &&
+ lhs.lidDefault==rhs.lidDefault &&
+ lhs.lidFE==rhs.lidFE &&
+ lhs.idct==rhs.idct &&
+ lhs.idctHint==rhs.idctHint &&
+ lhs.wCharScale==rhs.wCharScale &&
+ lhs.fcPic_fcObj_lTagObj==rhs.fcPic_fcObj_lTagObj &&
+ lhs.ibstRMark==rhs.ibstRMark &&
+ lhs.ibstRMarkDel==rhs.ibstRMarkDel &&
+ lhs.dttmRMark==rhs.dttmRMark &&
+ lhs.dttmRMarkDel==rhs.dttmRMarkDel &&
+ lhs.unused52==rhs.unused52 &&
+ lhs.istd==rhs.istd &&
+ lhs.ftcSym==rhs.ftcSym &&
+ lhs.xchSym==rhs.xchSym &&
+ lhs.idslRMReason==rhs.idslRMReason &&
+ lhs.idslRMReasonDel==rhs.idslRMReasonDel &&
+ lhs.ysr==rhs.ysr &&
+ lhs.chYsr==rhs.chYsr &&
+ lhs.chse==rhs.chse &&
+ lhs.hpsKern==rhs.hpsKern &&
+ lhs.icoHighlight==rhs.icoHighlight &&
+ lhs.fHighlight==rhs.fHighlight &&
+ lhs.kcd==rhs.kcd &&
+ lhs.fNavHighlight==rhs.fNavHighlight &&
+ lhs.fChsDiff==rhs.fChsDiff &&
+ lhs.fMacChs==rhs.fMacChs &&
+ lhs.fFtcAsciSym==rhs.fFtcAsciSym &&
+ lhs.reserved_3==rhs.reserved_3 &&
+ lhs.fPropMark==rhs.fPropMark &&
+ lhs.ibstPropRMark==rhs.ibstPropRMark &&
+ lhs.dttmPropRMark==rhs.dttmPropRMark &&
+ lhs.sfxtText==rhs.sfxtText &&
+ lhs.unused81==rhs.unused81 &&
+ lhs.unused82==rhs.unused82 &&
+ lhs.unused83==rhs.unused83 &&
+ lhs.unused85==rhs.unused85 &&
+ lhs.unused87==rhs.unused87 &&
+ lhs.fDispFldRMark==rhs.fDispFldRMark &&
+ lhs.ibstDispFldRMark==rhs.ibstDispFldRMark &&
+ lhs.dttmDispFldRMark==rhs.dttmDispFldRMark &&
+ lhs.shd==rhs.shd &&
+ lhs.brc==rhs.brc;
+}
+
+bool operator!=(const CHP &lhs, const CHP &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// DCS implementation
+
+DCS::DCS() {
+ clear();
+}
+
+DCS::DCS(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+DCS::DCS(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool DCS::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU8=stream->readU8();
+ fdct=shifterU8;
+ shifterU8>>=3;
+ lines=shifterU8;
+ unused1=stream->readU8();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DCS::readPtr(const U8 *ptr) {
+
+ U8 shifterU8;
+
+ shifterU8=readU8(ptr);
+ ptr+=sizeof(U8);
+ fdct=shifterU8;
+ shifterU8>>=3;
+ lines=shifterU8;
+ unused1=readU8(ptr);
+ ptr+=sizeof(U8);
+}
+
+bool DCS::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU8=fdct;
+ shifterU8|=lines << 3;
+ stream->write(shifterU8);
+ stream->write(unused1);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DCS::clear() {
+ fdct=0;
+ lines=0;
+ unused1=0;
+}
+
+void DCS::dump() const
+{
+ wvlog << "Dumping DCS:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping DCS done." << std::endl;
+}
+
+std::string DCS::toString() const
+{
+ std::string s( "DCS:" );
+ s += "\nfdct=";
+ s += uint2string( fdct );
+ s += "\nlines=";
+ s += uint2string( lines );
+ s += "\nunused1=";
+ s += uint2string( unused1 );
+ s += "\nDCS Done.";
+ return s;
+}
+
+bool operator==(const DCS &lhs, const DCS &rhs) {
+
+ return lhs.fdct==rhs.fdct &&
+ lhs.lines==rhs.lines &&
+ lhs.unused1==rhs.unused1;
+}
+
+bool operator!=(const DCS &lhs, const DCS &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// DOGRID implementation
+
+DOGRID::DOGRID() {
+ clear();
+}
+
+DOGRID::DOGRID(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool DOGRID::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ xaGrid=stream->readS16();
+ yaGrid=stream->readS16();
+ dxaGrid=stream->readS16();
+ dyaGrid=stream->readS16();
+ shifterU16=stream->readU16();
+ dyGridDisplay=shifterU16;
+ shifterU16>>=7;
+ fTurnItOff=shifterU16;
+ shifterU16>>=1;
+ dxGridDisplay=shifterU16;
+ shifterU16>>=7;
+ fFollowMargins=shifterU16;
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool DOGRID::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(xaGrid);
+ stream->write(yaGrid);
+ stream->write(dxaGrid);
+ stream->write(dyaGrid);
+ shifterU16=dyGridDisplay;
+ shifterU16|=fTurnItOff << 7;
+ shifterU16|=dxGridDisplay << 8;
+ shifterU16|=fFollowMargins << 15;
+ stream->write(shifterU16);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DOGRID::clear() {
+ xaGrid=0;
+ yaGrid=0;
+ dxaGrid=0;
+ dyaGrid=0;
+ dyGridDisplay=0;
+ fTurnItOff=0;
+ dxGridDisplay=0;
+ fFollowMargins=0;
+}
+
+bool operator==(const DOGRID &lhs, const DOGRID &rhs) {
+
+ return lhs.xaGrid==rhs.xaGrid &&
+ lhs.yaGrid==rhs.yaGrid &&
+ lhs.dxaGrid==rhs.dxaGrid &&
+ lhs.dyaGrid==rhs.dyaGrid &&
+ lhs.dyGridDisplay==rhs.dyGridDisplay &&
+ lhs.fTurnItOff==rhs.fTurnItOff &&
+ lhs.dxGridDisplay==rhs.dxGridDisplay &&
+ lhs.fFollowMargins==rhs.fFollowMargins;
+}
+
+bool operator!=(const DOGRID &lhs, const DOGRID &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// DOP implementation
+
+DOP::DOP() {
+ clear();
+}
+
+DOP::DOP(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool DOP::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+ U16 shifterU16;
+ U32 shifterU32;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ fFacingPages=shifterU16;
+ shifterU16>>=1;
+ fWidowControl=shifterU16;
+ shifterU16>>=1;
+ fPMHMainDoc=shifterU16;
+ shifterU16>>=1;
+ grfSuppression=shifterU16;
+ shifterU16>>=2;
+ fpc=shifterU16;
+ shifterU16>>=2;
+ unused0_7=shifterU16;
+ shifterU16>>=1;
+ grpfIhdt=shifterU16;
+ shifterU16=stream->readU16();
+ rncFtn=shifterU16;
+ shifterU16>>=2;
+ nFtn=shifterU16;
+ shifterU8=stream->readU8();
+ fOutlineDirtySave=shifterU8;
+ shifterU8>>=1;
+ unused4_1=shifterU8;
+ shifterU8=stream->readU8();
+ fOnlyMacPics=shifterU8;
+ shifterU8>>=1;
+ fOnlyWinPics=shifterU8;
+ shifterU8>>=1;
+ fLabelDoc=shifterU8;
+ shifterU8>>=1;
+ fHyphCapitals=shifterU8;
+ shifterU8>>=1;
+ fAutoHyphen=shifterU8;
+ shifterU8>>=1;
+ fFormNoFields=shifterU8;
+ shifterU8>>=1;
+ fLinkStyles=shifterU8;
+ shifterU8>>=1;
+ fRevMarking=shifterU8;
+ shifterU8=stream->readU8();
+ fBackup=shifterU8;
+ shifterU8>>=1;
+ fExactCWords=shifterU8;
+ shifterU8>>=1;
+ fPagHidden=shifterU8;
+ shifterU8>>=1;
+ fPagResults=shifterU8;
+ shifterU8>>=1;
+ fLockAtn=shifterU8;
+ shifterU8>>=1;
+ fMirrorMargins=shifterU8;
+ shifterU8>>=1;
+ unused6_6=shifterU8;
+ shifterU8>>=1;
+ fDfltTrueType=shifterU8;
+ shifterU8=stream->readU8();
+ fPagSuppressTopSpacing=shifterU8;
+ shifterU8>>=1;
+ fProtEnabled=shifterU8;
+ shifterU8>>=1;
+ fDispFormFldSel=shifterU8;
+ shifterU8>>=1;
+ fRMView=shifterU8;
+ shifterU8>>=1;
+ fRMPrint=shifterU8;
+ shifterU8>>=1;
+ unused7_5=shifterU8;
+ shifterU8>>=1;
+ fLockRev=shifterU8;
+ shifterU8>>=1;
+ fEmbedFonts=shifterU8;
+ shifterU16=stream->readU16();
+ copts_fNoTabForInd=shifterU16;
+ shifterU16>>=1;
+ copts_fNoSpaceRaiseLower=shifterU16;
+ shifterU16>>=1;
+ copts_fSuppressSpbfAfterPageBreak=shifterU16;
+ shifterU16>>=1;
+ copts_fWrapTrailSpaces=shifterU16;
+ shifterU16>>=1;
+ copts_fMapPrintTextColor=shifterU16;
+ shifterU16>>=1;
+ copts_fNoColumnBalance=shifterU16;
+ shifterU16>>=1;
+ copts_fConvMailMergeEsc=shifterU16;
+ shifterU16>>=1;
+ copts_fSupressTopSpacing=shifterU16;
+ shifterU16>>=1;
+ copts_fOrigWordTableRules=shifterU16;
+ shifterU16>>=1;
+ copts_fTransparentMetafiles=shifterU16;
+ shifterU16>>=1;
+ copts_fShowBreaksInFrames=shifterU16;
+ shifterU16>>=1;
+ copts_fSwapBordersFacingPgs=shifterU16;
+ shifterU16>>=1;
+ unused8_12=shifterU16;
+ dxaTab=stream->readU16();
+ wSpare=stream->readU16();
+ dxaHotZ=stream->readU16();
+ cConsecHypLim=stream->readU16();
+ wSpare2=stream->readU16();
+ dttmCreated.read(stream, false);
+ dttmRevised.read(stream, false);
+ dttmLastPrint.read(stream, false);
+ nRevision=stream->readS16();
+ tmEdited=stream->readS32();
+ cWords=stream->readS32();
+ cCh=stream->readS32();
+ cPg=stream->readS16();
+ cParas=stream->readS32();
+ shifterU16=stream->readU16();
+ rncEdn=shifterU16;
+ shifterU16>>=2;
+ nEdn=shifterU16;
+ shifterU16=stream->readU16();
+ epc=shifterU16;
+ shifterU16>>=2;
+ nfcFtnRef=shifterU16;
+ shifterU16>>=4;
+ nfcEdnRef=shifterU16;
+ shifterU16>>=4;
+ fPrintFormData=shifterU16;
+ shifterU16>>=1;
+ fSaveFormData=shifterU16;
+ shifterU16>>=1;
+ fShadeFormData=shifterU16;
+ shifterU16>>=1;
+ unused54_13=shifterU16;
+ shifterU16>>=2;
+ fWCFtnEdn=shifterU16;
+ cLines=stream->readS32();
+ cWordsFtnEnd=stream->readS32();
+ cChFtnEdn=stream->readS32();
+ cPgFtnEdn=stream->readS16();
+ cParasFtnEdn=stream->readS32();
+ cLinesFtnEdn=stream->readS32();
+ lKeyProtDoc=stream->readS32();
+ shifterU16=stream->readU16();
+ wvkSaved=shifterU16;
+ shifterU16>>=3;
+ wScaleSaved=shifterU16;
+ shifterU16>>=9;
+ zkSaved=shifterU16;
+ shifterU16>>=2;
+ fRotateFontW6=shifterU16;
+ shifterU16>>=1;
+ iGutterPos=shifterU16;
+ shifterU32=stream->readU32();
+ fNoTabForInd=shifterU32;
+ shifterU32>>=1;
+ fNoSpaceRaiseLower=shifterU32;
+ shifterU32>>=1;
+ fSupressSpbfAfterPageBreak=shifterU32;
+ shifterU32>>=1;
+ fWrapTrailSpaces=shifterU32;
+ shifterU32>>=1;
+ fMapPrintTextColor=shifterU32;
+ shifterU32>>=1;
+ fNoColumnBalance=shifterU32;
+ shifterU32>>=1;
+ fConvMailMergeEsc=shifterU32;
+ shifterU32>>=1;
+ fSupressTopSpacing=shifterU32;
+ shifterU32>>=1;
+ fOrigWordTableRules=shifterU32;
+ shifterU32>>=1;
+ fTransparentMetafiles=shifterU32;
+ shifterU32>>=1;
+ fShowBreaksInFrames=shifterU32;
+ shifterU32>>=1;
+ fSwapBordersFacingPgs=shifterU32;
+ shifterU32>>=1;
+ unused84_12=shifterU32;
+ shifterU32>>=4;
+ fSuppressTopSpacingMac5=shifterU32;
+ shifterU32>>=1;
+ fTruncDxaExpand=shifterU32;
+ shifterU32>>=1;
+ fPrintBodyBeforeHdr=shifterU32;
+ shifterU32>>=1;
+ fNoLeading=shifterU32;
+ shifterU32>>=1;
+ unused84_20=shifterU32;
+ shifterU32>>=1;
+ fMWSmallCaps=shifterU32;
+ shifterU32>>=1;
+ unused84_22=shifterU32;
+ adt=stream->readU16();
+ doptypography.read(stream, false);
+ dogrid.read(stream, false);
+ shifterU16=stream->readU16();
+ reserved=shifterU16;
+ shifterU16>>=1;
+ lvl=shifterU16;
+ shifterU16>>=4;
+ fGramAllDone=shifterU16;
+ shifterU16>>=1;
+ fGramAllClean=shifterU16;
+ shifterU16>>=1;
+ fSubsetFonts=shifterU16;
+ shifterU16>>=1;
+ fHideLastVersion=shifterU16;
+ shifterU16>>=1;
+ fHtmlDoc=shifterU16;
+ shifterU16>>=1;
+ unused410_11=shifterU16;
+ shifterU16>>=1;
+ fSnapBorder=shifterU16;
+ shifterU16>>=1;
+ fIncludeHeader=shifterU16;
+ shifterU16>>=1;
+ fIncludeFooter=shifterU16;
+ shifterU16>>=1;
+ fForcePageSizePag=shifterU16;
+ shifterU16>>=1;
+ fMinFontSizePag=shifterU16;
+ shifterU16=stream->readU16();
+ fHaveVersions=shifterU16;
+ shifterU16>>=1;
+ fAutoVersion=shifterU16;
+ shifterU16>>=1;
+ unused412_2=shifterU16;
+ asumyi.read(stream, false);
+ cChWS=stream->readS32();
+ cChWSFtnEdn=stream->readS32();
+ grfDocEvents=stream->readS32();
+ shifterU32=stream->readU32();
+ fVirusPrompted=shifterU32;
+ shifterU32>>=1;
+ fVirusLoadSafe=shifterU32;
+ shifterU32>>=1;
+ KeyVirusSession30=shifterU32;
+ for(int _i=0; _i<(30); ++_i)
+ Spare[_i]=stream->readU8();
+ unused472=stream->readU32();
+ unused476=stream->readU32();
+ cDBC=stream->readS32();
+ cDBCFtnEdn=stream->readS32();
+ unused488=stream->readU32();
+ nfcFtnRef2=stream->readS16();
+ nfcEdnRef2=stream->readS16();
+ hpsZoonFontPag=stream->readS16();
+ dywDispPag=stream->readS16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool DOP::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+ U16 shifterU16;
+ U32 shifterU32;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=fFacingPages;
+ shifterU16|=fWidowControl << 1;
+ shifterU16|=fPMHMainDoc << 2;
+ shifterU16|=grfSuppression << 3;
+ shifterU16|=fpc << 5;
+ shifterU16|=unused0_7 << 7;
+ shifterU16|=grpfIhdt << 8;
+ stream->write(shifterU16);
+ shifterU16=rncFtn;
+ shifterU16|=nFtn << 2;
+ stream->write(shifterU16);
+ shifterU8=fOutlineDirtySave;
+ shifterU8|=unused4_1 << 1;
+ stream->write(shifterU8);
+ shifterU8=fOnlyMacPics;
+ shifterU8|=fOnlyWinPics << 1;
+ shifterU8|=fLabelDoc << 2;
+ shifterU8|=fHyphCapitals << 3;
+ shifterU8|=fAutoHyphen << 4;
+ shifterU8|=fFormNoFields << 5;
+ shifterU8|=fLinkStyles << 6;
+ shifterU8|=fRevMarking << 7;
+ stream->write(shifterU8);
+ shifterU8=fBackup;
+ shifterU8|=fExactCWords << 1;
+ shifterU8|=fPagHidden << 2;
+ shifterU8|=fPagResults << 3;
+ shifterU8|=fLockAtn << 4;
+ shifterU8|=fMirrorMargins << 5;
+ shifterU8|=unused6_6 << 6;
+ shifterU8|=fDfltTrueType << 7;
+ stream->write(shifterU8);
+ shifterU8=fPagSuppressTopSpacing;
+ shifterU8|=fProtEnabled << 1;
+ shifterU8|=fDispFormFldSel << 2;
+ shifterU8|=fRMView << 3;
+ shifterU8|=fRMPrint << 4;
+ shifterU8|=unused7_5 << 5;
+ shifterU8|=fLockRev << 6;
+ shifterU8|=fEmbedFonts << 7;
+ stream->write(shifterU8);
+ shifterU16=copts_fNoTabForInd;
+ shifterU16|=copts_fNoSpaceRaiseLower << 1;
+ shifterU16|=copts_fSuppressSpbfAfterPageBreak << 2;
+ shifterU16|=copts_fWrapTrailSpaces << 3;
+ shifterU16|=copts_fMapPrintTextColor << 4;
+ shifterU16|=copts_fNoColumnBalance << 5;
+ shifterU16|=copts_fConvMailMergeEsc << 6;
+ shifterU16|=copts_fSupressTopSpacing << 7;
+ shifterU16|=copts_fOrigWordTableRules << 8;
+ shifterU16|=copts_fTransparentMetafiles << 9;
+ shifterU16|=copts_fShowBreaksInFrames << 10;
+ shifterU16|=copts_fSwapBordersFacingPgs << 11;
+ shifterU16|=unused8_12 << 12;
+ stream->write(shifterU16);
+ stream->write(dxaTab);
+ stream->write(wSpare);
+ stream->write(dxaHotZ);
+ stream->write(cConsecHypLim);
+ stream->write(wSpare2);
+ dttmCreated.write(stream, false);
+ dttmRevised.write(stream, false);
+ dttmLastPrint.write(stream, false);
+ stream->write(nRevision);
+ stream->write(tmEdited);
+ stream->write(cWords);
+ stream->write(cCh);
+ stream->write(cPg);
+ stream->write(cParas);
+ shifterU16=rncEdn;
+ shifterU16|=nEdn << 2;
+ stream->write(shifterU16);
+ shifterU16=epc;
+ shifterU16|=nfcFtnRef << 2;
+ shifterU16|=nfcEdnRef << 6;
+ shifterU16|=fPrintFormData << 10;
+ shifterU16|=fSaveFormData << 11;
+ shifterU16|=fShadeFormData << 12;
+ shifterU16|=unused54_13 << 13;
+ shifterU16|=fWCFtnEdn << 15;
+ stream->write(shifterU16);
+ stream->write(cLines);
+ stream->write(cWordsFtnEnd);
+ stream->write(cChFtnEdn);
+ stream->write(cPgFtnEdn);
+ stream->write(cParasFtnEdn);
+ stream->write(cLinesFtnEdn);
+ stream->write(lKeyProtDoc);
+ shifterU16=wvkSaved;
+ shifterU16|=wScaleSaved << 3;
+ shifterU16|=zkSaved << 12;
+ shifterU16|=fRotateFontW6 << 14;
+ shifterU16|=iGutterPos << 15;
+ stream->write(shifterU16);
+ shifterU32=fNoTabForInd;
+ shifterU32|=fNoSpaceRaiseLower << 1;
+ shifterU32|=fSupressSpbfAfterPageBreak << 2;
+ shifterU32|=fWrapTrailSpaces << 3;
+ shifterU32|=fMapPrintTextColor << 4;
+ shifterU32|=fNoColumnBalance << 5;
+ shifterU32|=fConvMailMergeEsc << 6;
+ shifterU32|=fSupressTopSpacing << 7;
+ shifterU32|=fOrigWordTableRules << 8;
+ shifterU32|=fTransparentMetafiles << 9;
+ shifterU32|=fShowBreaksInFrames << 10;
+ shifterU32|=fSwapBordersFacingPgs << 11;
+ shifterU32|=unused84_12 << 12;
+ shifterU32|=fSuppressTopSpacingMac5 << 16;
+ shifterU32|=fTruncDxaExpand << 17;
+ shifterU32|=fPrintBodyBeforeHdr << 18;
+ shifterU32|=fNoLeading << 19;
+ shifterU32|=unused84_20 << 20;
+ shifterU32|=fMWSmallCaps << 21;
+ shifterU32|=unused84_22 << 22;
+ stream->write(shifterU32);
+ stream->write(adt);
+ doptypography.write(stream, false);
+ dogrid.write(stream, false);
+ shifterU16=reserved;
+ shifterU16|=lvl << 1;
+ shifterU16|=fGramAllDone << 5;
+ shifterU16|=fGramAllClean << 6;
+ shifterU16|=fSubsetFonts << 7;
+ shifterU16|=fHideLastVersion << 8;
+ shifterU16|=fHtmlDoc << 9;
+ shifterU16|=unused410_11 << 10;
+ shifterU16|=fSnapBorder << 11;
+ shifterU16|=fIncludeHeader << 12;
+ shifterU16|=fIncludeFooter << 13;
+ shifterU16|=fForcePageSizePag << 14;
+ shifterU16|=fMinFontSizePag << 15;
+ stream->write(shifterU16);
+ shifterU16=fHaveVersions;
+ shifterU16|=fAutoVersion << 1;
+ shifterU16|=unused412_2 << 2;
+ stream->write(shifterU16);
+ asumyi.write(stream, false);
+ stream->write(cChWS);
+ stream->write(cChWSFtnEdn);
+ stream->write(grfDocEvents);
+ shifterU32=fVirusPrompted;
+ shifterU32|=fVirusLoadSafe << 1;
+ shifterU32|=KeyVirusSession30 << 2;
+ stream->write(shifterU32);
+ for(int _i=0; _i<(30); ++_i)
+ stream->write(Spare[_i]);
+ stream->write(unused472);
+ stream->write(unused476);
+ stream->write(cDBC);
+ stream->write(cDBCFtnEdn);
+ stream->write(unused488);
+ stream->write(nfcFtnRef2);
+ stream->write(nfcEdnRef2);
+ stream->write(hpsZoonFontPag);
+ stream->write(dywDispPag);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void DOP::clear() {
+ fFacingPages=0;
+ fWidowControl=1;
+ fPMHMainDoc=0;
+ grfSuppression=0;
+ fpc=1;
+ unused0_7=0;
+ grpfIhdt=0;
+ rncFtn=0;
+ nFtn=1;
+ fOutlineDirtySave=0;
+ unused4_1=0;
+ fOnlyMacPics=0;
+ fOnlyWinPics=0;
+ fLabelDoc=0;
+ fHyphCapitals=0;
+ fAutoHyphen=0;
+ fFormNoFields=0;
+ fLinkStyles=0;
+ fRevMarking=0;
+ fBackup=0;
+ fExactCWords=0;
+ fPagHidden=0;
+ fPagResults=0;
+ fLockAtn=0;
+ fMirrorMargins=0;
+ unused6_6=0;
+ fDfltTrueType=0;
+ fPagSuppressTopSpacing=0;
+ fProtEnabled=0;
+ fDispFormFldSel=0;
+ fRMView=0;
+ fRMPrint=0;
+ unused7_5=0;
+ fLockRev=0;
+ fEmbedFonts=0;
+ copts_fNoTabForInd=0;
+ copts_fNoSpaceRaiseLower=0;
+ copts_fSuppressSpbfAfterPageBreak=0;
+ copts_fWrapTrailSpaces=0;
+ copts_fMapPrintTextColor=0;
+ copts_fNoColumnBalance=0;
+ copts_fConvMailMergeEsc=0;
+ copts_fSupressTopSpacing=0;
+ copts_fOrigWordTableRules=0;
+ copts_fTransparentMetafiles=0;
+ copts_fShowBreaksInFrames=0;
+ copts_fSwapBordersFacingPgs=0;
+ unused8_12=0;
+ dxaTab=720;
+ wSpare=0;
+ dxaHotZ=0;
+ cConsecHypLim=0;
+ wSpare2=0;
+ dttmCreated.clear();
+ dttmRevised.clear();
+ dttmLastPrint.clear();
+ nRevision=0;
+ tmEdited=0;
+ cWords=0;
+ cCh=0;
+ cPg=0;
+ cParas=0;
+ rncEdn=0;
+ nEdn=0;
+ epc=0;
+ nfcFtnRef=0;
+ nfcEdnRef=0;
+ fPrintFormData=0;
+ fSaveFormData=0;
+ fShadeFormData=0;
+ unused54_13=0;
+ fWCFtnEdn=0;
+ cLines=0;
+ cWordsFtnEnd=0;
+ cChFtnEdn=0;
+ cPgFtnEdn=0;
+ cParasFtnEdn=0;
+ cLinesFtnEdn=0;
+ lKeyProtDoc=0;
+ wvkSaved=0;
+ wScaleSaved=0;
+ zkSaved=0;
+ fRotateFontW6=0;
+ iGutterPos=0;
+ fNoTabForInd=0;
+ fNoSpaceRaiseLower=0;
+ fSupressSpbfAfterPageBreak=0;
+ fWrapTrailSpaces=0;
+ fMapPrintTextColor=0;
+ fNoColumnBalance=0;
+ fConvMailMergeEsc=0;
+ fSupressTopSpacing=0;
+ fOrigWordTableRules=0;
+ fTransparentMetafiles=0;
+ fShowBreaksInFrames=0;
+ fSwapBordersFacingPgs=0;
+ unused84_12=0;
+ fSuppressTopSpacingMac5=0;
+ fTruncDxaExpand=0;
+ fPrintBodyBeforeHdr=0;
+ fNoLeading=0;
+ unused84_20=0;
+ fMWSmallCaps=0;
+ unused84_22=0;
+ adt=0;
+ doptypography.clear();
+ dogrid.clear();
+ reserved=0;
+ lvl=0;
+ fGramAllDone=0;
+ fGramAllClean=0;
+ fSubsetFonts=0;
+ fHideLastVersion=0;
+ fHtmlDoc=0;
+ unused410_11=0;
+ fSnapBorder=0;
+ fIncludeHeader=0;
+ fIncludeFooter=0;
+ fForcePageSizePag=0;
+ fMinFontSizePag=0;
+ fHaveVersions=0;
+ fAutoVersion=0;
+ unused412_2=0;
+ asumyi.clear();
+ cChWS=0;
+ cChWSFtnEdn=0;
+ grfDocEvents=0;
+ fVirusPrompted=0;
+ fVirusLoadSafe=0;
+ KeyVirusSession30=0;
+ for(int _i=0; _i<(30); ++_i)
+ Spare[_i]=0;
+ unused472=0;
+ unused476=0;
+ cDBC=0;
+ cDBCFtnEdn=0;
+ unused488=0;
+ nfcFtnRef2=0;
+ nfcEdnRef2=0;
+ hpsZoonFontPag=0;
+ dywDispPag=0;
+}
+
+bool operator==(const DOP &lhs, const DOP &rhs) {
+
+ for(int _i=0; _i<(30); ++_i) {
+ if(lhs.Spare[_i]!=rhs.Spare[_i])
+ return false;
+ }
+
+ return lhs.fFacingPages==rhs.fFacingPages &&
+ lhs.fWidowControl==rhs.fWidowControl &&
+ lhs.fPMHMainDoc==rhs.fPMHMainDoc &&
+ lhs.grfSuppression==rhs.grfSuppression &&
+ lhs.fpc==rhs.fpc &&
+ lhs.unused0_7==rhs.unused0_7 &&
+ lhs.grpfIhdt==rhs.grpfIhdt &&
+ lhs.rncFtn==rhs.rncFtn &&
+ lhs.nFtn==rhs.nFtn &&
+ lhs.fOutlineDirtySave==rhs.fOutlineDirtySave &&
+ lhs.unused4_1==rhs.unused4_1 &&
+ lhs.fOnlyMacPics==rhs.fOnlyMacPics &&
+ lhs.fOnlyWinPics==rhs.fOnlyWinPics &&
+ lhs.fLabelDoc==rhs.fLabelDoc &&
+ lhs.fHyphCapitals==rhs.fHyphCapitals &&
+ lhs.fAutoHyphen==rhs.fAutoHyphen &&
+ lhs.fFormNoFields==rhs.fFormNoFields &&
+ lhs.fLinkStyles==rhs.fLinkStyles &&
+ lhs.fRevMarking==rhs.fRevMarking &&
+ lhs.fBackup==rhs.fBackup &&
+ lhs.fExactCWords==rhs.fExactCWords &&
+ lhs.fPagHidden==rhs.fPagHidden &&
+ lhs.fPagResults==rhs.fPagResults &&
+ lhs.fLockAtn==rhs.fLockAtn &&
+ lhs.fMirrorMargins==rhs.fMirrorMargins &&
+ lhs.unused6_6==rhs.unused6_6 &&
+ lhs.fDfltTrueType==rhs.fDfltTrueType &&
+ lhs.fPagSuppressTopSpacing==rhs.fPagSuppressTopSpacing &&
+ lhs.fProtEnabled==rhs.fProtEnabled &&
+ lhs.fDispFormFldSel==rhs.fDispFormFldSel &&
+ lhs.fRMView==rhs.fRMView &&
+ lhs.fRMPrint==rhs.fRMPrint &&
+ lhs.unused7_5==rhs.unused7_5 &&
+ lhs.fLockRev==rhs.fLockRev &&
+ lhs.fEmbedFonts==rhs.fEmbedFonts &&
+ lhs.copts_fNoTabForInd==rhs.copts_fNoTabForInd &&
+ lhs.copts_fNoSpaceRaiseLower==rhs.copts_fNoSpaceRaiseLower &&
+ lhs.copts_fSuppressSpbfAfterPageBreak==rhs.copts_fSuppressSpbfAfterPageBreak &&
+ lhs.copts_fWrapTrailSpaces==rhs.copts_fWrapTrailSpaces &&
+ lhs.copts_fMapPrintTextColor==rhs.copts_fMapPrintTextColor &&
+ lhs.copts_fNoColumnBalance==rhs.copts_fNoColumnBalance &&
+ lhs.copts_fConvMailMergeEsc==rhs.copts_fConvMailMergeEsc &&
+ lhs.copts_fSupressTopSpacing==rhs.copts_fSupressTopSpacing &&
+ lhs.copts_fOrigWordTableRules==rhs.copts_fOrigWordTableRules &&
+ lhs.copts_fTransparentMetafiles==rhs.copts_fTransparentMetafiles &&
+ lhs.copts_fShowBreaksInFrames==rhs.copts_fShowBreaksInFrames &&
+ lhs.copts_fSwapBordersFacingPgs==rhs.copts_fSwapBordersFacingPgs &&
+ lhs.unused8_12==rhs.unused8_12 &&
+ lhs.dxaTab==rhs.dxaTab &&
+ lhs.wSpare==rhs.wSpare &&
+ lhs.dxaHotZ==rhs.dxaHotZ &&
+ lhs.cConsecHypLim==rhs.cConsecHypLim &&
+ lhs.wSpare2==rhs.wSpare2 &&
+ lhs.dttmCreated==rhs.dttmCreated &&
+ lhs.dttmRevised==rhs.dttmRevised &&
+ lhs.dttmLastPrint==rhs.dttmLastPrint &&
+ lhs.nRevision==rhs.nRevision &&
+ lhs.tmEdited==rhs.tmEdited &&
+ lhs.cWords==rhs.cWords &&
+ lhs.cCh==rhs.cCh &&
+ lhs.cPg==rhs.cPg &&
+ lhs.cParas==rhs.cParas &&
+ lhs.rncEdn==rhs.rncEdn &&
+ lhs.nEdn==rhs.nEdn &&
+ lhs.epc==rhs.epc &&
+ lhs.nfcFtnRef==rhs.nfcFtnRef &&
+ lhs.nfcEdnRef==rhs.nfcEdnRef &&
+ lhs.fPrintFormData==rhs.fPrintFormData &&
+ lhs.fSaveFormData==rhs.fSaveFormData &&
+ lhs.fShadeFormData==rhs.fShadeFormData &&
+ lhs.unused54_13==rhs.unused54_13 &&
+ lhs.fWCFtnEdn==rhs.fWCFtnEdn &&
+ lhs.cLines==rhs.cLines &&
+ lhs.cWordsFtnEnd==rhs.cWordsFtnEnd &&
+ lhs.cChFtnEdn==rhs.cChFtnEdn &&
+ lhs.cPgFtnEdn==rhs.cPgFtnEdn &&
+ lhs.cParasFtnEdn==rhs.cParasFtnEdn &&
+ lhs.cLinesFtnEdn==rhs.cLinesFtnEdn &&
+ lhs.lKeyProtDoc==rhs.lKeyProtDoc &&
+ lhs.wvkSaved==rhs.wvkSaved &&
+ lhs.wScaleSaved==rhs.wScaleSaved &&
+ lhs.zkSaved==rhs.zkSaved &&
+ lhs.fRotateFontW6==rhs.fRotateFontW6 &&
+ lhs.iGutterPos==rhs.iGutterPos &&
+ lhs.fNoTabForInd==rhs.fNoTabForInd &&
+ lhs.fNoSpaceRaiseLower==rhs.fNoSpaceRaiseLower &&
+ lhs.fSupressSpbfAfterPageBreak==rhs.fSupressSpbfAfterPageBreak &&
+ lhs.fWrapTrailSpaces==rhs.fWrapTrailSpaces &&
+ lhs.fMapPrintTextColor==rhs.fMapPrintTextColor &&
+ lhs.fNoColumnBalance==rhs.fNoColumnBalance &&
+ lhs.fConvMailMergeEsc==rhs.fConvMailMergeEsc &&
+ lhs.fSupressTopSpacing==rhs.fSupressTopSpacing &&
+ lhs.fOrigWordTableRules==rhs.fOrigWordTableRules &&
+ lhs.fTransparentMetafiles==rhs.fTransparentMetafiles &&
+ lhs.fShowBreaksInFrames==rhs.fShowBreaksInFrames &&
+ lhs.fSwapBordersFacingPgs==rhs.fSwapBordersFacingPgs &&
+ lhs.unused84_12==rhs.unused84_12 &&
+ lhs.fSuppressTopSpacingMac5==rhs.fSuppressTopSpacingMac5 &&
+ lhs.fTruncDxaExpand==rhs.fTruncDxaExpand &&
+ lhs.fPrintBodyBeforeHdr==rhs.fPrintBodyBeforeHdr &&
+ lhs.fNoLeading==rhs.fNoLeading &&
+ lhs.unused84_20==rhs.unused84_20 &&
+ lhs.fMWSmallCaps==rhs.fMWSmallCaps &&
+ lhs.unused84_22==rhs.unused84_22 &&
+ lhs.adt==rhs.adt &&
+ lhs.doptypography==rhs.doptypography &&
+ lhs.dogrid==rhs.dogrid &&
+ lhs.reserved==rhs.reserved &&
+ lhs.lvl==rhs.lvl &&
+ lhs.fGramAllDone==rhs.fGramAllDone &&
+ lhs.fGramAllClean==rhs.fGramAllClean &&
+ lhs.fSubsetFonts==rhs.fSubsetFonts &&
+ lhs.fHideLastVersion==rhs.fHideLastVersion &&
+ lhs.fHtmlDoc==rhs.fHtmlDoc &&
+ lhs.unused410_11==rhs.unused410_11 &&
+ lhs.fSnapBorder==rhs.fSnapBorder &&
+ lhs.fIncludeHeader==rhs.fIncludeHeader &&
+ lhs.fIncludeFooter==rhs.fIncludeFooter &&
+ lhs.fForcePageSizePag==rhs.fForcePageSizePag &&
+ lhs.fMinFontSizePag==rhs.fMinFontSizePag &&
+ lhs.fHaveVersions==rhs.fHaveVersions &&
+ lhs.fAutoVersion==rhs.fAutoVersion &&
+ lhs.unused412_2==rhs.unused412_2 &&
+ lhs.asumyi==rhs.asumyi &&
+ lhs.cChWS==rhs.cChWS &&
+ lhs.cChWSFtnEdn==rhs.cChWSFtnEdn &&
+ lhs.grfDocEvents==rhs.grfDocEvents &&
+ lhs.fVirusPrompted==rhs.fVirusPrompted &&
+ lhs.fVirusLoadSafe==rhs.fVirusLoadSafe &&
+ lhs.KeyVirusSession30==rhs.KeyVirusSession30 &&
+ lhs.unused472==rhs.unused472 &&
+ lhs.unused476==rhs.unused476 &&
+ lhs.cDBC==rhs.cDBC &&
+ lhs.cDBCFtnEdn==rhs.cDBCFtnEdn &&
+ lhs.unused488==rhs.unused488 &&
+ lhs.nfcFtnRef2==rhs.nfcFtnRef2 &&
+ lhs.nfcEdnRef2==rhs.nfcEdnRef2 &&
+ lhs.hpsZoonFontPag==rhs.hpsZoonFontPag &&
+ lhs.dywDispPag==rhs.dywDispPag;
+}
+
+bool operator!=(const DOP &lhs, const DOP &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// FIB implementation
+
+FIB::FIB() {
+ clear();
+}
+
+FIB::FIB(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool FIB::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ wIdent=stream->readU16();
+ nFib=stream->readU16();
+ nProduct=stream->readU16();
+ lid=stream->readU16();
+ pnNext=stream->readS16();
+ shifterU16=stream->readU16();
+ fDot=shifterU16;
+ shifterU16>>=1;
+ fGlsy=shifterU16;
+ shifterU16>>=1;
+ fComplex=shifterU16;
+ shifterU16>>=1;
+ fHasPic=shifterU16;
+ shifterU16>>=1;
+ cQuickSaves=shifterU16;
+ shifterU16>>=4;
+ fEncrypted=shifterU16;
+ shifterU16>>=1;
+ fWhichTblStm=shifterU16;
+ shifterU16>>=1;
+ fReadOnlyRecommended=shifterU16;
+ shifterU16>>=1;
+ fWriteReservation=shifterU16;
+ shifterU16>>=1;
+ fExtChar=shifterU16;
+ shifterU16>>=1;
+ fLoadOverride=shifterU16;
+ shifterU16>>=1;
+ fFarEast=shifterU16;
+ shifterU16>>=1;
+ fCrypto=shifterU16;
+ nFibBack=stream->readU16();
+ lKey=stream->readU32();
+ envr=stream->readU8();
+ shifterU8=stream->readU8();
+ fMac=shifterU8;
+ shifterU8>>=1;
+ fEmptySpecial=shifterU8;
+ shifterU8>>=1;
+ fLoadOverridePage=shifterU8;
+ shifterU8>>=1;
+ fFutureSavedUndo=shifterU8;
+ shifterU8>>=1;
+ fWord97Saved=shifterU8;
+ shifterU8>>=1;
+ fSpare0=shifterU8;
+ chs=stream->readU16();
+ chsTables=stream->readU16();
+ fcMin=stream->readU32();
+ fcMac=stream->readU32();
+ csw=stream->readU16();
+ wMagicCreated=stream->readU16();
+ wMagicRevised=stream->readU16();
+ wMagicCreatedPrivate=stream->readU16();
+ wMagicRevisedPrivate=stream->readU16();
+ pnFbpChpFirst_W6=stream->readU16();
+ pnChpFirst_W6=stream->readU16();
+ cpnBteChp_W6=stream->readU16();
+ pnFbpPapFirst_W6=stream->readU16();
+ pnPapFirst_W6=stream->readU16();
+ cpnBtePap_W6=stream->readU16();
+ pnFbpLvcFirst_W6=stream->readU16();
+ pnLvcFirst_W6=stream->readU16();
+ cpnBteLvc_W6=stream->readU16();
+ lidFE=stream->readS16();
+ clw=stream->readU16();
+ cbMac=stream->readU32();
+ lProductCreated=stream->readU32();
+ lProductRevised=stream->readU32();
+ ccpText=stream->readU32();
+ ccpFtn=stream->readU32();
+ ccpHdd=stream->readU32();
+ ccpMcr=stream->readU32();
+ ccpAtn=stream->readU32();
+ ccpEdn=stream->readU32();
+ ccpTxbx=stream->readU32();
+ ccpHdrTxbx=stream->readU32();
+ pnFbpChpFirst=stream->readU32();
+ pnChpFirst=stream->readU32();
+ cpnBteChp=stream->readU32();
+ pnFbpPapFirst=stream->readU32();
+ pnPapFirst=stream->readU32();
+ cpnBtePap=stream->readU32();
+ pnFbpLvcFirst=stream->readU32();
+ pnLvcFirst=stream->readU32();
+ cpnBteLvc=stream->readU32();
+ fcIslandFirst=stream->readU32();
+ fcIslandLim=stream->readU32();
+ cfclcb=stream->readU16();
+ fcStshfOrig=stream->readU32();
+ lcbStshfOrig=stream->readU32();
+ fcStshf=stream->readU32();
+ lcbStshf=stream->readU32();
+ fcPlcffndRef=stream->readU32();
+ lcbPlcffndRef=stream->readU32();
+ fcPlcffndTxt=stream->readU32();
+ lcbPlcffndTxt=stream->readU32();
+ fcPlcfandRef=stream->readU32();
+ lcbPlcfandRef=stream->readU32();
+ fcPlcfandTxt=stream->readU32();
+ lcbPlcfandTxt=stream->readU32();
+ fcPlcfsed=stream->readU32();
+ lcbPlcfsed=stream->readU32();
+ fcPlcfpad=stream->readU32();
+ lcbPlcfpad=stream->readU32();
+ fcPlcfphe=stream->readU32();
+ lcbPlcfphe=stream->readU32();
+ fcSttbfglsy=stream->readU32();
+ lcbSttbfglsy=stream->readU32();
+ fcPlcfglsy=stream->readU32();
+ lcbPlcfglsy=stream->readU32();
+ fcPlcfhdd=stream->readU32();
+ lcbPlcfhdd=stream->readU32();
+ fcPlcfbteChpx=stream->readU32();
+ lcbPlcfbteChpx=stream->readU32();
+ fcPlcfbtePapx=stream->readU32();
+ lcbPlcfbtePapx=stream->readU32();
+ fcPlcfsea=stream->readU32();
+ lcbPlcfsea=stream->readU32();
+ fcSttbfffn=stream->readU32();
+ lcbSttbfffn=stream->readU32();
+ fcPlcffldMom=stream->readU32();
+ lcbPlcffldMom=stream->readU32();
+ fcPlcffldHdr=stream->readU32();
+ lcbPlcffldHdr=stream->readU32();
+ fcPlcffldFtn=stream->readU32();
+ lcbPlcffldFtn=stream->readU32();
+ fcPlcffldAtn=stream->readU32();
+ lcbPlcffldAtn=stream->readU32();
+ fcPlcffldMcr=stream->readU32();
+ lcbPlcffldMcr=stream->readU32();
+ fcSttbfbkmk=stream->readU32();
+ lcbSttbfbkmk=stream->readU32();
+ fcPlcfbkf=stream->readU32();
+ lcbPlcfbkf=stream->readU32();
+ fcPlcfbkl=stream->readU32();
+ lcbPlcfbkl=stream->readU32();
+ fcCmds=stream->readU32();
+ lcbCmds=stream->readU32();
+ fcPlcmcr=stream->readU32();
+ lcbPlcmcr=stream->readU32();
+ fcSttbfmcr=stream->readU32();
+ lcbSttbfmcr=stream->readU32();
+ fcPrDrvr=stream->readU32();
+ lcbPrDrvr=stream->readU32();
+ fcPrEnvPort=stream->readU32();
+ lcbPrEnvPort=stream->readU32();
+ fcPrEnvLand=stream->readU32();
+ lcbPrEnvLand=stream->readU32();
+ fcWss=stream->readU32();
+ lcbWss=stream->readU32();
+ fcDop=stream->readU32();
+ lcbDop=stream->readU32();
+ fcSttbfAssoc=stream->readU32();
+ lcbSttbfAssoc=stream->readU32();
+ fcClx=stream->readU32();
+ lcbClx=stream->readU32();
+ fcPlcfpgdFtn=stream->readU32();
+ lcbPlcfpgdFtn=stream->readU32();
+ fcAutosaveSource=stream->readU32();
+ lcbAutosaveSource=stream->readU32();
+ fcGrpXstAtnOwners=stream->readU32();
+ lcbGrpXstAtnOwners=stream->readU32();
+ fcSttbfAtnbkmk=stream->readU32();
+ lcbSttbfAtnbkmk=stream->readU32();
+ fcPlcdoaMom=stream->readU32();
+ lcbPlcdoaMom=stream->readU32();
+ fcPlcdoaHdr=stream->readU32();
+ lcbPlcdoaHdr=stream->readU32();
+ fcPlcspaMom=stream->readU32();
+ lcbPlcspaMom=stream->readU32();
+ fcPlcspaHdr=stream->readU32();
+ lcbPlcspaHdr=stream->readU32();
+ fcPlcfAtnbkf=stream->readU32();
+ lcbPlcfAtnbkf=stream->readU32();
+ fcPlcfAtnbkl=stream->readU32();
+ lcbPlcfAtnbkl=stream->readU32();
+ fcPms=stream->readU32();
+ lcbPms=stream->readU32();
+ fcFormFldSttbf=stream->readU32();
+ lcbFormFldSttbf=stream->readU32();
+ fcPlcfendRef=stream->readU32();
+ lcbPlcfendRef=stream->readU32();
+ fcPlcfendTxt=stream->readU32();
+ lcbPlcfendTxt=stream->readU32();
+ fcPlcffldEdn=stream->readU32();
+ lcbPlcffldEdn=stream->readU32();
+ fcPlcfpgdEdn=stream->readU32();
+ lcbPlcfpgdEdn=stream->readU32();
+ fcDggInfo=stream->readU32();
+ lcbDggInfo=stream->readU32();
+ fcSttbfRMark=stream->readU32();
+ lcbSttbfRMark=stream->readU32();
+ fcSttbfCaption=stream->readU32();
+ lcbSttbfCaption=stream->readU32();
+ fcSttbfAutoCaption=stream->readU32();
+ lcbSttbfAutoCaption=stream->readU32();
+ fcPlcfwkb=stream->readU32();
+ lcbPlcfwkb=stream->readU32();
+ fcPlcfspl=stream->readU32();
+ lcbPlcfspl=stream->readU32();
+ fcPlcftxbxTxt=stream->readU32();
+ lcbPlcftxbxTxt=stream->readU32();
+ fcPlcffldTxbx=stream->readU32();
+ lcbPlcffldTxbx=stream->readU32();
+ fcPlcfHdrtxbxTxt=stream->readU32();
+ lcbPlcfHdrtxbxTxt=stream->readU32();
+ fcPlcffldHdrTxbx=stream->readU32();
+ lcbPlcffldHdrTxbx=stream->readU32();
+ fcStwUser=stream->readU32();
+ lcbStwUser=stream->readU32();
+ fcSttbttmbd=stream->readU32();
+ lcbSttbttmbd=stream->readU32();
+ fcUnused=stream->readU32();
+ lcbUnused=stream->readU32();
+ fcPgdMother=stream->readU32();
+ lcbPgdMother=stream->readU32();
+ fcBkdMother=stream->readU32();
+ lcbBkdMother=stream->readU32();
+ fcPgdFtn=stream->readU32();
+ lcbPgdFtn=stream->readU32();
+ fcBkdFtn=stream->readU32();
+ lcbBkdFtn=stream->readU32();
+ fcPgdEdn=stream->readU32();
+ lcbPgdEdn=stream->readU32();
+ fcBkdEdn=stream->readU32();
+ lcbBkdEdn=stream->readU32();
+ fcSttbfIntlFld=stream->readU32();
+ lcbSttbfIntlFld=stream->readU32();
+ fcRouteSlip=stream->readU32();
+ lcbRouteSlip=stream->readU32();
+ fcSttbSavedBy=stream->readU32();
+ lcbSttbSavedBy=stream->readU32();
+ fcSttbFnm=stream->readU32();
+ lcbSttbFnm=stream->readU32();
+ fcPlcfLst=stream->readU32();
+ lcbPlcfLst=stream->readU32();
+ fcPlfLfo=stream->readU32();
+ lcbPlfLfo=stream->readU32();
+ fcPlcftxbxBkd=stream->readU32();
+ lcbPlcftxbxBkd=stream->readU32();
+ fcPlcftxbxHdrBkd=stream->readU32();
+ lcbPlcftxbxHdrBkd=stream->readU32();
+ fcDocUndo=stream->readU32();
+ lcbDocUndo=stream->readU32();
+ fcRgbuse=stream->readU32();
+ lcbRgbuse=stream->readU32();
+ fcUsp=stream->readU32();
+ lcbUsp=stream->readU32();
+ fcUskf=stream->readU32();
+ lcbUskf=stream->readU32();
+ fcPlcupcRgbuse=stream->readU32();
+ lcbPlcupcRgbuse=stream->readU32();
+ fcPlcupcUsp=stream->readU32();
+ lcbPlcupcUsp=stream->readU32();
+ fcSttbGlsyStyle=stream->readU32();
+ lcbSttbGlsyStyle=stream->readU32();
+ fcPlgosl=stream->readU32();
+ lcbPlgosl=stream->readU32();
+ fcPlcocx=stream->readU32();
+ lcbPlcocx=stream->readU32();
+ fcPlcfbteLvc=stream->readU32();
+ lcbPlcfbteLvc=stream->readU32();
+ dwLowDateTime=stream->readU32();
+ dwHighDateTime=stream->readU32();
+ fcPlcflvc=stream->readU32();
+ lcbPlcflvc=stream->readU32();
+ fcPlcasumy=stream->readU32();
+ lcbPlcasumy=stream->readU32();
+ fcPlcfgram=stream->readU32();
+ lcbPlcfgram=stream->readU32();
+ fcSttbListNames=stream->readU32();
+ lcbSttbListNames=stream->readU32();
+ fcSttbfUssr=stream->readU32();
+ lcbSttbfUssr=stream->readU32();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool FIB::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(wIdent);
+ stream->write(nFib);
+ stream->write(nProduct);
+ stream->write(lid);
+ stream->write(pnNext);
+ shifterU16=fDot;
+ shifterU16|=fGlsy << 1;
+ shifterU16|=fComplex << 2;
+ shifterU16|=fHasPic << 3;
+ shifterU16|=cQuickSaves << 4;
+ shifterU16|=fEncrypted << 8;
+ shifterU16|=fWhichTblStm << 9;
+ shifterU16|=fReadOnlyRecommended << 10;
+ shifterU16|=fWriteReservation << 11;
+ shifterU16|=fExtChar << 12;
+ shifterU16|=fLoadOverride << 13;
+ shifterU16|=fFarEast << 14;
+ shifterU16|=fCrypto << 15;
+ stream->write(shifterU16);
+ stream->write(nFibBack);
+ stream->write(lKey);
+ stream->write(envr);
+ shifterU8=fMac;
+ shifterU8|=fEmptySpecial << 1;
+ shifterU8|=fLoadOverridePage << 2;
+ shifterU8|=fFutureSavedUndo << 3;
+ shifterU8|=fWord97Saved << 4;
+ shifterU8|=fSpare0 << 5;
+ stream->write(shifterU8);
+ stream->write(chs);
+ stream->write(chsTables);
+ stream->write(fcMin);
+ stream->write(fcMac);
+ stream->write(csw);
+ stream->write(wMagicCreated);
+ stream->write(wMagicRevised);
+ stream->write(wMagicCreatedPrivate);
+ stream->write(wMagicRevisedPrivate);
+ stream->write(pnFbpChpFirst_W6);
+ stream->write(pnChpFirst_W6);
+ stream->write(cpnBteChp_W6);
+ stream->write(pnFbpPapFirst_W6);
+ stream->write(pnPapFirst_W6);
+ stream->write(cpnBtePap_W6);
+ stream->write(pnFbpLvcFirst_W6);
+ stream->write(pnLvcFirst_W6);
+ stream->write(cpnBteLvc_W6);
+ stream->write(lidFE);
+ stream->write(clw);
+ stream->write(cbMac);
+ stream->write(lProductCreated);
+ stream->write(lProductRevised);
+ stream->write(ccpText);
+ stream->write(ccpFtn);
+ stream->write(ccpHdd);
+ stream->write(ccpMcr);
+ stream->write(ccpAtn);
+ stream->write(ccpEdn);
+ stream->write(ccpTxbx);
+ stream->write(ccpHdrTxbx);
+ stream->write(pnFbpChpFirst);
+ stream->write(pnChpFirst);
+ stream->write(cpnBteChp);
+ stream->write(pnFbpPapFirst);
+ stream->write(pnPapFirst);
+ stream->write(cpnBtePap);
+ stream->write(pnFbpLvcFirst);
+ stream->write(pnLvcFirst);
+ stream->write(cpnBteLvc);
+ stream->write(fcIslandFirst);
+ stream->write(fcIslandLim);
+ stream->write(cfclcb);
+ stream->write(fcStshfOrig);
+ stream->write(lcbStshfOrig);
+ stream->write(fcStshf);
+ stream->write(lcbStshf);
+ stream->write(fcPlcffndRef);
+ stream->write(lcbPlcffndRef);
+ stream->write(fcPlcffndTxt);
+ stream->write(lcbPlcffndTxt);
+ stream->write(fcPlcfandRef);
+ stream->write(lcbPlcfandRef);
+ stream->write(fcPlcfandTxt);
+ stream->write(lcbPlcfandTxt);
+ stream->write(fcPlcfsed);
+ stream->write(lcbPlcfsed);
+ stream->write(fcPlcfpad);
+ stream->write(lcbPlcfpad);
+ stream->write(fcPlcfphe);
+ stream->write(lcbPlcfphe);
+ stream->write(fcSttbfglsy);
+ stream->write(lcbSttbfglsy);
+ stream->write(fcPlcfglsy);
+ stream->write(lcbPlcfglsy);
+ stream->write(fcPlcfhdd);
+ stream->write(lcbPlcfhdd);
+ stream->write(fcPlcfbteChpx);
+ stream->write(lcbPlcfbteChpx);
+ stream->write(fcPlcfbtePapx);
+ stream->write(lcbPlcfbtePapx);
+ stream->write(fcPlcfsea);
+ stream->write(lcbPlcfsea);
+ stream->write(fcSttbfffn);
+ stream->write(lcbSttbfffn);
+ stream->write(fcPlcffldMom);
+ stream->write(lcbPlcffldMom);
+ stream->write(fcPlcffldHdr);
+ stream->write(lcbPlcffldHdr);
+ stream->write(fcPlcffldFtn);
+ stream->write(lcbPlcffldFtn);
+ stream->write(fcPlcffldAtn);
+ stream->write(lcbPlcffldAtn);
+ stream->write(fcPlcffldMcr);
+ stream->write(lcbPlcffldMcr);
+ stream->write(fcSttbfbkmk);
+ stream->write(lcbSttbfbkmk);
+ stream->write(fcPlcfbkf);
+ stream->write(lcbPlcfbkf);
+ stream->write(fcPlcfbkl);
+ stream->write(lcbPlcfbkl);
+ stream->write(fcCmds);
+ stream->write(lcbCmds);
+ stream->write(fcPlcmcr);
+ stream->write(lcbPlcmcr);
+ stream->write(fcSttbfmcr);
+ stream->write(lcbSttbfmcr);
+ stream->write(fcPrDrvr);
+ stream->write(lcbPrDrvr);
+ stream->write(fcPrEnvPort);
+ stream->write(lcbPrEnvPort);
+ stream->write(fcPrEnvLand);
+ stream->write(lcbPrEnvLand);
+ stream->write(fcWss);
+ stream->write(lcbWss);
+ stream->write(fcDop);
+ stream->write(lcbDop);
+ stream->write(fcSttbfAssoc);
+ stream->write(lcbSttbfAssoc);
+ stream->write(fcClx);
+ stream->write(lcbClx);
+ stream->write(fcPlcfpgdFtn);
+ stream->write(lcbPlcfpgdFtn);
+ stream->write(fcAutosaveSource);
+ stream->write(lcbAutosaveSource);
+ stream->write(fcGrpXstAtnOwners);
+ stream->write(lcbGrpXstAtnOwners);
+ stream->write(fcSttbfAtnbkmk);
+ stream->write(lcbSttbfAtnbkmk);
+ stream->write(fcPlcdoaMom);
+ stream->write(lcbPlcdoaMom);
+ stream->write(fcPlcdoaHdr);
+ stream->write(lcbPlcdoaHdr);
+ stream->write(fcPlcspaMom);
+ stream->write(lcbPlcspaMom);
+ stream->write(fcPlcspaHdr);
+ stream->write(lcbPlcspaHdr);
+ stream->write(fcPlcfAtnbkf);
+ stream->write(lcbPlcfAtnbkf);
+ stream->write(fcPlcfAtnbkl);
+ stream->write(lcbPlcfAtnbkl);
+ stream->write(fcPms);
+ stream->write(lcbPms);
+ stream->write(fcFormFldSttbf);
+ stream->write(lcbFormFldSttbf);
+ stream->write(fcPlcfendRef);
+ stream->write(lcbPlcfendRef);
+ stream->write(fcPlcfendTxt);
+ stream->write(lcbPlcfendTxt);
+ stream->write(fcPlcffldEdn);
+ stream->write(lcbPlcffldEdn);
+ stream->write(fcPlcfpgdEdn);
+ stream->write(lcbPlcfpgdEdn);
+ stream->write(fcDggInfo);
+ stream->write(lcbDggInfo);
+ stream->write(fcSttbfRMark);
+ stream->write(lcbSttbfRMark);
+ stream->write(fcSttbfCaption);
+ stream->write(lcbSttbfCaption);
+ stream->write(fcSttbfAutoCaption);
+ stream->write(lcbSttbfAutoCaption);
+ stream->write(fcPlcfwkb);
+ stream->write(lcbPlcfwkb);
+ stream->write(fcPlcfspl);
+ stream->write(lcbPlcfspl);
+ stream->write(fcPlcftxbxTxt);
+ stream->write(lcbPlcftxbxTxt);
+ stream->write(fcPlcffldTxbx);
+ stream->write(lcbPlcffldTxbx);
+ stream->write(fcPlcfHdrtxbxTxt);
+ stream->write(lcbPlcfHdrtxbxTxt);
+ stream->write(fcPlcffldHdrTxbx);
+ stream->write(lcbPlcffldHdrTxbx);
+ stream->write(fcStwUser);
+ stream->write(lcbStwUser);
+ stream->write(fcSttbttmbd);
+ stream->write(lcbSttbttmbd);
+ stream->write(fcUnused);
+ stream->write(lcbUnused);
+ stream->write(fcPgdMother);
+ stream->write(lcbPgdMother);
+ stream->write(fcBkdMother);
+ stream->write(lcbBkdMother);
+ stream->write(fcPgdFtn);
+ stream->write(lcbPgdFtn);
+ stream->write(fcBkdFtn);
+ stream->write(lcbBkdFtn);
+ stream->write(fcPgdEdn);
+ stream->write(lcbPgdEdn);
+ stream->write(fcBkdEdn);
+ stream->write(lcbBkdEdn);
+ stream->write(fcSttbfIntlFld);
+ stream->write(lcbSttbfIntlFld);
+ stream->write(fcRouteSlip);
+ stream->write(lcbRouteSlip);
+ stream->write(fcSttbSavedBy);
+ stream->write(lcbSttbSavedBy);
+ stream->write(fcSttbFnm);
+ stream->write(lcbSttbFnm);
+ stream->write(fcPlcfLst);
+ stream->write(lcbPlcfLst);
+ stream->write(fcPlfLfo);
+ stream->write(lcbPlfLfo);
+ stream->write(fcPlcftxbxBkd);
+ stream->write(lcbPlcftxbxBkd);
+ stream->write(fcPlcftxbxHdrBkd);
+ stream->write(lcbPlcftxbxHdrBkd);
+ stream->write(fcDocUndo);
+ stream->write(lcbDocUndo);
+ stream->write(fcRgbuse);
+ stream->write(lcbRgbuse);
+ stream->write(fcUsp);
+ stream->write(lcbUsp);
+ stream->write(fcUskf);
+ stream->write(lcbUskf);
+ stream->write(fcPlcupcRgbuse);
+ stream->write(lcbPlcupcRgbuse);
+ stream->write(fcPlcupcUsp);
+ stream->write(lcbPlcupcUsp);
+ stream->write(fcSttbGlsyStyle);
+ stream->write(lcbSttbGlsyStyle);
+ stream->write(fcPlgosl);
+ stream->write(lcbPlgosl);
+ stream->write(fcPlcocx);
+ stream->write(lcbPlcocx);
+ stream->write(fcPlcfbteLvc);
+ stream->write(lcbPlcfbteLvc);
+ stream->write(dwLowDateTime);
+ stream->write(dwHighDateTime);
+ stream->write(fcPlcflvc);
+ stream->write(lcbPlcflvc);
+ stream->write(fcPlcasumy);
+ stream->write(lcbPlcasumy);
+ stream->write(fcPlcfgram);
+ stream->write(lcbPlcfgram);
+ stream->write(fcSttbListNames);
+ stream->write(lcbSttbListNames);
+ stream->write(fcSttbfUssr);
+ stream->write(lcbSttbfUssr);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void FIB::clear() {
+ wIdent=0;
+ nFib=0;
+ nProduct=0;
+ lid=0;
+ pnNext=0;
+ fDot=0;
+ fGlsy=0;
+ fComplex=0;
+ fHasPic=0;
+ cQuickSaves=0;
+ fEncrypted=0;
+ fWhichTblStm=0;
+ fReadOnlyRecommended=0;
+ fWriteReservation=0;
+ fExtChar=0;
+ fLoadOverride=0;
+ fFarEast=0;
+ fCrypto=0;
+ nFibBack=0;
+ lKey=0;
+ envr=0;
+ fMac=0;
+ fEmptySpecial=0;
+ fLoadOverridePage=0;
+ fFutureSavedUndo=0;
+ fWord97Saved=0;
+ fSpare0=0;
+ chs=0;
+ chsTables=0;
+ fcMin=0;
+ fcMac=0;
+ csw=0;
+ wMagicCreated=0;
+ wMagicRevised=0;
+ wMagicCreatedPrivate=0;
+ wMagicRevisedPrivate=0;
+ pnFbpChpFirst_W6=0;
+ pnChpFirst_W6=0;
+ cpnBteChp_W6=0;
+ pnFbpPapFirst_W6=0;
+ pnPapFirst_W6=0;
+ cpnBtePap_W6=0;
+ pnFbpLvcFirst_W6=0;
+ pnLvcFirst_W6=0;
+ cpnBteLvc_W6=0;
+ lidFE=0;
+ clw=0;
+ cbMac=0;
+ lProductCreated=0;
+ lProductRevised=0;
+ ccpText=0;
+ ccpFtn=0;
+ ccpHdd=0;
+ ccpMcr=0;
+ ccpAtn=0;
+ ccpEdn=0;
+ ccpTxbx=0;
+ ccpHdrTxbx=0;
+ pnFbpChpFirst=0;
+ pnChpFirst=0;
+ cpnBteChp=0;
+ pnFbpPapFirst=0;
+ pnPapFirst=0;
+ cpnBtePap=0;
+ pnFbpLvcFirst=0;
+ pnLvcFirst=0;
+ cpnBteLvc=0;
+ fcIslandFirst=0;
+ fcIslandLim=0;
+ cfclcb=0;
+ fcStshfOrig=0;
+ lcbStshfOrig=0;
+ fcStshf=0;
+ lcbStshf=0;
+ fcPlcffndRef=0;
+ lcbPlcffndRef=0;
+ fcPlcffndTxt=0;
+ lcbPlcffndTxt=0;
+ fcPlcfandRef=0;
+ lcbPlcfandRef=0;
+ fcPlcfandTxt=0;
+ lcbPlcfandTxt=0;
+ fcPlcfsed=0;
+ lcbPlcfsed=0;
+ fcPlcfpad=0;
+ lcbPlcfpad=0;
+ fcPlcfphe=0;
+ lcbPlcfphe=0;
+ fcSttbfglsy=0;
+ lcbSttbfglsy=0;
+ fcPlcfglsy=0;
+ lcbPlcfglsy=0;
+ fcPlcfhdd=0;
+ lcbPlcfhdd=0;
+ fcPlcfbteChpx=0;
+ lcbPlcfbteChpx=0;
+ fcPlcfbtePapx=0;
+ lcbPlcfbtePapx=0;
+ fcPlcfsea=0;
+ lcbPlcfsea=0;
+ fcSttbfffn=0;
+ lcbSttbfffn=0;
+ fcPlcffldMom=0;
+ lcbPlcffldMom=0;
+ fcPlcffldHdr=0;
+ lcbPlcffldHdr=0;
+ fcPlcffldFtn=0;
+ lcbPlcffldFtn=0;
+ fcPlcffldAtn=0;
+ lcbPlcffldAtn=0;
+ fcPlcffldMcr=0;
+ lcbPlcffldMcr=0;
+ fcSttbfbkmk=0;
+ lcbSttbfbkmk=0;
+ fcPlcfbkf=0;
+ lcbPlcfbkf=0;
+ fcPlcfbkl=0;
+ lcbPlcfbkl=0;
+ fcCmds=0;
+ lcbCmds=0;
+ fcPlcmcr=0;
+ lcbPlcmcr=0;
+ fcSttbfmcr=0;
+ lcbSttbfmcr=0;
+ fcPrDrvr=0;
+ lcbPrDrvr=0;
+ fcPrEnvPort=0;
+ lcbPrEnvPort=0;
+ fcPrEnvLand=0;
+ lcbPrEnvLand=0;
+ fcWss=0;
+ lcbWss=0;
+ fcDop=0;
+ lcbDop=0;
+ fcSttbfAssoc=0;
+ lcbSttbfAssoc=0;
+ fcClx=0;
+ lcbClx=0;
+ fcPlcfpgdFtn=0;
+ lcbPlcfpgdFtn=0;
+ fcAutosaveSource=0;
+ lcbAutosaveSource=0;
+ fcGrpXstAtnOwners=0;
+ lcbGrpXstAtnOwners=0;
+ fcSttbfAtnbkmk=0;
+ lcbSttbfAtnbkmk=0;
+ fcPlcdoaMom=0;
+ lcbPlcdoaMom=0;
+ fcPlcdoaHdr=0;
+ lcbPlcdoaHdr=0;
+ fcPlcspaMom=0;
+ lcbPlcspaMom=0;
+ fcPlcspaHdr=0;
+ lcbPlcspaHdr=0;
+ fcPlcfAtnbkf=0;
+ lcbPlcfAtnbkf=0;
+ fcPlcfAtnbkl=0;
+ lcbPlcfAtnbkl=0;
+ fcPms=0;
+ lcbPms=0;
+ fcFormFldSttbf=0;
+ lcbFormFldSttbf=0;
+ fcPlcfendRef=0;
+ lcbPlcfendRef=0;
+ fcPlcfendTxt=0;
+ lcbPlcfendTxt=0;
+ fcPlcffldEdn=0;
+ lcbPlcffldEdn=0;
+ fcPlcfpgdEdn=0;
+ lcbPlcfpgdEdn=0;
+ fcDggInfo=0;
+ lcbDggInfo=0;
+ fcSttbfRMark=0;
+ lcbSttbfRMark=0;
+ fcSttbfCaption=0;
+ lcbSttbfCaption=0;
+ fcSttbfAutoCaption=0;
+ lcbSttbfAutoCaption=0;
+ fcPlcfwkb=0;
+ lcbPlcfwkb=0;
+ fcPlcfspl=0;
+ lcbPlcfspl=0;
+ fcPlcftxbxTxt=0;
+ lcbPlcftxbxTxt=0;
+ fcPlcffldTxbx=0;
+ lcbPlcffldTxbx=0;
+ fcPlcfHdrtxbxTxt=0;
+ lcbPlcfHdrtxbxTxt=0;
+ fcPlcffldHdrTxbx=0;
+ lcbPlcffldHdrTxbx=0;
+ fcStwUser=0;
+ lcbStwUser=0;
+ fcSttbttmbd=0;
+ lcbSttbttmbd=0;
+ fcUnused=0;
+ lcbUnused=0;
+ fcPgdMother=0;
+ lcbPgdMother=0;
+ fcBkdMother=0;
+ lcbBkdMother=0;
+ fcPgdFtn=0;
+ lcbPgdFtn=0;
+ fcBkdFtn=0;
+ lcbBkdFtn=0;
+ fcPgdEdn=0;
+ lcbPgdEdn=0;
+ fcBkdEdn=0;
+ lcbBkdEdn=0;
+ fcSttbfIntlFld=0;
+ lcbSttbfIntlFld=0;
+ fcRouteSlip=0;
+ lcbRouteSlip=0;
+ fcSttbSavedBy=0;
+ lcbSttbSavedBy=0;
+ fcSttbFnm=0;
+ lcbSttbFnm=0;
+ fcPlcfLst=0;
+ lcbPlcfLst=0;
+ fcPlfLfo=0;
+ lcbPlfLfo=0;
+ fcPlcftxbxBkd=0;
+ lcbPlcftxbxBkd=0;
+ fcPlcftxbxHdrBkd=0;
+ lcbPlcftxbxHdrBkd=0;
+ fcDocUndo=0;
+ lcbDocUndo=0;
+ fcRgbuse=0;
+ lcbRgbuse=0;
+ fcUsp=0;
+ lcbUsp=0;
+ fcUskf=0;
+ lcbUskf=0;
+ fcPlcupcRgbuse=0;
+ lcbPlcupcRgbuse=0;
+ fcPlcupcUsp=0;
+ lcbPlcupcUsp=0;
+ fcSttbGlsyStyle=0;
+ lcbSttbGlsyStyle=0;
+ fcPlgosl=0;
+ lcbPlgosl=0;
+ fcPlcocx=0;
+ lcbPlcocx=0;
+ fcPlcfbteLvc=0;
+ lcbPlcfbteLvc=0;
+ dwLowDateTime=0;
+ dwHighDateTime=0;
+ fcPlcflvc=0;
+ lcbPlcflvc=0;
+ fcPlcasumy=0;
+ lcbPlcasumy=0;
+ fcPlcfgram=0;
+ lcbPlcfgram=0;
+ fcSttbListNames=0;
+ lcbSttbListNames=0;
+ fcSttbfUssr=0;
+ lcbSttbfUssr=0;
+}
+
+bool operator==(const FIB &lhs, const FIB &rhs) {
+
+ return lhs.wIdent==rhs.wIdent &&
+ lhs.nFib==rhs.nFib &&
+ lhs.nProduct==rhs.nProduct &&
+ lhs.lid==rhs.lid &&
+ lhs.pnNext==rhs.pnNext &&
+ lhs.fDot==rhs.fDot &&
+ lhs.fGlsy==rhs.fGlsy &&
+ lhs.fComplex==rhs.fComplex &&
+ lhs.fHasPic==rhs.fHasPic &&
+ lhs.cQuickSaves==rhs.cQuickSaves &&
+ lhs.fEncrypted==rhs.fEncrypted &&
+ lhs.fWhichTblStm==rhs.fWhichTblStm &&
+ lhs.fReadOnlyRecommended==rhs.fReadOnlyRecommended &&
+ lhs.fWriteReservation==rhs.fWriteReservation &&
+ lhs.fExtChar==rhs.fExtChar &&
+ lhs.fLoadOverride==rhs.fLoadOverride &&
+ lhs.fFarEast==rhs.fFarEast &&
+ lhs.fCrypto==rhs.fCrypto &&
+ lhs.nFibBack==rhs.nFibBack &&
+ lhs.lKey==rhs.lKey &&
+ lhs.envr==rhs.envr &&
+ lhs.fMac==rhs.fMac &&
+ lhs.fEmptySpecial==rhs.fEmptySpecial &&
+ lhs.fLoadOverridePage==rhs.fLoadOverridePage &&
+ lhs.fFutureSavedUndo==rhs.fFutureSavedUndo &&
+ lhs.fWord97Saved==rhs.fWord97Saved &&
+ lhs.fSpare0==rhs.fSpare0 &&
+ lhs.chs==rhs.chs &&
+ lhs.chsTables==rhs.chsTables &&
+ lhs.fcMin==rhs.fcMin &&
+ lhs.fcMac==rhs.fcMac &&
+ lhs.csw==rhs.csw &&
+ lhs.wMagicCreated==rhs.wMagicCreated &&
+ lhs.wMagicRevised==rhs.wMagicRevised &&
+ lhs.wMagicCreatedPrivate==rhs.wMagicCreatedPrivate &&
+ lhs.wMagicRevisedPrivate==rhs.wMagicRevisedPrivate &&
+ lhs.pnFbpChpFirst_W6==rhs.pnFbpChpFirst_W6 &&
+ lhs.pnChpFirst_W6==rhs.pnChpFirst_W6 &&
+ lhs.cpnBteChp_W6==rhs.cpnBteChp_W6 &&
+ lhs.pnFbpPapFirst_W6==rhs.pnFbpPapFirst_W6 &&
+ lhs.pnPapFirst_W6==rhs.pnPapFirst_W6 &&
+ lhs.cpnBtePap_W6==rhs.cpnBtePap_W6 &&
+ lhs.pnFbpLvcFirst_W6==rhs.pnFbpLvcFirst_W6 &&
+ lhs.pnLvcFirst_W6==rhs.pnLvcFirst_W6 &&
+ lhs.cpnBteLvc_W6==rhs.cpnBteLvc_W6 &&
+ lhs.lidFE==rhs.lidFE &&
+ lhs.clw==rhs.clw &&
+ lhs.cbMac==rhs.cbMac &&
+ lhs.lProductCreated==rhs.lProductCreated &&
+ lhs.lProductRevised==rhs.lProductRevised &&
+ lhs.ccpText==rhs.ccpText &&
+ lhs.ccpFtn==rhs.ccpFtn &&
+ lhs.ccpHdd==rhs.ccpHdd &&
+ lhs.ccpMcr==rhs.ccpMcr &&
+ lhs.ccpAtn==rhs.ccpAtn &&
+ lhs.ccpEdn==rhs.ccpEdn &&
+ lhs.ccpTxbx==rhs.ccpTxbx &&
+ lhs.ccpHdrTxbx==rhs.ccpHdrTxbx &&
+ lhs.pnFbpChpFirst==rhs.pnFbpChpFirst &&
+ lhs.pnChpFirst==rhs.pnChpFirst &&
+ lhs.cpnBteChp==rhs.cpnBteChp &&
+ lhs.pnFbpPapFirst==rhs.pnFbpPapFirst &&
+ lhs.pnPapFirst==rhs.pnPapFirst &&
+ lhs.cpnBtePap==rhs.cpnBtePap &&
+ lhs.pnFbpLvcFirst==rhs.pnFbpLvcFirst &&
+ lhs.pnLvcFirst==rhs.pnLvcFirst &&
+ lhs.cpnBteLvc==rhs.cpnBteLvc &&
+ lhs.fcIslandFirst==rhs.fcIslandFirst &&
+ lhs.fcIslandLim==rhs.fcIslandLim &&
+ lhs.cfclcb==rhs.cfclcb &&
+ lhs.fcStshfOrig==rhs.fcStshfOrig &&
+ lhs.lcbStshfOrig==rhs.lcbStshfOrig &&
+ lhs.fcStshf==rhs.fcStshf &&
+ lhs.lcbStshf==rhs.lcbStshf &&
+ lhs.fcPlcffndRef==rhs.fcPlcffndRef &&
+ lhs.lcbPlcffndRef==rhs.lcbPlcffndRef &&
+ lhs.fcPlcffndTxt==rhs.fcPlcffndTxt &&
+ lhs.lcbPlcffndTxt==rhs.lcbPlcffndTxt &&
+ lhs.fcPlcfandRef==rhs.fcPlcfandRef &&
+ lhs.lcbPlcfandRef==rhs.lcbPlcfandRef &&
+ lhs.fcPlcfandTxt==rhs.fcPlcfandTxt &&
+ lhs.lcbPlcfandTxt==rhs.lcbPlcfandTxt &&
+ lhs.fcPlcfsed==rhs.fcPlcfsed &&
+ lhs.lcbPlcfsed==rhs.lcbPlcfsed &&
+ lhs.fcPlcfpad==rhs.fcPlcfpad &&
+ lhs.lcbPlcfpad==rhs.lcbPlcfpad &&
+ lhs.fcPlcfphe==rhs.fcPlcfphe &&
+ lhs.lcbPlcfphe==rhs.lcbPlcfphe &&
+ lhs.fcSttbfglsy==rhs.fcSttbfglsy &&
+ lhs.lcbSttbfglsy==rhs.lcbSttbfglsy &&
+ lhs.fcPlcfglsy==rhs.fcPlcfglsy &&
+ lhs.lcbPlcfglsy==rhs.lcbPlcfglsy &&
+ lhs.fcPlcfhdd==rhs.fcPlcfhdd &&
+ lhs.lcbPlcfhdd==rhs.lcbPlcfhdd &&
+ lhs.fcPlcfbteChpx==rhs.fcPlcfbteChpx &&
+ lhs.lcbPlcfbteChpx==rhs.lcbPlcfbteChpx &&
+ lhs.fcPlcfbtePapx==rhs.fcPlcfbtePapx &&
+ lhs.lcbPlcfbtePapx==rhs.lcbPlcfbtePapx &&
+ lhs.fcPlcfsea==rhs.fcPlcfsea &&
+ lhs.lcbPlcfsea==rhs.lcbPlcfsea &&
+ lhs.fcSttbfffn==rhs.fcSttbfffn &&
+ lhs.lcbSttbfffn==rhs.lcbSttbfffn &&
+ lhs.fcPlcffldMom==rhs.fcPlcffldMom &&
+ lhs.lcbPlcffldMom==rhs.lcbPlcffldMom &&
+ lhs.fcPlcffldHdr==rhs.fcPlcffldHdr &&
+ lhs.lcbPlcffldHdr==rhs.lcbPlcffldHdr &&
+ lhs.fcPlcffldFtn==rhs.fcPlcffldFtn &&
+ lhs.lcbPlcffldFtn==rhs.lcbPlcffldFtn &&
+ lhs.fcPlcffldAtn==rhs.fcPlcffldAtn &&
+ lhs.lcbPlcffldAtn==rhs.lcbPlcffldAtn &&
+ lhs.fcPlcffldMcr==rhs.fcPlcffldMcr &&
+ lhs.lcbPlcffldMcr==rhs.lcbPlcffldMcr &&
+ lhs.fcSttbfbkmk==rhs.fcSttbfbkmk &&
+ lhs.lcbSttbfbkmk==rhs.lcbSttbfbkmk &&
+ lhs.fcPlcfbkf==rhs.fcPlcfbkf &&
+ lhs.lcbPlcfbkf==rhs.lcbPlcfbkf &&
+ lhs.fcPlcfbkl==rhs.fcPlcfbkl &&
+ lhs.lcbPlcfbkl==rhs.lcbPlcfbkl &&
+ lhs.fcCmds==rhs.fcCmds &&
+ lhs.lcbCmds==rhs.lcbCmds &&
+ lhs.fcPlcmcr==rhs.fcPlcmcr &&
+ lhs.lcbPlcmcr==rhs.lcbPlcmcr &&
+ lhs.fcSttbfmcr==rhs.fcSttbfmcr &&
+ lhs.lcbSttbfmcr==rhs.lcbSttbfmcr &&
+ lhs.fcPrDrvr==rhs.fcPrDrvr &&
+ lhs.lcbPrDrvr==rhs.lcbPrDrvr &&
+ lhs.fcPrEnvPort==rhs.fcPrEnvPort &&
+ lhs.lcbPrEnvPort==rhs.lcbPrEnvPort &&
+ lhs.fcPrEnvLand==rhs.fcPrEnvLand &&
+ lhs.lcbPrEnvLand==rhs.lcbPrEnvLand &&
+ lhs.fcWss==rhs.fcWss &&
+ lhs.lcbWss==rhs.lcbWss &&
+ lhs.fcDop==rhs.fcDop &&
+ lhs.lcbDop==rhs.lcbDop &&
+ lhs.fcSttbfAssoc==rhs.fcSttbfAssoc &&
+ lhs.lcbSttbfAssoc==rhs.lcbSttbfAssoc &&
+ lhs.fcClx==rhs.fcClx &&
+ lhs.lcbClx==rhs.lcbClx &&
+ lhs.fcPlcfpgdFtn==rhs.fcPlcfpgdFtn &&
+ lhs.lcbPlcfpgdFtn==rhs.lcbPlcfpgdFtn &&
+ lhs.fcAutosaveSource==rhs.fcAutosaveSource &&
+ lhs.lcbAutosaveSource==rhs.lcbAutosaveSource &&
+ lhs.fcGrpXstAtnOwners==rhs.fcGrpXstAtnOwners &&
+ lhs.lcbGrpXstAtnOwners==rhs.lcbGrpXstAtnOwners &&
+ lhs.fcSttbfAtnbkmk==rhs.fcSttbfAtnbkmk &&
+ lhs.lcbSttbfAtnbkmk==rhs.lcbSttbfAtnbkmk &&
+ lhs.fcPlcdoaMom==rhs.fcPlcdoaMom &&
+ lhs.lcbPlcdoaMom==rhs.lcbPlcdoaMom &&
+ lhs.fcPlcdoaHdr==rhs.fcPlcdoaHdr &&
+ lhs.lcbPlcdoaHdr==rhs.lcbPlcdoaHdr &&
+ lhs.fcPlcspaMom==rhs.fcPlcspaMom &&
+ lhs.lcbPlcspaMom==rhs.lcbPlcspaMom &&
+ lhs.fcPlcspaHdr==rhs.fcPlcspaHdr &&
+ lhs.lcbPlcspaHdr==rhs.lcbPlcspaHdr &&
+ lhs.fcPlcfAtnbkf==rhs.fcPlcfAtnbkf &&
+ lhs.lcbPlcfAtnbkf==rhs.lcbPlcfAtnbkf &&
+ lhs.fcPlcfAtnbkl==rhs.fcPlcfAtnbkl &&
+ lhs.lcbPlcfAtnbkl==rhs.lcbPlcfAtnbkl &&
+ lhs.fcPms==rhs.fcPms &&
+ lhs.lcbPms==rhs.lcbPms &&
+ lhs.fcFormFldSttbf==rhs.fcFormFldSttbf &&
+ lhs.lcbFormFldSttbf==rhs.lcbFormFldSttbf &&
+ lhs.fcPlcfendRef==rhs.fcPlcfendRef &&
+ lhs.lcbPlcfendRef==rhs.lcbPlcfendRef &&
+ lhs.fcPlcfendTxt==rhs.fcPlcfendTxt &&
+ lhs.lcbPlcfendTxt==rhs.lcbPlcfendTxt &&
+ lhs.fcPlcffldEdn==rhs.fcPlcffldEdn &&
+ lhs.lcbPlcffldEdn==rhs.lcbPlcffldEdn &&
+ lhs.fcPlcfpgdEdn==rhs.fcPlcfpgdEdn &&
+ lhs.lcbPlcfpgdEdn==rhs.lcbPlcfpgdEdn &&
+ lhs.fcDggInfo==rhs.fcDggInfo &&
+ lhs.lcbDggInfo==rhs.lcbDggInfo &&
+ lhs.fcSttbfRMark==rhs.fcSttbfRMark &&
+ lhs.lcbSttbfRMark==rhs.lcbSttbfRMark &&
+ lhs.fcSttbfCaption==rhs.fcSttbfCaption &&
+ lhs.lcbSttbfCaption==rhs.lcbSttbfCaption &&
+ lhs.fcSttbfAutoCaption==rhs.fcSttbfAutoCaption &&
+ lhs.lcbSttbfAutoCaption==rhs.lcbSttbfAutoCaption &&
+ lhs.fcPlcfwkb==rhs.fcPlcfwkb &&
+ lhs.lcbPlcfwkb==rhs.lcbPlcfwkb &&
+ lhs.fcPlcfspl==rhs.fcPlcfspl &&
+ lhs.lcbPlcfspl==rhs.lcbPlcfspl &&
+ lhs.fcPlcftxbxTxt==rhs.fcPlcftxbxTxt &&
+ lhs.lcbPlcftxbxTxt==rhs.lcbPlcftxbxTxt &&
+ lhs.fcPlcffldTxbx==rhs.fcPlcffldTxbx &&
+ lhs.lcbPlcffldTxbx==rhs.lcbPlcffldTxbx &&
+ lhs.fcPlcfHdrtxbxTxt==rhs.fcPlcfHdrtxbxTxt &&
+ lhs.lcbPlcfHdrtxbxTxt==rhs.lcbPlcfHdrtxbxTxt &&
+ lhs.fcPlcffldHdrTxbx==rhs.fcPlcffldHdrTxbx &&
+ lhs.lcbPlcffldHdrTxbx==rhs.lcbPlcffldHdrTxbx &&
+ lhs.fcStwUser==rhs.fcStwUser &&
+ lhs.lcbStwUser==rhs.lcbStwUser &&
+ lhs.fcSttbttmbd==rhs.fcSttbttmbd &&
+ lhs.lcbSttbttmbd==rhs.lcbSttbttmbd &&
+ lhs.fcUnused==rhs.fcUnused &&
+ lhs.lcbUnused==rhs.lcbUnused &&
+ lhs.fcPgdMother==rhs.fcPgdMother &&
+ lhs.lcbPgdMother==rhs.lcbPgdMother &&
+ lhs.fcBkdMother==rhs.fcBkdMother &&
+ lhs.lcbBkdMother==rhs.lcbBkdMother &&
+ lhs.fcPgdFtn==rhs.fcPgdFtn &&
+ lhs.lcbPgdFtn==rhs.lcbPgdFtn &&
+ lhs.fcBkdFtn==rhs.fcBkdFtn &&
+ lhs.lcbBkdFtn==rhs.lcbBkdFtn &&
+ lhs.fcPgdEdn==rhs.fcPgdEdn &&
+ lhs.lcbPgdEdn==rhs.lcbPgdEdn &&
+ lhs.fcBkdEdn==rhs.fcBkdEdn &&
+ lhs.lcbBkdEdn==rhs.lcbBkdEdn &&
+ lhs.fcSttbfIntlFld==rhs.fcSttbfIntlFld &&
+ lhs.lcbSttbfIntlFld==rhs.lcbSttbfIntlFld &&
+ lhs.fcRouteSlip==rhs.fcRouteSlip &&
+ lhs.lcbRouteSlip==rhs.lcbRouteSlip &&
+ lhs.fcSttbSavedBy==rhs.fcSttbSavedBy &&
+ lhs.lcbSttbSavedBy==rhs.lcbSttbSavedBy &&
+ lhs.fcSttbFnm==rhs.fcSttbFnm &&
+ lhs.lcbSttbFnm==rhs.lcbSttbFnm &&
+ lhs.fcPlcfLst==rhs.fcPlcfLst &&
+ lhs.lcbPlcfLst==rhs.lcbPlcfLst &&
+ lhs.fcPlfLfo==rhs.fcPlfLfo &&
+ lhs.lcbPlfLfo==rhs.lcbPlfLfo &&
+ lhs.fcPlcftxbxBkd==rhs.fcPlcftxbxBkd &&
+ lhs.lcbPlcftxbxBkd==rhs.lcbPlcftxbxBkd &&
+ lhs.fcPlcftxbxHdrBkd==rhs.fcPlcftxbxHdrBkd &&
+ lhs.lcbPlcftxbxHdrBkd==rhs.lcbPlcftxbxHdrBkd &&
+ lhs.fcDocUndo==rhs.fcDocUndo &&
+ lhs.lcbDocUndo==rhs.lcbDocUndo &&
+ lhs.fcRgbuse==rhs.fcRgbuse &&
+ lhs.lcbRgbuse==rhs.lcbRgbuse &&
+ lhs.fcUsp==rhs.fcUsp &&
+ lhs.lcbUsp==rhs.lcbUsp &&
+ lhs.fcUskf==rhs.fcUskf &&
+ lhs.lcbUskf==rhs.lcbUskf &&
+ lhs.fcPlcupcRgbuse==rhs.fcPlcupcRgbuse &&
+ lhs.lcbPlcupcRgbuse==rhs.lcbPlcupcRgbuse &&
+ lhs.fcPlcupcUsp==rhs.fcPlcupcUsp &&
+ lhs.lcbPlcupcUsp==rhs.lcbPlcupcUsp &&
+ lhs.fcSttbGlsyStyle==rhs.fcSttbGlsyStyle &&
+ lhs.lcbSttbGlsyStyle==rhs.lcbSttbGlsyStyle &&
+ lhs.fcPlgosl==rhs.fcPlgosl &&
+ lhs.lcbPlgosl==rhs.lcbPlgosl &&
+ lhs.fcPlcocx==rhs.fcPlcocx &&
+ lhs.lcbPlcocx==rhs.lcbPlcocx &&
+ lhs.fcPlcfbteLvc==rhs.fcPlcfbteLvc &&
+ lhs.lcbPlcfbteLvc==rhs.lcbPlcfbteLvc &&
+ lhs.dwLowDateTime==rhs.dwLowDateTime &&
+ lhs.dwHighDateTime==rhs.dwHighDateTime &&
+ lhs.fcPlcflvc==rhs.fcPlcflvc &&
+ lhs.lcbPlcflvc==rhs.lcbPlcflvc &&
+ lhs.fcPlcasumy==rhs.fcPlcasumy &&
+ lhs.lcbPlcasumy==rhs.lcbPlcasumy &&
+ lhs.fcPlcfgram==rhs.fcPlcfgram &&
+ lhs.lcbPlcfgram==rhs.lcbPlcfgram &&
+ lhs.fcSttbListNames==rhs.fcSttbListNames &&
+ lhs.lcbSttbListNames==rhs.lcbSttbListNames &&
+ lhs.fcSttbfUssr==rhs.fcSttbfUssr &&
+ lhs.lcbSttbfUssr==rhs.lcbSttbfUssr;
+}
+
+bool operator!=(const FIB &lhs, const FIB &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// FIBFCLCB implementation
+
+FIBFCLCB::FIBFCLCB() {
+ clear();
+}
+
+FIBFCLCB::FIBFCLCB(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool FIBFCLCB::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ fc=stream->readU32();
+ lcb=stream->readU32();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool FIBFCLCB::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(fc);
+ stream->write(lcb);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void FIBFCLCB::clear() {
+ fc=0;
+ lcb=0;
+}
+
+bool operator==(const FIBFCLCB &lhs, const FIBFCLCB &rhs) {
+
+ return lhs.fc==rhs.fc &&
+ lhs.lcb==rhs.lcb;
+}
+
+bool operator!=(const FIBFCLCB &lhs, const FIBFCLCB &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// FRD implementation
+
+const unsigned int FRD::sizeOf = 2;
+
+FRD::FRD() {
+ clear();
+}
+
+FRD::FRD(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool FRD::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ nAuto=stream->readS16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool FRD::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(nAuto);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void FRD::clear() {
+ nAuto=0;
+}
+
+bool operator==(const FRD &lhs, const FRD &rhs) {
+
+ return lhs.nAuto==rhs.nAuto;
+}
+
+bool operator!=(const FRD &lhs, const FRD &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// FSPA implementation
+
+const unsigned int FSPA::sizeOf = 26;
+
+FSPA::FSPA() {
+ clear();
+}
+
+FSPA::FSPA(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool FSPA::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ spid=stream->readS32();
+ xaLeft=stream->readS32();
+ yaTop=stream->readS32();
+ xaRight=stream->readS32();
+ yaBottom=stream->readS32();
+ shifterU16=stream->readU16();
+ fHdr=shifterU16;
+ shifterU16>>=1;
+ bx=shifterU16;
+ shifterU16>>=2;
+ by=shifterU16;
+ shifterU16>>=2;
+ wr=shifterU16;
+ shifterU16>>=4;
+ wrk=shifterU16;
+ shifterU16>>=4;
+ fRcaSimple=shifterU16;
+ shifterU16>>=1;
+ fBelowText=shifterU16;
+ shifterU16>>=1;
+ fAnchorLock=shifterU16;
+ cTxbx=stream->readS32();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool FSPA::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(spid);
+ stream->write(xaLeft);
+ stream->write(yaTop);
+ stream->write(xaRight);
+ stream->write(yaBottom);
+ shifterU16=fHdr;
+ shifterU16|=bx << 1;
+ shifterU16|=by << 3;
+ shifterU16|=wr << 5;
+ shifterU16|=wrk << 9;
+ shifterU16|=fRcaSimple << 13;
+ shifterU16|=fBelowText << 14;
+ shifterU16|=fAnchorLock << 15;
+ stream->write(shifterU16);
+ stream->write(cTxbx);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void FSPA::clear() {
+ spid=0;
+ xaLeft=0;
+ yaTop=0;
+ xaRight=0;
+ yaBottom=0;
+ fHdr=0;
+ bx=0;
+ by=0;
+ wr=0;
+ wrk=0;
+ fRcaSimple=0;
+ fBelowText=0;
+ fAnchorLock=0;
+ cTxbx=0;
+}
+
+bool operator==(const FSPA &lhs, const FSPA &rhs) {
+
+ return lhs.spid==rhs.spid &&
+ lhs.xaLeft==rhs.xaLeft &&
+ lhs.yaTop==rhs.yaTop &&
+ lhs.xaRight==rhs.xaRight &&
+ lhs.yaBottom==rhs.yaBottom &&
+ lhs.fHdr==rhs.fHdr &&
+ lhs.bx==rhs.bx &&
+ lhs.by==rhs.by &&
+ lhs.wr==rhs.wr &&
+ lhs.wrk==rhs.wrk &&
+ lhs.fRcaSimple==rhs.fRcaSimple &&
+ lhs.fBelowText==rhs.fBelowText &&
+ lhs.fAnchorLock==rhs.fAnchorLock &&
+ lhs.cTxbx==rhs.cTxbx;
+}
+
+bool operator!=(const FSPA &lhs, const FSPA &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// FTXBXS implementation
+
+const unsigned int FTXBXS::sizeOf = 22;
+
+FTXBXS::FTXBXS() {
+ clear();
+}
+
+FTXBXS::FTXBXS(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool FTXBXS::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ cTxbx_iNextReuse=stream->readS32();
+ cReusable=stream->readS32();
+ fReusable=stream->readS16();
+ reserved=stream->readU32();
+ lid=stream->readS32();
+ txidUndo=stream->readS32();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool FTXBXS::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(cTxbx_iNextReuse);
+ stream->write(cReusable);
+ stream->write(fReusable);
+ stream->write(reserved);
+ stream->write(lid);
+ stream->write(txidUndo);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void FTXBXS::clear() {
+ cTxbx_iNextReuse=0;
+ cReusable=0;
+ fReusable=0;
+ reserved=0;
+ lid=0;
+ txidUndo=0;
+}
+
+bool operator==(const FTXBXS &lhs, const FTXBXS &rhs) {
+
+ return lhs.cTxbx_iNextReuse==rhs.cTxbx_iNextReuse &&
+ lhs.cReusable==rhs.cReusable &&
+ lhs.fReusable==rhs.fReusable &&
+ lhs.reserved==rhs.reserved &&
+ lhs.lid==rhs.lid &&
+ lhs.txidUndo==rhs.txidUndo;
+}
+
+bool operator!=(const FTXBXS &lhs, const FTXBXS &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// LFO implementation
+
+const unsigned int LFO::sizeOf = 16;
+
+LFO::LFO() {
+ clear();
+}
+
+LFO::LFO(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool LFO::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ lsid=stream->readS32();
+ unused4=stream->readS32();
+ unused8=stream->readS32();
+ clfolvl=stream->readU8();
+ for(int _i=0; _i<(3); ++_i)
+ reserved[_i]=stream->readU8();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool LFO::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(lsid);
+ stream->write(unused4);
+ stream->write(unused8);
+ stream->write(clfolvl);
+ for(int _i=0; _i<(3); ++_i)
+ stream->write(reserved[_i]);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void LFO::clear() {
+ lsid=0;
+ unused4=0;
+ unused8=0;
+ clfolvl=0;
+ for(int _i=0; _i<(3); ++_i)
+ reserved[_i]=0;
+}
+
+bool operator==(const LFO &lhs, const LFO &rhs) {
+
+ for(int _i=0; _i<(3); ++_i) {
+ if(lhs.reserved[_i]!=rhs.reserved[_i])
+ return false;
+ }
+
+ return lhs.lsid==rhs.lsid &&
+ lhs.unused4==rhs.unused4 &&
+ lhs.unused8==rhs.unused8 &&
+ lhs.clfolvl==rhs.clfolvl;
+}
+
+bool operator!=(const LFO &lhs, const LFO &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// LFOLVL implementation
+
+LFOLVL::LFOLVL() {
+ clear();
+}
+
+LFOLVL::LFOLVL(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool LFOLVL::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ iStartAt=stream->readS32();
+ shifterU8=stream->readU8();
+ ilvl=shifterU8;
+ shifterU8>>=4;
+ fStartAt=shifterU8;
+ shifterU8>>=1;
+ fFormatting=shifterU8;
+ shifterU8>>=1;
+ unsigned4_6=shifterU8;
+ for(int _i=0; _i<(3); ++_i)
+ reserved[_i]=stream->readU8();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool LFOLVL::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(iStartAt);
+ shifterU8=ilvl;
+ shifterU8|=fStartAt << 4;
+ shifterU8|=fFormatting << 5;
+ shifterU8|=unsigned4_6 << 6;
+ stream->write(shifterU8);
+ for(int _i=0; _i<(3); ++_i)
+ stream->write(reserved[_i]);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void LFOLVL::clear() {
+ iStartAt=0;
+ ilvl=0;
+ fStartAt=0;
+ fFormatting=0;
+ unsigned4_6=0;
+ for(int _i=0; _i<(3); ++_i)
+ reserved[_i]=0;
+}
+
+bool operator==(const LFOLVL &lhs, const LFOLVL &rhs) {
+
+ for(int _i=0; _i<(3); ++_i) {
+ if(lhs.reserved[_i]!=rhs.reserved[_i])
+ return false;
+ }
+
+ return lhs.iStartAt==rhs.iStartAt &&
+ lhs.ilvl==rhs.ilvl &&
+ lhs.fStartAt==rhs.fStartAt &&
+ lhs.fFormatting==rhs.fFormatting &&
+ lhs.unsigned4_6==rhs.unsigned4_6;
+}
+
+bool operator!=(const LFOLVL &lhs, const LFOLVL &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// LSPD implementation
+
+LSPD::LSPD() {
+ clear();
+}
+
+LSPD::LSPD(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool LSPD::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ dyaLine=stream->readS16();
+ fMultLinespace=stream->readS16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool LSPD::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(dyaLine);
+ stream->write(fMultLinespace);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void LSPD::clear() {
+ dyaLine=240;
+ fMultLinespace=1;
+}
+
+void LSPD::dump() const
+{
+ wvlog << "Dumping LSPD:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping LSPD done." << std::endl;
+}
+
+std::string LSPD::toString() const
+{
+ std::string s( "LSPD:" );
+ s += "\ndyaLine=";
+ s += int2string( dyaLine );
+ s += "\nfMultLinespace=";
+ s += int2string( fMultLinespace );
+ s += "\nLSPD Done.";
+ return s;
+}
+
+bool operator==(const LSPD &lhs, const LSPD &rhs) {
+
+ return lhs.dyaLine==rhs.dyaLine &&
+ lhs.fMultLinespace==rhs.fMultLinespace;
+}
+
+bool operator!=(const LSPD &lhs, const LSPD &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// LSTF implementation
+
+const unsigned int LSTF::sizeOf = 28;
+
+LSTF::LSTF() {
+ clear();
+}
+
+LSTF::LSTF(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool LSTF::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ lsid=stream->readS32();
+ tplc=stream->readS32();
+ for(int _i=0; _i<(9); ++_i)
+ rgistd[_i]=stream->readU16();
+ shifterU8=stream->readU8();
+ fSimpleList=shifterU8;
+ shifterU8>>=1;
+ fRestartHdn=shifterU8;
+ shifterU8>>=1;
+ unsigned26_2=shifterU8;
+ reserved=stream->readU8();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool LSTF::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(lsid);
+ stream->write(tplc);
+ for(int _i=0; _i<(9); ++_i)
+ stream->write(rgistd[_i]);
+ shifterU8=fSimpleList;
+ shifterU8|=fRestartHdn << 1;
+ shifterU8|=unsigned26_2 << 2;
+ stream->write(shifterU8);
+ stream->write(reserved);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void LSTF::clear() {
+ lsid=0;
+ tplc=0;
+ for(int _i=0; _i<(9); ++_i)
+ rgistd[_i]=0;
+ fSimpleList=0;
+ fRestartHdn=0;
+ unsigned26_2=0;
+ reserved=0;
+}
+
+bool operator==(const LSTF &lhs, const LSTF &rhs) {
+
+ for(int _i=0; _i<(9); ++_i) {
+ if(lhs.rgistd[_i]!=rhs.rgistd[_i])
+ return false;
+ }
+
+ return lhs.lsid==rhs.lsid &&
+ lhs.tplc==rhs.tplc &&
+ lhs.fSimpleList==rhs.fSimpleList &&
+ lhs.fRestartHdn==rhs.fRestartHdn &&
+ lhs.unsigned26_2==rhs.unsigned26_2 &&
+ lhs.reserved==rhs.reserved;
+}
+
+bool operator!=(const LSTF &lhs, const LSTF &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// LVLF implementation
+
+LVLF::LVLF() {
+ clear();
+}
+
+LVLF::LVLF(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool LVLF::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ iStartAt=stream->readU32();
+ nfc=stream->readU8();
+ shifterU8=stream->readU8();
+ jc=shifterU8;
+ shifterU8>>=2;
+ fLegal=shifterU8;
+ shifterU8>>=1;
+ fNoRestart=shifterU8;
+ shifterU8>>=1;
+ fPrev=shifterU8;
+ shifterU8>>=1;
+ fPrevSpace=shifterU8;
+ shifterU8>>=1;
+ fWord6=shifterU8;
+ shifterU8>>=1;
+ unused5_7=shifterU8;
+ for(int _i=0; _i<(9); ++_i)
+ rgbxchNums[_i]=stream->readU8();
+ ixchFollow=stream->readU8();
+ dxaSpace=stream->readS32();
+ dxaIndent=stream->readS32();
+ cbGrpprlChpx=stream->readU8();
+ cbGrpprlPapx=stream->readU8();
+ reserved=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool LVLF::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(iStartAt);
+ stream->write(nfc);
+ shifterU8=jc;
+ shifterU8|=fLegal << 2;
+ shifterU8|=fNoRestart << 3;
+ shifterU8|=fPrev << 4;
+ shifterU8|=fPrevSpace << 5;
+ shifterU8|=fWord6 << 6;
+ shifterU8|=unused5_7 << 7;
+ stream->write(shifterU8);
+ for(int _i=0; _i<(9); ++_i)
+ stream->write(rgbxchNums[_i]);
+ stream->write(ixchFollow);
+ stream->write(dxaSpace);
+ stream->write(dxaIndent);
+ stream->write(cbGrpprlChpx);
+ stream->write(cbGrpprlPapx);
+ stream->write(reserved);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void LVLF::clear() {
+ iStartAt=0;
+ nfc=0;
+ jc=0;
+ fLegal=0;
+ fNoRestart=0;
+ fPrev=0;
+ fPrevSpace=0;
+ fWord6=0;
+ unused5_7=0;
+ for(int _i=0; _i<(9); ++_i)
+ rgbxchNums[_i]=0;
+ ixchFollow=0;
+ dxaSpace=0;
+ dxaIndent=0;
+ cbGrpprlChpx=0;
+ cbGrpprlPapx=0;
+ reserved=0;
+}
+
+bool operator==(const LVLF &lhs, const LVLF &rhs) {
+
+ for(int _i=0; _i<(9); ++_i) {
+ if(lhs.rgbxchNums[_i]!=rhs.rgbxchNums[_i])
+ return false;
+ }
+
+ return lhs.iStartAt==rhs.iStartAt &&
+ lhs.nfc==rhs.nfc &&
+ lhs.jc==rhs.jc &&
+ lhs.fLegal==rhs.fLegal &&
+ lhs.fNoRestart==rhs.fNoRestart &&
+ lhs.fPrev==rhs.fPrev &&
+ lhs.fPrevSpace==rhs.fPrevSpace &&
+ lhs.fWord6==rhs.fWord6 &&
+ lhs.unused5_7==rhs.unused5_7 &&
+ lhs.ixchFollow==rhs.ixchFollow &&
+ lhs.dxaSpace==rhs.dxaSpace &&
+ lhs.dxaIndent==rhs.dxaIndent &&
+ lhs.cbGrpprlChpx==rhs.cbGrpprlChpx &&
+ lhs.cbGrpprlPapx==rhs.cbGrpprlPapx &&
+ lhs.reserved==rhs.reserved;
+}
+
+bool operator!=(const LVLF &lhs, const LVLF &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// METAFILEPICT implementation
+
+METAFILEPICT::METAFILEPICT() {
+ clear();
+}
+
+METAFILEPICT::METAFILEPICT(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool METAFILEPICT::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ mm=stream->readS16();
+ xExt=stream->readS16();
+ yExt=stream->readS16();
+ hMF=stream->readS16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool METAFILEPICT::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(mm);
+ stream->write(xExt);
+ stream->write(yExt);
+ stream->write(hMF);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void METAFILEPICT::clear() {
+ mm=0;
+ xExt=0;
+ yExt=0;
+ hMF=0;
+}
+
+void METAFILEPICT::dump() const
+{
+ wvlog << "Dumping METAFILEPICT:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping METAFILEPICT done." << std::endl;
+}
+
+std::string METAFILEPICT::toString() const
+{
+ std::string s( "METAFILEPICT:" );
+ s += "\nmm=";
+ s += int2string( mm );
+ s += "\nxExt=";
+ s += int2string( xExt );
+ s += "\nyExt=";
+ s += int2string( yExt );
+ s += "\nhMF=";
+ s += int2string( hMF );
+ s += "\nMETAFILEPICT Done.";
+ return s;
+}
+
+bool operator==(const METAFILEPICT &lhs, const METAFILEPICT &rhs) {
+
+ return lhs.mm==rhs.mm &&
+ lhs.xExt==rhs.xExt &&
+ lhs.yExt==rhs.yExt &&
+ lhs.hMF==rhs.hMF;
+}
+
+bool operator!=(const METAFILEPICT &lhs, const METAFILEPICT &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// NUMRM implementation
+
+NUMRM::NUMRM() {
+ clear();
+}
+
+NUMRM::NUMRM(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+NUMRM::NUMRM(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool NUMRM::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ fNumRM=stream->readU8();
+ unused1=stream->readU8();
+ ibstNumRM=stream->readS16();
+ dttmNumRM.read(stream, false);
+ for(int _i=0; _i<(9); ++_i)
+ rgbxchNums[_i]=stream->readU8();
+ for(int _i=0; _i<(9); ++_i)
+ rgnfc[_i]=stream->readU8();
+ unused26=stream->readS16();
+ for(int _i=0; _i<(9); ++_i)
+ PNBR[_i]=stream->readU32();
+ for(int _i=0; _i<(32); ++_i)
+ xst[_i]=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void NUMRM::readPtr(const U8 *ptr) {
+
+ fNumRM=readU8(ptr);
+ ptr+=sizeof(U8);
+ unused1=readU8(ptr);
+ ptr+=sizeof(U8);
+ ibstNumRM=readS16(ptr);
+ ptr+=sizeof(S16);
+ dttmNumRM.readPtr(ptr);
+ ptr+=DTTM::sizeOf;
+ for(int _i=0; _i<(9); ++_i) {
+ rgbxchNums[_i]=readU8(ptr);
+ ptr+=sizeof(U8);
+ }
+ for(int _i=0; _i<(9); ++_i) {
+ rgnfc[_i]=readU8(ptr);
+ ptr+=sizeof(U8);
+ }
+ unused26=readS16(ptr);
+ ptr+=sizeof(S16);
+ for(int _i=0; _i<(9); ++_i) {
+ PNBR[_i]=readU32(ptr);
+ ptr+=sizeof(U32);
+ }
+ for(int _i=0; _i<(32); ++_i) {
+ xst[_i]=readU16(ptr);
+ ptr+=sizeof(U16);
+ }
+}
+
+bool NUMRM::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(fNumRM);
+ stream->write(unused1);
+ stream->write(ibstNumRM);
+ dttmNumRM.write(stream, false);
+ for(int _i=0; _i<(9); ++_i)
+ stream->write(rgbxchNums[_i]);
+ for(int _i=0; _i<(9); ++_i)
+ stream->write(rgnfc[_i]);
+ stream->write(unused26);
+ for(int _i=0; _i<(9); ++_i)
+ stream->write(PNBR[_i]);
+ for(int _i=0; _i<(32); ++_i)
+ stream->write(xst[_i]);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void NUMRM::clear() {
+ fNumRM=0;
+ unused1=0;
+ ibstNumRM=0;
+ dttmNumRM.clear();
+ for(int _i=0; _i<(9); ++_i)
+ rgbxchNums[_i]=0;
+ for(int _i=0; _i<(9); ++_i)
+ rgnfc[_i]=0;
+ unused26=0;
+ for(int _i=0; _i<(9); ++_i)
+ PNBR[_i]=0;
+ for(int _i=0; _i<(32); ++_i)
+ xst[_i]=0;
+}
+
+void NUMRM::dump() const
+{
+ wvlog << "Dumping NUMRM:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping NUMRM done." << std::endl;
+}
+
+std::string NUMRM::toString() const
+{
+ std::string s( "NUMRM:" );
+ s += "\nfNumRM=";
+ s += uint2string( fNumRM );
+ s += "\nunused1=";
+ s += uint2string( unused1 );
+ s += "\nibstNumRM=";
+ s += int2string( ibstNumRM );
+ s += "\ndttmNumRM=";
+ s += "\n{" + dttmNumRM.toString() + "}\n";
+ for(int _i=0; _i<(9); ++_i) {
+ s += "\nrgbxchNums[" + int2string( _i ) + "]=";
+ s += uint2string( rgbxchNums[_i] );
+ }
+ for(int _i=0; _i<(9); ++_i) {
+ s += "\nrgnfc[" + int2string( _i ) + "]=";
+ s += uint2string( rgnfc[_i] );
+ }
+ s += "\nunused26=";
+ s += int2string( unused26 );
+ for(int _i=0; _i<(9); ++_i) {
+ s += "\nPNBR[" + int2string( _i ) + "]=";
+ s += uint2string( PNBR[_i] );
+ }
+ for(int _i=0; _i<(32); ++_i) {
+ s += "\nxst[" + int2string( _i ) + "]=";
+ s += uint2string( xst[_i] );
+ }
+ s += "\nNUMRM Done.";
+ return s;
+}
+
+bool operator==(const NUMRM &lhs, const NUMRM &rhs) {
+
+ for(int _i=0; _i<(9); ++_i) {
+ if(lhs.rgbxchNums[_i]!=rhs.rgbxchNums[_i])
+ return false;
+ }
+
+ for(int _i=0; _i<(9); ++_i) {
+ if(lhs.rgnfc[_i]!=rhs.rgnfc[_i])
+ return false;
+ }
+
+ for(int _i=0; _i<(9); ++_i) {
+ if(lhs.PNBR[_i]!=rhs.PNBR[_i])
+ return false;
+ }
+
+ for(int _i=0; _i<(32); ++_i) {
+ if(lhs.xst[_i]!=rhs.xst[_i])
+ return false;
+ }
+
+ return lhs.fNumRM==rhs.fNumRM &&
+ lhs.unused1==rhs.unused1 &&
+ lhs.ibstNumRM==rhs.ibstNumRM &&
+ lhs.dttmNumRM==rhs.dttmNumRM &&
+ lhs.unused26==rhs.unused26;
+}
+
+bool operator!=(const NUMRM &lhs, const NUMRM &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// OBJHEADER implementation
+
+OBJHEADER::OBJHEADER() {
+ clear();
+}
+
+OBJHEADER::OBJHEADER(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool OBJHEADER::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ lcb=stream->readU32();
+ cbHeader=stream->readU16();
+ icf=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool OBJHEADER::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(lcb);
+ stream->write(cbHeader);
+ stream->write(icf);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void OBJHEADER::clear() {
+ lcb=0;
+ cbHeader=0;
+ icf=0;
+}
+
+bool operator==(const OBJHEADER &lhs, const OBJHEADER &rhs) {
+
+ return lhs.lcb==rhs.lcb &&
+ lhs.cbHeader==rhs.cbHeader &&
+ lhs.icf==rhs.icf;
+}
+
+bool operator!=(const OBJHEADER &lhs, const OBJHEADER &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// OLST implementation
+
+const unsigned int OLST::sizeOf = 212;
+
+OLST::OLST() {
+ clear();
+}
+
+OLST::OLST(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+OLST::OLST(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool OLST::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ for(int _i=0; _i<(9); ++_i)
+ rganlv[_i].read(stream, false);
+ fRestartHdr=stream->readU8();
+ fSpareOlst2=stream->readU8();
+ fSpareOlst3=stream->readU8();
+ fSpareOlst4=stream->readU8();
+ for(int _i=0; _i<(32); ++_i)
+ rgxch[_i]=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void OLST::readPtr(const U8 *ptr) {
+
+ for(int _i=0; _i<(9); ++_i) {
+ rganlv[_i].readPtr(ptr);
+ ptr+=ANLV::sizeOf;
+ }
+ fRestartHdr=readU8(ptr);
+ ptr+=sizeof(U8);
+ fSpareOlst2=readU8(ptr);
+ ptr+=sizeof(U8);
+ fSpareOlst3=readU8(ptr);
+ ptr+=sizeof(U8);
+ fSpareOlst4=readU8(ptr);
+ ptr+=sizeof(U8);
+ for(int _i=0; _i<(32); ++_i) {
+ rgxch[_i]=readU16(ptr);
+ ptr+=sizeof(U16);
+ }
+}
+
+bool OLST::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ for(int _i=0; _i<(9); ++_i)
+ rganlv[_i].write(stream, false);
+ stream->write(fRestartHdr);
+ stream->write(fSpareOlst2);
+ stream->write(fSpareOlst3);
+ stream->write(fSpareOlst4);
+ for(int _i=0; _i<(32); ++_i)
+ stream->write(rgxch[_i]);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void OLST::clear() {
+ for(int _i=0; _i<(9); ++_i)
+ rganlv[_i].clear();
+ fRestartHdr=0;
+ fSpareOlst2=0;
+ fSpareOlst3=0;
+ fSpareOlst4=0;
+ for(int _i=0; _i<(32); ++_i)
+ rgxch[_i]=0;
+}
+
+void OLST::dump() const
+{
+ wvlog << "Dumping OLST:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping OLST done." << std::endl;
+}
+
+std::string OLST::toString() const
+{
+ std::string s( "OLST:" );
+ for(int _i=0; _i<(9); ++_i) {
+ s += "\nrganlv[" + int2string( _i ) + "]=";
+ s += "\n{" + rganlv[_i].toString() + "}\n";
+ }
+ s += "\nfRestartHdr=";
+ s += uint2string( fRestartHdr );
+ s += "\nfSpareOlst2=";
+ s += uint2string( fSpareOlst2 );
+ s += "\nfSpareOlst3=";
+ s += uint2string( fSpareOlst3 );
+ s += "\nfSpareOlst4=";
+ s += uint2string( fSpareOlst4 );
+ for(int _i=0; _i<(32); ++_i) {
+ s += "\nrgxch[" + int2string( _i ) + "]=";
+ s += uint2string( rgxch[_i] );
+ }
+ s += "\nOLST Done.";
+ return s;
+}
+
+bool operator==(const OLST &lhs, const OLST &rhs) {
+
+ for(int _i=0; _i<(9); ++_i) {
+ if(lhs.rganlv[_i]!=rhs.rganlv[_i])
+ return false;
+ }
+
+ for(int _i=0; _i<(32); ++_i) {
+ if(lhs.rgxch[_i]!=rhs.rgxch[_i])
+ return false;
+ }
+
+ return lhs.fRestartHdr==rhs.fRestartHdr &&
+ lhs.fSpareOlst2==rhs.fSpareOlst2 &&
+ lhs.fSpareOlst3==rhs.fSpareOlst3 &&
+ lhs.fSpareOlst4==rhs.fSpareOlst4;
+}
+
+bool operator!=(const OLST &lhs, const OLST &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// PAP implementation
+
+PAP::PAP() : Shared() {
+ clear();
+}
+
+PAP::PAP(OLEStreamReader *stream, bool preservePos) : Shared() {
+ clear();
+ read(stream, preservePos);
+}
+
+bool PAP::read(OLEStreamReader *stream, bool preservePos) {
+
+ U8 shifterU8;
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ istd=stream->readU16();
+ jc=stream->readU8();
+ fKeep=stream->readU8();
+ fKeepFollow=stream->readU8();
+ fPageBreakBefore=stream->readU8();
+ shifterU8=stream->readU8();
+ fBrLnAbove=shifterU8;
+ shifterU8>>=1;
+ fBrLnBelow=shifterU8;
+ shifterU8>>=1;
+ fUnused=shifterU8;
+ shifterU8>>=2;
+ pcVert=shifterU8;
+ shifterU8>>=2;
+ pcHorz=shifterU8;
+ brcp=stream->readU8();
+ brcl=stream->readU8();
+ unused9=stream->readU8();
+ ilvl=stream->readU8();
+ fNoLnn=stream->readU8();
+ ilfo=stream->readS16();
+ nLvlAnm=stream->readU8();
+ unused15=stream->readU8();
+ fSideBySide=stream->readU8();
+ unused17=stream->readU8();
+ fNoAutoHyph=stream->readU8();
+ fWidowControl=stream->readU8();
+ dxaRight=stream->readS32();
+ dxaLeft=stream->readS32();
+ dxaLeft1=stream->readS32();
+ lspd.read(stream, false);
+ dyaBefore=stream->readU32();
+ dyaAfter=stream->readU32();
+ phe.read(stream, false);
+ fCrLf=stream->readU8();
+ fUsePgsuSettings=stream->readU8();
+ fAdjustRight=stream->readU8();
+ unused59=stream->readU8();
+ fKinsoku=stream->readU8();
+ fWordWrap=stream->readU8();
+ fOverflowPunct=stream->readU8();
+ fTopLinePunct=stream->readU8();
+ fAutoSpaceDE=stream->readU8();
+ fAutoSpaceDN=stream->readU8();
+ wAlignFont=stream->readU16();
+ shifterU16=stream->readU16();
+ fVertical=shifterU16;
+ shifterU16>>=1;
+ fBackward=shifterU16;
+ shifterU16>>=1;
+ fRotateFont=shifterU16;
+ shifterU16>>=1;
+ unused68_3=shifterU16;
+ unused70=stream->readU16();
+ fInTable=stream->readS8();
+ fTtp=stream->readS8();
+ wr=stream->readU8();
+ fLocked=stream->readU8();
+ ptap=stream->readU32();
+ dxaAbs=stream->readS32();
+ dyaAbs=stream->readS32();
+ dxaWidth=stream->readS32();
+ brcTop.read(stream, false);
+ brcLeft.read(stream, false);
+ brcBottom.read(stream, false);
+ brcRight.read(stream, false);
+ brcBetween.read(stream, false);
+ brcBar.read(stream, false);
+ dxaFromText=stream->readS32();
+ dyaFromText=stream->readS32();
+ shifterU16=stream->readU16();
+ dyaHeight=shifterU16;
+ shifterU16>>=15;
+ fMinHeight=shifterU16;
+ shd.read(stream, false);
+ dcs.read(stream, false);
+ lvl=stream->readS8();
+ fNumRMIns=stream->readS8();
+ anld.read(stream, false);
+ fPropRMark=stream->readS16();
+ ibstPropRMark=stream->readS16();
+ dttmPropRMark.read(stream, false);
+ numrm.read(stream, false);
+ itbdMac=stream->readS16();
+ // skipping the std::vector rgdxaTab
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool PAP::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U8 shifterU8;
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(istd);
+ stream->write(jc);
+ stream->write(fKeep);
+ stream->write(fKeepFollow);
+ stream->write(fPageBreakBefore);
+ shifterU8=fBrLnAbove;
+ shifterU8|=fBrLnBelow << 1;
+ shifterU8|=fUnused << 2;
+ shifterU8|=pcVert << 4;
+ shifterU8|=pcHorz << 6;
+ stream->write(shifterU8);
+ stream->write(brcp);
+ stream->write(brcl);
+ stream->write(unused9);
+ stream->write(ilvl);
+ stream->write(fNoLnn);
+ stream->write(ilfo);
+ stream->write(nLvlAnm);
+ stream->write(unused15);
+ stream->write(fSideBySide);
+ stream->write(unused17);
+ stream->write(fNoAutoHyph);
+ stream->write(fWidowControl);
+ stream->write(dxaRight);
+ stream->write(dxaLeft);
+ stream->write(dxaLeft1);
+ lspd.write(stream, false);
+ stream->write(dyaBefore);
+ stream->write(dyaAfter);
+ phe.write(stream, false);
+ stream->write(fCrLf);
+ stream->write(fUsePgsuSettings);
+ stream->write(fAdjustRight);
+ stream->write(unused59);
+ stream->write(fKinsoku);
+ stream->write(fWordWrap);
+ stream->write(fOverflowPunct);
+ stream->write(fTopLinePunct);
+ stream->write(fAutoSpaceDE);
+ stream->write(fAutoSpaceDN);
+ stream->write(wAlignFont);
+ shifterU16=fVertical;
+ shifterU16|=fBackward << 1;
+ shifterU16|=fRotateFont << 2;
+ shifterU16|=unused68_3 << 3;
+ stream->write(shifterU16);
+ stream->write(unused70);
+ stream->write(fInTable);
+ stream->write(fTtp);
+ stream->write(wr);
+ stream->write(fLocked);
+ stream->write(ptap);
+ stream->write(dxaAbs);
+ stream->write(dyaAbs);
+ stream->write(dxaWidth);
+ brcTop.write(stream, false);
+ brcLeft.write(stream, false);
+ brcBottom.write(stream, false);
+ brcRight.write(stream, false);
+ brcBetween.write(stream, false);
+ brcBar.write(stream, false);
+ stream->write(dxaFromText);
+ stream->write(dyaFromText);
+ shifterU16=dyaHeight;
+ shifterU16|=fMinHeight << 15;
+ stream->write(shifterU16);
+ shd.write(stream, false);
+ dcs.write(stream, false);
+ stream->write(lvl);
+ stream->write(fNumRMIns);
+ anld.write(stream, false);
+ stream->write(fPropRMark);
+ stream->write(ibstPropRMark);
+ dttmPropRMark.write(stream, false);
+ numrm.write(stream, false);
+ stream->write(itbdMac);
+ // skipping the std::vector rgdxaTab
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PAP::clear() {
+ istd=0;
+ jc=0;
+ fKeep=0;
+ fKeepFollow=0;
+ fPageBreakBefore=0;
+ fBrLnAbove=0;
+ fBrLnBelow=0;
+ fUnused=0;
+ pcVert=0;
+ pcHorz=0;
+ brcp=0;
+ brcl=0;
+ unused9=0;
+ ilvl=0;
+ fNoLnn=0;
+ ilfo=0;
+ nLvlAnm=0;
+ unused15=0;
+ fSideBySide=0;
+ unused17=0;
+ fNoAutoHyph=0;
+ fWidowControl=1;
+ dxaRight=0;
+ dxaLeft=0;
+ dxaLeft1=0;
+ lspd.clear();
+ dyaBefore=0;
+ dyaAfter=0;
+ phe.clear();
+ fCrLf=0;
+ fUsePgsuSettings=0;
+ fAdjustRight=0;
+ unused59=0;
+ fKinsoku=0;
+ fWordWrap=0;
+ fOverflowPunct=0;
+ fTopLinePunct=0;
+ fAutoSpaceDE=0;
+ fAutoSpaceDN=0;
+ wAlignFont=0;
+ fVertical=0;
+ fBackward=0;
+ fRotateFont=0;
+ unused68_3=0;
+ unused70=0;
+ fInTable=0;
+ fTtp=0;
+ wr=0;
+ fLocked=0;
+ ptap=0;
+ dxaAbs=0;
+ dyaAbs=0;
+ dxaWidth=0;
+ brcTop.clear();
+ brcLeft.clear();
+ brcBottom.clear();
+ brcRight.clear();
+ brcBetween.clear();
+ brcBar.clear();
+ dxaFromText=0;
+ dyaFromText=0;
+ dyaHeight=0;
+ fMinHeight=0;
+ shd.clear();
+ dcs.clear();
+ lvl=9;
+ fNumRMIns=0;
+ anld.clear();
+ fPropRMark=0;
+ ibstPropRMark=0;
+ dttmPropRMark.clear();
+ numrm.clear();
+ itbdMac=0;
+ rgdxaTab.clear();
+}
+
+void PAP::dump() const
+{
+ wvlog << "Dumping PAP:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping PAP done." << std::endl;
+}
+
+std::string PAP::toString() const
+{
+ std::string s( "PAP:" );
+ s += "\nistd=";
+ s += uint2string( istd );
+ s += "\njc=";
+ s += uint2string( jc );
+ s += "\nfKeep=";
+ s += uint2string( fKeep );
+ s += "\nfKeepFollow=";
+ s += uint2string( fKeepFollow );
+ s += "\nfPageBreakBefore=";
+ s += uint2string( fPageBreakBefore );
+ s += "\nfBrLnAbove=";
+ s += uint2string( fBrLnAbove );
+ s += "\nfBrLnBelow=";
+ s += uint2string( fBrLnBelow );
+ s += "\nfUnused=";
+ s += uint2string( fUnused );
+ s += "\npcVert=";
+ s += uint2string( pcVert );
+ s += "\npcHorz=";
+ s += uint2string( pcHorz );
+ s += "\nbrcp=";
+ s += uint2string( brcp );
+ s += "\nbrcl=";
+ s += uint2string( brcl );
+ s += "\nunused9=";
+ s += uint2string( unused9 );
+ s += "\nilvl=";
+ s += uint2string( ilvl );
+ s += "\nfNoLnn=";
+ s += uint2string( fNoLnn );
+ s += "\nilfo=";
+ s += int2string( ilfo );
+ s += "\nnLvlAnm=";
+ s += uint2string( nLvlAnm );
+ s += "\nunused15=";
+ s += uint2string( unused15 );
+ s += "\nfSideBySide=";
+ s += uint2string( fSideBySide );
+ s += "\nunused17=";
+ s += uint2string( unused17 );
+ s += "\nfNoAutoHyph=";
+ s += uint2string( fNoAutoHyph );
+ s += "\nfWidowControl=";
+ s += uint2string( fWidowControl );
+ s += "\ndxaRight=";
+ s += int2string( dxaRight );
+ s += "\ndxaLeft=";
+ s += int2string( dxaLeft );
+ s += "\ndxaLeft1=";
+ s += int2string( dxaLeft1 );
+ s += "\nlspd=";
+ s += "\n{" + lspd.toString() + "}\n";
+ s += "\ndyaBefore=";
+ s += uint2string( dyaBefore );
+ s += "\ndyaAfter=";
+ s += uint2string( dyaAfter );
+ s += "\nphe=";
+ s += "\n{" + phe.toString() + "}\n";
+ s += "\nfCrLf=";
+ s += uint2string( fCrLf );
+ s += "\nfUsePgsuSettings=";
+ s += uint2string( fUsePgsuSettings );
+ s += "\nfAdjustRight=";
+ s += uint2string( fAdjustRight );
+ s += "\nunused59=";
+ s += uint2string( unused59 );
+ s += "\nfKinsoku=";
+ s += uint2string( fKinsoku );
+ s += "\nfWordWrap=";
+ s += uint2string( fWordWrap );
+ s += "\nfOverflowPunct=";
+ s += uint2string( fOverflowPunct );
+ s += "\nfTopLinePunct=";
+ s += uint2string( fTopLinePunct );
+ s += "\nfAutoSpaceDE=";
+ s += uint2string( fAutoSpaceDE );
+ s += "\nfAutoSpaceDN=";
+ s += uint2string( fAutoSpaceDN );
+ s += "\nwAlignFont=";
+ s += uint2string( wAlignFont );
+ s += "\nfVertical=";
+ s += uint2string( fVertical );
+ s += "\nfBackward=";
+ s += uint2string( fBackward );
+ s += "\nfRotateFont=";
+ s += uint2string( fRotateFont );
+ s += "\nunused68_3=";
+ s += uint2string( unused68_3 );
+ s += "\nunused70=";
+ s += uint2string( unused70 );
+ s += "\nfInTable=";
+ s += int2string( fInTable );
+ s += "\nfTtp=";
+ s += int2string( fTtp );
+ s += "\nwr=";
+ s += uint2string( wr );
+ s += "\nfLocked=";
+ s += uint2string( fLocked );
+ s += "\nptap=";
+ s += uint2string( ptap );
+ s += "\ndxaAbs=";
+ s += int2string( dxaAbs );
+ s += "\ndyaAbs=";
+ s += int2string( dyaAbs );
+ s += "\ndxaWidth=";
+ s += int2string( dxaWidth );
+ s += "\nbrcTop=";
+ s += "\n{" + brcTop.toString() + "}\n";
+ s += "\nbrcLeft=";
+ s += "\n{" + brcLeft.toString() + "}\n";
+ s += "\nbrcBottom=";
+ s += "\n{" + brcBottom.toString() + "}\n";
+ s += "\nbrcRight=";
+ s += "\n{" + brcRight.toString() + "}\n";
+ s += "\nbrcBetween=";
+ s += "\n{" + brcBetween.toString() + "}\n";
+ s += "\nbrcBar=";
+ s += "\n{" + brcBar.toString() + "}\n";
+ s += "\ndxaFromText=";
+ s += int2string( dxaFromText );
+ s += "\ndyaFromText=";
+ s += int2string( dyaFromText );
+ s += "\ndyaHeight=";
+ s += uint2string( dyaHeight );
+ s += "\nfMinHeight=";
+ s += uint2string( fMinHeight );
+ s += "\nshd=";
+ s += "\n{" + shd.toString() + "}\n";
+ s += "\ndcs=";
+ s += "\n{" + dcs.toString() + "}\n";
+ s += "\nlvl=";
+ s += int2string( lvl );
+ s += "\nfBiDi=";
+ s += int2string( fBiDi );
+ s += "\nfNumRMIns=";
+ s += int2string( fNumRMIns );
+ s += "\nanld=";
+ s += "\n{" + anld.toString() + "}\n";
+ s += "\nfPropRMark=";
+ s += int2string( fPropRMark );
+ s += "\nibstPropRMark=";
+ s += int2string( ibstPropRMark );
+ s += "\ndttmPropRMark=";
+ s += "\n{" + dttmPropRMark.toString() + "}\n";
+ s += "\nnumrm=";
+ s += "\n{" + numrm.toString() + "}\n";
+ s += "\nitbdMac=";
+ s += int2string( itbdMac );
+ s += "\nrgdxaTab=";
+ // skipping the std::vector rgdxaTab
+ s += "\nPAP Done.";
+ return s;
+}
+
+bool operator==(const PAP &lhs, const PAP &rhs) {
+
+ return lhs.istd==rhs.istd &&
+ lhs.jc==rhs.jc &&
+ lhs.fKeep==rhs.fKeep &&
+ lhs.fKeepFollow==rhs.fKeepFollow &&
+ lhs.fPageBreakBefore==rhs.fPageBreakBefore &&
+ lhs.fBrLnAbove==rhs.fBrLnAbove &&
+ lhs.fBrLnBelow==rhs.fBrLnBelow &&
+ lhs.fUnused==rhs.fUnused &&
+ lhs.pcVert==rhs.pcVert &&
+ lhs.pcHorz==rhs.pcHorz &&
+ lhs.brcp==rhs.brcp &&
+ lhs.brcl==rhs.brcl &&
+ lhs.unused9==rhs.unused9 &&
+ lhs.ilvl==rhs.ilvl &&
+ lhs.fNoLnn==rhs.fNoLnn &&
+ lhs.ilfo==rhs.ilfo &&
+ lhs.nLvlAnm==rhs.nLvlAnm &&
+ lhs.unused15==rhs.unused15 &&
+ lhs.fSideBySide==rhs.fSideBySide &&
+ lhs.unused17==rhs.unused17 &&
+ lhs.fNoAutoHyph==rhs.fNoAutoHyph &&
+ lhs.fWidowControl==rhs.fWidowControl &&
+ lhs.dxaRight==rhs.dxaRight &&
+ lhs.dxaLeft==rhs.dxaLeft &&
+ lhs.dxaLeft1==rhs.dxaLeft1 &&
+ lhs.lspd==rhs.lspd &&
+ lhs.dyaBefore==rhs.dyaBefore &&
+ lhs.dyaAfter==rhs.dyaAfter &&
+ lhs.phe==rhs.phe &&
+ lhs.fCrLf==rhs.fCrLf &&
+ lhs.fUsePgsuSettings==rhs.fUsePgsuSettings &&
+ lhs.fAdjustRight==rhs.fAdjustRight &&
+ lhs.unused59==rhs.unused59 &&
+ lhs.fKinsoku==rhs.fKinsoku &&
+ lhs.fWordWrap==rhs.fWordWrap &&
+ lhs.fOverflowPunct==rhs.fOverflowPunct &&
+ lhs.fTopLinePunct==rhs.fTopLinePunct &&
+ lhs.fAutoSpaceDE==rhs.fAutoSpaceDE &&
+ lhs.fAutoSpaceDN==rhs.fAutoSpaceDN &&
+ lhs.wAlignFont==rhs.wAlignFont &&
+ lhs.fVertical==rhs.fVertical &&
+ lhs.fBackward==rhs.fBackward &&
+ lhs.fRotateFont==rhs.fRotateFont &&
+ lhs.unused68_3==rhs.unused68_3 &&
+ lhs.unused70==rhs.unused70 &&
+ lhs.fInTable==rhs.fInTable &&
+ lhs.fTtp==rhs.fTtp &&
+ lhs.wr==rhs.wr &&
+ lhs.fLocked==rhs.fLocked &&
+ lhs.ptap==rhs.ptap &&
+ lhs.dxaAbs==rhs.dxaAbs &&
+ lhs.dyaAbs==rhs.dyaAbs &&
+ lhs.dxaWidth==rhs.dxaWidth &&
+ lhs.brcTop==rhs.brcTop &&
+ lhs.brcLeft==rhs.brcLeft &&
+ lhs.brcBottom==rhs.brcBottom &&
+ lhs.brcRight==rhs.brcRight &&
+ lhs.brcBetween==rhs.brcBetween &&
+ lhs.brcBar==rhs.brcBar &&
+ lhs.dxaFromText==rhs.dxaFromText &&
+ lhs.dyaFromText==rhs.dyaFromText &&
+ lhs.dyaHeight==rhs.dyaHeight &&
+ lhs.fMinHeight==rhs.fMinHeight &&
+ lhs.shd==rhs.shd &&
+ lhs.dcs==rhs.dcs &&
+ lhs.lvl==rhs.lvl &&
+ lhs.fBiDi==rhs.fBiDi &&
+ lhs.fNumRMIns==rhs.fNumRMIns &&
+ lhs.anld==rhs.anld &&
+ lhs.fPropRMark==rhs.fPropRMark &&
+ lhs.ibstPropRMark==rhs.ibstPropRMark &&
+ lhs.dttmPropRMark==rhs.dttmPropRMark &&
+ lhs.numrm==rhs.numrm &&
+ lhs.itbdMac==rhs.itbdMac &&
+ lhs.rgdxaTab==rhs.rgdxaTab;
+}
+
+bool operator!=(const PAP &lhs, const PAP &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// PCD implementation
+
+const unsigned int PCD::sizeOf = 8;
+
+PCD::PCD() {
+ clear();
+}
+
+PCD::PCD(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+PCD::PCD(const U8 *ptr) {
+ clear();
+ readPtr(ptr);
+}
+
+bool PCD::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ fNoParaLast=shifterU16;
+ shifterU16>>=1;
+ fPaphNil=shifterU16;
+ shifterU16>>=1;
+ fCopied=shifterU16;
+ shifterU16>>=1;
+ unused0_3=shifterU16;
+ shifterU16>>=5;
+ fn=shifterU16;
+ fc=stream->readU32();
+ prm.read(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PCD::readPtr(const U8 *ptr) {
+
+ U16 shifterU16;
+
+ shifterU16=readU16(ptr);
+ ptr+=sizeof(U16);
+ fNoParaLast=shifterU16;
+ shifterU16>>=1;
+ fPaphNil=shifterU16;
+ shifterU16>>=1;
+ fCopied=shifterU16;
+ shifterU16>>=1;
+ unused0_3=shifterU16;
+ shifterU16>>=5;
+ fn=shifterU16;
+ fc=readU32(ptr);
+ ptr+=sizeof(U32);
+ prm.readPtr(ptr);
+ ptr+=PRM::sizeOf;
+}
+
+bool PCD::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=fNoParaLast;
+ shifterU16|=fPaphNil << 1;
+ shifterU16|=fCopied << 2;
+ shifterU16|=unused0_3 << 3;
+ shifterU16|=fn << 8;
+ stream->write(shifterU16);
+ stream->write(fc);
+ prm.write(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PCD::clear() {
+ fNoParaLast=0;
+ fPaphNil=0;
+ fCopied=0;
+ unused0_3=0;
+ fn=0;
+ fc=0;
+ prm.clear();
+}
+
+bool operator==(const PCD &lhs, const PCD &rhs) {
+
+ return lhs.fNoParaLast==rhs.fNoParaLast &&
+ lhs.fPaphNil==rhs.fPaphNil &&
+ lhs.fCopied==rhs.fCopied &&
+ lhs.unused0_3==rhs.unused0_3 &&
+ lhs.fn==rhs.fn &&
+ lhs.fc==rhs.fc &&
+ lhs.prm==rhs.prm;
+}
+
+bool operator!=(const PCD &lhs, const PCD &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// PGD implementation
+
+PGD::PGD() {
+ clear();
+}
+
+PGD::PGD(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool PGD::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=stream->readU16();
+ fContinue=shifterU16;
+ shifterU16>>=1;
+ fUnk=shifterU16;
+ shifterU16>>=1;
+ fRight=shifterU16;
+ shifterU16>>=1;
+ fPgnRestart=shifterU16;
+ shifterU16>>=1;
+ fEmptyPage=shifterU16;
+ shifterU16>>=1;
+ fAllFtn=shifterU16;
+ shifterU16>>=1;
+ unused0_6=shifterU16;
+ shifterU16>>=1;
+ fTableBreaks=shifterU16;
+ shifterU16>>=1;
+ fMarked=shifterU16;
+ shifterU16>>=1;
+ fColumnBreaks=shifterU16;
+ shifterU16>>=1;
+ fTableHeader=shifterU16;
+ shifterU16>>=1;
+ fNewPage=shifterU16;
+ shifterU16>>=1;
+ bkc=shifterU16;
+ lnn=stream->readU16();
+ pgn=stream->readU16();
+ dym=stream->readS32();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool PGD::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU16=fContinue;
+ shifterU16|=fUnk << 1;
+ shifterU16|=fRight << 2;
+ shifterU16|=fPgnRestart << 3;
+ shifterU16|=fEmptyPage << 4;
+ shifterU16|=fAllFtn << 5;
+ shifterU16|=unused0_6 << 6;
+ shifterU16|=fTableBreaks << 7;
+ shifterU16|=fMarked << 8;
+ shifterU16|=fColumnBreaks << 9;
+ shifterU16|=fTableHeader << 10;
+ shifterU16|=fNewPage << 11;
+ shifterU16|=bkc << 12;
+ stream->write(shifterU16);
+ stream->write(lnn);
+ stream->write(pgn);
+ stream->write(dym);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PGD::clear() {
+ fContinue=0;
+ fUnk=0;
+ fRight=0;
+ fPgnRestart=0;
+ fEmptyPage=0;
+ fAllFtn=0;
+ unused0_6=0;
+ fTableBreaks=0;
+ fMarked=0;
+ fColumnBreaks=0;
+ fTableHeader=0;
+ fNewPage=0;
+ bkc=0;
+ lnn=0;
+ pgn=0;
+ dym=0;
+}
+
+bool operator==(const PGD &lhs, const PGD &rhs) {
+
+ return lhs.fContinue==rhs.fContinue &&
+ lhs.fUnk==rhs.fUnk &&
+ lhs.fRight==rhs.fRight &&
+ lhs.fPgnRestart==rhs.fPgnRestart &&
+ lhs.fEmptyPage==rhs.fEmptyPage &&
+ lhs.fAllFtn==rhs.fAllFtn &&
+ lhs.unused0_6==rhs.unused0_6 &&
+ lhs.fTableBreaks==rhs.fTableBreaks &&
+ lhs.fMarked==rhs.fMarked &&
+ lhs.fColumnBreaks==rhs.fColumnBreaks &&
+ lhs.fTableHeader==rhs.fTableHeader &&
+ lhs.fNewPage==rhs.fNewPage &&
+ lhs.bkc==rhs.bkc &&
+ lhs.lnn==rhs.lnn &&
+ lhs.pgn==rhs.pgn &&
+ lhs.dym==rhs.dym;
+}
+
+bool operator!=(const PGD &lhs, const PGD &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// PHE2 implementation
+
+PHE2::PHE2() {
+ clear();
+}
+
+PHE2::PHE2(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool PHE2::read(OLEStreamReader *stream, bool preservePos) {
+
+ U32 shifterU32;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU32=stream->readU32();
+ fSpare=shifterU32;
+ shifterU32>>=1;
+ fUnk=shifterU32;
+ shifterU32>>=1;
+ dcpTtpNext=shifterU32;
+ dxaCol=stream->readS32();
+ dymTableHeight=stream->readS32();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool PHE2::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U32 shifterU32;
+
+ if(preservePos)
+ stream->push();
+
+ shifterU32=fSpare;
+ shifterU32|=fUnk << 1;
+ shifterU32|=dcpTtpNext << 2;
+ stream->write(shifterU32);
+ stream->write(dxaCol);
+ stream->write(dymTableHeight);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PHE2::clear() {
+ fSpare=0;
+ fUnk=0;
+ dcpTtpNext=0;
+ dxaCol=0;
+ dymTableHeight=0;
+}
+
+bool operator==(const PHE2 &lhs, const PHE2 &rhs) {
+
+ return lhs.fSpare==rhs.fSpare &&
+ lhs.fUnk==rhs.fUnk &&
+ lhs.dcpTtpNext==rhs.dcpTtpNext &&
+ lhs.dxaCol==rhs.dxaCol &&
+ lhs.dymTableHeight==rhs.dymTableHeight;
+}
+
+bool operator!=(const PHE2 &lhs, const PHE2 &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// PICF implementation
+
+PICF::PICF() : Shared() {
+ clear();
+}
+
+PICF::PICF(OLEStreamReader *stream, bool preservePos) : Shared() {
+ clear();
+ read(stream, preservePos);
+}
+
+bool PICF::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ lcb=stream->readU32();
+ cbHeader=stream->readU16();
+ mfp.read(stream, false);
+ for(int _i=0; _i<(14); ++_i)
+ bm_rcWinMF[_i]=stream->readU8();
+ dxaGoal=stream->readS16();
+ dyaGoal=stream->readS16();
+ mx=stream->readU16();
+ my=stream->readU16();
+ dxaCropLeft=stream->readS16();
+ dyaCropTop=stream->readS16();
+ dxaCropRight=stream->readS16();
+ dyaCropBottom=stream->readS16();
+ shifterU16=stream->readU16();
+ brcl=shifterU16;
+ shifterU16>>=4;
+ fFrameEmpty=shifterU16;
+ shifterU16>>=1;
+ fBitmap=shifterU16;
+ shifterU16>>=1;
+ fDrawHatch=shifterU16;
+ shifterU16>>=1;
+ fError=shifterU16;
+ shifterU16>>=1;
+ bpp=shifterU16;
+ brcTop.read(stream, false);
+ brcLeft.read(stream, false);
+ brcBottom.read(stream, false);
+ brcRight.read(stream, false);
+ dxaOrigin=stream->readS16();
+ dyaOrigin=stream->readS16();
+ cProps=stream->readS16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool PICF::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(lcb);
+ stream->write(cbHeader);
+ mfp.write(stream, false);
+ for(int _i=0; _i<(14); ++_i)
+ stream->write(bm_rcWinMF[_i]);
+ stream->write(dxaGoal);
+ stream->write(dyaGoal);
+ stream->write(mx);
+ stream->write(my);
+ stream->write(dxaCropLeft);
+ stream->write(dyaCropTop);
+ stream->write(dxaCropRight);
+ stream->write(dyaCropBottom);
+ shifterU16=brcl;
+ shifterU16|=fFrameEmpty << 4;
+ shifterU16|=fBitmap << 5;
+ shifterU16|=fDrawHatch << 6;
+ shifterU16|=fError << 7;
+ shifterU16|=bpp << 8;
+ stream->write(shifterU16);
+ brcTop.write(stream, false);
+ brcLeft.write(stream, false);
+ brcBottom.write(stream, false);
+ brcRight.write(stream, false);
+ stream->write(dxaOrigin);
+ stream->write(dyaOrigin);
+ stream->write(cProps);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void PICF::clear() {
+ lcb=0;
+ cbHeader=0;
+ mfp.clear();
+ for(int _i=0; _i<(14); ++_i)
+ bm_rcWinMF[_i]=0;
+ dxaGoal=0;
+ dyaGoal=0;
+ mx=0;
+ my=0;
+ dxaCropLeft=0;
+ dyaCropTop=0;
+ dxaCropRight=0;
+ dyaCropBottom=0;
+ brcl=0;
+ fFrameEmpty=0;
+ fBitmap=0;
+ fDrawHatch=0;
+ fError=0;
+ bpp=0;
+ brcTop.clear();
+ brcLeft.clear();
+ brcBottom.clear();
+ brcRight.clear();
+ dxaOrigin=0;
+ dyaOrigin=0;
+ cProps=0;
+}
+
+void PICF::dump() const
+{
+ wvlog << "Dumping PICF:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping PICF done." << std::endl;
+}
+
+std::string PICF::toString() const
+{
+ std::string s( "PICF:" );
+ s += "\nlcb=";
+ s += uint2string( lcb );
+ s += "\ncbHeader=";
+ s += uint2string( cbHeader );
+ s += "\nmfp=";
+ s += "\n{" + mfp.toString() + "}\n";
+ for(int _i=0; _i<(14); ++_i) {
+ s += "\nbm_rcWinMF[" + int2string( _i ) + "]=";
+ s += uint2string( bm_rcWinMF[_i] );
+ }
+ s += "\ndxaGoal=";
+ s += int2string( dxaGoal );
+ s += "\ndyaGoal=";
+ s += int2string( dyaGoal );
+ s += "\nmx=";
+ s += uint2string( mx );
+ s += "\nmy=";
+ s += uint2string( my );
+ s += "\ndxaCropLeft=";
+ s += int2string( dxaCropLeft );
+ s += "\ndyaCropTop=";
+ s += int2string( dyaCropTop );
+ s += "\ndxaCropRight=";
+ s += int2string( dxaCropRight );
+ s += "\ndyaCropBottom=";
+ s += int2string( dyaCropBottom );
+ s += "\nbrcl=";
+ s += uint2string( brcl );
+ s += "\nfFrameEmpty=";
+ s += uint2string( fFrameEmpty );
+ s += "\nfBitmap=";
+ s += uint2string( fBitmap );
+ s += "\nfDrawHatch=";
+ s += uint2string( fDrawHatch );
+ s += "\nfError=";
+ s += uint2string( fError );
+ s += "\nbpp=";
+ s += uint2string( bpp );
+ s += "\nbrcTop=";
+ s += "\n{" + brcTop.toString() + "}\n";
+ s += "\nbrcLeft=";
+ s += "\n{" + brcLeft.toString() + "}\n";
+ s += "\nbrcBottom=";
+ s += "\n{" + brcBottom.toString() + "}\n";
+ s += "\nbrcRight=";
+ s += "\n{" + brcRight.toString() + "}\n";
+ s += "\ndxaOrigin=";
+ s += int2string( dxaOrigin );
+ s += "\ndyaOrigin=";
+ s += int2string( dyaOrigin );
+ s += "\ncProps=";
+ s += int2string( cProps );
+ s += "\nPICF Done.";
+ return s;
+}
+
+bool operator==(const PICF &lhs, const PICF &rhs) {
+
+ for(int _i=0; _i<(14); ++_i) {
+ if(lhs.bm_rcWinMF[_i]!=rhs.bm_rcWinMF[_i])
+ return false;
+ }
+
+ return lhs.lcb==rhs.lcb &&
+ lhs.cbHeader==rhs.cbHeader &&
+ lhs.mfp==rhs.mfp &&
+ lhs.dxaGoal==rhs.dxaGoal &&
+ lhs.dyaGoal==rhs.dyaGoal &&
+ lhs.mx==rhs.mx &&
+ lhs.my==rhs.my &&
+ lhs.dxaCropLeft==rhs.dxaCropLeft &&
+ lhs.dyaCropTop==rhs.dyaCropTop &&
+ lhs.dxaCropRight==rhs.dxaCropRight &&
+ lhs.dyaCropBottom==rhs.dyaCropBottom &&
+ lhs.brcl==rhs.brcl &&
+ lhs.fFrameEmpty==rhs.fFrameEmpty &&
+ lhs.fBitmap==rhs.fBitmap &&
+ lhs.fDrawHatch==rhs.fDrawHatch &&
+ lhs.fError==rhs.fError &&
+ lhs.bpp==rhs.bpp &&
+ lhs.brcTop==rhs.brcTop &&
+ lhs.brcLeft==rhs.brcLeft &&
+ lhs.brcBottom==rhs.brcBottom &&
+ lhs.brcRight==rhs.brcRight &&
+ lhs.dxaOrigin==rhs.dxaOrigin &&
+ lhs.dyaOrigin==rhs.dyaOrigin &&
+ lhs.cProps==rhs.cProps;
+}
+
+bool operator!=(const PICF &lhs, const PICF &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// RR implementation
+
+RR::RR() {
+ clear();
+}
+
+RR::RR(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool RR::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ cb=stream->readU16();
+ cbSzRecip=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool RR::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(cb);
+ stream->write(cbSzRecip);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void RR::clear() {
+ cb=0;
+ cbSzRecip=0;
+}
+
+bool operator==(const RR &lhs, const RR &rhs) {
+
+ return lhs.cb==rhs.cb &&
+ lhs.cbSzRecip==rhs.cbSzRecip;
+}
+
+bool operator!=(const RR &lhs, const RR &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// RS implementation
+
+RS::RS() {
+ clear();
+}
+
+RS::RS(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool RS::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ fRouted=stream->readS16();
+ fReturnOrig=stream->readS16();
+ fTrackStatus=stream->readS16();
+ fDirty=stream->readS16();
+ nProtect=stream->readS16();
+ iStage=stream->readS16();
+ delOption=stream->readS16();
+ cRecip=stream->readS16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool RS::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(fRouted);
+ stream->write(fReturnOrig);
+ stream->write(fTrackStatus);
+ stream->write(fDirty);
+ stream->write(nProtect);
+ stream->write(iStage);
+ stream->write(delOption);
+ stream->write(cRecip);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void RS::clear() {
+ fRouted=0;
+ fReturnOrig=0;
+ fTrackStatus=0;
+ fDirty=0;
+ nProtect=0;
+ iStage=0;
+ delOption=0;
+ cRecip=0;
+}
+
+bool operator==(const RS &lhs, const RS &rhs) {
+
+ return lhs.fRouted==rhs.fRouted &&
+ lhs.fReturnOrig==rhs.fReturnOrig &&
+ lhs.fTrackStatus==rhs.fTrackStatus &&
+ lhs.fDirty==rhs.fDirty &&
+ lhs.nProtect==rhs.nProtect &&
+ lhs.iStage==rhs.iStage &&
+ lhs.delOption==rhs.delOption &&
+ lhs.cRecip==rhs.cRecip;
+}
+
+bool operator!=(const RS &lhs, const RS &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// SED implementation
+
+const unsigned int SED::sizeOf = 12;
+
+SED::SED() {
+ clear();
+}
+
+SED::SED(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool SED::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ fn=stream->readS16();
+ fcSepx=stream->readU32();
+ fnMpr=stream->readS16();
+ fcMpr=stream->readU32();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool SED::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(fn);
+ stream->write(fcSepx);
+ stream->write(fnMpr);
+ stream->write(fcMpr);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void SED::clear() {
+ fn=0;
+ fcSepx=0;
+ fnMpr=0;
+ fcMpr=0;
+}
+
+bool operator==(const SED &lhs, const SED &rhs) {
+
+ return lhs.fn==rhs.fn &&
+ lhs.fcSepx==rhs.fcSepx &&
+ lhs.fnMpr==rhs.fnMpr &&
+ lhs.fcMpr==rhs.fcMpr;
+}
+
+bool operator!=(const SED &lhs, const SED &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// SEP implementation
+
+SEP::SEP() : Shared() {
+ clear();
+}
+
+SEP::SEP(OLEStreamReader *stream, bool preservePos) : Shared() {
+ clear();
+ read(stream, preservePos);
+}
+
+bool SEP::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ bkc=stream->readU8();
+ fTitlePage=stream->readU8();
+ fAutoPgn=stream->readS8();
+ nfcPgn=stream->readU8();
+ fUnlocked=stream->readU8();
+ cnsPgn=stream->readU8();
+ fPgnRestart=stream->readU8();
+ fEndNote=stream->readU8();
+ lnc=stream->readS8();
+ grpfIhdt=stream->readS8();
+ nLnnMod=stream->readU16();
+ dxaLnn=stream->readS32();
+ dxaPgn=stream->readS16();
+ dyaPgn=stream->readS16();
+ fLBetween=stream->readS8();
+ vjc=stream->readS8();
+ dmBinFirst=stream->readU16();
+ dmBinOther=stream->readU16();
+ dmPaperReq=stream->readU16();
+ brcTop.read(stream, false);
+ brcLeft.read(stream, false);
+ brcBottom.read(stream, false);
+ brcRight.read(stream, false);
+ fPropRMark=stream->readS16();
+ ibstPropRMark=stream->readS16();
+ dttmPropRMark.read(stream, false);
+ dxtCharSpace=stream->readS32();
+ dyaLinePitch=stream->readS32();
+ clm=stream->readU16();
+ unused62=stream->readU16();
+ dmOrientPage=stream->readU8();
+ iHeadingPgn=stream->readU8();
+ pgnStart=stream->readU16();
+ lnnMin=stream->readS16();
+ wTextFlow=stream->readU16();
+ unused72=stream->readU16();
+ shifterU16=stream->readU16();
+ pgbApplyTo=shifterU16;
+ shifterU16>>=3;
+ pgbPageDepth=shifterU16;
+ shifterU16>>=2;
+ pgbOffsetFrom=shifterU16;
+ shifterU16>>=3;
+ unused74_8=shifterU16;
+ xaPage=stream->readU32();
+ yaPage=stream->readU32();
+ xaPageNUp=stream->readU32();
+ yaPageNUp=stream->readU32();
+ dxaLeft=stream->readU32();
+ dxaRight=stream->readU32();
+ dyaTop=stream->readS32();
+ dyaBottom=stream->readS32();
+ dzaGutter=stream->readU32();
+ dyaHdrTop=stream->readU32();
+ dyaHdrBottom=stream->readU32();
+ ccolM1=stream->readS16();
+ fEvenlySpaced=stream->readS8();
+ unused123=stream->readU8();
+ dxaColumns=stream->readS32();
+ // skipping the std::vector rgdxaColumnWidthSpacing
+ dxaColumnWidth=stream->readS32();
+ dmOrientFirst=stream->readU8();
+ fLayout=stream->readU8();
+ unused490=stream->readU16();
+ olstAnm.read(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool SEP::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(bkc);
+ stream->write(fTitlePage);
+ stream->write(fAutoPgn);
+ stream->write(nfcPgn);
+ stream->write(fUnlocked);
+ stream->write(cnsPgn);
+ stream->write(fPgnRestart);
+ stream->write(fEndNote);
+ stream->write(lnc);
+ stream->write(grpfIhdt);
+ stream->write(nLnnMod);
+ stream->write(dxaLnn);
+ stream->write(dxaPgn);
+ stream->write(dyaPgn);
+ stream->write(fLBetween);
+ stream->write(vjc);
+ stream->write(dmBinFirst);
+ stream->write(dmBinOther);
+ stream->write(dmPaperReq);
+ brcTop.write(stream, false);
+ brcLeft.write(stream, false);
+ brcBottom.write(stream, false);
+ brcRight.write(stream, false);
+ stream->write(fPropRMark);
+ stream->write(ibstPropRMark);
+ dttmPropRMark.write(stream, false);
+ stream->write(dxtCharSpace);
+ stream->write(dyaLinePitch);
+ stream->write(clm);
+ stream->write(unused62);
+ stream->write(dmOrientPage);
+ stream->write(iHeadingPgn);
+ stream->write(pgnStart);
+ stream->write(lnnMin);
+ stream->write(wTextFlow);
+ stream->write(unused72);
+ shifterU16=pgbApplyTo;
+ shifterU16|=pgbPageDepth << 3;
+ shifterU16|=pgbOffsetFrom << 5;
+ shifterU16|=unused74_8 << 8;
+ stream->write(shifterU16);
+ stream->write(xaPage);
+ stream->write(yaPage);
+ stream->write(xaPageNUp);
+ stream->write(yaPageNUp);
+ stream->write(dxaLeft);
+ stream->write(dxaRight);
+ stream->write(dyaTop);
+ stream->write(dyaBottom);
+ stream->write(dzaGutter);
+ stream->write(dyaHdrTop);
+ stream->write(dyaHdrBottom);
+ stream->write(ccolM1);
+ stream->write(fEvenlySpaced);
+ stream->write(unused123);
+ stream->write(dxaColumns);
+ // skipping the std::vector rgdxaColumnWidthSpacing
+ stream->write(dxaColumnWidth);
+ stream->write(dmOrientFirst);
+ stream->write(fLayout);
+ stream->write(unused490);
+ olstAnm.write(stream, false);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void SEP::clear() {
+ bkc=2;
+ fTitlePage=0;
+ fAutoPgn=0;
+ nfcPgn=0;
+ fUnlocked=0;
+ cnsPgn=0;
+ fPgnRestart=0;
+ fEndNote=1;
+ lnc=0;
+ grpfIhdt=0;
+ nLnnMod=0;
+ dxaLnn=0;
+ dxaPgn=720;
+ dyaPgn=720;
+ fLBetween=0;
+ vjc=0;
+ dmBinFirst=0;
+ dmBinOther=0;
+ dmPaperReq=0;
+ brcTop.clear();
+ brcLeft.clear();
+ brcBottom.clear();
+ brcRight.clear();
+ fPropRMark=0;
+ ibstPropRMark=0;
+ dttmPropRMark.clear();
+ dxtCharSpace=0;
+ dyaLinePitch=0;
+ clm=0;
+ unused62=0;
+ dmOrientPage=1;
+ iHeadingPgn=0;
+ pgnStart=1;
+ lnnMin=0;
+ wTextFlow=0;
+ unused72=0;
+ pgbApplyTo=0;
+ pgbPageDepth=0;
+ pgbOffsetFrom=0;
+ unused74_8=0;
+ xaPage=12240;
+ yaPage=15840;
+ xaPageNUp=12240;
+ yaPageNUp=15840;
+ dxaLeft=1800;
+ dxaRight=1800;
+ dyaTop=1440;
+ dyaBottom=1440;
+ dzaGutter=0;
+ dyaHdrTop=720;
+ dyaHdrBottom=720;
+ ccolM1=0;
+ fEvenlySpaced=1;
+ unused123=0;
+ dxaColumns=720;
+ rgdxaColumnWidthSpacing.clear();
+ dxaColumnWidth=0;
+ dmOrientFirst=0;
+ fLayout=0;
+ unused490=0;
+ olstAnm.clear();
+}
+
+void SEP::dump() const
+{
+ wvlog << "Dumping SEP:" << std::endl;
+ wvlog << toString().c_str() << std::endl;
+ wvlog << "\nDumping SEP done." << std::endl;
+}
+
+std::string SEP::toString() const
+{
+ std::string s( "SEP:" );
+ s += "\nbkc=";
+ s += uint2string( bkc );
+ s += "\nfTitlePage=";
+ s += uint2string( fTitlePage );
+ s += "\nfAutoPgn=";
+ s += int2string( fAutoPgn );
+ s += "\nnfcPgn=";
+ s += uint2string( nfcPgn );
+ s += "\nfUnlocked=";
+ s += uint2string( fUnlocked );
+ s += "\ncnsPgn=";
+ s += uint2string( cnsPgn );
+ s += "\nfPgnRestart=";
+ s += uint2string( fPgnRestart );
+ s += "\nfEndNote=";
+ s += uint2string( fEndNote );
+ s += "\nlnc=";
+ s += int2string( lnc );
+ s += "\ngrpfIhdt=";
+ s += int2string( grpfIhdt );
+ s += "\nnLnnMod=";
+ s += uint2string( nLnnMod );
+ s += "\ndxaLnn=";
+ s += int2string( dxaLnn );
+ s += "\ndxaPgn=";
+ s += int2string( dxaPgn );
+ s += "\ndyaPgn=";
+ s += int2string( dyaPgn );
+ s += "\nfLBetween=";
+ s += int2string( fLBetween );
+ s += "\nvjc=";
+ s += int2string( vjc );
+ s += "\ndmBinFirst=";
+ s += uint2string( dmBinFirst );
+ s += "\ndmBinOther=";
+ s += uint2string( dmBinOther );
+ s += "\ndmPaperReq=";
+ s += uint2string( dmPaperReq );
+ s += "\nbrcTop=";
+ s += "\n{" + brcTop.toString() + "}\n";
+ s += "\nbrcLeft=";
+ s += "\n{" + brcLeft.toString() + "}\n";
+ s += "\nbrcBottom=";
+ s += "\n{" + brcBottom.toString() + "}\n";
+ s += "\nbrcRight=";
+ s += "\n{" + brcRight.toString() + "}\n";
+ s += "\nfPropRMark=";
+ s += int2string( fPropRMark );
+ s += "\nibstPropRMark=";
+ s += int2string( ibstPropRMark );
+ s += "\ndttmPropRMark=";
+ s += "\n{" + dttmPropRMark.toString() + "}\n";
+ s += "\ndxtCharSpace=";
+ s += int2string( dxtCharSpace );
+ s += "\ndyaLinePitch=";
+ s += int2string( dyaLinePitch );
+ s += "\nclm=";
+ s += uint2string( clm );
+ s += "\nunused62=";
+ s += uint2string( unused62 );
+ s += "\ndmOrientPage=";
+ s += uint2string( dmOrientPage );
+ s += "\niHeadingPgn=";
+ s += uint2string( iHeadingPgn );
+ s += "\npgnStart=";
+ s += uint2string( pgnStart );
+ s += "\nlnnMin=";
+ s += int2string( lnnMin );
+ s += "\nwTextFlow=";
+ s += uint2string( wTextFlow );
+ s += "\nunused72=";
+ s += uint2string( unused72 );
+ s += "\npgbApplyTo=";
+ s += uint2string( pgbApplyTo );
+ s += "\npgbPageDepth=";
+ s += uint2string( pgbPageDepth );
+ s += "\npgbOffsetFrom=";
+ s += uint2string( pgbOffsetFrom );
+ s += "\nunused74_8=";
+ s += uint2string( unused74_8 );
+ s += "\nxaPage=";
+ s += uint2string( xaPage );
+ s += "\nyaPage=";
+ s += uint2string( yaPage );
+ s += "\nxaPageNUp=";
+ s += uint2string( xaPageNUp );
+ s += "\nyaPageNUp=";
+ s += uint2string( yaPageNUp );
+ s += "\ndxaLeft=";
+ s += uint2string( dxaLeft );
+ s += "\ndxaRight=";
+ s += uint2string( dxaRight );
+ s += "\ndyaTop=";
+ s += int2string( dyaTop );
+ s += "\ndyaBottom=";
+ s += int2string( dyaBottom );
+ s += "\ndzaGutter=";
+ s += uint2string( dzaGutter );
+ s += "\ndyaHdrTop=";
+ s += uint2string( dyaHdrTop );
+ s += "\ndyaHdrBottom=";
+ s += uint2string( dyaHdrBottom );
+ s += "\nccolM1=";
+ s += int2string( ccolM1 );
+ s += "\nfEvenlySpaced=";
+ s += int2string( fEvenlySpaced );
+ s += "\nunused123=";
+ s += uint2string( unused123 );
+ s += "\ndxaColumns=";
+ s += int2string( dxaColumns );
+ s += "\nrgdxaColumnWidthSpacing=";
+ // skipping the std::vector rgdxaColumnWidthSpacing
+ s += "\ndxaColumnWidth=";
+ s += int2string( dxaColumnWidth );
+ s += "\ndmOrientFirst=";
+ s += uint2string( dmOrientFirst );
+ s += "\nfLayout=";
+ s += uint2string( fLayout );
+ s += "\nunused490=";
+ s += uint2string( unused490 );
+ s += "\nolstAnm=";
+ s += "\n{" + olstAnm.toString() + "}\n";
+ s += "\nSEP Done.";
+ return s;
+}
+
+bool operator==(const SEP &lhs, const SEP &rhs) {
+
+ return lhs.bkc==rhs.bkc &&
+ lhs.fTitlePage==rhs.fTitlePage &&
+ lhs.fAutoPgn==rhs.fAutoPgn &&
+ lhs.nfcPgn==rhs.nfcPgn &&
+ lhs.fUnlocked==rhs.fUnlocked &&
+ lhs.cnsPgn==rhs.cnsPgn &&
+ lhs.fPgnRestart==rhs.fPgnRestart &&
+ lhs.fEndNote==rhs.fEndNote &&
+ lhs.lnc==rhs.lnc &&
+ lhs.grpfIhdt==rhs.grpfIhdt &&
+ lhs.nLnnMod==rhs.nLnnMod &&
+ lhs.dxaLnn==rhs.dxaLnn &&
+ lhs.dxaPgn==rhs.dxaPgn &&
+ lhs.dyaPgn==rhs.dyaPgn &&
+ lhs.fLBetween==rhs.fLBetween &&
+ lhs.vjc==rhs.vjc &&
+ lhs.dmBinFirst==rhs.dmBinFirst &&
+ lhs.dmBinOther==rhs.dmBinOther &&
+ lhs.dmPaperReq==rhs.dmPaperReq &&
+ lhs.brcTop==rhs.brcTop &&
+ lhs.brcLeft==rhs.brcLeft &&
+ lhs.brcBottom==rhs.brcBottom &&
+ lhs.brcRight==rhs.brcRight &&
+ lhs.fPropRMark==rhs.fPropRMark &&
+ lhs.ibstPropRMark==rhs.ibstPropRMark &&
+ lhs.dttmPropRMark==rhs.dttmPropRMark &&
+ lhs.dxtCharSpace==rhs.dxtCharSpace &&
+ lhs.dyaLinePitch==rhs.dyaLinePitch &&
+ lhs.clm==rhs.clm &&
+ lhs.unused62==rhs.unused62 &&
+ lhs.dmOrientPage==rhs.dmOrientPage &&
+ lhs.iHeadingPgn==rhs.iHeadingPgn &&
+ lhs.pgnStart==rhs.pgnStart &&
+ lhs.lnnMin==rhs.lnnMin &&
+ lhs.wTextFlow==rhs.wTextFlow &&
+ lhs.unused72==rhs.unused72 &&
+ lhs.pgbApplyTo==rhs.pgbApplyTo &&
+ lhs.pgbPageDepth==rhs.pgbPageDepth &&
+ lhs.pgbOffsetFrom==rhs.pgbOffsetFrom &&
+ lhs.unused74_8==rhs.unused74_8 &&
+ lhs.xaPage==rhs.xaPage &&
+ lhs.yaPage==rhs.yaPage &&
+ lhs.xaPageNUp==rhs.xaPageNUp &&
+ lhs.yaPageNUp==rhs.yaPageNUp &&
+ lhs.dxaLeft==rhs.dxaLeft &&
+ lhs.dxaRight==rhs.dxaRight &&
+ lhs.dyaTop==rhs.dyaTop &&
+ lhs.dyaBottom==rhs.dyaBottom &&
+ lhs.dzaGutter==rhs.dzaGutter &&
+ lhs.dyaHdrTop==rhs.dyaHdrTop &&
+ lhs.dyaHdrBottom==rhs.dyaHdrBottom &&
+ lhs.ccolM1==rhs.ccolM1 &&
+ lhs.fEvenlySpaced==rhs.fEvenlySpaced &&
+ lhs.unused123==rhs.unused123 &&
+ lhs.dxaColumns==rhs.dxaColumns &&
+ lhs.rgdxaColumnWidthSpacing==rhs.rgdxaColumnWidthSpacing &&
+ lhs.dxaColumnWidth==rhs.dxaColumnWidth &&
+ lhs.dmOrientFirst==rhs.dmOrientFirst &&
+ lhs.fLayout==rhs.fLayout &&
+ lhs.unused490==rhs.unused490 &&
+ lhs.olstAnm==rhs.olstAnm;
+}
+
+bool operator!=(const SEP &lhs, const SEP &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// SEPX implementation
+
+SEPX::SEPX() {
+ clearInternal();
+}
+
+SEPX::SEPX(OLEStreamReader *stream, bool preservePos) {
+ clearInternal();
+ read(stream, preservePos);
+}
+
+SEPX::SEPX(const SEPX &rhs) {
+ cb=rhs.cb;
+ grpprl=rhs.grpprl;
+}
+
+SEPX::~SEPX() {
+ delete [] grpprl;
+}
+
+SEPX &SEPX::operator=(const SEPX &rhs) {
+
+ // Check for assignment to self
+ if(this==&rhs)
+ return *this;
+
+ cb=rhs.cb;
+ grpprl=rhs.grpprl;
+
+ return *this;
+}
+
+bool SEPX::read(OLEStreamReader *stream, bool preservePos) {
+
+ if(preservePos)
+ stream->push();
+
+ cb=stream->readU16();
+ // Attention: I don't know how to read grpprl - U8[]
+#ifdef __GNUC__
+#warning "Couldn't generate reading code for SEPX::grpprl"
+#endif
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool SEPX::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(cb);
+ // Attention: I don't know how to write grpprl - U8[]
+#ifdef __GNUC__
+#warning "Couldn't generate writing code for SEPX::grpprl"
+#endif
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void SEPX::clear() {
+ delete [] grpprl;
+ clearInternal();
+}
+
+void SEPX::clearInternal() {
+ cb=0;
+ grpprl=0;
+}
+
+bool operator==(const SEPX &lhs, const SEPX &rhs) {
+ // Attention: I don't know how to compare grpprl - U8[]
+#ifdef __GNUC__
+#warning "Can't compare SEPX::grpprl items"
+#endif
+
+ return lhs.cb==rhs.cb;
+}
+
+bool operator!=(const SEPX &lhs, const SEPX &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// STSHI implementation
+
+const unsigned int STSHI::sizeOf = 18;
+
+STSHI::STSHI() {
+ clear();
+}
+
+STSHI::STSHI(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool STSHI::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ cstd=stream->readU16();
+ cbSTDBaseInFile=stream->readU16();
+ shifterU16=stream->readU16();
+ fStdStylenamesWritten=shifterU16;
+ shifterU16>>=1;
+ unused4_2=shifterU16;
+ stiMaxWhenSaved=stream->readU16();
+ istdMaxFixedWhenSaved=stream->readU16();
+ nVerBuiltInNamesWhenSaved=stream->readU16();
+ for(int _i=0; _i<(3); ++_i)
+ rgftcStandardChpStsh[_i]=stream->readU16();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool STSHI::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(cstd);
+ stream->write(cbSTDBaseInFile);
+ shifterU16=fStdStylenamesWritten;
+ shifterU16|=unused4_2 << 1;
+ stream->write(shifterU16);
+ stream->write(stiMaxWhenSaved);
+ stream->write(istdMaxFixedWhenSaved);
+ stream->write(nVerBuiltInNamesWhenSaved);
+ for(int _i=0; _i<(3); ++_i)
+ stream->write(rgftcStandardChpStsh[_i]);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void STSHI::clear() {
+ cstd=0;
+ cbSTDBaseInFile=0;
+ fStdStylenamesWritten=0;
+ unused4_2=0;
+ stiMaxWhenSaved=0;
+ istdMaxFixedWhenSaved=0;
+ nVerBuiltInNamesWhenSaved=0;
+ for(int _i=0; _i<(3); ++_i)
+ rgftcStandardChpStsh[_i]=0;
+}
+
+bool operator==(const STSHI &lhs, const STSHI &rhs) {
+
+ for(int _i=0; _i<(3); ++_i) {
+ if(lhs.rgftcStandardChpStsh[_i]!=rhs.rgftcStandardChpStsh[_i])
+ return false;
+ }
+
+ return lhs.cstd==rhs.cstd &&
+ lhs.cbSTDBaseInFile==rhs.cbSTDBaseInFile &&
+ lhs.fStdStylenamesWritten==rhs.fStdStylenamesWritten &&
+ lhs.unused4_2==rhs.unused4_2 &&
+ lhs.stiMaxWhenSaved==rhs.stiMaxWhenSaved &&
+ lhs.istdMaxFixedWhenSaved==rhs.istdMaxFixedWhenSaved &&
+ lhs.nVerBuiltInNamesWhenSaved==rhs.nVerBuiltInNamesWhenSaved;
+}
+
+bool operator!=(const STSHI &lhs, const STSHI &rhs) {
+ return !(lhs==rhs);
+}
+
+
+// WKB implementation
+
+WKB::WKB() {
+ clear();
+}
+
+WKB::WKB(OLEStreamReader *stream, bool preservePos) {
+ clear();
+ read(stream, preservePos);
+}
+
+bool WKB::read(OLEStreamReader *stream, bool preservePos) {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ fn=stream->readS16();
+ grfwkb=stream->readU16();
+ lvl=stream->readS16();
+ shifterU16=stream->readU16();
+ fnpt=shifterU16;
+ shifterU16>>=4;
+ fnpd=shifterU16;
+ doc=stream->readS32();
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+bool WKB::write(OLEStreamWriter *stream, bool preservePos) const {
+
+ U16 shifterU16;
+
+ if(preservePos)
+ stream->push();
+
+ stream->write(fn);
+ stream->write(grfwkb);
+ stream->write(lvl);
+ shifterU16=fnpt;
+ shifterU16|=fnpd << 4;
+ stream->write(shifterU16);
+ stream->write(doc);
+
+ if(preservePos)
+ stream->pop();
+ return true;
+}
+
+void WKB::clear() {
+ fn=0;
+ grfwkb=0;
+ lvl=0;
+ fnpt=0;
+ fnpd=0;
+ doc=0;
+}
+
+bool operator==(const WKB &lhs, const WKB &rhs) {
+
+ return lhs.fn==rhs.fn &&
+ lhs.grfwkb==rhs.grfwkb &&
+ lhs.lvl==rhs.lvl &&
+ lhs.fnpt==rhs.fnpt &&
+ lhs.fnpd==rhs.fnpd &&
+ lhs.doc==rhs.doc;
+}
+
+bool operator!=(const WKB &lhs, const WKB &rhs) {
+ return !(lhs==rhs);
+}
+
+
+
+} // namespace Word97
+
+} // namespace wvWare
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/word97_generated.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/word97_generated.h
new file mode 100644
index 00000000..8ca9067d
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/word97_generated.h
@@ -0,0 +1,8740 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+// This code is generated from the Microsoft HTML specification of the
+// WinWord format. Do NOT edit this code, but fix the spec or the script
+// generating the sources.
+// For information about the script and the "hidden features" please read
+// the comments at the begin of the script.
+
+// If you find bugs or strange behavior please contact Werner Trobin
+
+#ifndef WORD97_GENERATED_H
+#define WORD97_GENERATED_H
+
+#include "global.h"
+#include "sharedptr.h"
+#include "utilities.h"
+#include "ustring.h"
+#include <vector> // for Word97::PAP
+
+namespace wvWare {
+
+class OLEStreamReader;
+class OLEStreamWriter;
+class StyleSheet;
+class Style;
+
+namespace Word97 {
+
+ /**
+ * Helper function to convert ico color codes to 24bit rgb values
+ */
+ U32 icoToRGB(U16 ico);
+
+/**
+ * Font Family Name (FFN), this code is located in the template-Word97.h
+ */
+struct FFN {
+ enum Version { Word95, Word97 };
+ /**
+ * Creates an empty FFN structure and sets the defaults
+ */
+ FFN();
+ /**
+ * Simply calls read(...)
+ */
+ FFN(OLEStreamReader *stream, Version version, bool preservePos=false);
+
+ /**
+ * This method reads the FFN structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, Version version, bool preservePos=false);
+
+ /**
+ * Same as reading, not implemented yet
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * total length of FFN - 1.
+ */
+ U8 cbFfnM1;
+
+ /**
+ * pitch request
+ */
+ U8 prq:2;
+
+ /**
+ * when 1, font is a TrueType font
+ */
+ U8 fTrueType:1;
+
+ /**
+ * reserved
+ */
+ U8 unused1_3:1;
+
+ /**
+ * font family id
+ */
+ U8 ff:3;
+
+ /**
+ * reserved
+ */
+ U8 unused1_7:1;
+
+ /**
+ * base weight of font
+ */
+ S16 wWeight;
+
+ /**
+ * character set identifier
+ */
+ U8 chs;
+
+ /**
+ * index into ffn.szFfn to the name of the alternate font
+ */
+ U8 ixchSzAlt;
+
+ /**
+ * ? This is supposed to be of type PANOSE.
+ */
+ U8 panose[10];
+
+ /**
+ * ? This is supposed to be of type FONTSIGNATURE.
+ */
+ U8 fs[24];
+
+ /**
+ * zero terminated string that records name of font. Possibly followed
+ * by a second xsz which records the name of an alternate font to use if the
+ * first named font does not exist on this system. Maximal size of xszFfn
+ * is 65 characters.
+ */
+ //U8 *xszFfn; // U8 xszFfn[];
+ /**
+ * We are using two UStrings here, the alternative string (xszFfnAlt) will
+ * contain the alternative font name in case ixchSzAlt is != 0
+ */
+ UString xszFfn;
+ UString xszFfnAlt;
+
+private:
+ FFN(const FFN &rhs);
+ FFN &operator=(const FFN &rhs);
+
+ void clearInternal();
+}; // FFN
+
+/**
+ * Tab Descriptor (TBD)
+ */
+struct TBD
+{
+ TBD() : jc( 0 ), tlc( 0 ), unused0_6( 0 ) {}
+ TBD( U8 tbd )
+ {
+ jc = tbd;
+ tbd >>= 3;
+ tlc = tbd;
+ tbd >>= 3;
+ unused0_6 = tbd;
+ }
+
+ /**
+ * justification code
+ * 0 left tab
+ * 1 centered tab
+ * 2 right tab
+ * 3 decimal tab
+ * 4 bar
+ */
+ U8 jc:3;
+
+ /**
+ * tab leader code
+ * 0 no leader
+ * 1 dotted leader
+ * 2 hyphenated leader
+ * 3 single line leader
+ * 4 heavy line leader
+ */
+ U8 tlc:3;
+
+ /**
+ * reserved
+ */
+ U8 unused0_6:2;
+};
+
+/**
+ * Convenient structure for describing tabs
+ * It's difficult to sort two arrays in parallel, so instead of rgdxaTab[] and rgtbd[]
+ * we combine all the data for one tab into this struct, and the PAP has
+ * a vector<TabDescriptor>
+ */
+struct TabDescriptor
+{
+ /**
+ * Position of the tab
+ */
+ S16 dxaTab;
+ /**
+ * Options (justification and tab-leading code)
+ */
+ Word97::TBD tbd;
+
+}; // TabDescriptor
+
+// There can be only one tab at a given position, no matter what the other options are
+bool operator==( const TabDescriptor& lhs, const TabDescriptor& rhs );
+bool operator!=( const TabDescriptor& lhs, const TabDescriptor& rhs );
+bool operator<( const TabDescriptor& lhs, const TabDescriptor& rhs );
+bool operator>( const TabDescriptor& lhs, const TabDescriptor& rhs );
+
+
+/**
+ * Date and Time (internal date format) (DTTM)
+ */
+struct DTTM {
+ /**
+ * Creates an empty DTTM structure and sets the defaults
+ */
+ DTTM();
+ /**
+ * Simply calls read(...)
+ */
+ DTTM(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ DTTM(const U8 *ptr);
+
+ /**
+ * This method reads the DTTM structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * minutes (0-59)
+ */
+ U16 mint:6;
+
+ /**
+ * hours (0-23)
+ */
+ U16 hr:5;
+
+ /**
+ * days of month (1-31)
+ */
+ U16 dom:5;
+
+ /**
+ * months (1-12)
+ */
+ U16 mon:4;
+
+ /**
+ * years (1900-2411)-1900
+ */
+ U16 yr:9;
+
+ /**
+ * weekday
+ * Sunday=0
+ * Monday=1
+ * Tuesday=2
+ * Wednesday=3
+ * Thursday=4
+ * Friday=5
+ * Saturday=6
+ */
+ U16 wdy:3;
+
+}; // DTTM
+
+bool operator==(const DTTM &lhs, const DTTM &rhs);
+bool operator!=(const DTTM &lhs, const DTTM &rhs);
+
+
+/**
+ * Document Typography Info (DOPTYPOGRAPHY)
+ */
+struct DOPTYPOGRAPHY {
+ /**
+ * Creates an empty DOPTYPOGRAPHY structure and sets the defaults
+ */
+ DOPTYPOGRAPHY();
+ /**
+ * Simply calls read(...)
+ */
+ DOPTYPOGRAPHY(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the DOPTYPOGRAPHY structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * true if we're kerning punctuation
+ */
+ U16 fKerningPunct:1;
+
+ /**
+ * Kinsoku method of justification:
+ * 0 = always expand
+ * 1 = compress punctuation
+ * 2 = compress punctuation and kana.
+ */
+ U16 iJustification:2;
+
+ /**
+ * Level of Kinsoku:
+ * 0 = Level 1
+ * 1 = Level 2
+ * 2 = Custom
+ */
+ U16 iLevelOfKinsoku:2;
+
+ /**
+ * 2-page-on-1 feature is turned on.
+ */
+ U16 f2on1:1;
+
+ /**
+ * reserved
+ */
+ U16 unused0_6:10;
+
+ /**
+ * length of rgxchFPunct
+ */
+ S16 cchFollowingPunct;
+
+ /**
+ * length of rgxchLPunct
+ */
+ S16 cchLeadingPunct;
+
+ /**
+ * array of characters that should never appear at the start of a line
+ */
+ XCHAR rgxchFPunct[101];
+
+ /**
+ * array of characters that should never appear at the end of a line
+ */
+ XCHAR rgxchLPunct[51];
+
+}; // DOPTYPOGRAPHY
+
+bool operator==(const DOPTYPOGRAPHY &lhs, const DOPTYPOGRAPHY &rhs);
+bool operator!=(const DOPTYPOGRAPHY &lhs, const DOPTYPOGRAPHY &rhs);
+
+
+/**
+ * Property Modifier(variant 2) (PRM2)
+ */
+struct PRM2 {
+ /**
+ * Creates an empty PRM2 structure and sets the defaults
+ */
+ PRM2();
+ /**
+ * Simply calls read(...)
+ */
+ PRM2(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the PRM2 structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * set to 1 for variant 2
+ */
+ U16 fComplex:1;
+
+ /**
+ * index to a <b>grpprl</b> stored in <b>CLX</b> portion of file.
+ */
+ U16 igrpprl:15;
+
+}; // PRM2
+
+bool operator==(const PRM2 &lhs, const PRM2 &rhs);
+bool operator!=(const PRM2 &lhs, const PRM2 &rhs);
+
+
+/**
+ * Property Modifier(variant 1) (PRM)
+ */
+struct PRM {
+ /**
+ * Creates an empty PRM structure and sets the defaults
+ */
+ PRM();
+ /**
+ * Simply calls read(...)
+ */
+ PRM(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ PRM(const U8 *ptr);
+
+ /**
+ * This method reads the PRM structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * This method returns a PRM2 created from the current PRM
+ */
+ PRM2 toPRM2() const;
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * set to 0 for variant 1
+ */
+ U16 fComplex:1;
+
+ /**
+ * index to entry into rgsprmPrm
+ */
+ U16 isprm:7;
+
+ /**
+ * sprm's operand
+ */
+ U16 val:8;
+
+}; // PRM
+
+bool operator==(const PRM &lhs, const PRM &rhs);
+bool operator!=(const PRM &lhs, const PRM &rhs);
+
+
+/**
+ * Shading Descriptor (SHD)
+ */
+struct SHD {
+ /**
+ * Creates an empty SHD structure and sets the defaults
+ */
+ SHD();
+ /**
+ * Simply calls read(...)
+ */
+ SHD(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ SHD(const U8 *ptr);
+
+ /**
+ * This method reads the SHD structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * This method reads the struct from a pointer (later than word97)
+ */
+ void read90Ptr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * foreground color
+ */
+ U32 cvFore;
+
+ /**
+ * background color
+ */
+ U32 cvBack;
+
+ /**
+ * shading pattern (see ipat table below)
+ * 0 Automatic
+ * 1 Solid
+ * 2 5 Percent
+ * 3 10 Percent
+ * 4 20 Percent
+ * 5 25 Percent
+ * 6 30 Percent
+ * 7 40 Percent
+ * 8 50 Percent
+ * 9 60 Percent
+ * 10 70 Percent
+ * 11 75 Percent
+ * 12 80 Percent
+ * 13 90 Percent
+ * 14 Dark Horizontal
+ * 15 Dark Vertical
+ * 16 Dark Forward Diagonal
+ * 17 Dark Backward Diagonal
+ * 18 Dark Cross
+ * 19 Dark Diagonal Cross
+ * 20 Horizontal
+ * 21 Vertical
+ * 22 Forward Diagonal
+ * 23 Backward Diagonal
+ * 24 Cross
+ * 25 Diagonal Cross
+ * 35 2.5 Percent
+ * 36 7.5 Percent
+ * 37 12.5 Percent
+ * 38 15 Percent
+ * 39 17.5 Percent
+ * 40 22.5 Percent
+ * 41 27.5 Percent
+ * 42 32.5 Percent
+ * 43 35 Percent
+ * 44 37.5 Percent
+ * 45 42.5 Percent
+ * 46 45 Percent
+ * 47 47.5 Percent
+ * 48 52.5 Percent
+ * 49 55 Percent
+ * 50 57.5 Percent
+ * 51 62.5 Percent
+ * 52 65 Percent
+ * 53 67.5 Percent
+ * 54 72.5 Percent
+ * 55 77.5 Percent
+ * 56 82.5 Percent
+ * 57 85 Percent
+ * 58 87.5 Percent
+ * 59 92.5 Percent
+ * 60 95 Percent
+ * 61 97.5 Percent
+ * 62 97 Percent
+ */
+ U16 ipat;
+
+}; // SHD
+
+bool operator==(const SHD &lhs, const SHD &rhs);
+bool operator!=(const SHD &lhs, const SHD &rhs);
+
+
+/**
+ * Paragraph Height (PHE)
+ */
+struct PHE {
+ /**
+ * Creates an empty PHE structure and sets the defaults
+ */
+ PHE();
+ /**
+ * Simply calls read(...)
+ */
+ PHE(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ PHE(const U8 *ptr);
+
+ /**
+ * This method reads the PHE structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * reserved
+ */
+ U16 fSpare:1;
+
+ /**
+ * PHE entry is invalid when == 1
+ */
+ U16 fUnk:1;
+
+ /**
+ * when 1, total height of paragraph is known but lines in paragraph have
+ * different heights.
+ */
+ U16 fDiffLines:1;
+
+ /**
+ * reserved
+ */
+ U16 unused0_3:5;
+
+ /**
+ * when fDiffLines is 0 is number of lines in paragraph
+ */
+ U16 clMac:8;
+
+ /**
+ * reserved
+ */
+ U16 unused2;
+
+ /**
+ * width of lines in paragraph
+ */
+ S32 dxaCol;
+
+ /**
+ * when fDiffLines is 0, is height of every line in paragraph in pixels
+ * (dymLine)
+ * when fDiffLines is 1, is the total height in pixels of the paragraph
+ * (dymHeight)
+ */
+ S32 dym;
+
+}; // PHE
+
+bool operator==(const PHE &lhs, const PHE &rhs);
+bool operator!=(const PHE &lhs, const PHE &rhs);
+
+
+/**
+ * Border Code (BRC)
+ */
+struct BRC {
+ /**
+ * Creates an empty BRC structure and sets the defaults
+ */
+ BRC();
+ /**
+ * Simply calls read(...)
+ */
+ BRC(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ BRC(const U8 *ptr);
+
+ /**
+ * This method reads the BRC structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer (brc80)
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * This method reads the struct from a pointer (later than word97)
+ */
+ void read90Ptr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+ static const unsigned int sizeOf97;
+
+ // Data
+
+ /**
+ * 24-bit border color
+ */
+ U32 cv;
+
+ /**
+ * width of a single line in 1/8 pt, max of 32 pt.
+ */
+ U16 dptLineWidth:8;
+
+ /**
+ * border type code:
+ * 0 none
+ * 1 single
+ * 2 thick
+ * 3 double
+ * 5 hairline
+ * 6 dot
+ * 7 dash large gap
+ * 8 dot dash
+ * 9 dot dot dash
+ * 10 triple
+ * 11 thin-thick small gap
+ * 12 thick-thin small gap
+ * 13 thin-thick-thin small gap
+ * 14 thin-thick medium gap
+ * 15 thick-thin medium gap
+ * 16 thin-thick-thin medium gap
+ * 17 thin-thick large gap
+ * 18 thick-thin large gap
+ * 19 thin-thick-thin large gap
+ * 20 wave
+ * 21 double wave
+ * 22 dash small gap
+ * 23 dash dot stroked
+ * 24 emboss 3D
+ * 25 engrave 3D
+ * codes 64 - 230 represent border art types and are used only for page
+ * borders.
+ */
+ U16 brcType:8;
+
+ /**
+ * width of space to maintain between border and text within border. Must
+ * be 0 when BRC is a substructure of TC. Stored in points.
+ */
+ U16 dptSpace:5;
+
+ /**
+ * when 1, border is drawn with shadow. Must be 0 when BRC is a substructure
+ * of the TC
+ */
+ U16 fShadow:1;
+
+ U16 fFrame:1;
+
+ /**
+ * reserved
+ */
+ U16 unused2_15:9;
+
+}; // BRC
+
+bool operator==(const BRC &lhs, const BRC &rhs);
+bool operator!=(const BRC &lhs, const BRC &rhs);
+
+
+/**
+ * Table Autoformat Look sPecifier (TLP)
+ */
+struct TLP {
+ /**
+ * Creates an empty TLP structure and sets the defaults
+ */
+ TLP();
+ /**
+ * Simply calls read(...)
+ */
+ TLP(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ TLP(const U8 *ptr);
+
+ /**
+ * This method reads the TLP structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * index to Word's table of table looks:
+ * 0 (none)
+ * 1 Simple 1
+ * 2 Simple 2
+ * 3 Simple 3
+ * 4 Classic 1
+ * 5 Classic 2
+ * 6 Classic 3
+ * 7 Classic 4
+ * 8 Colorful 1
+ * 9 Colorful 2
+ * 10 Colorful 3
+ * 11 Columns 1
+ * 12 Columns 2
+ * 13 Columns 3
+ * 14 Columns 4
+ * 15 Columns 5
+ * 16 Grid 1
+ * 17 Grid 2
+ * 18 Grid 3
+ * 19 Grid 4
+ * 20 Grid 5
+ * 21 Grid 6
+ * 22 Grid 7
+ * 23 Grid 8
+ * 24 List 1
+ * 25 List 2
+ * 26 List 3
+ * 27 List 4
+ * 28 List 5
+ * 29 List 6
+ * 30 List 7
+ * 31 List 8
+ * 32 3D Effects 1
+ * 33 3D Effects 2
+ * 34 3D Effects 3
+ * 35 Contemporary
+ * 36 Elegant
+ * 37 Professional
+ * 38 Subtle1
+ * 39 Subtle2
+ */
+ S16 itl;
+
+ /**
+ * when ==1, use the border properties from the selected table look
+ */
+ U16 fBorders:1;
+
+ /**
+ * when ==1, use the shading properties from the selected table look
+ */
+ U16 fShading:1;
+
+ /**
+ * when ==1, use the font from the selected table look
+ */
+ U16 fFont:1;
+
+ /**
+ * when ==1, use the color from the selected table look
+ */
+ U16 fColor:1;
+
+ /**
+ * when ==1, do best fit from the selected table look
+ */
+ U16 fBestFit:1;
+
+ /**
+ * when ==1, apply properties from the selected table look to the header
+ * rows in the table
+ */
+ U16 fHdrRows:1;
+
+ /**
+ * when ==1, apply properties from the selected table look to the last
+ * row in the table
+ */
+ U16 fLastRow:1;
+
+ /**
+ * when ==1, apply properties from the selected table look to the header
+ * columns of the table
+ */
+ U16 fHdrCols:1;
+
+ /**
+ * when ==1, apply properties from the selected table look to the last
+ * column of the table
+ */
+ U16 fLastCol:1;
+
+ /**
+ * unused
+ */
+ U16 unused2_9:7;
+
+}; // TLP
+
+bool operator==(const TLP &lhs, const TLP &rhs);
+bool operator!=(const TLP &lhs, const TLP &rhs);
+
+
+/**
+ * Table Cell Descriptors (TC)
+ */
+struct TC {
+ /**
+ * Creates an empty TC structure and sets the defaults
+ */
+ TC();
+ /**
+ * Simply calls read(...)
+ */
+ TC(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ TC(const U8 *ptr);
+
+ /**
+ * This method reads the TC structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * set to 1 when cell is first cell of a range of cells that have been
+ * merged. When a cell is merged, the display areas of the merged cells are
+ * consolidated and the text within the cells is interpreted as belonging
+ * to one text stream for purposes of calculating line breaks.
+ */
+ U16 fFirstMerged:1;
+
+ /**
+ * set to 1 when cell has been merged with preceding cell.
+ */
+ U16 fMerged:1;
+
+ /**
+ * set to 1 when cell has vertical text flow
+ */
+ U16 fVertical:1;
+
+ /**
+ * for a vertical table cell, text flow is bottom to top when 1 and is
+ * bottom to top when 0.
+ */
+ U16 fBackward:1;
+
+ /**
+ * set to 1 when cell has rotated characters (i.e. uses @font)
+ */
+ U16 fRotateFont:1;
+
+ /**
+ * set to 1 when cell is vertically merged with the cell(s) above and/or
+ * below. When cells are vertically merged, the display area of the merged
+ * cells are consolidated. The consolidated area is used to display the contents
+ * of the first vertically merged cell (the cell with fVertRestart set to
+ * 1), and all other vertically merged cells (those with fVertRestart set
+ * to 0) must be empty. Cells can only be merged vertically if their left
+ * and right boundaries are (nearly) identical (i.e. if corresponding entries
+ * in rgdxaCenter of the table rows differ by at most 3).
+ */
+ U16 fVertMerge:1;
+
+ /**
+ * set to 1 when the cell is the first of a set of vertically merged cells.
+ * The contents of a cell with fVertStart set to 1 are displayed in the consolidated
+ * area belonging to the entire set of vertically merged cells. Vertically
+ * merged cells with fVertRestart set to 0 must be empty.
+ */
+ U16 fVertRestart:1;
+
+ /**
+ * specifies the alignment of the cell contents relative to text flow
+ * (e.g. in a cell with bottom to top text flow and bottom vertical alignment,
+ * the text is shifted horizontally to match the cell's right boundary):
+ * 0 top
+ * 1 center
+ * 2 bottom
+ */
+ U16 vertAlign:2;
+
+ /**
+ * reserved
+ */
+ U16 fUnused:7;
+
+ /**
+ * reserved
+ */
+ U16 wUnused;
+
+ /**
+ * BRC[cbrcTc] rgbrc: notational convenience for referring to brcTop,
+ * brcLeft, etc. fields.
+ * specification of the top border of a table cell
+ */
+ BRC brcTop;
+
+ /**
+ * specification of left border of table row
+ */
+ BRC brcLeft;
+
+ /**
+ * specification of bottom border of table row
+ */
+ BRC brcBottom;
+
+ /**
+ * specification of right border of table row.
+ */
+ BRC brcRight;
+
+}; // TC
+
+bool operator==(const TC &lhs, const TC &rhs);
+bool operator!=(const TC &lhs, const TC &rhs);
+
+
+/**
+ * Table Properties (TAP)
+ */
+struct TAP : public Shared {
+ /**
+ * Creates an empty TAP structure and sets the defaults
+ */
+ TAP();
+ /**
+ * Simply calls read(...)
+ */
+ TAP(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the TAP structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * This method applies a grpprl with @param count elements
+ */
+ void apply(const U8 *grpprl, U16 count, const Style* style, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version);
+
+ /**
+ * This method applies a whole TAPX to the structure.
+ * The reason that we only pass a pointer to the start of the exception
+ * structure is, that we don't know the type in the FKP template :}
+ */
+ void applyExceptions(const U8 *exceptions, const StyleSheet *styleSheet, OLEStreamReader* dataStream, WordVersion version);
+
+ /**
+ * This method applies one single SPRM. It returns -1 if it wasn't
+ * a TAP SPRM and it returns the length of the applied SPRM
+ * if it was successful.
+ */
+ S16 applyTAPSPRM(const U8* ptr, const Style* style, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version);
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * justification code. specifies how table row should be justified within
+ * its column.
+ * 0 left justify
+ * 1 center
+ * 2 right justify
+ */
+ S16 jc;
+
+ /**
+ * measures half of the white space that will be maintained between text
+ * in adjacent columns of a table row. A dxaGapHalf width of white space will
+ * be maintained on both sides of a column boundary.
+ */
+ S32 dxaGapHalf;
+
+ /**
+ * when greater than 0. guarantees that the height of the table will be
+ * at least dyaRowHeight high. When less than 0, guarantees that the height
+ * of the table will be exactly absolute value of dyaRowHeight high. When
+ * 0, table will be given a height large enough to represent all of the text
+ * in all of the cells of the table. Cells with vertical text flow make no
+ * contribution to the computation of the height of rows with auto or at least
+ * height. Neither do vertically merged cells, except in the last row of the
+ * vertical merge. If an auto height row consists entirely of cells which
+ * have vertical text direction or are vertically merged, and the row does
+ * not contain the last cell in any vertical cell merge, then the row is given
+ * height equal to that of the end of cell mark in the first cell.
+ */
+ S32 dyaRowHeight;
+
+ /**
+ * when 1, table row may not be split across page bounds
+ */
+ U8 fCantSplit;
+
+ /**
+ * when 1, table row is to be used as the header of the table
+ */
+ U8 fTableHeader;
+
+ /**
+ * table look specifier (see TLP definition)
+ */
+ TLP tlp;
+
+ /**
+ * reserved for future use
+ */
+ S32 lwHTMLProps;
+
+ /**
+ * used internally by Word
+ */
+ U16 fCaFull:1;
+
+ /**
+ * used internally by Word
+ */
+ U16 fFirstRow:1;
+
+ /**
+ * used internally by Word
+ */
+ U16 fLastRow:1;
+
+ /**
+ * used internally by Word
+ */
+ U16 fOutline:1;
+
+ /**
+ * reserved
+ */
+ U16 unused20_12:12;
+
+ /**
+ * count of cells defined for this row. ItcMac must be >= 0 and less than
+ * or equal to 64.
+ */
+ S16 itcMac;
+
+ /**
+ * used internally by Word
+ */
+ S32 dxaAdjust;
+
+ /**
+ * used internally by Word
+ */
+ S32 dxaScale;
+
+ /**
+ * used internally by Word
+ */
+ S32 dxsInch;
+
+ /**
+ * rgdxaCenter[0] is the left boundary of cell 0 measured relative to
+ * margin.. rgdxaCenter[tap.itcMac - 1] is left boundary of last cell. rgdxaCenter[tap.itcMac]
+ * is right boundary of last cell. (Changed the array to a vector)
+ */
+ std::vector<S16> rgdxaCenter;
+
+ /**
+ * used internally by Word (Changed the array to a vector)
+ */
+ std::vector<S16> rgdxaCenterPrint;
+
+ /**
+ * array of table cell descriptors (Changed the array to a vector)
+ */
+ std::vector<TC> rgtc;
+
+ /**
+ * array of cell shades (Changed the array to a vector)
+ */
+ std::vector<SHD> rgshd;
+
+ /**
+ * array of border defaults for cells
+ */
+ BRC rgbrcTable[6];
+
+}; // TAP
+
+bool operator==(const TAP &lhs, const TAP &rhs);
+bool operator!=(const TAP &lhs, const TAP &rhs);
+
+
+/**
+ * Tab Descriptor (TBD)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct TBD {
+// /**
+// * Creates an empty TBD structure and sets the defaults
+// */
+// TBD();
+// /**
+// * Simply calls read(...)
+// */
+// TBD(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * This method reads the TBD structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * justification code
+// * 0 left tab
+// * 1 centered tab
+// * 2 right tab
+// * 3 decimal tab
+// * 4 bar
+// */
+// U8 jc:3;
+
+// /**
+// * tab leader code
+// * 0 no leader
+// * 1 dotted leader
+// * 2 hyphenated leader
+// * 3 single line leader
+// * 4 heavy line leader
+// */
+// U8 tlc:3;
+
+// /**
+// * reserved
+// */
+// U8 unused0_6:2;
+
+//}; // TBD
+
+//bool operator==(const TBD &lhs, const TBD &rhs);
+//bool operator!=(const TBD &lhs, const TBD &rhs);
+
+
+/**
+ * Autonumbered List Data Descriptor (ANLD)
+ */
+struct ANLD {
+ /**
+ * Creates an empty ANLD structure and sets the defaults
+ */
+ ANLD();
+ /**
+ * Simply calls read(...)
+ */
+ ANLD(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ ANLD(const U8 *ptr);
+
+ /**
+ * This method reads the ANLD structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * number format code
+ * 0 Arabic numbering (1, 2, 3, ...)
+ * 1 Upper case Roman (I, II, III, ...)
+ * 2 Lower case Roman (i, ii, iii, ...)
+ * 3 Upper case Letter (A, B, C, ...)
+ * 4 Lower case letter (a, b, c, ...)
+ * 5 Ordinal (1., 2., 3., ...)
+ * 6 Numbered (One, Two, Three, ...)
+ * 7 Ordinal (text) (First, Second, Third, ...)
+ * 22 Leading Zero (01, 02,..., 09, 10, 11,..., 99, 100, 101,...)
+ * 23 Bullet (check the character code in the text)
+ */
+ U8 nfc;
+
+ /**
+ * offset into anld.rgxch that is the limit of the text that will be displayed
+ * as the prefix of the autonumber text
+ */
+ U8 cxchTextBefore;
+
+ /**
+ * anld.cxchTextBefore will be the beginning offset of the text in the
+ * anld.rgxch that will be displayed as the suffix of an autonumber. The sum
+ * of anld.cxchTextBefore + anld.cxchTextAfter will be the limit of the autonumber
+ * suffix in anld.rgch
+ */
+ U8 cxchTextAfter;
+
+ /**
+ * justification code
+ * 0 left justify
+ * 1 center
+ * 2 right justify
+ * 3 left and right justify
+ */
+ U8 jc:2;
+
+ /**
+ * when ==1, number generated will include previous levels (used for legal
+ * numbering)
+ */
+ U8 fPrev:1;
+
+ /**
+ * when ==1, number will be displayed using a hanging indent
+ */
+ U8 fHang:1;
+
+ /**
+ * when ==1, boldness of number will be determined by anld.fBold.
+ */
+ U8 fSetBold:1;
+
+ /**
+ * when ==1, italicness of number will be determined by anld.fItalic
+ */
+ U8 fSetItalic:1;
+
+ /**
+ * when ==1, anld.fSmallCaps will determine whether number will be displayed
+ * in small caps or not.
+ */
+ U8 fSetSmallCaps:1;
+
+ /**
+ * when ==1, anld.fCaps will determine whether number will be displayed
+ * capitalized or not
+ */
+ U8 fSetCaps:1;
+
+ /**
+ * when ==1, anld.fStrike will determine whether the number will be displayed
+ * using strikethrough or not.
+ */
+ U8 fSetStrike:1;
+
+ /**
+ * when ==1, anld.kul will determine the underlining state of the autonumber.
+ */
+ U8 fSetKul:1;
+
+ /**
+ * when ==1, autonumber will be displayed with a single prefixing space
+ * character
+ */
+ U8 fPrevSpace:1;
+
+ /**
+ * determines boldness of autonumber when anld.fSetBold == 1.
+ */
+ U8 fBold:1;
+
+ /**
+ * determines italicness of autonumber when anld.fSetItalic == 1.
+ */
+ U8 fItalic:1;
+
+ /**
+ * determines whether autonumber will be displayed using small caps when
+ * anld.fSetSmallCaps == 1.
+ */
+ U8 fSmallCaps:1;
+
+ /**
+ * determines whether autonumber will be displayed using caps when anld.fSetCaps
+ * == 1.
+ */
+ U8 fCaps:1;
+
+ /**
+ * determines whether autonumber will be displayed using caps when anld.fSetStrike
+ * == 1.
+ */
+ U8 fStrike:1;
+
+ /**
+ * determines whether autonumber will be displayed with underlining when
+ * anld.fSetKul == 1.
+ */
+ U8 kul:3;
+
+ /**
+ * color of autonumber
+ */
+ U8 ico:5;
+
+ /**
+ * font code of autonumber
+ */
+ S16 ftc;
+
+ /**
+ * font half point size (or 0=auto)
+ */
+ U16 hps;
+
+ /**
+ * starting value (0 to 65535)
+ */
+ U16 iStartAt;
+
+ /**
+ * width of prefix text (same as indent)
+ */
+ U16 dxaIndent;
+
+ /**
+ * minimum space between number and paragraph
+ */
+ U16 dxaSpace;
+
+ /**
+ * number only 1 item per table cell
+ */
+ U8 fNumber1;
+
+ /**
+ * number across cells in table rows(instead of down)
+ */
+ U8 fNumberAcross;
+
+ /**
+ * restart heading number on section boundary
+ */
+ U8 fRestartHdn;
+
+ /**
+ * unused( should be 0)
+ */
+ U8 fSpareX;
+
+ /**
+ * characters displayed before/after autonumber
+ */
+ XCHAR rgxch[32];
+
+}; // ANLD
+
+bool operator==(const ANLD &lhs, const ANLD &rhs);
+bool operator!=(const ANLD &lhs, const ANLD &rhs);
+
+
+/**
+ * Autonumber Level Descriptor (ANLV)
+ */
+struct ANLV {
+ /**
+ * Creates an empty ANLV structure and sets the defaults
+ */
+ ANLV();
+ /**
+ * Simply calls read(...)
+ */
+ ANLV(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ ANLV(const U8 *ptr);
+
+ /**
+ * This method reads the ANLV structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * number format code
+ * 0 Arabic numbering
+ * 1 Upper case Roman
+ * 2 Lower case Roman
+ * 3 Upper case Letter
+ * 4 Lower case letter
+ * 5 Ordinal
+ */
+ U8 nfc;
+
+ /**
+ * offset into anld.rgxch that is the limit of the text that will be displayed
+ * as the prefix of the autonumber text
+ */
+ U8 cxchTextBefore;
+
+ /**
+ * anld.cxchTextBefore will be the beginning offset of the text in the
+ * anld.rgxch that will be displayed as the suffix of an autonumber. The sum
+ * of anld.cxchTextBefore + anld.cxchTextAfter will be the limit of the autonumber
+ * suffix in anld.rgxch
+ */
+ U8 cxchTextAfter;
+
+ /**
+ * justification code
+ * 0 left justify
+ * 1 center
+ * 2 right justify
+ * 3 left and right justify
+ */
+ U8 jc:2;
+
+ /**
+ * when ==1, number generated will include previous levels (used for legal
+ * numbering)
+ */
+ U8 fPrev:1;
+
+ /**
+ * when ==1, number will be displayed using a hanging indent
+ */
+ U8 fHang:1;
+
+ /**
+ * when ==1, boldness of number will be determined by anld.fBold.
+ */
+ U8 fSetBold:1;
+
+ /**
+ * when ==1, italicness of number will be determined by anld.fItalic
+ */
+ U8 fSetItalic:1;
+
+ /**
+ * when ==1, anld.fSmallCaps will determine whether number will be displayed
+ * in small caps or not.
+ */
+ U8 fSetSmallCaps:1;
+
+ /**
+ * when ==1, anld.fCaps will determine whether number will be displayed
+ * capitalized or not
+ */
+ U8 fSetCaps:1;
+
+ /**
+ * when ==1, anld.fStrike will determine whether the number will be displayed
+ * using strikethrough or not.
+ */
+ U8 fSetStrike:1;
+
+ /**
+ * when ==1, anld.kul will determine the underlining state of the autonumber.
+ */
+ U8 fSetKul:1;
+
+ /**
+ * when ==1, autonumber will be displayed with a single prefixing space
+ * character
+ */
+ U8 fPrevSpace:1;
+
+ /**
+ * determines boldness of autonumber when anld.fSetBold == 1.
+ */
+ U8 fBold:1;
+
+ /**
+ * determines italicness of autonumber when anld.fSetItalic == 1.
+ */
+ U8 fItalic:1;
+
+ /**
+ * determines whether autonumber will be displayed using small caps when
+ * anld.fSetSmallCaps == 1.
+ */
+ U8 fSmallCaps:1;
+
+ /**
+ * determines whether autonumber will be displayed using caps when anld.fSetCaps
+ * == 1.
+ */
+ U8 fCaps:1;
+
+ /**
+ * determines whether autonumber will be displayed using caps when anld.fSetStrike
+ * == 1.
+ */
+ U8 fStrike:1;
+
+ /**
+ * determines whether autonumber will be displayed with underlining when
+ * anld.fSetKul == 1.
+ */
+ U8 kul:3;
+
+ /**
+ * color of autonumber
+ */
+ U8 ico:5;
+
+ /**
+ * font code of autonumber
+ */
+ S16 ftc;
+
+ /**
+ * font half point size (or 0=auto)
+ */
+ U16 hps;
+
+ /**
+ * starting value (0 to 65535)
+ */
+ U16 iStartAt;
+
+ /**
+ * width of prefix text (same as indent)
+ */
+ U16 dxaIndent;
+
+ /**
+ * minimum space between number and paragraph
+ */
+ U16 dxaSpace;
+
+}; // ANLV
+
+bool operator==(const ANLV &lhs, const ANLV &rhs);
+bool operator!=(const ANLV &lhs, const ANLV &rhs);
+
+
+/**
+ * AutoSummary Analysis (ASUMY)
+ */
+struct ASUMY {
+ /**
+ * Creates an empty ASUMY structure and sets the defaults
+ */
+ ASUMY();
+ /**
+ * Simply calls read(...)
+ */
+ ASUMY(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the ASUMY structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * AutoSummary level
+ */
+ S32 lLevel;
+
+}; // ASUMY
+
+bool operator==(const ASUMY &lhs, const ASUMY &rhs);
+bool operator!=(const ASUMY &lhs, const ASUMY &rhs);
+
+
+/**
+ * AutoSummary Info (ASUMYI)
+ */
+struct ASUMYI {
+ /**
+ * Creates an empty ASUMYI structure and sets the defaults
+ */
+ ASUMYI();
+ /**
+ * Simply calls read(...)
+ */
+ ASUMYI(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the ASUMYI structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * true iff the ASUMYI is valid
+ */
+ U16 fValid:1;
+
+ /**
+ * true iff AutoSummary View is active
+ */
+ U16 fView:1;
+
+ /**
+ * Display method for AutoSummary View:
+ * 0 = Emphasize in current doc
+ * 1 = Reduce doc to summary
+ * 2 = Insert into doc
+ * 3 = Show in new document
+ */
+ U16 iViewBy:2;
+
+ /**
+ * true if we should update File Properties summary information after
+ * the next summarization
+ */
+ U16 fUpdateProps:1;
+
+ /**
+ * reserved
+ */
+ U16 unused0_5:11;
+
+ /**
+ * Dialog summary level
+ */
+ S16 wDlgLevel;
+
+ /**
+ * upper bound for lLevel for sentences in this document
+ */
+ S32 lHighestLevel;
+
+ /**
+ * show document sentences at or below this level
+ */
+ S32 lCurrentLevel;
+
+}; // ASUMYI
+
+bool operator==(const ASUMYI &lhs, const ASUMYI &rhs);
+bool operator!=(const ASUMYI &lhs, const ASUMYI &rhs);
+
+
+/**
+ * AnnoTation Reference Descriptor (ATRD)
+ */
+struct ATRD {
+ /**
+ * Creates an empty ATRD structure and sets the defaults
+ */
+ ATRD();
+ /**
+ * Simply calls read(...)
+ */
+ ATRD(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the ATRD structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * pascal-style string holding initials of annotation author
+ */
+ XCHAR xstUsrInitl[10];
+
+ /**
+ * index into GrpXstAtnOwners
+ */
+ S16 ibst;
+
+ /**
+ * unused
+ */
+ U16 ak:2;
+
+ /**
+ * unused
+ */
+ U16 unused22_2:14;
+
+ /**
+ * unused
+ */
+ U16 grfbmc;
+
+ /**
+ * when not -1, this tag identifies the annotation bookmark that locates
+ * the range of CPs in the main document which this annotation references.
+ */
+ S32 lTagBkmk;
+
+}; // ATRD
+
+bool operator==(const ATRD &lhs, const ATRD &rhs);
+bool operator!=(const ATRD &lhs, const ATRD &rhs);
+
+
+/**
+ * BreaK Descriptor (BKD)
+ */
+struct BKD {
+ /**
+ * Creates an empty BKD structure and sets the defaults
+ */
+ BKD();
+ /**
+ * Simply calls read(...)
+ */
+ BKD(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the BKD structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * except in textbox BKD, index to <b>PGD</b> in <b>plfpgd</b> that describes
+ * the page this break is on. in textbox BKD, <br/>
+ * Note: different behavior in textboxes! Check Version 1.9 or earlier for the "original" version (Werner)
+ */
+ S16 ipgd_itxbxs;
+
+ /**
+ * number of cp's considered for this break; note that the CP's described
+ * by cpDepend in this break reside in the next BKD
+ */
+ S16 dcpDepend;
+
+ U16 icol:8;
+
+ /**
+ * when 1, this indicates that this is a table break.
+ */
+ U16 fTableBreak:1;
+
+ /**
+ * when 1, this indicates that this is a column break.
+ */
+ U16 fColumnBreak:1;
+
+ /**
+ * used temporarily while word is running.
+ */
+ U16 fMarked:1;
+
+ /**
+ * in textbox BKD, when == 1 indicates cpLim of this textbox is not valid
+ */
+ U16 fUnk:1;
+
+ /**
+ * in textbox BKD, when == 1 indicates that text overflows the end of
+ * this textbox
+ */
+ U16 fTextOverflow:1;
+
+ U16 unused4_13:3;
+
+}; // BKD
+
+bool operator==(const BKD &lhs, const BKD &rhs);
+bool operator!=(const BKD &lhs, const BKD &rhs);
+
+
+/**
+ * BooKmark First descriptor (BKF)
+ */
+struct BKF {
+ /**
+ * Creates an empty BKF structure and sets the defaults
+ */
+ BKF();
+ /**
+ * Simply calls read(...)
+ */
+ BKF(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the BKF structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * index to <b>BKL</b> entry in <b>plcfbkl</b> that describes the ending
+ * position of this bookmark in the <b>CP</b> stream.
+ */
+ S16 ibkl;
+
+ /**
+ * when bkf.fCol is 1, this is the index to the first column of a table
+ * column bookmark.
+ */
+ U16 itcFirst:7;
+
+ /**
+ * when 1, this indicates that this bookmark is marking the range of a
+ * Macintosh Publisher section.
+ */
+ U16 fPub:1;
+
+ /**
+ * when bkf.fCol is 1, this is the index to limit column of a table column
+ * bookmark.
+ */
+ U16 itcLim:7;
+
+ /**
+ * when 1, this bookmark marks a range of columns in a table specified
+ * by [bkf.itcFirst, bkf.itcLim).
+ */
+ U16 fCol:1;
+
+}; // BKF
+
+bool operator==(const BKF &lhs, const BKF &rhs);
+bool operator!=(const BKF &lhs, const BKF &rhs);
+
+
+/**
+ * BooKmark Lim descriptor (BKL)
+ */
+struct BKL {
+ /**
+ * Creates an empty BKL structure and sets the defaults
+ */
+ BKL();
+ /**
+ * Simply calls read(...)
+ */
+ BKL(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the BKL structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * index to <b>BKF</b> entry in <b>plcfbkf</b> that describes the beginning
+ * position of this bookmark in the <b>CP</b> stream. If the bkl.ibkf is negative,
+ * add on the number of bookmarks recorded in the hplcbkf to the bkl.ibkf
+ * to calculate the index to the BKF that corresponds to this entry.
+ */
+ S16 ibkf;
+
+}; // BKL
+
+bool operator==(const BKL &lhs, const BKL &rhs);
+bool operator!=(const BKL &lhs, const BKL &rhs);
+
+
+/**
+ * Border Code for Windows Word 1.0 (BRC10)
+ */
+struct BRC10 {
+ /**
+ * Creates an empty BRC10 structure and sets the defaults
+ */
+ BRC10();
+ /**
+ * Simply calls read(...)
+ */
+ BRC10(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the BRC10 structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * width of second line of border in pixels
+ */
+ U16 dxpLine2Width:3;
+
+ /**
+ * distance to maintain between both lines of border in pixels
+ */
+ U16 dxpSpaceBetween:3;
+
+ /**
+ * width of first border line in pixels
+ */
+ U16 dxpLine1Width:3;
+
+ /**
+ * width of space to maintain between border and text within border. Must
+ * be 0 when BRC is a substructure of the TC.
+ */
+ U16 dxpSpace:5;
+
+ /**
+ * when 1, border is drawn with shadow. Must be 0 when BRC10 is a substructure
+ * of the TC.
+ */
+ U16 fShadow:1;
+
+ /**
+ * reserved
+ */
+ U16 fSpare:1;
+
+}; // BRC10
+
+bool operator==(const BRC10 &lhs, const BRC10 &rhs);
+bool operator!=(const BRC10 &lhs, const BRC10 &rhs);
+
+
+/**
+ * Bin Table Entry (BTE)
+ */
+struct BTE {
+ /**
+ * Creates an empty BTE structure and sets the defaults
+ */
+ BTE();
+ /**
+ * Simply calls read(...)
+ */
+ BTE(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the BTE structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * Page Number for FKP
+ */
+ U32 pn;
+
+}; // BTE
+
+bool operator==(const BTE &lhs, const BTE &rhs);
+bool operator!=(const BTE &lhs, const BTE &rhs);
+
+
+/**
+ * Character Properties (CHP)
+ */
+struct CHP : public Shared {
+ /**
+ * Creates an empty CHP structure and sets the defaults
+ */
+ CHP();
+ /**
+ * Simply calls read(...)
+ */
+ CHP(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the CHP structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * This method applies a grpprl with @param count elements
+ */
+ void apply(const U8 *grpprl, U16 count, const Style* style, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version);
+
+ /**
+ * This method applies a whole CHPX to the structure.
+ * The reason that we only pass a pointer to the start of the exception
+ * structure is, that we don't know the type in the FKP template :}
+ */
+ void applyExceptions(const U8* exceptions, const Style* paragraphStyle, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version);
+
+ /**
+ * This method applies one single SPRM. It returns -1 if it wasn't
+ * a CHP SPRM and it returns the length of the applied SPRM
+ * if it was successful.
+ */
+ S16 applyCHPSPRM(const U8* ptr, const Style* style, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version);
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * text is bold when 1 , and not bold when 0.
+ */
+ U8 fBold:1;
+
+ /**
+ * italic when 1, not italic when 0
+ */
+ U8 fItalic:1;
+
+ /**
+ * when 1, text has been deleted and will be displayed with strikethrough
+ * when revision marked text is to be displayed
+ */
+ U8 fRMarkDel:1;
+
+ /**
+ * outlined when 1, not outlined when 0
+ */
+ U8 fOutline:1;
+
+ /**
+ * used internally by Word
+ */
+ U8 fFldVanish:1;
+
+ /**
+ * displayed with small caps when 1, no small caps when 0
+ */
+ U8 fSmallCaps:1;
+
+ /**
+ * displayed with caps when 1, no caps when 0
+ */
+ U8 fCaps:1;
+
+ /**
+ * when 1, text has "hidden" format, and is not displayed unless fPagHidden
+ * is set in the DOP
+ */
+ U8 fVanish:1;
+
+ /**
+ * when 1, text is newly typed since the last time revision marks have
+ * been accepted and will be displayed with an underline when revision marked
+ * text is to be displayed
+ */
+ U8 fRMark:1;
+
+ /**
+ * character is a Word special character when 1, not a special character
+ * when 0
+ */
+ U8 fSpec:1;
+
+ /**
+ * displayed with strikethrough when 1, no strikethrough when 0
+ */
+ U8 fStrike:1;
+
+ /**
+ * embedded object when 1, not an embedded object when 0
+ */
+ U8 fObj:1;
+
+ /**
+ * character is drawn with a shadow when 1; drawn without shadow when
+ * 0
+ */
+ U8 fShadow:1;
+
+ /**
+ * character is displayed in lower case when 1. No case transformation
+ * is performed when 0. This field may be set to 1 only when chp.fSmallCaps
+ * is 1.
+ */
+ U8 fLowerCase:1;
+
+ /**
+ * when 1, chp.fcPic points to an FFDATA, the data structure binary data
+ * used by Word to describe a form field. The bit chp.fData may only be 1
+ * when chp.fSpec is also 1 and the special character in the document stream
+ * that has this property is a chPicture (0x01).
+ */
+ U8 fData:1;
+
+ /**
+ * when 1, chp.lTagObj specifies a particular object in the object stream
+ * that specifies the particular OLE object in the stream that should be displayed
+ * when the chPicture fSpec character that is tagged with the fOle2 is encountered.
+ * The bit chp.fOle2 may only be 1 when chp.fSpec is also 1 and the special
+ * character in the document stream that has this property is a chPicture
+ * (0x01).
+ */
+ U8 fOle2:1;
+
+ /**
+ * text is embossed when 1 and not embossed when 0
+ */
+ U16 fEmboss:1;
+
+ /**
+ * text is engraved when 1 and not engraved when 0
+ */
+ U16 fImprint:1;
+
+ /**
+ * displayed with double strikethrough when 1, no double strikethrough
+ * when 0
+ */
+ U16 fDStrike:1;
+
+ U16 fUsePgsuSettings:1;
+
+ /**
+ * Reserved
+ */
+ U16 unused2_4:12;
+
+ /**
+ * Reserved
+ */
+ S32 unused4;
+
+ /**
+ * no longer stored
+ */
+ S16 ftc;
+
+ /**
+ * (rgftc[0]) font for ASCII text
+ */
+ S16 ftcAscii;
+
+ /**
+ * (rgftc[1]) font for Far East text
+ */
+ S16 ftcFE;
+
+ /**
+ * (rgftc[2]) font for non-Far East text
+ */
+ S16 ftcOther;
+
+ /**
+ * font size in half points
+ */
+ U16 hps;
+
+ /**
+ * space following each character in the run expressed in twip units.
+ */
+ S32 dxaSpace;
+
+ /**
+ * superscript/subscript indices
+ * 0 means no super/subscripting
+ * 1 means text in run is superscripted
+ * 2 means text in run is subscripted
+ */
+ U8 iss:3;
+
+ /**
+ * underline code:
+ * 0 none
+ * 1 single
+ * 2 by word
+ * 3 double
+ * 4 dotted
+ * 5 hidden
+ * 6 thick
+ * 7 dash
+ * 8 dot (not used)
+ * 9 dot dash
+ * 10 dot dot dash
+ * 11 wave
+ */
+ U8 kul:4;
+
+ /**
+ * used by Word internally, not stored in file
+ */
+ U8 fSpecSymbol:1;
+
+ /**
+ * color of text:
+ * 0 Auto
+ * 1 Black
+ * 2 Blue
+ * 3 Cyan
+ * 4 Green
+ * 5 Magenta
+ * 6 Red
+ * 7 Yellow
+ * 8 White
+ * 9 DkBlue
+ * 10 DkCyan
+ * 11 DkGreen
+ * 12 DkMagenta
+ * 13 DkRed
+ * 14 DkYellow
+ * 15 DkGray
+ * 16 LtGray
+ */
+
+ U8 icoObsolete:5;
+
+ /**
+ * reserved
+ */
+ U8 unused23_5:1;
+
+ /**
+ * used by Word internally, not stored in file
+ */
+ U8 fSysVanish:1;
+
+ /**
+ * reserved
+ */
+ U8 hpScript:1;
+
+ /**
+ * super/subscript position in half points; positive means text is raised;
+ * negative means text is lowered.
+ */
+ S16 hpsPos;
+
+ /**
+ * foreground color, color of the text
+ */
+ U32 cv;
+
+ /**
+ * LID language identification code (no longer stored here, see rglid
+ * below):
+ * 0x0400 No Proofing
+ * 0x0401 Arabic
+ * 0x0402 Bulgarian
+ * 0x0403 Catalan
+ * 0x0404 Traditional Chinese
+ * 0x0804 Simplified Chinese
+ * 0x0405 Czech
+ * 0x0406 Danish
+ * 0x0407 German
+ * 0x0807 Swiss German
+ * 0x0408 Greek
+ * 0x0409 U.S. English
+ * 0x0809 U.K. English
+ * 0x0c09 Australian English
+ * 0x040a Castilian Spanish
+ * 0x080a Mexican Spanish
+ * 0x040b Finnish
+ * 0x040c French
+ * 0x080c Belgian French
+ * 0x0c0c Canadian French
+ * 0x100c Swiss French
+ * 0x040d Hebrew
+ * 0x040e Hungarian
+ * 0x040f Icelandic
+ * 0x0410 Italian
+ * 0x0810 Swiss Italian
+ * 0x0411 Japanese
+ * 0x0412 Korean
+ * 0x0413 Dutch
+ * 0x0813 Belgian Dutch
+ * 0x0414 Norwegian - Bokmal
+ * 0x0814 Norwegian - Nynorsk
+ * 0x0415 Polish
+ * 0x0416 Brazilian Portuguese
+ * 0x0816 Portuguese
+ * 0x0417 Rhaeto-Romanic
+ * 0x0418 Romanian
+ * 0x0419 Russian
+ * 0x041a Croato-Serbian (Latin)
+ * 0x081a Serbo-Croatian (Cyrillic)
+ * 0x041b Slovak
+ * 0x041c Albanian
+ * 0x041d Swedish
+ * 0x041e Thai
+ * 0x041f Turkish
+ * 0x0420 Urdu
+ * 0x0421 Bahasa
+ * 0x0422 Ukrainian
+ * 0x0423 Byelorussian
+ * 0x0424 Slovenian
+ * 0x0425 Estonian
+ * 0x0426 Latvian
+ * 0x0427 Lithuanian
+ * 0x0429 Farsi
+ * 0x042D Basque
+ * 0x042F Macedonian
+ * 0x0436 Afrikaans
+ * 0x043E Malaysian
+ */
+ U16 lid;
+
+ /**
+ * (rglid[0]) LID language for non-Far East text
+ */
+ U16 lidDefault;
+
+ /**
+ * (rglid[1]) LID language for Far East text
+ */
+ U16 lidFE;
+
+ /**
+ * not stored in file
+ */
+ U8 idct;
+
+ /**
+ * Identifier of Characte type
+ * 0 -> shared chars get non-FE props
+ * 1 -> shared chars get FE props
+ * (see Appendix C)
+ */
+ U8 idctHint;
+
+ U16 wCharScale;
+
+ /**
+ * (fcPic) FC offset in data stream pointing to beginning of a picture
+ * when character is a picture character (character is 0x01 and chp.fSpec
+ * is 1)
+ * <p>(fcObj) FC offset in data stream pointing to beginning of a picture
+ * when character is an OLE1 object character (character is 0x20 and chp.fSpec
+ * is 1, chp.fOle2 is 0)
+ * <p>(lTagObj) long word tag that identifies an OLE2 object in the object
+ * stream when the character is an OLE2 object character. (character is 0x01
+ * and chp.fSpec is 1, chp.fOle2 is 1)
+ */
+ S32 fcPic_fcObj_lTagObj;
+
+ /**
+ * index to author IDs stored in hsttbfRMark. used when text in run was
+ * newly typed when revision marking was enabled
+ */
+ S16 ibstRMark;
+
+ /**
+ * index to author IDs stored in hsttbfRMark. used when text in run was
+ * deleted when revision marking was enabled
+ */
+ S16 ibstRMarkDel;
+
+ /**
+ * Date/time at which this run of text was entered/modified by the author.
+ * (Only recorded when revision marking is on.)
+ */
+ DTTM dttmRMark;
+
+ /**
+ * Date/time at which this run of text was deleted by the author. (Only
+ * recorded when revision marking is on.)
+ */
+ DTTM dttmRMarkDel;
+
+ S16 unused52;
+
+ /**
+ * index to character style descriptor in the stylesheet that tags this
+ * run of text When istd is istdNormalChar (10 decimal), characters in run
+ * are not affected by a character style. If chp.istd contains any other value,
+ * chpx of the specified character style are applied to CHP for this run before
+ * any other exceptional properties are applied.
+ */
+ U16 istd;
+
+ /**
+ * when chp.fSpec is 1 and the character recorded for the run in the document
+ * stream is chSymbol (0x28), chp.ftcSym identifies the font code of the symbol
+ * font that will be used to display the symbol character recorded in chp.xchSym.
+ * chp.ftcSym is an index into the rgffn structure.
+ */
+ S16 ftcSym;
+
+ /**
+ * when chp.fSpec is 1 and the character recorded for the run in the document
+ * stream is chSymbol (0x28), the character stored chp.xchSym will be displayed
+ * using the font specified in chp.ftcSym.
+ */
+ XCHAR xchSym;
+
+ /**
+ * an index to strings displayed as reasons for actions taken by Word's
+ * AutoFormat code
+ */
+ S16 idslRMReason;
+
+ /**
+ * an index to strings displayed as reasons for actions taken by Word's
+ * AutoFormat code
+ */
+ S16 idslRMReasonDel;
+
+ /**
+ * hyphenation rule
+ * 0 No hyphenation
+ * 1 Normal hyphenation
+ * 2 Add letter before hyphen
+ * 3 Change letter before hyphen
+ * 4 Delete letter before hyphen
+ * 5 Change letter after hyphen
+ * 6 Delete letter before the hyphen and change the letter preceding the
+ * deleted character
+ */
+ U8 ysr;
+
+ /**
+ * the character that will be used to add or change a letter when chp.ysr
+ * is 2,3, 5 or 6
+ */
+ U8 chYsr;
+
+ /**
+ * extended character set id
+ * 0 characters in run should be interpreted using the ANSI set used by
+ * Windows
+ * 256 characters in run should be interpreted using the Macintosh character
+ * set.
+ */
+ U16 chse;
+
+ /**
+ * kerning distance for characters in run recorded in half points
+ */
+ U16 hpsKern;
+
+ /**
+ * highlight color (see chp.ico)
+ */
+ U16 icoHighlight:5;
+
+ /**
+ * when 1, characters are highlighted with color specified by chp.icoHighlight.
+ */
+ U16 fHighlight:1;
+
+ U16 kcd:3;
+
+ /**
+ * used internally by Word
+ */
+ U16 fNavHighlight:1;
+
+ U16 fChsDiff:1;
+
+ U16 fMacChs:1;
+
+ U16 fFtcAsciSym:1;
+
+ /**
+ * Reserved
+ */
+ U16 reserved_3:3;
+
+ /**
+ * when 1, properties have been changed with revision marking on
+ */
+ U16 fPropMark;
+
+ /**
+ * index to author IDs stored in hsttbfRMark. used when properties have
+ * been changed when revision marking was enabled
+ */
+ S16 ibstPropRMark;
+
+ /**
+ * Date/time at which properties of this were changed for this run of
+ * text by the author. (Only recorded when revision marking is on.)
+ */
+ DTTM dttmPropRMark;
+
+ /**
+ * text animation:
+ * 0 no animation
+ * 1 Las Vegas lights
+ * 2 background blink
+ * 3 sparkle text
+ * 4 marching ants
+ * 5 marchine red ants
+ * 6 shimmer
+ */
+ U8 sfxtText;
+
+ /**
+ * reserved
+ */
+ U8 unused81;
+
+ /**
+ * reserved
+ */
+ U8 unused82;
+
+ /**
+ * reserved
+ */
+ U16 unused83;
+
+ /**
+ * reserved
+ */
+ S16 unused85;
+
+ /**
+ * reserved
+ */
+ U32 unused87;
+
+ /**
+ * (Only valid for ListNum fields). When 1, the number for a ListNum field
+ * is being tracked in xstDispFldRMark -- if that number is different from
+ * the current value, the number has changed.
+ */
+ S8 fDispFldRMark;
+
+ /**
+ * Index to author IDs stored in hsttbfRMark. used when ListNum field
+ * numbering has been changed when revision marking was enabled
+ */
+ S16 ibstDispFldRMark;
+
+ /**
+ * The date for the ListNum field number change
+ */
+ U32 dttmDispFldRMark;
+
+ /**
+ * The string value of the ListNum field when revision mark tracking began
+ */
+ XCHAR xstDispFldRMark[16];
+
+ /**
+ * shading
+ */
+ SHD shd;
+
+ /**
+ * border
+ */
+ BRC brc;
+
+}; // CHP
+
+bool operator==(const CHP &lhs, const CHP &rhs);
+bool operator!=(const CHP &lhs, const CHP &rhs);
+
+
+/**
+ * Character Property Exceptions (CHPX)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct CHPX {
+// /**
+// * Creates an empty CHPX structure and sets the defaults
+// */
+// CHPX();
+// /**
+// * Simply calls read(...)
+// */
+// CHPX(OLEStreamReader *stream, bool preservePos=false);
+// /**
+// * Attention: This struct allocates memory on the heap
+// */
+// CHPX(const CHPX &rhs);
+// ~CHPX();
+
+// CHPX &operator=(const CHPX &rhs);
+
+// /**
+// * This method reads the CHPX structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * count of bytes of following data in CHPX.
+// */
+// U8 cb;
+
+// /**
+// * a list of the sprms that encode the differences between CHP for a run
+// * of text and the CHP generated by the paragraph and character styles that
+// * tag the run.
+// */
+// U8 *grpprl; // U8 grpprl[cb];
+
+//private:
+// void clearInternal();
+
+//}; // CHPX
+
+//bool operator==(const CHPX &lhs, const CHPX &rhs);
+//bool operator!=(const CHPX &lhs, const CHPX &rhs);
+
+
+/**
+ * Formatted Disk Page for CHPXs (CHPXFKP)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct CHPXFKP {
+// /**
+// * Creates an empty CHPXFKP structure and sets the defaults
+// */
+// CHPXFKP();
+// /**
+// * Simply calls read(...)
+// */
+// CHPXFKP(OLEStreamReader *stream, bool preservePos=false);
+// /**
+// * Attention: This struct allocates memory on the heap
+// */
+// CHPXFKP(const CHPXFKP &rhs);
+// ~CHPXFKP();
+
+// CHPXFKP &operator=(const CHPXFKP &rhs);
+
+// /**
+// * This method reads the CHPXFKP structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * Each <b>FC</b> is the limit <b>FC</b> of a run of exception text.
+// */
+// FC *rgfc; // FC rgfc[];
+
+// /**
+// * an array of bytes where each byte is the word offset of a<b> CHPX</b>.
+// * If the byte stored is 0, there is no difference between run's character
+// * properties and the style's character properties.
+// */
+// U8 *rgb; // U8 rgb[];
+
+// /**
+// * As new runs/paragraphs are recorded in the <b>FKP</b>, unused space
+// * is reduced by 5 if CHPX is already recorded and is reduced by 5+sizeof(CHPX)
+// * if property is not already recorded.
+// */
+// U8 *unusedSpace; // U8 unusedSpace[];
+
+// /**
+// * grpchpx consists of all of the <b>CHPX</b>s stored in <b>FKP</b> concatenated
+// * end to end. Each <b>CHPX</b> is prefixed with a count of bytes which records
+// * its length.
+// */
+// U8 *grpchpx; // U8 grpchpx[];
+
+// /**
+// * count of runs for <b>CHPX FKP,</b>
+// */
+// U8 crun;
+
+//private:
+// void clearInternal();
+
+//}; // CHPXFKP
+
+//bool operator==(const CHPXFKP &lhs, const CHPXFKP &rhs);
+//bool operator!=(const CHPXFKP &lhs, const CHPXFKP &rhs);
+
+
+/**
+ * Drop Cap Specifier(DCS)
+ */
+struct DCS {
+ /**
+ * Creates an empty DCS structure and sets the defaults
+ */
+ DCS();
+ /**
+ * Simply calls read(...)
+ */
+ DCS(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ DCS(const U8 *ptr);
+
+ /**
+ * This method reads the DCS structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * default value 0
+ * drop cap type
+ * 0 no drop cap
+ * 1 normal drop cap
+ * 2 drop cap in margin
+ */
+ U8 fdct:3;
+
+ /**
+ * default value 0
+ * count of lines to drop
+ */
+ U8 lines:5;
+
+ /**
+ * reserved
+ */
+ U8 unused1;
+
+}; // DCS
+
+bool operator==(const DCS &lhs, const DCS &rhs);
+bool operator!=(const DCS &lhs, const DCS &rhs);
+
+
+/**
+ * Drawing Object Grid (DOGRID)
+ */
+struct DOGRID {
+ /**
+ * Creates an empty DOGRID structure and sets the defaults
+ */
+ DOGRID();
+ /**
+ * Simply calls read(...)
+ */
+ DOGRID(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the DOGRID structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * x-coordinate of the upper left-hand corner of the grid
+ */
+ S16 xaGrid;
+
+ /**
+ * y-coordinate of the upper left-hand corner of the grid
+ */
+ S16 yaGrid;
+
+ /**
+ * width of each grid square
+ */
+ S16 dxaGrid;
+
+ /**
+ * height of each grid square
+ */
+ S16 dyaGrid;
+
+ /**
+ * the number of grid squares (in the y direction) between each gridline
+ * drawn on the screen. 0 means don't display any gridlines in the y direction.
+ */
+ U16 dyGridDisplay:7;
+
+ /**
+ * suppress display of gridlines
+ */
+ U16 fTurnItOff:1;
+
+ /**
+ * the number of grid squares (in the x direction) between each gridline
+ * drawn on the screen. 0 means don't display any gridlines in the y direction.
+ */
+ U16 dxGridDisplay:7;
+
+ /**
+ * if true, the grid will start at the left and top margins and ignore
+ * xaGrid and yaGrid.
+ */
+ U16 fFollowMargins:1;
+
+}; // DOGRID
+
+bool operator==(const DOGRID &lhs, const DOGRID &rhs);
+bool operator!=(const DOGRID &lhs, const DOGRID &rhs);
+
+
+/**
+ * Document Properties (DOP)
+ */
+struct DOP {
+ /**
+ * Creates an empty DOP structure and sets the defaults
+ */
+ DOP();
+ /**
+ * Simply calls read(...)
+ */
+ DOP(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the DOP structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * 1 when facing pages should be printed.
+ * Default 0.
+ */
+ U16 fFacingPages:1;
+
+ /**
+ * 1 when widow control is in effect. 0 when widow control disabled.
+ * Default 1.
+ */
+ U16 fWidowControl:1;
+
+ /**
+ * 1 when doc is a main doc for Print Merge Helper, 0 when not; default=0
+ */
+ U16 fPMHMainDoc:1;
+
+ /**
+ * Default line suppression storage; 0= form letter line suppression;
+ * 1= no line suppression; default=0. No longer used.
+ */
+ U16 grfSuppression:2;
+
+ /**
+ * footnote position code
+ * 0 print as endnotes
+ * 1 print at bottom of page
+ * 2 print immediately beneath text
+ * Default 1.
+ */
+ U16 fpc:2;
+
+ /**
+ * unused. Default 0.
+ */
+ U16 unused0_7:1;
+
+ /**
+ * No longer used. Default 0.
+ */
+ U16 grpfIhdt:8;
+
+ /**
+ * restart index for footnotes
+ * 0 don't restart note numbering
+ * 1 restart for each section
+ * 2 restart for each page
+ * Default 0.
+ */
+ U16 rncFtn:2;
+
+ /**
+ * initial footnote number for document. Default 1.
+ */
+ U16 nFtn:14;
+
+ /**
+ * when 1, indicates that information in the hplcpad should be refreshed
+ * since outline has been dirtied
+ */
+ U8 fOutlineDirtySave:1;
+
+ /**
+ * reserved
+ */
+ U8 unused4_1:7;
+
+ /**
+ * when 1, Word believes all pictures recorded in the document were created
+ * on a Macintosh
+ */
+ U8 fOnlyMacPics:1;
+
+ /**
+ * when 1, Word believes all pictures recorded in the document were created
+ * in Windows
+ */
+ U8 fOnlyWinPics:1;
+
+ /**
+ * when 1, document was created as a print merge labels document
+ */
+ U8 fLabelDoc:1;
+
+ /**
+ * when 1, Word is allowed to hyphenate words that are capitalized. When
+ * 0, capitalized may not be hyphenated
+ */
+ U8 fHyphCapitals:1;
+
+ /**
+ * when 1, Word will hyphenate newly typed text as a background task
+ */
+ U8 fAutoHyphen:1;
+
+ U8 fFormNoFields:1;
+
+ /**
+ * when 1, Word will merge styles from its template
+ */
+ U8 fLinkStyles:1;
+
+ /**
+ * when 1, Word will mark revisions as the document is edited
+ */
+ U8 fRevMarking:1;
+
+ /**
+ * always make backup when document saved when 1.
+ */
+ U8 fBackup:1;
+
+ /**
+ * when 1, the results of the last Word Count execution (as recorded in
+ * several DOP fields) are still exactly correct.
+ */
+ U8 fExactCWords:1;
+
+ /**
+ * when 1, hidden document contents are displayed.
+ */
+ U8 fPagHidden:1;
+
+ /**
+ * when 1, field results are displayed, when 0 field codes are displayed.
+ */
+ U8 fPagResults:1;
+
+ /**
+ * when 1, annotations are locked for editing
+ */
+ U8 fLockAtn:1;
+
+ /**
+ * swap margins on left/right pages when 1.
+ */
+ U8 fMirrorMargins:1;
+
+ /**
+ * reserved
+ */
+ U8 unused6_6:1;
+
+ /**
+ * when 1, use TrueType fonts by default (flag obeyed only when doc was
+ * created by WinWord 2.x)
+ */
+ U8 fDfltTrueType:1;
+
+ /**
+ * when 1, file created with SUPPRESSTOPSPACING=YES in win.ini. (flag
+ * obeyed only when doc was created by WinWord 2.x).
+ */
+ U8 fPagSuppressTopSpacing:1;
+
+ /**
+ * when 1, document is protected from edit operations
+ */
+ U8 fProtEnabled:1;
+
+ /**
+ * when 1, restrict selections to occur only within form fields
+ */
+ U8 fDispFormFldSel:1;
+
+ /**
+ * when 1, show revision markings on screen
+ */
+ U8 fRMView:1;
+
+ /**
+ * when 1, print revision marks when document is printed
+ */
+ U8 fRMPrint:1;
+
+ /**
+ * reserved
+ */
+ U8 unused7_5:1;
+
+ /**
+ * when 1, the current revision marking state is locked
+ */
+ U8 fLockRev:1;
+
+ /**
+ * when 1, document contains embedded TrueType fonts
+ */
+ U8 fEmbedFonts:1;
+
+ /**
+ * compatibility option: when 1, don't add automatic tab stops for hanging
+ * indent
+ */
+ U16 copts_fNoTabForInd:1;
+
+ /**
+ * compatibility option: when 1, don't add extra space for raised or lowered
+ * characters
+ */
+ U16 copts_fNoSpaceRaiseLower:1;
+
+ /**
+ * compatibility option: when 1, suppress the paragraph Space Before and
+ * Space After options after a page break
+ */
+ U16 copts_fSuppressSpbfAfterPageBreak:1;
+
+ /**
+ * compatibility option: when 1, wrap trailing spaces at the end of a
+ * line to the next line
+ */
+ U16 copts_fWrapTrailSpaces:1;
+
+ /**
+ * compatibility option: when 1, print colors as black on non-color printers
+ */
+ U16 copts_fMapPrintTextColor:1;
+
+ /**
+ * compatibility option: when 1, don't balance columns for Continuous
+ * Section starts
+ */
+ U16 copts_fNoColumnBalance:1;
+
+ U16 copts_fConvMailMergeEsc:1;
+
+ /**
+ * compatibility option: when 1, suppress extra line spacing at top of
+ * page
+ */
+ U16 copts_fSupressTopSpacing:1;
+
+ /**
+ * compatibility option: when 1, combine table borders like Word 5.x for
+ * the Macintosh
+ */
+ U16 copts_fOrigWordTableRules:1;
+
+ /**
+ * compatibility option: when 1, don't blank area between metafile pictures
+ */
+ U16 copts_fTransparentMetafiles:1;
+
+ /**
+ * compatibility option: when 1, show hard page or column breaks in frames
+ */
+ U16 copts_fShowBreaksInFrames:1;
+
+ /**
+ * compatibility option: when 1, swap left and right pages on odd facing
+ * pages
+ */
+ U16 copts_fSwapBordersFacingPgs:1;
+
+ /**
+ * reserved
+ */
+ U16 unused8_12:4;
+
+ /**
+ * default tab width. Default 720 twips.
+ */
+ U16 dxaTab;
+
+ U16 wSpare;
+
+ /**
+ * width of hyphenation hot zone measured in twips
+ */
+ U16 dxaHotZ;
+
+ /**
+ * number of lines allowed to have consecutive hyphens
+ */
+ U16 cConsecHypLim;
+
+ /**
+ * reserved
+ */
+ U16 wSpare2;
+
+ /**
+ * date and time document was created
+ */
+ DTTM dttmCreated;
+
+ /**
+ * date and time document was last revised
+ */
+ DTTM dttmRevised;
+
+ /**
+ * date and time document was last printed
+ */
+ DTTM dttmLastPrint;
+
+ /**
+ * number of times document has been revised since its creation
+ */
+ S16 nRevision;
+
+ /**
+ * time document was last edited
+ */
+ S32 tmEdited;
+
+ /**
+ * count of words tallied by last Word Count execution
+ */
+ S32 cWords;
+
+ /**
+ * count of characters tallied by last Word Count execution
+ */
+ S32 cCh;
+
+ /**
+ * count of pages tallied by last Word Count execution
+ */
+ S16 cPg;
+
+ /**
+ * count of paragraphs tallied by last Word Count execution
+ */
+ S32 cParas;
+
+ /**
+ * restart endnote number code
+ * 0 don't restart endnote numbering
+ * 1 restart for each section
+ * 2 restart for each page
+ */
+ U16 rncEdn:2;
+
+ /**
+ * beginning endnote number
+ */
+ U16 nEdn:14;
+
+ /**
+ * endnote position code
+ * 0 display endnotes at end of section
+ * 3 display endnotes at end of document
+ */
+ U16 epc:2;
+
+ /**
+ * number format code for auto footnotes
+ * 0 Arabic
+ * 1 Upper case Roman
+ * 2 Lower case Roman
+ * 3 Upper case Letter
+ * 4 Lower case Letter
+ * [This field is obsoleted by nfcFtnRef2 at 0x1ec (Werner)]
+ */
+ U16 nfcFtnRef:4;
+
+ /**
+ * number format code for auto endnotes
+ * 0 Arabic
+ * 1 Upper case Roman
+ * 2 Lower case Roman
+ * 3 Upper case Letter
+ * 4 Lower case Letter
+ * [This field is obsoleted by nfcEdnRef2 at 0x1ee (Werner)]
+ */
+ U16 nfcEdnRef:4;
+
+ /**
+ * only print data inside of form fields
+ */
+ U16 fPrintFormData:1;
+
+ /**
+ * only save document data that is inside of a form field.
+ */
+ U16 fSaveFormData:1;
+
+ /**
+ * shade form fields
+ */
+ U16 fShadeFormData:1;
+
+ /**
+ * reserved
+ */
+ U16 unused54_13:2;
+
+ /**
+ * when 1, include footnotes and endnotes in word count
+ */
+ U16 fWCFtnEdn:1;
+
+ /**
+ * count of lines tallied by last Word Count operation
+ */
+ S32 cLines;
+
+ /**
+ * count of words in footnotes and endnotes tallied by last Word Count
+ * operation
+ */
+ S32 cWordsFtnEnd;
+
+ /**
+ * count of characters in footnotes and endnotes tallied by last Word
+ * Count operation
+ */
+ S32 cChFtnEdn;
+
+ /**
+ * count of pages in footnotes and endnotes tallied by last Word Count
+ * operation
+ */
+ S16 cPgFtnEdn;
+
+ /**
+ * count of paragraphs in footnotes and endnotes tallied by last Word
+ * Count operation
+ */
+ S32 cParasFtnEdn;
+
+ /**
+ * count of paragraphs in footnotes and endnotes tallied by last Word
+ * Count operation
+ */
+ S32 cLinesFtnEdn;
+
+ /**
+ * document protection password key, only valid if dop.fProtEnabled, dop.fLockAtn
+ * or dop.fLockRev are 1.
+ */
+ S32 lKeyProtDoc;
+
+ /**
+ * document view kind
+ * 0 Normal view
+ * 1 Outline view
+ * 2 Page View
+ */
+ U16 wvkSaved:3;
+
+ /**
+ * zoom percentage
+ */
+ U16 wScaleSaved:9;
+
+ /**
+ * zoom type
+ * 0 None
+ * 1 Full page
+ * 2 Page width
+ */
+ U16 zkSaved:2;
+
+ /**
+ * This is a vertical document (Word 6/95 only)
+ */
+ U16 fRotateFontW6:1;
+
+ /**
+ * Gutter position for this doc: 0 => side; 1 => top.
+ */
+ U16 iGutterPos:1;
+
+ /**
+ * (see above)
+ */
+ U32 fNoTabForInd:1;
+
+ /**
+ * (see above)
+ */
+ U32 fNoSpaceRaiseLower:1;
+
+ /**
+ * (see above)
+ */
+ U32 fSupressSpbfAfterPageBreak:1;
+
+ /**
+ * (see above)
+ */
+ U32 fWrapTrailSpaces:1;
+
+ /**
+ * (see above)
+ */
+ U32 fMapPrintTextColor:1;
+
+ /**
+ * (see above)
+ */
+ U32 fNoColumnBalance:1;
+
+ /**
+ * (see above)
+ */
+ U32 fConvMailMergeEsc:1;
+
+ /**
+ * (see above)
+ */
+ U32 fSupressTopSpacing:1;
+
+ /**
+ * (see above)
+ */
+ U32 fOrigWordTableRules:1;
+
+ /**
+ * (see above)
+ */
+ U32 fTransparentMetafiles:1;
+
+ /**
+ * (see above)
+ */
+ U32 fShowBreaksInFrames:1;
+
+ /**
+ * (see above)
+ */
+ U32 fSwapBordersFacingPgs:1;
+
+ /**
+ * (reserved)
+ */
+ U32 unused84_12:4;
+
+ /**
+ * Suppress extra line spacing at top of page like MacWord5.x
+ */
+ U32 fSuppressTopSpacingMac5:1;
+
+ /**
+ * Expand/Condense by whole number of points.
+ */
+ U32 fTruncDxaExpand:1;
+
+ /**
+ * Print body text before header/footer
+ */
+ U32 fPrintBodyBeforeHdr:1;
+
+ /**
+ * Don't add leading (extra space) between rows of text
+ */
+ U32 fNoLeading:1;
+
+ /**
+ * (reserved)
+ */
+ U32 unused84_20:1;
+
+ /**
+ * Use larger small caps like MacWord 5.x
+ */
+ U32 fMWSmallCaps:1;
+
+ /**
+ * (reserved)
+ */
+ U32 unused84_22:10;
+
+ /**
+ * Autoformat Document Type: 0 for normal. 1 for letter, and 2 for email.
+ */
+ U16 adt;
+
+ /**
+ * see DOPTYPOGRAPHY
+ */
+ DOPTYPOGRAPHY doptypography;
+
+ /**
+ * see DOGRID
+ */
+ DOGRID dogrid;
+
+ /**
+ * Always set to zero when writing files
+ */
+ U16 reserved:1;
+
+ /**
+ * Which outline levels are showing in outline view (0 => heading 1 only,
+ * 4 => headings 1 through 5, 9 => all levels showing)
+ */
+ U16 lvl:4;
+
+ /**
+ * Doc has been completely grammar checked
+ */
+ U16 fGramAllDone:1;
+
+ /**
+ * No grammer errors exist in doc
+ */
+ U16 fGramAllClean:1;
+
+ /**
+ * if you are doing font embedding, you should only embed the characters
+ * in the font that are used in the document
+ */
+ U16 fSubsetFonts:1;
+
+ /**
+ * Hide the version created for autoversion
+ */
+ U16 fHideLastVersion:1;
+
+ /**
+ * This file is based upon an HTML file
+ */
+ U16 fHtmlDoc:1;
+
+ /**
+ * Always set to zero when writing files
+ */
+ U16 unused410_11:1;
+
+ /**
+ * Snap table and page borders to page border
+ */
+ U16 fSnapBorder:1;
+
+ /**
+ * Place header inside page border
+ */
+ U16 fIncludeHeader:1;
+
+ /**
+ * Place footer inside page border
+ */
+ U16 fIncludeFooter:1;
+
+ /**
+ * Are we in online view
+ */
+ U16 fForcePageSizePag:1;
+
+ /**
+ * Are we auto-promoting fonts to >= hpsZoonFontPag?
+ */
+ U16 fMinFontSizePag:1;
+
+ /**
+ * versioning is turned on
+ */
+ U16 fHaveVersions:1;
+
+ /**
+ * autoversioning is enabled
+ */
+ U16 fAutoVersion:1;
+
+ /**
+ * Always set to zero when writing files
+ */
+ U16 unused412_2:14;
+
+ /**
+ * Autosummary info
+ */
+ ASUMYI asumyi;
+
+ /**
+ * Count of characters with spaces
+ */
+ S32 cChWS;
+
+ /**
+ * Count of characters with spaces in footnotes and endnotes
+ */
+ S32 cChWSFtnEdn;
+
+ S32 grfDocEvents;
+
+ /**
+ * Have we prompted for virus protection on this doc?
+ */
+ U32 fVirusPrompted:1;
+
+ /**
+ * If prompted, load safely for this doc?
+ */
+ U32 fVirusLoadSafe:1;
+
+ /**
+ * Random session key to sign above bits for a Word session.
+ */
+ U32 KeyVirusSession30:30;
+
+ /**
+ * Spare
+ */
+ U8 Spare[30];
+
+ /**
+ * Always set to zero when writing files
+ */
+ U32 unused472;
+
+ /**
+ * Always set to zero when writing files
+ */
+ U32 unused476;
+
+ /**
+ * Count of double byte characters
+ */
+ S32 cDBC;
+
+ /**
+ * Count od double byte characters in footnotes and endnotes
+ */
+ S32 cDBCFtnEdn;
+
+ /**
+ * Always set to zero when writing files
+ */
+ U32 unused488;
+
+ /**
+ * number format code for auto footnote references
+ * 0 Arabic
+ * 1 Upper case Roman
+ * 2 Lower case Roman
+ * 3 Upper case Letter
+ * 4 Lower case Letter
+ */
+ S16 nfcFtnRef2;
+
+ /**
+ * number format code for auto endnote references
+ * 0 Arabic
+ * <div CLASS="tt">1 Upper case Roman</div>
+ * 2 Lower case Roman
+ * 3 Upper case Letter
+ * 4 Lower case Letter
+ */
+ S16 nfcEdnRef2;
+
+ /**
+ * minimum font size if fMinFontSizePag is true
+ */
+ S16 hpsZoonFontPag;
+
+ /**
+ * height of the window in online view during last repag
+ */
+ S16 dywDispPag;
+
+}; // DOP
+
+bool operator==(const DOP &lhs, const DOP &rhs);
+bool operator!=(const DOP &lhs, const DOP &rhs);
+
+
+/**
+ * Font Family Name (FFN)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct FFN {
+// /**
+// * Creates an empty FFN structure and sets the defaults
+// */
+// FFN();
+// /**
+// * Simply calls read(...)
+// */
+// FFN(OLEStreamReader *stream, bool preservePos=false);
+// /**
+// * Attention: This struct allocates memory on the heap
+// */
+// FFN(const FFN &rhs);
+// ~FFN();
+
+// FFN &operator=(const FFN &rhs);
+
+// /**
+// * This method reads the FFN structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * total length of FFN - 1.
+// */
+// U8 cbFfnM1;
+
+// /**
+// * pitch request
+// */
+// U8 prq:2;
+
+// /**
+// * when 1, font is a TrueType font
+// */
+// U8 fTrueType:1;
+
+// /**
+// * reserved
+// */
+// U8 unused1_3:1;
+
+// /**
+// * font family id
+// */
+// U8 ff:3;
+
+// /**
+// * reserved
+// */
+// U8 unused1_7:1;
+
+// /**
+// * base weight of font
+// */
+// S16 wWeight;
+
+// /**
+// * character set identifier
+// */
+// U8 chs;
+
+// /**
+// * index into ffn.szFfn to the name of the alternate font
+// */
+// U8 ixchSzAlt;
+
+// /**
+// * ? This is supposed to be of type PANOSE.
+// */
+// U8 panose[10];
+
+// /**
+// * ? This is supposed to be of type FONTSIGNATURE.
+// */
+// U8 fs[24];
+
+// /**
+// * zero terminated string that records name of font. Possibly followed
+// * by a second xsz which records the name of an alternate font to use if the
+// * first named font does not exist on this system. Maximal size of xszFfn
+// * is 65 characters.
+// */
+// U8 *xszFfn; // U8 xszFfn[];
+
+//private:
+// void clearInternal();
+
+//}; // FFN
+
+//bool operator==(const FFN &lhs, const FFN &rhs);
+//bool operator!=(const FFN &lhs, const FFN &rhs);
+
+
+/**
+ * File Information Block (FIB)
+ */
+struct FIB {
+ /**
+ * Creates an empty FIB structure and sets the defaults
+ */
+ FIB();
+ /**
+ * Simply calls read(...)
+ */
+ FIB(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the FIB structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * (fibh) FIBH Beginning of the FIB header magic number
+ */
+ U16 wIdent;
+
+ /**
+ * FIB version written. This will be >= 101 for all Word 6.0 for Windows
+ * and after documents.
+ */
+ U16 nFib;
+
+ /**
+ * product version written by
+ */
+ U16 nProduct;
+
+ /**
+ * language stamp -- localized version
+ * In pre-WinWord 2.0 files this value was the nLocale. If value is &lt;
+ * 999, then it is the nLocale, otherwise it is the lid.
+ */
+ U16 lid;
+
+ S16 pnNext;
+
+ /**
+ * Set if this document is a template
+ */
+ U16 fDot:1;
+
+ /**
+ * Set if this document is a glossary
+ */
+ U16 fGlsy:1;
+
+ /**
+ * when 1, file is in <b>complex, fast-saved format.</b>
+ */
+ U16 fComplex:1;
+
+ /**
+ * set if file contains 1 or more pictures
+ */
+ U16 fHasPic:1;
+
+ /**
+ * count of times file was quicksaved
+ */
+ U16 cQuickSaves:4;
+
+ /**
+ * Set if file is encrypted
+ */
+ U16 fEncrypted:1;
+
+ /**
+ * When 0, this fib refers to the table stream named "0Table", when 1,
+ * this fib refers to the table stream named "1Table". Normally, a file will
+ * have only one table stream, but under unusual circumstances a file may
+ * have table streams with both names. In that case, this flag must be used
+ * to decide which table stream is valid.
+ */
+ U16 fWhichTblStm:1;
+
+ /**
+ * Set when user has recommended that file be read read-only
+ */
+ U16 fReadOnlyRecommended:1;
+
+ /**
+ * Set when file owner has made the file write reserved
+ */
+ U16 fWriteReservation:1;
+
+ /**
+ * Set when using extended character set in file
+ */
+ U16 fExtChar:1;
+
+ /**
+ * REVIEW
+ */
+ U16 fLoadOverride:1;
+
+ /**
+ * REVIEW
+ */
+ U16 fFarEast:1;
+
+ /**
+ * REVIEW
+ */
+ U16 fCrypto:1;
+
+ /**
+ * This file format it compatible with readers that understand nFib at
+ * or above this value.
+ */
+ U16 nFibBack;
+
+ /**
+ * File encrypted key, only valid if fEncrypted.
+ */
+ U32 lKey;
+
+ /**
+ * environment in which file was created
+ * 0 created by Win Word
+ * 1 created by Mac Word
+ */
+ U8 envr;
+
+ /**
+ * when 1, this file was last saved in the Mac environment
+ */
+ U8 fMac:1;
+
+ U8 fEmptySpecial:1;
+
+ U8 fLoadOverridePage:1;
+
+ U8 fFutureSavedUndo:1;
+
+ U8 fWord97Saved:1;
+
+ U8 fSpare0:3;
+
+ /**
+ * Default extended character set id for text in document stream. (overridden
+ * by chp.chse)
+ * 0 by default characters in doc stream should be interpreted using the
+ * ANSI character set used by Windows
+ * 256 characters in doc stream should be interpreted using the Macintosh
+ * character set.
+ */
+ U16 chs;
+
+ /**
+ * Default extended character set id for text in internal data structures
+ * 0 by default characters stored in internal data structures should be
+ * interpreted using the ANSI character set used by Windows
+ * 256 characters stored in internal data structures should be interpreted
+ * using the Macintosh character set.
+ */
+ U16 chsTables;
+
+ /**
+ * file offset of first character of text. In <b>non-complex files</b>
+ * a <b>CP</b> can be transformed into an <b>FC</b> by the following transformation:
+ * fc = cp + fib.fcMin.
+ */
+ U32 fcMin;
+
+ /**
+ * file offset of last character of text in document text stream + 1
+ */
+ U32 fcMac;
+
+ /**
+ * Count of fields in the array of "shorts"
+ */
+ U16 csw;
+
+ /**
+ * [Beginning of the array of shorts, rgls]
+ * Unique number Identifying the File's creator 0x6A62 is the creator
+ * ID for Word and is reserved. Other creators should choose a different value.
+ */
+ U16 wMagicCreated;
+
+ /**
+ * identifies the File's last modifier
+ */
+ U16 wMagicRevised;
+
+ /**
+ * private data
+ */
+ U16 wMagicCreatedPrivate;
+
+ /**
+ * private data
+ */
+ U16 wMagicRevisedPrivate;
+
+ /**
+ * not used
+ */
+ U16 pnFbpChpFirst_W6;
+
+ /**
+ * not used
+ */
+ U16 pnChpFirst_W6;
+
+ /**
+ * not used
+ */
+ U16 cpnBteChp_W6;
+
+ /**
+ * not used
+ */
+ U16 pnFbpPapFirst_W6;
+
+ /**
+ * not used
+ */
+ U16 pnPapFirst_W6;
+
+ /**
+ * not used
+ */
+ U16 cpnBtePap_W6;
+
+ /**
+ * not used
+ */
+ U16 pnFbpLvcFirst_W6;
+
+ /**
+ * not used
+ */
+ U16 pnLvcFirst_W6;
+
+ /**
+ * not used
+ */
+ U16 cpnBteLvc_W6;
+
+ /**
+ * Language id if document was written by Far East version of Word (i.e.
+ * FIB.fFarEast is on)
+ */
+ S16 lidFE;
+
+ /**
+ * Number of fields in the array of longs
+ */
+ U16 clw;
+
+ /**
+ * [Beginning of the array of longs, rglw]
+ * file offset of last byte written to file + 1.
+ */
+ U32 cbMac;
+
+ /**
+ * contains the build date of the creator. 10695 indicates the creator
+ * program was compiled on Jan 6, 1995
+ */
+ U32 lProductCreated;
+
+ /**
+ * contains the build date of the File's last modifier
+ */
+ U32 lProductRevised;
+
+ /**
+ * length of main document text stream
+ */
+ U32 ccpText;
+
+ /**
+ * length of footnote subdocument text stream
+ */
+ U32 ccpFtn;
+
+ /**
+ * length of header subdocument text stream
+ */
+ U32 ccpHdd;
+
+ /**
+ * length of macro subdocument text stream, which should now always be
+ * 0.
+ */
+ U32 ccpMcr;
+
+ /**
+ * length of annotation subdocument text stream
+ */
+ U32 ccpAtn;
+
+ /**
+ * length of endnote subdocument text stream
+ */
+ U32 ccpEdn;
+
+ /**
+ * length of textbox subdocument text stream
+ */
+ U32 ccpTxbx;
+
+ /**
+ * length of header textbox subdocument text stream.
+ */
+ U32 ccpHdrTxbx;
+
+ /**
+ * when there was insufficient memory for Word to expand the plcfbte at
+ * save time, the plcfbte is written to the file in a linked list of 512-byte
+ * pieces starting with this pn
+ */
+ U32 pnFbpChpFirst;
+
+ /**
+ * the page number of the lowest numbered page in the document that records
+ * CHPX FKP information
+ */
+ U32 pnChpFirst;
+
+ /**
+ * count of CHPX FKPs recorded in file. In non-complex files if the number
+ * of entries in the plcfbteChpx is less than this, the plcfbteChpx is incomplete.
+ */
+ U32 cpnBteChp;
+
+ /**
+ * when there was insufficient memory for Word to expand the plcfbte at
+ * save time, the plcfbte is written to the file in a linked list of 512-byte
+ * pieces starting with this pn
+ */
+ U32 pnFbpPapFirst;
+
+ /**
+ * the page number of the lowest numbered page in the document that records
+ * PAPX FKP information
+ */
+ U32 pnPapFirst;
+
+ /**
+ * count of PAPX FKPs recorded in file. In non-complex files if the number
+ * of entries in the plcfbtePapx is less than this, the plcfbtePapx is incomplete.
+ */
+ U32 cpnBtePap;
+
+ /**
+ * when there was insufficient memory for Word to expand the plcfbte at
+ * save time, the plcfbte is written to the file in a linked list of 512-byte
+ * pieces starting with this pn
+ */
+ U32 pnFbpLvcFirst;
+
+ /**
+ * the page number of the lowest numbered page in the document that records
+ * LVC FKP information
+ */
+ U32 pnLvcFirst;
+
+ /**
+ * count of LVC FKPs recorded in file. In non-complex files if the number
+ * of entries in the plcfbtePapx is less than this, the plcfbtePapx is incomplete.
+ */
+ U32 cpnBteLvc;
+
+ U32 fcIslandFirst;
+
+ U32 fcIslandLim;
+
+ /**
+ * Number of fields in the array of FC/LCB pairs.
+ */
+ U16 cfclcb;
+
+ /**
+ * [Beginning of array of FC/LCB pairs, rgfclcb]
+ * file offset of original allocation for STSH in table stream. During
+ * fast save Word will attempt to reuse this allocation if STSH is small enough
+ * to fit.
+ */
+ U32 fcStshfOrig;
+
+ /**
+ * count of bytes of original STSH allocation
+ */
+ U32 lcbStshfOrig;
+
+ /**
+ * offset of STSH in table stream.
+ */
+ U32 fcStshf;
+
+ /**
+ * count of bytes of current STSH allocation
+ */
+ U32 lcbStshf;
+
+ /**
+ * offset in table stream of footnote reference PLCF of FRD structures.
+ * CPs in PLC are relative to main document text stream and give location
+ * of footnote references.
+ */
+ U32 fcPlcffndRef;
+
+ /**
+ * count of bytes of footnote reference PLC== 0 if no footnotes defined
+ * in document.
+ */
+ U32 lcbPlcffndRef;
+
+ /**
+ * offset in table stream of footnote text PLC. CPs in PLC are relative
+ * to footnote subdocument text stream and give location of beginnings of
+ * footnote text for corresponding references recorded in plcffndRef. No structure
+ * is stored in this plc. There will just be <b>n+1</b> <b>FC</b> entries
+ * in this PLC when there are <b>n</b> footnotes
+ */
+ U32 fcPlcffndTxt;
+
+ /**
+ * count of bytes of footnote text PLC. == 0 if no footnotes defined in
+ * document
+ */
+ U32 lcbPlcffndTxt;
+
+ /**
+ * offset in table stream of annotation reference ATRD PLC. The CPs recorded
+ * in this PLC give the offset of annotation references in the main document.
+ */
+ U32 fcPlcfandRef;
+
+ /**
+ * count of bytes of annotation reference PLC.
+ */
+ U32 lcbPlcfandRef;
+
+ /**
+ * offset in table stream of annotation text PLC. The Cps recorded in
+ * this PLC give the offset of the annotation text in the annotation sub document
+ * corresponding to the references stored in the plcfandRef. There is a 1
+ * to 1 correspondence between entries recorded in the plcfandTxt and the
+ * plcfandRef. No structure is stored in this PLC.
+ */
+ U32 fcPlcfandTxt;
+
+ /**
+ * count of bytes of the annotation text PLC
+ */
+ U32 lcbPlcfandTxt;
+
+ /**
+ * offset in table stream of section descriptor SED PLC. CPs in PLC are
+ * relative to main document.
+ */
+ U32 fcPlcfsed;
+
+ /**
+ * count of bytes of section descriptor PLC.
+ */
+ U32 lcbPlcfsed;
+
+ /**
+ * no longer used
+ */
+ U32 fcPlcfpad;
+
+ /**
+ * no longer used
+ */
+ U32 lcbPlcfpad;
+
+ /**
+ * offset in table stream of PHE PLC of paragraph heights. CPs in PLC
+ * are relative to main document text stream. Only written for files in <b>complex</b>
+ * format. Should not be written by third party creators of Word files.
+ */
+ U32 fcPlcfphe;
+
+ /**
+ * count of bytes of paragraph height PLC. ==0 when file is
+ * <b>non-complex</b>.
+ */
+ U32 lcbPlcfphe;
+
+ /**
+ * offset in table stream of glossary string table. This table consists
+ * of Pascal style strings (strings stored prefixed with a length byte) concatenated
+ * one after another.
+ */
+ U32 fcSttbfglsy;
+
+ /**
+ * count of bytes of glossary string table. == 0 for non-glossary documents.!=0
+ * for glossary documents.
+ */
+ U32 lcbSttbfglsy;
+
+ /**
+ * offset in table stream of glossary PLC. CPs in PLC are relative to
+ * main document and mark the beginnings of glossary entries and are in 1-1
+ * correspondence with entries of sttbfglsy. No structure is stored in this
+ * PLC. There will be <b>n+1</b> <b>FC</b> entries in this PLC when there
+ * are <b>n</b> glossary entries.
+ */
+ U32 fcPlcfglsy;
+
+ /**
+ * count of bytes of glossary PLC.== 0 for non-glossary documents.!=0
+ * for glossary documents.
+ */
+ U32 lcbPlcfglsy;
+
+ /**
+ * byte offset in table stream of header HDD PLC. CPs are relative to
+ * header subdocument and mark the beginnings of individual headers in the
+ * header subdocument. No structure is stored in this PLC. There will be <b>n+1FC</b>
+ * entries in this PLC when there are <b>n</b> headers stored for the document.
+ */
+ U32 fcPlcfhdd;
+
+ /**
+ * count of bytes of header PLC.
+ * == 0 if document contains no headers
+ */
+ U32 lcbPlcfhdd;
+
+ /**
+ * offset in table stream of character property bin table.PLC. FCs in
+ * PLC are file offsets in the main stream. Describes text of main document
+ * and all subdocuments.
+ */
+ U32 fcPlcfbteChpx;
+
+ /**
+ * count of bytes of character property bin table PLC.
+ */
+ U32 lcbPlcfbteChpx;
+
+ /**
+ * offset in table stream of paragraph property bin table.PLC. FCs in
+ * PLC are file offsets in the main stream. Describes text of main document
+ * and all subdocuments.
+ */
+ U32 fcPlcfbtePapx;
+
+ /**
+ * count of bytes of paragraph property bin table PLC
+ */
+ U32 lcbPlcfbtePapx;
+
+ /**
+ * offset in table stream of PLC reserved for private use. The <b>SEA</b>
+ * is 6 bytes long.
+ */
+ U32 fcPlcfsea;
+
+ /**
+ * count of bytes of private use PLC.
+ */
+ U32 lcbPlcfsea;
+
+ /**
+ * offset in table stream of font information STTBF. The sttbfffn is a
+ * STTBF where is string is actually an FFN structure. The <b>n</b>th entry
+ * in the STTBF describes the font that will be displayed when the chp.ftc
+ * for text is equal to <b>n.</b> See the FFN file structure definition.
+ */
+ U32 fcSttbfffn;
+
+ /**
+ * count of bytes in sttbfffn.
+ */
+ U32 lcbSttbfffn;
+
+ /**
+ * offset in table stream to the FLD PLC of field positions in the main
+ * document. The CPs point to the beginning CP of a field, the CP of field
+ * separator character inside a field and the ending CP of the field. A field
+ * may be nested within another field. 20 levels of field nesting are allowed.
+ */
+ U32 fcPlcffldMom;
+
+ /**
+ * count of bytes in plcffldMom
+ */
+ U32 lcbPlcffldMom;
+
+ /**
+ * offset in table stream to the FLD PLC of field positions in the header
+ * subdocument.
+ */
+ U32 fcPlcffldHdr;
+
+ /**
+ * count of bytes in plcffldHdr
+ */
+ U32 lcbPlcffldHdr;
+
+ /**
+ * offset in table stream to the FLD PLC of field positions in the footnote
+ * subdocument.
+ */
+ U32 fcPlcffldFtn;
+
+ /**
+ * count of bytes in plcffldFtn
+ */
+ U32 lcbPlcffldFtn;
+
+ /**
+ * offset in table stream to the FLD PLC of field positions in the annotation
+ * subdocument.
+ */
+ U32 fcPlcffldAtn;
+
+ /**
+ * count of bytes in plcffldAtn
+ */
+ U32 lcbPlcffldAtn;
+
+ /**
+ * no longer used
+ */
+ U32 fcPlcffldMcr;
+
+ /**
+ * no longer used
+ */
+ U32 lcbPlcffldMcr;
+
+ /**
+ * offset in table stream of the STTBF that records bookmark names in
+ * the main document
+ */
+ U32 fcSttbfbkmk;
+
+ U32 lcbSttbfbkmk;
+
+ /**
+ * offset in table stream of the PLCF that records the beginning CP offsets
+ * of bookmarks in the main document. See BKF structure definition
+ */
+ U32 fcPlcfbkf;
+
+ U32 lcbPlcfbkf;
+
+ /**
+ * offset in table stream of the PLCF that records the ending CP offsets
+ * of bookmarks recorded in the main document. No structure is stored in this
+ * PLCF.
+ */
+ U32 fcPlcfbkl;
+
+ U32 lcbPlcfbkl;
+
+ /**
+ * offset in table stream of the macro commands. These commands are private
+ * and undocumented.
+ */
+ U32 fcCmds;
+
+ /**
+ * undocument size of undocument structure not documented above
+ */
+ U32 lcbCmds;
+
+ /**
+ * no longer used
+ */
+ U32 fcPlcmcr;
+
+ U32 lcbPlcmcr;
+
+ /**
+ * no longer used
+ */
+ U32 fcSttbfmcr;
+
+ U32 lcbSttbfmcr;
+
+ /**
+ * offset in table stream of the printer driver information (names of
+ * drivers, port, etc.)
+ */
+ U32 fcPrDrvr;
+
+ /**
+ * count of bytes of the printer driver information (names of drivers,
+ * port, etc.)
+ */
+ U32 lcbPrDrvr;
+
+ /**
+ * offset in table stream of the print environment in portrait mode.
+ */
+ U32 fcPrEnvPort;
+
+ /**
+ * count of bytes of the print environment in portrait mode.
+ */
+ U32 lcbPrEnvPort;
+
+ /**
+ * offset in table stream of the print environment in landscape mode.
+ */
+ U32 fcPrEnvLand;
+
+ /**
+ * count of bytes of the print environment in landscape mode.
+ */
+ U32 lcbPrEnvLand;
+
+ /**
+ * offset in table stream of <b>W</b>indow <b>S</b>ave <b>S</b>tate data
+ * structure. <b>WSS</b> contains dimensions of document's main text window
+ * and the last selection made by Word user.
+ */
+ U32 fcWss;
+
+ /**
+ * count of bytes of WSS. ==0 if unable to store the window state. Should
+ * not be written by third party creators of Word files.
+ */
+ U32 lcbWss;
+
+ /**
+ * offset in table stream of document property data structure.
+ */
+ U32 fcDop;
+
+ /**
+ * count of bytes of document properties.
+ */
+ U32 lcbDop;
+
+ /**
+ * offset in table stream of STTBF of associated strings. The strings
+ * in this table specify document summary info and the paths to special documents
+ * related to this document. See documentation of the STTBFASSOC.
+ */
+ U32 fcSttbfAssoc;
+
+ U32 lcbSttbfAssoc;
+
+ /**
+ * offset in table stream of beginning of information for <b>complex</b>
+ * files. Consists of an encoding of all of the <b>prm</b>s quoted by the
+ * document followed by the <b>plcpcd</b> (piece table) for the document.
+ */
+ U32 fcClx;
+
+ /**
+ * count of bytes of complex file information == 0 if file is <b>non-complex</b>.
+ */
+ U32 lcbClx;
+
+ /**
+ * not used
+ */
+ U32 fcPlcfpgdFtn;
+
+ U32 lcbPlcfpgdFtn;
+
+ /**
+ * offset in table stream of the name of the original file. fcAutosaveSource
+ * and cbAutosaveSource should both be 0 if autosave is off.
+ */
+ U32 fcAutosaveSource;
+
+ /**
+ * count of bytes of the name of the original file.
+ */
+ U32 lcbAutosaveSource;
+
+ /**
+ * offset in table stream of group of strings recording the names of the
+ * owners of annotations stored in the document
+ */
+ U32 fcGrpXstAtnOwners;
+
+ /**
+ * count of bytes of the group of strings
+ */
+ U32 lcbGrpXstAtnOwners;
+
+ /**
+ * offset in table stream of the sttbf that records names of bookmarks
+ * for the annotation subdocument
+ */
+ U32 fcSttbfAtnbkmk;
+
+ /**
+ * length in bytes of the sttbf that records names of bookmarks for the
+ * annotation subdocument
+ */
+ U32 lcbSttbfAtnbkmk;
+
+ /**
+ * no longer used
+ */
+ U32 fcPlcdoaMom;
+
+ U32 lcbPlcdoaMom;
+
+ /**
+ * no longer used
+ */
+ U32 fcPlcdoaHdr;
+
+ U32 lcbPlcdoaHdr;
+
+ /**
+ * offset in table stream of the <b>FSPA</b> PLC for main document. ==
+ * 0 if document has no office art objects.
+ */
+ U32 fcPlcspaMom;
+
+ /**
+ * length in bytes of the <b>FSPA</b> PLC of the main document.
+ */
+ U32 lcbPlcspaMom;
+
+ /**
+ * offset in table stream of the <b>FSPA</b> PLC for header document.
+ * == 0 if document has no office art objects.
+ */
+ U32 fcPlcspaHdr;
+
+ /**
+ * length in bytes of the <b>FSPA</b> PLC of the header document.
+ */
+ U32 lcbPlcspaHdr;
+
+ /**
+ * offset in table stream of BKF (bookmark first) PLC of the annotation
+ * subdocument
+ */
+ U32 fcPlcfAtnbkf;
+
+ /**
+ * length in bytes of BKF (bookmark first) PLC of the annotation subdocument
+ */
+ U32 lcbPlcfAtnbkf;
+
+ /**
+ * offset in table stream of BKL (bookmark last) PLC of the annotation
+ * subdocument
+ */
+ U32 fcPlcfAtnbkl;
+
+ /**
+ * length in bytes of PLC marking the CP limits of the annotation bookmarks.
+ * No structure is stored in this PLC.
+ */
+ U32 lcbPlcfAtnbkl;
+
+ /**
+ * offset in table stream of PMS (Print Merge State) information block.
+ * This contains the current state of a print merge operation
+ */
+ U32 fcPms;
+
+ /**
+ * length in bytes of PMS. ==0 if no current print merge state. Should
+ * not be written by third party creators of Word files.
+ */
+ U32 lcbPms;
+
+ /**
+ * offset in table stream of form field Sttbf which contains strings used
+ * in form field dropdown controls
+ */
+ U32 fcFormFldSttbf;
+
+ /**
+ * length in bytes of form field Sttbf
+ */
+ U32 lcbFormFldSttbf;
+
+ /**
+ * offset in table stream of endnote reference PLCF of FRD structures.
+ * CPs in PLCF are relative to main document text stream and give location
+ * of endnote references.
+ */
+ U32 fcPlcfendRef;
+
+ U32 lcbPlcfendRef;
+
+ /**
+ * offset in table stream of PlcfendRef which points to endnote text in
+ * the endnote document stream which corresponds with the plcfendRef. No structure
+ * is stored in this PLC.
+ */
+ U32 fcPlcfendTxt;
+
+ U32 lcbPlcfendTxt;
+
+ /**
+ * offset in table stream to FLD PLCF of field positions in the endnote
+ * subdoc
+ */
+ U32 fcPlcffldEdn;
+
+ U32 lcbPlcffldEdn;
+
+ /**
+ * not used
+ */
+ U32 fcPlcfpgdEdn;
+
+ U32 lcbPlcfpgdEdn;
+
+ /**
+ * offset in table stream of the office art object table data. The format
+ * of office art object table data is found in a separate document.
+ */
+ U32 fcDggInfo;
+
+ /**
+ * length in bytes of the office art object table data
+ */
+ U32 lcbDggInfo;
+
+ /**
+ * offset in table stream to STTBF that records the author abbreviations
+ * for authors who have made revisions in the document.
+ */
+ U32 fcSttbfRMark;
+
+ U32 lcbSttbfRMark;
+
+ /**
+ * offset in table stream to STTBF that records caption titles used in
+ * the document.
+ */
+ U32 fcSttbfCaption;
+
+ U32 lcbSttbfCaption;
+
+ /**
+ * offset in table stream to the STTBF that records the object names and
+ * indices into the caption STTBF for objects which get auto captions.
+ */
+ U32 fcSttbfAutoCaption;
+
+ U32 lcbSttbfAutoCaption;
+
+ /**
+ * offset in table stream to WKB PLCF that describes the boundaries of
+ * contributing documents in a master document
+ */
+ U32 fcPlcfwkb;
+
+ U32 lcbPlcfwkb;
+
+ /**
+ * offset in table stream of PLCF (of SPLS structures) that records spell
+ * check state
+ */
+ U32 fcPlcfspl;
+
+ U32 lcbPlcfspl;
+
+ /**
+ * offset in table stream of PLCF that records the beginning CP in the
+ * text box subdoc of the text of individual text box entries. No structure
+ * is stored in this PLCF
+ */
+ U32 fcPlcftxbxTxt;
+
+ U32 lcbPlcftxbxTxt;
+
+ /**
+ * offset in table stream of the FLD PLCF that records field boundaries
+ * recorded in the textbox subdoc.
+ */
+ U32 fcPlcffldTxbx;
+
+ U32 lcbPlcffldTxbx;
+
+ /**
+ * offset in table stream of PLCF that records the beginning CP in the
+ * header text box subdoc of the text of individual header text box entries.
+ * No structure is stored in this PLC.
+ */
+ U32 fcPlcfHdrtxbxTxt;
+
+ U32 lcbPlcfHdrtxbxTxt;
+
+ /**
+ * offset in table stream of the FLD PLCF that records field boundaries
+ * recorded in the header textbox subdoc.
+ */
+ U32 fcPlcffldHdrTxbx;
+
+ U32 lcbPlcffldHdrTxbx;
+
+ /**
+ * Macro User storage
+ */
+ U32 fcStwUser;
+
+ U32 lcbStwUser;
+
+ /**
+ * offset in table stream of embedded true type font data.
+ */
+ U32 fcSttbttmbd;
+
+ U32 lcbSttbttmbd;
+
+ U32 fcUnused;
+
+ U32 lcbUnused;
+
+ /**
+ * (FCPGD, beginning of array of fcPgd / fcBkd pairs rgpgdbkd).
+ * offset in table stream of the PLF that records the page descriptors
+ * for the main text of the doc.
+ */
+ U32 fcPgdMother;
+
+ U32 lcbPgdMother;
+
+ /**
+ * offset in table stream of the PLCF that records the break descriptors
+ * for the main text of the doc.
+ */
+ U32 fcBkdMother;
+
+ U32 lcbBkdMother;
+
+ /**
+ * offset in table stream of the PLF that records the page descriptors
+ * for the footnote text of the doc.
+ */
+ U32 fcPgdFtn;
+
+ U32 lcbPgdFtn;
+
+ /**
+ * offset in table stream of the PLCF that records the break descriptors
+ * for the footnote text of the doc.
+ */
+ U32 fcBkdFtn;
+
+ U32 lcbBkdFtn;
+
+ /**
+ * offset in table stream of the PLF that records the page descriptors
+ * for the endnote text of the doc.
+ */
+ U32 fcPgdEdn;
+
+ U32 lcbPgdEdn;
+
+ /**
+ * offset in table stream of the PLCF that records the break descriptors
+ * for the endnote text of the doc.
+ */
+ U32 fcBkdEdn;
+
+ U32 lcbBkdEdn;
+
+ /**
+ * offset in table stream of the STTBF containing field keywords. This
+ * is only used in a small number of the international versions of word. This
+ * field is no longer written to the file for nFib >= 167.
+ */
+ U32 fcSttbfIntlFld;
+
+ /**
+ * Always 0 for nFib >= 167.
+ */
+ U32 lcbSttbfIntlFld;
+
+ /**
+ * offset in table stream of a mailer routing slip.
+ */
+ U32 fcRouteSlip;
+
+ U32 lcbRouteSlip;
+
+ /**
+ * offset in table stream of STTBF recording the names of the users who
+ * have saved this document alternating with the save locations.
+ */
+ U32 fcSttbSavedBy;
+
+ U32 lcbSttbSavedBy;
+
+ /**
+ * offset in table stream of STTBF recording filenames of documents which
+ * are referenced by this document.
+ */
+ U32 fcSttbFnm;
+
+ U32 lcbSttbFnm;
+
+ /**
+ * offset in the table stream of list format information.
+ */
+ U32 fcPlcfLst;
+
+ U32 lcbPlcfLst;
+
+ /**
+ * offset in the table stream of list format override information.
+ */
+ U32 fcPlfLfo;
+
+ U32 lcbPlfLfo;
+
+ /**
+ * offset in the table stream of the textbox break table (a PLCF of BKDs)
+ * for the main document
+ */
+ U32 fcPlcftxbxBkd;
+
+ U32 lcbPlcftxbxBkd;
+
+ /**
+ * offset in the table stream of the textbox break table (a PLCF of BKDs)
+ * for the header subdocument
+ */
+ U32 fcPlcftxbxHdrBkd;
+
+ U32 lcbPlcftxbxHdrBkd;
+
+ /**
+ * offset in main stream of undocumented undo / versioning data
+ */
+ U32 fcDocUndo;
+
+ U32 lcbDocUndo;
+
+ /**
+ * offset in main stream of undocumented undo / versioning data
+ */
+ U32 fcRgbuse;
+
+ U32 lcbRgbuse;
+
+ /**
+ * offset in main stream of undocumented undo / versioning data
+ */
+ U32 fcUsp;
+
+ U32 lcbUsp;
+
+ /**
+ * offset in table stream of undocumented undo / versioning data
+ */
+ U32 fcUskf;
+
+ U32 lcbUskf;
+
+ /**
+ * offset in table stream of undocumented undo / versioning data
+ */
+ U32 fcPlcupcRgbuse;
+
+ U32 lcbPlcupcRgbuse;
+
+ /**
+ * offset in table stream of undocumented undo / versioning data
+ */
+ U32 fcPlcupcUsp;
+
+ U32 lcbPlcupcUsp;
+
+ /**
+ * offset in table stream of string table of style names for glossary
+ * entries
+ */
+ U32 fcSttbGlsyStyle;
+
+ U32 lcbSttbGlsyStyle;
+
+ /**
+ * offset in table stream of undocumented grammar options PL
+ */
+ U32 fcPlgosl;
+
+ U32 lcbPlgosl;
+
+ /**
+ * offset in table stream of undocumented ocx data
+ */
+ U32 fcPlcocx;
+
+ U32 lcbPlcocx;
+
+ /**
+ * offset in table stream of character property bin table.PLC. FCs in
+ * PLC are file offsets. Describes text of main document and all subdocuments.
+ */
+ U32 fcPlcfbteLvc;
+
+ U32 lcbPlcfbteLvc;
+
+ /**
+ * (a.k.a FILETIME ftModified)
+ */
+ U32 dwLowDateTime;
+
+ U32 dwHighDateTime;
+
+ /**
+ * offset in table stream of LVC PLCF
+ */
+ U32 fcPlcflvc;
+
+ /**
+ * size of LVC PLCF, ==0 for <b>non-complex</b> files
+ */
+ U32 lcbPlcflvc;
+
+ /**
+ * offset in table stream of autosummary ASUMY PLCF.
+ */
+ U32 fcPlcasumy;
+
+ U32 lcbPlcasumy;
+
+ /**
+ * offset in table stream of PLCF (of SPLS structures) which records grammar
+ * check state
+ */
+ U32 fcPlcfgram;
+
+ U32 lcbPlcfgram;
+
+ /**
+ * offset in table stream of list names string table
+ */
+ U32 fcSttbListNames;
+
+ U32 lcbSttbListNames;
+
+ /**
+ * offset in table stream of undocumented undo / versioning data
+ */
+ U32 fcSttbfUssr;
+
+ U32 lcbSttbfUssr;
+
+}; // FIB
+
+bool operator==(const FIB &lhs, const FIB &rhs);
+bool operator!=(const FIB &lhs, const FIB &rhs);
+
+
+/**
+ * File Information FC/LCB pair (FIBFCLCB)
+ */
+struct FIBFCLCB {
+ /**
+ * Creates an empty FIBFCLCB structure and sets the defaults
+ */
+ FIBFCLCB();
+ /**
+ * Simply calls read(...)
+ */
+ FIBFCLCB(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the FIBFCLCB structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * File position where data begins.
+ */
+ U32 fc;
+
+ /**
+ * Size of data. Ignore fc if lcb is zero.
+ */
+ U32 lcb;
+
+}; // FIBFCLCB
+
+bool operator==(const FIBFCLCB &lhs, const FIBFCLCB &rhs);
+bool operator!=(const FIBFCLCB &lhs, const FIBFCLCB &rhs);
+
+
+/**
+ * Field Descriptor (FLD)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct FLD {
+// /**
+// * Creates an empty FLD structure and sets the defaults
+// */
+// FLD();
+// /**
+// * Simply calls read(...)
+// */
+// FLD(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * This method reads the FLD structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * type of field boundary the FLD describes:
+// * 19 field begin mark
+// * 20 field separator mark
+// * 21 field end mark
+// */
+// U8 ch:5;
+
+// /**
+// * reserved
+// */
+// U8 unused0_5:3;
+
+// /**
+// * fld.ch == 19 (field begin mark) -> U8 field type (see flt table below).
+// * fld.ch == 20 (field separator mark) -> not present
+// * fld.ch == 21 (field end mark) ->
+// * fDiffer:1 - ignored for saved file
+// * fZombieEmbed:1 - 1 when result still believes this field is an EMBED
+// * or LINK field.
+// * fResultDirty:1 - when user has edited or formatted the result.
+// * == 0 otherwise.
+// * fResultEdited:1 - 1 when user has inserted text into or deleted text
+// * from the result.
+// * fLocked:1 - 1 when field is locked from recalc.
+// * fPrivateResult:1 - 1 whenever the result of the field is never to be
+// * shown.
+// * fNested:1 - 1 when field is nested within another field.
+// * fHasSep:1 - 1 when field has a field separator.
+// */
+// S8 flt;
+
+//}; // FLD
+
+//bool operator==(const FLD &lhs, const FLD &rhs);
+//bool operator!=(const FLD &lhs, const FLD &rhs);
+
+
+/**
+ * Footnote Reference Descriptor (FRD)
+ */
+struct FRD {
+ /**
+ * Creates an empty FRD structure and sets the defaults
+ */
+ FRD();
+ /**
+ * Simply calls read(...)
+ */
+ FRD(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the FRD structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * if > 0, the note is an automatically numbered note, otherwise it has
+ * a custom mark
+ */
+ S16 nAuto;
+
+}; // FRD
+
+bool operator==(const FRD &lhs, const FRD &rhs);
+bool operator!=(const FRD &lhs, const FRD &rhs);
+
+
+/**
+ * File Shape Address (FSPA)
+ */
+struct FSPA {
+ /**
+ * Creates an empty FSPA structure and sets the defaults
+ */
+ FSPA();
+ /**
+ * Simply calls read(...)
+ */
+ FSPA(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the FSPA structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * Shape Identifier. Used in conjunction with the office art data (found
+ * via <b>fcDggInfo</b> in the <b>FIB</b>) to find the actual data for this
+ * shape.
+ */
+ S32 spid;
+
+ /**
+ * xa left of rectangle enclosing shape relative to the origin of the
+ * shape
+ */
+ S32 xaLeft;
+
+ /**
+ * ya top of rectangle enclosing shape relative to the origin of the shape
+ */
+ S32 yaTop;
+
+ /**
+ * xa right of rectangle enclosing shape relative to the origin of the
+ * shape
+ */
+ S32 xaRight;
+
+ /**
+ * ya bottom of the rectangle enclosing shape relative to the origin of
+ * the shape
+ */
+ S32 yaBottom;
+
+ /**
+ * 1 in the undo doc when shape is from the header doc, 0 otherwise (undefined
+ * when not in the undo doc)
+ */
+ U16 fHdr:1;
+
+ /**
+ * x position of shape relative to anchor CP
+ * 0 relative to page margin
+ * 1 relative to top of page
+ * 2 relative to text (column for horizontal text; paragraph for vertical
+ * text)
+ * 3 reserved for future use
+ */
+ U16 bx:2;
+
+ /**
+ * y position of shape relative to anchor CP
+ * 0 relative to page margin
+ * 1 relative to top of page
+ * 2 relative to text (paragraph for horizontal text; column for vertical
+ * text)
+ */
+ U16 by:2;
+
+ /**
+ * text wrapping mode
+ * 0 like 2, but doesn't require absolute object
+ * 1 no text next to shape
+ * 2 wrap around absolute object
+ * 3 wrap as if no object present
+ * 4 wrap tightly around object
+ * 5 wrap tightly, but allow holes
+ * 6-15 reserved for future use
+ */
+ U16 wr:4;
+
+ /**
+ * text wrapping mode type (valid only for wrapping modes 2 and 4
+ * 0 wrap both sides
+ * 1 wrap only on left
+ * 2 wrap only on right
+ * 3 wrap only on largest side
+ */
+ U16 wrk:4;
+
+ /**
+ * when set, temporarily overrides bx, by, forcing the xaLeft, xaRight,
+ * yaTop, and yaBottom fields to all be page relative.
+ */
+ U16 fRcaSimple:1;
+
+ /**
+ * 1 shape is below text
+ * 0 shape is above text
+ */
+ U16 fBelowText:1;
+
+ /**
+ * 1 anchor is locked
+ * 0 anchor is not locked
+ */
+ U16 fAnchorLock:1;
+
+ /**
+ * count of textboxes in shape (undo doc only)
+ */
+ S32 cTxbx;
+
+}; // FSPA
+
+bool operator==(const FSPA &lhs, const FSPA &rhs);
+bool operator!=(const FSPA &lhs, const FSPA &rhs);
+
+
+/**
+ * TeXtBoX Story (FTXBXS)
+ */
+struct FTXBXS {
+ /**
+ * Creates an empty FTXBXS structure and sets the defaults
+ */
+ FTXBXS();
+ /**
+ * Simply calls read(...)
+ */
+ FTXBXS(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the FTXBXS structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * when not fReusable, counts the number of textboxes in this story chain. when
+ * fReusable, the index of the next in the linked list of reusable FTXBXSs
+ */
+ S32 cTxbx_iNextReuse;
+
+ /**
+ * if fReusable, counts the number of reusable FTXBXSs follow this one
+ * in the linked list
+ */
+ S32 cReusable;
+
+ /**
+ * this FTXBXS is not currently in use
+ */
+ S16 fReusable;
+
+ /**
+ * reserved
+ */
+ U32 reserved;
+
+ /**
+ * Shape Identifier (see FSPA) for first Office Shape in textbox chain.
+ */
+ S32 lid;
+
+ S32 txidUndo;
+
+}; // FTXBXS
+
+bool operator==(const FTXBXS &lhs, const FTXBXS &rhs);
+bool operator!=(const FTXBXS &lhs, const FTXBXS &rhs);
+
+
+/**
+ * List Format Override (LFO)
+ */
+struct LFO {
+ /**
+ * Creates an empty LFO structure and sets the defaults
+ */
+ LFO();
+ /**
+ * Simply calls read(...)
+ */
+ LFO(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the LFO structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * List ID of corresponding LSTF (see LSTF)
+ */
+ S32 lsid;
+
+ /**
+ * reserved
+ */
+ S32 unused4;
+
+ /**
+ * reserved
+ */
+ S32 unused8;
+
+ /**
+ * count of levels whose format is overridden (see LFOLVL)
+ */
+ U8 clfolvl;
+
+ /**
+ * reserved
+ */
+ U8 reserved[3];
+
+}; // LFO
+
+bool operator==(const LFO &lhs, const LFO &rhs);
+bool operator!=(const LFO &lhs, const LFO &rhs);
+
+
+/**
+ * List Format Override for a single LeVeL (LFOLVL)
+ */
+struct LFOLVL {
+ /**
+ * Creates an empty LFOLVL structure and sets the defaults
+ */
+ LFOLVL();
+ /**
+ * Simply calls read(...)
+ */
+ LFOLVL(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the LFOLVL structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * start-at value if fFormatting == false and fStartAt == true. (if fFormatting
+ * == true, the start-at is stored in the LVL)
+ */
+ S32 iStartAt;
+
+ /**
+ * the level to be overridden
+ */
+ U8 ilvl:4;
+
+ /**
+ * true if the start-at value is overridden
+ */
+ U8 fStartAt:1;
+
+ /**
+ * true if the formatting is overriden (in which case the LFOLVL should
+ * contain a pointer to a LVL)
+ */
+ U8 fFormatting:1;
+
+ /**
+ * reserved
+ */
+ U8 unsigned4_6:2;
+
+ /**
+ * reserved
+ */
+ U8 reserved[3];
+
+}; // LFOLVL
+
+bool operator==(const LFOLVL &lhs, const LFOLVL &rhs);
+bool operator!=(const LFOLVL &lhs, const LFOLVL &rhs);
+
+
+/**
+ * Line Spacing Descriptor (LSPD)
+ */
+struct LSPD {
+ /**
+ * Creates an empty LSPD structure and sets the defaults
+ */
+ LSPD();
+ /**
+ * Simply calls read(...)
+ */
+ LSPD(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the LSPD structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * see description of sprmPDyaLine for description of the meaning of dyaLine
+ */
+ S16 dyaLine;
+
+ /**
+ * see description of sprmPDyaLine in the Sprm Definitions section for
+ * description of the meaning of dyaLine and fMultLinespace fields.
+ */
+ S16 fMultLinespace;
+
+}; // LSPD
+
+bool operator==(const LSPD &lhs, const LSPD &rhs);
+bool operator!=(const LSPD &lhs, const LSPD &rhs);
+
+
+/**
+ * LiST Data (on File) (LSTF)
+ */
+struct LSTF {
+ /**
+ * Creates an empty LSTF structure and sets the defaults
+ */
+ LSTF();
+ /**
+ * Simply calls read(...)
+ */
+ LSTF(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the LSTF structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * Unique List ID
+ */
+ S32 lsid;
+
+ /**
+ * Unique template code
+ */
+ S32 tplc;
+
+ /**
+ * Array of shorts containing the istd's linked to each level of the list,
+ * or istdNil (4095) if no style is linked.
+ */
+ U16 rgistd[9];
+
+ /**
+ * true if this is a simple (one-level) list; false if this is a multilevel
+ * (nine-level) list.
+ */
+ U8 fSimpleList:1;
+
+ /**
+ * Word 6 compatibility option: true if the list should start numbering
+ * over at the beginning of each section
+ */
+ U8 fRestartHdn:1;
+
+ /**
+ * reserved
+ */
+ U8 unsigned26_2:6;
+
+ /**
+ * reserved
+ */
+ U8 reserved;
+
+}; // LSTF
+
+bool operator==(const LSTF &lhs, const LSTF &rhs);
+bool operator!=(const LSTF &lhs, const LSTF &rhs);
+
+
+/**
+ * List LeVeL (on File) (LVLF)
+ */
+struct LVLF {
+ /**
+ * Creates an empty LVLF structure and sets the defaults
+ */
+ LVLF();
+ /**
+ * Simply calls read(...)
+ */
+ LVLF(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the LVLF structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * start at value for this list level
+ */
+ U32 iStartAt;
+
+ /**
+ * number format code (see anld.nfc for a list of options)
+ */
+ U8 nfc;
+
+ /**
+ * alignment (left, right, or centered) of the paragraph number.
+ */
+ U8 jc:2;
+
+ /**
+ * true (==1) if the level turns all inherited numbers to arabic, false
+ * if it preserves their number format code (nfc)
+ */
+ U8 fLegal:1;
+
+ /**
+ * true if the level's number sequence is not restarted by higher (more
+ * significant) levels in the list
+ */
+ U8 fNoRestart:1;
+
+ /**
+ * Word 6 compatibility option: equivalent to anld.fPrev (see ANLD)
+ */
+ U8 fPrev:1;
+
+ /**
+ * Word 6 compatibility option: equivalent to anld.fPrevSpace (see ANLD)
+ */
+ U8 fPrevSpace:1;
+
+ /**
+ * true if this level was from a converted Word 6 document. If it is true,
+ * all of the Word 6 compability options become valid; otherwise they are
+ * ignored.
+ */
+ U8 fWord6:1;
+
+ /**
+ * unused.
+ */
+ U8 unused5_7:1;
+
+ /**
+ * contains the character offsets into the LVL's XST of the inherited
+ * numbers of previous levels. This array should be zero terminated unless
+ * it is full (all 9 levels full). The XST contains place holders for any
+ * paragraph numbers contained in the text of the number, and the place holder
+ * contains the ilvl of the inherited number, so lvl.xst[lvl.rgbxchNums[0]]
+ * == the level of the first inherited number in this level.
+ */
+ U8 rgbxchNums[9];
+
+ /**
+ * the type of character following the number text for the paragraph:
+ * 0 == tab, 1 == space, 2 == nothing.
+ */
+ U8 ixchFollow;
+
+ /**
+ * Word 6 compatibility option: equivalent to anld.dxaSpace (see ANLD)
+ */
+ S32 dxaSpace;
+
+ /**
+ * Word 6 compatibility optino: equivalent to anld.dxaIndent (see ANLD)
+ */
+ S32 dxaIndent;
+
+ /**
+ * length, in bytes, of the LVL's grpprlChpx
+ */
+ U8 cbGrpprlChpx;
+
+ /**
+ * length, in bytes, of the LVL's grpprlPapx
+ */
+ U8 cbGrpprlPapx;
+
+ /**
+ * reserved
+ */
+ U16 reserved;
+
+}; // LVLF
+
+bool operator==(const LVLF &lhs, const LVLF &rhs);
+bool operator!=(const LVLF &lhs, const LVLF &rhs);
+
+
+/**
+ * Window's (METAFILEPICT)
+ */
+struct METAFILEPICT {
+ /**
+ * Creates an empty METAFILEPICT structure and sets the defaults
+ */
+ METAFILEPICT();
+ /**
+ * Simply calls read(...)
+ */
+ METAFILEPICT(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the METAFILEPICT structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * Specifies the mapping mode in which the picture is drawn.
+ */
+ S16 mm;
+
+ /**
+ * Specifies the size of the metafile picture for all modes except the
+ * MM_ISOTROPIC and MM_ANISOTROPIC modes. (For more information about these
+ * modes, see the yExt member.) The x-extent specifies the width of the rectangle
+ * within which the picture is drawn. The coordinates are in units that correspond
+ * to the mapping mode.
+ */
+ S16 xExt;
+
+ /**
+ * Specifies the size of the metafile picture for all modes except the
+ * MM_ISOTROPIC and MM_ANISOTROPIC modes. The y-extent specifies the height
+ * of the rectangle within which the picture is drawn. The coordinates are
+ * in units that correspond to the mapping mode.
+ * <p>For MM_ISOTROPIC and MM_ANISOTROPIC modes, which can be scaled, the
+ * xExt and yExt members contain an optional suggested size in MM_HIMETRIC
+ * units.
+ * <p>For MM_ANISOTROPIC pictures, xExt and yExt can be zero when no suggested
+ * size is supplied. For MM_ISOTROPIC pictures, an aspect ratio must be supplied
+ * even when no suggested size is given. (If a suggested size is given, the
+ * aspect ratio is implied by the size.) To give an aspect ratio without implying
+ * a suggested size, set xExt and yExt to negative values whose ratio is the
+ * appropriate aspect ratio. The magnitude of the negative xExt and yExt values
+ * is ignored; only the ratio is used.
+ */
+ S16 yExt;
+
+ /**
+ * Identifies a memory metafile.
+ */
+ S16 hMF;
+
+}; // METAFILEPICT
+
+bool operator==(const METAFILEPICT &lhs, const METAFILEPICT &rhs);
+bool operator!=(const METAFILEPICT &lhs, const METAFILEPICT &rhs);
+
+
+/**
+ * Number Revision Mark Data (NUMRM)
+ */
+struct NUMRM {
+ /**
+ * Creates an empty NUMRM structure and sets the defaults
+ */
+ NUMRM();
+ /**
+ * Simply calls read(...)
+ */
+ NUMRM(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ NUMRM(const U8 *ptr);
+
+ /**
+ * This method reads the NUMRM structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * True if this paragraph was numbered when revision mark tracking was
+ * turned on
+ */
+ U8 fNumRM;
+
+ U8 unused1;
+
+ /**
+ * index to author IDs stored in hsttbfRMark for the paragraph number
+ * change
+ */
+ S16 ibstNumRM;
+
+ /**
+ * Date of the paragraph number change
+ */
+ DTTM dttmNumRM;
+
+ /**
+ * Index into NUMRM.xst of the locations of paragraph number place holders
+ * for each level (see LVL.rgxchNums)
+ */
+ U8 rgbxchNums[9];
+
+ /**
+ * Number Format Code for the paragraph number place holders for each
+ * level (see LVL.nfc)
+ */
+ U8 rgnfc[9];
+
+ S16 unused26;
+
+ /**
+ * Numerical value for each level place holder in NUMRM.xst.
+ */
+ U32 PNBR[9];
+
+ /**
+ * The text string for the paragraph number, containing level place holders
+ */
+ XCHAR xst[32];
+
+}; // NUMRM
+
+bool operator==(const NUMRM &lhs, const NUMRM &rhs);
+bool operator!=(const NUMRM &lhs, const NUMRM &rhs);
+
+
+/**
+ * Embedded Object properties (OBJHEADER)
+ */
+struct OBJHEADER {
+ /**
+ * Creates an empty OBJHEADER structure and sets the defaults
+ */
+ OBJHEADER();
+ /**
+ * Simply calls read(...)
+ */
+ OBJHEADER(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the OBJHEADER structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * length of object (including this header)
+ */
+ U32 lcb;
+
+ /**
+ * length of this header (for future use)
+ */
+ U16 cbHeader;
+
+ /**
+ * Index to clipboard format of object
+ */
+ U16 icf;
+
+}; // OBJHEADER
+
+bool operator==(const OBJHEADER &lhs, const OBJHEADER &rhs);
+bool operator!=(const OBJHEADER &lhs, const OBJHEADER &rhs);
+
+
+/**
+ * Outline LiST Data (OLST)
+ */
+struct OLST {
+ /**
+ * Creates an empty OLST structure and sets the defaults
+ */
+ OLST();
+ /**
+ * Simply calls read(...)
+ */
+ OLST(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ OLST(const U8 *ptr);
+
+ /**
+ * This method reads the OLST structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * an array of 9 ANLV structures describing how heading numbers should
+ * be displayed for each of Word's 9 outline heading levels
+ */
+ ANLV rganlv[9];
+
+ /**
+ * when ==1, restart heading on section break
+ */
+ U8 fRestartHdr;
+
+ /**
+ * reserved
+ */
+ U8 fSpareOlst2;
+
+ /**
+ * reserved
+ */
+ U8 fSpareOlst3;
+
+ /**
+ * reserved
+ */
+ U8 fSpareOlst4;
+
+ /**
+ * text before/after number
+ */
+ XCHAR rgxch[32];
+
+}; // OLST
+
+bool operator==(const OLST &lhs, const OLST &rhs);
+bool operator!=(const OLST &lhs, const OLST &rhs);
+
+
+/**
+ * Paragraph Properties (PAP)
+ */
+struct PAP : public Shared {
+ /**
+ * Creates an empty PAP structure and sets the defaults
+ */
+ PAP();
+ /**
+ * Simply calls read(...)
+ */
+ PAP(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the PAP structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * This method applies a grpprl with @param count elements
+ */
+ void apply(const U8 *grpprl, U16 count, const Style* style, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version);
+
+ /**
+ * This method applies a whole PAPX to the structure.
+ * The reason that we only pass a pointer to the start of the exception
+ * structure is, that we don't know the type in the FKP template :}
+ */
+ void applyExceptions(const U8 *exceptions, const StyleSheet *styleSheet, OLEStreamReader* dataStream, WordVersion version);
+
+ /**
+ * This method applies one single SPRM. It returns -1 if it wasn't
+ * a PAP SPRM and it returns the length of the applied SPRM
+ * if it was successful.
+ */
+ S16 applyPAPSPRM(const U8* ptr, const Style* style, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version);
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * index to style descriptor . This is an index to an STD in the <b>STSH</b>
+ * structure
+ */
+ U16 istd;
+
+ /**
+ * justification code
+ * 0 left justify
+ * 1 center
+ * 2 right justify
+ * 3 left and right justify
+ */
+ U8 jc;
+
+ /**
+ * keep entire paragraph on one page if possible
+ */
+ U8 fKeep;
+
+ /**
+ * keep paragraph on same page with next paragraph if possible
+ */
+ U8 fKeepFollow;
+
+ /**
+ * start this paragraph on new page
+ */
+ U8 fPageBreakBefore;
+
+ U8 fBrLnAbove:1;
+
+ U8 fBrLnBelow:1;
+
+ /**
+ * reserved
+ */
+ U8 fUnused:2;
+
+ /**
+ * vertical position code. Specifies coordinate frame to use when paragraphs
+ * are absolutely positioned.
+ * 0 vertical position coordinates are relative to margin
+ * 1 coordinates are relative to page
+ * 2 coordinates are relative to text. This means: relative to where the
+ * next non-APO text would have been placed if this APO did not exist.
+ */
+ U8 pcVert:2;
+
+ /**
+ * horizontal position code. Specifies coordinate frame to use when paragraphs
+ * are absolutely positioned.
+ * 0 horiz. position coordinates are relative to column.
+ * 1 coordinates are relative to margin
+ * 2 coordinates are relative to page
+ */
+ U8 pcHorz:2;
+
+ /**
+ * the brcp and brcl fields have been superseded by the newly defined
+ * brcLeft, brcTop, etc. fields. They remain in the PAP for compatibility
+ * with MacWord 3.0
+ * rectangle border codes
+ * 0 none
+ * 1 border above
+ * 2 border below
+ * 15 box around
+ * 16 bar to left of paragraph
+ */
+ U8 brcp;
+
+ /**
+ * border line style
+ * 0 single
+ * 1 thick
+ * 2 double
+ * 3 shadow
+ */
+ U8 brcl;
+
+ /**
+ * reserved
+ */
+ U8 unused9;
+
+ /**
+ * when non-zero, list level for this paragraph (0-based index! Look at the sprmPIlvl docu (Werner))
+ */
+ U8 ilvl;
+
+ /**
+ * no line numbering for this paragraph. (makes this an exception to the
+ * section property of line numbering)
+ */
+ U8 fNoLnn;
+
+ /**
+ * when non-zero, (1-based) index into the pllfo identifying the list
+ * to which the paragraph belongs
+ */
+ S16 ilfo;
+
+ /**
+ * no longer used
+ */
+ U8 nLvlAnm;
+
+ /**
+ * reserved
+ */
+ U8 unused15;
+
+ /**
+ * when 1, paragraph is a side by side paragraph
+ */
+ U8 fSideBySide;
+
+ /**
+ * reserved
+ */
+ U8 unused17;
+
+ /**
+ * when 0, text in paragraph may be auto hyphenated.
+ */
+ U8 fNoAutoHyph;
+
+ /**
+ * when 1, Word will prevent widowed lines in this paragraph from being
+ * placed at the beginning of a page
+ */
+ U8 fWidowControl;
+
+ /**
+ * indent from right margin (signed).
+ */
+ S32 dxaRight;
+
+ /**
+ * indent from left margin (signed)
+ */
+ S32 dxaLeft;
+
+ /**
+ * first line indent; signed number relative to dxaLeft
+ */
+ S32 dxaLeft1;
+
+ /**
+ * line spacing descriptor
+ */
+ LSPD lspd;
+
+ /**
+ * vertical spacing before paragraph (unsigned)
+ */
+ U32 dyaBefore;
+
+ /**
+ * vertical spacing after paragraph (unsigned)
+ */
+ U32 dyaAfter;
+
+ /**
+ * height of current paragraph.
+ */
+ PHE phe;
+
+ U8 fCrLf;
+
+ U8 fUsePgsuSettings;
+
+ U8 fAdjustRight;
+
+ /**
+ * reserved
+ */
+ U8 unused59;
+
+ /**
+ * when 1, apply kinsoku rules when performing line wrapping
+ */
+ U8 fKinsoku;
+
+ /**
+ * when 1, perform word wrap
+ */
+ U8 fWordWrap;
+
+ /**
+ * when 1, apply overflow punctuation rules when performing line wrapping
+ */
+ U8 fOverflowPunct;
+
+ /**
+ * when 1, perform top line punctuation processing
+ */
+ U8 fTopLinePunct;
+
+ /**
+ * when 1, auto space FE and alphabetic characters
+ */
+ U8 fAutoSpaceDE;
+
+ /**
+ * when 1, auto space FE and numeric characters
+ */
+ U8 fAutoSpaceDN;
+
+ /**
+ * font alignment
+ * 0 Hanging
+ * 1 Centered
+ * 2 Roman
+ * 3 Variable
+ * 4 Auto
+ */
+ U16 wAlignFont;
+
+ U16 fVertical:1;
+
+ U16 fBackward:1;
+
+ U16 fRotateFont:1;
+
+ /**
+ * reserved
+ */
+ U16 unused68_3:13;
+
+ /**
+ * reserved
+ */
+ U16 unused70;
+
+ /**
+ * when 1, paragraph is contained in a table row
+ */
+ S8 fInTable;
+
+ /**
+ * when 1, paragraph consists only of the row mark special character and
+ * marks the end of a table row.
+ */
+ S8 fTtp;
+
+ /**
+ * Wrap Code for absolute objects
+ */
+ U8 wr;
+
+ /**
+ * when 1, paragraph may not be edited
+ */
+ U8 fLocked;
+
+ /**
+ * TAP used internally by Word
+ */
+ U32 ptap;
+
+ /**
+ * when positive, is the horizontal distance from the reference frame
+ * specified by pap.pcHorz. 0 means paragraph is positioned at the left with
+ * respect to the reference frame specified by pcHorz. Certain negative values
+ * have special meaning:
+ * -4 paragraph centered horizontally within reference frame
+ * -8 paragraph adjusted right within reference frame
+ * -12 paragraph placed immediately inside of reference frame
+ * -16 paragraph placed immediately outside of reference frame
+ */
+ S32 dxaAbs;
+
+ /**
+ * when positive, is the vertical distance from the reference frame specified
+ * by pap.pcVert. 0 means paragraph's y-position is unconstrained. Certain
+ * negative values have special meaning:
+ * -4 paragraph is placed at top of reference frame
+ * -8 paragraph is centered vertically within reference frame
+ * -12 paragraph is placed at bottom of reference frame.
+ */
+ S32 dyaAbs;
+
+ /**
+ * when not == 0, paragraph is constrained to be dxaWidth wide, independent
+ * of current margin or column settings.
+ */
+ S32 dxaWidth;
+
+ /**
+ * specification for border above paragraph
+ */
+ BRC brcTop;
+
+ /**
+ * specification for border to the left of paragraph
+ */
+ BRC brcLeft;
+
+ /**
+ * specification for border below paragraph
+ */
+ BRC brcBottom;
+
+ /**
+ * specification for border to the right of paragraph
+ */
+ BRC brcRight;
+
+ /**
+ * specification of border to place between conforming paragraphs. Two
+ * paragraphs conform when both have borders, their brcLeft and brcRight matches,
+ * their widths are the same, they both belong to tables or both do not, and
+ * have the same absolute positioning props.
+ */
+ BRC brcBetween;
+
+ /**
+ * specification of border to place on outside of text when facing pages
+ * are to be displayed.
+ */
+ BRC brcBar;
+
+ /**
+ * horizontal distance to be maintained between an absolutely positioned
+ * paragraph and any non-absolute positioned text
+ */
+ S32 dxaFromText;
+
+ /**
+ * vertical distance to be maintained between an absolutely positioned
+ * paragraph and any non-absolute positioned text
+ */
+ S32 dyaFromText;
+
+ /**
+ * height of abs obj; 0 == Auto
+ */
+ U16 dyaHeight:15;
+
+ /**
+ * 0 = Exact, 1 = At Least
+ */
+ U16 fMinHeight:1;
+
+ /**
+ * shading
+ */
+ SHD shd;
+
+ /**
+ * drop cap specifier (see DCS definition)
+ */
+ DCS dcs;
+
+ S8 lvl;
+
+ S8 fBiDi;
+
+ S8 fNumRMIns;
+
+ /**
+ * autonumber list descriptor (see ANLD definition)
+ */
+ ANLD anld;
+
+ /**
+ * when 1, properties have been changed with revision marking on
+ */
+ S16 fPropRMark;
+
+ /**
+ * index to author IDs stored in hsttbfRMark. used when properties have
+ * been changed when revision marking was enabled
+ */
+ S16 ibstPropRMark;
+
+ /**
+ * Date/time at which properties of this were changed for this run of
+ * text by the author. (Only recorded when revision marking is on.)
+ */
+ DTTM dttmPropRMark;
+
+ /**
+ * paragraph numbering revision mark data (see NUMRM)
+ */
+ NUMRM numrm;
+
+ /**
+ * number of tabs stops defined for paragraph. Must be >= 0 and &lt;=
+ * 64.
+ */
+ S16 itbdMac;
+
+ /**
+ * array of { positions of itbdMac tab stops ; itbdMac tab descriptors }
+ * itbdMax == 64.
+ * The SPEC doesn't have such a structure, obviously. This is a wv2 change.
+ * (This data is never in the file as is, it comes from the SPRMs).
+ */
+ std::vector<Word97::TabDescriptor> rgdxaTab;
+
+}; // PAP
+
+bool operator==(const PAP &lhs, const PAP &rhs);
+bool operator!=(const PAP &lhs, const PAP &rhs);
+
+
+/**
+ * Paragraph Property Exceptions (PAPX)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct PAPX {
+// /**
+// * Creates an empty PAPX structure and sets the defaults
+// */
+// PAPX();
+// /**
+// * Simply calls read(...)
+// */
+// PAPX(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * This method reads the PAPX structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * count of bytes of following data in PAPX. The first byte of a PAPX
+// * is a count of bytes when a PAPX is stored in a STSH. Count of bytes is
+// * used because only paragraph sprms are stored in a STSH PAPX.
+// */
+// U8 cb;
+
+// /**
+// * count of words for this byte and the following data in PAPX. The first
+// * byte of a PAPX is a count of words when PAPX is stored in an FKP. If this
+// * value is 0, it is a 'pad' byte and the count is stored in the following
+// * byte, Count of words is used because PAPX in an FKP can contain paragraph
+// * <b>and</b>
+// * table sprms.
+// */
+// U8 cw;
+
+// /**
+// * if previous byte is 0, this is the count of words of following data
+// * in PAPX (not including this and previous 'pad' byte)
+// */
+// U8 (cw);
+
+// /**
+// * index to style descriptor of the style from which the paragraph inherits
+// * its paragraph and character properties
+// */
+// U16 istd;
+
+// /**
+// * a list of the sprms that encode the differences between PAP for a paragraph
+// * and the PAP for the style used. When a paragraph bound is also the end
+// * of a table row, the PAPX also contains a list of table sprms which express
+// * the difference of table row's TAP from an empty TAP that has been cleared
+// * to zeros. The table sprms are recorded in the list after all of the paragraph
+// * sprms. See Sprms definitions for list of sprms that are used in PAPXs.
+// */
+// character array grpprl;
+
+//}; // PAPX
+
+//bool operator==(const PAPX &lhs, const PAPX &rhs);
+//bool operator!=(const PAPX &lhs, const PAPX &rhs);
+
+
+/**
+ * Formatted Disk Page for PAPXs (PAPXFKP)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct PAPXFKP {
+// /**
+// * Creates an empty PAPXFKP structure and sets the defaults
+// */
+// PAPXFKP();
+// /**
+// * Simply calls read(...)
+// */
+// PAPXFKP(OLEStreamReader *stream, bool preservePos=false);
+// /**
+// * Attention: This struct allocates memory on the heap
+// */
+// PAPXFKP(const PAPXFKP &rhs);
+// ~PAPXFKP();
+
+// PAPXFKP &operator=(const PAPXFKP &rhs);
+
+// /**
+// * This method reads the PAPXFKP structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * Each <b>FC</b> is the limit <b>FC</b> of a paragraph (i.e. points to
+// * the next character past an end of paragraph mark). There will be fkp.crun+1
+// * recorded in the FKP.
+// */
+// FC *rgfc; // FC rgfc[fkp.crun+1];
+
+// /**
+// * an array of the BX data structure. The <b>ith</b> BX entry in the array
+// * describes the paragraph beginning at fkp.rgfc[i]. The BX is a 13 byte data
+// * structure. The first byte of each BX is the word offset of the <b>PAPX</b>
+// * recorded for the paragraph corresponding to this BX.
+// * <b>.</b>. If the byte
+// * stored is 0, this represents a 1 line paragraph 15 pixels high with Normal
+// * style (stc == 0) whose column width is 7980 dxas. The last 12 bytes of
+// * the BX is a PHE structure which stores the current paragraph height for
+// * the paragraph corresponding to the BX. If a plcfphe has an entry that maps
+// * to the FC for this paragraph, that entry's PHE overrides the PHE stored
+// * in the FKP.11*fkp.crun+4 unused space. As new runs/paragraphs are recorded
+// * in the <b>FKP</b>, unused space is reduced by 17 if CHPX/PAPX is already
+// * recorded and is reduced by 17+sizeof(PAPX) if property is not already recorded.
+// */
+// BX *rgbx; // BX rgbx[fkp.crun];
+
+// /**
+// * grppapx consists of all of the <b>PAPX</b>s stored in <b>FKP</b> concatenated
+// * end to end. Each <b>PAPX</b> begins with a count of words which records
+// * its length padded to a word boundary.
+// */
+// U8 *grppapx; // U8 grppapx[];
+
+// /**
+// * count of paragraphs for <b>PAPX FKP.</b>
+// */
+// U8 crun;
+
+//private:
+// void clearInternal();
+
+//}; // PAPXFKP
+
+//bool operator==(const PAPXFKP &lhs, const PAPXFKP &rhs);
+//bool operator!=(const PAPXFKP &lhs, const PAPXFKP &rhs);
+
+
+/**
+ * Piece Descriptor (PCD)
+ */
+struct PCD {
+ /**
+ * Creates an empty PCD structure and sets the defaults
+ */
+ PCD();
+ /**
+ * Simply calls read(...)
+ */
+ PCD(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Simply calls readPtr(...)
+ */
+ PCD(const U8 *ptr);
+
+ /**
+ * This method reads the PCD structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr(const U8 *ptr);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * when 1, means that piece contains no end of paragraph marks.
+ */
+ U16 fNoParaLast:1;
+
+ /**
+ * used internally by Word
+ */
+ U16 fPaphNil:1;
+
+ /**
+ * used internally by Word
+ */
+ U16 fCopied:1;
+
+ U16 unused0_3:5;
+
+ /**
+ * used internally by Word
+ */
+ U16 fn:8;
+
+ /**
+ * file offset of beginning of piece. The size of the <b>ith</b> piece
+ * can be determined by subtracting rgcp[<b>i</b>] of the containing
+ * <b>plcfpcd</b>
+ * from its rgcp[<b>i+1</b>].
+ */
+ U32 fc;
+
+ /**
+ * contains either a single sprm or else an index number of the grpprl
+ * which contains the sprms that modify the properties of the piece.
+ */
+ PRM prm;
+
+}; // PCD
+
+bool operator==(const PCD &lhs, const PCD &rhs);
+bool operator!=(const PCD &lhs, const PCD &rhs);
+
+
+/**
+ * Page Descriptor (PGD)
+ */
+struct PGD {
+ /**
+ * Creates an empty PGD structure and sets the defaults
+ */
+ PGD();
+ /**
+ * Simply calls read(...)
+ */
+ PGD(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the PGD structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * 1 only when footnote is continued from previous page
+ */
+ U16 fContinue:1;
+
+ /**
+ * 1 when page is dirty (i.e. pagination cannot be trusted)
+ */
+ U16 fUnk:1;
+
+ /**
+ * 1 when right hand side page
+ */
+ U16 fRight:1;
+
+ /**
+ * 1 when page number must be reset to 1.
+ */
+ U16 fPgnRestart:1;
+
+ /**
+ * 1 when section break forced page to be empty.
+ */
+ U16 fEmptyPage:1;
+
+ /**
+ * 1 when page contains nothing but footnotes
+ */
+ U16 fAllFtn:1;
+
+ /**
+ * unused
+ */
+ U16 unused0_6:1;
+
+ /**
+ * table breaks have been calculated for this page.
+ */
+ U16 fTableBreaks:1;
+
+ /**
+ * used temporarily while word is running.
+ */
+ U16 fMarked:1;
+
+ /**
+ * column breaks have been calculated for this page.
+ */
+ U16 fColumnBreaks:1;
+
+ /**
+ * page had a table header at the end
+ */
+ U16 fTableHeader:1;
+
+ /**
+ * page has never been valid since created, must recalculate the bounds
+ * of this page. If this is the last page, this PGD may really represent many
+ * pages.
+ */
+ U16 fNewPage:1;
+
+ /**
+ * section break code
+ */
+ U16 bkc:4;
+
+ /**
+ * line number of first line, -1 if no line numbering
+ */
+ U16 lnn;
+
+ /**
+ * page number as printed
+ */
+ U16 pgn;
+
+ S32 dym;
+
+}; // PGD
+
+bool operator==(const PGD &lhs, const PGD &rhs);
+bool operator!=(const PGD &lhs, const PGD &rhs);
+
+
+/**
+ * Paragraph Height in a Table (PHE2)
+ */
+struct PHE2 {
+ /**
+ * Creates an empty PHE2 structure and sets the defaults
+ */
+ PHE2();
+ /**
+ * Simply calls read(...)
+ */
+ PHE2(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the PHE2 structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * reserved
+ */
+ U32 fSpare:1;
+
+ /**
+ * PHE entry is invalid when == 1
+ */
+ U32 fUnk:1;
+
+ /**
+ * if not == 0, used as a hint when finding the next row
+ */
+ U32 dcpTtpNext:30;
+
+ S32 dxaCol;
+
+ /**
+ * height of table row
+ */
+ S32 dymTableHeight;
+
+}; // PHE2
+
+bool operator==(const PHE2 &lhs, const PHE2 &rhs);
+bool operator!=(const PHE2 &lhs, const PHE2 &rhs);
+
+
+/**
+ * Picture Descriptor (on File) (PICF)
+ */
+struct PICF : public Shared {
+ /**
+ * Creates an empty PICF structure and sets the defaults
+ */
+ PICF();
+ /**
+ * Simply calls read(...)
+ */
+ PICF(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the PICF structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * This method applies a grpprl with @param count elements
+ */
+ void apply(const U8 *grpprl, U16 count, const Style* style, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version);
+
+ /**
+ * This method applies a whole PICFX to the structure.
+ * The reason that we only pass a pointer to the start of the exception
+ * structure is, that we don't know the type in the FKP template :}
+ */
+ void applyExceptions(const U8 *exceptions, const StyleSheet *styleSheet, OLEStreamReader* dataStream, WordVersion version);
+
+ /**
+ * This method applies one single SPRM. It returns -1 if it wasn't
+ * a PICF SPRM and it returns the length of the applied SPRM
+ * if it was successful.
+ */
+ S16 applyPICFSPRM(const U8* ptr, const Style* style, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version);
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * number of bytes in the PIC structure plus size of following picture
+ * data which may be a Window's metafile, a bitmap, or the filename of a TIFF
+ * file. In the case of a Macintosh PICT picture, this includes the size of
+ * the PIC, the standard "x" metafile, and the Macintosh PICT data. See Appendix
+ * B for more information.
+ */
+ U32 lcb;
+
+ /**
+ * number of bytes in the PIC (to allow for future expansion).
+ */
+ U16 cbHeader;
+
+ /**
+ * If a Windows metafile is stored immediately following the PIC structure,
+ * the mfp is a Window's METAFILEPICT structure. When the data immediately
+ * following the PIC is a TIFF filename, mfp.mm == 98 If a bitmap is stored
+ * after the pic, mfp.mm == 99
+ * <p>When the PIC describes a bitmap, mfp.xExt is the width of the bitmap
+ * in pixels and mfp.yExt is the height of the bitmap in pixels..
+ */
+ METAFILEPICT mfp;
+
+ /**
+ * Window's bitmap structure when PIC describes a BITMAP (14 bytes).
+ * Rect for window origin and extents when metafile is stored -- ignored
+ * if 0 (8 bytes).
+ */
+ U8 bm_rcWinMF[14];
+
+ /**
+ * horizontal measurement in twips of the rectangle the picture should
+ * be imaged within. when scaling bitmaps, dxaGoal and dyaGoal may be ignored
+ * if the operation would cause the bitmap to shrink or grow by a non -power-of-two
+ * factor
+ */
+ S16 dxaGoal;
+
+ /**
+ * vertical measurement in twips of the rectangle the picture should be
+ * imaged within.
+ */
+ S16 dyaGoal;
+
+ /**
+ * horizontal scaling factor supplied by user expressed in .001% units.
+ */
+ U16 mx;
+
+ /**
+ * vertical scaling factor supplied by user expressed in .001% units.
+ */
+ U16 my;
+
+ /**
+ * the amount the picture has been cropped on the left in twips. for all
+ * of the Crop values, a positive measurement means the specified border has
+ * been moved inward from its original setting and a negative measurement
+ * means the border has been moved outward from its original setting.
+ */
+ S16 dxaCropLeft;
+
+ /**
+ * the amount the picture has been cropped on the top in twips.
+ */
+ S16 dyaCropTop;
+
+ /**
+ * the amount the picture has been cropped on the right in twips.
+ */
+ S16 dxaCropRight;
+
+ /**
+ * the amount the picture has been cropped on the bottom in twips.
+ */
+ S16 dyaCropBottom;
+
+ /**
+ * Obsolete, superseded by brcTop, etc. In WinWord 1.x, it was the type
+ * of border to place around picture
+ * 0 single
+ * 1 thick
+ * 2 double
+ * 3 shadow
+ */
+ U16 brcl:4;
+
+ /**
+ * picture consists of a single frame
+ */
+ U16 fFrameEmpty:1;
+
+ /**
+ * ==1, when picture is just a bitmap
+ */
+ U16 fBitmap:1;
+
+ /**
+ * ==1, when picture is an active OLE object
+ */
+ U16 fDrawHatch:1;
+
+ /**
+ * ==1, when picture is just an error message
+ */
+ U16 fError:1;
+
+ /**
+ * bits per pixel
+ * 0 unknown
+ * 1 monochrome
+ * 4 VGA
+ */
+ U16 bpp:8;
+
+ /**
+ * specification for border above picture
+ */
+ BRC brcTop;
+
+ /**
+ * specification for border to the left of picture
+ */
+ BRC brcLeft;
+
+ /**
+ * specification for border below picture
+ */
+ BRC brcBottom;
+
+ /**
+ * specification for border to the right of picture
+ */
+ BRC brcRight;
+
+ /**
+ * horizontal offset of hand annotation origin
+ */
+ S16 dxaOrigin;
+
+ /**
+ * vertical offset of hand annotation origin
+ */
+ S16 dyaOrigin;
+
+ /**
+ * unused
+ */
+ S16 cProps;
+
+}; // PICF
+
+bool operator==(const PICF &lhs, const PICF &rhs);
+bool operator!=(const PICF &lhs, const PICF &rhs);
+
+
+/**
+ * Plex of CPs stored in File (PLCF)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct PLCF {
+// /**
+// * Creates an empty PLCF structure and sets the defaults
+// */
+// PLCF();
+// /**
+// * Simply calls read(...)
+// */
+// PLCF(OLEStreamReader *stream, bool preservePos=false);
+// /**
+// * Attention: This struct allocates memory on the heap
+// */
+// PLCF(const PLCF &rhs);
+// ~PLCF();
+
+// PLCF &operator=(const PLCF &rhs);
+
+// /**
+// * This method reads the PLCF structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * given that the size of PLCF is cb and the size of the structure stored
+// * in plc is cbStruct, then the number of structure instances stored in PLCF,
+// * iMac is given by (cb -4)/(4 + cbStruct) The number of FCs stored in the
+// * PLCF will be iMac + 1.
+// */
+// FC *rgfc; // FC rgfc[];
+
+// /**
+// * array of some arbitrary structure.
+// */
+// U8 *rgstruct; // U8 rgstruct[];
+
+//private:
+// void clearInternal();
+
+//}; // PLCF
+
+//bool operator==(const PLCF &lhs, const PLCF &rhs);
+//bool operator!=(const PLCF &lhs, const PLCF &rhs);
+
+
+/**
+ * Routing Recipient (RR)
+ */
+struct RR {
+ /**
+ * Creates an empty RR structure and sets the defaults
+ */
+ RR();
+ /**
+ * Simply calls read(...)
+ */
+ RR(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the RR structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * count of bytes of private system data
+ */
+ U16 cb;
+
+ /**
+ * count of bytes in recipient string (including null terminator).
+ */
+ U16 cbSzRecip;
+
+}; // RR
+
+bool operator==(const RR &lhs, const RR &rhs);
+bool operator!=(const RR &lhs, const RR &rhs);
+
+
+/**
+ * Routing Slip (RS)
+ */
+struct RS {
+ /**
+ * Creates an empty RS structure and sets the defaults
+ */
+ RS();
+ /**
+ * Simply calls read(...)
+ */
+ RS(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the RS structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * when 1, document has been routed to at least one recipient.
+ */
+ S16 fRouted;
+
+ /**
+ * when 1, document should be routed to the originator after it has been
+ * routed to all recipients.
+ */
+ S16 fReturnOrig;
+
+ /**
+ * when 1, a status message is sent to the originator each time the document
+ * is forwarded to a recipient on the routing list.
+ */
+ S16 fTrackStatus;
+
+ /**
+ * unused( should be 0)
+ */
+ S16 fDirty;
+
+ /**
+ * document protection while routing
+ * 0 recipients can make changes to the document and all changes are untracked.
+ * 1 recipients can add annotations and make changes to the document.
+ * Any changes are tracked by revision marks, and revision marking cannot
+ * be turned off.
+ * 2 recipients can only add annotations to the document.
+ * 3 recipients can enter information only in form fields.
+ */
+ S16 nProtect;
+
+ /**
+ * index of the current recipient.
+ */
+ S16 iStage;
+
+ /**
+ * when 0, document is routed to each recipient in turn. when 1, document
+ * is routed to all recipients simultaneously.
+ */
+ S16 delOption;
+
+ /**
+ * count of recipients.
+ */
+ S16 cRecip;
+
+}; // RS
+
+bool operator==(const RS &lhs, const RS &rhs);
+bool operator!=(const RS &lhs, const RS &rhs);
+
+
+/**
+ * Section Descriptor (SED)
+ */
+struct SED {
+ /**
+ * Creates an empty SED structure and sets the defaults
+ */
+ SED();
+ /**
+ * Simply calls read(...)
+ */
+ SED(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the SED structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * used internally by Word
+ */
+ S16 fn;
+
+ /**
+ * file offset in main stream to beginning of SEPX stored for section.
+ * If sed.fcSepx == 0xFFFFFFFF, the section properties for the section are
+ * equal to the standard SEP (see SEP definition).
+ */
+ U32 fcSepx;
+
+ /**
+ * used internally by Word
+ */
+ S16 fnMpr;
+
+ /**
+ * points to offset in FC space of main stream where the Macintosh Print
+ * Record for a document created on a Mac will be stored
+ */
+ U32 fcMpr;
+
+}; // SED
+
+bool operator==(const SED &lhs, const SED &rhs);
+bool operator!=(const SED &lhs, const SED &rhs);
+
+
+/**
+ * Section Properties (SEP)
+ */
+struct SEP : public Shared {
+ /**
+ * Creates an empty SEP structure and sets the defaults
+ */
+ SEP();
+ /**
+ * Simply calls read(...)
+ */
+ SEP(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the SEP structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ /**
+ * This method applies a grpprl with @param count elements
+ */
+ void apply(const U8 *grpprl, U16 count, const Style* style, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version);
+
+ /**
+ * This method applies a whole SEPX to the structure.
+ * The reason that we only pass a pointer to the start of the exception
+ * structure is, that we don't know the type in the FKP template :}
+ */
+ void applyExceptions(const U8 *exceptions, const StyleSheet *styleSheet, OLEStreamReader* dataStream, WordVersion version);
+
+ /**
+ * This method applies one single SPRM. It returns -1 if it wasn't
+ * a SEP SPRM and it returns the length of the applied SPRM
+ * if it was successful.
+ */
+ S16 applySEPSPRM(const U8* ptr, const Style* style, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version);
+
+ /**
+ * Dumps all fields of this structure (for debugging)
+ */
+ void dump() const;
+
+ /**
+ * Converts the data structure to a string (for debugging)
+ */
+ std::string toString() const;
+
+ // Data
+ /**
+ * break code:
+ * 0 No break
+ * 1 New column
+ * 2 New page
+ * 3 Even page
+ * 4 Odd page
+ */
+ U8 bkc;
+
+ /**
+ * set to 1 when a title page is to be displayed
+ */
+ U8 fTitlePage;
+
+ /**
+ * only for Mac compatibility, used only during open, when 1, sep.dxaPgn
+ * and sep.dyaPgn are valid page number locations
+ */
+ S8 fAutoPgn;
+
+ /**
+ * page number format code:
+ * 0 Arabic
+ * 1 Roman (upper case)
+ * 2 Roman (lower case)
+ * 3 Letter (upper case)
+ * 4 Letter (lower case)
+ */
+ U8 nfcPgn;
+
+ /**
+ * set to 1, when a section in a locked document is unlocked
+ */
+ U8 fUnlocked;
+
+ /**
+ * chapter number separator for page numbers
+ */
+ U8 cnsPgn;
+
+ /**
+ * set to 1 when page numbering should be restarted at the beginning of
+ * this section
+ */
+ U8 fPgnRestart;
+
+ /**
+ * when 1, footnotes placed at end of section. When 0, footnotes are placed
+ * at bottom of page.
+ */
+ U8 fEndNote;
+
+ /**
+ * line numbering code:
+ * 0 Per page
+ * 1 Restart
+ * 2 Continue
+ */
+ S8 lnc;
+
+ /**
+ * specification of which headers and footers are included in this section.
+ * See explanation in Headers and Footers topic. No longer used.
+ */
+ S8 grpfIhdt;
+
+ /**
+ * if 0, no line numbering, otherwise this is the line number modulus
+ * (e.g. if nLnnMod is 5, line numbers appear on line 5, 10, etc.)
+ */
+ U16 nLnnMod;
+
+ /**
+ * distance of
+ */
+ S32 dxaLnn;
+
+ /**
+ * when fAutoPgn ==1, gives the x position of auto page number on page
+ * in twips (for Mac compatibility only)
+ */
+ S16 dxaPgn;
+
+ /**
+ * when fAutoPgn ==1, gives the y position of auto page number on page
+ * in twips (for Mac compatibility only)
+ */
+ S16 dyaPgn;
+
+ /**
+ * when ==1, draw vertical lines between columns
+ */
+ S8 fLBetween;
+
+ /**
+ * vertical justification code
+ * 0 top justified
+ * 1 centered
+ * 2 fully justified vertically
+ * 3 bottom justified
+ */
+ S8 vjc;
+
+ /**
+ * bin number supplied from windows printer driver indicating which bin
+ * the first page of section will be printed.
+ */
+ U16 dmBinFirst;
+
+ /**
+ * bin number supplied from windows printer driver indicating which bin
+ * the pages other than the first page of section will be printed.
+ */
+ U16 dmBinOther;
+
+ /**
+ * dmPaper code for form selected by user
+ */
+ U16 dmPaperReq;
+
+ /**
+ * top page border
+ */
+ BRC brcTop;
+
+ /**
+ * left page border
+ */
+ BRC brcLeft;
+
+ /**
+ * bottom page border
+ */
+ BRC brcBottom;
+
+ /**
+ * right page border
+ */
+ BRC brcRight;
+
+ /**
+ * when 1, properties have been changed with revision marking on
+ */
+ S16 fPropRMark;
+
+ /**
+ * index to author IDs stored in hsttbfRMark. used when properties have
+ * been changed when revision marking was enabled
+ */
+ S16 ibstPropRMark;
+
+ /**
+ * Date/time at which properties of this were changed for this run of
+ * text by the author. (Only recorded when revision marking is on.)
+ */
+ DTTM dttmPropRMark;
+
+ S32 dxtCharSpace;
+
+ S32 dyaLinePitch;
+
+ U16 clm;
+
+ /**
+ * reserved
+ */
+ U16 unused62;
+
+ /**
+ * orientation of pages in that section. set to 1 when portrait, 2 when
+ * landscape
+ */
+ U8 dmOrientPage;
+
+ /**
+ * heading number level for page number
+ */
+ U8 iHeadingPgn;
+
+ /**
+ * user specified starting page number.
+ */
+ U16 pgnStart;
+
+ /**
+ * beginning line number for section
+ */
+ S16 lnnMin;
+
+ U16 wTextFlow;
+
+ /**
+ * reserved
+ */
+ U16 unused72;
+
+ /**
+ * pgbProp page border properties. page border applies to:
+ * 0 all pages in this section
+ * 1 first page in this section
+ * 2 all pages in this section but first
+ * 3 whole document (all sections)
+ */
+ U16 pgbApplyTo:3;
+
+ /**
+ * page border depth:
+ * 0 in front
+ * 1 in back
+ */
+ U16 pgbPageDepth:2;
+
+ /**
+ * page border offset from:
+ * 0 offset from text
+ * 1 offset from edge of page
+ */
+ U16 pgbOffsetFrom:3;
+
+ /**
+ * reserved
+ */
+ U16 unused74_8:8;
+
+ /**
+ * default value is 12240 twipswidth of page
+ */
+ U32 xaPage;
+
+ /**
+ * default value is 15840 twipsheight of page
+ */
+ U32 yaPage;
+
+ /**
+ * used internally by Word
+ */
+ U32 xaPageNUp;
+
+ /**
+ * used internally by Word
+ */
+ U32 yaPageNUp;
+
+ /**
+ * default value is 1800 twipsleft margin
+ */
+ U32 dxaLeft;
+
+ /**
+ * default value is 1800 twipsright margin
+ */
+ U32 dxaRight;
+
+ /**
+ * default value is 1440 twipstop margin
+ */
+ S32 dyaTop;
+
+ /**
+ * default value is 1440 twipsbottom margin
+ */
+ S32 dyaBottom;
+
+ /**
+ * default value is 0 twips gutter width
+ */
+ U32 dzaGutter;
+
+ /**
+ * y position of top header measured from top edge of page.
+ */
+ U32 dyaHdrTop;
+
+ /**
+ * y position of bottom header measured from top edge of page.
+ */
+ U32 dyaHdrBottom;
+
+ /**
+ * number of columns in section - 1.
+ */
+ S16 ccolM1;
+
+ /**
+ * when == 1, columns are evenly spaced. Default value is 1.
+ */
+ S8 fEvenlySpaced;
+
+ /**
+ * reserved
+ */
+ U8 unused123;
+
+ /**
+ * distance that will be maintained between columns
+ */
+ S32 dxaColumns;
+
+ /**
+ * array of 89 longs that determine bounds of irregular width columns [Changed that to a
+ * vector for obvoius reasons (Werner)]
+ */
+ std::vector<U32> rgdxaColumnWidthSpacing;
+
+ /**
+ * used internally by Word
+ */
+ S32 dxaColumnWidth;
+
+ U8 dmOrientFirst;
+
+ /**
+ * used internally by Word
+ */
+ U8 fLayout;
+
+ /**
+ * reserved
+ */
+ U16 unused490;
+
+ /**
+ * multilevel autonumbering list data (see OLST definition)
+ */
+ OLST olstAnm;
+
+}; // SEP
+
+bool operator==(const SEP &lhs, const SEP &rhs);
+bool operator!=(const SEP &lhs, const SEP &rhs);
+
+
+/**
+ * Section Property Exceptions (SEPX)
+ */
+struct SEPX {
+ /**
+ * Creates an empty SEPX structure and sets the defaults
+ */
+ SEPX();
+ /**
+ * Simply calls read(...)
+ */
+ SEPX(OLEStreamReader *stream, bool preservePos=false);
+ /**
+ * Attention: This struct allocates memory on the heap
+ */
+ SEPX(const SEPX &rhs);
+ ~SEPX();
+
+ SEPX &operator=(const SEPX &rhs);
+
+ /**
+ * This method reads the SEPX structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ /**
+ * count of bytes in remainder of <b>SEPX.</b>
+ */
+ U16 cb;
+
+ /**
+ * list of sprms that encodes the differences between the properties of
+ * a section and Word's default section properties.
+ */
+ U8 *grpprl; // U8 grpprl[];
+
+private:
+ void clearInternal();
+
+}; // SEPX
+
+bool operator==(const SEPX &lhs, const SEPX &rhs);
+bool operator!=(const SEPX &lhs, const SEPX &rhs);
+
+
+/**
+ * STyle Definition (STD)
+ */
+/* This structure has been commented out because we can't handle it correctly
+ * Please don't try to fix it here in this file, but rather copy this broken
+ * structure definition and fix it in some auxilliary file. If you want to
+ * include that aux. file here, please change the template file.
+ */
+//struct STD {
+// /**
+// * Creates an empty STD structure and sets the defaults
+// */
+// STD();
+// /**
+// * Simply calls read(...)
+// */
+// STD(OLEStreamReader *stream, bool preservePos=false);
+// /**
+// * Attention: This struct allocates memory on the heap
+// */
+// STD(const STD &rhs);
+// ~STD();
+
+// STD &operator=(const STD &rhs);
+
+// /**
+// * This method reads the STD structure from the stream.
+// * If preservePos is true we push/pop the position of
+// * the stream to save the state. If it's false the state
+// * of stream will be changed!
+// */
+// bool read(OLEStreamReader *stream, bool preservePos=false);
+
+// /**
+// * Same as reading :)
+// */
+// bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+// /**
+// * Set all the fields to the inital value (default is 0)
+// */
+// void clear();
+
+// // Data
+// /**
+// * invariant style identifier
+// */
+// U16 sti:12;
+
+// /**
+// * spare field for any temporary use, always reset back to zero!
+// */
+// U16 fScratch:1;
+
+// /**
+// * PHEs of all text with this style are wrong
+// */
+// U16 fInvalHeight:1;
+
+// /**
+// * UPEs have been generated
+// */
+// U16 fHasUpe:1;
+
+// /**
+// * std has been mass-copied; if unused at save time, style should be deleted
+// */
+// U16 fMassCopy:1;
+
+// /**
+// * style type code
+// */
+// U16 sgc:4;
+
+// /**
+// * base style
+// */
+// U16 istdBase:12;
+
+// /**
+// * # of UPXs (and UPEs)
+// */
+// U16 cupx:4;
+
+// /**
+// * next style
+// */
+// U16 istdNext:12;
+
+// /**
+// * offset to end of upx's, start of upe's
+// */
+// U16 bchUpe;
+
+// /**
+// * auto redefine style when appropriate
+// */
+// U16 fAutoRedef:1;
+
+// /**
+// * hidden from UI?
+// */
+// U16 fHidden:1;
+
+// /**
+// * unused bits
+// */
+// U16 unused8_3:14;
+
+// /**
+// * sub-names are separated by chDelimStyle
+// */
+// XCHAR *xstzName; // XCHAR xstzName[];
+
+// U8 *grupx; // U8 grupx[];
+
+// /**
+// * the UPEs are not stored on the file; they are a cache of the based-on
+// * chain
+// */
+// U8 *grupe; // U8 grupe[];
+
+//private:
+// void clearInternal();
+
+//}; // STD
+
+//bool operator==(const STD &lhs, const STD &rhs);
+//bool operator!=(const STD &lhs, const STD &rhs);
+
+
+/**
+ * STyleSHeet Information (STSHI)
+ */
+struct STSHI {
+ /**
+ * Creates an empty STSHI structure and sets the defaults
+ */
+ STSHI();
+ /**
+ * Simply calls read(...)
+ */
+ STSHI(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the STSHI structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * Count of styles in stylesheet
+ */
+ U16 cstd;
+
+ /**
+ * Length of STD Base as stored in a file
+ */
+ U16 cbSTDBaseInFile;
+
+ /**
+ * Are built-in stylenames stored?
+ */
+ U16 fStdStylenamesWritten:1;
+
+ /**
+ * Spare flags
+ */
+ U16 unused4_2:15;
+
+ /**
+ * Max sti known when this file was written
+ */
+ U16 stiMaxWhenSaved;
+
+ /**
+ * How many fixed-index istds are there?
+ */
+ U16 istdMaxFixedWhenSaved;
+
+ /**
+ * Current version of built-in stylenames
+ */
+ U16 nVerBuiltInNamesWhenSaved;
+
+ /**
+ * ftc used by StandardChpStsh for this document
+ */
+ U16 rgftcStandardChpStsh[3];
+
+}; // STSHI
+
+bool operator==(const STSHI &lhs, const STSHI &rhs);
+bool operator!=(const STSHI &lhs, const STSHI &rhs);
+
+
+/**
+ * WorK Book (WKB)
+ */
+struct WKB {
+ /**
+ * Creates an empty WKB structure and sets the defaults
+ */
+ WKB();
+ /**
+ * Simply calls read(...)
+ */
+ WKB(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * This method reads the WKB structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read(OLEStreamReader *stream, bool preservePos=false);
+
+ /**
+ * Same as reading :)
+ */
+ bool write(OLEStreamWriter *stream, bool preservePos=false) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Data
+ S16 fn;
+
+ U16 grfwkb;
+
+ S16 lvl;
+
+ U16 fnpt:4;
+
+ U16 fnpd:12;
+
+ /**
+ * unused
+ */
+ S32 doc;
+
+}; // WKB
+
+bool operator==(const WKB &lhs, const WKB &rhs);
+bool operator!=(const WKB &lhs, const WKB &rhs);
+
+
+
+
+} // namespace Word97
+
+} // namespace wvWare
+
+#endif // WORD97_GENERATED_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/word97_helper.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/word97_helper.cpp
new file mode 100644
index 00000000..14653e8b
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/word97_helper.cpp
@@ -0,0 +1,2344 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "word97_helper.h"
+#include "word95_helper.h"
+#include "word97_generated.h"
+#include "word95_generated.h"
+#include "convert.h"
+#include "olestream.h"
+#include "styles.h"
+#include "paragraphproperties.h"
+
+#include <string.h> // memcpy
+#include <algorithm>
+#include <functional> // std::bind2nd for gcc 2.9x
+
+#include "wvlog.h"
+
+namespace wvWare
+{
+
+namespace Word97
+{
+
+namespace SPRM
+{
+
+struct opcodeBits
+{
+ U16 ispmd:9;
+ U16 fSpec:1;
+ U16 sgc:3;
+ U16 spra:3;
+};
+
+// Apart from all the SPRMs in the documentation I added some from the OOo code.
+// Additionally there are some xyzFake entries, which are used to get Word 6 sprms
+// through the same code :-}
+typedef enum
+{
+ sprmNoop = 0x0000,
+ sprmCFRMarkDel = 0x0800,
+ sprmCFRMark = 0x0801,
+ sprmCFFldVanish = 0x0802,
+ sprmCFData = 0x0806,
+ sprmCFOle2 = 0x080A,
+ sprmCFBold = 0x0835,
+ sprmCFItalic = 0x0836,
+ sprmCFStrike = 0x0837,
+ sprmCFOutline = 0x0838,
+ sprmCFShadow = 0x0839,
+ sprmCFSmallCaps = 0x083A,
+ sprmCFCaps = 0x083B,
+ sprmCFVanish = 0x083C,
+ sprmCFImprint = 0x0854,
+ sprmCFSpec = 0x0855,
+ sprmCFObj = 0x0856,
+ sprmCFEmboss = 0x0858,
+ sprmCFBiDi = 0x085A,
+ sprmCFDiacColor = 0x085B,
+ sprmCFBoldBi = 0x085C,
+ sprmCFItalicBi = 0x085D,
+ sprmCFUsePgsuSettings = 0x0868,
+ sprmCUndocumented1 = 0x875,
+ sprmPJc = 0x2403,
+ sprmPJcFE = 0x2461, // Undocumented. According to OOo it's the asian equivalent to sprmPJc
+ sprmPFSideBySide = 0x2404,
+ sprmPFKeep = 0x2405,
+ sprmPFKeepFollow = 0x2406,
+ sprmPFPageBreakBefore = 0x2407,
+ sprmPBrcl = 0x2408,
+ sprmPBrcp = 0x2409,
+ sprmPFNoLineNumb = 0x240C,
+ sprmPFInTable = 0x2416,
+ sprmPFTtp = 0x2417,
+ sprmPWr = 0x2423,
+ sprmPFNoAutoHyph = 0x242A,
+ sprmPFLocked = 0x2430,
+ sprmPFWidowControl = 0x2431,
+ sprmPFKinsoku = 0x2433,
+ sprmPFWordWrap = 0x2434,
+ sprmPFOverflowPunct = 0x2435,
+ sprmPFTopLinePunct = 0x2436,
+ sprmPFAutoSpaceDE = 0x2437,
+ sprmPFAutoSpaceDN = 0x2438,
+ sprmPISnapBaseLine = 0x243B,
+ sprmPFBiDi = 0x2441,
+ sprmPFNumRMIns = 0x2443,
+ sprmPCrLf = 0x2444,
+ sprmPFUsePgsuSettings = 0x2447,
+ sprmPFAdjustRight = 0x2448,
+ sprmPNLvlAnmFake = 0x25FF, // Fake entry!
+ sprmPIncLvl = 0x2602,
+ sprmPIlvl = 0x260A,
+ sprmPPc = 0x261B,
+ sprmPOutLvl = 0x2640,
+ sprmCSfxText = 0x2859,
+ sprmCIdctHint = 0x286F,
+ sprmCHighlight = 0x2A0C,
+ sprmCFFtcAsciSymb = 0x2A10,
+ sprmCDefault = 0x2A32,
+ sprmCPlain = 0x2A33,
+ sprmCKcd = 0x2A34,
+ sprmCKul = 0x2A3E,
+ sprmCIco = 0x2A42,
+ sprmCHpsInc = 0x2A44,
+ sprmCHpsPosAdj = 0x2A46,
+ sprmCIss = 0x2A48,
+ sprmCFDStrike = 0x2A53,
+ sprmPicBrcl = 0x2E00,
+ sprmScnsPgn = 0x3000,
+ sprmSiHeadingPgn = 0x3001,
+ sprmSFEvenlySpaced = 0x3005,
+ sprmSFProtected = 0x3006,
+ sprmSBkc = 0x3009,
+ sprmSFTitlePage = 0x300A,
+ sprmSFAutoPgn = 0x300D,
+ sprmSNfcPgn = 0x300E,
+ sprmSFPgnRestart = 0x3011,
+ sprmSFEndnote = 0x3012,
+ sprmSLnc = 0x3013,
+ sprmSGprfIhdt = 0x3014,
+ sprmSLBetween = 0x3019,
+ sprmSVjc = 0x301A,
+ sprmSBOrientation = 0x301D,
+ sprmSBCustomize = 0x301E,
+ sprmSFBiDi = 0x3228,
+ sprmSFFacingCol = 0x3229,
+ sprmSFRTLGutter = 0x322A,
+ sprmTFCantSplit = 0x3403,
+ sprmTTableHeader = 0x3404,
+ sprmTUndocumented1 = 0x3615,
+ sprmPWHeightAbs = 0x442B,
+ sprmPDcs = 0x442C,
+ sprmPShd = 0x442D,
+ sprmPWAlignFont = 0x4439,
+ sprmPFrameTextFlow = 0x443A,
+ sprmPIstd = 0x4600,
+ sprmPIlfo = 0x460B,
+ sprmPNest = 0x4610,
+ sprmPBrcTop10 = 0x461C,
+ sprmPBrcLeft10 = 0x461D,
+ sprmPBrcBottom10 = 0x461E,
+ sprmPBrcRight10 = 0x461F,
+ sprmPBrcBetween10 = 0x4620,
+ sprmPBrcBar10 = 0x4621,
+ sprmPDxaFromText10 = 0x4622,
+ sprmCIbstRMark = 0x4804,
+ sprmCIdslRMark = 0x4807,
+ sprmCIdCharType = 0x480B,
+ sprmCHpsPos = 0x4845,
+ sprmCHpsKern = 0x484B,
+ sprmCYsri = 0x484E,
+ sprmCCharScale = 0x4852,
+ sprmCLidBi = 0x485F,
+ sprmCIbstRMarkDel = 0x4863,
+ sprmCShd80 = 0x4866,
+ sprmCIdslRMarkDel = 0x4867,
+ sprmCCpg = 0x486B,
+ sprmCRgLid0 = 0x486D,
+ sprmCRgLid1 = 0x486E,
+ sprmCRgLidUndocumented1 = 0x4873, // According to OOo it's equal to sprmCRgLid0
+ sprmCUndocumented2 = 0x4874,
+ sprmCIstd = 0x4A30,
+ sprmCFtcDefault = 0x4A3D,
+ sprmCLid = 0x4A41,
+ sprmCHps = 0x4A43,
+ sprmCHpsMul = 0x4A4D,
+ sprmCRgFtc0 = 0x4A4F,
+ sprmCRgFtc1 = 0x4A50,
+ sprmCRgFtc2 = 0x4A51,
+ sprmCFtcBi = 0x4A5E,
+ sprmCIcoBi = 0x4A60,
+ sprmCHpsBi = 0x4A61,
+ sprmSDmBinFirst = 0x5007,
+ sprmSDmBinOther = 0x5008,
+ sprmSCcolumns = 0x500B,
+ sprmSNLnnMod = 0x5015,
+ sprmSLnnMin = 0x501B,
+ sprmSPgnStart = 0x501C,
+ sprmSDmPaperReq = 0x5026,
+ sprmSClm = 0x5032,
+ sprmSTextFlow = 0x5033,
+ sprmSPgbProp = 0x522F,
+ sprmTJc = 0x5400,
+ sprmTFBiDi = 0x560B,
+ sprmTDelete = 0x5622,
+ sprmTMerge = 0x5624,
+ sprmTSplit = 0x5625,
+ sprmTUndocumented2 = 0x5664,
+ sprmPDyaLine = 0x6412,
+ sprmPBrcTop = 0x6424,
+ sprmPBrcLeft = 0x6425,
+ sprmPBrcBottom = 0x6426,
+ sprmPBrcRight = 0x6427,
+ sprmPBrcBetween = 0x6428,
+ sprmPBrcBar = 0x6629,
+ sprmPHugePapx = 0x6645,
+ sprmPHugePapx2 = 0x6646,
+ sprmPTableLevelUndoc = 0x6649, // Undocumented. According to OOo it's the table level
+ sprmCDttmRMark = 0x6805,
+ sprmCObjLocation = 0x680E,
+ sprmCDttmRMarkDel = 0x6864,
+ sprmCBrc = 0x6865,
+ sprmCCv = 0x6870,
+ sprmCPicLocation = 0x6A03,
+ sprmCSymbol = 0x6A09,
+ sprmPicBrcTop = 0x6C02,
+ sprmPicBrcLeft = 0x6C03,
+ sprmPicBrcBottom = 0x6C04,
+ sprmPicBrcRight = 0x6C05,
+ sprmSBrcTop = 0x702B,
+ sprmSBrcLeft = 0x702C,
+ sprmSBrcBottom = 0x702D,
+ sprmSBrcRight = 0x702E,
+ sprmSDxtCharSpace = 0x7030,
+ sprmTTlp = 0x740A,
+ sprmTHTMLProps = 0x740C,
+ sprmTInsert = 0x7621,
+ sprmTDxaCol = 0x7623,
+ sprmTSetShd = 0x7627,
+ sprmTSetShdOdd = 0x7628,
+ sprmTTextFlow = 0x7629,
+ sprmPDxaRight = 0x840E,
+ sprmPDxaRightFE = 0x845D, // Undocumented. According to OOo it's the asian equivalent to sprmPDxaRight
+ sprmPDxaLeft = 0x840F,
+ sprmPDxaLeftFE = 0x845E, // Undocumented. According to OOo it's the asian equivalent to sprmPDxaLeft
+ sprmPDxaLeft1 = 0x8411,
+ sprmPDxaLeft1FE = 0x8460, // Undocumented. According to OOo it's the asian equivalent to sprmPDxaLeft1
+ sprmPDxaAbs = 0x8418,
+ sprmPDyaAbs = 0x8419,
+ sprmPDxaWidth = 0x841A,
+ sprmPDyaFromText = 0x842E,
+ sprmPDxaFromText = 0x842F,
+ sprmCDxaSpace = 0x8840,
+ sprmSDxaColumns = 0x900C,
+ sprmSDxaLnn = 0x9016,
+ sprmSDyaTop = 0x9023,
+ sprmSDyaBottom = 0x9024,
+ sprmSDyaLinePitch = 0x9031,
+ sprmTDyaRowHeight = 0x9407,
+ sprmTDxaLeft = 0x9601,
+ sprmTDxaGapHalf = 0x9602,
+ sprmPDyaBefore = 0xA413,
+ sprmPDyaAfter = 0xA414,
+ sprmSDyaPgn = 0xB00F,
+ sprmSDxaPgn = 0xB010,
+ sprmSDyaHdrTop = 0xB017,
+ sprmSDyaHdrBottom = 0xB018,
+ sprmSXaPage = 0xB01F,
+ sprmSYaPage = 0xB020,
+ sprmSDxaLeft = 0xB021,
+ sprmSDxaRight = 0xB022,
+ sprmSDzaGutter = 0xB025,
+ sprmPIstdPermute = 0xC601,
+ sprmPChgTabsPapx = 0xC60D,
+ sprmPChgTabs = 0xC615,
+ sprmPRuler = 0xC632,
+ sprmPAnld = 0xC63E,
+ sprmPPropRMark = 0xC63F,
+ sprmPNumRM = 0xC645,
+ sprmPUndocumented1 = 0xC64E,
+ sprmPUndocumented2 = 0xC64F,
+ sprmPUndocumented3 = 0xC650,
+ sprmPUndocumented4 = 0xC651,
+ sprmCIstdPermute = 0xCA31,
+ sprmCMajority = 0xCA47,
+ sprmCHpsNew50 = 0xCA49,
+ sprmCHpsInc1 = 0xCA4A,
+ sprmCMajority50 = 0xCA4C,
+ sprmCPropRMark = 0xCA57,
+ sprmCDispFldRMark = 0xCA62,
+ sprmCShd = 0xCA71,
+ sprmPicScale = 0xCE01,
+ sprmSOlstAnm = 0xD202,
+ sprmSPropRMark = 0xD227,
+ sprmTTableBorders80 = 0xD605,
+ sprmTDefTable10 = 0xD606,
+ sprmTDefTable = 0xD608,
+ sprmTDefTableShd80 = 0xD609,
+ sprmTDefTableShd = 0xD612,
+ sprmTTableBorders = 0xD613,
+ sprmTDefTableShd2nd = 0xD616,
+ sprmTDefTableShd3rd = 0xD60C,
+ sprmTBrcTopCv = 0xD61A,
+ sprmTBrcLeftCv = 0xD61B,
+ sprmTBrcBottomCv = 0xD61C,
+ sprmTBrcRightCv = 0xD61D,
+ sprmTSetBrc80 = 0xD620,
+ sprmTSetBrc10 = 0xD626,
+ sprmTDiagLine = 0xD62A,
+ sprmTVertMerge = 0xD62B,
+ sprmTVertAlign = 0xD62C,
+ sprmTSetBrc = 0xD62F,
+ sprmTUndocumentedSpacing = 0xD632, // OOo: specific spacing
+ sprmTUndocumented8 = 0xD634,
+ sprmTUndocumented9 = 0xD660, // "something to do with color" (OOo)
+ sprmTCellBrcType = 0xD662,
+ sprmCChs = 0xEA08,
+ sprmCSizePos = 0xEA3F,
+ sprmSDxaColWidth = 0xF203,
+ sprmSDxaColSpacing = 0xF204,
+ sprmTUndocumented10 = 0xF614,
+ sprmTUndocumented11 = 0xF617,
+ sprmTUndocumented12 = 0xF618,
+ sprmTUndocumented13 = 0xF661
+} opcodes;
+
+// The length of the SPRM parameter
+U16 determineParameterLength( U16 sprm, const U8* in, WordVersion version )
+{
+ if ( version == Word8 ) {
+ static const char operandSizes[ 8 ] = { 1, 1, 2, 4, 2, 2, 0, 3 };
+
+ int index = ( sprm & 0xE000 ) >> 13;
+ if ( operandSizes[ index ] != 0 )
+ return operandSizes[ index ];
+ else {
+ // Get length of variable size operand.
+ switch ( sprm ) {
+ case sprmTDefTable10:
+ case sprmTDefTable:
+ return readU16( in ) + 1;
+ break;
+ case sprmPChgTabs:
+ if ( *in == 255 ) {
+ U8 itbdDelMax = in[ 1 ];
+ U8 itbdAddMax = in[ 1 + itbdDelMax * 4 ];
+ return 1 + itbdDelMax * 4 + itbdAddMax * 3;
+ }
+ else
+ return *in + 1;
+ break;
+ default:
+ return *in + 1;
+ break;
+ }
+ }
+ }
+ else { // Word67
+ if ( sprm > 255 )
+ wvlog << "Error: Trying to get the length of a flaky SPRM (" << sprm << ", 0x" << std::hex
+ << sprm << std::dec << ") via the Word 95 method!" << std::endl;
+ return Word95::SPRM::determineParameterLength( static_cast<U8>( sprm ), in );
+ }
+}
+
+// Apply a <T> grpprl of a given size ("count" bytes long)
+// This template function might be a bit sick, but it helps to
+// avoid duplicated code, so what ;)
+template<class T>
+void apply(T* const t,
+ S16 ( T::* applySPRM ) ( const U8*, const Style*, const StyleSheet*, OLEStreamReader*, WordVersion ),
+ const U8* grpprl, U16 count, const Style* style, const StyleSheet* styleSheet,
+ OLEStreamReader* dataStream, WordVersion version )
+{
+ if ( !grpprl )
+ return;
+
+ // We are using an integer here, that we can detect situations where
+ // we read beyond the limit due to a buggy spec/impl.
+ // The plain U16 would overflow and we'd be trapped in a loop.
+ int safeCount = count;
+
+ // walk through the grpprl, applying one sprm after the other
+ while ( safeCount > 1 ) {
+ S16 result = ( t->*applySPRM )( grpprl, style, styleSheet, dataStream, version );
+ if ( result == -1 ) {
+ U16 sprm;
+ if ( version == Word8 ) {
+ sprm = readU16( grpprl );
+ grpprl += 2;
+#ifdef WV2_DEBUG_SPRMS
+ wvlog << "Seems like that's a different SPRM (0x" << std::hex << sprm << std::dec << ")... skipping" << std::endl;
+#endif
+ }
+ else {
+ sprm = *grpprl++;
+#ifdef WV2_DEBUG_SPRMS
+ wvlog << "Seems like that's a different SPRM (" << sprm << ")... skipping" << std::endl;
+#endif
+ }
+
+ U16 len = determineParameterLength( sprm, grpprl, version );
+ grpprl += len;
+ safeCount -= len + ( version == Word8 ? 2 : 1 );
+ }
+ else {
+ grpprl += result;
+ safeCount -= result;
+ }
+ }
+ if ( safeCount < 0 )
+ wvlog << "Warning: We read past the end of the grpprl, buggy spec?" << std::endl;
+}
+
+U16 unzippedOpCode( U8 isprm )
+{
+ // Note: Changed sprmCFStrikeRM to sprmCFStrike and sprmPPnbrRMarkNot to sprmNoop
+ static const U16 lut[] = {
+ sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmPIncLvl, sprmPJc, sprmPFSideBySide,
+ sprmPFKeep, sprmPFKeepFollow, sprmPFPageBreakBefore, sprmPBrcl, sprmPBrcp,
+ sprmPIlvl, sprmNoop, sprmPFNoLineNumb, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
+ sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmPFInTable, sprmPFTtp,
+ sprmNoop, sprmNoop, sprmNoop, sprmPPc, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
+ sprmNoop, sprmNoop, sprmNoop, sprmPWr, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
+ sprmNoop, sprmNoop, sprmPFNoAutoHyph, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
+ sprmNoop, sprmPFLocked, sprmPFWidowControl, sprmNoop, sprmPFKinsoku, sprmPFWordWrap,
+ sprmPFOverflowPunct, sprmPFTopLinePunct, sprmPFAutoSpaceDE, sprmPFAutoSpaceDN,
+ sprmNoop, sprmNoop, sprmPISnapBaseLine, sprmNoop, sprmNoop, sprmNoop, sprmCFStrike,
+ sprmCFRMark, sprmCFFldVanish, sprmNoop, sprmNoop, sprmNoop, sprmCFData,
+ sprmNoop, sprmNoop, sprmNoop, sprmCFOle2, sprmNoop, sprmCHighlight, sprmCFEmboss,
+ sprmCSfxText, sprmNoop, sprmNoop, sprmNoop, sprmCPlain, sprmNoop, sprmCFBold,
+ sprmCFItalic, sprmCFStrike, sprmCFOutline, sprmCFShadow, sprmCFSmallCaps,
+ sprmCFCaps, sprmCFVanish, sprmNoop, sprmCKul, sprmNoop, sprmNoop, sprmNoop,
+ sprmCIco, sprmNoop, sprmCHpsInc, sprmNoop, sprmCHpsPosAdj, sprmNoop, sprmCIss,
+ sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
+ sprmNoop, sprmNoop, sprmCFDStrike, sprmCFImprint, sprmCFSpec, sprmCFObj,
+ sprmPicBrcl, sprmPOutLvl, sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
+ sprmNoop };
+
+ return lut[ isprm ];
+}
+
+/**
+ * Converts a Word 6/7 SPRM to a Word 8 one.
+ */
+U16 word6toWord8( U8 sprm )
+{
+ static const U16 lut[] = {
+ sprmNoop, sprmNoop, sprmPIstd, sprmPIstdPermute, sprmPIncLvl,
+ sprmPJc, sprmPFSideBySide, sprmPFKeep, sprmPFKeepFollow, sprmPFPageBreakBefore,
+ sprmPBrcl, sprmPBrcp, sprmPAnld, sprmPNLvlAnmFake, sprmPFNoLineNumb,
+ sprmPChgTabsPapx, sprmPDxaRight, sprmPDxaLeft, sprmPNest, sprmPDxaLeft1,
+ sprmPDyaLine, sprmPDyaBefore, sprmPDyaAfter, sprmPChgTabs, sprmPFInTable,
+ sprmPFTtp, sprmPDxaAbs, sprmPDyaAbs, sprmPDxaWidth, sprmPPc,
+ sprmPBrcTop10, sprmPBrcLeft10, sprmPBrcBottom10, sprmPBrcRight10, sprmPBrcBetween10,
+ sprmPBrcBar10, sprmPDxaFromText10, sprmPWr, sprmPBrcTop, sprmPBrcLeft,
+ sprmPBrcBottom, sprmPBrcRight, sprmPBrcBetween, sprmPBrcBar, sprmPFNoAutoHyph,
+ sprmPWHeightAbs, sprmPDcs, sprmPShd, sprmPDyaFromText, sprmPDxaFromText,
+ sprmPFLocked, sprmPFWidowControl, sprmPRuler, sprmNoop, sprmNoop,
+ sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
+ sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
+ sprmCFRMarkDel, sprmCFRMark, sprmCFFldVanish, sprmCPicLocation, sprmCIbstRMark,
+ sprmCDttmRMark, sprmCFData, sprmCIdslRMark, sprmCChs, sprmCSymbol,
+ sprmCFOle2, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
+ sprmCIstd, sprmCIstdPermute, sprmCDefault, sprmCPlain, sprmNoop,
+ sprmCFBold, sprmCFItalic, sprmCFStrike, sprmCFOutline, sprmCFShadow,
+ sprmCFSmallCaps, sprmCFCaps, sprmCFVanish, sprmCFtcDefault, sprmCKul,
+ sprmCSizePos, sprmCDxaSpace, sprmCLid, sprmCIco, sprmCHps,
+ sprmCHpsInc, sprmCHpsPos, sprmCHpsPosAdj, sprmCMajority, sprmCIss,
+ sprmCHpsNew50, sprmCHpsInc1, sprmCHpsKern, sprmCMajority50, sprmCHpsMul,
+ sprmCYsri, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
+ sprmNoop, sprmNoop, sprmCFSpec, sprmCFObj, sprmPicBrcl,
+ sprmPicScale, sprmPicBrcTop, sprmPicBrcLeft, sprmPicBrcBottom, sprmPicBrcRight,
+ sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
+ sprmNoop, sprmScnsPgn, sprmSiHeadingPgn, sprmSOlstAnm, sprmNoop,
+ sprmNoop, sprmSDxaColWidth, sprmSDxaColSpacing, sprmSFEvenlySpaced, sprmSFProtected,
+ sprmSDmBinFirst, sprmSDmBinOther, sprmSBkc, sprmSFTitlePage, sprmSCcolumns,
+ sprmSDxaColumns, sprmSFAutoPgn, sprmSNfcPgn, sprmSDyaPgn, sprmSDxaPgn,
+ sprmSFPgnRestart, sprmSFEndnote, sprmSLnc, sprmSGprfIhdt, sprmSNLnnMod,
+ sprmSDxaLnn, sprmSDyaHdrTop, sprmSDyaHdrBottom, sprmSLBetween, sprmSVjc,
+ sprmSLnnMin, sprmSPgnStart, sprmSBOrientation, sprmSBCustomize, sprmSXaPage,
+ sprmSYaPage, sprmSDxaLeft, sprmSDxaRight, sprmSDyaTop, sprmSDyaBottom,
+ sprmSDzaGutter, sprmSDmPaperReq, sprmNoop, sprmNoop, sprmNoop,
+ sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
+ sprmNoop, sprmNoop, sprmTJc, sprmTDxaLeft, sprmTDxaGapHalf,
+ sprmTFCantSplit, sprmTTableHeader, sprmTTableBorders80, sprmTDefTable10, sprmTDyaRowHeight,
+ sprmTDefTable, sprmTDefTableShd80, sprmTTlp, sprmTSetBrc80, sprmTInsert,
+ sprmTDelete, sprmTDxaCol, sprmTMerge, sprmTSplit, sprmTSetBrc10,
+ sprmTSetShd };
+
+ U16 s;
+ if ( sprm > 200 )
+ s = sprmNoop;
+ else
+ s = lut[ sprm ];
+ if ( s == sprmNoop )
+ wvlog << "Warning: Got a Word 6 " << static_cast<int>( sprm ) << " and return a noop!" << std::endl;
+ return s;
+}
+
+} // namespace SPRM
+
+
+ParagraphProperties* initPAPFromStyle( const U8* exceptions, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version )
+{
+ ParagraphProperties* properties = 0;
+ if ( exceptions == 0 ) {
+ if ( !styleSheet ) {
+ wvlog << "Warning: Couldn't read from the stylesheet." << std::endl;
+ return new ParagraphProperties();
+ }
+ const Style* normal = styleSheet->styleByID( 0 ); // stiNormal == 0x0000
+ if ( normal )
+ properties = new ParagraphProperties( normal->paragraphProperties() );
+ else
+ properties = new ParagraphProperties();
+ }
+ else {
+ int cb = static_cast<int>( *exceptions++ ) << 1; // Count of words (x2) -> count of bytes
+ if ( cb == 0 ) { // odd PAPX -> skip the padding byte
+ cb = static_cast<int>( *exceptions++ ) << 1;
+ cb -= 2;
+ }
+ else
+ cb -= version == Word8 ? 3 : 2; // Don't ask me, why Word 6/7 only needs -2 bytes
+
+ U16 tmpIstd = readU16( exceptions );
+ exceptions += 2;
+
+ const Style* style = 0;
+ if ( styleSheet ) {
+ style = styleSheet->styleByIndex( tmpIstd );
+ if ( style )
+ properties = new ParagraphProperties( style->paragraphProperties() );
+ else {
+ wvlog << "Warning: Couldn't read from the style, just applying the PAPX." << std::endl;
+ properties = new ParagraphProperties();
+ }
+ }
+ else {
+ wvlog << "Warning: Couldn't read from the stylesheet, just applying the PAPX." << std::endl;
+ properties = new ParagraphProperties();
+ }
+
+ properties->pap().istd = tmpIstd;
+
+ cb = cb < 0 ? 0 : cb; // safety :-}
+ // Note: The caller also has to override the PHE from this
+ // PAP with the PHE stored in the BX
+ properties->pap().apply( exceptions, cb, style, styleSheet, dataStream, version );
+ }
+ return properties;
+}
+
+Word97::TAP* initTAP( const U8* exceptions, OLEStreamReader* dataStream, WordVersion version )
+{
+ Word97::TAP* tap = new Word97::TAP;
+
+ if ( exceptions == 0 )
+ return tap;
+
+ int cb = static_cast<int>( *exceptions++ ) << 1; // Count of words (x2) -> count of bytes
+ if ( cb == 0 ) { // odd PAPX -> skip the padding byte
+ cb = static_cast<int>( *exceptions++ ) << 1;
+ cb -= 2;
+ }
+ else
+ cb -= 3;
+
+ exceptions += 2; // skip the istd
+ cb = cb < 0 ? 0 : cb; // safety :-}
+ tap->apply( exceptions, cb, 0, 0, dataStream, version ); // we don't need a style(sheet), do we?
+
+
+ return tap;
+}
+
+
+// Apply a PAP grpprl of a given size ("count" bytes long)
+void PAP::apply( const U8* grpprl, U16 count, const Style* style, const StyleSheet* styleSheet,
+ OLEStreamReader* dataStream, WordVersion version )
+{
+ // A PAP grpprl might contain TAP sprms, we just skip them
+ SPRM::apply<PAP>( this, &PAP::applyPAPSPRM, grpprl, count, style, styleSheet, dataStream, version );
+}
+
+ U32 icoToRGB(U16 ico)
+ {
+ switch(ico)
+ {
+ case 0: //default and we choose black as most paper is white
+ return 0xFF000000;
+ case 1://black
+ return 0x00000000;
+ case 2://blue
+ return 0x000000FF;
+ case 3://cyan
+ return 0x0000FFFF;
+ case 4://green
+ return 0x00008000;
+ case 5://magenta
+ return 0x00FF00FF;
+ case 6://red
+ return 0x00FF0000;
+ case 7://yellow
+ return 0x00FFFF00;
+ case 8://white
+ return 0x00FFFFFF;
+ case 9://dark blue
+ return 0x0000008B;
+ case 10://dark cyan
+ return 0x00008B8B;
+ case 11://dark green
+ return 0x00006400;
+ case 12://dark magenta
+ return 0x008B008B;
+ case 13://dark red
+ return 0x008B0000;
+ case 14://dark yellow
+ return 0x00808000;
+ case 15://dark gray
+ return 0x00A9A9A9;
+ case 16://light gray
+ return 0x00D3D3D3;
+
+ default:
+ return 0x000000;
+ }
+ }
+
+// Helper methods for the more complex sprms
+namespace
+{
+ // Adds the tabs of the sprmPChgTabs* sprms. Pass a pointer to the
+ // itbdAddMax and the vector
+ // Returns the number of tabs added
+ typedef std::vector<Word97::TabDescriptor> TabDescVector;
+ U8 addTabs( const U8* ptr, TabDescVector& rgdxaTab )
+ {
+ //wvlog << "Before adding the tabs: " << (int)rgdxaTab.size() << std::endl;
+ // Remember where the end was
+ const TabDescVector::size_type oldSize = rgdxaTab.size();
+ // Now append the new ones, we'll then sort the vector using inplace_merge
+ const U8 itbdAddMax = *ptr++;
+ //wvlog << " itbdAddMax=" << (int)itbdAddMax << std::endl;
+ for ( U8 i = 0 ; i < itbdAddMax ; ++i )
+ {
+ // #### We should probably add a proper constructor to TabDescriptor (Werner)
+ TabDescriptor descr;
+ descr.dxaTab = readS16( ptr + sizeof( S16 ) * i );
+ //wvlog << " dxaPos=" << descr.dxaTab << std::endl;
+ descr.tbd = TBD( readU8( ptr + sizeof( S16 ) * itbdAddMax + i ) );
+ rgdxaTab.push_back( descr );
+ }
+ if ( oldSize != 0 && itbdAddMax ) {
+ TabDescVector::iterator middle = rgdxaTab.begin();
+ middle += oldSize + 1u;
+ std::inplace_merge( rgdxaTab.begin(), middle, rgdxaTab.end() );
+ }
+ TabDescVector::iterator uend = std::unique( rgdxaTab.begin(), rgdxaTab.end() );
+ if ( uend != rgdxaTab.end() )
+ rgdxaTab.erase( uend, rgdxaTab.end() );
+ //wvlog << "After applying sprmPChgTabs(Papx) : " << (int)rgdxaTab.size() << std::endl;
+ return itbdAddMax;
+ }
+
+ // A zone where tabstops are forbidden, needed for sprmPChgTabs
+ struct Zone
+ {
+ Zone( const U8* ptr, U8 index, U8 itbdDelMax )
+ {
+ m_center = readS16( ptr + index * sizeof( S16 ) );
+ // A negative value doesn't make sense here, right? Hmmm
+ m_plusMinus = std::abs( readS16( ptr + itbdDelMax * sizeof( S16 ) + index * sizeof( S16 ) ) );
+ }
+
+ bool contains( S16 position ) const { return m_center - m_plusMinus <= position && m_center + m_plusMinus >= position; }
+
+ S16 m_center;
+ S16 m_plusMinus;
+ };
+
+ struct InZone : public std::binary_function<TabDescriptor, Zone, bool>
+ {
+ bool operator()(const TabDescriptor &tab, const Zone& zone) const { return zone.contains( tab.dxaTab ); }
+ };
+
+ U16 getSPRM( const U8** ptr, WordVersion version, U16& sprmLength )
+ {
+ U16 sprm;
+ if ( version == Word8 ) {
+ sprm = readU16( *ptr );
+ ( *ptr ) += 2;
+ sprmLength = SPRM::determineParameterLength( sprm, *ptr, version ) + 2;
+ }
+ else {
+ sprm = **ptr;
+ ++( *ptr );
+ sprmLength = SPRM::determineParameterLength( sprm, *ptr, version ) + 1;
+ sprm = SPRM::word6toWord8( sprm ); // "fix" it for the Word 8 switch statements below
+ }
+ return sprm;
+ }
+
+ void readBRC( BRC& brc, const U8* ptr, WordVersion version )
+ {
+ if ( version == Word8 )
+ brc.readPtr( ptr );
+ else
+ brc = toWord97( Word95::BRC( ptr ) );
+ }
+}
+
+// Returns -1 if this wasn't a PAP sprm and it returns the length
+// of the applied sprm if it was successful
+S16 PAP::applyPAPSPRM( const U8* ptr, const Style* style, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version )
+{
+ U16 sprmLength;
+ const U16 sprm( getSPRM( &ptr, version, sprmLength ) );
+#ifdef WV2_DEBUG_SPRMS
+ wvlog << "got a sprm: 0x" << std::hex << sprm << std::dec << std::endl;
+#endif
+
+ // Is it a PAP sprm?
+ if ( ( ( sprm & 0x1C00 ) >> 10 ) != 1 ) {
+#ifdef WV2_DEBUG_SPRMS
+ wvlog << "Warning: You're trying to apply a non PAP sprm to a PAP. Not necessarily bad." << std::endl;
+#endif
+ return -1; // tell the caller to try with something else (e.g. applying a TAP)...
+ }
+ // which one? ;)
+ switch ( sprm ) {
+ case SPRM::sprmNoop:
+ wvlog << "Huh? Found a sprmNoop..." << std::endl;
+ break;
+ case SPRM::sprmPIstd:
+ istd = readU16( ptr );
+ break;
+ case SPRM::sprmPIstdPermute:
+ {
+ const U8* myPtr = ptr + 3; // cch, fLongg, fSpare
+ const U16 istdFirst = readU16( myPtr );
+ myPtr += 2;
+ const U16 istdLast = readU16( myPtr );
+ myPtr += 2;
+ if ( istd > istdFirst && istd <= istdLast )
+ istd = myPtr[ istd - istdFirst ];
+ break;
+ }
+ case SPRM::sprmPIncLvl:
+ // Applies only to list styles, note: SPEC defect, there's no stc anymore
+ if ( istd >= 1 && istd <= 9 ) {
+ istd += static_cast<S8>( *ptr );
+ lvl += static_cast<S8>( *ptr );
+ }
+ break;
+ case SPRM::sprmPJc:
+ case SPRM::sprmPJcFE: // asian version, according to OOo (fall-through intended)
+ jc = *ptr;
+ break;
+ case SPRM::sprmPFSideBySide:
+ fSideBySide = *ptr == 1;
+ break;
+ case SPRM::sprmPFKeep:
+ fKeep = *ptr == 1;
+ break;
+ case SPRM::sprmPFKeepFollow:
+ fKeepFollow = *ptr == 1;
+ break;
+ case SPRM::sprmPFPageBreakBefore:
+ fPageBreakBefore = *ptr == 1;
+ break;
+ case SPRM::sprmPBrcl:
+ brcl = *ptr;
+ break;
+ case SPRM::sprmPBrcp:
+ brcp = *ptr;
+ break;
+ case SPRM::sprmPIlvl:
+ ilvl = *ptr;
+ break;
+ case SPRM::sprmPIlfo:
+ ilfo = readS16( ptr );
+ break;
+ case SPRM::sprmPFNoLineNumb:
+ fNoLnn = *ptr == 1;
+ break;
+ case SPRM::sprmPChgTabsPapx:
+ {
+ const U8* myPtr = ptr;
+ U8 cch = *myPtr++;
+ U8 itbdDelMax = *myPtr++;
+ std::vector<Word97::TabDescriptor>::iterator tabIt = rgdxaTab.begin();
+ //wvlog << "Applying sprmPChgTabsPapx. itbdDelMax=" << (int)itbdDelMax << std::endl;
+ // First the 'to be deleted' array
+ for ( U8 i = 0 ; i < itbdDelMax ; ++i )
+ {
+ TabDescriptor testDescr;
+ testDescr.dxaTab = readS16( myPtr );
+ myPtr += 2;
+ // Look for this one, starting at last position (they are sorted)
+ tabIt = std::find( tabIt, rgdxaTab.end(), testDescr );
+ if ( tabIt != rgdxaTab.end() )
+ {
+ tabIt = rgdxaTab.erase( tabIt );
+ itbdMac--;
+ }
+ }
+ U8 itbdAddMax = addTabs( myPtr, rgdxaTab );
+ itbdMac += itbdAddMax;
+
+ //wvlog << "After applying sprmPChgTabsPapx : " << (int)rgdxaTab.size() << std::endl;
+
+ if ( cch != 1 + 2 * itbdDelMax + 1 + 3 * itbdAddMax )
+ wvlog << "Offset problem in sprmPChgTabsPapx. cch=" << static_cast<int>( cch ) << " data size=" << 1 + 2 * itbdDelMax + 1 + 3 * itbdAddMax << std::endl;
+ break;
+ }
+ case SPRM::sprmPDxaRight:
+ case SPRM::sprmPDxaRightFE: // asian version, according to OOo (fall-through intended)
+ dxaRight = readS16( ptr );
+ break;
+ case SPRM::sprmPDxaLeft:
+ case SPRM::sprmPDxaLeftFE: // asian version, according to OOo (fall-through intended)
+ dxaLeft = readS16( ptr );
+ break;
+ case SPRM::sprmPNest:
+ dxaLeft += readS16( ptr );
+ dxaLeft = dxaLeft < 0 ? 0 : dxaLeft;
+ break;
+ case SPRM::sprmPDxaLeft1:
+ case SPRM::sprmPDxaLeft1FE: // asian version, according to OOo (fall-through intended)
+ dxaLeft1 = readS16( ptr );
+ break;
+ case SPRM::sprmPDyaLine:
+ lspd.dyaLine = readS16( ptr );
+ lspd.fMultLinespace = readS16( ptr + 2 );
+ break;
+ case SPRM::sprmPDyaBefore:
+ dyaBefore = readU16( ptr );
+ break;
+ case SPRM::sprmPDyaAfter:
+ dyaAfter = readU16( ptr );
+ break;
+ case SPRM::sprmPChgTabs:
+ {
+ const U8* myPtr = ptr;
+ const U8 cch = *myPtr++;
+ const U8 itbdDelMax = *myPtr++;
+ // Remove the tabs within the deletion zones
+ std::vector<TabDescriptor>::iterator newEnd = rgdxaTab.end();
+ for ( U8 i = 0; i < itbdDelMax; ++i )
+ newEnd = std::remove_if ( rgdxaTab.begin(), newEnd, std::bind2nd( InZone(), Zone( myPtr, i, itbdDelMax ) ) );
+ rgdxaTab.erase( newEnd, rgdxaTab.end() ); // really get rid of them
+ itbdMac = rgdxaTab.size();
+
+ // Add the new tabs
+ myPtr += itbdDelMax * 4;
+ U8 itbdAddMax = addTabs( myPtr, rgdxaTab );
+ itbdMac += itbdAddMax;
+
+ if ( cch != 255 && cch != 1 + 4 * itbdDelMax + 1 + 3 * itbdAddMax )
+ wvlog << "Offset problem in sprmPChgTabs. cch=" << static_cast<int>( cch ) << " data size=" << 1 + 4 * itbdDelMax + 1 + 3 * itbdAddMax << std::endl;
+ //wvlog << "SPRM::sprmPChgTabs done ### " << rgdxaTab.size() << std::endl;
+ break;
+ }
+ case SPRM::sprmPFInTable:
+ fInTable = *ptr == 1;
+ break;
+ case SPRM::sprmPFTtp:
+ fTtp = *ptr == 1;
+ break;
+ case SPRM::sprmPDxaAbs:
+ dxaAbs = readS16( ptr );
+ break;
+ case SPRM::sprmPDyaAbs:
+ dyaAbs = readS16( ptr );
+ break;
+ case SPRM::sprmPDxaWidth:
+ dxaWidth = readS16( ptr );
+ break;
+ case SPRM::sprmPPc:
+ {
+ U8 pcTmp = ( *ptr & 0x30 ) >> 4;
+ if ( pcTmp != 3 )
+ pcVert = pcTmp;
+ pcTmp = ( *ptr & 0xC0 ) >> 6;
+ if ( pcTmp != 3 )
+ pcHorz = pcTmp;
+ break;
+ }
+ case SPRM::sprmPBrcTop10:
+ wvlog << "Warning: sprmPBrcTop10 doesn't make sense for Word 8" << std::endl;
+ break;
+ case SPRM::sprmPBrcLeft10:
+ wvlog << "Warning: sprmPBrcLeft10 doesn't make sense for Word 8" << std::endl;
+ break;
+ case SPRM::sprmPBrcBottom10:
+ wvlog << "Warning: sprmPBrcBottom10 doesn't make sense for Word 8" << std::endl;
+ break;
+ case SPRM::sprmPBrcRight10:
+ wvlog << "Warning: sprmPBrcRight10 doesn't make sense for Word 8" << std::endl;
+ break;
+ case SPRM::sprmPBrcBetween10:
+ wvlog << "Warning: sprmPBrcBetween10 doesn't make sense for Word 8" << std::endl;
+ break;
+ case SPRM::sprmPBrcBar10:
+ wvlog << "Warning: sprmPBrcBar10 doesn't make sense for Word 8" << std::endl;
+ break;
+ case SPRM::sprmPDxaFromText10:
+ wvlog << "Warning: sprmPDxaFromText10 doesn't make sense for Word 8" << std::endl;
+ break;
+ case SPRM::sprmPWr:
+ wr = *ptr;
+ break;
+ case SPRM::sprmPBrcTop:
+ readBRC( brcTop, ptr, version );
+ break;
+ case SPRM::sprmPBrcLeft:
+ readBRC( brcLeft, ptr, version );
+ break;
+ case SPRM::sprmPBrcBottom:
+ readBRC( brcBottom, ptr, version );
+ break;
+ case SPRM::sprmPBrcRight:
+ readBRC( brcRight, ptr, version );
+ break;
+ case SPRM::sprmPBrcBetween:
+ readBRC( brcBetween, ptr, version );
+ break;
+ case SPRM::sprmPBrcBar:
+ readBRC( brcBar, ptr, version );
+ break;
+ case SPRM::sprmPFNoAutoHyph:
+ fNoAutoHyph = *ptr == 1;
+ break;
+ case SPRM::sprmPWHeightAbs:
+ // Seems to be undocumented...
+ wvlog << "Warning: sprmPWHeightAbs not implemented" << std::endl;
+ break;
+ case SPRM::sprmPDcs:
+ dcs.readPtr( ptr );
+ break;
+ case SPRM::sprmPShd:
+ shd.readPtr( ptr );
+ break;
+ case SPRM::sprmPDyaFromText:
+ dyaFromText = readS16( ptr );
+ break;
+ case SPRM::sprmPDxaFromText:
+ dxaFromText = readS16( ptr );
+ break;
+ case SPRM::sprmPFLocked:
+ fLocked = *ptr == 1;
+ break;
+ case SPRM::sprmPFWidowControl:
+ fWidowControl = *ptr == 1;
+ break;
+ case SPRM::sprmPRuler:
+ wvlog << "Warning: sprmPRuler not implemented" << std::endl;
+ break;
+ case SPRM::sprmPFKinsoku:
+ fKinsoku = *ptr == 1;
+ break;
+ case SPRM::sprmPFWordWrap:
+ fWordWrap = *ptr == 1;
+ break;
+ case SPRM::sprmPFOverflowPunct:
+ fOverflowPunct = *ptr == 1;
+ break;
+ case SPRM::sprmPFTopLinePunct:
+ fTopLinePunct = *ptr == 1;
+ break;
+ case SPRM::sprmPFAutoSpaceDE:
+ fAutoSpaceDE = *ptr == 1;
+ break;
+ case SPRM::sprmPFAutoSpaceDN:
+ fAutoSpaceDN = *ptr == 1;
+ break;
+ case SPRM::sprmPWAlignFont:
+ wAlignFont = readU16( ptr );
+ break;
+ case SPRM::sprmPFrameTextFlow:
+ wvlog << "Warning: sprmPFrameTextFlow not implemented" << std::endl;
+ break;
+ case SPRM::sprmPISnapBaseLine:
+ wvlog << "Warning: sprmPISnapBaseLine is obsolete" << std::endl;
+ break;
+ case SPRM::sprmPAnld:
+ if ( version == Word8 )
+ anld.readPtr( ptr + 1 ); // variable length, skip lenght byte
+ else
+ anld = toWord97( Word95::ANLD( ptr + 1 ) );
+ break;
+ case SPRM::sprmPPropRMark:
+ fPropRMark = *( ptr + 1 );
+ ibstPropRMark = readS16( ptr + 2 );
+ dttmPropRMark.readPtr( ptr + 4 );
+ break;
+ case SPRM::sprmPOutLvl:
+ lvl = readS8( ptr );
+ break;
+ case SPRM::sprmPFBiDi:
+ fBiDi = readS8( ptr );
+ break;
+ case SPRM::sprmPFNumRMIns:
+ fNumRMIns = *ptr == 1;
+ break;
+ case SPRM::sprmPCrLf:
+ fCrLf = *ptr;
+ break;
+ case SPRM::sprmPNumRM:
+ numrm.readPtr( ptr + 1 );
+ break;
+ case SPRM::sprmPHugePapx:
+ case SPRM::sprmPHugePapx2:
+ {
+ if ( dataStream ) {
+ dataStream->push();
+ dataStream->seek( readU32( ptr ), G_SEEK_SET );
+ const U16 count( dataStream->readU16() );
+ U8* grpprl = new U8[ count ];
+ dataStream->read( grpprl, count );
+ dataStream->pop();
+
+ apply( grpprl, count, style, styleSheet, dataStream, version );
+ delete [] grpprl;
+ }
+ else
+ wvlog << "Error: sprmPHugePapx found, but no data stream!" << std::endl;
+ break;
+ }
+ case SPRM::sprmPFUsePgsuSettings:
+ fUsePgsuSettings = *ptr == 1;
+ break;
+ case SPRM::sprmPFAdjustRight:
+ fAdjustRight = *ptr == 1;
+ break;
+ case SPRM::sprmPNLvlAnmFake:
+ nLvlAnm = *ptr;
+ break;
+ case SPRM::sprmPTableLevelUndoc:
+ // No idea if we have to use that one... for Word 2000 or newer it's there
+ if ( readU32( ptr ) != 1 )
+ wvlog << "++++++++++++++++ Table level=" << readU32( ptr ) << std::endl;
+ break;
+ case SPRM::sprmPUndocumented1:
+ case SPRM::sprmPUndocumented2:
+ case SPRM::sprmPUndocumented3:
+ case SPRM::sprmPUndocumented4:
+ break;
+ default:
+ wvlog << "Huh? None of the defined sprms matches 0x" << std::hex << sprm << std::dec << "... trying to skip anyway" << std::endl;
+ break;
+ }
+ return static_cast<S16>( sprmLength ); // length of the SPRM
+}
+
+// Apply a CHP grpprl of a given size ("count" bytes long)
+void CHP::apply( const U8* grpprl, U16 count, const Style* paragraphStyle, const StyleSheet* styleSheet,
+ OLEStreamReader* dataStream, WordVersion version )
+{
+ // There should be only CHP sprms in the grpprl we get
+ SPRM::apply<CHP>( this, &CHP::applyCHPSPRM, grpprl, count, paragraphStyle, styleSheet, dataStream, version );
+}
+
+void CHP::applyExceptions( const U8* exceptions, const Style* paragraphStyle, const StyleSheet* styleSheet,
+ OLEStreamReader* dataStream, WordVersion version )
+{
+ if ( exceptions == 0 )
+ return;
+ U8 cb = *exceptions;
+ ++exceptions;
+ apply( exceptions, cb, paragraphStyle, styleSheet, dataStream, version );
+}
+
+// Helper functions for more complex sprms
+namespace
+{
+ const Word97::CHP* determineCHP( U16 istd, const Style* paragraphStyle, const StyleSheet* styleSheet )
+ {
+ const Word97::CHP* chp( 0 );
+ if ( istd == 10 && paragraphStyle )
+ chp = &paragraphStyle->chp();
+ else if ( istd != 10 && styleSheet ) {
+ const Style* style( styleSheet->styleByIndex( istd ) );
+ chp = style != 0 && style->type() == Style::sgcChp ? &style->chp() : 0;
+ }
+ else
+ wvlog << "Warning: sprmCFxyz couldn't find a style" << std::endl;
+ return chp;
+ }
+}
+
+// Returns -1 if this wasn't a CHP sprm and it returns the length
+// of the applied sprm if it was successful
+S16 CHP::applyCHPSPRM( const U8* ptr, const Style* paragraphStyle, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version )
+{
+ U16 sprmLength;
+ const U16 sprm( getSPRM( &ptr, version, sprmLength ) );
+#ifdef WV2_DEBUG_SPRMS
+ wvlog << "got a sprm: 0x" << std::hex << sprm << std::dec << std::endl;
+#endif
+
+ // Is it a CHP sprm?
+ if ( ( ( sprm & 0x1C00 ) >> 10 ) != 2 ) {
+#ifdef WV2_DEBUG_SPRMS
+ wvlog << "Warning: You're trying to apply a non CHP sprm to a CHP. Not necessarily bad." << std::endl;
+#endif
+ return -1;
+ }
+ // which one? ;)
+ switch ( sprm ) {
+ case SPRM::sprmNoop:
+ wvlog << "Huh? Found a sprmNoop..." << std::endl;
+ break;
+ case SPRM::sprmCFRMarkDel:
+ fRMarkDel = *ptr == 1;
+ break;
+ case SPRM::sprmCFRMark:
+ fRMark = *ptr == 1;
+ break;
+ case SPRM::sprmCFFldVanish:
+ fFldVanish = *ptr == 1;
+ break;
+ case SPRM::sprmCPicLocation:
+ fSpec = 1;
+ fcPic_fcObj_lTagObj = readS32( ptr + ( version == Word8 ? 0 : 1 ) );
+ break;
+ case SPRM::sprmCIbstRMark:
+ ibstRMark = readS16( ptr );
+ break;
+ case SPRM::sprmCDttmRMark:
+ dttmRMark.readPtr( ptr );
+ break;
+ case SPRM::sprmCFData:
+ fData = *ptr == 1;
+ break;
+ case SPRM::sprmCIdslRMark:
+ idslRMReason = readS16( ptr );
+ break;
+ case SPRM::sprmCChs:
+ fChsDiff = *ptr == 1;
+ chse = readU16( ptr + 1 );
+ break;
+ case SPRM::sprmCSymbol:
+ // First the length byte...
+ ftcSym = readS16( ptr + 1 );
+ if ( version == Word8 )
+ xchSym = readS16( ptr + 3 );
+ else
+ xchSym = *( ptr + 3 );
+#ifdef WV2_DEBUG_SPRMS
+ wvlog << "sprmCSymbol: ftcSym=" << ftcSym << " xchSym=" << xchSym << std::endl;
+#endif
+ fSpec = 1;
+ break;
+ case SPRM::sprmCFOle2:
+ fOle2 = *ptr == 1;
+ break;
+ case SPRM::sprmCIdCharType:
+ wvlog << "Warning: sprmCIdCharType doesn't make sense for Word 8" << std::endl;
+ break;
+ case SPRM::sprmCHighlight:
+ icoHighlight = *ptr;
+ fHighlight = icoHighlight != 0 ? 1 : 0;
+ break;
+ case SPRM::sprmCObjLocation:
+ fcPic_fcObj_lTagObj = readU32( ptr );
+ break;
+ case SPRM::sprmCFFtcAsciSymb:
+ fFtcAsciSym = *ptr == 1;
+ break;
+ case SPRM::sprmCIstd:
+ {
+ wvlog << "######################## old character style = " << istd << std::endl;
+ istd = readS16( ptr );
+ if ( styleSheet ) {
+ wvlog << "Trying to change the character style to " << istd << std::endl;
+ const Style* style = styleSheet->styleByIndex( istd );
+ if ( style && style->type() == Style::sgcChp ) {
+ wvlog << "got a character style!" << std::endl;
+ const UPECHPX& upechpx( style->upechpx() );
+ apply( upechpx.grpprl, upechpx.cb, paragraphStyle, styleSheet, dataStream, version );
+ }
+ else
+ wvlog << "Warning: Couldn't find the character style with istd " << istd << std::endl;
+ }
+ else
+ wvlog << "Warning: Tried to change the character style, but the stylesheet was 0" << std::endl;
+ break;
+ }
+ case SPRM::sprmCIstdPermute:
+ {
+ const U8* myPtr = ptr + 3; // cch, fLongg, fSpare
+ const U16 istdFirst = readU16( myPtr );
+ myPtr += 2;
+ const U16 istdLast = readU16( myPtr );
+ myPtr += 2;
+ if ( istd > istdFirst && istd <= istdLast )
+ istd = myPtr[ istd - istdFirst ];
+ break;
+ }
+ case SPRM::sprmCDefault:
+ fBold = false;
+ fItalic = false;
+ fOutline = false;
+ fStrike = false;
+ fShadow = false;
+ fSmallCaps = false;
+ fCaps = false;
+ fVanish = false;
+ kul = 0;
+ cv = 0;
+ break;
+ case SPRM::sprmCPlain:
+ {
+ bool fSpecBackup = fSpec;
+ if ( paragraphStyle )
+ *this = paragraphStyle->chp();
+ fSpec = fSpecBackup;
+ break;
+ }
+ case SPRM::sprmCKcd:
+ kcd = *ptr;
+ break;
+ case SPRM::sprmCFBold:
+ if ( *ptr < 128 )
+ fBold = *ptr == 1;
+ else {
+ const Word97::CHP* chp( determineCHP( istd, paragraphStyle, styleSheet ) );
+ if ( *ptr == 128 && chp )
+ fBold = chp->fBold;
+ else if ( *ptr == 129 && chp )
+ fBold = !chp->fBold;
+ }
+ break;
+ case SPRM::sprmCFItalic:
+ if ( *ptr < 128 )
+ fItalic = *ptr == 1;
+ else {
+ const Word97::CHP* chp( determineCHP( istd, paragraphStyle, styleSheet ) );
+ if ( *ptr == 128 && chp )
+ fItalic = chp->fItalic;
+ else if ( *ptr == 129 && chp )
+ fItalic = !chp->fItalic;
+ }
+ break;
+ case SPRM::sprmCFStrike:
+ wvlog << "sprmCFStrike -- fStrike = " << static_cast<int>( fStrike ) << " *ptr = " << static_cast<int>( *ptr ) << std::endl;
+ if ( *ptr < 128 )
+ fStrike = *ptr == 1;
+ else {
+ const Word97::CHP* chp( determineCHP( istd, paragraphStyle, styleSheet ) );
+ if ( chp )
+ wvlog << "chp->fStrike = " << static_cast<int>( chp->fStrike ) << std::endl;
+ if ( *ptr == 128 && chp )
+ fStrike = chp->fStrike;
+ else if ( *ptr == 129 && chp )
+ fStrike = !chp->fStrike;
+ }
+ wvlog << "sprmCFStrike -- fStrike (changed) = " << static_cast<int>( fStrike ) << std::endl;
+ break;
+ case SPRM::sprmCFOutline:
+ if ( *ptr < 128 )
+ fOutline = *ptr == 1;
+ else {
+ const Word97::CHP* chp( determineCHP( istd, paragraphStyle, styleSheet ) );
+ if ( *ptr == 128 && chp )
+ fOutline = chp->fOutline;
+ else if ( *ptr == 129 && chp )
+ fOutline = !chp->fOutline;
+ }
+ break;
+ case SPRM::sprmCFShadow:
+ if ( *ptr < 128 )
+ fShadow = *ptr == 1;
+ else {
+ const Word97::CHP* chp( determineCHP( istd, paragraphStyle, styleSheet ) );
+ if ( *ptr == 128 && chp )
+ fShadow = chp->fShadow;
+ else if ( *ptr == 129 && chp )
+ fShadow = !chp->fShadow;
+ }
+ break;
+ case SPRM::sprmCFSmallCaps:
+ if ( *ptr < 128 )
+ fSmallCaps = *ptr == 1;
+ else {
+ const Word97::CHP* chp( determineCHP( istd, paragraphStyle, styleSheet ) );
+ if ( *ptr == 128 && chp )
+ fSmallCaps = chp->fSmallCaps;
+ else if ( *ptr == 129 && chp )
+ fSmallCaps = !chp->fSmallCaps;
+ }
+ break;
+ case SPRM::sprmCFCaps:
+ if ( *ptr < 128 )
+ fCaps = *ptr == 1;
+ else {
+ const Word97::CHP* chp( determineCHP( istd, paragraphStyle, styleSheet ) );
+ if ( *ptr == 128 && chp )
+ fCaps = chp->fCaps;
+ else if ( *ptr == 129 && chp )
+ fCaps = !chp->fCaps;
+ }
+ break;
+ case SPRM::sprmCFVanish:
+ if ( *ptr < 128 )
+ fVanish = *ptr == 1;
+ else {
+ const Word97::CHP* chp( determineCHP( istd, paragraphStyle, styleSheet ) );
+ if ( *ptr == 128 && chp )
+ fVanish = chp->fVanish;
+ else if ( *ptr == 129 && chp )
+ fVanish = !chp->fVanish;
+ }
+ break;
+ case SPRM::sprmCFtcDefault:
+ // We are abusing this SPRM for Word 6 purposes (sprmCFtc, 93)
+ //wvlog << "Error: sprmCFtcDefault only used internally in MS Word" << std::endl;
+ ftcAscii = ftcFE = ftcOther = ftc = readS16( ptr );
+ break;
+ case SPRM::sprmCKul:
+ kul = *ptr;
+ break;
+ case SPRM::sprmCSizePos:
+ // The hps sprms would be quite hard to implement in a sane way
+ wvlog << "Warning: sprmCSizePos not implemented" << std::endl;
+ break;
+ case SPRM::sprmCDxaSpace:
+ dxaSpace = readS16( ptr );
+ break;
+ case SPRM::sprmCLid:
+ // We are abusing this SPRM for Word 6 purposes (sprmCLid, 97)
+ lidDefault = lidFE = lid = readU16( ptr );
+ //wvlog << "Error: sprmCLid only used internally in MS Word" << std::endl;
+ break;
+ case SPRM::sprmCIco: {
+ U16 ico = *ptr;
+ cv=Word97::icoToRGB(ico);
+ break;
+ }
+ case SPRM::sprmCCv: {
+ U8 r,g,b,k;
+
+ r=readU8(ptr);
+ ptr+=sizeof(U8);
+ g=readU8(ptr);
+ ptr+=sizeof(U8);
+ b=readU8(ptr);
+ ptr+=sizeof(U8);
+ k=readU8(ptr);
+ ptr+=sizeof(U8);
+ cv=(k<<24)|(r<<16)|(g<<8)|(b);
+ break;
+ }
+ case SPRM::sprmCHps:
+ hps = readU16( ptr );
+ break;
+ case SPRM::sprmCHpsInc:
+ // The hps sprms would be quite hard to implement in a sane way
+ wvlog << "Warning: sprmCHpsInc not implemented" << std::endl;
+ break;
+ case SPRM::sprmCHpsPos:
+ hpsPos = readS16( ptr );
+ break;
+ case SPRM::sprmCHpsPosAdj:
+ // The hps sprms would be quite hard to implement in a sane way
+ wvlog << "Warning: sprmCHpsPosAdj not implemented" << std::endl;
+ break;
+ case SPRM::sprmCMajority:
+ case SPRM::sprmCMajority50: // same as sprmCMajority
+ {
+ CHP tmpChp;
+ tmpChp.ftc = 4; // the rest is default, looks a bit strange
+ tmpChp.apply( ptr + 1, *ptr, paragraphStyle, styleSheet, dataStream, version );
+ if ( paragraphStyle ) {
+ const CHP& pstyle( paragraphStyle->chp() );
+ if ( tmpChp.fBold == fBold )
+ fBold = pstyle.fBold;
+ if ( tmpChp.fItalic == fItalic )
+ fItalic = pstyle.fItalic;
+ if ( tmpChp.fStrike == fStrike )
+ fStrike = pstyle.fStrike;
+ if ( tmpChp.fOutline == fOutline )
+ fOutline = pstyle.fOutline;
+ if ( tmpChp.fShadow == fShadow )
+ fShadow = pstyle.fShadow;
+ if ( tmpChp.fSmallCaps == fSmallCaps )
+ fSmallCaps = pstyle.fSmallCaps;
+ if ( tmpChp.fCaps == fCaps )
+ fCaps = pstyle.fCaps;
+ if ( tmpChp.ftc == ftc )
+ ftc = pstyle.ftc;
+ if ( tmpChp.hps == hps )
+ hps = pstyle.hps;
+ if ( tmpChp.hpsPos == hpsPos )
+ hpsPos = pstyle.hpsPos;
+ if ( tmpChp.kul == kul )
+ kul = pstyle.kul;
+ if ( tmpChp.dxaSpace == dxaSpace ) // qpsSpace???
+ dxaSpace = pstyle.dxaSpace;
+ if ( tmpChp.cv == cv )
+ cv = pstyle.cv;
+ }
+ else
+ wvlog << "Warning: sprmCMajority couldn't find a style" << std::endl;
+ break;
+ }
+ case SPRM::sprmCIss:
+ iss = *ptr;
+ break;
+ case SPRM::sprmCHpsNew50:
+ if ( *ptr != 2 )
+ wvlog << "Warning: sprmCHpsNew50 has a different lenght than 2" << std::endl;
+ else
+ hps = readU16( ptr + 1 );
+ break;
+ case SPRM::sprmCHpsInc1:
+ // The hps sprms would be quite hard to implement in a sane way
+ wvlog << "Warning: sprmCHpsInc1 not implemented" << std::endl;
+ break;
+ case SPRM::sprmCHpsKern:
+ hpsKern = readU16( ptr );
+ break;
+ case SPRM::sprmCHpsMul:
+ hps = static_cast<int>( static_cast<double>( hps ) * ( 1.0 + static_cast<double>( readS16( ptr ) ) / 100.0 ) );
+ break;
+ case SPRM::sprmCYsri:
+ // Undocumented, no idea if that's implemented correctly
+ ysr = *ptr;
+ chYsr = *( ptr + 1 );
+ break;
+ case SPRM::sprmCRgFtc0:
+ ftcAscii = readS16( ptr );
+ break;
+ case SPRM::sprmCRgFtc1:
+ ftcFE = readS16( ptr );
+ break;
+ case SPRM::sprmCRgFtc2:
+ ftcOther = readS16( ptr );
+ break;
+ case SPRM::sprmCCharScale:
+ wCharScale = readU16( ptr ); // undocumented, but should be okay
+ break;
+ case SPRM::sprmCFDStrike:
+ fDStrike = *ptr == 1;
+ break;
+ case SPRM::sprmCFImprint:
+ if ( *ptr < 128 )
+ fImprint = *ptr == 1;
+ else if ( *ptr == 128 && paragraphStyle )
+ fImprint = paragraphStyle->chp().fImprint;
+ else if ( *ptr == 129 && paragraphStyle )
+ fImprint = !( paragraphStyle->chp().fImprint );
+ else
+ wvlog << "Warning: sprmCFImprint couldn't find a style" << std::endl;
+ break;
+ case SPRM::sprmCFSpec:
+ fSpec = *ptr == 1;
+ break;
+ case SPRM::sprmCFObj:
+ fObj = *ptr == 1;
+ break;
+ case SPRM::sprmCPropRMark:
+ if ( *ptr != 7 )
+ wvlog << "Error: sprmCPropRMark has an unexpected size" << std::endl;
+ fPropMark = *( ptr + 1 ) == 1;
+ ibstPropRMark = readS16( ptr + 2 );
+ dttmPropRMark.readPtr( ptr + 4 );
+ break;
+ case SPRM::sprmCFEmboss:
+ if ( *ptr < 128 )
+ fEmboss = *ptr == 1;
+ else if ( *ptr == 128 && paragraphStyle )
+ fEmboss = paragraphStyle->chp().fEmboss;
+ else if ( *ptr == 129 && paragraphStyle )
+ fEmboss = !( paragraphStyle->chp().fEmboss );
+ else
+ wvlog << "Warning: sprmCFEmboss couldn't find a style" << std::endl;
+ break;
+ case SPRM::sprmCSfxText:
+ sfxtText = *ptr;
+ break;
+ // All the BiDi flags below aren't documented. The question is whether we should
+ // add some BiDi versions of e.g. fBold and interpret these sprms here like plain
+ // sprmCFBold. For now I just ignore them, as the only user of wv2 is KWord, and
+ // KWord is intelligent enough to support BiDi "the right way." (Werner)
+ case SPRM::sprmCFBiDi:
+ // ###### Undocumented
+ //wvlog << "Warning: sprmCFBiDi not implemented" << std::endl;
+ break;
+ case SPRM::sprmCFDiacColor:
+ // ###### Undocumented
+ //wvlog << "Warning: sprmCFDiacColor not implemented" << std::endl;
+ break;
+ case SPRM::sprmCFBoldBi:
+ // ###### Undocumented
+ //wvlog << "Warning: sprmCFBoldBi not implemented" << std::endl;
+ break;
+ case SPRM::sprmCFItalicBi:
+ // ###### Undocumented
+ //wvlog << "Warning: sprmCFItalicBi not implemented" << std::endl;
+ break;
+ case SPRM::sprmCFtcBi:
+ // ###### Undocumented
+ //wvlog << "Warning: sprmCFtcBi not implemented" << std::endl;
+ break;
+ case SPRM::sprmCLidBi:
+ // OOo does something with that flag.
+ wvlog << "Warning: sprmCLidBi not implemented (no documentation available)" << std::endl;
+ break;
+ case SPRM::sprmCIcoBi:
+ // ###### Undocumented
+ //wvlog << "Warning: sprmCIcoBi not implemented" << std::endl;
+ break;
+ case SPRM::sprmCHpsBi:
+ // OOo does something with that flag.
+ wvlog << "Warning: sprmCHpsBi not implemented (no documentation available)" << std::endl;
+ break;
+ case SPRM::sprmCDispFldRMark:
+ {
+ if ( *ptr != 39 )
+ wvlog << "Warning: sprmCDispFldRMark has a different lenght than 39" << std::endl;
+ else {
+ fDispFldRMark = *( ptr + 1 ) == 1;
+ ibstDispFldRMark = readS16( ptr + 2 );
+ dttmPropRMark.readPtr( ptr + 4 );
+ for ( int i = 0; i < 16; ++i )
+ xstDispFldRMark[ i ] = readU16( ptr + 8 + i * sizeof( U16 ) );
+ }
+ break;
+ }
+ case SPRM::sprmCShd:
+ ptr++;
+ shd.read90Ptr( ptr );
+ break;
+ case SPRM::sprmCIbstRMarkDel:
+ ibstRMarkDel = readS16( ptr );
+ break;
+ case SPRM::sprmCDttmRMarkDel:
+ dttmRMarkDel.readPtr( ptr );
+ break;
+ case SPRM::sprmCBrc:
+ readBRC( brc, ptr, version );
+ break;
+ case SPRM::sprmCShd80:
+ shd.readPtr( ptr );
+ break;
+ case SPRM::sprmCIdslRMarkDel:
+ idslRMReasonDel = readS16( ptr );
+ break;
+ case SPRM::sprmCFUsePgsuSettings:
+ fUsePgsuSettings = *ptr == 1;
+ break;
+ case SPRM::sprmCCpg:
+ // Undocumented, no idea what this variable is for. I changed it to chse in
+ // the spec as it made more sense. (Werner)
+ //wvlog << "Warning: sprmCCpg not implemented" << std::endl;
+ break;
+ case SPRM::sprmCRgLid0:
+ case SPRM::sprmCRgLidUndocumented1: // according to OOo a dup. of sprmCRgLid0
+ lidDefault = readU16( ptr );
+ break;
+ case SPRM::sprmCRgLid1:
+ lidFE = readU16( ptr );
+ break;
+ case SPRM::sprmCIdctHint:
+ idct = *ptr;
+ break;
+ // Fall-through intended
+ case SPRM::sprmCUndocumented1:
+ case SPRM::sprmCUndocumented2:
+ break; // They are not documented but they are skipped correctly
+ default:
+ wvlog << "Huh? None of the defined sprms matches 0x" << std::hex << sprm << std::dec << "... trying to skip anyway" << std::endl;
+ break;
+ }
+ return static_cast<S16>( sprmLength ); // length of the SPRM
+}
+
+
+// Apply a PICF grpprl of a given size ("count" bytes long)
+void PICF::apply( const U8* grpprl, U16 count, const Style* style, const StyleSheet* styleSheet,
+ OLEStreamReader* dataStream, WordVersion version )
+{
+ // There should be only PICF sprms in the grpprl we get
+ SPRM::apply<PICF>( this, &PICF::applyPICFSPRM, grpprl, count, style, styleSheet, dataStream, version );
+}
+
+void PICF::applyExceptions(const U8* /*exceptions*/, const StyleSheet* /*stylesheet*/, OLEStreamReader* /*dataStream*/, WordVersion /*version*/ )
+{
+ // ### CHECK: Do we need that at all?
+}
+
+// Returns -1 if this wasn't a PICF sprm and it returns the length
+// of the applied sprm if it was successful
+S16 PICF::applyPICFSPRM( const U8* ptr, const Style* /*style*/, const StyleSheet* /*styleSheet*/,
+ OLEStreamReader* /*dataStream*/, WordVersion version )
+{
+ U16 sprmLength;
+ const U16 sprm( getSPRM( &ptr, version, sprmLength ) );
+
+ // Is it a PICF sprm?
+ if ( ( ( sprm & 0x1C00 ) >> 10 ) != 3 ) {
+ wvlog << "Warning: You're trying to apply a non PICF sprm to a PICF." << std::endl;
+ return -1;
+ }
+ // which one? ;)
+ switch ( sprm ) {
+ case SPRM::sprmNoop:
+ wvlog << "Huh? Found a sprmNoop..." << std::endl;
+ break;
+ case SPRM::sprmPicBrcl:
+ brcl = *ptr;
+ break;
+ case SPRM::sprmPicScale:
+ if ( *ptr != 12 )
+ wvlog << "Warning: sprmPicScale has a different size (" << static_cast<int>( *ptr )
+ << ") than expected (12)." << std::endl;
+ mx = readU16( ptr + 1 );
+ my = readU16( ptr + 3 );
+ dxaCropLeft = readU16( ptr + 5 );
+ dyaCropTop = readU16( ptr + 7 );
+ dxaCropRight = readU16( ptr + 9 );
+ dyaCropBottom = readU16( ptr + 11 );
+ break;
+ case SPRM::sprmPicBrcTop:
+ readBRC( brcTop, ptr, version );
+ break;
+ case SPRM::sprmPicBrcLeft:
+ readBRC( brcLeft, ptr, version );
+ break;
+ case SPRM::sprmPicBrcBottom:
+ readBRC( brcBottom, ptr, version );
+ break;
+ case SPRM::sprmPicBrcRight:
+ readBRC( brcRight, ptr, version );
+ break;
+ default:
+ wvlog << "Huh? None of the defined sprms matches 0x" << std::hex << sprm << std::dec << "... trying to skip anyway" << std::endl;
+ break;
+ }
+ return static_cast<S16>( sprmLength ); // length of the SPRM
+}
+
+
+// Apply a SEP grpprl of a given size ("count" bytes long)
+void SEP::apply( const U8* grpprl, U16 count, const Style* style, const StyleSheet* styleSheet,
+ OLEStreamReader* dataStream, WordVersion version )
+{
+ // There should be only SEP sprms in the grpprl we get
+ SPRM::apply<SEP>( this, &SEP::applySEPSPRM, grpprl, count, style, styleSheet, dataStream, version );
+}
+
+void SEP::applyExceptions( const U8* exceptions, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version )
+{
+ if ( exceptions == 0 )
+ return;
+ U16 cb = readU16( exceptions );
+ exceptions += 2;
+ apply( exceptions, cb, 0, styleSheet, dataStream, version );
+}
+
+// Returns -1 if this wasn't a SEP sprm and it returns the length
+// of the applied sprm if it was successful
+S16 SEP::applySEPSPRM( const U8* ptr, const Style* /*style*/, const StyleSheet* /*styleSheet*/, OLEStreamReader* /*dataStream*/, WordVersion version )
+{
+ U16 sprmLength;
+ const U16 sprm( getSPRM( &ptr, version, sprmLength ) );
+
+ // Is it a SEP sprm?
+ if ( ( ( sprm & 0x1C00 ) >> 10 ) != 4 ) {
+ wvlog << "Warning: You're trying to apply a non SEP sprm to a SEP." << std::endl;
+ return -1;
+ }
+ // which one? ;)
+ switch ( sprm ) {
+ case SPRM::sprmNoop:
+ wvlog << "Huh? Found a sprmNoop..." << std::endl;
+ break;
+ case SPRM::sprmScnsPgn:
+ cnsPgn = *ptr;
+ break;
+ case SPRM::sprmSiHeadingPgn:
+ iHeadingPgn = *ptr;
+ break;
+ case SPRM::sprmSOlstAnm:
+ if ( version == Word8 )
+ olstAnm.readPtr( ptr + 1 ); // variable length, skip length byte
+ else
+ olstAnm = toWord97( Word95::OLST( ptr + 1 ) );
+ break;
+ case SPRM::sprmSDxaColWidth:
+ wvlog << "Warning: sprmSDxaColWidth not implemented" << std::endl;
+ break;
+ case SPRM::sprmSDxaColSpacing:
+ wvlog << "Warning: sprmSDxaColSpacing not implemented" << std::endl;
+ break;
+ case SPRM::sprmSFEvenlySpaced:
+ fEvenlySpaced = *ptr == 1;
+ break;
+ case SPRM::sprmSFProtected:
+ fUnlocked = *ptr == 1;
+ break;
+ case SPRM::sprmSDmBinFirst:
+ dmBinFirst = readU16( ptr );
+ break;
+ case SPRM::sprmSDmBinOther:
+ dmBinOther = readU16( ptr );
+ break;
+ case SPRM::sprmSBkc:
+ bkc = *ptr;
+ break;
+ case SPRM::sprmSFTitlePage:
+ fTitlePage = *ptr == 1;
+ break;
+ case SPRM::sprmSCcolumns:
+ ccolM1 = readS16( ptr );
+ break;
+ case SPRM::sprmSDxaColumns:
+ dxaColumns = readS16( ptr );
+ break;
+ case SPRM::sprmSFAutoPgn:
+ fAutoPgn = *ptr == 1;
+ break;
+ case SPRM::sprmSNfcPgn:
+ nfcPgn = *ptr;
+ break;
+ case SPRM::sprmSDyaPgn:
+ dyaPgn = readS16( ptr );
+ break;
+ case SPRM::sprmSDxaPgn:
+ dxaPgn = readS16( ptr );
+ break;
+ case SPRM::sprmSFPgnRestart:
+ fPgnRestart = *ptr == 1;
+ break;
+ case SPRM::sprmSFEndnote:
+ fEndNote = *ptr == 1;
+ break;
+ case SPRM::sprmSLnc:
+ lnc = *ptr;
+ break;
+ case SPRM::sprmSGprfIhdt:
+ grpfIhdt = *ptr;
+ break;
+ case SPRM::sprmSNLnnMod:
+ nLnnMod = readU16( ptr );
+ break;
+ case SPRM::sprmSDxaLnn:
+ dxaLnn = readS16( ptr );
+ break;
+ case SPRM::sprmSDyaHdrTop:
+ dyaHdrTop = readU16( ptr );
+ break;
+ case SPRM::sprmSDyaHdrBottom:
+ dyaHdrBottom = readU16( ptr );
+ break;
+ case SPRM::sprmSLBetween:
+ fLBetween = *ptr == 1;
+ break;
+ case SPRM::sprmSVjc:
+ vjc = *ptr;
+ break;
+ case SPRM::sprmSLnnMin:
+ lnnMin = readS16( ptr );
+ break;
+ case SPRM::sprmSPgnStart:
+ pgnStart = readU16( ptr );
+ break;
+ case SPRM::sprmSBOrientation:
+ dmOrientPage = *ptr;
+ break;
+ case SPRM::sprmSBCustomize:
+ wvlog << "Warning: sprmSBCustomize not implemented" << std::endl;
+ break;
+ case SPRM::sprmSXaPage:
+ xaPage = readU16( ptr );
+ break;
+ case SPRM::sprmSYaPage:
+ yaPage = readU16( ptr );
+ break;
+ case SPRM::sprmSDxaLeft:
+ dxaLeft = readU16( ptr );
+ break;
+ case SPRM::sprmSDxaRight:
+ dxaRight = readU16( ptr );
+ break;
+ case SPRM::sprmSDyaTop:
+ dyaTop = readU16( ptr );
+ break;
+ case SPRM::sprmSDyaBottom:
+ dyaBottom = readU16( ptr );
+ break;
+ case SPRM::sprmSDzaGutter:
+ dzaGutter = readU16( ptr );
+ break;
+ case SPRM::sprmSDmPaperReq:
+ dmPaperReq = readU16( ptr );
+ break;
+ case SPRM::sprmSPropRMark:
+ fPropRMark = *( ptr + 1 );
+ ibstPropRMark = readS16( ptr + 2 );
+ dttmPropRMark.readPtr( ptr + 4 );
+ break;
+ case SPRM::sprmSFBiDi:
+ wvlog << "Warning: sprmSFBiDi not implemented" << std::endl;
+ break;
+ case SPRM::sprmSFFacingCol:
+ wvlog << "Warning: sprmSFFacingCol not implemented" << std::endl;
+ break;
+ case SPRM::sprmSFRTLGutter:
+ wvlog << "Warning: sprmSFRTLGutter not implemented" << std::endl;
+ break;
+ case SPRM::sprmSBrcTop:
+ readBRC( brcTop, ptr, version );
+ break;
+ case SPRM::sprmSBrcLeft:
+ readBRC( brcLeft, ptr, version );
+ break;
+ case SPRM::sprmSBrcBottom:
+ readBRC( brcBottom, ptr, version );
+ break;
+ case SPRM::sprmSBrcRight:
+ readBRC( brcRight, ptr, version );
+ break;
+ case SPRM::sprmSPgbProp:
+ {
+ U16 pgbProp = readU16( ptr );
+ pgbApplyTo = pgbProp;
+ pgbProp >>= 3;
+ pgbPageDepth = pgbProp;
+ pgbProp >>= 2;
+ pgbOffsetFrom = pgbProp;
+ pgbProp >>= 3;
+ unused74_8 = pgbProp;
+ break;
+ }
+ case SPRM::sprmSDxtCharSpace:
+ dxtCharSpace = readS32( ptr );
+ break;
+ case SPRM::sprmSDyaLinePitch:
+ dyaLinePitch = readS32( ptr );
+ break;
+ case SPRM::sprmSClm:
+ clm = readU16( ptr );
+ break;
+ case SPRM::sprmSTextFlow:
+ wTextFlow = readU16( ptr );
+ break;
+ default:
+ wvlog << "Huh? None of the defined sprms matches 0x" << std::hex << sprm << std::dec << "... trying to skip anyway" << std::endl;
+ break;
+ }
+ return static_cast<S16>( sprmLength ); // length of the SPRM
+}
+
+
+// Apply a TAP grpprl (or at least the TAP properties of a PAP/TAP grpprl)
+// of a given size ("count" bytes long)
+void TAP::apply( const U8* grpprl, U16 count, const Style* style, const StyleSheet* styleSheet,
+ OLEStreamReader* dataStream, WordVersion version )
+{
+ // There should be mostly TAP sprms in the grpprl we get, and we
+ // have to ignore the remaining PAP sprms, just what the template does
+ SPRM::apply<TAP>( this, &TAP::applyTAPSPRM, grpprl, count, style, styleSheet, dataStream, version );
+}
+
+void TAP::applyExceptions( const U8* /*exceptions*/, const StyleSheet* /*stylesheet*/, OLEStreamReader* /*dataStream*/, WordVersion /*version*/ )
+{
+ // ### TODO -- is that needed at all?
+}
+
+namespace
+{
+ void cropIndices( U8& itcFirst, U8& itcLim, U8 size )
+ {
+ if ( itcFirst >= size ) {
+ wvlog << "Warning: itcFirst out of bounds" << std::endl;
+ itcFirst = size - 1;
+ }
+ if ( itcLim > size ) {
+ wvlog << "Warning: itcLim out of bounds" << std::endl;
+ itcLim = size;
+ }
+ }
+}
+
+// Returns -1 if this wasn't a TAP sprm and it returns the length
+// of the applied sprm if it was successful
+S16 TAP::applyTAPSPRM( const U8* ptr, const Style* style, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version )
+{
+ U16 sprmLength;
+ const U16 sprm( getSPRM( &ptr, version, sprmLength ) );
+
+ // Is it a TAP sprm? Not really an error if it's none, as all TAP sprms live
+ // inside PAP grpprls
+ if ( ( ( sprm & 0x1C00 ) >> 10 ) != 5 && sprm != SPRM::sprmPHugePapx && sprm != SPRM::sprmPHugePapx2 ) {
+#ifdef WV2_DEBUG_SPRMS
+ wvlog << "Warning: You're trying to apply a non TAP sprm to a TAP. Not necessarily bad." << std::endl;
+#endif
+ return -1;
+ }
+ // which one? ;)
+ switch ( sprm ) {
+ case SPRM::sprmNoop:
+ wvlog << "Huh? Found a sprmNoop..." << std::endl;
+ break;
+ case SPRM::sprmTJc:
+ jc = readS16( ptr );
+ break;
+ case SPRM::sprmTDxaLeft:
+ {
+ const S16 dxaNew = readS16( ptr ) - ( rgdxaCenter[ 0 ] + dxaGapHalf );
+ std::transform( rgdxaCenter.begin(), rgdxaCenter.end(), rgdxaCenter.begin(), std::bind1st( std::plus<S16>(), dxaNew ) );
+ break;
+ }
+ case SPRM::sprmTDxaGapHalf:
+ {
+ const S16 dxaGapHalfNew = readS16( ptr );
+ if ( !rgdxaCenter.empty() )
+ rgdxaCenter[ 0 ] += dxaGapHalf - dxaGapHalfNew;
+ dxaGapHalf = dxaGapHalfNew;
+ break;
+ }
+ case SPRM::sprmTFCantSplit:
+ fCantSplit = *ptr == 1;
+ break;
+ case SPRM::sprmTTableHeader:
+ fTableHeader = *ptr == 1;
+ break;
+ case SPRM::sprmTTableBorders80:
+ {
+ const U8 inc = version == Word8 ? Word97::BRC::sizeOf97 : Word95::BRC::sizeOf;
+ for ( int i = 0; i < 6; ++i )
+ {
+ // skip the leading size byte
+ readBRC( rgbrcTable[ i ], ptr + 1 + i * inc, version );
+ }
+ break;
+ }
+ case SPRM::sprmTTableBorders:
+ {
+ const U8 inc = version == Word8 ? Word97::BRC::sizeOf : Word95::BRC::sizeOf;
+ for ( int i = 0; i < 6; ++i )
+ // skip the leading size byte
+ rgbrcTable[ i ].read90Ptr( ptr + 1 + i * inc );
+ break;
+ }
+ case SPRM::sprmTDefTable10:
+ wvlog << "Warning: sprmTDefTable10 is obsolete" << std::endl;
+ break;
+ case SPRM::sprmTDyaRowHeight:
+ dyaRowHeight = readS16( ptr );
+ break;
+ case SPRM::sprmTDefTable:
+ {
+ if ( itcMac != 0 ) {
+ wvlog << "Bug: Assumption about sprmTDefTable not true" << std::endl;
+ break;
+ }
+ int remainingLength = readU16( ptr ) - 1;
+ itcMac = *( ptr + 2 );
+
+ remainingLength -= 2 * ( itcMac + 1 );
+ if ( remainingLength < 0 ) {
+ wvlog << "Bug: Not even enough space for the dxas!" << std::endl;
+ break;
+ }
+
+ const U8* myPtr = ptr + 3;
+ const U8* myLim = ptr + 3 + 2 * ( itcMac + 1 );
+ while ( myPtr < myLim ) {
+ rgdxaCenter.push_back( readS16( myPtr ) );
+ myPtr += 2;
+ }
+
+ const int tcSize = version == Word8 ? Word97::TC::sizeOf : Word95::TC::sizeOf;
+ myLim = myPtr + ( remainingLength / tcSize ) * tcSize;
+ while ( myPtr < myLim ) {
+ if ( version == Word8 )
+ rgtc.push_back( TC( myPtr ) );
+ else
+ rgtc.push_back( toWord97( Word95::TC( myPtr ) ) );
+ myPtr += tcSize;
+ }
+ if ( rgtc.size() < static_cast<std::vector<S16>::size_type>( itcMac ) )
+ rgtc.insert( rgtc.end(), itcMac - rgtc.size(), TC() );
+
+ rgshd.insert( rgshd.begin(), itcMac, SHD() );
+ break;
+ }
+ case SPRM::sprmTDefTableShd80:
+ {
+ const U8* myPtr = ptr + 1;
+ const U8* myLim = ptr + 1 + *ptr;
+ rgshd.clear();
+ while ( myPtr < myLim ) {
+ rgshd.push_back( SHD( myPtr ) );
+ myPtr += SHD::sizeOf;
+ }
+ if ( rgshd.size() < static_cast<std::vector<S16>::size_type>( itcMac ) )
+ rgshd.insert( rgshd.end(), itcMac - rgshd.size(), SHD() );
+ break;
+ }
+ case SPRM::sprmTDefTableShd:
+ {
+ const U8* myPtr = ptr + 1;
+ const U8* myLim = ptr + 1 + *ptr;
+ rgshd.clear();
+ while ( myPtr < myLim ) {
+ SHD shd;
+ shd.read90Ptr(myPtr);
+ rgshd.push_back( shd );
+ myPtr += SHD::sizeOf;
+ }
+ if ( rgshd.size() < static_cast<std::vector<S16>::size_type>( itcMac ) )
+ rgshd.insert( rgshd.end(), itcMac - rgshd.size(), SHD() );
+ break;
+ }
+ case SPRM::sprmTDefTableShd2nd:
+ {
+ break;
+ }
+ case SPRM::sprmTDefTableShd3rd:
+ {
+ break;
+ }
+ case SPRM::sprmTTlp:
+ tlp.readPtr( ptr );
+ break;
+ case SPRM::sprmTFBiDi:
+ wvlog << "Warning: sprmTFBiDi not implemented" << std::endl;
+ break;
+ case SPRM::sprmTHTMLProps:
+ wvlog << "Warning: sprmTHTMLProps not implemented" << std::endl;
+ break;
+ case SPRM::sprmTSetBrc80:
+ {
+ const U8* myPtr( version == Word8 ? ptr + 1 : ptr ); // variable size byte for Word 8!
+ U8 itcFirst = *myPtr;
+ U8 itcLim = *( myPtr + 1 );
+ cropIndices( itcFirst, itcLim, rgtc.size() );
+ const U8 flags = *( myPtr + 2 );
+ BRC brc;
+ readBRC( brc, myPtr + 3, version );
+
+ for ( ; itcFirst < itcLim; ++itcFirst ) {
+ if ( flags & 0x01 )
+ rgtc[ itcFirst ].brcTop = brc;
+ if ( flags & 0x02 )
+ rgtc[ itcFirst ].brcLeft = brc;
+ if ( flags & 0x04 )
+ rgtc[ itcFirst ].brcBottom = brc;
+ if ( flags & 0x08 )
+ rgtc[ itcFirst ].brcRight = brc;
+ }
+ break;
+ }
+ case SPRM::sprmTInsert:
+ {
+ const U8 itcInsert = *ptr;
+ const U8 ctc = *( ptr + 1 );
+ const S16 dxaCol = readS16( ptr + 2 );
+
+ // Sanity check
+ if ( static_cast<std::vector<S16>::size_type>( itcMac ) + 1 != rgdxaCenter.size() ) {
+ wvlog << "Bug: Somehow itcMac and the rgdxaCenter.size() aren't in sync anymore!" << std::endl;
+ itcMac = rgdxaCenter.size() - 1;
+ }
+
+ if ( itcMac < itcInsert ) {
+ // Shaky, no idea why we would have to subtract ctc here?
+ // The implementation below is a guess from me, but it looks like this never happens
+ // in real documents.
+ wvlog << "Warning: sprmTInsert: Debug me ########################################" << std::endl;
+
+ S16 runningDxaCol = 0;
+ if ( !rgdxaCenter.empty() )
+ runningDxaCol = rgdxaCenter.back();
+
+ for ( ; itcMac < itcInsert; ++itcMac ) {
+ // If the index is bigger than our current array we just fill the
+ // hole with dummy cells (dxaCol wide, default TC) as suggested in
+ // the documentation
+ runningDxaCol += dxaCol;
+ rgdxaCenter.push_back( runningDxaCol );
+ rgtc.push_back( TC() );
+ }
+ }
+ else {
+ S16 runningDxaCol;
+ if ( itcInsert > 0 )
+ runningDxaCol = rgdxaCenter[ itcInsert - 1 ] + dxaCol;
+ else // preserve the position of the table row
+ runningDxaCol = rgdxaCenter[ 0 ];
+
+ for ( int i = 0; i < ctc; ++i ) {
+ std::vector<S16>::iterator dxaIt = rgdxaCenter.begin() + itcInsert + i;
+ rgdxaCenter.insert( dxaIt, runningDxaCol );
+ runningDxaCol += dxaCol;
+ }
+
+ rgtc.insert( rgtc.begin() + itcInsert, ctc, TC() );
+ rgshd.insert( rgshd.begin() + itcInsert, ctc, SHD() );
+ itcMac += ctc;
+
+ // Adjust all successive items (+= ctc * dxaCol)
+ std::transform( rgdxaCenter.begin() + itcInsert + ctc, rgdxaCenter.end(),
+ rgdxaCenter.begin() + itcInsert + ctc, std::bind1st( std::plus<S16>(), ctc * dxaCol ) );
+ }
+ break;
+ }
+ case SPRM::sprmTDelete:
+ {
+ U8 itcFirst = *ptr;
+ U8 itcLim = *( ptr + 1 );
+ cropIndices( itcFirst, itcLim, rgdxaCenter.size() );
+
+ rgdxaCenter.erase( rgdxaCenter.begin() + itcFirst, rgdxaCenter.begin() + itcLim );
+ rgtc.erase( rgtc.begin() + itcFirst, rgtc.begin() + itcLim );
+ rgshd.erase( rgshd.begin() + itcFirst, rgshd.begin() + itcLim );
+
+ itcMac -= itcLim - itcFirst;
+ break;
+ }
+ case SPRM::sprmTDxaCol:
+ {
+ U8 itcFirst = *ptr;
+ U8 itcLim = *( ptr + 1 );
+ cropIndices( itcFirst, itcLim, rgdxaCenter.size() );
+ const S16 dxaCol = readS16( ptr + 2 );
+ S16 shift = 0;
+
+ for ( ; itcFirst < itcLim; ++itcFirst ) {
+ shift += rgdxaCenter[ itcFirst + 1 ] - rgdxaCenter[ itcFirst ] - dxaCol;
+ rgdxaCenter[ itcFirst + 1 ] = rgdxaCenter[ itcFirst ] + dxaCol;
+ }
+
+ // Adjust all the following columns
+ ++itcFirst;
+ std::transform( rgdxaCenter.begin() + itcFirst, rgdxaCenter.end(),
+ rgdxaCenter.begin() + itcFirst, std::bind2nd( std::minus<S16>(), shift ) );
+ break;
+ }
+ case SPRM::sprmTMerge:
+ {
+ wvlog << "Debug me (sprmTMerge) #########################################################" << std::endl;
+ U8 itcFirst = *ptr;
+ U8 itcLim = *( ptr + 1 );
+ cropIndices( itcFirst, itcLim, rgtc.size() );
+
+ rgtc[ itcFirst++ ].fFirstMerged = 1;
+ for ( ; itcFirst < itcLim; ++itcFirst )
+ rgtc[ itcFirst ].fMerged = 1;
+ break;
+ }
+ case SPRM::sprmTSplit:
+ {
+ wvlog << "Debug me (sprmTSplit) #########################################################" << std::endl;
+ U8 itcFirst = *ptr;
+ U8 itcLim = *( ptr + 1 );
+ cropIndices( itcFirst, itcLim, rgtc.size() );
+
+ std::vector<TC>::iterator it = rgtc.begin() + itcFirst;
+ std::vector<TC>::const_iterator end = rgtc.begin() + itcLim;
+ for ( ; it != end; ++it ) {
+ ( *it ).fFirstMerged = 0;
+ ( *it ).fMerged = 0;
+ }
+ break;
+ }
+ case SPRM::sprmTSetBrc10:
+ wvlog << "Warning: sprmTSetBrc10 doesn't make sense for Word97 structures" << std::endl;
+ break;
+ case SPRM::sprmTSetShd:
+ {
+ U8 itcFirst = *ptr;
+ U8 itcLim = *( ptr + 1 );
+ cropIndices( itcFirst, itcLim, rgshd.size() );
+ const SHD shd( ptr + 2 );
+
+ std::fill_n( rgshd.begin() + itcFirst, itcLim - itcFirst, shd );
+ break;
+ }
+ case SPRM::sprmTSetShdOdd:
+ {
+ U8 itcFirst = *ptr;
+ U8 itcLim = *( ptr + 1 );
+ cropIndices( itcFirst, itcLim, rgshd.size() );
+ const SHD shd( ptr + 2 );
+
+ for ( ; itcFirst < itcLim; ++itcFirst )
+ if ( itcFirst & 0x01 )
+ rgshd[ itcFirst ] = shd;
+ break;
+ }
+ case SPRM::sprmTTextFlow:
+ wvlog << "Warning: sprmTTextFlow is undocumented. Please send this document to [email protected]." << std::endl;
+ break;
+ case SPRM::sprmTDiagLine:
+ wvlog << "Warning: sprmTDiagLine is undocumented. Please send this document to [email protected]." << std::endl;
+ break;
+ case SPRM::sprmTVertMerge:
+ {
+ const U8 index = *ptr;
+ const U8 flags = *( ptr + 1 );
+ if ( index < rgtc.size() ) {
+ rgtc[ index ].fVertMerge = flags;
+ rgtc[ index ].fVertRestart = ( flags & 0x02 ) >> 1;
+ }
+ else
+ wvlog << "Warning: sprmTVertMerge: Out of bounds access" << std::endl;
+ break;
+ }
+ case SPRM::sprmTVertAlign:
+ {
+ U8 itcFirst = *ptr;
+ U8 itcLim = *( ptr + 1 );
+ cropIndices( itcFirst, itcLim, rgtc.size() );
+ const U8 vertAlign = *( ptr + 2 );
+
+ for ( ; itcFirst < itcLim; ++itcFirst )
+ rgtc[ itcFirst ].vertAlign = vertAlign;
+ break;
+ }
+ case SPRM::sprmTSetBrc:
+ {
+ const U8* myPtr( version == Word8 ? ptr + 1 : ptr ); // variable size byte for Word 8!
+ U8 itcFirst = *myPtr;
+ U8 itcLim = *( myPtr + 1 );
+ cropIndices( itcFirst, itcLim, rgtc.size() );
+ const U8 flags = *( myPtr + 2 );
+ BRC brc;
+ brc.read90Ptr(myPtr + 3 );
+
+ for ( ; itcFirst < itcLim; ++itcFirst ) {
+ if ( flags & 0x01 )
+ rgtc[ itcFirst ].brcTop = brc;
+ if ( flags & 0x02 )
+ rgtc[ itcFirst ].brcLeft = brc;
+ if ( flags & 0x04 )
+ rgtc[ itcFirst ].brcBottom = brc;
+ if ( flags & 0x08 )
+ rgtc[ itcFirst ].brcRight = brc;
+ }
+ break;
+ }
+ case SPRM::sprmTUndocumentedSpacing:
+ if ( *ptr == 6 ) {
+/* wvlog << "sprmTUndocumentedSpacing----" << std::endl;
+ const U8 itcFirst( *( ptr + 1 ) );
+ for ( int i = 0; i < 6; ++i )
+ wvlog << " byte " << i << ": " << std::hex << ( int )*( ptr + i ) << std::dec << std::endl;
+*/
+ }
+ else
+ wvlog << "Warning: sprmTUndocumentedSpacing with unusual length=" << static_cast<int>( *ptr ) << std::endl;
+ break;
+ case SPRM::sprmTUndocumented8:
+ // ###### TODO
+ //wvlog << "sprmTUndocumented8: some undocumented spacing thingy, TODO" << std::endl;
+ break;
+ case SPRM::sprmTUndocumented1:
+ case SPRM::sprmTUndocumented2:
+ break;
+ case SPRM::sprmTBrcTopCv:
+ {
+ const U8* myPtr( version == Word8 ? ptr + 1 : ptr ); // variable size byte for Word 8!
+
+ for (int i=0 ; i < 64 && i < rgtc.size(); ++i ) {
+ rgtc[ i ].brcTop.cv = ((*(myPtr + i*4))<<16) | ((*(myPtr + 1 + i*4))<<8) | (*(myPtr + 2 + i*4)) ;
+ }
+ break;
+ }
+ case SPRM::sprmTBrcLeftCv:
+ {
+ const U8* myPtr( version == Word8 ? ptr + 1 : ptr ); // variable size byte for Word 8!
+
+ for (int i=0 ; i < 64 && i < rgtc.size(); ++i ) {
+ rgtc[ i ].brcLeft.cv = ((*(myPtr + i*4))<<16) | ((*(myPtr + 1 + i*4))<<8) | (*(myPtr + 2 + i*4)) ;
+ }
+ break;
+ }
+ case SPRM::sprmTBrcRightCv:
+ {
+ const U8* myPtr( version == Word8 ? ptr + 1 : ptr ); // variable size byte for Word 8!
+
+ for (int i=0 ; i < 64 && i < rgtc.size(); ++i ) {
+ rgtc[ i ].brcRight.cv = ((*(myPtr + i*4))<<16) | ((*(myPtr + 1 + i*4))<<8) | (*(myPtr + 2 + i*4)) ;
+ }
+ break;
+ }
+ case SPRM::sprmTBrcBottomCv:
+ {
+ const U8* myPtr( version == Word8 ? ptr + 1 : ptr ); // variable size byte for Word 8!
+
+ for (int i=0 ; i < 64 && i < rgtc.size(); ++i ) {
+ rgtc[ i ].brcBottom.cv = ((*(myPtr + i*4))<<16) | ((*(myPtr + 1 + i*4))<<8) | (*(myPtr + 2 + i*4)) ;
+ }
+ break;
+ }
+ case SPRM::sprmTUndocumented9:
+ case SPRM::sprmTUndocumented10:
+ case SPRM::sprmTUndocumented11:
+ case SPRM::sprmTUndocumented12:
+ case SPRM::sprmTUndocumented13:
+ break;
+ // These are needed in case there are table properties inside the huge papx
+ case SPRM::sprmPHugePapx:
+ case SPRM::sprmPHugePapx2:
+ {
+ if ( dataStream ) {
+ dataStream->push();
+ dataStream->seek( readU32( ptr ), G_SEEK_SET );
+ const U16 count( dataStream->readU16() );
+ U8* grpprl = new U8[ count ];
+ dataStream->read( grpprl, count );
+ dataStream->pop();
+
+ apply( grpprl, count, style, styleSheet, dataStream, version );
+ delete [] grpprl;
+ }
+ else
+ wvlog << "Error: sprmPHugePapx found, but no data stream!" << std::endl;
+ break;
+ }
+ default:
+ wvlog << "Huh? None of the defined sprms matches 0x" << std::hex << sprm << std::dec << "... trying to skip anyway" << std::endl;
+ break;
+ }
+ return static_cast<S16>( sprmLength ); // length of the SPRM
+}
+
+
+// Creates a PRM2 from a plain PRM
+PRM2 PRM::toPRM2() const
+{
+ PRM2 prm;
+ prm.fComplex = fComplex;
+ prm.igrpprl = ( val << 7 ) | isprm;
+ return prm;
+}
+
+} // namespace Word97
+} // namespace wvWare
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/word97_helper.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/word97_helper.h
new file mode 100644
index 00000000..aa9c3f78
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/word97_helper.h
@@ -0,0 +1,49 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef WORD97_HELPER_H
+#define WORD97_HELPER_H
+
+#include "global.h"
+
+namespace wvWare
+{
+ class OLEStreamReader;
+ class ParagraphProperties;
+ class StyleSheet;
+
+ namespace Word97
+ {
+ struct TAP;
+ }
+
+ namespace Word97
+ {
+ ParagraphProperties* initPAPFromStyle( const U8* exceptions, const StyleSheet* styleSheet, OLEStreamReader* dataStream, WordVersion version );
+ Word97::TAP* initTAP( const U8* exceptions, OLEStreamReader* dataStream, WordVersion version );
+
+ namespace SPRM
+ {
+ U16 unzippedOpCode( U8 isprm );
+ U16 determineParameterLength( U16 sprm, const U8* in, WordVersion version );
+ U16 word6toWord8( U8 sprm );
+ }
+ } // namespace Word97
+} // namespace wvWare
+
+#endif // WORD97_HELPER_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/word_helper.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/word_helper.cpp
new file mode 100644
index 00000000..b1c8a1c1
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/word_helper.cpp
@@ -0,0 +1,319 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "word_helper.h"
+#include "olestream.h"
+#include "textconverter.h"
+#include "ustring.h"
+
+namespace wvWare
+{
+
+ STTBF::STTBF( U16 lid, OLEStreamReader* reader, bool preservePos )
+ {
+ if ( preservePos )
+ reader->push();
+ init( lid, reader, 0 );
+ if ( preservePos )
+ reader->pop();
+ }
+
+ STTBF::STTBF( U16 lid, const U8* ptr )
+ {
+ init( lid, 0, ptr );
+ }
+
+ STTBF::STTBF( const STTBF& rhs ) : m_strings( rhs.m_strings ), m_extraDataLength( rhs.m_extraDataLength )
+ {
+ std::vector<U8*>::const_iterator it = rhs.m_extraData.begin();
+ std::vector<U8*>::const_iterator end = rhs.m_extraData.end();
+ for ( ; it != end; ++it ) {
+ U8* tmp = new U8[ m_extraDataLength ];
+ memcpy( tmp, *it, m_extraDataLength );
+ m_extraData.push_back( tmp );
+ }
+ }
+
+ STTBF::~STTBF()
+ {
+ std::vector<U8*>::const_iterator it = m_extraData.begin();
+ for ( ; it != m_extraData.end(); ++it )
+ delete [] *it;
+ }
+
+ unsigned int STTBF::count() const
+ {
+ return m_strings.size();
+ }
+
+ UString STTBF::firstString() const
+ {
+ m_stringIt = m_strings.begin();
+ if ( m_stringIt != m_strings.end() )
+ return *m_stringIt;
+ return UString::null;
+ }
+
+ UString STTBF::nextString() const
+ {
+ if ( m_stringIt == m_strings.end() )
+ return UString::null;
+ ++m_stringIt;
+ if ( m_stringIt != m_strings.end() )
+ return *m_stringIt;
+ return UString::null;
+ }
+
+ UString STTBF::prevString() const
+ {
+ if ( m_strings.size() == 0 )
+ return UString::null;
+ if ( m_stringIt != m_strings.begin() )
+ --m_stringIt;
+ return *m_stringIt;
+ }
+
+ UString STTBF::lastString() const
+ {
+ m_stringIt = m_strings.end();
+ if ( m_stringIt == m_strings.begin() )
+ return UString::null;
+ --m_stringIt;
+ return *m_stringIt;
+ }
+
+ UString STTBF::stringAt( unsigned int index ) const
+ {
+ if ( index < m_strings.size() )
+ return m_strings[ index ];
+ return UString::null;
+ }
+
+ const U8* STTBF::firstExtra() const
+ {
+ m_extraIt = m_extraData.begin();
+ if ( m_extraIt != m_extraData.end() )
+ return *m_extraIt;
+ return 0;
+ }
+
+ const U8* STTBF::nextExtra() const
+ {
+ if ( m_extraIt == m_extraData.end() )
+ return 0;
+ ++m_extraIt;
+ if ( m_extraIt != m_extraData.end() )
+ return *m_extraIt;
+ return 0;
+ }
+
+ const U8* STTBF::prevExtra() const
+ {
+ if ( m_extraData.size() == 0 )
+ return 0;
+ if ( m_extraIt != m_extraData.begin() )
+ --m_extraIt;
+ return *m_extraIt;
+ }
+
+ const U8* STTBF::lastExtra() const
+ {
+ m_extraIt = m_extraData.end();
+ if ( m_extraIt == m_extraData.begin() )
+ return 0;
+ --m_extraIt;
+ return *m_extraIt;
+ }
+
+ const U8* STTBF::extraAt( unsigned int index ) const
+ {
+ if ( index < m_extraData.size() )
+ return m_extraData[ index ];
+ return 0;
+ }
+
+ void STTBF::dumpStrings() const
+ {
+ wvlog << "STTBF::dumpStrings(): count=" << count() << " extraDataLength="
+ << extraDataLength() << std::endl;
+ std::vector<UString>::const_iterator it = m_strings.begin();
+ std::vector<UString>::const_iterator end = m_strings.end();
+ for ( ; it != end; ++it )
+ wvlog << " '" << ( *it ).ascii() << "'" << std::endl;
+ }
+
+ void STTBF::init( U16 lid, OLEStreamReader* reader, const U8* ptr )
+ {
+ bool extended = false;
+ U16 count = readU16( reader, &ptr );
+ // "extended" characters?
+ if ( count == 0xffff ) {
+ extended = true;
+ // read the real size
+ count = readU16( reader, &ptr );
+ }
+ m_extraDataLength = readU16( reader, &ptr );
+
+ // If we don't read unicode strings we have to set up a text converter
+ TextConverter* textconverter = 0;
+ if ( !extended )
+ textconverter = new TextConverter( lid );
+
+ // read one string after the other
+ for ( U16 i = 0; i < count; ++i ) {
+ U16 len = 0;
+ if ( extended ) // double byte count!
+ len = readU16( reader, &ptr );
+ else
+ len = readU8( reader, &ptr );
+
+ if ( len != 0 ) {
+ if ( extended ) {
+ XCHAR* string = new XCHAR[ len ];
+ for ( U16 j = 0; j < len; ++j )
+ string[ j ] = readU16( reader, &ptr );
+ UString ustring( reinterpret_cast<const wvWare::UChar *>( string ), len );
+ delete [] string;
+ m_strings.push_back( ustring );
+ }
+ else {
+ U8* string = new U8[ len ];
+ read( reader, &ptr, string, len );
+ UString ustring( textconverter->convert( reinterpret_cast<char*>( string ),
+ static_cast<unsigned int>( len ) ) );
+ delete [] string;
+ m_strings.push_back( ustring );
+ }
+ }
+ else
+ m_strings.push_back( UString("") );
+ if ( m_extraDataLength != 0 ) {
+ U8* extra = new U8[ m_extraDataLength ];
+ read( reader, &ptr, extra, m_extraDataLength );
+ m_extraData.push_back( extra );
+ }
+ }
+ delete textconverter;
+ }
+
+ U16 STTBF::readU16( OLEStreamReader* reader, const U8** ptr ) const
+ {
+ if ( reader )
+ return reader->readU16();
+ else if ( *ptr ) {
+ U16 ret = wvWare::readU16( *ptr );
+ *ptr += 2;
+ return ret;
+ }
+ else {
+ wvlog << "Warning: Internal error while reading STTBF" << std::endl;
+ return 0;
+ }
+ }
+
+ U8 STTBF::readU8( OLEStreamReader* reader, const U8** ptr ) const
+ {
+ if ( reader )
+ return reader->readU8();
+ else if ( *ptr ) {
+ U8 ret = **ptr;
+ *ptr += 1;
+ return ret;
+ }
+ else {
+ wvlog << "Warning: Internal error while reading STTBF" << std::endl;
+ return 0;
+ }
+ }
+
+ bool STTBF::read( OLEStreamReader* reader, const U8** ptr, U8* buffer, size_t length ) const
+ {
+ if ( reader )
+ return reader->read( buffer, length );
+ else if ( *ptr ) {
+ memcpy( buffer, *ptr, length );
+ *ptr += length;
+ return true;
+ }
+ else {
+ wvlog << "Warning: Internal error while reading STTBF" << std::endl;
+ return false;
+ }
+ }
+
+
+ CHPFKP_BX::CHPFKP_BX()
+ {
+ clear();
+ }
+
+ CHPFKP_BX::CHPFKP_BX( OLEStreamReader* stream, bool preservePos )
+ {
+ clear();
+ read( stream, preservePos );
+ }
+
+ CHPFKP_BX::CHPFKP_BX( const U8* ptr )
+ {
+ clear();
+ readPtr( ptr );
+ }
+
+ bool CHPFKP_BX::read( OLEStreamReader* stream, bool preservePos )
+ {
+ if ( preservePos )
+ stream->push();
+ offset = stream->readU8();
+ if ( preservePos )
+ stream->pop();
+ return true;
+ }
+
+ void CHPFKP_BX::readPtr( const U8* ptr )
+ {
+ offset = *ptr;
+ }
+
+ bool CHPFKP_BX::write( OLEStreamWriter* stream, bool preservePos ) const
+ {
+ if ( preservePos )
+ stream->push();
+ stream->write( offset );
+ if ( preservePos )
+ stream->pop();
+ return true;
+ }
+
+ void CHPFKP_BX::clear()
+ {
+ offset = 0;
+ }
+
+ bool operator==( const CHPFKP_BX& lhs, const CHPFKP_BX& rhs )
+ {
+ return lhs.offset == rhs.offset;
+ }
+
+ bool operator!=( const CHPFKP_BX& lhs, const CHPFKP_BX& rhs )
+ {
+ return !( lhs == rhs );
+ }
+
+ const unsigned int CHPFKP_BX::sizeOf = 1;
+
+} // namespace wvWare
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/word_helper.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/word_helper.h
new file mode 100644
index 00000000..2fb9a1f6
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/word_helper.h
@@ -0,0 +1,745 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef WORD_HELPER_H
+#define WORD_HELPER_H
+
+#include "olestream.h"
+#include "wvlog.h"
+
+#include <vector>
+#include <string.h>
+
+namespace wvWare
+{
+ namespace Word97 { class PHE; class BTE; }
+ namespace Word95
+ {
+ class PHE;
+ class BTE;
+ Word97::PHE toWord97( const Word95::PHE& phe ); // fake, to make gcc 3.4 happy :-(
+ Word97::BTE toWord97( const Word95::BTE& s ); // fake, to make gcc 3.4 happy :-(
+ }
+
+ class OLEStreamReader;
+ class OLEStreamWriter;
+ class ParagraphProperties;
+ class UString;
+
+ class STTBF
+ {
+ public:
+ STTBF( U16 lid, OLEStreamReader* reader, bool preservePos = false );
+ STTBF( U16 lid, const U8* ptr );
+ STTBF( const STTBF& rhs );
+ ~STTBF();
+
+ unsigned int count() const;
+ unsigned int extraDataLength() const { return m_extraDataLength; }
+
+ UString firstString() const;
+ UString nextString() const;
+ UString prevString() const;
+ UString lastString() const;
+ UString stringAt( unsigned int index ) const;
+
+ const U8* firstExtra() const;
+ const U8* nextExtra() const;
+ const U8* prevExtra() const;
+ const U8* lastExtra() const;
+ const U8* extraAt( unsigned int index ) const;
+
+ void dumpStrings() const;
+
+ private:
+ STTBF& operator=( const STTBF& rhs );
+
+ // Internal helper methods to avoid code duplication in the CTORs
+ void init( U16 lid, OLEStreamReader* reader, const U8* ptr );
+ U16 readU16( OLEStreamReader* reader, const U8** ptr ) const;
+ U8 readU8( OLEStreamReader* reader, const U8** ptr ) const;
+ bool read( OLEStreamReader* reader, const U8** ptr, U8* buffer, size_t length ) const;
+
+ std::vector<UString> m_strings;
+ mutable std::vector<UString>::const_iterator m_stringIt;
+ U16 m_extraDataLength;
+ std::vector<U8*> m_extraData;
+ mutable std::vector<U8*>::const_iterator m_extraIt;
+ };
+
+ // Attention: structs used as template parameters for this class need to
+ // enable the sizeOf field in the code generator (see comment (7)) in
+ // the header of generate.pl
+ // Use the short count for "broken" plfs like the LSTF one (surprisingly
+ // labeled plcflst(!) (see spec_defects for more information)
+ template<class T, bool shortCount = false> class PLF
+ {
+ public:
+ PLF( OLEStreamReader* reader, bool preservePos = false );
+ PLF( const U8* ptr );
+ ~PLF();
+
+ size_t count() const { return m_items.size(); }
+
+ const T* first() const { it = m_items.begin(); if ( it != m_items.end() ) return *it; return 0; }
+ const T* next() const;
+ const T* prev() const;
+ const T* last() const { it = m_items.end(); if ( it == m_items.begin() ) return 0; --it; return *it; }
+ const T* current() const { if ( it != m_items.end() ) return *it; return 0; }
+ const T* at( unsigned int index ) const { if ( index < m_items.size() ) return m_items[ index ]; return 0; }
+
+ private:
+ // don't copy or assign it
+ PLF( const PLF<T, shortCount>& rhs );
+ PLF<T, shortCount>& operator=( const PLF<T, shortCount>& rhs );
+
+ std::vector<T*> m_items;
+ mutable typename std::vector<T*>::const_iterator it;
+ };
+
+ template<class T, bool shortCount>
+ PLF<T, shortCount>::PLF( OLEStreamReader* reader, bool preservePos )
+ {
+ if ( preservePos )
+ reader->push();
+
+ U32 count = 0;
+ if ( shortCount ) // work around a broken spec, e.g. for LSTF
+ count = reader->readU16();
+ else
+ count = reader->readU32();
+
+ for ( U32 i = 0; i < count; ++i )
+ m_items.push_back( new T( reader, false ) );
+ if ( preservePos )
+ reader->pop();
+ it = m_items.begin();
+ }
+
+ template<class T, bool shortCount>
+ PLF<T, shortCount>::PLF( const U8* ptr )
+ {
+ U32 count = 0;
+ if ( shortCount ) { // work around a broken spec, e.g. for LSTF
+ count = readU16( ptr );
+ ptr += 2;
+ }
+ else {
+ count = readU32( ptr );
+ ptr += 4;
+ }
+
+ for ( U32 i = 0; i < count; ++i, ptr += T::sizeOf )
+ m_items.push_back( new T( ptr ) );
+ it = m_items.begin();
+ }
+
+ template<class T, bool shortCount>
+ PLF<T, shortCount>::~PLF()
+ {
+ for ( it = m_items.begin(); it != m_items.end(); ++it )
+ delete *it;
+ }
+
+ template<class T, bool shortCount>
+ const T* PLF<T, shortCount>::next() const
+ {
+ if ( it == m_items.end() )
+ return 0;
+ ++it;
+ if ( it != m_items.end() )
+ return *it;
+ return 0;
+ }
+
+ template<class T, bool shortCount>
+ const T* PLF<T, shortCount>::prev() const
+ {
+ if ( m_items.size() == 0 )
+ return 0;
+ if ( it != m_items.begin() )
+ --it;
+ return *it;
+ }
+
+
+ template<class T> class PLCF;
+ template<class T> class PLCFIterator;
+ template<typename OldT, typename NewT> PLCF<NewT>* convertPLCF( const PLCF<OldT>& old ); // evil, eh? :-)
+
+ template<class T> class PLCF
+ {
+ friend class PLCFIterator<T>;
+ template<typename OldT, typename NewT> friend PLCF<NewT>* convertPLCF( const PLCF<OldT>& old );
+ public:
+ PLCF( U32 length, OLEStreamReader *reader, bool preservePos = false );
+ PLCF( U32 length, const U8* ptr );
+ PLCF( const PLCF<T>& rhs );
+ ~PLCF();
+
+ PLCFIterator<T> at( unsigned int index ) const;
+ size_t count() const { return m_items.size(); }
+ bool isEmpty() const { return m_items.empty(); }
+
+ // Inserts the given index/item pair at the end of the PLCF (but before(!) the final n+1 index)
+ // Normally you won't need that method. The ownership of the item is transferred.
+ void insert( U32 index, T* item );
+
+ void dumpCPs() const;
+ private:
+ // don't assign it
+ PLCF<T>& operator=( const PLCF<T>& rhs );
+
+ // An empty default constructor for the convertPLCF friend. Don't use it
+ // unless you know what you are doing :-)
+ PLCF() {}
+
+ U32 calculateCount( U32 length );
+
+ std::vector<U32> m_indices;
+ std::vector<T*> m_items;
+ };
+
+ template<class T>
+ PLCF<T>::PLCF( U32 length, OLEStreamReader* reader, bool preservePos )
+ {
+ if ( preservePos )
+ reader->push();
+ U32 count = calculateCount( length );
+ for ( U32 i = 0; i < count + 1; ++i ) // n+1 CPs/FCs
+ m_indices.push_back( reader->readU32() );
+ for ( U32 i = 0; i < count; ++i ) // n "T"s
+ m_items.push_back( new T( reader, false ) );
+ if ( preservePos )
+ reader->pop();
+ }
+
+ template<class T>
+ PLCF<T>::PLCF( U32 length, const U8* ptr )
+ {
+ U32 count = calculateCount( length );
+ for ( U32 i = 0; i < count + 1; ++i, ptr += 4 ) // n+1 CPs/FCs
+ m_indices.push_back( readU32( ptr ) );
+ for ( U32 i = 0; i < count; ++i, ptr += T::sizeOf ) // n "T"s
+ m_items.push_back( new T( ptr ) );
+ }
+
+ template<class T>
+ PLCF<T>::PLCF( const PLCF<T>& rhs ) : m_indices( rhs.m_indices )
+ {
+ typename std::vector<T*>::const_iterator it = rhs.m_items.begin();
+ typename std::vector<T*>::const_iterator end = rhs.m_items.end();
+ for ( ; it != end; ++it )
+ m_items.push_back( new T( **it ) );
+ }
+
+ template<class T>
+ PLCF<T>::~PLCF()
+ {
+ typename std::vector<T*>::const_iterator it = m_items.begin();
+ for ( ; it != m_items.end(); ++it )
+ delete *it;
+ }
+
+ template<class T>
+ PLCFIterator<T> PLCF<T>::at( unsigned int index ) const
+ {
+ PLCFIterator<T> it( *this );
+ it.m_itemIt += index;
+ it.m_indexIt += index;
+ return it;
+ }
+
+ template<class T>
+ void PLCF<T>::insert( U32 index, T* item )
+ {
+ if ( m_indices.empty() ) {
+ delete item;
+ return;
+ }
+ std::vector<U32>::iterator it( m_indices.end() );
+ --it;
+ m_indices.insert( it, index );
+ m_items.push_back( item );
+ }
+
+ template<class T>
+ void PLCF<T>::dumpCPs() const
+ {
+ wvlog << "PLCF: count=" << count() << std::endl;
+ std::vector<U32>::const_iterator it = m_indices.begin();
+ std::vector<U32>::const_iterator end = m_indices.end();
+ for ( ; it != end; ++it )
+ wvlog << " " << ( *it ) << std::endl;
+ wvlog << "PLCF done." << std::endl;
+ }
+
+ template<class T>
+ U32 PLCF<T>::calculateCount( U32 length )
+ {
+ if ( ( length - 4 ) % ( T::sizeOf + 4 ) ) {
+ wvlog << "Warning: PLCF size seems to be screwed" << std::endl;
+ wvlog << "Warning: length: " << length << ", size: " << T::sizeOf << ", mod: " << ( length - 4 ) % ( T::sizeOf + 4 ) << std::endl;
+ return 0;
+ }
+ return ( length - 4 ) / ( T::sizeOf + 4 );
+ }
+
+
+ // A method to "upgrade" the type of a PLCF from Word 6/7 to Word 8
+ // data structures, using the generated conversion code. Tricky :-)
+ // The ownership of the new PLCF is transferred to you!
+ template<typename OldT, typename NewT> PLCF<NewT>* convertPLCF( const PLCF<OldT>& old )
+ {
+ PLCF<NewT>* ret( new PLCF<NewT> );
+ ret->m_indices = old.m_indices; // the indices remain the same
+
+ typename std::vector<OldT*>::const_iterator oldIt( old.m_items.begin() );
+ typename std::vector<OldT*>::const_iterator oldEnd( old.m_items.end() );
+ for ( ; oldIt != oldEnd; ++oldIt )
+ ret->m_items.push_back( new NewT( Word95::toWord97( **oldIt ) ) );
+ return ret;
+ }
+
+
+ template<class T> class PLCFIterator
+ {
+ friend PLCFIterator<T> PLCF<T>::at( unsigned int ) const;
+ public:
+ PLCFIterator( const PLCF<T>& plcf ) : m_plcf( plcf )
+ {
+ m_itemIt = m_plcf.m_items.begin();
+ m_indexIt = m_plcf.m_indices.begin();
+ }
+
+ unsigned int count() const { return m_plcf.m_items.count(); }
+ bool isEmpty() const { return m_plcf.m_items.count() == 0; }
+
+ T* toFirst();
+ T* toLast();
+
+ U32 currentStart() const { if ( m_itemIt != m_plcf.m_items.end() ) return *m_indexIt; return 0; }
+ U32 currentLim() const;
+ T* current() const { if ( m_itemIt != m_plcf.m_items.end() ) return *m_itemIt; return 0; }
+
+ U32 currentRun() const { return currentLim() - currentStart(); }
+
+ PLCFIterator& operator++();
+ PLCFIterator& operator--();
+
+ private:
+ // don't assign it
+ PLCFIterator<T>& operator=( const PLCFIterator<T>& rhs );
+
+ const PLCF<T>& m_plcf;
+ typename std::vector<T*>::const_iterator m_itemIt;
+ std::vector<U32>::const_iterator m_indexIt;
+ };
+
+ template<class T>
+ T* PLCFIterator<T>::toFirst()
+ {
+ m_itemIt = m_plcf.m_items.begin();
+ m_indexIt = m_plcf.m_indices.begin();
+ if ( m_itemIt != m_plcf.m_items.end() )
+ return *m_itemIt;
+ return 0;
+ }
+
+ // Note: m_indexIt-=2 as we have n+1 indices!
+ template<class T>
+ T* PLCFIterator<T>::toLast()
+ {
+ m_itemIt = m_plcf.m_items.end();
+ m_indexIt = m_plcf.m_indices.end();
+ if ( m_itemIt == m_plcf.m_items.begin() )
+ return 0;
+ --m_itemIt;
+ m_indexIt -= 2;
+ return *m_itemIt;
+ }
+
+ template<class T>
+ U32 PLCFIterator<T>::currentLim() const
+ {
+ std::vector<U32>::const_iterator it = m_indexIt;
+ if ( m_itemIt == m_plcf.m_items.end() )
+ return 0;
+ ++it;
+ return *it;
+ }
+
+ template<class T>
+ PLCFIterator<T>& PLCFIterator<T>::operator++()
+ {
+ if ( m_itemIt == m_plcf.m_items.end() )
+ return *this;
+ ++m_itemIt;
+ ++m_indexIt;
+ return *this;
+ }
+
+ template<class T>
+ PLCFIterator<T>& PLCFIterator<T>::operator--()
+ {
+ if ( m_plcf.m_items.size() != 0 && m_itemIt != m_plcf.m_items.begin() ) {
+ --m_itemIt;
+ --m_indexIt;
+ }
+ return *this;
+ }
+
+
+ template<class PHE> struct BX;
+ template<class Offset> class FKP;
+ template<class Offset> class FKPIterator;
+ FKP< BX<Word97::PHE> >* convertFKP( const FKP< BX<Word95::PHE> >& old );
+
+ template<class Offset> class FKP
+ {
+ friend class FKPIterator<Offset>;
+ friend FKP< BX<Word97::PHE> >* convertFKP( const FKP< BX<Word95::PHE> >& old );
+ public:
+ FKP( OLEStreamReader* reader, bool preservePos = false );
+ FKP( const U8* ptr );
+ FKP( const FKP<Offset>& rhs );
+ ~FKP() { delete [] m_rgfc; delete [] m_rgb; delete [] m_fkp; }
+
+ unsigned int crun() const { return m_crun; }
+ bool isEmpty() const { return m_crun == 0; }
+
+ private:
+ // don't assign it
+ FKP<Offset>& operator=( const FKP<Offset>& rhs );
+
+ // An empty default constructor for the convertFKP friend. Don't use it
+ // unless you know what you are doing :-)
+ FKP() {}
+
+ U8 m_crun;
+ U32* m_rgfc; // array of FCs (crun+1)
+ Offset* m_rgb; // array of offsets/BXs
+ U16 m_internalOffset; // offset to the start position of the "rest"
+ U8* m_fkp; // the "rest" of the FKP
+ };
+
+ template<class Offset>
+ FKP<Offset>::FKP( OLEStreamReader* reader, bool preservePos )
+ {
+ if ( preservePos )
+ reader->push();
+ reader->push();
+ reader->seek( 511, G_SEEK_CUR );
+ m_crun = reader->readU8();
+ reader->pop();
+
+ m_rgfc = new U32[ m_crun + 1 ];
+ for ( U8 i = 0; i <= m_crun; ++i ) // <= crun, because of crun+1 FCs!
+ m_rgfc[ i ] = reader->readU32();
+
+ m_rgb = new Offset[ m_crun ];
+ for ( U8 i = 0; i < m_crun; ++i )
+ m_rgb[ i ].read( reader, false );
+
+ m_internalOffset = ( static_cast<U16>( m_crun ) + 1 ) * 4 + static_cast<U16>( m_crun ) * Offset::sizeOf;
+
+ // store the rest of the FKP in an internal array for later use
+ const U16 length = 511 - m_internalOffset;
+ m_fkp = new U8[ length ]; // 511, because we don't need crun
+ for ( U16 i = 0; i < length; ++i )
+ m_fkp[ i ] = reader->readU8();
+
+ if ( preservePos )
+ reader->pop();
+ }
+
+ template<class Offset>
+ FKP<Offset>::FKP( const U8* ptr )
+ {
+ m_crun = ptr[ 511 ];
+
+ m_rgfc = new U32[ m_crun + 1 ];
+ for ( U8 i = 0; i <= m_crun; ++i, ptr += 4 ) // <= crun, because of crun+1 FCs!
+ m_rgfc[ i ] = readU32( ptr );
+
+ m_rgb = new Offset[ m_crun ];
+ for ( U8 i = 0; i < m_crun; ++i, ptr += Offset::sizeOf )
+ m_rgb[ i ].readPtr( ptr );
+
+ m_internalOffset = ( static_cast<U16>( m_crun ) + 1 ) * 4 + static_cast<U16>( m_crun ) * Offset::sizeOf;
+
+ // store the rest of the FKP in an internal array for later use
+ U16 length = 511 - m_internalOffset;
+ m_fkp = new U8[ length ]; // 511, because we don't need crun
+ for ( U16 i = 0; i < length; ++i, ++ptr )
+ m_fkp[ i ] = *ptr;
+ }
+
+ template<class Offset>
+ FKP<Offset>::FKP( const FKP<Offset>& rhs ) :
+ m_crun( rhs.m_crun ), m_internalOffset( rhs.m_internalOffset )
+ {
+ m_rgfc = new U32[ m_crun + 1 ];
+ ::memcpy( m_rgfc, rhs.m_rgfc, sizeof( U32 ) * ( m_crun + 1 ) );
+
+ m_rgb = new Offset[ m_crun ];
+ for ( U8 i = 0; i < m_crun; ++i )
+ m_rgb[ i ] = rhs.m_rgb[ i ];
+
+ const U16 length = 511 - m_internalOffset;
+ m_fkp = new U8[ length ]; // 511, because we don't need crun
+ ::memcpy( m_fkp, rhs.m_fkp, sizeof( U8 ) * length );
+ }
+
+
+ // Attention: This iterator has a non standard behavior of the current()
+ // method. Use it that way: for( ; !it.atEnd(); ++it)
+ template<class Offset> class FKPIterator
+ {
+ public:
+ FKPIterator( const FKP<Offset>& fkp ) : m_fkp( fkp ), m_index( 0 ) {}
+
+ void toFirst() { m_index = 0; }
+ void toLast() { m_index = m_fkp.m_crun - 1; }
+
+ U32 currentStart() const { if ( m_index < m_fkp.m_crun ) return m_fkp.m_rgfc[ m_index ]; return 0; }
+ U32 currentLim() const { if ( m_index < m_fkp.m_crun ) return m_fkp.m_rgfc[ m_index + 1 ]; return 0; }
+ Offset currentOffset() const { if ( m_index < m_fkp.m_crun ) return m_fkp.m_rgb[ m_index ]; return Offset(); }
+
+ // Pointer to the start of the current CHPX/PAPX/..., 0 if we are at the end of the array
+ // Attention: This iterator has a non standard behavior of the current()
+ // method. Use it that way: for( ; !it.atEnd(); ++it)
+ const U8* current() const;
+
+ FKPIterator& operator++() { if ( m_index < m_fkp.m_crun ) ++m_index; return *this; }
+ FKPIterator& operator--() { if ( m_index > 0 ) --m_index; return *this; }
+
+ U8 index() const { return m_index; }
+ void setIndex( U8 index ) { if ( index < m_fkp.m_crun ) m_index = index; }
+
+ bool atEnd() { return m_index >= m_fkp.m_crun; }
+
+ private:
+ // don't copy or assign it
+ FKPIterator( const FKPIterator<Offset>& rhs );
+ FKPIterator<Offset>& operator=( const FKPIterator<Offset>& rhs );
+
+ const FKP<Offset>& m_fkp;
+ U8 m_index;
+ };
+
+ template<class Offset>
+ const U8* FKPIterator<Offset>::current() const
+ {
+ if ( m_index < m_fkp.m_crun ) {
+ // Note: The first byte of the "offset" types (BX or U8) is always
+ // the word offset into the array (or 0!).
+ const U8 tmp = m_fkp.m_rgb[ m_index ].offset;
+ // Now we have to calculate the real offset and then locate it
+ // within our cached array...
+ if ( tmp != 0 ) {
+ const int pos = tmp * 2 - m_fkp.m_internalOffset;
+ if ( pos < 0 ) {
+ wvlog << "ERROR: FKP internalOffset (" << m_fkp.m_internalOffset << ") is bigger than " <<
+ "2*" << (int)tmp << ", FKP array index would be negative!" << std::endl;
+ return 0;
+ } else if ( pos >= 511 - m_fkp.m_internalOffset ) {
+ wvlog << "ERROR: FKP array index (" << pos << " is bigger than allocated size ("
+ << 511 - m_fkp.m_internalOffset << ")" << std::endl;
+ return 0;
+ } else {
+ return &m_fkp.m_fkp[ pos ];
+ }
+ }
+ }
+ return 0;
+ }
+
+
+ /**
+ * BX entry in a PAP FKP (1 byte word offset + 1 PHE). This is a template, as Word 95
+ * PHEs are shorter than Word 97 ones.
+ */
+ template<typename PHE> struct BX
+ {
+ /**
+ * Creates an empty BX structure and sets the defaults
+ */
+ BX() { clear(); }
+ /**
+ * Simply calls read(...)
+ */
+ BX( OLEStreamReader* stream, bool preservePos = false )
+ {
+ clear();
+ read( stream, preservePos );
+ }
+ /**
+ * Simply calls readPtr(...)
+ */
+ BX( const U8* ptr )
+ {
+ clear();
+ readPtr( ptr );
+ }
+
+ /**
+ * This method reads the BX structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read( OLEStreamReader* stream, bool preservePos = false )
+ {
+ if ( preservePos )
+ stream->push();
+ offset = stream->readU8();
+ phe.read( stream, false );
+ if ( preservePos )
+ stream->pop();
+ return true;
+ }
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr( const U8* ptr )
+ {
+ offset = *ptr;
+ ++ptr;
+ phe.readPtr( ptr );
+ }
+
+ /**
+ * Same as reading :)
+ */
+ bool write( OLEStreamWriter* stream, bool preservePos = false ) const
+ {
+ if ( preservePos )
+ stream->push();
+ stream->write( offset );
+ phe.write( stream, false );
+ if ( preservePos )
+ stream->pop();
+ return true;
+ }
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear()
+ {
+ offset = 0;
+ phe.clear();
+ }
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * One byte offset. This byte is a word offset, so that we can
+ * address 512 bytes with one unsigned char and all the CHPX/PAPX
+ * grpprls are aligned at 2 byte boundaries.
+ */
+ U8 offset;
+
+ /**
+ * The PHE for the paragraph described by this BX structure.
+ */
+ PHE phe;
+
+ };
+
+ template<typename PHE> const unsigned int BX<PHE>::sizeOf = 1 + PHE::sizeOf;
+
+ template<typename PHE> bool operator==( const BX<PHE>& lhs, const BX<PHE>& rhs )
+ {
+ return lhs.offset == rhs.offset && lhs.phe == rhs.phe;
+ }
+
+ template<typename PHE> bool operator!=( const BX<PHE>& lhs, const BX<PHE>& rhs )
+ {
+ return !( lhs == rhs );
+ }
+
+
+ /**
+ * A fake "BX" entry in a CHP FKP (1 byte word offset only).
+ */
+ struct CHPFKP_BX
+ {
+ /**
+ * Creates an empty CHPFKP_BX structure and sets the defaults
+ */
+ CHPFKP_BX();
+ /**
+ * Simply calls read(...)
+ */
+ CHPFKP_BX( OLEStreamReader* stream, bool preservePos = false );
+ /**
+ * Simply calls readPtr(...)
+ */
+ CHPFKP_BX( const U8* ptr );
+
+ /**
+ * This method reads the CHPFKP_BX structure from the stream.
+ * If preservePos is true we push/pop the position of
+ * the stream to save the state. If it's false the state
+ * of stream will be changed!
+ */
+ bool read( OLEStreamReader* stream, bool preservePos = false );
+ /**
+ * This method reads the struct from a pointer
+ */
+ void readPtr( const U8* ptr );
+
+ /**
+ * Same as reading :)
+ */
+ bool write( OLEStreamWriter* stream, bool preservePos = false ) const;
+
+ /**
+ * Set all the fields to the inital value (default is 0)
+ */
+ void clear();
+
+ // Size of the structure
+ static const unsigned int sizeOf;
+
+ // Data
+ /**
+ * One byte offset. This byte is a word offset, so that we can
+ * address 512 bytes with one unsigned char and all the CHPX/PAPX
+ * grpprls are aligned at 2 byte boundaries.
+ */
+ U8 offset;
+ };
+
+ bool operator==( const CHPFKP_BX& lhs, const CHPFKP_BX& rhs );
+ bool operator!=( const CHPFKP_BX& lhs, const CHPFKP_BX& rhs );
+
+
+ // This enum is a "convenience enum" for reading the piece table
+ typedef enum {
+ clxtGrpprl = 1,
+ clxtPlcfpcd = 2
+ } clxtENUM;
+
+} // namespace wvWare
+
+#endif // WORD_HELPER_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/wv2version.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/wv2version.cpp
new file mode 100644
index 00000000..f09b4218
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/wv2version.cpp
@@ -0,0 +1,45 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2003 KOffice Team
+ Copyright (C) 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "wv2version.h"
+
+unsigned int wvWare::version()
+{
+ return WV2_VERSION;
+}
+
+unsigned int wvWare::versionMajor()
+{
+ return WV2_VERSION_MAJOR;
+}
+
+unsigned int wvWare::versionMinor()
+{
+ return WV2_VERSION_MINOR;
+}
+
+unsigned int wvWare::versionRelease()
+{
+ return WV2_VERSION_RELEASE;
+}
+
+const char *wvWare::versionString()
+{
+ return WV2_VERSION_STRING;
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/wv2version.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/wv2version.h
new file mode 100644
index 00000000..6abfad0d
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/wv2version.h
@@ -0,0 +1,69 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2003 KOffice Team
+ Copyright (C) 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef WV2_VERSION_H
+#define WV2_VERSION_H
+
+#define WV2_VERSION_STRING "0.4.2"
+#define WV2_VERSION_MAJOR 0
+#define WV2_VERSION_MINOR 4
+#define WV2_VERSION_RELEASE 2
+#define WV2_MAKE_VERSION( a, b, c ) ( ( ( a ) << 16 ) | ( ( b ) << 8 ) | ( c ) )
+
+#define WV2_VERSION \
+ WV2_MAKE_VERSION( WV2_VERSION_MAJOR, WV2_VERSION_MINOR, WV2_VERSION_RELEASE )
+
+#define WV2_IS_VERSION( a, b, c ) ( WV2_VERSION >= WV2_MAKE_VERSION( a, b, c ) )
+
+namespace wvWare
+{
+ /**
+ * Returns the encoded number of wv2's version, see the WV2_VERSION macro.
+ * In contrary to that macro this function returns the number of the actually
+ * installed wv2 version, not the number of the wv2 version that was
+ * installed when the program was compiled.
+ * @return the version number, encoded in a single uint
+ */
+ unsigned int version();
+ /**
+ * Returns the major number of wv2's version, e.g.
+ * 0 for wv2 0.2.5.
+ * @return the major version number
+ */
+ unsigned int versionMajor();
+ /**
+ * Returns the minor number of wv2's version, e.g.
+ * 2 for wv2 0.2.5.
+ * @return the minor version number
+ */
+ unsigned int versionMinor();
+ /**
+ * Returns the release of wv2's version, e.g.
+ * 5 for wv2 0.2.5.
+ * @return the release number
+ */
+ unsigned int versionRelease();
+ /**
+ * Returns the wv2 version as string, e.g. "0.2.5".
+ * @return the wv2 version. You can keep the string forever
+ */
+ const char *versionString();
+}
+
+#endif // WV2_VERSION_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/wvlog.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/src/wvlog.cpp
new file mode 100644
index 00000000..a6c198ed
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/wvlog.cpp
@@ -0,0 +1,24 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "wvlog.h"
+
+namespace wvWare
+{
+ const wvlogstream wvlog = wvlog;
+} // wvWare
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/wvlog.h b/debian/wv2/wv2-0.4.2.dfsg.2/src/wvlog.h
new file mode 100644
index 00000000..7fea8d7e
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/wvlog.h
@@ -0,0 +1,117 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef WVLOG_H
+#define WVLOG_H
+
+#include <iostream>
+#include <string> // Make gcc 2.95.x happy
+
+// ...and work around gcc 2.95.x's STL problems (e.g. ostream isn't a template)
+#if defined(__GNUC__)
+# if __GNUC__ < 3
+# define WV2_OLD_STL_WORKAROUND 1
+# endif
+#endif
+
+/**
+ * @file A very primitve logging mechanism used to disable any
+ * debug output for release builds. Use it like std::cerr, as it
+ * is std::cerr (if it's enabled).
+ */
+namespace wvWare
+{
+
+ class wvdebugstream
+ {
+ public:
+#ifdef WV2_OLD_STL_WORKAROUND
+ const wvdebugstream& operator<<( ostream& (*__pf)( ostream& ) ) const { std::cerr << __pf; return *this; }
+ const wvdebugstream& operator<<( ios (*__pf)( ios& ) ) const { std::cerr << __pf; return *this; }
+#else
+ const wvdebugstream& operator<<( std::basic_ostream<char>& (*__pf)( std::basic_ostream<char>& ) ) const { std::cerr << __pf; return *this; }
+ const wvdebugstream& operator<<( std::ios (*__pf)( std::ios& ) ) const { std::cerr << __pf; return *this; }
+ const wvdebugstream& operator<<( std::ios_base& (*__pf) ( std::ios_base& ) ) const { std::cerr << __pf; return *this; }
+#endif
+ const wvdebugstream& operator<<( long l ) const { std::cerr << l; return *this; }
+ const wvdebugstream& operator<<( unsigned long l ) const { std::cerr << l; return *this; }
+ const wvdebugstream& operator<<( bool b ) const { std::cerr << b; return *this; }
+ const wvdebugstream& operator<<( short s ) const { std::cerr << s; return *this; }
+ const wvdebugstream& operator<<( unsigned short s ) const { std::cerr << s; return *this; }
+ const wvdebugstream& operator<<( int i ) const { std::cerr << i; return *this; }
+ const wvdebugstream& operator<<( unsigned int i ) const { std::cerr << i; return *this; }
+ const wvdebugstream& operator<<( double d ) const { std::cerr << d; return *this; }
+ const wvdebugstream& operator<<( float f ) const { std::cerr << f; return *this; }
+ const wvdebugstream& operator<<( long double d ) const { std::cerr << d; return *this; }
+ const wvdebugstream& operator<<( const void* cv ) const { std::cerr << cv; return *this; }
+#ifdef WV2_OLD_STL_WORKAROUND
+ const wvdebugstream& operator<<( streambuf* s ) const { std::cerr << s; return *this; }
+#else
+ const wvdebugstream& operator<<( std::basic_streambuf<char>* s ) const { std::cerr << s; return *this; }
+#endif
+ const wvdebugstream& operator<<( signed char c ) const { std::cerr << c; return *this; }
+ const wvdebugstream& operator<<( unsigned char c ) const { std::cerr << c; return *this; }
+ const wvdebugstream& operator<<( const char* s ) const { std::cerr << s; return *this; }
+ const wvdebugstream& operator<<( const std::string& s ) const { std::cerr << s; return *this; }
+ };
+
+
+ class wvnodebugstream
+ {
+ public:
+#ifdef WV2_OLD_STL_WORKAROUND
+ const wvnodebugstream& operator<<( ostream& (*__pf)( ostream& ) ) const { std::cerr << __pf; return *this; }
+ const wvnodebugstream& operator<<( ios (*__pf)( ios& ) ) const { std::cerr << __pf; return *this; }
+#else
+ const wvnodebugstream& operator<<( std::basic_ostream<char>& (*__pf)( std::basic_ostream<char>& ) ) const { return *this; }
+ const wvnodebugstream& operator<<( std::ios (*__pf)( std::ios& ) ) const { return *this; }
+ const wvnodebugstream& operator<<( std::ios_base& (*__pf) ( std::ios_base& ) ) const { return *this; }
+#endif
+ const wvnodebugstream& operator<<( long ) const { return *this; }
+ const wvnodebugstream& operator<<( unsigned long ) const { return *this; }
+ const wvnodebugstream& operator<<( bool ) const { return *this; }
+ const wvnodebugstream& operator<<( short ) const { return *this; }
+ const wvnodebugstream& operator<<( unsigned short ) const { return *this; }
+ const wvnodebugstream& operator<<( int ) const { return *this; }
+ const wvnodebugstream& operator<<( unsigned int ) const { return *this; }
+ const wvnodebugstream& operator<<( double ) const { return *this; }
+ const wvnodebugstream& operator<<( float ) const { return *this; }
+ const wvnodebugstream& operator<<( long double ) const { return *this; }
+ const wvnodebugstream& operator<<( const void* ) const { return *this; }
+#ifdef WV2_OLD_STL_WORKAROUND
+ const wvnodebugstream& operator<<( streambuf* ) const { return *this; }
+#else
+ const wvnodebugstream& operator<<( std::basic_streambuf<char>* ) const { return *this; }
+#endif
+ const wvnodebugstream& operator<<( signed char ) const { return *this; }
+ const wvnodebugstream& operator<<( unsigned char ) const { return *this; }
+ const wvnodebugstream& operator<<( const char* ) const { return *this; }
+ const wvnodebugstream& operator<<( const std::string& ) const { return *this; }
+ };
+
+#ifdef NDEBUG
+ typedef wvnodebugstream wvlogstream;
+#else
+ typedef wvdebugstream wvlogstream;
+#endif
+
+ extern const wvlogstream wvlog;
+
+} // wvWare
+
+#endif // WVLOG_H
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/zcodec.cxx b/debian/wv2/wv2-0.4.2.dfsg.2/src/zcodec.cxx
new file mode 100644
index 00000000..d0bf508b
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/zcodec.cxx
@@ -0,0 +1,573 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: zcodec.cxx,v $
+ *
+ * $Revision: 1.4 $
+ *
+ * last change: $Author: tuubaaku $ $Date: 2009/02/14 02:51:13 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+/*
+ * Modified by Benjamin Cail for wv2
+ */
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+//#include "precompiled_tools.hxx"
+
+//#ifndef _STREAM_HXX
+//#include <tools/stream.hxx>
+//#endif
+#include "olestream.h"
+
+#ifndef _ZLIB_H
+//#ifdef SYSTEM_ZLIB
+#include "zlib.h"
+//#else
+//#include "zlib/zlib.h"
+//#endif
+#endif
+
+#ifndef _ZCODEC_HXX
+#include "zcodec.hxx"
+#endif
+//#ifndef _RTL_CRC_H_
+//#include <rtl/crc.h>
+//#endif
+//#ifndef _OSL_ENDIAN_H_
+//#include <osl/endian.h>
+//#endif
+
+#include "wvlog.h" //give us wv2 logging capabilities
+
+// -----------
+// - Defines -
+// -----------
+
+//z_stream is a struct defined in zlib
+//define PZSTREAM as a pointer to mpsC_Stream, which is
+//cast as a pointer to a z_stream
+#define PZSTREAM ((z_stream*) mpsC_Stream)
+
+/* gzip flag byte */
+#define GZ_ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
+#define GZ_HEAD_CRC 0x02 /* bit 1 set: header CRC present */
+#define GZ_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define GZ_ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define GZ_COMMENT 0x10 /* bit 4 set: file comment present */
+#define GZ_RESERVED 0xE0 /* bits 5..7: reserved */
+
+static int gz_magic[2] = { 0x1f, 0x8b }; /* gzip magic header */
+
+
+// ----------
+// - ZCodec -
+// ----------
+
+ZCodec::ZCodec( ULONG nInBufSize, ULONG nOutBufSize, ULONG nMemUsage )
+ : mnCRC(0)
+{
+ wvlog << "Creating ZCodec object..." << std::endl;
+ //initialize variables
+ mnMemUsage = nMemUsage;
+ mnInBufSize = nInBufSize;
+ mnOutBufSize = nOutBufSize;
+ //create a new z_stream
+ mpsC_Stream = new z_stream;
+}
+
+ZCodec::ZCodec( void )
+ : mnCRC(0)
+{
+ //set variables to defaults
+ mnMemUsage = MAX_MEM_USAGE;
+ mnInBufSize = DEFAULT_IN_BUFSIZE;
+ mnOutBufSize = DEFAULT_OUT_BUFSIZE;
+ //create new z_stream
+ mpsC_Stream = new z_stream;
+}
+
+// ------------------------------------------------------------------------
+
+ZCodec::~ZCodec()
+{
+ delete (z_stream*) mpsC_Stream;
+}
+
+// ------------------------------------------------------------------------
+
+void ZCodec::BeginCompression( ULONG nCompressMethod )
+{
+ mbInit = 0;
+ mbStatus = TRUE;
+ mbFinish = FALSE;
+ mpIStm = NULL;
+ 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(std::vector<U8>* outBuffer)
+{
+ long retvalue = 0;
+
+ //various actions based on mbInit value...
+ if ( mbInit != 0 )
+ {
+ if ( mbInit & 2 ) // 1->decompress, 3->compress
+ {
+ do
+ {
+ ImplWriteBack(outBuffer);
+ }
+ while ( deflate( PZSTREAM, Z_FINISH ) != Z_STREAM_END );
+
+ ImplWriteBack(outBuffer);
+
+ retvalue = PZSTREAM->total_in;
+ deflateEnd( PZSTREAM );
+ }
+ else
+ {
+ retvalue = PZSTREAM->total_out;
+ inflateEnd( PZSTREAM );
+ }
+ delete[] mpOutBuf;
+ delete[] mpInBuf;
+ }
+ return ( mbStatus ) ? retvalue : -1;
+}
+
+
+// ------------------------------------------------------------------------
+
+long ZCodec::Compress( OLEStreamReader& rIStm, OLEStreamWriter& rOStm )
+{
+ long nOldTotal_In = PZSTREAM->total_in;
+
+ if ( mbInit == 0 )
+ {
+ //set streams
+ mpIStm = &rIStm;
+ mpOStm = &rOStm;
+ ImplInitBuf( FALSE );
+ mpInBuf = new BYTE[ mnInBufSize ];
+ }
+ while (( PZSTREAM->avail_in = mpIStm->read( PZSTREAM->next_in = mpInBuf, mnInBufSize )) != 0 )
+ {
+ //fix this if I ever use this function...
+ if ( PZSTREAM->avail_out == 0 );
+ //ImplWriteBack();
+ if ( deflate( PZSTREAM, Z_NO_FLUSH ) < 0 )
+ {
+ mbStatus = FALSE;
+ break;
+ }
+ };
+ return ( mbStatus ) ? (long)(PZSTREAM->total_in - nOldTotal_In) : -1;
+}
+
+// ------------------------------------------------------------------------
+
+long ZCodec::Decompress( OLEStreamReader& rIStm, std::vector<U8>* outBuffer )
+{
+ wvlog << "Decompressing... (mnInToRead=" << mnInToRead << ",avail_in="
+ << PZSTREAM->avail_in << ")" << std::endl;
+ int err;
+ ULONG nInToRead;
+ long nOldTotal_Out = PZSTREAM->total_out;
+
+ if ( mbFinish )
+ return PZSTREAM->total_out - nOldTotal_Out;
+
+ if ( mbInit == 0 )
+ {
+ wvlog << " decompression initialization" << std::endl;
+ mpIStm = &rIStm;
+ //mpOStm = &rOStm;
+ ImplInitBuf( TRUE );
+ PZSTREAM->next_out = mpOutBuf = new BYTE[ PZSTREAM->avail_out = mnOutBufSize ];
+ }
+ //loop through all the data to be decompressed
+ do
+ {
+ wvlog << "top of do-while loop; PZSTREAM->avail_out=" << PZSTREAM->avail_out
+ << "; PZSTREAM->avail_in=" << PZSTREAM->avail_in << "; mnInToRead=" << mnInToRead << std::endl;
+ //replenish in-buffer if needed
+ if ( PZSTREAM->avail_in == 0 && mnInToRead )
+ {
+ //figure out how many bytes to read - whatever's left that can be handled by in-buffer
+ nInToRead = ( mnInBufSize > mnInToRead ) ? mnInToRead : mnInBufSize;
+ //read some more bytes
+ wvlog << " trying to read " << nInToRead << " bytes from stream at "
+ << mpIStm->tell() << std::endl;
+ //read nInToRead bytes into the next_in, which is mpInBuf
+ //and put number of bytes read into avail_in
+ //PZSTREAM->avail_in =
+ //this read() function doesn't return the number of bytes read...
+ bool read = mpIStm->read( PZSTREAM->next_in = mpInBuf, nInToRead );
+ if(!read)
+ wvlog << "Error reading bytes!" << std::endl;
+ PZSTREAM->avail_in = nInToRead;
+ //update the number of bytes left to read
+ mnInToRead -= nInToRead;
+
+ //TODO fix CRC handling
+ //if ( mnCompressMethod & ZCODEC_UPDATE_CRC )
+ // mnCRC = UpdateCRC( mnCRC, mpInBuf, nInToRead );
+
+ }
+ //actually perform the decompression, storing error code in err
+ wvlog << " inflate()" << std::endl;
+ err = inflate( PZSTREAM, Z_NO_FLUSH );
+ wvlog << "inflate() return code: " << err << std::endl;
+ if ( err < 0 )
+ {
+ mbStatus = FALSE;
+ break;
+ }
+ //now write that decompressed data to the data vector
+ ImplWriteBack(outBuffer);
+ }
+ while ( ( err != Z_STREAM_END) && ( PZSTREAM->avail_in || mnInToRead ) );
+
+ //set the "finished" flag if we got the stream-end signal?
+ if ( err == Z_STREAM_END )
+ mbFinish = TRUE;
+ wvlog << " total_in=" << PZSTREAM->total_in << ",total_out=" << PZSTREAM->total_out << std::endl;
+ //return code: -1 if mbStatus is false, otherwise # of bytes decompressed
+ return ( mbStatus ) ? (long)(PZSTREAM->total_out - nOldTotal_Out) : -1;
+}
+
+// ------------------------------------------------------------------------
+
+void ZCodec::ImplWriteBack( std::vector<U8>* outBuffer )
+{
+ ULONG nAvail = mnOutBufSize - PZSTREAM->avail_out;
+ wvlog << "ImplWriteBack() nAvail=" << nAvail << std::endl;
+
+ if ( nAvail )
+ {
+ //TODO fix CRC handling
+ //if ( mbInit & 2 && ( mnCompressMethod & ZCODEC_UPDATE_CRC ) )
+ // mnCRC = UpdateCRC( mnCRC, mpOutBuf, nAvail );
+ //mpOStm->write( PZSTREAM->next_out = mpOutBuf, nAvail );
+ for(int i = 0; i < nAvail; i++)
+ {
+ outBuffer->push_back( (U8) mpOutBuf[i]);
+ }
+ //reset PZSTREAM settings
+ PZSTREAM->avail_out = mnOutBufSize;
+ PZSTREAM->next_out = mpOutBuf;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void ZCodec::SetBreak( ULONG nInToRead )
+{
+ mnInToRead = nInToRead;
+}
+
+// ------------------------------------------------------------------------
+
+void ZCodec::ImplInitBuf ( BOOL nIOFlag )
+{
+ if ( mbInit == 0 )
+ {
+ if ( nIOFlag )
+ {
+ mbInit = 1;
+ if ( mbStatus && ( mnCompressMethod & ZCODEC_GZ_LIB ) )
+ {
+ U8 n1, n2, j, nMethod, nFlags;
+ for ( int i = 0; i < 2; i++ ) // gz - magic number
+ {
+ //*mpIStm >> j;
+ mpIStm->read(&j, 1);
+ if ( j != gz_magic[ i ] )
+ mbStatus = FALSE;
+ }
+ //*mpIStm >> nMethod;
+ mpIStm->read(&nMethod, 1);
+ //*mpIStm >> nFlags;
+ mpIStm->read(&nFlags, 1);
+ if ( nMethod != Z_DEFLATED )
+ mbStatus = FALSE;
+ if ( ( nFlags & GZ_RESERVED ) != 0 )
+ mbStatus = FALSE;
+ /* Discard time, xflags and OS code: */
+ //mpIStm->SeekRel( 6 );
+ mpIStm->seek( 6, G_SEEK_CUR );
+ /* skip the extra field */
+ if ( nFlags & GZ_EXTRA_FIELD )
+ {
+ //*mpIStm >> n1 >> n2;
+ mpIStm->read(&n1, 1);
+ mpIStm->read(&n2, 1);
+ //mpIStm->SeekRel( n1 + ( n2 << 8 ) );
+ mpIStm->seek( n1 + ( n2 << 8 ), G_SEEK_CUR );
+ }
+ /* skip the original file name */
+ if ( nFlags & GZ_ORIG_NAME)
+ {
+ do
+ {
+ //*mpIStm >> j;
+ mpIStm->read(&j, 1);
+ }
+ //while ( j && !mpIStm->IsEof() );
+ while ( j && mpIStm->isValid() ); //TODO check this!
+ }
+ /* skip the .gz file comment */
+ if ( nFlags & GZ_COMMENT )
+ {
+ do
+ {
+ //*mpIStm >> j;
+ mpIStm->read(&j, 1);
+ }
+ //while ( j && !mpIStm->IsEof() );
+ while ( j && mpIStm->isValid() ); //TODO check this!
+ }
+ /* skip the header crc */
+ if ( nFlags & GZ_HEAD_CRC )
+ //mpIStm->SeekRel( 2 );
+ mpIStm->seek( 2, G_SEEK_CUR);
+ if ( mbStatus )
+ mbStatus = ( inflateInit2( PZSTREAM, -MAX_WBITS) != Z_OK ) ? FALSE : TRUE;
+ }
+ else
+ {
+ mbStatus = ( inflateInit( PZSTREAM ) >= 0 );
+ }
+ mpInBuf = new BYTE[ mnInBufSize ];
+ }
+ else
+ {
+ mbInit = 3;
+
+ mbStatus = ( deflateInit2_( PZSTREAM, mnCompressMethod & 0xff, Z_DEFLATED,
+ MAX_WBITS, mnMemUsage, ( mnCompressMethod >> 8 ) & 0xff,
+ ZLIB_VERSION, sizeof( z_stream ) ) >= 0 );
+
+ PZSTREAM->next_out = mpOutBuf = new BYTE[ PZSTREAM->avail_out = mnOutBufSize ];
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+/*
+long ZCodec::Write( OLEStreamWriter& rOStm, const BYTE* pData, ULONG nSize )
+{
+ if ( mbInit == 0 )
+ {
+ mpOStm = &rOStm;
+ ImplInitBuf( FALSE );
+ }
+
+ PZSTREAM->avail_in = nSize;
+ PZSTREAM->next_in = (unsigned char*)pData;
+
+ while ( PZSTREAM->avail_in || ( PZSTREAM->avail_out == 0 ) )
+ {
+ if ( PZSTREAM->avail_out == 0 )
+ ImplWriteBack();
+
+ if ( deflate( PZSTREAM, Z_NO_FLUSH ) < 0 )
+ {
+ mbStatus = FALSE;
+ break;
+ }
+ }
+ return ( mbStatus ) ? (long)nSize : -1;
+}
+
+// ------------------------------------------------------------------------
+
+long ZCodec::Read( OLEStreamReader& rIStm, BYTE* pData, ULONG nSize )
+{
+ int err;
+ ULONG nInToRead;
+
+ if ( mbFinish )
+ return 0; // PZSTREAM->total_out;
+
+ mpIStm = &rIStm;
+ if ( mbInit == 0 )
+ {
+ ImplInitBuf( TRUE );
+ }
+ PZSTREAM->avail_out = nSize;
+ PZSTREAM->next_out = pData;
+ do
+ {
+ if ( PZSTREAM->avail_in == 0 && mnInToRead )
+ {
+ nInToRead = (mnInBufSize > mnInToRead) ? mnInToRead : mnInBufSize;
+ PZSTREAM->avail_in = mpIStm->read (
+ PZSTREAM->next_in = mpInBuf, nInToRead);
+ mnInToRead -= nInToRead;
+
+ //TODO fix CRC handling
+ //if ( mnCompressMethod & ZCODEC_UPDATE_CRC )
+ // mnCRC = UpdateCRC( mnCRC, mpInBuf, nInToRead );
+
+ }
+ err = inflate( PZSTREAM, Z_NO_FLUSH );
+ if ( err < 0 )
+ {
+ // Accept Z_BUF_ERROR as EAGAIN or EWOULDBLOCK.
+ mbStatus = (err == Z_BUF_ERROR);
+ break;
+ }
+ }
+ while ( (err != Z_STREAM_END) &&
+ (PZSTREAM->avail_out != 0) &&
+ (PZSTREAM->avail_in || mnInToRead) );
+ if ( err == Z_STREAM_END )
+ mbFinish = TRUE;
+
+ return (mbStatus ? (long)(nSize - PZSTREAM->avail_out) : -1);
+}
+
+// ------------------------------------------------------------------------
+
+long ZCodec::ReadAsynchron( OLEStreamReader& rIStm, BYTE* pData, ULONG nSize )
+{
+ int err = 0;
+ ULONG nInToRead;
+
+ if ( mbFinish )
+ return 0; // PZSTREAM->total_out;
+
+ if ( mbInit == 0 )
+ {
+ mpIStm = &rIStm;
+ ImplInitBuf( TRUE );
+ }
+ PZSTREAM->avail_out = nSize;
+ PZSTREAM->next_out = pData;
+ do
+ {
+ if ( PZSTREAM->avail_in == 0 && mnInToRead )
+ {
+ nInToRead = (mnInBufSize > mnInToRead) ? mnInToRead : mnInBufSize;
+
+ ULONG nStreamPos = rIStm.tell();
+ rIStm.seek( G_SEEK_END );
+ ULONG nMaxPos = rIStm.tell();
+ rIStm.seek( nStreamPos );
+ if ( ( nMaxPos - nStreamPos ) < nInToRead )
+ {
+ //TODO figure out the replacement code for this
+ //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;
+
+ //TODO fix CRC handling
+ //if ( mnCompressMethod & ZCODEC_UPDATE_CRC )
+ // mnCRC = UpdateCRC( mnCRC, mpInBuf, nInToRead );
+
+ }
+ err = inflate( PZSTREAM, Z_NO_FLUSH );
+ if ( err < 0 )
+ {
+ // Accept Z_BUF_ERROR as EAGAIN or EWOULDBLOCK.
+ mbStatus = (err == Z_BUF_ERROR);
+ break;
+ }
+ }
+ while ( (err != Z_STREAM_END) &&
+ (PZSTREAM->avail_out != 0) &&
+ (PZSTREAM->avail_in || mnInToRead) );
+ if ( err == Z_STREAM_END )
+ mbFinish = TRUE;
+
+ return (mbStatus ? (long)(nSize - PZSTREAM->avail_out) : -1);
+}
+
+// ------------------------------------------------------------------------
+
+ULONG ZCodec::GetBreak( void )
+{
+ return ( mnInToRead + PZSTREAM->avail_in );
+}
+
+// ------------------------------------------------------------------------
+
+void ZCodec::SetCRC( ULONG nCRC )
+{
+ mnCRC = nCRC;
+}
+
+// ------------------------------------------------------------------------
+
+ULONG ZCodec::GetCRC()
+{
+ return mnCRC;
+}
+
+// ------------------------------------------------------------------------
+
+/*ULONG ZCodec::UpdateCRC ( ULONG nLatestCRC, ULONG nNumber )
+{
+
+#ifdef OSL_LITENDIAN
+ nNumber = SWAPLONG( nNumber );
+#endif
+ return rtl_crc32( nLatestCRC, &nNumber, 4 );
+}
+
+// ------------------------------------------------------------------------
+
+ULONG ZCodec::UpdateCRC ( ULONG nLatestCRC, BYTE* pSource, long nDatSize)
+{
+ return rtl_crc32( nLatestCRC, pSource, nDatSize );
+}
+
+// ------------------------------------------------------------------------
+
+void GZCodec::BeginCompression( ULONG nCompressMethod )
+{
+ ZCodec::BeginCompression( nCompressMethod | ZCODEC_GZ_LIB );
+}*/
+
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/src/zcodec.hxx b/debian/wv2/wv2-0.4.2.dfsg.2/src/zcodec.hxx
new file mode 100644
index 00000000..a099fc17
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/src/zcodec.hxx
@@ -0,0 +1,151 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: zcodec.hxx,v $
+ *
+ * $Revision: 1.4 $
+ *
+ * last change: $Author: tuubaaku $ $Date: 2009/02/14 02:51:13 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef _ZCODEC_HXX
+#define _ZCODEC_HXX
+
+//#ifndef INCLUDED_TOOLSDLLAPI_H
+//#include "tools/toolsdllapi.h"
+//#endif
+
+//#ifndef _SOLAR_H
+//#include <tools/solar.h>
+//#endif
+
+#include "global.h" //for U8
+#include <vector> //for std::vector
+
+// -----------
+// - 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 OLEStreamReader;
+//class OLEStreamWriter;
+
+using namespace wvWare;
+
+typedef unsigned long ULONG;
+typedef bool BOOL;
+typedef U8 BYTE;
+
+class ZCodec
+{
+private:
+
+ ULONG mbInit;
+ BOOL mbStatus; //status good or bad
+ BOOL mbFinish; //are we finished yet?
+ ULONG mnMemUsage; //total memory we can use?
+ OLEStreamReader* mpIStm; //in-stream
+ BYTE* mpInBuf; //in-buffer
+ ULONG mnInBufSize; //size of the in-buffer
+ ULONG mnInToRead; //how many bytes overall we still want to read
+ OLEStreamWriter* mpOStm; //out-stream
+ BYTE* mpOutBuf; //out-buffer
+ ULONG mnOutBufSize; //size of the out-buffer
+
+ ULONG mnCRC;
+ ULONG mnCompressMethod;
+ void* mpsC_Stream;
+
+ void ImplInitBuf( BOOL nIOFlag );
+ void ImplWriteBack( std::vector<U8>* outBuffer );
+
+public:
+ ZCodec( ULONG nInBuf, ULONG nOutBuf, ULONG nMemUsage = MAX_MEM_USAGE );
+ ZCodec( void );
+ virtual ~ZCodec();
+
+ virtual void BeginCompression( ULONG nCompressMethod = ZCODEC_DEFAULT );
+ virtual long EndCompression(std::vector<U8>* outBuffer);
+ BOOL IsFinished () const { return mbFinish; }
+
+ long Compress( OLEStreamReader& rIStm, OLEStreamWriter& rOStm );
+ long Decompress( OLEStreamReader& rIStm, std::vector<U8>* outBuffer );
+
+ //long Write( OLEStreamWriter& rOStm, const BYTE* pData, ULONG nSize );
+ //long Read( OLEStreamReader& rIStm, BYTE* pData, ULONG nSize );
+ //long ReadAsynchron( OLEStreamReader& rIStm, BYTE* pData, ULONG nSize );
+
+ void SetBreak( ULONG );
+ //ULONG GetBreak( void );
+ //void SetCRC( ULONG nCurrentCRC );
+ //ULONG UpdateCRC( ULONG nLatestCRC, ULONG nSource );
+ //ULONG UpdateCRC( ULONG nLatestCRC, BYTE* pSource, long nDatSize );
+ //ULONG GetCRC();
+};
+
+class GZCodec : public ZCodec
+{
+
+public:
+ GZCodec(){};
+ ~GZCodec(){};
+ virtual void BeginCompression( ULONG nCompressMethod = ZCODEC_DEFAULT );
+};
+
+#endif // _ZCODEC_HXX
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/tests/.cvsignore b/debian/wv2/wv2-0.4.2.dfsg.2/tests/.cvsignore
new file mode 100644
index 00000000..717a7bf4
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/tests/.cvsignore
@@ -0,0 +1,15 @@
+Makefile.in
+Makefile
+.deps
+.libs
+oletest
+word9?_test
+test123456.doc
+word9?_test.doc
+iconvtest
+parsertest
+parsertest_mem
+helpertest
+ustringtest
+sharedptrtest
+handlertest
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/tests/CMakeLists.txt b/debian/wv2/wv2-0.4.2.dfsg.2/tests/CMakeLists.txt
new file mode 100644
index 00000000..249a156b
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/tests/CMakeLists.txt
@@ -0,0 +1,48 @@
+IF( EXISTS ${wvWare_BINARY_DIR}/config.h )
+ ADD_DEFINITIONS( -DHAVE_CONFIG_H )
+ENDIF( EXISTS ${wvWare_BINARY_DIR}/config.h )
+
+INCLUDE_DIRECTORIES( ${wvWare_BINARY_DIR} ${wvWare_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR} )
+
+SET( oletest_SOURCES oletest.cpp )
+ADD_EXECUTABLE( oletest EXCLUDE_FROM_ALL ${oletest_SOURCES} )
+TARGET_LINK_LIBRARIES( oletest wv2 ${LIBGSF_LIBRARIES} )
+
+SET( word97_test_SOURCES word97_test.cpp )
+ADD_EXECUTABLE( word97_test EXCLUDE_FROM_ALL ${word97_test_SOURCES} )
+TARGET_LINK_LIBRARIES( word97_test wv2 ${LIBGSF_LIBRARIES} )
+
+SET( word95_test_SOURCES word95_test.cpp )
+ADD_EXECUTABLE( word95_test EXCLUDE_FROM_ALL ${word95_test_SOURCES} )
+TARGET_LINK_LIBRARIES( word95_test wv2 ${LIBGSF_LIBRARIES} )
+
+SET( iconvtest_SOURCES iconvtest.cpp )
+ADD_EXECUTABLE( iconvtest EXCLUDE_FROM_ALL ${iconvtest_SOURCES} )
+TARGET_LINK_LIBRARIES( iconvtest wv2 ${LIBGSF_LIBRARIES} )
+
+SET( parsertest_SOURCES parsertest.cpp )
+ADD_EXECUTABLE( parsertest EXCLUDE_FROM_ALL ${parsertest_SOURCES} )
+TARGET_LINK_LIBRARIES( parsertest wv2 ${LIBGSF_LIBRARIES} )
+
+SET( parsertest_mem_SOURCES parsertest_mem.cpp )
+ADD_EXECUTABLE( parsertest_mem EXCLUDE_FROM_ALL ${parsertest_mem_SOURCES} )
+TARGET_LINK_LIBRARIES( parsertest_mem wv2 ${LIBGSF_LIBRARIES} )
+
+SET( helpertest_SOURCES helpertest.cpp )
+ADD_EXECUTABLE( helpertest EXCLUDE_FROM_ALL ${helpertest_SOURCES} )
+TARGET_LINK_LIBRARIES( helpertest wv2 ${LIBGSF_LIBRARIES} )
+
+SET( ustringtest_SOURCES ustringtest.cpp )
+ADD_EXECUTABLE( ustringtest EXCLUDE_FROM_ALL ${ustringtest_SOURCES} )
+TARGET_LINK_LIBRARIES( ustringtest wv2 ${LIBGSF_LIBRARIES} )
+
+SET( sharedptrtest_SOURCES sharedptrtest.cpp )
+ADD_EXECUTABLE( sharedptrtest EXCLUDE_FROM_ALL ${sharedptrtest_SOURCES} )
+TARGET_LINK_LIBRARIES( sharedptrtest wv2 ${LIBGSF_LIBRARIES} )
+
+SET( handlertest_SOURCES handlertest.cpp )
+ADD_EXECUTABLE( handlertest EXCLUDE_FROM_ALL ${handlertest_SOURCES} )
+TARGET_LINK_LIBRARIES( handlertest wv2 ${LIBGSF_LIBRARIES} )
+
+# Add a global 'make test' target
+ADD_CUSTOM_TARGET( test DEPENDS oletest word97_test word95_test iconvtest parsertest parsertest_mem helpertest ustringtest sharedptrtest handlertest )
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/tests/handlertest.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/tests/handlertest.cpp
new file mode 100644
index 00000000..47fa8c09
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/tests/handlertest.cpp
@@ -0,0 +1,404 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <parser.h>
+#include <handlers.h>
+#include <parserfactory.h>
+#include <word97_generated.h>
+#include <paragraphproperties.h>
+#include <lists.h>
+#include <ustring.h>
+#include <fields.h>
+
+#include <iostream>
+#include <string>
+
+
+class InlineReplacementTest : public wvWare::InlineReplacementHandler
+{
+public:
+ virtual wvWare::U8 tab();
+ virtual wvWare::U8 hardLineBreak();
+ virtual wvWare::U8 columnBreak();
+ virtual wvWare::U8 nonBreakingHyphen();
+ virtual wvWare::U8 nonRequiredHyphen();
+ virtual wvWare::U8 nonBreakingSpace();
+};
+
+
+class SubDocumentTest : public wvWare::SubDocumentHandler
+{
+public:
+ virtual void bodyStart();
+ virtual void bodyEnd();
+
+ virtual void footnoteStart();
+ virtual void footnoteEnd();
+
+ virtual void headersStart();
+ virtual void headersEnd();
+ virtual void headerStart( wvWare::HeaderData::Type type );
+ virtual void headerEnd();
+};
+
+
+class TableTest : public wvWare::TableHandler
+{
+public:
+ virtual void tableRowStart( wvWare::SharedPtr<const wvWare::Word97::TAP> tap );
+ virtual void tableRowEnd();
+ virtual void tableCellStart();
+ virtual void tableCellEnd();
+};
+
+
+class PictureTest : public wvWare::PictureHandler
+{
+public:
+ virtual void bitmapData( wvWare::OLEImageReader& reader, wvWare::SharedPtr<const wvWare::Word97::PICF> picf );
+ virtual void wmfData( wvWare::OLEImageReader& reader, wvWare::SharedPtr<const wvWare::Word97::PICF> picf );
+ virtual void externalImage( const wvWare::UString& name, wvWare::SharedPtr<const wvWare::Word97::PICF> picf );
+};
+
+
+class TextTest : public wvWare::TextHandler
+{
+public:
+ virtual void sectionStart( wvWare::SharedPtr<const wvWare::Word97::SEP> sep );
+ virtual void sectionEnd();
+ virtual void pageBreak();
+
+ virtual void headersFound( const wvWare::HeaderFunctor& parseHeaders );
+
+ virtual void paragraphStart( wvWare::SharedPtr<const wvWare::ParagraphProperties> paragraphProperties );
+ virtual void paragraphEnd();
+
+ virtual void runOfText( const wvWare::UString& text, wvWare::SharedPtr<const wvWare::Word97::CHP> chp );
+
+ virtual void specialCharacter( SpecialCharacter character, wvWare::SharedPtr<const wvWare::Word97::CHP> chp );
+
+ virtual void footnoteFound( wvWare::FootnoteData::Type type, wvWare::UChar character,
+ wvWare::SharedPtr<const wvWare::Word97::CHP> chp, const wvWare::FootnoteFunctor& parseFootnote );
+ virtual void footnoteAutoNumber( wvWare::SharedPtr<const wvWare::Word97::CHP> chp );
+
+ virtual void fieldStart( const wvWare::FLD* fld, wvWare::SharedPtr<const wvWare::Word97::CHP> chp );
+ virtual void fieldSeparator( const wvWare::FLD* fld, wvWare::SharedPtr<const wvWare::Word97::CHP> chp );
+ virtual void fieldEnd( const wvWare::FLD* fld, wvWare::SharedPtr<const wvWare::Word97::CHP> chp );
+
+ virtual void tableRowFound( const wvWare::TableRowFunctor& tableRow, wvWare::SharedPtr<const wvWare::Word97::TAP> tap );
+
+ virtual void pictureFound( const wvWare::PictureFunctor& picture, wvWare::SharedPtr<const wvWare::Word97::PICF> picf,
+ wvWare::SharedPtr<const wvWare::Word97::CHP> chp );
+};
+
+
+using namespace wvWare;
+std::string indent;
+
+U8 InlineReplacementTest::tab()
+{
+ std::cout << indent << "INLINE: tab" << std::endl;
+ return InlineReplacementHandler::tab();
+}
+
+U8 InlineReplacementTest::hardLineBreak()
+{
+ std::cout << indent << "INLINE: hard line break" << std::endl;
+ return InlineReplacementHandler::hardLineBreak();
+}
+
+U8 InlineReplacementTest::columnBreak()
+{
+ std::cout << indent << "INLINE: column break" << std::endl;
+ return InlineReplacementHandler::columnBreak();
+}
+
+U8 InlineReplacementTest::nonBreakingHyphen()
+{
+ std::cout << indent << "INLINE: non breaking hyphen" << std::endl;
+ return InlineReplacementHandler::nonBreakingHyphen();
+}
+
+U8 InlineReplacementTest::nonRequiredHyphen()
+{
+ std::cout << indent << "INLINE: non required hyphen" << std::endl;
+ return InlineReplacementHandler::nonRequiredHyphen();
+}
+
+U8 InlineReplacementTest::nonBreakingSpace()
+{
+ std::cout << indent << "INLINE: non breaking space" << std::endl;
+ return InlineReplacementHandler::nonBreakingSpace();
+}
+
+
+void SubDocumentTest::bodyStart()
+{
+ std::cout << indent << "SUBDOCUMENT: body start" << std::endl;
+ indent.push_back( ' ' );
+ SubDocumentHandler::bodyStart();
+}
+
+void SubDocumentTest::bodyEnd()
+{
+ std::cout << indent << "SUBDOCUMENT: body end" << std::endl;
+ indent.erase( indent.size() - 1 );
+ SubDocumentHandler::bodyEnd();
+}
+
+void SubDocumentTest::footnoteStart()
+{
+ std::cout << indent << "SUBDOCUMENT: footnote start" << std::endl;
+ indent.push_back( ' ' );
+ SubDocumentHandler::footnoteStart();
+}
+
+void SubDocumentTest::footnoteEnd()
+{
+ std::cout << indent << "SUBDOCUMENT: footnote end" << std::endl;
+ indent.erase( indent.size() - 1 );
+ SubDocumentHandler::footnoteEnd();
+}
+
+void SubDocumentTest::headersStart()
+{
+ std::cout << indent << "SUBDOCUMENT: headers start" << std::endl;
+ indent.push_back( ' ' );
+ SubDocumentHandler::headersStart();
+}
+
+void SubDocumentTest::headersEnd()
+{
+ std::cout << indent << "SUBDOCUMENT: headers end" << std::endl;
+ indent.erase( indent.size() - 1 );
+ SubDocumentHandler::headersEnd();
+}
+
+void SubDocumentTest::headerStart( HeaderData::Type type )
+{
+ std::cout << indent << "SUBDOCUMENT: header start " << static_cast<int>( type ) << std::endl;
+ indent.push_back( ' ' );
+ SubDocumentHandler::headerStart( type );
+}
+
+void SubDocumentTest::headerEnd()
+{
+ std::cout << indent << "SUBDOCUMENT: header end" << std::endl;
+ indent.erase( indent.size() - 1 );
+ SubDocumentHandler::headerEnd();
+}
+
+
+void TableTest::tableRowStart( SharedPtr<const Word97::TAP> tap )
+{
+ std::cout << indent << "TABLE: table row start" << std::endl;
+ indent.push_back( ' ' );
+ tap->dump();
+ TableHandler::tableRowStart( tap );
+}
+
+void TableTest::tableRowEnd()
+{
+ std::cout << indent << "TABLE: table row end" << std::endl;
+ indent.erase( indent.size() - 1 );
+ TableHandler::tableRowEnd();
+}
+
+void TableTest::tableCellStart()
+{
+ std::cout << indent << "TABLE: table cell start" << std::endl;
+ indent.push_back( ' ' );
+ TableHandler::tableCellStart();
+}
+
+void TableTest::tableCellEnd()
+{
+ std::cout << indent << "TABLE: table cell end" << std::endl;
+ indent.erase( indent.size() - 1 );
+ TableHandler::tableCellEnd();
+}
+
+
+void PictureTest::bitmapData( wvWare::OLEImageReader& /*reader*/, wvWare::SharedPtr<const wvWare::Word97::PICF> /*picf*/ )
+{
+ // ###### TODO
+ std::cout << indent << "PICTURE: bitmapData" << std::endl;
+}
+
+void PictureTest::wmfData( wvWare::OLEImageReader& /*reader*/, wvWare::SharedPtr<const wvWare::Word97::PICF> /*picf*/ )
+{
+ // ###### TODO
+ std::cout << indent << "PICTURE: wmfData" << std::endl;
+}
+
+void PictureTest::externalImage( const wvWare::UString& name, wvWare::SharedPtr<const wvWare::Word97::PICF> /*picf*/ )
+{
+ // ###### TODO
+ std::cout << indent << "PICTURE: externalImage: " << name.ascii() << std::endl;
+}
+
+
+void TextTest::sectionStart( SharedPtr<const Word97::SEP> sep )
+{
+ std::cout << indent << "TEXT: section start" << std::endl;
+ indent.push_back( ' ' );
+ sep->dump();
+ TextHandler::sectionStart( sep );
+}
+
+void TextTest::sectionEnd()
+{
+ std::cout << indent << "TEXT: section end" << std::endl;
+ indent.erase( indent.size() - 1 );
+ TextHandler::sectionEnd();
+}
+
+void TextTest::pageBreak()
+{
+ std::cout << indent << "TEXT: page break" << std::endl;
+ TextHandler::pageBreak();
+}
+
+void TextTest::headersFound( const HeaderFunctor& parseHeaders )
+{
+ std::cout << indent << "TEXT: headers found" << std::endl;
+ TextHandler::headersFound( parseHeaders );
+}
+
+void TextTest::paragraphStart( SharedPtr<const ParagraphProperties> paragraphProperties )
+{
+ std::cout << indent << "TEXT: paragraph start" << std::endl;
+ indent.push_back( ' ' );
+ paragraphProperties->pap().dump();
+ if ( paragraphProperties->listInfo() )
+ paragraphProperties->listInfo()->dump();
+ TextHandler::paragraphStart( paragraphProperties );
+}
+
+void TextTest::paragraphEnd()
+{
+ std::cout << indent << "TEXT: paragraph end" << std::endl;
+ indent.erase( indent.size() - 1 );
+ TextHandler::paragraphEnd();
+}
+
+void TextTest::runOfText( const UString& text, SharedPtr<const Word97::CHP> chp )
+{
+ std::cout << indent << "TEXT: run of text" << std::endl;
+ chp->dump();
+ std::cout << "TEXT: [";
+ for ( int i = 0; i < text.length(); ++i )
+ std::cout << "<" << text[ i ].unicode() << "|" << text[ i ].low() << ">";
+ std::cout << "]" << std::endl;
+ TextHandler::runOfText( text, chp );
+}
+
+void TextTest::specialCharacter( SpecialCharacter character, SharedPtr<const Word97::CHP> chp )
+{
+ std::cout << indent << "TEXT: special character " << static_cast<int>( character ) << std::endl;
+ chp->dump();
+ TextHandler::specialCharacter( character, chp );
+}
+
+void TextTest::footnoteFound( FootnoteData::Type type, UChar character,
+ SharedPtr<const Word97::CHP> chp, const FootnoteFunctor& parseFootnote )
+{
+ std::cout << indent << "TEXT: footnote found " << static_cast<int>( type )
+ << " character " << character.unicode() << std::endl;
+ chp->dump();
+ TextHandler::footnoteFound( type, character, chp, parseFootnote );
+}
+
+void TextTest::footnoteAutoNumber( SharedPtr<const Word97::CHP> chp )
+{
+ std::cout << indent << "TEXT: footnote auto-number" << std::endl;
+ chp->dump();
+ TextHandler::footnoteAutoNumber( chp );
+}
+
+void TextTest::fieldStart( const FLD* fld, SharedPtr<const Word97::CHP> chp )
+{
+ std::cout << indent << "TEXT: field start " << static_cast<int>( fld->ch ) << std::endl;
+ indent.push_back( ' ' );
+ chp->dump();
+ TextHandler::fieldStart( fld, chp );
+}
+
+void TextTest::fieldSeparator( const FLD* fld, SharedPtr<const Word97::CHP> chp )
+{
+ std::cout << indent << "TEXT: field separator " << static_cast<int>( fld->ch ) << std::endl;
+ chp->dump();
+ TextHandler::fieldSeparator( fld, chp );
+}
+
+void TextTest::fieldEnd( const FLD* fld, SharedPtr<const Word97::CHP> chp )
+{
+ std::cout << indent << "TEXT: field end " << static_cast<int>( fld->ch ) << std::endl;
+ chp->dump();
+ indent.erase( indent.size() - 1 );
+ TextHandler::fieldEnd( fld, chp );
+}
+
+void TextTest::tableRowFound( const wvWare::TableRowFunctor& tableRow, wvWare::SharedPtr<const wvWare::Word97::TAP> tap )
+{
+ std::cout << indent << "TEXT: table row found" << std::endl;
+ tap->dump();
+ TextHandler::tableRowFound( tableRow, tap );
+}
+
+void TextTest::pictureFound( const wvWare::PictureFunctor& picture, wvWare::SharedPtr<const wvWare::Word97::PICF> picf,
+ wvWare::SharedPtr<const wvWare::Word97::CHP> chp )
+{
+ std::cout << indent << "TEXT: picture found" << std::endl;
+ picf->dump();
+ chp->dump();
+ TextHandler::pictureFound( picture, picf, chp );
+}
+
+
+int main( int argc, char** argv )
+{
+ if ( argc != 2 ) {
+ std::cerr << "Usage: handlertest foo.doc" << std::endl;
+ ::exit( 1 );
+ }
+
+ std::string document( argv[ 1 ] );
+ SharedPtr<Parser> parser( ParserFactory::createParser( document ) );
+ if ( !parser || !parser->isOk() ) {
+ std::cerr << "Error: Couldn't create a parser for this document" << std::endl;
+ ::exit( 2 );
+ }
+
+ TextTest* textTest( new TextTest );
+ parser->setTextHandler( textTest );
+ InlineReplacementTest* replacementTest( new InlineReplacementTest );
+ parser->setInlineReplacementHandler( replacementTest );
+
+ if ( !parser->parse() ) {
+ std::cerr << "Error: The parser failed" << std::endl;
+ delete replacementTest;
+ delete textTest;
+ ::exit( 3 );
+ }
+ std::cout << "Done." << std::endl;
+
+ delete replacementTest;
+ delete textTest;
+ return 0;
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/tests/helpertest.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/tests/helpertest.cpp
new file mode 100644
index 00000000..11e2c212
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/tests/helpertest.cpp
@@ -0,0 +1,151 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <test.h>
+#include <olestream.h>
+#include <word_helper.h>
+#include <word97_helper.h>
+#include <word97_generated.h>
+
+using namespace wvWare;
+
+// A small testcase for the word97_helper stuff
+int main( int, char** )
+{
+ std::cerr << "Testing some auxilliary classes..." << std::endl;
+
+ OLEStorage storage( std::string( "testole.doc" ) );
+ test( storage.open( OLEStorage::ReadOnly ) );
+
+ OLEStreamReader* document = storage.createStreamReader( "WordDocument" );
+ test( document && document->isValid(), "Error: Couldn't open the WordDocument stream" );
+ //document->dumpStream( "document.stream" );
+
+ Word97::FIB fib( document, true );
+
+ OLEStreamReader* table = storage.createStreamReader( fib.fWhichTblStm ? "1Table" : "0Table" );
+ test( table && table->isValid(), "Error: Couldn't open the Table stream" );
+
+ // Test STTBFASSOC reading from memory
+ std::cerr << "Test 1: Read the STTBFASSOC from memory: ";
+ table->seek( fib.fcSttbfAssoc );
+ //table->dumpStream( "table.stream" );
+ U8* data = new U8[ fib.lcbSttbfAssoc ];
+ table->read( data, fib.lcbSttbfAssoc );
+ STTBF sttbf( 0x0400, data );
+ delete [] data;
+ test( sttbf.count() == 18 );
+
+ for ( UString s = sttbf.firstString(); !s.isNull(); s = sttbf.nextString() )
+ std::cerr << "String: '" << s.ascii() << "'" << std::endl;
+
+ // Test STTBFASSOC reading from a stream
+ std::cerr << "Test 2: Read the STTBFASSOC from a stream: ";
+ table->seek( fib.fcSttbfAssoc );
+ STTBF sttbf2( 0x0400, table );
+
+ UString s1 = sttbf.firstString(), s2 = sttbf2.firstString();
+ bool failed = false;
+ for ( ; !s1.isNull() && !s2.isNull(); s1 = sttbf.nextString(), s2 = sttbf2.nextString() ) {
+ if ( s1 != s2 ) {
+ failed = true;
+ break;
+ }
+ }
+ test( !failed );
+
+ // Testing PLF reading/iterating
+ std::cerr << "Test 3a: Reading a PLF (LFO): ";
+ table->seek( fib.fcPlfLfo );
+ PLF<Word97::LFO> plf( table );
+ test( plf.count() == 10 ); // we have some padding data at the end, so the size is screwed
+
+ std::cerr << "Test 3b: Reading a PLF (LSTF, \"short count\" PLF): ";
+ table->seek( fib.fcPlcfLst );
+ PLF<Word97::LSTF, true> plf1( table );
+ test( plf1.count() * Word97::LSTF::sizeOf + 2 == fib.lcbPlcfLst );
+
+ std::cerr << "Test 3c: Trying to match the list IDs: ";
+ // Check whether all list ids match, then the file is okay (and we read it correctly)
+ // Yes, I know that this is O(n^2), but hey, this is a test case for 10 elements ;)
+ bool success = true;
+ bool found = false;
+ for ( const Word97::LSTF* lstf = plf1.first(); lstf != 0; lstf = plf1.next() ) {
+ found = false;
+ for ( const Word97::LFO* lfo = plf.first(); lfo != 0; lfo = plf.next() )
+ if ( lstf->lsid == lfo->lsid ) {
+ found = true;
+ break;
+ }
+ if ( !found ) {
+ success = false;
+ break;
+ }
+ }
+ test( success );
+
+ table->seek( fib.fcPlcfbtePapx );
+ std::cerr << "Test 4: Reading a PLCF: " << std::endl;
+ //std::cerr << "Size: " << fib.lcbPlcfbtePapx << std::endl;
+ PLCF<Word97::BTE> plcf( fib.lcbPlcfbtePapx, table );
+
+ std::cerr << "Test 4a: Checking the size of the PLCF: ";
+ test( plcf.count() == 6 );
+
+ PLCFIterator<Word97::BTE> it( plcf );
+ for ( ; it.current(); ++it ) {
+ std::cerr << "Item: " << std::endl;
+ std::cerr << " start: " << it.currentStart() << std::endl;
+ std::cerr << " lim: " << it.currentLim() << std::endl;
+ std::cerr << " value: " << it.current()->pn << std::endl;
+ }
+
+ // Test the FKP template
+ it.toFirst(); // rewind the iterator ;)
+ std::cerr << "Test 5: Reading a FKP: " << std::endl;
+ document->seek( it.current()->pn << 9, G_SEEK_SET );
+ FKP< BX<Word97::PHE> > fkp( document, false );
+ std::cerr << "crun: " << fkp.crun() << std::endl;
+ FKPIterator< BX<Word97::PHE> > it2( fkp );
+ for ( int i = 0; !it2.atEnd(); ++it2, ++i ) {
+ std::cerr << "Item(" << i << "): " << std::endl;
+ std::cerr << " start: " << it2.currentStart() << std::endl;
+ std::cerr << " lim: " << it2.currentLim() << std::endl;
+ if ( it2.current() )
+ std::cerr << " plain entry" << std::endl;
+ else
+ std::cerr << " null entry" << std::endl;
+ }
+
+ std::cerr << "sizeof(PRM): " << sizeof(Word97::PRM) << std::endl;
+ std::cerr << "sizeof(PRM2): " << sizeof(Word97::PRM2) << std::endl;
+ std::cerr << "sizeof(PCD): " << sizeof(Word97::PCD) << std::endl;
+ std::cerr << "sizeof(DTTM): " << sizeof(Word97::DTTM) << std::endl;
+ std::cerr << "sizeof(BTE): " << sizeof(Word97::BTE) << std::endl;
+ std::cerr << "sizeof(PHE): " << sizeof(Word97::PHE) << std::endl;
+ std::cerr << "sizeof(BX): " << sizeof(BX<Word97::PHE>) << std::endl;
+
+ delete document;
+ delete table;
+ std::cerr << "Done." << std::endl;
+ return 0;
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/tests/iconvtest.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/tests/iconvtest.cpp
new file mode 100644
index 00000000..619536fe
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/tests/iconvtest.cpp
@@ -0,0 +1,111 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include <test.h>
+
+#include "textconverter.h"
+#include "ustring.h"
+
+using namespace wvWare;
+
+int cp_test( const std::string& codepage );
+
+// A small testcase for the text converter (iconv interface)
+int main( int, char** )
+{
+ int status = 0;
+
+ std::cout << "===================================" << std::endl;
+ std::cout << "textconverter: (1) codepage support" << std::endl;
+ std::cout << "===================================" << std::endl;
+
+ status += cp_test( "CP874" );
+ status += cp_test( "CP936" );
+ status += cp_test( "CP932" );
+ status += cp_test( "CP949" );
+ status += cp_test( "CP950" );
+ status += cp_test( "CP1250" );
+ status += cp_test( "CP1251" );
+ status += cp_test( "CP1252" );
+ status += cp_test( "CP1253" );
+ status += cp_test( "CP1254" );
+ status += cp_test( "CP1255" );
+ status += cp_test( "CP1256" );
+ status += cp_test( "CP1257" );
+ status += cp_test( "UCS-2" );
+ status += cp_test( "UCS-2-INTERNAL" );
+ status += cp_test( "UNICODEBIG" );
+ status += cp_test( "UNICODELITTLE" );
+ status += cp_test( "UTF-8" );
+ status += cp_test( "koi8-r" );
+ status += cp_test( "tis-620" );
+ status += cp_test( "iso-8859-15" );
+
+ std::cout << "==========================================" << std::endl;
+ std::cout << "textconverter: (2) conversion completeness" << std::endl;
+ std::cout << "==========================================" << std::endl;
+
+ TextConverter converter(0x0407);
+
+ std::string t( "The quick brown fox jumped over the lazy dog." );
+
+ UString result = converter.convert( t );
+
+ std::cout << "String: " << t << std::endl;
+ std::cout << "Result: " << result.ascii() << std::endl;
+
+ test( strcmp( t.c_str(), result.ascii() ) == 0, "The strings aren't matching!" );
+
+ /*
+ converter.setFromCode( "CP1255" ); // Hebrew
+ t = "������, ����� ���������: Unicode ���� ���� ������ ������ ��� ���� Unicode ��������� ������, ������ ��� �������� 12�10 ���� 1997, ������ ��������. ���� ������ ������ ��� ���� ������� ����� �������� ������ ���Unicode, ������ ���� ��������� �������, ������ Unicode ������� ����� ���������, �������, ������ ���� ������� ��������. some english inbetween ���� ����� ���� ����, ��� ���� ��Unicode";
+
+ result = converter.convert( t );
+ std::cout << "String: " << t << std::endl;
+ std::cout << "Result: " << result.ascii() << std::endl;
+ */
+ std::cout << "===================" << std::endl;
+ std::cout << "textconverter: done" << std::endl;
+ std::cout << "failures=" << status << std::endl;
+ std::cout << "===================" << std::endl;
+
+ return status;
+}
+
+int cp_test( const std::string& codepage )
+{
+ int status = 0;
+
+ TextConverter tc( codepage );
+ if ( !tc.isOk() )
+ status=1;
+ std::cout << codepage << ": " << ( status==0 ? "yes" : "no" ) << std::endl;
+
+ return status;
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/tests/oletest.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/tests/oletest.cpp
new file mode 100644
index 00000000..baa19518
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/tests/oletest.cpp
@@ -0,0 +1,290 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <olestorage.h>
+#include <olestream.h>
+#include <utilities.h>
+#ifdef HAVE_UNISTD
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <time.h>
+
+#include <test.h>
+
+using namespace wvWare;
+
+// Uncomment that line to check whether libole2 correctly handles
+// files containing only so called small blocks
+//#define SMALL_BLOCKS_ONLY 1
+
+// Some basic test for the storage system. Please don't change the oletest.doc
+// file as some tests depend on exacly that file (e.g. directory names)
+int main( int, char** )
+{
+ std::cerr << "Testing the OLE storage and the streams..." << std::endl;
+ std::cerr << "###############################################################################" << std::endl;
+ std::cerr << "Test 1: Open the sample file: ";
+ OLEStorage storage( "testole.doc" );
+ test( storage.open( OLEStorage::ReadOnly ) );
+ std::cerr << "###############################################################################" << std::endl;
+
+ std::cerr << "Test2: List the contents of the root directory:" << std::endl;
+ std::list<std::string> dir = storage.listDirectory();
+ test( storage.isValid() );
+
+ std::list<std::string>::const_iterator it = dir.begin();
+ std::list<std::string>::const_iterator end = dir.end();
+ for ( ; it != end; ++it )
+ std::cerr << " - " << *it << std::endl;
+ std::cerr << "###############################################################################" << std::endl;
+
+ std::cerr << "Test3: Stat a stream: skipped" << std::endl;
+ /*
+ MsOleStat s = storage.stat( "WordDocument" );
+ test( storage.lastError() == MS_OLE_ERR_OK && s.type == MsOleStreamT &&
+ s.size != static_cast<unsigned int>( -1 ), "### Error in Test 3: " + int2string( storage.lastError() ), "Passed." );
+ */
+
+ std::cerr << "Test4: Stat a storage (directory): skipped" << std::endl;
+ /*
+ s = storage.stat( "ObjectPool" );
+ test( storage.lastError() == MS_OLE_ERR_OK && s.type == MsOleStorageT &&
+ s.size != static_cast<unsigned int>( -1 ) , "### Error in Test 4: " + int2string( storage.lastError() ), "Passed." );
+ */
+
+ std::cerr << "Test5: Enter a directory: ";
+ test( storage.enterDirectory( "ObjectPool" ) );
+ std::cerr << "###############################################################################" << std::endl;
+
+ std::cerr << "Test6: List the contents of the current directory:" << std::endl;
+ dir = storage.listDirectory();
+ test( storage.isValid() );
+ it = dir.begin();
+ end = dir.end();
+ for ( ; it != end; ++it )
+ std::cerr << " - " << *it << std::endl;
+ std::cerr << "###############################################################################" << std::endl;
+
+ std::cerr << "Test7: Leave a directory." << std::endl;
+ storage.leaveDirectory();
+ storage.leaveDirectory(); // we can do that as often as we want to
+ storage.leaveDirectory(); // as we will never leave '/'
+ std::cerr << "###############################################################################" << std::endl;
+
+ std::cerr << "Test8: List the contents of the current directory (should be the root dir):" << std::endl;
+ dir = storage.listDirectory();
+ test( storage.isValid() );
+ it = dir.begin();
+ end = dir.end();
+ for ( ; it != end; ++it )
+ std::cerr << " - " << *it << std::endl;
+ std::cerr << "###############################################################################" << std::endl;
+
+ // go somewhere (for testing purpose)
+ storage.enterDirectory( "ObjectPool" );
+ std::cerr << "Test9: Set a few custom paths:" << std::endl;
+ std::cerr << " Trying '/ObjectPool/_1020966487': ";
+ test( storage.setPath("/ObjectPool/_1020966487") );
+ std::cerr << " Trying '/ObjectPool/_1020966487': ";
+ test( storage.setPath("/ObjectPool/_1020966487") );
+ std::cerr << " Trying 'ObjectPool/_1020966487': ";
+ test( storage.setPath("ObjectPool/_1020966487") );
+ std::cerr << " Trying 'ObjectPool/_1020966487/': ";
+ test( storage.setPath("ObjectPool/_1020966487/") );
+ std::cerr << " Trying '/ObjectPool/_1020966487/': ";
+ test( storage.setPath("/ObjectPool/_1020966487/") );
+ std::cerr << " Trying '/ObjectPool_1020966487': ";
+ test( !storage.setPath("/ObjectPool_1020966487") );
+ std::cerr << " Trying '/': ";
+ test( storage.setPath("/") && storage.path()=="/" );
+ std::cerr << "###############################################################################" << std::endl;
+
+ std::cerr << "Test10: Open a stream for reading: ";
+ OLEStreamReader* reader = storage.createStreamReader( "1Table" );
+ test( reader && reader->isValid() );
+
+ std::cerr << "Test11: Check whether we are at 0 right after opening: ";
+ test( reader->tell() == 0 );
+
+ std::cerr << "Test12: Check the size of the stream: ";
+ test( reader->size() == 0x20a6 );
+
+ std::cerr << "Test13: Seek in the stream: ";
+ reader->seek( 0x100 );
+ test( reader->seek( 1, G_SEEK_CUR ) && reader->tell() == 0x101 );
+ reader->push(); // save the current pos (0x101)
+
+ std::cerr << "Test14: More seeking: ";
+ test( reader->seek( -2, G_SEEK_CUR ) && reader->tell() == 0xff );
+ reader->push(); // save the current pos (0xff)
+
+ std::cerr << "Test15: Even more seeking: ";
+ test( reader->seek( -2, G_SEEK_END ) && reader->tell() == 0x20a4 );
+
+ std::cerr << "Test16: Checking the stack: ";
+ test( reader->pop() && reader->tell() == 0xff );
+
+ std::cerr << "Test17: Checking the stack again: ";
+ test( reader->pop() && reader->tell() == 0x101 );
+
+ // clean up the current stream
+ delete reader;
+ reader = 0;
+
+ std::cerr << "Test18: Open another stream for reading: ";
+ reader = storage.createStreamReader( "WordDocument" );
+ test( reader && reader->isValid() );
+
+ std::cerr << "Test19: Read the magic 16 Bit value: ";
+ test( reader->readU16() == 0xa5ec );
+
+ std::cerr << "Test20: Check the nFib: ";
+ test( reader->readU16() == 193 );
+
+ std::cerr << "Test21: Check the byte reading: ";
+ reader->seek( 2 );
+ test( reader->readU8() == 0xc1 );
+
+ std::cerr << "Test22: Check the word reading: ";
+ reader->seek( 0 );
+ test( reader->readU32() == 0x00c1a5ec );
+
+ // Get rid of our test document
+ // The warning we get is the intended behavior :)
+ storage.close();
+
+ // Open a new document for write tests (make sure
+ // it doesn't exist)
+ system( "rm test123456.doc &> /dev/null" );
+ storage.setName( "test123456.doc" );
+ test( storage.open( OLEStorage::WriteOnly ) );
+
+ std::cerr << "Test23: Open a stream for writing (I): ";
+ OLEStreamWriter* writer = storage.createStreamWriter( "Check1" );
+ test( writer && writer->isValid() );
+
+ writer->write( static_cast<U32>( 0x11111111 ) );
+ writer->write( static_cast<U32>( 0x11111111 ) );
+ writer->write( static_cast<U32>( 0x11111111 ) );
+ writer->write( static_cast<U32>( 0x11111111 ) );
+ writer->write( static_cast<U32>( 0x11111111 ) );
+ writer->write( static_cast<U32>( 0x11111111 ) );
+ writer->write( static_cast<U32>( 0x11111111 ) );
+ writer->write( static_cast<U32>( 0x11111111 ) );
+ writer->write( static_cast<U32>( 0x11111111 ) );
+
+ // write it to disk...
+ delete writer;
+ writer = 0;
+
+ std::cerr << "Test24: Open a stream for writing (II): ";
+ writer = storage.createStreamWriter( "Check2" );
+ test( writer && writer->isValid() );
+
+ writer->write( static_cast<U8>( 200 ) );
+ writer->write( static_cast<S8>( 123 ) );
+ writer->write( static_cast<U16>( 42420 ) );
+ writer->write( static_cast<S16>( -21420 ) );
+ writer->write( static_cast<U32>( 0xdeadbeef ) );
+ writer->write( static_cast<S32>( 0x7fffffff ) );
+
+ // write it to disk...
+ delete writer;
+ writer = 0;
+
+#ifndef SMALL_BLOCKS_ONLY
+ std::cerr << "Test25: Open a stream for writing (III): ";
+ writer = storage.createStreamWriter( "Check3" );
+ test( writer && writer->isValid() );
+
+ for ( int i = 0; i < 10000; ++i ) {
+ writer->write( static_cast<S32>( 0x22222222 ) );
+ writer->write( static_cast<S32>( 0x22222222 ) );
+ writer->write( static_cast<S32>( 0x22222222 ) );
+ writer->write( static_cast<S32>( 0x22222222 ) );
+ writer->write( static_cast<S32>( 0x22222222 ) );
+ }
+
+ delete writer;
+ writer = 0;
+#endif
+
+ std::cerr << "Test26: Open a stream for writing (IV): ";
+ writer = storage.createStreamWriter( "Check4" );
+ test( writer && writer->isValid() );
+
+ srand( time( 0 ) );
+ U8 buffer1[ 256 ];
+ for ( int i = 0; i< 256; ++i )
+ buffer1[ i ] = rand() % 256;
+
+ writer->write( buffer1, 256 );
+
+ delete writer;
+ writer = 0;
+
+ storage.close();
+
+ std::cerr << "Test27: Read back the created file: ";
+ test( storage.open( OLEStorage::ReadOnly ) && storage.isValid() );
+
+ std::cerr << "Test28: Open the stream I for reading: ";
+ reader = storage.createStreamReader( "Check1" );
+ test( reader && reader->isValid() );
+
+ std::cerr << "Test29: Check the size of the stream I: ";
+ test( reader->size() == 36 );
+
+ delete reader;
+ reader = 0;
+
+ std::cerr << "Test30: Open the stream II for reading: ";
+ reader = storage.createStreamReader( "Check2" );
+ test( reader && reader->isValid() );
+
+ std::cerr << "Test31: Check the size of the stream II: ";
+ test( reader->size() == 14 );
+
+ std::cerr << "Test32: Check the contents of the stream II: ";
+ test( reader->readU8() == 200 && reader->readS8() == 123 && reader->readU16() == 42420 &&
+ reader->readS16() == -21420 && reader->readU32() == 0xdeadbeef && reader->readS32() == 0x7fffffff );
+
+ delete reader;
+ reader = 0;
+
+ std::cerr << "Test33: Open the stream IV for reading: ";
+ reader = storage.createStreamReader( "Check4" );
+ test( reader && reader->isValid() );
+
+ std::cerr << "Test34: Read back and compare the content with the expected values: ";
+ U8 buffer2[ 256 ];
+ reader->read( buffer2, 256 );
+ bool success = true;
+ for ( int i = 0; i < 256; ++i )
+ if ( buffer1[ i ] != buffer2[ i ] ) {
+ success = false;
+ break;
+ }
+ test( success );
+
+ storage.close(); // missing delete reader; intendet, doesn't result in memleaks
+
+ std::cerr << "Done." << std::endl;
+ return 0;
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/tests/parsertest.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/tests/parsertest.cpp
new file mode 100644
index 00000000..84c0e152
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/tests/parsertest.cpp
@@ -0,0 +1,49 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <test.h>
+#include <parser.h>
+#include <parserfactory.h>
+#include <global.h>
+
+using namespace wvWare;
+
+// A small testcase for the parser (Word97)
+int main( int argc, char** argv )
+{
+ if ( argc > 2 ) {
+ std::cerr << "Usage: parsertest [foo.doc]" << std::endl;
+ ::exit( 1 );
+ }
+
+ std::string file;
+ if ( argc == 1 )
+ file = "testole.doc";
+ else
+ file = argv[ 1 ];
+
+ std::cerr << "Testing the parser with " << file << "..." << std::endl;
+
+ SharedPtr<Parser> parser( ParserFactory::createParser( file ) );
+ std::cerr << "Trying... " << std::endl;
+ if ( parser )
+ test ( parser->parse() );
+ std::cerr << "Done." << std::endl;
+
+ return 0;
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/tests/parsertest_mem.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/tests/parsertest_mem.cpp
new file mode 100644
index 00000000..d5e0df74
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/tests/parsertest_mem.cpp
@@ -0,0 +1,66 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <test.h>
+#include <parser.h>
+#include <parserfactory.h>
+#include <global.h>
+
+using namespace wvWare;
+
+// A small testcase for the parser (Word97)
+int main( int argc, char** argv )
+{
+ if ( argc > 2 ) {
+ std::cerr << "Usage: parsertest_mem [foo.doc]" << std::endl;
+ ::exit( 1 );
+ }
+
+ std::string file;
+ if ( argc == 1 )
+ file = "testole.doc";
+ else
+ file = argv[ 1 ];
+
+ std::cerr << "Testing the parser with " << file << "..." << std::endl;
+
+ FILE *fp;
+ if( ( fp = fopen( file.c_str(), "rb" ) ) != 0 )
+ {
+ fseek( fp, 0, SEEK_END );
+ size_t size = ftell( fp );
+ fseek( fp, 0, SEEK_SET );
+ unsigned char *mem = new unsigned char[ size ];
+ if ( fread( mem, 1, size, fp ) == size )
+ {
+ SharedPtr<Parser> parser( ParserFactory::createParser( mem, size ) );
+ std::cerr << "Trying... " << std::endl;
+ if ( parser )
+ test ( parser->parse() );
+ std::cerr << "Done." << std::endl;
+ }
+ else
+ std::cerr << "couldn't read file" << std::endl;
+ fclose( fp );
+ delete [] mem;
+ }
+ else
+ std::cerr << "couldn't open file" << std::endl;
+
+ return 0;
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/tests/regression b/debian/wv2/wv2-0.4.2.dfsg.2/tests/regression
new file mode 100644
index 00000000..b268c281
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/tests/regression
@@ -0,0 +1,171 @@
+#! /usr/bin/env python
+##############################################################################
+# This file is part of the wvWare 2 project
+# Copyright (C) 2003 Werner Trobin <[email protected]>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License version 2 as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+##############################################################################
+
+# An automatic regression test script, based on a record/replay approach.
+# It runs .doc files through wv2, using a verbose "consumer", printing tons
+# of information about the .doc file. This information is compared to a
+# previously recorded and verified template.
+
+import getopt, sys, os, filecmp
+from stat import *
+
+
+# Prints usage information to stdout
+def usage():
+ print "Regression test for the wv2 library..."
+ print "Usage: regression [OPTION]... [FILE]...\n"
+ print "Examples:"
+ print " regression --record <document.doc> # Record a template of the given .doc"
+ print " regression <file/directory> # Verify the given file/directory\n"
+ print "Options:"
+ print " -d, --diff In case the regression test fails, output the diff"
+ print " -h, --help Output this information"
+ print " -l, --local Don't recurse to subdirectories"
+ print " -m, --missing-only Record only missing template files (implies -r)"
+ print " -p, --pedantic Abort on any .doc error"
+ print " -r, --record Record a template file"
+ print " -x, --extension=EXT Use EXT as extension for the template files (default=reg)"
+
+
+# Processes all remaining command line arguments after getopt removed
+# all the options.
+def process(args):
+ for a in args:
+ try:
+ mode = os.stat(a)[ST_MODE]
+ if S_ISDIR(mode):
+ processDirectory(a)
+ elif S_ISREG(mode):
+ processDocument(a)
+ else:
+ print "Skipping %s: This isn't a file or directory" % (a)
+ except OSError, e:
+ print "Skipping %s: %s (%d)" % (a, e.strerror, e.errno)
+
+
+# Recursively processes all (.doc) files of a directory
+def processDirectory(directory):
+ for f in os.listdir(directory):
+ pathname = '%s/%s' % (directory, f)
+ mode = os.stat(pathname)[ST_MODE]
+ if S_ISDIR(mode) and local == 0:
+ processDirectory(pathname)
+ elif S_ISREG(mode):
+ processDocument(pathname)
+ else:
+ # Unknown file type, print a message
+ print "Skipping", pathname
+
+
+# Process a single (.doc) file. Starts wv2 on it and compares (or generates)
+# the template file
+def processDocument(document):
+ root, ext = os.path.splitext(document)
+ if ext != ".doc" and ext != ".DOC":
+ return
+
+ print "Processing:", document
+ status = 0
+ result = 0
+ templateFile = root + '.' + extension
+
+ if record == 1:
+ if missing == 0 or not os.path.exists(templateFile):
+ status = os.system("./handlertest \"%s\" &> \"%s\"" % (document, templateFile))
+ if status != 0:
+ os.unlink(templateFile)
+ else:
+ # Does the template file exist at all?
+ try:
+ mode = os.stat(templateFile)[ST_MODE]
+ if not S_ISREG(mode):
+ status = -42
+ except OSError:
+ status = -42
+
+ if status == -42:
+ print "Error: There's no template file for '%s'" % (document)
+ result = 1 # We don't want to exit even with --pedantic
+ else: # Okay, it makes sense to start the comparison
+ tmpFile = os.tempnam()
+ status = os.system("./handlertest \"%s\" &> \"%s\"" % (document, tmpFile))
+ # If the status is okay we compare the files
+ if status == 0:
+ result = filecmp.cmp(tmpFile, templateFile)
+ if result == 0 and diff == 1:
+ os.system("diff -ua \"%s\" \"%s\"" % (templateFile, tmpFile))
+ print "%s: %d (status = %d)" % (document, result, status)
+ os.unlink(tmpFile)
+
+ if result != 1 and pedantic == 1:
+ print "Error: Aborting the test run (--pedantic), status", status, "result", result
+ sys.exit(status)
+
+
+# Interpret the options and kick off the testing process.
+# Sets the global variables "record", "extension", and "pedantic"
+def main():
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], "dhrx:plm", ["diff", "help", "record", "extension=", "pedantic", "local", "missing-only"])
+ except getopt.GetoptError:
+ # print help information and exit:
+ usage()
+ sys.exit(2)
+
+ global diff, record, extension, pedantic, local, missing
+ # Does the user want to see the diff on failure?
+ diff = 0
+ # Are we in record or in verify mode?
+ record = 0
+ # What extension do we use?
+ extension = "reg"
+ # Pedantic mode?
+ pedantic = 0
+ # Recurse?
+ local = 0
+ # Missing only?
+ missing = 0
+
+ for o, a in opts:
+ if o in ("-d", "--diff"):
+ diff = 1
+ if o in ("-h", "--help"):
+ usage()
+ sys.exit()
+ if o in ("-r", "--record"):
+ record = 1
+ if o in ("-x", "--extension"):
+ extension = a
+ if o in ("-p", "--pedantic"):
+ pedantic = 1
+ if o in ("-l", "--local"):
+ local = 1
+ if o in ("-m", "--missing-only"):
+ missing = 1
+ record = 1
+
+ if len(args) == 0:
+ usage()
+ sys.exit(2)
+
+ process(args)
+
+if __name__ == "__main__":
+ main()
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/tests/sharedptrtest.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/tests/sharedptrtest.cpp
new file mode 100644
index 00000000..2fe8ee7f
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/tests/sharedptrtest.cpp
@@ -0,0 +1,58 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <test.h>
+#include <sharedptr.h>
+
+using namespace wvWare;
+
+struct Foo : public Shared
+{
+ Foo() : bar( 42 ), baz( 42.42 ) { std::cerr << "Creating Foo" << std::endl; }
+ ~Foo() { std::cerr << "Destroying Foo" << std::endl; }
+
+ int bar;
+ double baz;
+};
+
+SharedPtr<const Foo> createFoo()
+{
+ return SharedPtr<const Foo>( new Foo() );
+}
+
+void testMe()
+{
+ SharedPtr<const Foo> foo = createFoo();
+ std::cerr << "Test 1: Passing around the object: ";
+ test( foo->bar == 42 && foo.count() == 1 );
+
+ std::cerr << "Test 2: Copying the \"pointer\": ";
+ SharedPtr<const Foo> foo2( foo );
+ test( foo2->bar == 42 && foo2.count() == 2 && foo->bar == 42 && foo.count() == 2 );
+
+ std::cerr << "Going out of scope..." << std::endl;
+}
+
+// A small testcase for the SharedPtr template
+int main( int, char** )
+{
+ std::cerr << "Testing the SharedPtr template..." << std::endl;
+ testMe();
+ std::cerr << "Done." << std::endl;
+ return 0;
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/tests/test.h b/debian/wv2/wv2-0.4.2.dfsg.2/tests/test.h
new file mode 100644
index 00000000..23c222f5
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/tests/test.h
@@ -0,0 +1,46 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2002-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <cstdlib>
+#include <iostream>
+#include <string>
+
+#include <stdio.h>
+
+namespace wvWare
+{
+
+ void test( bool result, const std::string& failureMessage, const std::string& successMessage = "" )
+ {
+ if ( result ) {
+ if ( !successMessage.empty() )
+ std::cerr << successMessage << std::endl;
+ }
+ else {
+ std::cerr << failureMessage << std::endl;
+ std::cerr << "Test NOT finished successfully." << std::endl;
+ ::exit( 1 );
+ }
+ }
+
+ void test( bool result )
+ {
+ test( result, "Failed", "Passed" );
+ }
+
+} // namespace wvWare
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/tests/testole.doc b/debian/wv2/wv2-0.4.2.dfsg.2/tests/testole.doc
new file mode 100644
index 00000000..dd94bba7
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/tests/testole.doc
Binary files differ
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/tests/ustringtest.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/tests/ustringtest.cpp
new file mode 100644
index 00000000..5a59c120
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/tests/ustringtest.cpp
@@ -0,0 +1,91 @@
+/* This file is part of the wvWare 2 project
+ Copyright (C) 2001-2003 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <test.h>
+#include <ustring.h>
+#include <string.h>
+
+using namespace wvWare;
+
+// A small testcase for the UString class
+int main( int, char** )
+{
+ std::cerr << "Testing the UString class..." << std::endl;
+
+ std::cerr << "Test 1: isNull/isEmpty: ";
+ UString string1;
+ test( string1.isNull() && string1.isEmpty() );
+
+ std::cerr << "Test 2: isNull vs. isEmpty: ";
+ UString string2("");
+ test( !string2.isNull() && string2.isEmpty() );
+
+ std::cerr << "Test 3: isEmpty: ";
+ UString string3( "test" );
+ test( !string3.isNull() && !string3.isEmpty() );
+
+ std::cerr << "Test 4: Copying a null string: ";
+ UString string4( string1 );
+ test( string4.isNull() && string4.isEmpty() );
+
+ std::cerr << "Test 5: Copying an empty string: ";
+ UString string5( string2 );
+ test( !string5.isNull() && string5.isEmpty() );
+
+ std::cerr << "Test 6: Creating and deleting a UConstString on static data: ";
+ const int length = 12;
+ { // open a new scope level to let the string go out of scope sooner
+ // Not 0 terminated!
+ UChar data[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
+ UConstString string( data, length );
+ test( strcmp( string.string().ascii(), "Hello World!" ) == 0 );
+ }
+
+ std::cerr << "Test 7: Checking whether the data gets copied properly: ";
+ UString testString;
+ UChar *data = new UChar[ length ];
+ data[ 0 ] = 'H'; data[ 1 ] = 'e'; data[ 2 ] = 'l'; data[ 3 ] = 'l';
+ data[ 4 ] = 'o'; data[ 5 ] = ' '; data[ 6 ] = 'W'; data[ 7 ] = 'o';
+ data[ 8 ] = 'r'; data[ 9 ] = 'l'; data[ 10 ] = 'd'; data[ 11 ] = '!';
+
+ { // open a new scope level to let the string go out of scope sooner
+ UConstString str( data, length );
+ testString = str.string();
+ }
+ delete [] data;
+ test( strcmp( testString.ascii(), "Hello World!" ) == 0 );
+
+ std::cerr << "Test 8: Checking whether modifying a shallow copy works as expected I: ";
+ data = new UChar[ length ];
+ data[ 0 ] = 'H'; data[ 1 ] = 'e'; data[ 2 ] = 'l'; data[ 3 ] = 'l';
+ data[ 4 ] = 'o'; data[ 5 ] = ' '; data[ 6 ] = 'W'; data[ 7 ] = 'o';
+ data[ 8 ] = 'r'; data[ 9 ] = 'l'; data[ 10 ] = 'd'; data[ 11 ] = '!';
+
+ { // open a new scope level to let the string go out of scope sooner
+ UConstString str( data, length );
+ testString = str.string();
+ testString[ 0 ] = 'C';
+ test( strcmp( str.string().ascii(), "Hello World!" ) == 0 );
+ }
+ delete [] data;
+ std::cerr << "Test 9: Checking whether modifying a shallow copy works as expected II: ";
+ test( strcmp( testString.ascii(), "Cello World!" ) == 0 );
+
+ std::cerr << "Done." << std::endl;
+ return 0;
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/tests/word95_test.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/tests/word95_test.cpp
new file mode 100644
index 00000000..2351c784
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/tests/word95_test.cpp
@@ -0,0 +1,1167 @@
+// This file contains generated testing code. We do some basic tests
+// like writing and reading from/to streams. Of course these tests are
+// neither complete nor very advanced, so watch out :)
+
+#include <word95_generated.h>
+#include <olestream.h>
+#include <iostream>
+#include <stdlib.h> // rand(), srand()
+
+#include <time.h> // time()
+
+using namespace wvWare;
+using namespace Word95;
+
+int main(int, char**) {
+
+ // First we have to create some infrastructure
+ system("rm word95_test.doc &> /dev/null");
+ OLEStorage storage("word95_test.doc");
+ if(!storage.open(OLEStorage::WriteOnly)) {
+ std::cout << "Error: Couldn't open the storage!" << std::endl;
+ ::exit(1);
+ }
+
+ OLEStreamWriter *writer=storage.createStreamWriter("TestStream");
+ if(!writer || !writer->isValid()) {
+ std::cout << "Error: Couldn't open a stream for writing!" << std::endl;
+ ::exit(1);
+ }
+
+ // Initialize the random number generator
+ srand( time( 0 ) );
+
+ // Some "global" variables...
+ int *ptr=0; // used to "initialize" the structs
+ int tmp;
+ std::cout << "Testing the Word95 structures..." << std::endl;
+ // Begin of writing test for DTTM
+ std::cout << "Testing writing for DTTM: ";
+ DTTM dttm1;
+ // Initilaize the struct with random data
+ tmp=sizeof(DTTM)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &dttm1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DTTM) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(dttm1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ dttm1.dump();
+ // End of writing test for DTTM
+
+ // Begin of writing test for PRM2
+ std::cout << "Testing writing for PRM2: ";
+ PRM2 prm21;
+ // Initilaize the struct with random data
+ tmp=sizeof(PRM2)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &prm21 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PRM2) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(prm21.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for PRM2
+
+ // Begin of writing test for PRM
+ std::cout << "Testing writing for PRM: ";
+ PRM prm1;
+ // Initilaize the struct with random data
+ tmp=sizeof(PRM)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &prm1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PRM) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(prm1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for PRM
+
+ // Begin of writing test for SHD
+ std::cout << "Testing writing for SHD: ";
+ SHD shd1;
+ // Initilaize the struct with random data
+ tmp=sizeof(SHD)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &shd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(SHD) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(shd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ shd1.dump();
+ // End of writing test for SHD
+
+ // Begin of writing test for PHE
+ std::cout << "Testing writing for PHE: ";
+ PHE phe1;
+ // Initilaize the struct with random data
+ tmp=sizeof(PHE)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &phe1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PHE) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(phe1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ phe1.dump();
+ // End of writing test for PHE
+
+ // Begin of writing test for BRC
+ std::cout << "Testing writing for BRC: ";
+ BRC brc1;
+ // Initilaize the struct with random data
+ tmp=sizeof(BRC)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &brc1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BRC) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(brc1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ brc1.dump();
+ // End of writing test for BRC
+
+ // Begin of writing test for TLP
+ std::cout << "Testing writing for TLP: ";
+ TLP tlp1;
+ // Initilaize the struct with random data
+ tmp=sizeof(TLP)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &tlp1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(TLP) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(tlp1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ tlp1.dump();
+ // End of writing test for TLP
+
+ // Begin of writing test for TC
+ std::cout << "Testing writing for TC: ";
+ TC tc1;
+ // Initilaize the struct with random data
+ tmp=sizeof(TC)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &tc1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(TC) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(tc1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ tc1.dump();
+ // End of writing test for TC
+
+ // Begin of writing test for DPHEAD
+ std::cout << "Testing writing for DPHEAD: ";
+ DPHEAD dphead1;
+ // Initilaize the struct with random data
+ tmp=sizeof(DPHEAD)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &dphead1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DPHEAD) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(dphead1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for DPHEAD
+
+ // Begin of writing test for DPTXBX
+ std::cout << "Testing writing for DPTXBX: ";
+ DPTXBX dptxbx1;
+ // Initilaize the struct with random data
+ tmp=sizeof(DPTXBX)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &dptxbx1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DPTXBX) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(dptxbx1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for DPTXBX
+
+ std::cout << "Testing writing for DPPOLYLINE:" << std::endl;
+ std::cout << " Sorry, testing dynamic structures isn't implemented,"
+ << " yet." << std::endl;
+ // Begin of writing test for ANLD
+ std::cout << "Testing writing for ANLD: ";
+ ANLD anld1;
+ // Initilaize the struct with random data
+ tmp=sizeof(ANLD)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &anld1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(ANLD) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(anld1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ anld1.dump();
+ // End of writing test for ANLD
+
+ // Begin of writing test for ANLV
+ std::cout << "Testing writing for ANLV: ";
+ ANLV anlv1;
+ // Initilaize the struct with random data
+ tmp=sizeof(ANLV)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &anlv1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(ANLV) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(anlv1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ anlv1.dump();
+ // End of writing test for ANLV
+
+ // Begin of writing test for BKF
+ std::cout << "Testing writing for BKF: ";
+ BKF bkf1;
+ // Initilaize the struct with random data
+ tmp=sizeof(BKF)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &bkf1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BKF) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(bkf1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for BKF
+
+ // Begin of writing test for BKL
+ std::cout << "Testing writing for BKL: ";
+ BKL bkl1;
+ // Initilaize the struct with random data
+ tmp=sizeof(BKL)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &bkl1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BKL) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(bkl1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for BKL
+
+ // Begin of writing test for BRC10
+ std::cout << "Testing writing for BRC10: ";
+ BRC10 brc101;
+ // Initilaize the struct with random data
+ tmp=sizeof(BRC10)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &brc101 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BRC10) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(brc101.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for BRC10
+
+ // Begin of writing test for BTE
+ std::cout << "Testing writing for BTE: ";
+ BTE bte1;
+ // Initilaize the struct with random data
+ tmp=sizeof(BTE)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &bte1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BTE) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(bte1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for BTE
+
+ // Begin of writing test for CHP
+ std::cout << "Testing writing for CHP: ";
+ CHP chp1;
+ // Initilaize the struct with random data
+ tmp=sizeof(CHP)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &chp1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(CHP) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(chp1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ chp1.dump();
+ // End of writing test for CHP
+
+ // Begin of writing test for DCS
+ std::cout << "Testing writing for DCS: ";
+ DCS dcs1;
+ // Initilaize the struct with random data
+ tmp=sizeof(DCS)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &dcs1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DCS) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(dcs1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ dcs1.dump();
+ // End of writing test for DCS
+
+ // Begin of writing test for DO
+ std::cout << "Testing writing for DO: ";
+ DO do1;
+ // Initilaize the struct with random data
+ tmp=sizeof(DO)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &do1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DO) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(do1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for DO
+
+ // Begin of writing test for DOP
+ std::cout << "Testing writing for DOP: ";
+ DOP dop1;
+ // Initilaize the struct with random data
+ tmp=sizeof(DOP)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &dop1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DOP) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(dop1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for DOP
+
+ // Begin of writing test for DPARC
+ std::cout << "Testing writing for DPARC: ";
+ DPARC dparc1;
+ // Initilaize the struct with random data
+ tmp=sizeof(DPARC)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &dparc1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DPARC) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(dparc1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for DPARC
+
+ // Begin of writing test for DPELLIPSE
+ std::cout << "Testing writing for DPELLIPSE: ";
+ DPELLIPSE dpellipse1;
+ // Initilaize the struct with random data
+ tmp=sizeof(DPELLIPSE)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &dpellipse1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DPELLIPSE) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(dpellipse1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for DPELLIPSE
+
+ // Begin of writing test for DPLINE
+ std::cout << "Testing writing for DPLINE: ";
+ DPLINE dpline1;
+ // Initilaize the struct with random data
+ tmp=sizeof(DPLINE)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &dpline1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DPLINE) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(dpline1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for DPLINE
+
+ // Begin of writing test for DPRECT
+ std::cout << "Testing writing for DPRECT: ";
+ DPRECT dprect1;
+ // Initilaize the struct with random data
+ tmp=sizeof(DPRECT)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &dprect1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DPRECT) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(dprect1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for DPRECT
+
+ // Begin of writing test for DPSAMPLE
+ std::cout << "Testing writing for DPSAMPLE: ";
+ DPSAMPLE dpsample1;
+ // Initilaize the struct with random data
+ tmp=sizeof(DPSAMPLE)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &dpsample1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DPSAMPLE) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(dpsample1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for DPSAMPLE
+
+ // Begin of writing test for FDOA
+ std::cout << "Testing writing for FDOA: ";
+ FDOA fdoa1;
+ // Initilaize the struct with random data
+ tmp=sizeof(FDOA)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &fdoa1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(FDOA) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(fdoa1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for FDOA
+
+ // Begin of writing test for FIB
+ std::cout << "Testing writing for FIB: ";
+ FIB fib1;
+ // Initilaize the struct with random data
+ tmp=sizeof(FIB)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &fib1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(FIB) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(fib1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for FIB
+
+ // Begin of writing test for LSPD
+ std::cout << "Testing writing for LSPD: ";
+ LSPD lspd1;
+ // Initilaize the struct with random data
+ tmp=sizeof(LSPD)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &lspd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(LSPD) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(lspd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ lspd1.dump();
+ // End of writing test for LSPD
+
+ // Begin of writing test for METAFILEPICT
+ std::cout << "Testing writing for METAFILEPICT: ";
+ METAFILEPICT metafilepict1;
+ // Initilaize the struct with random data
+ tmp=sizeof(METAFILEPICT)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &metafilepict1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(METAFILEPICT) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(metafilepict1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ metafilepict1.dump();
+ // End of writing test for METAFILEPICT
+
+ // Begin of writing test for OBJHEADER
+ std::cout << "Testing writing for OBJHEADER: ";
+ OBJHEADER objheader1;
+ // Initilaize the struct with random data
+ tmp=sizeof(OBJHEADER)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &objheader1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(OBJHEADER) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(objheader1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for OBJHEADER
+
+ // Begin of writing test for OLST
+ std::cout << "Testing writing for OLST: ";
+ OLST olst1;
+ // Initilaize the struct with random data
+ tmp=sizeof(OLST)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &olst1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(OLST) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(olst1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ olst1.dump();
+ // End of writing test for OLST
+
+ // Begin of writing test for PCD
+ std::cout << "Testing writing for PCD: ";
+ PCD pcd1;
+ // Initilaize the struct with random data
+ tmp=sizeof(PCD)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &pcd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PCD) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(pcd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for PCD
+
+ // Begin of writing test for PGD
+ std::cout << "Testing writing for PGD: ";
+ PGD pgd1;
+ // Initilaize the struct with random data
+ tmp=sizeof(PGD)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &pgd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PGD) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(pgd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for PGD
+
+ // Begin of writing test for PICF
+ std::cout << "Testing writing for PICF: ";
+ PICF picf1;
+ // Initilaize the struct with random data
+ tmp=sizeof(PICF)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &picf1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PICF) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(picf1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ picf1.dump();
+ // End of writing test for PICF
+
+ // Begin of writing test for SED
+ std::cout << "Testing writing for SED: ";
+ SED sed1;
+ // Initilaize the struct with random data
+ tmp=sizeof(SED)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &sed1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(SED) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(sed1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for SED
+
+ std::cout << "Testing writing for SEPX:" << std::endl;
+ std::cout << " Sorry, testing dynamic structures isn't implemented,"
+ << " yet." << std::endl;
+ // Begin of writing test for STSHI
+ std::cout << "Testing writing for STSHI: ";
+ STSHI stshi1;
+ // Initilaize the struct with random data
+ tmp=sizeof(STSHI)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &stshi1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(STSHI) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(stshi1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for STSHI
+
+
+ // Okay, close the stream writer and open it for reading...
+ int position=writer->tell(); // store the position for a check
+ delete writer;
+ storage.close();
+ if(!storage.open(OLEStorage::ReadOnly)) {
+ std::cout << "Error: Couldn't open the storage!" << std::endl;
+ ::exit(1);
+ }
+ OLEStreamReader *reader=storage.createStreamReader("TestStream");
+ if(!reader || !reader->isValid()) {
+ std::cout << "Error: Couldn't open a stream for reading!" << std::endl;
+ ::exit(1);
+ }
+
+ // Begin of reading test for DTTM
+ std::cout << "Testing reading for DTTM: ";
+ DTTM dttm2;
+ // Read the data from the stream
+ if(!dttm2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ DTTM dttm3(dttm2);
+ if(dttm1==dttm2 && dttm2==dttm3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for DTTM
+
+ // Begin of reading test for PRM2
+ std::cout << "Testing reading for PRM2: ";
+ PRM2 prm22;
+ // Read the data from the stream
+ if(!prm22.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ PRM2 prm23(prm22);
+ if(prm21==prm22 && prm22==prm23)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for PRM2
+
+ // Begin of reading test for PRM
+ std::cout << "Testing reading for PRM: ";
+ PRM prm2;
+ // Read the data from the stream
+ if(!prm2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ PRM prm3(prm2);
+ if(prm1==prm2 && prm2==prm3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for PRM
+
+ // Begin of reading test for SHD
+ std::cout << "Testing reading for SHD: ";
+ SHD shd2;
+ // Read the data from the stream
+ if(!shd2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ SHD shd3(shd2);
+ if(shd1==shd2 && shd2==shd3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for SHD
+
+ // Begin of reading test for PHE
+ std::cout << "Testing reading for PHE: ";
+ PHE phe2;
+ // Read the data from the stream
+ if(!phe2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ PHE phe3(phe2);
+ if(phe1==phe2 && phe2==phe3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for PHE
+
+ // Begin of reading test for BRC
+ std::cout << "Testing reading for BRC: ";
+ BRC brc2;
+ // Read the data from the stream
+ if(!brc2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ BRC brc3(brc2);
+ if(brc1==brc2 && brc2==brc3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for BRC
+
+ // Begin of reading test for TLP
+ std::cout << "Testing reading for TLP: ";
+ TLP tlp2;
+ // Read the data from the stream
+ if(!tlp2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ TLP tlp3(tlp2);
+ if(tlp1==tlp2 && tlp2==tlp3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for TLP
+
+ // Begin of reading test for TC
+ std::cout << "Testing reading for TC: ";
+ TC tc2;
+ // Read the data from the stream
+ if(!tc2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ TC tc3(tc2);
+ if(tc1==tc2 && tc2==tc3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for TC
+
+ // Begin of reading test for DPHEAD
+ std::cout << "Testing reading for DPHEAD: ";
+ DPHEAD dphead2;
+ // Read the data from the stream
+ if(!dphead2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ DPHEAD dphead3(dphead2);
+ if(dphead1==dphead2 && dphead2==dphead3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for DPHEAD
+
+ // Begin of reading test for DPTXBX
+ std::cout << "Testing reading for DPTXBX: ";
+ DPTXBX dptxbx2;
+ // Read the data from the stream
+ if(!dptxbx2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ DPTXBX dptxbx3(dptxbx2);
+ if(dptxbx1==dptxbx2 && dptxbx2==dptxbx3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for DPTXBX
+
+ std::cout << "Testing reading for DPPOLYLINE:" << std::endl;
+ std::cout << " Sorry, testing dynamic structures isn't implemented,"
+ << " yet." << std::endl;
+ // Begin of reading test for ANLD
+ std::cout << "Testing reading for ANLD: ";
+ ANLD anld2;
+ // Read the data from the stream
+ if(!anld2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ ANLD anld3(anld2);
+ if(anld1==anld2 && anld2==anld3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for ANLD
+
+ // Begin of reading test for ANLV
+ std::cout << "Testing reading for ANLV: ";
+ ANLV anlv2;
+ // Read the data from the stream
+ if(!anlv2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ ANLV anlv3(anlv2);
+ if(anlv1==anlv2 && anlv2==anlv3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for ANLV
+
+ // Begin of reading test for BKF
+ std::cout << "Testing reading for BKF: ";
+ BKF bkf2;
+ // Read the data from the stream
+ if(!bkf2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ BKF bkf3(bkf2);
+ if(bkf1==bkf2 && bkf2==bkf3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for BKF
+
+ // Begin of reading test for BKL
+ std::cout << "Testing reading for BKL: ";
+ BKL bkl2;
+ // Read the data from the stream
+ if(!bkl2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ BKL bkl3(bkl2);
+ if(bkl1==bkl2 && bkl2==bkl3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for BKL
+
+ // Begin of reading test for BRC10
+ std::cout << "Testing reading for BRC10: ";
+ BRC10 brc102;
+ // Read the data from the stream
+ if(!brc102.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ BRC10 brc103(brc102);
+ if(brc101==brc102 && brc102==brc103)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for BRC10
+
+ // Begin of reading test for BTE
+ std::cout << "Testing reading for BTE: ";
+ BTE bte2;
+ // Read the data from the stream
+ if(!bte2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ BTE bte3(bte2);
+ if(bte1==bte2 && bte2==bte3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for BTE
+
+ // Begin of reading test for CHP
+ std::cout << "Testing reading for CHP: ";
+ CHP chp2;
+ // Read the data from the stream
+ if(!chp2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ CHP chp3(chp2);
+ if(chp1==chp2 && chp2==chp3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for CHP
+
+ // Begin of reading test for DCS
+ std::cout << "Testing reading for DCS: ";
+ DCS dcs2;
+ // Read the data from the stream
+ if(!dcs2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ DCS dcs3(dcs2);
+ if(dcs1==dcs2 && dcs2==dcs3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for DCS
+
+ // Begin of reading test for DO
+ std::cout << "Testing reading for DO: ";
+ DO do2;
+ // Read the data from the stream
+ if(!do2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ DO do3(do2);
+ if(do1==do2 && do2==do3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for DO
+
+ // Begin of reading test for DOP
+ std::cout << "Testing reading for DOP: ";
+ DOP dop2;
+ // Read the data from the stream
+ if(!dop2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ DOP dop3(dop2);
+ if(dop1==dop2 && dop2==dop3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for DOP
+
+ // Begin of reading test for DPARC
+ std::cout << "Testing reading for DPARC: ";
+ DPARC dparc2;
+ // Read the data from the stream
+ if(!dparc2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ DPARC dparc3(dparc2);
+ if(dparc1==dparc2 && dparc2==dparc3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for DPARC
+
+ // Begin of reading test for DPELLIPSE
+ std::cout << "Testing reading for DPELLIPSE: ";
+ DPELLIPSE dpellipse2;
+ // Read the data from the stream
+ if(!dpellipse2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ DPELLIPSE dpellipse3(dpellipse2);
+ if(dpellipse1==dpellipse2 && dpellipse2==dpellipse3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for DPELLIPSE
+
+ // Begin of reading test for DPLINE
+ std::cout << "Testing reading for DPLINE: ";
+ DPLINE dpline2;
+ // Read the data from the stream
+ if(!dpline2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ DPLINE dpline3(dpline2);
+ if(dpline1==dpline2 && dpline2==dpline3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for DPLINE
+
+ // Begin of reading test for DPRECT
+ std::cout << "Testing reading for DPRECT: ";
+ DPRECT dprect2;
+ // Read the data from the stream
+ if(!dprect2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ DPRECT dprect3(dprect2);
+ if(dprect1==dprect2 && dprect2==dprect3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for DPRECT
+
+ // Begin of reading test for DPSAMPLE
+ std::cout << "Testing reading for DPSAMPLE: ";
+ DPSAMPLE dpsample2;
+ // Read the data from the stream
+ if(!dpsample2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ DPSAMPLE dpsample3(dpsample2);
+ if(dpsample1==dpsample2 && dpsample2==dpsample3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for DPSAMPLE
+
+ // Begin of reading test for FDOA
+ std::cout << "Testing reading for FDOA: ";
+ FDOA fdoa2;
+ // Read the data from the stream
+ if(!fdoa2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ FDOA fdoa3(fdoa2);
+ if(fdoa1==fdoa2 && fdoa2==fdoa3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for FDOA
+
+ // Begin of reading test for FIB
+ std::cout << "Testing reading for FIB: ";
+ FIB fib2;
+ // Read the data from the stream
+ if(!fib2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ FIB fib3(fib2);
+ if(fib1==fib2 && fib2==fib3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for FIB
+
+ // Begin of reading test for LSPD
+ std::cout << "Testing reading for LSPD: ";
+ LSPD lspd2;
+ // Read the data from the stream
+ if(!lspd2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ LSPD lspd3(lspd2);
+ if(lspd1==lspd2 && lspd2==lspd3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for LSPD
+
+ // Begin of reading test for METAFILEPICT
+ std::cout << "Testing reading for METAFILEPICT: ";
+ METAFILEPICT metafilepict2;
+ // Read the data from the stream
+ if(!metafilepict2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ METAFILEPICT metafilepict3(metafilepict2);
+ if(metafilepict1==metafilepict2 && metafilepict2==metafilepict3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for METAFILEPICT
+
+ // Begin of reading test for OBJHEADER
+ std::cout << "Testing reading for OBJHEADER: ";
+ OBJHEADER objheader2;
+ // Read the data from the stream
+ if(!objheader2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ OBJHEADER objheader3(objheader2);
+ if(objheader1==objheader2 && objheader2==objheader3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for OBJHEADER
+
+ // Begin of reading test for OLST
+ std::cout << "Testing reading for OLST: ";
+ OLST olst2;
+ // Read the data from the stream
+ if(!olst2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ OLST olst3(olst2);
+ if(olst1==olst2 && olst2==olst3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for OLST
+
+ // Begin of reading test for PCD
+ std::cout << "Testing reading for PCD: ";
+ PCD pcd2;
+ // Read the data from the stream
+ if(!pcd2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ PCD pcd3(pcd2);
+ if(pcd1==pcd2 && pcd2==pcd3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for PCD
+
+ // Begin of reading test for PGD
+ std::cout << "Testing reading for PGD: ";
+ PGD pgd2;
+ // Read the data from the stream
+ if(!pgd2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ PGD pgd3(pgd2);
+ if(pgd1==pgd2 && pgd2==pgd3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for PGD
+
+ // Begin of reading test for PICF
+ std::cout << "Testing reading for PICF: ";
+ PICF picf2;
+ // Read the data from the stream
+ if(!picf2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ PICF picf3(picf2);
+ if(picf1==picf2 && picf2==picf3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for PICF
+
+ // Begin of reading test for SED
+ std::cout << "Testing reading for SED: ";
+ SED sed2;
+ // Read the data from the stream
+ if(!sed2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ SED sed3(sed2);
+ if(sed1==sed2 && sed2==sed3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for SED
+
+ std::cout << "Testing reading for SEPX:" << std::endl;
+ std::cout << " Sorry, testing dynamic structures isn't implemented,"
+ << " yet." << std::endl;
+ // Begin of reading test for STSHI
+ std::cout << "Testing reading for STSHI: ";
+ STSHI stshi2;
+ // Read the data from the stream
+ if(!stshi2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ STSHI stshi3(stshi2);
+ if(stshi1==stshi2 && stshi2==stshi3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for STSHI
+
+
+ if(position!=reader->tell())
+ std::cout << "Error: Different amount of bytes read/written!" << std::endl;
+ delete reader;
+
+ std::cout << "Done." << std::endl;
+ // Clean up
+ storage.close();
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/tests/word97_test.cpp b/debian/wv2/wv2-0.4.2.dfsg.2/tests/word97_test.cpp
new file mode 100644
index 00000000..902dfc8a
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/tests/word97_test.cpp
@@ -0,0 +1,1462 @@
+// This file contains generated testing code. We do some basic tests
+// like writing and reading from/to streams. Of course these tests are
+// neither complete nor very advanced, so watch out :)
+
+#include <word97_generated.h>
+#include <olestream.h>
+#include <iostream>
+#include <stdlib.h> // rand(), srand()
+
+#include <time.h> // time()
+
+using namespace wvWare;
+using namespace Word97;
+
+int main(int, char**) {
+
+ // First we have to create some infrastructure
+ system("rm word97_test.doc &> /dev/null");
+ OLEStorage storage("word97_test.doc");
+ if(!storage.open(OLEStorage::WriteOnly)) {
+ std::cout << "Error: Couldn't open the storage!" << std::endl;
+ ::exit(1);
+ }
+
+ OLEStreamWriter *writer=storage.createStreamWriter("TestStream");
+ if(!writer || !writer->isValid()) {
+ std::cout << "Error: Couldn't open a stream for writing!" << std::endl;
+ ::exit(1);
+ }
+
+ // Initialize the random number generator
+ srand( time( 0 ) );
+
+ // Some "global" variables...
+ int *ptr=0; // used to "initialize" the structs
+ int tmp;
+ std::cout << "Testing the Word97 structures..." << std::endl;
+ // Begin of writing test for DTTM
+ std::cout << "Testing writing for DTTM: ";
+ DTTM dttm1;
+ // Initilaize the struct with random data
+ tmp=sizeof(DTTM)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &dttm1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DTTM) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(dttm1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ dttm1.dump();
+ // End of writing test for DTTM
+
+ // Begin of writing test for DOPTYPOGRAPHY
+ std::cout << "Testing writing for DOPTYPOGRAPHY: ";
+ DOPTYPOGRAPHY doptypography1;
+ // Initilaize the struct with random data
+ tmp=sizeof(DOPTYPOGRAPHY)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &doptypography1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DOPTYPOGRAPHY) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(doptypography1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for DOPTYPOGRAPHY
+
+ // Begin of writing test for PRM2
+ std::cout << "Testing writing for PRM2: ";
+ PRM2 prm21;
+ // Initilaize the struct with random data
+ tmp=sizeof(PRM2)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &prm21 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PRM2) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(prm21.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for PRM2
+
+ // Begin of writing test for PRM
+ std::cout << "Testing writing for PRM: ";
+ PRM prm1;
+ // Initilaize the struct with random data
+ tmp=sizeof(PRM)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &prm1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PRM) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(prm1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for PRM
+
+ // Begin of writing test for SHD
+ std::cout << "Testing writing for SHD: ";
+ SHD shd1;
+ // Initilaize the struct with random data
+ tmp=sizeof(SHD)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &shd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(SHD) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(shd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ shd1.dump();
+ // End of writing test for SHD
+
+ // Begin of writing test for PHE
+ std::cout << "Testing writing for PHE: ";
+ PHE phe1;
+ // Initilaize the struct with random data
+ tmp=sizeof(PHE)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &phe1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PHE) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(phe1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ phe1.dump();
+ // End of writing test for PHE
+
+ // Begin of writing test for BRC
+ std::cout << "Testing writing for BRC: ";
+ BRC brc1;
+ // Initilaize the struct with random data
+ tmp=sizeof(BRC)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &brc1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BRC) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(brc1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ brc1.dump();
+ // End of writing test for BRC
+
+ // Begin of writing test for TLP
+ std::cout << "Testing writing for TLP: ";
+ TLP tlp1;
+ // Initilaize the struct with random data
+ tmp=sizeof(TLP)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &tlp1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(TLP) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(tlp1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ tlp1.dump();
+ // End of writing test for TLP
+
+ // Begin of writing test for TC
+ std::cout << "Testing writing for TC: ";
+ TC tc1;
+ // Initilaize the struct with random data
+ tmp=sizeof(TC)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &tc1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(TC) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(tc1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ tc1.dump();
+ // End of writing test for TC
+
+ // Begin of writing test for ANLD
+ std::cout << "Testing writing for ANLD: ";
+ ANLD anld1;
+ // Initilaize the struct with random data
+ tmp=sizeof(ANLD)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &anld1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(ANLD) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(anld1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ anld1.dump();
+ // End of writing test for ANLD
+
+ // Begin of writing test for ANLV
+ std::cout << "Testing writing for ANLV: ";
+ ANLV anlv1;
+ // Initilaize the struct with random data
+ tmp=sizeof(ANLV)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &anlv1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(ANLV) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(anlv1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ anlv1.dump();
+ // End of writing test for ANLV
+
+ // Begin of writing test for ASUMY
+ std::cout << "Testing writing for ASUMY: ";
+ ASUMY asumy1;
+ // Initilaize the struct with random data
+ tmp=sizeof(ASUMY)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &asumy1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(ASUMY) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(asumy1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for ASUMY
+
+ // Begin of writing test for ASUMYI
+ std::cout << "Testing writing for ASUMYI: ";
+ ASUMYI asumyi1;
+ // Initilaize the struct with random data
+ tmp=sizeof(ASUMYI)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &asumyi1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(ASUMYI) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(asumyi1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for ASUMYI
+
+ // Begin of writing test for ATRD
+ std::cout << "Testing writing for ATRD: ";
+ ATRD atrd1;
+ // Initilaize the struct with random data
+ tmp=sizeof(ATRD)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &atrd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(ATRD) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(atrd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for ATRD
+
+ // Begin of writing test for BKD
+ std::cout << "Testing writing for BKD: ";
+ BKD bkd1;
+ // Initilaize the struct with random data
+ tmp=sizeof(BKD)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &bkd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BKD) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(bkd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for BKD
+
+ // Begin of writing test for BKF
+ std::cout << "Testing writing for BKF: ";
+ BKF bkf1;
+ // Initilaize the struct with random data
+ tmp=sizeof(BKF)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &bkf1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BKF) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(bkf1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for BKF
+
+ // Begin of writing test for BKL
+ std::cout << "Testing writing for BKL: ";
+ BKL bkl1;
+ // Initilaize the struct with random data
+ tmp=sizeof(BKL)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &bkl1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BKL) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(bkl1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for BKL
+
+ // Begin of writing test for BRC10
+ std::cout << "Testing writing for BRC10: ";
+ BRC10 brc101;
+ // Initilaize the struct with random data
+ tmp=sizeof(BRC10)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &brc101 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BRC10) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(brc101.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for BRC10
+
+ // Begin of writing test for BTE
+ std::cout << "Testing writing for BTE: ";
+ BTE bte1;
+ // Initilaize the struct with random data
+ tmp=sizeof(BTE)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &bte1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(BTE) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(bte1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for BTE
+
+ // Begin of writing test for CHP
+ std::cout << "Testing writing for CHP: ";
+ CHP chp1;
+ // Initilaize the struct with random data
+ tmp=sizeof(CHP)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &chp1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(CHP) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(chp1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ chp1.dump();
+ // End of writing test for CHP
+
+ // Begin of writing test for DCS
+ std::cout << "Testing writing for DCS: ";
+ DCS dcs1;
+ // Initilaize the struct with random data
+ tmp=sizeof(DCS)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &dcs1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DCS) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(dcs1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ dcs1.dump();
+ // End of writing test for DCS
+
+ // Begin of writing test for DOGRID
+ std::cout << "Testing writing for DOGRID: ";
+ DOGRID dogrid1;
+ // Initilaize the struct with random data
+ tmp=sizeof(DOGRID)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &dogrid1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DOGRID) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(dogrid1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for DOGRID
+
+ // Begin of writing test for DOP
+ std::cout << "Testing writing for DOP: ";
+ DOP dop1;
+ // Initilaize the struct with random data
+ tmp=sizeof(DOP)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &dop1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(DOP) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(dop1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for DOP
+
+ // Begin of writing test for FIB
+ std::cout << "Testing writing for FIB: ";
+ FIB fib1;
+ // Initilaize the struct with random data
+ tmp=sizeof(FIB)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &fib1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(FIB) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(fib1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for FIB
+
+ // Begin of writing test for FIBFCLCB
+ std::cout << "Testing writing for FIBFCLCB: ";
+ FIBFCLCB fibfclcb1;
+ // Initilaize the struct with random data
+ tmp=sizeof(FIBFCLCB)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &fibfclcb1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(FIBFCLCB) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(fibfclcb1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for FIBFCLCB
+
+ // Begin of writing test for FRD
+ std::cout << "Testing writing for FRD: ";
+ FRD frd1;
+ // Initilaize the struct with random data
+ tmp=sizeof(FRD)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &frd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(FRD) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(frd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for FRD
+
+ // Begin of writing test for FSPA
+ std::cout << "Testing writing for FSPA: ";
+ FSPA fspa1;
+ // Initilaize the struct with random data
+ tmp=sizeof(FSPA)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &fspa1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(FSPA) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(fspa1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for FSPA
+
+ // Begin of writing test for FTXBXS
+ std::cout << "Testing writing for FTXBXS: ";
+ FTXBXS ftxbxs1;
+ // Initilaize the struct with random data
+ tmp=sizeof(FTXBXS)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &ftxbxs1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(FTXBXS) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(ftxbxs1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for FTXBXS
+
+ // Begin of writing test for LFO
+ std::cout << "Testing writing for LFO: ";
+ LFO lfo1;
+ // Initilaize the struct with random data
+ tmp=sizeof(LFO)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &lfo1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(LFO) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(lfo1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for LFO
+
+ // Begin of writing test for LFOLVL
+ std::cout << "Testing writing for LFOLVL: ";
+ LFOLVL lfolvl1;
+ // Initilaize the struct with random data
+ tmp=sizeof(LFOLVL)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &lfolvl1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(LFOLVL) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(lfolvl1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for LFOLVL
+
+ // Begin of writing test for LSPD
+ std::cout << "Testing writing for LSPD: ";
+ LSPD lspd1;
+ // Initilaize the struct with random data
+ tmp=sizeof(LSPD)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &lspd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(LSPD) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(lspd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ lspd1.dump();
+ // End of writing test for LSPD
+
+ // Begin of writing test for LSTF
+ std::cout << "Testing writing for LSTF: ";
+ LSTF lstf1;
+ // Initilaize the struct with random data
+ tmp=sizeof(LSTF)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &lstf1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(LSTF) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(lstf1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for LSTF
+
+ // Begin of writing test for LVLF
+ std::cout << "Testing writing for LVLF: ";
+ LVLF lvlf1;
+ // Initilaize the struct with random data
+ tmp=sizeof(LVLF)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &lvlf1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(LVLF) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(lvlf1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for LVLF
+
+ // Begin of writing test for METAFILEPICT
+ std::cout << "Testing writing for METAFILEPICT: ";
+ METAFILEPICT metafilepict1;
+ // Initilaize the struct with random data
+ tmp=sizeof(METAFILEPICT)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &metafilepict1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(METAFILEPICT) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(metafilepict1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ metafilepict1.dump();
+ // End of writing test for METAFILEPICT
+
+ // Begin of writing test for NUMRM
+ std::cout << "Testing writing for NUMRM: ";
+ NUMRM numrm1;
+ // Initilaize the struct with random data
+ tmp=sizeof(NUMRM)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &numrm1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(NUMRM) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(numrm1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ numrm1.dump();
+ // End of writing test for NUMRM
+
+ // Begin of writing test for OBJHEADER
+ std::cout << "Testing writing for OBJHEADER: ";
+ OBJHEADER objheader1;
+ // Initilaize the struct with random data
+ tmp=sizeof(OBJHEADER)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &objheader1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(OBJHEADER) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(objheader1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for OBJHEADER
+
+ // Begin of writing test for OLST
+ std::cout << "Testing writing for OLST: ";
+ OLST olst1;
+ // Initilaize the struct with random data
+ tmp=sizeof(OLST)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &olst1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(OLST) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(olst1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ olst1.dump();
+ // End of writing test for OLST
+
+ // Begin of writing test for PCD
+ std::cout << "Testing writing for PCD: ";
+ PCD pcd1;
+ // Initilaize the struct with random data
+ tmp=sizeof(PCD)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &pcd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PCD) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(pcd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for PCD
+
+ // Begin of writing test for PGD
+ std::cout << "Testing writing for PGD: ";
+ PGD pgd1;
+ // Initilaize the struct with random data
+ tmp=sizeof(PGD)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &pgd1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PGD) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(pgd1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for PGD
+
+ // Begin of writing test for PHE2
+ std::cout << "Testing writing for PHE2: ";
+ PHE2 phe21;
+ // Initilaize the struct with random data
+ tmp=sizeof(PHE2)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &phe21 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PHE2) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(phe21.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for PHE2
+
+ // Begin of writing test for PICF
+ std::cout << "Testing writing for PICF: ";
+ PICF picf1;
+ // Initilaize the struct with random data
+ tmp=sizeof(PICF)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &picf1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(PICF) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(picf1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ picf1.dump();
+ // End of writing test for PICF
+
+ // Begin of writing test for RR
+ std::cout << "Testing writing for RR: ";
+ RR rr1;
+ // Initilaize the struct with random data
+ tmp=sizeof(RR)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &rr1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(RR) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(rr1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for RR
+
+ // Begin of writing test for RS
+ std::cout << "Testing writing for RS: ";
+ RS rs1;
+ // Initilaize the struct with random data
+ tmp=sizeof(RS)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &rs1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(RS) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(rs1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for RS
+
+ // Begin of writing test for SED
+ std::cout << "Testing writing for SED: ";
+ SED sed1;
+ // Initilaize the struct with random data
+ tmp=sizeof(SED)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &sed1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(SED) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(sed1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for SED
+
+ std::cout << "Testing writing for SEPX:" << std::endl;
+ std::cout << " Sorry, testing dynamic structures isn't implemented,"
+ << " yet." << std::endl;
+ // Begin of writing test for STSHI
+ std::cout << "Testing writing for STSHI: ";
+ STSHI stshi1;
+ // Initilaize the struct with random data
+ tmp=sizeof(STSHI)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &stshi1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(STSHI) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(stshi1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for STSHI
+
+ // Begin of writing test for WKB
+ std::cout << "Testing writing for WKB: ";
+ WKB wkb1;
+ // Initilaize the struct with random data
+ tmp=sizeof(WKB)/sizeof(int);
+ ptr=reinterpret_cast<int*>( &wkb1 );
+ for(int _i=0; _i<tmp; ++_i)
+ *ptr++=rand();
+ *ptr |= rand() & (0x00ffffff >> (((sizeof(int)-1)-(sizeof(WKB) % sizeof(int)))*8)); // yay! :)
+ // and write it out...
+ if(wkb1.write(writer, false))
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of writing test for WKB
+
+
+ // Okay, close the stream writer and open it for reading...
+ int position=writer->tell(); // store the position for a check
+ delete writer;
+ storage.close();
+ if(!storage.open(OLEStorage::ReadOnly)) {
+ std::cout << "Error: Couldn't open the storage!" << std::endl;
+ ::exit(1);
+ }
+ OLEStreamReader *reader=storage.createStreamReader("TestStream");
+ if(!reader || !reader->isValid()) {
+ std::cout << "Error: Couldn't open a stream for reading!" << std::endl;
+ ::exit(1);
+ }
+
+ // Begin of reading test for DTTM
+ std::cout << "Testing reading for DTTM: ";
+ DTTM dttm2;
+ // Read the data from the stream
+ if(!dttm2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ DTTM dttm3(dttm2);
+ if(dttm1==dttm2 && dttm2==dttm3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for DTTM
+
+ // Begin of reading test for DOPTYPOGRAPHY
+ std::cout << "Testing reading for DOPTYPOGRAPHY: ";
+ DOPTYPOGRAPHY doptypography2;
+ // Read the data from the stream
+ if(!doptypography2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ DOPTYPOGRAPHY doptypography3(doptypography2);
+ if(doptypography1==doptypography2 && doptypography2==doptypography3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for DOPTYPOGRAPHY
+
+ // Begin of reading test for PRM2
+ std::cout << "Testing reading for PRM2: ";
+ PRM2 prm22;
+ // Read the data from the stream
+ if(!prm22.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ PRM2 prm23(prm22);
+ if(prm21==prm22 && prm22==prm23)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for PRM2
+
+ // Begin of reading test for PRM
+ std::cout << "Testing reading for PRM: ";
+ PRM prm2;
+ // Read the data from the stream
+ if(!prm2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ PRM prm3(prm2);
+ if(prm1==prm2 && prm2==prm3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for PRM
+
+ // Begin of reading test for SHD
+ std::cout << "Testing reading for SHD: ";
+ SHD shd2;
+ // Read the data from the stream
+ if(!shd2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ SHD shd3(shd2);
+ if(shd1==shd2 && shd2==shd3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for SHD
+
+ // Begin of reading test for PHE
+ std::cout << "Testing reading for PHE: ";
+ PHE phe2;
+ // Read the data from the stream
+ if(!phe2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ PHE phe3(phe2);
+ if(phe1==phe2 && phe2==phe3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for PHE
+
+ // Begin of reading test for BRC
+ std::cout << "Testing reading for BRC: ";
+ BRC brc2;
+ // Read the data from the stream
+ if(!brc2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ BRC brc3(brc2);
+ if(brc1==brc2 && brc2==brc3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for BRC
+
+ // Begin of reading test for TLP
+ std::cout << "Testing reading for TLP: ";
+ TLP tlp2;
+ // Read the data from the stream
+ if(!tlp2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ TLP tlp3(tlp2);
+ if(tlp1==tlp2 && tlp2==tlp3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for TLP
+
+ // Begin of reading test for TC
+ std::cout << "Testing reading for TC: ";
+ TC tc2;
+ // Read the data from the stream
+ if(!tc2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ TC tc3(tc2);
+ if(tc1==tc2 && tc2==tc3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for TC
+
+ // Begin of reading test for ANLD
+ std::cout << "Testing reading for ANLD: ";
+ ANLD anld2;
+ // Read the data from the stream
+ if(!anld2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ ANLD anld3(anld2);
+ if(anld1==anld2 && anld2==anld3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for ANLD
+
+ // Begin of reading test for ANLV
+ std::cout << "Testing reading for ANLV: ";
+ ANLV anlv2;
+ // Read the data from the stream
+ if(!anlv2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ ANLV anlv3(anlv2);
+ if(anlv1==anlv2 && anlv2==anlv3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for ANLV
+
+ // Begin of reading test for ASUMY
+ std::cout << "Testing reading for ASUMY: ";
+ ASUMY asumy2;
+ // Read the data from the stream
+ if(!asumy2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ ASUMY asumy3(asumy2);
+ if(asumy1==asumy2 && asumy2==asumy3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for ASUMY
+
+ // Begin of reading test for ASUMYI
+ std::cout << "Testing reading for ASUMYI: ";
+ ASUMYI asumyi2;
+ // Read the data from the stream
+ if(!asumyi2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ ASUMYI asumyi3(asumyi2);
+ if(asumyi1==asumyi2 && asumyi2==asumyi3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for ASUMYI
+
+ // Begin of reading test for ATRD
+ std::cout << "Testing reading for ATRD: ";
+ ATRD atrd2;
+ // Read the data from the stream
+ if(!atrd2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ ATRD atrd3(atrd2);
+ if(atrd1==atrd2 && atrd2==atrd3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for ATRD
+
+ // Begin of reading test for BKD
+ std::cout << "Testing reading for BKD: ";
+ BKD bkd2;
+ // Read the data from the stream
+ if(!bkd2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ BKD bkd3(bkd2);
+ if(bkd1==bkd2 && bkd2==bkd3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for BKD
+
+ // Begin of reading test for BKF
+ std::cout << "Testing reading for BKF: ";
+ BKF bkf2;
+ // Read the data from the stream
+ if(!bkf2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ BKF bkf3(bkf2);
+ if(bkf1==bkf2 && bkf2==bkf3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for BKF
+
+ // Begin of reading test for BKL
+ std::cout << "Testing reading for BKL: ";
+ BKL bkl2;
+ // Read the data from the stream
+ if(!bkl2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ BKL bkl3(bkl2);
+ if(bkl1==bkl2 && bkl2==bkl3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for BKL
+
+ // Begin of reading test for BRC10
+ std::cout << "Testing reading for BRC10: ";
+ BRC10 brc102;
+ // Read the data from the stream
+ if(!brc102.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ BRC10 brc103(brc102);
+ if(brc101==brc102 && brc102==brc103)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for BRC10
+
+ // Begin of reading test for BTE
+ std::cout << "Testing reading for BTE: ";
+ BTE bte2;
+ // Read the data from the stream
+ if(!bte2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ BTE bte3(bte2);
+ if(bte1==bte2 && bte2==bte3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for BTE
+
+ // Begin of reading test for CHP
+ std::cout << "Testing reading for CHP: ";
+ CHP chp2;
+ // Read the data from the stream
+ if(!chp2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ CHP chp3(chp2);
+ if(chp1==chp2 && chp2==chp3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for CHP
+
+ // Begin of reading test for DCS
+ std::cout << "Testing reading for DCS: ";
+ DCS dcs2;
+ // Read the data from the stream
+ if(!dcs2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ DCS dcs3(dcs2);
+ if(dcs1==dcs2 && dcs2==dcs3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for DCS
+
+ // Begin of reading test for DOGRID
+ std::cout << "Testing reading for DOGRID: ";
+ DOGRID dogrid2;
+ // Read the data from the stream
+ if(!dogrid2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ DOGRID dogrid3(dogrid2);
+ if(dogrid1==dogrid2 && dogrid2==dogrid3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for DOGRID
+
+ // Begin of reading test for DOP
+ std::cout << "Testing reading for DOP: ";
+ DOP dop2;
+ // Read the data from the stream
+ if(!dop2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ DOP dop3(dop2);
+ if(dop1==dop2 && dop2==dop3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for DOP
+
+ // Begin of reading test for FIB
+ std::cout << "Testing reading for FIB: ";
+ FIB fib2;
+ // Read the data from the stream
+ if(!fib2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ FIB fib3(fib2);
+ if(fib1==fib2 && fib2==fib3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for FIB
+
+ // Begin of reading test for FIBFCLCB
+ std::cout << "Testing reading for FIBFCLCB: ";
+ FIBFCLCB fibfclcb2;
+ // Read the data from the stream
+ if(!fibfclcb2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ FIBFCLCB fibfclcb3(fibfclcb2);
+ if(fibfclcb1==fibfclcb2 && fibfclcb2==fibfclcb3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for FIBFCLCB
+
+ // Begin of reading test for FRD
+ std::cout << "Testing reading for FRD: ";
+ FRD frd2;
+ // Read the data from the stream
+ if(!frd2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ FRD frd3(frd2);
+ if(frd1==frd2 && frd2==frd3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for FRD
+
+ // Begin of reading test for FSPA
+ std::cout << "Testing reading for FSPA: ";
+ FSPA fspa2;
+ // Read the data from the stream
+ if(!fspa2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ FSPA fspa3(fspa2);
+ if(fspa1==fspa2 && fspa2==fspa3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for FSPA
+
+ // Begin of reading test for FTXBXS
+ std::cout << "Testing reading for FTXBXS: ";
+ FTXBXS ftxbxs2;
+ // Read the data from the stream
+ if(!ftxbxs2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ FTXBXS ftxbxs3(ftxbxs2);
+ if(ftxbxs1==ftxbxs2 && ftxbxs2==ftxbxs3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for FTXBXS
+
+ // Begin of reading test for LFO
+ std::cout << "Testing reading for LFO: ";
+ LFO lfo2;
+ // Read the data from the stream
+ if(!lfo2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ LFO lfo3(lfo2);
+ if(lfo1==lfo2 && lfo2==lfo3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for LFO
+
+ // Begin of reading test for LFOLVL
+ std::cout << "Testing reading for LFOLVL: ";
+ LFOLVL lfolvl2;
+ // Read the data from the stream
+ if(!lfolvl2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ LFOLVL lfolvl3(lfolvl2);
+ if(lfolvl1==lfolvl2 && lfolvl2==lfolvl3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for LFOLVL
+
+ // Begin of reading test for LSPD
+ std::cout << "Testing reading for LSPD: ";
+ LSPD lspd2;
+ // Read the data from the stream
+ if(!lspd2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ LSPD lspd3(lspd2);
+ if(lspd1==lspd2 && lspd2==lspd3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for LSPD
+
+ // Begin of reading test for LSTF
+ std::cout << "Testing reading for LSTF: ";
+ LSTF lstf2;
+ // Read the data from the stream
+ if(!lstf2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ LSTF lstf3(lstf2);
+ if(lstf1==lstf2 && lstf2==lstf3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for LSTF
+
+ // Begin of reading test for LVLF
+ std::cout << "Testing reading for LVLF: ";
+ LVLF lvlf2;
+ // Read the data from the stream
+ if(!lvlf2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ LVLF lvlf3(lvlf2);
+ if(lvlf1==lvlf2 && lvlf2==lvlf3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for LVLF
+
+ // Begin of reading test for METAFILEPICT
+ std::cout << "Testing reading for METAFILEPICT: ";
+ METAFILEPICT metafilepict2;
+ // Read the data from the stream
+ if(!metafilepict2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ METAFILEPICT metafilepict3(metafilepict2);
+ if(metafilepict1==metafilepict2 && metafilepict2==metafilepict3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for METAFILEPICT
+
+ // Begin of reading test for NUMRM
+ std::cout << "Testing reading for NUMRM: ";
+ NUMRM numrm2;
+ // Read the data from the stream
+ if(!numrm2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ NUMRM numrm3(numrm2);
+ if(numrm1==numrm2 && numrm2==numrm3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for NUMRM
+
+ // Begin of reading test for OBJHEADER
+ std::cout << "Testing reading for OBJHEADER: ";
+ OBJHEADER objheader2;
+ // Read the data from the stream
+ if(!objheader2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ OBJHEADER objheader3(objheader2);
+ if(objheader1==objheader2 && objheader2==objheader3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for OBJHEADER
+
+ // Begin of reading test for OLST
+ std::cout << "Testing reading for OLST: ";
+ OLST olst2;
+ // Read the data from the stream
+ if(!olst2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ OLST olst3(olst2);
+ if(olst1==olst2 && olst2==olst3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for OLST
+
+ // Begin of reading test for PCD
+ std::cout << "Testing reading for PCD: ";
+ PCD pcd2;
+ // Read the data from the stream
+ if(!pcd2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ PCD pcd3(pcd2);
+ if(pcd1==pcd2 && pcd2==pcd3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for PCD
+
+ // Begin of reading test for PGD
+ std::cout << "Testing reading for PGD: ";
+ PGD pgd2;
+ // Read the data from the stream
+ if(!pgd2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ PGD pgd3(pgd2);
+ if(pgd1==pgd2 && pgd2==pgd3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for PGD
+
+ // Begin of reading test for PHE2
+ std::cout << "Testing reading for PHE2: ";
+ PHE2 phe22;
+ // Read the data from the stream
+ if(!phe22.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ PHE2 phe23(phe22);
+ if(phe21==phe22 && phe22==phe23)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for PHE2
+
+ // Begin of reading test for PICF
+ std::cout << "Testing reading for PICF: ";
+ PICF picf2;
+ // Read the data from the stream
+ if(!picf2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ PICF picf3(picf2);
+ if(picf1==picf2 && picf2==picf3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for PICF
+
+ // Begin of reading test for RR
+ std::cout << "Testing reading for RR: ";
+ RR rr2;
+ // Read the data from the stream
+ if(!rr2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ RR rr3(rr2);
+ if(rr1==rr2 && rr2==rr3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for RR
+
+ // Begin of reading test for RS
+ std::cout << "Testing reading for RS: ";
+ RS rs2;
+ // Read the data from the stream
+ if(!rs2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ RS rs3(rs2);
+ if(rs1==rs2 && rs2==rs3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for RS
+
+ // Begin of reading test for SED
+ std::cout << "Testing reading for SED: ";
+ SED sed2;
+ // Read the data from the stream
+ if(!sed2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ SED sed3(sed2);
+ if(sed1==sed2 && sed2==sed3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for SED
+
+ std::cout << "Testing reading for SEPX:" << std::endl;
+ std::cout << " Sorry, testing dynamic structures isn't implemented,"
+ << " yet." << std::endl;
+ // Begin of reading test for STSHI
+ std::cout << "Testing reading for STSHI: ";
+ STSHI stshi2;
+ // Read the data from the stream
+ if(!stshi2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ STSHI stshi3(stshi2);
+ if(stshi1==stshi2 && stshi2==stshi3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for STSHI
+
+ // Begin of reading test for WKB
+ std::cout << "Testing reading for WKB: ";
+ WKB wkb2;
+ // Read the data from the stream
+ if(!wkb2.read(reader, false))
+ std::cout << "Failed. " << std::endl;
+ // Test the copy CTOR
+ WKB wkb3(wkb2);
+ if(wkb1==wkb2 && wkb2==wkb3)
+ std::cout << "Passed." << std::endl;
+ else
+ std::cout << "Failed." << std::endl;
+ // End of reading test for WKB
+
+
+ if(position!=reader->tell())
+ std::cout << "Error: Different amount of bytes read/written!" << std::endl;
+ delete reader;
+
+ std::cout << "Done." << std::endl;
+ // Clean up
+ storage.close();
+}
diff --git a/debian/wv2/wv2-0.4.2.dfsg.2/wv2-config.cmake b/debian/wv2/wv2-0.4.2.dfsg.2/wv2-config.cmake
new file mode 100644
index 00000000..ab299ec6
--- /dev/null
+++ b/debian/wv2/wv2-0.4.2.dfsg.2/wv2-config.cmake
@@ -0,0 +1,103 @@
+#!/bin/sh
+
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+exec_prefix_set=no
+
+usage()
+{
+ cat <<EOF
+Usage: wv2-config [OPTIONS] [LIBRARIES]
+Options:
+ [--prefix[=DIR]]
+ [--exec-prefix[=DIR]]
+ [--version]
+ [--libs]
+ [--cflags]
+Libraries/Headers:
+ wv2
+EOF
+ exit $1
+}
+
+if test $# -eq 0; then
+ usage 1 1>&2
+fi
+
+lib_wv2=yes
+
+while test $# -gt 0; do
+ case "$1" in
+ -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ case $1 in
+ --prefix=*)
+ prefix=$optarg
+ if test $exec_prefix_set = no ; then
+ exec_prefix=$optarg
+ fi
+ ;;
+ --prefix)
+ echo_prefix=yes
+ ;;
+ --exec-prefix=*)
+ exec_prefix=$optarg
+ exec_prefix_set=yes
+ ;;
+ --exec-prefix)
+ echo_exec_prefix=yes
+ ;;
+ --version)
+ echo @WV2_MAJOR_VERSION@.@WV2_MINOR_VERSION@.@WV2_MICRO_VERSION@
+ ;;
+ --cflags)
+ echo_cflags=yes
+ ;;
+ --libs)
+ echo_libs=yes
+ ;;
+ wv2)
+ lib_wv2=yes
+ ;;
+ *)
+ usage 1 1>&2
+ ;;
+ esac
+ shift
+done
+
+if test "$echo_prefix" = "yes"; then
+ echo $prefix
+fi
+
+if test "$echo_exec_prefix" = "yes"; then
+ echo $exec_prefix
+fi
+
+wv2_libs="@WV2_LDFLAGS@ -lwv2 @WV2_LIBS@"
+
+if test "$echo_cflags" = "yes"; then
+ includes="@WV2_CFLAGS@"
+ if test "$lib_wv2" = "yes"; then
+ includes="-I${prefix}/include $includes"
+ fi
+ echo $includes
+fi
+
+if test "$echo_libs" = "yes"; then
+ libdirs=-L${exec_prefix}/lib@LIB_SUFFIX@
+ my_wv2_libs=
+ for i in $wv2_libs ; do
+ if test "x$i" != "x-L${exec_prefix}/lib@LIB_SUFFIX@" ; then
+ if test -z "$my_wv2_libs" ; then
+ my_wv2_libs="$i"
+ else
+ my_wv2_libs="$my_wv2_libs $i"
+ fi
+ fi
+ done
+
+ echo $libdirs $my_wv2_libs
+fi