home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1988
/
05
/
porter
/
nonpas.pas
< prev
Wrap
Pascal/Delphi Source File
|
1988-04-04
|
5KB
|
155 lines
PROGRAM nonpas;
{ Reads a non-Pascal database table with a header record }
{ and some number of fixed-length data records }
CONST signature = 19364; { application signature }
divider = '---------------------------------------------------';
TYPE s20 = STRING [20];
pac = PACKED ARRAY [1..20] OF CHAR;
headrec = RECORD CASE tag : INTEGER OF
1: (signature : WORD; { This is the real layout }
nrecs : WORD; { # data records }
placeholdr : PACKED ARRAY [1..10] OF CHAR; { table name }
reclen : INTEGER; { data record length }
datastart : LONGINT; { file offset for data }
descrsize : INTEGER; { field descriptor size }
ndescr : INTEGER); { number of fields per rec }
2: (dummy1,
dummy2 : WORD;
tablename : pac); { To fool typechecking }
3: (stream : PACKED ARRAY [1..24] OF BYTE);
END;
fieldrec = RECORD CASE tag : INTEGER OF
1: (fname : pac;
ftype : INTEGER;
flen : INTEGER);
2: (stream : PACKED ARRAY [1..24] OF BYTE);
END;
VAR header : headrec;
field : ARRAY [1..10] OF fieldrec; { descriptors }
n : INTEGER;
table : FILE OF BYTE;
{ --------------------------- }
FUNCTION asciiz (max : INTEGER; VAR strng : pac) : s20;
{ Returns a Pascal string from a null-terminated string
that is <= max bytes long }
VAR i : INTEGER;
result : STRING [20];
BEGIN
result := '';
FOR i := 1 TO max DO
IF strng [i] <> CHR (0) THEN
result := result + strng [i];
asciiz := result;
END;
{ --------------------------- }
PROCEDURE getDescriptors;
{ Reads field descriptors from header record }
VAR c, d : INTEGER;
BEGIN
FOR d := 1 to header.ndescr DO
FOR c := 1 TO header.descrsize DO
READ (table, field [d].stream [c]);
END;
{ --------------------------- }
PROCEDURE showHeaderInfo;
{ List information about the file format }
VAR d : INTEGER;
BEGIN
WRITELN (divider);
WRITELN ('Table name is ',
asciiz (10, header.tablename));
WRITELN ('Table contains ', header.nrecs, ' records');
WRITELN ('Data record length in bytes is ',
header.reclen);
WRITELN ('Each record contains ', header.ndescr, ' fields:');
getDescriptors;
FOR d := 1 TO header.ndescr DO BEGIN
WRITELN (' Field name: ', asciiz (20, field [d].fname));
WRITE (' Data type: ');
CASE field [d].ftype OF
0: WRITELN ('Integer');
1: WRITELN ('Character');
END;
WRITELN (' Length: ', field [d].flen);
WRITELN;
END;
WRITELN ('Data records follow:');
WRITELN;
END;
{ --------------------------- }
PROCEDURE showData;
{ List contents of each data record by fieldname }
TYPE int = RECORD CASE tag : INTEGER OF
1: (number : INTEGER);
2: (stream : PACKED ARRAY [1..2] OF BYTE);
END;
TYPE charfield = RECORD CASE tag : INTEGER OF
1: (bf : PACKED ARRAY [1..20] OF BYTE);
2: (cf : pac);
END;
VAR rec, descr, n : INTEGER;
intfield : int; { integer data field }
chfield : charfield; { character data field }
BEGIN
FOR rec := 1 TO header.nrecs DO { For each record }
FOR descr := 1 TO header.ndescr DO BEGIN { For each field }
WRITE (asciiz (20, field [descr].fname)); { Show name }
FOR n := LENGTH (asciiz (20, field [descr].fname)) TO 25 DO
WRITE (' '); { cosmetic spacing }
CASE field [descr].ftype OF
0: BEGIN
FOR n := 1 TO 2 DO
READ (table, intfield.stream [n]); { get int field }
WRITELN (intfield.number);
END;
1: BEGIN
FOR n := 1 TO field [descr].flen DO
READ (table, chfield.bf [n]); { get character field }
WRITELN (asciiz (20, chfield.cf));
END;
END;
END;
END;
{ --------------------------- }
BEGIN
ASSIGN (table, 'DATABASE.XYZ'); { open table }
RESET (table);
FOR n := 1 TO 24 DO { read header record }
READ (table, header.stream [n]);
IF signature <> header.signature THEN
WRITELN ('File not in proper format. Program ended.')
ELSE
BEGIN
showHeaderInfo; { Show info about the file }
SEEK (table, header.datastart); { go to start of data }
showData; { List each record's data }
END;
CLOSE (table);
END.