testing buffer improvements from mazgch
Fork of M2XStreamClient by
Revision 12:0c9041dd96a6, committed 2014-09-24
- Comitter:
- jb8414
- Date:
- Wed Sep 24 16:46:43 2014 +0000
- Parent:
- 11:a11af0c81cfa
- Commit message:
- testing buffer improvements from mazgch
Changed in this revision
Client.cpp | Show annotated file Show diff for this revision Revisions of this file |
Client.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r a11af0c81cfa -r 0c9041dd96a6 Client.cpp --- a/Client.cpp Mon Sep 15 14:01:40 2014 +0000 +++ b/Client.cpp Wed Sep 24 16:46:43 2014 +0000 @@ -1,60 +1,108 @@ #include "Client.h" #include "mbed.h" - + #include <stdint.h> - -Client::Client() : _len(0), _sock() { + +Client::Client() : _incnt(0), _outcnt(0), _sock() { + _sock.set_blocking(false, 1500); } - + Client::~Client() { } - + int Client::connect(const char *host, uint16_t port) { return _sock.connect(host, port) == 0; } - + size_t Client::write(uint8_t b) { return write(&b, 1); } - + size_t Client::write(const uint8_t *buf, size_t size) { - _sock.set_blocking(false, 15000); - // NOTE: we know it's dangerous to cast from (const uint8_t *) to (char *), - // but we are trying to maintain a stable interface between the Arduino - // one and the mbed one. What's more, while TCPSocketConnection has no - // intention of modifying the data here, it requires us to send a (char *) - // typed data. So we belive it's safe to do the cast here. - return _sock.send_all(const_cast<char*>((const char*) buf), size); + size_t cnt = 0; + while (size) { + int tmp = sizeof(_outbuf) - _outcnt; + if (tmp > size) tmp = size; + memcpy(_outbuf + _outcnt, buf, tmp); + _outcnt += tmp; + buf += tmp; + size -= tmp; + cnt += tmp; + // if no space flush it + if (_outcnt == sizeof(_outbuf)) + _flushout(); + } + return cnt; } - -int Client::available() { - if (_len > 0) { return 1; } - int ret = read(_buf, 1); - if (ret <= 0) { return 0; } - _len = ret; - return 1; + +void Client::_flushout(void) +{ + if (_outcnt > 0) { + // NOTE: we know it's dangerous to cast from (const uint8_t *) to (char *), + // but we are trying to maintain a stable interface between the Arduino + // one and the mbed one. What's more, while TCPSocketConnection has no + // intention of modifying the data here, it requires us to send a (char *) + // typed data. So we belive it's safe to do the cast here. + _sock.send_all(const_cast<char*>((const char*) _outbuf), _outcnt); + _outcnt = 0; + } +} + +void Client::_fillin(void) +{ + int tmp = sizeof(_inbuf) - _incnt; + if (tmp) { + tmp = _sock.receive_all((char*)_inbuf + _incnt, tmp); + if (tmp > 0) + _incnt += tmp; + } } - + +void Client::flush() { + _flushout(); +} + +int Client::available() { + if (_incnt == 0) { + _flushout(); + _fillin(); + } + return (_incnt > 0) ? 1 : 0; +} + int Client::read() { - if (_len > 0) { - _len = 0; - return _buf[0]; - } - return -1; + uint8_t ch; + return (read(&ch, 1) == 1) ? ch : -1; } - -int Client::read(uint8_t *buf, size_t size) { - return _sock.receive_all((char*) buf, size); + +int Client::read(uint8_t *buf, size_t size) { + int cnt = 0; + while (size) { + // need more + if (size > _incnt) { + _flushout(); + _fillin(); + } + if (_incnt > 0) { + int tmp = _incnt; + if (tmp > size) tmp = size; + memcpy(buf, _inbuf, tmp); + if (tmp != _incnt) + memmove(_inbuf, _inbuf + tmp, _incnt - tmp); + _incnt -= tmp; + size -= tmp; + buf += tmp; + cnt += tmp; + } else // no data + break; + } + return cnt; } - -void Client::flush() { - // does nothing, TCP stack takes care of this -} - + void Client::stop() { _sock.close(); } - + uint8_t Client::connected() { - return _sock.is_connected(); -} + return _sock.is_connected() ? 1 : 0; +} \ No newline at end of file
diff -r a11af0c81cfa -r 0c9041dd96a6 Client.h --- a/Client.h Mon Sep 15 14:01:40 2014 +0000 +++ b/Client.h Wed Sep 24 16:46:43 2014 +0000 @@ -1,11 +1,11 @@ #ifndef Client_h #define Client_h - + #include "TCPSocketConnection.h" - + #include "Print.h" #include "Utility.h" - + /* * TCP Client */ @@ -13,7 +13,7 @@ public: Client(); ~Client(); - + virtual int connect(const char *host, uint16_t port); virtual size_t write(uint8_t); virtual size_t write(const uint8_t *buf, size_t size); @@ -24,9 +24,14 @@ virtual uint8_t connected(); private: virtual int read(uint8_t *buf, size_t size); - uint8_t _buf[1]; - uint8_t _len; + void _fillin(void); + uint8_t _inbuf[128]; + uint8_t _incnt; + void _flushout(void); + uint8_t _outbuf[128]; + uint8_t _outcnt; TCPSocketConnection _sock; }; - + #endif + \ No newline at end of file