[JEDI.NET-commits] main/run Jedi.System.Strings.pas,1.2,1.3
Status: Pre-Alpha
Brought to you by:
jedi_mbe
From: Marcel B. <jed...@us...> - 2005-01-22 15:04:47
|
Update of /cvsroot/jedidotnet/main/run In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13188/main/run Modified Files: Jedi.System.Strings.pas Log Message: * Added string escape handling (ie. \r, \n \t, etc) * Grouped the class into categories * Added SourceInfo attribute Index: Jedi.System.Strings.pas =================================================================== RCS file: /cvsroot/jedidotnet/main/run/Jedi.System.Strings.pas,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Jedi.System.Strings.pas 6 Dec 2004 10:51:44 -0000 1.2 --- Jedi.System.Strings.pas 22 Jan 2005 15:04:39 -0000 1.3 *************** *** 29,40 **** uses System.Collections, ! System.Text; {$ENDREGION} ! {$REGION 'String utilities'} type ! [Flags] ExtractQuotedStringFlags = (Default = 0, IgnoreGarbage = 1, EndQuoteMandetory = 2); StringUtils = class {$REGION 'TabSet class'} --- 29,45 ---- uses System.Collections, ! System.Text, ! Jedi.System.SourceVersioning; {$ENDREGION} ! {$REGION 'Enumerations'} type ! [Flags, CVSSourceInfo('$Header$')] ExtractQuotedStringFlags = (Default = 0, IgnoreGarbage = 1, EndQuoteMandetory = 2); + {$ENDREGION} + {$REGION 'String utilities class'} + type + [CVSSourceInfo('$Header$')] StringUtils = class {$REGION 'TabSet class'} *************** *** 80,85 **** --- 85,155 ---- end; {$ENDREGION} + {$REGION 'Hidden constructor'} strict protected constructor Create; + {$ENDREGION} + {$REGION 'Escaped strings'} + public + class function EscapeString(s: string): string; overload; static; + class function EscapeString(s: string; escapeCharacters: array of Char): string; overload; static; + class function ParseEscapedString(s: string): string; static; + {$ENDREGION} + {$REGION 'Escaped strings common implementation methods'} + strict protected + class function EscapeStringImpl(s: string; escapeCharacters: array of Char): string; static; + {$ENDREGION} + {$REGION 'Escaped strings constants'} + strict protected + const SpecialEscapeChars = #0#7#8#9#10#11#12#13; + const SpecialEscapeSequences = '0abtnvfr'; + {$ENDREGION} + {$REGION 'Integer<->string in base conversion'} + public + class function BinToInt(s: string): Integer; overload; static; + class function BinToInt(s: string; out digitsUsed: Integer): Integer; overload; static; + class function BinToInt(s: string; maxDigits: Integer; ignoreLeadingZeros: Boolean): Integer; overload; static; + class function BinToInt(s: string; maxDigits: Integer; ignoreLeadingZeros: Boolean; + out digitsUsed: Integer): Integer; overload; static; + class function IntToBin(value: Integer): string; overload; static; + class function IntToBin(value: Integer; minimumDigits: Integer): string; overload; static; + class function IntToBin(value: Integer; padToShortestByteSize: Boolean): string; overload; static; + class function IntToHex(value: Integer): string; overload; static; + class function IntToHex(value: Integer; minimumDigits: Integer): string; overload; static; + class function IntToHex(value: Integer; padToShortestByteSize: Boolean): string; overload; static; + class function IntToOct(value: Integer): string; overload; static; + class function IntToOct(value: Integer; minimumDigits: Integer): string; overload; static; + class function IntToOct(value: Integer; padToShortestByteSize: Boolean): string; overload; static; + class function HexToInt(s: string): Integer; overload; static; + class function HexToInt(s: string; out digitsUsed: Integer): Integer; overload; static; + class function HexToInt(s: string; maxDigits: Integer; ignoreLeadingZeros: Boolean): Integer; overload; static; + class function HexToInt(s: string; maxDigits: Integer; ignoreLeadingZeros: Boolean; + out digitsUsed: Integer): Integer; overload; static; + class function OctToInt(s: string): Integer; overload; static; + class function OctToInt(s: string; out digitsUsed: Integer): Integer; overload; static; + class function OctToInt(s: string; maxDigits: Integer; ignoreLeadingZeros: Boolean): Integer; overload; static; + class function OctToInt(s: string; maxDigits: Integer; ignoreLeadingZeros: Boolean; + out digitsUsed: Integer): Integer; overload; static; + {$ENDREGION} + {$REGION 'Integer<->string in base conversion common implementation methods'} + strict protected + class function IntBaseToStringImpl(value, base, minDigits: Integer): string; static; + class function ParseIntBaseImpl(s: string; base, maxDigits: Integer; ignoreLeadingZeros: Boolean; + out digitsUsed: Integer): Integer; static; + {$ENDREGION} + {$REGION 'Manipulations'} + public + class function RemoveDuplicateChars(s: string; char: System.Char): string; overload; static; + class function RemoveDuplicateChars(s: string; chars: array of System.Char): string; overload; static; + class function &Repeat(s: string; count: Integer): string; static; + {$ENDREGION} + {$REGION 'Quoted strings'} + public + class function ExtractQuotedString(s: string): string; overload; static; + class function ExtractQuotedString(s: string; flags: ExtractQuotedStringFlags): string; overload; static; + class function ExtractQuotedString(s: string; out lastUsedChar: Integer): string; overload; static; + class function QuoteString(s: string): string; overload; static; + class function QuoteString(s: string; quoteChar: Char): string; overload; static; + {$ENDREGION} + {$REGION 'Subsets'} public class function After(s: string; delimiter: System.Char): string; static; *************** *** 91,108 **** class function BeforeLast(s: string; delimiter: System.Char): string; static; class function BeforeLastAnyOf(s: string; delimiters: array of System.Char): string; static; - class function ExpandTabs(s: string; tabs: array of Int32): string; overload; static; - class function ExpandTabs(s: string; tabs: array of Int32; additionalTabsWidth: Int32): string; overload; static; - class function ExpandTabs(s: string; tabSet: TabSet): string; overload; static; - class function ExtractQuotedString(s: string): string; overload; static; - class function ExtractQuotedString(s: string; flags: ExtractQuotedStringFlags): string; overload; static; - class function ExtractQuotedString(s: string; out lastUsedChar: Integer): string; overload; static; class function Left(s: string; length: Integer): string; static; class function Mid(s: string; from, &to: Integer): string; static; - class function RemoveDuplicateChars(s: string; char: System.Char): string; overload; static; - class function RemoveDuplicateChars(s: string; chars: array of System.Char): string; overload; static; - class function &Repeat(s: string; count: Integer): string; static; class function Right(s: string; length: Integer): string; static; ! class function QuoteString(s: string): string; overload; static; ! class function QuoteString(s: string; quoteChar: Char): string; overload; static; end; {$ENDREGION} --- 161,174 ---- class function BeforeLast(s: string; delimiter: System.Char): string; static; class function BeforeLastAnyOf(s: string; delimiters: array of System.Char): string; static; class function Left(s: string; length: Integer): string; static; class function Mid(s: string; from, &to: Integer): string; static; class function Right(s: string; length: Integer): string; static; ! {$ENDREGION} ! {$REGION 'Tab expansions'} ! public ! class function ExpandTabs(s: string; tabs: array of Int32): string; overload; static; ! class function ExpandTabs(s: string; tabs: array of Int32; additionalTabsWidth: Int32): string; overload; static; ! class function ExpandTabs(s: string; tabSet: TabSet): string; overload; static; ! {$ENDREGION} end; {$ENDREGION} *************** *** 112,115 **** --- 178,191 ---- {$AUTOBOX ON} + {$REGION 'implementation uses'} + uses + System.Globalization; + {$ENDREGION} + + {$REGION 'Array type declarations'} + type + CharArray = array of Char; + {$ENDREGION} + {$REGION 'StringUtils'} constructor StringUtils.Create; *************** *** 206,209 **** --- 282,382 ---- end; + class function StringUtils.BinToInt(s: string): Integer; + var + digitsUsed: Integer; + begin + Result := ParseIntBaseImpl(s, 2, s.Length, False, digitsUsed); + end; + + class function StringUtils.BinToInt(s: string; out digitsUsed: Integer): Integer; + begin + Result := ParseIntBaseImpl(s, 2, s.Length, False, digitsUsed); + end; + + class function StringUtils.BinToInt(s: string; maxDigits: Integer; ignoreLeadingZeros: Boolean): Integer; + var + digitsUsed: Integer; + begin + Result := ParseIntBaseImpl(s, 2, maxDigits, ignoreLeadingZeros, digitsUsed); + end; + + class function StringUtils.BinToInt(s: string; maxDigits: Integer; ignoreLeadingZeros: Boolean; + out digitsUsed: Integer): Integer; + begin + Result := ParseIntBaseImpl(s, 2, maxDigits, ignoreLeadingZeros, digitsUsed); + end; + + class function StringUtils.EscapeString(s: string): string; + var + al: ArrayList; + i: Integer; + begin + al := ArrayList.Create(33); + for i := 0 to 31 do + al.Add(System.Char(i)); + al.Add(System.Char('\')); + Result := EscapeStringImpl(s, CharArray(al.ToArray(TypeOf(System.Char)))); + end; + + class function StringUtils.EscapeString(s: string; escapeCharacters: array of Char): string; + var + al: ArrayList; + i: Integer; + idx: Integer; + begin + al := ArrayList.Create(&Array(escapeCharacters)); + al.Sort; + for i := 0 to 31 do + begin + idx := al.BinarySearch(System.Char(i)); + if idx < 0 then + al.Insert(not idx, System.Char(i)); + end; + idx := al.BinarySearch(System.Char('\')); + if idx < 0 then + al.Insert(not idx, System.Char('\')); + Result := EscapeStringImpl(s, CharArray(al.ToArray(TypeOf(System.Char)))); + end; + + class function StringUtils.EscapeStringImpl(s: string; escapeCharacters: array of Char): string; + var + sb: StringBuilder; + lastIdx: Integer; + idx: Integer; + escapeIdx: Integer; + begin + sb := StringBuilder.Create(s.Length); + lastIdx := 0; + repeat + idx := s.IndexOfAny(escapeCharacters, lastIdx); + if idx < 0 then + idx := s.Length; + if idx > lastIdx then + sb.Append(Mid(s, lastIdx, idx - 1)); + lastIdx := idx + 1; + if idx < s.Length then + begin + sb.Append('\'); + escapeIdx := SpecialEscapeChars.IndexOf(s.Chars[idx]); + if escapeIdx > -1 then + begin + if (escapeIdx > 0) or (lastIdx >= s.Length) or (s.Chars[lastIdx] < '0') or (s.Chars[lastIdx] > '7') then + sb.Append(SpecialEscapeSequences.Chars[escapeIdx]) + else + sb.Append('000'); + end + else + if s.Chars[idx] < ' ' then + begin + sb.Append('x'); + sb.Append(IntBaseToStringImpl(System.Int32(s.Chars[idx]), 16, 2)); + end + else + sb.Append(s.Chars[idx]); + end; + until lastIdx >= s.Length; + Result := sb.ToString; + end; + class function StringUtils.ExpandTabs(s: string; tabs: array of Integer): string; begin *************** *** 310,313 **** --- 483,617 ---- end; + class function StringUtils.IntBaseToStringImpl(value, base, minDigits: Integer): string; + var + adaptedValue: Int64; + sb: StringBuilder; + digits: string; + base64: Int64; + begin + if (base < 2) or (base > 16) then + raise ArgumentOutOfRangeException.Create('base'); + if (minDigits < 0) or (minDigits > 100) then + raise ArgumentOutOfRangeException.Create('minDigits'); + if value < 0 then + adaptedValue := $100000000 + value + else + adaptedValue := value; + sb := StringBuilder.Create(minDigits); + digits := '0123456789abcdef'; + base64 := base; // avoids (repeated) conversion inside the while loop + while adaptedValue <> 0 do + begin + sb.Insert(0, digits.Chars[adaptedValue mod base64]); + adaptedValue := adaptedValue div base64; + end; + if sb.Length < minDigits then + sb.Insert(0, '0', minDigits - sb.Length); + Result := sb.ToString; + end; + + class function StringUtils.IntToBin(value: Integer): string; + begin + Result := IntBaseToStringImpl(value, 2, 1); + end; + + class function StringUtils.IntToBin(value: Integer; minimumDigits: Integer): string; + begin + Result := IntBaseToStringImpl(value, 2, minimumDigits); + end; + + class function StringUtils.IntToBin(value: Integer; padToShortestByteSize: Boolean): string; + var + len: Integer; + begin + Result := IntBaseToStringImpl(value, 2, 1); + if padToShortestByteSize then + begin + len := 8; + while len < Result.Length do + len := len shl 1; + len := len - Result.Length; + if len > 0 then + Result := System.String.Concat(System.String.Create('0', len), Result); + end; + end; + + class function StringUtils.IntToHex(value: Integer): string; + begin + Result := IntBaseToStringImpl(value, 16, 1); + end; + + class function StringUtils.IntToHex(value: Integer; minimumDigits: Integer): string; + begin + Result := IntBaseToStringImpl(value, 16, minimumDigits); + end; + + class function StringUtils.IntToHex(value: Integer; padToShortestByteSize: Boolean): string; + var + len: Integer; + begin + Result := IntBaseToStringImpl(value, 16, 1); + if padToShortestByteSize then + begin + len := 2; + while len < Result.Length do + len := len shl 1; + len := len - Result.Length; + if len > 0 then + Result := System.String.Concat(System.String.Create('0', len), Result); + end; + end; + + class function StringUtils.IntToOct(value: Integer): string; + begin + Result := IntBaseToStringImpl(value, 8, 1); + end; + + class function StringUtils.IntToOct(value: Integer; minimumDigits: Integer): string; + begin + Result := IntBaseToStringImpl(value, 8, minimumDigits); + end; + + class function StringUtils.IntToOct(value: Integer; padToShortestByteSize: Boolean): string; + var + len: Integer; + begin + Result := IntBaseToStringImpl(value, 8, 1); + if padToShortestByteSize then + begin + len := 3; + while len < Result.Length do + len := len shl 1; + len := len - Result.Length; + if len > 0 then + Result := System.String.Concat(System.String.Create('0', len), Result); + end; + end; + + class function StringUtils.HexToInt(s: string): Integer; + var + digitsUsed: Integer; + begin + Result := ParseIntBaseImpl(s, 16, s.Length, False, digitsUsed); + end; + + class function StringUtils.HexToInt(s: string; out digitsUsed: Integer): Integer; + begin + Result := ParseIntBaseImpl(s, 16, s.Length, False, digitsUsed); + end; + + class function StringUtils.HexToInt(s: string; maxDigits: Integer; ignoreLeadingZeros: Boolean): Integer; + var + digitsUsed: Integer; + begin + Result := ParseIntBaseImpl(s, 16, maxDigits, ignoreLeadingZeros, digitsUsed); + end; + + class function StringUtils.HexToInt(s: string; maxDigits: Integer; ignoreLeadingZeros: Boolean; + out digitsUsed: Integer): Integer; + begin + Result := ParseIntBaseImpl(s, 16, maxDigits, ignoreLeadingZeros, digitsUsed); + end; + class function StringUtils.Left(s: string; length: Integer): string; begin *************** *** 320,323 **** --- 624,735 ---- end; + class function StringUtils.OctToInt(s: string): Integer; + var + digitsUsed: Integer; + begin + Result := ParseIntBaseImpl(s, 8, s.Length, False, digitsUsed); + end; + + class function StringUtils.OctToInt(s: string; out digitsUsed: Integer): Integer; + begin + Result := ParseIntBaseImpl(s, 8, s.Length, False, digitsUsed); + end; + + class function StringUtils.OctToInt(s: string; maxDigits: Integer; ignoreLeadingZeros: Boolean): Integer; + var + digitsUsed: Integer; + begin + Result := ParseIntBaseImpl(s, 8, maxDigits, ignoreLeadingZeros, digitsUsed); + end; + + class function StringUtils.OctToInt(s: string; maxDigits: Integer; ignoreLeadingZeros: Boolean; + out digitsUsed: Integer): Integer; + begin + Result := ParseIntBaseImpl(s, 8, maxDigits, ignoreLeadingZeros, digitsUsed); + end; + + class function StringUtils.ParseEscapedString(s: string): string; + var + sb: StringBuilder; + lastIdx: Integer; + idx: Integer; + specIdx: Integer; + parseCount: Integer; + begin + sb := StringBuilder.Create(s.Length); + lastIdx := 0; + repeat + idx := s.IndexOf('\', lastIdx); + if idx > -1 then + begin + sb.Append(Mid(s, lastIdx, idx - 1)); + Inc(idx); + if idx >= s.Length then + raise ArgumentException.Create('Specified string ends with the escape character.'); + specIdx := SpecialEscapeSequences.IndexOf(System.Char.ToLower(s.Chars[idx])); + if System.Char.IsDigit(s, idx) then + begin + sb.Append(System.Char(ParseIntBaseImpl(s.Substring(idx), 8, 3, False, parseCount))); + Inc(idx, parseCount); + end + else + if specIdx > -1 then + begin + sb.Append(SpecialEscapeChars.Chars[specIdx]); + Inc(idx); + end + else + if (s.Chars[idx] = 'x') or (s.Chars[idx] = 'X') then + begin + sb.Append(System.Char(ParseIntBaseImpl(s.Substring(idx + 1), 16, 2, False, parseCount))); + Inc(idx, parseCount + 1); + end + else + begin + sb.Append(s.Chars[idx]); + Inc(idx); + end; + lastIdx := idx; + if lastIdx >= s.Length then + idx := -1; + end + else + sb.Append(s.Substring(lastIdx)); + until idx < 0; + Result := sb.ToString; + end; + + class function StringUtils.ParseIntBaseImpl(s: string; base, maxDigits: Integer; ignoreLeadingZeros: Boolean; + out digitsUsed: Integer): Integer; + var + leadZeroCount: Integer; + digits: string; + newValue: Int64; + begin + if (base < 2) or (base > 16) then + raise ArgumentOutOfRangeException.Create('base'); + if (maxDigits < 0) or (maxDigits > 100) then + raise ArgumentOutOfRangeException.Create('maxDigits'); + digitsUsed := 0; + leadZeroCount := 0; + if ignoreLeadingZeros then + while (leadZeroCount < s.Length) and (s.Chars[leadZeroCount] = '0') do + Inc(leadZeroCount); + maxDigits := Math.Min(s.Length, maxDigits); + s := s.Substring(leadZeroCount, maxDigits).ToUpper(CultureInfo.InvariantCulture); + digits := '0123456789ABCDEF'.Substring(0, base); + newValue := 0; + while (digitsUsed < maxDigits) and (digits.IndexOf(s.Chars[digitsUsed]) > -1) do + begin + newValue := newValue * base + digits.IndexOf(s.Chars[digitsUsed]); + Inc(digitsUsed); + end; + digitsUsed := digitsUsed + leadZeroCount; + if newValue > System.Int32.MaxValue then + Result := newValue - $100000000 + else + Result := newValue; + end; + class function StringUtils.RemoveDuplicateChars(s: string; char: System.Char): string; var |