#include "base64.hh"
#include <limits>
+#include <memory>
#include <stdexcept>
+
#include <boost/scoped_array.hpp>
#include <openssl/bio.h>
#include <openssl/evp.h>
}
const size_t dlen = (src.length() * 6 + 7) / 8;
dst.resize(dlen);
- BIO* bio = BIO_new(BIO_s_mem());
- if (bio == nullptr) {
+ auto bio = std::unique_ptr<BIO, void (*)(BIO*)>(BIO_new(BIO_s_mem()), BIO_free_all);
+ if (!bio) {
throw std::runtime_error("BIO_new failed");
}
- if (BIO_write(bio, src.c_str(), src.length()) != static_cast<int>(src.length())) {
- BIO_free_all(bio);
+ if (BIO_write(bio.get(), src.c_str(), src.length()) != static_cast<int>(src.length())) {
throw std::runtime_error("BIO_write failed");
}
- BIO* b64 = BIO_new(BIO_f_base64());
+ auto* b64 = BIO_new(BIO_f_base64());
if (b64 == nullptr) {
- BIO_free_all(bio);
throw std::runtime_error("BIO_new failed");
}
- bio = BIO_push(b64, bio);
- BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
+ bio = std::unique_ptr<BIO, void (*)(BIO*)>(BIO_push(b64, bio.release()), BIO_free_all);
+ BIO_set_flags(bio.get(), BIO_FLAGS_BASE64_NO_NL);
auto olen = BIO_read(b64, &dst.at(0), dlen);
- if ((olen == 0 || olen == -1) && BIO_should_retry(bio)) {
- BIO_free_all(bio);
+ if ((olen == 0 || olen == -1) && BIO_should_retry(bio.get())) {
throw std::runtime_error("BIO_read failed to read all data from memory buffer");
}
- BIO_free_all(bio);
+ bio.reset();
if (olen > 0) {
dst.resize(olen);
return 0;
std::string Base64Encode(const std::string& src)
{
if (!src.empty()) {
- BIO* b64 = BIO_new(BIO_f_base64());
- if (b64 == nullptr) {
+ auto bio = std::unique_ptr<BIO, void (*)(BIO*)>(BIO_new(BIO_s_mem()), BIO_free_all);
+ if (!bio) {
throw std::runtime_error("BIO_new failed");
}
- BIO* bio = BIO_new(BIO_s_mem());
- if (bio == nullptr) {
- BIO_free_all(b64);
+ auto* b64 = BIO_new(BIO_f_base64());
+ if (b64 == nullptr) {
throw std::runtime_error("BIO_new failed");
}
- bio = BIO_push(b64, bio);
- BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
- int bioWriteRet = BIO_write(bio, src.c_str(), src.length());
+ bio = std::unique_ptr<BIO, void (*)(BIO*)>(BIO_push(b64, bio.release()), BIO_free_all);
+ BIO_set_flags(bio.get(), BIO_FLAGS_BASE64_NO_NL);
+ int bioWriteRet = BIO_write(bio.get(), src.c_str(), src.length());
if (bioWriteRet < 0 || static_cast<size_t>(bioWriteRet) != src.length()) {
- BIO_free_all(bio);
throw std::runtime_error("BIO_write failed to write all data to memory buffer");
}
- (void)BIO_flush(bio);
+ (void)BIO_flush(bio.get());
char* pp;
std::string out;
- auto olen = BIO_get_mem_data(bio, &pp);
+ auto olen = BIO_get_mem_data(bio.get(), &pp);
if (olen > 0) {
out = std::string(pp, olen);
}
- BIO_free_all(bio);
+ bio.reset();
return out;
}
return "";