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 : #ifndef _STREAM_HXX
20 : #define _STREAM_HXX
21 :
22 : #include <limits>
23 : #include "tools/toolsdllapi.h"
24 : #include <tools/solar.h>
25 : #include <tools/lineend.hxx>
26 : #include <tools/errinf.hxx>
27 : #include <tools/ref.hxx>
28 : #include <tools/rtti.hxx>
29 : #include <rtl/string.hxx>
30 :
31 : class StreamData;
32 :
33 27508 : inline rtl_TextEncoding GetStoreCharSet( rtl_TextEncoding eEncoding )
34 : {
35 27508 : if ( eEncoding == RTL_TEXTENCODING_ISO_8859_1 )
36 0 : return RTL_TEXTENCODING_MS_1252;
37 : else
38 27508 : return eEncoding;
39 : }
40 :
41 : // StreamTypes
42 :
43 : typedef sal_uInt16 StreamMode;
44 :
45 : // read, write, create,... options
46 : #define STREAM_READ 0x0001 ///< allow read accesses
47 : #define STREAM_WRITE 0x0002 ///< allow write accesses
48 : // file i/o
49 : #define STREAM_NOCREATE 0x0004 ///< 1 == Dont create file
50 : #define STREAM_TRUNC 0x0008 ///< Truncate _existing_ file to zero length
51 : #define STREAM_COPY_ON_SYMLINK 0x0010 ///< copy-on-write for symlinks (UNX)
52 :
53 : #define STREAM_READWRITEBITS (STREAM_READ | STREAM_WRITE | \
54 : STREAM_NOCREATE | STREAM_TRUNC)
55 :
56 : // sharing options
57 : #define STREAM_SHARE_DENYNONE 0x0100
58 : #define STREAM_SHARE_DENYREAD 0x0200 // overrides denynone
59 : #define STREAM_SHARE_DENYWRITE 0x0400 // overrides denynone
60 : #define STREAM_SHARE_DENYALL 0x0800 // overrides denyread,write,none
61 :
62 : #define STREAM_SHAREBITS (STREAM_SHARE_DENYNONE | STREAM_SHARE_DENYREAD |\
63 : STREAM_SHARE_DENYWRITE | STREAM_SHARE_DENYALL)
64 :
65 : #define STREAM_READWRITE (STREAM_READ | STREAM_WRITE)
66 : #define STREAM_SHARE_DENYREADWRITE (STREAM_SHARE_DENYREAD | STREAM_SHARE_DENYWRITE)
67 :
68 : #define STREAM_STD_READ (STREAM_READ | STREAM_SHARE_DENYNONE | STREAM_NOCREATE)
69 : #define STREAM_STD_WRITE (STREAM_WRITE | STREAM_SHARE_DENYALL)
70 : #define STREAM_STD_READWRITE (STREAM_READWRITE | STREAM_SHARE_DENYALL)
71 :
72 : #define STREAM_SEEK_TO_BEGIN 0L
73 : #define STREAM_SEEK_TO_END ULONG_MAX
74 :
75 : #define NUMBERFORMAT_INT_BIGENDIAN (sal_uInt16)0x0000
76 : #define NUMBERFORMAT_INT_LITTLEENDIAN (sal_uInt16)0xFFFF
77 :
78 : #define COMPRESSMODE_NONE (sal_uInt16)0x0000
79 : #define COMPRESSMODE_ZBITMAP (sal_uInt16)0x0001
80 : #define COMPRESSMODE_NATIVE (sal_uInt16)0x0010
81 :
82 : #define ID_STREAM 1
83 : #define ID_FILESTREAM 2
84 : #define ID_MEMORYSTREAM 3
85 : #define ID_SHAREDMEMORYSTREAM 4
86 : #define ID_STORAGESTREAM 5
87 : #define ID_PERSISTSTREAM 6
88 :
89 : class SvStream;
90 :
91 : typedef SvStream& (*SvStrPtr)( SvStream& );
92 :
93 : inline SvStream& operator<<( SvStream& rStr, SvStrPtr f );
94 :
95 : // SvLockBytes
96 :
97 : enum LockType {};
98 :
99 : struct SvLockBytesStat
100 : {
101 : sal_Size nSize;
102 :
103 27592 : SvLockBytesStat() : nSize(0) {}
104 : };
105 :
106 : enum SvLockBytesStatFlag { SVSTATFLAG_DEFAULT };
107 :
108 : class TOOLS_DLLPUBLIC SvLockBytes: public virtual SvRefBase
109 : {
110 : SvStream * m_pStream;
111 : bool m_bOwner;
112 : bool m_bSync;
113 :
114 : protected:
115 : void close();
116 :
117 : public:
118 : TYPEINFO();
119 :
120 14778 : SvLockBytes() : m_pStream(0), m_bOwner(false), m_bSync(false) {}
121 :
122 1 : SvLockBytes(SvStream * pTheStream, bool bTheOwner = false) :
123 1 : m_pStream(pTheStream), m_bOwner(bTheOwner), m_bSync(false) {}
124 :
125 14750 : virtual ~SvLockBytes() { close(); }
126 :
127 14783 : virtual const SvStream * GetStream() const { return m_pStream; }
128 :
129 23303 : virtual void SetSynchronMode(bool bTheSync = true) { m_bSync = bTheSync; }
130 72543 : virtual bool IsSynchronMode() const { return m_bSync; }
131 :
132 : virtual ErrCode ReadAt(sal_Size nPos, void * pBuffer, sal_Size nCount,
133 : sal_Size * pRead) const;
134 : virtual ErrCode WriteAt(sal_Size nPos, const void * pBuffer, sal_Size nCount,
135 : sal_Size * pWritten);
136 :
137 : virtual ErrCode Flush() const;
138 :
139 : virtual ErrCode SetSize(sal_Size nSize);
140 :
141 : virtual ErrCode Stat(SvLockBytesStat * pStat, SvLockBytesStatFlag) const;
142 : };
143 :
144 335978 : SV_DECL_IMPL_REF(SvLockBytes);
145 :
146 : // SvOpenLockBytes
147 :
148 0 : class TOOLS_DLLPUBLIC SvOpenLockBytes: public SvLockBytes
149 : {
150 : public:
151 : TYPEINFO();
152 :
153 0 : SvOpenLockBytes() : SvLockBytes(0, false) {}
154 0 : SvOpenLockBytes(SvStream * pStream, bool bOwner):
155 0 : SvLockBytes(pStream, bOwner) {}
156 :
157 : virtual ErrCode FillAppend(const void * pBuffer, sal_Size nCount,
158 : sal_Size * pWritten) = 0;
159 :
160 : virtual sal_Size Tell() const = 0;
161 :
162 : virtual sal_Size Seek(sal_Size nPos) = 0;
163 :
164 : virtual void Terminate() = 0;
165 : };
166 :
167 : SV_DECL_IMPL_REF(SvOpenLockBytes);
168 :
169 : // SvAsyncLockBytes
170 :
171 0 : class SvAsyncLockBytes: public SvOpenLockBytes
172 : {
173 : sal_Size m_nSize;
174 : bool m_bTerminated;
175 :
176 : public:
177 : TYPEINFO();
178 :
179 0 : SvAsyncLockBytes(SvStream * pStream, bool bOwner):
180 0 : SvOpenLockBytes(pStream, bOwner), m_nSize(0), m_bTerminated(false) {}
181 :
182 : virtual ErrCode ReadAt(sal_Size nPos, void * pBuffer, sal_Size nCount,
183 : sal_Size * pRead) const;
184 : virtual ErrCode WriteAt(sal_Size nPos, const void * pBuffer, sal_Size nCount,
185 : sal_Size * pWritten);
186 :
187 : virtual ErrCode FillAppend(const void * pBuffer, sal_Size nCount,
188 : sal_Size * pWritten);
189 :
190 0 : virtual sal_Size Tell() const { return m_nSize; }
191 :
192 : virtual sal_Size Seek(sal_Size nPos);
193 :
194 0 : virtual void Terminate() { m_bTerminated = true; }
195 : };
196 :
197 : SV_DECL_IMPL_REF(SvAsyncLockBytes);
198 :
199 : // SvStream
200 :
201 : class TOOLS_DLLPUBLIC SvStream
202 : {
203 : private:
204 : // LockBytes Interface
205 : void* pImp; // unused
206 : SvLockBytesRef xLockBytes; // Default implementation
207 : sal_Size nActPos;
208 :
209 : // Puffer-Verwaltung
210 : sal_uInt8* pRWBuf; // Points to read/write buffer
211 : sal_uInt8* pBufPos; // pRWBuf + nBufActualPos
212 : sal_uInt16 nBufSize; // Allocated size of buffer
213 : sal_uInt16 nBufActualLen; // Length of used segment of puffer
214 : // = nBufSize, if EOF did not occur
215 : sal_uInt16 nBufActualPos; // current position in buffer (0..nBufSize-1)
216 : sal_uInt16 nBufFree; // number of free slots in buffer to IO of type eIOMode
217 : bool bIoRead;
218 : bool bIoWrite;
219 :
220 : // Error codes, conversion, compression, ...
221 : bool bIsDirty; // true: Stream != buffer content
222 : bool bIsConsistent;// false: Buffer contains data, which were
223 : // NOT allowed to be written by PutData
224 : // into the derived stream (cf. PutBack)
225 : bool bSwap;
226 : bool bIsEof;
227 : sal_uInt32 nError;
228 : sal_uInt16 nNumberFormatInt;
229 : sal_uInt16 nCompressMode;
230 : LineEnd eLineDelimiter;
231 : rtl_TextEncoding eStreamCharSet;
232 :
233 : // Encryption
234 : OString m_aCryptMaskKey;// aCryptMaskKey.getLength != 0 -> Encryption used
235 : unsigned char nCryptMask;
236 :
237 : // Userdata
238 : long nVersion; // for external use
239 :
240 : // helper methods
241 : TOOLS_DLLPRIVATE void ImpInit();
242 :
243 : SvStream ( const SvStream& rStream ); // not implemented
244 : SvStream& operator=( const SvStream& rStream ); // not implemented
245 :
246 : protected:
247 : sal_Size nBufFilePos;///< File position of pBuf[0]
248 : sal_uInt16 eStreamMode;
249 : bool bIsWritable;
250 :
251 : virtual sal_Size GetData( void* pData, sal_Size nSize );
252 : virtual sal_Size PutData( const void* pData, sal_Size nSize );
253 : virtual sal_Size SeekPos( sal_Size nPos );
254 : virtual void FlushData();
255 : virtual void SetSize( sal_Size nSize );
256 :
257 : void ClearError();
258 : void ClearBuffer();
259 :
260 : // encrypt and write in blocks
261 : sal_Size CryptAndWriteBuffer( const void* pStart, sal_Size nLen );
262 : bool EncryptBuffer( void* pStart, sal_Size nLen );
263 :
264 : void SyncSvStream( sal_Size nNewStreamPos ); ///< SvStream <- Medium
265 : void SyncSysStream(); ///< SvStream -> Medium
266 :
267 : public:
268 : SvStream();
269 : SvStream( SvLockBytes *pLockBytes);
270 : virtual ~SvStream();
271 :
272 76 : SvLockBytes* GetLockBytes() const { return xLockBytes; }
273 :
274 13191939 : sal_uInt32 GetError() const { return ERRCODE_TOERROR(nError); }
275 20532 : sal_uInt32 GetErrorCode() const { return nError; }
276 :
277 : void SetError( sal_uInt32 nErrorCode );
278 : virtual void ResetError();
279 :
280 : void SetNumberFormatInt( sal_uInt16 nNewFormat );
281 17919 : sal_uInt16 GetNumberFormatInt() const { return nNumberFormatInt; }
282 : /// Enable/disable swapping of endians, may be needed for Unicode import/export
283 : inline void SetEndianSwap( bool bVal );
284 : /// returns status of endian swap flag
285 78080 : bool IsEndianSwap() const { return 0 != bSwap; }
286 :
287 1023 : void SetCompressMode( sal_uInt16 nNewMode )
288 1023 : { nCompressMode = nNewMode; }
289 4468 : sal_uInt16 GetCompressMode() const { return nCompressMode; }
290 :
291 : void SetCryptMaskKey(const OString& rCryptMaskKey);
292 : const OString& GetCryptMaskKey() const { return m_aCryptMaskKey; }
293 :
294 11342 : void SetStreamCharSet( rtl_TextEncoding eCharSet )
295 11342 : { eStreamCharSet = eCharSet; }
296 144944 : rtl_TextEncoding GetStreamCharSet() const { return eStreamCharSet; }
297 :
298 124 : void SetLineDelimiter( LineEnd eLineEnd )
299 124 : { eLineDelimiter = eLineEnd; }
300 497214 : LineEnd GetLineDelimiter() const { return eLineDelimiter; }
301 :
302 : SvStream& operator>>( sal_uInt16& rUInt16 );
303 : SvStream& operator>>( sal_uInt32& rUInt32 );
304 : SvStream& operator>>( sal_uInt64& rUInt64 );
305 : SvStream& operator>>( sal_Int16& rInt16 );
306 : SvStream& operator>>( sal_Int32& rInt32 );
307 : SvStream& operator>>( sal_Int64& rInt64 ) SAL_DELETED_FUNCTION;
308 : SvStream& ReadInt64(sal_Int64 & rInt64);
309 :
310 : SvStream& operator>>( signed char& rChar );
311 : SvStream& operator>>( char& rChar );
312 : SvStream& operator>>( unsigned char& rChar );
313 : SvStream& operator>>( float& rFloat );
314 : SvStream& operator>>( double& rDouble );
315 : SvStream& operator>>( SvStream& rStream );
316 :
317 : SvStream& operator<<( sal_uInt16 nUInt16 );
318 : SvStream& operator<<( sal_uInt32 nUInt32 );
319 : SvStream& operator<<( sal_uInt64 nuInt64 );
320 : SvStream& operator<<( sal_Int16 nInt16 );
321 : SvStream& operator<<( sal_Int32 nInt32 );
322 : SvStream& operator<<( sal_Int64 nInt64 ) SAL_DELETED_FUNCTION;
323 : SvStream& WriteInt64(sal_Int64 nInt64);
324 :
325 0 : SvStream& operator<<( bool b )
326 0 : { return operator<<(static_cast< sal_Bool >(b)); }
327 : SvStream& operator<<( signed char nChar );
328 : SvStream& operator<<( char nChar );
329 : SvStream& operator<<( unsigned char nChar );
330 : SvStream& operator<<( float nFloat );
331 : SvStream& operator<<( const double& rDouble );
332 : SvStream& operator<<( const char* pBuf );
333 : SvStream& operator<<( const unsigned char* pBuf );
334 : SvStream& operator<<( SvStream& rStream );
335 :
336 : SvStream& WriteNumber( sal_uInt32 nUInt32 );
337 : SvStream& WriteNumber( sal_Int32 nInt32 );
338 :
339 : sal_Size Read( void* pData, sal_Size nSize );
340 : sal_Size Write( const void* pData, sal_Size nSize );
341 : sal_Size Seek( sal_Size nPos );
342 : sal_Size SeekRel( sal_sSize nPos );
343 7260379 : sal_Size Tell() const { return nBufFilePos+nBufActualPos; }
344 : // length between current (Tell()) pos and end of stream
345 : virtual sal_Size remainingSize();
346 : void Flush();
347 2099125 : bool IsEof() const { return bIsEof; }
348 : // next Tell() <= nSize
349 : bool SetStreamSize( sal_Size nSize );
350 :
351 : /** Read a line of bytes.
352 :
353 : @param nMaxBytesToRead
354 : Maximum of bytes to read, if line is longer it will be
355 : truncated.
356 :
357 : @note NOTE that the default is one character less than STRING_MAXLEN to
358 : prevent problems after conversion to String that may be lurking
359 : in various places doing something like
360 : @code
361 : for (sal_uInt16 i=0; i < aString.Len(); ++i)
362 : @endcode
363 : causing endless loops ...
364 : */
365 : bool ReadLine( OString& rStr, sal_Int32 nMaxBytesToRead = 0xFFFE );
366 : bool WriteLine( const OString& rStr );
367 :
368 : /** Read a line of bytes.
369 :
370 : @param nMaxBytesToRead
371 : Maximum of bytes to read, if line is longer it will be
372 : truncated.
373 :
374 : @note NOTE that the default is one character less than STRING_MAXLEN to
375 : prevent problems after conversion to String that may be lurking
376 : in various places doing something like
377 : @code
378 : for (sal_uInt16 i=0; i < aString.Len(); ++i)
379 : @endcode
380 : causing endless loops ...
381 : */
382 : bool ReadByteStringLine( OUString& rStr, rtl_TextEncoding eSrcCharSet,
383 : sal_Int32 nMaxBytesToRead = 0xFFFE );
384 : bool WriteByteStringLine( const OUString& rStr, rtl_TextEncoding eDestCharSet );
385 :
386 : /// Switch to no endian swapping and write 0xfeff
387 : bool StartWritingUnicodeText();
388 :
389 : /** If eReadBomCharSet==RTL_TEXTENCODING_DONTKNOW: read 16bit, if 0xfeff do
390 : nothing (UTF-16), if 0xfffe switch endian swapping (UTF-16), if 0xefbb
391 : or 0xbbef read another byte and check for UTF-8. If no UTF-* BOM was
392 : detected put all read bytes back. This means that if 2 bytes were read
393 : it was an UTF-16 BOM, if 3 bytes were read it was an UTF-8 BOM. There
394 : is no UTF-7, UTF-32 or UTF-EBCDIC BOM detection!
395 :
396 : If eReadBomCharSet!=RTL_TEXTENCODING_DONTKNOW: only read a BOM of that
397 : encoding and switch endian swapping if UTF-16 and 0xfffe. */
398 : bool StartReadingUnicodeText( rtl_TextEncoding eReadBomCharSet );
399 :
400 : /** Read a line of Unicode.
401 :
402 : @param nMaxCodepointsToRead
403 : Maximum of codepoints (UCS-2 or UTF-16 pairs, not bytes) to
404 : read, if line is longer it will be truncated.
405 :
406 : @note NOTE that the default is one character less than STRING_MAXLEN to
407 : prevent problems after conversion to String that may be lurking in
408 : various places doing something like
409 : @code
410 : for (sal_uInt16 i=0; i < aString.Len(); ++i)
411 : @endcode
412 : causing endless loops ...
413 : */
414 : bool ReadUniStringLine( OUString& rStr, sal_Int32 nMaxCodepointsToRead = 0xFFFE );
415 : /** Read a 32bit length prefixed sequence of utf-16 if
416 : eSrcCharSet==RTL_TEXTENCODING_UNICODE, otherwise read a 16bit length
417 : prefixed sequence of bytes and convert from eSrcCharSet */
418 : OUString ReadUniOrByteString(rtl_TextEncoding eSrcCharSet);
419 : /** Write a 32bit length prefixed sequence of utf-16 if
420 : eSrcCharSet==RTL_TEXTENCODING_UNICODE, otherwise convert to eSrcCharSet
421 : and write a 16bit length prefixed sequence of bytes */
422 : SvStream& WriteUniOrByteString( const OUString& rStr, rtl_TextEncoding eDestCharSet );
423 :
424 : /** Read a line of Unicode if eSrcCharSet==RTL_TEXTENCODING_UNICODE,
425 : otherwise read a line of Bytecode and convert from eSrcCharSet
426 :
427 : @param nMaxCodepointsToRead
428 : Maximum of codepoints (2 bytes if Unicode, bytes if not
429 : Unicode) to read, if line is longer it will be truncated.
430 :
431 : @note NOTE that the default is one character less than STRING_MAXLEN to
432 : prevent problems after conversion to String that may be lurking in
433 : various places doing something like
434 : @code
435 : for (sal_uInt16 i=0; i < aString.Len(); ++i)
436 : @endcode
437 : causing endless loops ...
438 : */
439 : bool ReadUniOrByteStringLine( OUString& rStr, rtl_TextEncoding eSrcCharSet,
440 : sal_Int32 nMaxCodepointsToRead = 0xFFFE );
441 : /** Write a sequence of Unicode characters if
442 : eDestCharSet==RTL_TEXTENCODING_UNICODE, otherwise write a sequence of
443 : Bytecodes converted to eDestCharSet */
444 : bool WriteUnicodeOrByteText( const OUString& rStr, rtl_TextEncoding eDestCharSet );
445 6654 : bool WriteUnicodeOrByteText( const OUString& rStr )
446 6654 : { return WriteUnicodeOrByteText( rStr, GetStreamCharSet() ); }
447 :
448 : /** Write a Unicode character if eDestCharSet==RTL_TEXTENCODING_UNICODE,
449 : otherwise write as Bytecode converted to eDestCharSet.
450 :
451 : This may result in more than one byte being written if a multi byte
452 : encoding (e.g. UTF7, UTF8) is chosen. */
453 : bool WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet );
454 0 : bool WriteUniOrByteChar( sal_Unicode ch )
455 0 : { return WriteUniOrByteChar( ch, GetStreamCharSet() ); }
456 :
457 : void SetBufferSize( sal_uInt16 nBufSize );
458 53 : sal_uInt16 GetBufferSize() const { return nBufSize; }
459 :
460 : void RefreshBuffer();
461 : SvStream& PutBack( char aCh );
462 :
463 642 : bool IsWritable() const { return bIsWritable; }
464 0 : StreamMode GetStreamMode() const { return eStreamMode; }
465 : virtual sal_uInt16 IsA() const;
466 :
467 7235 : long GetVersion() { return nVersion; }
468 4107 : void SetVersion( long n ) { nVersion = n; }
469 :
470 : friend SvStream& operator<<( SvStream& rStr, SvStrPtr f ); // for Manips
471 :
472 : /// end of input seen during previous i/o operation
473 7754780 : bool eof() const { return bIsEof; }
474 :
475 : /// stream is broken
476 7588829 : bool bad() const { return GetError() != 0; }
477 :
478 : /** Get state
479 :
480 : If the state is good() the previous i/o operation succeeded.
481 :
482 : If the state is good(), the next input operation might succeed;
483 : otherwise, it will fail.
484 :
485 : Applying an input operation to a stream that is not in the good() state
486 : is a null operation as far as the variable being read into is concerned.
487 :
488 : If we try to read into a variable v and the operation fails, the value
489 : of v should be unchanged,
490 : */
491 7754767 : bool good() const { return !(eof() || bad()); }
492 : };
493 :
494 203636 : inline SvStream& operator<<( SvStream& rStr, SvStrPtr f )
495 : {
496 203636 : (*f)(rStr);
497 203636 : return rStr;
498 : }
499 :
500 0 : inline void SvStream::SetEndianSwap( bool bVal )
501 : {
502 : #ifdef OSL_BIGENDIAN
503 : SetNumberFormatInt( bVal ? NUMBERFORMAT_INT_LITTLEENDIAN : NUMBERFORMAT_INT_BIGENDIAN );
504 : #else
505 0 : SetNumberFormatInt( bVal ? NUMBERFORMAT_INT_BIGENDIAN : NUMBERFORMAT_INT_LITTLEENDIAN );
506 : #endif
507 0 : }
508 :
509 : TOOLS_DLLPUBLIC SvStream& endl( SvStream& rStr );
510 : /// same as endl() but Unicode
511 : TOOLS_DLLPUBLIC SvStream& endlu( SvStream& rStr );
512 : /// call endlu() if eStreamCharSet==RTL_TEXTECODING_UNICODE otherwise endl()
513 : TOOLS_DLLPUBLIC SvStream& endlub( SvStream& rStr );
514 :
515 : /// Attempt to read nUnits 8bit units to an OString, returned OString's
516 : /// length is number of units successfully read
517 : TOOLS_DLLPUBLIC OString read_uInt8s_ToOString(SvStream& rStrm,
518 : sal_Size nUnits);
519 :
520 : /// Attempt to read nUnits 8bit units to an OUString
521 59 : TOOLS_DLLPUBLIC inline OUString read_uInt8s_ToOUString(SvStream& rStrm,
522 : sal_Size nUnits, rtl_TextEncoding eEnc)
523 : {
524 59 : return OStringToOUString(read_uInt8s_ToOString(rStrm, nUnits), eEnc);
525 : }
526 :
527 : /// Attempt to read nUnits 16bit units to an OUString, returned
528 : /// OUString's length is number of units successfully read
529 : TOOLS_DLLPUBLIC OUString read_uInt16s_ToOUString(SvStream& rStrm,
530 : sal_Size nUnits);
531 :
532 : /// Attempt to read a pascal-style length (of type prefix) prefixed sequence of
533 : /// 16bit units to an OUString, returned OString's length is number of
534 : /// units successfully read.
535 : template<typename prefix>
536 35606 : OUString read_lenPrefixed_uInt16s_ToOUString(SvStream& rStrm)
537 : {
538 35606 : prefix nUnits = 0;
539 35606 : rStrm >> nUnits;
540 35606 : return read_uInt16s_ToOUString(rStrm, nUnits);
541 : }
542 :
543 : /// Attempt to write a prefixed sequence of nUnits 16bit units from an OUString,
544 : /// returned value is number of bytes written
545 : TOOLS_DLLPUBLIC sal_Size write_uInt16s_FromOUString(SvStream& rStrm,
546 : const OUString& rStr, sal_Size nUnits);
547 :
548 0 : TOOLS_DLLPUBLIC inline sal_Size write_uInt16s_FromOUString(SvStream& rStrm,
549 : const OUString& rStr)
550 : {
551 0 : return write_uInt16s_FromOUString(rStrm, rStr, rStr.getLength());
552 : }
553 :
554 : namespace streamdetail
555 : {
556 : /// Attempt to write a pascal-style length (of type prefix) prefixed
557 : /// sequence of units from a string-type, returned value is number of bytes
558 : /// written (including byte-count of prefix)
559 : template<typename prefix, typename S, sal_Size (*writeOper)(SvStream&, const S&, sal_Size)>
560 181330 : sal_Size write_lenPrefixed_seq_From_str(SvStream& rStrm, const S &rStr)
561 : {
562 181330 : sal_Size nWritten = 0;
563 181330 : prefix nUnits = std::min<sal_Size>(rStr.getLength(), std::numeric_limits<prefix>::max());
564 : SAL_WARN_IF(static_cast<sal_Size>(nUnits) != static_cast<sal_Size>(rStr.getLength()),
565 : "tools.stream",
566 : "string too long for prefix count to fit in output type");
567 181330 : rStrm << nUnits;
568 181330 : if (rStrm.good())
569 : {
570 181330 : nWritten += sizeof(prefix);
571 181330 : nWritten += writeOper(rStrm, rStr, nUnits);
572 : }
573 181330 : return nWritten;
574 : }
575 : }
576 :
577 : /// Attempt to write a pascal-style length (of type prefix) prefixed sequence
578 : /// of 16bit units from an OUString, returned value is number of bytes written
579 : /// (including byte-count of prefix)
580 : template<typename prefix>
581 35298 : sal_Size write_lenPrefixed_uInt16s_FromOUString(SvStream& rStrm,
582 : const OUString &rStr)
583 : {
584 35298 : return streamdetail::write_lenPrefixed_seq_From_str<prefix, OUString, write_uInt16s_FromOUString>(rStrm, rStr);
585 : }
586 :
587 : /// Attempt to read 8bit units to an OString until a zero terminator is
588 : /// encountered, returned OString's length is number of units *definitely*
589 : /// successfully read, check SvStream::good() to see if null terminator was
590 : /// successfully read
591 : TOOLS_DLLPUBLIC OString read_zeroTerminated_uInt8s_ToOString(SvStream& rStrm);
592 :
593 : /// Attempt to read 8bit units assuming source encoding eEnc to an OUString
594 : /// until a zero terminator is encountered. Check SvStream::good() to see if
595 : /// null terminator was successfully read
596 : TOOLS_DLLPUBLIC OUString read_zeroTerminated_uInt8s_ToOUString(SvStream& rStrm, rtl_TextEncoding eEnc);
597 :
598 : /// Attempt to read a pascal-style length (of type prefix) prefixed sequence of
599 : /// 8bit units to an OString, returned OString's length is number of units
600 : /// successfully read.
601 : template<typename prefix>
602 85999 : OString read_lenPrefixed_uInt8s_ToOString(SvStream& rStrm)
603 : {
604 85999 : prefix nUnits = 0;
605 85999 : rStrm >> nUnits;
606 85999 : return read_uInt8s_ToOString(rStrm, nUnits);
607 : }
608 :
609 : /// Attempt to read a pascal-style length (of type prefix) prefixed sequence of
610 : /// 8bit units to an OUString
611 : template<typename prefix>
612 69276 : OUString read_lenPrefixed_uInt8s_ToOUString(SvStream& rStrm,
613 : rtl_TextEncoding eEnc)
614 : {
615 69276 : return OStringToOUString(read_lenPrefixed_uInt8s_ToOString<prefix>(rStrm), eEnc);
616 : }
617 :
618 : /// Attempt to write a prefixed sequence of nUnits 8bit units from an OString,
619 : /// returned value is number of bytes written
620 146149 : TOOLS_DLLPUBLIC inline sal_Size write_uInt8s_FromOString(SvStream& rStrm, const OString& rStr,
621 : sal_Size nUnits)
622 : {
623 146149 : return rStrm.Write(rStr.getStr(), nUnits);
624 : }
625 :
626 92 : TOOLS_DLLPUBLIC inline sal_Size write_uInt8s_FromOString(SvStream& rStrm, const OString& rStr)
627 : {
628 92 : return write_uInt8s_FromOString(rStrm, rStr, rStr.getLength());
629 : }
630 :
631 : /// Attempt to write a pascal-style length (of type prefix) prefixed sequence
632 : /// of 8bit units from an OString, returned value is number of bytes written
633 : /// (including byte-count of prefix)
634 : template<typename prefix>
635 146032 : sal_Size write_lenPrefixed_uInt8s_FromOString(SvStream& rStrm,
636 : const OString &rStr)
637 : {
638 146032 : return streamdetail::write_lenPrefixed_seq_From_str<prefix, OString, write_uInt8s_FromOString>(rStrm, rStr);
639 : }
640 :
641 : /// Attempt to write a pascal-style length (of type prefix) prefixed sequence
642 : /// of 8bit units from an OUString, returned value is number of bytes written
643 : /// (including byte-count of prefix)
644 : template<typename prefix>
645 84073 : sal_Size write_lenPrefixed_uInt8s_FromOUString(SvStream& rStrm,
646 : const OUString &rStr,
647 : rtl_TextEncoding eEnc)
648 : {
649 84073 : return write_lenPrefixed_uInt8s_FromOString<prefix>(rStrm, OUStringToOString(rStr, eEnc));
650 : }
651 :
652 : // FileStream
653 :
654 : class TOOLS_DLLPUBLIC SvFileStream : public SvStream
655 : {
656 : private:
657 : StreamData* pInstanceData;
658 : OUString aFilename;
659 : sal_uInt16 nLockCounter;
660 : bool bIsOpen;
661 : #ifdef UNX
662 : sal_uInt32 GetFileHandle() const;
663 : #endif
664 : // Forbidden and not implemented.
665 : SvFileStream (const SvFileStream&);
666 : SvFileStream & operator= (const SvFileStream&);
667 :
668 : bool LockRange( sal_Size nByteOffset, sal_Size nBytes );
669 : bool UnlockRange( sal_Size nByteOffset, sal_Size nBytes );
670 : bool LockFile();
671 : bool UnlockFile();
672 :
673 : protected:
674 : virtual sal_Size GetData( void* pData, sal_Size nSize );
675 : virtual sal_Size PutData( const void* pData, sal_Size nSize );
676 : virtual sal_Size SeekPos( sal_Size nPos );
677 : virtual void SetSize( sal_Size nSize );
678 : virtual void FlushData();
679 :
680 : public:
681 : // Switches to Read StreamMode on failed attempt of Write opening
682 : SvFileStream( const OUString& rFileName, StreamMode eOpenMode );
683 : SvFileStream();
684 : ~SvFileStream();
685 :
686 : virtual void ResetError();
687 :
688 : void Open( const OUString& rFileName, StreamMode eOpenMode );
689 : void Close();
690 354727 : bool IsOpen() const { return bIsOpen; }
691 : bool IsLocked() const { return ( nLockCounter!=0 ); }
692 : virtual sal_uInt16 IsA() const;
693 :
694 541 : const OUString& GetFileName() const { return aFilename; }
695 : };
696 :
697 : // MemoryStream
698 :
699 : class TOOLS_DLLPUBLIC SvMemoryStream : public SvStream
700 : {
701 : // Forbidden and not implemented.
702 : SvMemoryStream (const SvMemoryStream&);
703 : SvMemoryStream & operator= (const SvMemoryStream&);
704 :
705 : friend class SvCacheStream;
706 5667 : sal_Size GetSize() const { return nSize; }
707 :
708 : protected:
709 : sal_Size nSize;
710 : sal_Size nResize;
711 : sal_Size nPos;
712 : sal_Size nEndOfData;
713 : sal_uInt8* pBuf;
714 : bool bOwnsData;
715 :
716 : virtual sal_Size GetData( void* pData, sal_Size nSize );
717 : virtual sal_Size PutData( const void* pData, sal_Size nSize );
718 : virtual sal_Size SeekPos( sal_Size nPos );
719 : virtual void SetSize( sal_Size nSize );
720 : virtual void FlushData();
721 :
722 : /// AllocateMemory must update pBuf accordingly
723 : /// - pBuf: Address of new block
724 : virtual bool AllocateMemory( sal_Size nSize );
725 :
726 : /// ReAllocateMemory must update the following variables:
727 : /// - pBuf: Address of new block
728 : /// - nEndOfData: Set to nNewSize-1L , if outside of block
729 : /// Set to 0 , if new block size is 0 bytes
730 : /// - nSize: New block size
731 : /// - nPos: Set to 0 if position outside of block
732 : virtual bool ReAllocateMemory( long nDiff );
733 :
734 : /// Is called when this stream allocated the buffer or the buffer is
735 : /// resized. FreeMemory may need to NULLify handles in derived classes.
736 : virtual void FreeMemory();
737 :
738 : SvMemoryStream(void*) { } // for sub-classes
739 :
740 : public:
741 : SvMemoryStream( void* pBuf, sal_Size nSize, StreamMode eMode);
742 : SvMemoryStream( sal_Size nInitSize=512, sal_Size nResize=64 );
743 : ~SvMemoryStream();
744 :
745 : virtual void ResetError();
746 :
747 10 : sal_Size GetEndOfData() const { return nEndOfData; }
748 16992 : const void* GetData() { Flush(); return pBuf; }
749 : operator const void*() { Flush(); return pBuf; }
750 : virtual sal_uInt16 IsA() const;
751 :
752 : void* SwitchBuffer( sal_Size nInitSize=512, sal_Size nResize=64 );
753 : void* SetBuffer( void* pBuf, sal_Size nSize,
754 : bool bOwnsData=true, sal_Size nEOF=0 );
755 :
756 329 : void ObjectOwnsMemory( bool bOwn ) { bOwnsData = bOwn; }
757 : bool IsObjectMemoryOwner() { return bOwnsData; }
758 51 : void SetResizeOffset( sal_Size nNewResize ) { nResize = nNewResize; }
759 : sal_Size GetResizeOffset() const { return nResize; }
760 0 : virtual sal_Size remainingSize() { return GetSize() - Tell(); }
761 : };
762 :
763 : /** Data Copy Stream
764 :
765 : This class is the foundation for all classes, using SvData
766 : (SO2\DTRANS.HXX/CXX) for transportation (e.g., graphics).
767 : */
768 292947 : class TOOLS_DLLPUBLIC SvDataCopyStream
769 : {
770 : public:
771 : // repeated execution of Load or Assign is allowed
772 : TYPEINFO();
773 292784 : virtual ~SvDataCopyStream(){}
774 : virtual void Load( SvStream & ) = 0;
775 : virtual void Save( SvStream & ) = 0;
776 : virtual void Assign( const SvDataCopyStream & );
777 : };
778 :
779 : #endif
780 :
781 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|