The Phone Losers Of England Presents: Last Updated 6th of January 2001
Back To Information Archive
PSIONICS FILE - DBF.FMT
=======================
Format and use of Data files
Last modified 1998-08-03
========================

File format
-----------

A data file (also called a DBF file) begins with a 22 byte header of the
following form:
  Offset  0 to  15: file signature
  Offset 16 (word): DBF software version number used to create the file
  Offset 18 (word): size of header in bytes (N)
  Offset 20 (word): earliest DBF software version number that can use the file
  Offset 22 to N-1: extended header

The signature is used to verify that the file is applicable to the application
using it. The version numbers are used to verify that the format is compatible;
only the top 4 bits are tested.

Files created using the Data or Agenda (Series 3t) applications or the CREATE
keyword have a signature which is the cstr "OPLDatabaseFile". Series 3c Jotter
files are also DBF files.

The rest of the file consists of records. All records have the form:
  Offset  0 (word):
    Bits  0 to 11: size of data portion (L)
    Bits 12 to 15: record type
       0 = deleted record (should be ignored)
       1 = mergable data record
       2 = field information record
       3 = descriptive record
       4 = private data record
       5 = private data record
       6 = private data record
       7 = private data record
       8 = mergable data record
       9 = mergable data record
      10 = mergable data record
      11 = mergable data record
      12 = mergable data record
      13 = mergable data record
      14 = mergable voice data record
      15 = reserved for system use
  Offset  2 to L+1: data portion

There may be at most 65534 records, and the data portion of each is limited
to 4094 bytes (so the total record length is limited to 4096 bytes).

When a file is merged into another one, mergable data records will be copied,
but not private data records, the field information record, or the descriptive
record.

Data files are based around fields. fields may be words, longs, reals, or
qstrs (limited to 254 characters). Fields after the first 32 are less usable;
for example, they must be qstrs, and cannot be accessed through OPL data file
keywords.

The first record in the file must be a field information record, and all other
field information records in the file will be ignored. Each byte of the record
specifies the type of the corresponding field:
    0 = word
    1 = long
    2 = real
    3 = qstr
The field information record must define between 1 and 32 fields; if it defines
exactly 32, then fields 33 onwards are all qstrs, as noted above.

Data records are broken into fields by the DBF software according to the field
information record; there are no separators between the fields of a record.
Trailing fields that are empty qstrs or zero numbers may be omitted from a
record.

The Data application uses the following special character codes within qstr
fields:
   5 = diallable telephone number follows
  20 = (if first character of field) treat this field as joined on to the
       previous one, which must also be a qstr
  21 = forced line feed

There should only be one descriptive record in a file, but it can occur
anywhere in the file. The descriptive record consists of one or more subrecords
with the same format (length, type, data) as normal records. In general,
unknown types of subrecord should be copied unchanged, as other applications
may be using them.

The Data application uses the following types of subrecord. Types 2 and 3 are
used on the MC and are not described. Types 6 to 11 are not used on the
Series 3t version of Data, and types 12 to 14 are only used on the Series 3c
and Siena.

* Subrecord type 1
This contains 2 bytes:
  Offset  0 (word): tab size

* Subrecord type 4
This contains the field labels as qstrs, in order. Trailing blank labels may,
but need not, be omitted.

* Subrecord type 5
This contains 2 bytes:
  Offset  0 (byte):
    Bit 0:        status window visible (Series 3t)
    Bit 1:        wrap on
    Bit 2:        labels visible
    Bits 3 and 4: status window (Series 3a): 0=none, 1=narrow, 2=full
    Bits 4 and 5: zoom level (3, 0, 1, 2 from smallest to largest, 0 default)
  Offset  1 (byte): unused

* Subrecord type 6
This holds information about printer set-up and is identical to record type 2
in Word files (see WORD.FMT).

* Subrecord type 7
This is used to store the printer driver. It is identical to record type 3 in
Word files:
  Offset  0 (byte): printer driver model number
  Offset  1 (cstr): printer driver library
A printer driver library can support several similar printers; the model number
specifies which is selected.

* Subrecord type 8
This holds the header text as a cstr.

* Subrecord type 9
This holds the footer text as a cstr.

* Subrecord type 10
This contains 3 bytes and holds diamond settings:
  Offset  0 (byte): 0=omit Find,   255=include Find
  Offset  1 (byte): 0=omit Change, 255=include Change
  Offset  2 (byte): 0=omit Add,    255=include Add

