Guest User

ASCIIString

a guest
Jun 2nd, 2013
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 35.17 KB | None | 0 0
  1.     public sealed class ASCIIString : IEnumerable<ASCIIChar>, IComparable<ASCIIString>
  2.     {
  3.         public static readonly ASCIIString Empty;
  4.  
  5.         static ASCIIString()
  6.         {
  7.             Empty = new ASCIIString(new byte[] { });
  8.         }
  9.  
  10.         public static implicit operator String(ASCIIString value)
  11.         {
  12.             return value.ToString();
  13.         }
  14.         public static ASCIIString operator +(ASCIIString strA, ASCIIString strB)
  15.         {
  16.             return ASCIIString.Concat(strA, strB);
  17.         }
  18.         public static ASCIIString operator +(ASCIIString str, ASCIIChar chr)
  19.         {
  20.             if (str == null) throw new ArgumentNullException("str");
  21.  
  22.             int totalBytes = str.data.Length + 1;
  23.  
  24.             byte[] data = new byte[totalBytes];
  25.  
  26.             Buffer.BlockCopy(str.data, 0, data, 0, str.data.Length);
  27.             data[totalBytes - 1] = chr.ToByte();
  28.  
  29.             return new ASCIIString(data);
  30.         }
  31.         public static bool operator ==(ASCIIString strA, ASCIIString strB)
  32.         {
  33.             return ASCIIString.Compare(strA, strB) == 0;
  34.         }
  35.         public static bool operator !=(ASCIIString strA, ASCIIString strB)
  36.         {
  37.             return ASCIIString.Compare(strA, strB) != 0;
  38.         }
  39.  
  40.         public static int Compare(ASCIIString strA, ASCIIString strB)
  41.         {
  42.             return Compare(strA, strB, false);
  43.         }
  44.         public static int Compare(ASCIIString strA, ASCIIString strB, bool ignoreCase)
  45.         {
  46.             if (strA == null) throw new ArgumentNullException("strA");
  47.             if (strB == null) throw new ArgumentNullException("strB");
  48.  
  49.             return SafeCompare(strA, 0, strB, 0, Math.Max(strA.data.Length, strB.data.Length), ignoreCase);
  50.         }
  51.         public static int Compare(ASCIIString strA, int indexA, ASCIIString strB, int indexB, int length)
  52.         {
  53.             return Compare(strA, indexA, strB, indexB, length, false);
  54.         }
  55.         public static int Compare(ASCIIString strA, int indexA, ASCIIString strB, int indexB, int length, bool ignoreCase)
  56.         {
  57.             if (strA == null) throw new ArgumentNullException("strA");
  58.             if (strB == null) throw new ArgumentNullException("strB");
  59.             if (indexA < 0 || indexA > strA.data.Length) throw new ArgumentOutOfRangeException("indexA");
  60.             if (indexB < 0 || indexB > strB.data.Length) throw new ArgumentOutOfRangeException("indexB");
  61.             if (length < 0 || indexA + length > strA.data.Length || indexB + length > strB.data.Length) throw new ArgumentOutOfRangeException("length");
  62.  
  63.             return SafeCompare(strA, indexA, strB, indexB, length, ignoreCase);
  64.         }
  65.         private static int SafeCompare(ASCIIString strA, int indexA, ASCIIString strB, int indexB, int length, bool ignoreCase)
  66.         {
  67.             for (int i = 0; i < length; i++)
  68.             {
  69.                 int iA = i + indexA;
  70.                 int iB = i + indexB;
  71.  
  72.                 if (iA == strA.data.Length && iB == strB.data.Length) return 0;
  73.                 if (iA == strA.data.Length) return -1;
  74.                 if (iB == strB.data.Length) return 1;
  75.  
  76.                 byte byteA = strA.data[iA];
  77.                 byte byteB = strB.data[iB];
  78.  
  79.                 if (ignoreCase)
  80.                 {
  81.                     byteA = ASCIIChar.ToLower(byteA);
  82.                     byteB = ASCIIChar.ToLower(byteB);
  83.                 }
  84.  
  85.                 if (byteA < byteB) return -1;
  86.                 if (byteB < byteA) return 1;
  87.             }
  88.  
  89.             return 0;
  90.         }
  91.         public static ASCIIString Copy(ASCIIString value)
  92.         {
  93.             byte[] data = new byte[value.data.Length];
  94.             Buffer.BlockCopy(value.data, 0, data, 0, value.data.Length);
  95.             return new ASCIIString(data);
  96.         }
  97.         public static ASCIIString Concat(params ASCIIString[] values)
  98.         {
  99.             return Concat((IEnumerable<ASCIIString>)values);
  100.         }
  101.         public static ASCIIString Concat(IEnumerable<ASCIIString> values)
  102.         {
  103.             if (values == null) throw new ArgumentNullException("values");
  104.  
  105.             int totalBytes = 0;
  106.             int offset = 0;
  107.  
  108.             foreach (ASCIIString asciiString in values)
  109.             {
  110.                 if (asciiString == null) continue;
  111.                 totalBytes += asciiString.data.Length;
  112.             }
  113.  
  114.             byte[] data = new byte[totalBytes];
  115.  
  116.             foreach (ASCIIString asciiString in values)
  117.             {
  118.                 if (asciiString == null) continue;
  119.                 Buffer.BlockCopy(asciiString.data, 0, data, offset, asciiString.data.Length);
  120.                 offset += asciiString.data.Length;
  121.             }
  122.  
  123.             return new ASCIIString(data);
  124.         }
  125.         public static bool IsNullOrEmpty(ASCIIString value)
  126.         {
  127.             return value == null || value.data.Length == 0;
  128.         }
  129.         public static bool IsNullOrWhitespace(ASCIIString value)
  130.         {
  131.             if (value == null || value.data.Length == 0)
  132.             {
  133.                 return true;
  134.             }
  135.  
  136.             foreach (byte b in value.data)
  137.             {
  138.                 if (!ASCIIChar.IsWhitespace(b))
  139.                 {
  140.                     return false;
  141.                 }
  142.             }
  143.  
  144.             return true;
  145.         }
  146.         public static ASCIIString Join(ASCIIString seperator, params ASCIIString[] values)
  147.         {
  148.             return Join(seperator, (IEnumerable<ASCIIString>)values);
  149.         }
  150.         public static ASCIIString Join(ASCIIString seperator, IEnumerable<ASCIIString> values)
  151.         {
  152.             if (seperator == null) throw new ArgumentNullException("seperator");
  153.             if (values == null) throw new ArgumentNullException("values");
  154.  
  155.             int totalBytes = 0;
  156.             int offset = 0;
  157.  
  158.             foreach (ASCIIString asciiString in values)
  159.             {
  160.                 if (asciiString == null) continue;
  161.                 totalBytes += asciiString.data.Length;
  162.                 totalBytes += seperator.data.Length;
  163.             }
  164.  
  165.             if (totalBytes > 0) totalBytes -= seperator.data.Length;
  166.  
  167.             byte[] data = new byte[totalBytes];
  168.  
  169.             foreach (ASCIIString asciiString in values)
  170.             {
  171.                 if (asciiString == null) continue;
  172.  
  173.                 Buffer.BlockCopy(asciiString.data, 0, data, offset, asciiString.data.Length);
  174.                 offset += asciiString.data.Length;
  175.  
  176.                 if (offset < totalBytes)
  177.                 {
  178.                     Buffer.BlockCopy(seperator.data, 0, data, offset, seperator.data.Length);
  179.                     offset += seperator.data.Length;
  180.                 }
  181.             }
  182.  
  183.             return new ASCIIString(data);
  184.         }
  185.  
  186.         private readonly byte[] data;
  187.  
  188.         public int Length
  189.         {
  190.             get
  191.             {
  192.                 return data.Length;
  193.             }
  194.         }
  195.  
  196.         public ASCIIString(byte[] data, int startIndex, int length)
  197.         {
  198.             if (data == null) throw new ArgumentNullException("data");
  199.             if (startIndex < 0 || startIndex > data.Length) throw new ArgumentOutOfRangeException("startIndex");
  200.             if (length < 0 || startIndex + length > data.Length) throw new ArgumentOutOfRangeException("length");
  201.  
  202.             foreach (byte b in data)
  203.             {
  204.                 if (!ASCIIChar.ValidateByte(b))
  205.                 {
  206.                     throw new ArgumentOutOfRangeException("data");
  207.                 }
  208.             }
  209.  
  210.             this.data = new byte[length];
  211.             Buffer.BlockCopy(data, startIndex, this.data, 0, length);
  212.         }
  213.         private ASCIIString(byte[] data)
  214.         {
  215.             this.data = data;
  216.         }
  217.  
  218.         public ASCIIChar this[int index]
  219.         {
  220.             get
  221.             {
  222.                 return new ASCIIChar(this.data[index]);
  223.             }
  224.         }
  225.  
  226.         public ASCIIString Clone()
  227.         {
  228.             return this;
  229.         }
  230.         public int CompareTo(ASCIIString value)
  231.         {
  232.             if (value == null) throw new ArgumentNullException("value");
  233.             return ASCIIString.Compare(this, value);
  234.         }
  235.         public bool Contains(ASCIIString value)
  236.         {
  237.             if (value == null) throw new ArgumentNullException("value");
  238.             return this.IndexOf(value) >= 0;
  239.         }
  240.         public bool Contains(ASCIIChar value)
  241.         {
  242.             byte valueByte = value.ToByte();
  243.  
  244.             foreach (byte b in this.data)
  245.             {
  246.                 if (b.Equals(valueByte))
  247.                 {
  248.                     return true;
  249.                 }
  250.             }
  251.  
  252.             return false;
  253.         }
  254.         public bool EndsWith(ASCIIString value)
  255.         {
  256.             return this.EndsWith(value, false);
  257.         }
  258.         public bool EndsWith(ASCIIString value, bool ignoreCase)
  259.         {
  260.             if (value == null) throw new ArgumentNullException("value");
  261.             return ASCIIString.Compare(this, this.data.Length - value.data.Length, value, 0, value.Length, ignoreCase) == 0;
  262.         }
  263.         public override bool Equals(object obj)
  264.         {
  265.             if (obj is ASCIIString)
  266.             {
  267.                 return base.Equals((ASCIIString)obj);
  268.             }
  269.             else
  270.             {
  271.                 return false;
  272.             }
  273.         }
  274.         public bool Equals(ASCIIString value)
  275.         {
  276.             return this.CompareTo(value) == 0;
  277.         }
  278.         public override int GetHashCode()
  279.         {
  280.             return base.GetHashCode();
  281.         }
  282.         public int IndexOf(ASCIIString value)
  283.         {
  284.             return this.IndexOf(value, 0, this.Length, false);
  285.         }
  286.         public int IndexOf(ASCIIString value, bool ignoreCase)
  287.         {
  288.             return this.IndexOf(value, 0, this.Length, ignoreCase);
  289.         }
  290.         public int IndexOf(ASCIIString value, int startIndex)
  291.         {
  292.             return this.IndexOf(value, startIndex, this.Length - startIndex, false);
  293.         }
  294.         public int IndexOf(ASCIIString value, int startIndex, bool ignoreCase)
  295.         {
  296.             return this.IndexOf(value, startIndex, this.Length - startIndex, ignoreCase);
  297.         }
  298.         public int IndexOf(ASCIIString value, int startIndex, int count)
  299.         {
  300.             return this.IndexOf(value, startIndex, count, false);
  301.         }
  302.         public int IndexOf(ASCIIString value, int startIndex, int count, bool ignoreCase)
  303.         {
  304.             if (value == null) throw new ArgumentNullException("value");
  305.             if (startIndex < 0 || startIndex > this.data.Length) throw new ArgumentOutOfRangeException("startIndex");
  306.             if (count < 0 || startIndex + count > this.data.Length || count < value.data.Length) throw new ArgumentOutOfRangeException("count");
  307.  
  308.             int charactersFound = 0;
  309.  
  310.             for (int i = startIndex; i < startIndex + count; i++)
  311.             {
  312.                 if (i + (value.data.Length - charactersFound) > this.data.Length) return -1;
  313.  
  314.                 byte byteA = this.data[i];
  315.                 byte byteB = value.data[charactersFound];
  316.  
  317.                 if (ignoreCase)
  318.                 {
  319.                     byteA = ASCIIChar.ToLower(byteA);
  320.                     byteB = ASCIIChar.ToLower(byteB);
  321.                 }
  322.  
  323.                 if (byteA == byteB) charactersFound++;
  324.                 else charactersFound = 0;
  325.  
  326.                 if (charactersFound == value.data.Length) return (i - charactersFound + 1);
  327.             }
  328.  
  329.             return -1;
  330.         }
  331.         public int IndexOfAny(params ASCIIChar[] values)
  332.         {
  333.             return this.IndexOfAny(values, 0, this.data.Length, false);
  334.         }
  335.         public int IndexOfAny(IEnumerable<ASCIIChar> values)
  336.         {
  337.             return this.IndexOfAny(values, 0, this.data.Length, false);
  338.         }
  339.         public int IndexOfAny(IEnumerable<ASCIIChar> values, bool ignoreCase)
  340.         {
  341.             return this.IndexOfAny(values, 0, this.data.Length, ignoreCase);
  342.         }
  343.         public int IndexOfAny(IEnumerable<ASCIIChar> values, int startIndex)
  344.         {
  345.             return this.IndexOfAny(values, startIndex, this.data.Length - startIndex, false);
  346.         }
  347.         public int IndexOfAny(IEnumerable<ASCIIChar> values, int startIndex, bool ignoreCase)
  348.         {
  349.             return this.IndexOfAny(values, startIndex, this.data.Length - startIndex, ignoreCase);
  350.         }
  351.         public int IndexOfAny(IEnumerable<ASCIIChar> values, int startIndex, int count)
  352.         {
  353.             return this.IndexOfAny(values, startIndex, count, false);
  354.         }
  355.         public int IndexOfAny(IEnumerable<ASCIIChar> values, int startIndex, int count, bool ignoreCase)
  356.         {
  357.             if (values == null) throw new ArgumentNullException("values");
  358.             if (startIndex < 0 || startIndex > this.data.Length) throw new ArgumentOutOfRangeException("startIndex");
  359.             if (count < 0 || startIndex + count > this.data.Length) throw new ArgumentOutOfRangeException("count");
  360.  
  361.             List<byte> valueBytes = new List<byte>();
  362.  
  363.             foreach (ASCIIChar c in values)
  364.             {
  365.                 if (ignoreCase) valueBytes.Add(ASCIIChar.ToLower(c.ToByte()));
  366.                 else valueBytes.Add(c.ToByte());
  367.             }
  368.  
  369.             for (int i = 0; i < this.data.Length; i++)
  370.             {
  371.                 byte b = this.data[i];
  372.                 if (ignoreCase) b = ASCIIChar.ToLower(b);
  373.                 if (valueBytes.Contains(this.data[i])) return i;
  374.             }
  375.  
  376.             return -1;
  377.         }
  378.         public ASCIIString Insert(ASCIIString value, int index)
  379.         {
  380.             if (value == null) throw new ArgumentNullException("value");
  381.             if (index < 0 || index > this.data.Length) throw new ArgumentOutOfRangeException("index");
  382.  
  383.             int totalBytes = this.data.Length + value.data.Length;
  384.             byte[] data = new byte[totalBytes];
  385.  
  386.             Buffer.BlockCopy(this.data, 0, data, 0, index);
  387.             Buffer.BlockCopy(value.data, 0, data, index, value.data.Length);
  388.             Buffer.BlockCopy(this.data, index, data, index + value.data.Length, this.data.Length - index);
  389.  
  390.             return new ASCIIString(data);
  391.         }
  392.         public int LastIndexOf(ASCIIString value)
  393.         {
  394.             return this.LastIndexOf(value, 0, this.Length, false);
  395.         }
  396.         public int LastIndexOf(ASCIIString value, bool ignoreCase)
  397.         {
  398.             return this.LastIndexOf(value, 0, this.Length, ignoreCase);
  399.         }
  400.         public int LastIndexOf(ASCIIString value, int startIndex)
  401.         {
  402.             return this.LastIndexOf(value, startIndex, this.Length - startIndex, false);
  403.         }
  404.         public int LastIndexOf(ASCIIString value, int startIndex, bool ignoreCase)
  405.         {
  406.             return this.LastIndexOf(value, startIndex, this.Length - startIndex, ignoreCase);
  407.         }
  408.         public int LastIndexOf(ASCIIString value, int startIndex, int count)
  409.         {
  410.             return this.LastIndexOf(value, startIndex, count, false);
  411.         }
  412.         public int LastIndexOf(ASCIIString value, int startIndex, int count, bool ignoreCase)
  413.         {
  414.             if (value == null) throw new ArgumentNullException("value");
  415.             if (startIndex < 0 || startIndex > this.data.Length) throw new ArgumentOutOfRangeException("startIndex");
  416.             if (count < 0 || startIndex + count > this.data.Length) throw new ArgumentOutOfRangeException("count");
  417.  
  418.             int lastIndexFound = -1;
  419.             int result = startIndex - 1;
  420.  
  421.             do
  422.             {
  423.                 result = this.IndexOf(value, result + 1, count - (result + 1), ignoreCase);
  424.  
  425.                 if (result >= 0)
  426.                 {
  427.                     lastIndexFound = result;
  428.                 }
  429.             }
  430.             while (result >= 0 && result + 1 < this.data.Length - value.data.Length);
  431.  
  432.             return lastIndexFound;
  433.         }
  434.         public int LastIndexOfAny(params ASCIIChar[] values)
  435.         {
  436.             return this.LastIndexOfAny(values, 0, this.data.Length, false);
  437.         }
  438.         public int LastIndexOfAny(IEnumerable<ASCIIChar> values)
  439.         {
  440.             return this.LastIndexOfAny(values, 0, this.data.Length, false);
  441.         }
  442.         public int LastIndexOfAny(IEnumerable<ASCIIChar> values, bool ignoreCase)
  443.         {
  444.             return this.LastIndexOfAny(values, 0, this.data.Length, ignoreCase);
  445.         }
  446.         public int LastIndexOfAny(IEnumerable<ASCIIChar> values, int startIndex)
  447.         {
  448.             return this.LastIndexOfAny(values, startIndex, this.data.Length - startIndex, false);
  449.         }
  450.         public int LastIndexOfAny(IEnumerable<ASCIIChar> values, int startIndex, bool ignoreCase)
  451.         {
  452.             return this.LastIndexOfAny(values, startIndex, this.data.Length - startIndex, ignoreCase);
  453.         }
  454.         public int LastIndexOfAny(IEnumerable<ASCIIChar> values, int startIndex, int count)
  455.         {
  456.             return this.LastIndexOfAny(values, startIndex, count, false);
  457.         }
  458.         public int LastIndexOfAny(IEnumerable<ASCIIChar> values, int startIndex, int count, bool ignoreCase)
  459.         {
  460.             if (values == null) throw new ArgumentNullException("values");
  461.             if (startIndex < 0 || startIndex > this.data.Length) throw new ArgumentOutOfRangeException("startIndex");
  462.             if (count < 0 || startIndex + count > this.data.Length) throw new ArgumentOutOfRangeException("count");
  463.  
  464.             List<byte> valueBytes = new List<byte>();
  465.  
  466.             foreach (ASCIIChar c in values)
  467.             {
  468.                 if (ignoreCase) valueBytes.Add(ASCIIChar.ToLower(c.ToByte()));
  469.                 else valueBytes.Add(c.ToByte());
  470.             }
  471.  
  472.             int lastIndex = -1;
  473.  
  474.             for (int i = 0; i < this.data.Length; i++)
  475.             {
  476.                 byte b = this.data[i];
  477.                 if (ignoreCase) b = ASCIIChar.ToLower(b);
  478.                 if (valueBytes.Contains(this.data[i])) lastIndex = i;
  479.             }
  480.  
  481.             return lastIndex;
  482.         }
  483.         public ASCIIString PadLeft(int totalLength)
  484.         {
  485.             return this.PadLeft(totalLength, ASCIIChars.Space);
  486.         }
  487.         public ASCIIString PadLeft(int totalLength, ASCIIChar c)
  488.         {
  489.             if (totalLength < this.data.Length) throw new ArgumentOutOfRangeException("totalLength");
  490.  
  491.             byte[] data = new byte[totalLength];
  492.             byte charByte = c.ToByte();
  493.  
  494.             int i = 0;
  495.  
  496.             for (; i + this.data.Length < totalLength; i++)
  497.             {
  498.                 data[i] = charByte;
  499.             }
  500.  
  501.             Buffer.BlockCopy(this.data, 0, data, i, this.data.Length);
  502.  
  503.             return new ASCIIString(data);
  504.         }
  505.         public ASCIIString PadRight(int totalLength)
  506.         {
  507.             return this.PadRight(totalLength, ASCIIChars.Space);
  508.         }
  509.         public ASCIIString PadRight(int totalLength, ASCIIChar c)
  510.         {
  511.             if (totalLength < this.data.Length) throw new ArgumentOutOfRangeException("totalLength");
  512.  
  513.             byte[] data = new byte[totalLength];
  514.             byte charByte = c.ToByte();
  515.  
  516.             Buffer.BlockCopy(this.data, 0, data, 0, this.data.Length);
  517.  
  518.             for (int i = this.data.Length; i < totalLength; i++)
  519.             {
  520.                 data[i] = charByte;
  521.             }
  522.  
  523.             return new ASCIIString(data);
  524.         }
  525.         public ASCIIString Parse(string value)
  526.         {
  527.             if (value == null) throw new ArgumentNullException("value");
  528.  
  529.             return new ASCIIString(Encoding.ASCII.GetBytes(value));
  530.         }
  531.         public ASCIIString Remove(int startIndex)
  532.         {
  533.             return this.Remove(startIndex, this.data.Length - startIndex);
  534.         }
  535.         public ASCIIString Remove(int startIndex, int count)
  536.         {
  537.             if (startIndex < 0 || startIndex > this.data.Length) throw new ArgumentOutOfRangeException("startIndex");
  538.             if (count < 0 || startIndex + count > this.data.Length) throw new ArgumentOutOfRangeException("count");
  539.  
  540.             byte[] data = new byte[this.data.Length - count];
  541.  
  542.             Buffer.BlockCopy(this.data, 0, data, 0, startIndex);
  543.             Buffer.BlockCopy(this.data, startIndex + count, data, startIndex, this.data.Length - count - startIndex);
  544.  
  545.             return new ASCIIString(data);
  546.         }
  547.         public ASCIIString Replace(ASCIIString oldString, ASCIIString newString)
  548.         {
  549.             if (oldString == null) throw new ArgumentNullException("oldString");
  550.             if (newString == null) throw new ArgumentNullException("newString");
  551.  
  552.             List<int> indexes = new List<int>();
  553.             int index = 0;
  554.  
  555.             do
  556.             {
  557.                 index = this.IndexOf(oldString, index, false);
  558.  
  559.                 if (index >= 0)
  560.                 {
  561.                     indexes.Add(index);
  562.                     index += oldString.data.Length;
  563.                 }
  564.             }
  565.             while (index >= 0 && index + oldString.Length < this.data.Length);
  566.  
  567.             if (indexes.Count == 0)
  568.             {
  569.                 return this.Clone();
  570.             }
  571.  
  572.             byte[] data = new byte[this.data.Length - (oldString.data.Length * indexes.Count) + (newString.data.Length * indexes.Count)];
  573.  
  574.             int oldIndex = 0;
  575.             int newIndex = 0;
  576.  
  577.             foreach (int stringIndex in indexes)
  578.             {
  579.                 Buffer.BlockCopy(this.data, oldIndex, data, newIndex, stringIndex - oldIndex);
  580.                 newIndex += stringIndex - oldIndex;
  581.                 oldIndex = stringIndex + oldString.data.Length;
  582.                 Buffer.BlockCopy(newString.data, 0, data, newIndex, newString.data.Length);
  583.                 newIndex += newString.data.Length;
  584.             }
  585.  
  586.             Buffer.BlockCopy(this.data, oldIndex, data, newIndex, this.data.Length - oldIndex);
  587.  
  588.             return new ASCIIString(data);
  589.         }
  590.         public ASCIIString Replace(ASCIIChar oldChar, ASCIIChar newChar)
  591.         {
  592.             if (oldChar == newChar) return this.Clone();
  593.  
  594.             ASCIIChar[] oldChars = new ASCIIChar[] { oldChar };
  595.  
  596.             List<int> indexes = new List<int>();
  597.             int index = 0;
  598.  
  599.             do
  600.             {
  601.                 index = this.IndexOfAny(oldChars, index, false);
  602.  
  603.                 if (index >= 0)
  604.                 {
  605.                     indexes.Add(index);
  606.                     index ++;
  607.                 }
  608.             }
  609.             while (index >= 0 && index + 1 < this.data.Length);
  610.  
  611.             if (indexes.Count == 0) return this.Clone();
  612.  
  613.             byte[] data = new byte[this.data.Length];
  614.  
  615.             int oldIndex = 0;
  616.             int newIndex = 0;
  617.  
  618.             foreach (int stringIndex in indexes)
  619.             {
  620.                 Buffer.BlockCopy(this.data, oldIndex, data, newIndex, stringIndex - oldIndex);
  621.                 newIndex += stringIndex - oldIndex;
  622.                 oldIndex = stringIndex + 1;
  623.                 data[newIndex] = newChar.ToByte();
  624.                 newIndex++;
  625.             }
  626.  
  627.             Buffer.BlockCopy(this.data, oldIndex, data, newIndex, this.data.Length - oldIndex);
  628.  
  629.             return new ASCIIString(data);
  630.         }
  631.         public ASCIIString[] Split(params ASCIIString[] seperators)
  632.         {
  633.             return this.Split(seperators, int.MaxValue, StringSplitOptions.None);
  634.         }
  635.         public ASCIIString[] Split(IEnumerable<ASCIIString> seperators)
  636.         {
  637.             return this.Split(seperators, int.MaxValue, StringSplitOptions.None);
  638.         }
  639.         public ASCIIString[] Split(IEnumerable<ASCIIString> seperators, StringSplitOptions options)
  640.         {
  641.             return this.Split(seperators, int.MaxValue, options);
  642.         }
  643.         public ASCIIString[] Split(IEnumerable<ASCIIString> seperators, int count)
  644.         {
  645.             return this.Split(seperators, count, StringSplitOptions.None);
  646.         }
  647.         public ASCIIString[] Split(IEnumerable<ASCIIString> seperators, int count, StringSplitOptions options)
  648.         {
  649.             List<ASCIIString> parts = new List<ASCIIString>();
  650.  
  651.             int startIndex = 0;
  652.  
  653.             for (int dataIndex = 0; dataIndex < this.data.Length; dataIndex++)
  654.             {
  655.                 int charsFound = 0;
  656.                 bool found = false;
  657.  
  658.                 foreach (ASCIIString seperator in seperators)
  659.                 {
  660.                     charsFound = 0;
  661.  
  662.                     if (dataIndex + seperator.data.Length > this.data.Length) break;
  663.  
  664.                     for (int sepIndex = 0; sepIndex < seperator.Length; sepIndex++)
  665.                     {
  666.                         if (this.data[dataIndex + sepIndex] == seperator[sepIndex]) charsFound++;
  667.                         else charsFound = 0;
  668.                     }
  669.  
  670.                     if (charsFound == seperator.data.Length) found = true;
  671.                 }
  672.  
  673.                 if (found)
  674.                 {
  675.                     ASCIIString part = this.Substring(startIndex, dataIndex - startIndex);
  676.                     if (part.data.Length > 0 || options == StringSplitOptions.None)
  677.                     {
  678.                         parts.Add(part);
  679.                     }
  680.                     startIndex = dataIndex + charsFound;
  681.                     dataIndex += charsFound - 1;
  682.  
  683.                     if (parts.Count + 1 == count) break;
  684.                 }
  685.             }
  686.  
  687.             ASCIIString remainingPart = this.Substring(startIndex);
  688.             if (remainingPart.data.Length > 0 || options == StringSplitOptions.None)
  689.             {
  690.                 parts.Add(remainingPart);
  691.             }
  692.  
  693.             return parts.ToArray();
  694.         }
  695.         public ASCIIString[] Split(params ASCIIChar[] seperators)
  696.         {
  697.             return this.Split(seperators, int.MaxValue, StringSplitOptions.None);
  698.         }
  699.         public ASCIIString[] Split(IEnumerable<ASCIIChar> seperators)
  700.         {
  701.             return this.Split(seperators, int.MaxValue, StringSplitOptions.None);
  702.         }
  703.         public ASCIIString[] Split(IEnumerable<ASCIIChar> seperators, StringSplitOptions options)
  704.         {
  705.             return this.Split(seperators, int.MaxValue, options);
  706.         }
  707.         public ASCIIString[] Split(IEnumerable<ASCIIChar> seperators, int count)
  708.         {
  709.             return this.Split(seperators, count, StringSplitOptions.None);
  710.         }
  711.         public ASCIIString[] Split(IEnumerable<ASCIIChar> seperators, int count, StringSplitOptions options)
  712.         {
  713.             List<ASCIIString> parts = new List<ASCIIString>();
  714.  
  715.             int startIndex = 0;
  716.  
  717.             for (int dataIndex = 0; dataIndex < this.data.Length; dataIndex++)
  718.             {
  719.                 bool found = false;
  720.  
  721.                 foreach (ASCIIChar seperator in seperators)
  722.                 {
  723.                     if (this.data[dataIndex] == seperator)
  724.                     {
  725.                         found = true;
  726.                     }
  727.                 }
  728.  
  729.                 if (found)
  730.                 {
  731.                     ASCIIString part = this.Substring(startIndex, dataIndex - startIndex);
  732.                     if (part.data.Length > 0 || options == StringSplitOptions.None)
  733.                     {
  734.                         parts.Add(part);
  735.                     }
  736.  
  737.                     startIndex = dataIndex + 1;
  738.  
  739.                     if (parts.Count + 1 == count) break;
  740.                 }
  741.             }
  742.  
  743.             ASCIIString remainingPart = this.Substring(startIndex);
  744.             if (remainingPart.data.Length > 0 || options == StringSplitOptions.None)
  745.             {
  746.                 parts.Add(remainingPart);
  747.             }
  748.  
  749.             return parts.ToArray();
  750.         }
  751.         public bool StartsWith(ASCIIString value)
  752.         {
  753.             return this.StartsWith(value, false);
  754.         }
  755.         public bool StartsWith(ASCIIString value, bool ignoreCase)
  756.         {
  757.             if (value == null) throw new ArgumentNullException("value");
  758.             return ASCIIString.Compare(this, 0, value, 0, value.Length, ignoreCase) == 0;
  759.         }
  760.         public ASCIIString Substring(int startIndex)
  761.         {
  762.             return this.Substring(startIndex, this.data.Length - startIndex);
  763.         }
  764.         public ASCIIString Substring(int startIndex, int length)
  765.         {
  766.             if (startIndex < 0 || startIndex > data.Length) throw new ArgumentOutOfRangeException("startIndex");
  767.             if (length < 0 || startIndex + length > data.Length) throw new ArgumentOutOfRangeException("length");
  768.  
  769.             byte[] newData = new byte[length];
  770.             Buffer.BlockCopy(data, startIndex, newData, 0, length);
  771.             return new ASCIIString(newData);
  772.         }
  773.         public ASCIIChar[] ToCharArray()
  774.         {
  775.             ASCIIChar[] chars = new ASCIIChar[this.data.Length];
  776.             for (int i = 0; i < this.data.Length; i++)
  777.             {
  778.                 chars[i] = new ASCIIChar(this.data[i]);
  779.             }
  780.             return chars;
  781.         }
  782.         public ASCIIString ToLower()
  783.         {
  784.             ASCIIString s = ASCIIString.Copy(this);
  785.  
  786.             for (int i = 0; i < s.data.Length; i++)
  787.             {
  788.                 byte b = s.data[i];
  789.                 if (ASCIIChar.IsUpper(b))
  790.                 {
  791.                     s.data[i] = ASCIIChar.ToLower(b);
  792.                 }
  793.             }
  794.  
  795.             return s;
  796.         }
  797.         public ASCIIString ToUpper()
  798.         {
  799.             ASCIIString s = ASCIIString.Copy(this);
  800.  
  801.             for (int i = 0; i < s.data.Length; i++)
  802.             {
  803.                 byte b = s.data[i];
  804.                 if (ASCIIChar.IsLower(b))
  805.                 {
  806.                     s.data[i] = ASCIIChar.ToUpper(b);
  807.                 }
  808.             }
  809.  
  810.             return s;
  811.         }
  812.         public ASCIIString Trim()
  813.         {
  814.             int charsAtStart = 0;
  815.             int charsAtEnd = 0;
  816.  
  817.             for (int i = 0; i < this.data.Length; i++)
  818.             {
  819.                 if (ASCIIChar.IsWhitespace(this.data[i]))
  820.                 {
  821.                     charsAtStart++;
  822.                 }
  823.                 else
  824.                 {
  825.                     break;
  826.                 }
  827.             }
  828.  
  829.             for (int i = this.data.Length - 1; i >= charsAtStart; i--)
  830.             {
  831.                 if (ASCIIChar.IsWhitespace(this.data[i]))
  832.                 {
  833.                     charsAtEnd++;
  834.                 }
  835.                 else
  836.                 {
  837.                     break;
  838.                 }
  839.             }
  840.  
  841.             byte[] data = new byte[this.data.Length - charsAtStart - charsAtEnd];
  842.             Buffer.BlockCopy(this.data, charsAtStart, data, 0, data.Length);
  843.             return new ASCIIString(data);
  844.         }
  845.         public ASCIIString Trim(params ASCIIChar[] values)
  846.         {
  847.             int charsAtStart = 0;
  848.             int charsAtEnd = 0;
  849.  
  850.             for (int i = 0; i < this.data.Length; i++)
  851.             {
  852.                 bool found = false;
  853.  
  854.                 foreach (ASCIIChar c in values)
  855.                 {
  856.                     if (this.data[i].Equals(c.ToByte()))
  857.                     {
  858.                         charsAtStart++;
  859.                         found = true;
  860.                         break;
  861.                     }
  862.                 }
  863.  
  864.                 if (!found) break;
  865.             }
  866.  
  867.             for (int i = this.data.Length - 1; i >= charsAtStart; i--)
  868.             {
  869.                 bool found = false;
  870.  
  871.                 foreach (ASCIIChar c in values)
  872.                 {
  873.                     if (this.data[i].Equals(c.ToByte()))
  874.                     {
  875.                         charsAtEnd++;
  876.                         found = true;
  877.                         break;
  878.                     }
  879.                 }
  880.  
  881.                 if (!found) break;
  882.             }
  883.  
  884.             byte[] data = new byte[this.data.Length - charsAtStart - charsAtEnd];
  885.             Buffer.BlockCopy(this.data, charsAtStart, data, 0, data.Length);
  886.             return new ASCIIString(data);
  887.         }
  888.         public ASCIIString TrimEnd()
  889.         {
  890.             int charsAtEnd = 0;
  891.  
  892.             for (int i = this.data.Length - 1; i >= 0; i--)
  893.             {
  894.                 if (ASCIIChar.IsWhitespace(this.data[i]))
  895.                 {
  896.                     charsAtEnd++;
  897.                 }
  898.                 else
  899.                 {
  900.                     break;
  901.                 }
  902.             }
  903.  
  904.             byte[] data = new byte[this.data.Length - charsAtEnd];
  905.             Buffer.BlockCopy(this.data, 0, data, 0, data.Length);
  906.             return new ASCIIString(data);
  907.         }
  908.         public ASCIIString TrimEnd(params ASCIIChar[] values)
  909.         {
  910.             int charsAtEnd = 0;
  911.  
  912.             for (int i = this.data.Length - 1; i >= 0; i--)
  913.             {
  914.                 bool found = false;
  915.  
  916.                 foreach (ASCIIChar c in values)
  917.                 {
  918.                     if (this.data[i].Equals(c.ToByte()))
  919.                     {
  920.                         charsAtEnd++;
  921.                         found = true;
  922.                         break;
  923.                     }
  924.                 }
  925.  
  926.                 if (!found) break;
  927.             }
  928.  
  929.             byte[] data = new byte[this.data.Length - charsAtEnd];
  930.             Buffer.BlockCopy(this.data, 0, data, 0, data.Length);
  931.             return new ASCIIString(data);
  932.         }
  933.         public ASCIIString TrimStart()
  934.         {
  935.             int charsAtStart = 0;
  936.  
  937.             for (int i = 0; i < this.data.Length; i++)
  938.             {
  939.                 if (ASCIIChar.IsWhitespace(this.data[i]))
  940.                 {
  941.                     charsAtStart++;
  942.                 }
  943.                 else
  944.                 {
  945.                     break;
  946.                 }
  947.             }
  948.  
  949.             byte[] data = new byte[this.data.Length - charsAtStart];
  950.             Buffer.BlockCopy(this.data, charsAtStart, data, 0, data.Length);
  951.             return new ASCIIString(data);
  952.         }
  953.         public ASCIIString TrimStart(params ASCIIChar[] values)
  954.         {
  955.             int charsAtStart = 0;
  956.  
  957.             for (int i = 0; i < this.data.Length; i++)
  958.             {
  959.                 bool found = false;
  960.  
  961.                 foreach (ASCIIChar c in values)
  962.                 {
  963.                     if (this.data[i].Equals(c.ToByte()))
  964.                     {
  965.                         charsAtStart++;
  966.                         found = true;
  967.                         break;
  968.                     }
  969.                 }
  970.  
  971.                 if (!found) break;
  972.             }
  973.  
  974.             byte[] data = new byte[this.data.Length - charsAtStart];
  975.             Buffer.BlockCopy(this.data, charsAtStart, data, 0, data.Length);
  976.             return new ASCIIString(data);
  977.         }
  978.  
  979.         public override string ToString()
  980.         {
  981.             return Encoding.ASCII.GetString(this.data);
  982.         }
  983.  
  984.         public IEnumerator<ASCIIChar> GetEnumerator()
  985.         {
  986.             foreach (byte b in this.data)
  987.             {
  988.                 yield return new ASCIIChar(b);
  989.             }
  990.         }
  991.         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  992.         {
  993.             return this.GetEnumerator();
  994.         }
  995.  
  996.         int IComparable<ASCIIString>.CompareTo(ASCIIString other)
  997.         {
  998.             return this.CompareTo(other);
  999.         }
  1000.     }
Advertisement
Add Comment
Please, Sign In to add comment