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>
27 : #include <stdlib.h>
28 :
29 : #include <osl/endian.h>
30 : #include <osl/diagnose.h>
31 : #include <sal/log.hxx>
32 :
33 : #include <comphelper/string.hxx>
34 :
35 : #define SWAPNIBBLES(c) \
36 : unsigned char nSwapTmp=c; \
37 : nSwapTmp <<= 4; \
38 : c >>= 4; \
39 : c |= nSwapTmp;
40 :
41 : #include <tools/debug.hxx>
42 : #include <tools/stream.hxx>
43 : #include <osl/thread.h>
44 : #include <algorithm>
45 :
46 : // !!! Do not inline if already the operators <<,>> are inline
47 11053 : inline static void SwapUShort( sal_uInt16& r )
48 11053 : { r = OSL_SWAPWORD(r); }
49 30112 : inline static void SwapShort( short& r )
50 30112 : { r = OSL_SWAPWORD(r); }
51 101853 : inline static void SwapULong( sal_uInt32& r )
52 101853 : { r = OSL_SWAPDWORD(r); }
53 31725 : inline static void SwapLongInt( sal_Int32& r )
54 31725 : { r = OSL_SWAPDWORD(r); }
55 :
56 0 : inline static void SwapUInt64( sal_uInt64& r )
57 : {
58 : union
59 : {
60 : sal_uInt64 n;
61 : sal_uInt32 c[2];
62 : } s;
63 :
64 0 : s.n = r;
65 0 : s.c[0] ^= s.c[1]; // swap the 32 bit words
66 0 : s.c[1] ^= s.c[0];
67 0 : s.c[0] ^= s.c[1];
68 : // swap the bytes in the words
69 0 : s.c[0] = OSL_SWAPDWORD(s.c[0]);
70 0 : s.c[1] = OSL_SWAPDWORD(s.c[1]);
71 0 : r = s.n;
72 0 : }
73 0 : inline static void SwapInt64( sal_Int64& r )
74 : {
75 : union
76 : {
77 : sal_Int64 n;
78 : sal_Int32 c[2];
79 : } s;
80 :
81 0 : s.n = r;
82 0 : s.c[0] ^= s.c[1]; // swap the 32 bit words
83 0 : s.c[1] ^= s.c[0];
84 0 : s.c[0] ^= s.c[1];
85 : // swap the bytes in the words
86 0 : s.c[0] = OSL_SWAPDWORD(s.c[0]);
87 0 : s.c[1] = OSL_SWAPDWORD(s.c[1]);
88 0 : r = s.n;
89 0 : }
90 :
91 : #ifdef UNX
92 0 : inline static void SwapFloat( float& r )
93 : {
94 : union
95 : {
96 : float f;
97 : sal_uInt32 c;
98 : } s;
99 :
100 0 : s.f = r;
101 0 : s.c = OSL_SWAPDWORD( s.c );
102 0 : r = s.f;
103 0 : }
104 :
105 0 : inline static void SwapDouble( double& r )
106 : {
107 : if( sizeof(double) != 8 )
108 : {
109 : DBG_ASSERT( false, "Can only swap 8-Byte-doubles\n" );
110 : }
111 : else
112 : {
113 : union
114 : {
115 : double d;
116 : sal_uInt32 c[2];
117 : } s;
118 :
119 0 : s.d = r;
120 0 : s.c[0] ^= s.c[1]; // swap 32-bit values in situ
121 0 : s.c[1] ^= s.c[0];
122 0 : s.c[0] ^= s.c[1];
123 0 : s.c[0] = OSL_SWAPDWORD(s.c[0]); // swap dword itself in situ
124 0 : s.c[1] = OSL_SWAPDWORD(s.c[1]);
125 0 : r = s.d;
126 : }
127 0 : }
128 : #endif
129 :
130 : //SDO
131 :
132 : #define READNUMBER_WITHOUT_SWAP(datatype,value) \
133 : if( bIoRead && sizeof(datatype)<=nBufFree) \
134 : { \
135 : for (std::size_t i = 0; i < sizeof(datatype); i++) \
136 : reinterpret_cast<char *>(&value)[i] = pBufPos[i]; \
137 : nBufActualPos += sizeof(datatype); \
138 : pBufPos += sizeof(datatype); \
139 : nBufFree -= sizeof(datatype); \
140 : } \
141 : else \
142 : { \
143 : Read( &value, sizeof(datatype) ); \
144 : } \
145 :
146 :
147 : #define WRITENUMBER_WITHOUT_SWAP(datatype,value) \
148 : if( bIoWrite && sizeof(datatype) <= nBufFree) \
149 : { \
150 : for (std::size_t i = 0; i < sizeof(datatype); i++) \
151 : pBufPos[i] = reinterpret_cast<char const *>(&value)[i]; \
152 : nBufFree -= sizeof(datatype); \
153 : nBufActualPos += sizeof(datatype); \
154 : if( nBufActualPos > nBufActualLen ) \
155 : nBufActualLen = nBufActualPos; \
156 : pBufPos += sizeof(datatype); \
157 : bIsDirty = true; \
158 : } \
159 : else \
160 : { \
161 : Write( &value, sizeof(datatype) ); \
162 : } \
163 :
164 : // class SvLockBytes
165 :
166 46722 : void SvLockBytes::close()
167 : {
168 46722 : if (m_bOwner)
169 0 : delete m_pStream;
170 46722 : m_pStream = 0;
171 46722 : }
172 :
173 0 : TYPEINIT0(SvLockBytes);
174 :
175 : // virtual
176 1 : ErrCode SvLockBytes::ReadAt(sal_uInt64 const nPos, void * pBuffer, sal_Size nCount,
177 : sal_Size * pRead) const
178 : {
179 1 : if (!m_pStream)
180 : {
181 : OSL_FAIL("SvLockBytes::ReadAt(): Bad stream");
182 0 : return ERRCODE_NONE;
183 : }
184 :
185 1 : m_pStream->Seek(nPos);
186 1 : sal_Size nTheRead = m_pStream->Read(pBuffer, nCount);
187 1 : if (pRead)
188 1 : *pRead = nTheRead;
189 1 : return m_pStream->GetErrorCode();
190 : }
191 :
192 : // virtual
193 0 : ErrCode SvLockBytes::WriteAt(sal_uInt64 const nPos, const void * pBuffer, sal_Size nCount,
194 : sal_Size * pWritten)
195 : {
196 0 : if (!m_pStream)
197 : {
198 : OSL_FAIL("SvLockBytes::WriteAt(): Bad stream");
199 0 : return ERRCODE_NONE;
200 : }
201 :
202 0 : m_pStream->Seek(nPos);
203 0 : sal_Size nTheWritten = m_pStream->Write(pBuffer, nCount);
204 0 : if (pWritten)
205 0 : *pWritten = nTheWritten;
206 0 : return m_pStream->GetErrorCode();
207 : }
208 :
209 : // virtual
210 0 : ErrCode SvLockBytes::Flush() const
211 : {
212 0 : if (!m_pStream)
213 : {
214 : OSL_FAIL("SvLockBytes::Flush(): Bad stream");
215 0 : return ERRCODE_NONE;
216 : }
217 :
218 0 : m_pStream->Flush();
219 0 : return m_pStream->GetErrorCode();
220 : }
221 :
222 : // virtual
223 0 : ErrCode SvLockBytes::SetSize(sal_uInt64 const nSize)
224 : {
225 0 : if (!m_pStream)
226 : {
227 : OSL_FAIL("SvLockBytes::SetSize(): Bad stream");
228 0 : return ERRCODE_NONE;
229 : }
230 :
231 0 : m_pStream->SetStreamSize(nSize);
232 0 : return m_pStream->GetErrorCode();
233 : }
234 :
235 0 : ErrCode SvLockBytes::Stat(SvLockBytesStat * pStat, SvLockBytesStatFlag) const
236 : {
237 0 : if (!m_pStream)
238 : {
239 : OSL_FAIL("SvLockBytes::Stat(): Bad stream");
240 0 : return ERRCODE_NONE;
241 : }
242 :
243 0 : if (pStat)
244 : {
245 0 : sal_uInt64 const nPos = m_pStream->Tell();
246 0 : pStat->nSize = m_pStream->Seek(STREAM_SEEK_TO_END);
247 0 : m_pStream->Seek(nPos);
248 : }
249 0 : return ERRCODE_NONE;
250 : }
251 :
252 : // class SvOpenLockBytes
253 :
254 0 : TYPEINIT1(SvOpenLockBytes, SvLockBytes);
255 :
256 : // class SvAsyncLockBytes
257 :
258 0 : TYPEINIT1(SvAsyncLockBytes, SvOpenLockBytes);
259 :
260 : // virtual
261 0 : ErrCode SvAsyncLockBytes::ReadAt(sal_uInt64 const nPos, void * pBuffer, sal_Size nCount,
262 : sal_Size * pRead) const
263 : {
264 0 : if (m_bTerminated)
265 0 : return SvOpenLockBytes::ReadAt(nPos, pBuffer, nCount, pRead);
266 : else
267 : {
268 : sal_Size nTheCount =
269 0 : std::min<sal_Size>(nPos < m_nSize ? m_nSize - nPos : 0, nCount);
270 : ErrCode nError = SvOpenLockBytes::ReadAt(nPos, pBuffer, nTheCount,
271 0 : pRead);
272 0 : return !nCount || nTheCount == nCount || nError ? nError :
273 0 : ERRCODE_IO_PENDING;
274 : }
275 : }
276 :
277 : // virtual
278 0 : ErrCode SvAsyncLockBytes::WriteAt(sal_uInt64 const nPos, const void * pBuffer,
279 : sal_Size nCount, sal_Size * pWritten)
280 : {
281 0 : if (m_bTerminated)
282 0 : return SvOpenLockBytes::WriteAt(nPos, pBuffer, nCount, pWritten);
283 : else
284 : {
285 : sal_Size nTheCount =
286 0 : std::min<sal_Size>(nPos < m_nSize ? m_nSize - nPos : 0, nCount);
287 : ErrCode nError = SvOpenLockBytes::WriteAt(nPos, pBuffer, nTheCount,
288 0 : pWritten);
289 0 : return !nCount || nTheCount == nCount || nError ? nError :
290 0 : ERRCODE_IO_PENDING;
291 : }
292 : }
293 :
294 : // virtual
295 0 : ErrCode SvAsyncLockBytes::FillAppend(const void * pBuffer, sal_Size nCount,
296 : sal_Size * pWritten)
297 : {
298 0 : sal_Size nTheWritten(0);
299 : ErrCode nError = SvOpenLockBytes::WriteAt(m_nSize, pBuffer, nCount,
300 0 : &nTheWritten);
301 0 : if (!nError)
302 0 : m_nSize += nTheWritten;
303 0 : if (pWritten)
304 0 : *pWritten = nTheWritten;
305 0 : return nError;
306 : }
307 :
308 : // virtual
309 0 : sal_uInt64 SvAsyncLockBytes::Seek(sal_uInt64 const nPos)
310 : {
311 : // check if a truncated STREAM_SEEK_TO_END was passed
312 : assert(nPos != SAL_MAX_UINT32);
313 0 : if (nPos != STREAM_SEEK_TO_END)
314 0 : m_nSize = nPos;
315 0 : return m_nSize;
316 : }
317 :
318 : // class SvStream
319 :
320 197533 : sal_Size SvStream::GetData( void* pData, sal_Size nSize )
321 : {
322 197533 : if( !GetError() )
323 : {
324 : DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
325 197387 : sal_Size nRet(0);
326 197387 : nError = xLockBytes->ReadAt(m_nActPos, pData, nSize, &nRet);
327 197387 : m_nActPos += nRet;
328 197387 : return nRet;
329 : }
330 146 : else return 0;
331 : }
332 :
333 41451 : sal_Size SvStream::PutData( const void* pData, sal_Size nSize )
334 : {
335 41451 : if( !GetError() )
336 : {
337 : DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
338 41450 : sal_Size nRet(0);
339 41450 : nError = xLockBytes->WriteAt(m_nActPos, pData, nSize, &nRet);
340 41450 : m_nActPos += nRet;
341 41450 : return nRet;
342 : }
343 1 : else return 0;
344 : }
345 :
346 469084 : sal_uInt64 SvStream::SeekPos(sal_uInt64 const nPos)
347 : {
348 : // check if a truncated STREAM_SEEK_TO_END was passed
349 : assert(nPos != SAL_MAX_UINT32);
350 469084 : if( !GetError() && nPos == STREAM_SEEK_TO_END )
351 : {
352 : DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
353 72632 : SvLockBytesStat aStat;
354 72632 : xLockBytes->Stat( &aStat, SVSTATFLAG_DEFAULT );
355 72632 : m_nActPos = aStat.nSize;
356 : }
357 : else
358 396452 : m_nActPos = nPos;
359 469084 : return m_nActPos;
360 : }
361 :
362 50420 : void SvStream::FlushData()
363 : {
364 50420 : if( !GetError() )
365 : {
366 : DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
367 50347 : nError = xLockBytes->Flush();
368 : }
369 50420 : }
370 :
371 3571 : void SvStream::SetSize(sal_uInt64 const nSize)
372 : {
373 : DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
374 3571 : nError = xLockBytes->SetSize( nSize );
375 3571 : }
376 :
377 133263 : void SvStream::ImpInit()
378 : {
379 133263 : m_nActPos = 0;
380 133263 : nCompressMode = SvStreamCompressFlags::NONE;
381 133263 : eStreamCharSet = osl_getThreadTextEncoding();
382 133263 : nCryptMask = 0;
383 133263 : bIsEof = false;
384 : #if defined UNX
385 133263 : eLineDelimiter = LINEEND_LF; // UNIX-Format
386 : #else
387 : eLineDelimiter = LINEEND_CRLF; // DOS-Format
388 : #endif
389 :
390 133263 : SetEndian( SvStreamEndian::LITTLE );
391 :
392 133263 : m_nBufFilePos = 0;
393 133263 : nBufActualPos = 0;
394 133263 : bIsDirty = false;
395 133263 : bIsConsistent = true;
396 133263 : bIsWritable = true;
397 :
398 133263 : pRWBuf = 0;
399 133263 : pBufPos = 0;
400 133263 : nBufSize = 0;
401 133263 : nBufActualLen = 0;
402 133263 : bIoRead = false;
403 133263 : bIoWrite = false;
404 133263 : nBufFree = 0;
405 :
406 133263 : eStreamMode = StreamMode::NONE;
407 :
408 133263 : nVersion = 0;
409 :
410 133263 : ClearError();
411 133263 : }
412 :
413 46773 : SvStream::SvStream( SvLockBytes* pLockBytesP )
414 : {
415 46773 : ImpInit();
416 46773 : xLockBytes = pLockBytesP;
417 46773 : if( pLockBytesP ) {
418 46773 : const SvStream* pStrm = pLockBytesP->GetStream();
419 46773 : if( pStrm ) {
420 0 : SetError( pStrm->GetErrorCode() );
421 : }
422 : }
423 46773 : SetBufferSize( 256 );
424 46773 : }
425 :
426 86490 : SvStream::SvStream()
427 : {
428 86490 : ImpInit();
429 86490 : }
430 :
431 313099 : SvStream::~SvStream()
432 : {
433 133189 : if ( xLockBytes.Is() )
434 46721 : Flush();
435 :
436 133189 : if( pRWBuf )
437 103312 : delete[] pRWBuf;
438 179910 : }
439 :
440 174662 : void SvStream::ClearError()
441 : {
442 174662 : bIsEof = false;
443 174662 : nError = SVSTREAM_OK;
444 174662 : }
445 :
446 2936453 : void SvStream::SetError( sal_uInt32 nErrorCode )
447 : {
448 2936453 : if ( nError == SVSTREAM_OK )
449 2936155 : nError = nErrorCode;
450 2936453 : }
451 :
452 252826 : void SvStream::SetEndian( SvStreamEndian nNewFormat )
453 : {
454 252826 : nEndian = nNewFormat;
455 252826 : bSwap = false;
456 : #ifdef OSL_BIGENDIAN
457 : if( nEndian == SvStreamEndian::LITTLE )
458 : bSwap = true;
459 : #else
460 252826 : if( nEndian == SvStreamEndian::BIG )
461 29529 : bSwap = true;
462 : #endif
463 252826 : }
464 :
465 189815 : void SvStream::SetBufferSize( sal_uInt16 nBufferSize )
466 : {
467 189815 : sal_uInt64 const nActualFilePos = Tell();
468 189815 : bool bDontSeek = (pRWBuf == 0);
469 :
470 189815 : if( bIsDirty && bIsConsistent && bIsWritable ) // due to Windows NT: Access denied
471 68 : Flush();
472 :
473 189815 : if( nBufSize )
474 : {
475 54218 : delete[] pRWBuf;
476 54218 : m_nBufFilePos += nBufActualPos;
477 : }
478 :
479 189815 : pRWBuf = 0;
480 189815 : nBufActualLen = 0;
481 189815 : nBufActualPos = 0;
482 189815 : nBufSize = nBufferSize;
483 189815 : if( nBufSize )
484 157604 : pRWBuf = new sal_uInt8[ nBufSize ];
485 189815 : bIsConsistent = true;
486 189815 : pBufPos = pRWBuf;
487 189815 : bIoRead = bIoWrite = false;
488 189815 : if( !bDontSeek )
489 54218 : SeekPos( nActualFilePos );
490 189815 : }
491 :
492 23135 : void SvStream::ClearBuffer()
493 : {
494 23135 : nBufActualLen = 0;
495 23135 : nBufActualPos = 0;
496 23135 : m_nBufFilePos = 0;
497 23135 : pBufPos = pRWBuf;
498 23135 : bIsDirty = false;
499 23135 : bIsConsistent = true;
500 23135 : bIoRead = bIoWrite = false;
501 :
502 23135 : bIsEof = false;
503 23135 : }
504 :
505 9911 : void SvStream::ResetError()
506 : {
507 9911 : ClearError();
508 9911 : }
509 :
510 181 : bool SvStream::ReadByteStringLine( OUString& rStr, rtl_TextEncoding eSrcCharSet,
511 : sal_Int32 nMaxBytesToRead )
512 : {
513 181 : OString aStr;
514 181 : bool bRet = ReadLine( aStr, nMaxBytesToRead);
515 181 : rStr = OStringToOUString(aStr, eSrcCharSet);
516 181 : return bRet;
517 : }
518 :
519 756245 : bool SvStream::ReadLine( OString& rStr, sal_Int32 nMaxBytesToRead )
520 : {
521 : sal_Char buf[256+1];
522 756245 : bool bEnd = false;
523 756245 : sal_uInt64 nOldFilePos = Tell();
524 756245 : sal_Char c = 0;
525 756245 : sal_Size nTotalLen = 0;
526 :
527 756245 : OStringBuffer aBuf(4096);
528 2358467 : while( !bEnd && !GetError() ) // Don't test for EOF as we
529 : // are reading block-wise!
530 : {
531 847506 : sal_uInt16 nLen = (sal_uInt16)Read( buf, sizeof(buf)-1 );
532 847506 : if ( !nLen )
533 : {
534 1529 : if ( aBuf.isEmpty() )
535 : {
536 : // Exit on first block-read error
537 1526 : bIsEof = true;
538 1526 : rStr.clear();
539 1526 : return false;
540 : }
541 : else
542 3 : break;
543 : }
544 :
545 : sal_uInt16 j, n;
546 44195980 : for( j = n = 0; j < nLen ; ++j )
547 : {
548 44104703 : c = buf[j];
549 44104703 : if ( c == '\n' || c == '\r' )
550 : {
551 754700 : bEnd = true;
552 754700 : break;
553 : }
554 43350003 : if ( n < j )
555 0 : buf[n] = c;
556 43350003 : ++n;
557 : }
558 845977 : nTotalLen += j;
559 845977 : if (nTotalLen > static_cast<sal_Size>(nMaxBytesToRead))
560 : {
561 0 : n -= nTotalLen - nMaxBytesToRead;
562 0 : nTotalLen = nMaxBytesToRead;
563 0 : bEnd = true;
564 : }
565 845977 : if ( n )
566 771488 : aBuf.append(buf, n);
567 : }
568 :
569 754719 : if ( !bEnd && !GetError() && !aBuf.isEmpty() )
570 3 : bEnd = true;
571 :
572 754719 : nOldFilePos += nTotalLen;
573 754719 : if( Tell() > nOldFilePos )
574 754700 : nOldFilePos++;
575 754719 : Seek( nOldFilePos ); // Seek pointer due to BlockRead above
576 :
577 754719 : if ( bEnd && (c=='\r' || c=='\n') ) // Special treatment for DOS files
578 : {
579 : char cTemp;
580 754700 : sal_Size nLen = Read(&cTemp , sizeof(cTemp) );
581 754700 : if ( nLen ) {
582 753837 : if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
583 753837 : Seek( nOldFilePos );
584 : }
585 : }
586 :
587 754719 : if ( bEnd )
588 754703 : bIsEof = false;
589 754719 : rStr = aBuf.makeStringAndClear();
590 754719 : return bEnd;
591 : }
592 :
593 4 : bool SvStream::ReadUniStringLine( OUString& rStr, sal_Int32 nMaxCodepointsToRead )
594 : {
595 : sal_Unicode buf[256+1];
596 4 : bool bEnd = false;
597 4 : sal_uInt64 nOldFilePos = Tell();
598 4 : sal_Unicode c = 0;
599 4 : sal_Size nTotalLen = 0;
600 :
601 : DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "ReadUniStringLine: swapping sizeof(sal_Unicode) not implemented" );
602 :
603 4 : OUStringBuffer aBuf(4096);
604 10 : while( !bEnd && !GetError() ) // Don't test for EOF as we
605 : // are reading block-wise!
606 : {
607 6 : sal_uInt16 nLen = (sal_uInt16)Read( buf, sizeof(buf)-sizeof(sal_Unicode) );
608 6 : nLen /= sizeof(sal_Unicode);
609 6 : if ( !nLen )
610 : {
611 4 : if ( aBuf.isEmpty() )
612 : {
613 : // exit on first BlockRead error
614 2 : bIsEof = true;
615 2 : rStr.clear();
616 2 : return false;
617 : }
618 : else
619 2 : break;
620 : }
621 :
622 : sal_uInt16 j, n;
623 12 : for( j = n = 0; j < nLen ; ++j )
624 : {
625 10 : if ( bSwap )
626 0 : SwapUShort( buf[n] );
627 10 : c = buf[j];
628 10 : if ( c == '\n' || c == '\r' )
629 : {
630 0 : bEnd = true;
631 0 : break;
632 : }
633 : // erAck 26.02.01: Old behavior was no special treatment of '\0'
634 : // character here, but a following rStr+=c did ignore it. Is this
635 : // really intended? Or should a '\0' better terminate a line?
636 : // The nOldFilePos stuff wasn't correct then anyways.
637 10 : if ( c )
638 : {
639 10 : if ( n < j )
640 0 : buf[n] = c;
641 10 : ++n;
642 : }
643 : }
644 2 : nTotalLen += j;
645 2 : if (nTotalLen > static_cast<sal_Size>(nMaxCodepointsToRead))
646 : {
647 0 : n -= nTotalLen - nMaxCodepointsToRead;
648 0 : nTotalLen = nMaxCodepointsToRead;
649 0 : bEnd = true;
650 : }
651 2 : if ( n )
652 2 : aBuf.append( buf, n );
653 : }
654 :
655 2 : if ( !bEnd && !GetError() && !aBuf.isEmpty() )
656 2 : bEnd = true;
657 :
658 2 : nOldFilePos += nTotalLen * sizeof(sal_Unicode);
659 2 : if( Tell() > nOldFilePos )
660 0 : nOldFilePos += sizeof(sal_Unicode);
661 2 : Seek( nOldFilePos ); // seek due to BlockRead above
662 :
663 2 : if ( bEnd && (c=='\r' || c=='\n') ) // special treatment for DOS files
664 : {
665 : sal_Unicode cTemp;
666 0 : Read( &cTemp, sizeof(cTemp) );
667 0 : if ( bSwap )
668 0 : SwapUShort( cTemp );
669 0 : if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
670 0 : Seek( nOldFilePos );
671 : }
672 :
673 2 : if ( bEnd )
674 2 : bIsEof = false;
675 2 : rStr = aBuf.makeStringAndClear();
676 2 : return bEnd;
677 : }
678 :
679 185 : bool SvStream::ReadUniOrByteStringLine( OUString& rStr, rtl_TextEncoding eSrcCharSet,
680 : sal_Int32 nMaxCodepointsToRead )
681 : {
682 185 : if ( eSrcCharSet == RTL_TEXTENCODING_UNICODE )
683 4 : return ReadUniStringLine( rStr, nMaxCodepointsToRead );
684 : else
685 181 : return ReadByteStringLine( rStr, eSrcCharSet, nMaxCodepointsToRead );
686 : }
687 :
688 4 : OString read_zeroTerminated_uInt8s_ToOString(SvStream& rStream)
689 : {
690 4 : OStringBuffer aOutput(256);
691 :
692 : sal_Char buf[ 256 + 1 ];
693 4 : bool bEnd = false;
694 4 : sal_uInt64 nFilePos = rStream.Tell();
695 :
696 12 : while( !bEnd && !rStream.GetError() )
697 : {
698 4 : sal_Size nLen = rStream.Read(buf, sizeof(buf)-1);
699 4 : if (!nLen)
700 0 : break;
701 :
702 4 : sal_Size nReallyRead = nLen;
703 4 : const sal_Char* pPtr = buf;
704 24 : while (nLen && *pPtr)
705 16 : ++pPtr, --nLen;
706 :
707 4 : bEnd = ( nReallyRead < sizeof(buf)-1 ) // read less than attempted to read
708 8 : || ( ( nLen > 0 ) // OR it is inside the block we read
709 0 : && ( 0 == *pPtr ) // AND found a string terminator
710 4 : );
711 :
712 4 : aOutput.append(buf, pPtr - buf);
713 : }
714 :
715 4 : nFilePos += aOutput.getLength();
716 4 : if (rStream.Tell() > nFilePos)
717 3 : rStream.Seek(nFilePos+1); // seek due to FileRead above
718 4 : return aOutput.makeStringAndClear();
719 : }
720 :
721 0 : OUString read_zeroTerminated_uInt8s_ToOUString(SvStream& rStream, rtl_TextEncoding eEnc)
722 : {
723 : return OStringToOUString(
724 0 : read_zeroTerminated_uInt8s_ToOString(rStream), eEnc);
725 : }
726 :
727 : /** Attempt to write a prefixed sequence of nUnits 16bit units from an OUString,
728 : returned value is number of bytes written */
729 73954 : sal_Size write_uInt16s_FromOUString(SvStream& rStrm, const OUString& rStr,
730 : sal_Size nUnits)
731 : {
732 : DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "write_uInt16s_FromOUString: swapping sizeof(sal_Unicode) not implemented" );
733 : sal_Size nWritten;
734 73954 : if (!rStrm.IsEndianSwap())
735 73954 : nWritten = rStrm.Write( rStr.getStr(), nUnits * sizeof(sal_Unicode) );
736 : else
737 : {
738 0 : sal_Size nLen = nUnits;
739 : sal_Unicode aBuf[384];
740 0 : sal_Unicode* const pTmp = ( nLen > 384 ? new sal_Unicode[nLen] : aBuf);
741 0 : memcpy( pTmp, rStr.getStr(), nLen * sizeof(sal_Unicode) );
742 0 : sal_Unicode* p = pTmp;
743 0 : const sal_Unicode* const pStop = pTmp + nLen;
744 0 : while ( p < pStop )
745 : {
746 0 : SwapUShort( *p );
747 0 : p++;
748 : }
749 0 : nWritten = rStrm.Write( pTmp, nLen * sizeof(sal_Unicode) );
750 0 : if ( pTmp != aBuf )
751 0 : delete [] pTmp;
752 : }
753 73954 : return nWritten;
754 : }
755 :
756 13441 : bool SvStream::WriteUnicodeOrByteText( const OUString& rStr, rtl_TextEncoding eDestCharSet )
757 : {
758 13441 : if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
759 : {
760 13439 : write_uInt16s_FromOUString(*this, rStr, rStr.getLength());
761 13439 : return nError == SVSTREAM_OK;
762 : }
763 : else
764 : {
765 2 : OString aStr(OUStringToOString(rStr, eDestCharSet));
766 2 : write_uInt8s_FromOString(*this, aStr, aStr.getLength());
767 2 : return nError == SVSTREAM_OK;
768 : }
769 : }
770 :
771 0 : bool SvStream::WriteByteStringLine( const OUString& rStr, rtl_TextEncoding eDestCharSet )
772 : {
773 0 : return WriteLine(OUStringToOString(rStr, eDestCharSet));
774 : }
775 :
776 188358 : bool SvStream::WriteLine(const OString& rStr)
777 : {
778 188358 : Write(rStr.getStr(), rStr.getLength());
779 188358 : endl(*this);
780 188358 : return nError == SVSTREAM_OK;
781 : }
782 :
783 0 : bool SvStream::WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet )
784 : {
785 0 : if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
786 0 : WriteUnicode(ch);
787 : else
788 : {
789 0 : OString aStr(&ch, 1, eDestCharSet);
790 0 : Write(aStr.getStr(), aStr.getLength());
791 : }
792 0 : return nError == SVSTREAM_OK;
793 : }
794 :
795 0 : bool SvStream::StartWritingUnicodeText()
796 : {
797 : // BOM, Byte Order Mark, U+FEFF, see
798 : // http://www.unicode.org/faq/utf_bom.html#BOM
799 : // Upon read: 0xfeff(-257) => no swap; 0xfffe(-2) => swap
800 0 : sal_uInt16 v = 0xfeff;
801 0 : WRITENUMBER_WITHOUT_SWAP(sal_uInt16, v); // write native format
802 0 : return nError == SVSTREAM_OK;
803 : }
804 :
805 1046 : bool SvStream::StartReadingUnicodeText( rtl_TextEncoding eReadBomCharSet )
806 : {
807 1046 : if (!( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
808 : eReadBomCharSet == RTL_TEXTENCODING_UNICODE ||
809 3 : eReadBomCharSet == RTL_TEXTENCODING_UTF8))
810 3 : return true; // nothing to read
811 :
812 1043 : bool bTryUtf8 = false;
813 1043 : sal_uInt16 nFlag(0);
814 1043 : sal_sSize nBack = sizeof(nFlag);
815 1043 : this->ReadUInt16( nFlag );
816 1043 : switch ( nFlag )
817 : {
818 : case 0xfeff :
819 : // native UTF-16
820 0 : if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
821 : eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
822 0 : nBack = 0;
823 0 : break;
824 : case 0xfffe :
825 : // swapped UTF-16
826 0 : if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
827 : eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
828 : {
829 0 : SetEndian( nEndian == SvStreamEndian::BIG ? SvStreamEndian::LITTLE : SvStreamEndian::BIG );
830 0 : nBack = 0;
831 : }
832 0 : break;
833 : case 0xefbb :
834 0 : if (nEndian == SvStreamEndian::BIG &&
835 0 : (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
836 : eReadBomCharSet == RTL_TEXTENCODING_UTF8))
837 0 : bTryUtf8 = true;
838 0 : break;
839 : case 0xbbef :
840 0 : if (nEndian == SvStreamEndian::LITTLE &&
841 0 : (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
842 : eReadBomCharSet == RTL_TEXTENCODING_UTF8))
843 0 : bTryUtf8 = true;
844 0 : break;
845 : default:
846 : ; // nothing
847 : }
848 1043 : if (bTryUtf8)
849 : {
850 0 : unsigned char nChar(0);
851 0 : nBack += sizeof(nChar);
852 0 : this->ReadUChar( nChar );
853 0 : if (nChar == 0xbf)
854 0 : nBack = 0; // it is UTF-8
855 : }
856 1043 : if (nBack)
857 1043 : SeekRel( -nBack ); // no BOM, pure data
858 1043 : return nError == SVSTREAM_OK;
859 : }
860 :
861 1397019 : sal_uInt64 SvStream::SeekRel(sal_Int64 const nPos)
862 : {
863 1397019 : sal_uInt64 nActualPos = Tell();
864 :
865 1397019 : if ( nPos >= 0 )
866 : {
867 1213898 : if (SAL_MAX_UINT64 - nActualPos > static_cast<sal_uInt64>(nPos))
868 1213898 : nActualPos += nPos;
869 : }
870 : else
871 : {
872 183121 : sal_uInt64 const nAbsPos = static_cast<sal_uInt64>(-nPos);
873 183121 : if ( nActualPos >= nAbsPos )
874 183121 : nActualPos -= nAbsPos;
875 : }
876 :
877 1397019 : pBufPos = pRWBuf + nActualPos;
878 1397019 : return Seek( nActualPos );
879 : }
880 :
881 8229168 : SvStream& SvStream::ReadUInt16(sal_uInt16& r)
882 : {
883 8229168 : sal_uInt16 n = 0;
884 8229168 : READNUMBER_WITHOUT_SWAP(sal_uInt16, n)
885 8229168 : if (good())
886 : {
887 8227138 : if (bSwap)
888 11053 : SwapUShort(n);
889 8227138 : r = n;
890 : }
891 8229168 : return *this;
892 : }
893 :
894 1006742 : SvStream& SvStream::ReadUInt32(sal_uInt32& r)
895 : {
896 1006742 : sal_uInt32 n = 0;
897 1006742 : READNUMBER_WITHOUT_SWAP(sal_uInt32, n)
898 1006742 : if (good())
899 : {
900 1005103 : if (bSwap)
901 99638 : SwapULong(n);
902 1005103 : r = n;
903 : }
904 1006742 : return *this;
905 : }
906 :
907 0 : SvStream& SvStream::ReadUInt64(sal_uInt64& r)
908 : {
909 0 : sal_uInt64 n = 0;
910 0 : READNUMBER_WITHOUT_SWAP(sal_uInt64, n)
911 0 : if (good())
912 : {
913 0 : if (bSwap)
914 0 : SwapUInt64(n);
915 0 : r = n;
916 : }
917 0 : return *this;
918 : }
919 :
920 238536 : SvStream& SvStream::ReadInt16(sal_Int16& r)
921 : {
922 238536 : sal_Int16 n = 0;
923 238536 : READNUMBER_WITHOUT_SWAP(sal_Int16, n)
924 238536 : if (good())
925 : {
926 238492 : if (bSwap)
927 30112 : SwapShort(n);
928 238492 : r = n;
929 : }
930 238536 : return *this;
931 : }
932 :
933 1959052 : SvStream& SvStream::ReadInt32(sal_Int32& r)
934 : {
935 1959052 : sal_Int32 n = 0;
936 1959052 : READNUMBER_WITHOUT_SWAP(sal_Int32, n)
937 1959052 : if (good())
938 : {
939 1954123 : if (bSwap)
940 31725 : SwapLongInt(n);
941 1954123 : r = n;
942 : }
943 1959052 : return *this;
944 : }
945 :
946 0 : SvStream& SvStream::ReadInt64(sal_Int64& r)
947 : {
948 0 : sal_Int64 n = 0;
949 0 : READNUMBER_WITHOUT_SWAP(sal_Int64, n)
950 0 : if (good())
951 : {
952 0 : if (bSwap)
953 0 : SwapInt64(n);
954 0 : r = n;
955 : }
956 0 : return *this;
957 : }
958 :
959 3785 : SvStream& SvStream::ReadSChar( signed char& r )
960 : {
961 6449 : if( (bIoRead || !bIsConsistent) &&
962 2664 : sizeof(signed char) <= nBufFree )
963 : {
964 2662 : r = *pBufPos;
965 2662 : nBufActualPos += sizeof(signed char);
966 2662 : pBufPos += sizeof(signed char);
967 2662 : nBufFree -= sizeof(signed char);
968 : }
969 : else
970 1123 : Read( &r, sizeof(signed char) );
971 3785 : return *this;
972 : }
973 :
974 : // Special treatment for Chars due to PutBack
975 :
976 17581704 : SvStream& SvStream::ReadChar( char& r )
977 : {
978 35002460 : if( (bIoRead || !bIsConsistent) &&
979 17420756 : sizeof(char) <= nBufFree )
980 : {
981 17416556 : r = *pBufPos;
982 17416556 : nBufActualPos += sizeof(char);
983 17416556 : pBufPos += sizeof(char);
984 17416556 : nBufFree -= sizeof(char);
985 : }
986 : else
987 165148 : Read( &r, sizeof(char) );
988 17581704 : return *this;
989 : }
990 :
991 27602969 : SvStream& SvStream::ReadUChar( unsigned char& r )
992 : {
993 55058805 : if( (bIoRead || !bIsConsistent) &&
994 27455836 : sizeof(char) <= nBufFree )
995 : {
996 17396013 : r = *pBufPos;
997 17396013 : nBufActualPos += sizeof(char);
998 17396013 : pBufPos += sizeof(char);
999 17396013 : nBufFree -= sizeof(char);
1000 : }
1001 : else
1002 10206956 : Read( &r, sizeof(char) );
1003 27602969 : return *this;
1004 : }
1005 :
1006 205375 : SvStream& SvStream::ReadCharAsBool( bool& r )
1007 : {
1008 410540 : if( (bIoRead || !bIsConsistent) &&
1009 205165 : sizeof(char) <= nBufFree )
1010 : {
1011 : SAL_WARN_IF(
1012 : *pBufPos > 1, "tools.stream", unsigned(*pBufPos) << " not 0/1");
1013 205023 : r = *pBufPos != 0;
1014 205023 : nBufActualPos += sizeof(char);
1015 205023 : pBufPos += sizeof(char);
1016 205023 : nBufFree -= sizeof(char);
1017 : }
1018 : else
1019 : {
1020 : unsigned char c;
1021 352 : if (Read(&c, 1) == 1)
1022 : {
1023 : SAL_WARN_IF(c > 1, "tools.stream", unsigned(c) << " not 0/1");
1024 352 : r = c != 0;
1025 : }
1026 : }
1027 205375 : return *this;
1028 : }
1029 :
1030 7950 : SvStream& SvStream::ReadFloat(float& r)
1031 : {
1032 7950 : float n = 0;
1033 7950 : READNUMBER_WITHOUT_SWAP(float, n)
1034 7950 : if (good())
1035 : {
1036 : #if defined UNX
1037 7950 : if (bSwap)
1038 0 : SwapFloat(n);
1039 : #endif
1040 7950 : r = n;
1041 : }
1042 7950 : return *this;
1043 : }
1044 :
1045 11991 : SvStream& SvStream::ReadDouble(double& r)
1046 : {
1047 11991 : double n = 0;
1048 11991 : READNUMBER_WITHOUT_SWAP(double, n)
1049 11991 : if (good())
1050 : {
1051 : #if defined UNX
1052 11991 : if (bSwap)
1053 0 : SwapDouble(n);
1054 : #endif
1055 11991 : r = n;
1056 : }
1057 11991 : return *this;
1058 : }
1059 :
1060 95 : SvStream& SvStream::ReadStream( SvStream& rStream )
1061 : {
1062 95 : const sal_uInt32 cBufLen = 0x8000;
1063 95 : char* pBuf = new char[ cBufLen ];
1064 :
1065 : sal_uInt32 nCount;
1066 143 : do {
1067 143 : nCount = Read( pBuf, cBufLen );
1068 143 : rStream.Write( pBuf, nCount );
1069 : } while( nCount == cBufLen );
1070 :
1071 95 : delete[] pBuf;
1072 95 : return *this;
1073 : }
1074 :
1075 3708554 : SvStream& SvStream::WriteUInt16( sal_uInt16 v )
1076 : {
1077 3708554 : if( bSwap )
1078 0 : SwapUShort(v);
1079 3708554 : WRITENUMBER_WITHOUT_SWAP(sal_uInt16,v)
1080 3708554 : return *this;
1081 : }
1082 :
1083 1013310 : SvStream& SvStream::WriteUInt32( sal_uInt32 v )
1084 : {
1085 1013310 : if( bSwap )
1086 2215 : SwapULong(v);
1087 1013310 : WRITENUMBER_WITHOUT_SWAP(sal_uInt32,v)
1088 1013310 : return *this;
1089 : }
1090 :
1091 563 : SvStream& SvStream::WriteUInt64( sal_uInt64 v )
1092 : {
1093 563 : if( bSwap )
1094 0 : SwapUInt64(v);
1095 563 : WRITENUMBER_WITHOUT_SWAP(sal_uInt64,v)
1096 563 : return *this;
1097 : }
1098 :
1099 73814 : SvStream& SvStream::WriteInt16( sal_Int16 v )
1100 : {
1101 73814 : if( bSwap )
1102 0 : SwapShort(v);
1103 73814 : WRITENUMBER_WITHOUT_SWAP(sal_Int16,v)
1104 73814 : return *this;
1105 : }
1106 :
1107 1596800 : SvStream& SvStream::WriteInt32( sal_Int32 v )
1108 : {
1109 1596800 : if( bSwap )
1110 0 : SwapLongInt(v);
1111 1596800 : WRITENUMBER_WITHOUT_SWAP(sal_Int32,v)
1112 1596800 : return *this;
1113 : }
1114 :
1115 0 : SvStream& SvStream::WriteInt64 (sal_Int64 v)
1116 : {
1117 0 : if( bSwap )
1118 0 : SwapInt64(v);
1119 0 : WRITENUMBER_WITHOUT_SWAP(sal_Int64,v)
1120 0 : return *this;
1121 : }
1122 :
1123 2848 : SvStream& SvStream::WriteSChar( signed char v )
1124 : {
1125 : //SDO
1126 2848 : if(bIoWrite && sizeof(signed char) <= nBufFree )
1127 : {
1128 2848 : *pBufPos = v;
1129 2848 : pBufPos++; // sizeof(char);
1130 2848 : nBufActualPos++;
1131 2848 : if( nBufActualPos > nBufActualLen ) // Append ?
1132 2848 : nBufActualLen = nBufActualPos;
1133 2848 : nBufFree--; // = sizeof(char);
1134 2848 : bIsDirty = true;
1135 : }
1136 : else
1137 0 : Write( &v, sizeof(signed char) );
1138 2848 : return *this;
1139 : }
1140 :
1141 : // Special treatment for Chars due to PutBack
1142 :
1143 3915907 : SvStream& SvStream::WriteChar( char v )
1144 : {
1145 : //SDO
1146 3915907 : if(bIoWrite && sizeof(char) <= nBufFree )
1147 : {
1148 3898017 : *pBufPos = v;
1149 3898017 : pBufPos++; // sizeof(char);
1150 3898017 : nBufActualPos++;
1151 3898017 : if( nBufActualPos > nBufActualLen ) // Append ?
1152 3898017 : nBufActualLen = nBufActualPos;
1153 3898017 : nBufFree--; // = sizeof(char);
1154 3898017 : bIsDirty = true;
1155 : }
1156 : else
1157 17890 : Write( &v, sizeof(char) );
1158 3915907 : return *this;
1159 : }
1160 :
1161 468783 : SvStream& SvStream::WriteUChar( unsigned char v )
1162 : {
1163 : //SDO
1164 468783 : if(bIoWrite && sizeof(char) <= nBufFree )
1165 : {
1166 422428 : *reinterpret_cast<unsigned char*>(pBufPos) = v;
1167 422428 : pBufPos++; // = sizeof(char);
1168 422428 : nBufActualPos++; // = sizeof(char);
1169 422428 : if( nBufActualPos > nBufActualLen ) // Append ?
1170 422428 : nBufActualLen = nBufActualPos;
1171 422428 : nBufFree--;
1172 422428 : bIsDirty = true;
1173 : }
1174 : else
1175 46355 : Write( &v, sizeof(char) );
1176 468783 : return *this;
1177 : }
1178 :
1179 12732 : SvStream& SvStream::WriteUInt8( sal_uInt8 v )
1180 : {
1181 12732 : return WriteUChar(v);
1182 : }
1183 :
1184 0 : SvStream& SvStream::WriteUnicode( sal_Unicode v )
1185 : {
1186 0 : return WriteUInt16(v);
1187 : }
1188 :
1189 480 : SvStream& SvStream::WriteFloat( float v )
1190 : {
1191 : #ifdef UNX
1192 480 : if( bSwap )
1193 0 : SwapFloat(v);
1194 : #endif
1195 480 : WRITENUMBER_WITHOUT_SWAP(float,v)
1196 480 : return *this;
1197 : }
1198 :
1199 11759 : SvStream& SvStream::WriteDouble ( const double& r )
1200 : {
1201 : #if defined UNX
1202 11759 : if( bSwap )
1203 : {
1204 0 : double nHelp = r;
1205 0 : SwapDouble(nHelp);
1206 0 : WRITENUMBER_WITHOUT_SWAP(double,nHelp)
1207 0 : return *this;
1208 : }
1209 : else
1210 : #endif
1211 : {
1212 11759 : WRITENUMBER_WITHOUT_SWAP(double,r);
1213 : }
1214 11759 : return *this;
1215 : }
1216 :
1217 7259993 : SvStream& SvStream::WriteCharPtr( const char* pBuf )
1218 : {
1219 7259993 : Write( pBuf, strlen( pBuf ) );
1220 7259993 : return *this;
1221 : }
1222 :
1223 71 : SvStream& SvStream::WriteStream( SvStream& rStream )
1224 : {
1225 71 : const sal_uInt32 cBufLen = 0x8000;
1226 71 : char* pBuf = new char[ cBufLen ];
1227 : sal_uInt32 nCount;
1228 1577 : do {
1229 1577 : nCount = rStream.Read( pBuf, cBufLen );
1230 1577 : Write( pBuf, nCount );
1231 : } while( nCount == cBufLen );
1232 :
1233 71 : delete[] pBuf;
1234 71 : return *this;
1235 : }
1236 :
1237 115224 : OUString SvStream::ReadUniOrByteString( rtl_TextEncoding eSrcCharSet )
1238 : {
1239 : // read UTF-16 string directly from stream ?
1240 115224 : if (eSrcCharSet == RTL_TEXTENCODING_UNICODE)
1241 12824 : return read_uInt32_lenPrefixed_uInt16s_ToOUString(*this);
1242 102400 : return read_uInt16_lenPrefixed_uInt8s_ToOUString(*this, eSrcCharSet);
1243 : }
1244 :
1245 145341 : SvStream& SvStream::WriteUniOrByteString( const OUString& rStr, rtl_TextEncoding eDestCharSet )
1246 : {
1247 : // write UTF-16 string directly into stream ?
1248 145341 : if (eDestCharSet == RTL_TEXTENCODING_UNICODE)
1249 14112 : write_uInt32_lenPrefixed_uInt16s_FromOUString(*this, rStr);
1250 : else
1251 131229 : write_uInt16_lenPrefixed_uInt8s_FromOUString(*this, rStr, eDestCharSet);
1252 145341 : return *this;
1253 : }
1254 :
1255 16792276 : sal_Size SvStream::Read( void* pData, sal_Size nCount )
1256 : {
1257 16792276 : sal_Size nSaveCount = nCount;
1258 16792276 : if( !bIsConsistent )
1259 0 : RefreshBuffer();
1260 :
1261 16792276 : if( !pRWBuf )
1262 : {
1263 2253590 : nCount = GetData( pData,nCount);
1264 2253590 : if( nCryptMask )
1265 0 : EncryptBuffer(pData, nCount);
1266 2253590 : m_nBufFilePos += nCount;
1267 : }
1268 : else
1269 : {
1270 : // check if block is completely within buffer
1271 14538686 : bIoRead = true;
1272 14538686 : bIoWrite = false;
1273 14538686 : if( nCount <= (sal_Size)(nBufActualLen - nBufActualPos ) )
1274 : {
1275 : // => yes
1276 3907156 : memcpy(pData, pBufPos, (size_t) nCount);
1277 3907156 : nBufActualPos = nBufActualPos + (sal_uInt16)nCount;
1278 3907156 : pBufPos += nCount;
1279 3907156 : nBufFree = nBufFree - (sal_uInt16)nCount;
1280 : }
1281 : else
1282 : {
1283 10631530 : if( bIsDirty ) // Does stream require a flush?
1284 : {
1285 301 : SeekPos(m_nBufFilePos);
1286 301 : if( nCryptMask )
1287 0 : CryptAndWriteBuffer(pRWBuf, nBufActualLen);
1288 : else
1289 301 : PutData( pRWBuf, nBufActualLen );
1290 301 : bIsDirty = false;
1291 : }
1292 :
1293 : // Does data block fit into buffer?
1294 10631530 : if( nCount > nBufSize )
1295 : {
1296 : // => No! Thus read directly
1297 : // into target area without using the buffer
1298 :
1299 212006 : bIoRead = false;
1300 :
1301 212006 : SeekPos(m_nBufFilePos + nBufActualPos);
1302 212006 : nBufActualLen = 0;
1303 212006 : pBufPos = pRWBuf;
1304 212006 : nCount = GetData( pData, nCount );
1305 212006 : if( nCryptMask )
1306 0 : EncryptBuffer(pData, nCount);
1307 212006 : m_nBufFilePos += nCount;
1308 212006 : m_nBufFilePos += nBufActualPos;
1309 212006 : nBufActualPos = 0;
1310 : }
1311 : else
1312 : {
1313 : // => Yes. Fill buffer first, then copy to target area
1314 :
1315 10419524 : m_nBufFilePos += nBufActualPos;
1316 10419524 : SeekPos(m_nBufFilePos);
1317 :
1318 : // TODO: Typecast before GetData, sal_uInt16 nCountTmp
1319 10419524 : sal_Size nCountTmp = GetData( pRWBuf, nBufSize );
1320 10419524 : if( nCryptMask )
1321 0 : EncryptBuffer(pRWBuf, nCountTmp);
1322 10419524 : nBufActualLen = (sal_uInt16)nCountTmp;
1323 10419524 : if( nCount > nCountTmp )
1324 : {
1325 10069904 : nCount = nCountTmp; // trim count back, EOF see below
1326 : }
1327 10419524 : memcpy( pData, pRWBuf, (size_t)nCount );
1328 10419524 : nBufActualPos = (sal_uInt16)nCount;
1329 10419524 : pBufPos = pRWBuf + nCount;
1330 : }
1331 : }
1332 : }
1333 16792276 : bIsEof = false;
1334 16792276 : nBufFree = nBufActualLen - nBufActualPos;
1335 16792276 : if( nCount != nSaveCount && nError != ERRCODE_IO_PENDING )
1336 10095628 : bIsEof = true;
1337 16792276 : if( nCount == nSaveCount && nError == ERRCODE_IO_PENDING )
1338 0 : nError = ERRCODE_NONE;
1339 16792276 : return nCount;
1340 : }
1341 :
1342 10277800 : sal_Size SvStream::Write( const void* pData, sal_Size nCount )
1343 : {
1344 10277800 : if( !nCount )
1345 81519 : return 0;
1346 10196281 : if( !bIsWritable )
1347 : {
1348 0 : SetError( ERRCODE_IO_CANTWRITE );
1349 0 : return 0;
1350 : }
1351 10196281 : if( !bIsConsistent )
1352 0 : RefreshBuffer(); // Remove changes in buffer through PutBack
1353 :
1354 10196281 : if( !pRWBuf )
1355 : {
1356 274591 : if( nCryptMask )
1357 0 : nCount = CryptAndWriteBuffer( pData, nCount );
1358 : else
1359 274591 : nCount = PutData( pData, nCount );
1360 274591 : m_nBufFilePos += nCount;
1361 274591 : return nCount;
1362 : }
1363 :
1364 9921690 : bIoRead = false;
1365 9921690 : bIoWrite = true;
1366 9921690 : if( nCount <= (sal_Size)(nBufSize - nBufActualPos) )
1367 : {
1368 9536048 : memcpy( pBufPos, pData, (size_t)nCount );
1369 9536048 : nBufActualPos = nBufActualPos + (sal_uInt16)nCount;
1370 : // Update length if buffer was updated
1371 9536048 : if( nBufActualPos > nBufActualLen )
1372 9533781 : nBufActualLen = nBufActualPos;
1373 :
1374 9536048 : pBufPos += nCount;
1375 9536048 : bIsDirty = true;
1376 : }
1377 : else
1378 : {
1379 : // Does stream require flushing?
1380 385642 : if( bIsDirty )
1381 : {
1382 246114 : SeekPos(m_nBufFilePos);
1383 246114 : if( nCryptMask )
1384 0 : CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
1385 : else
1386 246114 : PutData( pRWBuf, nBufActualLen );
1387 246114 : bIsDirty = false;
1388 : }
1389 :
1390 : // Does data block fit into buffer?
1391 385642 : if( nCount > nBufSize )
1392 : {
1393 149390 : bIoWrite = false;
1394 149390 : m_nBufFilePos += nBufActualPos;
1395 149390 : nBufActualLen = 0;
1396 149390 : nBufActualPos = 0;
1397 149390 : pBufPos = pRWBuf;
1398 149390 : SeekPos(m_nBufFilePos);
1399 149390 : if( nCryptMask )
1400 0 : nCount = CryptAndWriteBuffer( pData, nCount );
1401 : else
1402 149390 : nCount = PutData( pData, nCount );
1403 149390 : m_nBufFilePos += nCount;
1404 : }
1405 : else
1406 : {
1407 : // Copy block to buffer
1408 236252 : memcpy( pRWBuf, pData, (size_t)nCount );
1409 :
1410 : // Mind the order!
1411 236252 : m_nBufFilePos += nBufActualPos;
1412 236252 : nBufActualPos = (sal_uInt16)nCount;
1413 236252 : pBufPos = pRWBuf + nCount;
1414 236252 : nBufActualLen = (sal_uInt16)nCount;
1415 236252 : bIsDirty = true;
1416 : }
1417 : }
1418 9921690 : nBufFree = nBufSize - nBufActualPos;
1419 9921690 : return nCount;
1420 : }
1421 :
1422 7264320 : sal_uInt64 SvStream::Seek(sal_uInt64 const nFilePos)
1423 : {
1424 7264320 : bIoRead = bIoWrite = false;
1425 7264320 : bIsEof = false;
1426 7264320 : if( !pRWBuf )
1427 : {
1428 1325206 : m_nBufFilePos = SeekPos( nFilePos );
1429 : DBG_ASSERT(Tell() == m_nBufFilePos,"Out Of Sync!");
1430 1325206 : return m_nBufFilePos;
1431 : }
1432 :
1433 : // Is seek position within buffer?
1434 5939114 : if (nFilePos >= m_nBufFilePos && nFilePos <= (m_nBufFilePos + nBufActualLen))
1435 : {
1436 3845804 : nBufActualPos = (sal_uInt16)(nFilePos - m_nBufFilePos);
1437 3845804 : pBufPos = pRWBuf + nBufActualPos;
1438 : // Update nBufFree to avoid crash upon PutBack
1439 3845804 : nBufFree = nBufActualLen - nBufActualPos;
1440 : }
1441 : else
1442 : {
1443 2093310 : if( bIsDirty && bIsConsistent)
1444 : {
1445 1571813 : SeekPos(m_nBufFilePos);
1446 1571813 : if( nCryptMask )
1447 0 : CryptAndWriteBuffer( pRWBuf, nBufActualLen );
1448 : else
1449 1571813 : PutData( pRWBuf, nBufActualLen );
1450 1571813 : bIsDirty = false;
1451 : }
1452 2093310 : nBufActualLen = 0;
1453 2093310 : nBufActualPos = 0;
1454 2093310 : pBufPos = pRWBuf;
1455 2093310 : m_nBufFilePos = SeekPos( nFilePos );
1456 : }
1457 5939114 : return m_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 7162 : sal_uInt64 SvStream::remainingSize()
1464 : {
1465 7162 : sal_uInt64 const nCurr = Tell();
1466 7162 : sal_uInt64 const nEnd = Seek(STREAM_SEEK_TO_END);
1467 7162 : sal_uInt64 nMaxAvailable = nEnd-nCurr;
1468 7162 : Seek(nCurr);
1469 7162 : return nMaxAvailable;
1470 : }
1471 :
1472 187052 : void SvStream::Flush()
1473 : {
1474 187052 : if( bIsDirty && bIsConsistent )
1475 : {
1476 19931 : SeekPos(m_nBufFilePos);
1477 19931 : if( nCryptMask )
1478 0 : CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
1479 : else
1480 19931 : if( PutData( pRWBuf, nBufActualLen ) != nBufActualLen )
1481 5 : SetError( SVSTREAM_WRITE_ERROR );
1482 19931 : bIsDirty = false;
1483 : }
1484 187052 : if( bIsWritable )
1485 162311 : FlushData();
1486 187052 : }
1487 :
1488 22 : void SvStream::RefreshBuffer()
1489 : {
1490 22 : if( bIsDirty && bIsConsistent )
1491 : {
1492 0 : SeekPos(m_nBufFilePos);
1493 0 : if( nCryptMask )
1494 0 : CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
1495 : else
1496 0 : PutData( pRWBuf, nBufActualLen );
1497 0 : bIsDirty = false;
1498 : }
1499 22 : SeekPos(m_nBufFilePos);
1500 22 : nBufActualLen = (sal_uInt16)GetData( pRWBuf, nBufSize );
1501 22 : if( nBufActualLen && nError == ERRCODE_IO_PENDING )
1502 0 : nError = ERRCODE_NONE;
1503 22 : if( nCryptMask )
1504 0 : EncryptBuffer(pRWBuf, (sal_Size)nBufActualLen);
1505 22 : bIsConsistent = true;
1506 22 : bIoRead = bIoWrite = false;
1507 22 : }
1508 :
1509 0 : SvStream& SvStream::WriteInt32AsString(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::WriteUInt32AsString(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 const * pDataPtr = static_cast<unsigned char const *>(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( pTemp, nBufCount );
1553 0 : pDataPtr += nBufCount;
1554 : }
1555 : while ( nLen );
1556 0 : return nCount;
1557 : }
1558 :
1559 0 : bool SvStream::EncryptBuffer(void* pStart, sal_Size nLen)
1560 : {
1561 0 : unsigned char* pTemp = static_cast<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 true;
1572 : }
1573 :
1574 13 : static unsigned char implGetCryptMask(const sal_Char* pStr, sal_Int32 nLen, long nVersion)
1575 : {
1576 13 : unsigned char nCryptMask = 0;
1577 :
1578 13 : if (!nLen)
1579 13 : 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_Int32 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 13 : void SvStream::SetCryptMaskKey(const OString& rCryptMaskKey)
1610 : {
1611 13 : m_aCryptMaskKey = rCryptMaskKey;
1612 : nCryptMask = implGetCryptMask(m_aCryptMaskKey.getStr(),
1613 13 : m_aCryptMaskKey.getLength(), GetVersion());
1614 13 : }
1615 :
1616 426 : void SvStream::SyncSvStream( sal_Size nNewStreamPos )
1617 : {
1618 426 : ClearBuffer();
1619 426 : SvStream::m_nBufFilePos = nNewStreamPos;
1620 426 : }
1621 :
1622 426 : void SvStream::SyncSysStream()
1623 : {
1624 426 : Flush();
1625 426 : SeekPos( Tell() );
1626 426 : }
1627 :
1628 4181 : bool SvStream::SetStreamSize(sal_uInt64 const nSize)
1629 : {
1630 : #ifdef DBG_UTIL
1631 : sal_uInt64 nFPos = Tell();
1632 : #endif
1633 4181 : sal_uInt16 nBuf = nBufSize;
1634 4181 : SetBufferSize( 0 );
1635 4181 : SetSize( nSize );
1636 4181 : SetBufferSize( nBuf );
1637 : DBG_ASSERT(Tell()==nFPos,"SetStreamSize failed");
1638 4181 : return (nError == 0);
1639 : }
1640 :
1641 246092 : SvStream& endl( SvStream& rStr )
1642 : {
1643 246092 : LineEnd eDelim = rStr.GetLineDelimiter();
1644 246092 : if ( eDelim == LINEEND_CR )
1645 0 : rStr.WriteChar('\r');
1646 246092 : else if( eDelim == LINEEND_LF )
1647 246092 : rStr.WriteChar('\n');
1648 : else
1649 0 : rStr.WriteChar('\r').WriteChar('\n');
1650 246092 : return rStr;
1651 : }
1652 :
1653 0 : SvStream& endlu( SvStream& rStrm )
1654 : {
1655 0 : switch ( rStrm.GetLineDelimiter() )
1656 : {
1657 : case LINEEND_CR :
1658 0 : rStrm.WriteUnicode('\r');
1659 0 : break;
1660 : case LINEEND_LF :
1661 0 : rStrm.WriteUnicode('\n');
1662 0 : break;
1663 : default:
1664 0 : rStrm.WriteUnicode('\r').WriteUnicode('\n');
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 25148 : SvMemoryStream::SvMemoryStream( void* pBuffer, sal_Size bufSize,
1678 25148 : StreamMode eMode )
1679 : {
1680 25148 : if( eMode & StreamMode::WRITE )
1681 4945 : bIsWritable = true;
1682 : else
1683 20203 : bIsWritable = false;
1684 25148 : nEndOfData = bufSize;
1685 25148 : bOwnsData = false;
1686 25148 : pBuf = static_cast<sal_uInt8 *>(pBuffer);
1687 25148 : nResize = 0L;
1688 25148 : nSize = bufSize;
1689 25148 : nPos = 0L;
1690 25148 : SetBufferSize( 0 );
1691 25148 : }
1692 :
1693 47045 : SvMemoryStream::SvMemoryStream( sal_Size nInitSize, sal_Size nResizeOffset )
1694 : {
1695 47045 : bIsWritable = true;
1696 47045 : bOwnsData = true;
1697 47045 : nEndOfData = 0L;
1698 47045 : nResize = nResizeOffset;
1699 47045 : nPos = 0;
1700 47045 : pBuf = 0;
1701 47045 : if( nResize != 0 && nResize < 16 )
1702 0 : nResize = 16;
1703 47045 : if( nInitSize && !AllocateMemory( nInitSize ) )
1704 : {
1705 0 : SetError( SVSTREAM_OUTOFMEMORY );
1706 0 : nSize = 0;
1707 : }
1708 : else
1709 47045 : nSize = nInitSize;
1710 47045 : SetBufferSize( 64 );
1711 47045 : }
1712 :
1713 144682 : SvMemoryStream::~SvMemoryStream()
1714 : {
1715 72193 : if( pBuf )
1716 : {
1717 68235 : if( bOwnsData )
1718 43851 : FreeMemory();
1719 : else
1720 24384 : Flush();
1721 : }
1722 72489 : }
1723 :
1724 17 : const void* SvMemoryStream::GetBuffer()
1725 : {
1726 17 : Flush();
1727 17 : return GetData();
1728 : }
1729 :
1730 8085 : sal_uIntPtr SvMemoryStream::GetSize()
1731 : {
1732 8085 : Flush();
1733 8085 : sal_uInt64 const nTemp = Tell();
1734 8085 : sal_uInt64 const nLength = Seek( STREAM_SEEK_TO_END );
1735 8085 : Seek( nTemp );
1736 8085 : return nLength;
1737 : }
1738 :
1739 364 : void* SvMemoryStream::SetBuffer( void* pNewBuf, sal_Size nCount,
1740 : bool bOwnsDat, sal_Size nEOF )
1741 : {
1742 : void* pResult;
1743 364 : SetBufferSize( 0 ); // Buffering in der Basisklasse initialisieren
1744 364 : Seek( 0 );
1745 364 : if( bOwnsData )
1746 : {
1747 364 : pResult = 0;
1748 364 : if( pNewBuf != pBuf )
1749 364 : FreeMemory();
1750 : }
1751 : else
1752 0 : pResult = pBuf;
1753 :
1754 364 : pBuf = static_cast<sal_uInt8 *>(pNewBuf);
1755 364 : nPos = 0;
1756 364 : nSize = nCount;
1757 364 : nResize = 0;
1758 364 : bOwnsData = bOwnsDat;
1759 :
1760 364 : if( nEOF > nCount )
1761 0 : nEOF = nCount;
1762 364 : nEndOfData = nEOF;
1763 :
1764 364 : ResetError();
1765 :
1766 364 : return pResult;
1767 : }
1768 :
1769 935495 : sal_Size SvMemoryStream::GetData( void* pData, sal_Size nCount )
1770 : {
1771 935495 : sal_Size nMaxCount = nEndOfData-nPos;
1772 935495 : if( nCount > nMaxCount )
1773 30047 : nCount = nMaxCount;
1774 935495 : if (nCount != 0)
1775 : {
1776 931851 : memcpy( pData, pBuf+nPos, (size_t)nCount );
1777 : }
1778 935495 : nPos += nCount;
1779 935495 : return nCount;
1780 : }
1781 :
1782 2076295 : sal_Size SvMemoryStream::PutData( const void* pData, sal_Size nCount )
1783 : {
1784 2076295 : if( GetError() )
1785 0 : return 0L;
1786 :
1787 2076295 : sal_Size nMaxCount = nSize-nPos;
1788 :
1789 : // check for overflow
1790 2076295 : if( nCount > nMaxCount )
1791 : {
1792 17744 : if( nResize == 0 )
1793 : {
1794 : // copy as much as possible
1795 0 : nCount = nMaxCount;
1796 0 : SetError( SVSTREAM_OUTOFMEMORY );
1797 : }
1798 : else
1799 : {
1800 : long nNewResize;
1801 17744 : if( nSize && nSize > nResize )
1802 16561 : nNewResize = nSize;
1803 : else
1804 1183 : nNewResize = nResize;
1805 :
1806 17744 : if( (nCount-nMaxCount) < nResize )
1807 : {
1808 : // lacking memory is smaller than nResize,
1809 : // resize accordingly
1810 11167 : if( !ReAllocateMemory( nNewResize) )
1811 : {
1812 0 : nCount = 0;
1813 0 : SetError( SVSTREAM_WRITE_ERROR );
1814 : }
1815 : }
1816 : else
1817 : {
1818 : // lacking memory is larger than nResize,
1819 : // resize by (nCoount-nMaxCount) + resize offset
1820 6577 : if( !ReAllocateMemory( nCount-nMaxCount+nNewResize ) )
1821 : {
1822 0 : nCount = 0;
1823 0 : SetError( SVSTREAM_WRITE_ERROR );
1824 : }
1825 : }
1826 : }
1827 : }
1828 : assert(pBuf && "Possibly Reallocate failed");
1829 2076295 : memcpy( pBuf+nPos, pData, (size_t)nCount);
1830 :
1831 2076295 : nPos += nCount;
1832 2076295 : if( nPos > nEndOfData )
1833 1137281 : nEndOfData = nPos;
1834 2076295 : return nCount;
1835 : }
1836 :
1837 4021200 : sal_uInt64 SvMemoryStream::SeekPos(sal_uInt64 const nNewPos)
1838 : {
1839 : // nEndOfData: First position in stream not allowed to read from
1840 : // nSize: Size of allocated buffer
1841 :
1842 : // check if a truncated STREAM_SEEK_TO_END was passed
1843 : assert(nNewPos != SAL_MAX_UINT32);
1844 4021200 : if( nNewPos < nEndOfData )
1845 1950092 : nPos = nNewPos;
1846 2071108 : else if( nNewPos == STREAM_SEEK_TO_END )
1847 29633 : nPos = nEndOfData;
1848 : else
1849 : {
1850 2041475 : if( nNewPos >= nSize ) // Does buffer need extension?
1851 : {
1852 2452 : if( nResize ) // Is extension possible?
1853 : {
1854 727 : long nDiff = (long)(nNewPos - nSize + 1);
1855 727 : nDiff += (long)nResize;
1856 727 : ReAllocateMemory( nDiff );
1857 727 : nPos = nNewPos;
1858 727 : nEndOfData = nNewPos;
1859 : }
1860 : else // Extension not possible, set pos to end of data
1861 : {
1862 : // SetError( SVSTREAM_OUTOFMEMORY );
1863 1725 : nPos = nEndOfData;
1864 : }
1865 : }
1866 : else // Expand buffer size
1867 : {
1868 2039023 : nPos = nNewPos;
1869 2039023 : nEndOfData = nNewPos;
1870 : }
1871 : }
1872 4021200 : return nPos;
1873 : }
1874 :
1875 102724 : void SvMemoryStream::FlushData()
1876 : {
1877 102724 : }
1878 :
1879 8584 : void SvMemoryStream::ResetError()
1880 : {
1881 8584 : SvStream::ClearError();
1882 8584 : }
1883 :
1884 43113 : bool SvMemoryStream::AllocateMemory( sal_Size nNewSize )
1885 : {
1886 43113 : pBuf = new sal_uInt8[nNewSize];
1887 43113 : return( pBuf != 0 );
1888 : }
1889 :
1890 : // (using Bozo algorithm)
1891 19567 : bool SvMemoryStream::ReAllocateMemory( long nDiff )
1892 : {
1893 19567 : bool bRetVal = false;
1894 19567 : long nTemp = (long)nSize;
1895 19567 : nTemp += nDiff;
1896 19567 : sal_Size nNewSize = (sal_Size)nTemp;
1897 :
1898 19567 : if( nNewSize )
1899 : {
1900 19567 : sal_uInt8* pNewBuf = new sal_uInt8[nNewSize];
1901 :
1902 19567 : bRetVal = true; // Success!
1903 19567 : if( nNewSize < nSize ) // Are we shrinking?
1904 : {
1905 41 : memcpy( pNewBuf, pBuf, (size_t)nNewSize );
1906 41 : if( nPos > nNewSize )
1907 9 : nPos = 0L;
1908 41 : if( nEndOfData >= nNewSize )
1909 9 : nEndOfData = nNewSize-1L;
1910 : }
1911 19526 : else if (nSize != 0)
1912 : {
1913 19520 : memcpy( pNewBuf, pBuf, (size_t)nSize );
1914 : }
1915 :
1916 19567 : FreeMemory();
1917 :
1918 19567 : pBuf = pNewBuf;
1919 19567 : nSize = nNewSize;
1920 : }
1921 : else
1922 : {
1923 0 : bRetVal = true;
1924 0 : FreeMemory();
1925 0 : pBuf = 0;
1926 0 : nSize = 0;
1927 0 : nEndOfData = 0;
1928 0 : nPos = 0;
1929 : }
1930 :
1931 19567 : return bRetVal;
1932 : }
1933 :
1934 63782 : void SvMemoryStream::FreeMemory()
1935 : {
1936 63782 : delete[] pBuf;
1937 63782 : }
1938 :
1939 32 : void* SvMemoryStream::SwitchBuffer( sal_Size nInitSize, sal_Size nResizeOffset)
1940 : {
1941 32 : Flush();
1942 32 : if( !bOwnsData )
1943 0 : return 0;
1944 32 : Seek( STREAM_SEEK_TO_BEGIN );
1945 :
1946 32 : void* pRetVal = pBuf;
1947 32 : pBuf = 0;
1948 32 : nEndOfData = 0L;
1949 32 : nResize = nResizeOffset;
1950 32 : nPos = 0;
1951 :
1952 32 : if( nResize != 0 && nResize < 16 )
1953 0 : nResize = 16;
1954 :
1955 32 : ResetError();
1956 :
1957 32 : if( nInitSize && !AllocateMemory(nInitSize) )
1958 : {
1959 0 : SetError( SVSTREAM_OUTOFMEMORY );
1960 0 : nSize = 0;
1961 : }
1962 : else
1963 32 : nSize = nInitSize;
1964 :
1965 32 : SetBufferSize( 64 );
1966 32 : return pRetVal;
1967 : }
1968 :
1969 1077 : void SvMemoryStream::SetSize(sal_uInt64 const nNewSize)
1970 : {
1971 1077 : long nDiff = (long)nNewSize - (long)nSize;
1972 1077 : ReAllocateMemory( nDiff );
1973 1077 : }
1974 :
1975 0 : SvScriptStream::SvScriptStream(const OUString& rUrl):
1976 0 : mpProcess(NULL), mpHandle(NULL)
1977 : {
1978 : oslProcessError rc;
1979 : rc = osl_executeProcess_WithRedirectedIO(
1980 : rUrl.pData,
1981 : NULL, 0,
1982 : osl_Process_HIDDEN,
1983 : NULL,
1984 : NULL,
1985 : NULL, 0,
1986 : &mpProcess,
1987 0 : NULL, &mpHandle, NULL);
1988 0 : if (osl_Process_E_None != rc)
1989 : {
1990 0 : mpProcess = NULL;
1991 0 : mpHandle = NULL;
1992 : }
1993 0 : }
1994 :
1995 0 : SvScriptStream::~SvScriptStream()
1996 : {
1997 0 : if (mpProcess)
1998 : {
1999 0 : osl_terminateProcess(mpProcess);
2000 0 : osl_freeProcessHandle(mpProcess);
2001 : }
2002 0 : if (mpHandle)
2003 0 : osl_closeFile(mpHandle);
2004 0 : }
2005 :
2006 0 : bool SvScriptStream::ReadLine(OString &rStr, sal_Int32)
2007 : {
2008 0 : rStr.clear();
2009 0 : if (!good())
2010 0 : return false;
2011 :
2012 0 : OStringBuffer sBuf;
2013 0 : sal_Char aChar('\n');
2014 : sal_uInt64 nBytesRead;
2015 0 : while (osl_File_E_None == osl_readFile(mpHandle, &aChar, 1, &nBytesRead)
2016 0 : && nBytesRead == 1 && aChar != '\n')
2017 : {
2018 0 : sBuf.append( aChar );
2019 : }
2020 0 : rStr = sBuf.makeStringAndClear();
2021 0 : if (!rStr.isEmpty())
2022 0 : return true;
2023 :
2024 0 : return false;
2025 : }
2026 :
2027 0 : bool SvScriptStream::good() const
2028 : {
2029 0 : return mpHandle != NULL;
2030 : }
2031 :
2032 0 : TYPEINIT0 ( SvDataCopyStream )
2033 :
2034 0 : void SvDataCopyStream::Assign( const SvDataCopyStream& )
2035 : {
2036 0 : }
2037 :
2038 : //Create a OString of nLen bytes from rStream
2039 110383 : OString read_uInt8s_ToOString(SvStream& rStrm, sal_Size nLen)
2040 : {
2041 110383 : rtl_String *pStr = NULL;
2042 110383 : if (nLen)
2043 : {
2044 69678 : nLen = std::min(nLen, static_cast<sal_Size>(SAL_MAX_INT32));
2045 : //alloc a (ref-count 1) rtl_String of the desired length.
2046 : //rtl_String's buffer is uninitialized, except for null termination
2047 69678 : pStr = rtl_string_alloc(sal::static_int_cast<sal_Int32>(nLen));
2048 : SAL_WARN_IF(!pStr, "tools", "allocation failed");
2049 69678 : if (pStr)
2050 : {
2051 69678 : sal_Size nWasRead = rStrm.Read(pStr->buffer, nLen);
2052 69678 : if (nWasRead != nLen)
2053 : {
2054 : //on (typically unlikely) short read set length to what we could
2055 : //read, and null terminate. Excess buffer capacity remains of
2056 : //course, could create a (true) replacement OString if it matters.
2057 498 : pStr->length = sal::static_int_cast<sal_Int32>(nWasRead);
2058 498 : pStr->buffer[pStr->length] = 0;
2059 : }
2060 : }
2061 : }
2062 :
2063 : //take ownership of buffer and return, otherwise return empty string
2064 110383 : return pStr ? OString(pStr, SAL_NO_ACQUIRE) : OString();
2065 : }
2066 :
2067 : //Create a OUString of nLen sal_Unicodes from rStream
2068 56897 : OUString read_uInt16s_ToOUString(SvStream& rStrm, sal_Size nLen)
2069 : {
2070 56897 : rtl_uString *pStr = NULL;
2071 56897 : if (nLen)
2072 : {
2073 54833 : nLen = std::min(nLen, static_cast<sal_Size>(SAL_MAX_INT32));
2074 : //alloc a (ref-count 1) rtl_uString of the desired length.
2075 : //rtl_String's buffer is uninitialized, except for null termination
2076 54833 : pStr = rtl_uString_alloc(sal::static_int_cast<sal_Int32>(nLen));
2077 : SAL_WARN_IF(!pStr, "tools", "allocation failed");
2078 54833 : if (pStr)
2079 : {
2080 54833 : sal_Size nWasRead = rStrm.Read(pStr->buffer, nLen*2)/2;
2081 54833 : if (nWasRead != nLen)
2082 : {
2083 : //on (typically unlikely) short read set length to what we could
2084 : //read, and null terminate. Excess buffer capacity remains of
2085 : //course, could create a (true) replacement OUString if it matters.
2086 4 : pStr->length = sal::static_int_cast<sal_Int32>(nWasRead);
2087 4 : pStr->buffer[pStr->length] = 0;
2088 : }
2089 54833 : if (rStrm.IsEndianSwap())
2090 : {
2091 0 : for (sal_Int32 i = 0; i < pStr->length; ++i)
2092 0 : pStr->buffer[i] = OSL_SWAPWORD(pStr->buffer[i]);
2093 : }
2094 : }
2095 : }
2096 :
2097 : //take ownership of buffer and return, otherwise return empty string
2098 56897 : return pStr ? OUString(pStr, SAL_NO_ACQUIRE) : OUString();
2099 : }
2100 :
2101 : namespace
2102 : {
2103 109817 : template <typename T, typename O> T tmpl_convertLineEnd(const T &rIn, LineEnd eLineEnd)
2104 : {
2105 : // Determine linebreaks and compute length
2106 109817 : bool bConvert = false; // Needs conversion
2107 109817 : sal_Int32 nStrLen = rIn.getLength();
2108 109817 : sal_Int32 nLineEndLen = (eLineEnd == LINEEND_CRLF) ? 2 : 1;
2109 109817 : sal_Int32 nLen = 0; // Target length
2110 109817 : sal_Int32 i = 0; // Source counter
2111 :
2112 850477 : while (i < nStrLen)
2113 : {
2114 : // \r or \n causes linebreak
2115 630843 : if ( (rIn[i] == '\r') || (rIn[i] == '\n') )
2116 : {
2117 9840 : nLen = nLen + nLineEndLen;
2118 :
2119 : // If set already, skip expensive test
2120 9840 : if ( !bConvert )
2121 : {
2122 : // Muessen wir Konvertieren
2123 21698 : if ( ((eLineEnd != LINEEND_LF) && (rIn[i] == '\n')) ||
2124 0 : ((eLineEnd == LINEEND_CRLF) && (i+1) < nStrLen && (rIn[i+1] != '\n')) ||
2125 : ((eLineEnd == LINEEND_LF) &&
2126 12065 : ((rIn[i] == '\r') || ((i+1) < nStrLen && rIn[i+1] == '\r'))) ||
2127 : ((eLineEnd == LINEEND_CR) &&
2128 0 : ((rIn[i] == '\n') || ((i+1) < nStrLen && rIn[i+1] == '\n'))) )
2129 3557 : bConvert = true;
2130 : }
2131 :
2132 : // skip char if \r\n or \n\r
2133 9851 : if ( (i+1) < nStrLen && ((rIn[i+1] == '\r') || (rIn[i+1] == '\n')) &&
2134 11 : (rIn[i] != rIn[i+1]) )
2135 0 : ++i;
2136 : }
2137 : else
2138 621003 : ++nLen;
2139 630843 : ++i;
2140 : }
2141 :
2142 109817 : if (!bConvert)
2143 106260 : return rIn;
2144 :
2145 : // convert linebreaks, insert string
2146 3557 : O aNewData(nLen);
2147 3557 : i = 0;
2148 11401 : while (i < nStrLen)
2149 : {
2150 : // \r or \n causes linebreak
2151 4287 : if ( (rIn[i] == '\r') || (rIn[i] == '\n') )
2152 : {
2153 3764 : if ( eLineEnd == LINEEND_CRLF )
2154 : {
2155 0 : aNewData.append('\r');
2156 0 : aNewData.append('\n');
2157 : }
2158 : else
2159 : {
2160 3764 : if ( eLineEnd == LINEEND_CR )
2161 0 : aNewData.append('\r');
2162 : else
2163 3764 : aNewData.append('\n');
2164 : }
2165 :
2166 3764 : if ( (i+1) < nStrLen && ((rIn[i+1] == '\r') || (rIn[i+1] == '\n')) &&
2167 0 : (rIn[i] != rIn[i+1]) )
2168 0 : ++i;
2169 : }
2170 : else
2171 : {
2172 523 : aNewData.append(rIn[i]);
2173 : }
2174 :
2175 4287 : ++i;
2176 : }
2177 :
2178 3557 : return aNewData.makeStringAndClear();
2179 : }
2180 : }
2181 :
2182 84 : OString convertLineEnd(const OString &rIn, LineEnd eLineEnd)
2183 : {
2184 84 : return tmpl_convertLineEnd<OString, OStringBuffer>(rIn, eLineEnd);
2185 : }
2186 :
2187 109733 : OUString convertLineEnd(const OUString &rIn, LineEnd eLineEnd)
2188 : {
2189 109733 : return tmpl_convertLineEnd<OUString, OUStringBuffer>(rIn, eLineEnd);
2190 : }
2191 :
2192 14112 : sal_Size write_uInt32_lenPrefixed_uInt16s_FromOUString(SvStream& rStrm,
2193 : const OUString &rStr)
2194 : {
2195 14112 : sal_Size nWritten = 0;
2196 14112 : sal_uInt32 nUnits = std::min<sal_Size>(rStr.getLength(), std::numeric_limits<sal_uInt32>::max());
2197 : SAL_WARN_IF(static_cast<sal_Size>(nUnits) != static_cast<sal_Size>(rStr.getLength()),
2198 : "tools.stream",
2199 : "string too long for prefix count to fit in output type");
2200 14112 : rStrm.WriteUInt32(nUnits);
2201 14112 : if (rStrm.good())
2202 : {
2203 14112 : nWritten += sizeof(sal_uInt32);
2204 14112 : nWritten += write_uInt16s_FromOUString(rStrm, rStr, nUnits);
2205 : }
2206 14112 : return nWritten;
2207 : }
2208 :
2209 46403 : sal_Size write_uInt16_lenPrefixed_uInt16s_FromOUString(SvStream& rStrm,
2210 : const OUString &rStr)
2211 : {
2212 46403 : sal_Size nWritten = 0;
2213 46403 : sal_uInt16 nUnits = std::min<sal_Size>(rStr.getLength(), std::numeric_limits<sal_uInt16>::max());
2214 : SAL_WARN_IF(nUnits != rStr.getLength(),
2215 : "tools.stream",
2216 : "string too long for prefix count to fit in output type");
2217 46403 : rStrm.WriteUInt16(nUnits);
2218 46403 : if (rStrm.good())
2219 : {
2220 46403 : nWritten += sizeof(nUnits);
2221 46403 : nWritten += write_uInt16s_FromOUString(rStrm, rStr, nUnits);
2222 : }
2223 46403 : return nWritten;
2224 : }
2225 :
2226 164854 : sal_Size write_uInt16_lenPrefixed_uInt8s_FromOString(SvStream& rStrm,
2227 : const OString &rStr)
2228 : {
2229 164854 : sal_Size nWritten = 0;
2230 164854 : sal_uInt16 nUnits = std::min<sal_Size>(rStr.getLength(), std::numeric_limits<sal_uInt16>::max());
2231 : SAL_WARN_IF(static_cast<sal_Size>(nUnits) != static_cast<sal_Size>(rStr.getLength()),
2232 : "tools.stream",
2233 : "string too long for sal_uInt16 count to fit in output type");
2234 164854 : rStrm.WriteUInt16( nUnits );
2235 164854 : if (rStrm.good())
2236 : {
2237 164854 : nWritten += sizeof(sal_uInt16);
2238 164854 : nWritten += write_uInt8s_FromOString(rStrm, rStr, nUnits);
2239 : }
2240 164854 : return nWritten;
2241 : }
2242 :
2243 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|