MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OutputStream.cpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 
19 #include <ndb_global.h>
20 
21 #include <OutputStream.hpp>
22 #include <socket_io.h>
23 
24 FileOutputStream::FileOutputStream(FILE * file){
25  f = file;
26 }
27 
28 int
29 FileOutputStream::print(const char * fmt, ...){
30  va_list ap;
31  va_start(ap, fmt);
32  const int ret = vfprintf(f, fmt, ap);
33  va_end(ap);
34  return ret;
35 }
36 
37 int
38 FileOutputStream::println(const char * fmt, ...){
39  va_list ap;
40  va_start(ap, fmt);
41  const int ret = vfprintf(f, fmt, ap);
42  va_end(ap);
43  return ret + fprintf(f, "\n");
44 }
45 
46 SocketOutputStream::SocketOutputStream(NDB_SOCKET_TYPE socket,
47  unsigned write_timeout_ms) :
48  m_socket(socket),
49  m_timeout_ms(write_timeout_ms),
50  m_timedout(false),
51  m_timeout_remain(write_timeout_ms)
52 {
53 }
54 
55 int
56 SocketOutputStream::print(const char * fmt, ...){
57  va_list ap;
58 
59  if(timedout())
60  return -1;
61 
62  int time= 0;
63  va_start(ap, fmt);
64  int ret = vprint_socket(m_socket, m_timeout_ms, &time, fmt, ap);
65  va_end(ap);
66 
67  if(ret >= 0)
68  m_timeout_remain-=time;
69  if((ret < 0 && errno==SOCKET_ETIMEDOUT) || m_timeout_remain<=0)
70  {
71  m_timedout= true;
72  ret= -1;
73  }
74 
75  return ret;
76 }
77 int
78 SocketOutputStream::println(const char * fmt, ...){
79  va_list ap;
80 
81  if(timedout())
82  return -1;
83 
84  int time= 0;
85  va_start(ap, fmt);
86  int ret = vprintln_socket(m_socket, m_timeout_ms, &time, fmt, ap);
87  va_end(ap);
88 
89  if(ret >= 0)
90  m_timeout_remain-=time;
91  if ((ret < 0 && errno==SOCKET_ETIMEDOUT) || m_timeout_remain<=0)
92  {
93  m_timedout= true;
94  ret= -1;
95  }
96 
97  return ret;
98 }
99 
100 #include <UtilBuffer.hpp>
101 #include <BaseString.hpp>
102 
103 BufferedSockOutputStream::BufferedSockOutputStream(NDB_SOCKET_TYPE socket,
104  unsigned write_timeout_ms) :
105  SocketOutputStream(socket, write_timeout_ms),
106  m_buffer(*new UtilBuffer)
107 {
108 }
109 
110 BufferedSockOutputStream::~BufferedSockOutputStream()
111 {
112  delete &m_buffer;
113 }
114 
115 int
116 BufferedSockOutputStream::print(const char * fmt, ...){
117  char buf[1];
118  va_list ap;
119  int len;
120  char* pos;
121 
122  // Find out length of string
123  va_start(ap, fmt);
124  len = BaseString::vsnprintf(buf, sizeof(buf), fmt, ap);
125  va_end(ap);
126 
127  // Allocate a temp buffer for the string
128  UtilBuffer tmp;
129  if (tmp.append(len+1) == 0)
130  return -1;
131 
132  // Print to temp buffer
133  va_start(ap, fmt);
134  len = BaseString::vsnprintf((char*)tmp.get_data(), len+1, fmt, ap);
135  va_end(ap);
136 
137  // Grow real buffer so it can hold the string
138  if ((pos= (char*)m_buffer.append(len)) == 0)
139  return -1;
140 
141  // Move everything except ending 0 to real buffer
142  memcpy(pos, tmp.get_data(), tmp.length()-1);
143 
144  return 0;
145 }
146 
147 int
148 BufferedSockOutputStream::println(const char * fmt, ...){
149  char buf[1];
150  va_list ap;
151  int len;
152  char* pos;
153 
154  // Find out length of string
155  va_start(ap, fmt);
156  len = BaseString::vsnprintf(buf, sizeof(buf), fmt, ap);
157  va_end(ap);
158 
159  // Grow buffer so it can hold the string and the new line
160  if ((pos= (char*)m_buffer.append(len+1)) == 0)
161  return -1;
162 
163  // Print string to buffer
164  va_start(ap, fmt);
165  len = BaseString::vsnprintf((char*)pos, len+1, fmt, ap);
166  va_end(ap);
167 
168  // Add newline
169  pos+= len;
170  *pos= '\n';
171 
172  return 0;
173 }
174 
175 void BufferedSockOutputStream::flush(){
176  int elapsed = 0;
177  if (write_socket(m_socket, m_timeout_ms, &elapsed,
178  (const char*)m_buffer.get_data(), m_buffer.length()) != 0)
179  {
180  fprintf(stderr, "Failed to flush buffer to socket, errno: %d\n", errno);
181  }
182 
183  m_buffer.clear();
184 }
185