Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : // TODO: Read->RefreshBuffer-> React to changes from nBufActualLen
21 :
22 : #include <cstddef>
23 :
24 : #include <string.h>
25 : #include <stdio.h>
26 : #include <ctype.h> // isspace
27 : #include <stdlib.h> // strtol, _crotl
28 :
29 : #include "boost/static_assert.hpp"
30 :
31 : #include <tools/solar.h>
32 : #include <osl/endian.h>
33 :
34 : #include <comphelper/string.hxx>
35 :
36 : #define SWAPNIBBLES(c) \
37 : unsigned char nSwapTmp=c; \
38 : nSwapTmp <<= 4; \
39 : c >>= 4; \
40 : c |= nSwapTmp;
41 :
42 : #include <tools/debug.hxx>
43 : #include <tools/stream.hxx>
44 : #include <osl/thread.h>
45 : #include <algorithm>
46 :
47 : DBG_NAME( Stream )
48 :
49 : // !!! Do not inline if already the operators <<,>> are inline
50 3676 : inline static void SwapUShort( sal_uInt16& r )
51 3676 : { r = OSL_SWAPWORD(r); }
52 5672 : inline static void SwapShort( short& r )
53 5672 : { r = OSL_SWAPWORD(r); }
54 : inline static void SwapLong( long& r )
55 : { r = OSL_SWAPDWORD(r); }
56 5512 : inline static void SwapULong( sal_uInt32& r )
57 5512 : { r = OSL_SWAPDWORD(r); }
58 1334 : inline static void SwapLongInt( sal_Int32& r )
59 1334 : { r = OSL_SWAPDWORD(r); }
60 : inline static void SwapLongUInt( unsigned int& r )
61 : { r = OSL_SWAPDWORD(r); }
62 :
63 0 : inline static void SwapUInt64( sal_uInt64& r )
64 : {
65 : union
66 : {
67 : sal_uInt64 n;
68 : sal_uInt32 c[2];
69 : } s;
70 :
71 0 : s.n = r;
72 0 : s.c[0] ^= s.c[1]; // swap the 32 bit words
73 0 : s.c[1] ^= s.c[0];
74 0 : s.c[0] ^= s.c[1];
75 : // swap the bytes in the words
76 0 : s.c[0] = OSL_SWAPDWORD(s.c[0]);
77 0 : s.c[1] = OSL_SWAPDWORD(s.c[1]);
78 0 : r = s.n;
79 0 : }
80 0 : inline static void SwapInt64( sal_Int64& r )
81 : {
82 : union
83 : {
84 : sal_Int64 n;
85 : sal_Int32 c[2];
86 : } s;
87 :
88 0 : s.n = r;
89 0 : s.c[0] ^= s.c[1]; // swap the 32 bit words
90 0 : s.c[1] ^= s.c[0];
91 0 : s.c[0] ^= s.c[1];
92 : // swap the bytes in the words
93 0 : s.c[0] = OSL_SWAPDWORD(s.c[0]);
94 0 : s.c[1] = OSL_SWAPDWORD(s.c[1]);
95 0 : r = s.n;
96 0 : }
97 :
98 : #ifdef UNX
99 0 : inline static void SwapFloat( float& r )
100 : {
101 : union
102 : {
103 : float f;
104 : sal_uInt32 c;
105 : } s;
106 :
107 0 : s.f = r;
108 0 : s.c = OSL_SWAPDWORD( s.c );
109 0 : r = s.f;
110 0 : }
111 :
112 0 : inline static void SwapDouble( double& r )
113 : {
114 : if( sizeof(double) != 8 )
115 : {
116 : DBG_ASSERT( sal_False, "Can only swap 8-Byte-doubles\n" );
117 : }
118 : else
119 : {
120 : union
121 : {
122 : double d;
123 : sal_uInt32 c[2];
124 : } s;
125 :
126 0 : s.d = r;
127 0 : s.c[0] ^= s.c[1]; // swap 32-bit values in situ
128 0 : s.c[1] ^= s.c[0];
129 0 : s.c[0] ^= s.c[1];
130 0 : s.c[0] = OSL_SWAPDWORD(s.c[0]); // swap dword itself in situ
131 0 : s.c[1] = OSL_SWAPDWORD(s.c[1]);
132 0 : r = s.d;
133 : }
134 0 : }
135 : #endif
136 :
137 : //SDO
138 :
139 : #define READNUMBER_WITHOUT_SWAP(datatype,value) \
140 : {\
141 : int tmp = eIOMode; \
142 : if( (tmp == STREAM_IO_READ) && sizeof(datatype)<=nBufFree) \
143 : {\
144 : for (std::size_t i = 0; i < sizeof(datatype); i++)\
145 : ((char *)&value)[i] = pBufPos[i];\
146 : nBufActualPos += sizeof(datatype);\
147 : pBufPos += sizeof(datatype);\
148 : nBufFree -= sizeof(datatype);\
149 : }\
150 : else\
151 : Read( (char*)&value, sizeof(datatype) );\
152 : }
153 :
154 : #define WRITENUMBER_WITHOUT_SWAP(datatype,value) \
155 : {\
156 : int tmp = eIOMode; \
157 : if( (tmp==STREAM_IO_WRITE) && sizeof(datatype) <= nBufFree)\
158 : {\
159 : for (std::size_t i = 0; i < sizeof(datatype); i++)\
160 : pBufPos[i] = ((char *)&value)[i];\
161 : nBufFree -= sizeof(datatype);\
162 : nBufActualPos += sizeof(datatype);\
163 : if( nBufActualPos > nBufActualLen )\
164 : nBufActualLen = nBufActualPos;\
165 : pBufPos += sizeof(datatype);\
166 : bIsDirty = sal_True;\
167 : }\
168 : else\
169 : Write( (char*)&value, sizeof(datatype) );\
170 : }
171 :
172 : // class SvLockBytes
173 :
174 11594 : void SvLockBytes::close()
175 : {
176 11594 : if (m_bOwner)
177 0 : delete m_pStream;
178 11594 : m_pStream = 0;
179 11594 : }
180 :
181 0 : TYPEINIT0(SvLockBytes);
182 :
183 : // virtual
184 0 : ErrCode SvLockBytes::ReadAt(sal_Size nPos, void * pBuffer, sal_Size nCount,
185 : sal_Size * pRead) const
186 : {
187 0 : if (!m_pStream)
188 : {
189 : OSL_FAIL("SvLockBytes::ReadAt(): Bad stream");
190 0 : return ERRCODE_NONE;
191 : }
192 :
193 0 : m_pStream->Seek(nPos);
194 0 : sal_Size nTheRead = m_pStream->Read(pBuffer, nCount);
195 0 : if (pRead)
196 0 : *pRead = nTheRead;
197 0 : return m_pStream->GetErrorCode();
198 : }
199 :
200 : // virtual
201 0 : ErrCode SvLockBytes::WriteAt(sal_Size nPos, const void * pBuffer, sal_Size nCount,
202 : sal_Size * pWritten)
203 : {
204 0 : if (!m_pStream)
205 : {
206 : OSL_FAIL("SvLockBytes::WriteAt(): Bad stream");
207 0 : return ERRCODE_NONE;
208 : }
209 :
210 0 : m_pStream->Seek(nPos);
211 0 : sal_Size nTheWritten = m_pStream->Write(pBuffer, nCount);
212 0 : if (pWritten)
213 0 : *pWritten = nTheWritten;
214 0 : return m_pStream->GetErrorCode();
215 : }
216 :
217 : // virtual
218 0 : ErrCode SvLockBytes::Flush() const
219 : {
220 0 : if (!m_pStream)
221 : {
222 : OSL_FAIL("SvLockBytes::Flush(): Bad stream");
223 0 : return ERRCODE_NONE;
224 : }
225 :
226 0 : m_pStream->Flush();
227 0 : return m_pStream->GetErrorCode();
228 : }
229 :
230 : // virtual
231 0 : ErrCode SvLockBytes::SetSize(sal_Size nSize)
232 : {
233 0 : if (!m_pStream)
234 : {
235 : OSL_FAIL("SvLockBytes::SetSize(): Bad stream");
236 0 : return ERRCODE_NONE;
237 : }
238 :
239 0 : m_pStream->SetStreamSize(nSize);
240 0 : return m_pStream->GetErrorCode();
241 : }
242 :
243 0 : ErrCode SvLockBytes::Stat(SvLockBytesStat * pStat, SvLockBytesStatFlag) const
244 : {
245 0 : if (!m_pStream)
246 : {
247 : OSL_FAIL("SvLockBytes::Stat(): Bad stream");
248 0 : return ERRCODE_NONE;
249 : }
250 :
251 0 : if (pStat)
252 : {
253 0 : sal_Size nPos = m_pStream->Tell();
254 0 : pStat->nSize = m_pStream->Seek(STREAM_SEEK_TO_END);
255 0 : m_pStream->Seek(nPos);
256 : }
257 0 : return ERRCODE_NONE;
258 : }
259 :
260 : // class SvOpenLockBytes
261 :
262 0 : TYPEINIT1(SvOpenLockBytes, SvLockBytes);
263 :
264 : // class SvAsyncLockBytes
265 :
266 0 : TYPEINIT1(SvAsyncLockBytes, SvOpenLockBytes);
267 :
268 : // virtual
269 0 : ErrCode SvAsyncLockBytes::ReadAt(sal_Size nPos, void * pBuffer, sal_Size nCount,
270 : sal_Size * pRead) const
271 : {
272 0 : if (m_bTerminated)
273 0 : return SvOpenLockBytes::ReadAt(nPos, pBuffer, nCount, pRead);
274 : else
275 : {
276 0 : sal_Size nTheCount = std::min(nPos < m_nSize ? m_nSize - nPos : 0, nCount);
277 : ErrCode nError = SvOpenLockBytes::ReadAt(nPos, pBuffer, nTheCount,
278 0 : pRead);
279 0 : return !nCount || nTheCount == nCount || nError ? nError :
280 0 : ERRCODE_IO_PENDING;
281 : }
282 : }
283 :
284 : // virtual
285 0 : ErrCode SvAsyncLockBytes::WriteAt(sal_Size nPos, const void * pBuffer,
286 : sal_Size nCount, sal_Size * pWritten)
287 : {
288 0 : if (m_bTerminated)
289 0 : return SvOpenLockBytes::WriteAt(nPos, pBuffer, nCount, pWritten);
290 : else
291 : {
292 0 : sal_Size nTheCount = std::min(nPos < m_nSize ? m_nSize - nPos : 0, nCount);
293 : ErrCode nError = SvOpenLockBytes::WriteAt(nPos, pBuffer, nTheCount,
294 0 : pWritten);
295 0 : return !nCount || nTheCount == nCount || nError ? nError :
296 0 : ERRCODE_IO_PENDING;
297 : }
298 : }
299 :
300 : // virtual
301 0 : ErrCode SvAsyncLockBytes::FillAppend(const void * pBuffer, sal_Size nCount,
302 : sal_Size * pWritten)
303 : {
304 : sal_Size nTheWritten;
305 : ErrCode nError = SvOpenLockBytes::WriteAt(m_nSize, pBuffer, nCount,
306 0 : &nTheWritten);
307 0 : if (!nError)
308 0 : m_nSize += nTheWritten;
309 0 : if (pWritten)
310 0 : *pWritten = nTheWritten;
311 0 : return nError;
312 : }
313 :
314 : // virtual
315 0 : sal_Size SvAsyncLockBytes::Seek(sal_Size nPos)
316 : {
317 0 : if (nPos != STREAM_SEEK_TO_END)
318 0 : m_nSize = nPos;
319 0 : return m_nSize;
320 : }
321 :
322 : // class SvStream
323 :
324 41040 : sal_Size SvStream::GetData( void* pData, sal_Size nSize )
325 : {
326 41040 : if( !GetError() )
327 : {
328 : DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
329 : sal_Size nRet;
330 41034 : nError = xLockBytes->ReadAt( nActPos, pData, nSize, &nRet );
331 41034 : nActPos += nRet;
332 41034 : return nRet;
333 : }
334 6 : else return 0;
335 : }
336 :
337 3843 : sal_Size SvStream::PutData( const void* pData, sal_Size nSize )
338 : {
339 3843 : if( !GetError() )
340 : {
341 : DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
342 : sal_Size nRet;
343 3843 : nError = xLockBytes->WriteAt( nActPos, pData, nSize, &nRet );
344 3843 : nActPos += nRet;
345 3843 : return nRet;
346 : }
347 0 : else return 0;
348 : }
349 :
350 90150 : sal_Size SvStream::SeekPos( sal_Size nPos )
351 : {
352 90150 : if( !GetError() && nPos == STREAM_SEEK_TO_END )
353 : {
354 : DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
355 14168 : SvLockBytesStat aStat;
356 14168 : xLockBytes->Stat( &aStat, SVSTATFLAG_DEFAULT );
357 14168 : nActPos = aStat.nSize;
358 : }
359 : else
360 75982 : nActPos = nPos;
361 90150 : return nActPos;
362 : }
363 :
364 12376 : void SvStream::FlushData()
365 : {
366 12376 : if( !GetError() )
367 : {
368 : DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
369 10422 : nError = xLockBytes->Flush();
370 : }
371 12376 : }
372 :
373 1376 : void SvStream::SetSize( sal_Size nSize )
374 : {
375 : DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
376 1376 : nError = xLockBytes->SetSize( nSize );
377 1376 : }
378 :
379 29254 : void SvStream::ImpInit()
380 : {
381 29254 : nActPos = 0;
382 29254 : nCompressMode = COMPRESSMODE_NONE;
383 29254 : eStreamCharSet = osl_getThreadTextEncoding();
384 29254 : nCryptMask = 0;
385 29254 : bIsEof = sal_False;
386 : #if defined UNX
387 29254 : eLineDelimiter = LINEEND_LF; // UNIX-Format
388 : #else
389 : eLineDelimiter = LINEEND_CRLF; // DOS-Format
390 : #endif
391 :
392 29254 : SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
393 :
394 29254 : nBufFilePos = 0;
395 29254 : nBufActualPos = 0;
396 29254 : bIsDirty = sal_False;
397 29254 : bIsConsistent = sal_True;
398 29254 : bIsWritable = sal_True;
399 :
400 29254 : pRWBuf = 0;
401 29254 : pBufPos = 0;
402 29254 : nBufSize = 0;
403 29254 : nBufActualLen = 0;
404 29254 : eIOMode = STREAM_IO_DONTKNOW;
405 29254 : nBufFree = 0;
406 :
407 29254 : eStreamMode = 0;
408 :
409 29254 : nVersion = 0;
410 :
411 29254 : ClearError();
412 29254 : }
413 :
414 12290 : SvStream::SvStream( SvLockBytes* pLockBytesP )
415 : {
416 : DBG_CTOR( Stream, NULL );
417 :
418 12290 : ImpInit();
419 12290 : xLockBytes = pLockBytesP;
420 : const SvStream* pStrm;
421 12290 : if( pLockBytesP ) {
422 12290 : pStrm = pLockBytesP->GetStream();
423 12290 : if( pStrm ) {
424 0 : SetError( pStrm->GetErrorCode() );
425 : }
426 : }
427 12290 : SetBufferSize( 256 );
428 12290 : }
429 :
430 16964 : SvStream::SvStream()
431 : {
432 : DBG_CTOR( Stream, NULL );
433 :
434 16964 : ImpInit();
435 16964 : }
436 :
437 67558 : SvStream::~SvStream()
438 : {
439 : DBG_DTOR( Stream, NULL );
440 :
441 27982 : if ( xLockBytes.Is() )
442 11594 : Flush();
443 :
444 27982 : if( pRWBuf )
445 22055 : delete[] pRWBuf;
446 39576 : }
447 :
448 0 : sal_uInt16 SvStream::IsA() const
449 : {
450 0 : return (sal_uInt16)ID_STREAM;
451 : }
452 :
453 37500 : void SvStream::ClearError()
454 : {
455 37500 : bIsEof = sal_False;
456 37500 : nError = SVSTREAM_OK;
457 37500 : }
458 :
459 3432904 : void SvStream::SetError( sal_uInt32 nErrorCode )
460 : {
461 3432904 : if ( nError == SVSTREAM_OK )
462 3432720 : nError = nErrorCode;
463 3432904 : }
464 :
465 68495 : void SvStream::SetNumberFormatInt( sal_uInt16 nNewFormat )
466 : {
467 68495 : nNumberFormatInt = nNewFormat;
468 68495 : bSwap = sal_False;
469 : #ifdef OSL_BIGENDIAN
470 : if( nNumberFormatInt == NUMBERFORMAT_INT_LITTLEENDIAN )
471 : bSwap = sal_True;
472 : #else
473 68495 : if( nNumberFormatInt == NUMBERFORMAT_INT_BIGENDIAN )
474 410 : bSwap = sal_True;
475 : #endif
476 68495 : }
477 :
478 44289 : void SvStream::SetBufferSize( sal_uInt16 nBufferSize )
479 : {
480 44289 : sal_Size nActualFilePos = Tell();
481 44289 : sal_Bool bDontSeek = (sal_Bool)(pRWBuf == 0);
482 :
483 44289 : if( bIsDirty && bIsConsistent && bIsWritable ) // due to Windows NT: Access denied
484 16 : Flush();
485 :
486 44289 : if( nBufSize )
487 : {
488 14742 : delete[] pRWBuf;
489 14742 : nBufFilePos += nBufActualPos;
490 : }
491 :
492 44289 : pRWBuf = 0;
493 44289 : nBufActualLen = 0;
494 44289 : nBufActualPos = 0;
495 44289 : nBufSize = nBufferSize;
496 44289 : if( nBufSize )
497 38069 : pRWBuf = new sal_uInt8[ nBufSize ];
498 44289 : bIsConsistent = sal_True;
499 44289 : pBufPos = pRWBuf;
500 44289 : eIOMode = STREAM_IO_DONTKNOW;
501 44289 : if( !bDontSeek )
502 14742 : SeekPos( nActualFilePos );
503 44289 : }
504 :
505 2608 : void SvStream::ClearBuffer()
506 : {
507 2608 : nBufActualLen = 0;
508 2608 : nBufActualPos = 0;
509 2608 : nBufFilePos = 0;
510 2608 : pBufPos = pRWBuf;
511 2608 : bIsDirty = sal_False;
512 2608 : bIsConsistent = sal_True;
513 2608 : eIOMode = STREAM_IO_DONTKNOW;
514 :
515 2608 : bIsEof = sal_False;
516 2608 : }
517 :
518 5824 : void SvStream::ResetError()
519 : {
520 5824 : ClearError();
521 5824 : }
522 :
523 380 : sal_Bool SvStream::ReadByteStringLine( rtl::OUString& rStr, rtl_TextEncoding eSrcCharSet,
524 : sal_Int32 nMaxBytesToRead )
525 : {
526 380 : rtl::OString aStr;
527 380 : sal_Bool bRet = ReadLine( aStr, nMaxBytesToRead);
528 380 : rStr = rtl::OStringToOUString(aStr, eSrcCharSet);
529 380 : return bRet;
530 : }
531 :
532 0 : sal_Bool SvStream::ReadByteStringLine( String& rStr, rtl_TextEncoding eSrcCharSet )
533 : {
534 0 : rtl::OString aStr;
535 0 : sal_Bool bRet = ReadLine(aStr);
536 0 : rStr = rtl::OStringToOUString(aStr, eSrcCharSet);
537 0 : return bRet;
538 : }
539 :
540 60120 : sal_Bool SvStream::ReadLine( rtl::OString& rStr, sal_Int32 nMaxBytesToRead )
541 : {
542 : sal_Char buf[256+1];
543 60120 : sal_Bool bEnd = sal_False;
544 60120 : sal_Size nOldFilePos = Tell();
545 60120 : sal_Char c = 0;
546 60120 : sal_Size nTotalLen = 0;
547 :
548 60120 : rtl::OStringBuffer aBuf(4096);
549 180292 : while( !bEnd && !GetError() ) // Don't test for EOF as we
550 : // are reading block-wise!
551 : {
552 60150 : sal_uInt16 nLen = (sal_uInt16)Read( buf, sizeof(buf)-1 );
553 60150 : if ( !nLen )
554 : {
555 98 : if ( aBuf.getLength() == 0 )
556 : {
557 : // Exit on first block-read error
558 92 : bIsEof = sal_True;
559 92 : rStr = rtl::OString();
560 92 : return sal_False;
561 : }
562 : else
563 6 : break;
564 : }
565 :
566 : sal_uInt16 j, n;
567 1567485 : for( j = n = 0; j < nLen ; ++j )
568 : {
569 1567455 : c = buf[j];
570 1567455 : if ( c == '\n' || c == '\r' )
571 : {
572 60022 : bEnd = sal_True;
573 60022 : break;
574 : }
575 1507433 : if ( n < j )
576 0 : buf[n] = c;
577 1507433 : ++n;
578 : }
579 60052 : nTotalLen += j;
580 60052 : if (nTotalLen > static_cast<sal_Size>(nMaxBytesToRead))
581 : {
582 0 : n -= nTotalLen - nMaxBytesToRead;
583 0 : nTotalLen = nMaxBytesToRead;
584 0 : bEnd = sal_True;
585 : }
586 60052 : if ( n )
587 51272 : aBuf.append(buf, n);
588 : }
589 :
590 60028 : if ( !bEnd && !GetError() && aBuf.getLength() )
591 6 : bEnd = sal_True;
592 :
593 60028 : nOldFilePos += nTotalLen;
594 60028 : if( Tell() > nOldFilePos )
595 60022 : nOldFilePos++;
596 60028 : Seek( nOldFilePos ); // Seek pointer due to BlockRead above
597 :
598 60028 : if ( bEnd && (c=='\r' || c=='\n') ) // Special treatment for DOS files
599 : {
600 : char cTemp;
601 60022 : sal_Size nLen = Read((char*)&cTemp , sizeof(cTemp) );
602 60022 : if ( nLen ) {
603 59922 : if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
604 59922 : Seek( nOldFilePos );
605 : }
606 : }
607 :
608 60028 : if ( bEnd )
609 60028 : bIsEof = sal_False;
610 60028 : rStr = aBuf.makeStringAndClear();
611 60028 : return bEnd;
612 : }
613 :
614 0 : sal_Bool SvStream::ReadUniStringLine( rtl::OUString& rStr, sal_Int32 nMaxCodepointsToRead )
615 : {
616 : sal_Unicode buf[256+1];
617 0 : sal_Bool bEnd = sal_False;
618 0 : sal_Size nOldFilePos = Tell();
619 0 : sal_Unicode c = 0;
620 0 : sal_Size nTotalLen = 0;
621 :
622 : DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "ReadUniStringLine: swapping sizeof(sal_Unicode) not implemented" );
623 :
624 0 : rtl::OUStringBuffer aBuf(4096);
625 0 : while( !bEnd && !GetError() ) // Don't test for EOF as we
626 : // are reading block-wise!
627 : {
628 0 : sal_uInt16 nLen = (sal_uInt16)Read( (char*)buf, sizeof(buf)-sizeof(sal_Unicode) );
629 0 : nLen /= sizeof(sal_Unicode);
630 0 : if ( !nLen )
631 : {
632 0 : if ( aBuf.getLength() == 0 )
633 : {
634 : // exit on first BlockRead error
635 0 : bIsEof = sal_True;
636 0 : rStr = rtl::OUString();
637 0 : return sal_False;
638 : }
639 : else
640 0 : break;
641 : }
642 :
643 : sal_uInt16 j, n;
644 0 : for( j = n = 0; j < nLen ; ++j )
645 : {
646 0 : if ( bSwap )
647 0 : SwapUShort( buf[n] );
648 0 : c = buf[j];
649 0 : if ( c == '\n' || c == '\r' )
650 : {
651 0 : bEnd = sal_True;
652 0 : break;
653 : }
654 : // erAck 26.02.01: Old behavior was no special treatment of '\0'
655 : // character here, but a following rStr+=c did ignore it. Is this
656 : // really intended? Or should a '\0' better terminate a line?
657 : // The nOldFilePos stuff wasn't correct then anyways.
658 0 : if ( c )
659 : {
660 0 : if ( n < j )
661 0 : buf[n] = c;
662 0 : ++n;
663 : }
664 : }
665 0 : nTotalLen += j;
666 0 : if (nTotalLen > static_cast<sal_Size>(nMaxCodepointsToRead))
667 : {
668 0 : n -= nTotalLen - nMaxCodepointsToRead;
669 0 : nTotalLen = nMaxCodepointsToRead;
670 0 : bEnd = sal_True;
671 : }
672 0 : if ( n )
673 0 : aBuf.append( buf, n );
674 : }
675 :
676 0 : if ( !bEnd && !GetError() && aBuf.getLength() )
677 0 : bEnd = sal_True;
678 :
679 0 : nOldFilePos += nTotalLen * sizeof(sal_Unicode);
680 0 : if( Tell() > nOldFilePos )
681 0 : nOldFilePos += sizeof(sal_Unicode);
682 0 : Seek( nOldFilePos ); // seek due to BlockRead above
683 :
684 0 : if ( bEnd && (c=='\r' || c=='\n') ) // special treatment for DOS files
685 : {
686 : sal_Unicode cTemp;
687 0 : Read( (char*)&cTemp, sizeof(cTemp) );
688 0 : if ( bSwap )
689 0 : SwapUShort( cTemp );
690 0 : if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
691 0 : Seek( nOldFilePos );
692 : }
693 :
694 0 : if ( bEnd )
695 0 : bIsEof = sal_False;
696 0 : rStr = aBuf.makeStringAndClear();
697 0 : return bEnd;
698 : }
699 :
700 380 : sal_Bool SvStream::ReadUniOrByteStringLine( rtl::OUString& rStr, rtl_TextEncoding eSrcCharSet,
701 : sal_Int32 nMaxCodepointsToRead )
702 : {
703 380 : if ( eSrcCharSet == RTL_TEXTENCODING_UNICODE )
704 0 : return ReadUniStringLine( rStr, nMaxCodepointsToRead );
705 : else
706 380 : return ReadByteStringLine( rStr, eSrcCharSet, nMaxCodepointsToRead );
707 : }
708 :
709 4 : rtl::OString read_zeroTerminated_uInt8s_ToOString(SvStream& rStream)
710 : {
711 4 : rtl::OStringBuffer aOutput(256);
712 :
713 : sal_Char buf[ 256 + 1 ];
714 4 : sal_Bool bEnd = sal_False;
715 4 : sal_Size nFilePos = rStream.Tell();
716 :
717 12 : while( !bEnd && !rStream.GetError() )
718 : {
719 4 : sal_Size nLen = rStream.Read(buf, sizeof(buf)-1);
720 4 : if (!nLen)
721 0 : break;
722 :
723 4 : sal_Size nReallyRead = nLen;
724 4 : const sal_Char* pPtr = buf;
725 26 : while (nLen && *pPtr)
726 18 : ++pPtr, --nLen;
727 :
728 : bEnd = ( nReallyRead < sizeof(buf)-1 ) // read less than attempted to read
729 : || ( ( nLen > 0 ) // OR it is inside the block we read
730 : && ( 0 == *pPtr ) // AND found a string terminator
731 4 : );
732 :
733 4 : aOutput.append(buf, pPtr - buf);
734 : }
735 :
736 4 : nFilePos += aOutput.getLength();
737 4 : if (rStream.Tell() > nFilePos)
738 2 : rStream.Seek(nFilePos+1); // seek due to FileRead above
739 4 : return aOutput.makeStringAndClear();
740 : }
741 :
742 0 : rtl::OUString read_zeroTerminated_uInt8s_ToOUString(SvStream& rStream, rtl_TextEncoding eEnc)
743 : {
744 : return rtl::OStringToOUString(
745 0 : read_zeroTerminated_uInt8s_ToOString(rStream), eEnc);
746 : }
747 :
748 : /** Attempt to write a prefixed sequence of nUnits 16bit units from an OUString,
749 : returned value is number of bytes written */
750 59711 : sal_Size write_uInt16s_FromOUString(SvStream& rStrm, const rtl::OUString& rStr,
751 : sal_Size nUnits)
752 : {
753 : DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "write_uInt16s_FromOUString: swapping sizeof(sal_Unicode) not implemented" );
754 : sal_Size nWritten;
755 59711 : if (!rStrm.IsEndianSwap())
756 59711 : nWritten = rStrm.Write( (char*)rStr.getStr(), nUnits * sizeof(sal_Unicode) );
757 : else
758 : {
759 0 : sal_Size nLen = nUnits;
760 : sal_Unicode aBuf[384];
761 0 : sal_Unicode* const pTmp = ( nLen > 384 ? new sal_Unicode[nLen] : aBuf);
762 0 : memcpy( pTmp, rStr.getStr(), nLen * sizeof(sal_Unicode) );
763 0 : sal_Unicode* p = pTmp;
764 0 : const sal_Unicode* const pStop = pTmp + nLen;
765 0 : while ( p < pStop )
766 : {
767 0 : SwapUShort( *p );
768 0 : p++;
769 : }
770 0 : nWritten = rStrm.Write( (char*)pTmp, nLen * sizeof(sal_Unicode) );
771 0 : if ( pTmp != aBuf )
772 0 : delete [] pTmp;
773 : }
774 59711 : return nWritten;
775 : }
776 :
777 61 : sal_Bool SvStream::WriteUnicodeOrByteText( const String& rStr, rtl_TextEncoding eDestCharSet )
778 : {
779 61 : if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
780 : {
781 57 : write_uInt16s_FromOUString(*this, rStr, rStr.Len());
782 57 : return nError == SVSTREAM_OK;
783 : }
784 : else
785 : {
786 4 : rtl::OString aStr(rtl::OUStringToOString(rStr, eDestCharSet));
787 4 : write_uInt8s_FromOString(*this, aStr, aStr.getLength());
788 4 : return nError == SVSTREAM_OK;
789 : }
790 : }
791 :
792 0 : sal_Bool SvStream::WriteByteStringLine( const String& rStr, rtl_TextEncoding eDestCharSet )
793 : {
794 0 : return WriteLine(rtl::OUStringToOString(rStr, eDestCharSet));
795 : }
796 :
797 0 : sal_Bool SvStream::WriteLine(const rtl::OString& rStr)
798 : {
799 0 : Write(rStr.getStr(), rStr.getLength());
800 0 : endl(*this);
801 0 : return nError == SVSTREAM_OK;
802 : }
803 :
804 0 : sal_Bool SvStream::WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet )
805 : {
806 0 : if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
807 0 : *this << ch;
808 : else
809 : {
810 0 : rtl::OString aStr(&ch, 1, eDestCharSet);
811 0 : Write(aStr.getStr(), aStr.getLength());
812 : }
813 0 : return nError == SVSTREAM_OK;
814 : }
815 :
816 0 : sal_Bool SvStream::StartWritingUnicodeText()
817 : {
818 0 : SetEndianSwap( sal_False ); // write native format
819 : // BOM, Byte Order Mark, U+FEFF, see
820 : // http://www.unicode.org/faq/utf_bom.html#BOM
821 : // Upon read: 0xfeff(-257) => no swap; 0xfffe(-2) => swap
822 0 : *this << sal_uInt16( 0xfeff );
823 0 : return nError == SVSTREAM_OK;
824 : }
825 :
826 4 : sal_Bool SvStream::StartReadingUnicodeText( rtl_TextEncoding eReadBomCharSet )
827 : {
828 4 : if (!( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
829 : eReadBomCharSet == RTL_TEXTENCODING_UNICODE ||
830 4 : eReadBomCharSet == RTL_TEXTENCODING_UTF8))
831 4 : return sal_True; // nothing to read
832 :
833 0 : bool bTryUtf8 = false;
834 : sal_uInt16 nFlag;
835 0 : sal_sSize nBack = sizeof(nFlag);
836 0 : *this >> nFlag;
837 0 : switch ( nFlag )
838 : {
839 : case 0xfeff :
840 : // native UTF-16
841 0 : if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
842 : eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
843 0 : nBack = 0;
844 0 : break;
845 : case 0xfffe :
846 : // swapped UTF-16
847 0 : if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
848 : eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
849 : {
850 0 : SetEndianSwap( !bSwap );
851 0 : nBack = 0;
852 : }
853 0 : break;
854 : case 0xefbb :
855 0 : if (nNumberFormatInt == NUMBERFORMAT_INT_BIGENDIAN &&
856 : (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
857 : eReadBomCharSet == RTL_TEXTENCODING_UTF8))
858 0 : bTryUtf8 = true;
859 0 : break;
860 : case 0xbbef :
861 0 : if (nNumberFormatInt == NUMBERFORMAT_INT_LITTLEENDIAN &&
862 : (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
863 : eReadBomCharSet == RTL_TEXTENCODING_UTF8))
864 0 : bTryUtf8 = true;
865 0 : break;
866 : default:
867 : ; // nothing
868 : }
869 0 : if (bTryUtf8)
870 : {
871 : sal_uChar nChar;
872 0 : nBack += sizeof(nChar);
873 0 : *this >> nChar;
874 0 : if (nChar == 0xbf)
875 0 : nBack = 0; // it is UTF-8
876 : }
877 0 : if (nBack)
878 0 : SeekRel( -nBack ); // no BOM, pure data
879 0 : return nError == SVSTREAM_OK;
880 : }
881 :
882 610811 : sal_Size SvStream::SeekRel( sal_sSize nPos )
883 : {
884 610811 : sal_Size nActualPos = Tell();
885 :
886 610811 : if ( nPos >= 0 )
887 : {
888 544389 : if ( SAL_MAX_SIZE - nActualPos > (sal_Size)nPos )
889 544389 : nActualPos += nPos;
890 : }
891 : else
892 : {
893 66422 : sal_Size nAbsPos = (sal_Size)-nPos;
894 66422 : if ( nActualPos >= nAbsPos )
895 66422 : nActualPos -= nAbsPos;
896 : }
897 :
898 610811 : pBufPos = pRWBuf + nActualPos;
899 610811 : return Seek( nActualPos );
900 : }
901 :
902 2996035 : SvStream& SvStream::operator>>(sal_uInt16& r)
903 : {
904 2996035 : sal_uInt16 n = 0;
905 2996035 : READNUMBER_WITHOUT_SWAP(sal_uInt16, n)
906 2996035 : if (good())
907 : {
908 2992125 : if (bSwap)
909 3676 : SwapUShort(n);
910 2992125 : r = n;
911 : }
912 2996035 : return *this;
913 : }
914 :
915 797869 : SvStream& SvStream::operator>>(sal_uInt32& r)
916 : {
917 797869 : sal_uInt32 n = 0;
918 797869 : READNUMBER_WITHOUT_SWAP(sal_uInt32, n)
919 797869 : if (good())
920 : {
921 797227 : if (bSwap)
922 4808 : SwapULong(n);
923 797227 : r = n;
924 : }
925 797869 : return *this;
926 : }
927 :
928 0 : SvStream& SvStream::operator>>(sal_uInt64& r)
929 : {
930 0 : sal_uInt64 n = 0;
931 0 : READNUMBER_WITHOUT_SWAP(sal_uInt64, n)
932 0 : if (good())
933 : {
934 0 : if (bSwap)
935 0 : SwapUInt64(n);
936 0 : r = n;
937 : }
938 0 : return *this;
939 : }
940 :
941 366728 : SvStream& SvStream::operator>>(sal_Int16& r)
942 : {
943 366728 : sal_Int16 n = 0;
944 366728 : READNUMBER_WITHOUT_SWAP(sal_Int16, n)
945 366728 : if (good())
946 : {
947 123100 : if (bSwap)
948 5672 : SwapShort(n);
949 123100 : r = n;
950 : }
951 366728 : return *this;
952 : }
953 :
954 483201 : SvStream& SvStream::operator>>(sal_Int32& r)
955 : {
956 483201 : sal_Int32 n = 0;
957 483201 : READNUMBER_WITHOUT_SWAP(sal_Int32, n)
958 483201 : if (good())
959 : {
960 459919 : if (bSwap)
961 1334 : SwapLongInt(n);
962 459919 : r = n;
963 : }
964 483201 : return *this;
965 : }
966 :
967 0 : SvStream& SvStream::operator>>(sal_Int64& r)
968 : {
969 0 : sal_Int64 n = 0;
970 0 : READNUMBER_WITHOUT_SWAP(sal_Int64, n)
971 0 : if (good())
972 : {
973 0 : if (bSwap)
974 0 : SwapInt64(n);
975 0 : r = n;
976 : }
977 0 : return *this;
978 : }
979 :
980 168 : SvStream& SvStream::operator>>( signed char& r )
981 : {
982 168 : if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
983 : sizeof(signed char) <= nBufFree )
984 : {
985 0 : r = *pBufPos;
986 0 : nBufActualPos += sizeof(signed char);
987 0 : pBufPos += sizeof(signed char);
988 0 : nBufFree -= sizeof(signed char);
989 : }
990 : else
991 168 : Read( (char*)&r, sizeof(signed char) );
992 168 : return *this;
993 : }
994 :
995 : // Special treatment for Chars due to PutBack
996 :
997 2260144 : SvStream& SvStream::operator>>( char& r )
998 : {
999 2260144 : if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
1000 : sizeof(char) <= nBufFree )
1001 : {
1002 2206340 : r = *pBufPos;
1003 2206340 : nBufActualPos += sizeof(char);
1004 2206340 : pBufPos += sizeof(char);
1005 2206340 : nBufFree -= sizeof(char);
1006 : }
1007 : else
1008 53804 : Read( (char*)&r, sizeof(char) );
1009 2260144 : return *this;
1010 : }
1011 :
1012 4183056 : SvStream& SvStream::operator>>( unsigned char& r )
1013 : {
1014 4183056 : if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
1015 : sizeof(char) <= nBufFree )
1016 : {
1017 3925578 : r = *pBufPos;
1018 3925578 : nBufActualPos += sizeof(char);
1019 3925578 : pBufPos += sizeof(char);
1020 3925578 : nBufFree -= sizeof(char);
1021 : }
1022 : else
1023 257478 : Read( (char*)&r, sizeof(char) );
1024 4183056 : return *this;
1025 : }
1026 :
1027 516 : SvStream& SvStream::operator>>(float& r)
1028 : {
1029 516 : float n = 0;
1030 516 : READNUMBER_WITHOUT_SWAP(float, n)
1031 516 : if (good())
1032 : {
1033 : #if defined UNX
1034 516 : if (bSwap)
1035 0 : SwapFloat(n);
1036 : #endif
1037 516 : r = n;
1038 : }
1039 516 : return *this;
1040 : }
1041 :
1042 10680 : SvStream& SvStream::operator>>(double& r)
1043 : {
1044 10680 : double n = 0;
1045 10680 : READNUMBER_WITHOUT_SWAP(double, n)
1046 10680 : if (good())
1047 : {
1048 : #if defined UNX
1049 10680 : if (bSwap)
1050 0 : SwapDouble(n);
1051 : #endif
1052 10680 : r = n;
1053 : }
1054 10680 : return *this;
1055 : }
1056 :
1057 8 : SvStream& SvStream::operator>> ( SvStream& rStream )
1058 : {
1059 8 : const sal_uInt32 cBufLen = 0x8000;
1060 8 : char* pBuf = new char[ cBufLen ];
1061 :
1062 : sal_uInt32 nCount;
1063 8 : do {
1064 8 : nCount = Read( pBuf, cBufLen );
1065 8 : rStream.Write( pBuf, nCount );
1066 : } while( nCount == cBufLen );
1067 :
1068 8 : delete[] pBuf;
1069 8 : return *this;
1070 : }
1071 :
1072 2405841 : SvStream& SvStream::operator<< ( sal_uInt16 v )
1073 : {
1074 2405841 : if( bSwap )
1075 0 : SwapUShort(v);
1076 2405841 : WRITENUMBER_WITHOUT_SWAP(sal_uInt16,v)
1077 2405841 : return *this;
1078 : }
1079 :
1080 781114 : SvStream& SvStream::operator<< ( sal_uInt32 v )
1081 : {
1082 781114 : if( bSwap )
1083 704 : SwapULong(v);
1084 781114 : WRITENUMBER_WITHOUT_SWAP(sal_uInt32,v)
1085 781114 : return *this;
1086 : }
1087 :
1088 0 : SvStream& SvStream::operator<< ( sal_uInt64 v )
1089 : {
1090 0 : if( bSwap )
1091 0 : SwapUInt64(v);
1092 0 : WRITENUMBER_WITHOUT_SWAP(sal_uInt64,v)
1093 0 : return *this;
1094 : }
1095 :
1096 90056 : SvStream& SvStream::operator<< ( sal_Int16 v )
1097 : {
1098 90056 : if( bSwap )
1099 0 : SwapShort(v);
1100 90056 : WRITENUMBER_WITHOUT_SWAP(sal_Int16,v)
1101 90056 : return *this;
1102 : }
1103 :
1104 299220 : SvStream& SvStream::operator<< ( sal_Int32 v )
1105 : {
1106 299220 : if( bSwap )
1107 0 : SwapLongInt(v);
1108 299220 : WRITENUMBER_WITHOUT_SWAP(sal_Int32,v)
1109 299220 : return *this;
1110 : }
1111 :
1112 0 : SvStream& SvStream::operator<< ( sal_Int64 v )
1113 : {
1114 0 : if( bSwap )
1115 0 : SwapInt64(v);
1116 0 : WRITENUMBER_WITHOUT_SWAP(sal_Int64,v)
1117 0 : return *this;
1118 : }
1119 :
1120 0 : SvStream& SvStream::operator<< ( signed char v )
1121 : {
1122 : //SDO
1123 0 : int tmp = eIOMode;
1124 0 : if(tmp == STREAM_IO_WRITE && sizeof(signed char) <= nBufFree )
1125 : {
1126 0 : *pBufPos = v;
1127 0 : pBufPos++; // sizeof(char);
1128 0 : nBufActualPos++;
1129 0 : if( nBufActualPos > nBufActualLen ) // Append ?
1130 0 : nBufActualLen = nBufActualPos;
1131 0 : nBufFree--; // = sizeof(char);
1132 0 : bIsDirty = sal_True;
1133 : }
1134 : else
1135 0 : Write( (char*)&v, sizeof(signed char) );
1136 0 : return *this;
1137 : }
1138 :
1139 : // Special treatment for Chars due to PutBack
1140 :
1141 112672 : SvStream& SvStream::operator<< ( char v )
1142 : {
1143 : //SDO
1144 112672 : int tmp = eIOMode;
1145 112672 : if(tmp == STREAM_IO_WRITE && sizeof(char) <= nBufFree )
1146 : {
1147 110886 : *pBufPos = v;
1148 110886 : pBufPos++; // sizeof(char);
1149 110886 : nBufActualPos++;
1150 110886 : if( nBufActualPos > nBufActualLen ) // Append ?
1151 110886 : nBufActualLen = nBufActualPos;
1152 110886 : nBufFree--; // = sizeof(char);
1153 110886 : bIsDirty = sal_True;
1154 : }
1155 : else
1156 1786 : Write( (char*)&v, sizeof(char) );
1157 112672 : return *this;
1158 : }
1159 :
1160 397672 : SvStream& SvStream::operator<< ( unsigned char v )
1161 : {
1162 : //SDO
1163 397672 : int tmp = eIOMode;
1164 397672 : if(tmp == STREAM_IO_WRITE && sizeof(char) <= nBufFree )
1165 : {
1166 383512 : *(unsigned char*)pBufPos = v;
1167 383512 : pBufPos++; // = sizeof(char);
1168 383512 : nBufActualPos++; // = sizeof(char);
1169 383512 : if( nBufActualPos > nBufActualLen ) // Append ?
1170 383512 : nBufActualLen = nBufActualPos;
1171 383512 : nBufFree--;
1172 383512 : bIsDirty = sal_True;
1173 : }
1174 : else
1175 14160 : Write( (char*)&v, sizeof(char) );
1176 397672 : return *this;
1177 : }
1178 :
1179 72 : SvStream& SvStream::operator<< ( float v )
1180 : {
1181 : #ifdef UNX
1182 72 : if( bSwap )
1183 0 : SwapFloat(v);
1184 : #endif
1185 72 : WRITENUMBER_WITHOUT_SWAP(float,v)
1186 72 : return *this;
1187 : }
1188 :
1189 302 : SvStream& SvStream::operator<< ( const double& r )
1190 : {
1191 : #if defined UNX
1192 302 : if( bSwap )
1193 : {
1194 0 : double nHelp = r;
1195 0 : SwapDouble(nHelp);
1196 0 : WRITENUMBER_WITHOUT_SWAP(double,nHelp)
1197 0 : return *this;
1198 : }
1199 : else
1200 : #endif
1201 302 : WRITENUMBER_WITHOUT_SWAP(double,r)
1202 :
1203 302 : return *this;
1204 : }
1205 :
1206 12168 : SvStream& SvStream::operator<< ( const char* pBuf )
1207 : {
1208 12168 : Write( pBuf, strlen( pBuf ) );
1209 12168 : return *this;
1210 : }
1211 :
1212 0 : SvStream& SvStream::operator<< ( const unsigned char* pBuf )
1213 : {
1214 0 : Write( (char*)pBuf, strlen( (char*)pBuf ) );
1215 0 : return *this;
1216 : }
1217 :
1218 8 : SvStream& SvStream::operator<< ( SvStream& rStream )
1219 : {
1220 8 : const sal_uInt32 cBufLen = 0x8000;
1221 8 : char* pBuf = new char[ cBufLen ];
1222 : sal_uInt32 nCount;
1223 8 : do {
1224 8 : nCount = rStream.Read( pBuf, cBufLen );
1225 8 : Write( pBuf, nCount );
1226 : } while( nCount == cBufLen );
1227 :
1228 8 : delete[] pBuf;
1229 8 : return *this;
1230 : }
1231 :
1232 129096 : rtl::OUString SvStream::ReadUniOrByteString( rtl_TextEncoding eSrcCharSet )
1233 : {
1234 : // read UTF-16 string directly from stream ?
1235 129096 : if (eSrcCharSet == RTL_TEXTENCODING_UNICODE)
1236 14464 : return read_lenPrefixed_uInt16s_ToOUString<sal_uInt32>(*this);
1237 114632 : return read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(*this, eSrcCharSet);
1238 : }
1239 :
1240 142798 : SvStream& SvStream::WriteUniOrByteString( const rtl::OUString& rStr, rtl_TextEncoding eDestCharSet )
1241 : {
1242 : // write UTF-16 string directly into stream ?
1243 142798 : if (eDestCharSet == RTL_TEXTENCODING_UNICODE)
1244 15368 : write_lenPrefixed_uInt16s_FromOUString<sal_uInt32>(*this, rStr);
1245 : else
1246 127430 : write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(*this, rStr, eDestCharSet);
1247 142798 : return *this;
1248 : }
1249 :
1250 3169411 : sal_Size SvStream::Read( void* pData, sal_Size nCount )
1251 : {
1252 3169411 : sal_Size nSaveCount = nCount;
1253 3169411 : if( !bIsConsistent )
1254 0 : RefreshBuffer();
1255 :
1256 3169411 : if( !pRWBuf )
1257 : {
1258 2042981 : nCount = GetData( (char*)pData,nCount);
1259 2042981 : if( nCryptMask )
1260 0 : EncryptBuffer(pData, nCount);
1261 2042981 : nBufFilePos += nCount;
1262 : }
1263 : else
1264 : {
1265 : // check if block is completely within buffer
1266 1126430 : eIOMode = STREAM_IO_READ;
1267 1126430 : if( nCount <= (sal_Size)(nBufActualLen - nBufActualPos ) )
1268 : {
1269 : // => yes
1270 674896 : memcpy(pData, pBufPos, (size_t) nCount);
1271 674896 : nBufActualPos = nBufActualPos + (sal_uInt16)nCount;
1272 674896 : pBufPos += nCount;
1273 674896 : nBufFree = nBufFree - (sal_uInt16)nCount;
1274 : }
1275 : else
1276 : {
1277 451534 : if( bIsDirty ) // Does stream require a flush?
1278 : {
1279 66 : SeekPos( nBufFilePos );
1280 66 : if( nCryptMask )
1281 0 : CryptAndWriteBuffer(pRWBuf, nBufActualLen);
1282 : else
1283 66 : PutData( pRWBuf, nBufActualLen );
1284 66 : bIsDirty = sal_False;
1285 : }
1286 :
1287 : // Does data block fit into buffer?
1288 451534 : if( nCount > nBufSize )
1289 : {
1290 : // => No! Thus read directly
1291 : // into target area without using the buffer
1292 :
1293 8397 : eIOMode = STREAM_IO_DONTKNOW;
1294 :
1295 8397 : SeekPos( nBufFilePos + nBufActualPos );
1296 8397 : nBufActualLen = 0;
1297 8397 : pBufPos = pRWBuf;
1298 8397 : nCount = GetData( (char*)pData, nCount );
1299 8397 : if( nCryptMask )
1300 0 : EncryptBuffer(pData, nCount);
1301 8397 : nBufFilePos += nCount;
1302 8397 : nBufFilePos += nBufActualPos;
1303 8397 : nBufActualPos = 0;
1304 : }
1305 : else
1306 : {
1307 : // => Yes. Fill buffer first, then copy to target area
1308 :
1309 443137 : nBufFilePos += nBufActualPos;
1310 443137 : SeekPos( nBufFilePos );
1311 :
1312 : // TODO: Typecast before GetData, sal_uInt16 nCountTmp
1313 443137 : sal_Size nCountTmp = GetData( pRWBuf, nBufSize );
1314 443137 : if( nCryptMask )
1315 0 : EncryptBuffer(pRWBuf, nCountTmp);
1316 443137 : nBufActualLen = (sal_uInt16)nCountTmp;
1317 443137 : if( nCount > nCountTmp )
1318 : {
1319 390077 : nCount = nCountTmp; // trim count back, EOF see below
1320 : }
1321 443137 : memcpy( pData, pRWBuf, (size_t)nCount );
1322 443137 : nBufActualPos = (sal_uInt16)nCount;
1323 443137 : pBufPos = pRWBuf + nCount;
1324 : }
1325 : }
1326 : }
1327 3169411 : bIsEof = sal_False;
1328 3169411 : nBufFree = nBufActualLen - nBufActualPos;
1329 3169411 : if( nCount != nSaveCount && nError != ERRCODE_IO_PENDING )
1330 440105 : bIsEof = sal_True;
1331 3169411 : if( nCount == nSaveCount && nError == ERRCODE_IO_PENDING )
1332 0 : nError = ERRCODE_NONE;
1333 3169411 : return nCount;
1334 : }
1335 :
1336 1639897 : sal_Size SvStream::Write( const void* pData, sal_Size nCount )
1337 : {
1338 1639897 : if( !nCount )
1339 52808 : return 0;
1340 1587089 : if( !bIsWritable )
1341 : {
1342 0 : SetError( ERRCODE_IO_CANTWRITE );
1343 0 : return 0;
1344 : }
1345 1587089 : if( !bIsConsistent )
1346 0 : RefreshBuffer(); // Remove changes in buffer through PutBack
1347 :
1348 1587089 : if( !pRWBuf )
1349 : {
1350 67732 : if( nCryptMask )
1351 0 : nCount = CryptAndWriteBuffer( pData, nCount );
1352 : else
1353 67732 : nCount = PutData( (char*)pData, nCount );
1354 67732 : nBufFilePos += nCount;
1355 67732 : return nCount;
1356 : }
1357 :
1358 1519357 : eIOMode = STREAM_IO_WRITE;
1359 1519357 : if( nCount <= (sal_Size)(nBufSize - nBufActualPos) )
1360 : {
1361 1496963 : memcpy( pBufPos, pData, (size_t)nCount );
1362 1496963 : nBufActualPos = nBufActualPos + (sal_uInt16)nCount;
1363 : // Update length if buffer was updated
1364 1496963 : if( nBufActualPos > nBufActualLen )
1365 1495857 : nBufActualLen = nBufActualPos;
1366 :
1367 1496963 : pBufPos += nCount;
1368 1496963 : bIsDirty = sal_True;
1369 : }
1370 : else
1371 : {
1372 : // Does stream require flushing?
1373 22394 : if( bIsDirty )
1374 : {
1375 21176 : SeekPos( nBufFilePos );
1376 21176 : if( nCryptMask )
1377 0 : CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
1378 : else
1379 21176 : PutData( pRWBuf, nBufActualLen );
1380 21176 : bIsDirty = sal_False;
1381 : }
1382 :
1383 : // Does data block fit into buffer?
1384 22394 : if( nCount > nBufSize )
1385 : {
1386 1798 : eIOMode = STREAM_IO_DONTKNOW;
1387 1798 : nBufFilePos += nBufActualPos;
1388 1798 : nBufActualLen = 0;
1389 1798 : nBufActualPos = 0;
1390 1798 : pBufPos = pRWBuf;
1391 1798 : SeekPos( nBufFilePos );
1392 1798 : if( nCryptMask )
1393 0 : nCount = CryptAndWriteBuffer( pData, nCount );
1394 : else
1395 1798 : nCount = PutData( (char*)pData, nCount );
1396 1798 : nBufFilePos += nCount;
1397 : }
1398 : else
1399 : {
1400 : // Copy block to buffer
1401 20596 : memcpy( pRWBuf, pData, (size_t)nCount );
1402 :
1403 : // Mind the order!
1404 20596 : nBufFilePos += nBufActualPos;
1405 20596 : nBufActualPos = (sal_uInt16)nCount;
1406 20596 : pBufPos = pRWBuf + nCount;
1407 20596 : nBufActualLen = (sal_uInt16)nCount;
1408 20596 : bIsDirty = sal_True;
1409 : }
1410 : }
1411 1519357 : nBufFree = nBufSize - nBufActualPos;
1412 1519357 : return nCount;
1413 : }
1414 :
1415 3608652 : sal_Size SvStream::Seek( sal_Size nFilePos )
1416 : {
1417 3608652 : eIOMode = STREAM_IO_DONTKNOW;
1418 :
1419 3608652 : bIsEof = sal_False;
1420 3608652 : if( !pRWBuf )
1421 : {
1422 1502903 : nBufFilePos = SeekPos( nFilePos );
1423 : DBG_ASSERT(Tell()==nBufFilePos,"Out Of Sync!");
1424 1502903 : return nBufFilePos;
1425 : }
1426 :
1427 : // Is seek position within buffer?
1428 2105749 : if( nFilePos >= nBufFilePos && nFilePos <= (nBufFilePos + nBufActualLen))
1429 : {
1430 668554 : nBufActualPos = (sal_uInt16)(nFilePos - nBufFilePos);
1431 668554 : pBufPos = pRWBuf + nBufActualPos;
1432 : // Update nBufFree to avoid crash upon PutBack
1433 668554 : nBufFree = nBufActualLen - nBufActualPos;
1434 : }
1435 : else
1436 : {
1437 1437195 : if( bIsDirty && bIsConsistent)
1438 : {
1439 1268707 : SeekPos( nBufFilePos );
1440 1268707 : if( nCryptMask )
1441 0 : CryptAndWriteBuffer( pRWBuf, nBufActualLen );
1442 : else
1443 1268707 : PutData( pRWBuf, nBufActualLen );
1444 1268707 : bIsDirty = sal_False;
1445 : }
1446 1437195 : nBufActualLen = 0;
1447 1437195 : nBufActualPos = 0;
1448 1437195 : pBufPos = pRWBuf;
1449 1437195 : nBufFilePos = SeekPos( nFilePos );
1450 : }
1451 : #ifdef OV_DEBUG
1452 : {
1453 : sal_Size nDebugTemp = nBufFilePos + nBufActualPos;
1454 : DBG_ASSERT(Tell()==nDebugTemp,"Sync?");
1455 : }
1456 : #endif
1457 2105749 : return nBufFilePos + nBufActualPos;
1458 : }
1459 :
1460 : //STREAM_SEEK_TO_END in the some of the Seek backends is special cased to be
1461 : //efficient, in others e.g. SotStorageStream it's really horribly slow, and in
1462 : //those this should be overridden
1463 0 : sal_Size SvStream::remainingSize()
1464 : {
1465 0 : sal_Size nCurr = Tell();
1466 0 : sal_Size nEnd = Seek(STREAM_SEEK_TO_END);
1467 0 : sal_Size nMaxAvailable = nEnd-nCurr;
1468 0 : Seek(nCurr);
1469 0 : return nMaxAvailable;
1470 : }
1471 :
1472 30428 : void SvStream::Flush()
1473 : {
1474 30428 : if( bIsDirty && bIsConsistent )
1475 : {
1476 1890 : SeekPos( nBufFilePos );
1477 1890 : if( nCryptMask )
1478 0 : CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
1479 : else
1480 1890 : if( PutData( pRWBuf, nBufActualLen ) != nBufActualLen )
1481 6 : SetError( SVSTREAM_WRITE_ERROR );
1482 1890 : bIsDirty = sal_False;
1483 : }
1484 30428 : if( bIsWritable )
1485 26658 : FlushData();
1486 30428 : }
1487 :
1488 0 : void SvStream::RefreshBuffer()
1489 : {
1490 0 : if( bIsDirty && bIsConsistent )
1491 : {
1492 0 : SeekPos( nBufFilePos );
1493 0 : if( nCryptMask )
1494 0 : CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
1495 : else
1496 0 : PutData( pRWBuf, nBufActualLen );
1497 0 : bIsDirty = sal_False;
1498 : }
1499 0 : SeekPos( nBufFilePos );
1500 0 : nBufActualLen = (sal_uInt16)GetData( pRWBuf, nBufSize );
1501 0 : if( nBufActualLen && nError == ERRCODE_IO_PENDING )
1502 0 : nError = ERRCODE_NONE;
1503 0 : if( nCryptMask )
1504 0 : EncryptBuffer(pRWBuf, (sal_Size)nBufActualLen);
1505 0 : bIsConsistent = sal_True;
1506 0 : eIOMode = STREAM_IO_DONTKNOW;
1507 0 : }
1508 :
1509 0 : SvStream& SvStream::WriteNumber(sal_Int32 nInt32)
1510 : {
1511 : char buffer[12];
1512 0 : sal_Size nLen = sprintf(buffer, "%" SAL_PRIdINT32, nInt32);
1513 0 : Write(buffer, nLen);
1514 0 : return *this;
1515 : }
1516 :
1517 0 : SvStream& SvStream::WriteNumber(sal_uInt32 nUInt32)
1518 : {
1519 : char buffer[11];
1520 0 : sal_Size nLen = sprintf(buffer, "%" SAL_PRIuUINT32, nUInt32);
1521 0 : Write(buffer, nLen);
1522 0 : return *this;
1523 : }
1524 :
1525 : #define CRYPT_BUFSIZE 1024
1526 :
1527 : /// Encrypt and write
1528 0 : sal_Size SvStream::CryptAndWriteBuffer( const void* pStart, sal_Size nLen)
1529 : {
1530 : unsigned char pTemp[CRYPT_BUFSIZE];
1531 0 : unsigned char* pDataPtr = (unsigned char*)pStart;
1532 0 : sal_Size nCount = 0;
1533 : sal_Size nBufCount;
1534 0 : unsigned char nMask = nCryptMask;
1535 0 : do
1536 : {
1537 0 : if( nLen >= CRYPT_BUFSIZE )
1538 0 : nBufCount = CRYPT_BUFSIZE;
1539 : else
1540 0 : nBufCount = nLen;
1541 0 : nLen -= nBufCount;
1542 0 : memcpy( pTemp, pDataPtr, (sal_uInt16)nBufCount );
1543 : // **** Verschluesseln *****
1544 0 : for ( sal_uInt16 n=0; n < CRYPT_BUFSIZE; n++ )
1545 : {
1546 0 : unsigned char aCh = pTemp[n];
1547 0 : aCh ^= nMask;
1548 0 : SWAPNIBBLES(aCh)
1549 0 : pTemp[n] = aCh;
1550 : }
1551 : // *************************
1552 0 : nCount += PutData( (char*)pTemp, nBufCount );
1553 0 : pDataPtr += nBufCount;
1554 : }
1555 : while ( nLen );
1556 0 : return nCount;
1557 : }
1558 :
1559 0 : sal_Bool SvStream::EncryptBuffer(void* pStart, sal_Size nLen)
1560 : {
1561 0 : unsigned char* pTemp = (unsigned char*)pStart;
1562 0 : unsigned char nMask = nCryptMask;
1563 :
1564 0 : for ( sal_Size n=0; n < nLen; n++, pTemp++ )
1565 : {
1566 0 : unsigned char aCh = *pTemp;
1567 0 : SWAPNIBBLES(aCh)
1568 0 : aCh ^= nMask;
1569 0 : *pTemp = aCh;
1570 : }
1571 0 : return sal_True;
1572 : }
1573 :
1574 12 : unsigned char implGetCryptMask(const sal_Char* pStr, sal_Int32 nLen, long nVersion)
1575 : {
1576 12 : unsigned char nCryptMask = 0;
1577 :
1578 12 : if (!nLen)
1579 12 : return nCryptMask;
1580 :
1581 0 : if( nVersion <= SOFFICE_FILEFORMAT_31 )
1582 : {
1583 0 : while( nLen )
1584 : {
1585 0 : nCryptMask ^= *pStr;
1586 0 : pStr++;
1587 0 : nLen--;
1588 : }
1589 : }
1590 : else // BugFix #25888#
1591 : {
1592 0 : for( sal_uInt16 i = 0; i < nLen; i++ ) {
1593 0 : nCryptMask ^= pStr[i];
1594 0 : if( nCryptMask & 0x80 ) {
1595 0 : nCryptMask <<= 1;
1596 0 : nCryptMask++;
1597 : }
1598 : else
1599 0 : nCryptMask <<= 1;
1600 : }
1601 : }
1602 :
1603 0 : if( !nCryptMask )
1604 0 : nCryptMask = 67;
1605 :
1606 0 : return nCryptMask;
1607 : }
1608 :
1609 12 : void SvStream::SetCryptMaskKey(const rtl::OString& rCryptMaskKey)
1610 : {
1611 12 : m_aCryptMaskKey = rCryptMaskKey;
1612 : nCryptMask = implGetCryptMask(m_aCryptMaskKey.getStr(),
1613 12 : m_aCryptMaskKey.getLength(), GetVersion());
1614 12 : }
1615 :
1616 432 : void SvStream::SyncSvStream( sal_Size nNewStreamPos )
1617 : {
1618 432 : ClearBuffer();
1619 432 : SvStream::nBufFilePos = nNewStreamPos;
1620 432 : }
1621 :
1622 432 : void SvStream::SyncSysStream()
1623 : {
1624 432 : Flush();
1625 432 : SeekPos( Tell() );
1626 432 : }
1627 :
1628 1458 : sal_Bool SvStream::SetStreamSize( sal_Size nSize )
1629 : {
1630 : #ifdef DBG_UTIL
1631 : sal_Size nFPos = Tell();
1632 : #endif
1633 1458 : sal_uInt16 nBuf = nBufSize;
1634 1458 : SetBufferSize( 0 );
1635 1458 : SetSize( nSize );
1636 1458 : SetBufferSize( nBuf );
1637 : DBG_ASSERT(Tell()==nFPos,"SetStreamSize failed");
1638 1458 : return (sal_Bool)(nError == 0);
1639 : }
1640 :
1641 0 : SvStream& endl( SvStream& rStr )
1642 : {
1643 0 : LineEnd eDelim = rStr.GetLineDelimiter();
1644 0 : if ( eDelim == LINEEND_CR )
1645 0 : rStr << _CR;
1646 0 : else if( eDelim == LINEEND_LF )
1647 0 : rStr << _LF;
1648 : else
1649 0 : rStr << _CR << _LF;
1650 0 : return rStr;
1651 : }
1652 :
1653 0 : SvStream& endlu( SvStream& rStrm )
1654 : {
1655 0 : switch ( rStrm.GetLineDelimiter() )
1656 : {
1657 : case LINEEND_CR :
1658 0 : rStrm << sal_Unicode(_CR);
1659 0 : break;
1660 : case LINEEND_LF :
1661 0 : rStrm << sal_Unicode(_LF);
1662 0 : break;
1663 : default:
1664 0 : rStrm << sal_Unicode(_CR) << sal_Unicode(_LF);
1665 : }
1666 0 : return rStrm;
1667 : }
1668 :
1669 0 : SvStream& endlub( SvStream& rStrm )
1670 : {
1671 0 : if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
1672 0 : return endlu( rStrm );
1673 : else
1674 0 : return endl( rStrm );
1675 : }
1676 :
1677 3832 : SvMemoryStream::SvMemoryStream( void* pBuffer, sal_Size bufSize,
1678 3832 : StreamMode eMode )
1679 : {
1680 3832 : if( eMode & STREAM_WRITE )
1681 1180 : bIsWritable = sal_True;
1682 : else
1683 2652 : bIsWritable = sal_False;
1684 3832 : nEndOfData = bufSize;
1685 3832 : bOwnsData = sal_False;
1686 3832 : pBuf = (sal_uInt8 *) pBuffer;
1687 3832 : nResize = 0L;
1688 3832 : nSize = bufSize;
1689 3832 : nPos = 0L;
1690 3832 : SetBufferSize( 0 );
1691 3832 : }
1692 :
1693 10043 : SvMemoryStream::SvMemoryStream( sal_Size nInitSize, sal_Size nResizeOffset )
1694 : {
1695 10043 : bIsWritable = sal_True;
1696 10043 : bOwnsData = sal_True;
1697 10043 : nEndOfData = 0L;
1698 10043 : nResize = nResizeOffset;
1699 10043 : nPos = 0;
1700 10043 : pBuf = 0;
1701 10043 : if( nResize != 0 && nResize < 16 )
1702 0 : nResize = 16;
1703 10043 : if( nInitSize && !AllocateMemory( nInitSize ) )
1704 : {
1705 0 : SetError( SVSTREAM_OUTOFMEMORY );
1706 0 : nSize = 0;
1707 : }
1708 : else
1709 10043 : nSize = nInitSize;
1710 10043 : SetBufferSize( 64 );
1711 10043 : }
1712 :
1713 28223 : SvMemoryStream::~SvMemoryStream()
1714 : {
1715 13869 : if( pBuf )
1716 : {
1717 13633 : if( bOwnsData )
1718 9755 : FreeMemory();
1719 : else
1720 3878 : Flush();
1721 : }
1722 14354 : }
1723 :
1724 0 : sal_uInt16 SvMemoryStream::IsA() const
1725 : {
1726 0 : return (sal_uInt16)ID_MEMORYSTREAM;
1727 : }
1728 :
1729 138 : void* SvMemoryStream::SetBuffer( void* pNewBuf, sal_Size nCount,
1730 : sal_Bool bOwnsDat, sal_Size nEOF )
1731 : {
1732 : void* pResult;
1733 138 : SetBufferSize( 0 ); // Buffering in der Basisklasse initialisieren
1734 138 : Seek( 0 );
1735 138 : if( bOwnsData )
1736 : {
1737 138 : pResult = 0;
1738 138 : if( pNewBuf != pBuf )
1739 138 : FreeMemory();
1740 : }
1741 : else
1742 0 : pResult = pBuf;
1743 :
1744 138 : pBuf = (sal_uInt8 *) pNewBuf;
1745 138 : nPos = 0;
1746 138 : nSize = nCount;
1747 138 : nResize = 0;
1748 138 : bOwnsData = bOwnsDat;
1749 :
1750 138 : if( nEOF > nCount )
1751 0 : nEOF = nCount;
1752 138 : nEndOfData = nEOF;
1753 :
1754 138 : ResetError();
1755 :
1756 : DBG_ASSERT( nEndOfData<STREAM_SEEK_TO_END,"Invalid EOF");
1757 138 : return pResult;
1758 : }
1759 :
1760 376811 : sal_Size SvMemoryStream::GetData( void* pData, sal_Size nCount )
1761 : {
1762 376811 : sal_Size nMaxCount = nEndOfData-nPos;
1763 376811 : if( nCount > nMaxCount )
1764 230831 : nCount = nMaxCount;
1765 376811 : memcpy( pData, pBuf+nPos, (size_t)nCount );
1766 376811 : nPos += nCount;
1767 376811 : return nCount;
1768 : }
1769 :
1770 1353744 : sal_Size SvMemoryStream::PutData( const void* pData, sal_Size nCount )
1771 : {
1772 1353744 : if( GetError() )
1773 0 : return 0L;
1774 :
1775 1353744 : sal_Size nMaxCount = nSize-nPos;
1776 :
1777 : // check for overflow
1778 1353744 : if( nCount > nMaxCount )
1779 : {
1780 2528 : if( nResize == 0 )
1781 : {
1782 : // copy as much as possible
1783 0 : nCount = nMaxCount;
1784 0 : SetError( SVSTREAM_OUTOFMEMORY );
1785 : }
1786 : else
1787 : {
1788 : long nNewResize;
1789 2528 : if( nSize && nSize > nResize )
1790 1870 : nNewResize = nSize;
1791 : else
1792 658 : nNewResize = nResize;
1793 :
1794 2528 : if( (nCount-nMaxCount) < nResize )
1795 : {
1796 : // lacking memory is smaller than nResize,
1797 : // resize accordingly
1798 2234 : if( !ReAllocateMemory( nNewResize) )
1799 : {
1800 0 : nCount = 0;
1801 0 : SetError( SVSTREAM_WRITE_ERROR );
1802 : }
1803 : }
1804 : else
1805 : {
1806 : // lacking memory is larger than nResize,
1807 : // resize by (nCoount-nMaxCount) + resize offset
1808 294 : if( !ReAllocateMemory( nCount-nMaxCount+nNewResize ) )
1809 : {
1810 0 : nCount = 0;
1811 0 : SetError( SVSTREAM_WRITE_ERROR );
1812 : }
1813 : }
1814 : }
1815 : }
1816 : DBG_ASSERT(pBuf,"Possibly Reallocate failed");
1817 1353744 : memcpy( pBuf+nPos, pData, (size_t)nCount);
1818 :
1819 1353744 : nPos += nCount;
1820 1353744 : if( nPos > nEndOfData )
1821 844652 : nEndOfData = nPos;
1822 1353744 : return nCount;
1823 : }
1824 :
1825 2926581 : sal_Size SvMemoryStream::SeekPos( sal_Size nNewPos )
1826 : {
1827 : // nEndOfData: First position in stream not allowed to read from
1828 : // nSize: Size of allocated buffer
1829 :
1830 2926581 : if( nNewPos < nEndOfData )
1831 1012822 : nPos = nNewPos;
1832 1913759 : else if( nNewPos == STREAM_SEEK_TO_END )
1833 6089 : nPos = nEndOfData;
1834 : else
1835 : {
1836 1907670 : if( nNewPos >= nSize ) // Does buffer need extension?
1837 : {
1838 550 : if( nResize ) // Is extension possible?
1839 : {
1840 526 : long nDiff = (long)(nNewPos - nSize + 1);
1841 526 : nDiff += (long)nResize;
1842 526 : ReAllocateMemory( nDiff );
1843 526 : nPos = nNewPos;
1844 526 : nEndOfData = nNewPos;
1845 : }
1846 : else // Extension not possible, set pos to end of data
1847 : {
1848 : // SetError( SVSTREAM_OUTOFMEMORY );
1849 24 : nPos = nEndOfData;
1850 : }
1851 : }
1852 : else // Expand buffer size
1853 : {
1854 1907120 : nPos = nNewPos;
1855 1907120 : nEndOfData = nNewPos;
1856 : }
1857 : }
1858 2926581 : return nPos;
1859 : }
1860 :
1861 13017 : void SvMemoryStream::FlushData()
1862 : {
1863 13017 : }
1864 :
1865 158 : void SvMemoryStream::ResetError()
1866 : {
1867 158 : SvStream::ClearError();
1868 158 : }
1869 :
1870 9825 : sal_Bool SvMemoryStream::AllocateMemory( sal_Size nNewSize )
1871 : {
1872 9825 : pBuf = new sal_uInt8[nNewSize];
1873 9825 : return( pBuf != 0 );
1874 : }
1875 :
1876 : // (using Bozo algorithm)
1877 3054 : sal_Bool SvMemoryStream::ReAllocateMemory( long nDiff )
1878 : {
1879 3054 : sal_Bool bRetVal = sal_False;
1880 3054 : long nTemp = (long)nSize;
1881 3054 : nTemp += nDiff;
1882 3054 : sal_Size nNewSize = (sal_Size)nTemp;
1883 :
1884 3054 : if( nNewSize )
1885 : {
1886 3054 : sal_uInt8* pNewBuf = new sal_uInt8[nNewSize];
1887 :
1888 3054 : if( pNewBuf )
1889 : {
1890 3054 : bRetVal = sal_True; // Success!
1891 3054 : if( nNewSize < nSize ) // Are we shrinking?
1892 : {
1893 0 : memcpy( pNewBuf, pBuf, (size_t)nNewSize );
1894 0 : if( nPos > nNewSize )
1895 0 : nPos = 0L;
1896 0 : if( nEndOfData >= nNewSize )
1897 0 : nEndOfData = nNewSize-1L;
1898 : }
1899 : else
1900 : {
1901 3054 : memcpy( pNewBuf, pBuf, (size_t)nSize );
1902 : }
1903 :
1904 3054 : FreeMemory();
1905 :
1906 3054 : pBuf = pNewBuf;
1907 3054 : nSize = nNewSize;
1908 : }
1909 : }
1910 : else
1911 : {
1912 0 : bRetVal = sal_True;
1913 0 : FreeMemory();
1914 0 : pBuf = 0;
1915 0 : nSize = 0;
1916 0 : nEndOfData = 0;
1917 0 : nPos = 0;
1918 : }
1919 :
1920 3054 : return bRetVal;
1921 : }
1922 :
1923 12947 : void SvMemoryStream::FreeMemory()
1924 : {
1925 12947 : delete[] pBuf;
1926 12947 : }
1927 :
1928 18 : void* SvMemoryStream::SwitchBuffer( sal_Size nInitSize, sal_Size nResizeOffset)
1929 : {
1930 18 : Flush();
1931 18 : if( !bOwnsData )
1932 0 : return 0;
1933 18 : Seek( STREAM_SEEK_TO_BEGIN );
1934 :
1935 18 : void* pRetVal = pBuf;
1936 18 : pBuf = 0;
1937 18 : nEndOfData = 0L;
1938 18 : nResize = nResizeOffset;
1939 18 : nPos = 0;
1940 :
1941 18 : if( nResize != 0 && nResize < 16 )
1942 0 : nResize = 16;
1943 :
1944 18 : ResetError();
1945 :
1946 18 : if( nInitSize && !AllocateMemory(nInitSize) )
1947 : {
1948 0 : SetError( SVSTREAM_OUTOFMEMORY );
1949 0 : nSize = 0;
1950 : }
1951 : else
1952 18 : nSize = nInitSize;
1953 :
1954 18 : SetBufferSize( 64 );
1955 18 : return pRetVal;
1956 : }
1957 :
1958 0 : void SvMemoryStream::SetSize( sal_Size nNewSize )
1959 : {
1960 0 : long nDiff = (long)nNewSize - (long)nSize;
1961 0 : ReAllocateMemory( nDiff );
1962 0 : }
1963 :
1964 0 : TYPEINIT0 ( SvDataCopyStream )
1965 :
1966 0 : void SvDataCopyStream::Assign( const SvDataCopyStream& )
1967 : {
1968 0 : }
1969 :
1970 : //Create a OString of nLen bytes from rStream
1971 148070 : rtl::OString read_uInt8s_ToOString(SvStream& rStrm, sal_Size nLen)
1972 : {
1973 148070 : rtl_String *pStr = NULL;
1974 148070 : if (nLen)
1975 : {
1976 70980 : nLen = std::min(nLen, static_cast<sal_Size>(SAL_MAX_INT32));
1977 : //alloc a (ref-count 1) rtl_String of the desired length.
1978 : //rtl_String's buffer is uninitialized, except for null termination
1979 70980 : pStr = rtl_string_alloc(sal::static_int_cast<sal_Int32>(nLen));
1980 70980 : sal_Size nWasRead = rStrm.Read(pStr->buffer, nLen);
1981 70980 : if (nWasRead != nLen)
1982 : {
1983 : //on (typically unlikely) short read set length to what we could
1984 : //read, and null terminate. Excess buffer capacity remains of
1985 : //course, could create a (true) replacement OString if it matters.
1986 8 : pStr->length = sal::static_int_cast<sal_Int32>(nWasRead);
1987 8 : pStr->buffer[pStr->length] = 0;
1988 : }
1989 : }
1990 :
1991 : //take ownership of buffer and return, otherwise return empty string
1992 148070 : return pStr ? rtl::OString(pStr, SAL_NO_ACQUIRE) : rtl::OString();
1993 : }
1994 :
1995 : //Create a OUString of nLen sal_Unicodes from rStream
1996 62254 : rtl::OUString read_uInt16s_ToOUString(SvStream& rStrm, sal_Size nLen)
1997 : {
1998 62254 : rtl_uString *pStr = NULL;
1999 62254 : if (nLen)
2000 : {
2001 60440 : nLen = std::min(nLen, static_cast<sal_Size>(SAL_MAX_INT32));
2002 : //alloc a (ref-count 1) rtl_uString of the desired length.
2003 : //rtl_String's buffer is uninitialized, except for null termination
2004 60440 : pStr = rtl_uString_alloc(sal::static_int_cast<sal_Int32>(nLen));
2005 60440 : sal_Size nWasRead = rStrm.Read(pStr->buffer, nLen*2)/2;
2006 60440 : if (nWasRead != nLen)
2007 : {
2008 : //on (typically unlikely) short read set length to what we could
2009 : //read, and null terminate. Excess buffer capacity remains of
2010 : //course, could create a (true) replacement OUString if it matters.
2011 8 : pStr->length = sal::static_int_cast<sal_Int32>(nWasRead);
2012 8 : pStr->buffer[pStr->length] = 0;
2013 : }
2014 60440 : if (rStrm.IsEndianSwap())
2015 : {
2016 0 : for (sal_Int32 i = 0; i < pStr->length; ++i)
2017 0 : pStr->buffer[i] = OSL_SWAPWORD(pStr->buffer[i]);
2018 : }
2019 : }
2020 :
2021 : //take ownership of buffer and return, otherwise return empty string
2022 62254 : return pStr ? rtl::OUString(pStr, SAL_NO_ACQUIRE) : rtl::OUString();
2023 : }
2024 :
2025 : namespace
2026 : {
2027 17102 : template <typename T, typename O> T tmpl_convertLineEnd(const T &rIn, LineEnd eLineEnd)
2028 : {
2029 : // Determine linebreaks and compute length
2030 17102 : bool bConvert = false; // Needs conversion
2031 17102 : sal_Int32 nStrLen = rIn.getLength();
2032 17102 : sal_Int32 nLineEndLen = (eLineEnd == LINEEND_CRLF) ? 2 : 1;
2033 17102 : sal_Int32 nLen = 0; // Target length
2034 17102 : sal_Int32 i = 0; // Source counter
2035 :
2036 162848 : while (i < nStrLen)
2037 : {
2038 : // \r or \n causes linebreak
2039 128644 : if ( (rIn[i] == _CR) || (rIn[i] == _LF) )
2040 : {
2041 1538 : nLen = nLen + nLineEndLen;
2042 :
2043 : // If set already, skip expensive test
2044 1538 : if ( !bConvert )
2045 : {
2046 : // Muessen wir Konvertieren
2047 1538 : if ( ((eLineEnd != LINEEND_LF) && (rIn[i] == _LF)) ||
2048 : ((eLineEnd == LINEEND_CRLF) && (rIn[i+1] != _LF)) ||
2049 : ((eLineEnd == LINEEND_LF) &&
2050 : ((rIn[i] == _CR) || (rIn[i+1] == _CR))) ||
2051 : ((eLineEnd == LINEEND_CR) &&
2052 : ((rIn[i] == _LF) || (rIn[i+1] == _LF))) )
2053 630 : bConvert = true;
2054 : }
2055 :
2056 : // skip char if \r\n oder \n\r
2057 1538 : if ( ((rIn[i+1] == _CR) || (rIn[i+1] == _LF)) &&
2058 : (rIn[i] != rIn[i+1]) )
2059 0 : ++i;
2060 : }
2061 : else
2062 127106 : ++nLen;
2063 128644 : ++i;
2064 : }
2065 :
2066 17102 : if (!bConvert)
2067 16472 : return rIn;
2068 :
2069 : // convert linebreaks, insert string
2070 630 : O aNewData(nLen);
2071 630 : i = 0;
2072 1890 : while (i < nStrLen)
2073 : {
2074 : // \r or \n causes linebreak
2075 630 : if ( (rIn[i] == _CR) || (rIn[i] == _LF) )
2076 : {
2077 630 : if ( eLineEnd == LINEEND_CRLF )
2078 : {
2079 0 : aNewData.append(_CR);
2080 0 : aNewData.append(_LF);
2081 : }
2082 : else
2083 : {
2084 630 : if ( eLineEnd == LINEEND_CR )
2085 0 : aNewData.append(_CR);
2086 : else
2087 630 : aNewData.append(_LF);
2088 : }
2089 :
2090 630 : if ( ((rIn[i+1] == _CR) || (rIn[i+1] == _LF)) &&
2091 : (rIn[i] != rIn[i+1]) )
2092 0 : ++i;
2093 : }
2094 : else
2095 : {
2096 0 : aNewData.append(rIn[i]);
2097 : }
2098 :
2099 630 : ++i;
2100 : }
2101 :
2102 630 : return aNewData.makeStringAndClear();
2103 : }
2104 : }
2105 :
2106 0 : rtl::OString convertLineEnd(const rtl::OString &rIn, LineEnd eLineEnd)
2107 : {
2108 0 : return tmpl_convertLineEnd<rtl::OString, rtl::OStringBuffer>(rIn, eLineEnd);
2109 : }
2110 :
2111 17102 : rtl::OUString convertLineEnd(const rtl::OUString &rIn, LineEnd eLineEnd)
2112 : {
2113 17102 : return tmpl_convertLineEnd<rtl::OUString, rtl::OUStringBuffer>(rIn, eLineEnd);
2114 : }
2115 :
2116 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|