~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/linebuffer.cc

  • Committer: Monty Taylor
  • Date: 2010-12-24 02:13:05 UTC
  • mto: This revision was merged to the branch mainline in revision 2038.
  • Revision ID: mordred@inaugust.com-20101224021305-e3slv1cyjczqorij
Changed the bzrignore file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
15
 
16
16
/* readline for batch mode */
17
17
 
18
 
#include <drizzled/global.h>
19
 
#include <mysys/my_sys.h>
20
 
#include <mystrings/m_string.h>
21
 
#include "my_readline.h"
 
18
#include "config.h"
 
19
#include "drizzled/internal/my_sys.h"
 
20
#include "client/linebuffer.h"
 
21
#include <boost/version.hpp>
 
22
 
 
23
#include <vector>
22
24
 
23
25
using namespace std;
24
 
 
25
 
static bool init_line_buffer(LINE_BUFFER *buffer,File file,uint32_t size,
26
 
                            uint32_t max_size);
27
 
static bool init_line_buffer_from_string(LINE_BUFFER *buffer,char * str);
28
 
static size_t fill_buffer(LINE_BUFFER *buffer);
29
 
static char *intern_read_line(LINE_BUFFER *buffer,uint32_t *out_length);
30
 
 
31
 
 
32
 
LINE_BUFFER *batch_readline_init(uint32_t max_size,FILE *file)
33
 
{
34
 
  LINE_BUFFER *line_buff;
35
 
  if (!(line_buff=(LINE_BUFFER*)
36
 
        my_malloc(sizeof(*line_buff),MYF(MY_WME | MY_ZEROFILL))))
37
 
    return 0;
38
 
  if (init_line_buffer(line_buff,fileno(file),IO_SIZE,max_size))
39
 
  {
40
 
    free(line_buff);
41
 
    return 0;
42
 
  }
43
 
  return line_buff;
44
 
}
45
 
 
46
 
 
47
 
char *batch_readline(LINE_BUFFER *line_buff)
48
 
{
49
 
  char *pos;
50
 
  uint32_t out_length;
51
 
 
52
 
  if (!(pos=intern_read_line(line_buff,&out_length)))
53
 
    return 0;
54
 
  if (out_length && pos[out_length-1] == '\n')
55
 
    if (--out_length && pos[out_length-1] == '\r')  /* Remove '\n' */
56
 
      out_length--;                                 /* Remove '\r' */
57
 
  line_buff->read_length=out_length;
58
 
  pos[out_length]=0;
59
 
  return pos;
60
 
}
61
 
 
62
 
 
63
 
void batch_readline_end(LINE_BUFFER *line_buff)
64
 
{
65
 
  if (line_buff)
66
 
  {
67
 
    free(line_buff->buffer);
68
 
    free(line_buff);
69
 
  }
70
 
}
71
 
 
72
 
 
73
 
LINE_BUFFER *batch_readline_command(LINE_BUFFER *line_buff, char * str)
74
 
{
75
 
  if (!line_buff)
76
 
    if (!(line_buff=(LINE_BUFFER*)
77
 
          my_malloc(sizeof(*line_buff),MYF(MY_WME | MY_ZEROFILL))))
78
 
      return 0;
79
 
  if (init_line_buffer_from_string(line_buff,str))
80
 
  {
81
 
    free(line_buff);
82
 
    return 0;
83
 
  }
84
 
  return line_buff;
85
 
}
86
 
 
87
 
 
88
 
/*****************************************************************************
89
 
      Functions to handle buffered readings of lines from a stream
90
 
******************************************************************************/
91
 
 
92
 
static bool
93
 
init_line_buffer(LINE_BUFFER *buffer,File file,uint32_t size,uint32_t max_buffer)
94
 
{
95
 
  buffer->file=file;
96
 
  buffer->bufread=size;
97
 
  buffer->max_size=max_buffer;
98
 
  if (!(buffer->buffer = (char*) my_malloc(buffer->bufread+1,
99
 
                                           MYF(MY_WME | MY_FAE))))
100
 
    return 1;
101
 
  buffer->end_of_line=buffer->end=buffer->buffer;
102
 
  buffer->buffer[0]=0;                          /* For easy start test */
103
 
  return 0;
104
 
}
105
 
 
106
 
/*
107
 
  init_line_buffer_from_string can be called on the same buffer
108
 
  several times. the resulting buffer will contain a
109
 
  concatenation of all strings separated by spaces
110
 
*/
111
 
static bool init_line_buffer_from_string(LINE_BUFFER *buffer,char * str)
112
 
{
113
 
  uint old_length=(uint)(buffer->end - buffer->buffer);
114
 
  uint length= (uint) strlen(str);
115
 
  if (!(buffer->buffer= buffer->start_of_line= buffer->end_of_line=
116
 
        (char*) my_realloc((unsigned char*) buffer->buffer, old_length+length+2,
117
 
                           MYF(MY_FAE|MY_ALLOW_ZERO_PTR))))
118
 
    return 1;
119
 
  buffer->end= buffer->buffer + old_length;
120
 
  if (old_length)
121
 
    buffer->end[-1]=' ';
122
 
  memcpy(buffer->end, str, length);
123
 
  buffer->end[length]= '\n';
124
 
  buffer->end[length+1]= 0;
125
 
  buffer->end+= length+1;
126
 
  buffer->eof=1;
127
 
  buffer->max_size=1;
128
 
  return 0;
129
 
}
130
 
 
131
 
 
132
 
