forked from tplgy/cppcodec
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request tplgy#51 from jpetso/master
Finishing touches for v0.2
- Loading branch information
Showing
9 changed files
with
223 additions
and
49 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
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
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,6 @@ | ||
# For cppcodec itself, don't prefer system headers over development ones. | ||
include_directories(BEFORE ${PROJECT_SOURCE_DIR}) | ||
|
||
add_executable(helloworld helloworld.cpp) | ||
|
||
add_executable(type_support_wrapper type_support_wrapper.cpp) |
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,149 @@ | ||
/** | ||
* This is free and unencumbered software released into the public domain. | ||
* Anyone is free to copy, modify, publish, use, compile, sell, or | ||
* distribute this software, either in source code form or as a compiled | ||
* binary, for any purpose, commercial or non-commercial, and by any | ||
* means. | ||
* | ||
* In jurisdictions that recognize copyright laws, the author or authors | ||
* of this software dedicate any and all copyright interest in the | ||
* software to the public domain. We make this dedication for the benefit | ||
* of the public at large and to the detriment of our heirs and | ||
* successors. We intend this dedication to be an overt act of | ||
* relinquishment in perpetuity of all present and future rights to this | ||
* software under copyright law. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
* OTHER DEALINGS IN THE SOFTWARE. | ||
* | ||
* For more information, please refer to <http://unlicense.org/> | ||
*/ | ||
|
||
#include <cppcodec/base64_rfc4648.hpp> | ||
#include <iostream> | ||
|
||
|
||
// This example shows how to wrap a type (here: std::string) in another | ||
// result type in order to modify the standard behavior for that type. | ||
// Use this when you're in a position to wrap the result variable. | ||
// | ||
// This is the more straightforward of two ways for modifying cppcodec's | ||
// behavior for a given type, the other one being able to modify the | ||
// default behavior but also being more complex/intricate. | ||
// | ||
// The overall approach is straightforward: Define a result type with | ||
// push_back(char) and size() methods, implement template specializations | ||
// for init() and finish() for the result type, and call encode()/decode() | ||
// with an object of this type as result parameter. | ||
|
||
class string_append_wrapper | ||
{ | ||
public: | ||
string_append_wrapper(std::string& backing) | ||
: m_backing(backing) | ||
, m_offset(0) | ||
, m_orig_size(0) | ||
{ | ||
} | ||
|
||
void init(size_t capacity) | ||
{ | ||
m_orig_size = m_backing.size(); | ||
m_offset = m_orig_size; | ||
m_backing.resize(m_orig_size + capacity); | ||
} | ||
void finish() | ||
{ | ||
m_backing.resize(m_offset); | ||
} | ||
|
||
// Methods required for satisfying default result type requirements: | ||
CPPCODEC_ALWAYS_INLINE void push_back(char c) { m_backing[m_offset++] = c; } | ||
CPPCODEC_ALWAYS_INLINE size_t size() const { return m_offset - m_orig_size; } | ||
|
||
// Note that the above implementation of push_back() is not the fastest, | ||
// because operator[] for std::string (for C++11 and above) still includes | ||
// a check for whether the size of the string fits into its allocation-less | ||
// character array union. | ||
// | ||
// With C++17 and above, it's legitimate to get the character array as a | ||
// mutable (non-const) char pointer, so this check can be skipped. | ||
// This is implemented via template specialization in cppcodec's | ||
// default behavior for std::string, but omitted here for simplicity. | ||
// If you need that last bit of extra performance, see | ||
// direct_data_access_result_state in cppcodec/data/access.hpp | ||
// for an example of optimal C++17 string access. | ||
|
||
private: | ||
std::string& m_backing; | ||
size_t m_offset; | ||
size_t m_orig_size; | ||
}; | ||
|
||
|
||
// init() and finish() must be declared in the cppcodec::data namespace. | ||
namespace cppcodec { | ||
namespace data { | ||
|
||
template <> inline void init<string_append_wrapper>( | ||
string_append_wrapper& result, empty_result_state&, size_t capacity) | ||
{ | ||
// init() is called to prepare the output buffer. cppcodec will call it | ||
// with the maximum output size, null termination not included. | ||
// | ||
// Any thrown exception will not be caught by cppcodec itself, | ||
// the caller of the encode/decode function is responsible for handling it. | ||
// | ||
// empty_result_state can be ignored in this case because the wrapper type | ||
// can carry all required state internally. | ||
// | ||
// In order to maximize performance, init() should generally try to | ||
// allocate or guarantee the entire output buffer at once, so that | ||
// subsequent calls to push_back() don't result in extra checks (slower) | ||
// or even re-allocations. | ||
|
||
result.init(capacity); | ||
} | ||
|
||
// Between init() and finish(), cppcodec will call result.push_back(char) | ||
// repeatedly, once for each output character with no rewinding. | ||
// While init() can ask for greater capacity than the final output length, | ||
// cppcodec guarantees that push_back() will never be called too often. | ||
// | ||
// (If you know exactly how long your output is, you could theoretically | ||
// overcommit on capacity while allocating only the exact expected length | ||
// of the output buffer. This is of course dangerous, because you can | ||
// hardly ever know for sure and everyone's often wrong, so don't try it | ||
// unless you have a business-critical reason to reduce/avoid the allocation.) | ||
|
||
template <> inline void finish<string_append_wrapper>( | ||
string_append_wrapper& result, empty_result_state&) | ||
{ | ||
// finish() is called after encoding/decoding is done. | ||
// Its main purpose is to reduce the size of the result type | ||
// from capacity to the actual (often slightly smaller) output length. | ||
// | ||
// After finish(), cppcodec will assert that result.size() does indeed | ||
// equal the number of times that push_back() has been called. | ||
|
||
result.finish(); | ||
} | ||
|
||
} // namespace data | ||
} // namespace cppcodec | ||
|
||
|
||
int main() { | ||
using base64 = cppcodec::base64_rfc4648; | ||
|
||
std::string result = "Result: "; | ||
string_append_wrapper appender(result); | ||
base64::encode(appender, std::string("any carnal pleasure")); | ||
std::cout << result << std::endl; // "Result: YW55IGNhcm5hbCBwbGVhc3VyZQ==" | ||
return 0; | ||
} |
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