* bin/commit.hb
* config/detect.mk
* config/detfun.mk
* config/detplat.mk
* config/dir.mk
* config/dirsh.mk
* config/global.mk
* config/globsh.mk
* config/instsh.mk
* config/lang.hb
* config/lang2po.hb
* config/po2lang.hb
* config/postinst.hb
* contrib/hbexpat/tests/tohash.prg
* contrib/hbformat/utils/hbformat.ini
* contrib/hbmisc/hbedit.prg
* contrib/hbmxml/tests/testmxml.prg
* contrib/hbnetio/utils/hbnetio/_console.prg
* contrib/hbnetio/utils/hbnetio/_winsvc.prg
* contrib/hbnetio/utils/hbnetio/hbnetio.prg
* contrib/hbnetio/utils/hbnetio/netiomgm.hb
* contrib/hbwin/tests/ole.prg
* contrib/hbwin/tests/oletst2.js
* contrib/hbwin/tests/oletst2.vbs
* contrib/hbxpp/doc/en/binnumx.txt
* contrib/hbxpp/doc/en/dbcmdx.txt
* contrib/xhb/htmutil.prg
* contrib/xhb/tfile.prg
* contrib/xhb/tframe.prg
* contrib/xhb/thtm.prg
* ChangeLog.txt
* debian/copyright
* doc/class_tp.txt
* doc/hdr_tpl.txt
* doc/xhb-diff.txt
* LICENSE.txt
* package/harbour-wce.spec.in
* package/harbour-win.spec.in
* package/harbour.spec
* package/mpkg_rpm_wce.sh
* package/mpkg_rpm_win.sh
* package/mpkg_rpm.sh
* package/mpkg_src.sh
* package/mpkg_ver.sh
* src/rtl/achoice.prg
* src/rtl/getsys53.prg
* src/rtl/tgetlist.prg
* src/rtl/tlabel.prg
* src/rtl/tmenusys.prg
* tests/hbdoc.prg
* tests/langmsg.prg
* tests/rto_get.prg
* tests/rto_tb.prg
+ doc/en/ati.txt
+ doc/en/dirdrive.txt
+ doc/en/hashfunc.txt
+ doc/en/hbtoken.txt
+ doc/en/left.txt
+ doc/en/proc.txt
+ doc/en/strtran.txt
+ doc/en/transfrm.txt
+ doc/en/typefile.txt
* doc/en/*
* more partial sync with 3.4 fork
509 lines
10 KiB
Plaintext
509 lines
10 KiB
Plaintext
/*
|
|
* Base fileIO class.
|
|
*
|
|
* Copyright 2000 Manos Aspradakis <maspr@otenet.gr>
|
|
* Copyright 2000 Luiz Rafael Culik <culik@sl.conex.net> (Porting this library to Harbour)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; see the file LICENSE.txt. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301 USA (or visit https://www.gnu.org/licenses/).
|
|
*
|
|
* As a special exception, the Harbour Project gives permission for
|
|
* additional uses of the text contained in its release of Harbour.
|
|
*
|
|
* The exception is that, if you link the Harbour libraries with other
|
|
* files to produce an executable, this does not by itself cause the
|
|
* resulting executable to be covered by the GNU General Public License.
|
|
* Your use of that executable is in no way restricted on account of
|
|
* linking the Harbour library code into it.
|
|
*
|
|
* This exception does not however invalidate any other reasons why
|
|
* the executable file might be covered by the GNU General Public License.
|
|
*
|
|
* This exception applies only to the code released by the Harbour
|
|
* Project under the name Harbour. If you copy code from other
|
|
* Harbour Project or Free Software Foundation releases into a copy of
|
|
* Harbour, as the General Public License permits, the exception does
|
|
* not apply to the code that you add in this way. To avoid misleading
|
|
* anyone as to the status of such modified files, you must delete
|
|
* this exception notice from them.
|
|
*
|
|
* If you write modifications of your own for Harbour, it is your choice
|
|
* whether to permit this exception to apply to your modifications.
|
|
* If you do not wish that, delete this exception notice.
|
|
*
|
|
*/
|
|
|
|
#include "hbclass.ch"
|
|
#include "fileio.ch"
|
|
#include "cgi.ch"
|
|
|
|
#translate FPOS( <f> ) => FSeek( <f>, 0, FS_RELATIVE )
|
|
|
|
CREATE CLASS TCgiFile
|
|
|
|
VAR Buffer INIT ""
|
|
VAR Name INIT ""
|
|
VAR Handle
|
|
VAR FileSize INIT 0
|
|
VAR BytesRead INIT 0
|
|
VAR cPage INIT ""
|
|
VAR nPage INIT 0
|
|
VAR nPageSize INIT 1024
|
|
VAR nRecord INIT 0
|
|
|
|
METHOD New( cName )
|
|
|
|
METHOD Open( nMode )
|
|
|
|
METHOD Close() INLINE FClose( ::Handle ), ;
|
|
::Handle := -999
|
|
|
|
METHOD Rename( c ) INLINE FRename( ::File, c ) == 0
|
|
|
|
METHOD Erase() INLINE FErase( ::File ) == 0
|
|
|
|
METHOD Exists() INLINE hb_FileExists( ::File )
|
|
|
|
METHOD Error() INLINE FError() != 0
|
|
|
|
METHOD Tell() INLINE FSeek( ::handle, 0, FS_RELATIVE )
|
|
|
|
METHOD Pointer() INLINE FPOS( ::handle )
|
|
|
|
METHOD ReadStr( n ) INLINE ::Buffer := ;
|
|
FReadStr( ::Handle, n )
|
|
METHOD Write( c, n ) INLINE FWrite( ::Handle, c, n )
|
|
|
|
METHOD WriteByte( nByte )
|
|
|
|
METHOD WriteInt( nInt )
|
|
|
|
METHOD WriteLong( nLong )
|
|
|
|
METHOD GetBuffer() INLINE ::Buffer
|
|
|
|
METHOD GoTop() INLINE FSeek( ::Handle, 0 )
|
|
|
|
METHOD GoBottom() INLINE FSeek( ::Handle, 0, FS_END )
|
|
|
|
METHOD Bof() INLINE( FPOS( ::Handle ) == 0 )
|
|
|
|
METHOD Eof() INLINE FPOS( ::Handle ) == ::FileSize
|
|
|
|
METHOD Seek( n, o ) INLINE FSeek( ::Handle, n, o )
|
|
|
|
METHOD Create( nAttr )
|
|
|
|
METHOD Size()
|
|
|
|
METHOD _Read( nSize, cBuff )
|
|
|
|
METHOD ReadAhead( nSize, cBuff )
|
|
|
|
METHOD ReadLine( nSize )
|
|
|
|
METHOD PrevLine( nBytes )
|
|
|
|
METHOD ReadByte()
|
|
|
|
METHOD ReadInt()
|
|
|
|
METHOD ReadLong()
|
|
|
|
METHOD Goto( nLine )
|
|
|
|
METHOD Skip( nLines )
|
|
|
|
METHOD MaxPages( nPageSize )
|
|
|
|
METHOD PrevPage( nBytes )
|
|
|
|
METHOD NextPage( nBytes )
|
|
|
|
ENDCLASS
|
|
|
|
METHOD New( cName ) CLASS TCgiFile
|
|
|
|
::Name := cName
|
|
::Buffer := ""
|
|
::Handle := 0
|
|
::FileSize := 0
|
|
::BytesRead := 0
|
|
::cPage := ""
|
|
::nPage := 0
|
|
::nPageSize := 1024
|
|
::nRecord := 0
|
|
|
|
RETURN Self
|
|
|
|
/*
|
|
** ::Open( [<nMode>] ) --> lSuccess
|
|
*/
|
|
|
|
METHOD Open( nMode ) CLASS TCgiFile
|
|
|
|
__defaultNIL( @nMode, FO_EXCLUSIVE )
|
|
::Handle := FOpen( ::Name, nMode )
|
|
IF ::Handle != F_ERROR
|
|
::Size()
|
|
ENDIF
|
|
|
|
RETURN ::Handle != F_ERROR
|
|
|
|
/*
|
|
** ::Create( [<nAttrib>] ) --> lSuccess
|
|
*/
|
|
|
|
METHOD Create( nAttr ) CLASS TCgiFile
|
|
|
|
LOCAL nSuccess
|
|
|
|
__defaultNIL( @nAttr, 0 )
|
|
nSuccess := FCreate( ::Name, nAttr )
|
|
::Handle := nSuccess
|
|
|
|
RETURN nSuccess != F_ERROR
|
|
|
|
/*
|
|
** ::Size() --> nFileSize
|
|
**
|
|
** RETURNs the size in bytes of the current file.
|
|
*/
|
|
|
|
METHOD Size() CLASS TCgiFile
|
|
|
|
LOCAL nCurrent
|
|
LOCAL nLength
|
|
|
|
nCurrent := FPOS( ::Handle )
|
|
nLength := FSeek( ::Handle, 0, FS_END )
|
|
|
|
FSeek( ::Handle, nCurrent )
|
|
::FileSize := nLength
|
|
|
|
RETURN nLength
|
|
|
|
/*
|
|
** ::Read( [<nSize>], [@<cBuff>] ) --> nBytesRead
|
|
*/
|
|
|
|
METHOD _Read( nSize, cBuff ) CLASS TCgiFile
|
|
|
|
__defaultNIL( @nSize, 1024 )
|
|
__defaultNIL( @cBuff, Space( nSize ) )
|
|
|
|
::BytesRead := FRead( ::Handle, @cBuff, nSize )
|
|
::Buffer := cBuff
|
|
|
|
RETURN cBuff // nBytesRead )
|
|
|
|
/*
|
|
** ::ReadAhead( [<nSize>], [@<cBuff>] ) --> nBytesRead
|
|
**
|
|
** Read forward in the file without moving the pointer.
|
|
*/
|
|
|
|
METHOD ReadAhead( nSize, cBuff ) CLASS TCgiFile
|
|
|
|
LOCAL nCurrent
|
|
|
|
__defaultNIL( @nSize, 1024 )
|
|
__defaultNIL( @cBuff, Space( nSize ) )
|
|
|
|
// --> save position in file
|
|
nCurrent := FPOS( ::Handle )
|
|
|
|
// --> read ahead
|
|
::BytesRead := FRead( ::Handle, @cBuff, nSize )
|
|
|
|
// --> RETURN to saved position
|
|
FSeek( ::Handle, nCurrent )
|
|
|
|
RETURN cBuff
|
|
|
|
/*
|
|
** ::ReadLine( [<nBytes>] ) --> cLine
|
|
*/
|
|
|
|
METHOD Readline( nSize ) CLASS TCgiFile
|
|
|
|
LOCAL cString
|
|
LOCAL nCurrent
|
|
LOCAL nCr
|
|
|
|
__defaultNIL( @nSize, 1024 )
|
|
|
|
IF nSize <= 0
|
|
RETURN ""
|
|
ENDIF
|
|
|
|
nCurrent := FSeek( ::Handle, 0, FS_RELATIVE )
|
|
cString := FReadStr( ::Handle, nSize )
|
|
nCr := At( Chr( 13 ), cString )
|
|
|
|
FSeek( ::Handle, nCurrent, FS_SET )
|
|
FSeek( ::Handle, nCr + 1, FS_RELATIVE )
|
|
|
|
::Buffer := SubStr( cString, 1, nCr - 1 )
|
|
::nRecord++
|
|
|
|
RETURN ::Buffer
|
|
|
|
/*
|
|
** ::ReadByte() --> nByte or -1 if unsuccessfull
|
|
*/
|
|
|
|
METHOD ReadByte() CLASS TCgiFile
|
|
|
|
LOCAL nBytes
|
|
LOCAL cBuff := Space( 1 )
|
|
|
|
nBytes := FRead( ::Handle, @cBuff, hb_BLen( cBuff ) )
|
|
|
|
RETURN iif( nBytes > 0, Asc( cBuff ), -1 )
|
|
|
|
/*
|
|
** ::ReadInt() --> nUnsignedInt or -1 if unsuccessfull
|
|
*/
|
|
|
|
METHOD ReadInt() CLASS TCgiFile
|
|
|
|
LOCAL nBytes
|
|
LOCAL cBuff := Space( 2 )
|
|
|
|
nBytes := FRead( ::Handle, @cBuff, hb_BLen( cBuff ) )
|
|
|
|
RETURN iif( nBytes > 0, Bin2I( cBuff ), -1 )
|
|
|
|
/*
|
|
** ::ReadLong() --> nLong or -1 if unsuccessfull
|
|
*/
|
|
|
|
METHOD ReadLong() CLASS TCgiFile
|
|
|
|
LOCAL nBytes
|
|
LOCAL cBuff := Space( 4 )
|
|
|
|
nBytes := FRead( ::Handle, @cBuff, hb_BLen( cBuff ) )
|
|
|
|
RETURN iif( nBytes > 0, Bin2L( cBuff ), -1 )
|
|
|
|
/*
|
|
** ::WriteByte( nByte ) --> lSuccess
|
|
*/
|
|
|
|
METHOD WriteByte( nByte ) CLASS TCgiFile
|
|
|
|
LOCAL lSuccess := ( FWrite( ::nHandle, hb_BCode( nByte ), 1 ) == 1 )
|
|
|
|
RETURN lSuccess
|
|
|
|
/*
|
|
** ::WriteInt( nInt ) --> lSuccess
|
|
*/
|
|
|
|
METHOD WriteInt( nInt ) CLASS TCgiFile
|
|
|
|
LOCAL lSuccess := ( FWrite( ::nHandle, I2Bin( nInt ), 2 ) == 2 )
|
|
|
|
RETURN lSuccess
|
|
|
|
/*
|
|
** ::WriteLong( nLong ) --> lSuccess
|
|
*/
|
|
|
|
METHOD WriteLong( nLong ) CLASS TCgiFile
|
|
|
|
LOCAL lSuccess := ( FWrite( ::nHandle, L2Bin( nLong ), 4 ) == 4 )
|
|
|
|
RETURN lSuccess
|
|
|
|
/*
|
|
** ::GOTO( <nLine> ) --> nPrevPos
|
|
**
|
|
** Skips to line <nLine> from top. RETURNs previous position in file.
|
|
**
|
|
*/
|
|
|
|
METHOD Goto( nLine ) CLASS TCgiFile
|
|
|
|
LOCAL nCount := 1
|
|
LOCAL nPos := FPOS( ::Handle )
|
|
|
|
::GoTop()
|
|
|
|
IF nLine < 0 // don't accept < 0
|
|
RETURN nPos
|
|
ELSEIF nLine == 0
|
|
nLine := 1
|
|
::nRecord := 1
|
|
::GoTop()
|
|
RETURN nPos
|
|
ENDIF
|
|
|
|
WHILE ! ::Eof()
|
|
|
|
::ReadLine()
|
|
|
|
IF nCount == nLine
|
|
EXIT
|
|
ENDIF
|
|
|
|
nCount++
|
|
ENDDO
|
|
|
|
RETURN nPos
|
|
|
|
/*
|
|
** ::Skip( [<nLines>] ) --> nPrevPos
|
|
**
|
|
** Skips to line <nLine> from top. RETURNs previous position in file.
|
|
**
|
|
*/
|
|
|
|
METHOD Skip( nLines ) CLASS TCgiFile
|
|
|
|
LOCAL nCount := 0
|
|
LOCAL nPos := FPOS( ::Handle )
|
|
|
|
__defaultNIL( @nLines, 1 )
|
|
|
|
IF nLines <= 0 // don't accept < 0
|
|
|
|
RETURN nPos
|
|
|
|
ENDIF
|
|
|
|
WHILE ! ::Eof()
|
|
|
|
IF nCount == nLines
|
|
EXIT
|
|
ENDIF
|
|
|
|
::ReadLine()
|
|
nCount++
|
|
ENDDO
|
|
|
|
RETURN nPos
|
|
|
|
/*
|
|
** ::MaxPages( <nPageSize> ) --> nMaxPages
|
|
*/
|
|
|
|
METHOD MaxPages( nPageSize ) CLASS TCgiFile
|
|
|
|
__defaultNIL( @nPageSize, ::nPageSize )
|
|
|
|
RETURN ::Size() / nPageSize
|
|
|
|
/*
|
|
** ::PrevPage( [<nBytes>] ) --> cPage
|
|
*/
|
|
|
|
METHOD PrevPage( nBytes ) CLASS TCgiFile
|
|
|
|
__defaultNIL( @nBytes, 1024 )
|
|
|
|
IF nBytes <= 0
|
|
RETURN ""
|
|
ENDIF
|
|
|
|
IF ! ::Bof()
|
|
FSeek( ::Handle, - nBytes, FS_RELATIVE )
|
|
::cPage := FReadStr( ::Handle, nBytes )
|
|
FSeek( ::Handle, - nBytes, FS_RELATIVE )
|
|
::nPage --
|
|
ENDIF
|
|
|
|
RETURN ::cPage
|
|
|
|
/*
|
|
** ::NextPage( [<nBytes>] ) --> cPage
|
|
*/
|
|
|
|
METHOD NextPage( nBytes ) CLASS TCgiFile
|
|
|
|
__defaultNIL( @nBytes, 1024 )
|
|
|
|
IF nBytes <= 0
|
|
RETURN ""
|
|
ENDIF
|
|
|
|
IF ! ::Eof()
|
|
::cPage := FReadStr( ::Handle, nBytes )
|
|
::nPage++
|
|
ENDIF
|
|
|
|
RETURN ::cPage
|
|
|
|
/*
|
|
** ::PrevLine( [<nBytes>] ) --> ::Buffer
|
|
*/
|
|
|
|
METHOD PrevLine( nBytes ) CLASS TCgiFile
|
|
|
|
LOCAL fHandle := ::Handle
|
|
LOCAL nOrigPos := FPOS( fHandle )
|
|
LOCAL nMaxRead
|
|
LOCAL nNewPos
|
|
LOCAL lMoved
|
|
LOCAL cBuff
|
|
LOCAL nWhereCrLf
|
|
LOCAL nPrev
|
|
LOCAL cTemp
|
|
|
|
__defaultNIL( @nBytes, 256 )
|
|
|
|
IF nOrigPos == 0
|
|
|
|
lMoved := .F.
|
|
|
|
ELSE
|
|
|
|
lMoved := .T.
|
|
|
|
// Check preceeding 2 chars for CR+LF
|
|
FSeek( fHandle, -2, FS_RELATIVE )
|
|
cTemp := Space( 2 )
|
|
FRead( fHandle, @cTemp, hb_BLen( cTemp ) )
|
|
|
|
IF cTemp == CRLF()
|
|
FSeek( fHandle, -2, FS_RELATIVE )
|
|
ENDIF
|
|
|
|
nMaxRead := Min( nBytes, FPOS( fHandle ) )
|
|
|
|
cBuff := Space( nMaxRead )
|
|
nNewPos := FSeek( fHandle, -nMaxRead, FS_RELATIVE )
|
|
FRead( fHandle, @cBuff, nMaxRead )
|
|
nWhereCrLf := RAt( CRLF(), cBuff )
|
|
IF nWhereCrLf == 0
|
|
|
|
nPrev := nNewPos
|
|
::Buffer := cBuff
|
|
|
|
ELSE
|
|
|
|
nPrev := nNewPos + nWhereCrLf + 1
|
|
::Buffer := SubStr( cBuff, nWhereCrLf + 2 )
|
|
|
|
ENDIF
|
|
|
|
FSeek( fHandle, nPrev, FS_SET )
|
|
|
|
ENDIF
|
|
|
|
RETURN iif( lMoved, ::Buffer, "" )
|