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