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 INCLUDED_SW_INC_SHELLIO_HXX
20 : #define INCLUDED_SW_INC_SHELLIO_HXX
21 :
22 : #include <memory>
23 : #include <boost/utility.hpp>
24 :
25 : #include <com/sun/star/uno/Reference.h>
26 : #include <com/sun/star/embed/XStorage.hpp>
27 : #include <sfx2/docfile.hxx>
28 : #include <sfx2/fcontnr.hxx>
29 : #include <sot/formats.hxx>
30 : #include <sot/storage.hxx>
31 : #include <svtools/parhtml.hxx>
32 : #include <tools/date.hxx>
33 : #include <tools/time.hxx>
34 : #include <tools/datetime.hxx>
35 : #include <tools/ref.hxx>
36 : #include <swdllapi.h>
37 : #include <swtypes.hxx>
38 : #include <docfac.hxx>
39 : #include <iodetect.hxx>
40 : #include <IMark.hxx>
41 :
42 : class SfxFilterContainer;
43 : class SfxFilter;
44 : class SfxItemPool;
45 : class SfxItemSet;
46 : class SfxMedium;
47 : class SvStream;
48 : class SvxFontItem;
49 : class SvxMacroTableDtor;
50 : class SwCntntNode;
51 : class SwCrsrShell;
52 : class SwDoc;
53 : class SwPaM;
54 : class SwTextBlocks;
55 : struct SwPosition;
56 : struct Writer_Impl;
57 :
58 : // Defines the count of chars at which a paragraph read via ASCII/W4W-Reader
59 : // is forced to wrap. It has to be always greater than 200!!!
60 : #define MAX_ASCII_PARA 10000
61 :
62 108380 : class SW_DLLPUBLIC SwAsciiOptions
63 : {
64 : OUString sFont;
65 : rtl_TextEncoding eCharSet;
66 : sal_uInt16 nLanguage;
67 : LineEnd eCRLF_Flag;
68 :
69 : public:
70 :
71 24 : OUString GetFontName() const { return sFont; }
72 0 : void SetFontName( const OUString& rFont ) { sFont = rFont; }
73 :
74 35658 : rtl_TextEncoding GetCharSet() const { return eCharSet; }
75 15402 : void SetCharSet( rtl_TextEncoding nVal ) { eCharSet = nVal; }
76 :
77 12 : sal_uInt16 GetLanguage() const { return nLanguage; }
78 0 : void SetLanguage( sal_uInt16 nVal ) { nLanguage = nVal; }
79 :
80 15952 : LineEnd GetParaFlags() const { return eCRLF_Flag; }
81 0 : void SetParaFlags( LineEnd eVal ) { eCRLF_Flag = eVal; }
82 :
83 31658 : void Reset()
84 : {
85 31658 : sFont = OUString();
86 31658 : eCRLF_Flag = GetSystemLineEnd();
87 31658 : eCharSet = ::osl_getThreadTextEncoding();
88 31658 : nLanguage = 0;
89 31658 : }
90 : // for the automatic conversion (mail/news/...)
91 : void ReadUserData( const OUString& );
92 : void WriteUserData( OUString& );
93 :
94 31364 : SwAsciiOptions() { Reset(); }
95 : };
96 :
97 : // Base class of possible options for a special reader.
98 : class Reader;
99 : // Calls reader with its options, document, cursor etc.
100 : class SwReader;
101 : // SwRead is pointer to the read-options base class.
102 : typedef Reader *SwRead;
103 :
104 288 : class SwgReaderOption
105 : {
106 : SwAsciiOptions aASCIIOpts;
107 : union
108 : {
109 : bool bFmtsOnly;
110 : struct
111 : {
112 : bool bFrmFmts: 1;
113 : bool bPageDescs: 1;
114 : bool bTxtFmts: 1;
115 : bool bNumRules: 1;
116 : bool bMerge:1;
117 : } Fmts;
118 : } What;
119 :
120 : public:
121 606 : void ResetAllFmtsOnly() { What.bFmtsOnly = false; }
122 2098 : bool IsFmtsOnly() const { return What.bFmtsOnly; }
123 :
124 0 : bool IsFrmFmts() const { return What.Fmts.bFrmFmts; }
125 0 : void SetFrmFmts( const bool bNew) { What.Fmts.bFrmFmts = bNew; }
126 :
127 2 : bool IsPageDescs() const { return What.Fmts.bPageDescs; }
128 0 : void SetPageDescs( const bool bNew) { What.Fmts.bPageDescs = bNew; }
129 :
130 0 : bool IsTxtFmts() const { return What.Fmts.bTxtFmts; }
131 0 : void SetTxtFmts( const bool bNew) { What.Fmts.bTxtFmts = bNew; }
132 :
133 0 : bool IsNumRules() const { return What.Fmts.bNumRules; }
134 0 : void SetNumRules( const bool bNew) { What.Fmts.bNumRules = bNew; }
135 :
136 0 : bool IsMerge() const { return What.Fmts.bMerge; }
137 0 : void SetMerge( const bool bNew ) { What.Fmts.bMerge = bNew; }
138 :
139 6 : const SwAsciiOptions& GetASCIIOpts() const { return aASCIIOpts; }
140 6 : void SetASCIIOpts( const SwAsciiOptions& rOpts ) { aASCIIOpts = rOpts; }
141 6 : void ResetASCIIOpts() { aASCIIOpts.Reset(); }
142 :
143 288 : SwgReaderOption()
144 288 : { ResetAllFmtsOnly(); aASCIIOpts.Reset(); }
145 : };
146 :
147 540 : class SW_DLLPUBLIC SwReader: public SwDocFac
148 : {
149 : SvStream* pStrm;
150 : SotStorageRef pStg;
151 : com::sun::star::uno::Reference < com::sun::star::embed::XStorage > xStg;
152 : SfxMedium* pMedium; // Who wants to obtain a Medium (W4W).
153 :
154 : SwPaM* pCrsr;
155 : OUString aFileName;
156 : OUString sBaseURL;
157 :
158 : public:
159 :
160 : // Initial reading. Document is created only at Read(...)
161 : // or in case it is given, into that.
162 : // Special case for Load with Sw3Reader.
163 : SwReader( SfxMedium&, const OUString& rFilename, SwDoc *pDoc = 0 );
164 :
165 : // Read into existing document.
166 : // Document and position in document are taken from SwPaM.
167 : SwReader( SvStream&, const OUString& rFilename, const OUString& rBaseURL, SwPaM& );
168 : SwReader( SfxMedium&, const OUString& rFilename, SwPaM& );
169 : SwReader( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >&, const OUString& rFilename, SwPaM& );
170 :
171 : // The only export interface is SwReader::Read(...)!!!
172 : bool NeedsPasswd( const Reader& );
173 : bool CheckPasswd( const OUString&, const Reader& );
174 : sal_uLong Read( const Reader& );
175 :
176 : // Ask for glossaries.
177 : bool HasGlossaries( const Reader& );
178 : bool ReadGlossaries( const Reader&, SwTextBlocks&, bool bSaveRelFiles );
179 :
180 540 : OUString GetBaseURL() const { return sBaseURL;}
181 :
182 : protected:
183 540 : void SetBaseURL( const OUString& rURL ) { sBaseURL = rURL; }
184 : };
185 :
186 : // Special Readers can be both!! (Excel, W4W, .. ).
187 : #define SW_STREAM_READER 1
188 : #define SW_STORAGE_READER 2
189 :
190 : class SW_DLLPUBLIC Reader
191 : {
192 : friend class SwReader;
193 : SwDoc* pTemplate;
194 : OUString aTemplateNm;
195 :
196 : Date aDStamp;
197 : tools::Time aTStamp;
198 : DateTime aChkDateTime;
199 :
200 : protected:
201 : SvStream* pStrm;
202 : SotStorageRef pStg;
203 : com::sun::star::uno::Reference < com::sun::star::embed::XStorage > xStg;
204 : SfxMedium* pMedium; // Who wants to obtain a Medium (W4W).
205 :
206 : SwgReaderOption aOpt;
207 : bool bInsertMode : 1;
208 : bool bTmplBrowseMode : 1;
209 : bool bReadUTF8: 1; // Interprete stream as UTF-8.
210 : bool bBlockMode: 1;
211 : bool bOrganizerMode : 1;
212 : bool bHasAskTemplateName : 1;
213 : bool bIgnoreHTMLComments : 1;
214 :
215 : virtual OUString GetTemplateName() const;
216 :
217 : public:
218 : Reader();
219 : virtual ~Reader();
220 :
221 : virtual int GetReaderType();
222 6 : SwgReaderOption& GetReaderOpt() { return aOpt; }
223 :
224 : virtual void SetFltName( const OUString& rFltNm );
225 :
226 : // Adapt item-set of a Frm-Format to the old format.
227 : static void ResetFrmFmtAttrs( SfxItemSet &rFrmSet );
228 :
229 : // Adapt Frame-/Graphics-/OLE- styles to the old format
230 : // (without borders etc.).
231 : static void ResetFrmFmts( SwDoc& rDoc );
232 :
233 : // Load filter template, set it and release it again.
234 : SwDoc* GetTemplateDoc();
235 : bool SetTemplate( SwDoc& rDoc );
236 : void ClearTemplate();
237 : void SetTemplateName( const OUString& rDir );
238 : void MakeHTMLDummyTemplateDoc();
239 :
240 22 : bool IsReadUTF8() const { return bReadUTF8; }
241 540 : void SetReadUTF8( bool bSet ) { bReadUTF8 = bSet; }
242 :
243 1248 : bool IsBlockMode() const { return bBlockMode; }
244 540 : void SetBlockMode( bool bSet ) { bBlockMode = bSet; }
245 :
246 1588 : bool IsOrganizerMode() const { return bOrganizerMode; }
247 556 : void SetOrganizerMode( bool bSet ) { bOrganizerMode = bSet; }
248 :
249 540 : void SetIgnoreHTMLComments( bool bSet ) { bIgnoreHTMLComments = bSet; }
250 :
251 : virtual bool HasGlossaries() const;
252 : virtual bool ReadGlossaries( SwTextBlocks&, bool bSaveRelFiles ) const;
253 :
254 : // Read the sections of the document, which is equal to the medium.
255 : // Returns the count of it
256 : virtual size_t GetSectionList( SfxMedium& rMedium,
257 : std::vector<OUString*>& rStrings ) const;
258 :
259 220 : SotStorageRef getSotStorageRef() { return pStg; };
260 220 : void setSotStorageRef(SotStorageRef pStgRef) { pStg = pStgRef; };
261 :
262 : private:
263 : virtual sal_uLong Read(SwDoc &, const OUString& rBaseURL, SwPaM &, const OUString &)=0;
264 :
265 : // Everyone who does not need the streams / storages open
266 : // has to overload the method (W4W!!).
267 : virtual int SetStrmStgPtr();
268 : };
269 :
270 180 : class AsciiReader: public Reader
271 : {
272 : friend class SwReader;
273 : virtual sal_uLong Read( SwDoc &, const OUString& rBaseURL, SwPaM &, const OUString &) SAL_OVERRIDE;
274 : public:
275 90 : AsciiReader(): Reader() {}
276 : };
277 :
278 32 : class SW_DLLPUBLIC StgReader : public Reader
279 : {
280 : OUString aFltName;
281 :
282 : protected:
283 : sal_uLong OpenMainStream( SotStorageStreamRef& rRef, sal_uInt16& rBuffSize );
284 : public:
285 : virtual int GetReaderType() SAL_OVERRIDE;
286 192 : OUString GetFltName() { return aFltName; }
287 : virtual void SetFltName( const OUString& r ) SAL_OVERRIDE;
288 : };
289 :
290 : // The given stream has to be created dynamically and must
291 : // be requested via Stream() before the instance is deleted!
292 :
293 : class SwImpBlocks;
294 :
295 : class SW_DLLPUBLIC SwTextBlocks
296 : {
297 : SwImpBlocks* pImp;
298 : sal_uLong nErr;
299 :
300 : public:
301 : SwTextBlocks( const OUString& );
302 : ~SwTextBlocks();
303 :
304 : void Flush(){}
305 :
306 : SwDoc* GetDoc();
307 : void ClearDoc(); // Delete Doc-contents.
308 : OUString GetName();
309 : void SetName( const OUString& );
310 216 : sal_uLong GetError() const { return nErr; }
311 :
312 : OUString GetBaseURL() const;
313 : void SetBaseURL( const OUString& rURL );
314 :
315 : bool IsOld() const;
316 : sal_uLong ConvertToNew(); // Convert text modules.
317 :
318 : sal_uInt16 GetCount() const; // Get count text modules.
319 : sal_uInt16 GetIndex( const OUString& ) const; // Get index of short names.
320 : sal_uInt16 GetLongIndex( const OUString& ) const; // Get index of long names.
321 : OUString GetShortName( sal_uInt16 ) const; // Get short name for index.
322 : OUString GetLongName( sal_uInt16 ) const; // Get long name for index.
323 :
324 : bool Delete( sal_uInt16 );
325 : sal_uInt16 Rename( sal_uInt16, const OUString*, const OUString* );
326 : sal_uLong CopyBlock( SwTextBlocks& rSource, OUString& rSrcShort,
327 : const OUString& rLong );
328 :
329 : bool BeginGetDoc( sal_uInt16 ); // Read text modules.
330 : void EndGetDoc(); // Release text modules.
331 :
332 : bool BeginPutDoc( const OUString&, const OUString& ); // Begin save.
333 : sal_uInt16 PutDoc(); // End save.
334 :
335 : sal_uInt16 PutText( const OUString&, const OUString&, const OUString& ); // Save (short name, text).
336 :
337 : bool IsOnlyTextBlock( sal_uInt16 ) const;
338 : bool IsOnlyTextBlock( const OUString& rShort ) const;
339 :
340 : OUString GetFileName() const; // Filename of pImp.
341 : bool IsReadOnly() const; // ReadOnly-flag of pImp.
342 :
343 : bool GetMacroTable( sal_uInt16 nIdx, SvxMacroTableDtor& rMacroTbl );
344 : bool SetMacroTable( sal_uInt16 nIdx, const SvxMacroTableDtor& rMacroTbl );
345 :
346 : bool StartPutMuchBlockEntries();
347 : void EndPutMuchBlockEntries();
348 : };
349 :
350 : // BEGIN source/filter/basflt/fltini.cxx
351 :
352 : extern SwRead ReadAscii, /*ReadSwg, ReadSw3, */ReadHTML, ReadXML;
353 :
354 : SW_DLLPUBLIC SwRead SwGetReaderXML();
355 :
356 : // END source/filter/basflt/fltini.cxx
357 :
358 : extern bool SetHTMLTemplate( SwDoc &rDoc ); //For templates from HTML before loading shellio.cxx.
359 :
360 : // Base-class of all writers.
361 :
362 : class IDocumentSettingAccess;
363 : class IDocumentStylePoolAccess;
364 :
365 : class SW_DLLPUBLIC Writer
366 : : public SvRefBase
367 : , private ::boost::noncopyable
368 : {
369 : SwAsciiOptions aAscOpts;
370 : OUString sBaseURL;
371 :
372 : void _AddFontItem( SfxItemPool& rPool, const SvxFontItem& rFont );
373 : void _AddFontItems( SfxItemPool& rPool, sal_uInt16 nWhichId );
374 :
375 : ::std::unique_ptr<Writer_Impl> m_pImpl;
376 :
377 : protected:
378 :
379 : SwPaM* pOrigPam; // Last Pam that has to be processed.
380 : const OUString* pOrigFileName;
381 :
382 : void ResetWriter();
383 : bool CopyNextPam( SwPaM ** );
384 :
385 : void PutNumFmtFontsInAttrPool();
386 : void PutEditEngFontsInAttrPool( bool bIncl_CJK_CTL = true );
387 :
388 : virtual sal_uLong WriteStream() = 0;
389 120 : void SetBaseURL( const OUString& rURL ) { sBaseURL = rURL; }
390 :
391 : IDocumentSettingAccess* getIDocumentSettingAccess();
392 : const IDocumentSettingAccess* getIDocumentSettingAccess() const;
393 :
394 : IDocumentStylePoolAccess* getIDocumentStylePoolAccess();
395 : const IDocumentStylePoolAccess* getIDocumentStylePoolAccess() const;
396 :
397 : public:
398 : SwDoc* pDoc;
399 : SwPaM* pCurPam;
400 : bool bWriteAll : 1;
401 : bool bShowProgress : 1;
402 : bool bWriteClipboardDoc : 1;
403 : bool bWriteOnlyFirstTable : 1;
404 : bool bASCII_ParaAsCR : 1;
405 : bool bASCII_ParaAsBlanc : 1;
406 : bool bASCII_NoLastLineEnd : 1;
407 : bool bUCS2_WithStartChar : 1;
408 : bool bExportPargraphNumbering : 1;
409 :
410 : bool bBlock : 1;
411 : bool bOrganizerMode : 1;
412 :
413 : Writer();
414 : virtual ~Writer();
415 :
416 : virtual sal_uLong Write( SwPaM&, SfxMedium&, const OUString* = 0 );
417 : sal_uLong Write( SwPaM&, SvStream&, const OUString* = 0 );
418 : virtual sal_uLong Write( SwPaM&, const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >&, const OUString* = 0, SfxMedium* = 0 );
419 : virtual sal_uLong Write( SwPaM&, SotStorage&, const OUString* = 0 );
420 :
421 : virtual void SetupFilterOptions(SfxMedium& rMedium);
422 :
423 : virtual void SetVersion( const OUString&, long );
424 : virtual bool IsStgWriter() const;
425 :
426 2 : void SetShowProgress( bool bFlag = false ) { bShowProgress = bFlag; }
427 :
428 : const OUString* GetOrigFileName() const { return pOrigFileName; }
429 :
430 81856 : const SwAsciiOptions& GetAsciiOptions() const { return aAscOpts; }
431 30806 : void SetAsciiOptions( const SwAsciiOptions& rOpt ) { aAscOpts = rOpt; }
432 :
433 92 : OUString GetBaseURL() const { return sBaseURL;}
434 :
435 : // Look up next bookmark position from bookmark-table.
436 : sal_Int32 FindPos_Bkmk( const SwPosition& rPos ) const;
437 : // Build a bookmark table, which is sort by the node position. The
438 : // OtherPos of the bookmarks also inserted.
439 : void CreateBookmarkTbl();
440 : // Search alle Bookmarks in the range and return it in the Array.
441 : sal_uInt16 GetBookmarks( const SwCntntNode& rNd,
442 : sal_Int32 nStt, sal_Int32 nEnd,
443 : std::vector< const ::sw::mark::IMark* >& rArr );
444 :
445 : // Create new PaM at position.
446 : static SwPaM * NewSwPaM(SwDoc & rDoc,
447 : sal_uLong const nStartIdx, sal_uLong const nEndIdx);
448 :
449 : // Stream-specific routines. Do not use in storage-writer!
450 :
451 : // Optimizing output on stream.
452 : SvStream& OutLong( SvStream& rStrm, long nVal );
453 : SvStream& OutULong( SvStream& rStrm, sal_uLong nVal );
454 :
455 : inline SvStream& OutLong( long nVal ) { return OutLong( Strm(), nVal ); }
456 : inline SvStream& OutULong( sal_uLong nVal ) { return OutULong( Strm(), nVal ); }
457 :
458 : void SetStream(SvStream *const pStream);
459 : SvStream& Strm();
460 :
461 0 : void SetOrganizerMode( bool bSet ) { bOrganizerMode = bSet; }
462 : };
463 :
464 : typedef tools::SvRef<Writer> WriterRef;
465 :
466 : // Base class for all storage writers.
467 94 : class SW_DLLPUBLIC StgWriter : public Writer
468 : {
469 : protected:
470 : OUString aFltName;
471 : SotStorageRef pStg;
472 : com::sun::star::uno::Reference < com::sun::star::embed::XStorage > xStg;
473 :
474 : // Create error at call.
475 : virtual sal_uLong WriteStream() SAL_OVERRIDE;
476 : virtual sal_uLong WriteStorage() = 0;
477 : virtual sal_uLong WriteMedium( SfxMedium& ) = 0;
478 :
479 : using Writer::Write;
480 :
481 : public:
482 94 : StgWriter() : Writer() {}
483 :
484 : virtual bool IsStgWriter() const SAL_OVERRIDE;
485 :
486 : virtual sal_uLong Write( SwPaM&, const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >&, const OUString* = 0, SfxMedium* = 0 ) SAL_OVERRIDE;
487 : virtual sal_uLong Write( SwPaM&, SotStorage&, const OUString* = 0 ) SAL_OVERRIDE;
488 :
489 242 : SotStorage& GetStorage() const { return *pStg; }
490 : };
491 :
492 : // Interface class for general access on special writers.
493 :
494 15524 : class SW_DLLPUBLIC SwWriter
495 : {
496 : SvStream* pStrm;
497 : SotStorageRef pStg;
498 : com::sun::star::uno::Reference < com::sun::star::embed::XStorage > xStg;
499 : SfxMedium* pMedium;
500 :
501 : SwPaM* pOutPam;
502 : SwCrsrShell *pShell;
503 : SwDoc &rDoc;
504 :
505 : bool bWriteAll;
506 :
507 : public:
508 : sal_uLong Write( WriterRef& rxWriter, const OUString* = 0);
509 :
510 : SwWriter( SvStream&, SwCrsrShell &, bool bWriteAll = false );
511 : SwWriter( SvStream&, SwDoc & );
512 : SwWriter( SvStream&, SwPaM &, bool bWriteAll = false );
513 :
514 : SwWriter( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >&, SwDoc& );
515 :
516 : SwWriter( SfxMedium&, SwCrsrShell &, bool bWriteAll = false );
517 : SwWriter( SfxMedium&, SwDoc & );
518 : };
519 :
520 : typedef Reader* (*FnGetReader)();
521 : typedef void (*FnGetWriter)(const OUString&, const OUString& rBaseURL, WriterRef&);
522 : sal_uLong SaveOrDelMSVBAStorage( SfxObjectShell&, SotStorage&, bool, const OUString& );
523 : sal_uLong GetSaveWarningOfMSVBAStorage( SfxObjectShell &rDocS );
524 :
525 : struct SwReaderWriterEntry
526 : {
527 : Reader* pReader;
528 : FnGetReader fnGetReader;
529 : FnGetWriter fnGetWriter;
530 : bool bDelReader;
531 :
532 900 : SwReaderWriterEntry( const FnGetReader fnReader, const FnGetWriter fnWriter, bool bDel )
533 900 : : pReader( NULL ), fnGetReader( fnReader ), fnGetWriter( fnWriter ), bDelReader( bDel )
534 900 : {}
535 :
536 : /// Get access to the reader.
537 : Reader* GetReader();
538 :
539 : /// Get access to the writer.
540 : void GetWriter( const OUString& rNm, const OUString& rBaseURL, WriterRef& xWrt ) const;
541 : };
542 :
543 : namespace SwReaderWriter
544 : {
545 : /// Return reader based on ReaderWriterEnum.
546 : SW_DLLPUBLIC Reader* GetReader( ReaderWriterEnum eReader );
547 :
548 : /// Return reader based on the name.
549 : Reader* GetReader( const OUString& rFltName );
550 :
551 : /// Return writer based on the name.
552 : SW_DLLPUBLIC void GetWriter( const OUString& rFltName, const OUString& rBaseURL, WriterRef& xWrt );
553 : }
554 :
555 : void GetRTFWriter( const OUString&, const OUString&, WriterRef& );
556 : void GetASCWriter( const OUString&, const OUString&, WriterRef& );
557 : void GetHTMLWriter( const OUString&, const OUString&, WriterRef& );
558 : void GetXMLWriter( const OUString&, const OUString&, WriterRef& );
559 :
560 : #endif
561 :
562 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|