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.

169 lines
6.2 KiB

4 years ago
  1. #if MYSQL_6_10
  2. // Copyright ?2004, 2016 Oracle and/or its affiliates. All rights reserved.
  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. readonly bool _escapeBackslash;
  31. // Create a private ctor so the compiler doesn't give us a default one
  32. public ContextString(string contextMarkers, bool escapeBackslash)
  33. {
  34. ContextMarkers = contextMarkers;
  35. _escapeBackslash = escapeBackslash;
  36. }
  37. public string ContextMarkers { get; set; }
  38. public int IndexOf(string src, string target)
  39. {
  40. return IndexOf(src, target, 0);
  41. }
  42. public int IndexOf(string src, string target, int startIndex)
  43. {
  44. int index = src.IndexOf(target, startIndex);
  45. while (index != -1)
  46. {
  47. if (!IndexInQuotes(src, index, startIndex)) break;
  48. index = src.IndexOf(target, index + 1);
  49. }
  50. return index;
  51. }
  52. private bool IndexInQuotes(string src, int index, int startIndex)
  53. {
  54. char contextMarker = Char.MinValue;
  55. bool escaped = false;
  56. for (int i = startIndex; i < index; i++)
  57. {
  58. char c = src[i];
  59. int contextIndex = ContextMarkers.IndexOf(c);
  60. // if we have found the closing marker for our open marker, then close the context
  61. if (contextIndex > -1 && contextMarker == ContextMarkers[contextIndex] && !escaped)
  62. contextMarker = Char.MinValue;
  63. // if we have found a context marker and we are not in a context yet, then start one
  64. else if (contextMarker == Char.MinValue && contextIndex > -1 && !escaped)
  65. contextMarker = c;
  66. else if (c == '\\' && _escapeBackslash)
  67. escaped = !escaped;
  68. }
  69. return contextMarker != Char.MinValue || escaped;
  70. }
  71. public int IndexOf(string src, char target)
  72. {
  73. char contextMarker = Char.MinValue;
  74. bool escaped = false;
  75. int pos = 0;
  76. foreach (char c in src)
  77. {
  78. int contextIndex = ContextMarkers.IndexOf(c);
  79. // if we have found the closing marker for our open marker, then close the context
  80. if (contextIndex > -1 && contextMarker == ContextMarkers[contextIndex] && !escaped)
  81. contextMarker = Char.MinValue;
  82. // if we have found a context marker and we are not in a context yet, then start one
  83. else if (contextMarker == Char.MinValue && contextIndex > -1 && !escaped)
  84. contextMarker = c;
  85. else if (contextMarker == Char.MinValue && c == target)
  86. return pos;
  87. else if (c == '\\' && _escapeBackslash)
  88. escaped = !escaped;
  89. pos++;
  90. }
  91. return -1;
  92. }
  93. public string[] Split(string src, string delimiters)
  94. {
  95. ArrayList parts = new ArrayList();
  96. StringBuilder sb = new StringBuilder();
  97. bool escaped = false;
  98. char contextMarker = Char.MinValue;
  99. foreach (char c in src)
  100. {
  101. if (delimiters.IndexOf(c) != -1 && !escaped)
  102. {
  103. if (contextMarker != Char.MinValue)
  104. sb.Append(c);
  105. else
  106. {
  107. if (sb.Length <= 0) continue;
  108. parts.Add(sb.ToString());
  109. sb.Remove(0, sb.Length);
  110. }
  111. }
  112. else if (c == '\\' && _escapeBackslash)
  113. escaped = !escaped;
  114. else
  115. {
  116. int contextIndex = ContextMarkers.IndexOf(c);
  117. if (!escaped && contextIndex != -1)
  118. {
  119. // if we have found the closing marker for our open
  120. // marker, then close the context
  121. if ((contextIndex % 2) == 1)
  122. {
  123. if (contextMarker == ContextMarkers[contextIndex - 1])
  124. contextMarker = Char.MinValue;
  125. }
  126. else
  127. {
  128. // if the opening and closing context markers are
  129. // the same then we will always find the opening
  130. // marker.
  131. if (contextMarker == ContextMarkers[contextIndex + 1])
  132. contextMarker = Char.MinValue;
  133. else if (contextMarker == Char.MinValue)
  134. contextMarker = c;
  135. }
  136. }
  137. sb.Append(c);
  138. }
  139. }
  140. if (sb.Length > 0)
  141. parts.Add(sb.ToString());
  142. return (string[])parts.ToArray(typeof(string));
  143. }
  144. }
  145. }
  146. #endif