-
-
Notifications
You must be signed in to change notification settings - Fork 168
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
split out zlib stuff to its own file
- Loading branch information
1 parent
3119752
commit 31594f1
Showing
4 changed files
with
173 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/************************************************************************************ | ||
* | ||
* D++, A Lightweight C++ library for Discord | ||
* | ||
* Copyright 2021 Craig Edwards and D++ contributors | ||
* (https://github.com/brainboxdotcc/DPP/graphs/contributors) | ||
* | ||
* 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. | ||
* | ||
************************************************************************************/ | ||
#pragma once | ||
#include <dpp/export.h> | ||
#include <dpp/exception.h> | ||
#include <cstdint> | ||
#include <vector> | ||
#include <memory> | ||
|
||
/** | ||
* @brief Forward declaration for zlib stream type | ||
*/ | ||
typedef struct z_stream_s z_stream; | ||
|
||
namespace dpp { | ||
|
||
/** | ||
* @brief Size of decompression buffer for zlib compressed traffic | ||
*/ | ||
constexpr size_t DECOMP_BUFFER_SIZE = 512 * 1024; | ||
|
||
/** | ||
* @brief This is an opaque class containing zlib library specific structures. | ||
* This wraps the C pointers needed for zlib with unique_ptr and gives us a nice | ||
* buffer abstraction so we don't need to wrestle with raw pointers. | ||
*/ | ||
class zlibcontext { | ||
public: | ||
/** | ||
* @brief Zlib stream struct. The actual type is defined in zlib.h | ||
* so is only defined in the implementation file. | ||
*/ | ||
std::unique_ptr<z_stream> d_stream{}; | ||
|
||
/** | ||
* @brief ZLib decompression buffer. | ||
* This is automatically set to DECOMP_BUFFER_SIZE bytes when | ||
* the class is constructed. | ||
*/ | ||
std::vector<unsigned char> decomp_buffer{}; | ||
|
||
/** | ||
* @brief Total decompressed received bytes counter | ||
*/ | ||
uint64_t decompressed_total{}; | ||
|
||
/** | ||
* @brief Initialise zlib struct via inflateInit() | ||
* and size the buffer | ||
*/ | ||
zlibcontext(); | ||
|
||
/** | ||
* @brief Destroy zlib struct via inflateEnd() | ||
*/ | ||
~zlibcontext(); | ||
|
||
/** | ||
* @brief Decompress zlib deflated buffer | ||
* @param buffer input compressed stream | ||
* @param decompressed output decompressed content | ||
* @return an error code on error, or err_no_code_specified (0) on success | ||
*/ | ||
exception_error_code decompress(const std::string& buffer, std::string& decompressed); | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/************************************************************************************ | ||
* | ||
* D++, A Lightweight C++ library for Discord | ||
* | ||
* Copyright 2021 Craig Edwards and D++ contributors | ||
* (https://github.com/brainboxdotcc/DPP/graphs/contributors) | ||
* | ||
* 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. | ||
* | ||
************************************************************************************/ | ||
#include <zlib.h> | ||
#include <memory> | ||
#include <cstring> | ||
#include <dpp/zlibcontext.h> | ||
|
||
namespace dpp { | ||
|
||
zlibcontext::zlibcontext() { | ||
d_stream = std::make_unique<z_stream>(); | ||
std::memset(d_stream.get(), 0, sizeof(z_stream)); | ||
int error = inflateInit(d_stream.get()); | ||
if (error != Z_OK) { | ||
throw dpp::connection_exception((exception_error_code)error, "Can't initialise stream compression!"); | ||
} | ||
decomp_buffer.resize(DECOMP_BUFFER_SIZE); | ||
} | ||
|
||
zlibcontext::~zlibcontext() { | ||
inflateEnd(d_stream.get()); | ||
} | ||
|
||
exception_error_code zlibcontext::decompress(const std::string& buffer, std::string& decompressed) { | ||
decompressed.clear(); | ||
/* This is safe; zlib requires us to cast away the const. The underlying buffer is unchanged. */ | ||
d_stream->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(buffer.data())); | ||
d_stream->avail_in = static_cast<uInt>(buffer.size()); | ||
do { | ||
d_stream->next_out = static_cast<Bytef*>(decomp_buffer.data()); | ||
d_stream->avail_out = DECOMP_BUFFER_SIZE; | ||
int ret = inflate(d_stream.get(), Z_NO_FLUSH); | ||
size_t have = DECOMP_BUFFER_SIZE - d_stream->avail_out; | ||
switch (ret) | ||
{ | ||
case Z_NEED_DICT: | ||
case Z_STREAM_ERROR: | ||
return err_compression_stream; | ||
case Z_DATA_ERROR: | ||
return err_compression_data; | ||
case Z_MEM_ERROR: | ||
return err_compression_memory; | ||
case Z_OK: | ||
decompressed.append(decomp_buffer.begin(), decomp_buffer.begin() + have); | ||
decompressed_total += have; | ||
break; | ||
default: | ||
/* Stub */ | ||
break; | ||
} | ||
} while (d_stream->avail_out == 0); | ||
return err_no_code_specified; | ||
} | ||
|
||
}; |