summaryrefslogtreecommitdiffstats
path: root/storage/spider/hs_client/escape.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/spider/hs_client/escape.cpp')
-rw-r--r--storage/spider/hs_client/escape.cpp129
1 files changed, 129 insertions, 0 deletions
diff --git a/storage/spider/hs_client/escape.cpp b/storage/spider/hs_client/escape.cpp
new file mode 100644
index 00000000..f3e60afc
--- /dev/null
+++ b/storage/spider/hs_client/escape.cpp
@@ -0,0 +1,129 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * Copyright (C) 2011-2017 Kentoku SHIBA
+ * See COPYRIGHT.txt for details.
+ */
+
+#include <my_global.h>
+#include "mysql_version.h"
+#include "hs_compat.h"
+#include "escape.hpp"
+#include "string_buffer.hpp"
+#include "fatal.hpp"
+#include "string_util.hpp"
+
+#define DBG_OP(x)
+#define DBG_BUF(x)
+
+namespace dena {
+
+enum special_char_t {
+ special_char_escape_prefix = 0x01, /* SOH */
+ special_char_noescape_min = 0x10, /* DLE */
+ special_char_escape_shift = 0x40, /* '@' */
+};
+
+void
+escape_string(char *& wp, const char *start, const char *finish)
+{
+ while (start != finish) {
+ const unsigned char c = *start;
+ if (c >= special_char_noescape_min) {
+ wp[0] = c; /* no need to escape */
+ } else {
+ wp[0] = special_char_escape_prefix;
+ ++wp;
+ wp[0] = c + special_char_escape_shift;
+ }
+ ++start;
+ ++wp;
+ }
+}
+
+void
+escape_string(string_buffer& ar, const char *start, const char *finish)
+{
+ const size_t buflen = (finish - start) * 2;
+ char *const wp_begin = ar.make_space(buflen);
+ char *wp = wp_begin;
+ escape_string(wp, start, finish);
+ ar.space_wrote(wp - wp_begin);
+}
+
+bool
+unescape_string(char *& wp, const char *start, const char *finish)
+{
+ /* works even if wp == start */
+ while (start != finish) {
+ const unsigned char c = *start;
+ if (c != special_char_escape_prefix) {
+ wp[0] = c;
+ } else if (start + 1 != finish) {
+ ++start;
+ const unsigned char cn = *start;
+ if (cn < special_char_escape_shift) {
+ return false;
+ }
+ wp[0] = cn - special_char_escape_shift;
+ } else {
+ return false;
+ }
+ ++start;
+ ++wp;
+ }
+ return true;
+}
+
+bool
+unescape_string(string_buffer& ar, const char *start, const char *finish)
+{
+ const size_t buflen = finish - start;
+ char *const wp_begin = ar.make_space(buflen);
+ char *wp = wp_begin;
+ const bool r = unescape_string(wp, start, finish);
+ ar.space_wrote(wp - wp_begin);
+ return r;
+}
+
+uint32
+read_ui32(char *& start, char *finish)
+{
+ char *const n_begin = start;
+ read_token(start, finish);
+ char *const n_end = start;
+ uint32 v = 0;
+ for (char *p = n_begin; p != n_end; ++p) {
+ const char ch = p[0];
+ if (ch >= '0' && ch <= '9') {
+ v *= 10;
+ v += (ch - '0');
+ }
+ }
+ return v;
+}
+
+void
+write_ui32(string_buffer& buf, uint32 v)
+{
+ char *wp = buf.make_space(12);
+ int len = snprintf(wp, 12, "%u", v);
+ if (len > 0) {
+ buf.space_wrote(len);
+ }
+}
+
+void
+write_ui64(string_buffer& buf, uint64 v)
+{
+ char *wp = buf.make_space(22);
+ int len = snprintf(wp, 22, "%llu", static_cast<unsigned long long>(v));
+ if (len > 0) {
+ buf.space_wrote(len);
+ }
+}
+
+};
+