* Subrecord type 11
This contains 4 bytes and holds the current search status:
  Offset  0 (word): start field (0 means all fields, 1 means first field, etc.)
  Offset  2 (word): end field (255 means all from start field)

* Subrecord type 12
This contains information concerning List view. The first 6 bytes are:
  Offset  0 (word): number of locked columns
  Offset  2 (byte): zoom level
  Offset  3 (byte): status window size
  Offset  4 (word): 0=no grid lines, 2=grid lines
This is followed by words giving the width in pixels of the columns in order.

* Subrecord type 13
This contains 4 bytes and holds diamond settings (overriding those in any
subrecord type 10):
  Offset  0 (byte): 0=omit Find,   255=include Find
  Offset  1 (byte): 0=omit Change, 255=include Change
  Offset  2 (byte): 0=omit Add,    255=include Add
  Offset  3 (byte): 0=omit List,   255=include List

* Subrecord type 14
This contains 16 bytes and holds the sort settings:
  Offset  0 (word): number of sort keys (1 to 3)
  Offset  2 (word): field number of sort key 1
  Offset  4 (word): field number of sort key 2
  Offset  6 (word): field number of sort key 3
  Offset  8 (word):
    Bit @: set if sort is case sensitive, clear if case insensitive
    Bit @: set if sort key 1 is descending, clear if ascending
  Offset 10 (word): 0 = sort key 2 is ascending, @ = descending
  Offset 12 (word): 0 = sort key 3 is ascending, @ = descending
  Offset 14 (byte): size of sort key to be stored (@@@?)
  Offset 15 (byte): sort file on opening (0 = no, 1 = ask, 2 = yes)

* Subrecord type 15
This is used by the Series 3t Agenda. See AGENDA.FMT for more details.


Kernel services
---------------

See the file SYSCALLS.1 for the general notation used. In every case, the
Fn value is $D8.

Most calls require use of a working buffer. This buffer can be between 512 and
16384 bytes long, but must be at least as long as the longest record in the
relevant file (including the header), so a buffer of 4096 bytes is always
sufficient. In general, file access will be faster with a larger buffer.
Except where stated, the contents of the buffer may changed by any call on that
DBF, and must not be altered by the application.

A file may be opened in indexed or unindexed mode. Unindexed mode is faster to
open, but certain calls (those marked "indexed") can only be made if the file
was opened in indexed mode. It is not possible to change the mode once the
file has been opened. It is only possible to access one type of record via a
given file handle (though, if a read-only-sharing mode is used, more than one
handle can be open to the same file); to change the type, it is necessary to
close and reopen the file.

Record numbers are those of the selected record type (starting at 0), ignoring
all other types. If a file holds more than 65534 records of a given type, those
beyond that number are ignored unless stated otherwise.

Calls that read a record always read it into the working buffer. The call will
always return two values: the record length and the record "offset". The
length is that of the data portion. The offset is the offset, in the working
buffer, where a copy of the record can be found. This copy includes the size
and type word, so the data starts two bytes later. This mechanism allows data
to be read into the buffer ahead of time, improving efficiency.


Sub $00
DbfOpen fails
    BX: address of control block
    CX: record type to access (1, or 4 to 14)
    DX: size of the working buffer
    SI: address of the working buffer
    DI: open flag -> new flag
Opens a DBF file. The open flag may be one of the following:
  -2 = open in unindexed mode; when the call returns, the file is open
  -1 = open in indexed mode; when the call returns, the file is open
   0 = open in indexed mode; when the call returns, the file is not yet open.
       The call should then be repeated until 0 is returned in DI.
       Alternatively, the file may be closed before it is completely open.
       The total number of calls required to open the file is approximately
       the file size divided by the working buffer size.
When the file is completely open, the current record is set to record 0.

The control block has the following format:
  Offset  0 (word): address of a word into which the DBF handle will be written
  Offset  2 (word): (cstr) file name
  Offset  4 (word): file open mode
  Offset  6 (word): address of header block
The meaning of the file open mode is as for IOOPEN (see Psionics file FILEIO),
except that the format component is ignored. The header block consists of a 56
byte block as follows:
  Offset  0 to  15: file signature
  Offset 16 (word): DBF software version number used to create the file
  Offset 18 (word): size of file header in bytes
  Offset 20 (word): earliest DBF software version number that can use the file
  Offset 22 (word): header of the field information record ($2000 plus the
                    number of fields, or $2020 if more than 32 fields)
  Offset 24 to  55: body of the field information record

