home *** CD-ROM | disk | FTP | other *** search
- (****************************************************************)
- (* DATABASE TOOLBOX 4.0 *)
- (* Copyright (c) 1984, 87 by Borland International, Inc. *)
- (* *)
- (* Reflex Unit *)
- (* Routines to create Reflex files from Turbo Pascal Access *)
- (* files and vice versa. *)
- (****************************************************************)
- unit Reflex;
-
- interface
-
- uses DOS,
- CRT,
- FileUtil,
- MiscTool,
- { If a compiler error occurs here, you need to unpack the source
- to the MiscTool unit from the archived file Tools.arc. See the
- README file on disk 1 for detailed instructions. }
-
- FieldDef,
- RealConv,
- RefDate;
-
- const
- MaxSections = 44; { Maximum number of sections in a Reflex file }
- MaxField = 249; { Maximum number of fields in Reflex record }
-
- type
- FileName = String[66];
- ErrorStr = string[80];
- { Information needed to access a particular logical section in
- a Reflex file }
- SectionDesc = record
- SectionType : integer;
- SectionAddr,
- SectionLen : LongInt;
- end; { SectionDesc }
-
- { Fixed length Reflex file header. We are mostly concerned with
- Dfsection, which holds the information on the other, variable
- length sections in the file where the actual data will be stored }
- RefHeader = record
- HdrSz : integer;
- Stamp : array[1..12] of char;
- Dirty,
- VerViews,
- VerModels,
- VerData,
- fRecalc : integer;
- { If error set fRecalc so that Reflex will recalculate }
- ScreenType,
- CheckSum : byte;
- Reserved : array[1..38] of byte;
- SectionCt : integer;
- DfSection : array[1..MaxSections] of SectionDesc;
- buffer : real;
- end; { RefHeader }
-
- { Besides the File Header, a reflex file is built out of variable length
- structures. Data records for example are variable size. To represent
- a variable sized record we will use the following structure }
- VarLenBuf = record { represents a variable length buffer }
- MaxAllocate, { length initially allocated for buffer }
- Len : word; { length of the buffer }
- Buf : ^byte; { pointer to the buffer, use GetMem }
- end;
-
-
- { This is how the field names are actually stored in the Reflex file.
- There are three variable length records. FieldNamePool actually
- contains the names of the record fields. The FieldNameIndex is
- a pointer into the FieldNamePointers. FieldDescriptions contains
- the information about each field name (pool ptr), type, offset in
- record etc. At this time a RepeatingTextPool will not be created.
- }
- ReflexFieldDirectory = record
- FieldNameIndex,
- FieldNamePool,
- FieldDescriptions,
- RepeatingTextPool : VarLenBuf;
- end;
-
- ETRec = record
- Index,
- Pool : LongInt;
- end;
- DescPtr = ^FieldDesc;
- FieldDesc = record
- NameOffset : integer;
- DataType : byte;
- PrecForm : byte;
- FieldOffset : integer;
- Etr : ETRec;
- SortPos,
- Reserved : byte;
- end;
-
- FieldDescTbl = array[0..MaxField] of DescPtr;
-
- RepTPool = ^TextPool;
- TextPool = record
- FIDNum : byte;
- PoolIndex,
- Pool : VarLenBuf;
- Next : RepTPool;
- end;
-
- ReflexRef = record
- { This record represents a Reflex Database file variables
- of this type are used in almost every routine to indicate
- which Reflex file is being manipulated and the record
- structure of that file. }
- RefFile : File; { Reflex file variable }
- CurrentRecord,
- NumberOfRecs : integer;
- Modified : boolean;
- LocalTextPool, { used for the current record }
- RepeatingTextPool : VarLenBuf;
- DataSectionAddr, { start of the data section }
- DataSectionLen : LongInt; { length of the data section }
- ReflexHeader : RefHeader; { Reflex file header }
- FieldsIncluded : integer;
- FieldDir : ReflexFieldDirectory;
- FieldDescriptors : FieldDescTbl;
- RepTextPool : RepTPool;
- FixedRecordLen : word;
- TextFields : byte;
- ReflexRec : VarLenBuf;
- FDTable : FieldDirectory;
- end;
-
- procedure AddReflexRec(var ReflexF : ReflexRef;
- var TurboRec);
- { Converts the Pascal record TurboRec into a Reflex record
- and adds it to the file specified by ReflexF.
- }
-
- procedure CloseReflexFile(var ReflexF : ReflexRef);
- { Saves important reflex file header information and closes the
- file specified by ReflexF. Note: This routine is required! when
- modifying reflex files. }
-
- procedure GetReflexRec(var ReflexTable : ReflexRef;
- var TurboRec;
- RecordNum : integer);
- { Gets a reflex variable length data record specified by
- record num and translates it to a Turbo Pascal fixed length
- record of the type specificed in the .DEF file. }
-
- procedure MakeReflexFile(var ReflexF : ReflexRef;
- RefFileNm : FileName;
- var FD : FieldDirectory);
- { Creates a reflex file name RefFileNm, with a record
- definition specified in FD. ReflexF will be used to refer
- to this file in all subsequent operation.
- }
-
- function OpenReflexFile(var ReflexF : ReflexRef;
- RefFileNm : FileName): boolean;
- { Opens the reflex file named RefFileNm, and generates
- a defintion file which describes the structure
- of the reflex record. ReflexF will be used to refer to
- this file in all subsequent operations. }
-
- function ReflexFileLen(var ReflexF : ReflexRef) : integer;
- { Returns the number of Records in the Reflex file referenced
- by ReflexF. }
-
- function SetUpReflexFD(var ReflexF : ReflexRef;
- var FDFileNm : FileSpec;
- TAccessF,
- LoadFDFile : boolean) : boolean;
-
- implementation
-
- {$V-}
-
- const
- DataSectionNum = 1;
- MasterSectionNum = 2;
- FieldDirSectionNum = 3;
- FieldDirSection = 2; { relevant sections in the reflex file }
- MasterRecSection = 9;
- DataRecSection = 1;
-
- type
- { We move through the records, one field at a time. This record
- is used to keep track of the offset into the records. }
- TranslateRec = record
- ReflexOffset,
- TurboOffset : word;
- end;
-
- var
- Trans : TranslateRec;
-
- procedure TranslateError(E : ErrorStr);
- { Tells the user the error and then halts }
- begin
- Beep;
- Window(1, 1, 80, 25);
- GotoXY(1, 24);
- Write('Translate Error: ');
- GotoXY(1, 25);
- Write(' ', E, ', terminating...');
- Halt;
- end; { TranslateError }
-
- procedure AllocateBuf(var V : VarLenBuf; Max : integer);
- { Allocates the space for a variable length buffer of Max
- number of bytes }
- begin
- FillChar(V, SizeOf(V), 0);
- with V do
- begin
- MaxAllocate := Max;
- GetMem(Buf, MaxAllocate);
- end;
- end; { AllocateBuf }
-
- procedure DeallocateBuf(var V : VarLenBuf);
- { Deallocates the space used by a variable length buffer }
- begin
- with V do
- begin
- FreeMem(Buf, MaxAllocate);
- Buf := nil;
- end;
- end; { DeallocateBuf }
-
- procedure WriteBuffer(var OutFile : File;
- var B : VarLenBuf);
- var
- BlocksWritten : integer;
- begin
- with B do
- begin
- BlockWrite(OutFile, Len, SizeOf(Len), BlocksWritten);
- BlockWrite(OutFile, Buf^, Len, BlocksWritten);
- end;
- end; { WriteBuffer }
-
- procedure ReadBuffer(var InFile : File;
- var B : VarLenBuf);
- var
- RecsRead : integer;
- begin
- with B do
- begin
- BlockRead(InFile, Len, 2, RecsRead);
- AllocateBuf(B, Len);
- Len := MaxAllocate;
- BlockRead(InFile, Buf^, Len, RecsRead);
- if RecsRead <> Len then
- TranslateError('In ReadBuffer the length is wrong, eof?...');
- end;
- end; { ReadBuffer }
-
- procedure GetText(FieldNameText : VarLenBuf;
- Offset : integer;
- var T : String);
- { Gets a null terminated string of text from the
- at the specified offset in a variable length buffer }
- var
- CurByte : byte;
- begin
- T := '';
- with FieldNameText do
- repeat
- CurByte := Mem[Seg(Buf^):Ofs(Buf^) + Offset];
- if (CurByte <> 0) and (Length(T) < pred(SizeOf(t))) then
- { temporary }
- T := T + Chr(CurByte);
- Offset := succ(Offset);
- until (CurByte = 0) or (Offset > Len);
- end; { GetText }
-
- procedure AddBlock(var V : VarLenBuf;
- var B;
- NumBytes : integer);
- { Copies Numbytes from B onto the end of the variable length
- Buffer B }
- begin
- with V do
- begin
- Move(B, Mem[Seg(Buf^):Ofs(Buf^) + Len], NumBytes);
- Len := Len + NumBytes;
- end;
- end; { AddBlock }
-
- procedure AddTextToPool(var T : VarLenBuf;
- S : String;
- var TextOffset : word);
- { A text pool is a variable length buffer which contains a
- number of AsciiZ strings. This routine converts the
- String to an Asccii Z string and copies it onto the
- end of the pool. }
- var
- MaxLen : byte;
- begin
- if T.Buf = nil then
- TranslateError('In AddTextToPool, the text pool is empty');
- with T do
- begin
- TextOffset := Len;
- MaxLen := Length(S);
- if MaxLen = 255 then
- MaxLen := MaxLen - 1; { Longest string in Reflex }
- Move(S[1], Mem[Seg(Buf^):Ofs(Buf^) + Len], MaxLen);
- Len := Len + MaxLen;
- Mem[Seg(Buf^):Ofs(Buf^) + Len] := 0;
- Len := Succ(Len);
- end;
- end; { AddTextToPool }
-
- procedure InitReflexFields(var ReflexF : ReflexRef);
- const
- MaxFieldNameLen = 74;
- begin
- with ReflexF, FieldDir, FDTable do
- begin
- FillChar(FieldDir, SizeOf(FieldDir), 0);
- FieldsIncluded := FieldTotals[ReflexFile] + FieldTotals[Translate];
- AllocateBuf(FieldNameIndex, FieldsIncluded * 2);
- AllocateBuf(FieldNamePool, FieldsIncluded * MaxFieldNameLen);
- AllocateBuf(FieldDescriptions, FieldsIncluded * SizeOf(FieldDesc));
- end;
- end; { InitReflexFields }
-
- procedure MakeFieldEntry(var FieldDir : ReflexFieldDirectory;
- var CurField : FieldInfoPtr;
- var RecordOffset : integer);
- var
- RefField : FieldDesc;
- TextOffset : word;
-
- begin
- FillChar(RefField, SizeOf(RefField), 0);
- with FieldDir, CurField^ , RefField do
- begin
- AddTextToPool(FieldNamePool, FieldName, TextOffset);
- NameOffset := TextOffset;
- AddBlock(FieldNameIndex, TextOffset, SizeOf(TextOffset));
- TurboToRefType(CurField^);
- DataType := Ord(ReflexType);
- FieldOffset := RecordOffset;
- AddBlock(FieldDescriptions, RefField, SizeOf(RefField));
- Inc(RecordOffset, FieldDefaults[ReflexType].TypeSize);
- end;
- end; { MakeFieldEntry }
-
- procedure ConvertFDTable(var ReflexF : ReflexRef);
- { Converts the Field Definition table into the Format that
- Reflex expects for a field directory }
- var
- RecordOffset : integer;
- CurField : byte;
- begin
- RecordOffset := 4;
- with ReflexF, FDTable, FieldDir do
- begin
- InitReflexFields(ReflexF);
- for CurField := 0 to (TotalFields - 1) do
- with FieldEntries[CurField]^ do
- if (XLateStatus = Translate)
- or (XLateStatus = ReflexFile) then
- begin
- MakeFieldEntry(FieldDir, FieldEntries[CurField], RecordOffset);
- if FieldEntries[CurField]^.ReflexType = TextVal then
- Inc(TextFields);
- end;
- FixedRecordLen := RecordOffset;
- end;
- end; { ConvertFDTable }
-
-
- procedure CloseReflexFile(var ReflexF : ReflexRef);
- { Saves important reflex file header information and closes the
- file specified by ReflexF. Note: This routine is required! when
- modifying reflex files.
- }
-
- procedure PutMasterRec(var ReflexF : ReflexRef);
- var
- Master : record
- Total,
- Filtered : integer;
- end;
- BlocksWritten : integer;
- begin
- with ReflexF, Master do
- begin
- with ReflexHeader.DfSection[MasterSectionNum] do
- begin
- SectionType := MasterRecSection;
- SectionAddr := FilePos(RefFile);
- SectionLen := SizeOf(Master);
- end;
- Total := CurrentRecord;
- Filtered := CurrentRecord;
- BlockWrite(RefFile, Master, SizeOf(Master), BlocksWritten);
- end;
- end; { PutMasterRec }
-
- procedure PutFieldDir(var ReflexF : ReflexRef);
- var
- FieldDir : ReflexFieldDirectory;
- SavedPosition : LongInt;
-
- procedure WriteFieldDir(var RefFile : File;
- var FieldDir : ReflexFieldDirectory);
- const
- FieldSortSpec : array[1..12] of byte =
- ($FF,0,0,0,0,0,0,0,0,0,0,0);
- DefaultFormat : array[1..6] of byte =
- ($13,00,01,00,00,00);
- var
- BlocksWritten : integer;
- begin
- with FieldDir do
- begin
- BlockWrite(RefFile, FieldSortSpec, SizeOf(FieldSortSpec), BlocksWritten);
- WriteBuffer(RefFile, FieldNameIndex);
- DeallocateBuf(FieldNameIndex);
- WriteBuffer(RefFile, FieldNamePool);
- DeallocateBuf(FieldNamePool);
- WriteBuffer(RefFile, FieldDescriptions);
- DeallocateBuf(FieldDescriptions);
- BlockWrite(RefFile, DefaultFormat, SizeOf(DefaultFormat), BlocksWritten);
- end;
- end; { WriteFieldDir }
-
- begin { PutFieldDir }
- with ReflexF do
- begin
- with ReflexHeader.DfSection[FieldDirSectionNum] do
- begin
- SectionType := FieldDirSection;
- SectionAddr := FilePos(RefFile);
- SavedPosition := FilePos(RefFile);
- WriteFieldDir(RefFile, FieldDir);
- SectionLen := FilePos(RefFile) - SavedPosition;
- end;
- end;
- end; { PutFieldDir }
-
- procedure UpdateReflexHeader(var ReflexF : ReflexRef);
- var
- BlocksWritten : integer;
- begin
- with ReflexF, ReflexHeader do
- begin
- Seek(RefFile, 0);
- SectionCt := 3;
- Dirty := 0;
- with DfSection[DataSectionNum] do
- begin
- SectionType := DataRecSection;
- SectionAddr := DataSectionAddr;
- SectionLen := DataSectionLen;
- end;
- BlockWrite(RefFile, ReflexHeader, SizeOf(ReflexHeader), BlocksWritten);
- end;
- end; { UpdateReflexHeader }
-
- begin { CloseReflexFile }
- with ReflexF do
- begin
- if Modified then
- begin
- PutMasterRec(ReflexF);
- PutFieldDir(ReflexF);
- UpdateReflexHeader(ReflexF);
- end;
- Close(RefFile);
- end;
- end; { CloseReflexFile }
-
- function ReflexFileLen{(var ReflexF : ReflexRef) : integer};
- { Returns the number of Records in the Reflex file referenced
- by ReflexF. }
- begin
- ReflexFileLen := ReflexF.NumberOfRecs;
- end; { ReflexFileLen }
-
- function GetReflexType(var DataType : byte) : ReflexTypes;
- var
- found : boolean;
- FieldType : FieldTypes;
-
- begin
- found := false;
- FieldType := Untyped;
- repeat
- if ord(FieldType) = DataType then
- found := true
- else
- begin
- if (FieldType = IntegerVal) then
- FieldType := Untyped
- else
- FieldType := Succ(FieldType);
- end;
- until found or (FieldType = Untyped);
- GetReflexType := FieldType;
- end; { GetReflexType }
-
- procedure GenerateFD(var ReflexF : ReflexRef;
- TAccessDef : boolean);
- var
- CurField,
- ExportField : integer;
-
- begin
- with ReflexF, FDTable, FieldDir do
- begin
- ExportField := 0;
- if TAccessDef then
- begin
- new(FieldEntries[ExportField]);
- FieldEntries[ExportField]^ := StatusField;
- Inc(RecordSize, FieldEntries[ExportField]^.TFieldLength);
- Inc(ExportField);
- DataFileType := TAccessFile;
- end
- else
- DataFileType := PascalFile;
- for CurField := 0 to pred(FieldTotals[Translate]) do
- begin
- new(FieldEntries[ExportField]);
- with FieldEntries[ExportField]^,
- FieldDescriptors[CurField]^ do
- begin
- FillChar(FieldEntries[ExportField]^, SizeOf(FieldEntries[ExportField]^), 0);
- GetText(FieldNamePool, NameOffset, FieldName);
- ReflexType := GetReflexType(DataType);
- XLateStatus := Translate;
- RefToTurboType(FieldEntries[ExportField]^);
- Inc(RecordSize, TFieldLength);
- Inc(ExportField);
- end; { with }
- end; { for }
- TotalFields := ExportField;
- end;
- end; { GenerateFD }
-
- function CheckFD(var ReflexFD,
- LoadedFD : FieldDirectory) : boolean;
- var
- FDOk : boolean;
- NewField,
- RefField : integer;
-
-
- begin
- with LoadedFD do
- begin
- FDOk := TotalFields >= ReflexFD.TotalFields;
- if FDOK then
- FDOk := (FieldTotals[Translate] + FieldTotals[ReflexFile]) =
- ReflexFD.FieldTotals[Translate];
- RefField := 0;
- NewField := 0;
- while FDOK and (NewField < TotalFields) do
- begin
- TurboToRefType(FieldEntries[NewField]^);
- with FieldEntries[NewField]^ do
- begin
- if (XLateStatus = ReflexFile) or (XLateStatus = Translate) then
- begin
- FDOK := RefField < ReflexFD.TotalFields;
- if FDOK then
- begin
- FDOK := ReflexFD.FieldEntries[RefField]^.ReflexType = ReflexType;
- if not FDOK then
- FDOK := (ReflexFD.FieldEntries[RefField]^.ReflexType = RepText)
- and (ReflexType = TextVal);
- end;
- Inc(RefField);
- end
- else
- with ReflexFD.FieldEntries[RefField]^ do
- if (XLateStatus = TAccessFile) then
- Inc(RefField);
- Inc(NewField);
- end;
- end;
- end;
- CheckFD := FDOk;
- end; { CheckFD }
-
- var
- LoadedFD : FieldDirectory;
-
- function SetUpReflexFD(var ReflexF : ReflexRef;
- var FDFileNm : FileSpec;
- TAccessF,
- LoadFDFile : boolean) : boolean;
- var
- Ok : boolean;
-
- begin
- Ok := true;
- with ReflexF, FDTable, FDFileNm do
- begin
- GenerateFD(ReflexF, TAccessF);
- RecordName := Name + 'Record';
- if LoadFDFile and Exist(Path + Name + Ext) then
- begin
- FillChar(LoadedFD, SizeOf(LoadedFD), 0);
- LoadFD(LoadedFD, Path + Name + Ext);
- OK := CheckFD(FDTable, LoadedFD);
- if OK then
- begin
- DisposeFD(FDTable);
- CopyFD(LoadedFD, FDTable);
- end
- else
- Abort(Path + Name + Ext + ' is inconsistent with the Reflex file');
- DisposeFD(LoadedFD);
- end;
- end;
- SetUpReflexFD := OK;
- end; { SetUpReflexFD }
-
-
- function OpenReflexFile(var ReflexF : ReflexRef;
- RefFileNm : FileName) : boolean;
- { Opens the reflex file named RefFileNm, and generates
- a field defintion file which describes the structure
- of the reflex record. ReflexF will be used to refer to
- this file in all subsequent operations. }
-
- function GetSectionAddr(var Header : RefHeader;
- CurSection : integer) : LongInt;
- { Returns the start of the specified reflex file section }
-
- var
- SecAddr : LongInt;
- i : integer;
- SectionFound : boolean;
- begin
- with Header do
- begin
- i := 1;
- repeat
- SectionFound := (DfSection[i].SectionType = CurSection);
- SecAddr := DfSection[i].SectionAddr;
- i := i + 1;
- until (i > SectionCt) or SectionFound;
- if SectionFound then
- GetSectionAddr := SecAddr
- else
- GetSectionAddr := 0;
- end;
- end; { GetSectionAddr }
-
- function GetNumberOfRecs(var ReflexF : ReflexRef) : integer;
- var
- SectionAddr : LongInt;
- NumRecs, BlocksRead : integer;
- begin
- with ReflexF do
- begin
- SectionAddr := GetSectionAddr(ReflexHeader, MasterRecSection);
- if SectionAddr > FileSize(RefFile) then
- begin
- TranslateError('Seek past EOF in getting master record');
- GetNumberOfRecs := 0;
- end
- else
- begin
- Seek(RefFile, SectionAddr);
- BlockRead(RefFile, NumRecs, SizeOf(NumRecs), BlocksRead);
- GetNumberOfRecs := NumRecs;
- end;
- end;
- end; { GetNumberOfRecs }
-
-
- procedure GetReflexHeader(var ReflexFile : File;
- var Header : RefHeader);
- { Reads in the fixed length Reflex file header of 512 bytes
- note that the block size is 1 byte, set in OpenReflexFile }
- var
- BlocksRead : integer;
- begin
- Seek(ReflexFile, 0);
- BlockRead(ReflexFile, Header, SizeOf(Header), BlocksRead);
- if BlocksRead <> SizeOf(Header) then
- TranslateError('The Reflex file is too small for a legal header');
- end; { GetReflexHeader }
-
- procedure BuildFieldNameTables(var InFile : File;
- var FieldDir : ReflexFieldDirectory;
- var TotalFields : integer);
- const
- SkipSize = 12; { Field sort }
-
- begin { BuildFieldNameTables }
- Seek(Infile, FilePos(InFile) + SkipSize);
- with FieldDir do
- begin
- ReadBuffer(InFile, FieldNameIndex);
- TotalFields := Lo(FieldNameIndex.Len div 2);
- ReadBuffer(InFile, FieldNamePool);
- ReadBuffer(InFile, FieldDescriptions);
- end;
- end; { BuildFieldNameTables }
-
- procedure GetFieldDesc(FieldDirectory : VarLenBuf;
- FieldNum : integer;
- var CurField : FieldDesc);
- var
- Start, Offset : integer;
- begin
- Start := FieldNum * SizeOf(CurField);
- with FieldDirectory do
- for OffSet := 0 to SizeOf(CurField) - 1 do
- begin
- Mem[Seg(CurField):Ofs(CurField) + Offset] :=
- Mem[Seg(Buf^):Ofs(Buf^) + Start + Offset];
- end; { for }
- end; { GetFieldDesc }
-
- procedure AddPool(var RepTextPool : RepTPool;
- var T : TextPool);
- var
- P : RepTPool;
- begin
- New(P);
- P^ := T;
- if RepTextPool <> nil then
- P^.next := RepTextPool;
- RepTextPool := P;
- end; { AddPool }
-
- procedure BuildRepTextPool(var ReflexF : ReflexRef;
- var InFile : File;
- FieldCount : byte);
- var
- CurPool : TextPool;
- begin
- for FieldCount := FieldCount downto 0 do
- with ReflexF, FieldDescriptors[FieldCount]^, CurPool do
- if FieldDescriptors[FieldCount]^.DataType = ord(RepText) then
- begin
- FIDNum := FieldCount;
- ReadBuffer(InFile, PoolIndex);
- ReadBuffer(InFile, Pool);
- Next := nil;
- AddPool(RepTextPool, CurPool);
- end;
- end; { BuildRepTextPool }
-
- procedure BuildFieldDescTbl(var ReflexF : ReflexRef;
- var InFile : File;
- var FieldDirectory : VarLenBuf;
- FieldCount : integer);
- var
- CurDesc : 0..MaxField;
- CurField : FieldDesc;
- begin
- with ReflexF do
- begin
- for CurDesc := 0 to MaxField do
- FieldDescriptors[CurDesc] := nil;
- for CurDesc := 0 to (FieldCount - 1) do
- begin
- New(FieldDescriptors[CurDesc]);
- GetFieldDesc(FieldDirectory, CurDesc, CurField);
- FieldDescriptors[CurDesc]^ := CurField;
- end;
- end;
- end; { BuildFieldDescTbl }
-
- procedure BuildFieldDir(var ReflexF : ReflexRef;
- var TotalFields : integer);
- const
- SkipSize = 6;
- begin
- with ReflexF, FieldDir do
- begin
- Seek(RefFile, GetSectionAddr(ReflexHeader, FieldDirSection));
- BuildFieldNameTables(RefFile, FieldDir, TotalFields);
- BuildFieldDescTbl(ReflexF, RefFile, FieldDescriptions, TotalFields);
- Seek(RefFile, FilePos(RefFile) + SkipSize);
- RepTextPool := nil;
- BuildRepTextPool(ReflexF, RefFile, TotalFields - 1);
- end;
- end; { BuildFieldDir }
-
-
- begin
- OpenReflexFile := true;
- with ReflexF, FDTable do
- begin
- if not Exist(RefFileNm) then
- begin
- OpenReflexFile := false;
- Exit;
- end;
- Assign(RefFile, RefFileNm);
- Reset(RefFile, 1); { Open file with a block size of 1 }
- { This allows us the flexibility of reading various sized }
- { records and the ability to seek to any byte in the file }
- GetReflexHeader(RefFile, ReflexHeader);
- FillChar(FDTable, SizeOf(FDTable), 0);
- BuildFieldDir(ReflexF, FDTable.FieldTotals[Translate]);
- NumberOfRecs := GetNumberOfRecs(ReflexF);
- CurrentRecord := 0;
- DataSectionAddr := GetSectionAddr(ReflexHeader, DataSectionNum) + 2;
- Seek(RefFile, DataSectionAddr);
- Modified := false; { Open for reading, Modified used in close proc. }
- end;
- end; { OpenReflexFile }
-
-
- procedure GetReflexRec(var ReflexTable : ReflexRef;
- var TurboRec;
- RecordNum : integer);
- { Gets a reflex variable length data record specified by
- record num and translates it to a Turbo Pascal fixed length
- record of the type specificed in the .DEF file. }
-
- procedure GetFieldCount(var RecBuf : VarLenBuf;
- var FieldCount : byte);
- { Returns the number of fields in the given data
- record }
- type
- RecHdr = record
- temp : array[1..3] of byte;
- CtFlds : integer;
- end;
- var
- CurRec : RecHdr;
- begin
- with RecBuf, CurRec do
- begin
- Move(Buf^, CurRec, SizeOf(CurRec));
- FieldCount := Lo(CtFlds);
- end;
- end; { GetFieldCount }
-
- procedure TranslateLocText(var ReflexF : ReflexRef;
- var ReflexRecord : VarLenBuf;
- var TurboRecord;
- FieldNum : integer;
- var Trans : TranslateRec);
- var
- TextPos : word;
- S : String;
- begin
- {$ifdef FlexDebug}
- Write('In TranslateLocText');
- Readln;
- {$endif}
-
- with ReflexF, ReflexRecord, Trans do
- begin
- TextPos := MemW[Seg(Buf^):Ofs(Buf^) + ReflexOffset];
- Inc(ReflexOffset,2); { Move the offset to the next field }
- if (TextPos = 0) then
- S := ''
- else
- if (TextPos = 1) then
- S := 'ERROR'
- else
- if (TextPos >= 2) and (TextPos < Len) then
- GetText(ReflexRecord, TextPos, S)
- else
- S := '';
- {$ifdef FlexDebug}
- Write('TextPos = ', TextPos, ' Text returned = ', S);
- Readln;
- {$endif}
- with FDTable, FieldEntries[FieldNum]^ do
- begin
- Move(S, Mem[Seg(TurboRecord):Ofs(TurboRecord) + TurboOffset], TFieldLength);
- Inc(TurboOffset, TFieldLength);
- end;
- end;
- end; { TranslateLocText }
-
- function GetPool(var CurPool : RepTPool;
- FieldNum : byte) : boolean;
- var
- found : boolean;
- begin
- found := false;
- while (CurPool <> nil) and not found do
- with CurPool^ do
- begin
- found := (FIDNum = FieldNum);
- if not found then
- CurPool := CurPool^.Next
- end;
- {$ifdef FlexDebug}
- Write('In GetPool, we found it = ', found);
- Readln;
- {$endif}
- GetPool := Found;
- end; { GetPool }
-
- procedure GetRepText(ReflexF : ReflexRef;
- FieldNum : byte;
- TextPos : word;
- var RepText : String);
- var
- CurPool : RepTPool;
- begin
- {$ifdef FlexDebug}
- Write('In GetRepText');
- Readln;
- {$endif}
- with ReflexF do
- begin
- CurPool := RepTextPool;
- if GetPool(CurPool, FieldNum) then
- begin
- {$ifdef FlexDebug}
- Write('Successfully got the text pool');
- Readln;
- {$endif}
- if TextPos <= 1 then
- RepText := ''
- else
- GetText(CurPool^.Pool, TextPos, RepText);
- {$ifdef FlexDebug}
- Write('String returned is *', RepText,'*');
- Readln;
- {$endif}
- (*if RepText = '' then
- TranslateError('The text was not returned from the text pool'); *)
- end
- else
- RepText := '';
- end;
- end; { GetRepText }
-
- procedure TranslateRepText(var ReflexF : ReflexRef;
- var ReflexRecord : VarLenBuf;
- var TurboRecord;
- FieldNum : byte;
- ReflexFieldNum : byte;
- var Trans : TranslateRec);
- var
- TextPos : integer;
- RepText : String;
- begin
- {$ifdef FlexDebug}
- Write('In Translate RepText for field ', FieldNum);
- Readln;
- {$endif}
-
- with ReflexF, ReflexRecord, Trans do
- begin
- TextPos := MemW[Seg(Buf^):Ofs(Buf^) + ReflexOffset];
- {$ifdef FlexDebug}
- Write('TextPos = ', TextPos);
- Readln;
- {$endif}
- Inc(ReflexOffset, 2); { Move the offset to the next field }
- GetRepText(ReflexF, ReflexFieldNum, TextPos, RepText);
- with FDTable, FieldEntries[FieldNum]^ do
- begin
- Move(RepText, Mem[Seg(TurboRecord) : Ofs(TurboRecord) + TurboOffset], TFieldLength);
- Inc(TurboOffset, TFieldLength);
- end;
- end;
- end; { TranslateRepText }
-
-
- procedure TransferBytes(var ReflexRecord : VarLenBuf;
- var TurboRecord;
- NumBytes : byte;
- var Trans : TranslateRec);
- begin
- with ReflexRecord, Trans do
- begin
- Move(Mem[Seg(Buf^) : Ofs(Buf^) + ReflexOffset],
- Mem[Seg(TurboRecord) : Ofs(TurboRecord) + TurboOffset], NumBytes);
- Inc(ReflexOffset, NumBytes);
- Inc(TurboOffset, NumBytes);
- end;
- end; { TransferBytes }
-
- procedure TransRealNum(var ReflexRecord : VarLenBuf;
- var TurboRecord;
- FieldLength : byte;
- var Trans : TranslateRec);
-
- var
- EightByteReal : ieee;
- r : real;
-
- begin
- with ReflexRecord, Trans do
- if (FieldLength = 6) then { Convert number }
- begin
- Move(Mem[Seg(Buf^):Ofs(Buf^) + ReflexOffset], EightByteReal, 8);
- IEEEToTurbo(EightByteReal, r);
- Inc(ReflexOffset, 8);
- Move(r, Mem[Seg(TurboRecord) : Ofs(TurboRecord) + TurboOffset], SizeOf(r));
- Inc(TurboOffset, 6);
- end
- else
- TransferBytes(ReflexRecord, TurboRecord, FieldLength, Trans);
- end; { TransRealNum }
-
- procedure TranslateDate(var ReflexRecord : VarLenBuf;
- var TurboRecord;
- var Trans : TranslateRec);
- var
- D : RDate;
- S : Date;
- begin
- with ReflexRecord, Trans do
- begin
- Move(Mem[Seg(Buf^):Ofs(Buf^) + ReflexOffset], D, 2);
- Inc(ReflexOffset, 2);
- DateToStr(D, S);
- Move(S, Mem[Seg(TurboRecord) : Ofs(TurboRecord) + TurboOffset],
- SizeOf(S));
- Inc(TurboOffset, SizeOf(S));
- end;
- end; { TranslateDate }
-
- function GetFieldNum(var FDTable : FieldDirectory;
- CurField : byte) : byte;
- var
- F, Total : byte;
- begin
- F := 0;
- for CurField := 0 to pred(CurField) do
- with FDTable, FieldEntries[CurField]^ do
- begin
- if (XLateStatus = Translate) or (XLateStatus = ReflexFile) then
- F := succ(F);
- end;
- GetFieldNum := F;
- end; { GetFieldNum }
-
- procedure TranslateField(var ReflexF : ReflexRef;
- var ReflexRecord : VarLenBuf;
- var TurboRecord;
- FieldCount : byte; { needed for repeating text }
- var Trans : TranslateRec);
- begin
- with ReflexF, ReflexRecord, FDTable, FieldEntries[FieldCount]^, Trans do
- case XLateStatus of
- Translate :
- case ReflexType of
- Untyped : ;
- TextVal : TranslateLocText(ReflexF, ReflexRecord, TurboRecord,
- FieldCount, Trans);
- RepText : TranslateRepText(ReflexF, ReflexRecord, TurboRecord,
- FieldCount,
- GetFieldNum(FDTable, FieldCount), Trans);
- DoubleVal : TransRealNum(ReflexRecord, TurboRecord,
- TFieldLength, Trans);
- IntegerVal : TransferBytes(ReflexRecord, TurboRecord, 2, Trans);
- RDateVal : TranslateDate(ReflexRecord, TurboRecord, Trans);
- end;
- ReflexFile : Inc(ReflexOffset, FieldDefaults[ReflexType].TypeSize);
- TAccessFile,
- PascalFile : Inc(TurboOffset, TFieldLength);
- end;
- end; { TranslateField }
-
- procedure ReflexToTurbo(var ReflexTable : ReflexRef;
- var ReflexRecord : VarLenBuf;
- var TurboRecord);
- var
- FieldCount : byte;
- Trans : TranslateRec;
- begin
- GetFieldCount(ReflexRecord, FieldCount);
- {$ifdef FlexDebug}
- Write('In ReflexToTurbo FieldCount is ', succ(FieldCount));
- Readln;
- {$endif}
- with Trans, ReflexTable, FDTable do
- begin
- ReflexOffset := 4;
- TurboOffset := 0;
- for FieldCount := 0 to (TotalFields - 1) do
- begin
- {$ifdef FlexDebug}
- Writeln;
- Write('Translating field ', FieldCount, ' ', FieldEntries[FieldCount]^.FieldName);
- Readln;
- {$endif}
- TranslateField(ReflexTable, ReflexRecord, TurboRecord, FieldCount, Trans);
- end;
- end;
- end; { ReflexToTurbo }
-
- procedure SkipRecord(var CurFile : File);
- var
- RecLen,
- BlocksRead : integer;
- begin
- BlockRead(CurFile, RecLen, SizeOf(RecLen), BlocksRead);
- Seek(CurFile, FilePos(CurFile) + RecLen);
- end; { SkipRecord }
-
- procedure ReflexRecSeek(var ReflexTable : ReflexRef;
- RecordNum : word);
- begin
- with ReflexTable do
- if RecordNum <= NumberOfRecs then
- begin
- if CurrentRecord > RecordNum then
- { If the pointer is past us set it back to the first record }
- CurrentRecord := 0;
- if CurrentRecord = 0 then
- Seek(RefFile, DataSectionAddr);
- while RecordNum > CurrentRecord do
- begin
- SkipRecord(RefFile);
- CurrentRecord := Succ(CurrentRecord);
- end;
- end
- else
- TranslateError('Seek past EOF, record number = ' + NumStr(RecordNum));
- end; { ReflexRecSeek }
-
- var
- ReflexRecord : VarLenBuf;
- begin
- ReflexRecSeek(ReflexTable, RecordNum);
- with ReflexTable do
- begin
- ReadBuffer(RefFile, ReflexRecord);
- ReflexToTurbo(ReflexTable, ReflexRecord, TurboRec);
- DeallocateBuf(ReflexRecord);
- CurrentRecord := Succ(CurrentRecord);
- end;
- end; { GetReflexRec }
-
- { The following are routines allow you to create Reflex files. You can
- translate Pascal fixed length records into Reflex variable
- length records and add these records to the Reflex files.
- }
-
- procedure MakeReflexFile(var ReflexF : ReflexRef;
- RefFileNm : FileName;
- var FD : FieldDirectory);
- { Creates a reflex file name RefFileNm, with a record
- definition specified in FD. ReflexF will be used to refer
- to this file in all subsequent operation.
- }
-
- type
- HeaderBlock = array[1..512] of byte;
-
- const
- DefaultHdr : HeaderBlock =
- ($00,$02,$33,$51,$2E,$21,$26,$40,$23,$24,$21,$26,$26,$00,$FF,$FF,
- $07,$00,$04,$00,$03,$00,$00,$00,$01,$C2,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $0C,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
- $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
- );
- var
- BlocksWritten : integer;
- begin
- FillChar(ReflexF, SizeOf(ReflexF), 0);
- with ReflexF do
- begin
- Assign(RefFile, RefFileNm);
- Rewrite(RefFile, 1); { Open and set the block size to 1 }
- ReflexHeader := RefHeader(DefaultHdr);
- BlockWrite(RefFile, ReflexHeader, SizeOf(ReflexHeader), BlocksWritten);
- FDTable := FD;
- ConvertFDTable(ReflexF);
- Modified := true;
- end;
- end; { MakeReflexFile }
-
- procedure AddReflexRec(var ReflexF : ReflexRef;
- var TurboRec);
- { Converts the Pascal record TurboRec into a Reflex record and
- adds it to the file specified by ReflexF. }
-
- procedure SetFieldCount(var ReflexRec : VarLenBuf;
- var NumFields : integer);
- var
- RecHdr : record
- temp : array[1..3] of byte;
- CtFields : byte;
- end;
- begin
- with RecHdr do
- begin
- FillChar(temp, SizeOf(Temp), 0);
- CtFields := NumFields;
- end;
- Move(RecHdr, Mem[Seg(ReflexRec.Buf^):Ofs(ReflexRec.Buf^)], SizeOf(RecHdr));
- ReflexRec.Len := SizeOf(RecHdr);
- end; { SetFieldCount }
-
- procedure TransTurboBytes(var TurboRec;
- var ReflexRec : VarLenBuf;
- NumBytes : byte;
- var Trans : TranslateRec);
- begin
- with ReflexRec, Trans do
- begin
- Move(Mem[Seg(TurboRec) : Ofs(TurboRec) + TurboOffset],
- Mem[Seg(Buf^) : Ofs(Buf^) + Len], NumBytes);
- Inc(Len, NumBytes);
- Inc(TurboOffset, NumBytes);
- end;
- end; { TransTurboBytes }
-
- procedure TransTurboByte(var TurboRec;
- var ReflexRec : VarLenBuf;
- var Trans : TranslateRec);
- var
- b : byte;
- i : integer;
- begin
- with ReflexRec, Trans do
- begin
- Move(Mem[Seg(TurboRec) : Ofs(TurboRec) + TurboOffset],
- b, SizeOf(byte));
- Inc(TurboOffset);
- i := b;
- Move(i, Mem[Seg(Buf^) : Ofs(Buf^) + Len], 2);
- Inc(Len, 2);
- end;
- end; { TransTurboByte }
-
- procedure TransTurboReal(var TurboRec;
- var ReflexRec : VarLenBuf;
- var Trans : TranslateRec);
- var
- EightByteReal : ieee;
- r : real;
- begin
- with ReflexRec, Trans do
- begin
- Move(Mem[Seg(TurboRec):Ofs(TurboRec) + TurboOffset], r, SizeOf(real));
- Inc(TurboOffset, SizeOf(Real));
- TurboToIEEE(r, EightByteReal);
- Move(EightByteReal, Mem[Seg(Buf^):Ofs(Buf^) + Len], SizeOf(EightByteReal));
- Inc(Len, SizeOf(EightByteReal));
- end;
- end; { TransTurboReal }
-
- procedure TransTurboLong(var TurboRec;
- var ReflexRec : VarLenBuf;
- var Trans : TranslateRec);
- var
- l : LongInt;
- r : real;
- EightByteReal : ieee;
- begin
- with ReflexRec, Trans do
- begin
- Move(Mem[Seg(TurboRec):Ofs(TurboRec) + TurboOffset], l, SizeOf(l));
- Inc(TurboOffset, SizeOf(l));
- r := l;
- TurboToIEEE(r, EightByteReal);
- Move(EightByteReal, Mem[Seg(Buf^):Ofs(Buf^) + Len], SizeOf(EightByteReal));
- Inc(Len, SizeOf(EightByteReal));
- end;
- end; { TransTurboLong }
-
- procedure MoveLocalText(var TurboRec;
- Offset,
- FieldLength : integer;
- var S);
- begin
- Move(Mem[Seg(TurboRec):Ofs(TurboRec) + Offset], S, FieldLength);
- end;
-
- procedure TransTurboDate(var TurboRec;
- var ReflexRec : VarLenBuf;
- var Trans : TranslateRec);
- var
- S : string;
- D : RDate;
- begin
- MoveLocalText(TurboRec, Trans.TurboOffset,
- FieldDefaults[DateVal].TypeSize, S);
- Inc(Trans.TurboOffset, FieldDefaults[DateVal].TypeSize);
- if not StrToDate(S, D) then
- D := 0;
- AddBlock(ReflexRec, D, SizeOf(D));
- end;
-
- procedure TransTurboText(var ReflexF : ReflexRef;
- var TurboRec;
- var ReflexRec : VarLenBuf;
- var LocalTextPool : VarLenBuf;
- var Trans : TranslateRec;
- FieldLength : integer);
- var
- S : String;
- Offset : word;
-
- begin
- MoveLocalText(TurboRec, Trans.TurboOffset, FieldLength, S);
- with ReflexF, ReflexRec, Trans do
- begin
- TurboOffset := TurboOffset + FieldLength;
- AddTextToPool(LocalTextPool, S, Offset);
- Inc(Offset, FixedRecordLen);
- AddBlock(ReflexRec, Offset, SizeOf(Offset));
- end;
- end; { TransTurboText }
-
- procedure TransTurboChar(var ReflexF : ReflexRef;
- var TurboRec;
- var ReflexRec : VarLenBuf;
- var LocalTextPool : VarLenBuf;
- var Trans : TranslateRec);
- var
- S : String;
- Offset : word;
-
- begin
- MoveLocalText(TurboRec, Trans.TurboOffset, 1, S[1]);
- S[0] := chr(1);
- with ReflexF, ReflexRec, Trans do
- begin
- Inc(TurboOffset);
- AddTextToPool(LocalTextPool, S, Offset);
- Inc(Offset, FixedRecordLen);
- AddBlock(ReflexRec, Offset, SizeOf(Offset));
- end;
- end; { TransTurboChar }
-
- procedure ConcatBuffers(var Buffer1, Buffer2 : VarLenBuf);
- begin
- with Buffer1 do
- begin
- Move(Buffer2.Buf^,
- Mem[Seg(Buffer1.Buf^):Ofs(Buffer1.Buf^) + Len], Buffer2.Len);
- Len := Len + Buffer2.Len;
- end;
- end; { ConcatBuffers }
-
- procedure CreateField(var ReflexF : ReflexRef;
- var ReflexRec : VarLenBuf;
- ReflexType : ReflexTypes);
- var
- D : RDate;
- i, Offset : word;
- begin
-
- with ReflexF, ReflexRec do
- case
- ReflexType of
- TextVal : begin
- AddTextToPool(LocalTextPool, '', Offset);
- Inc(Offset, FixedRecordLen);
- AddBlock(ReflexRec, Offset, SizeOf(Offset));
- end;
- RDateVal : AddBlock(ReflexRec, NullIEEE, SizeOf(NullIEEE));
- DoubleVal : begin
- D := DateNull;
- AddBlock(ReflexRec, D, SizeOf(D));
- end;
- IntegerVal : begin
- i := 0;
- AddBlock(ReflexRec, i, SizeOf(i));
- end;
- else ;
- end;
- end; { CreateField }
-
- procedure TurboToReflex(var ReflexF : ReflexRef;
- var TurboRec;
- var ReflexRec : VarlenBuf);
- var
- Trans : TranslateRec;
- CurField : byte;
- begin
- FillChar(Trans, SizeOf(Trans), 0);
- with ReflexF, FDTable, Trans, ReflexRec do
- begin
- SetFieldCount(ReflexRec, FieldsIncluded);
- for CurField := 0 to TotalFields - 1 do
- begin
- with FieldEntries[CurField]^ do
- case XLateStatus of
- Translate :
- begin
- case TFieldType of
- IntegerVal,
- DoubleVal,
- RDateVal : TransTurboBytes(TurboRec, ReflexRec, TFieldLength, Trans);
- RealVal : TransTurboReal(TurboRec, ReflexRec, Trans);
- StringVal : TransTurboText(ReflexF, TurboRec, ReflexRec,
- LocalTextPool, Trans, TFieldLength);
- CharVal : TransTurboChar(ReflexF, TurboRec, ReflexRec,
- LocalTextPool, Trans);
- ByteVal : TransTurboByte(TurboRec, ReflexRec, Trans);
- LongIntVal : TransTurboLong(TurboRec, ReflexRec, Trans);
- DateVal : TransTurboDate(TurboRec, ReflexRec, Trans);
- end;
- end;
- TAccessFile,
- PascalFile : Inc(TurboOffset, TFieldLength);
- ReflexFile : CreateField(ReflexF, ReflexRec, ReflexType);
- end; { case }
- end; { for }
- if TextFields > 0 then
- begin
- ConcatBuffers(ReflexRec, LocalTextPool);
- LocalTextPool.Len := 0;
- end;
- end;
- end; { TurboToReflex }
-
- const
- MaxText = 255;
- var
- i, BlocksWritten : integer;
-
- begin { AddReflexRec }
- i := 0;
- with ReflexF do
- begin
- ReflexRec.Len := 0;
- LocalTextPool.Len := 0;
- if (CurrentRecord = 0) then
- begin
- AllocateBuf(ReflexRec, FixedRecordLen + (MaxText * TextFields));
- if (TextFields > 0) then
- AllocateBuf(LocalTextPool, MaxText * TextFields);
- DataSectionAddr := FilePos(RefFile);
- BlockWrite(RefFile, i, SizeOf(i), BlocksWritten);
- end;
- CurrentRecord := Succ(CurrentRecord);
- TurboToReflex(ReflexF, TurboRec, ReflexRec);
- WriteBuffer(RefFile, ReflexRec);
- DataSectionLen := FilePos(RefFile) - DataSectionAddr;
- end;
- end; { AddReflexRec }
-
- end.