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
14namespace dena {
15
16string_wref
17get_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
29template <typename T> T
30atoi_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
44template <typename T> T
45atoi_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
72uint32_t
73atoi_uint32_nocheck(const char *start, const char *finish)
74{
75 return atoi_tmpl_nocheck<uint32_t>(start, finish);
76}
77
78long long
79atoll_nocheck(const char *start, const char *finish)
80{
81 return atoi_signed_tmpl_nocheck<long long>(start, finish);
82}
83
84void
85append_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
94std::string
95to_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
102int
103errno_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
111template <typename T> size_t
112split_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
135size_t
136split(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
142size_t
143split(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
149template <typename T, typename V> size_t
150split_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
169size_t
170split(char delim, const string_ref& buf, std::vector<string_ref>& parts_r)
171{
172 return split_tmpl_vec(delim, buf, parts_r);
173}
174
175size_t
176split(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