If the file is being created or replaced, the entire block will be written to
the file (with a gap before the field information record if offset 18 is
greater than 22, and truncated to the length of the field information record).
The top 4 bits of offset 20 must be consistent with the current DBF software
version number (see DbfVersion).

If an existing file is being opened, the file signature (all 16 bytes) must be
identical to that in the file, and the top 4 bits of the software version
number at offset 20 of the file must be consistent with the current DBF
software. If both are true, the file header and field information record are
copied into the header block. Otherwise the open fails.


Sub $01
DbfClose fails
    BX: DBF handle
The DBF file is closed.


Sub $02
DbfFlush fails
    BX: DBF handle
All buffers associated with the DBF file are flushed.


Sub $03
DbfTrash
    BX: DBF handle
Instructs the kernel that the working buffer contents are about to be altered,
and so will not be valid at the point of the next call on this DBF. The
application can then use the buffer for other purposes (e.g. to construct the
record to be written by DbfAppend).


Sub $04
DbfCopyDown
    AX: -> length of record
    BX: DBF handle
    SI: record offset returned by another DBF call
The record at the given offset is copied to the start of the working buffer,
and instructs the kernel that the working buffer must not be used.


Sub $05
DbfCompress fails indexed
    BX: DBF handle
    DI: compress flag -> new flag
Compresses the DBF file if on a compressible device. The flag may be:
  -1 = when the call returns, the file is compressed
   0 = when the call returns, the file is not yet compressed. The call should
       then be repeated until 0 is returned in DI. The total number of calls
       required is approximately the file size divided by the working buffer
       size.
When the file is compressed, the current record will be the end of file.


Sub $06
DbfCopyFile fails
    BX: DBF handle
    CX: record type to copy (15=all types), plus 256 if copying in, not out
    DX: open mode for target file (see DbfOpen for details)
    SI: (cstr) target file name
    DI: copy flag -> new flag
Copies all records of the indicated type from the DBF file indicated by the
handle to the target file (if 256 was added to CX, then copies from the target
file to the open file).

If the target file is created or replaced, the original file's header and field
information record are copied to the target file. If an existing file is
opened (including when copying in), the signatures must be the same and the
field information records must be compatible. Opening for append only is the
same as opening for update.

If type 15 is selected, then:
* if copying to an existing file or copying in, only mergable data records
  (record types 1 and 8 to 14) are copied;
* if copying to a new or replaced file, all records (types 1 to 14) are copied.

The copy flag may be:
  -1 = when the call returns, the copy is complete.
   0 = when the call returns, the copy is not yet complete. The call should
       then be repeated until 0 is returned in DI. Alternatively, DI may be
       set to -2, which will abandon the copy. The total number of calls
       required is approximately the file size divided by the working buffer
       size.


Sub $07
DbfFileSize fails
    BX: DBF handle
    DX: low half of file size
    DI: high half of file size
Returns the size of the file, in bytes.


Sub $08
DbfExtHeaderRead fails
    AX: 0=start at beginning, 1=continue -> number of bytes read
    BX: DBF handle
    CX: number of bytes to read
    SI: address of buffer
The indicated number of bytes are read from the extended header of the file
into the buffer; the call fails when the header is exhausted. If AX is 0, the
first byte read is from offset 22. If AX is 1, it is that following the last
byte read by the previous call.


Sub $09
DbfExtHeaderWrite fails
    AX: 0=start at beginning, 1=continue -> number of bytes written
    BX: DBF handle
    CX: number of bytes in buffer
    SI: address of buffer
The indicated number of bytes are written from the buffer to the extended
header of the file. If AX is 0, the first byte is written to offset 22. If AX
is 1, it is written immediately following the last byte written by the previous
call. The call fails if offset 18 of the file is 22, or if the previous call
(when AX is 1) filled the space indicated by offset 18.


Sub $0A
DbfVersion
    AX: -> version number
Returns the version of the DBF software. The top 4 bits indicate the major
version number, which is used to determine compatibility of files.


Sub $0B
DbfAbsReadSense fails
Sub $0C
DbfAbsRead fails
    AX: -> record length
    BX: DBF handle
    CX: record number
    DX: -> low  half of record position within file
    SI: -> record offset
    DI: -> high half of record position within file
