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

Side by Side Diff: blimp/net/compressed_packet_writer.cc

Issue 1825263003: Blimp: add packet-level DEFLATE compression using zlib. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: wez feedback Created 4 years, 8 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
« no previous file with comments | « blimp/net/compressed_packet_writer.h ('k') | blimp/net/stream_packet_reader.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "blimp/net/compressed_packet_writer.h"
6
7 #include <vector>
8
9 #include "base/logging.h"
10 #include "base/numerics/safe_conversions.h"
11 #include "base/sys_byteorder.h"
12 #include "blimp/net/common.h"
13 #include "net/base/io_buffer.h"
14 #include "third_party/zlib/zlib.h"
15
16 namespace blimp {
17 namespace {
18
19 // Allocate the maxmimum amount of memory to deflate (512KB) for higher
20 // compression. (See zconf.h for details on memLevel semantics.)
21 const int kZlibMemoryLevel = 9;
22
23 } // namespace
24
25 CompressedPacketWriter::CompressedPacketWriter(scoped_ptr<PacketWriter> sink)
26 : sink_(std::move(sink)), compressed_buf_(new net::GrowableIOBuffer) {
27 DCHECK(sink_);
28
29 memset(&zlib_stream_, 0, sizeof(z_stream));
30
31 // MAX_WBITS means we are using the maximal window size for decompression;
32 // negating it means that we are ignoring headers and CRC checks.
33 int init_error =
34 deflateInit2(&zlib_stream_, Z_BEST_COMPRESSION, Z_DEFLATED,
35 -MAX_WBITS, // Negative value = no headers or CRC.
36 kZlibMemoryLevel, Z_DEFAULT_STRATEGY);
37 CHECK_EQ(Z_OK, init_error);
38 }
39
40 CompressedPacketWriter::~CompressedPacketWriter() {
41 deflateEnd(&zlib_stream_);
42 }
43
44 void CompressedPacketWriter::WritePacket(
45 const scoped_refptr<net::DrainableIOBuffer>& write_buffer,
46 const net::CompletionCallback& callback) {
47 DCHECK(write_buffer);
48 DCHECK(!callback.is_null());
49 size_t uncompressed_size =
50 base::checked_cast<size_t>(write_buffer->BytesRemaining());
51
52 // Zero-length input => zero-length output.
53 if (uncompressed_size == 0) {
54 sink_->WritePacket(write_buffer, callback);
55 return;
56 }
57
58 // Don't compress anything that's bigger than the maximum allowable payload
59 // size.
60 if (uncompressed_size > kMaxPacketPayloadSizeBytes) {
61 callback.Run(net::ERR_FILE_TOO_BIG);
62 return;
63 }
64
65 int compress_result = Compress(write_buffer, compressed_buf_);
66 if (compress_result < 0) {
67 callback.Run(compress_result);
68 return;
69 }
70
71 #if !defined(NDEBUG)
72 uncompressed_size_total_ += uncompressed_size;
73 compressed_size_total_ += compress_result;
74 #endif // !defined(NDEBUG)
75
76 scoped_refptr<net::DrainableIOBuffer> compressed_outbuf(
77 new net::DrainableIOBuffer(compressed_buf_.get(), compress_result));
78 sink_->WritePacket(compressed_outbuf, callback);
79 DVLOG(4) << "deflate packet: " << uncompressed_size << " in, "
80 << compress_result << " out.";
81 DVLOG(3) << "deflate total: " << uncompressed_size_total_ << " in, "
82 << compressed_size_total_ << " out.";
83 }
84
85 int CompressedPacketWriter::Compress(
86 const scoped_refptr<net::DrainableIOBuffer>& src_buf,
87 const scoped_refptr<net::GrowableIOBuffer>& dest_buf) {
88 DCHECK_EQ(0, dest_buf->offset());
89
90 const int zlib_output_ubound =
91 deflateBound(&zlib_stream_, src_buf->BytesRemaining());
92 if (dest_buf->capacity() < zlib_output_ubound) {
93 dest_buf->SetCapacity(zlib_output_ubound);
94 }
95
96 zlib_stream_.next_in = reinterpret_cast<uint8_t*>(src_buf->data());
97 zlib_stream_.avail_in = static_cast<unsigned>(src_buf->BytesRemaining());
98 zlib_stream_.next_out = reinterpret_cast<uint8_t*>(dest_buf->data());
99 zlib_stream_.avail_out = static_cast<unsigned>(zlib_output_ubound);
100 int deflate_error = deflate(&zlib_stream_, Z_SYNC_FLUSH);
101
102 if (deflate_error != Z_OK) {
103 DLOG(FATAL) << "Unexpected deflate() return value: " << deflate_error;
104 return net::ERR_UNEXPECTED;
105 }
106 if (zlib_stream_.avail_in > 0) {
107 DLOG(ERROR) << "deflate() did not consume all data, remainder: "
108 << zlib_stream_.avail_in << " bytes.";
109 return net::ERR_UNEXPECTED;
110 }
111
112 return zlib_output_ubound - zlib_stream_.avail_out;
113 }
114
115 } // namespace blimp
OLDNEW
« no previous file with comments | « blimp/net/compressed_packet_writer.h ('k') | blimp/net/stream_packet_reader.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698