Pascal Viandier wrote:
- In fact, the rows in the database store only the string contents, not the
"capacity" and "length" fields.
There must be some way to store length info. If you do that by blank-padding, then you might consider fixed-strings, i.e., (packed) arrays of Char, as defined in ISO 7185 (it requires packed, GPC doesn't require it), which naturally behave this way and don't have Capacity and Length fields. Since in EP (and thus GPC) these are assignment-compatible to other string types, you can use them only for storing/loading data if you like, and use other string types in operations.
At the early stages of the conversion, I tried "Array[1..x] Of Char" but I lost almost all of the GPC facilities for strings manipulation, and the automatic blank padding when comparing them generated problems.
So how do you retrieve the length? If you get it differently, you could still do something like:
var Length: Integer; Foo: packed array [1 .. x] of Char; s: String (x);
begin { retrieve Foo, Length } if Length = 0 then s := '' else s := Foo[1 .. Length]; end;
Similar for storing.
I also tried my own schemata, similar to the String but with no "Capacity" field.
If you really mean a schema type, it wouldn't help. All schemas in GPC store their disciminants, as String does Capacity.
I was unable to assign contents directly as "MyStr := 'ABC';" (I was unable to implement a custom assignment operator ":=") so I adopted the String() type.
Can't comment on this, without any concrete examples.
- Thanks for the answer to my question regarding the Capacity field after a
call to FillChar. It is clearer for me now. So, do not spend your precious time to test the result of an operation which should not be done. However, I wouldn't call "a low-level trick" the call to FillChar() ;-)
It it a low-level trick, as it does direct memory manipulation, stepping around Pascal typing!
- As Gale Paeper suggested I tried Extended Pascal's initial-state-specifier
and since I do not use variant records in records, this works pretty well and I found no bug in my case. However I decided to generate initialization procedures automatically anyway since the existing code needs more than first-time initialization: FillChar() is potentially called many times on the same variable (between database accesses for example).
You could assign from a local, initialized variable:
type UninitializedMyType = record ... end; InitializedMyType = UninitializedType value [ ... ];
procedure InititalizeMyType (var a: UninitializedType); var Init: InititalizeMyType; begin a := Init end;
Frank