title: Using stream to treat received data
body: <p>I am receiving messages from a socket.
  The socket is packed within a header (that is basically the size of the message) and a footer that is a crc (a kind of code to check if the message is not corrupted)</p>
  
  <p>So, the layout is something like :</p>
  
  <pre><code>size (2 bytes) | message (240 bytes) | crc (4 byte)
  </code></pre>
  
  <p>I wrote a <code>operator&gt;&gt;</code></p>
  
  <p>The <code>operator&gt;&gt;</code> is as following :</p>
  
  <pre><code>std::istream &amp;operator&gt;&gt;(std::istream &amp;stream, Message &amp;msg) {
      std::int16_t size;
      stream &gt;&gt; size;
      stream.read(reinterpret_cast&lt;char*&gt;(&amp;msg), size);
  
      // Not receive enough data
      if (stream.rdbuf()-&gt;in_avail() &lt; dataSize + 4) {
          stream.setstate(std::ios_base::failbit);
          return stream;
      }
  
      std::int16_t gotCrc;
      stream &gt;&gt; gotCrc;
  
      // Data not received correctly
      if(gotCrc != computeCrc(msg)) {
          stream.setstate(std::ios_base::failbit);
      }
      return stream;
  }
  </code></pre>
  
  <p>The message can arrive byte by byte, or can arrive totally. We can even receive several messages in once.</p>
  
  <p>Basically, what I did is something like this :</p>
  
  <pre><code>struct MessageReceiver {
      std::string totalDataReceived;
      void messageArrived(std::string data) {
          // We add the data to totaldataReceived
          totalDataReceived += data;
  
          std::stringbuf buf(totalDataReceived);
          std::istream stream(&amp;buf);
          std::vector&lt;Message&gt; messages(
              std::istream_iterator&lt;Message&gt;(stream), 
              std::istream_iterator&lt;Message&gt;{});
          std::for_each(begin(messages), end(messages), processMessage);
          // +4 for crc and + 2 for the size to remove
          auto sizeToRemove = [](auto init, auto message) {return init + message.size + 4 + 2;};
          // remove the proceed messages
          totalDataReceived.remove(accumulate(begin(messages), end(messages), 0, sizeToRemove);
      }
  };
  </code></pre>
  
  <p>So basically, we receive data, we insert it into a total array of data received. We stream it, and if we got at least one message, we remove it from the buffer <code>totalDataReceived</code>.</p>
  
  <p>However, I am not sure it is the good way to go. Indeed, this code does not work when a compute a bad crc... (The message is not created, so we don't iterate over it). So each time, I am going to try to read the message with a bad crc...</p>
  
  <p>How can I do this? I can not keep all the data in <code>totalDataReceived</code> because I can receive a lot of messages during the execution life time.</p>
  
  <p>Should I implement my own streambuf?</p>