Test for golden version-7 safe-browsing file.
[chromium-blink-merge.git] / chrome / common / partial_circular_buffer.cc
blob4161cc1864706b2ddbce9037d26c72ecf0203e48
1 // Copyright 2013 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.
5 #include "chrome/common/partial_circular_buffer.h"
7 #include <algorithm>
9 #include "base/logging.h"
11 namespace {
13 inline uint32 Min3(uint32 a, uint32 b, uint32 c) {
14 return std::min(a, std::min(b, c));
17 } // namespace
19 PartialCircularBuffer::PartialCircularBuffer(void* buffer,
20 uint32 buffer_size)
21 : buffer_data_(reinterpret_cast<BufferData*>(buffer)),
22 memory_buffer_size_(buffer_size),
23 data_size_(0),
24 position_(0),
25 total_read_(0) {
26 uint32 header_size =
27 buffer_data_->data - reinterpret_cast<uint8*>(buffer_data_);
28 data_size_ = memory_buffer_size_ - header_size;
30 DCHECK(buffer_data_);
31 DCHECK_GE(memory_buffer_size_, header_size);
32 DCHECK_LE(buffer_data_->total_written, data_size_);
33 DCHECK_LT(buffer_data_->wrap_position, data_size_);
34 DCHECK_LT(buffer_data_->end_position, data_size_);
37 PartialCircularBuffer::PartialCircularBuffer(void* buffer,
38 uint32 buffer_size,
39 uint32 wrap_position,
40 bool append)
41 : buffer_data_(reinterpret_cast<BufferData*>(buffer)),
42 memory_buffer_size_(buffer_size),
43 data_size_(0),
44 position_(0),
45 total_read_(0) {
46 uint32 header_size =
47 buffer_data_->data - reinterpret_cast<uint8*>(buffer_data_);
48 data_size_ = memory_buffer_size_ - header_size;
50 DCHECK(buffer_data_);
51 DCHECK_GE(memory_buffer_size_, header_size);
53 if (append) {
54 DCHECK_LT(buffer_data_->wrap_position, data_size_);
55 position_ = buffer_data_->end_position;
56 } else {
57 DCHECK_LT(wrap_position, data_size_);
58 buffer_data_->total_written = 0;
59 buffer_data_->wrap_position = wrap_position;
60 buffer_data_->end_position = 0;
64 uint32 PartialCircularBuffer::Read(void* buffer, uint32 buffer_size) {
65 DCHECK(buffer_data_);
66 if (total_read_ >= buffer_data_->total_written)
67 return 0;
69 uint8* buffer_uint8 = reinterpret_cast<uint8*>(buffer);
70 uint32 read = 0;
72 // Read from beginning part.
73 if (position_ < buffer_data_->wrap_position) {
74 uint32 to_wrap_pos = buffer_data_->wrap_position - position_;
75 uint32 to_eow = buffer_data_->total_written - total_read_;
76 uint32 to_read = Min3(buffer_size, to_wrap_pos, to_eow);
77 memcpy(buffer_uint8, buffer_data_->data + position_, to_read);
78 position_ += to_read;
79 total_read_ += to_read;
80 read += to_read;
81 if (position_ == buffer_data_->wrap_position &&
82 buffer_data_->total_written == data_size_) {
83 // We've read all the beginning part, set the position to the middle part.
84 // (The second condition above checks if the wrapping part is filled, i.e.
85 // writing has wrapped.)
86 position_ = buffer_data_->end_position;
88 if (read >= buffer_size) {
89 DCHECK_EQ(read, buffer_size);
90 return read;
92 if (read >= to_eow) {
93 DCHECK_EQ(read, to_eow);
94 DCHECK_EQ(total_read_, buffer_data_->total_written);
95 return read;
99 // Read from middle part.
100 DCHECK_GE(position_, buffer_data_->wrap_position);
101 if (position_ >= buffer_data_->end_position) {
102 uint32 remaining_buffer_size = buffer_size - read;
103 uint32 to_eof = data_size_ - position_;
104 uint32 to_eow = buffer_data_->total_written - total_read_;
105 uint32 to_read = Min3(remaining_buffer_size, to_eof, to_eow);
106 memcpy(buffer_uint8 + read, buffer_data_->data + position_, to_read);
107 position_ += to_read;
108 total_read_ += to_read;
109 read += to_read;
110 if (position_ == data_size_) {
111 // We've read all the middle part, set position to the end part.
112 position_ = buffer_data_->wrap_position;
114 if (read >= buffer_size) {
115 DCHECK_EQ(read, buffer_size);
116 return read;
118 if (total_read_ >= buffer_data_->total_written) {
119 DCHECK_EQ(total_read_, buffer_data_->total_written);
120 return read;
124 // Read from end part.
125 DCHECK_GE(position_, buffer_data_->wrap_position);
126 DCHECK_LT(position_, buffer_data_->end_position);
127 uint32 remaining_buffer_size = buffer_size - read;
128 uint32 to_eob = buffer_data_->end_position - position_;
129 uint32 to_eow = buffer_data_->total_written - total_read_;
130 uint32 to_read = Min3(remaining_buffer_size, to_eob, to_eow);
131 memcpy(buffer_uint8 + read, buffer_data_->data + position_, to_read);
132 position_ += to_read;
133 total_read_ += to_read;
134 read += to_read;
135 DCHECK_LE(read, buffer_size);
136 DCHECK_LE(total_read_, buffer_data_->total_written);
137 return read;
140 void PartialCircularBuffer::Write(const void* buffer, uint32 buffer_size) {
141 DCHECK(buffer_data_);
142 uint32 position_before_write = position_;
144 uint32 to_eof = data_size_ - position_;
145 uint32 to_write = std::min(buffer_size, to_eof);
146 DoWrite(buffer_data_->data + position_, buffer, to_write);
147 if (position_ >= data_size_) {
148 DCHECK_EQ(position_, data_size_);
149 position_ = buffer_data_->wrap_position;
152 if (to_write < buffer_size) {
153 uint32 remainder_to_write = buffer_size - to_write;
154 DCHECK_LT(position_, position_before_write);
155 DCHECK_LE(position_ + remainder_to_write, position_before_write);
156 DoWrite(buffer_data_->data + position_,
157 reinterpret_cast<const uint8*>(buffer) + to_write,
158 remainder_to_write);
162 void PartialCircularBuffer::DoWrite(void* dest, const void* src, uint32 num) {
163 memcpy(dest, src, num);
164 position_ += num;
165 buffer_data_->total_written =
166 std::min(buffer_data_->total_written + num, data_size_);
167 buffer_data_->end_position = position_;