]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/inspstring.cpp
Merge pull request #1018 from SaberUK/insp20+hidekills
[user/henk/code/inspircd.git] / src / inspstring.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2010 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
6  *   Copyright (C) 2005-2007 Craig Edwards <craigedwards@brainbox.cc>
7  *
8  * This file is part of InspIRCd.  InspIRCd is free software: you can
9  * redistribute it and/or modify it under the terms of the GNU General Public
10  * License as published by the Free Software Foundation, version 2.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21
22 #include "inspircd.h"
23
24 /*
25  * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
26  * All rights reserved.
27  *
28  * Redistribution and use in source and binary forms, with or without
29  * modification, are permitted provided that the following conditions
30  * are met:
31  * 1. Redistributions of source code must retain the above copyright
32  *    notice, this list of conditions and the following disclaimer.
33  * 2. Redistributions in binary form must reproduce the above copyright
34  *    notice, this list of conditions and the following disclaimer in the
35  *    documentation and/or other materials provided with the distribution.
36  * 3. The name of the author may not be used to endorse or promote products
37  *    derived from this software without specific prior written permission.
38  *
39  * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
40  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
41  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
42  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
43  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
44  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
45  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
46  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
47  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
48  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49  */
50
51 #ifndef HAS_STRLCPY
52 CoreExport size_t strlcat(char *dst, const char *src, size_t siz)
53 {
54         char *d = dst;
55         const char *s = src;
56         size_t n = siz, dlen;
57
58         while (n-- != 0 && *d != '\0')
59                 d++;
60
61         dlen = d - dst;
62         n = siz - dlen;
63
64         if (n == 0)
65                 return(dlen + strlen(s));
66
67         while (*s != '\0')
68         {
69                 if (n != 1)
70                 {
71                         *d++ = *s;
72                         n--;
73                 }
74
75                 s++;
76         }
77
78         *d = '\0';
79         return(dlen + (s - src)); /* count does not include NUL */
80 }
81
82 CoreExport size_t strlcpy(char *dst, const char *src, size_t siz)
83 {
84         char *d = dst;
85         const char *s = src;
86         size_t n = siz;
87
88         /* Copy as many bytes as will fit */
89         if (n != 0 && --n != 0)
90         {
91                 do
92                 {
93                         if ((*d++ = *s++) == 0)
94                                 break;
95                 } while (--n != 0);
96         }
97
98         /* Not enough room in dst, add NUL and traverse rest of src */
99         if (n == 0)
100         {
101                 if (siz != 0)
102                         *d = '\0'; /* NUL-terminate dst */
103                 while (*s++);
104         }
105
106         return(s - src - 1); /* count does not include NUL */
107 }
108 #endif
109
110 CoreExport int charlcat(char* x,char y,int z)
111 {
112         char* x__n = x;
113         int v = 0;
114
115         while(*x__n++)
116                 v++;
117
118         if (v < z - 1)
119         {
120                 *--x__n = y;
121                 *++x__n = 0;
122         }
123
124         return v;
125 }
126
127 CoreExport bool charremove(char* mp, char remove)
128 {
129         char* mptr = mp;
130         bool shift_down = false;
131
132         while (*mptr)
133         {
134                 if (*mptr == remove)
135                 shift_down = true;
136
137                 if (shift_down)
138                         *mptr = *(mptr+1);
139
140                 mptr++;
141         }
142
143         return shift_down;
144 }
145
146 static const char hextable[] = "0123456789abcdef";
147
148 std::string BinToHex(const std::string& data)
149 {
150         int l = data.length();
151         std::string rv;
152         rv.reserve(l * 2);
153         for(int i=0; i < l; i++)
154         {
155                 unsigned char c = data[i];
156                 rv.append(1, hextable[c >> 4]);
157                 rv.append(1, hextable[c & 0xF]);
158         }
159         return rv;
160 }
161
162 static const char b64table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
163
164 std::string BinToBase64(const std::string& data_str, const char* table, char pad)
165 {
166         if (!table)
167                 table = b64table;
168
169         uint32_t buffer;
170         uint8_t* data = (uint8_t*)data_str.data();
171         std::string rv;
172         size_t i = 0;
173         while (i + 2 < data_str.length())
174         {
175                 buffer = (data[i] << 16 | data[i+1] << 8 | data[i+2]);
176                 rv.push_back(table[0x3F & (buffer >> 18)]);
177                 rv.push_back(table[0x3F & (buffer >> 12)]);
178                 rv.push_back(table[0x3F & (buffer >>  6)]);
179                 rv.push_back(table[0x3F & (buffer >>  0)]);
180                 i += 3;
181         }
182         if (data_str.length() == i)
183         {
184                 // no extra characters
185         }
186         else if (data_str.length() == i + 1)
187         {
188                 buffer = data[i] << 16;
189                 rv.push_back(table[0x3F & (buffer >> 18)]);
190                 rv.push_back(table[0x3F & (buffer >> 12)]);
191                 if (pad)
192                 {
193                         rv.push_back(pad);
194                         rv.push_back(pad);
195                 }
196         }
197         else if (data_str.length() == i + 2)
198         {
199                 buffer = (data[i] << 16 | data[i+1] << 8);
200                 rv.push_back(table[0x3F & (buffer >> 18)]);
201                 rv.push_back(table[0x3F & (buffer >> 12)]);
202                 rv.push_back(table[0x3F & (buffer >>  6)]);
203                 if (pad)
204                         rv.push_back(pad);
205         }
206         return rv;
207 }
208
209 std::string Base64ToBin(const std::string& data_str, const char* table)
210 {
211         if (!table)
212                 table = b64table;
213
214         int bitcount = 0;
215         uint32_t buffer = 0;
216         const char* data = data_str.c_str();
217         std::string rv;
218         while (true)
219         {
220                 const char* find = strchr(table, *data++);
221                 if (!find || find >= table + 64)
222                         break;
223                 buffer = (buffer << 6) | (find - table);
224                 bitcount += 6;
225                 if (bitcount >= 8)
226                 {
227                         bitcount -= 8;
228                         rv.push_back((buffer >> bitcount) & 0xFF);
229                 }
230         }
231         return rv;
232 }