Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

PB/DLL fast line input replacement

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • PB/DLL fast line input replacement

    Code:
    '+--------------------------------------------------------------------------+
    '|                                                                          |
    '|                                  BUFIN                                   |
    '|                                                                          |
    '|    Fast line input replacement based on the core Windows API file I/O    |
    '|                                                                          |
    '|               Adapted from the WinLIFT's skBufin function                |                                                                          |
    '|                                                                          |
    '|                  "ZAP image solution" programming tools                  |
    '|                                                                          |
    '+--------------------------------------------------------------------------+
    '|                                                                          |
    '|                         Author Patrice TERRIER                           |
    '|            8 Domaine de Rochagnon. 38800 Champagnier  FRANCE             |
    '|               [url="http://www.zapsolution.com/winlift/index.htm"]http://www.zapsolution.com/winlift/index.htm[/url]                |
    '|                    E-mail: [email protected]                      |
    '|                                                                          |
    '|                   copyright (c) 2000 Patrice TERRIER                     |
    '|                                                                          |
    '+--------------------------------------------------------------------------+
    '|                  Project started on : 04-19-2000                         |
    '|                        Last revised : 04-19-2000                         |
    '+--------------------------------------------------------------------------+
    '
    ' This example shows how to use the Bufin$ function to read
    ' in a sequential ASCII text file.
    ' Text line can be delimited with a single CR or both CR+LF.
    '
    ' This example works in console mode, you must use the MKCON.EXE utility
    ' to make it work from a DOS windows session.
    
    #COMPILE EXE
    
    #INCLUDE "WIN32API.INC"
    
    DECLARE FUNCTION GetStdHandle LIB "KERNEL32.DLL" ALIAS "GetStdHandle" (BYVAL nStdHandle AS LONG) AS LONG
    DECLARE FUNCTION WriteConsole LIB "KERNEL32.DLL" ALIAS "WriteConsoleA" (BYVAL hConsoleOutput AS LONG, lpBuffer AS ASCIIZ, BYVAL nNumberOfCharsToWrite AS LONG, lpNumberOfCharsWritten AS LONG, BYVAL lpReserved AS LONG) AS LONG
    
    %STD_OUTPUT_HANDLE    = -11&
    GLOBAL zTmp AS ASCIIZ * 256
    
    ' Determines the presence of a file.
    FUNCTION Exist& (BYVAL FileSpec$) EXPORT
    
        LOCAL fd AS WIN32_FIND_DATA
    
        IF LEN(FileSpec$) THEN
           hFind& = FindFirstFile(BYVAL STRPTR(FileSpec$), fd)
           IF hFind& <> %INVALID_HANDLE_VALUE THEN
              CALL FindClose(hFind&)
              FUNCTION = -1
           END IF
        END IF
    
    END FUNCTION
    
    ' Changes the character being used as delimiter to read in a sequential text file.
    FUNCTION SetBufinChar$(BYVAL Char$) STATIC EXPORT
        IF LEN(Char$) THEN UserChar$ = Char$
        IF LEN(UserChar$) THEN
           FUNCTION = UserChar$
        ELSE
           FUNCTION = CHR$(13)
        END IF
    END FUNCTION
    
    ' Generic open file function
    FUNCTION FOpen& (BYVAL FilName$, BYVAL AccessMode&, BYVAL ShareMode&, hFile&) EXPORT
    '@'skdebug "98"
    
        zTmp = FilName$
        AccessMode& = MIN(MAX(AccessMode&, 0), 2) ' Coherce between 0-2
        IF AccessMode& = 0 THEN                   ' 0 Open for read only.
           AccessIs& = %GENERIC_READ
        ELSEIF AccessMode& = 1 THEN               ' 1 Open for write only.
           AccessIs& = %GENERIC_WRITE
        ELSE                                      ' 2 Open for read and write.
           AccessIs& = %GENERIC_READ OR %GENERIC_WRITE
        END IF
    
        ShareMode& = MIN(MAX(ShareMode&, 1), 4)   ' Coherce between 1-4
        IF ShareMode& = 1 THEN                    ' 1 Deny read/write access.
           ShareIs& = 0
        ELSEIF ShareMode& = 2 THEN                ' 2 Deny write access.
           ShareIs& =  %FILE_SHARE_READ
        ELSEIF ShareMode& = 3 THEN                ' 3 Deny read access.
           ShareIs& =  %FILE_SHARE_WRITE
        ELSE                                      ' 4 Deny none (full share mode).
           ShareIs& =  %FILE_SHARE_READ OR %FILE_SHARE_WRITE
        END IF
    
        IF hFile& = -1 THEN
           FlagAndAttribute& = %FILE_ATTRIBUTE_NORMAL OR %FILE_FLAG_WRITE_THROUGH
        ELSE
           FlagAndAttribute& = %FILE_ATTRIBUTE_NORMAL
        END IF
    
        hFile& = CreateFile(zTmp, AccessIs&, ShareIs&, BYVAL %NULL, %OPEN_ALWAYS, FlagAndAttribute&, BYVAL %NULL)
    
        IF hFile& = %INVALID_HANDLE_VALUE THEN    ' -1 Fail to create the file
           FUNCTION = GetLastError                ' Set the error code
           hFile& = 0                             ' Reset handle number
        END IF
    
    END FUNCTION
    
    ' Dito LOF
    FUNCTION Flof& (BYVAL hFile&) EXPORT
        IF GetFileType(hFile&) = %FILE_TYPE_DISK THEN
           fSize& = GetFileSize(hFile&, BYVAL %NULL)
           IF fSize& > -1& THEN FUNCTION = fSize&
        END IF
    END FUNCTION
    
    ' Dito SEEK
    FUNCTION FSeek& (hFile&, BYVAL PosByte&) EXPORT
        IF SetFilePointer(hFile&, PosByte&, BYVAL %NULL, %FILE_BEGIN) < 0 THEN
           FUNCTION = GetLastError
        END IF
    END FUNCTION
    
    ' Dito GET
    FUNCTION FGet& (BYVAL hFile&, Buf$) EXPORT
        IF hFile& THEN
           LenBuf& = LEN(Buf$)
           IF LenBuf& THEN
              IF ReadFile&(hFile&, BYVAL STRPTR(Buf$), LenBuf&, ByttesReaded&, BYVAL %NULL) = 0 THEN
                 FUNCTION = GetLastError
              END IF
           END IF
        END IF
    END FUNCTION
    
    ' GET at a specific offset
    FUNCTION FGetAt& (BYVAL hFile&, BYVAL PosByte&, Buf$) EXPORT
        ErrCode& = FSeek(hFile&, PosByte&)
        IF ErrCode& = 0 THEN ErrCode& = FGet(hFile&, Buf$)
        FUNCTION = ErrCode&
    END FUNCTION
    
    ' Dito CLOSE
    SUB FClose (hFile&) EXPORT
        IF hFile& THEN CALL CloseHandle(hFile&)
        hFile& = 0
    END SUB
    
    ' Enhanced sequential LINEINPUT
    FUNCTION Bufin$ (FilName$, Done&) STATIC EXPORT
    IF LEN(FilName$) THEN
       IF NOT Reading& THEN
          Cr$ = SetBufinChar$("")           ' added for spec char
          Reading& = -1: Done& = 0
          IF ASC(Cr$) = 13 THEN             ' added for spec char
             LenCr& = 0: Cr$ = CHR$(13)
          ELSE                              ' added for spec char
             LenCr& = LEN(Cr$)              ' added for spec char
          END IF                            ' added for spec char
          iCr& = 0: Location& = 0
          IF NOT Exist(FilName$) THEN GOTO BufEnd  ' Nothing to do
          ErrCode& = FOpen(FilName$, 0, 2, hFile&)
          IF ErrCode& THEN
             Done& = ErrCode&: Reading& = 0
             EXIT FUNCTION
          END IF
          Remaining& = Flof(hFile&)                  ' Bytes count to be read
          SizeFile& = Remaining&                     ' Remember this
          IF Remaining& = 0 GOTO BufEnd              ' Nothing to read
          BufSize& = 16384
          Buffer$ = SPACE$(BufSize&)
       END IF
       DO WHILE Remaining&                           ' While more in the file
          IF iCr& = 0 THEN                           ' If no return was found
             IF Remaining& < BufSize& THEN           ' read only what remains.
                BufSize& = Remaining&                ' Resize the buffer.
                IF BufSize& < 1 THEN EXIT DO         ' Possible only if EOF 26.
                Buffer$ = SPACE$(BufSize&)
             END IF
             ErrCode& = FGetAt&(hFile&, Location&, Buffer$) ' Read a bloc.
             Location& = Location& + BufSize&        ' Here we are.
             BufPos& = 1                             ' Start at the beginning
          END IF                                     ' of that bloc.
          DO                                         ' Walk through buffer.
             iCr& = INSTR(BufPos&, Buffer$, Cr$)     ' Look for a Return.
             IF LenCr& = 0 THEN                      ' Do this to read files with
                LenCr& = 1                           ' or without LF after CR.
                IF ASC(Buffer$, iCr& + 1) = 10 THEN LenCr& = 2
             END IF
             IF iCr& THEN                            ' We found one.
                SaveCr& = iCr&                       ' Save where
                FUNCTION = MID$(Buffer$, BufPos&, iCr& - BufPos&)
                BufPos& = iCr& + LenCr&              ' In case of LF skip it
                EXIT FUNCTION                        ' all done for now.
             ELSE                                    ' Back up in the file.
              ' If we reached the end of file and no iCR&
              ' was found, return what remains in the string.
                IF Location& >= SizeFile& THEN
                 ' Assign function and trap ^Z
                   FUNCTION = RTRIM$(MID$(Buffer$, SaveCr& + LenCr&), CHR$(26))
                   Remaining& = BufSize&
                   EXIT DO
                END IF
              ' 05-06-1998 () were missing on each side of (LenCr& - 1)
                Slop& = BufSize& - SaveCr& - (LenCr& - 1) ' Calc buffer excess.
                Remaining& = Remaining& + Slop&           ' Calc file excess.
                Location& = Location& - Slop&
             END IF
          LOOP WHILE iCr&                                 ' While more in buffer.
          Remaining& = Remaining& - BufSize&
          SaveCr& = 0 
       LOOP
    END IF
    
    BufEnd:
    Reading& = 0: Done& = -1: CALL FClose(hFile&)
    END FUNCTION
    
    FUNCTION WinMain& (BYVAL CurInst&, BYVAL PrvInst&, CmdL AS ASCIIZ PTR, BYVAL CmdShow&) EXPORT
    
        hOutput& = GetStdHandle(%STD_OUTPUT_HANDLE)
        FilName$ = "BUFIN.BAS"
        DO
            X$ = Bufin$(FilName$, Done&) + CHR$(13,10)
            Buffer& = STRPTR(X$)
            WriteConsole hOutput&, BYVAL Buffer&, LEN(X$), Written&, BYVAL 0&
        LOOP UNTIL Done&
        
        CALL Bufin$("", Done&) ' This can be used to close the handle
                               ' before full file completion
    END FUNCTION

    -------------
    Patrice Terrier
    mailto[email protected][email protected]</A>
    Patrice Terrier
    www.zapsolution.com
    www.objreader.com
    Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).
Working...
X