1 /* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; version 2 of the License.
6 
7    This program is distributed in the hope that it will be useful,
8    but WITHOUT ANY WARRANTY; without even the implied warranty of
9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10    GNU General Public License for more details.
11 
12    You should have received a copy of the GNU General Public License
13    along with this program; if not, write to the Free Software
14    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */
15 
16 /*
17   Functions to read and parse geometrical data.
18   NOTE: These functions assumes that the string is end \0 terminated!
19 */
20 
21 #include "mariadb.h"
22 #include "sql_priv.h"
23 #include "gstream.h"
24 #include "m_string.h"                           // LEX_STRING
25 
26 enum Gis_read_stream::enum_tok_types Gis_read_stream::get_next_toc_type()
27 {
28   skip_space();
29   if (m_cur >= m_limit)
30     return eostream;
31   if (my_isvar_start(&my_charset_bin, *m_cur))
32     return word;
33   if ((*m_cur >= '0' && *m_cur <= '9') || *m_cur == '-' || *m_cur == '+')
34     return numeric;
35   if (*m_cur == '(')
36     return l_bra;
37   if (*m_cur == ')')
38     return r_bra;
39   if (*m_cur == ',')
40     return comma;
41   return unknown;
42 }
43 
44 
45 bool Gis_read_stream::lookup_next_word(LEX_STRING *res)
46 {
47   const char *cur= m_cur;
48 
49   skip_space();
50   res->str= (char*) cur;
51   /* The following will also test for \0 */
52   if ((cur >= m_limit) || !my_isvar_start(&my_charset_bin, *cur))
53     return 1;
54 
55   /*
56     We can't combine the following increment with my_isvar() because
57     my_isvar() is a macro that would cause side effects
58   */
59   cur++;
60   while ((cur < m_limit) && my_isvar(&my_charset_bin, *cur))
61     cur++;
62 
63   res->length= (uint32) (cur - res->str);
64   return 0;
65 }
66 
67 
68 bool Gis_read_stream::get_next_word(LEX_STRING *res)
69 {
70   skip_space();
71   res->str= (char*) m_cur;
72   /* The following will also test for \0 */
73   if ((m_cur >= m_limit) || !my_isvar_start(&my_charset_bin, *m_cur))
74     return 1;
75 
76   /*
77     We can't combine the following increment with my_isvar() because
78     my_isvar() is a macro that would cause side effects
79   */
80   m_cur++;
81   while ((m_cur < m_limit) && my_isvar(&my_charset_bin, *m_cur))
82     m_cur++;
83 
84   res->length= (uint32) (m_cur - res->str);
85   return 0;
86 }
87 
88 
89 /*
90   Read a floating point number
91 
92   NOTE: Number must start with a digit or sign. It can't start with a decimal
93   point
94 */
95 
96 bool Gis_read_stream::get_next_number(double *d)
97 {
98   char *endptr;
99   int err;
100 
101   skip_space();
102 
103   if ((m_cur >= m_limit) ||
104       ((*m_cur < '0' || *m_cur > '9') && *m_cur != '-' && *m_cur != '+'))
105   {
106     set_error_msg("Numeric constant expected");
107     return 1;
108   }
109 
110   *d = my_strntod(m_charset, (char *)m_cur,
111 		  (uint) (m_limit-m_cur), &endptr, &err);
112   if (err)
113     return 1;
114   if (endptr)
115     m_cur = endptr;
116   return 0;
117 }
118 
119 
120 bool Gis_read_stream::check_next_symbol(char symbol)
121 {
122   skip_space();
123   if ((m_cur >= m_limit) || (*m_cur != symbol))
124   {
125     char buff[32];
126     strmov(buff, "'?' expected");
127     buff[2]= symbol;
128     set_error_msg(buff);
129     return 1;
130   }
131   m_cur++;
132   return 0;
133 }
134 
135 
136 /*
137   Remember error message.
138 */
139 
140 void Gis_read_stream::set_error_msg(const char *msg)
141 {
142   size_t len= strlen(msg);			// ok in this context
143   m_err_msg= (char *) my_realloc(m_err_msg, (uint) len + 1, MYF(MY_ALLOW_ZERO_PTR));
144   memcpy(m_err_msg, msg, len + 1);
145 }
146