diff options
Diffstat (limited to 'debian/wv2/wv2-0.4.2.dfsg.2')
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 +// <[email protected]> + +#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 +// <[email protected]> + +#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 thingies + s/ //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 thingies + s/ //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 +// <[email protected]> +@@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 +// <[email protected]> +@@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 +// <[email protected]> +@@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 +// <[email protected]> +@@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 +// <[email protected]> +@@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 +// <[email protected]> +@@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 *>( © ) ); +} + +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 *>( © ) ); +} + +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 +// <[email protected]> + +#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 +// <[email protected]> + +#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; + + /** + * <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 < + * 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 <= + * 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 +// <[email protected]> + +#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 +// <[email protected]> + +#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 < + * 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 <= + * 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 = ¶graphStyle->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 Binary files differnew file mode 100644 index 00000000..dd94bba7 --- /dev/null +++ b/debian/wv2/wv2-0.4.2.dfsg.2/tests/testole.doc 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 |