home *** CD-ROM | disk | FTP | other *** search
- {
- From: LEE LEFLER
- Subj: Shared textfiles
-
- Want to do some reading of LARGE textfiles on a network.
- How can I open a textfile for reading in
- (readonly+denywrite) mode ?
-
- Some say that Text files can't be shared ?!?!?
-
- Sure they can, but it takes a little special work to do it. I use
- the following unit to share the nodelist. I don't know who originally wrote it
- so I hope it's OK to post. It's going to need a little cleaning up since the
- message readers are going to wrap it, but I don't want to modify it so you guys
- will have to handle that when you export it.
- }
-
- Unit TxtShare;
-
- {$F+}
-
- { This UNIT implements a TEXT file device driver to access TEXT files with a }
- { user specified network access mode (see DOS Technical Reference for DOS }
- { function 3Dh). This can be accomplished for non-TEXT files by setting the }
- { standard global variable "FileMode" (part of the System unit) to the desired
- }
- { value, and then calling the appropriate open function. This is not supported
- }
- { for TEXT files in Turbo Pascal v4.0. }
-
- { To open a Text file with a user specified access mode, place a call to the }
- { procedure AssignText to associate a filename with the text file variable. }
- { Next, set the standard global variable FileMode with the desired DOS access }
- { mode value. RESET, REWRITE, and APPEND will now use the access mode }
- { assigned to the FileMode variable when opening the file. }
-
- { By default, no EOF marker is written to text files that have been "assigned"
- }
- { using this unit's routines. If you require a ^Z at the end of any file }
- { opened for output, set the global variable WriteTextEofChar to TRUE before }
- { closing the file. }
-
- Interface
-
- Uses Dos;
-
- Var
- WriteTextEofChar : Boolean;
-
- Procedure AssignText(Var F : Text; FileName : String);
-
- Implementation
-
- {$R-,S-}
-
- Var
- ReadText_Addr : Pointer;
- WriteText_Addr : Pointer;
- SeekText_Addr : Pointer;
- DoNothing_Addr : Pointer;
- CloseText_Addr : Pointer;
-
- Function ReadText(Var F : TextRec) : Word;
- Begin
- Inline(
- $1E/ { push ds ;Save data segment
- value}
- $C5/$76/$06/ { lds si,[bp+6] ;Address the file var
- structure}
- $AD/ { lodsw ;Pick up file handle}
- $89/$C3/ { mov bx,ax ; ... and store in bx}
- $46/ { inc si ;Skip past the Mode
- field}
- $46/ { inc si ; ... and address the
- BufSize field}
- $AD/ { lodsw ;Pick up BufSize (# of
- bytes to read)}
- $89/$C1/ { mov cx,ax ; ... and store in cx}
- $81/$C6/$06/$00/ { add si,6 ;Address the BufPtr
- field}
- $AD/ { lodsw ;Pick up Offset part
- of the pointer}
- $89/$C2/ { mov dx,ax ; ... and store in dx}
- $AD/ { lodsw ;Pick up Segment part
- of the pointer}
- $8E/$D8/ { mov ds,ax ; ... and store in ds}
- $B4/$3F/ { mov ah,$3F ;DOS Read a
- File/Device function}
- $CD/$21/ { int $21 ;Call DOS}
- $72/$0F/ { jc Error ;Error if Carry Flag
- set}
- $50/ { push ax ;Save # of bytes
- actually read}
- $31/$C0/ { xor ax,ax ;Clear ax to zero}
- $C4/$7E/$06/ { les di,[bp+6] ;Address the file var
- structure}
- $81/$C7/$08/$00/ { add di,8 ;Address the BufPos
- field}
- $AB/ { stosw ;Store 0 in the BufPos
- field}
- $58/ { pop ax ;Retrieve bytes
- actually read}
- $AB/ { stosw ; ... and store in
- BufEnd field}
- $31/$C0/ { xor ax,ax ;Return 0 ==> no
- errors}
- $1F/ {Error: pop ds ;Restore ds value}
- $89/$46/$FE); { mov [bp-2],ax ;Store returned value}
- End {ReadText};
-
- Function WriteText(Var F : TextRec) : Word;
- Begin
- Inline(
- $1E/ { push ds ;Save value of data
- seg register}
- $C5/$76/$06/ { lds si,[bp+6] ;DS:SI points to
- TextRec structure}
- $AD/ { lodsw ;Pick up file handle}
- $89/$C3/ { mov bx,ax ; ... and store in BX}
- $81/$C6/$06/$00/ { add si,6 ;DS:SI points to
- BufPos field}
- $AD/ { lodsw ;Pick up # of bytes to
- write}
- $89/$C1/ { mov cx,ax ; ... and store in CX}
- $46/ { inc si}
- $46/ { inc si ;DS:SI points to
- BufPtr field}
- $AD/ { lodsw ;Pick up offset part
- of buffer addr.}
- $89/$C2/ { mov dx,ax ; ... and store in DX}
- $AD/ { lodsw ;Pick up segment part
- of buffer addr.}
- $8E/$D8/ { mov ds,ax ; ... and store in DS}
- $B4/$40/ { mov ah,$40 ;DOS write file/device
- function}
- $CD/$21/ { int $21 ;Call DOS}
- $72/$0B/ { jc Error ;Error if Carry Flag
- is set on return}
- $31/$C0/ { xor ax,ax ;Clear AX to zero}
- $C4/$7E/$06/ { les di,[bp+6] ;ES:DI points to
- TextRec structure}
- $81/$C7/$08/$00/ { add di,8 ;ES:DI points to
- BufPos field}
- $AB/ { stosw ;Reset BufPos to zero}
- $AB/ { stosw ;Reset BufEnd to zero}
- $1F/ {Error: pop ds ;Restore data seg
- register}
- $89/$46/$FE); { mov [bp-2],ax ;Store function
- result}
- End {WriteText};
-
- Function DoNothing(Var F : TextRec) : Word;
- Begin
- Inline(
- $C7/$46/$FE/$00/$00); { mov word [bp-2],0}
- End {DoNothing};
-
- Function SeekEofText(Var F : TextRec) : Word;
- Begin
- Inline(
- $1E/ { push ds ;Save Data
- Seg register}
- $C4/$7E/$06/ { les di,[bp+6] ;ES:DI
- points to the TextRec}
- $26/$8B/$1D/ { es: mov word bx,[di] ;File
- handle into BX}
- $31/$C9/ { xor cx,cx ;CX:DX =
- Offset for Seek function}
- $89/$CA/ { mov dx,cx ;With AL=2
- and CX:DX=0, will seek eof}
- $B8/$02/$42/ { mov ax,$4202}
- $CD/$21/ { int $21 ;DX:AX
- should now contain filesize}
- $72/$7B/ { jc Error}
- $2D/$80/$00/ { sub ax,128
- ;Reposition to read the last 128 bytes of}
- $81/$DA/$00/$00/ { sbb dx,0 ;the file
- (or as much as we can)}
- $79/$04/ { jns NonNeg ;If less
- than 128 chars in file}
- $31/$C0/ { xor ax,ax ; then
- just read from beginning}
- $89/$C2/ { mov dx,ax}
- $89/$D1/ {NonNeg: mov cx,dx ;Set up
- for Seek function}
- $89/$C2/ { mov dx,ax ;CX:DX =
- Absolute position to seek}
- $26/$89/$55/$20/ { es: mov word [di+32],dx ;Save in
- UserData field for later}
- $26/$89/$4D/$22/ { es: mov word [di+34],cx}
- $26/$8B/$1D/ { es: mov word bx,[di] ;File
- handle in BX}
- $B8/$00/$42/ { mov ax,$4200 ;Dos seek
- (absolute) function}
- $CD/$21/ { int $21}
- $72/$58/ { jc Error}
- $06/ { push es ;Set up
- for call to read by pushing}
- $57/ { push di ;TextRec
- address onto stack}
- $FF/$1E/>READTEXT_ADDR/ { call far [>ReadText_Addr] ;Read the
- file}
- $09/$C0/ { or ax,ax ;Any
- errors?}
- $75/$4E/ { jnz Error}
- $C5/$76/$06/ { lds si,[bp+6] ;Use DS:SI
- as TextRec ptr}
- $8B/$4C/$0A/ { mov word cx,[si+10] ;CX = #
- bytes read}
- $E3/$44/ { jcxz Done ;If 0
- bytes read, then we're done}
- $8B/$44/$0C/ { mov word ax,[si+12] ;BufPtr
- offset}
- $89/$C7/ { mov di,ax ;ES:DI
- will point at the buffer of data}
- $4F/ { dec di ; that
- was just read in}
- $01/$CF/ { add di,cx}
- $8B/$44/$0E/ { mov word ax,[si+14]}
- $8E/$C0/ { mov es,ax}
- $B0/$1A/ { mov al,$1A}
- $FD/ { std}
- $F2/$AE/ { repnz scasb ;Search
- buffer for a ^Z}
- $FC/ { cld}
- $75/$2F/ { jnz Done ;If no ^Z
- found, then we're done}
- $C4/$7E/$06/ { les di,[bp+6] ;Back to
- using ES:DI for TextRec}
- $1F/ { pop ds ;Point DS
- back at global variable segment}
- $1E/ { push ds ;But push
- back for final pop}
- $89/$C8/ { mov ax,cx ;ax=offset
- in buffer at which ^Z was found}
- $26/$8B/$55/$20/ { es: mov word dx,[di+32] ;Retrieve
- saved file ptr pos.}
- $26/$8B/$4D/$22/ { es: mov word cx,[di+34]}
- $01/$C2/ { add dx,ax ;Add in
- offset of ^Z}
- $81/$D1/$00/$00/ { adc cx,0}
- $26/$8B/$1D/ { es: mov word bx,[di] ;file
- handle back in BX}
- $B8/$00/$42/ { mov ax,$4200 ;Again
- with the Seek function}
- $CD/$21/ { int $21
- ;Reposition file pointer to ^Z char}
- $72/$12/ { jc Error}
- $26/$C7/$44/$08/$00/$00/ { es: mov word [si+8],0 ;BufPos=0
- (write 0 bytes to truncate ...}
- $06/ { push es ; ... the
- file at the ^Z)}
- $57/ { push di ;Setup for
- call to write routine}
- $FF/$1E/>WRITETEXT_ADDR/ { call far [>WriteText_Addr]}
- $09/$C0/ { or ax,ax ;Any
- errors}
- $75/$02/ { jnz Error}
- $31/$C0/ {Done: xor ax,ax ;Return 0
- if no errors}
- $1F/ {Error: pop ds}
- $89/$46/$FE); { mov [bp-2],ax}
- End {SeekEofText};
-
- Function CloseText(Var F : TextRec) : Word;
- Begin
- Inline(
- $1E/ { push ds
- ;Must preserve DS for return}
- $C4/$7E/$06/ { les di,[bp+6]
- ;ES:DI is our ptr to the TextRec}
- $26/$8B/$44/$02/ { es: mov ax,[si+2]
- ;Magic Number into AX}
- $3D/>FMOUTPUT/ { cmp word ax,>fmOutput
- ;File opened with Rewrite or Append?}
- $75/$2D/ { jnz SkipEof
- ;No, skip ^Z stuff}
- $80/$3E/>WRITETEXTEOFCHAR/$01/ { cmp byte [>WriteTextEofChar],1
- ;Use ^Z to mark end of file?}
- $75/$26/ { jnz SkipEof
- ;No, skip ^Z stuff}
- $26/$8B/$45/$0C/ { es: mov word ax,[di+12]
- ;Get address of output buffer}
- $26/$8B/$5D/$0E/ { es: mov word bx,[di+14]}
- $89/$C7/ { mov di,ax}
- $8E/$C3/ { mov es,bx
- ;ES:DI points to buffer now}
- $B8/$1A/$00/ { mov ax,$1A}
- $AB/ { stosw
- ;Put a ^Z into the buffer}
- $C4/$7E/$06/ { les di,[bp+6]
- ;Point ES:DI back at the TextRec}
- $26/$C7/$45/$08/$01/$00/ { es: mov word [di+8],1
- ;Set BufPos to show 1 char to write}
- $06/ { push es
- ;Put TextRec Address onto stack}
- $57/ { push di}
- $FF/$1E/>WRITETEXT_ADDR/ { call far [>WriteText_Addr]
- ;Call Write routine to write the ^Z}
- $09/$C0/ { or ax,ax
- ;Any problems with the write?}
- $75/$1D/ { jnz Error
- ;Yes, exit with error code in AX}
- $C4/$7E/$06/ { les di,[bp+6]
- ;ES:DI probably trashed in call}
- {SkipEof:}
- $26/$8B/$1D/ { es: mov bx,[di]
- ;File handle in BX}
- $B8/$00/$3E/ { mov ax,$3E00
- ;Dos Close function}
- $CD/$21/ { int $21
- ;Close the file}
- $72/$10/ { jc Error
- ;If error, exit with code in AX}
- $31/$C0/ { xor ax,ax}
- $26/$89/$45/$08/ { es: mov word [di+8],ax
- ;Stuff zeros in BufPos and BufEnd}
- $26/$89/$45/$0A/ { es: mov word [di+10],ax}
- $26/$C7/$45/$02/>FMCLOSED/ { es: mov word [di+2],>fmClosed
- ;Reset the magic number}
- $1F/ {Error: pop ds}
- $89/$46/$FE); { mov [bp-2],ax
- ;Store function result}
- End {CloseText};
-
- Function OpenText(Var F : TextRec) : Word;
- Begin
- Inline(
- $1E/ { push ds ;Save
- DS register}
- $C4/$7E/$06/ { les di,[bp+6] ;ES:DI
- is pointer to the TextRec structure}
- $B4/$3D/ {Start: mov ah,$3D ;DOS
- open a file/device function}
- $26/$81/$7D/$02/>FMOUTPUT/ { es: cmp word [di+2],>fmOutput ;Open
- for Rewrite?}
- $75/$02/ { jnz OpenIt ;No,
- skip next line}
- $B4/$3C/ { mov ah,$3C ;DOS
- create new/truncate old file}
- $A0/>FILEMODE/ {OpenIt: mov al,[>FileMode] ;Put
- user specified access mode in AL}
- $B9/$00/$00/ { mov cx,0 ;File
- attribute (nothing special) in CX}
- $8C/$C3/ { mov bx,es}
- $8E/$DB/ { mov ds,bx}
- $89/$FA/ { mov dx,di}
- $81/$C2/$30/$00/ { add dx,48 ;DS:DX
- points to asciiz filename}
- $CD/$21/ { int $21 ;Open
- the file}
- $1F/ { pop ds
- ;Restore DS to segment with global vars}
- $1E/ { push ds ; ...
- and save back on stack for later}
- $73/$15/ { jnc OpenOk ;If no
- errors, continue}
- $3D/$02/$00/ { cmp ax,2 ;File
- not found?}
- $75/$69/ { jnz Error ;No,
- exit with error code in ax}
- $26/$81/$7D/$02/>FMINOUT/ { es: cmp word [di+2],>fmInOut ;Opened
- for Append?}
- $75/$61/ { jnz Error ;No,
- exit with error code in ax}
- $26/$C7/$45/$02/>FMOUTPUT/ { es: mov word [di+2],>fmOutput ;No
- existing file to append ...}
- $EB/$C9/ { jmp short Start ; ...
- so try again with Rewrite}
- $AB/ {OpenOk: stosw ;Store
- file handle (in AX) into TextRec}
- $BE/>CLOSETEXT_ADDR/ { mov si,>CloseText_Addr ;DS:SI
- points at addr. of CloseText fn.}
- $81/$C7/$1A/$00/ { add di,26 ;ES:DI
- points to CloseFunc field}
- $B9/$02/$00/ { mov cx,2 ;Double
- word address to move}
- $F2/$A5/ { rep movsw ;Store
- address into CloseFunc field}
- $C4/$7E/$06/ { les di,[bp+6] ;ES:DI
- back to pointing at TextRec}
- $26/$81/$7D/$02/>FMINOUT/ { es: cmp word [di+2],>fmInOut ;Opened
- with Append?}
- $75/$13/ { jnz NoSeek ;No,
- skip the search for ^Z}
- $06/ { push es ;Set up
- stack for call to SeekEofText}
- $57/ { push di ;Addr
- of TextRec goes on the stack}
- $FF/$1E/>SEEKTEXT_ADDR/ { call far [>SeekText_Addr] ;Get
- rid of any ^Z at end of file}
- $09/$C0/ { or ax,ax ;Any
- errors?}
- $75/$37/ { jnz Error ;Yes,
- exit with error code in AX}
- $C4/$7E/$06/ { les di,[bp+6]
- ;Restore ptr to TextRec trashed in call}
- $26/$C7/$45/$02/>FMOUTPUT/ { es: mov word [di+2],>fmOutput ;Reset
- TextRec mode to show output only}
- {NoSeek:}
- $26/$C7/$45/$08/$00/$00/ { es: mov word [di+8],0 ;Set
- BufPos to 0}
- $26/$C7/$45/$0A/$00/$00/ { es: mov word [di+10],0 ;Set
- BufEnd to 0}
- $26/$81/$7D/$02/>FMINPUT/ { es: cmp word [di+2],>fmInput ;Opened
- with reset?}
- $74/$05/ { jz InFunc ;Yes,
- set pointers accordingly}
- $BE/>WRITETEXT_ADDR/ { mov si,>WriteText_Addr ;DS:SI
- --> Address of WriteText func.}
- $EB/$03/ { jmp short SetFunc ;Go set
- TextRec function pointers}
- $BE/>READTEXT_ADDR/ {InFunc: mov si,>ReadText_Addr ;DS:SI
- --> Address of ReadText func.}
- $81/$C7/$14/$00/ {SetFunc: add di,20 ;ES:DI
- --> InOutFunc field}
- $B9/$02/$00/ { mov cx,2 ;Moving
- a double word}
- $51/ { push cx ;Save
- this count for later}
- $F2/$A5/ { rep movsw ;Store
- address of I/O routine}
- $BE/>DONOTHING_ADDR/ { mov si,>DoNothing_Addr ;DS:SI
- --> Address of DoNothing func.}
- $59/ { pop cx ;ES:DI
- --> FlushFunc field - move 2 words}
- $F2/$A5/ { rep movsw ;Store
- address of flush routine}
- $31/$C0/ { xor ax,ax ;No
- errors, return a 0 to caller}
- $1F/ {Error: pop ds
- ;Restore DS register}
- $89/$46/$FE); { mov [bp-2],ax ;Store
- function result}
- End {OpenText};
-
- Procedure AssignText(Var F : Text; FileName : String);
- Var
- I : Integer;
- Begin
- With TextRec(F) do begin { Initialize textrec record }
- Handle := $FFFF; { Set file handle to junk }
- Mode := fmClosed; { Indicate the file is not yet open }
- BufSize := SizeOf(Buffer); { Set size of default buffer (128) }
- BufPtr := @Buffer; { Set up pointer to default buffer }
- OpenFunc := @OpenText; { Set up pointer to OPEN function }
- For I := 1 to Length(FileName) do { Set up asciiz filename }
- Name[I-1] := FileName[I];
- Name[Length(FileName)] := Chr(0);
- End {with};
- End {AssignText};
-
- Begin
- { Initialize global variable to suppress writing ^Z at the end of any }
- { text file opened with Append or Rewrite. }
- WriteTextEofChar := FALSE;
-
- { Initialize internally used Address variables (pointers) }
- ReadText_Addr := Addr(ReadText);
- WriteText_Addr := Addr(WriteText);
- SeekText_Addr := Addr(SeekEofText);
- DoNothing_Addr := Addr(DoNothing);
- CloseText_Addr := Addr(CloseText);
- End {Unit TxtShare}.
-
- {$F-}
-
- {end}