Strings and Formatting - CPULL/Dflat GitHub Wiki

Strings and Formatting

Dflat handles strings natively as UTF-8 data, heavily optimized for both short and long text, and includes a comprehensive formatting engine for data conversion.

String Basics

Strings in Dflat are UTF-8 encoded. The .len property returns the number of characters, while .sizeof returns the size in bytes.

  • Literals: Declared with double quotes (e.g., "text").
  • Concatenation: The + operator concatenates string and other types. "The" + ' ' + "book " + 32 is "The book 32". It evaluates left to right, so : 1 + 2 + "a" is equivalent to (1 + 2) + "a" and results in "3a".
  • Comparing strings and chars: == between a string and a char is true only if the string is exactly that one character ("\n" == '\n' is true, "\n\n" == '\n' is false). != is its opposite, so any string longer than one character is always != a char. <, >, <= and >= compare the char as a one-character string.
  • Comparing chars and integers: a char can be compared with an integer, using its code point (c == 13); the compiler emits a level 2 warning. In + a char is always treated as text: 'a' + 1 is "a1".
  • Nulls and Empty Strings: In Dflat, "" and null are identical. Because string is already nullable by default, declaring string? is a compile error, and strings cannot be unwrapped using enforce.
  • Memory Optimization: "Small strings" (up to 62 bytes) are stored compactly in a 64-byte block with a 1-byte length prefix. Large strings use a 32-byte header and can allocate 4 KB blocks. A compact string is inherently a valid C string.

Escapes and Interpolation

  • Escapes: Standard escapes are supported (\n, \r, \t, \\, \', \", \0). Unicode code points can be written in hex (\u{1F600}) or decimal (\#{123}). Invalid code points in literals trigger a compile error, while casting to a char an illegal code point generates an Exception.
  • Interpolation: Prefix a string with $ to inject expressions directly. Expressions must be wrapped in braces: $"Hello {name}". Use \{ and \} if you need literal braces.
    string greeting = $"Hello {name}, total is {x:D,02}"
    

Formatting Engine

Formatting is applied either via interpolated strings ($"{expr:spec}") or by calling the toStr("spec") method, which is available on all native types and classes. Formatting options can be combined in any order.

Number Formatting

Options are case-insensitive (except for upper/lower hex h/H):

  • Bases: bd (decimal, default), bh / bH (hex lowercase and uppercase), bb (binary), bo (octal), b64 (base-64).
  • Decimals (D): Specifies separators, fixed size, and rounding modes (e.g., u for half-up, b for banker's, c for ceil).
  • Signs (S): Control sign display. S- (negatives only, default), S+ (always), S() (parentheses for negatives).
  • Layout: Width (w<n>), fill character (f<char>), and alignment (a< left, a> right, a^ center, a. on decimal).
  • Scientific (e): Mantissa with one non-zero digit before the decimal. Format: e[<lit>]<min> (e.g., e[E+]02D2 outputs 1.23E+03).

String Formatting

  • Layout: Width in characters (w<n>), fill (f<char>), and alignment (a<, a^, a>).
  • Case adjustments: Upper (cU), lower (cL), sentence case, first letter up all others lower (cS), and title case, all first letters up (cT).
  • Trimming & Truncation: Trim both/left/right sides (s, sl, sr), or truncate keeping the start (t<'…') or the end (t>'…'), with a marker counted in the width.

Date Formatting

Dflat supports standard C# custom pattern letters (d, f, F, g, h, H, k, m, M, s, t, y, z) plus several additions:

  • w (week), q (quarter), i (ISO week), r (ISO year), e (day of year), j (day of week).

  • Spacing: Doubling any of the formatting letters pads the output with a space.

  • Alignment: Dates can be aligned using a< (left), a^ (center), or a> (right) followed by the width (e.g., a<20), with no truncation applied.

  • y: Year. yy outputs the last two digits, and yyyy outputs the full four digits.

  • M: Month (1–12). MM zero-pads, MMM gives the abbreviated name, and MMMM gives the full name.

  • d: Day of the month (1–31). dd zero-pads to two digits.

  • g: Era or period (e.g., A.D.).

  • k: Time zone information (e.g., +01:00).

  • z: Time zone offset from UTC in whole hours.

  • h: Hour using a 12-hour clock (1–12). hh zero-pads.

  • H: Hour using a 24-hour clock (0–23). HH zero-pads.

  • m: Minute (0–59). mm zero-pads.

  • s: Second (0–59). ss zero-pads.

  • t: AM/PM designator (e.g., t for A/P, tt for AM/PM).

  • f: Fractions of a second (e.g., ff for hundredths, fff for milliseconds).

  • F: Fractions of a second, but trailing zeros are omitted.

  • w: Week.

  • q: Quarter.

  • i: ISO week.

  • r: ISO year.

  • e: Day of the year (fixed to 3 characters wide).

  • j: Day of the week.

Formatting works in the same way in interpolated strings:

date now = Root.Now()
string today = $"{now:yyyyMMdd}"

and with toStr():

string today = Root.Now().toStr("yyyyMMdd")
⚠️ **GitHub.com Fallback** ⚠️