home *** CD-ROM | disk | FTP | other *** search
-
-
- Dear Turbo Pascal 6.0/Windows programmer,
-
-
-
- Thank you for downloading the Loose Data Binder! The
- Binder combines concepts from FlexList, OOP's generic
- container objects, and Borland's TurboVision/ObjectWindows
- TCollection object.
-
-
-
- Adaptability
- ============
-
- Think of the Loose Data Binder as a loose-leaf notebook.
- You can insert data into the LDB just like inserting pages
- into a notebook. And of course you can just as easily take
- the data back out. You can access the LDB as if it were a
- combination stack-queue-deque-list-array. You can arrange
- your data in any order and even specify a compare function
- for sorting and/or searching. The LDB expands or contracts
- automatically to accommodate varying numbers of nodes. The
- CopyBinder, derived from Binder (LDB), gives the LDB the
- ability to clone the data you want stored in a LDB on the
- fly. It can also copy the data to/from the LDB nodes and
- your variables. Since a LDB is initialized at run time,
- the data it holds or even its creation can be specified at
- run time, thus allowing your applications new dimensions of
- adaptability to user inputs.
-
-
-
- Getting Started
- ===============
-
- Copy bind.pas to your compiler's standard source directory.
- Now for an example. The compile and run LDB1.PAS. Its
- contents are listed below. It builds a LDB of cloned nodes
- and then displays them in several different ways.
-
-
-
- program ldb1;
- uses bind;
-
- type strPtr = ^string;
-
- procedure display(D, M, A : pointer); far;
- type strPtr = ^string;
- intPtr = ^integer;
- var i : integer;
- begin
- i := length(strPtr(D)^);
-
- inc(intPtr(A)^,i);
- writeln('length: ',i,
- ' accumulated: ',intPtr(A)^,
- ' string: ',strPtr(D)^);
- end;
-
- function strcmp(D1, D2 : pointer) : integer; far;
- begin
- if (strPtr(D1)^ < strPtr(D2)^) then
- strcmp := -1
- else if (strPtr(D1)^ > strPtr(D2)^) then
- strcmp := 1
- else
- strcmp := 0
- end;
-
-
- const
- s1 : string = 'Now is the time';
- s2 : string = 'for all programmers';
- s3 : string = 'to stop reinventing';
- s4 : string = 'the linked list!';
-
-
- var B : CopyBinder;
- i : word;
-
- begin
- B.Init(CSTRING);
-
- B.pushC(@s1);
- B.insqC(@s2);
- B.atInsC(B.getNodes,@s3);
- B.insqC(@s4);
-
- while (B.next) do
- writeln(strPtr(B.current)^);
-
- writeln;
-
- for i := 0 to (B.getNodes - 1) do
- writeln(strPtr(B.atGet(i))^);
-
- writeln;
-
- i := 0;
-
- B.forEach(display,nil,@i);
-
- writeln;
-
-
- B.setCompare(strcmp);
- B.sort;
-
- i := 0;
-
- B.forEach(display,nil,@i);
-
- B.Done;
-
- readln
-
- end.
-
-
- Notice that first the LDB is pushed like a stack. Next it
- is queued, arrayed, and finally queued. Next is used to
- walk across the binder. Notice that stack, queue, and
- array primitives don't disturb the current node!
-
-
- The LDB also has built in iterators, much more powerful than
- TurboVision's TCollection. The forEach iterator applies the
- given function against each element of the LDB and passes in
- what can be used as a mask and an accumulator. I'm using
- the accumulator to sum the length of strings printed thus
- far.
-
- Next a compare function is specified for the LDB and a sort
- is performed.
-
- The CopyBinder destructor calls Dfree() for each element
- when discarding the instance. Please note that the Binder
- destructor does not, by default, which allows it to bind
- data variables in your program. If you use the CopyBinder
- to bind non allocated data, besure to override its
- destructor so that it doesn't try to delete non-dynamic
- data!
-
-
-
- Our next example can be found in ldb2.cpp.
-
-
-
- program ldb2;
- uses bind;
-
- type strPtr = ^string;
-
-
- const
- s1 : string = 'Now is the time';
- s2 : string = 'for all programmers';
- s3 : string = 'to stop reinventing';
- s4 : string = 'the linked list';
- s5 : string = 'and container classes.';
-
-
- function strcmp(D1, D2 : pointer) : integer; far;
- begin
- if (strPtr(D1)^ < strPtr(D2)^) then
- strcmp := -1
- else if (strPtr(D1)^ > strPtr(D2)^) then
- strcmp := 1
- else
- strcmp := 0
- end;
-
-
- var B : Binder;
- i : word;
-
- begin
- B.Init;
- B.setDelta(1);
- B.setLimit(3);
- B.setMaxNodes(3);
-
- B.push(@s1);
- B.insq(@s2);
- B.atIns(B.getNodes,@s3);
- B.insq(@s4);
- B.insq(@s5);
-
- while (B.next) do
- writeln(strPtr(B.current)^);
-
- B.setComparE(strcmp);
- if (B.findFirst(@s3) <> BNOTFOUND) then
- writeln(strPtr(B.current)^);
-
- B.Done;
-
- readln
-
- end.
-
-
- I've used the Binder class here, which only binds pointers
- to data. The constructor is called, and then the LDB is
- restricted to having a maximum of three nodes. The
- following relationship is always maintained in a LDB:
-
- 1 <= delta <= limit <= maxNodes <= BMAXNODES
-
- The last two fail which cause them to call the binder
- error function explaining there are no vacancies left.
-
- Next the compare function is set and a search is performed.
- The LDB knows automatically that it isn't sorted so the
- search is a linear one. If it had been sorted than a
- binary search would have been used internally. FindFirst
- set the current node and returns its index.
-
- Remember the Binder destructor, by default, doesn't delete
- its member elements.
-
-
-
- For our last example, let's revisit the CopyBinder class.
-
- I didn't tell you before, but CopyBinder has two virtual
- functions, Dclone() and Dcopy(), that tells its other
- member functions how to clone and copy your data in the
- course of operations. CSTRING is defined as 0, which tells
- these functions to treat the data as normal C strings.
- When cloning the data, the clone was only made as big as
- necessary to hold the string being warehoused. If you
- give it another value, other than 0, then cloning and
- copying will be performed for data of this fixed size.
- If you have variant data, other than strings, or data with
- suballocated memory, than you can override these functions
- to handle your data accordingly. Besure to override Dfree()
- as appropriate. For this example, though, we'll use fixed
- sized data.
-
- The following listing can be found in ldb3.cpp.
-
-
-
- program ldb3;
- uses bind;
-
-
- type
-
- YourRecPtr = ^YourRec;
- YourRec = record
- name : ^string;
- end;
-
-
- procedure display(D, M, A : pointer); far;
- begin
- writeln(YourRecPtr(D)^.name^)
- end;
-
- const
- s : string = 'Pat Programmer';
-
-
- var
- B : CopyBinder;
- R : YourRec;
- i : word;
-
- begin
- B.Init(sizeof(YourRec));
-
-
- R.name := @s;
-
- for i := 1 to 10 do
- B.ins(@R);
-
- B.forEach(display,nil,nil);
-
- B.allDel;
-
- B.Done;
-
- readln
-
- end.
-
-
-
-
-
-
- Here the CopyBinder is constructed to clone and copy data
- that is sizeof(YourRec) bytes long. As it turns out though,
- I don't call any cloning functions (they end in capital C
- for Clone/Copy). Since CopyBinder is derived publicly from
- the Binder object the latter's functions are still available.
-
- The forEach iterator is used to display the elements.
- Notice that B.allDel is called to discard all elements of
- the binder without disposing them before the destructor can
- get at them to dispose them. Deleting nonallocated memory
- can be pretty serious business. Don't do it!
-
- This program brings up another point though. It has simply
- inserted five pointers to the same record. Even if I
- had called B.insC() instead there would have been five
- copies containing five pointers to the same name string:
- "Pat Programmer". You must be sure to resolve double
- ownership problems. Please note that if B.insC() had been
- called instead of calling B.ins() then B.allDel would
- have discarded the pointers to these five clones without
- disposing them! Since Dfree(), Dclone(), Dcopy() are virtual,
- your can resolve any complexities inherent in your data
- types by overriding these functions.
-
-
-
- Diving In
- =========
-
- I've tried to give you a flavor for the LDB and keep the
- download file to a reasonable length. Since you have the
- source code, study it, it's not too long. And use the
- bind.pas interface section as a quite reference guide.
-
-
-
- Small Code Sizes, Less Testing
- ==============================
-
- Your applications can now have as many stacks, queues,
- deques, lists, and/or elastic arrays without code size
- explosion. That's because the LDB operates on any type of
- data, so new objects needn't be derived to accommodate new
- data types. Laborious testing of a myriad of linked list
- primitives, especially for boundary condition faults, is
- thus avoided.
-
-
-
- Coherent Flexible Design - Lower Investment
- ===========================================
-
- It's no problem modifying your applications in midstream to
- incorporate various and differing list types, with the LDB
- no linked list code needs to be scrapped or rewritten.
- Investment in non reusable linked list code is essentially
- eliminated. And with uniformity across applications and
- between Turbo Pascal and Turbo/Borland C++ versions, your
- software maintenance costs can be greatly reduced.
-
-
-
- Less, Less, Less ...
- ====================
-
- When you use LDB's for all your linked list needs, your
- applications will require:
-
- * less documentation
- * less testing
- * less code space
- * less programming time
- * less investment in non reusable code
- * less software maintenance effort
- * less cross application training
-
-
-
- Get Popping - Register Today!
- =============================
-
- Register bind.pas today and get your applications popping!
- This version of bind.pas is shareware meaning try before you
- buy. It is provided for your convenience in evaluating the
- product to reach a buy/no buy decision. For any other use
- you are required, by law, to register. Registration,
- provides you with a license to use bind.pas and its
- associated files in your applications without royality.
-
- TP Loose Leaf Binder registration fee ... $15
-
- Upon registration, you will be sent a DOS formatted diskette
- with the next version of the LDB tool, when available.
- Please specify 3.5" or 5.25" diskette and the date of your
- current version! If I receive 100 or more registrations,
- I will write a full length manual and put a ready to print
- copy on diskette. Registrants are entitled to telephone
- support.
-
- Make your check or money order payable to:
-
- PSW / Power SoftWare
- P.O. Box 10072
- McLean, VA 22102 - 8072
- USA (703) 759-3838
-
-
-
- Additional Versions
- ===================
-
- Depending on demand, a version will be introduced for ANSI C.
- Please feel free to contact me with your comments or
- suggestions. If you call, please don't call in the middle of
- the night or on Sundays!
-
-
-
-
- Background
- ==========
-
-
- I had a need to port FlexList to Microsoft Windows and other
- "after-thought" virtual memory systems and also to expand it
- into what I call a PolyMesh, polymorphic nodes belonging to
- more than one FlexList at the same time.
-
- What you have downloaded here is a TP version incorporating
- the functionality of TCollect married to the functionality
- of FlexList. The binder is not streamable here. That code
- I extracted since most won't need it until their programs
- grow much more complex.
-
- Thanks again! John
-
-
-
-