|
ShortString |
Top Previous Next |
|
Pretranslated C# code > Delphi RTL > ShortString Delphi2C# converts the Delphi ShortString type to System.ShortString.
System.ShortString is a byte-based runtime type with a maximum payload length of 255 bytes. It remains distinct from C# string, AnsiString, WideString, and UnicodeString.
The separate type allows generated C# code to preserve the Delphi length byte, fixed maximum capacity, one-byte elements, code pages, embedded null bytes, truncation rules, PAnsiChar conversions, and vtString array of const values.
The generated code normally imports the required runtime declarations with:
using System; using static System.SystemInterface;
An unqulified Delphi ShortString has a maximum payload length of 255 bytes and occupies 256 bytes in Delphi storage: one length byte followed by 255 payload bytes.
Default initialization
An unqualified Delphi ShortString variable is initialized with ShortString.Empty:
Delphi:
var S: ShortString;
C#:
ShortString S = ShortString.Empty;
The empty value has Length zero, LengthByte zero, and MaximumLength 255.
A bounded Delphi string[N] variable is initialized with ShortString.Create(N), which preserves the declared capacity even while the value is empty:
Delphi:
var S: string[20];
C#:
ShortString S = ShortString.Create(20);
The allowed MaximumLength range is zero through 255. Values outside this range are rejected by the runtime.
Runtime representation
System.ShortString stores the active payload bytes, the effective code page, and the declared MaximumLength.
Length is the number of active payload bytes. LengthByte exposes the same value as byte and models the first byte of Delphi ShortString storage.
DelphiStorageSize is MaximumLength + 1. ToDelphiBuffer creates the complete Delphi representation containing the length byte followed by the declared payload capacity. Bytes beyond the active Length are zero filled.
ToLengthPrefixedByteArray creates the compact active representation containing one length byte followed only by the active payload bytes.
Embedded zero bytes are valid payload data and remain included in Length. ShortString is length based and does not use a zero byte as its terminator.
Assignments and truncation
A string literal assigned to an unqualified ShortString remains a C# string literal. The implicit conversion encodes the literal with the configured default ANSI code page:
Delphi:
S := 'Pascal';
C#:
S = "Pascal";
Assignment to a bounded string[N] must preserve the capacity declared by the destination. Delphi2C# emits ShortString.Assign with the declared maximum length:
Delphi:
var S: string[4]; begin S := 'abcdef';
C#:
ShortString S = ShortString.Create(4); ShortString.Assign(ref S, (ShortString)"abcdef", 4);
The resulting payload is "abcd". Data beyond the destination capacity is truncated, matching Delphi ShortString assignment behavior.
The destination code page is retained when an existing bounded value receives another ShortString. A source with a different code page is converted before the payload is truncated to MaximumLength.
AnsiChar values are represented as byte and can be converted to a one-byte ShortString:
Delphi:
S := C;
C#:
S = C;
Code pages
ShortString uses the same configurable ANSI code-page infrastructure as AnsiString. Code page zero is resolved through AnsiStringSettings.DefaultCodePage when a value is created.
The default code page is Windows-1252, matching a typical US Windows installation:
AnsiStringSettings.DefaultCodePage = 1252;
AnsiStringSettings.ConversionMode controls replacement or exception fallback at Unicode conversion boundaries. DelphiCompatible uses replacement fallback, while Strict reports invalid or lossy conversions.
Existing ShortString values retain their resolved code page if the process-wide default is changed later.
Length and payload indexing
The System.ShortString C# indexer is zero-based and returns byte. Delphi payload indexes are one-based, so Delphi2C# subtracts one from normal ShortString element access.
Delphi:
C := S[1]; C := S[Length(S)];
C#:
C = S[1 - 1]; C = S[Length(S) - 1];
The indexed value has type byte because Delphi ShortString elements have type AnsiChar.
System.ShortString is immutable, so an indexed payload write becomes ShortString.SetByte with a ref destination:
Delphi:
S[1] := 'p';
C#:
ShortString.SetByte(ref S, 1 - 1, (byte)'p');
Invalid payload indexes raise ArgumentOutOfRangeException in the managed runtime.
The special S[0] length byte
Delphi ShortString permits direct access to S[0], which is the stored length byte. This operation is different from payload indexing and is translated separately.
Reading S[0] becomes LengthByte:
Delphi:
L := Byte(S[0]);
C#:
L = S.LengthByte;
Writing S[0] changes the active length and becomes ShortString.SetLengthByte:
Delphi:
S[0] := AnsiChar(3);
C#:
ShortString.SetLengthByte(ref S, 3);
The new length cannot exceed MaximumLength. Shrinking keeps the requested prefix, while growing preserves existing bytes and adds zero bytes.
Length and SetLength
The Delphi Length function binds to the ShortString overload and returns the active payload byte count:
length = Length(S);
High returns the Delphi high payload index, which is equal to Length. Low returns one.
SetLength binds to the ShortString overload and replaces the immutable value through a ref parameter:
Delphi:
SetLength(S, 10);
C#:
SetLength(ref S, 10);
The requested length must remain between zero and the destination MaximumLength. Growing the managed value adds deterministic zero bytes.
Copy, Pos, Insert, and Delete
Delphi2C# binds standard string functions to typed ShortString overloads instead of converting the operands to C# string.
Copy, Insert, and Delete receive positions that the generator has already translated from one-based Delphi indexes to zero-based C# indexes:
Delphi:
Part := Copy(S, 2, 3); Insert('XY', S, 3); Delete(S, 2, 3);
C#:
part = Copy(S, 2 - 1, 3); Insert((ShortString)"XY", ref S, 3 - 1); Delete(ref S, 2 - 1, 3);
Insert preserves the destination MaximumLength and truncates data that would exceed the declared capacity.
Pos retains the Delphi result contract and returns a one-based byte position or zero when no match is found:
position = Pos((ShortString)"cat", S);
The instance method IndexOf follows C# rules instead. It accepts and returns zero-based indexes and returns -1 when the value is not found.
Immutability
System.ShortString is immutable even though a Delphi ShortString variable is writable inline storage.
Delphi2C# reproduces writes by replacing the destination variable. SetByte, SetLength, SetLengthByte, Insert, Delete, SetString, and Move receive or update the destination through ref where necessary.
Copying a ShortString reference in generated C# is safe because a later translated write creates a new value and leaves the previous value unchanged. This reproduces the value behavior expected from separate Delphi ShortString variables.
Concatenation and comparison
Delphi ShortString concatenation is emitted with the C# + operator. The result uses the code page and MaximumLength of the left operand.
ShortString result = left + " " + right;
The right operand is converted to the left operand's code page when necessary. The result is truncated when the combined payload would exceed the left operand's MaximumLength.
Equality, ordering, and hashing compare payload bytes. CodePage and MaximumLength are not part of byte equality, so values with identical active bytes compare as equal even if their metadata differs.
Comparison with a C# string literal encodes the literal with the ShortString code page before comparing the bytes.
Conversions
The conversion from C# string to ShortString is implicit so generated literal assignments remain compact:
ShortString value = "Text";
The conversion from ShortString to C# string is explicit because it crosses from ANSI bytes to UTF-16 text:
string text1 = value.Decode(); string text2 = (string)value;
ToString also decodes the payload. Generated byte-preserving code does not call Decode before selecting a ShortString overload.
Conversions between ShortString and byte[] copy the active payload bytes and perform no character encoding:
byte[] bytes = value.ToByteArray(); ShortString copy = ShortString.FromBytes(bytes, value.CodePage, value.MaximumLength);
Conversion from ShortString to AnsiString preserves the active bytes and code page but removes the ShortString maximum-length restriction:
AnsiString ansi = value.ToAnsiString();
Conversion from AnsiString to ShortString converts to the selected code page and truncates the result to MaximumLength.
PAnsiChar conversion
Delphi2C# maps a ShortString-to-PAnsiChar cast to the typed runtime conversion:
Delphi:
P := PAnsiChar(S);
C#:
P = (PAnsiChar)S;
The managed pointer receives a null-terminated copy of the active payload bytes and retains the ShortString code page.
An empty ShortString produces a non-null pointer buffer containing a zero terminator. This models the inline storage available for an empty Delphi ShortString and differs from an empty AnsiString cast, which produces a null PAnsiChar.
The typed Addr overload also returns PAnsiChar after Delphi2C# translates the payload index:
Delphi:
P := Addr(S[2]);
C#:
P = Addr(S, 2 - 1);
SetString with a PAnsiChar source and explicit length copies exactly that number of bytes up to MaximumLength. Embedded zero bytes are preserved because this overload does not rely on null termination.
Move operations
Delphi2C# binds Move involving ShortString to byte-oriented overloads. Source offsets, destination offsets, and count values are byte based after index translation.
Delphi:
Move(Source[2], Dest[3], 4);
C#:
Move(Source, 2 - 1, ref Dest, 3 - 1, 4);
The destination must already have a sufficient active Length, normally after assignment or SetLength. Move does not enlarge a ShortString.
The RTL provides byte-preserving overloads between ShortString, AnsiString, byte[], PAnsiChar, and UTF-16 string storage. These overloads copy memory bytes exactly and do not decode or encode text.
Move between ShortString and UTF-16 string storage uses the little-endian UTF-16 byte representation to reproduce Delphi memory behavior independently of the host platform.
UTF-8 functions
Delphi2C# preserves ShortString as a separate overload type for UTF-8 conversion functions.
UTF8ToString and UTF8ToUnicodeString receive ShortString directly and decode its payload as UTF-8:
string text = UTF8ToString(shortValue);
Delphi2C# does not emit shortValue.Decode() before this call because Decode would use the ShortString code page before the UTF-8 overload is selected.
UTF8EncodeToShortString returns ShortString instead of AnsiString or C# string:
ShortString encoded = UTF8EncodeToShortString(text);
The managed implementation reserves one byte for Delphi's trailing null during this conversion, so an unqualified ShortString receives at most 254 UTF-8 payload bytes. Truncation does not split a multibyte UTF-8 sequence.
TVarRec and array of const
Delphi ShortString in an array of const uses TVarRec VType vtString. It must remain distinct from vtAnsiString and vtUnicodeString.
A statically typed ShortString expression uses the implicit conversion or the typed factory:
TVarRec first = shortValue; TVarRec second = TVarRec.FromShortString(shortValue);
The runtime stores the ShortString value and reads it with ToShortStringValue or the VString property:
ShortString value1 = argument.ToShortStringValue(); ShortString value2 = argument.VString;
ToStringValue decodes ShortString to C# string and therefore crosses to Unicode. Generated code uses ToShortStringValue when the original Delphi operation requires the payload bytes, code page, or maximum length.
Overload selection
Delphi2C# resolves overloaded Delphi routines from the original static types before inserting C# conversions.
A ShortString argument remains ShortString during overload selection. It is not converted to string or AnsiString merely because either conversion could make another C# overload applicable.
When a literal must select a ShortString overload in the presence of a C# string overload, Delphi2C# emits an explicit ShortString cast:
result = Pos((ShortString)"cat", shortValue);
This rule is especially important for UTF8ToString, UTF8ToUnicodeString, Copy, Pos, SetString, Move, and TVarRec construction.
Translation summary
Delphi2C# applies the following ShortString translation rules:
These transformations preserve Delphi ShortString storage and value semantics without treating the type as a Unicode C# string.
|
|
This page belongs to the Delphi2C# Documentation |
Delphi2C# home Content |