Tom Wellige  

About Me
Home
My Blog

Favourites
Books
Drink

Open Source
Miscellaneous
CAN M3S Driver
HPShell
Web DB Editor
Open Queue

Miscellaneous
Wiki
Bookmark

My Programming Page - STREAM




STREAM

Contents of this page




DATA.PAS
{************************************************}
{                                                }
{   UNIT DATA                                    }
{   Copyright (c) 1997 by Tom Wellige            }
{   Donated as FREEWARE                          }
{                                                }
{   E-Mail: wellige@geocities.com                }
{                                                }
{************************************************}

{  Example unit for managing data inside of objects and       }
{  TCollections.                                              }
{                                                             }
{  Freeware, Author: Tom Wellige                              }
{                                                             }
{  This unit will be used in the DEMO.PAS program which is    }
{  part of this package. The unit defines the data object     }
{  TDATA with all its fields and methodes.                    }

unit Data;

{$O+,F+}

interface

uses objects;

type

  PData = ^TData;
  TData = object(TObject)

    { These are the data fields of the object. }

      AnyInteger: integer;
      AnyWord: integer;
      AnyString: string;

    { In addition to records an object defines a number of methodes
      to handle the data being stored in it. You have now all data and
      the needed functionality at the same place. }

    constructor Init(AInteger: integer; AWord: word; AString: string);
    constructor Load(var S: TStream);
    destructor  Done; virtual;
    procedure   Store(var S: TStream);
    procedure   SetData(AInteger: integer; AWord: word; AString: string);
    procedure   GetData(var AInteger: integer; var AWord: word; var AString: string);
  end;

