Skip to content

Slice, truncate, and convert scalar values

Slice, truncate, and convert scalar string/decimal values, triggered when caller formats a value for a fixed-width field or performs a numeric test*.

Field Value
Operation ID OP-033
Trigger Caller formats a value for a fixed-width field or performs a numeric test*
Inputs string / decimal
Outputs string / bool / decimal / int
Primary components StringExtensions.Left`, `Right`, `Truncate`, `Repeat`, `Wrap`, `ConvertToDecimalOrZero`, `ContainsOnlyNumericCharacters`; `NumericExtensions.IsNumeric`, `Precision`, `TruncatePrecision
Entry point Common/SAIF.Common/Extensions/StringExtensions.cs

Steps

  1. Left / Right slice without a length guard — an over-long request raises ArgumentOutOfRangeException. (BR-076)
  2. Truncate is the safe variant: it returns null unchanged and clamps the length with Math.Min(value.Length, length). (BR-076)
  3. ContainsOnlyNumericCharacters returns false for null/empty and otherwise requires Regex.Match(target, @"\D") to have zero length — no non-digit character anywhere. (BR-077)
  4. ConvertToDecimalOrZero returns 0 for a null/whitespace input, otherwise Convert.ToDecimal (which throws FormatException on non-numeric text). (BR-078)
  5. NumericExtensions.IsNumeric uses int.TryParse, so it is int-bounded — a decimal value, or one exceeding Int32.MaxValue, reports false. (BR-079)
  6. Precision reads the scale byte via BitConverter.GetBytes(decimal.GetBits(decimalValue)[3])[2] to return the declared decimal-place count. (BR-080)
  7. TruncatePrecision short-circuits to decimal.Truncate when precision is 0; otherwise it scales by 10^precision, truncates (does not round), and scales back. (BR-081)
  8. Repeat concatenates Enumerable.Repeat(value, count); Wrap returns $"{wrapValue}{target}{wrapValue}".

Process flow

The following diagram visualizes this operation's helper methods in the order documented above.

flowchart TD
    Start(["Caller formats a value<br>or performs a numeric test"]) --> S1["Left / Right slice<br>(no length guard)"]
    S1 --> D1{"Requested length exceeds<br>value length?"}
    D1 -->|Yes| X1(["ArgumentOutOfRangeException"])
    D1 -->|No| S2["Truncate: return null unchanged;<br>clamp length via Math.Min"]
    S2 --> S3["ContainsOnlyNumericCharacters"]
    S3 --> D2{"Input is null or empty?"}
    D2 -->|Yes| R1["Return false"]
    D2 -->|No| D3{"Any non-digit character<br>found via regex?"}
    D3 -->|Yes| R2["Return false"]
    D3 -->|No| R3["Return true"]
    R1 --> S4
    R2 --> S4
    R3 --> S4
    S4["ConvertToDecimalOrZero"] --> D4{"Input is null<br>or whitespace?"}
    D4 -->|Yes| R4["Return 0"]
    D4 -->|No| R5["Convert.ToDecimal<br>(throws FormatException<br>on non-numeric text)"]
    R4 --> S5
    R5 --> S5
    S5["IsNumeric via int.TryParse"] --> D5{"Value is decimal or<br>exceeds Int32.MaxValue?"}
    D5 -->|Yes| R6["Return false"]
    D5 -->|No| R7["Return TryParse result"]
    R6 --> S6
    R7 --> S6
    S6["Precision: read scale byte via<br>BitConverter.GetBytes and<br>decimal.GetBits(value)[3])[2]"] --> S7["TruncatePrecision"]
    S7 --> D6{"Precision is 0?"}
    D6 -->|Yes| R8["decimal.Truncate"]
    D6 -->|No| R9["Scale by 10^precision,<br>truncate, then scale back"]
    R8 --> S8
    R9 --> S8
    S8["Repeat: concatenate via<br>Enumerable.Repeat"] --> S9["Wrap: surround value<br>with delimiter"]
    S9 --> End(["Sliced, truncated, or<br>converted scalar value"])

Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.

Sources

  • Common/SAIF.Common/Extensions/StringExtensions.cs
  • Common/SAIF.Common/Extensions/NumericExtensions.cs