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.

216 lines
9.0 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.Generic;
  25. using System.Text;
  26. using Externals.MySql.Data.Common;
  27. namespace Externals.MySql.Data.MySqlClient
  28. {
  29. /// <summary>
  30. /// Summary description for CharSetMap.
  31. /// </summary>
  32. internal class CharSetMap
  33. {
  34. private static Dictionary<string, string> _defaultCollations;
  35. private static Dictionary<string, int> _maxLengths;
  36. private static Dictionary<string, CharacterSet> _mapping;
  37. private static readonly object LockObject;
  38. // we use a static constructor here since we only want to init
  39. // the mapping once
  40. static CharSetMap()
  41. {
  42. LockObject = new Object();
  43. InitializeMapping();
  44. }
  45. public static CharacterSet GetCharacterSet(DBVersion version, string charSetName)
  46. {
  47. if (charSetName == null)
  48. throw new ArgumentNullException("CharSetName is null");
  49. CharacterSet cs = null;
  50. if (_mapping.ContainsKey(charSetName))
  51. cs = _mapping[charSetName];
  52. if (cs == null)
  53. throw new NotSupportedException("Character set '" + charSetName + "' is not supported by .Net Framework.");
  54. return cs;
  55. }
  56. /// <summary>
  57. /// Returns the text encoding for a given MySQL character set name
  58. /// </summary>
  59. /// <param name="version">Version of the connection requesting the encoding</param>
  60. /// <param name="charSetName">Name of the character set to get the encoding for</param>
  61. /// <returns>Encoding object for the given character set name</returns>
  62. public static Encoding GetEncoding(DBVersion version, string charSetName)
  63. {
  64. try
  65. {
  66. CharacterSet cs = GetCharacterSet(version, charSetName);
  67. #if NETSTANDARD1_3
  68. Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
  69. #endif
  70. return Encoding.GetEncoding(cs.name);
  71. }
  72. catch (ArgumentException)
  73. {
  74. return Encoding.GetEncoding("utf-8");
  75. }
  76. catch (NotSupportedException)
  77. {
  78. return Encoding.GetEncoding("utf-8");
  79. }
  80. }
  81. /// <summary>
  82. /// Initializes the mapping.
  83. /// </summary>
  84. private static void InitializeMapping()
  85. {
  86. LoadCharsetMap();
  87. }
  88. private static void LoadCharsetMap()
  89. {
  90. _mapping = new Dictionary<string, CharacterSet>();
  91. _mapping.Add("latin1", new CharacterSet("windows-1252", 1));
  92. _mapping.Add("big5", new CharacterSet("big5", 2));
  93. _mapping.Add("dec8", _mapping["latin1"]);
  94. _mapping.Add("cp850", new CharacterSet("ibm850", 1));
  95. _mapping.Add("hp8", _mapping["latin1"]);
  96. _mapping.Add("koi8r", new CharacterSet("koi8-u", 1));
  97. _mapping.Add("latin2", new CharacterSet("latin2", 1));
  98. _mapping.Add("swe7", _mapping["latin1"]);
  99. _mapping.Add("ujis", new CharacterSet("EUC-JP", 3));
  100. _mapping.Add("eucjpms", _mapping["ujis"]);
  101. _mapping.Add("sjis", new CharacterSet("sjis", 2));
  102. _mapping.Add("cp932", _mapping["sjis"]);
  103. _mapping.Add("hebrew", new CharacterSet("hebrew", 1));
  104. _mapping.Add("tis620", new CharacterSet("windows-874", 1));
  105. _mapping.Add("euckr", new CharacterSet("euc-kr", 2));
  106. _mapping.Add("euc_kr", _mapping["euckr"]);
  107. _mapping.Add("koi8u", new CharacterSet("koi8-u", 1));
  108. _mapping.Add("koi8_ru", _mapping["koi8u"]);
  109. _mapping.Add("gb2312", new CharacterSet("gb2312", 2));
  110. _mapping.Add("gbk", _mapping["gb2312"]);
  111. _mapping.Add("greek", new CharacterSet("greek", 1));
  112. _mapping.Add("cp1250", new CharacterSet("windows-1250", 1));
  113. _mapping.Add("win1250", _mapping["cp1250"]);
  114. _mapping.Add("latin5", new CharacterSet("latin5", 1));
  115. _mapping.Add("armscii8", _mapping["latin1"]);
  116. _mapping.Add("utf8", new CharacterSet("utf-8", 3));
  117. _mapping.Add("ucs2", new CharacterSet("UTF-16BE", 2));
  118. _mapping.Add("cp866", new CharacterSet("cp866", 1));
  119. _mapping.Add("keybcs2", _mapping["latin1"]);
  120. _mapping.Add("macce", new CharacterSet("x-mac-ce", 1));
  121. _mapping.Add("macroman", new CharacterSet("x-mac-romanian", 1));
  122. _mapping.Add("cp852", new CharacterSet("ibm852", 2));
  123. _mapping.Add("latin7", new CharacterSet("iso-8859-7", 1));
  124. _mapping.Add("cp1251", new CharacterSet("windows-1251", 1));
  125. _mapping.Add("win1251ukr", _mapping["cp1251"]);
  126. _mapping.Add("cp1251csas", _mapping["cp1251"]);
  127. _mapping.Add("cp1251cias", _mapping["cp1251"]);
  128. _mapping.Add("win1251", _mapping["cp1251"]);
  129. _mapping.Add("cp1256", new CharacterSet("cp1256", 1));
  130. _mapping.Add("cp1257", new CharacterSet("windows-1257", 1));
  131. _mapping.Add("ascii", new CharacterSet("us-ascii", 1));
  132. _mapping.Add("usa7", _mapping["ascii"]);
  133. _mapping.Add("binary", _mapping["ascii"]);
  134. _mapping.Add("latin3", new CharacterSet("latin3", 1));
  135. _mapping.Add("latin4", new CharacterSet("latin4", 1));
  136. _mapping.Add("latin1_de", new CharacterSet("iso-8859-1", 1));
  137. _mapping.Add("german1", new CharacterSet("iso-8859-1", 1));
  138. _mapping.Add("danish", new CharacterSet("iso-8859-1", 1));
  139. _mapping.Add("czech", new CharacterSet("iso-8859-2", 1));
  140. _mapping.Add("hungarian", new CharacterSet("iso-8859-2", 1));
  141. _mapping.Add("croat", new CharacterSet("iso-8859-2", 1));
  142. _mapping.Add("latvian", new CharacterSet("iso-8859-13", 1));
  143. _mapping.Add("latvian1", new CharacterSet("iso-8859-13", 1));
  144. _mapping.Add("estonia", new CharacterSet("iso-8859-13", 1));
  145. _mapping.Add("dos", new CharacterSet("ibm437", 1));
  146. _mapping.Add("utf8mb4", new CharacterSet("utf-8", 4));
  147. _mapping.Add("utf16", new CharacterSet("utf-16BE", 2));
  148. _mapping.Add("utf16le", new CharacterSet("utf-16", 2));
  149. _mapping.Add("utf32", new CharacterSet("utf-32BE", 4));
  150. _mapping.Add("gb18030", new CharacterSet("gb18030", 4));
  151. }
  152. internal static void InitCollections(MySqlConnection connection)
  153. {
  154. _defaultCollations = new Dictionary<string, string>();
  155. _maxLengths = new Dictionary<string, int>();
  156. MySqlCommand cmd = new MySqlCommand("SHOW CHARSET", connection);
  157. using (MySqlDataReader reader = cmd.ExecuteReader())
  158. {
  159. while (reader.Read())
  160. {
  161. _defaultCollations.Add(reader.GetString(0), reader.GetString(2));
  162. _maxLengths.Add(reader.GetString(0), Convert.ToInt32(reader.GetValue(3)));
  163. }
  164. }
  165. }
  166. internal static string GetDefaultCollation(string charset, MySqlConnection connection)
  167. {
  168. lock (LockObject)
  169. {
  170. if (_defaultCollations == null)
  171. InitCollections(connection);
  172. }
  173. return !_defaultCollations.ContainsKey(charset) ? null : _defaultCollations[charset];
  174. }
  175. internal static int GetMaxLength(string charset, MySqlConnection connection)
  176. {
  177. lock (LockObject)
  178. {
  179. if (_maxLengths == null)
  180. InitCollections(connection);
  181. }
  182. return !_maxLengths.ContainsKey(charset) ? 1 : _maxLengths[charset];
  183. }
  184. }
  185. internal class CharacterSet
  186. {
  187. public string name;
  188. public int byteCount;
  189. public CharacterSet(string name, int byteCount)
  190. {
  191. this.name = name;
  192. this.byteCount = byteCount;
  193. }
  194. }
  195. }
  196. #endif