{ Defining TData as a descent of TObject has one big advantage:
  TObject is able to initilize all it's fields. This is sometihng 
  Pascal can't ! }

{ This procedure is ncessary to be able to use TData and TCollection    
  with TStreams. }
procedure Register;

const
  { This is the TData ID in the datastream of TStream. }
  RData: TStreamRec = (
    ObjType: 1000;
    VmtLink: Ofs(TypeOf(TData)^);
    Load:    @TData.Load;
    Store:   @TData.Store
  );

implementation

constructor TData.Init(AInteger: integer; AWord: word; AString: string);
begin
  { With Init everything starts. Here will our object be initialized. }  
  inherited Init;
  AnyInteger:= AInteger;
  AnyWord:= AWord;
  AnyString:= AString;
end;

constructor TData.Load(var S: TStream);
var
   t: string;
   c: word;
begin
  { With the Load method the object is able to load itself (i.e. it's data)
    from a stream. To do so the object must first initialize itself and then
    read every data field from the stream. }
  inherited Init;
  S.read(AnyInteger, SizeOf(AnyInteger));
  S.read(AnyWord, SizeOf(AnyWord));
  S.read(AnyString, SizeOf(AnyString));
end;

destructor TData.Done;
begin
  { At this point one can release memory which is being 
    dynamically being used by the object. }
  inherited Done;
end;

procedure TData.Store(var S: TStream);
begin
  { At this point the object stores itself (i.e. it's data) into a   
    stream. }
  S.write(AnyInteger, SizeOf(AnyInteger));
  S.write(AnyWord, SizeOf(AnyWord));
  S.write(AnyString, SizeOf(AnyString));
end;

{ The following methods be one of the ideas of object orientated 
  programming: capsulation. A program or any other object
  will *never* access any data inside of an data object directly. It
  instead uses the data object's methods to do so.
  This has one advantage: the data object will know best of all how 
  to access it's own data. }

procedure TData.SetData(AInteger: integer; AWord: word; AString: string);
begin
  { Set new data values. }
  if AInteger <> 0 then AnyInteger:= AInteger;
  if AWord <> 0 then AnyWord:= AWord;
  if AString <> '' then AnyString:= AString
end;

procedure TData.GetData(var AInteger: integer; var AWord: word; 
    var AString: string);
begin
  { Get current data values. }
  AInteger:= AnyInteger;
  AWord:= AnyWord;
  AString:= AnyString;
end;

procedure Register;
begin
  { From OBJECTS.PAS. Registers TObject and TCollection }
  RegisterObjects;
  { Register our own new data object TData. }
  RegisterType(RData);
end;

end.

page up


DEMO.PAS
{************************************************}
{                                                }
{   PROGRAM DEMO                                 }
{   Copyright (c) 1997 by Tom Wellige            }
{   Donated as FREEWARE                          }
{                                                }
{   E-Mail: wellige@geocities.com                }
{                                                }
{************************************************}


{  Example program for handling datas inside of objects and   }
{  TCollections.                                              }
{                                                             }
{  Freeware, Author: Tom Wellige                              }
{                                                             }
{  The unit DATA provides a TDATA object which holds a single }
{  data record. A TCollection object from the OBJECTS unit    }
{  manages all data objects in a linked list. A TStream       }
{  object is used to store/restore all data records on the    }
{  disk.                                                      }
{                                                             }
{  To do so, TStreams puts the TCollection which puts each    }
{  single TData object. The TData object knows by it's own    }
{  how to read from and write itself into a file.             }

program DEMO;

uses Crt, Objects, Data;

var
  c: char;
  { This list holds all data records }
  Liste: PCollection;

const
  DateiName: string = 'ANYDATA.DAT';


{ Eine simple Screen }
procedure Screen;
begin
  clrscr;
  writeln('Select:');
  writeln('-------');
  writeln;
  writeln('   1    -   Input Data');
  writeln;
  writeln('   2    -   List Data (single record)');
  writeln('   3    -   List data (all)');
  writeln;
  writeln('   4    -   Delete Data (single record)');
  writeln('   5    -   Delete Data (all)');
  writeln;
  writeln('   6    -   Load Data from Disk');
  writeln('   7    -   Write Data on Disk');
  writeln;
  writeln('   ESC  -   Quit');
  writeln;
end;

{ Input Data }
procedure Input;
var
  AInteger: integer;
  AWord: word;
  AString: string;
  Data: PData;
begin
  clrscr;
  writeln('Input Data:');
  writeln('-----------');
  writeln;
  write  ('   An Integer: '); readln(AInteger);
  write  ('   A Word    : '); readln(AWord);
  write  ('   A String  : '); readln(AString);

  Data:= New(PData, Init(AInteger, AWord, AString));
  Liste^.Insert(Data);

  Screen;
end;

{ List Data (single record) }
procedure ListSingle;
var
  Index: Word;
  Data: PData;
  AInteger: integer;
  AWord: word;
  AString: string;
begin
  clrscr;
  writeln('List Data:');
  writeln('----------');
  writeln;

  { Any data in the Collection ? }
  if Liste^.Count = 0 then
  begin
    writeln('   The list is empty.');
    writeln;
  end else
  begin
    writeln('   There are ', Liste^.Count, ' data records in the list.');
    writeln;

    repeat
      write('   Number of data record: '); readln(Index);
    until (Index > 0) and (Index <= Liste^.Count);

    writeln;
    writeln('   Data Record No. ', Index);

    { The first data record in the list has the index 0 }
    Data:= Liste^.At(Index-1);
    Data^.GetData(AInteger, AWord, AString);

    { This would also work:

    AInteger:= Data^.AnyInteger;
    AWord:= Data^.AnyWord;
    AString:= Data^.AnyString;

    But this not the idea of OOP. Surley will each single case
    decides which way will be the best: indirect or direct data
    access. }

    writeln;
    writeln('       Integer: ', AInteger);
    writeln('       Word   : ', AWord);
    writeln('       String : ', AString);

  end;

  writeln;
  writeln('   Press any key...');
  readkey;

  Screen;
end;

{ List Data (all) }
procedure ListAll;
var
  Index: word;
  Data: PData;
  AInteger: integer;
  AWord: word;
  AString: string;
begin
  clrscr;
  writeln('List Data:');
  writeln('----------');
  writeln;

  { Any data in the Collection ? }
  if Liste^.Count = 0 then
  begin
    writeln('   The list is empty.');
    writeln;
  end else
  begin
    writeln('   There are ', Liste^.Count, ' data records in the list.');
    writeln;

    for Index:= 0 to Liste^.Count-1 do
    begin
      Data:= Liste^.At(Index);
      Data^.Getdata(AInteger, AWord, AString);
      writeln('     ', Index+1, ':  Integer: ', AInteger:5, '   Word: ', 
        AWord:5, '  String: ', AString);
    end;
  end;

  writeln;
  writeln('   Press any key...');
  readkey;

  Screen;
end;

{ Delete Data (single record) }
procedure DeleteSingle;
var
  Index: Word;
begin
  clrscr;
  writeln('Delete Data:');
  writeln('------------');
  writeln;

  { Any data in the Collection ? }
  if Liste^.Count = 0 then
  begin
    writeln('   The list is empty.');
    writeln;
  end else
  begin
    writeln('   There are ', Liste^.Count, ' data records in the list.');
    writeln;

    repeat
      write('   Number of data record: '); readln(Index);
    until (Index > 0) and (Index <= Liste^.Count);

    Liste^.AtFree(Index-1);
    writeln('   Data record deleted.');
    writeln;
  end;

  writeln;
  writeln('   Press any key...');
  readkey;

  Screen;
end;

{ Delete Data (all) }
procedure DeleteAll;
begin
  clrscr;
  writeln('Delete Data:');
  writeln('------------');
  writeln;

  { Any data in the Collection ? }
  if Liste^.Count = 0 then
  begin
    writeln('   The list is empty.');
    writeln;
  end else
  begin
    Liste^.FreeAll;
    writeln('   All data records deleted.');
    writeln;
  end;

  writeln;
  writeln('   Press any key...');
  readkey;

  Screen;
end;

{ Load dat from stream, i.e. file }
procedure Load;
var
  S: PStream;
  P: PCollection;
begin
  P:= nil;
  { Open the stream }
  S:= New(PBufStream, Init(DateiName, stOpenRead, 1024));
  if S^.Status = stOk then
  begin
    { Load Collection from stream }
    P:= PCollection(S^.Get);
    if S^.Status <> stOk then
    begin
      writeln;
      write(#7);
      writeln('   ERROR LOADING DATA !');
    end else
    begin
      writeln;
      writeln('   ', P^.Count, ' data records loaded from file.');
    end;
  end else
  begin
    writeln;
    write(#7);
    writeln('   ERROR OPEN FILE !');
  end;

  Dispose(S, Done);

  { Did we have loaded a Collection including their dat from
    the stream successfully ? }
  if P <> nil then
  begin
    { delete old list }
    Dispose(Liste, Done);
    { repleace with new list }
    Liste:= P;
  end;

end;

{ Save data in stream, i.e. file }
procedure Store;
var
  S: PStream;
begin
  { Open the stream }
  S:= New(PBufStream, Init(DateiName, stCreate, 1024));
  if S^.Status = stOk then
  begin
    { put Collection including their data into stream }
    S^.Put(Liste);
    if S^.Status <> stOk then
    begin
      writeln;
      write(#7);
      writeln('   ERROR WRITING DATA !');
    end;
  end else
  begin
    writeln;
    write(#7);
    writeln('   ERROR OPEN FILE !');
  end;

  Dispose(S, Done);

end;


procedure Init;
begin
  { Initialize the Collection (data list). Allocates memory for management
    data for 10 data objects. When reaching this amount allocate new
    memory for management data for 5 additional data objects. }
  Liste:= New(PCollection, Init(10, 5));
  { This is necessary to be able to use TCollection and TData with
    a Stream. }
  Register;
  { Paint screen }
  Screen;
end;


procedure Done;
begin
  { Delete list including it's data }
  Dispose(Liste, Done);
end;


begin
  Init;

  repeat

    c:= readkey;
    case c of
      '1': Input;
      '2': ListSingle;
      '3': ListAll;
      '4': DeleteSingle;
      '5': DeleteAll;
      '6': Load;
      '7': Store;
    end;

  until c = #27;

  Done;
end.

page up

This page was created using Code Colorizer -    http://www.chami.com/colorizer





Bookmark this page.
 
 

Copyright © Tom Wellige, 1995-2008
All Rights Reserved