Unit ObjStr; { During the creation of many programs, I have been bugged by the fact that every "standard" string declared takes up 256 bytes of memory. If you try to work around this by declaring 'AVariable : String[5]' or some such, you then have to turn off Var-String checking when passing these variables to functions and procedures expecting variables of type 'String'. Writing your own procedures and functions for these variables has the same draw- back. This is my second attempt at another solution. The first attempt was implemented for a graphics mode program, was much more complicated, and was (is) too hard to maintain. I think this unit worked out better. As far as overhead is concerned, each instance requires 8 bytes (7 for object fields, 1 for length byte) plus the number of chars for that type. In other words, an instance of object type Str10 would require 18 bytes. You have the plusses of working with objects (encapsulation, extensibilty, ...etc.) and bypassing the Var-string checking problems that 'String[10]' poses. On the minus side, if you're the type who doesn't mind turning off Var-string checking and declaring all those different string types, this approach "wastes" 8 bytes per variable. With those 8 bytes, however, comes the freedom to use Str10.Val as type String. This unit works with TP 5.5 & 6.0 (just compile with appropriate version). This code may be freely copied and distributed. The user of this unit may not hold me liable for any damages resulting from the use or misuse of this unit. Any modifications to this unit should be noted if modified code is distributed. Comments, questions, and optional monetary contribu- tions should be made to: Jim Fralix 415 Parkdale Dr. Apt. 5-B Charleston, SC 29414 } Interface Const Zero : Byte = 0; Type StrPtr = ^String; StringObj = Object { Do not Define an instance of this, as Size is never defined } Constructor Init; { Allocates memory for MUST be called before using other functions the string } Procedure Read; Virtual; { Reads CR terminated Ex. StringObj.Read; String from keyboard, truncates to max len. } Procedure Write; Virtual; { Writes String value Ex. StringObj.Write; to Screen (TextMode) } Procedure SetTo (InStr : String); Virtual;{ Set string value equal Ex. StringObj.SetTo (InStr); to InStr, truncates if necessary} Function Value : String; Virtual; { Returns string value, Ex. NormStr := StrObj.Value; useful in standard Ex. Writeln ('Object String = ',StringObj.Value); procs & funcs needing a "normal" string } Destructor Done; { Delallocates memory } Private S : pointer; { To Access as String w/length Byte at index 0 } Size : Byte; { Stores max length, set by init procedure } End; { THESE ARE THE USABLE OBJECTS - TO IMPLEMENT A NEW STRING SIZE, JUST DEFINE IT AND CODE THE APPROPRIATE 'INIT' CONSTRUCTOR } Str2 = Object (StringObj) Constructor Init; { Sets Size to 2, allocates memory } End; Str3 = Object (StringObj) Constructor Init; { Sets Size to 3, allocates memory } End; Str4 = Object (StringObj) Constructor Init; { Sets Size to 4, allocates memory } End; Str5 = Object (StringObj) Constructor Init; { You should have the idea by now! } End; Str7 = Object (StringObj) Constructor Init; End; Str8 = Object (StringObj) Constructor Init; End; Str10 = Object (StringObj) Constructor Init; End; Str12 = Object (StringObj) Constructor Init; End; Str15 = Object (StringObj) Constructor Init; End; Str18 = Object (StringObj) Constructor Init; End; Str20 = Object (StringObj) Constructor Init; End; Str25 = Object (StringObj) Constructor Init; End; Str30 = Object (StringObj) Constructor Init; End; Str35 = Object (StringObj) Constructor Init; End; Str40 = Object (StringObj) Constructor Init; End; Str50 = Object (StringObj) Constructor Init; End; Str60 = Object (StringObj) Constructor Init; End; Str70 = Object (StringObj) Constructor Init; End; Str80 = Object (StringObj) Constructor Init; End; Str90 = Object (StringObj) Constructor Init; End; Str100 = Object (StringObj) Constructor Init; End; Var TempStr : String; { Sometimes you gotta have a standard string! } Implementation Constructor StringObj.Init; { Called by the other INIT Procedures } Begin GetMem (S, Size+1); { Allocate mem. for length byte & chars } Move (Zero, S^, 1); { Init to null String (length byte of 0) } End; Procedure StringObj.Read; { Read CR terminated string from input } Begin Readln (TempStr); Move (TempStr, StrPtr(S)^, Size+1); If (Length (TempStr) > Size) then { need to truncate } Move (Size, StrPtr(S)^, 1); End; Procedure StringObj.Write; { WritesString at current cursor location } Begin System.Write (StrPtr(S)^); End; Procedure StringObj.SetTo (InStr : String); { Sets value of StringObj } Begin Move (InStr, StrPtr(S)^, Size+1); If (Length(InStr) > Size) then { need to truncate } Move (StrPtr(S)^, Size, 1); End; Function StringObj.Value : String; { Returns string value of StringObj } Begin Value := StrPtr(S)^; End; Destructor StringObj.Done; { Releases Memory } Begin FreeMem (S, Size+1); End; Constructor Str2.Init; Begin Size := 2; StringObj.Init; End; Constructor Str3.Init; Begin Size := 3; StringObj.Init; End; Constructor Str4.Init; Begin Size := 4; StringObj.Init; End; Constructor Str5.Init; Begin Size := 5; StringObj.Init; End; Constructor Str7.Init; Begin Size := 7; StringObj.Init; End; Constructor Str8.Init; Begin Size := 8; StringObj.Init; End; Constructor Str10.Init; Begin Size := 10; StringObj.Init; End; Constructor Str12.Init; Begin Size := 12; StringObj.Init; End; Constructor Str15.Init; Begin Size := 15; StringObj.Init; End; Constructor Str18.Init; Begin Size := 18; StringObj.Init; End; Constructor Str20.Init; Begin Size := 20; StringObj.Init; End; Constructor Str25.Init; Begin Size := 25; StringObj.Init; End; Constructor Str30.Init; Begin Size := 30; StringObj.Init; End; Constructor Str35.Init; Begin Size := 35; StringObj.Init; End; Constructor Str40.Init; Begin Size := 40; StringObj.Init; End; Constructor Str50.Init; Begin Size := 50; StringObj.Init; End; Constructor Str60.Init; Begin Size := 60; StringObj.Init; End; Constructor Str70.Init; Begin Size := 70; StringObj.Init; End; Constructor Str80.Init; Begin Size := 80; StringObj.Init; End; Constructor Str90.Init; Begin Size := 90; StringObj.Init; End; Constructor Str100.Init; Begin Size := 100; StringObj.Init; End; { Begin Writeln ('Size of ObjStr is ',SizeOf(StringObj):1); } End.