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 <errno.h> |
10 | #include <stdio.h> |
11 | |
12 | #include "string_util.hpp" |
13 | |
14 | namespace dena { |
15 | |
16 | string_wref |
17 | get_token(char *& wp, char *wp_end, char delim) |
18 | { |
19 | char *const wp_begin = wp; |
20 | char *const p = memchr_char(wp_begin, delim, wp_end - wp_begin); |
21 | if (p == 0) { |
22 | wp = wp_end; |
23 | return string_wref(wp_begin, wp_end - wp_begin); |
24 | } |
25 | wp = p + 1; |
26 | return string_wref(wp_begin, p - wp_begin); |
27 | } |
28 | |
29 | template <typename T> T |
30 | atoi_tmpl_nocheck(const char *start, const char *finish) |
31 | { |
32 | T v = 0; |
33 | for (; start != finish; ++start) { |
34 | const char c = *start; |
35 | if (c < '0' || c > '9') { |
36 | break; |
37 | } |
38 | v *= 10; |
39 | v += static_cast<T>(c - '0'); |
40 | } |
41 | return v; |
42 | } |
43 | |
44 | template <typename T> T |
45 | atoi_signed_tmpl_nocheck(const char *start, const char *finish) |
46 | { |
47 | T v = 0; |
48 | bool negative = false; |
49 | if (start != finish) { |
50 | if (start[0] == '-') { |
51 | ++start; |
52 | negative = true; |
53 | } else if (start[0] == '+') { |
54 | ++start; |
55 | } |
56 | } |
57 | for (; start != finish; ++start) { |
58 | const char c = *start; |
59 | if (c < '0' || c > '9') { |
60 | break; |
61 | } |
62 | v *= 10; |
63 | if (negative) { |
64 | v -= static_cast<T>(c - '0'); |
65 | } else { |
66 | v += static_cast<T>(c - '0'); |
67 | } |
68 | } |
69 | return v; |
70 | } |
71 | |
72 | uint32_t |
73 | atoi_uint32_nocheck(const char *start, const char *finish) |
74 | { |
75 | return atoi_tmpl_nocheck<uint32_t>(start, finish); |
76 | } |
77 | |
78 | long long |
79 | atoll_nocheck(const char *start, const char *finish) |
80 | { |
81 | return atoi_signed_tmpl_nocheck<long long>(start, finish); |
82 | } |
83 | |
84 | void |
85 | append_uint32(string_buffer& buf, uint32_t v) |
86 | { |
87 | char *const wp = buf.make_space(64); |
88 | const int len = snprintf(wp, 64, "%lu" , static_cast<unsigned long>(v)); |
89 | if (len > 0) { |
90 | buf.space_wrote(len); |
91 | } |
92 | } |
93 | |
94 | std::string |
95 | to_stdstring(uint32_t v) |
96 | { |
97 | char buf[64]; |
98 | snprintf(buf, sizeof(buf), "%lu" , static_cast<unsigned long>(v)); |
99 | return std::string(buf); |
100 | } |
101 | |
102 | int |
103 | errno_string(const char *s, int en, std::string& err_r) |
104 | { |
105 | char buf[64]; |
106 | snprintf(buf, sizeof(buf), "%s: %d" , s, en); |
107 | err_r = std::string(buf); |
108 | return en; |
109 | } |
110 | |
111 | template <typename T> size_t |
112 | split_tmpl_arr(char delim, const T& buf, T *parts, size_t parts_len) |
113 | { |
114 | typedef typename T::value_type value_type; |
115 | size_t i = 0; |
116 | value_type *start = buf.begin(); |
117 | value_type *const finish = buf.end(); |
118 | for (i = 0; i < parts_len; ++i) { |
119 | value_type *const p = memchr_char(start, delim, finish - start); |
120 | if (p == 0) { |
121 | parts[i] = T(start, finish - start); |
122 | ++i; |
123 | break; |
124 | } |
125 | parts[i] = T(start, p - start); |
126 | start = p + 1; |
127 | } |
128 | const size_t r = i; |
129 | for (; i < parts_len; ++i) { |
130 | parts[i] = T(); |
131 | } |
132 | return r; |
133 | } |
134 | |
135 | size_t |
136 | split(char delim, const string_ref& buf, string_ref *parts, |
137 | size_t parts_len) |
138 | { |
139 | return split_tmpl_arr(delim, buf, parts, parts_len); |
140 | } |
141 | |
142 | size_t |
143 | split(char delim, const string_wref& buf, string_wref *parts, |
144 | size_t parts_len) |
145 | { |
146 | return split_tmpl_arr(delim, buf, parts, parts_len); |
147 | } |
148 | |
149 | template <typename T, typename V> size_t |
150 | split_tmpl_vec(char delim, const T& buf, V& parts) |
151 | { |
152 | typedef typename T::value_type value_type; |
153 | size_t i = 0; |
154 | value_type *start = buf.begin(); |
155 | value_type *const finish = buf.end(); |
156 | while (true) { |
157 | value_type *const p = memchr_char(start, delim, finish - start); |
158 | if (p == 0) { |
159 | parts.push_back(T(start, finish - start)); |
160 | break; |
161 | } |
162 | parts.push_back(T(start, p - start)); |
163 | start = p + 1; |
164 | } |
165 | const size_t r = i; |
166 | return r; |
167 | } |
168 | |
169 | size_t |
170 | split(char delim, const string_ref& buf, std::vector<string_ref>& parts_r) |
171 | { |
172 | return split_tmpl_vec(delim, buf, parts_r); |
173 | } |
174 | |
175 | size_t |
176 | split(char delim, const string_wref& buf, std::vector<string_wref>& parts_r) |
177 | { |
178 | return split_tmpl_vec(delim, buf, parts_r); |
179 | } |
180 | |
181 | }; |
182 | |
183 | |