BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
iostream.cpp
Go to the documentation of this file.
1 #include <fc/io/iostream.hpp>
2 #include <fc/io/sstream.hpp>
3 #include <fc/thread/thread.hpp>
4 #include <iostream>
5 #include <string.h>
6 #include <fc/thread/mutex.hpp>
8 #include <string>
9 #include <boost/lexical_cast.hpp>
10 #include <boost/thread/mutex.hpp>
11 #include <fc/io/stdio.hpp>
12 #include <fc/log/logger.hpp>
13 
14 namespace fc {
15 
16  struct cin_buffer {
17  cin_buffer():eof(false),write_pos(0),read_pos(0),cinthread("cin"){
18 
19  cinthread.async( [=](){read();}, "cin_buffer::read" );
20  }
21 
22  void read() {
23  char c;
24  std::cin.read(&c,1);
25  while( !std::cin.eof() ) {
26  while( write_pos - read_pos > 0xfffff ) {
27  fc::promise<void>::ptr wr = fc::promise<void>::create("cin_buffer::write_ready");
28  write_ready = wr;
29  if( write_pos - read_pos <= 0xfffff ) {
30  wr->wait();
31  }
32  write_ready.reset();
33  }
34  buf[write_pos&0xfffff] = c;
35  ++write_pos;
36 
38  { // copy read_ready because it is accessed from multiple threads
40  tmp = read_ready;
41  }
42 
43  if( tmp && !tmp->ready() ) {
44  tmp->set_value();
45  }
46  std::cin.read(&c,1);
47  }
48  eof = true;
50  { // copy read_ready because it is accessed from multiple threads
52  tmp = read_ready;
53  }
54  if( tmp && !tmp->ready() ) {
55  tmp->set_exception( exception_ptr( new eof_exception() ));
56  }
57  }
58  boost::mutex read_ready_mutex;
61 
62  volatile bool eof;
63 
64  volatile uint64_t write_pos;
65  char buf[0xfffff+1]; // 1 mb buffer
66  volatile uint64_t read_pos;
68  };
69 
71  static cin_buffer* b = new cin_buffer();
72  return *b;
73  }
74 
75 
76  fc::thread& cin_thread() { static fc::thread i("cin"); return i; }
77 
78  fc::istream& getline( fc::istream& i, std::string& s, char delim ) {
79  fc::stringstream ss;
80  char c;
81  i.read( &c, 1 );
82  while( true ) {
83  if( c == delim ) { s = ss.str(); return i; }
84  if( c != '\r' ) ss.write(&c,1);
85  i.read( &c, 1 );
86  }
87  s = ss.str();
88  return i;
89  }
90 
91 
92  size_t cout_t::writesome( const char* buf, size_t len ) { std::cout.write(buf,len); return len; }
93  size_t cout_t::writesome( const std::shared_ptr<const char>& buf, size_t len, size_t offset ) { return writesome(buf.get() + offset, len); }
94  void cout_t::close() {}
96 
97  size_t cerr_t::writesome( const char* buf, size_t len ) { std::cerr.write(buf,len); return len; }
98  size_t cerr_t::writesome( const std::shared_ptr<const char>& buf, size_t len, size_t offset ) { return writesome(buf.get() + offset, len); }
99  void cerr_t::close() {};
101 
102 
103  size_t cin_t::readsome( char* buf, size_t len ) {
104  cin_buffer& b = get_cin_buffer();
105  int64_t avail = b.write_pos - b.read_pos;
106  avail = (std::min)(int64_t(len),avail);
107  int64_t u = 0;
108 
109  if( !((avail>0) && (len>0)) ) {
110  read( buf, 1 );
111  ++buf;
112  ++u;
113  --len;
114  }
115 
116  while( (avail>0) && (len>0) ) {
117  *buf = b.buf[b.read_pos&0xfffff];
118  ++b.read_pos;
119  ++buf;
120  --avail;
121  --len;
122  ++u;
123  }
124  return size_t(u);
125  }
126  size_t cin_t::readsome( const std::shared_ptr<char>& buf, size_t len, size_t offset ) { return readsome(buf.get() + offset, len); }
127 
129  /*
130  cin_buffer& b = get_cin_buffer();
131  if( b.read_ready ) {
132  b.read_ready->wait();
133  }
134  */
135  }
136  istream& cin_t::read( char* buf, size_t len ) {
137  cin_buffer& b = get_cin_buffer();
138  do {
139  while( !b.eof && (b.write_pos - b.read_pos)==0 ){
140  // wait for more...
141  fc::promise<void>::ptr rr = fc::promise<void>::create("cin_buffer::read_ready");
142  { // copy read_ready because it is accessed from multiple threads
144  b.read_ready = rr;
145  }
146  if( b.write_pos - b.read_pos == 0 ) {
147  rr->wait();
148  }
149  // b.read_ready.reset();
150  { // copy read_ready because it is accessed from multiple threads
152  b.read_ready.reset();
153  }
154  }
155  if( b.eof ) FC_THROW_EXCEPTION( eof_exception, "cin" );
156  size_t r = readsome( buf, len );
157  buf += r;
158  len -= r;
159 
160  auto tmp = b.write_ready; // copy write_writey because it is accessed from multiple thwrites
161  if( tmp && !tmp->ready() ) {
162  tmp->set_value();
163  }
164  } while( len > 0 && !b.eof );
165  if( b.eof ) FC_THROW_EXCEPTION( eof_exception, "cin" );
166  return *this;
167  }
168 
169  bool cin_t::eof()const { return get_cin_buffer().eof; }
170 
171 
172  std::shared_ptr<cin_t> cin_ptr = std::make_shared<cin_t>();
173  std::shared_ptr<cout_t> cout_ptr = std::make_shared<cout_t>();
174  std::shared_ptr<cerr_t> cerr_ptr = std::make_shared<cerr_t>();
178 
179 
180  ostream& operator<<( ostream& o, const char v )
181  {
182  o.write( &v, 1 );
183  return o;
184  }
185  ostream& operator<<( ostream& o, const char* v )
186  {
187  o.write( v, strlen(v) );
188  return o;
189  }
190 
191  ostream& operator<<( ostream& o, const std::string& v )
192  {
193  o.write( v.c_str(), v.size() );
194  return o;
195  }
196 
197  ostream& operator<<( ostream& o, const double& v )
198  {
199  return o << boost::lexical_cast<std::string>(v).c_str();
200  }
201 
202  ostream& operator<<( ostream& o, const float& v )
203  {
204  return o << boost::lexical_cast<std::string>(v).c_str();
205  }
206 
207  ostream& operator<<( ostream& o, const int64_t& v )
208  {
209  return o << boost::lexical_cast<std::string>(v).c_str();
210  }
211 
212  ostream& operator<<( ostream& o, const uint64_t& v )
213  {
214  return o << boost::lexical_cast<std::string>(v).c_str();
215  }
216 
217  ostream& operator<<( ostream& o, const int32_t& v )
218  {
219  return o << boost::lexical_cast<std::string>(v).c_str();
220  }
221 
222  ostream& operator<<( ostream& o, const uint32_t& v )
223  {
224  return o << boost::lexical_cast<std::string>(v).c_str();
225  }
226 
227  ostream& operator<<( ostream& o, const int16_t& v )
228  {
229  return o << boost::lexical_cast<std::string>(v).c_str();
230  }
231 
232  ostream& operator<<( ostream& o, const uint16_t& v )
233  {
234  return o << boost::lexical_cast<std::string>(v).c_str();
235  }
236 
237  ostream& operator<<( ostream& o, const int8_t& v )
238  {
239  return o << boost::lexical_cast<std::string>(v).c_str();
240  }
241 
242  ostream& operator<<( ostream& o, const uint8_t& v )
243  {
244  return o << boost::lexical_cast<std::string>(v).c_str();
245  }
246 
247 #ifdef __APPLE__
248  ostream& operator<<( ostream& o, const size_t& v )
249  {
250  return o << boost::lexical_cast<std::string>(v).c_str();
251  }
252 
253 #endif
254 
255  istream& operator>>( istream& o, std::string& v )
256  {
257  assert(false && "not implemented");
258  return o;
259  }
260 
261  istream& operator>>( istream& o, char& v )
262  {
263  o.read(&v,1);
264  return o;
265  }
266 
268  {
269  char tmp;
270  read(&tmp,1);
271  return tmp;
272  }
273 
274  istream& istream::read( char* buf, size_t len )
275  {
276  char* pos = buf;
277  while( size_t(pos-buf) < len )
278  pos += readsome( pos, len - (pos - buf) );
279  return *this;
280  }
281 
282  istream& istream::read( const std::shared_ptr<char>& buf, size_t len, size_t offset )
283  {
284  size_t bytes_read = 0;
285  while( bytes_read < len )
286  bytes_read += readsome(buf, len - bytes_read, bytes_read + offset);
287  return *this;
288  }
289 
290  ostream& ostream::write( const char* buf, size_t len )
291  {
292  const char* pos = buf;
293  while( size_t(pos-buf) < len )
294  pos += writesome( pos, len - (pos - buf) );
295  return *this;
296  }
297 
298  ostream& ostream::write( const std::shared_ptr<const char>& buf, size_t len, size_t offset )
299  {
300  size_t bytes_written = 0;
301  while( bytes_written < len )
302  bytes_written += writesome(buf, len - bytes_written, bytes_written + offset);
303  return *this;
304  }
305 
306 } // namespace fc
fc::promise
Definition: future.hpp:109
stdio.hpp
fc::promise_base::ready
bool ready() const
Definition: future.cpp:37
fc::cin_buffer::read_pos
volatile uint64_t read_pos
Definition: iostream.cpp:66
fc::cerr_t::flush
virtual void flush()
Definition: iostream.cpp:100
fc::cin_buffer::read
void read()
Definition: iostream.cpp:22
fc::cin_buffer::buf
char buf[0xfffff+1]
Definition: iostream.cpp:65
fc::cin_buffer::eof
volatile bool eof
Definition: iostream.cpp:62
fc::scoped_lock
Definition: scoped_lock.hpp:5
fc::cin_t::~cin_t
~cin_t()
Definition: iostream.cpp:128
fc::cout_t::writesome
virtual size_t writesome(const char *buf, size_t len)
Definition: iostream.cpp:92
fc::promise::wait
const T & wait(const microseconds &timeout=microseconds::maximum())
Definition: future.hpp:127
fc::operator>>
auto operator>>(U &u, fwd< T, S, A > &f) -> typename detail::extract_op< U, T >::type
Definition: fwd_impl.hpp:53
fc::promise< void >::set_value
void set_value()
Definition: future.hpp:181
fc::cerr_t
Definition: stdio.hpp:15
fc::cout_t::close
virtual void close()
Definition: iostream.cpp:94
fc
Definition: api.hpp:15
fc::cin_thread
fc::thread & cin_thread()
Definition: iostream.cpp:76
fc::cin_t::read
virtual istream & read(char *buf, size_t len)
Definition: iostream.cpp:136
scoped_lock.hpp
fc::get_cin_buffer
cin_buffer & get_cin_buffer()
Definition: iostream.cpp:70
fc::cin_t
Definition: stdio.hpp:23
fc::cin
cin_t & cin
Definition: iostream.cpp:177
fc::stringstream::str
std::string str()
Definition: sstream.cpp:33
fc::promise::create
static ptr create(const char *desc FC_TASK_NAME_DEFAULT_ARG)
Definition: future.hpp:114
fc::exception_ptr
std::shared_ptr< exception > exception_ptr
Definition: exception.hpp:131
fc::cout
cout_t & cout
Definition: iostream.cpp:175
fc::istream::get
virtual char get()
Definition: iostream.cpp:267
iostream.hpp
fc::operator<<
auto operator<<(U &u, const fwd< T, S, A > &f) -> typename detail::insert_op< U, T >::type
Definition: fwd_impl.hpp:50
fc::thread
Definition: thread.hpp:39
sstream.hpp
thread.hpp
fc::cerr_t::close
virtual void close()
Definition: iostream.cpp:99
fc::cin_buffer::write_ready
fc::promise< void >::ptr write_ready
Definition: iostream.cpp:60
fc::istream::read
istream & read(char *buf, size_t len)
Definition: iostream.cpp:274
fc::ostream
Definition: iostream.hpp:41
fc::cin_buffer::cin_buffer
cin_buffer()
Definition: iostream.cpp:17
fc::cerr
cerr_t & cerr
Definition: iostream.cpp:176
fc::istream
Definition: iostream.hpp:11
fc::cerr_t::writesome
virtual size_t writesome(const char *buf, size_t len)
Definition: iostream.cpp:97
fc::istream::readsome
virtual size_t readsome(char *buf, size_t len)=0
fc::promise::set_value
void set_value(const T &v)
Definition: future.hpp:136
fc::cin_buffer::read_ready
fc::promise< void >::ptr read_ready
Definition: iostream.cpp:59
fc::cin_t::readsome
virtual size_t readsome(char *buf, size_t len)
Definition: iostream.cpp:103
fc::cout_t::flush
virtual void flush()
Definition: iostream.cpp:95
fc::cin_buffer::read_ready_mutex
boost::mutex read_ready_mutex
Definition: iostream.cpp:58
fc::cerr_ptr
std::shared_ptr< cerr_t > cerr_ptr
Definition: iostream.cpp:174
fc::promise_base::set_exception
void set_exception(const fc::exception_ptr &e)
Definition: future.cpp:44
fc::cin_buffer
Definition: iostream.cpp:16
fc::ostream::writesome
virtual size_t writesome(const char *buf, size_t len)=0
logger.hpp
fc::cin_t::eof
virtual bool eof() const
Definition: iostream.cpp:169
fc::cin_ptr
std::shared_ptr< cin_t > cin_ptr
Definition: iostream.cpp:172
fc::thread::async
auto async(Functor &&f, const char *desc FC_TASK_NAME_DEFAULT_ARG, priority prio=priority()) -> fc::future< decltype(f())>
Definition: thread.hpp:87
fc::cout_ptr
std::shared_ptr< cout_t > cout_ptr
Definition: iostream.cpp:173
fc::ostream::write
ostream & write(const char *buf, size_t len)
Definition: iostream.cpp:290
FC_THROW_EXCEPTION
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
Definition: exception.hpp:379
fc::stringstream
Definition: sstream.hpp:7
fc::cout_t
Definition: stdio.hpp:7
fc::cin_buffer::write_pos
volatile uint64_t write_pos
Definition: iostream.cpp:64
fc::getline
fc::istream & getline(fc::istream &, std::string &, char delim='\n')
Definition: iostream.cpp:78
mutex.hpp
fc::cin_buffer::cinthread
fc::thread cinthread
Definition: iostream.cpp:67