Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(473)

Side by Side Diff: net/filter/brotli_stream_source.cc

Issue 1662763002: [ON HOLD] Implement pull-based design for content decoding (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Refactor common logic Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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
5 #include "net/filter/brotli_stream_source.h"
6
7 #include "base/bind.h"
8 #include "base/bit_cast.h"
9 #include "base/metrics/histogram_macros.h"
10 #include "net/filter/block_buffer.h"
11
12 namespace net {
13
14 BrotliStreamSource::BrotliStreamSource(scoped_ptr<StreamSource> previous)
15 : StreamSource(StreamSource::SOURCE_BROTLI, std::move(previous)),
16 decoding_status_(DecodingStatus::DECODING_IN_PROGRESS),
17 used_memory_(0),
18 used_memory_maximum_(0),
19 produced_bytes_(0),
20 consumed_bytes_(0) {
21 brotli_state_ = BrotliCreateState(AllocateMemory, FreeMemory, this);
22 CHECK(brotli_state_);
23 }
24
25 BrotliStreamSource::~BrotliStreamSource() {
26 BrotliDestroyState(brotli_state_);
27 brotli_state_ = nullptr;
28 DCHECK(used_memory_ == 0);
29
30 UMA_HISTOGRAM_ENUMERATION(
31 "BrotliStreamSource.Status", static_cast<int>(decoding_status_),
32 static_cast<int>(DecodingStatus::DECODING_STATUS_COUNT));
33 if (decoding_status_ == DecodingStatus::DECODING_DONE) {
34 // CompressionPercent is undefined when there is no output produced.
35 if (produced_bytes_ != 0) {
36 UMA_HISTOGRAM_PERCENTAGE(
37 "BrotliStreamSource.CompressionPercent",
38 static_cast<int>((consumed_bytes_ * 100) / produced_bytes_));
39 }
40 }
41 // All code here is for gathering stats, and can be removed when
42 // BrotliStreamSource is considered stable.
43 static const int kBuckets = 48;
44 static const int64_t kMaxKb = 1 << (kBuckets / 3); // 64MiB in KiB
45 UMA_HISTOGRAM_CUSTOM_COUNTS("BrotliStreamSource.UsedMemoryKB",
46 used_memory_maximum_ / 1024, 1, kMaxKb, kBuckets);
47 }
48
49 Error BrotliStreamSource::ReadInternal(IOBuffer* dest_buffer,
50 size_t dest_buffer_size,
51 size_t* bytes_read) {
52 const uint8_t* next_in = bit_cast<uint8_t*>(buffer_->bytes());
53 size_t available_in = buffer_->bytes_left();
54 uint8_t* next_out = bit_cast<uint8_t*>(dest_buffer->data());
55 size_t available_out = dest_buffer_size;
56 size_t total_out = 0;
57 BrotliResult result =
58 BrotliDecompressStream(&available_in, &next_in, &available_out, &next_out,
59 &total_out, brotli_state_);
60
61 size_t bytes_used = buffer_->bytes_left() - available_in;
62 size_t bytes_written = dest_buffer_size - available_out;
63 CHECK_GE(bytes_used, 0u);
64 CHECK_GE(bytes_written, 0u);
65 *bytes_read = bytes_written;
66 produced_bytes_ += bytes_written;
67 consumed_bytes_ += bytes_used;
68
69 buffer_->WasDrained(bytes_used);
70
71 switch (result) {
72 case BROTLI_RESULT_NEEDS_MORE_OUTPUT:
73 // Fall through.
74 case BROTLI_RESULT_SUCCESS:
75 decoding_status_ = DecodingStatus::DECODING_DONE;
76 return OK;
77 case BROTLI_RESULT_NEEDS_MORE_INPUT:
78 decoding_status_ = DecodingStatus::DECODING_IN_PROGRESS;
79 if (bytes_written > 0) {
80 return OK;
81 }
82 break;
83 // If the decompressor threw an error, fail synchronously.
84 default:
85 decoding_status_ = DecodingStatus::DECODING_ERROR;
86 return ERR_CONTENT_DECODING_FAILED;
87 }
88
89 DCHECK_EQ(BROTLI_RESULT_NEEDS_MORE_INPUT, result);
90
91 // Since Decompress needs more input, it has consumed all existing input.
92 DCHECK(!buffer_->HasMoreBytes());
93
94 return OK;
95 }
96
97 void* BrotliStreamSource::AllocateMemory(void* opaque, size_t size) {
98 BrotliStreamSource* filter = reinterpret_cast<BrotliStreamSource*>(opaque);
99 return filter->AllocateMemoryInternal(size);
100 }
101
102 void BrotliStreamSource::FreeMemory(void* opaque, void* address) {
103 BrotliStreamSource* filter = reinterpret_cast<BrotliStreamSource*>(opaque);
104 filter->FreeMemoryInternal(address);
105 }
106
107 void* BrotliStreamSource::AllocateMemoryInternal(size_t size) {
108 size_t* array = reinterpret_cast<size_t*>(malloc(size + sizeof(size_t)));
109 if (!array)
110 return nullptr;
111 used_memory_ += size;
112 if (used_memory_maximum_ < used_memory_)
113 used_memory_maximum_ = used_memory_;
114 array[0] = size;
115 return &array[1];
116 }
117
118 void BrotliStreamSource::FreeMemoryInternal(void* address) {
119 if (!address)
120 return;
121 size_t* array = reinterpret_cast<size_t*>(address);
122 used_memory_ -= array[-1];
123 free(&array[-1]);
124 }
125
126 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698