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