问问题
1711 次
1 回答
1
According to manual of PostgreSQL bytea, there are 2 ways for writing a statement containing binary stream.
For a string "\x4A\xC3\xA1\xF2\x18"
- hex
bytea
:E'\\x4AC3A1F218'
- escaped
bytea
:E'J\\303\\241\\362\\030'::bytea
-- escape\
as\\\\
, escape'
as\'
and escape non-printable as\\three-digit-octal
So you can come up with functions like these.
std::string ascii_to_hex_bytea(std::string_view sv) {
std::ostringstream os;
os << R"(E'\\x)" << std::hex << std::uppercase;
for (unsigned char ch : sv) {
os << std::setfill('0') << std::setw(2) << static_cast<uint16_t>(ch);
}
os << "'";
return os.str();
}
std::string ascii_to_escaped_bytea(std::string_view sv) {
std::ostringstream os;
os << "E'" << std::oct;
for (unsigned char ch : sv) {
if (isprint(ch))
switch (ch) {
case('\\') : os << R"(\\\\)"; break; // escape back slash
case('\'') : os << R"(\')"; break; // escape single quote
default : os << ch; // simply put printable char
}
else // escape the rest as an octal with back slash leading
os << R"(\\)" << std::setfill('0') << std::setw(3) << static_cast<uint16_t>(ch);
}
os << "'::bytea";
return os.str();
}
Suppose you have ss
as stringstream
with some data (for demo, we just ramdom it here)
std::stringstream ss;
{ // random bits for length of 1024
std::string str(1024,'\0');
for (char* addr = str.data(); addr < str.data() + str.size(); ++addr )
*addr = static_cast<char>(std::experimental::randint<uint16_t>(0,255) );
ss.str(str);
}
You can write statement using those functions
auto hex_str = ascii_to_hex_bytea(ss.str() );
std::cout << hex_str << "\n";
std::string tableName{"table_name"};
std::string statement1 = "UPDATE " + tableName + " SET byte_info = " + hex_str + " WHERE id = 1;";
std::cout << statement1 << "\n\n";
auto escaped_str = ascii_to_escaped_bytea(ss.str() );
std::cout << escaped_str << "\n";
std::string statement2 = "UPDATE " + tableName + " SET byte_info = " + escaped_str + " WHERE id = 1;";
std::cout << statement2 << "\n";
E'\\x4AC3A1F218E1ED92AB0B3966C3E99CC5BD8419B4A91D504F85AE7621525F305A...'
UPDATE table_name SET byte_info = E'\\x4AC3A1F218E1ED92AB0B3966C3E99C...' WHERE id = 1;
E'J\\303\\241\\362\\030\\341\\355\\222\\253\\0139f\\303\\351\\234\\30...'::bytea
UPDATE table_name SET byte_info = E'J\\303\\241\\362\\030\\341\\355\\...'::bytea WHERE id = 1;
于 2018-08-05T06:48:28.540 回答