1 /*
2 * Copyright (C) 2006, 2007, 2009 Toni Corvera
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
14 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
15 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
16 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
18 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
19 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
20 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
22 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25 // $Id: str_utils.cc 1101 2009-04-05 17:33:40Z $
26
27 #include "str_utils.h"
28
29 #include <algorithm> // std::transform
30 #include <cctype> // std::toupper, std::tolower
31 #include <cassert>
32
33 #include <iostream>
34
35 namespace net_outlyer {
36
37 namespace str {
38
39 using std::string;
40 using std::transform;
41 using std::vector;
42 using std::max;
43
44 // [C++] local visibility
45 namespace {
46 /*!
47 * \brief Creates a copy of the input string by applying a transformation
48 * \param[in] s Input string
49 * \param[in] callback Transformation function to apply
50 * \return A copy of \em s after applying \em callback
51 * \remarks \em callback will be applied to each input character
52 */
53 inline
copy_transform(const string & s,int (* callback)(int))54 string copy_transform(const string & s, int(*callback)(int)) {
55 string cp(s);
56 transform(s.begin(), s.end(), cp.begin(), callback);
57 return cp;
58 }
59 }
60
to_upper(const string & s)61 string to_upper(const string & s) {
62 return copy_transform(s, std::toupper);
63 }
64
to_lower(const string & s)65 string to_lower(const string & s) {
66 return copy_transform(s, std::tolower);
67 }
68
to_hex(int n)69 string to_hex(int n) {
70 return to_string<int>(n, std::hex);
71 }
72
to_hex(int n,unsigned int minbytes,bool zeroex)73 string to_hex(int n, unsigned int minbytes, bool zeroex) {
74 return ( zeroex ? "0x" : "" ) + to_string(n, std::hex, minbytes*2);
75 }
76
pad(const string & s,size_t pad_to,const string & pad,const pad_direction & p)77 string pad(const string & s, size_t pad_to, const string & pad, const pad_direction & p) {
78 if (s.length() >= pad_to) return s;
79
80 string cp;
81 cp.reserve(pad_to);
82
83 const size_t diff = pad_to - s.length();
84
85 assert( diff > 0 );
86
87 switch (p) {
88 case PAD_RIGHT:
89 case PAD_LEFT:
90 {
91 string padding(pad);
92 while (padding.length() < diff) {
93 padding.append(pad);
94 }
95
96 if (PAD_RIGHT == p) {
97 cp = s + padding.substr(0, diff);
98 }
99 else {
100 assert( PAD_LEFT == p );
101 cp = padding.substr(0, diff) + s;
102 }
103 }
104 break;
105 case PAD_BOTH:
106 {
107 const size_t llen = diff / 2;
108 const size_t rlen = diff - llen;
109
110 string padding(pad);
111 while (padding.length() < max<size_t>(llen, rlen)) {
112 padding.append(pad);
113 }
114
115 cp = padding.substr(0, llen) + s + padding.substr(0, rlen);
116 }
117 break;
118 default:
119 assert( false );
120 } // switch
121
122 return cp;
123
124 } // pad [string]
125
pad(const string & s,size_t pad_to,char pad,const pad_direction & p)126 string pad(const string & s, size_t pad_to, char pad, const pad_direction & p) {
127 if (s.length() >= pad_to) return s;
128
129 const size_t diff = pad_to - s.length();
130 assert( diff > 0 );
131
132 string cp;
133 cp.reserve(pad_to);
134
135 switch (p) {
136 case PAD_RIGHT:
137 case PAD_LEFT:
138 {
139 const string padding(diff, pad);
140
141 if (PAD_RIGHT == p) {
142 cp = s + padding;
143 }
144 else {
145 assert( PAD_LEFT == p );
146 cp = padding + s;
147 }
148 }
149 break;
150 case PAD_BOTH:
151 {
152 const size_t llen = diff / 2;
153 const size_t rlen = diff - llen;
154
155 const string pl(llen, pad);
156 const string pr(rlen, pad);
157
158 cp = pl + s + pr;
159 }
160 break;
161 default:
162 assert( false );
163 } // switch
164
165 return cp;
166 } // pad [char]
167
ends_in(const string & s,const string & end)168 bool ends_in(const string & s, const string & end) {
169 assert( end.length() > 0 );
170
171 if (end.length() > s.length()) return false;
172
173 return s.substr(s.length() - end.length()) == end;
174 }
175
176
177 } // namespace str
178
179 } // namespace net_outlyer
180
181 // vim:set ts=4 et ai:
182