Skip to content

Commit

Permalink
Add interface for C++17 string_view (2.rc.02)
Browse files Browse the repository at this point in the history
  • Loading branch information
ReneNyffenegger committed May 13, 2020
1 parent e1b8707 commit 2ca8b88
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 8 deletions.
48 changes: 48 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
WARNINGS= \
-Werror \
-Wall \
-Wextra \
-pedantic \
-Wcast-align \
-Wcast-qual \
-Wctor-dtor-privacy \
-Wdisabled-optimization \
-Wformat=2 \
-Winit-self \
-Wlogical-op \
-Wmissing-include-dirs \
-Wnoexcept \
-Wold-style-cast \
-Woverloaded-virtual \
-Wredundant-decls \
-Wshadow \
-Wsign-promo \
-Wstrict-null-sentinel \
-Wstrict-overflow=5 \
-Wundef \
-Wno-unused \
-Wno-variadic-macros \
-Wno-parentheses \
-fdiagnostics-show-option

test: base64-test-11 base64-test-17
base64-test-11
base64-test-17

base64-test-11: base64-11.o test-11.o
g++ base64-11.o test-11.o -o $@

base64-test-17: base64-17.o test-17.o
g++ base64-17.o test-17.o -o $@

base64-11.o: base64.cpp base64.h
g++ -std=c++11 $(WARNINGS) -c base64.cpp -o base64-11.o

base64-17.o: base64.cpp base64.h
g++ -std=c++17 $(WARNINGS) -c base64.cpp -o base64-17.o

test-11.o: test.cpp
g++ -std=c++11 $(WARNINGS) -c test.cpp -o test-11.o

test-17.o: test.cpp
g++ -std=c++17 $(WARNINGS) -c test.cpp -o test-17.o
65 changes: 59 additions & 6 deletions base64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
More information at
https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp
Version: 2.rc.01 (release candidate)
Version: 2.rc.02 (release candidate)
Copyright (C) 2004-2017, 2020 René Nyffenegger
Expand Down Expand Up @@ -72,6 +72,26 @@ static std::string insert_linebreaks(std::string str, size_t distance) {
return str;
}

template <typename String, unsigned int line_length>
static std::string encode_with_line_breaks(String s) {
return insert_linebreaks(base64_encode(s, false), line_length);
}

template <typename String>
static std::string encode_pem(String s) {
return encode_with_line_breaks<String, 64>(s);
}

template <typename String>
static std::string encode_mime(String s) {
return encode_with_line_breaks<String, 76>(s);
}

template <typename String>
static std::string encode(String s, bool url) {
return base64_encode(reinterpret_cast<const unsigned char*>(s.data()), s.length(), url);
}

std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len, bool url) {
//
// Replace question marks in base64_chars:
Expand Down Expand Up @@ -123,8 +143,12 @@ std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_
return ret;
}


std::string base64_decode(std::string const& encoded_string, bool remove_linebreaks) {
template <typename String>
static std::string decode(String encoded_string, bool remove_linebreaks) {
//
// decode(…) is templated so that it can be used with String = const std::string&
// or std::string_view (requires at least C++17)
//

if (remove_linebreaks) {

Expand Down Expand Up @@ -181,14 +205,43 @@ std::string base64_decode(std::string const& encoded_string, bool remove_linebre
return ret;
}

std::string base64_decode(std::string const& s, bool remove_linebreaks) {
return decode(s, remove_linebreaks);
}

std::string base64_encode(std::string const& s, bool url) {
return base64_encode(reinterpret_cast<const unsigned char*>(s.c_str()), s.length(), url);
return encode(s, url);
}

std::string base64_encode_pem (std::string const& s) {
return insert_linebreaks(base64_encode(s, false), 64);
return encode_pem(s);
}

std::string base64_encode_mime(std::string const& s) {
return insert_linebreaks(base64_encode(s, false), 76);
return encode_mime(s);
}

#if __cplusplus >= 201703L
//
// Interface with std::string_view rather than const std::string&
// Requires C++17
// Provided by Yannic Bonenberger (https://github.com/Yannic)
//

std::string base64_encode(std::string_view s, bool url) {
return encode(s, url);
}

std::string base64_encode_pem(std::string_view s) {
return encode_pem(s);
}

std::string base64_encode_mime(std::string_view s) {
return encode_mime(s);
}

std::string base64_decode(std::string_view s, bool remove_linebreaks) {
return decode(s, remove_linebreaks);
}

#endif // __cplusplus >= 201703L
19 changes: 18 additions & 1 deletion base64.h
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
//
// base64 encoding and decoding with C++.
// Version: 2.rc.01 (release candidate)
// Version: 2.rc.02 (release candidate)
//

#ifndef BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A
#define BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A

#include <string>

#if __cplusplus >= 201703L
#include <string_view>
#endif // __cplusplus >= 201703L

std::string base64_encode (std::string const& s, bool url = false);
std::string base64_encode_pem (std::string const& s);
std::string base64_encode_mime(std::string const& s);

std::string base64_decode(std::string const& s, bool remove_linebreaks = false);
std::string base64_encode(unsigned char const*, unsigned int len, bool url = false);

#if __cplusplus >= 201703L
//
// Interface with std::string_view rather than const std::string&
// Requires C++17
// Provided by Yannic Bonenberger (https://github.com/Yannic)
//
std::string base64_encode (std::string_view s, bool url = false);
std::string base64_encode_pem (std::string_view s);
std::string base64_encode_mime(std::string_view s);

std::string base64_decode(std::string_view s, bool remove_linebreaks = false);
#endif // __cplusplus >= 201703L

#endif /* BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A */
26 changes: 25 additions & 1 deletion test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ int main() {

bool all_tests_passed = true;

const std::string orig =
const std::string orig =
"René Nyffenegger\n"
"http://www.renenyffenegger.ch\n"
"passion for data\n";
Expand Down Expand Up @@ -102,6 +102,30 @@ int main() {
all_tests_passed = false;
}


// --------------------------------------------------------------

#if __cplusplus >= 201703L
//
// Test the string_view interface (which required C++17)
//
std::string_view sv_orig = "foobarbaz";
std::string_view sv_encoded = base64_encode(sv_orig);

if (sv_encoded != "Zm9vYmFyYmF6") {
std::cout << "Failed to encode with string_view" << std::endl;
all_tests_passed = false;
}

std::string_view sv_decoded = base64_decode(sv_encoded);

if (sv_decoded != sv_orig) {
std::cout << "Failed to decode with string_view" << std::endl;
all_tests_passed = false;
}

#endif

if (all_tests_passed) return 0;
return 1;
}

0 comments on commit 2ca8b88

Please sign in to comment.