message_buffer.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. * Copyright (C) 2016 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef MESSAGE_BUFFER_H_
  17. #define MESSAGE_BUFFER_H_
  18. #include <cstdint>
  19. #include <memory>
  20. #include <tuple>
  21. #include "android-base/macros.h"
  22. #include "wifilogd/local_utils.h"
  23. namespace android {
  24. namespace wifilogd {
  25. // A fixed-size buffer, which provides FIFO access to read and write
  26. // a sequence of messages.
  27. class MessageBuffer {
  28. public:
  29. // A wrapper which guarantees that a MessageBuffer will be rewound,
  30. // when the program exits the wrapper's scope. The user must ensure that
  31. // |buffer| does not expire before the ScopedRewinder.
  32. class ScopedRewinder {
  33. public:
  34. explicit ScopedRewinder(NONNULL MessageBuffer* buffer) : buffer_(buffer) {}
  35. ~ScopedRewinder() { buffer_->Rewind(); }
  36. private:
  37. MessageBuffer* const buffer_;
  38. };
  39. // Constructs the buffer. |size| must be greater than GetHeaderSize().
  40. explicit MessageBuffer(size_t size);
  41. // Appends a single message to the buffer. |data_len| must be >=1. Returns
  42. // true if the message was added to the buffer.
  43. bool Append(NONNULL const uint8_t* data, uint16_t data_len);
  44. // Returns true if the buffer is large enough to hold |length| bytes of user
  45. // data, when the buffer is empty.
  46. bool CanFitEver(uint16_t length) const;
  47. // Returns true if the buffer currently has enough free space to hold |length|
  48. // bytes of user data.
  49. bool CanFitNow(uint16_t length) const;
  50. // Clears the buffer. An immediately following read operation will return an
  51. // empty message. An immediately following write operation will write to the
  52. // head of the buffer. Clearing may be lazy (i.e., underlying storage is not
  53. // necessarily zeroed).
  54. void Clear();
  55. // Returns the first unread message in the buffer. If there is no such
  56. // message, returns {nullptr, 0}. MessageBuffer retains ownership of the
  57. // message's storage.
  58. std::tuple<const uint8_t*, size_t> ConsumeNextMessage();
  59. // Returns the size of MessageBuffer's per-message header.
  60. static constexpr size_t GetHeaderSize() { return sizeof(LengthHeader); }
  61. // Returns the total available free space in the buffer. This may be
  62. // larger than the usable space, due to overheads.
  63. size_t GetFreeSize() const { return capacity_ - write_pos_; }
  64. // Resets the read pointer to the start of the buffer. An immediately
  65. // following read will return the first message in the buffer. An immediately
  66. // following write, however, will be placed at the same position as if
  67. // Rewind() had not been called.
  68. void Rewind();
  69. private:
  70. struct LengthHeader {
  71. uint16_t payload_len;
  72. };
  73. // Prepares a header, and writes that header into the buffer.
  74. void AppendHeader(uint16_t message_len);
  75. // Writes arbitrary data into the buffer.
  76. void AppendRawBytes(NONNULL const void* data_start, size_t data_len);
  77. // Returns the total number of bytes available for reading. This number
  78. // includes headers.
  79. size_t GetReadableSize() const { return write_pos_ - read_pos_; }
  80. const std::unique_ptr<uint8_t[]> data_;
  81. const size_t capacity_;
  82. size_t read_pos_;
  83. size_t write_pos_;
  84. // MessageBuffer is a value type, so it would be semantically reasonable to
  85. // support copy and assign. Performance-wise, though, we should avoid
  86. // copies. Remove the copy constructor and the assignment operator, to
  87. // ensure that we don't accidentally make copies.
  88. DISALLOW_COPY_AND_ASSIGN(MessageBuffer);
  89. };
  90. } // namespace wifilogd
  91. } // namespace android
  92. #endif // MESSAGE_BUFFER_H_