branch with improvemnts

Fork of M2XStreamClient by AT&T M2X Team

Revision:
11:5c71c2948812
Parent:
0:f479e4f4db0e
--- a/Client.cpp	Wed Sep 10 13:07:34 2014 +0000
+++ b/Client.cpp	Sat Sep 13 15:49:53 2014 +0000
@@ -3,7 +3,8 @@
 
 #include <stdint.h>
 
-Client::Client() : _len(0), _sock() {
+Client::Client() : _incnt(0), _outcnt(0), _sock() {
+    _sock.set_blocking(false, 1500);
 }
 
 Client::~Client() {
@@ -18,37 +19,84 @@
 }
 
 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;
+}
+
+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 (_len > 0) { return 1; }
-  int ret = read(_buf, 1);
-  if (ret <= 0) { return 0; }
-  _len = ret;
-  return 1;
+  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);
-}
-
-void Client::flush() {
-  // does nothing, TCP stack takes care of this
+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::stop() {
@@ -56,5 +104,5 @@
 }
 
 uint8_t Client::connected() {
-  return _sock.is_connected();
+  return _sock.is_connected() ? 1 : 0;
 }