source: sources/src/string.cc @ 1499:74fbdc7abbc2

Revision 1499:74fbdc7abbc2, 11.7 KB checked in by Dmytro Milinevskyy <millinevskyy@…>, 14 months ago (diff)

detect L1 cacheline size

Line 
1/***************************************************************************
2 *            string.cc
3 *
4 *  Thu Jun  10 2010
5 *  Copyright  2010  Dmytro Milinevskyy
6 *  milinevskyy@gmail.com
7 ****************************************************************************/
8
9/*
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU Lesser General Public License version 2.1 as published by
12 *  the Free Software Foundation;
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Lesser General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24/**
25 * vim indentation settings
26 * set tabstop=4
27 * set shiftwidth=4
28 */
29
30#include <libdodo/directives.h>
31
32#include <libdodo/string.h>
33
34#include <stdio.h>
35#include <string.h>
36
37using namespace dodo;
38
39#define ALIGN(x, a) (((x) + ((a) - 1))&~((a) - 1))
40#define ALIGN_STRING_BUFFER_SIZE(x) ALIGN(x, (x)>LEVEL1_DCACHE_LINESIZE?PAGE_SIZE:LEVEL1_DCACHE_LINESIZE)
41
42//-------------------------------------------------------------------
43
44string::string() : buf(new char[LEVEL1_DCACHE_LINESIZE]),
45                   bufSize(LEVEL1_DCACHE_LINESIZE),
46                   strLen(0)
47{
48    buf[0] = 0x0;
49}
50
51//-------------------------------------------------------------------
52
53string::string(const string &s) : buf(NULL),
54                                  bufSize(LEVEL1_DCACHE_LINESIZE),
55                                  strLen(s.strLen)
56{
57    if (strLen) {
58        bufSize = ALIGN_STRING_BUFFER_SIZE(strLen + 1);
59        buf = new char[bufSize];
60        memcpy(buf, s.buf, strLen);
61        buf[strLen] = 0x0;
62    } else {
63        buf = new char[LEVEL1_DCACHE_LINESIZE];
64        buf[0] = 0x0;
65    }
66}
67
68//-------------------------------------------------------------------
69
70string::string(const char *data) : buf(NULL),
71                                   bufSize(LEVEL1_DCACHE_LINESIZE),
72                                   strLen(0)
73{
74    if (data) {
75        strLen = strlen(data);
76        bufSize = ALIGN_STRING_BUFFER_SIZE(strLen + 1);
77        buf = new char[bufSize];
78        memcpy(buf, data, bufSize);
79    } else {
80        buf = new char[LEVEL1_DCACHE_LINESIZE];
81        buf[0] = 0x0;
82    }
83}
84
85//-------------------------------------------------------------------
86
87string::string(const char *str,
88               unsigned long length) : buf(NULL),
89                                       bufSize(LEVEL1_DCACHE_LINESIZE),
90                                       strLen(length)
91{
92    if (str) {
93        bufSize = ALIGN_STRING_BUFFER_SIZE(strLen + 1);
94        buf = new char[bufSize];
95        memcpy(buf, str, strLen);
96        buf[strLen] = 0x0;
97    } else {
98        buf = new char[LEVEL1_DCACHE_LINESIZE];
99        buf[0] = 0x0;
100    }
101}
102
103//-------------------------------------------------------------------
104
105string::string(char symbol,
106               unsigned long count) : buf(NULL),
107                                      bufSize(LEVEL1_DCACHE_LINESIZE),
108                                      strLen(count)
109{
110    if (strLen) {
111        bufSize = ALIGN_STRING_BUFFER_SIZE(strLen + 1);
112        buf = new char[bufSize];
113        memset(buf, symbol, strLen);
114        buf[strLen] = 0x0;
115    } else {
116        buf = new char[LEVEL1_DCACHE_LINESIZE];
117        buf[0] = 0x0;
118    }
119}
120
121//-------------------------------------------------------------------
122
123string::~string()
124{
125    delete [] buf;
126}
127
128//-------------------------------------------------------------------
129
130void
131string::erase(unsigned long index,
132              unsigned long count)
133{
134    if (count == POSITION_END)
135        count = strLen;
136
137    unsigned long end = index + count;
138
139
140    if (end >= strLen) {
141        buf[strLen = index] = 0x0;
142    } else {
143        strLen -= count;
144        memmove(buf+index, buf+end, strLen);
145        buf[strLen] = 0x0;
146    }
147}
148
149//-------------------------------------------------------------------
150
151void
152string::clear()
153{
154    strLen = 0;
155    buf[0] = 0x0;
156}
157
158//-------------------------------------------------------------------
159
160void
161string::resize(unsigned long len)
162{
163    if (len >= strLen)
164        return;
165
166    if (!(len < strLen || bufSize > len)) {
167        unsigned long newBufSize = ALIGN_STRING_BUFFER_SIZE(len + 1);
168
169        char *newBuf = new char[newBufSize];
170
171        memcpy(newBuf, buf, bufSize);
172        delete [] buf;
173        /* memset(newBuf+strLen, 0x0, newBufSize - bufSize); */
174
175        buf = newBuf;
176        bufSize = newBufSize;
177    }
178
179    strLen = len;
180    buf[strLen] = 0x0;
181}
182
183//-------------------------------------------------------------------
184
185unsigned long
186string::find(const string &str,
187             unsigned long index) const
188{
189    if (index > strLen)
190        return POSITION_END;
191
192    char *pos = strstr(buf+index, str.buf);
193    if (!pos)
194        return POSITION_END;
195    else
196        return pos - buf;
197}
198
199//-------------------------------------------------------------------
200
201string &
202string::replace(unsigned long index,
203                unsigned long num,
204                const string &str)
205{
206    if (index > strLen)
207        return *this;
208
209    if (bufSize < strLen - num + str.strLen) {
210        unsigned long newBufSize = ALIGN_STRING_BUFFER_SIZE(strLen - num + str.strLen + 1);
211
212        char *newBuf = new char[newBufSize];
213
214        memcpy(newBuf, buf, bufSize);
215        delete [] buf;
216
217        buf = newBuf;
218        bufSize = newBufSize;
219    }
220
221    if (num != str.strLen)
222        memmove(buf+index+str.strLen, buf+index+num, strLen-(index+num));
223    memcpy(buf+index, str.buf, str.strLen);
224    strLen += (int)str.strLen - (int)num;
225
226    return *this;
227}
228
229//-------------------------------------------------------------------
230
231string &
232string::insert(unsigned long index,
233               const string &str)
234{
235    if (index > strLen)
236        return *this;
237
238    if (bufSize < strLen + str.strLen) {
239        unsigned long newBufSize = ALIGN_STRING_BUFFER_SIZE(strLen + str.strLen + 1);
240
241        char *newBuf = new char[newBufSize];
242
243        memcpy(newBuf, buf, bufSize);
244        delete [] buf;
245
246        buf = newBuf;
247        bufSize = newBufSize;
248    }
249
250    memmove(buf+index+str.strLen, buf+index, strLen-index);
251    memcpy(buf+index, str.buf, str.strLen);
252    strLen += str.strLen;
253
254    return *this;
255}
256
257//-------------------------------------------------------------------
258
259string
260string::substr(unsigned long index,
261               unsigned long length) const
262{
263    if (index > strLen)
264        return string();
265
266    if (length == POSITION_END)
267        length = strLen;
268
269    return string(buf+index, (length+index>strLen)?strLen-index:length);
270}
271
272//-------------------------------------------------------------------
273
274void
275string::reserve(unsigned long count)
276{
277    if (count > bufSize) {
278        bufSize = ALIGN_STRING_BUFFER_SIZE(count + 1);
279
280        char *newBuf = new char[bufSize];
281
282        memcpy(newBuf, buf, strLen);
283        delete [] buf;
284
285        buf = newBuf;
286    }
287}
288
289//-------------------------------------------------------------------
290
291void
292string::assign(const char *data,
293               unsigned long length)
294{
295    strLen = length;
296
297    if (bufSize <= strLen) {
298        delete [] buf;
299
300        bufSize = ALIGN_STRING_BUFFER_SIZE(strLen + 1);
301        buf = new char[bufSize];
302    }
303
304    memcpy(buf, data, strLen);
305    buf[strLen] = 0x0;
306}
307
308//-------------------------------------------------------------------
309
310void
311string::append(const char *data,
312                   unsigned long length)
313{
314    if (bufSize < strLen + length) {
315        bufSize = ALIGN_STRING_BUFFER_SIZE(strLen + length + 1);
316
317        char *newBuf = new char[bufSize];
318
319        memcpy(newBuf, buf, strLen);
320        delete [] buf;
321
322        buf = newBuf;
323    }
324    memcpy(buf+strLen, data, length);
325    strLen += length;
326    buf[strLen] = 0x0;
327}
328
329//-------------------------------------------------------------------
330
331string &
332string::operator=(const string &data)
333{
334    strLen = data.strLen;
335
336    if (bufSize <= strLen) {
337        delete [] buf;
338
339        bufSize = ALIGN_STRING_BUFFER_SIZE(strLen + 1);
340        buf = new char[bufSize];
341    }
342
343    memcpy(buf, data.buf, bufSize);
344
345    return *this;
346}
347
348//-------------------------------------------------------------------
349
350string &
351string::operator=(const char *data)
352{
353    strLen = strlen(data);
354
355    if (bufSize <= strLen) {
356        delete [] buf;
357
358        bufSize = ALIGN_STRING_BUFFER_SIZE(strLen + 1);
359        buf = new char[bufSize];
360    }
361
362    memcpy(buf, data, bufSize);
363
364    return *this;
365}
366
367//-------------------------------------------------------------------
368
369string &
370string::operator=(char ch)
371{
372    buf[0] = ch;
373    buf[1] = 0x0;
374    strLen = 1;
375
376    return *this;
377}
378
379//-------------------------------------------------------------------
380
381string &
382string::operator+=(const string &str)
383{
384    if (bufSize < strLen + str.strLen) {
385        bufSize = ALIGN_STRING_BUFFER_SIZE(strLen + str.strLen + 1);
386
387        char *newBuf = new char[bufSize];
388
389        memcpy(newBuf, buf, strLen);
390        delete [] buf;
391
392        buf = newBuf;
393    }
394
395    memcpy(buf+strLen, str.buf, str.strLen+1);
396    strLen += str.strLen;
397
398    return *this;
399}
400
401//-------------------------------------------------------------------
402
403string &
404string::operator+=(const char *str)
405{
406    unsigned long len = strlen(str);
407
408    if (bufSize < strLen + len) {
409        bufSize = ALIGN_STRING_BUFFER_SIZE(strLen + len + 1);
410
411        char *newBuf = new char[bufSize];
412
413        memcpy(newBuf, buf, strLen);
414        delete [] buf;
415
416        buf = newBuf;
417    }
418    memcpy(buf+strLen, str, len+1);
419    strLen += len;
420
421    return *this;
422}
423
424//-------------------------------------------------------------------
425
426string &
427string::operator+=(char c)
428{
429    if (bufSize < strLen + 1) {
430        bufSize = ALIGN_STRING_BUFFER_SIZE(strLen + LEVEL1_DCACHE_LINESIZE + 1);
431
432        char *newBuf = new char[bufSize];
433
434        memcpy(newBuf, buf, strLen);
435        delete [] buf;
436
437        buf = newBuf;
438    }
439    buf[strLen] = c;
440    ++strLen;
441    buf[strLen] = 0x0;
442
443    return *this;
444}
445
446//-------------------------------------------------------------------
447
448namespace dodo {
449    bool
450    operator<(const string &s1,
451              const string &s2)
452    {
453        return memcmp(s1.buf, s2.buf, s1.strLen) < 0;
454    }
455
456    //-------------------------------------------------------------------
457
458    bool
459    operator>(const string &s1,
460              const string &s2)
461    {
462        return memcmp(s1.buf, s2.buf, s1.strLen) > 0;
463    }
464
465    //-------------------------------------------------------------------
466
467    bool
468    operator==(const string &s1,
469               const string &s2)
470    {
471        return memcmp(s1.buf, s2.buf, s1.strLen) == 0;
472    }
473
474    //-------------------------------------------------------------------
475
476    bool
477    operator==(const string &s1,
478               const char *s2)
479    {
480        return memcmp(s1.buf, s2, s1.strLen) == 0;
481    }
482
483    //-------------------------------------------------------------------
484
485    string
486    operator+(const string &s1,
487              const string &s2)
488    {
489        string str = s1;
490        str += s2;
491        return str;
492    }
493
494    //-------------------------------------------------------------------
495
496    string
497    operator+(const string &s1,
498              const char *s2)
499    {
500        string str = s1;
501        str += s2;
502        return str;
503    }
504
505    //-------------------------------------------------------------------
506
507    string
508    operator+(const char *s1,
509              const string &s2)
510    {
511        string str = s1;
512        str += s2;
513        return str;
514    }
515};
516
517//-------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.