1 /* This file is part of the wvWare 2 project
2    Copyright (C) 2002-2003 Werner Trobin <trobin@kde.org>
3 
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public
6    License version 2 as published by the Free Software Foundation.
7 
8    This library is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11    Library General Public License for more details.
12 
13    You should have received a copy of the GNU Library General Public License
14    along with this library; see the file COPYING.LIB.  If not, write to
15    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16    Boston, MA 02111-1307, USA.
17 */
18 
19 #include "fields.h"
20 #include "olestream.h"
21 #include "word_helper.h"
22 #include "word97_generated.h"
23 
24 #include "wvlog.h"
25 
26 namespace wvWare
27 {
FLD()28     FLD::FLD() : ch( 0 ), flt( 0 )
29     {
30     }
31 
FLD(OLEStreamReader * stream,bool preservePos)32     FLD::FLD( OLEStreamReader* stream, bool preservePos ) : ch( 0 ), flt( 0 )
33     {
34         read( stream, preservePos );
35     }
36 
FLD(const U8 * ptr)37     FLD::FLD( const U8* ptr ) : ch( 0 ), flt( 0 )
38     {
39         readPtr( ptr );
40     }
41 
read(OLEStreamReader * stream,bool preservePos)42     bool FLD::read( OLEStreamReader* stream, bool preservePos )
43     {
44         if ( preservePos )
45             stream->push();
46 
47         ch = stream->readU8();
48         flt = stream->readU8();
49 
50         if ( preservePos )
51             stream->pop();
52         return true;
53     }
54 
readPtr(const U8 * ptr)55     bool FLD::readPtr( const U8* ptr )
56     {
57         ch = *ptr++;
58         flt = *ptr;
59         return true;
60     }
61 
clear()62     void FLD::clear()
63     {
64         ch = 0;
65         flt = 0;
66     }
67 
68     const unsigned int FLD::sizeOf = 2;
69 
operator ==(const FLD & lhs,const FLD & rhs)70     bool operator==( const FLD &lhs, const FLD &rhs )
71     {
72         return lhs.ch == rhs.ch &&
73               lhs.flt == rhs.flt;
74     }
75 
operator !=(const FLD & lhs,const FLD & rhs)76     bool operator!=( const FLD &lhs, const FLD &rhs )
77     {
78         return !( lhs == rhs );
79     }
80 } // namespace wvWare
81 
82 using namespace wvWare;
83 
84 
Fields(OLEStreamReader * tableStream,const Word97::FIB & fib)85 Fields::Fields( OLEStreamReader* tableStream, const Word97::FIB& fib ) :
86     m_main( 0 ), m_header( 0 ), m_footnote( 0 ), m_annotation( 0 ),
87     m_endnote( 0 ), m_textbox( 0 ), m_headerTextbox( 0 ), m_bookmark( 0 )
88 {
89     tableStream->push();
90 
91 #ifdef WV2_DEBUG_FIELDS
92     wvlog << "Fields --------------" << endl
93           << "  main: fc=" << fib.fcPlcffldMom << " lcb=" << fib.lcbPlcffldMom << endl
94           << "  header: fc=" << fib.fcPlcffldHdr << " lcb=" << fib.lcbPlcffldHdr << endl
95           << "  footnote: fc=" << fib.fcPlcffldFtn << " lcb=" << fib.lcbPlcffldFtn << endl
96           << "  annotation: fc=" << fib.fcPlcffldAtn << " lcb=" << fib.lcbPlcffldAtn << endl
97           << "  endnote: fc=" << fib.fcPlcffldEdn << " lcb=" << fib.lcbPlcffldEdn << endl
98           << "  textbox: fc=" << fib.fcPlcffldTxbx << " lcb=" << fib.lcbPlcffldTxbx << endl
99           << "  bookmark: fc=" << fib.fcSttbfbkmk << " lcb=" << fib.lcbSttbfbkmk << endl
100           << "  headertextbox: fc=" << fib.fcPlcffldHdrTxbx << " lcb=" << fib.lcbPlcffldHdrTxbx << endl;
101 #endif
102     tableStream->seek( fib.fcPlcffldMom, WV2_SEEK_SET ); // to make the sanity check work
103     read( fib.fcPlcffldMom, fib.lcbPlcffldMom, tableStream, &m_main );
104 
105     sanityCheck( tableStream, fib.fcPlcffldHdr, fib.lcbPlcffldHdr );
106     read( fib.fcPlcffldHdr, fib.lcbPlcffldHdr, tableStream, &m_header );
107 
108     sanityCheck( tableStream, fib.fcPlcffldFtn, fib.lcbPlcffldFtn );
109     read( fib.fcPlcffldFtn, fib.lcbPlcffldFtn, tableStream, &m_footnote );
110 
111     sanityCheck( tableStream, fib.fcPlcffldAtn, fib.lcbPlcffldAtn );
112     read( fib.fcPlcffldAtn, fib.lcbPlcffldAtn, tableStream, &m_annotation );
113 
114     sanityCheck( tableStream, fib.fcPlcffldEdn, fib.lcbPlcffldEdn );
115     read( fib.fcPlcffldEdn, fib.lcbPlcffldEdn, tableStream, &m_endnote );
116 
117     sanityCheck( tableStream, fib.fcPlcffldTxbx, fib.lcbPlcffldTxbx );
118     read( fib.fcPlcffldTxbx, fib.lcbPlcffldTxbx, tableStream, &m_textbox );
119 
120     sanityCheck( tableStream, fib.fcSttbfbkmk, fib.lcbSttbfbkmk );
121     read( fib.fcSttbfbkmk, fib.lcbSttbfbkmk, tableStream, &m_bookmark );
122 
123     // No sanity check here, plcOcx might be in between
124     read( fib.fcPlcffldHdrTxbx, fib.lcbPlcffldHdrTxbx, tableStream, &m_headerTextbox );
125 
126     tableStream->pop();
127 }
128 
~Fields()129 Fields::~Fields()
130 {
131     delete m_bookmark;
132     delete m_headerTextbox;
133     delete m_textbox;
134     delete m_endnote;
135     delete m_annotation;
136     delete m_footnote;
137     delete m_header;
138     delete m_main;
139 }
140 
fldForCP(Parser::SubDocument subDocument,U32 cp) const141 const FLD* Fields::fldForCP( Parser::SubDocument subDocument, U32 cp ) const
142 {
143     switch( subDocument ) {
144         case Parser::None:
145             wvlog << "Error: The state of the parser is invalid!" << endl;
146             return 0;
147             break;
148         case Parser::Main:
149             return fldForCP( m_main, cp );
150             break;
151         case Parser::Footnote:
152             return fldForCP( m_footnote, cp );
153             break;
154         case Parser::Header:
155             return fldForCP( m_header, cp );
156             break;
157         case Parser::Macro:
158             wvlog << "Warning: There shouldn't be any fields in macro text" << endl;
159             return 0;
160             break;
161         case Parser::Annotation:
162             return fldForCP( m_annotation, cp );
163             break;
164         case Parser::Endnote:
165             return fldForCP( m_endnote, cp );
166             break;
167         case Parser::TextBox:
168             return fldForCP( m_textbox, cp );
169             break;
170         case Parser::HeaderTextBox:
171             return fldForCP( m_headerTextbox, cp );
172             break;
173         case Parser::Bookmark:
174             return fldForCP( m_bookmark, cp );
175             break;
176     }
177     return 0; // make the compiler happy, never reached
178 }
179 
read(U32 fc,U32 lcb,OLEStreamReader * tableStream,PLCFMap<FLD> ** plcf)180 void Fields::read( U32 fc, U32 lcb, OLEStreamReader* tableStream, PLCFMap<FLD>** plcf )
181 {
182     if ( lcb == 0 )
183         return;
184     tableStream->seek( fc, WV2_SEEK_SET );
185     *plcf = new PLCFMap<FLD>( lcb, tableStream );
186 }
187 
sanityCheck(const OLEStreamReader * tableStream,U32 nextFC,U32 lcb) const188 void Fields::sanityCheck( const OLEStreamReader* tableStream, U32 nextFC, U32 lcb ) const
189 {
190     if ( lcb != 0 && static_cast<U32>( tableStream->tell() ) != nextFC )
191         wvlog << "Warning: Detected a hole within the table stream (next fc=" << nextFC << ")" << endl;
192 }
193 
fldForCP(const PLCFMap<FLD> * plcf,U32 cp) const194 const FLD* Fields::fldForCP( const PLCFMap<FLD>* plcf, U32 cp ) const
195 {
196     if ( !plcf )
197         return 0;
198 
199     return plcf->item( cp );
200 }
201