1
2// vim:sw=2:ai
3
4/*
5 * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
6 * Copyright (C) 2011-2017 Kentoku SHIBA
7 * See COPYRIGHT.txt for details.
8 */
9
10#include <my_global.h>
11#include "mysql_version.h"
12#include "hs_compat.h"
13#include "escape.hpp"
14#include "string_buffer.hpp"
15#include "fatal.hpp"
16#include "string_util.hpp"
17
18#define DBG_OP(x)
19#define DBG_BUF(x)
20
21namespace dena {
22
23enum special_char_t {
24 special_char_escape_prefix = 0x01, /* SOH */
25 special_char_noescape_min = 0x10, /* DLE */
26 special_char_escape_shift = 0x40, /* '@' */
27};
28
29void
30escape_string(char *& wp, const char *start, const char *finish)
31{
32 while (start != finish) {
33 const unsigned char c = *start;
34 if (c >= special_char_noescape_min) {
35 wp[0] = c; /* no need to escape */
36 } else {
37 wp[0] = special_char_escape_prefix;
38 ++wp;
39 wp[0] = c + special_char_escape_shift;
40 }
41 ++start;
42 ++wp;
43 }
44}
45
46void
47escape_string(string_buffer& ar, const char *start, const char *finish)
48{
49 const size_t buflen = (finish - start) * 2;
50 char *const wp_begin = ar.make_space(buflen);
51 char *wp = wp_begin;
52 escape_string(wp, start, finish);
53 ar.space_wrote(wp - wp_begin);
54}
55
56bool
57unescape_string(char *& wp, const char *start, const char *finish)
58{
59 /* works even if wp == start */
60 while (start != finish) {
61 const unsigned char c = *start;
62 if (c != special_char_escape_prefix) {
63 wp[0] = c;
64 } else if (start + 1 != finish) {
65 ++start;
66 const unsigned char cn = *start;
67 if (cn < special_char_escape_shift) {
68 return false;
69 }
70 wp[0] = cn - special_char_escape_shift;
71 } else {
72 return false;
73 }
74 ++start;
75 ++wp;
76 }
77 return true;
78}
79
80bool
81unescape_string(string_buffer& ar, const char *start, const char *finish)
82{
83 const size_t buflen = finish - start;
84 char *const wp_begin = ar.make_space(buflen);
85 char *wp = wp_begin;
86 const bool r = unescape_string(wp, start, finish);
87 ar.space_wrote(wp - wp_begin);
88 return r;
89}
90
91uint32
92read_ui32(char *& start, char *finish)
93{
94 char *const n_begin = start;
95 read_token(start, finish);
96 char *const n_end = start;
97 uint32 v = 0;
98 for (char *p = n_begin; p != n_end; ++p) {
99 const char ch = p[0];
100 if (ch >= '0' && ch <= '9') {
101 v *= 10;
102 v += (ch - '0');
103 }
104 }
105 return v;
106}
107
108void
109write_ui32(string_buffer& buf, uint32 v)
110{
111 char *wp = buf.make_space(12);
112 int len = snprintf(wp, 12, "%u", v);
113 if (len > 0) {
114 buf.space_wrote(len);
115 }
116}
117
118void
119write_ui64(string_buffer& buf, uint64 v)
120{
121 char *wp = buf.make_space(22);
122 int len = snprintf(wp, 22, "%llu", static_cast<unsigned long long>(v));
123 if (len > 0) {
124 buf.space_wrote(len);
125 }
126}
127
128};
129
130