message_decoder.cc 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "remoting/protocol/message_decoder.h"
  5. #include <stdint.h>
  6. #include "base/check_op.h"
  7. #include "net/base/io_buffer.h"
  8. #include "remoting/base/compound_buffer.h"
  9. #include "remoting/proto/internal.pb.h"
  10. #include "third_party/webrtc/rtc_base/byte_order.h"
  11. namespace remoting {
  12. namespace protocol {
  13. MessageDecoder::MessageDecoder()
  14. : next_payload_(0),
  15. next_payload_known_(false) {
  16. }
  17. MessageDecoder::~MessageDecoder() = default;
  18. void MessageDecoder::AddData(scoped_refptr<net::IOBuffer> data,
  19. int data_size) {
  20. buffer_.Append(std::move(data), data_size);
  21. }
  22. CompoundBuffer* MessageDecoder::GetNextMessage() {
  23. // Determine the payload size. If we already know it then skip this part.
  24. // We may not have enough data to determine the payload size so use a
  25. // utility function to find out.
  26. int next_payload = -1;
  27. if (!next_payload_known_ && GetPayloadSize(&next_payload)) {
  28. DCHECK_NE(-1, next_payload);
  29. next_payload_ = next_payload;
  30. next_payload_known_ = true;
  31. }
  32. // If the next payload size is still not known or we don't have enough
  33. // data for parsing then exit.
  34. if (!next_payload_known_ || buffer_.total_bytes() < next_payload_)
  35. return nullptr;
  36. CompoundBuffer* message_buffer = new CompoundBuffer();
  37. message_buffer->CopyFrom(buffer_, 0, next_payload_);
  38. message_buffer->Lock();
  39. buffer_.CropFront(next_payload_);
  40. next_payload_known_ = false;
  41. return message_buffer;
  42. }
  43. bool MessageDecoder::GetPayloadSize(int* size) {
  44. // The header has a size of 4 bytes.
  45. const int kHeaderSize = sizeof(int32_t);
  46. if (buffer_.total_bytes() < kHeaderSize)
  47. return false;
  48. CompoundBuffer header_buffer;
  49. char header[kHeaderSize];
  50. header_buffer.CopyFrom(buffer_, 0, kHeaderSize);
  51. header_buffer.CopyTo(header, kHeaderSize);
  52. *size = rtc::GetBE32(header);
  53. buffer_.CropFront(kHeaderSize);
  54. return true;
  55. }
  56. } // namespace protocol
  57. } // namespace remoting