Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Short Strings in a Variant Record?

I'd like to be able to access sections of a short string as part of a record

Something like

TMyRecord = record
    case Boolean of
        True: 
        (
            EntireString: String[20];
        );
        False
        (
            StringStart: String[8];
            StringMiddle: String[4];
            StringEnd: String[8];
        );
end;

Is this possible or would I have to declare each char individually

TMyRecord = record
    private
        Chars: Array[1..20] of Char;
        Function GetStringStart:String;
        Procedure SetStringStart(Value: String);       
    public
        Property StringStart: String read GetStringStart write SetStringStart; // Can I have properties on a record?
end;

Function GetStringStart: String;
begin
    Result := Chars[1] + Char[2]....;
end;

Procedure SetStringStart(Value: String);   
begin
    for i := 1 to 8 do
    begin
        Chars[i] := Value[i];
    end;
end; 

Is this possible / worth the effort?

like image 538
James Barrass Avatar asked Nov 27 '25 09:11

James Barrass


2 Answers

A Delphi short string contains more than just the string contents. The initial byte in the data structure contains the length of the string. This is why short strings are limited to 255 characters.

So, you can't use short strings in your variant array the way you propose.

What you could do is adapt your second approach based on getter and setter methods to be a bit more readable.

For example:

function TMyRecord.GetStringStart: string;
begin
  SetString(Result, @Chars[1], 8);
end;

You might consider using a string rather than a char array, but it's a little hard to be 100% sure of that advice without knowing exactly what your underlying problem is.

As a final thought, why not turn the problem around? Store 3 strings: StartString, MiddleString and EndString. Then have a property backed with a getter and setter called EntireString. When you read EntireString it pieces it together from the 3 individual parts, and when you write to it it pulls the individual parts out. I suspect it would be easier that way around.

like image 189
David Heffernan Avatar answered Nov 29 '25 22:11

David Heffernan


Your first sample doesn't consider the length byte. The memory layout looks like this:

case True:
L12345678901234567890
^....................

case False:
L12345678L1234L12345678
^........^....^........

(L = length byte).

Depending on your requirements (e.g.: Are the partial strings always 8, 4 and 8 Chars?) I'd try storing the partial strings and make EntireString the property, using System.Copy, StrUtils.LeftStr etc.

like image 42
Uli Gerhardt Avatar answered Nov 29 '25 23:11

Uli Gerhardt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!