'   ********************************************************************** 
'   **                                                                  ** 
'   **  Resource stream for Rapid-Q (c) 2000 Pavel "Crusher" Minayev    ** 
'   **  Version 1.10 (built on 6/25/2000)                               ** 
'   **  If you find a bug, e-mail me to minayev@aport.ru                ** 
'   **                                                                  ** 
'   **  You can freely distribute & modify this file if you mention     ** 
'   **  somewhere that original file was written by me.                 ** 
'   **                                                                  ** 
'   **  To use this file, $INCLUDE it in your programs, and you will    ** 
'   **  be able to declare variables of QResourceStream type. They'll   ** 
'   **  work exactly like file streams opened in fmOpenRead mode, but   ** 
'   **  you should open resources by <variable>.Open(<resource-number>) ** 
'   **  Note that you don't have to use RESOURCE() function, it's done  ** 
'   **  automatically. Access mode is always read-only, calls to Write  ** 
'   **  functions doesn't do anything. Also, ReadUDT will not work at   ** 
'   **  all for now. And you should NEVER use resource streams as       ** 
'   **  arguments of CopyFrom method - that'll give you an error.       ** 
'   **                                                                  ** 
'   **  I don't know if this library will work on future versions of    ** 
'   **  Rapid-Q. It may work, or may not. However, I'll try to release  ** 
'   **  new versions of this library for the new versions of Rapid-Q.   ** 
'   **                                                                  ** 
'   **  This library was made for Win32. I doubt it works under Unix or ** 
'   **  Linux, and I don't have one to test it. You can however port it ** 
'   **  it to any OS you like if you want to do so.                     ** 
'   **                                                                  ** 
'   **  Program history:                                                ** 
'   **                                                                  ** 
'   **  Version 1.10                                                    ** 
'   **  - got rid of ResourceStart definition                           ** 
'   **  - implemented EOF property                                      ** 
'   **                                                                  ** 
'   **  Version 1.00                                                    ** 
'   **  - initial release                                               ** 
'   **                                                                  ** 
'   ********************************************************************** 

$TYPECHECK ON
$INCLUDE "rapidq.inc"

TYPE QResourceStream EXTENDS QFileStream
    PRIVATE:
        DataTypeToSize(Num_BYTE TO Num_DOUBLE) AS INTEGER
        Offset AS INTEGER
        ResourceStart AS INTEGER
        RealFile AS QFileStream

    PUBLIC:
        LineCount AS INTEGER
        Position AS INTEGER
        Size AS INTEGER
    
        CONSTRUCTOR
            Offset = 0
            LineCount = 0
            DataTypeToSize(Num_BYTE) = SIZEOF(BYTE)
            DataTypeToSize(Num_SHORT) = SIZEOF(SHORT)
            DataTypeToSize(Num_WORD) = SIZEOF(WORD)
            DataTypeToSize(Num_LONG) = SIZEOF(LONG)
            DataTypeToSize(Num_DWORD) = SIZEOF(DWORD)
            DataTypeToSize(Num_SINGLE) = SIZEOF(SINGLE)
            DataTypeToSize(Num_DOUBLE) = SIZEOF(DOUBLE)
            RealFile.Open(Command$(0), fmOpenRead)
            RealFile.Seek(-4, soFromEnd)
            ResourceStart = QResourceStream.RealFile.Size - QResourceStream.RealFile.ReadNum(Num_LONG) - 4
        END CONSTRUCTOR 

        FUNCTION Open(Res AS INTEGER) AS INTEGER
            WITH QResourceStream
                IF Res >= RESOURCECOUNT THEN
                    Result = False
                ELSE
                    .Offset = .ResourceStart + RESOURCE(Res)
                    .RealFile.Seek(.Offset, soFromBeginning)
                    .Size = .RealFile.ReadNum(Num_LONG)
                    .Offset + = SIZEOF(LONG)
                    .Position = 0
                    Result = True
                END IF
            END WITH
        END SUB

        SUB Close
            QResourceStream.Offset = 0
        END SUB

        SUB Seek(NewPos AS INTEGER, From AS INTEGER)
            WITH QResourceStream
                SELECT CASE From
                    CASE IS = soFromBeginning
                        .Position = NewPos
                    CASE IS = soFromCurrent
                        .Position + = NewPos
                    CASE IS = soFromEnd
                        .Position = .Size - NewPos - 1
                END SELECT
                IF .Position < 0 THEN .Position = 0
                IF .Position >= .Size THEN .Position = .Size - 1
                .RealFile.Seek(.Offset + .Position, soFromBeginning)
            END WITH
        END SUB

        FUNCTION EOF AS INTEGER
            IF QResourceStream.Position = QResourceStream.Size THEN
                Result = True
            ELSE
                Result = False
            END IF
        END FUNCTION

    PRIVATE:

        SUB CheckForEOF
            WITH QResourceStream
                IF .Position > .Size THEN
                    .Position = .Size
'                    .Seek(0, soFromEnd) 
                END IF
            END WITH
        END SUB

    PUBLIC:

        FUNCTION ReadNum(Size AS INTEGER) AS DOUBLE
            WITH QResourceStream
                IF .Position = .Size THEN EXIT FUNCTION     ' EOF 
                Result = .RealFile.ReadNum(Size)
                .Position + = .DataTypeToSize(Size)
                .CheckForEOF
            END WITH
        END FUNCTION

        FUNCTION ReadStr(Size AS INTEGER) AS STRING
            DEFSTR Tmp
            WITH QResourceStream
                IF .Position = .Size THEN EXIT FUNCTION     ' EOF 
                Tmp = .RealFile.ReadStr(Size)
                IF .Position >= .Size THEN
                    Tmp = LEFT$(Tmp, LEN(Tmp) - (.Position - .Size + 1))
                    .Position = .Size - 1
                    .Seek(0, soFromEnd)
                END IF
                Result = Tmp
            END WITH
        END FUNCTION

        FUNCTION ReadBinStr(Size AS INTEGER) AS STRING
            Result = QResourceStream.ReadStr(Size)
        END FUNCTION

        FUNCTION ReadLine AS STRING
            DEFINT char
            DEFSTR Res
            WITH QResourceStream
                IF .Position = .Size THEN EXIT FUNCTION     ' EOF 
                char = 0 : Res = ""
                WHILE char <> 13 AND .Size <> .Position
                    char = .ReadNum(Num_BYTE)
                    IF char <> 13 AND char <> 10 THEN
                        Res = Res + CHR$(char)
                    END IF
                WEND
                Result = Res
            END WITH
        END FUNCTION

        SUB ReadUDT(Data AS QObject)
            ' Not yet implemented 
        END SUB

        SUB WriteNum(Number AS INTEGER, Size AS INTEGER)
            ' Does nothing 
        END SUB

        SUB WriteStr(Data AS STRING, Size AS INTEGER)
            ' Does nothing 
        END SUB

        SUB WriteBinStr(Data AS STRING, Size AS INTEGER)
            ' Does nothing 
        END SUB

        SUB WriteLine(Line AS STRING)
            ' Does nothing 
        END SUB

        SUB WriteUDT(Data AS QObject)
            ' Does nothing 
        END SUB

        SUB CopyFrom(Stream AS QObject, Bytes AS INTEGER)
            ' Does nothing 
        END SUB
        
END TYPE