home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
database
/
pcfpl3_3.zip
/
TECHINFO
< prev
Wrap
Text File
|
1989-07-18
|
11KB
|
287 lines
TECHINFO - Technical information on the file formats used by PC-File+ 3.0
This information is provided for programmers who wish to use PC-File+
databases with their own programs--BASIC, Turbo Pascal, "C" or other
languages.
PC-File+ makes an excellent "Front End" program for other systems
which you might develop. You can use PC-File+ to handle the file
maintenance functions, and concentrate your efforts on the rest of the
system.
File Formats
The file "filename.DTA" (where "filename" is the name you gave the
database), is the main data file. Each field of the record is stored
in a fixed length format (the length that you defined for it) and
padded on the right if necessary with blanks. The fields appear in
the record in the same order that they are accessed in PC-File+.
Deleted records which have not been re-used have a slash "/" in the
first position of the record. A carriage return character (HEX 0D)
marks the end of each record. A special record containing a backslash
"\" as its first character is stored at the end of the database to
mark the end of the file. All records in the file are the same
length.
Records are usually stored in the same sequence in which they were
originally entered. New records will be added to the end of the file
unless there are deleted records. If there are deleted records,
PC-File+ will write the new record in place of a deleted one. The
sort command does not resequence the data portion of the database; it
only affects the index.
The file "filename.INX" is the index file for your database. There is
one index record for each data record, including deleted records.
Each index record is composed of the first two bytes from every data
field, followed by a two-byte (binary format) pointer to the relative
record number of the record in filename.DTA.
There is also a "filename.HDR" file for each database. This is a
standard ASCII file. The first line is similar to this:
PCF+3;00123,Sample database
The first part of this line identifies this file as a PC-File+ 3.0
file. The next available unique number appears after the semicolon.
The database description, which may be blank, appears after the comma.
After the database description line, there are two lines for each
field in the database. The first line is the field name followed by
its optional mask, constant and/or calculation. The field name always
takes up the first 12 bytes. The mask, constant and/or calculation
can start at any point thereafter.
The second line contains the field length, starting row, starting
column, and window size of the field. These are stored in ASCII
character format, and are separated by commas. An example:
ZIP_CODE :09--:
10,9,12,10
This entry is for a field named ZIP_CODE which has a mask of :09--:
Its field length is 10, screen row is 9, screen column is 12, and
window display size is 10. Since the field length and window size are
the same, this field is not a "window field".
There is one more part of the header file. It's a "picture" of the
data entry screen. This portion was not always created by earlier
versions of PC-File+, but is always created by PC-File+ 3.0. Each
line in the picture starts with the "|" character. This section is
quite long -- up to 1680 bytes in length.
Sample Programs
Here are sample BASIC and C programs to show you how to process the
Index and Data records in your PC-File+ 3.0 database. Note that
these are very limited programs; we are providing them only as
working demonstrations of how to access PC-File+ database files.
Please note: Due to limitations in BASICA and GWBASIC, this BASIC
program is NOT able to process databases containing more than
32,767 records.
______________________________________________________________________
10 '+-----------------------------------------------------+
20 ': PC-File+ Sample BASIC program. :
40 '+-----------------------------------------------------+
60 '* This program reads a database (named "SAMPLE")
70 '* in sequence by the Index.
80 '* For each record read, a line is printed.
100 '*
110 '* The sample database was defined as follows:
120 '* NAM 20
140 '* CITY 12
150 '* STATE 2
160 '* ZIP 5
180 '* = (39) total lngth of all fields
200 '* The lngth of an index record in this database:
210 '* 2 * (number of fields) + 2. 2 * 4 + 2 = 10.
240 '* The lngth of a data record in this database:
250 '* (Lngth of data fields) + 1. 39 + 1 = 40
320 '
360 INX.LEN = 10 'this length was calculated above
370 DTA.LEN = 40 'this length was calculated above
380 '
390 '.......... OPEN FILES FOR PROCESSING ..................
410 OPEN "SAMPLE.INX" AS #1 LEN=INX.LEN
420 FIELD#1,2 AS NM$,2 AS CI$,2 AS ST$,2 AS ZI$,2 AS PT.DTA$
430 ' Each of the above fields contains the 1st 2 bytes of
440 ' the corresponding field in the data file.
450 ' The last 2 bytes of the above index rcrd are a binary
460 ' pointer to the relative rcrd no. in the data file.
480 OPEN "SAMPLE.DTA" AS #2 LEN=DTA.LEN
490 FIELD #2, 20 AS NAM$, 12 AS CITY$, 2 AS STATE$,5 AS ZIP$
500 '
510 '.....FOR EACH INX RCRD, GET CORRESPONDING DTA RCRD.....
530 GET #1 'Get nxt INX rcd.
540 IF LEFT$(NM$,1) = "/" THEN 530 'Bypass deleted rcrd.
550 IF LEFT$(NM$,1) = "\" THEN 600 'End of file. " "
560 POINTER = CVI(PT.DTA$) 'Get ptr into DTA file.
570 GET #2,POINTER 'Random get DTA record.
580 LPRINT NAM$;" ";CITY$;" ";STATE$;" ";ZIP$
590 GOTO 530 'Loop until end file.
600 '
610 '..... PROCESSING IS COMPLETE. SHUT DOWN .............
630 CLOSE 'Close all files
640 END 'Leave the program
______________________________________________________________________
/* Sample C program
This program was compiled with Microsoft C 5.1. Note that you
may have to change the #include statements for other compilers.
This program reads a PC-File+ 3.0 database (named "SAMPLE")
in sequence by the index. For each record read, a line
is printed on the printer.
The SAMPLE database is defined as follows:
Name 20
City 12
State 2
Zip 5
= [39] total length of data fields
The length of an index record in this database is:
2 * (number of fields) + 2 --> 2 * 4 + 2 = 10
The length of a data record in this database is:
Length of the data fields + 1 --> 39 + 1 = 40
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <io.h>
#include <fcntl.h>
#define namelen 20
#define citylen 12
#define statelen 2
#define ziplen 5
#define numflds 4
#define inxlen numflds * 2 + 2
#define dtalen 1 + namelen + citylen + statelen + ziplen
static int dtafile; /* data file handle */
static int inxfile; /* index file handle */
static int fldlen[numflds]; /* array for field lengths */
struct db { /* structure for the sample database */
char name[namelen];
char city[citylen]; /* This structure will need to be */
char state[statelen]; /* modified for different databases */
char zip[ziplen];
} sample;
union {
char dtastring[dtalen]; /* Length of dtastring will need to */
struct db sample; /* be changed for different databases */
} rcd;
main()
{
register unsigned datarecno;
char inxstring[inxlen+1];
initialize();
inxfile = open("SAMPLE.INX",O_RDWR|O_BINARY);
dtafile = open("SAMPLE.DTA",O_RDWR|O_BINARY);
for ( ; ; ) {
read(inxfile,inxstring,inxlen); /* read an index record */
if (inxstring[0] == '\\') /* end of file */
break; /* stop processing */
if (inxstring[0] == '/') /* deleted record */
continue; /* skip deleted record */
datarecno = inxptr(inxstring); /* resolve index pointer */
getrcd(datarecno); /* retrieve data */
printrcd(); /* print data */
}
close(inxfile);
close(dtafile);
}
/*.................. initialize ..............*/
static initialize()
{
fldlen[0] = namelen;
fldlen[1] = citylen;
fldlen[2] = statelen;
fldlen[3] = ziplen;
}
/*.................. inxptr ..............*/
static inxptr(string)
char *string;
{
union {
unsigned binx;
char charx[2];
} inx;
/* The last two characters of an index record are a binary
pointer to the data record in the DTA file. This routine
will determine the binary pointer given the index string,
and will return the pointer to the data record. */
inx.charx[0] = string[inxlen - 2];
inx.charx[1] = string[inxlen - 1];
return(--inx.binx);
}
/*.................. getrcd ...............*/
static getrcd(recno)
unsigned int recno;
{
register long offset;
register int x;
x = dtalen;
offset = (long)recno * (long)x;
lseek(dtafile,offset,0); /* seek the record */
read(dtafile,rcd.dtastring,dtalen-1); /* read the record */
}
/*.................. printrcd ................*/
static printrcd()
{
register int len;
char scratch[dtalen+numflds+3];
len = build_output(scratch);
write(4,scratch,len); /* printer handle == 4 */
}
/*.................. build_output ............*/
static build_output(string)
char *string;
{
register int x;
register int y;
int z;
/* This routine will move the data for one field into the string
variable, add a space, move the data for the next field into
the string variable, add a space, etc. After all fields have
been moved into the string variable, carriage return and
line-feed characters will be appended to the end of the string. */
x = y = z = 0;
for (x = 0; x < numflds; x++) { /* loop for number of fields */
for (y = 0; y < fldlen[x]; y++,z++) /* loop for field length */
string[z] = rcd.dtastring[z - x]; /* move data */
string[z++] = ' '; /* add a space after the field */
}
string[z++] = '\r'; /* append carriage return */
string[z++] = '\n'; /* append line feed */
return(z); /* return length of string */
}
______________________________________________________________________