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¶
Left/Rightslice without a length guard — an over-long request raisesArgumentOutOfRangeException. (BR-076)Truncateis the safe variant: it returns null unchanged and clamps the length withMath.Min(value.Length, length). (BR-076)ContainsOnlyNumericCharactersreturnsfalsefor null/empty and otherwise requiresRegex.Match(target, @"\D")to have zero length — no non-digit character anywhere. (BR-077)ConvertToDecimalOrZeroreturns0for a null/whitespace input, otherwiseConvert.ToDecimal(which throwsFormatExceptionon non-numeric text). (BR-078)NumericExtensions.IsNumericusesint.TryParse, so it isint-bounded — a decimal value, or one exceedingInt32.MaxValue, reportsfalse. (BR-079)Precisionreads the scale byte viaBitConverter.GetBytes(decimal.GetBits(decimalValue)[3])[2]to return the declared decimal-place count. (BR-080)TruncatePrecisionshort-circuits todecimal.Truncatewhen precision is 0; otherwise it scales by10^precision, truncates (does not round), and scales back. (BR-081)RepeatconcatenatesEnumerable.Repeat(value, count);Wrapreturns$"{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"])
Related documentation¶
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.csCommon/SAIF.Common/Extensions/NumericExtensions.cs