summaryrefslogtreecommitdiff
path: root/sw/source/filter/ascii/parasc.cxx
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 16:15:01 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 16:15:01 +0000
commit7b0b5cdfeed656b279bc32cd929630d5fc25878b (patch)
tree5b89fb8497d7329d26c43f109bb014c54ffb0e8c /sw/source/filter/ascii/parasc.cxx
parentd791366863cf9659a01b171ce0e727bfe2f28cdf (diff)
initial import
Diffstat (limited to 'sw/source/filter/ascii/parasc.cxx')
-rw-r--r--sw/source/filter/ascii/parasc.cxx1180
1 files changed, 1180 insertions, 0 deletions
diff --git a/sw/source/filter/ascii/parasc.cxx b/sw/source/filter/ascii/parasc.cxx
new file mode 100644
index 000000000000..b26616ec668b
--- /dev/null
+++ b/sw/source/filter/ascii/parasc.cxx
@@ -0,0 +1,1180 @@
+/*************************************************************************
+ *
+ * $RCSfile: parasc.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:14:53 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PCH
+#include "filt_pch.hxx"
+#endif
+
+#ifndef _STREAM_HXX //autogen
+#include <tools/stream.hxx>
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include <hintids.hxx>
+#endif
+
+#ifndef _SFX_PRINTER_HXX
+#include <sfx2/printer.hxx>
+#endif
+#ifndef _SVX_FONTITEM_HXX //autogen wg. SvxFontItem
+#include <svx/fontitem.hxx>
+#endif
+#ifndef _SVX_LANGITEM_HXX //autogen wg. SvxLanguageItem
+#include <svx/langitem.hxx>
+#endif
+#ifndef _SVX_BRKITEM_HXX //autogen
+#include <svx/brkitem.hxx>
+#endif
+
+#ifndef _SHELLIO_HXX
+#include <shellio.hxx>
+#endif
+#ifndef _DOC_HXX
+#include <doc.hxx>
+#endif
+#ifndef _SWTYPES_HXX
+#include <swtypes.hxx>
+#endif
+#ifndef _NDTXT_HXX
+#include <ndtxt.hxx>
+#endif
+#ifndef _PAM_HXX
+#include <pam.hxx>
+#endif
+#ifndef _FRMATR_HXX
+#include <frmatr.hxx>
+#endif
+#ifndef _FLTINI_HXX
+#include <fltini.hxx>
+#endif
+#ifndef _PAGEDESC_HXX
+#include <pagedesc.hxx>
+#endif
+
+#ifndef _SWSWERROR_H
+#include <swerror.h>
+#endif
+#ifndef _STATSTR_HRC
+#include <statstr.hrc> // ResId fuer Statusleiste
+#endif
+#ifndef _MDIEXP_HXX
+#include <mdiexp.hxx> // ...Percent()
+#endif
+
+#define ASC_BUFFLEN 4096
+
+
+#ifdef ASYNCHRON
+
+class _SvLockBytes
+{
+ AutoTimer aTimer;
+ SvStream& rIn;
+
+ ULONG nDataRead;
+ Link aCallDataRead;
+
+ DECL_STATIC_LINK( _SvLockBytes, DataRead, Timer* );
+
+public:
+ _SvLockBytes( SvStream& rInput, const Link& rCallBack );
+ ~_SvLockBytes();
+
+ ErrCode ReadAt( ULONG nPos, void* pArr, ULONG nCount, ULONG* pReadCnt );
+
+ SvStream& GetStream() const { return rIn; }
+};
+
+
+// client vom Standard SwPageDesc. Wird dieser geloescht, dann
+// der Reader auch beendet werden!!
+class SwAsynchLoader : public SvRefBase, public SwClient
+{
+protected:
+
+ SwDoc* pDoc;
+ SwPaM* pPam;
+
+ BOOL bInCall;
+ _SvLockBytes* pLoader;
+
+ DECL_STATIC_LINK( SwAsynchLoader, NewData, _SvLockBytes* );
+
+protected:
+ virtual void Modify( SfxPoolItem *pOld, SfxPoolItem *pNew );
+ virtual ~SwAsynchLoader();
+
+ virtual ULONG NextData() = 0;
+
+public:
+ SwAsynchLoader( SvStream& rIn, const SwPaM& rCrsr );
+
+ ULONG CallParser();
+};
+
+SV_DECL_REF(SwAsynchLoader)
+SV_IMPL_REF(SwAsynchLoader)
+
+
+class SwASCIIParser : public SwAsynchLoader
+{
+ char* pArr, *pStt, *pEnd, *pLastStt;
+
+ long nLineLen;
+ ULONG nError, nReadCnt, nFileSize;
+
+ const SwAsciiOptions& rOpt;
+ char cLastCRLF;
+
+ virtual ULONG NextData();
+
+protected:
+ virtual ~SwASCIIParser();
+
+public:
+ SwASCIIParser( SwDoc* pD, const SwPaM& rCrsr, SvStream& rIn,
+ int bReadNewDoc, const SwAsciiOptions& rOpts);
+};
+
+SV_DECL_REF(SwASCIIParser)
+SV_IMPL_REF(SwASCIIParser)
+
+
+// Aufruf fuer die allg. Reader-Schnittstelle
+ULONG AsciiReader::Read( SwDoc &rDoc, SwPaM &rPam, const String & )
+{
+ if( !pStrm )
+ {
+ ASSERT( !this, "ASCII-Read ohne Stream" );
+ return ERR_SWG_READ_ERROR;
+ }
+
+ //JP 18.01.96: Alle Ueberschriften sind normalerweise ohne
+ // Kapitelnummer. Darum hier explizit abschalten
+ // weil das Default jetzt wieder auf AN ist.
+ if( !bInsertMode )
+ Reader::SetNoOutlineNum( rDoc );
+
+ SwASCIIParserRef xParser( new SwASCIIParser( &rDoc, rPam, *pStrm,
+ !bInsertMode, eCodeSet ));
+ ULONG nRet = xParser->CallParser();
+ // nach dem Lesen sofort wieder defaulten
+ eCodeSet = GetSystemCharSet();
+ return ERRCODE_IO_PENDING == nRet ? 0 : nRet;
+}
+
+
+/* */
+
+SwASCIIParser::SwASCIIParser( SwDoc* pD, const SwPaM& rCrsr, SvStream& rIn,
+ int bReadNewDoc, CharSet eSrc )
+ : SwAsynchLoader( rIn, rCrsr ),
+ eCodeSet( eSrc )
+{
+ pArr = new char [ ASC_BUFFLEN + 1 ];
+
+ pStt = pEnd = pLastStt = pArr;
+
+ cLastCRLF = 0;
+ nLineLen = 0;
+ nError = 0;
+ nReadCnt = 0;
+
+ rIn.Seek(STREAM_SEEK_TO_END);
+ rIn.ResetError();
+
+ nFileSize = rIn.Tell();
+ rIn.Seek(STREAM_SEEK_TO_BEGIN);
+ rIn.ResetError();
+
+}
+
+SwASCIIParser::~SwASCIIParser()
+{
+ delete pArr;
+}
+
+
+ULONG SwASCIIParser::NextData()
+{
+ SvStream& rInput = pLoader->GetStream();
+ do {
+ if( pStt >= pEnd )
+ {
+ if( pLastStt != pStt )
+ {
+ pDoc->Insert( *pPam, pLastStt, eCodeSet );
+ pLastStt = pStt;
+ }
+
+ // lese einen neuen Block ein
+ ULONG lGCount;
+
+ if (SVSTREAM_OK != rInput.GetError() || 0 != ( nError = pLoader->
+ ReadAt( nReadCnt, pArr, ASC_BUFFLEN, &lGCount )) ||
+ ( rInput.IsEof() && !lGCount ))
+ {
+ if( ERRCODE_IO_PENDING != nError || !lGCount )
+ break; // aus der WHILE-Schleife heraus
+ }
+
+ pEnd = pArr + lGCount;
+ nReadCnt += lGCount;
+ *pEnd = 0;
+ pStt = pLastStt = pArr;
+
+ ::SetProgressState( nReadCnt, pDoc->GetDocShell() );
+
+ if( cLastCRLF )
+ {
+ if( ( 0x0a == *pStt && 0x0d == cLastCRLF ) ||
+ ( 0x0d == *pStt && 0x0a == cLastCRLF ))
+ pLastStt = ++pStt;
+ cLastCRLF = 0;
+ nLineLen = 0;
+ // JP 03.04.96: das letze am Ende nehmen wir nicht
+ if( !rInput.IsEof() || !(pEnd == pStt ||
+ ( !*pEnd && pEnd == pStt+1 ) ) )
+ pDoc->SplitNode( *pPam->GetPoint() );
+ }
+ }
+
+ BOOL bIns = TRUE, bSplitNode = FALSE;
+ switch( *pStt )
+ {
+ case 0:
+ pEnd = pStt;
+ bIns = FALSE;
+ break;
+
+ case 0x0a:
+ bIns = FALSE;
+ *pStt = 0;
+ if( ++pStt == pEnd )
+ cLastCRLF = 0x0a;
+ else
+ {
+ if( 0x0d == *pStt )
+ pStt++;
+ // JP 03.04.96: das letze am Ende nehmen wir nicht
+ if( !rInput.IsEof() || !(pEnd == pStt ||
+ ( !*pEnd && pEnd == pStt+1 ) ) )
+ bSplitNode = TRUE;
+ }
+ break;
+
+ case 0x0d:
+ bIns = FALSE;
+ *pStt = 0;
+ if( ++pStt == pEnd )
+ cLastCRLF = 0x0d;
+ else
+ {
+ if( 0x0a == *pStt )
+ pStt++;
+ // JP 03.04.96: das letze am Ende nehmen wir nicht
+ if( !rInput.IsEof() || !(pEnd == pStt ||
+ ( !*pEnd && pEnd == pStt+1 ) ) )
+ bSplitNode = TRUE;
+ }
+ break;
+
+ case '\t': break;
+
+ case 0x0c:
+ {
+ // dann mal einen harten Seitenumbruch einfuegen
+ *pStt++ = 0;
+ if( nLineLen )
+ pDoc->Insert( *pPam, pLastStt, eCodeSet );
+ pDoc->SplitNode( *pPam->GetPoint() );
+ pDoc->Insert( *pPam, SvxFmtBreakItem(
+ SVX_BREAK_PAGE_BEFORE ));
+ pLastStt = pStt;
+ nLineLen = 0;
+ bIns = FALSE;
+ }
+ break;
+
+ case 0x1a:
+ if( nReadCnt == nFileSize && pStt+1 == pEnd )
+ *pStt = 0;
+ else
+ *pStt = '#'; // Ersatzdarstellung
+ break;
+
+ default:
+
+ if( (BYTE)' ' > (BYTE)*pStt )
+ // Ctrl-Zchn gefunden ersetze durch '#'
+ *pStt = '#';
+ }
+
+ if( bIns )
+ {
+ if( ( nLineLen >= MAX_ASCII_PARA - 100 ) &&
+ ( ( *pStt == ' ' ) || ( nLineLen >= MAX_ASCII_PARA - 1 ) ) )
+ {
+ char c = *pStt;
+ *pStt = 0;
+ pDoc->Insert( *pPam, pLastStt, eCodeSet );
+ pDoc->SplitNode( *pPam->GetPoint() );
+ pLastStt = pStt;
+ nLineLen = 0;
+ *pStt = c;
+ }
+ ++pStt;
+ ++nLineLen;
+ }
+ else if( bSplitNode )
+ {
+ // es wurde ein CR/LF erkannt, also speichere den Text
+ pDoc->Insert( *pPam, pLastStt, eCodeSet );
+ pDoc->SplitNode( *pPam->GetPoint() );
+ pLastStt = pStt;
+ nLineLen = 0;
+ }
+ } while( TRUE );
+
+ return nError;
+}
+
+
+/* */
+
+SwAsynchLoader::SwAsynchLoader( SvStream& rIn, const SwPaM& rCrsr )
+ : SwClient( 0 )
+{
+ bInCall = FALSE;
+ pDoc = (SwDoc*)rCrsr.GetDoc();
+ pPam = new SwPaM( pDoc, *rCrsr.GetPoint() );
+
+ SwPageDesc& rDesc = pDoc->_GetPageDesc( 0 );
+ rDesc.Add( this );
+
+ pLoader = new _SvLockBytes( rIn,
+ STATIC_LINK( this, SwAsynchLoader, NewData ) );
+}
+
+SwAsynchLoader::~SwAsynchLoader()
+{
+ delete pPam;
+ delete pLoader;
+}
+
+void SwAsynchLoader::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
+{
+ switch( pOld ? pOld->Which() : pNew ? pNew->Which() : 0 )
+ {
+ case RES_OBJECTDYING:
+ if( ((SwPtrMsgPoolItem *)pOld)->pObject == pRegisteredIn )
+ {
+ // dann uns selbst beenden
+ pRegisteredIn->Remove( this );
+ ReleaseRef(); // ansonsten sind wir fertig!
+ }
+ break;
+ }
+}
+
+IMPL_STATIC_LINK( SwAsynchLoader, NewData, _SvLockBytes*, p )
+{
+ ULONG nRet = 0;
+ if( !pThis->bInCall ) // kein mehrfaches Aufrufen
+ {
+ pThis->bInCall = TRUE;
+
+ BOOL bModify = pThis->pDoc->IsModified();
+ nRet = pThis->NextData();
+ if( !bModify )
+ pThis->pDoc->ResetModified();
+
+ if( ERRCODE_IO_PENDING != nRet )
+ pThis->ReleaseRef(); // ansonsten sind wir fertig!
+
+ pThis->bInCall = FALSE;
+ }
+
+ return nRet;
+}
+
+
+ULONG SwAsynchLoader::CallParser()
+{
+ bInCall = TRUE;
+ AddRef();
+ ULONG nRet = NextData();
+ if( ERRCODE_IO_PENDING != nRet )
+ ReleaseRef(); // ansonsten sind wir fertig!
+
+ // Sind wir im Pending-Status, wird ueber den Callback "geidelt" bis
+ // alles gelesen ist oder ein Fehler aufgetreten ist!
+
+ // Was passiert dann ???
+
+ bInCall = FALSE;
+ return nRet;
+}
+
+/* */
+
+_SvLockBytes::_SvLockBytes( SvStream& rInput, const Link& rCallback )
+ : rIn( rInput ), aCallDataRead( rCallback )
+{
+ nDataRead = 0;
+
+ aTimer.SetTimeout( 1000 ); // jede Sekunde 100 Zeichen lesen
+ aTimer.SetTimeoutHdl( STATIC_LINK( this, _SvLockBytes, DataRead ));
+ aTimer.Start();
+}
+
+_SvLockBytes::~_SvLockBytes()
+{
+ aTimer.Stop();
+}
+
+ErrCode _SvLockBytes::ReadAt( ULONG nPos, void* pArr, ULONG nCount,
+ ULONG* pReadCnt )
+{
+ ErrCode nRet = 0;
+ if( nPos + nCount > nDataRead )
+ {
+ nCount = nDataRead - nPos;
+ nRet = ERRCODE_IO_PENDING;
+ }
+
+ if( nCount )
+ {
+ rIn.Seek( nPos );
+ *pReadCnt = rIn.Read( pArr, nCount );
+ }
+ else
+ *pReadCnt = 0;
+ return rIn.GetError() ? rIn.GetError()
+ : ( rIn.IsEof() ? 0 : nRet );
+}
+
+IMPL_STATIC_LINK( _SvLockBytes, DataRead, Timer*, pTimer )
+{
+ pThis->nDataRead += 100;
+ pThis->aCallDataRead.Call( pThis );
+
+ return 0;
+}
+
+/* */
+
+#else
+
+class SwASCIIParser
+{
+ SwDoc* pDoc;
+ SwPaM* pPam;
+ SvStream& rInput;
+ sal_Char* pArr;
+ const SwAsciiOptions& rOpt;
+ SfxItemSet* pItemSet;
+ long nFileSize;
+ BOOL bNewDoc;
+
+ void ReadChars();
+ void ReadUnicode();
+
+public:
+ SwASCIIParser( SwDoc* pD, const SwPaM& rCrsr, SvStream& rIn,
+ int bReadNewDoc, const SwAsciiOptions& rOpts );
+ ~SwASCIIParser();
+
+ ULONG CallParser();
+};
+
+
+// Aufruf fuer die allg. Reader-Schnittstelle
+ULONG AsciiReader::Read( SwDoc &rDoc, SwPaM &rPam, const String & )
+{
+ if( !pStrm )
+ {
+ ASSERT( !this, "ASCII-Read ohne Stream" );
+ return ERR_SWG_READ_ERROR;
+ }
+
+ //JP 18.01.96: Alle Ueberschriften sind normalerweise ohne
+ // Kapitelnummer. Darum hier explizit abschalten
+ // weil das Default jetzt wieder auf AN ist.
+ if( !bInsertMode )
+ Reader::SetNoOutlineNum( rDoc );
+
+ SwASCIIParser* pParser = new SwASCIIParser( &rDoc, rPam, *pStrm,
+ !bInsertMode, aOpt.GetASCIIOpts() );
+ ULONG nRet = pParser->CallParser();
+
+ delete pParser;
+ // after Read reset the options
+ aOpt.ResetASCIIOpts();
+ return nRet;
+}
+
+void AsciiReader::SetFltName( const String& rFltNm )
+{
+ if( 5 <= rFltNm.Len() )
+ {
+ SwAsciiOptions aNewOpts;
+ switch( rFltNm.GetChar( 4 ) )
+ {
+ case 'D': aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_850 );
+ aNewOpts.SetParaFlags( LINEEND_CRLF );
+ if( 5 < rFltNm.Len() )
+ switch( rFltNm.Copy( 5 ).ToInt32() )
+ {
+ case 437: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_437 ); break;
+ case 850: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_850 ); break;
+ case 860: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_860 ); break;
+ case 861: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_861 ); break;
+ case 863: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_863 ); break;
+ case 865: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_865 ); break;
+ }
+ break;
+
+ case 'A': aNewOpts.SetCharSet( RTL_TEXTENCODING_MS_1252 );
+ aNewOpts.SetParaFlags( LINEEND_CRLF );
+ break;
+ case 'M': aNewOpts.SetCharSet( RTL_TEXTENCODING_APPLE_ROMAN );
+ aNewOpts.SetParaFlags( LINEEND_CR );
+ break;
+ case 'X': aNewOpts.SetCharSet( RTL_TEXTENCODING_MS_1252 );
+ aNewOpts.SetParaFlags( LINEEND_LF );
+ break;
+
+ default:
+ if( rFltNm.Copy( 4 ).EqualsAscii( "_DLG" ))
+ {
+ // use the options
+ aNewOpts = aOpt.GetASCIIOpts();
+ }
+ }
+ aOpt.SetASCIIOpts( aNewOpts );
+ }
+}
+
+
+SwASCIIParser::SwASCIIParser( SwDoc* pD, const SwPaM& rCrsr, SvStream& rIn,
+ int bReadNewDoc, const SwAsciiOptions& rOpts )
+ : pDoc( pD ), rInput( rIn ), rOpt( rOpts ), bNewDoc( bReadNewDoc ),
+ pItemSet( 0 )
+{
+ pPam = new SwPaM( *rCrsr.GetPoint() );
+ pArr = new sal_Char [ ASC_BUFFLEN + 1 ];
+
+ SfxItemSet aDfltSet( pDoc->GetAttrPool(), RES_CHRATR_FONT,
+ RES_CHRATR_LANGUAGE );
+
+ // set defaults from the options
+ if( rOpt.GetLanguage() )
+ {
+ aDfltSet.Put( SvxLanguageItem( (LanguageType)rOpt.GetLanguage(),
+ RES_CHRATR_LANGUAGE ) );
+ }
+ if( rOpt.GetFontName().Len() )
+ {
+ BOOL bDelete = FALSE;
+ const SfxFont* pFnt = 0;
+ if( pDoc->GetPrt() )
+ pFnt = pDoc->GetPrt()->GetFontByName( rOpt.GetFontName() );
+
+ if( !pFnt )
+ {
+ pFnt = new SfxFont( FAMILY_DONTKNOW, rOpt.GetFontName() );
+ bDelete = TRUE;
+ }
+
+ aDfltSet.Put( SvxFontItem( pFnt->GetFamily(), pFnt->GetName(),
+ aEmptyStr, pFnt->GetPitch(), pFnt->GetCharSet() ) );
+ }
+
+ if( aDfltSet.Count() )
+ {
+ if( bNewDoc )
+ pDoc->SetDefault( aDfltSet );
+ else
+ pItemSet = new SfxItemSet( aDfltSet );
+ }
+}
+
+SwASCIIParser::~SwASCIIParser()
+{
+ delete pPam;
+ delete pArr;
+ delete pItemSet;
+}
+
+
+// Aufruf des Parsers
+ULONG SwASCIIParser::CallParser()
+{
+ rInput.Seek(STREAM_SEEK_TO_END);
+ rInput.ResetError();
+
+ nFileSize = rInput.Tell();
+ rInput.Seek(STREAM_SEEK_TO_BEGIN);
+ rInput.ResetError();
+
+ ULONG nError = 0;
+ ::StartProgress( STR_STATSTR_W4WREAD, 0, nFileSize, pDoc->GetDocShell() );
+
+ SwPaM* pInsPam = 0;
+ xub_StrLen nSttCntnt;
+ if( !bNewDoc )
+ {
+ const SwNodeIndex& rTmp = pPam->GetPoint()->nNode;
+ pInsPam = new SwPaM( rTmp, rTmp, 0, -1 );
+ nSttCntnt = pPam->GetPoint()->nContent.GetIndex();
+ }
+
+ if( RTL_TEXTENCODING_UCS2 == rOpt.GetCharSet() )
+ ReadUnicode();
+ else
+ ReadChars();
+
+ if( pInsPam )
+ {
+ if( pItemSet )
+ {
+ // then set over the insert range the defined attributes
+ *pInsPam->GetMark() = *pPam->GetPoint();
+ pInsPam->GetPoint()->nNode++;
+ SwNode* pNd = pInsPam->GetNode();
+ if( pNd->IsCntntNode() )
+ pInsPam->GetPoint()->nContent.Assign(
+ (SwCntntNode*)pNd, nSttCntnt );
+ else
+ pInsPam->GetPoint()->nContent.Assign( 0, 0 );
+
+ // !!!!!
+ ASSERT( !this, "Have to change - hard attr. to para. style" );
+ pDoc->Insert( *pInsPam, *pItemSet );
+
+ delete pItemSet, pItemSet = 0;
+ }
+ delete pInsPam;
+ }
+
+ ::EndProgress( pDoc->GetDocShell() );
+ return nError;
+}
+
+void SwASCIIParser::ReadChars()
+{
+ sal_Char *pStt = pArr, *pEnd = pArr, *pLastStt = pArr;
+ long nReadCnt = 0;
+
+ sal_Char cLastCR = 0;
+ long nLineLen = 0;
+
+ do {
+ if( pStt >= pEnd )
+ {
+ if( pLastStt != pStt )
+ pDoc->Insert( *pPam, String( pLastStt, rOpt.GetCharSet() ));
+
+ // lese einen neuen Block ein
+ ULONG lGCount;
+ if (SVSTREAM_OK != rInput.GetError() ||
+ ((lGCount = rInput.Read(pArr, ASC_BUFFLEN)) == 0))
+ break; // aus der WHILE-Schleife heraus
+
+ if( lGCount == ASC_BUFFLEN )
+ {
+ if( RTL_TEXTENCODING_UTF8 == rOpt.GetCharSet() &&
+ 0 != ( pArr[ ASC_BUFFLEN - 1 ] & 0x80 ) )
+ {
+ // check the last char and skip before the start of it
+ long nBack = 0;
+ while( 0x80 == ( pArr[ ASC_BUFFLEN - 1 + nBack ] & 0xC0 ))
+ --nBack;
+ --nBack;
+ lGCount += nBack;
+ rInput.SeekRel( nBack );
+ }
+ else if( RTL_TEXTENCODING_UTF7 == rOpt.GetCharSet() )
+ {
+ // search any char that may not be convertet
+ long nBack = 0;
+ sal_Char c;
+ while( ' ' < ( c = pArr[ ASC_BUFFLEN - 1 + nBack ] ) &&
+ '+' != c )
+ --nBack;
+ if( '+' == c )
+ --nBack;
+ lGCount += nBack;
+ rInput.SeekRel( nBack );
+ }
+ }
+
+ pEnd = pArr + lGCount;
+ nReadCnt += lGCount;
+ *pEnd = 0;
+ pStt = pLastStt = pArr;
+
+ ::SetProgressState( nReadCnt, pDoc->GetDocShell() );
+
+ if( cLastCR )
+ {
+ if( 0x0a == *pStt && 0x0d == cLastCR )
+ pLastStt = ++pStt;
+ cLastCR = 0;
+ nLineLen = 0;
+ // JP 03.04.96: das letze am Ende nehmen wir nicht
+ if( !rInput.IsEof() || !(pEnd == pStt ||
+ ( !*pEnd && pEnd == pStt+1 ) ) )
+ pDoc->SplitNode( *pPam->GetPoint() );
+ }
+ }
+
+ BOOL bIns = TRUE, bSplitNode = FALSE;
+ switch( *pStt )
+ {
+ case 0:
+ pEnd = pStt;
+ bIns = FALSE;
+ break;
+
+ case 0x0a: if( LINEEND_LF == rOpt.GetParaFlags() )
+ {
+ bIns = FALSE;
+ *pStt = 0;
+ ++pStt;
+
+ // JP 03.04.96: das letze am Ende nehmen wir nicht
+ if( !rInput.IsEof() || !(pEnd == pStt ||
+ ( !*pEnd && pEnd == pStt+1 ) ) )
+ bSplitNode = TRUE;
+ }
+ break;
+
+ case 0x0d: if( LINEEND_LF != rOpt.GetParaFlags() )
+ {
+ bIns = FALSE;
+ *pStt = 0;
+ ++pStt;
+
+ BOOL bChkSplit = FALSE;
+ if( LINEEND_CRLF == rOpt.GetParaFlags() )
+ {
+ if( pStt == pEnd )
+ cLastCR = 0x0d;
+ else if( 0x0a == *pStt )
+ {
+ ++pStt;
+ bChkSplit = TRUE;
+ }
+ }
+ else
+ bChkSplit = TRUE;
+
+ // JP 03.04.96: das letze am Ende nehmen wir nicht
+ if( bChkSplit && ( !rInput.IsEof() ||
+ !(pEnd == pStt || ( !*pEnd && pEnd == pStt+1 ))))
+ bSplitNode = TRUE;
+ }
+ break;
+
+ case 0x0c:
+ {
+ // dann mal einen harten Seitenumbruch einfuegen
+ *pStt++ = 0;
+ if( nLineLen )
+ {
+ // Change to charset system!!!!
+ //rOpt.GetCharSet();
+ pDoc->Insert( *pPam, String( pLastStt,
+ rOpt.GetCharSet() ));
+ }
+ pDoc->SplitNode( *pPam->GetPoint() );
+ pDoc->Insert( *pPam, SvxFmtBreakItem(
+ SVX_BREAK_PAGE_BEFORE ));
+ pLastStt = pStt;
+ nLineLen = 0;
+ bIns = FALSE;
+ }
+ break;
+
+ case 0x1a:
+ if( nReadCnt == nFileSize && pStt+1 == pEnd )
+ *pStt = 0;
+ else
+ *pStt = '#'; // Ersatzdarstellung
+ break;
+
+ case '\t': break;
+
+ default:
+ if( (BYTE)' ' > (BYTE)*pStt )
+ // Ctrl-Zchn gefunden ersetze durch '#'
+ *pStt = '#';
+ break;
+ }
+
+ if( bIns )
+ {
+ if( ( nLineLen >= MAX_ASCII_PARA - 100 ) &&
+ ( ( *pStt == ' ' ) || ( nLineLen >= MAX_ASCII_PARA - 1 ) ) )
+ {
+ sal_Char c = *pStt;
+ *pStt = 0;
+
+ // Change to charset system!!!!
+ //rOpt.GetCharSet();
+ pDoc->Insert( *pPam, String( pLastStt, rOpt.GetCharSet() ));
+
+ pDoc->SplitNode( *pPam->GetPoint() );
+ pLastStt = pStt;
+ nLineLen = 0;
+ *pStt = c;
+ }
+ ++pStt;
+ ++nLineLen;
+ }
+ else if( bSplitNode )
+ {
+ // es wurde ein CR/LF erkannt, also speichere den Text
+
+ // Change to charset system!!!!
+ //rOpt.GetCharSet();
+ pDoc->Insert( *pPam, String( pLastStt, rOpt.GetCharSet() ));
+
+ pDoc->SplitNode( *pPam->GetPoint() );
+ pLastStt = pStt;
+ nLineLen = 0;
+ }
+ } while( TRUE );
+}
+
+void SwASCIIParser::ReadUnicode()
+{
+ BOOL bSwapUnicode = FALSE;
+ long nReadCnt = 0;
+
+ sal_Int16 nFlag;
+ rInput >> nFlag;
+
+ if( -2 == nFlag )
+ bSwapUnicode = TRUE; // must be swapped
+ else if( -257 != nFlag ) // notthing to do
+ rInput.SeekRel( sizeof( nFlag ) ); // no tag at start
+
+ sal_Unicode *pStt = (sal_Unicode*)pArr, *pEnd = pStt, *pLastStt = pStt;
+
+ sal_Unicode cLastCR = 0;
+ long nLineLen = 0;
+
+ do {
+ if( pStt >= pEnd )
+ {
+ if( pLastStt != pStt )
+ pDoc->Insert( *pPam, String( pLastStt ));
+
+ // lese einen neuen Block ein
+ ULONG lGCount;
+ if (SVSTREAM_OK != rInput.GetError() ||
+ ((lGCount = rInput.Read(pArr, ASC_BUFFLEN)) == 0))
+ break; // aus der WHILE-Schleife heraus
+
+ pEnd = (sal_Unicode*)(pArr + lGCount);
+ nReadCnt += lGCount;
+ *pEnd = 0;
+ pStt = pLastStt = (sal_Unicode*)pArr;
+
+ if( bSwapUnicode )
+ {
+ sal_Char* pF = pArr, *pN = pArr + 1;
+ for( ULONG n = 0; n < lGCount; n += 2, pF += 2, pN += 2 )
+ {
+ sal_Char c = *pF;
+ *pF = *pN;
+ *pN = c;
+ }
+ }
+
+ ::SetProgressState( nReadCnt, pDoc->GetDocShell() );
+
+ if( cLastCR )
+ {
+ if( 0x0a == *pStt && 0x0d == cLastCR )
+ pLastStt = ++pStt;
+ cLastCR = 0;
+ nLineLen = 0;
+ // JP 03.04.96: das letze am Ende nehmen wir nicht
+ if( !rInput.IsEof() || !(pEnd == pStt ||
+ ( !*pEnd && pEnd == pStt+1 ) ) )
+ pDoc->SplitNode( *pPam->GetPoint() );
+ }
+ }
+
+ BOOL bIns = TRUE, bSplitNode = FALSE;
+ switch( *pStt )
+ {
+ case 0:
+ pEnd = pStt;
+ bIns = FALSE;
+ break;
+
+ case 0x0a: if( LINEEND_LF == rOpt.GetParaFlags() )
+ {
+ bIns = FALSE;
+ *pStt = 0;
+ ++pStt;
+
+ // JP 03.04.96: das letze am Ende nehmen wir nicht
+ if( !rInput.IsEof() || !(pEnd == pStt ||
+ ( !*pEnd && pEnd == pStt+1 ) ) )
+ bSplitNode = TRUE;
+ }
+ break;
+
+ case 0x0d: if( LINEEND_LF != rOpt.GetParaFlags() )
+ {
+ bIns = FALSE;
+ *pStt = 0;
+ ++pStt;
+
+ BOOL bChkSplit = FALSE;
+ if( LINEEND_CRLF == rOpt.GetParaFlags() )
+ {
+ if( pStt == pEnd )
+ cLastCR = 0x0d;
+ else if( 0x0a == *pStt )
+ {
+ ++pStt;
+ bChkSplit = TRUE;
+ }
+ }
+ else
+ bChkSplit = TRUE;
+
+ // JP 03.04.96: das letze am Ende nehmen wir nicht
+ if( bChkSplit && ( !rInput.IsEof() ||
+ !(pEnd == pStt || ( !*pEnd && pEnd == pStt+1 ))))
+ bSplitNode = TRUE;
+ }
+ break;
+
+ case 0x0c:
+ {
+ // dann mal einen harten Seitenumbruch einfuegen
+ *pStt++ = 0;
+ if( nLineLen )
+ {
+ // Change to charset system!!!!
+ //rOpt.GetCharSet();
+ pDoc->Insert( *pPam, String( pLastStt ));
+ }
+ pDoc->SplitNode( *pPam->GetPoint() );
+ pDoc->Insert( *pPam, SvxFmtBreakItem(
+ SVX_BREAK_PAGE_BEFORE ));
+ pLastStt = pStt;
+ nLineLen = 0;
+ bIns = FALSE;
+ }
+ break;
+
+ case 0x1a:
+ if( nReadCnt == nFileSize && pStt+1 == pEnd )
+ *pStt = 0;
+ else
+ *pStt = '#'; // Ersatzdarstellung
+ break;
+
+ case '\t': break;
+
+ default:
+ if( ' ' > *pStt )
+ // Ctrl-Zchn gefunden ersetze durch '#'
+ *pStt = '#';
+ break;
+ }
+
+ if( bIns )
+ {
+ if( ( nLineLen >= MAX_ASCII_PARA - 100 ) &&
+ ( ( *pStt == ' ' ) || ( nLineLen >= MAX_ASCII_PARA - 1 ) ) )
+ {
+ sal_Unicode c = *pStt;
+ *pStt = 0;
+
+ // Change to charset system!!!!
+ //rOpt.GetCharSet();
+ pDoc->Insert( *pPam, String( pLastStt ));
+
+ pDoc->SplitNode( *pPam->GetPoint() );
+ pLastStt = pStt;
+ nLineLen = 0;
+ *pStt = c;
+ }
+ ++pStt;
+ ++nLineLen;
+ }
+ else if( bSplitNode )
+ {
+ // es wurde ein CR/LF erkannt, also speichere den Text
+
+ pDoc->Insert( *pPam, String( pLastStt ));
+
+ pDoc->SplitNode( *pPam->GetPoint() );
+ pLastStt = pStt;
+ nLineLen = 0;
+ }
+ } while( TRUE );
+}
+
+#endif
+
+/*************************************************************************
+
+ Source Code Control System - Header
+
+ $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/filter/ascii/parasc.cxx,v 1.1.1.1 2000-09-18 17:14:53 hr Exp $
+
+ Source Code Control System - Update
+
+ $Log: not supported by cvs2svn $
+ Revision 1.25 2000/09/18 16:04:39 willem.vandorp
+ OpenOffice header added.
+
+ Revision 1.24 2000/08/04 16:25:28 jp
+ read/write unicode ascii files
+
+ Revision 1.23 2000/05/08 17:37:02 jp
+ Changes for Unicode
+
+ Revision 1.22 2000/03/16 16:42:31 kz
+ chg. include to sfx2/printer
+
+ Revision 1.21 1999/10/25 19:26:58 jp
+ Bug #69048#: dont change LF to #
+
+ Revision 1.20 1999/10/08 16:31:54 jp
+ Bug #69048#: dont change tab to #
+
+ Revision 1.19 1999/08/26 18:34:10 JP
+ load and save Text with more options (charset/language/lineend/font)
+
+
+ Rev 1.18 26 Aug 1999 20:34:10 JP
+ load and save Text with more options (charset/language/lineend/font)
+
+ Rev 1.17 23 Jul 1998 11:11:14 JP
+ Task #52654#: Einfuegen Doc nicht mit einer CrsrShell sondern mit einen PaM
+
+ Rev 1.16 29 Jun 1998 13:01:16 JP
+ SvxFmtBreakItem ohne Flag!
+
+ Rev 1.15 29 Apr 1998 08:17:14 MIB
+ MUSS-Aenderung: SvStream::operator!() faellt weg
+
+ Rev 1.14 27 Feb 1998 09:19:56 JP
+ ObjectDying-MessageItem umbenannt
+
+ Rev 1.13 22 Jan 1998 20:00:10 JP
+ CTOR des SwPaM umgestellt
+
+ Rev 1.12 30 Oct 1997 17:13:52 AMA
+ Chg: Kein AutoFlag mehr an Break bzw. PageDesc-Attributen
+
+ Rev 1.11 10 Oct 1997 12:20:22 JP
+ Warnings vom Ueberlauf entfernt
+
+ Rev 1.10 09 Oct 1997 14:26:02 JP
+ Umstellung NodeIndex/-Array/BigPtrArray
+
+ Rev 1.9 12 Aug 1997 10:06:46 OS
+ Header-Umstellung
+
+ Rev 1.8 07 Aug 1997 15:07:08 OM
+ Headerfile-Umstellung
+
+ Rev 1.7 06 Aug 1997 12:46:52 HJS
+ includes
+
+ Rev 1.6 13 Dec 1996 12:18:58 JP
+ Bug #34482#: nach dem Lesen auf SystemCodeSet umschalten
+
+ Rev 1.5 29 Oct 1996 12:10:24 JP
+ am Doc ist das NodesArray nur noch ueber Get..() zugaenglich
+
+ Rev 1.4 09 Oct 1996 17:58:46 MA
+ Progress
+
+ Rev 1.3 28 Jun 1996 13:59:08 MA
+ includes
+
+ Rev 1.2 02 May 1996 11:48:46 JP
+ zum Testen: asynchrones Laden erweitert
+
+ Rev 1.1 30 Apr 1996 12:09:38 JP
+ Vorbereitung fuer asynchrones laden
+
+ Rev 1.0 29 Apr 1996 18:11:00 JP
+ Initial revision.
+
+*************************************************************************/
+