Skip to content
This repository was archived by the owner on Jul 4, 2025. It is now read-only.

Commit 3f80512

Browse files
committed
feat: Add nitro utils function for base64 and image load
1 parent 902dc3f commit 3f80512

File tree

1 file changed

+133
-1
lines changed

1 file changed

+133
-1
lines changed

utils/nitro_utils.h

Lines changed: 133 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@
33
#include "random"
44
#include "string"
55
#include <algorithm>
6+
#include <drogon/HttpClient.h>
67
#include <drogon/HttpResponse.h>
8+
#include <fstream>
79
#include <iostream>
810
#include <ostream>
911
#include <regex>
12+
#include <vector>
1013
// Include platform-specific headers
1114
#ifdef _WIN32
12-
#include <winsock2.h>
1315
#include <windows.h>
16+
#include <winsock2.h>
1417
#else
1518
#include <dirent.h>
1619
#endif
@@ -32,6 +35,135 @@ inline std::string extractBase64(const std::string &input) {
3235
return "";
3336
}
3437

38+
// Helper function to encode data to Base64
39+
inline std::string base64Encode(const std::vector<unsigned char> &data) {
40+
static const char encodingTable[] =
41+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
42+
std::string encodedData;
43+
int i = 0;
44+
int j = 0;
45+
unsigned char array3[3];
46+
unsigned char array4[4];
47+
48+
for (unsigned char c : data) {
49+
array3[i++] = c;
50+
if (i == 3) {
51+
array4[0] = (array3[0] & 0xfc) >> 2;
52+
array4[1] = ((array3[0] & 0x03) << 4) + ((array3[1] & 0xf0) >> 4);
53+
array4[2] = ((array3[1] & 0x0f) << 2) + ((array3[2] & 0xc0) >> 6);
54+
array4[3] = array3[2] & 0x3f;
55+
56+
for (i = 0; i < 4; i++)
57+
encodedData += encodingTable[array4[i]];
58+
i = 0;
59+
}
60+
}
61+
62+
if (i) {
63+
for (j = i; j < 3; j++)
64+
array3[j] = '\0';
65+
66+
array4[0] = (array3[0] & 0xfc) >> 2;
67+
array4[1] = ((array3[0] & 0x03) << 4) + ((array3[1] & 0xf0) >> 4);
68+
array4[2] = ((array3[1] & 0x0f) << 2) + ((array3[2] & 0xc0) >> 6);
69+
70+
for (j = 0; j < i + 1; j++)
71+
encodedData += encodingTable[array4[j]];
72+
73+
while (i++ < 3)
74+
encodedData += '=';
75+
}
76+
77+
return encodedData;
78+
}
79+
80+
// Function to load an image and convert it to Base64
81+
inline std::string imageToBase64(const std::string &imagePath) {
82+
std::ifstream imageFile(imagePath, std::ios::binary);
83+
if (!imageFile.is_open()) {
84+
throw std::runtime_error("Could not open the image file.");
85+
}
86+
87+
std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(imageFile),
88+
{});
89+
return base64Encode(buffer);
90+
}
91+
92+
// Helper function to generate a unique filename
93+
inline std::string generateUniqueFilename(const std::string &prefix,
94+
const std::string &extension) {
95+
// Get current time as a timestamp
96+
auto now = std::chrono::system_clock::now();
97+
auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
98+
auto epoch = now_ms.time_since_epoch();
99+
auto value = std::chrono::duration_cast<std::chrono::milliseconds>(epoch);
100+
101+
// Generate a random number
102+
std::random_device rd;
103+
std::mt19937 gen(rd());
104+
std::uniform_int_distribution<> dis(1000, 9999);
105+
106+
std::stringstream ss;
107+
ss << prefix << value.count() << "_" << dis(gen) << extension;
108+
return ss.str();
109+
}
110+
111+
// Function to download an image
112+
inline void downloadImage(const std::string &url, const std::string &savePath,
113+
std::function<void(bool)> callback) {
114+
auto client = drogon::HttpClient::newHttpClient(url);
115+
client->sendRequest(
116+
drogon::HttpRequest::newHttpRequest(),
117+
[savePath, callback](drogon::ReqResult result,
118+
const drogon::HttpResponsePtr &response) {
119+
if (result == drogon::ReqResult::Ok) {
120+
// Save the image to the specified path
121+
std::ofstream outFile(savePath, std::ios::binary);
122+
outFile.write(response->body().data(), response->body().size());
123+
outFile.close();
124+
125+
// Invoke the callback with true to indicate success
126+
callback(true);
127+
} else {
128+
std::cerr << "Failed to download the image: " << result << std::endl;
129+
// Invoke the callback with false to indicate failure
130+
callback(false);
131+
}
132+
});
133+
}
134+
135+
inline void
136+
processRemoteImage(const std::string &url,
137+
std::function<void(const std::string &)> callback) {
138+
std::string localPath =
139+
generateUniqueFilename("temp_", ".jpg"); // Generate a unique filename
140+
141+
downloadImage(url, localPath, [localPath, callback](bool success) {
142+
if (success) {
143+
try {
144+
std::string base64Image = imageToBase64(localPath);
145+
std::remove(localPath.c_str()); // Delete the local file
146+
callback(base64Image); // Invoke the callback with the Base64 string
147+
} catch (const std::exception &e) {
148+
std::cerr << "Error during processing: " << e.what() << std::endl;
149+
}
150+
} else {
151+
std::cerr << "Failed to download the image." << std::endl;
152+
}
153+
});
154+
}
155+
156+
inline void
157+
processLocalImage(const std::string &localPath,
158+
std::function<void(const std::string &)> callback) {
159+
try {
160+
std::string base64Image = imageToBase64(localPath);
161+
callback(base64Image); // Invoke the callback with the Base64 string
162+
} catch (const std::exception &e) {
163+
std::cerr << "Error during processing: " << e.what() << std::endl;
164+
}
165+
}
166+
35167
inline std::vector<std::string> listFilesInDir(const std::string &path) {
36168
std::vector<std::string> files;
37169

0 commit comments

Comments
 (0)