Reads the specified record into the working buffer. If the record number is
too large, the call fails and the current record is set to the end of file.
Otherwise the current record is set to the record read. DX and DI are only set
by DbfAbsReadSense, and are unaltered by DbfAbsRead.


Sub $0D
DbfNextRead fails
Sub $0E
DbfBackRead fails
Sub $0F
DbfFirstRead fails
Sub $10
DbfLastRead fails indexed
    AX: -> record length
    BX: DBF handle
    SI: -> record offset
Reads the next, previous, first, or last record. If the record does not exist,
the call fails and the current record is set to end of file; if DbfBackRead is
called when the current record is record 0, the call fails and the current
record remains record 0. Otherwise the current record is set to the record
just read.


Sub $11
DbfAppend fails indexed
    BX: DBF handle
    CX: record length
A record built from the data starting at offset 2 of the working buffer is
appended to the file.


Sub $12
DbfEraseRead fails indexed
    AX: -> record length
    BX: DBF handle
    SI: -> record offset
    DI: erase flag -> new flag
The current record is deleted, and the following record is read. The call will
fail if either the record deleted was the last one (though the record will have
been deleted) or if the current record was end of file (in which case nothing
is deleted). The erase flag may be:
  -1 = when the call returns, the operation is complete.
   0 = when the call returns, the operation is not yet complete. The call
       should then be repeated until 0 is returned in DI.


Sub $13
DbfUpdate fails indexed
    BX: DBF handle
    CX: record length
    DI: update flag -> new flag
A record built from the data starting at offset 2 of the working buffer is
appended to the file, after which the current record is deleted. When this has
been done, the current record is set to the newly written record. If there is
no record to delete, the call will fail without writing anything. If the record
deleted is the last one in the file, the write and delete will work, but the
call will still appear to fail.

The update flag may be:
  -1 = when the call returns, the operation is complete.
   0 = when the call returns, the operation is not yet complete. The call
       should then be repeated until 0 is returned in DI.


Sub $14
DbfFindRead fails indexed in some cases
    AX: number of fields to search -> record length
    BX: DBF handle
    CX: length of pattern
    DX: control flags
    SI: address of the pattern -> record offset
    DI: match flag -> new flag
Searches the file for a record containing a field matching the pattern (which
can contain wildcards). If a match is found, the corresponding record is read;
otherwise the call fails. Only the number of string fields indicated are
examined (non-string fields are ignored), or all string fields if AX is -1.
The control flags are as follows:
    Bits  0 to  7: maximum number of characters in the field to examine (255
                   means the entire field)
    Bits  8 to 11:
        0 = backwards starting at current record [not indexed]
        1 = forwards  starting at current record [not indexed]
        2 = backwards starting at end of file    [indexed]
        3 = forwards  starting at record 0       [not indexed]
    Bits 12 to 15:
        0 = case independent
        1 = case dependent
The match flag may be:
  -1 = when the call returns, the search is complete.
   0 = when the call returns, the search is not yet complete. The call should
       then be repeated until 0 is returned in DI. The total number of calls
       required is approximately the file size divided by the working buffer
       size.


Sub $15
DbfSense
    AX: -> record number
    BX: DBF handle
Returns the current record number (the number if records if the current record
is the end of file).


Sub $16
DbfCount indexed
    AX: -> number of records
    BX: DBF handle
Returns the number of records (of the appropriate type) in the file. The
current record is unaltered.


Sub $17
DbfDescRecordRead fails indexed
    AX: -> length of the descriptive record data
    BX: DBF handle
Reads the descriptive record into the start of the working buffer.


Sub $18
DbfDescRecordWrite fails indexed
    BX: DBF handle
    CX: length of descriptive record data (0 = delete descriptive record)
Replaces the descriptive record with that in the working buffer. The record
data should start at offset 2 (the word at offset 0 will be altered).


Sub $19
DbfFindReadField v3 fails indexed in some cases
    AX: number of fields to search -> record length
    BX: DBF handle
    CX: length of pattern
    DX: control flags
    SI: address of the pattern -> record offset
    DI: match flag -> new flag
This call is identical to DbfFindRead, except that it skips N string fields in
each record before examining the next AX string fields. The value of N is taken
from offset 14 of the data segment of the current process. For example, to
examine only the fourth and fifth string fields, set N to 3 and AX to 2.

Warning: this location is used by many OPL keywords (particularly those for
dialogs and menus). It should be saved and restored around the call to this
function.
This Site Is © Copyright Project Atlantis, 2000-2001