DEFINITION MODULE dBASE;


(*


     Written by Dexter (Chip) Orange  July, 1987.


     Copyright by Dexter (Chip) Orange 1987, 1989.
All rights reserved.



     This module is designed to work in conjunction with the RandomIO module
of the TurboFile system to give you easy access to dBASE formatted
databases.
     Note that since the dBASE format came from an 8088 environment, it
stores its binary  numbers in a reversed way from the 68000, and thus the
need for the "Backward" conversion procedures below.

                   Version 1.0  October, 1989.
Converted from TDI to M2Sprint.


*)

FROM SYSTEM IMPORT
  BYTE;
FROM RandomIO IMPORT
  RandomFile, RandomFileMode;


CONST

(* the MemoFileIndicator field should be equal to one of these values *)
  NoMemoFile = 3;
  YesMemoFile = 131;


  MaxFields = 128;

TYPE
  BackwardCard = ARRAY [1..2] OF BYTE;
  BackwardLongCard = ARRAY [1..4] OF BYTE;


  DataBaseInfoRec = RECORD
    MemoFileIndicator: BYTE;

(* the last modified date  *)
    Y: BYTE;
    M: BYTE;
    D: BYTE;
    RecordCount: BackwardLongCard;
    FileHeaderSize: BackwardCard;
    RecordLength: BackwardCard;
(* includes an extra byte for a "deleted" indicator *)
    Reserved: ARRAY [1..20] OF BYTE;
  END;

  FieldDescriptorRec = RECORD
    FieldName: ARRAY [1..10] OF CHAR;
    Pad: BYTE;                          (* SHOULD ALWAYS BE SET TO ZERO *)
    FieldType: CHAR;
(* Valid values are "L" for logical, "N" for numeric, "C" for character, "D"
for date, or "M" for memo. *)
    Reserved: ARRAY [1..4] OF BYTE;
    FieldLength: BYTE;
    FieldDecimals: BYTE;
    Reserved2: ARRAY [1..14] OF BYTE;
  END;

(* THE FOLLOWING DESCRIPTION OF A DBASE HEADER IS NOT COMPLETELY ACCURATE
SINCE THE NUMBER OF FIELDESCRIPTOR RECORDS IS VARIABLE *)
  dBASEHeaderRec = RECORD
    Info: DataBaseInfoRec;
    FieldList: ARRAY [1..MaxFields] OF FieldDescriptorRec;
    EndOfHeader: BYTE;                  (* SHOULD ALWAYS BE SET TO 13 *)
  END;

(* format of dBASE "date" fields *)
  YYYYMMDD = RECORD
    YYYY: ARRAY [1..4] OF CHAR;
    MM: ARRAY [1..2] OF CHAR;
    DD: ARRAY [1..2] OF CHAR;
  END;


PROCEDURE Card(BC: BackwardCard): CARDINAL;
(* TRanSLATE A BACKWARD (LEAST SIGNIFICANT BYTE FIRST) CARDINAL INTO A CARDINAL
 *)

PROCEDURE LCard(BLC: BackwardLongCard): LONGCARD;
(* TRanSLATE A BACKWARD LONGCARD INTO A LONGCARD *)


TYPE
  DataRecordPtr = POINTER TO ARRAY [0..32766] OF CHAR;


VAR
  dBASEErrorMessage : ARRAY [0..80] OF CHAR;
(* contains the text of an error message if an error occurs *)




PROCEDURE Use(FileName: ARRAY OF CHAR; VAR Hdr: dBASEHeaderRec; VAR F:
RandomFile; Mode: RandomFileMode; VAR NumFields: CARDINAL; VAR RecLength:
CARDINAL; BufferSize: LONGCARD; VAR DRPtr: DataRecordPtr) : BOOLEAN;
(*
     Attempt to open the file specified by FileName with the RandomIO
module, and then read in a dBASE header record into dBASEHeaderRec.  If the
header is read successfully, the parameters of the Random file are reset to
reflect the complete header size, and to set the record length properly.
You may then use RandomIO routines to read/write records in the database.
IF DRPtr is NIL, a record buffer of the appropriate size will automatically
be allocated for  you and DRPtr will point to it.  Remember that element 0
of this buffer will always be the byte which indicates whether the record is
deleted ("*") or not (" ").
     If a random file mode of NewFile or NewFileWriteOnly is specified,
instead of reading the header information, this routine will create the
specified file and write out the information contained in dBASEHeaderRec as
an empty dBASE file.
     This routine will automatically use a file extension of '.dbf' if one
is not specified in the file name.

*)


END dBASE.
