123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- /*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #ifndef MESSAGE_BUFFER_H_
- #define MESSAGE_BUFFER_H_
- #include <cstdint>
- #include <memory>
- #include <tuple>
- #include "android-base/macros.h"
- #include "wifilogd/local_utils.h"
- namespace android {
- namespace wifilogd {
- // A fixed-size buffer, which provides FIFO access to read and write
- // a sequence of messages.
- class MessageBuffer {
- public:
- // A wrapper which guarantees that a MessageBuffer will be rewound,
- // when the program exits the wrapper's scope. The user must ensure that
- // |buffer| does not expire before the ScopedRewinder.
- class ScopedRewinder {
- public:
- explicit ScopedRewinder(NONNULL MessageBuffer* buffer) : buffer_(buffer) {}
- ~ScopedRewinder() { buffer_->Rewind(); }
- private:
- MessageBuffer* const buffer_;
- };
- // Constructs the buffer. |size| must be greater than GetHeaderSize().
- explicit MessageBuffer(size_t size);
- // Appends a single message to the buffer. |data_len| must be >=1. Returns
- // true if the message was added to the buffer.
- bool Append(NONNULL const uint8_t* data, uint16_t data_len);
- // Returns true if the buffer is large enough to hold |length| bytes of user
- // data, when the buffer is empty.
- bool CanFitEver(uint16_t length) const;
- // Returns true if the buffer currently has enough free space to hold |length|
- // bytes of user data.
- bool CanFitNow(uint16_t length) const;
- // Clears the buffer. An immediately following read operation will return an
- // empty message. An immediately following write operation will write to the
- // head of the buffer. Clearing may be lazy (i.e., underlying storage is not
- // necessarily zeroed).
- void Clear();
- // Returns the first unread message in the buffer. If there is no such
- // message, returns {nullptr, 0}. MessageBuffer retains ownership of the
- // message's storage.
- std::tuple<const uint8_t*, size_t> ConsumeNextMessage();
- // Returns the size of MessageBuffer's per-message header.
- static constexpr size_t GetHeaderSize() { return sizeof(LengthHeader); }
- // Returns the total available free space in the buffer. This may be
- // larger than the usable space, due to overheads.
- size_t GetFreeSize() const { return capacity_ - write_pos_; }
- // Resets the read pointer to the start of the buffer. An immediately
- // following read will return the first message in the buffer. An immediately
- // following write, however, will be placed at the same position as if
- // Rewind() had not been called.
- void Rewind();
- private:
- struct LengthHeader {
- uint16_t payload_len;
- };
- // Prepares a header, and writes that header into the buffer.
- void AppendHeader(uint16_t message_len);
- // Writes arbitrary data into the buffer.
- void AppendRawBytes(NONNULL const void* data_start, size_t data_len);
- // Returns the total number of bytes available for reading. This number
- // includes headers.
- size_t GetReadableSize() const { return write_pos_ - read_pos_; }
- const std::unique_ptr<uint8_t[]> data_;
- const size_t capacity_;
- size_t read_pos_;
- size_t write_pos_;
- // MessageBuffer is a value type, so it would be semantically reasonable to
- // support copy and assign. Performance-wise, though, we should avoid
- // copies. Remove the copy constructor and the assignment operator, to
- // ensure that we don't accidentally make copies.
- DISALLOW_COPY_AND_ASSIGN(MessageBuffer);
- };
- } // namespace wifilogd
- } // namespace android
- #endif // MESSAGE_BUFFER_H_
|