You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
5.4 KiB

4 years ago
  1. #if MYSQL_6_9
  2. // Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
  3. //
  4. // MySQL Connector/NET is licensed under the terms of the GPLv2
  5. // <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
  6. // MySQL Connectors. There are special exceptions to the terms and
  7. // conditions of the GPLv2 as it is applied to this software, see the
  8. // FLOSS License Exception
  9. // <http://www.mysql.com/about/legal/licensing/foss-exception.html>.
  10. //
  11. // This program is free software; you can redistribute it and/or modify
  12. // it under the terms of the GNU General Public License as published
  13. // by the Free Software Foundation; version 2 of the License.
  14. //
  15. // This program is distributed in the hope that it will be useful, but
  16. // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  17. // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  18. // for more details.
  19. //
  20. // You should have received a copy of the GNU General Public License along
  21. // with this program; if not, write to the Free Software Foundation, Inc.,
  22. // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  23. using System;
  24. using System.Collections;
  25. using System.Text;
  26. namespace Externals.MySql.Data.Common
  27. {
  28. internal class ContextString
  29. {
  30. string contextMarkers;
  31. bool escapeBackslash;
  32. // Create a private ctor so the compiler doesn't give us a default one
  33. public ContextString(string contextMarkers, bool escapeBackslash)
  34. {
  35. this.contextMarkers = contextMarkers;
  36. this.escapeBackslash = escapeBackslash;
  37. }
  38. public string ContextMarkers
  39. {
  40. get { return contextMarkers; }
  41. set { contextMarkers = value; }
  42. }
  43. public int IndexOf(string src, string target)
  44. {
  45. return IndexOf(src, target, 0);
  46. }
  47. public int IndexOf(string src, string target, int startIndex)
  48. {
  49. int index = src.IndexOf(target, startIndex);
  50. while (index != -1)
  51. {
  52. if (!IndexInQuotes(src, index, startIndex)) break;
  53. index = src.IndexOf(target, index + 1);
  54. }
  55. return index;
  56. }
  57. private bool IndexInQuotes(string src, int index, int startIndex)
  58. {
  59. char contextMarker = Char.MinValue;
  60. bool escaped = false;
  61. for (int i = startIndex; i < index; i++)
  62. {
  63. char c = src[i];
  64. int contextIndex = contextMarkers.IndexOf(c);
  65. // if we have found the closing marker for our open marker, then close the context
  66. if (contextIndex > -1 && contextMarker == contextMarkers[contextIndex] && !escaped)
  67. contextMarker = Char.MinValue;
  68. // if we have found a context marker and we are not in a context yet, then start one
  69. else if (contextMarker == Char.MinValue && contextIndex > -1 && !escaped)
  70. contextMarker = c;
  71. else if (c == '\\' && escapeBackslash)
  72. escaped = !escaped;
  73. }
  74. return contextMarker != Char.MinValue || escaped;
  75. }
  76. public int IndexOf(string src, char target)
  77. {
  78. char contextMarker = Char.MinValue;
  79. bool escaped = false;
  80. int pos = 0;
  81. foreach (char c in src)
  82. {
  83. int contextIndex = contextMarkers.IndexOf(c);
  84. // if we have found the closing marker for our open marker, then close the context
  85. if (contextIndex > -1 && contextMarker == contextMarkers[contextIndex] && !escaped)
  86. contextMarker = Char.MinValue;
  87. // if we have found a context marker and we are not in a context yet, then start one
  88. else if (contextMarker == Char.MinValue && contextIndex > -1 && !escaped)
  89. contextMarker = c;
  90. else if (contextMarker == Char.MinValue && c == target)
  91. return pos;
  92. else if (c == '\\' && escapeBackslash)
  93. escaped = !escaped;
  94. pos++;
  95. }
  96. return -1;
  97. }
  98. public string[] Split(string src, string delimiters)
  99. {
  100. ArrayList parts = new ArrayList();
  101. StringBuilder sb = new StringBuilder();
  102. bool escaped = false;
  103. char contextMarker = Char.MinValue;
  104. foreach (char c in src)
  105. {
  106. if (delimiters.IndexOf(c) != -1 && !escaped)
  107. {
  108. if (contextMarker != Char.MinValue)
  109. sb.Append(c);
  110. else
  111. {
  112. if (sb.Length > 0)
  113. {
  114. parts.Add(sb.ToString());
  115. sb.Remove(0, sb.Length);
  116. }
  117. }
  118. }
  119. else if (c == '\\' && escapeBackslash)
  120. escaped = !escaped;
  121. else
  122. {
  123. int contextIndex = contextMarkers.IndexOf(c);
  124. if (!escaped && contextIndex != -1)
  125. {
  126. // if we have found the closing marker for our open
  127. // marker, then close the context
  128. if ((contextIndex % 2) == 1)
  129. {
  130. if (contextMarker == contextMarkers[contextIndex - 1])
  131. contextMarker = Char.MinValue;
  132. }
  133. else
  134. {
  135. // if the opening and closing context markers are
  136. // the same then we will always find the opening
  137. // marker.
  138. if (contextMarker == contextMarkers[contextIndex + 1])
  139. contextMarker = Char.MinValue;
  140. else if (contextMarker == Char.MinValue)
  141. contextMarker = c;
  142. }
  143. }
  144. sb.Append(c);
  145. }
  146. }
  147. if (sb.Length > 0)
  148. parts.Add(sb.ToString());
  149. return (string[])parts.ToArray(typeof(string));
  150. }
  151. }
  152. }
  153. #endif