1 /* This file is part of the wvWare 2 project 2 Copyright (C) 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., 59 Temple Place - Suite 330, 16 Boston, MA 02111-1307, USA. 17 */ 18 19 #include "word_helper.h" 20 #include "olestream.h" 21 #include "textconverter.h" 22 #include "ustring.h" 23 24 namespace wvWare 25 { 26 STTBF(U16 lid,OLEStreamReader * reader,bool preservePos)27 STTBF::STTBF( U16 lid, OLEStreamReader* reader, bool preservePos ) 28 { 29 if ( preservePos ) 30 reader->push(); 31 init( lid, reader, 0 ); 32 if ( preservePos ) 33 reader->pop(); 34 } 35 STTBF(U16 lid,const U8 * ptr)36 STTBF::STTBF( U16 lid, const U8* ptr ) 37 { 38 init( lid, 0, ptr ); 39 } 40 STTBF(const STTBF & rhs)41 STTBF::STTBF( const STTBF& rhs ) : m_strings( rhs.m_strings ), m_extraDataLength( rhs.m_extraDataLength ) 42 { 43 std::vector<U8*>::const_iterator it = rhs.m_extraData.begin(); 44 std::vector<U8*>::const_iterator end = rhs.m_extraData.end(); 45 for ( ; it != end; ++it ) { 46 U8* tmp = new U8[ m_extraDataLength ]; 47 memcpy( tmp, *it, m_extraDataLength ); 48 m_extraData.push_back( tmp ); 49 } 50 } 51 ~STTBF()52 STTBF::~STTBF() 53 { 54 std::vector<U8*>::const_iterator it = m_extraData.begin(); 55 for ( ; it != m_extraData.end(); ++it ) 56 delete [] *it; 57 } 58 count() const59 unsigned int STTBF::count() const 60 { 61 return m_strings.size(); 62 } 63 firstString() const64 UString STTBF::firstString() const 65 { 66 m_stringIt = m_strings.begin(); 67 if ( m_stringIt != m_strings.end() ) 68 return *m_stringIt; 69 return UString::null; 70 } 71 nextString() const72 UString STTBF::nextString() const 73 { 74 if ( m_stringIt == m_strings.end() ) 75 return UString::null; 76 ++m_stringIt; 77 if ( m_stringIt != m_strings.end() ) 78 return *m_stringIt; 79 return UString::null; 80 } 81 prevString() const82 UString STTBF::prevString() const 83 { 84 if ( m_strings.size() == 0 ) 85 return UString::null; 86 if ( m_stringIt != m_strings.begin() ) 87 --m_stringIt; 88 return *m_stringIt; 89 } 90 lastString() const91 UString STTBF::lastString() const 92 { 93 m_stringIt = m_strings.end(); 94 if ( m_stringIt == m_strings.begin() ) 95 return UString::null; 96 --m_stringIt; 97 return *m_stringIt; 98 } 99 stringAt(unsigned int index) const100 UString STTBF::stringAt( unsigned int index ) const 101 { 102 if ( index < m_strings.size() ) 103 return m_strings[ index ]; 104 return UString::null; 105 } 106 firstExtra() const107 const U8* STTBF::firstExtra() const 108 { 109 m_extraIt = m_extraData.begin(); 110 if ( m_extraIt != m_extraData.end() ) 111 return *m_extraIt; 112 return 0; 113 } 114 nextExtra() const115 const U8* STTBF::nextExtra() const 116 { 117 if ( m_extraIt == m_extraData.end() ) 118 return 0; 119 ++m_extraIt; 120 if ( m_extraIt != m_extraData.end() ) 121 return *m_extraIt; 122 return 0; 123 } 124 prevExtra() const125 const U8* STTBF::prevExtra() const 126 { 127 if ( m_extraData.size() == 0 ) 128 return 0; 129 if ( m_extraIt != m_extraData.begin() ) 130 --m_extraIt; 131 return *m_extraIt; 132 } 133 lastExtra() const134 const U8* STTBF::lastExtra() const 135 { 136 m_extraIt = m_extraData.end(); 137 if ( m_extraIt == m_extraData.begin() ) 138 return 0; 139 --m_extraIt; 140 return *m_extraIt; 141 } 142 extraAt(unsigned int index) const143 const U8* STTBF::extraAt( unsigned int index ) const 144 { 145 if ( index < m_extraData.size() ) 146 return m_extraData[ index ]; 147 return 0; 148 } 149 dumpStrings() const150 void STTBF::dumpStrings() const 151 { 152 wvlog << "STTBF::dumpStrings(): count=" << count() << " extraDataLength=" 153 << extraDataLength() << std::endl; 154 std::vector<UString>::const_iterator it = m_strings.begin(); 155 std::vector<UString>::const_iterator end = m_strings.end(); 156 for ( ; it != end; ++it ) 157 wvlog << " '" << ( *it ).ascii() << "'" << std::endl; 158 } 159 init(U16 lid,OLEStreamReader * reader,const U8 * ptr)160 void STTBF::init( U16 lid, OLEStreamReader* reader, const U8* ptr ) 161 { 162 bool extended = false; 163 U16 count = readU16( reader, &ptr ); 164 // "extended" characters? 165 if ( count == 0xffff ) { 166 extended = true; 167 // read the real size 168 count = readU16( reader, &ptr ); 169 } 170 m_extraDataLength = readU16( reader, &ptr ); 171 172 // If we don't read unicode strings we have to set up a text converter 173 TextConverter* textconverter = 0; 174 if ( !extended ) 175 textconverter = new TextConverter( lid ); 176 177 // read one string after the other 178 for ( U16 i = 0; i < count; ++i ) { 179 U16 len = 0; 180 if ( extended ) // double byte count! 181 len = readU16( reader, &ptr ); 182 else 183 len = readU8( reader, &ptr ); 184 185 if ( len != 0 ) { 186 if ( extended ) { 187 XCHAR* string = new XCHAR[ len ]; 188 for ( U16 j = 0; j < len; ++j ) 189 string[ j ] = readU16( reader, &ptr ); 190 UString ustring( reinterpret_cast<const wvWare::UChar *>( string ), len ); 191 delete [] string; 192 m_strings.push_back( ustring ); 193 } 194 else { 195 U8* string = new U8[ len ]; 196 read( reader, &ptr, string, len ); 197 UString ustring( textconverter->convert( reinterpret_cast<char*>( string ), 198 static_cast<unsigned int>( len ) ) ); 199 delete [] string; 200 m_strings.push_back( ustring ); 201 } 202 } 203 else 204 m_strings.push_back( UString("") ); 205 if ( m_extraDataLength != 0 ) { 206 U8* extra = new U8[ m_extraDataLength ]; 207 read( reader, &ptr, extra, m_extraDataLength ); 208 m_extraData.push_back( extra ); 209 } 210 } 211 delete textconverter; 212 } 213 readU16(OLEStreamReader * reader,const U8 ** ptr) const214 U16 STTBF::readU16( OLEStreamReader* reader, const U8** ptr ) const 215 { 216 if ( reader ) 217 return reader->readU16(); 218 else if ( *ptr ) { 219 U16 ret = wvWare::readU16( *ptr ); 220 *ptr += 2; 221 return ret; 222 } 223 else { 224 wvlog << "Warning: Internal error while reading STTBF" << std::endl; 225 return 0; 226 } 227 } 228 readU8(OLEStreamReader * reader,const U8 ** ptr) const229 U8 STTBF::readU8( OLEStreamReader* reader, const U8** ptr ) const 230 { 231 if ( reader ) 232 return reader->readU8(); 233 else if ( *ptr ) { 234 U8 ret = **ptr; 235 *ptr += 1; 236 return ret; 237 } 238 else { 239 wvlog << "Warning: Internal error while reading STTBF" << std::endl; 240 return 0; 241 } 242 } 243 read(OLEStreamReader * reader,const U8 ** ptr,U8 * buffer,size_t length) const244 bool STTBF::read( OLEStreamReader* reader, const U8** ptr, U8* buffer, size_t length ) const 245 { 246 if ( reader ) 247 return reader->read( buffer, length ); 248 else if ( *ptr ) { 249 memcpy( buffer, *ptr, length ); 250 *ptr += length; 251 return true; 252 } 253 else { 254 wvlog << "Warning: Internal error while reading STTBF" << std::endl; 255 return false; 256 } 257 } 258 259 CHPFKP_BX()260 CHPFKP_BX::CHPFKP_BX() 261 { 262 clear(); 263 } 264 CHPFKP_BX(OLEStreamReader * stream,bool preservePos)265 CHPFKP_BX::CHPFKP_BX( OLEStreamReader* stream, bool preservePos ) 266 { 267 clear(); 268 read( stream, preservePos ); 269 } 270 CHPFKP_BX(const U8 * ptr)271 CHPFKP_BX::CHPFKP_BX( const U8* ptr ) 272 { 273 clear(); 274 readPtr( ptr ); 275 } 276 read(OLEStreamReader * stream,bool preservePos)277 bool CHPFKP_BX::read( OLEStreamReader* stream, bool preservePos ) 278 { 279 if ( preservePos ) 280 stream->push(); 281 offset = stream->readU8(); 282 if ( preservePos ) 283 stream->pop(); 284 return true; 285 } 286 readPtr(const U8 * ptr)287 void CHPFKP_BX::readPtr( const U8* ptr ) 288 { 289 offset = *ptr; 290 } 291 write(OLEStreamWriter * stream,bool preservePos) const292 bool CHPFKP_BX::write( OLEStreamWriter* stream, bool preservePos ) const 293 { 294 if ( preservePos ) 295 stream->push(); 296 stream->write( offset ); 297 if ( preservePos ) 298 stream->pop(); 299 return true; 300 } 301 clear()302 void CHPFKP_BX::clear() 303 { 304 offset = 0; 305 } 306 operator ==(const CHPFKP_BX & lhs,const CHPFKP_BX & rhs)307 bool operator==( const CHPFKP_BX& lhs, const CHPFKP_BX& rhs ) 308 { 309 return lhs.offset == rhs.offset; 310 } 311 operator !=(const CHPFKP_BX & lhs,const CHPFKP_BX & rhs)312 bool operator!=( const CHPFKP_BX& lhs, const CHPFKP_BX& rhs ) 313 { 314 return !( lhs == rhs ); 315 } 316 317 const unsigned int CHPFKP_BX::sizeOf = 1; 318 319 } // namespace wvWare 320