*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.204 2009/08/04 16:08:36 tgl Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.205 2009/08/04 18:05:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
static_std_strings);
}
+
+/* HEX encoding support for bytea */
+static const char hextbl[] = "0123456789abcdef";
+
+static const int8 hexlookup[128] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
+static inline char
+get_hex(char c)
+{
+ int res = -1;
+
+ if (c > 0 && c < 127)
+ res = hexlookup[(unsigned char) c];
+
+ return (char) res;
+}
+
+
/*
* PQescapeBytea - converts from binary string to the
* minimal encoding necessary to include the string in an SQL
* INSERT statement with a bytea type column as the target.
*
- * The following transformations are applied
+ * We can use either hex or escape (traditional) encoding.
+ * In escape mode, the following transformations are applied:
* '\0' == ASCII 0 == \000
* '\'' == ASCII 39 == ''
* '\\' == ASCII 92 == \\
* anything < 0x20, or > 0x7e ---> \ooo
* (where ooo is an octal expression)
+ *
* If not std_strings, all backslashes sent to the output are doubled.
*/
static unsigned char *
PQescapeByteaInternal(PGconn *conn,
const unsigned char *from, size_t from_length,
- size_t *to_length, bool std_strings)
+ size_t *to_length, bool std_strings, bool use_hex)
{
const unsigned char *vp;
unsigned char *rp;
*/
len = 1;
- vp = from;
- for (i = from_length; i > 0; i--, vp++)
+ if (use_hex)
{
- if (*vp < 0x20 || *vp > 0x7e)
- len += bslash_len + 3;
- else if (*vp == '\'')
- len += 2;
- else if (*vp == '\\')
- len += bslash_len + bslash_len;
- else
- len++;
+ len += bslash_len + 1 + 2 * from_length;
+ }
+ else
+ {
+ vp = from;
+ for (i = from_length; i > 0; i--, vp++)
+ {
+ if (*vp < 0x20 || *vp > 0x7e)
+ len += bslash_len + 3;
+ else if (*vp == '\'')
+ len += 2;
+ else if (*vp == '\\')
+ len += bslash_len + bslash_len;
+ else
+ len++;
+ }
}
*to_length = len;
return NULL;
}
+ if (use_hex)
+ {
+ if (!std_strings)
+ *rp++ = '\\';
+ *rp++ = '\\';
+ *rp++ = 'x';
+ }
+
vp = from;
for (i = from_length; i > 0; i--, vp++)
{
- if (*vp < 0x20 || *vp > 0x7e)
- {
- int val = *vp;
+ unsigned char c = *vp;
+ if (use_hex)
+ {
+ *rp++ = hextbl[(c >> 4) & 0xF];
+ *rp++ = hextbl[c & 0xF];
+ }
+ else if (c < 0x20 || c > 0x7e)
+ {
if (!std_strings)
*rp++ = '\\';
*rp++ = '\\';
- *rp++ = (val >> 6) + '0';
- *rp++ = ((val >> 3) & 07) + '0';
- *rp++ = (val & 07) + '0';
+ *rp++ = (c >> 6) + '0';
+ *rp++ = ((c >> 3) & 07) + '0';
+ *rp++ = (c & 07) + '0';
}
- else if (*vp == '\'')
+ else if (c == '\'')
{
*rp++ = '\'';
*rp++ = '\'';
}
- else if (*vp == '\\')
+ else if (c == '\\')
{
if (!std_strings)
{
*rp++ = '\\';
}
else
- *rp++ = *vp;
+ *rp++ = c;
}
*rp = '\0';
if (!conn)
return NULL;
return PQescapeByteaInternal(conn, from, from_length, to_length,
- conn->std_strings);
+ conn->std_strings,
+ (conn->sversion >= 80500));
}
unsigned char *
PQescapeBytea(const unsigned char *from, size_t from_length, size_t *to_length)
{
return PQescapeByteaInternal(NULL, from, from_length, to_length,
- static_std_strings);
-}
-
-
-static const int8 hexlookup[128] = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
- -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-};
-
-static inline char
-get_hex(char c)
-{
- int res = -1;
-
- if (c > 0 && c < 127)
- res = hexlookup[(unsigned char) c];
-
- return (char) res;
+ static_std_strings,
+ false /* can't use hex */ );
}