~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to drizzled/typelib.cc

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2012-06-19 10:46:49 UTC
  • mfrom: (1.1.6)
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20120619104649-e2l0ggd4oz3um0f4
Tags: upstream-7.1.36-stable
ImportĀ upstreamĀ versionĀ 7.1.36-stable

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
#include <stdio.h>
21
21
 
22
22
#include <drizzled/internal/m_string.h>
23
 
#include <drizzled/charset_info.h>
 
23
#include <drizzled/charset.h>
 
24
#include <drizzled/memory/root.h>
24
25
#include <drizzled/typelib.h>
25
26
 
26
 
namespace drizzled
27
 
{
 
27
namespace drizzled {
28
28
 
29
29
static const char field_separator=',';
30
30
 
31
 
int st_typelib::find_type_or_exit(const char *x, const char *option) const
 
31
int TYPELIB::find_type_or_exit(const char *x, const char *option) const
32
32
{
33
 
  int res= find_type(const_cast<char*>(x), 2);
 
33
  int res= find_type(x, e_dont_complete);
34
34
  if (res > 0)
35
35
    return res;
36
36
  if (!*x)
54
54
   x                    String to find
55
55
   lib                  TYPELIB (struct of pointer to values + count)
56
56
   full_name            bitmap of what to do
57
 
                        If & 1 accept only whole names
58
 
                        If & 2 don't expand if half field
59
 
                        If & 4 allow #number# as type
60
 
                        If & 8 use ',' as string terminator
 
57
                        If & 1 accept only whole names - e_match_full
 
58
                        If & 2 don't expand if half field - e_dont_complete
 
59
                        If & 4 allow #number# as type - e_allow_int
 
60
                        If & 8 use ',' as string terminator - e_use_comma
61
61
 
62
62
  NOTES
63
63
    If part, uniq field is found and full_name == 0 then x is expanded
70
70
*/
71
71
 
72
72
 
73
 
int st_typelib::find_type(const char *x, uint32_t full_name) const
74
 
{
75
 
  assert(full_name & 2);
76
 
  return find_type(const_cast<char*>(x), full_name);
77
 
}
78
 
 
79
 
int st_typelib::find_type(char *x, uint32_t full_name) const
80
 
{
 
73
int TYPELIB::find_type(const char *x, e_find_options full_name) const
 
74
{
 
75
  assert(full_name & e_dont_complete);
81
76
  if (!count)
82
77
    return 0;
83
78
  int find= 0;
85
80
  const char *j;
86
81
  for (int pos= 0; (j= type_names[pos]); pos++)
87
82
  {
88
 
    const char *i;
89
 
    for (i= x;
90
 
        *i && (!(full_name & 8) || *i != field_separator) &&
91
 
        my_toupper(&my_charset_utf8_general_ci,*i) ==
92
 
                my_toupper(&my_charset_utf8_general_ci,*j) ; i++, j++) ;
93
 
    if (! *j)
 
83
    const char *i= x;
 
84
    for (; *i && *i != field_separator &&
 
85
      my_charset_utf8_general_ci.toupper(*i) == my_charset_utf8_general_ci.toupper(*j); i++, j++)
 
86
    {
 
87
    }
 
88
    if (not *j)
94
89
    {
95
90
      while (*i == ' ')
96
 
        i++;                                    /* skip_end_space */
97
 
      if (! *i || ((full_name & 8) && *i == field_separator))
98
 
        return(pos+1);
 
91
        i++;                                    /* skip_end_space */
 
92
      if (not *i)
 
93
        return pos + 1;
99
94
    }
100
 
    if ((!*i && (!(full_name & 8) || *i != field_separator)) &&
101
 
        (!*j || !(full_name & 1)))
 
95
    if (not *i && *i != field_separator && (not *j || not (full_name & e_match_full)))
102
96
    {
103
97
      find++;
104
 
      findpos=pos;
 
98
      findpos= pos;
105
99
    }
106
100
  }
107
 
  if (find == 0 && (full_name & 4) && x[0] == '#' && strchr(x, '\0')[-1] == '#' &&
108
 
      (findpos=atoi(x+1)-1) >= 0 && (uint32_t) findpos < count)
109
 
    find=1;
110
 
  else if (find == 0 || ! x[0])
111
 
  {
112
 
    return(0);
113
 
  }
114
 
  else if (find != 1 || (full_name & 1))
115
 
  {
116
 
    return(-1);
117
 
  }
118
 
  if (!(full_name & 2))
119
 
    strcpy(x, type_names[findpos]);
 
101
  if (find == 0 || not x[0])
 
102
    return 0;
 
103
  if (find != 1 || (full_name & e_match_full))
 
104
    return -1;
120
105
  return findpos + 1;
121
106
} /* find_type */
122
107
 
123
 
 
124
 
        /* Get name of type nr 'nr' */
125
 
        /* Warning first type is 1, 0 = empty field */
126
 
 
127
 
void st_typelib::make_type(char *to, uint32_t nr) const
128
 
{
129
 
  if (!nr)
130
 
    to[0]= 0;
131
 
  else
132
 
    strcpy(to, get_type(nr - 1));
133
 
} /* make_type */
134
 
 
135
 
 
136
 
        /* Get type */
137
 
        /* Warning first type is 0 */
138
 
 
139
 
const char *st_typelib::get_type(uint32_t nr) const
140
 
{
141
 
  if (nr < count && type_names)
142
 
    return type_names[nr];
143
 
  return "?";
144
 
}
145
 
 
146
 
 
147
 
/*
148
 
  Create an integer value to represent the supplied comma-seperated
149
 
  string where each string in the TYPELIB denotes a bit position.
150
 
 
151
 
  SYNOPSIS
152
 
    find_typeset()
153
 
    x           string to decompose
154
 
    lib         TYPELIB (struct of pointer to values + count)
155
 
    err         index (not char position) of string element which was not
156
 
                found or 0 if there was no error
157
 
 
158
 
  RETURN
159
 
    a integer representation of the supplied string
160
 
*/
161
 
 
162
 
uint64_t st_typelib::find_typeset(const char *x, int *err) const
163
 
{
164
 
  if (!count)
165
 
    return 0;
166
 
  uint64_t result= 0;
167
 
  *err= 0;
168
 
  while (*x)
169
 
  {
170
 
    (*err)++;
171
 
    const char *i= x;
172
 
    while (*x && *x != field_separator) x++;
173
 
    int find= find_type(i, 2 | 8) - 1;
174
 
    if (find < 0)
175
 
      return 0;
176
 
    result|= (1ULL << find);
177
 
  }
178
 
  *err= 0;
179
 
  return result;
180
 
} /* find_set */
181
 
 
182
 
 
183
108
/*
184
109
  Create a copy of a specified TYPELIB structure.
185
110
 
193
118
    NULL otherwise
194
119
*/
195
120
 
196
 
TYPELIB *st_typelib::copy_typelib(memory::Root *root) const
 
121
TYPELIB *TYPELIB::copy_typelib(memory::Root& root) const
197
122
{
198
 
  TYPELIB *to;
199
 
  uint32_t i;
200
 
 
201
 
  if (!this)
202
 
    return NULL;
203
 
 
204
 
  if (!(to= (TYPELIB*) root->alloc_root(sizeof(TYPELIB))))
205
 
    return NULL;
206
 
 
207
 
  if (!(to->type_names= (const char **)
208
 
        root->alloc_root((sizeof(char *) + sizeof(int)) * (count + 1))))
209
 
    return NULL; // leaking
210
 
  to->type_lengths= (unsigned int *)(to->type_names + count + 1);
 
123
  TYPELIB* to= new (root) TYPELIB;
 
124
  to->type_names= (const char**)root.alloc((sizeof(char *) + sizeof(int)) * (count + 1));
 
125
  to->type_lengths= (unsigned int*)(to->type_names + count + 1);
211
126
  to->count= count;
212
 
  if (name)
213
 
  {
214
 
    if (!(to->name= root->strdup_root(name)))
215
 
      return NULL; // leaking
216
 
  }
217
 
  else
218
 
    to->name= NULL;
219
 
 
220
 
  for (i= 0; i < count; i++)
221
 
  {
222
 
    if (!(to->type_names[i]= root->strmake_root(type_names[i], type_lengths[i])))
223
 
      return NULL; // leaking
 
127
  to->name= name ? root.strdup(name) : NULL;
 
128
  for (uint32_t i= 0; i < count; i++)
 
129
  {
 
130
    to->type_names[i]= root.strdup(type_names[i], type_lengths[i]);
224
131
    to->type_lengths[i]= type_lengths[i];
225
132
  }
226
133
  to->type_names[to->count]= NULL;
227
134
  to->type_lengths[to->count]= 0;
228
 
 
229
135
  return to;
230
136
}
231
137