xref: /aoo41x/main/tools/source/stream/stream.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_tools.hxx"
30 
31 // ToDo:
32 //  - Read->RefreshBuffer->Auf Aenderungen von nBufActualLen reagieren
33 
34 #include <cstddef>
35 
36 #include <string.h>
37 #include <stdio.h>
38 #include <ctype.h>  // isspace
39 #include <stdlib.h> // strtol, _crotl
40 
41 #include "boost/static_assert.hpp"
42 
43 /*
44 #if defined( DBG_UTIL ) && (OSL_DEBUG_LEVEL > 1)
45 // prueft Synchronisation des Buffers nach allen Read, Write, Seek
46 #define OV_DEBUG
47 #endif
48 */
49 
50 #include <tools/solar.h>
51 
52 #if defined(BLC)
53 #define SWAPNIBBLES(c) c=_crotl(c,4);
54 #else
55 #define SWAPNIBBLES(c)      \
56 unsigned char nSwapTmp=c;   \
57 nSwapTmp <<= 4;             \
58 c >>= 4;                    \
59 c |= nSwapTmp;
60 #endif
61 
62 #include <tools/debug.hxx>
63 #define ENABLE_BYTESTRING_STREAM_OPERATORS
64 #include <tools/stream.hxx>
65 #include <osl/thread.h>
66 #include <algorithm>
67 
68 // -----------------------------------------------------------------------
69 
70 DBG_NAME( Stream )
71 
72 // -----------------------------------------------------------------------
73 
74 // sprintf Param-Mode
75 #define SPECIAL_PARAM_NONE 0        // Format-Str, Number
76 #define SPECIAL_PARAM_WIDTH 1       // Format-Str, Width, Number
77 #define SPECIAL_PARAM_PRECISION 2   // Format-Str, Precision, Number
78 #define SPECIAL_PARAM_BOTH 3        // Format-Str, Width, Precision, Number
79 
80 // -----------------------------------------------------------------------
81 
82 // !!! Nicht inline, wenn Operatoren <<,>> inline sind
83 inline static void SwapUShort( sal_uInt16& r )
84     {   r = SWAPSHORT(r);   }
85 inline static void SwapShort( short& r )
86     {   r = SWAPSHORT(r);   }
87 inline static void SwapLong( long& r )
88     {   r = SWAPLONG(r);   }
89 inline static void SwapULong( sal_uInt32& r )
90     {   r = SWAPLONG(r);   }
91 inline static void SwapLongInt( int& r )
92     {   r = SWAPLONG(r);   }
93 inline static void SwapLongUInt( unsigned int& r )
94     {   r = SWAPLONG(r);   }
95 #ifdef UNX
96 inline static void SwapFloat( float& r )
97     {
98 		*((sal_uInt32*)(void*)&r) = SWAPLONG( *((sal_uInt32*)(void*)&r) );
99     }
100 inline static void SwapDouble( double& r )
101     {
102         if( sizeof(double) != 8 )
103         {
104           DBG_ASSERT( sal_False, "Can only swap 8-Byte-doubles\n" );
105         }
106         else
107         {
108           sal_uInt32* c = (sal_uInt32*)(void*)&r;
109           c[0] ^= c[1]; // zwei 32-Bit-Werte in situ vertauschen
110           c[1] ^= c[0];
111           c[0] ^= c[1];
112           c[0] = SWAPLONG(c[0]); // und die beiden 32-Bit-Werte selbst in situ drehen
113           c[1] = SWAPLONG(c[1]);
114         }
115     }
116 #endif
117 
118 //SDO
119 
120 #define READNUMBER_WITHOUT_SWAP(datatype,value) \
121 {\
122 int tmp = eIOMode; \
123 if( (tmp == STREAM_IO_READ) && sizeof(datatype)<=nBufFree) \
124 {\
125     for (std::size_t i = 0; i < sizeof(datatype); i++)\
126         ((char *)&value)[i] = pBufPos[i];\
127     nBufActualPos += sizeof(datatype);\
128     pBufPos += sizeof(datatype);\
129     nBufFree -= sizeof(datatype);\
130 }\
131 else\
132     Read( (char*)&value, sizeof(datatype) );\
133 }
134 
135 #define WRITENUMBER_WITHOUT_SWAP(datatype,value) \
136 {\
137 int tmp = eIOMode; \
138 if( (tmp==STREAM_IO_WRITE) && sizeof(datatype) <= nBufFree)\
139 {\
140     for (std::size_t i = 0; i < sizeof(datatype); i++)\
141         pBufPos[i] = ((char *)&value)[i];\
142     nBufFree -= sizeof(datatype);\
143     nBufActualPos += sizeof(datatype);\
144     if( nBufActualPos > nBufActualLen )\
145         nBufActualLen = nBufActualPos;\
146     pBufPos += sizeof(datatype);\
147     bIsDirty = sal_True;\
148 }\
149 else\
150     Write( (char*)&value, sizeof(datatype) );\
151 }
152 
153 //============================================================================
154 //
155 //  class SvLockBytes
156 //
157 //============================================================================
158 
159 void SvLockBytes::close()
160 {
161     if (m_bOwner)
162         delete m_pStream;
163     m_pStream = 0;
164 }
165 
166 //============================================================================
167 TYPEINIT0(SvLockBytes);
168 
169 //============================================================================
170 // virtual
171 ErrCode SvLockBytes::ReadAt(sal_Size nPos, void * pBuffer, sal_Size nCount,
172                             sal_Size * pRead) const
173 {
174     if (!m_pStream)
175     {
176         DBG_ERROR("SvLockBytes::ReadAt(): Bad stream");
177         return ERRCODE_NONE;
178     }
179 
180     m_pStream->Seek(nPos);
181     sal_Size nTheRead = m_pStream->Read(pBuffer, nCount);
182     if (pRead)
183         *pRead = nTheRead;
184     return m_pStream->GetErrorCode();
185 }
186 
187 //============================================================================
188 // virtual
189 ErrCode SvLockBytes::WriteAt(sal_Size nPos, const void * pBuffer, sal_Size nCount,
190                              sal_Size * pWritten)
191 {
192     if (!m_pStream)
193     {
194         DBG_ERROR("SvLockBytes::WriteAt(): Bad stream");
195         return ERRCODE_NONE;
196     }
197 
198     m_pStream->Seek(nPos);
199     sal_Size nTheWritten = m_pStream->Write(pBuffer, nCount);
200     if (pWritten)
201         *pWritten = nTheWritten;
202     return m_pStream->GetErrorCode();
203 }
204 
205 //============================================================================
206 // virtual
207 ErrCode SvLockBytes::Flush() const
208 {
209     if (!m_pStream)
210     {
211         DBG_ERROR("SvLockBytes::Flush(): Bad stream");
212         return ERRCODE_NONE;
213     }
214 
215     m_pStream->Flush();
216     return m_pStream->GetErrorCode();
217 }
218 
219 //============================================================================
220 // virtual
221 ErrCode SvLockBytes::SetSize(sal_Size nSize)
222 {
223     if (!m_pStream)
224     {
225         DBG_ERROR("SvLockBytes::SetSize(): Bad stream");
226         return ERRCODE_NONE;
227     }
228 
229     m_pStream->SetStreamSize(nSize);
230     return m_pStream->GetErrorCode();
231 }
232 
233 //============================================================================
234 ErrCode SvLockBytes::LockRegion(sal_Size, sal_Size, LockType)
235 {
236     DBG_ERROR("SvLockBytes::LockRegion(): Not implemented");
237     return ERRCODE_NONE;
238 }
239 
240 //============================================================================
241 
242 ErrCode SvLockBytes::UnlockRegion(sal_Size, sal_Size, LockType)
243 {
244     DBG_ERROR("SvLockBytes::UnlockRegion(): Not implemented");
245     return ERRCODE_NONE;
246 }
247 
248 //============================================================================
249 ErrCode SvLockBytes::Stat(SvLockBytesStat * pStat, SvLockBytesStatFlag) const
250 {
251     if (!m_pStream)
252     {
253         DBG_ERROR("SvLockBytes::Stat(): Bad stream");
254         return ERRCODE_NONE;
255     }
256 
257     if (pStat)
258     {
259         sal_Size nPos = m_pStream->Tell();
260         pStat->nSize = m_pStream->Seek(STREAM_SEEK_TO_END);
261         m_pStream->Seek(nPos);
262     }
263     return ERRCODE_NONE;
264 }
265 
266 //============================================================================
267 //
268 //  class SvOpenLockBytes
269 //
270 //============================================================================
271 
272 TYPEINIT1(SvOpenLockBytes, SvLockBytes);
273 
274 //============================================================================
275 //
276 //  class SvAsyncLockBytes
277 //
278 //============================================================================
279 
280 TYPEINIT1(SvAsyncLockBytes, SvOpenLockBytes);
281 
282 //============================================================================
283 // virtual
284 ErrCode SvAsyncLockBytes::ReadAt(sal_Size nPos, void * pBuffer, sal_Size nCount,
285                                  sal_Size * pRead) const
286 {
287     if (m_bTerminated)
288         return SvOpenLockBytes::ReadAt(nPos, pBuffer, nCount, pRead);
289     else
290     {
291         sal_Size nTheCount = std::min(nPos < m_nSize ? m_nSize - nPos : 0, nCount);
292         ErrCode nError = SvOpenLockBytes::ReadAt(nPos, pBuffer, nTheCount,
293                                                  pRead);
294         return !nCount || nTheCount == nCount || nError ? nError :
295                                                           ERRCODE_IO_PENDING;
296     }
297 }
298 
299 //============================================================================
300 // virtual
301 ErrCode SvAsyncLockBytes::WriteAt(sal_Size nPos, const void * pBuffer,
302                                   sal_Size nCount, sal_Size * pWritten)
303 {
304     if (m_bTerminated)
305         return SvOpenLockBytes::WriteAt(nPos, pBuffer, nCount, pWritten);
306     else
307     {
308         sal_Size nTheCount = std::min(nPos < m_nSize ? m_nSize - nPos : 0, nCount);
309         ErrCode nError = SvOpenLockBytes::WriteAt(nPos, pBuffer, nTheCount,
310                                                   pWritten);
311         return !nCount || nTheCount == nCount || nError ? nError :
312                                                           ERRCODE_IO_PENDING;
313     }
314 }
315 
316 //============================================================================
317 // virtual
318 ErrCode SvAsyncLockBytes::FillAppend(const void * pBuffer, sal_Size nCount,
319                                      sal_Size * pWritten)
320 {
321     sal_Size nTheWritten;
322     ErrCode nError = SvOpenLockBytes::WriteAt(m_nSize, pBuffer, nCount,
323                                               &nTheWritten);
324     if (!nError)
325         m_nSize += nTheWritten;
326     if (pWritten)
327         *pWritten = nTheWritten;
328     return nError;
329 }
330 
331 //============================================================================
332 // virtual
333 sal_Size SvAsyncLockBytes::Seek(sal_Size nPos)
334 {
335     if (nPos != STREAM_SEEK_TO_END)
336         m_nSize = nPos;
337     return m_nSize;
338 }
339 
340 //============================================================================
341 //
342 //  class SvStream
343 //
344 //============================================================================
345 
346 sal_Size SvStream::GetData( void* pData, sal_Size nSize )
347 {
348     if( !GetError() )
349     {
350         DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
351         sal_Size nRet;
352         nError = xLockBytes->ReadAt( nActPos, pData, nSize, &nRet );
353         nActPos += nRet;
354         return nRet;
355     }
356     else return 0;
357 }
358 
359 ErrCode SvStream::SetLockBytes( SvLockBytesRef& rLB )
360 {
361     xLockBytes = rLB;
362     RefreshBuffer();
363     return ERRCODE_NONE;
364 }
365 
366 //========================================================================
367 
368 sal_Size SvStream::PutData( const void* pData, sal_Size nSize )
369 {
370     if( !GetError() )
371     {
372         DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
373         sal_Size nRet;
374         nError = xLockBytes->WriteAt( nActPos, pData, nSize, &nRet );
375         nActPos += nRet;
376         return nRet;
377     }
378     else return 0;
379 }
380 
381 //========================================================================
382 
383 sal_Size SvStream::SeekPos( sal_Size nPos )
384 {
385     if( !GetError() && nPos == STREAM_SEEK_TO_END )
386     {
387         DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
388         SvLockBytesStat aStat;
389         xLockBytes->Stat( &aStat, SVSTATFLAG_DEFAULT );
390         nActPos = aStat.nSize;
391     }
392     else
393         nActPos = nPos;
394     return nActPos;
395 }
396 
397 //========================================================================
398 
399 void SvStream::FlushData()
400 {
401     if( !GetError() )
402     {
403         DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
404         nError = xLockBytes->Flush();
405     }
406 }
407 
408 //========================================================================
409 
410 void SvStream::SetSize( sal_Size nSize )
411 {
412     DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
413     nError = xLockBytes->SetSize( nSize );
414 }
415 
416 void SvStream::ImpInit()
417 {
418     nActPos             = 0;
419     nCompressMode       = COMPRESSMODE_NONE;
420     eStreamCharSet      = osl_getThreadTextEncoding();
421 //  eTargetCharSet      = osl_getThreadTextEncoding();
422     nCryptMask          = 0;
423     bIsEof              = sal_False;
424 #if defined UNX
425     eLineDelimiter      = LINEEND_LF;   // UNIX-Format
426 #else
427     eLineDelimiter      = LINEEND_CRLF; // DOS-Format
428 #endif
429 
430     SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
431 
432     nBufFilePos         = 0;
433     nBufActualPos       = 0;
434     bIsDirty            = sal_False;
435     bIsConsistent       = sal_True;
436     bIsWritable         = sal_True;
437 
438     pRWBuf              = 0;
439     pBufPos             = 0;
440     nBufSize            = 0;
441     nBufActualLen       = 0;
442     eIOMode             = STREAM_IO_DONTKNOW;
443     nBufFree            = 0;
444 
445     nRadix              = 10;
446     nPrecision          = 0;  // all significant digits
447     nWidth              = 0; // default width
448     cFiller             = ' ';
449     nJustification      = JUSTIFY_RIGHT;
450     eStreamMode         = 0;
451     CreateFormatString();
452 
453     nVersion           = 0;
454 
455     ClearError();
456 }
457 
458 /*************************************************************************
459 |*
460 |*    Stream::Stream()
461 |*
462 |*    Beschreibung      STREAM.SDW
463 |*    Ersterstellung    OV 08.06.94
464 |*    Letzte Aenderung  OV 08.06.94
465 |*
466 *************************************************************************/
467 
468 SvStream::SvStream( SvLockBytes* pLockBytesP )
469 {
470     DBG_CTOR( Stream, NULL );
471 
472     ImpInit();
473     xLockBytes = pLockBytesP;
474     const SvStream* pStrm;
475     if( pLockBytesP ) {
476         pStrm = pLockBytesP->GetStream();
477         if( pStrm ) {
478             SetError( pStrm->GetErrorCode() );
479         }
480     }
481     SetBufferSize( 256 );
482 }
483 
484 SvStream::SvStream()
485 {
486     DBG_CTOR( Stream, NULL );
487 
488     ImpInit();
489 }
490 
491 /*************************************************************************
492 |*
493 |*    Stream::~Stream()
494 |*
495 |*    Beschreibung      STREAM.SDW
496 |*    Ersterstellung    OV 08.06.94
497 |*    Letzte Aenderung  OV 08.06.94
498 |*
499 *************************************************************************/
500 
501 SvStream::~SvStream()
502 {
503     DBG_DTOR( Stream, NULL );
504 
505     if ( xLockBytes.Is() )
506         Flush();
507 
508     if( pRWBuf )
509         delete[] pRWBuf;
510 }
511 
512 /*************************************************************************
513 |*
514 |*    Stream::IsA()
515 |*
516 |*    Beschreibung      STREAM.SDW
517 |*    Ersterstellung    OV 08.06.94
518 |*    Letzte Aenderung  OV 08.06.94
519 |*
520 *************************************************************************/
521 
522 sal_uInt16 SvStream::IsA() const
523 {
524     return (sal_uInt16)ID_STREAM;
525 }
526 
527 /*************************************************************************
528 |*
529 |*    Stream::ClearError()
530 |*
531 |*    Beschreibung      STREAM.SDW
532 |*    Ersterstellung    OV 08.06.94
533 |*    Letzte Aenderung  OV 08.06.94
534 |*
535 *************************************************************************/
536 
537 void SvStream::ClearError()
538 {
539     bIsEof = sal_False;
540     nError = SVSTREAM_OK;
541 }
542 
543 /*************************************************************************
544 |*
545 |*    Stream::SetError()
546 |*
547 |*    Beschreibung      STREAM.SDW
548 |*    Ersterstellung    OV 08.06.94
549 |*    Letzte Aenderung  OV 08.06.94
550 |*
551 *************************************************************************/
552 
553 void SvStream::SetError( sal_uInt32 nErrorCode )
554 {
555     if ( nError == SVSTREAM_OK )
556         nError = nErrorCode;
557 }
558 
559 
560 /*************************************************************************
561 |*
562 |*    Stream::SetNumberFormatInt()
563 |*
564 |*    Beschreibung      STREAM.SDW
565 |*    Ersterstellung    OV 08.06.94
566 |*    Letzte Aenderung  OV 08.06.94
567 |*
568 *************************************************************************/
569 
570 void SvStream::SetNumberFormatInt( sal_uInt16 nNewFormat )
571 {
572     nNumberFormatInt = nNewFormat;
573     bSwap = sal_False;
574 #ifdef OSL_BIGENDIAN
575     if( nNumberFormatInt == NUMBERFORMAT_INT_LITTLEENDIAN )
576         bSwap = sal_True;
577 #else
578     if( nNumberFormatInt == NUMBERFORMAT_INT_BIGENDIAN )
579         bSwap = sal_True;
580 #endif
581 }
582 
583 /*************************************************************************
584 |*
585 |*    Stream::SetBufferSize()
586 |*
587 |*    Beschreibung      STREAM.SDW
588 |*    Ersterstellung    OV 08.06.94
589 |*    Letzte Aenderung  OV 08.06.94
590 |*
591 *************************************************************************/
592 
593 void SvStream::SetBufferSize( sal_uInt16 nBufferSize )
594 {
595     sal_Size nActualFilePos = Tell();
596     sal_Bool bDontSeek = (sal_Bool)(pRWBuf == 0);
597 
598     if( bIsDirty && bIsConsistent && bIsWritable )  // wg. Windows NT: Access denied
599         Flush();
600 
601     if( nBufSize )
602     {
603         delete[] pRWBuf;
604         nBufFilePos += nBufActualPos;
605     }
606 
607     pRWBuf          = 0;
608     nBufActualLen   = 0;
609     nBufActualPos   = 0;
610     nBufSize        = nBufferSize;
611     if( nBufSize )
612         pRWBuf = new sal_uInt8[ nBufSize ];
613     bIsConsistent   = sal_True;
614     pBufPos         = pRWBuf;
615     eIOMode = STREAM_IO_DONTKNOW;
616     if( !bDontSeek )
617         SeekPos( nActualFilePos );
618 }
619 
620 /*************************************************************************
621 |*
622 |*    Stream::ClearBuffer()
623 |*
624 |*    Beschreibung      STREAM.SDW
625 |*    Ersterstellung    OV 08.06.94
626 |*    Letzte Aenderung  OV 08.06.94
627 |*
628 *************************************************************************/
629 
630 void SvStream::ClearBuffer()
631 {
632     nBufActualLen   = 0;
633     nBufActualPos   = 0;
634     nBufFilePos     = 0;
635     pBufPos         = pRWBuf;
636     bIsDirty        = sal_False;
637     bIsConsistent   = sal_True;
638     eIOMode         = STREAM_IO_DONTKNOW;
639 
640     bIsEof          = sal_False;
641 }
642 
643 /*************************************************************************
644 |*
645 |*    Stream::ResetError()
646 |*
647 |*    Beschreibung      STREAM.SDW
648 |*    Ersterstellung    OV 08.06.94
649 |*    Letzte Aenderung  OV 08.06.94
650 |*
651 *************************************************************************/
652 
653 void SvStream::ResetError()
654 {
655     ClearError();
656 }
657 
658 /*************************************************************************
659 |*
660 |*    Stream::ReadLine()
661 |*
662 |*    Beschreibung      STREAM.SDW
663 |*    Ersterstellung    OV 08.06.94
664 |*    Letzte Aenderung  OV 08.06.94
665 |*
666 *************************************************************************/
667 
668 sal_Bool SvStream::ReadByteStringLine( String& rStr, rtl_TextEncoding eSrcCharSet )
669 {
670     sal_Bool bRet;
671     ByteString aStr;
672 
673     bRet = ReadLine(aStr);
674     rStr = UniString( aStr, eSrcCharSet );
675     return bRet;
676 }
677 
678 sal_Bool SvStream::ReadLine( ByteString& rStr )
679 {
680     sal_Char    buf[256+1];
681     sal_Bool        bEnd        = sal_False;
682     sal_Size       nOldFilePos = Tell();
683     sal_Char    c           = 0;
684     sal_Size       nTotalLen   = 0;
685 
686     rStr.Erase();
687     while( !bEnd && !GetError() )   // !!! nicht auf EOF testen,
688                                     // !!! weil wir blockweise
689                                     // !!! lesen
690     {
691         sal_uInt16 nLen = (sal_uInt16)Read( buf, sizeof(buf)-1 );
692         if ( !nLen )
693         {
694             if ( rStr.Len() == 0 )
695             {
696                 // der allererste Blockread hat fehlgeschlagen -> Abflug
697                 bIsEof = sal_True;
698                 return sal_False;
699             }
700             else
701                 break;
702         }
703 
704         sal_uInt16 j, n;
705         for( j = n = 0; j < nLen ; ++j )
706         {
707             c = buf[j];
708             if ( c == '\n' || c == '\r' )
709             {
710                 bEnd = sal_True;
711                 break;
712             }
713             // erAck 26.02.01: Old behavior was no special treatment of '\0'
714             // character here, but a following rStr+=c did ignore it. Is this
715             // really intended? Or should a '\0' better terminate a line?
716             // The nOldFilePos stuff wasn't correct then anyways.
717             if ( c )
718             {
719                 if ( n < j )
720                     buf[n] = c;
721                 ++n;
722             }
723         }
724         if ( n )
725             rStr.Append( buf, n );
726         nTotalLen += j;
727     }
728 
729     if ( !bEnd && !GetError() && rStr.Len() )
730         bEnd = sal_True;
731 
732     nOldFilePos += nTotalLen;
733     if( Tell() > nOldFilePos )
734         nOldFilePos++;
735     Seek( nOldFilePos );  // seeken wg. obigem BlockRead!
736 
737     if ( bEnd && (c=='\r' || c=='\n') )  // Sonderbehandlung DOS-Dateien
738     {
739         char cTemp;
740         sal_Size nLen = Read((char*)&cTemp , sizeof(cTemp) );
741         if ( nLen ) {
742             if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
743                 Seek( nOldFilePos );
744         }
745     }
746 
747     if ( bEnd )
748         bIsEof = sal_False;
749     return bEnd;
750 }
751 
752 sal_Bool SvStream::ReadUniStringLine( String& rStr )
753 {
754     sal_Unicode buf[256+1];
755     sal_Bool        bEnd        = sal_False;
756     sal_Size       nOldFilePos = Tell();
757     sal_Unicode c           = 0;
758     sal_Size       nTotalLen   = 0;
759 
760     DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "ReadUniStringLine: swapping sizeof(sal_Unicode) not implemented" );
761 
762     rStr.Erase();
763     while( !bEnd && !GetError() )   // !!! nicht auf EOF testen,
764                                     // !!! weil wir blockweise
765                                     // !!! lesen
766     {
767         sal_uInt16 nLen = (sal_uInt16)Read( (char*)buf, sizeof(buf)-sizeof(sal_Unicode) );
768         nLen /= sizeof(sal_Unicode);
769         if ( !nLen )
770         {
771             if ( rStr.Len() == 0 )
772             {
773                 // der allererste Blockread hat fehlgeschlagen -> Abflug
774                 bIsEof = sal_True;
775                 return sal_False;
776             }
777             else
778                 break;
779         }
780 
781         sal_uInt16 j, n;
782         for( j = n = 0; j < nLen ; ++j )
783         {
784             if ( bSwap )
785                 SwapUShort( buf[n] );
786             c = buf[j];
787             if ( c == '\n' || c == '\r' )
788             {
789                 bEnd = sal_True;
790                 break;
791             }
792             // erAck 26.02.01: Old behavior was no special treatment of '\0'
793             // character here, but a following rStr+=c did ignore it. Is this
794             // really intended? Or should a '\0' better terminate a line?
795             // The nOldFilePos stuff wasn't correct then anyways.
796             if ( c )
797             {
798                 if ( n < j )
799                     buf[n] = c;
800                 ++n;
801             }
802         }
803         if ( n )
804             rStr.Append( buf, n );
805         nTotalLen += j;
806     }
807 
808     if ( !bEnd && !GetError() && rStr.Len() )
809         bEnd = sal_True;
810 
811     nOldFilePos += nTotalLen * sizeof(sal_Unicode);
812     if( Tell() > nOldFilePos )
813         nOldFilePos += sizeof(sal_Unicode);
814     Seek( nOldFilePos );  // seeken wg. obigem BlockRead!
815 
816     if ( bEnd && (c=='\r' || c=='\n') )  // Sonderbehandlung DOS-Dateien
817     {
818         sal_Unicode cTemp;
819         Read( (char*)&cTemp, sizeof(cTemp) );
820         if ( bSwap )
821             SwapUShort( cTemp );
822         if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
823             Seek( nOldFilePos );
824     }
825 
826     if ( bEnd )
827         bIsEof = sal_False;
828     return bEnd;
829 }
830 
831 sal_Bool SvStream::ReadUniOrByteStringLine( String& rStr, rtl_TextEncoding eSrcCharSet )
832 {
833     if ( eSrcCharSet == RTL_TEXTENCODING_UNICODE )
834         return ReadUniStringLine( rStr );
835     else
836         return ReadByteStringLine( rStr, eSrcCharSet );
837 }
838 
839 /*************************************************************************
840 |*
841 |*    Stream::ReadCString
842 |*
843 *************************************************************************/
844 
845 sal_Bool SvStream::ReadCString( ByteString& rStr )
846 {
847     if( rStr.Len() )
848         rStr.Erase();
849 
850     sal_Char buf[ 256 + 1 ];
851     sal_Bool bEnd = sal_False;
852     sal_Size nFilePos = Tell();
853 
854     while( !bEnd && !GetError() )
855     {
856         sal_uInt16 nLen = (sal_uInt16)Read( buf, sizeof(buf)-1 );
857 		sal_uInt16 nReallyRead = nLen;
858         if( !nLen )
859             break;
860 
861         const sal_Char* pPtr = buf;
862         while( *pPtr && nLen )
863             ++pPtr, --nLen;
864 
865         bEnd =	( nReallyRead < sizeof(buf)-1 )			// read less than attempted to read
866                 ||  (  ( nLen > 0 )                    // OR it is inside the block we read
867 					&&	( 0 == *pPtr )					//    AND found a string terminator
868                     );
869 
870         rStr.Append( buf, ::sal::static_int_cast< xub_StrLen >( pPtr - buf ) );
871     }
872 
873     nFilePos += rStr.Len();
874     if( Tell() > nFilePos )
875         nFilePos++;
876     Seek( nFilePos );  // seeken wg. obigem BlockRead!
877     return bEnd;
878 }
879 
880 sal_Bool SvStream::ReadCString( String& rStr, rtl_TextEncoding eToEncode )
881 {
882     ByteString sStr;
883     sal_Bool bRet = ReadCString( sStr );
884     rStr = String( sStr, eToEncode );
885     return bRet;
886 }
887 
888 
889 /*************************************************************************
890 |*
891 |*    Stream::WriteUnicodeText()
892 |*
893 *************************************************************************/
894 
895 sal_Bool SvStream::WriteUnicodeText( const String& rStr )
896 {
897     DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "WriteUnicodeText: swapping sizeof(sal_Unicode) not implemented" );
898     if ( bSwap )
899     {
900         xub_StrLen nLen = rStr.Len();
901         sal_Unicode aBuf[384];
902         sal_Unicode* const pTmp = ( nLen > 384 ? new sal_Unicode[nLen] : aBuf);
903         memcpy( pTmp, rStr.GetBuffer(), nLen * sizeof(sal_Unicode) );
904         sal_Unicode* p = pTmp;
905         const sal_Unicode* const pStop = pTmp + nLen;
906         while ( p < pStop )
907         {
908             SwapUShort( *p );
909             p++;
910         }
911         Write( (char*)pTmp, nLen * sizeof(sal_Unicode) );
912         if ( pTmp != aBuf )
913             delete [] pTmp;
914     }
915     else
916         Write( (char*)rStr.GetBuffer(), rStr.Len() * sizeof(sal_Unicode) );
917     return nError == SVSTREAM_OK;
918 }
919 
920 sal_Bool SvStream::WriteUnicodeOrByteText( const String& rStr, rtl_TextEncoding eDestCharSet )
921 {
922     if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
923         return WriteUnicodeText( rStr );
924     else
925     {
926         ByteString aStr( rStr, eDestCharSet );
927         Write( aStr.GetBuffer(), aStr.Len() );
928         return nError == SVSTREAM_OK;
929     }
930 }
931 
932 /*************************************************************************
933 |*
934 |*    Stream::WriteLine()
935 |*
936 |*    Beschreibung      STREAM.SDW
937 |*    Ersterstellung    OV 08.06.94
938 |*    Letzte Aenderung  OV 08.06.94
939 |*
940 *************************************************************************/
941 
942 sal_Bool SvStream::WriteByteStringLine( const String& rStr, rtl_TextEncoding eDestCharSet )
943 {
944     return WriteLine( ByteString( rStr, eDestCharSet ) );
945 }
946 
947 sal_Bool SvStream::WriteLine( const ByteString& rStr )
948 {
949     Write( rStr.GetBuffer(), rStr.Len() );
950     endl(*this);
951     return nError == SVSTREAM_OK;
952 }
953 
954 sal_Bool SvStream::WriteUniStringLine( const String& rStr )
955 {
956     WriteUnicodeText( rStr );
957     endlu(*this);
958     return nError == SVSTREAM_OK;
959 }
960 
961 sal_Bool SvStream::WriteUniOrByteStringLine( const String& rStr, rtl_TextEncoding eDestCharSet )
962 {
963     if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
964         return WriteUniStringLine( rStr );
965     else
966         return WriteByteStringLine( rStr, eDestCharSet );
967 }
968 
969 /*************************************************************************
970 |*
971 |*    Stream::WriteLines()
972 |*
973 |*    Beschreibung      STREAM.SDW
974 |*    Ersterstellung    OV 17.07.95
975 |*    Letzte Aenderung  OV 17.07.95
976 |*
977 *************************************************************************/
978 
979 sal_Bool SvStream::WriteByteStringLines( const String& rStr, rtl_TextEncoding eDestCharSet )
980 {
981     return WriteLines( ByteString( rStr, eDestCharSet ) );
982 }
983 
984 sal_Bool SvStream::WriteLines( const ByteString& rStr )
985 {
986     ByteString aStr( rStr );
987     aStr.ConvertLineEnd( eLineDelimiter );
988     Write( aStr.GetBuffer(), aStr.Len() );
989     endl( *this );
990     return (sal_Bool)(nError == SVSTREAM_OK);
991 }
992 
993 sal_Bool SvStream::WriteUniStringLines( const String& rStr )
994 {
995     String aStr( rStr );
996     aStr.ConvertLineEnd( eLineDelimiter );
997     WriteUniStringLine( aStr );
998     return nError == SVSTREAM_OK;
999 }
1000 
1001 sal_Bool SvStream::WriteUniOrByteStringLines( const String& rStr, rtl_TextEncoding eDestCharSet )
1002 {
1003     if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
1004         return WriteUniStringLines( rStr );
1005     else
1006         return WriteByteStringLines( rStr, eDestCharSet );
1007 }
1008 
1009 /*************************************************************************
1010 |*
1011 |*    Stream::WriteUniOrByteChar()
1012 |*
1013 *************************************************************************/
1014 
1015 sal_Bool SvStream::WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet )
1016 {
1017     if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
1018         *this << ch;
1019     else
1020     {
1021         ByteString aStr( ch, eDestCharSet );
1022         Write( aStr.GetBuffer(), aStr.Len() );
1023     }
1024     return nError == SVSTREAM_OK;
1025 }
1026 
1027 /*************************************************************************
1028 |*
1029 |*    Stream::StartWritingUnicodeText()
1030 |*
1031 *************************************************************************/
1032 
1033 sal_Bool SvStream::StartWritingUnicodeText()
1034 {
1035     SetEndianSwap( sal_False );     // write native format
1036     // BOM, Byte Order Mark, U+FEFF, see
1037     // http://www.unicode.org/faq/utf_bom.html#BOM
1038     // Upon read: 0xfeff(-257) => no swap; 0xfffe(-2) => swap
1039     *this << sal_uInt16( 0xfeff );
1040     return nError == SVSTREAM_OK;
1041 }
1042 
1043 /*************************************************************************
1044 |*
1045 |*    Stream::StartReadingUnicodeText()
1046 |*
1047 *************************************************************************/
1048 
1049 sal_Bool SvStream::StartReadingUnicodeText( rtl_TextEncoding eReadBomCharSet )
1050 {
1051     if (!(  eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
1052             eReadBomCharSet == RTL_TEXTENCODING_UNICODE ||
1053             eReadBomCharSet == RTL_TEXTENCODING_UTF8))
1054         return sal_True;    // nothing to read
1055 
1056     bool bTryUtf8 = false;
1057     sal_uInt16 nFlag;
1058     sal_sSize nBack = sizeof(nFlag);
1059     *this >> nFlag;
1060     switch ( nFlag )
1061     {
1062         case 0xfeff :
1063             // native UTF-16
1064             if (    eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
1065                     eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
1066                 nBack = 0;
1067         break;
1068         case 0xfffe :
1069             // swapped UTF-16
1070             if (    eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
1071                     eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
1072             {
1073                 SetEndianSwap( !bSwap );
1074                 nBack = 0;
1075             }
1076         break;
1077         case 0xefbb :
1078             if (nNumberFormatInt == NUMBERFORMAT_INT_BIGENDIAN &&
1079                     (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
1080                      eReadBomCharSet == RTL_TEXTENCODING_UTF8))
1081                 bTryUtf8 = true;
1082         break;
1083         case 0xbbef :
1084             if (nNumberFormatInt == NUMBERFORMAT_INT_LITTLEENDIAN &&
1085                     (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
1086                      eReadBomCharSet == RTL_TEXTENCODING_UTF8))
1087                 bTryUtf8 = true;
1088         break;
1089         default:
1090             ;   // nothing
1091     }
1092     if (bTryUtf8)
1093     {
1094         sal_uChar nChar;
1095         nBack += sizeof(nChar);
1096         *this >> nChar;
1097         if (nChar == 0xbf)
1098             nBack = 0;      // it is UTF-8
1099     }
1100     if (nBack)
1101         SeekRel( -nBack );      // no BOM, pure data
1102     return nError == SVSTREAM_OK;
1103 }
1104 
1105 /*************************************************************************
1106 |*
1107 |*    Stream::ReadCsvLine()
1108 |*
1109 *************************************************************************/
1110 
1111 // Precondition: pStr is guaranteed to be non-NULL and points to a 0-terminated
1112 // array.
1113 inline const sal_Unicode* lcl_UnicodeStrChr( const sal_Unicode* pStr,
1114         sal_Unicode c )
1115 {
1116     while (*pStr)
1117     {
1118         if (*pStr == c)
1119             return pStr;
1120         ++pStr;
1121     }
1122     return 0;
1123 }
1124 
1125 sal_Bool SvStream::ReadCsvLine( String& rStr, sal_Bool bEmbeddedLineBreak,
1126         const String& rFieldSeparators, sal_Unicode cFieldQuote,
1127         sal_Bool bAllowBackslashEscape)
1128 {
1129     ReadUniOrByteStringLine( rStr);
1130 
1131     if (bEmbeddedLineBreak)
1132     {
1133         const sal_Unicode* pSeps = rFieldSeparators.GetBuffer();
1134         xub_StrLen nLastOffset = 0;
1135         xub_StrLen nQuotes = 0;
1136         while (!IsEof() && rStr.Len() < STRING_MAXLEN)
1137         {
1138             bool bBackslashEscaped = false;
1139             const sal_Unicode *p, *pStart;
1140             p = pStart = rStr.GetBuffer();
1141             p += nLastOffset;
1142             while (*p)
1143             {
1144                 if (nQuotes)
1145                 {
1146                     if (*p == cFieldQuote && !bBackslashEscaped)
1147                         ++nQuotes;
1148                     else if (bAllowBackslashEscape)
1149                     {
1150                         if (*p == '\\')
1151                             bBackslashEscaped = !bBackslashEscaped;
1152                         else
1153                             bBackslashEscaped = false;
1154                     }
1155                 }
1156                 else if (*p == cFieldQuote && (p == pStart ||
1157                             lcl_UnicodeStrChr( pSeps, p[-1])))
1158                     nQuotes = 1;
1159                 // A quote character inside a field content does not start
1160                 // a quote.
1161                 ++p;
1162             }
1163 
1164             if (nQuotes % 2 == 0)
1165                 break;
1166             else
1167             {
1168                 nLastOffset = rStr.Len();
1169                 String aNext;
1170                 ReadUniOrByteStringLine( aNext);
1171                 rStr += sal_Unicode(_LF);
1172                 rStr += aNext;
1173             }
1174         }
1175     }
1176     return nError == SVSTREAM_OK;
1177 }
1178 
1179 /*************************************************************************
1180 |*
1181 |*    Stream::SeekRel()
1182 |*
1183 |*    Beschreibung      STREAM.SDW
1184 |*    Ersterstellung    OV 08.06.94
1185 |*    Letzte Aenderung  OV 08.06.94
1186 |*
1187 *************************************************************************/
1188 
1189 sal_Size SvStream::SeekRel( sal_sSize nPos )
1190 {
1191     sal_Size nActualPos = Tell();
1192 
1193 	if ( nPos >= 0 )
1194 	{
1195 		if ( SAL_MAX_SIZE - nActualPos > (sal_Size)nPos )
1196     		nActualPos += nPos;
1197 	}
1198 	else
1199 	{
1200 		sal_Size nAbsPos = (sal_Size)-nPos;
1201 		if ( nActualPos >= nAbsPos )
1202 			nActualPos -= nAbsPos;
1203 	}
1204 
1205     pBufPos = pRWBuf + nActualPos;
1206     return Seek( nActualPos );
1207 }
1208 
1209 /*************************************************************************
1210 |*
1211 |*    Stream::operator>>()
1212 |*
1213 |*    Beschreibung      STREAM.SDW
1214 |*    Ersterstellung    OV 08.06.94
1215 |*    Letzte Aenderung  OV 08.06.94
1216 |*
1217 *************************************************************************/
1218 
1219 SvStream& SvStream::operator >> ( sal_uInt16& r )
1220 {
1221     READNUMBER_WITHOUT_SWAP(sal_uInt16,r)
1222     if( bSwap )
1223         SwapUShort(r);
1224     return *this;
1225 }
1226 
1227 SvStream& SvStream::operator>> ( sal_uInt32& r )
1228 {
1229     READNUMBER_WITHOUT_SWAP(sal_uInt32,r)
1230     if( bSwap )
1231         SwapULong(r);
1232     return *this;
1233 }
1234 
1235 SvStream& SvStream::operator >> ( long& r )
1236 {
1237 #if(SAL_TYPES_SIZEOFLONG != 4)
1238     int tmp = r;
1239     *this >> tmp;
1240     r = tmp;
1241 #else
1242     READNUMBER_WITHOUT_SWAP(long,r)
1243     if( bSwap )
1244         SwapLong(r);
1245 #endif
1246     return *this;
1247 }
1248 
1249 SvStream& SvStream::operator >> ( short& r )
1250 {
1251     READNUMBER_WITHOUT_SWAP(short,r)
1252     if( bSwap )
1253         SwapShort(r);
1254     return *this;
1255 }
1256 
1257 SvStream& SvStream::operator >> ( int& r )
1258 {
1259     READNUMBER_WITHOUT_SWAP(int,r)
1260     if( bSwap )
1261         SwapLongInt(r);
1262     return *this;
1263 }
1264 
1265 SvStream& SvStream::operator>>( signed char& r )
1266 {
1267     if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
1268         sizeof(signed char) <= nBufFree )
1269     {
1270         r = *pBufPos;
1271         nBufActualPos += sizeof(signed char);
1272         pBufPos += sizeof(signed char);
1273         nBufFree -= sizeof(signed char);
1274     }
1275     else
1276         Read( (char*)&r, sizeof(signed char) );
1277     return *this;
1278 }
1279 
1280 // Sonderbehandlung fuer Chars wegen PutBack
1281 
1282 SvStream& SvStream::operator>>( char& r )
1283 {
1284     if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
1285         sizeof(char) <= nBufFree )
1286     {
1287         r = *pBufPos;
1288         nBufActualPos += sizeof(char);
1289         pBufPos += sizeof(char);
1290         nBufFree -= sizeof(char);
1291     }
1292     else
1293         Read( (char*)&r, sizeof(char) );
1294     return *this;
1295 }
1296 
1297 SvStream& SvStream::operator>>( unsigned char& r )
1298 {
1299     if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
1300         sizeof(char) <= nBufFree )
1301     {
1302         r = *pBufPos;
1303         nBufActualPos += sizeof(char);
1304         pBufPos += sizeof(char);
1305         nBufFree -= sizeof(char);
1306     }
1307     else
1308         Read( (char*)&r, sizeof(char) );
1309     return *this;
1310 }
1311 
1312 SvStream& SvStream::operator>>( float& r )
1313 {
1314     // Read( (char*)&r, sizeof(float) );
1315     READNUMBER_WITHOUT_SWAP(float,r)
1316 #if defined UNX
1317     if( bSwap )
1318       SwapFloat(r);
1319 #endif
1320     return *this;
1321 }
1322 
1323 SvStream& SvStream::operator>>( double& r )
1324 {
1325     // Read( (char*)&r, sizeof(double) );
1326     READNUMBER_WITHOUT_SWAP(double,r)
1327 #if defined UNX
1328     if( bSwap )
1329       SwapDouble(r);
1330 #endif
1331     return *this;
1332 }
1333 
1334 SvStream& SvStream::operator>> ( SvStream& rStream )
1335 {
1336     const sal_uInt32 cBufLen = 0x8000;
1337     char* pBuf = new char[ cBufLen ];
1338 
1339     sal_uInt32 nCount;
1340     do {
1341         nCount = Read( pBuf, cBufLen );
1342         rStream.Write( pBuf, nCount );
1343     } while( nCount == cBufLen );
1344 
1345     delete[] pBuf;
1346     return *this;
1347 }
1348 
1349 /*************************************************************************
1350 |*
1351 |*    Stream::operator<<()
1352 |*
1353 |*    Beschreibung      STREAM.SDW
1354 |*    Ersterstellung    OV 08.06.94
1355 |*    Letzte Aenderung  OV 08.06.94
1356 |*
1357 *************************************************************************/
1358 
1359 SvStream& SvStream::operator<< ( sal_uInt16 v )
1360 {
1361     if( bSwap )
1362         SwapUShort(v);
1363     WRITENUMBER_WITHOUT_SWAP(sal_uInt16,v)
1364     return *this;
1365 }
1366 
1367 SvStream& SvStream::operator<<  ( sal_uInt32 v )
1368 {
1369     if( bSwap )
1370         SwapULong(v);
1371     WRITENUMBER_WITHOUT_SWAP(sal_uInt32,v)
1372     return *this;
1373 }
1374 
1375 SvStream& SvStream::operator<< ( long v )
1376 {
1377 #if(SAL_TYPES_SIZEOFLONG != 4)
1378     int tmp = v;
1379     *this << tmp;
1380 #else
1381     if( bSwap )
1382         SwapLong(v);
1383     WRITENUMBER_WITHOUT_SWAP(long,v)
1384 #endif
1385     return *this;
1386 }
1387 
1388 SvStream& SvStream::operator<<  ( short v )
1389 {
1390     if( bSwap )
1391         SwapShort(v);
1392     WRITENUMBER_WITHOUT_SWAP(short,v)
1393     return *this;
1394 }
1395 
1396 SvStream& SvStream::operator<<( int v )
1397 {
1398     if( bSwap )
1399         SwapLongInt( v );
1400     WRITENUMBER_WITHOUT_SWAP(int,v)
1401     return *this;
1402 }
1403 
1404 SvStream& SvStream::operator<<  ( signed char v )
1405 {
1406     //SDO
1407     int tmp = eIOMode;
1408     if(tmp == STREAM_IO_WRITE && sizeof(signed char) <= nBufFree )
1409     {
1410         *pBufPos = v;
1411         pBufPos++; // sizeof(char);
1412         nBufActualPos++;
1413         if( nBufActualPos > nBufActualLen )  // Append ?
1414             nBufActualLen = nBufActualPos;
1415         nBufFree--; // = sizeof(char);
1416         bIsDirty = sal_True;
1417     }
1418     else
1419         Write( (char*)&v, sizeof(signed char) );
1420     return *this;
1421 }
1422 
1423 // Sonderbehandlung fuer chars wegen PutBack
1424 
1425 SvStream& SvStream::operator<<  ( char v )
1426 {
1427     //SDO
1428     int tmp = eIOMode;
1429     if(tmp == STREAM_IO_WRITE && sizeof(char) <= nBufFree )
1430     {
1431         *pBufPos = v;
1432         pBufPos++; // sizeof(char);
1433         nBufActualPos++;
1434         if( nBufActualPos > nBufActualLen )  // Append ?
1435             nBufActualLen = nBufActualPos;
1436         nBufFree--; // = sizeof(char);
1437         bIsDirty = sal_True;
1438     }
1439     else
1440         Write( (char*)&v, sizeof(char) );
1441     return *this;
1442 }
1443 
1444 SvStream& SvStream::operator<<  ( unsigned char v )
1445 {
1446 //SDO
1447     int tmp = eIOMode;
1448     if(tmp == STREAM_IO_WRITE && sizeof(char) <= nBufFree )
1449     {
1450         *(unsigned char*)pBufPos = v;
1451         pBufPos++; // = sizeof(char);
1452         nBufActualPos++; // = sizeof(char);
1453         if( nBufActualPos > nBufActualLen )  // Append ?
1454             nBufActualLen = nBufActualPos;
1455         nBufFree--;
1456         bIsDirty = sal_True;
1457     }
1458     else
1459         Write( (char*)&v, sizeof(char) );
1460     return *this;
1461 }
1462 
1463 SvStream& SvStream::operator<< ( float v )
1464 {
1465 #ifdef UNX
1466     if( bSwap )
1467       SwapFloat(v);
1468 #endif
1469     WRITENUMBER_WITHOUT_SWAP(float,v)
1470     return *this;
1471 }
1472 
1473 SvStream& SvStream::operator<< ( const double& r )
1474 {
1475 //    Write( (char*)&r, sizeof( double ) );
1476 #if defined UNX
1477     if( bSwap )
1478     {
1479       double nHelp = r;
1480       SwapDouble(nHelp);
1481       WRITENUMBER_WITHOUT_SWAP(double,nHelp)
1482       return *this;
1483     }
1484     else
1485 #endif
1486     WRITENUMBER_WITHOUT_SWAP(double,r)
1487 
1488     return *this;
1489 }
1490 
1491 SvStream& SvStream::operator<<  ( const char* pBuf )
1492 {
1493     Write( pBuf, strlen( pBuf ) );
1494     return *this;
1495 }
1496 
1497 SvStream& SvStream::operator<<  ( const unsigned char* pBuf )
1498 {
1499     Write( (char*)pBuf, strlen( (char*)pBuf ) );
1500     return *this;
1501 }
1502 
1503 SvStream& SvStream::operator<< ( SvStream& rStream )
1504 {
1505     const sal_uInt32 cBufLen = 0x8000;
1506     char* pBuf = new char[ cBufLen ];
1507     sal_uInt32 nCount;
1508     do {
1509         nCount = rStream.Read( pBuf, cBufLen );
1510         Write( pBuf, nCount );
1511     } while( nCount == cBufLen );
1512 
1513     delete[] pBuf;
1514     return *this;
1515 }
1516 
1517 // -----------------------------------------------------------------------
1518 
1519 SvStream& SvStream::ReadByteString( UniString& rStr, rtl_TextEncoding eSrcCharSet )
1520 {
1521     // read UTF-16 string directly from stream ?
1522     if (eSrcCharSet == RTL_TEXTENCODING_UNICODE)
1523     {
1524         sal_uInt32 nLen;
1525         operator>> (nLen);
1526         if (nLen)
1527         {
1528             if (nLen > STRING_MAXLEN) {
1529                 SetError(SVSTREAM_GENERALERROR);
1530                 return *this;
1531             }
1532             sal_Unicode *pStr = rStr.AllocBuffer(
1533                 static_cast< xub_StrLen >(nLen));
1534             BOOST_STATIC_ASSERT(STRING_MAXLEN <= SAL_MAX_SIZE / 2);
1535             Read( pStr, nLen << 1 );
1536 
1537             if (bSwap)
1538                 for (sal_Unicode *pEnd = pStr + nLen; pStr < pEnd; pStr++)
1539                     SwapUShort(*pStr);
1540         }
1541         else
1542             rStr.Erase();
1543 
1544         return *this;
1545     }
1546 
1547     ByteString aStr;
1548     ReadByteString( aStr );
1549     rStr = UniString( aStr, eSrcCharSet );
1550     return *this;
1551 }
1552 
1553 // -----------------------------------------------------------------------
1554 
1555 SvStream& SvStream::ReadByteString( ByteString& rStr )
1556 {
1557     sal_uInt16 nLen = 0;
1558     operator>>( nLen );
1559     if( nLen )
1560     {
1561         char* pTmp = rStr.AllocBuffer( nLen );
1562         nLen = (sal_uInt16)Read( pTmp, nLen );
1563     }
1564     else
1565         rStr.Erase();
1566     return *this;
1567 }
1568 
1569 // -----------------------------------------------------------------------
1570 
1571 SvStream& SvStream::WriteByteString( const UniString& rStr, rtl_TextEncoding eDestCharSet )
1572 {
1573     // write UTF-16 string directly into stream ?
1574     if (eDestCharSet == RTL_TEXTENCODING_UNICODE)
1575     {
1576         sal_uInt32 nLen = rStr.Len();
1577         operator<< (nLen);
1578         if (nLen)
1579         {
1580             if (bSwap)
1581             {
1582                 const sal_Unicode *pStr = rStr.GetBuffer();
1583                 const sal_Unicode *pEnd = pStr + nLen;
1584 
1585                 for (; pStr < pEnd; pStr++)
1586                 {
1587                     sal_Unicode c = *pStr;
1588                     SwapUShort(c);
1589                     WRITENUMBER_WITHOUT_SWAP(sal_uInt16,c)
1590                 }
1591             }
1592             else
1593                 Write( rStr.GetBuffer(), nLen << 1 );
1594         }
1595 
1596         return *this;
1597     }
1598 
1599     return WriteByteString(ByteString( rStr, eDestCharSet ));
1600 }
1601 
1602 // -----------------------------------------------------------------------
1603 
1604 SvStream& SvStream::WriteByteString( const ByteString& rStr)
1605 {
1606     sal_uInt16 nLen = rStr.Len();
1607     operator<< ( nLen );
1608     if( nLen != 0 )
1609         Write( rStr.GetBuffer(), nLen );
1610     return *this;
1611 }
1612 
1613 /*************************************************************************
1614 |*
1615 |*    Stream::Read()
1616 |*
1617 |*    Beschreibung      STREAM.SDW
1618 |*    Ersterstellung    OV 08.06.94
1619 |*    Letzte Aenderung  OV 08.06.94
1620 |*
1621 *************************************************************************/
1622 
1623 sal_Size SvStream::Read( void* pData, sal_Size nCount )
1624 {
1625     sal_Size nSaveCount = nCount;
1626     if( !bIsConsistent )
1627         RefreshBuffer();
1628 
1629     if( !pRWBuf )
1630     {
1631         nCount = GetData( (char*)pData,nCount);
1632         if( nCryptMask )
1633             EncryptBuffer(pData, nCount);
1634         nBufFilePos += nCount;
1635     }
1636     else
1637     {
1638         // ist Block komplett im Puffer
1639         eIOMode = STREAM_IO_READ;
1640         if( nCount <= (sal_Size)(nBufActualLen - nBufActualPos ) )
1641         {
1642             // Ja!
1643             memcpy(pData, pBufPos, (size_t) nCount);
1644             nBufActualPos = nBufActualPos + (sal_uInt16)nCount;
1645             pBufPos += nCount;
1646             nBufFree = nBufFree - (sal_uInt16)nCount;
1647         }
1648         else
1649         {
1650             if( bIsDirty ) // Flushen ?
1651             {
1652                 SeekPos( nBufFilePos );
1653                 if( nCryptMask )
1654                     CryptAndWriteBuffer(pRWBuf, nBufActualLen);
1655                 else
1656                     PutData( pRWBuf, nBufActualLen );
1657                 bIsDirty = sal_False;
1658             }
1659 
1660             // passt der Datenblock in den Puffer ?
1661             if( nCount > nBufSize )
1662             {
1663                 // Nein! Deshalb ohne Umweg ueber den Puffer direkt
1664                 // in den Zielbereich einlesen
1665 
1666                 eIOMode = STREAM_IO_DONTKNOW;
1667 
1668                 SeekPos( nBufFilePos + nBufActualPos );
1669                 nBufActualLen = 0;
1670                 pBufPos       = pRWBuf;
1671                 nCount = GetData( (char*)pData, nCount );
1672                 if( nCryptMask )
1673                     EncryptBuffer(pData, nCount);
1674                 nBufFilePos += nCount;
1675                 nBufFilePos += nBufActualPos;
1676                 nBufActualPos = 0;
1677             }
1678             else
1679             {
1680                 // Der Datenblock passt komplett in den Puffer. Deshalb
1681                 // Puffer fuellen und dann die angeforderten Daten in den
1682                 // Zielbereich kopieren.
1683 
1684                 nBufFilePos += nBufActualPos;
1685                 SeekPos( nBufFilePos );
1686 
1687                 // TODO: Typecast vor GetData, sal_uInt16 nCountTmp
1688                 sal_Size nCountTmp = GetData( pRWBuf, nBufSize );
1689                 if( nCryptMask )
1690                     EncryptBuffer(pRWBuf, nCountTmp);
1691                 nBufActualLen = (sal_uInt16)nCountTmp;
1692                 if( nCount > nCountTmp )
1693                 {
1694                     nCount = nCountTmp;  // zurueckstutzen, Eof siehe unten
1695                 }
1696                 memcpy( pData, pRWBuf, (size_t)nCount );
1697                 nBufActualPos = (sal_uInt16)nCount;
1698                 pBufPos = pRWBuf + nCount;
1699             }
1700         }
1701     }
1702     bIsEof = sal_False;
1703     nBufFree = nBufActualLen - nBufActualPos;
1704     if( nCount != nSaveCount && nError != ERRCODE_IO_PENDING )
1705         bIsEof = sal_True;
1706     if( nCount == nSaveCount && nError == ERRCODE_IO_PENDING )
1707         nError = ERRCODE_NONE;
1708     return nCount;
1709 }
1710 
1711 /*************************************************************************
1712 |*
1713 |*    Stream::Write()
1714 |*
1715 |*    Beschreibung      STREAM.SDW
1716 |*    Ersterstellung    OV 08.06.94
1717 |*    Letzte Aenderung  OV 08.06.94
1718 |*
1719 *************************************************************************/
1720 
1721 sal_Size SvStream::Write( const void* pData, sal_Size nCount )
1722 {
1723     if( !nCount )
1724         return 0;
1725     if( !bIsWritable )
1726     {
1727         SetError( ERRCODE_IO_CANTWRITE );
1728         return 0;
1729     }
1730     if( !bIsConsistent )
1731         RefreshBuffer();   // Aenderungen des Puffers durch PutBack loeschen
1732 
1733     if( !pRWBuf )
1734     {
1735         if( nCryptMask )
1736             nCount = CryptAndWriteBuffer( pData, nCount );
1737         else
1738             nCount = PutData( (char*)pData, nCount );
1739         nBufFilePos += nCount;
1740         return nCount;
1741     }
1742 
1743     eIOMode = STREAM_IO_WRITE;
1744     if( nCount <= (sal_Size)(nBufSize - nBufActualPos) )
1745     {
1746         memcpy( pBufPos, pData, (size_t)nCount );
1747         nBufActualPos = nBufActualPos + (sal_uInt16)nCount;
1748         // wurde der Puffer erweitert ?
1749         if( nBufActualPos > nBufActualLen )
1750             nBufActualLen = nBufActualPos;
1751 
1752         pBufPos += nCount;
1753         bIsDirty = sal_True;
1754     }
1755     else
1756     {
1757         // Flushen ?
1758         if( bIsDirty )
1759         {
1760             SeekPos( nBufFilePos );
1761             if( nCryptMask )
1762                 CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
1763             else
1764                 PutData( pRWBuf, nBufActualLen );
1765             bIsDirty = sal_False;
1766         }
1767 
1768         // passt der Block in den Puffer ?
1769         if( nCount > nBufSize )
1770         {
1771             eIOMode = STREAM_IO_DONTKNOW;
1772             nBufFilePos += nBufActualPos;
1773             nBufActualLen = 0;
1774             nBufActualPos = 0;
1775             pBufPos       = pRWBuf;
1776             SeekPos( nBufFilePos );
1777             if( nCryptMask )
1778                 nCount = CryptAndWriteBuffer( pData, nCount );
1779             else
1780                 nCount = PutData( (char*)pData, nCount );
1781             nBufFilePos += nCount;
1782         }
1783         else
1784         {
1785             // Block in Puffer stellen
1786             memcpy( pRWBuf, pData, (size_t)nCount );
1787 
1788             // Reihenfolge!
1789             nBufFilePos += nBufActualPos;
1790             nBufActualPos = (sal_uInt16)nCount;
1791             pBufPos = pRWBuf + nCount;
1792             nBufActualLen = (sal_uInt16)nCount;
1793             bIsDirty = sal_True;
1794         }
1795     }
1796     nBufFree = nBufSize - nBufActualPos;
1797     return nCount;
1798 }
1799 
1800 
1801 /*************************************************************************
1802 |*
1803 |*    Stream::Seek()
1804 |*
1805 |*    Beschreibung      STREAM.SDW
1806 |*    Ersterstellung    OV 08.06.94
1807 |*    Letzte Aenderung  OV 08.06.94
1808 |*
1809 *************************************************************************/
1810 
1811 sal_Size SvStream::Seek( sal_Size nFilePos )
1812 {
1813     eIOMode = STREAM_IO_DONTKNOW;
1814 
1815     bIsEof = sal_False;
1816     if( !pRWBuf )
1817     {
1818         nBufFilePos = SeekPos( nFilePos );
1819         DBG_ASSERT(Tell()==nBufFilePos,"Out Of Sync!");
1820         return nBufFilePos;
1821     }
1822 
1823     // Ist Position im Puffer ?
1824     if( nFilePos >= nBufFilePos && nFilePos <= (nBufFilePos + nBufActualLen))
1825     {
1826         nBufActualPos = (sal_uInt16)(nFilePos - nBufFilePos);
1827         pBufPos = pRWBuf + nBufActualPos;
1828         // nBufFree korrigieren, damit wir nicht von einem
1829         // PutBack (ignoriert den StreamMode) getoetet werden
1830         nBufFree = nBufActualLen - nBufActualPos;
1831     }
1832     else
1833     {
1834         if( bIsDirty && bIsConsistent)
1835         {
1836             SeekPos( nBufFilePos );
1837             if( nCryptMask )
1838                 CryptAndWriteBuffer( pRWBuf, nBufActualLen );
1839             else
1840                 PutData( pRWBuf, nBufActualLen );
1841             bIsDirty = sal_False;
1842         }
1843         nBufActualLen = 0;
1844         nBufActualPos = 0;
1845         pBufPos       = pRWBuf;
1846         nBufFilePos = SeekPos( nFilePos );
1847     }
1848 #ifdef OV_DEBUG
1849     {
1850         sal_Size nDebugTemp = nBufFilePos + nBufActualPos;
1851         DBG_ASSERT(Tell()==nDebugTemp,"Sync?");
1852     }
1853 #endif
1854     return nBufFilePos + nBufActualPos;
1855 }
1856 
1857 /*************************************************************************
1858 |*
1859 |*    Stream::Flush()
1860 |*
1861 |*    Beschreibung      STREAM.SDW
1862 |*    Ersterstellung    OV 08.06.94
1863 |*    Letzte Aenderung  OV 08.06.94
1864 |*
1865 *************************************************************************/
1866 
1867 void SvStream::Flush()
1868 {
1869     if( bIsDirty && bIsConsistent )
1870     {
1871         SeekPos( nBufFilePos );
1872         if( nCryptMask )
1873             CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
1874         else
1875             if( PutData( pRWBuf, nBufActualLen ) != nBufActualLen )
1876                 SetError( SVSTREAM_WRITE_ERROR );
1877         bIsDirty = sal_False;
1878     }
1879     if( bIsWritable )
1880         FlushData();
1881 }
1882 
1883 
1884 /*************************************************************************
1885 |*
1886 |*    Stream::PutBack()
1887 |*
1888 |*    Beschreibung      STREAM.SDW
1889 |*    Ersterstellung    OV 01.08.94
1890 |*    Letzte Aenderung  OV 01.08.94
1891 |*
1892 *************************************************************************/
1893 
1894 /*
1895     4 Faelle :
1896 
1897     1. Datenzeiger steht mitten im Puffer (nBufActualPos >= 1)
1898     2. Datenzeiger auf Position 0, Puffer ist voll
1899     3. Datenzeiger auf Position 0, Puffer ist teilweise gefuellt
1900     4. Datenzeiger auf Position 0, Puffer ist leer -> Fehler!
1901 */
1902 
1903 SvStream& SvStream::PutBack( char aCh )
1904 {
1905     // wenn kein Buffer oder Zurueckscrollen nicht moeglich -> Fehler
1906     if( !pRWBuf || !nBufActualLen || ( !nBufActualPos && !nBufFilePos ) )
1907     {
1908         // 4. Fall
1909         SetError( SVSTREAM_GENERALERROR );
1910         return *this;
1911     }
1912 
1913     // Flush() (Phys. Flushen aber nicht notwendig, deshalb selbst schreiben)
1914     if( bIsConsistent && bIsDirty  )
1915     {
1916         SeekPos( nBufFilePos );
1917         if( nCryptMask )
1918             CryptAndWriteBuffer( pRWBuf, nBufActualLen );
1919         else
1920             PutData( pRWBuf, nBufActualLen );
1921         bIsDirty = sal_False;
1922     }
1923     bIsConsistent = sal_False;  // Puffer enthaelt jetzt TRASH
1924     if( nBufActualPos )
1925     {
1926         // 1. Fall
1927         nBufActualPos--;
1928         pBufPos--;
1929         *pBufPos = aCh;
1930         nBufFree++;
1931     }
1932     else  // Puffer muss verschoben werden
1933     {
1934         // Ist Puffer am Anschlag ?
1935         if( nBufSize == nBufActualLen )
1936         {
1937             // 2. Fall
1938             memmove( pRWBuf+1, pRWBuf, nBufSize-1 );
1939             // nBufFree behaelt den Wert!
1940         }
1941         else
1942         {
1943             // 3. Fall -> Puffer vergroessern
1944             memmove( pRWBuf+1, pRWBuf, (sal_uInt16)nBufActualLen );
1945             nBufActualLen++;
1946             nBufFree++;
1947         }
1948         nBufFilePos--;
1949         *pRWBuf = aCh;
1950     }
1951     eIOMode = STREAM_IO_DONTKNOW;
1952     bIsEof = sal_False;
1953     return *this;
1954 }
1955 
1956 /*************************************************************************
1957 |*
1958 |*    Stream::EatWhite()
1959 |*
1960 |*    Beschreibung      STREAM.SDW
1961 |*    Ersterstellung    OV 01.08.94
1962 |*    Letzte Aenderung  OV 01.08.94
1963 |*
1964 *************************************************************************/
1965 
1966 void SvStream::EatWhite()
1967 {
1968     char aCh;
1969     Read(&aCh, sizeof(char) );
1970     while( !bIsEof && isspace((int)aCh) )  //( aCh == ' ' || aCh == '\t' ) )
1971         Read(&aCh, sizeof(char) );
1972     if( !bIsEof ) // konnte das letzte Char gelesen werden ?
1973         SeekRel( -1L );
1974 }
1975 
1976 /*************************************************************************
1977 |*
1978 |*    Stream::RefreshBuffer()
1979 |*
1980 |*    Beschreibung      STREAM.SDW
1981 |*    Ersterstellung    OV 01.08.94
1982 |*    Letzte Aenderung  OV 01.08.94
1983 |*
1984 *************************************************************************/
1985 
1986 void SvStream::RefreshBuffer()
1987 {
1988     if( bIsDirty && bIsConsistent )
1989     {
1990         SeekPos( nBufFilePos );
1991         if( nCryptMask )
1992             CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
1993         else
1994             PutData( pRWBuf, nBufActualLen );
1995         bIsDirty = sal_False;
1996     }
1997     SeekPos( nBufFilePos );
1998     nBufActualLen = (sal_uInt16)GetData( pRWBuf, nBufSize );
1999     if( nBufActualLen && nError == ERRCODE_IO_PENDING )
2000         nError = ERRCODE_NONE;
2001     if( nCryptMask )
2002         EncryptBuffer(pRWBuf, (sal_Size)nBufActualLen);
2003     bIsConsistent = sal_True;
2004     eIOMode = STREAM_IO_DONTKNOW;
2005 }
2006 
2007 
2008 /*************************************************************************
2009 |*
2010 |*    Stream::CreateFormatString()
2011 |*
2012 |*    Beschreibung      Baut Formatstring zusammen
2013 |*    Ersterstellung    OV 08.06.94
2014 |*    Letzte Aenderung  OV 08.06.94
2015 |*
2016 *************************************************************************/
2017 
2018 void SvStream::CreateFormatString()
2019 {
2020     aFormatString = '%';
2021     nPrintfParams = SPECIAL_PARAM_NONE;
2022 
2023     if( nJustification )
2024     {
2025         aFormatString += '-';
2026     }
2027 
2028     if( nWidth )
2029     {
2030         if( cFiller != ' ' )
2031             aFormatString += '0';
2032         aFormatString += '*';
2033         nPrintfParams = SPECIAL_PARAM_WIDTH;
2034     }
2035 
2036     if( nPrecision )
2037     {
2038         aFormatString += ".*";
2039         if( nWidth )
2040             nPrintfParams = SPECIAL_PARAM_BOTH;
2041         else
2042             nPrintfParams = SPECIAL_PARAM_PRECISION;
2043     }
2044 }
2045 
2046 /*************************************************************************
2047 |*
2048 |*    Stream::ReadNumber()
2049 |*
2050 |*    Beschreibung      STREAM.SDW
2051 |*    Ersterstellung    OV 08.06.94
2052 |*    Letzte Aenderung  OV 08.06.94
2053 |*
2054 *************************************************************************/
2055 
2056 #define BUFSIZE_LONG 21  // log( 2 hoch 64 ) + 1
2057 
2058 SvStream& SvStream::ReadNumber( long& rLong )
2059 {
2060     EatWhite();
2061     if( bIsEof || nError )
2062     {
2063         SetError( SVSTREAM_GENERALERROR );
2064         return *this;
2065     }
2066     sal_Size nFPtr = Tell();
2067     char buf[ BUFSIZE_LONG ];
2068     memset( buf, 0, BUFSIZE_LONG );
2069     sal_Size nTemp = Read( buf, BUFSIZE_LONG-1 );
2070     if( !nTemp || nError )
2071     {
2072         SetError( SVSTREAM_GENERALERROR );
2073         return *this;
2074     }
2075     char *pEndPtr;
2076     rLong = strtol( buf, &pEndPtr, (int)nRadix );
2077     nFPtr += ( (sal_Size)pEndPtr - (sal_Size)(&(buf[0])) );
2078     Seek( nFPtr );
2079     bIsEof = sal_False;
2080     return *this;
2081 }
2082 
2083 SvStream& SvStream::ReadNumber( sal_uInt32& rUInt32 )
2084 {
2085     EatWhite();
2086     if( bIsEof || nError )
2087     {
2088         SetError( SVSTREAM_GENERALERROR );
2089         return *this;
2090     }
2091     sal_Size nFPtr = Tell();
2092     char buf[ BUFSIZE_LONG ];
2093     memset( buf, 0, BUFSIZE_LONG );
2094     sal_Size nTemp = Read( buf, BUFSIZE_LONG-1 );
2095     if( !nTemp || nError )
2096     {
2097         SetError( SVSTREAM_GENERALERROR );
2098         return *this;
2099     }
2100     char *pEndPtr;
2101     rUInt32 = strtoul( buf, &pEndPtr, (int)nRadix );
2102     nFPtr += ( (sal_uIntPtr)pEndPtr - (sal_uIntPtr)buf );
2103     Seek( nFPtr );
2104     bIsEof = sal_False;
2105     return *this;
2106 }
2107 
2108 SvStream& SvStream::ReadNumber( double& rDouble )
2109 {
2110     EatWhite();
2111     if( bIsEof || nError )
2112     {
2113         SetError( SVSTREAM_GENERALERROR );
2114         return *this;
2115     }
2116     sal_Size nFPtr = Tell();
2117     char buf[ BUFSIZE_LONG ];
2118     memset( buf, 0, BUFSIZE_LONG );
2119     sal_Size nTemp = Read( buf, BUFSIZE_LONG-1 );
2120     if( !nTemp || nError )
2121     {
2122         SetError( SVSTREAM_GENERALERROR );
2123         return *this;
2124     }
2125     char *pEndPtr;
2126     rDouble = strtod( buf, &pEndPtr );
2127     nFPtr += ( (sal_Size)pEndPtr - (sal_Size)buf );
2128     Seek( nFPtr );
2129     bIsEof = sal_False;
2130     return *this;
2131 }
2132 
2133 
2134 /*************************************************************************
2135 |*
2136 |*    Stream::WriteNumber()
2137 |*
2138 |*    Beschreibung      STREAM.SDW
2139 |*    Ersterstellung    OV 08.06.94
2140 |*    Letzte Aenderung  OV 08.06.94
2141 |*
2142 *************************************************************************/
2143 
2144 SvStream& SvStream::WriteNumber( long nLong )
2145 {
2146     char buffer[256+12];
2147     char pType[] = "ld"; // Nicht static!
2148     if( nRadix == 16 )
2149         pType[1] = 'x';
2150     else if( nRadix == 8 )
2151         pType[1] = 'o';
2152     ByteString aFStr( aFormatString);
2153     aFStr += pType;
2154     int nLen;
2155     switch ( nPrintfParams )
2156     {
2157         case SPECIAL_PARAM_NONE :
2158             nLen = sprintf( buffer, aFStr.GetBuffer(), nLong );
2159             break;
2160         case SPECIAL_PARAM_WIDTH :
2161             nLen = sprintf( buffer, aFStr.GetBuffer(), nWidth, nLong );
2162             break;
2163         case SPECIAL_PARAM_PRECISION :
2164             nLen = sprintf( buffer, aFStr.GetBuffer(), nPrecision,nLong);
2165             break;
2166         default:
2167             nLen=sprintf(buffer, aFStr.GetBuffer(),nWidth,nPrecision,nLong);
2168     }
2169     Write( buffer, (long)nLen );
2170     return *this;
2171 }
2172 
2173 SvStream& SvStream::WriteNumber( sal_uInt32 nUInt32 )
2174 {
2175     char buffer[256+12];
2176     char pType[] = "lu"; // Nicht static!
2177     if( nRadix == 16 )
2178         pType[1] = 'x';
2179     else if( nRadix == 8 )
2180         pType[1] = 'o';
2181     ByteString aFStr( aFormatString);
2182     aFStr += pType;
2183     int nLen;
2184     switch ( nPrintfParams )
2185     {
2186         case SPECIAL_PARAM_NONE :
2187             nLen = sprintf( buffer, aFStr.GetBuffer(), nUInt32 );
2188             break;
2189         case SPECIAL_PARAM_WIDTH :
2190             nLen = sprintf( buffer, aFStr.GetBuffer(), nWidth, nUInt32 );
2191             break;
2192         case SPECIAL_PARAM_PRECISION :
2193             nLen = sprintf( buffer, aFStr.GetBuffer(), nPrecision, nUInt32 );
2194             break;
2195         default:
2196             nLen=sprintf(buffer,aFStr.GetBuffer(),nWidth,nPrecision,nUInt32 );
2197     }
2198     Write( buffer, (long)nLen );
2199     return *this;
2200 }
2201 
2202 
2203 SvStream& SvStream::WriteNumber( const double& rDouble )
2204 {
2205     char buffer[256+24];
2206     ByteString aFStr( aFormatString);
2207     aFStr += "lf";
2208     int nLen;
2209     switch ( nPrintfParams )
2210     {
2211         case SPECIAL_PARAM_NONE :
2212             nLen = sprintf( buffer, aFStr.GetBuffer(), rDouble );
2213             break;
2214         case SPECIAL_PARAM_WIDTH :
2215             nLen = sprintf( buffer, aFStr.GetBuffer(), nWidth, rDouble );
2216             break;
2217         case SPECIAL_PARAM_PRECISION :
2218             nLen = sprintf( buffer, aFStr.GetBuffer(), nPrecision, rDouble);
2219             break;
2220         default:
2221             nLen=sprintf(buffer, aFStr.GetBuffer(),nWidth,nPrecision,rDouble);
2222     }
2223     Write( buffer, (long)nLen );
2224     return *this;
2225 }
2226 
2227 /*************************************************************************
2228 |*
2229 |*    Stream::CryptAndWriteBuffer()
2230 |*
2231 |*    Beschreibung      Verschluesseln und Schreiben
2232 |*    Ersterstellung    OV 08.06.94
2233 |*    Letzte Aenderung  OV 08.06.94
2234 |*
2235 *************************************************************************/
2236 
2237 #define CRYPT_BUFSIZE 1024
2238 
2239 sal_Size SvStream::CryptAndWriteBuffer( const void* pStart, sal_Size nLen)
2240 {
2241     unsigned char  pTemp[CRYPT_BUFSIZE];
2242     unsigned char* pDataPtr = (unsigned char*)pStart;
2243     sal_Size nCount = 0;
2244     sal_Size nBufCount;
2245     unsigned char nMask = nCryptMask;
2246     do
2247     {
2248         if( nLen >= CRYPT_BUFSIZE )
2249             nBufCount = CRYPT_BUFSIZE;
2250         else
2251             nBufCount = nLen;
2252         nLen -= nBufCount;
2253         memcpy( pTemp, pDataPtr, (sal_uInt16)nBufCount );
2254         // **** Verschluesseln *****
2255         for ( sal_uInt16 n=0; n < CRYPT_BUFSIZE; n++ )
2256         {
2257             unsigned char aCh = pTemp[n];
2258             aCh ^= nMask;
2259             SWAPNIBBLES(aCh)
2260             pTemp[n] = aCh;
2261         }
2262         // *************************
2263         nCount += PutData( (char*)pTemp, nBufCount );
2264         pDataPtr += nBufCount;
2265     }
2266     while ( nLen );
2267     return nCount;
2268 }
2269 
2270 /*************************************************************************
2271 |*
2272 |*    Stream::EncryptBuffer()
2273 |*
2274 |*    Beschreibung      Buffer entschluesseln
2275 |*    Ersterstellung    OV 08.06.94
2276 |*    Letzte Aenderung  OV 08.06.94
2277 |*
2278 *************************************************************************/
2279 
2280 sal_Bool SvStream::EncryptBuffer(void* pStart, sal_Size nLen)
2281 {
2282     unsigned char* pTemp = (unsigned char*)pStart;
2283     unsigned char nMask = nCryptMask;
2284 
2285     for ( sal_Size n=0; n < nLen; n++, pTemp++ )
2286     {
2287         unsigned char aCh = *pTemp;
2288         SWAPNIBBLES(aCh)
2289         aCh ^= nMask;
2290         *pTemp = aCh;
2291     }
2292     return sal_True;
2293 }
2294 
2295 /*************************************************************************
2296 |*
2297 |*    Stream::SetKey()
2298 |*
2299 |*    Beschreibung      STREAM.SDW
2300 |*    Ersterstellung    OV 08.06.94
2301 |*    Letzte Aenderung  OV 08.06.94
2302 |*
2303 *************************************************************************/
2304 
2305 unsigned char implGetCryptMask(const sal_Char* pStr, sal_Int32 nLen, long nVersion)
2306 {
2307     unsigned char nCryptMask = 0;
2308 
2309     if (!nLen)
2310         return nCryptMask;
2311 
2312     if( nVersion <= SOFFICE_FILEFORMAT_31 )
2313     {
2314         while( nLen )
2315         {
2316             nCryptMask ^= *pStr;
2317             pStr++;
2318             nLen--;
2319         }
2320     }
2321     else // BugFix #25888#
2322     {
2323         for( sal_uInt16 i = 0; i < nLen; i++ ) {
2324             nCryptMask ^= pStr[i];
2325             if( nCryptMask & 0x80 ) {
2326                 nCryptMask <<= 1;
2327                 nCryptMask++;
2328             }
2329             else
2330                 nCryptMask <<= 1;
2331         }
2332     }
2333 
2334     if( !nCryptMask )
2335         nCryptMask = 67;
2336 
2337     return nCryptMask;
2338 }
2339 
2340 void SvStream::SetKey( const ByteString& rKey )
2341 {
2342     aKey = rKey;
2343     nCryptMask = implGetCryptMask( aKey.GetBuffer(), aKey.Len(), GetVersion() );
2344 }
2345 
2346 /*************************************************************************
2347 |*
2348 |*    Stream::SyncSvStream()
2349 |*
2350 |*    Beschreibung      STREAM.SDW
2351 |*    Ersterstellung    OV 08.06.94
2352 |*    Letzte Aenderung  OV 08.06.94
2353 |*
2354 *************************************************************************/
2355 
2356 void SvStream::SyncSvStream( sal_Size nNewStreamPos )
2357 {
2358     ClearBuffer();
2359     SvStream::nBufFilePos = nNewStreamPos;
2360 }
2361 
2362 /*************************************************************************
2363 |*
2364 |*    Stream::SyncSysStream()
2365 |*
2366 |*    Beschreibung      STREAM.SDW
2367 |*    Ersterstellung    OV 08.06.94
2368 |*    Letzte Aenderung  OV 08.06.94
2369 |*
2370 *************************************************************************/
2371 
2372 void SvStream::SyncSysStream()
2373 {
2374     Flush();
2375     SeekPos( Tell() );
2376 }
2377 
2378 /*************************************************************************
2379 |*
2380 |*    Stream::SetStreamSize()
2381 |*
2382 |*    Beschreibung      STREAM.SDW
2383 |*    Ersterstellung    OV 08.06.94
2384 |*    Letzte Aenderung  OV 08.06.94
2385 |*
2386 *************************************************************************/
2387 
2388 sal_Bool SvStream::SetStreamSize( sal_Size nSize )
2389 {
2390 #ifdef DBG_UTIL
2391     sal_Size nFPos = Tell();
2392 #endif
2393     sal_uInt16 nBuf = nBufSize;
2394     SetBufferSize( 0 );
2395     SetSize( nSize );
2396     SetBufferSize( nBuf );
2397     DBG_ASSERT(Tell()==nFPos,"SetStreamSize failed");
2398     return (sal_Bool)(nError == 0);
2399 }
2400 
2401 //============================================================================
2402 
2403 void SvStream::AddMark( sal_Size )
2404 {
2405 }
2406 
2407 //============================================================================
2408 
2409 void SvStream::RemoveMark( sal_Size )
2410 {
2411 }
2412 
2413 /*************************************************************************
2414 |*
2415 |*    endl()
2416 |*
2417 |*    Beschreibung      STREAM.SDW
2418 |*    Ersterstellung    OV 08.06.94
2419 |*    Letzte Aenderung  TH 13.11.96
2420 |*
2421 *************************************************************************/
2422 
2423 SvStream& endl( SvStream& rStr )
2424 {
2425     LineEnd eDelim = rStr.GetLineDelimiter();
2426     if ( eDelim == LINEEND_CR )
2427         rStr << _CR;
2428     else if( eDelim == LINEEND_LF )
2429         rStr << _LF;
2430     else
2431         rStr << _CR << _LF;
2432     return rStr;
2433 }
2434 
2435 SvStream& endlu( SvStream& rStrm )
2436 {
2437     switch ( rStrm.GetLineDelimiter() )
2438     {
2439         case LINEEND_CR :
2440             rStrm << sal_Unicode(_CR);
2441         break;
2442         case LINEEND_LF :
2443             rStrm << sal_Unicode(_LF);
2444         break;
2445         default:
2446             rStrm << sal_Unicode(_CR) << sal_Unicode(_LF);
2447     }
2448     return rStrm;
2449 }
2450 
2451 SvStream& endlub( SvStream& rStrm )
2452 {
2453     if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
2454         return endlu( rStrm );
2455     else
2456         return endl( rStrm );
2457 }
2458 
2459 /*************************************************************************
2460 |*
2461 |*    SvMemoryStream::SvMemoryStream()
2462 |*
2463 |*    Beschreibung      STREAM.SDW
2464 |*    Ersterstellung    OV 20.06.94
2465 |*    Letzte Aenderung  OV 20.06.94
2466 |*
2467 *************************************************************************/
2468 
2469 SvMemoryStream::SvMemoryStream( void* pBuffer, sal_Size bufSize,
2470                                 StreamMode eMode )
2471 {
2472     if( eMode & STREAM_WRITE )
2473         bIsWritable = sal_True;
2474     else
2475         bIsWritable = sal_False;
2476     nEndOfData  = bufSize;
2477     bOwnsData   = sal_False;
2478     pBuf        = (sal_uInt8 *) pBuffer;
2479     nResize     = 0L;
2480     nSize       = bufSize;
2481     nPos        = 0L;
2482     SetBufferSize( 0 );
2483 }
2484 
2485 /*************************************************************************
2486 |*
2487 |*    SvMemoryStream::SvMemoryStream()
2488 |*
2489 |*    Beschreibung      STREAM.SDW
2490 |*    Ersterstellung    OV 20.06.94
2491 |*    Letzte Aenderung  OV 20.06.94
2492 |*
2493 *************************************************************************/
2494 
2495 SvMemoryStream::SvMemoryStream( sal_Size nInitSize, sal_Size nResizeOffset )
2496 {
2497     bIsWritable = sal_True;
2498     bOwnsData   = sal_True;
2499     nEndOfData  = 0L;
2500     nResize     = nResizeOffset;
2501     nPos        = 0;
2502     pBuf        = 0;
2503     if( nResize != 0 && nResize < 16 )
2504         nResize = 16;
2505     if( nInitSize && !AllocateMemory( nInitSize ) )
2506     {
2507         SetError( SVSTREAM_OUTOFMEMORY );
2508         nSize = 0;
2509     }
2510     else
2511         nSize = nInitSize;
2512     SetBufferSize( 64 );
2513 }
2514 
2515 /*************************************************************************
2516 |*
2517 |*    SvMemoryStream::~SvMemoryStream()
2518 |*
2519 |*    Beschreibung      STREAM.SDW
2520 |*    Ersterstellung    OV 20.06.94
2521 |*    Letzte Aenderung  OV 20.06.94
2522 |*
2523 *************************************************************************/
2524 
2525 SvMemoryStream::~SvMemoryStream()
2526 {
2527     if( pBuf )
2528     {
2529         if( bOwnsData )
2530             FreeMemory();
2531         else
2532             Flush();
2533     }
2534 }
2535 
2536 /*************************************************************************
2537 |*
2538 |*    SvMemoryStream::IsA()
2539 |*
2540 |*    Beschreibung      STREAM.SDW
2541 |*    Ersterstellung    OV 20.06.94
2542 |*    Letzte Aenderung  OV 20.06.94
2543 |*
2544 *************************************************************************/
2545 
2546 sal_uInt16 SvMemoryStream::IsA() const
2547 {
2548     return (sal_uInt16)ID_MEMORYSTREAM;
2549 }
2550 
2551 /*************************************************************************
2552 |*
2553 |*    SvMemoryStream::SetBuffer()
2554 |*
2555 |*    Beschreibung      STREAM.SDW
2556 |*    Ersterstellung    OV 20.06.94
2557 |*    Letzte Aenderung  OV 20.06.94
2558 |*
2559 *************************************************************************/
2560 
2561 void* SvMemoryStream::SetBuffer( void* pNewBuf, sal_Size nCount,
2562                                  sal_Bool bOwnsDat, sal_Size nEOF )
2563 {
2564     void* pResult;
2565     SetBufferSize( 0 ); // Buffering in der Basisklasse initialisieren
2566     Seek( 0 );
2567     if( bOwnsData )
2568     {
2569         pResult = 0;
2570         if( pNewBuf != pBuf )
2571             FreeMemory();
2572     }
2573     else
2574         pResult = pBuf;
2575 
2576     pBuf        = (sal_uInt8 *) pNewBuf;
2577     nPos        = 0;
2578     nSize       = nCount;
2579     nResize     = 0;
2580     bOwnsData   = bOwnsDat;
2581 
2582     if( nEOF > nCount )
2583         nEOF = nCount;
2584     nEndOfData = nEOF;
2585 
2586     ResetError();
2587 
2588     DBG_ASSERT( nEndOfData<STREAM_SEEK_TO_END,"Invalid EOF");
2589     return pResult;
2590 }
2591 
2592 /*************************************************************************
2593 |*
2594 |*    SvMemoryStream::GetData()
2595 |*
2596 |*    Beschreibung      STREAM.SDW
2597 |*    Ersterstellung    OV 20.06.94
2598 |*    Letzte Aenderung  OV 20.06.94
2599 |*
2600 *************************************************************************/
2601 
2602 sal_Size SvMemoryStream::GetData( void* pData, sal_Size nCount )
2603 {
2604     sal_Size nMaxCount = nEndOfData-nPos;
2605     if( nCount > nMaxCount )
2606         nCount = nMaxCount;
2607     memcpy( pData, pBuf+nPos, (size_t)nCount );
2608     nPos += nCount;
2609     return nCount;
2610 }
2611 
2612 /*************************************************************************
2613 |*
2614 |*    SvMemoryStream::PutData()
2615 |*
2616 |*    Beschreibung      STREAM.SDW
2617 |*    Ersterstellung    OV 20.06.94
2618 |*    Letzte Aenderung  OV 20.06.94
2619 |*
2620 *************************************************************************/
2621 
2622 sal_Size SvMemoryStream::PutData( const void* pData, sal_Size nCount )
2623 {
2624     if( GetError() )
2625         return 0L;
2626 
2627     sal_Size nMaxCount = nSize-nPos;
2628 
2629     // auf Ueberlauf testen
2630     if( nCount > nMaxCount )
2631     {
2632         if( nResize == 0 )
2633         {
2634             // soviel wie moeglich rueberschaufeln
2635             nCount = nMaxCount;
2636             SetError( SVSTREAM_OUTOFMEMORY );
2637         }
2638         else
2639         {
2640             long nNewResize;
2641             if( nSize && nSize > nResize )
2642                 nNewResize = nSize;
2643             else
2644                 nNewResize = nResize;
2645 
2646             if( (nCount-nMaxCount) < nResize )
2647             {
2648                 // fehlender Speicher ist kleiner als Resize-Offset,
2649                 // deshalb um Resize-Offset vergroessern
2650                 if( !ReAllocateMemory( nNewResize) )
2651                 {
2652                     nCount = 0;
2653                     SetError( SVSTREAM_WRITE_ERROR );
2654                 }
2655             }
2656             else
2657             {
2658                 // fehlender Speicher ist groesser als Resize-Offset
2659                 // deshalb um Differenz+ResizeOffset vergroessern
2660                 if( !ReAllocateMemory( nCount-nMaxCount+nNewResize ) )
2661                 {
2662                     nCount = 0;
2663                     SetError( SVSTREAM_WRITE_ERROR );
2664                 }
2665             }
2666         }
2667     }
2668     DBG_ASSERT(pBuf,"Possibly Reallocate failed");
2669     memcpy( pBuf+nPos, pData, (size_t)nCount);
2670 
2671     nPos += nCount;
2672     if( nPos > nEndOfData )
2673         nEndOfData = nPos;
2674     return nCount;
2675 }
2676 
2677 /*************************************************************************
2678 |*
2679 |*    SvMemoryStream::SeekPos()
2680 |*
2681 |*    Beschreibung      STREAM.SDW
2682 |*    Ersterstellung    OV 20.06.94
2683 |*    Letzte Aenderung  OV 20.06.94
2684 |*
2685 *************************************************************************/
2686 
2687 // nEndOfData: Erste Position im Stream, die nicht gelesen werden darf
2688 // nSize: Groesse des allozierten Speichers
2689 
2690 sal_Size SvMemoryStream::SeekPos( sal_Size nNewPos )
2691 {
2692     if( nNewPos < nEndOfData )
2693         nPos = nNewPos;
2694     else if( nNewPos == STREAM_SEEK_TO_END )
2695         nPos = nEndOfData;
2696     else
2697     {
2698         if( nNewPos >= nSize ) // muss Buffer vergroessert werden ?
2699         {
2700             if( nResize )  // ist vergroeseern erlaubt ?
2701             {
2702                 long nDiff = (long)(nNewPos - nSize + 1);
2703                 nDiff += (long)nResize;
2704                 ReAllocateMemory( nDiff );
2705                 nPos = nNewPos;
2706                 nEndOfData = nNewPos;
2707             }
2708             else  // vergroessern ist nicht erlaubt -> ans Ende setzen
2709             {
2710                 // SetError( SVSTREAM_OUTOFMEMORY );
2711                 nPos = nEndOfData;
2712             }
2713         }
2714         else  // gueltigen Bereich innerhalb des Buffers vergroessern
2715         {
2716             nPos = nNewPos;
2717             nEndOfData = nNewPos;
2718         }
2719     }
2720     return nPos;
2721 }
2722 
2723 /*************************************************************************
2724 |*
2725 |*    SvMemoryStream::FlushData()
2726 |*
2727 |*    Beschreibung      STREAM.SDW
2728 |*    Ersterstellung    OV 20.06.94
2729 |*    Letzte Aenderung  OV 20.06.94
2730 |*
2731 *************************************************************************/
2732 
2733 void SvMemoryStream::FlushData()
2734 {
2735 }
2736 
2737 /*************************************************************************
2738 |*
2739 |*    SvMemoryStream::ResetError()
2740 |*
2741 |*    Beschreibung      STREAM.SDW
2742 |*    Ersterstellung    OV 20.06.94
2743 |*    Letzte Aenderung  OV 20.06.94
2744 |*
2745 *************************************************************************/
2746 
2747 void SvMemoryStream::ResetError()
2748 {
2749     SvStream::ClearError();
2750 }
2751 
2752 /*************************************************************************
2753 |*
2754 |*    SvMemoryStream::AllocateMemory()
2755 |*
2756 |*    Beschreibung      STREAM.SDW
2757 |*    Ersterstellung    OV 20.06.94
2758 |*    Letzte Aenderung  OV 20.06.94
2759 |*
2760 *************************************************************************/
2761 
2762 sal_Bool SvMemoryStream::AllocateMemory( sal_Size nNewSize )
2763 {
2764     pBuf = new sal_uInt8[nNewSize];
2765     return( pBuf != 0 );
2766 }
2767 
2768 /*************************************************************************
2769 |*
2770 |*    SvMemoryStream::ReAllocateMemory()   (Bozo-Algorithmus)
2771 |*
2772 |*    Beschreibung      STREAM.SDW
2773 |*    Ersterstellung    OV 20.06.94
2774 |*    Letzte Aenderung  OV 20.06.94
2775 |*
2776 *************************************************************************/
2777 
2778 sal_Bool SvMemoryStream::ReAllocateMemory( long nDiff )
2779 {
2780     sal_Bool bRetVal    = sal_False;
2781     long nTemp      = (long)nSize;
2782     nTemp           += nDiff;
2783     sal_Size nNewSize  = (sal_Size)nTemp;
2784 
2785     if( nNewSize )
2786     {
2787         sal_uInt8* pNewBuf   = new sal_uInt8[nNewSize];
2788 
2789         if( pNewBuf )
2790         {
2791             bRetVal = sal_True; // Success!
2792             if( nNewSize < nSize )      // Verkleinern ?
2793             {
2794                 memcpy( pNewBuf, pBuf, (size_t)nNewSize );
2795                 if( nPos > nNewSize )
2796                     nPos = 0L;
2797                 if( nEndOfData >= nNewSize )
2798                     nEndOfData = nNewSize-1L;
2799             }
2800             else
2801             {
2802                 memcpy( pNewBuf, pBuf, (size_t)nSize );
2803             }
2804 
2805             FreeMemory();
2806 
2807             pBuf  = pNewBuf;
2808             nSize = nNewSize;
2809         }
2810     }
2811     else
2812     {
2813         bRetVal = sal_True;
2814         FreeMemory();
2815         pBuf = 0;
2816         nSize = 0;
2817         nEndOfData = 0;
2818         nPos = 0;
2819     }
2820 
2821     return bRetVal;
2822 }
2823 
2824 void SvMemoryStream::FreeMemory()
2825 {
2826     delete[] pBuf;
2827 }
2828 
2829 /*************************************************************************
2830 |*
2831 |*    SvMemoryStream::SwitchBuffer()
2832 |*
2833 |*    Beschreibung      STREAM.SDW
2834 |*    Ersterstellung    OV 26.07.94
2835 |*    Letzte Aenderung  OV 26.07.94
2836 |*
2837 *************************************************************************/
2838 
2839 void* SvMemoryStream::SwitchBuffer( sal_Size nInitSize, sal_Size nResizeOffset)
2840 {
2841     Flush();
2842     if( !bOwnsData )
2843         return 0;
2844     Seek( STREAM_SEEK_TO_BEGIN );
2845 
2846     void* pRetVal = pBuf;
2847     pBuf          = 0;
2848     nEndOfData    = 0L;
2849     nResize       = nResizeOffset;
2850     nPos          = 0;
2851 
2852     if( nResize != 0 && nResize < 16 )
2853         nResize = 16;
2854 
2855     ResetError();
2856 
2857     if( nInitSize && !AllocateMemory(nInitSize) )
2858     {
2859         SetError( SVSTREAM_OUTOFMEMORY );
2860         nSize = 0;
2861     }
2862     else
2863         nSize = nInitSize;
2864 
2865     SetBufferSize( 64 );
2866     return pRetVal;
2867 }
2868 
2869 void SvMemoryStream::SetSize( sal_Size nNewSize )
2870 {
2871     long nDiff = (long)nNewSize - (long)nSize;
2872     ReAllocateMemory( nDiff );
2873 }
2874 
2875 TYPEINIT0 ( SvDataCopyStream )
2876 
2877 void SvDataCopyStream::Assign( const SvDataCopyStream& )
2878 {
2879 }
2880