MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CharsetMapImpl.cpp
1 /*
2  Copyright 2010 Sun Microsystems, Inc.
3  All rights reserved. Use is subject to license terms.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 /*
20  * CharsetMapImpl.cpp
21  *
22 */
23 
24 #include "CharsetMapImpl.h"
25 
26 #include <string.h> // not using namespaces yet
27 
28 #include "my_global.h"
29 #include "mysql.h"
30 #include "my_sys.h"
31 
32 #define MYSQL_BINARY_CHARSET 63
33 
34 /* build_map():
35  Actually building the map is deferred until after my_init() etc. have
36  fully initialized mysql's strings library. They cannot be done as part
37  of static initialization.
38 */
39 void CharsetMapImpl::build_map()
40 {
41  int cs_ucs2 = 0;
42  int cs_utf16 = 0;
43  int cs_utf8 = 0;
44  int cs_utf8_3 = 0;
45  int cs_utf8_4 = 0;
46 
47  /* ISO 8859 Charsets */
48  put("latin1" , "windows-1252"); // Western Europe
49  put("latin2" , "ISO-8859-2"); // Central Europe
50  put("greek" , "ISO-8859-7");
51  put("hebrew", "ISO-8859-8");
52  put("latin5", "ISO-8859-9"); // Turkish
53  put("latin7", "ISO-8859-13"); // Baltics
54 
55  /* IBM & Microsoft code pages */
56  put("cp850", "IBM850");
57  put("cp852", "IBM852");
58  put("cp866", "IBM866");
59  put("cp1250", "windows-1250");
60  put("cp1251", "windows-1251");
61  put("cp1256", "windows-1256");
62  put("cp1257", "windows-1257");
63 
64  /* Asian Encodings */
65  put("ujis", "EUC-JP");
66  put("euckr", "EUC-KR");
67  put("cp932", "windows-31j");
68  put("eucjpms", "EUC_JP_Solaris");
69  put("tis620", "TIS-620");
70 
71  /* Unicode */
72  put("utf8", "UTF-8");
73  put("utf8mb3", "UTF-8");
74  put("utf8mb4", "UTF-8");
75  put("ucs2", "UTF-16");
76  put("utf16", "UTF-16");
77  put("utf32", "UTF-32");
78 
79  /* You could add here:
80  put("filename", "UTF-8"); // No. 17: filename encoding
81  ... but we're going to leave it out for now, because it should not be found
82  in the database. */
83 
84  /* Others */
85  put("hp8", "HP-ROMAN-8");
86  put("swe7", "ISO646-SE");
87  put("koi8r", "KOI8-R"); // Russian Cyrillic
88  put("koi8u", "KOI8-U"); // Ukrainian Cyrillic
89  put("macce", "MacCentralEurope");
90 
91  /* Build the fixed map */
92  for(unsigned int i = 0 ; i < 255 ; i++)
93  {
94  CHARSET_INFO *cs = get_charset(i, MYF(0));
95  register const char *mysql_name = 0;
96  const char *mapped_name = 0;
97 
98  if(cs)
99  {
100  mysql_name = cs->csname;
101  mapped_name = get(mysql_name);
102  if(! cs_ucs2 && ! strcmp(mysql_name, "ucs2")) cs_ucs2 = i;
103  if(! cs_utf16 && ! strcmp(mysql_name, "utf16")) cs_utf16 = i;
104  if(! cs_utf8 && ! strcmp(mysql_name, "utf8")) cs_utf8 = i;
105  if(! cs_utf8_3 && ! strcmp(mysql_name, "utf8mb3")) cs_utf8_3 = i;
106  if(! cs_utf8_4 && ! strcmp(mysql_name, "utf8mb4")) cs_utf8_4 = i;
107  }
108 
109  if(mapped_name) mysql_charset_name[i] = mapped_name;
110  else mysql_charset_name[i] = mysql_name;
111  }
112 
113  if(cs_utf16)
114  UTF16Charset = cs_utf16;
115  else if(cs_ucs2)
116  UTF16Charset = cs_ucs2;
117  else
118  UTF16Charset = 0;
119 
120  if(cs_utf8_4)
121  UTF8Charset = cs_utf8_4;
122  else if(cs_utf8_3)
123  UTF8Charset = cs_utf8_3;
124  else if(cs_utf8)
125  UTF8Charset = cs_utf8;
126  else
127  UTF8Charset = 0;
128 
129  ready = 1;
130 }
131 
132 
133 const char * CharsetMapImpl::getName(int csnum)
134 {
135  if((csnum > 255) || (csnum < 0))
136  {
137  return 0;
138  }
139  return mysql_charset_name[csnum];
140 }
141 
142 
143 inline int CharsetMapImpl::hash(const char *name) const
144 {
145  const unsigned char *p;
146  unsigned int h = 0;
147 
148  for (p = (const unsigned char *) name ; *p != '\0' ; p++)
149  h = 27 * h + *p;
150  return h % CHARSET_MAP_HASH_TABLE_SIZE;
151 }
152 
153 
154 void CharsetMapImpl::put(const char *name, const char *value)
155 {
156  unsigned int h = hash(name);
157  MapTableItem *i = & map[h];
158  if(i->name)
159  {
160  i = new MapTableItem;
161  map[h].next = i;
162  collisions++;
163  }
164 
165  i->name = name;
166  i->value = value;
167  n_items++;
168 }
169 
170 
171 const char * CharsetMapImpl::get(const char *name) const
172 {
173  unsigned int h = hash(name);
174  const MapTableItem *i = & map[h];
175  if(i->name)
176  {
177  for( ; i ; i = i->next)
178  {
179  if(! strcmp(name, i->name)) return i->value;
180  }
181  }
182  return 0;
183 }