/*
133
 
  Fill the buffer retaining the last n bytes at the beginning of the
134
 
  newly filled buffer (for backward context).   Returns the number of new
135
 
  bytes read from disk.
136
 
*/
137
 
 
138
 
static size_t fill_buffer(LINE_BUFFER *buffer)
139
 
{
140
 
  size_t read_count;
141
 
  uint bufbytes= (uint) (buffer->end - buffer->start_of_line);
142
 
 
143
 
  if (buffer->eof)
144
 
    return 0;                                   /* Everything read */
145
 
 
146
 
  /* See if we need to grow the buffer. */
147
 
 
148
 
  for (;;)
149
 
  {
150
 
    uint start_offset=(uint) (buffer->start_of_line - buffer->buffer);
151
 
    read_count=(buffer->bufread - bufbytes)/IO_SIZE;
152
 
    if ((read_count*=IO_SIZE))
153
 
      break;
154
 
    buffer->bufread *= 2;
155
 
    if (!(buffer->buffer = (char*) my_realloc(buffer->buffer,
156
 
                                              buffer->bufread+1,
157
 
                                              MYF(MY_WME | MY_FAE))))
158
 
      return (uint) -1;
159
 
    buffer->start_of_line=buffer->buffer+start_offset;
160
 
    buffer->end=buffer->buffer+bufbytes;
161
 
  }
162
 
 
163
 
  /* Shift stuff down. */
164
 
  if (buffer->start_of_line != buffer->buffer)
165
 
  {
166
 
    memmove(buffer->buffer, buffer->start_of_line, (uint) bufbytes);
167
 
    buffer->end=buffer->buffer+bufbytes;
168
 
  }
169
 
 
170
 
  /* Read in new stuff. */
171
 
  if ((read_count= my_read(buffer->file, (unsigned char*) buffer->end, read_count,
172
 
                           MYF(MY_WME))) == MY_FILE_ERROR)
173
 
    return (size_t) -1;
174
 
 
175
 
  /* Kludge to pretend every nonempty file ends with a newline. */
176
 
  if (!read_count && bufbytes && buffer->end[-1] != '\n')
177
 
  {
178
 
    buffer->eof = read_count = 1;
179
 
    *buffer->end = '\n';
180
 
  }
181
 
  buffer->end_of_line=(buffer->start_of_line=buffer->buffer)+bufbytes;
182
 
  buffer->end+=read_count;
183
 
  *buffer->end=0;                               /* Sentinel */
184
 
  return read_count;
185
 
}
186
 
 
187
 
 
188
 
 
189
 
char *intern_read_line(LINE_BUFFER *buffer,uint32_t *out_length)
190
 
{
191
 
  char *pos;
192
 
  size_t length;
193
 
 
194
 
 
195
 
  buffer->start_of_line=buffer->end_of_line;
196
 
  for (;;)
197
 
  {
198
 
    pos=buffer->end_of_line;
199
 
    while (*pos != '\n' && *pos)
200
 
      pos++;
201
 
    if (pos == buffer->end)
202
 
    {
203
 
      if ((uint) (pos - buffer->start_of_line) < buffer->max_size)
204
 
      {
205
 
        if (!(length=fill_buffer(buffer)) || length == (size_t) -1)
206
 
          return(0);
207
 
        continue;
208
 
      }
209
 
      pos--;                                    /* break line here */
210
 
    }
211
 
    buffer->end_of_line=pos+1;
212
 
    *out_length=(uint32_t) (pos + 1 - buffer->eof - buffer->start_of_line);
213
 
    return(buffer->start_of_line);
214
 
  }
215
 
}
 
26
using namespace drizzled;
 
27
 
 
28
LineBuffer::LineBuffer(uint32_t my_max_size,FILE *my_file)
 
29
  :
 
30
    file(my_file),
 
31
    max_size(my_max_size)
 
32
{
 
33
  if (my_file)
 
34
 
 
35
  /*
 
36
    if here beacuse the old way of using file_descriptor is deprecated in boost
 
37
    1.44.  There is a #define to re-enable the function but this is broken in
 
38
    Fedora 14. See https://bugzilla.redhat.com/show_bug.cgi?id=654480
 
39
  */
 
40
#if BOOST_VERSION < 104400
 
41
    file_stream = new boost::iostreams::stream<boost::iostreams::file_descriptor>(fileno(my_file), true);
 
42
#else
 
43
    file_stream = new boost::iostreams::stream<boost::iostreams::file_descriptor>(fileno(my_file), boost::iostreams::never_close_handle);
 
44
#endif
 
45
  else
 
46
    file_stream = new std::stringstream;
 
47
  line.reserve(max_size);
 
48
}
 
49
 
 
50
void LineBuffer::addString(const string &str)
 
51
{
 
52
  (*file_stream) << str << endl;
 
53
}
 
54
 
 
55
char *LineBuffer::readline()
 
56
{
 
57
  file_stream->getline(&line[0], max_size);
 
58
 
 
59
  if (file_stream->fail())
 
60
    return 0;
 
61
  else
 
62
    return &line[0];
 
63
}
 
64