Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

Annotation of /trunk/TTProxy/YCL/include/YCL/String.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 16 - (hide annotations) (download) (as text)
Thu Aug 3 13:33:30 2006 UTC (17 years, 10 months ago) by yutakakn
Original Path: TTProxy/trunk/YCL/include/YCL/String.h
File MIME type: text/x-chdr
File size: 16202 byte(s)
(none)

1 yutakakn 16 /*
2     * $Id: String.h,v 1.3 2006-08-03 13:33:18 yutakakn Exp $
3     */
4    
5     #ifndef _YCL_STRING_H_
6     #define _YCL_STRING_H_
7    
8     #if _MSC_VER >= 1000
9     #pragma once
10     #endif // _MSC_VER >= 1000
11    
12     #include <YCL/common.h>
13    
14     #include <string.h>
15    
16     namespace yebisuya {
17    
18     // 文字列の管理・操作を行うクラス。
19     class String {
20     private:
21     // 文字列を格納するバッファ。
22     // 文字列の前には参照カウンタを持ち、
23     // 代入や破棄の際にはそこを変更する。
24     const char* string;
25    
26     // utilities
27     // 文字列を格納するバッファを作成する。
28     // 文字列と参照カウンタの分の領域を確保する。
29     // 参照カウンタは0になっている。
30     // 引数:
31     // length 文字列の長さ。
32     // 返値:
33     // 作成したバッファの文字列部のアドレス。
34     static char* createBuffer(size_t length) {
35     size_t* count = (size_t*) new unsigned char[sizeof (size_t) + sizeof (char) * (length + 1)];
36     *count = 0;
37     return (char*) (count + 1);
38     }
39     // 文字列を格納したバッファを作成する。
40     // 引数:
41     // source 格納する文字列。
42     // 返値:
43     // 作成したバッファの文字列部のアドレス。
44     static const char* create(const char* source) {
45     return source != NULL ? create(source, strlen(source)) : NULL;
46     }
47     // 文字列を格納したバッファを作成する。
48     // 引数:
49     // source 格納する文字列。
50     // length 文字列の長さ。
51     // 返値:
52     // 作成したバッファの文字列部のアドレス。
53     static const char* create(const char* source, size_t length) {
54     if (source != NULL) {
55     char* buffer = createBuffer(length);
56     memcpy(buffer, source, length);
57     buffer[length] = '\0';
58     return buffer;
59     }
60     return NULL;
61     }
62     // 二つの文字列を連結し格納したバッファを作成する。
63     // 引数:
64     // str1 連結する文字列(前)。
65     // str2 連結する文字列(後)。
66     // 返値:
67     // 作成したバッファの文字列部のアドレス。
68     static const char* concat(const char* str1, const char* str2) {
69     size_t len1 = strlen(str1);
70     size_t len2 = strlen(str2);
71     char* buffer = createBuffer(len1 + len2);
72     memcpy(buffer, str1, len1);
73     memcpy(buffer + len1, str2, len2);
74     buffer[len1 + len2] = '\0';
75     return buffer;
76     }
77     // private methods
78     // 参照カウンタを減らし、0になったらバッファを破棄する。
79     void release() {
80     if (string != NULL) {
81     size_t* count = (size_t*) string - 1;
82     if (--*count == 0)
83     delete[] (unsigned char*) count;
84     }
85     }
86     // 参照カウンタを増やす。
87     void add() {
88     if (string != NULL) {
89     size_t* count = (size_t*) string - 1;
90     ++*count;
91     }
92     }
93     // 別のバッファと置き換える。
94     // 元のバッファの参照カウンタを減らし、
95     // 新しいバッファの参照カウンタを増やす。
96     // 引数:
97     // source 置き換える新しいバッファ。
98     void set(const char* source) {
99     if (string != source) {
100     release();
101     string = source;
102     add();
103     }
104     }
105     public:
106     // constructor
107     // デフォルトコンストラクタ。
108     // NULLが入っているので、このままで文字列操作するとアクセス違反になるので注意。
109     String():string(NULL) {
110     }
111     // 元の文字列を指定するコンストラクタ。
112     // 引数:
113     // source 元の文字列。
114     String(const char* source):string(NULL) {
115     set(create(source));
116     }
117     // 元の文字列を長さ付きで指定するコンストラクタ。
118     // 引数:
119     // source 元の文字列。
120     // length 文字列の長さ。
121     String(const char* source, size_t length):string(NULL) {
122     set(create(source, length));
123     }
124     // コピーコンストラクタ。
125     // 引数:
126     // source 元の文字列。
127     String(const String& source):string(NULL) {
128     set(source.string);
129     }
130     // 二つの文字列を連結するコンストラクタ。
131     // 引数:
132     // str1 前になる文字列。
133     // str2 後になる文字列。
134     String(const char* str1, const char* str2):string(NULL) {
135     set(concat(str1, str2));
136     }
137     // 二つの文字列を連結するコンストラクタ。
138     // 引数:
139     // str1 前になる文字列。
140     // str2 後になる文字列。
141     String(const String& str1, const char* str2):string(NULL) {
142     set(*str2 != '\0' ? concat(str1.string, str2) : str1.string);
143     }
144     // destructor
145     // デストラクタ。
146     // 派生することは考えていないので仮想関数にはしない。
147     ~String() {
148     release();
149     }
150     // public methods
151     // この文字列の後に指定の文字列を連結する。
152     // 引数:
153     // source 連結する文字列。
154     // 返値:
155     // 連結された文字列。
156     String concat(const char* source)const {
157     return String(*this, source);
158     }
159     // 文字列との比較を行う。
160     // NULLとも比較できる。
161     // 引数:
162     // str 比較する文字列。
163     // 返値:
164     // 等しければ0、strの方が大きければ負、小さければ正。
165     int compareTo(const char* str)const {
166     if (str == NULL)
167     return string == NULL ? 0 : 1;
168     else if (string == NULL)
169     return -1;
170     return strcmp(string, str);
171     }
172     // 文字列との比較を大文字小文字の区別なしで行う。
173     // NULLとも比較できる。
174     // 引数:
175     // str 比較する文字列。
176     // 返値:
177     // 等しければ0、strの方が大きければ負、小さければ正。
178     int compareToIgnoreCase(const char* str)const {
179     if (str == NULL)
180     return string == NULL ? 0 : 1;
181     else if (string == NULL)
182     return -1;
183     return _stricmp(string, str);
184     }
185     // 文字列との比較を行う。
186     // NULLとも比較できる。
187     // 引数:
188     // str 比較する文字列。
189     // 返値:
190     // 等しければ真。
191     bool equals(const char* str)const {
192     return compareTo(str) == 0;
193     }
194     // 文字列との比較を大文字小文字の区別なしで行う。
195     // NULLとも比較できる。
196     // 引数:
197     // str 比較する文字列。
198     // 返値:
199     // 等しければ真。
200     bool equalsIgnoreCase(const char* str)const {
201     return compareToIgnoreCase(str) == 0;
202     }
203     // 指定された文字列で始まっているかどうかを判定する。
204     // 引数:
205     // str 比較する文字列。
206     // 返値:
207     // 指定された文字列で始まっていれば真。
208     bool startsWith(const char* str)const {
209     return startsWith(str, 0);
210     }
211     // 指定の位置から指定された文字列で始まっているかどうかを判定する。
212     // 引数:
213     // str 比較する文字列。
214     // 返値:
215     // 指定された文字列で始まっていれば真。
216     bool startsWith(const char* str, int offset)const {
217     return strncmp(string, str, strlen(str)) == 0;
218     }
219     // 指定された文字列で終わっているかどうかを判定する。
220     // 引数:
221     // str 比較する文字列。
222     // 返値:
223     // 指定された文字列で終わっていれば真。
224     //
225     bool endsWith(const char* str)const {
226     size_t str_length = strlen(str);
227     size_t string_length = length();
228     if (string_length < str_length)
229     return false;
230     return strcmp(string + string_length - str_length, str) == 0;
231     }
232     // 指定の文字がどの位置にあるかを探す。
233     // 引数:
234     // chr 探す文字。
235     // 返値:
236     // 文字の見つかったインデックス。見つからなければ-1。
237     int indexOf(char chr)const {
238     return indexOf(chr, 0);
239     }
240     // 指定の文字がどの位置にあるかを指定の位置から探す。
241     // 引数:
242     // chr 探す文字。
243     // from 探し始める位置。
244     // 返値:
245     // 文字の見つかったインデックス。見つからなければ-1。
246     int indexOf(char chr, size_t from)const {
247     if (from < 0)
248     from = 0;
249     else if (from >= length())
250     return -1;
251     const char* found = strchr(string + from, chr);
252     if (found == NULL)
253     return -1;
254     return found - string;
255     }
256     // 指定の文字列がどの位置にあるかを探す。
257     // 引数:
258     // str 探す文字列。
259     // 返値:
260     // 文字列の見つかったインデックス。見つからなければ-1。
261     int indexOf(const char* str)const {
262     return indexOf(str, 0);
263     }
264     // 指定の文字列がどの位置にあるかを指定の位置から探す。
265     // 引数:
266     // str 探す文字列。
267     // from 探し始める位置。
268     // 返値:
269     // 文字列の見つかったインデックス。見つからなければ-1。
270     //
271     int indexOf(const char* str, size_t from)const {
272     if (from < 0)
273     from = 0;
274     else if (from >= length())
275     return -1;
276     const char* found = strstr(string + from, str);
277     if (found == NULL)
278     return -1;
279     return found - string;
280     }
281     // 文字列の長さを返す。
282     size_t length()const {
283     return strlen(string);
284     }
285     // 指定の文字が最後に見つかる位置を取得する。
286     // 引数:
287     // chr 探す文字。
288     // 返値:
289     // 文字の見つかったインデックス。見つからなければ-1。
290     int lastIndexOf(char chr)const {
291     return lastIndexOf(chr, (size_t) -1);
292     }
293     // 指定の文字が指定の位置よりも前で最後に見つかる位置を取得する。
294     // 引数:
295     // chr 探す文字。
296     // from 探し始める位置。
297     // 返値:
298     // 文字の見つかったインデックス。見つからなければ-1。
299     int lastIndexOf(char chr, size_t from)const {
300     size_t len = length();
301     if (from > len - 1)
302     from = len - 1;
303     const char* s = string;
304     const char* end = string + from;
305     const char* found = NULL;
306     while (*s != '0' && s <= end) {
307     if (*s == chr)
308     found = s;
309     if (isLeadByte(*s))
310     s++;
311     s++;
312     }
313     return found != NULL ? found - string : -1;
314     }
315     // 指定の文字列が最後に見つかる位置を取得する。
316     // 引数:
317     // str 探す文字列。
318     // 返値:
319     // 文字列の見つかったインデックス。見つからなければ-1。
320     int lastIndexOf(const char* str)const {
321     return lastIndexOf(str, (size_t) -1);
322     }
323     // 指定の文字列が指定の位置よりも前で最後に見つかる位置を取得する。
324     // 引数:
325     // str 探す文字列。
326     // from 探し始める位置。
327     // 返値:
328     // 文字列の見つかったインデックス。見つからなければ-1。
329     int lastIndexOf(const char* str, size_t from)const {
330     size_t len = length();
331     size_t str_len = strlen(str);
332     if (from > len - str_len)
333     from = len - str_len;
334     const char* s = string + from;
335     while (s >= string) {
336     if (strncmp(s, str, str_len) == 0)
337     return s - string;
338     s--;
339     }
340     return -1;
341     }
342     // 文字列の一部を取り出す。
343     // 引数:
344     // start 取り出す文字列の先頭の位置。
345     // 返値:
346     // 文字列の一部。
347     String substring(int start)const {
348     return String(string + start);
349     }
350     // 文字列の一部を取り出す。
351     // 引数:
352     // start 取り出す文字列の先頭の位置。
353     // end 取り出す文字列の後の位置。
354     // 返値:
355     // 文字列の一部。
356     String substring(int start, int end)const {
357     return String(string + start, end - start);
358     }
359     // 指定の位置にある文字を取り出す。
360     // 引数:
361     // index 取り出す文字の位置。
362     // 返値:
363     // 指定の位置にある文字。
364     char charAt(size_t index)const {
365     return index >= 0 && index < length() ? string[index] : '\0';
366     }
367     // 指定の文字を指定の文字に置き換えます。
368     // 引数:
369     // oldChr 元の文字。
370     // newChr 置き換える文字。
371     // 返値:
372     // 置換後の文字列。
373     String replace(char oldChr, char newChr)const {
374     String result(string);
375     char* s = (char*) result.string;
376     while (*s != '\0'){
377     if (String::isLeadByte(*s))
378     s++;
379     else if (*s == oldChr)
380     *s = newChr;
381     s++;
382     }
383     return result;
384     }
385     // 文字列中の大文字を小文字に変換する。
386     // 返値:
387     // 変換後の文字列。
388     String toLowerCase()const {
389     String result(string);
390     char* s = (char*) result.string;
391     while (*s != '\0'){
392     if (String::isLeadByte(*s))
393     s++;
394     else if ('A' <= *s && *s <= 'Z')
395     *s += 'a' - 'A';
396     s++;
397     }
398     return result;
399     }
400     // 文字列中の小文字を大文字に変換する。
401     // 返値:
402     // 変換後の文字列。
403     String toUpperCase()const {
404     String result(string);
405     char* s = (char*) result.string;
406     while (*s != '\0'){
407     if (String::isLeadByte(*s))
408     s++;
409     else if ('a' <= *s && *s <= 'z')
410     *s += 'A' - 'a';
411     s++;
412     }
413     return result;
414     }
415     // 文字列の前後の空白文字を削除する。
416     // 返値:
417     // 削除後の文字列。
418     String trim()const {
419     const char* s = string;
420     while (*s != '\0' && (unsigned char) *s <= ' ')
421     s++;
422     const char* start = s;
423     s = string + length();
424     while (s > start && (*s != '\0' && (unsigned char) *s <= ' '))
425     s--;
426     return String(start, s - start);
427     }
428    
429     // operators
430    
431     // const char*へのキャスト演算子
432     // 返値:
433     // 文字列へのアドレス。
434     operator const char*()const {
435     return string;
436     }
437     // char配列のように扱うための[]演算子。
438     // 引数:
439     // index 取得する文字のインデックス。
440     // 返値:
441     // 指定のインデックスにある文字。
442     char operator[](size_t index)const {
443     return charAt(index);
444     }
445     // 文字列を連結するための+演算子。
446     // 引数:
447     // source 連結する文字列。
448     // 返値:
449     // 連結した文字列。
450     String operator+(const char* source)const {
451     return String(string, source);
452     }
453     // 文字列を連結するための+演算子。
454     // 引数:
455     // source 連結する文字列。
456     // 返値:
457     // 連結した文字列。
458     String operator+(const String& source)const {
459     return *string != '\0' ? String(string, source.string) : source;
460     }
461     // 文字列を連結するための+演算子。
462     // 引数:
463     // str1 連結する文字列(前)。
464     // str2 連結する文字列(後)。
465     // 返値:
466     // 連結した文字列。
467     friend String operator+(const char* str1, const String& str2) {
468     return *str1 != '\0' ? String(str1, str2.string) : str2;
469     }
470     // 代入演算子。
471     // 引数:
472     // source 代入する文字列。
473     // 返値:
474     // 代入結果。
475     String& operator=(const char* source) {
476     set(create(source));
477     return *this;
478     }
479     // 代入演算子。
480     // 引数:
481     // source 代入する文字列。
482     // 返値:
483     // 代入結果。
484     String& operator=(const String& source) {
485     set(source.string);
486     return *this;
487     }
488     // 連結した結果を代入する演算子。
489     // 引数:
490     // source 連結する文字列。
491     // 返値:
492     // 連結結果。
493     String& operator+=(const char* source) {
494     if (*source != '\0')
495     set(concat(string, source));
496     return *this;
497     }
498     // 比較演算子。
499     // 引数:
500     // str 比較対象の文字列。
501     // 返値:
502     // strの方が等しければ真。
503     bool operator==(const String& str)const {
504     return compareTo(str.string) == 0;
505     }
506     // 比較演算子。
507     // 引数:
508     // str 比較対象の文字列。
509     // 返値:
510     // strの方が等しければ真。
511     bool operator==(const char* str)const {
512     return compareTo(str) == 0;
513     }
514     // 比較演算子。
515     // 引数:
516     // str1 比較する文字列。
517     // str2 比較する文字列。
518     // 返値:
519     // str1よりstr2の方が等しければ真。
520     friend bool operator==(const char* str1, const String& str2) {
521     return str2.compareTo(str1) == 0;
522     }
523     // 比較演算子。
524     // 引数:
525     // str 比較対象の文字列。
526     // 返値:
527     // strの方が等しくなければ真。
528     bool operator!=(const String& str)const {
529     return compareTo(str) != 0;
530     }
531     // 比較演算子。
532     // 引数:
533     // str 比較対象の文字列。
534     // 返値:
535     // strの方が等しくなければ真。
536     bool operator!=(const char* str)const {
537     return compareTo(str) != 0;
538     }
539     // 比較演算子。
540     // 引数:
541     // str1 比較する文字列。
542     // str2 比較する文字列。
543     // 返値:
544     // str1よりstr2の方が等しくなければ真。
545     friend bool operator!=(const char* str1, const String& str2) {
546     return str2.compareTo(str1) != 0;
547     }
548     // 比較演算子。
549     // 引数:
550     // str 比較対象の文字列。
551     // 返値:
552     // strの方が大きければ真。
553     bool operator<(const String& str)const {
554     return compareTo(str) < 0;
555     }
556     // 比較演算子。
557     // 引数:
558     // str 比較対象の文字列。
559     // 返値:
560     // strの方が大きければ真。
561     bool operator<(const char* str)const {
562     return compareTo(str) < 0;
563     }
564     // 比較演算子。
565     // 引数:
566     // str1 比較する文字列。
567     // str2 比較する文字列。
568     // 返値:
569     // str1よりstr2の方が大きければ真。
570     friend bool operator<(const char* str1, const String& str2) {
571     return str2.compareTo(str1) > 0;
572     }
573     // 比較演算子。
574     // 引数:
575     // str 比較対象の文字列。
576     // 返値:
577     // strの方が大きいか等しければ真。
578     bool operator<=(const String& str)const {
579     return compareTo(str) <= 0;
580     }
581     // 比較演算子。
582     // 引数:
583     // str 比較対象の文字列。
584     // 返値:
585     // strの方が大きいか等しければ真。
586     bool operator<=(const char* str)const {
587     return compareTo(str) <= 0;
588     }
589     // 比較演算子。
590     // 引数:
591     // str1 比較する文字列。
592     // str2 比較する文字列。
593     // 返値:
594     // str1よりstr2の方が大きいか等しければ真。
595     friend bool operator<=(const char* str1, const String& str2) {
596     return str2.compareTo(str1) >= 0;
597     }
598     // 比較演算子。
599     // 引数:
600     // str 比較対象の文字列。
601     // 返値:
602     // strの方が小さければ真。
603     bool operator>(const String& str)const {
604     return compareTo(str) > 0;
605     }
606     // 比較演算子。
607     // 引数:
608     // str 比較対象の文字列。
609     // 返値:
610     // strの方が小さければ真。
611     bool operator>(const char* str)const {
612     return compareTo(str) > 0;
613     }
614     // 比較演算子。
615     // 引数:
616     // str1 比較する文字列。
617     // str2 比較する文字列。
618     // 返値:
619     // str1よりstr2の方が小さければ真。
620     friend bool operator>(const char* str1, const String& str2) {
621     return str2.compareTo(str1) < 0;
622     }
623     // 比較演算子。
624     // 引数:
625     // str 比較対象の文字列。
626     // 返値:
627     // strの方が小さいか等しければ真。
628     bool operator>=(const String& str)const {
629     return compareTo(str) >= 0;
630     }
631     // 比較演算子。
632     // 引数:
633     // str 比較対象の文字列。
634     // 返値:
635     // strの方が小さいか等しければ真。
636     bool operator>=(const char* str)const {
637     return compareTo(str) >= 0;
638     }
639     // 比較演算子。
640     // 引数:
641     // str1 比較する文字列。
642     // str2 比較する文字列。
643     // 返値:
644     // str1よりstr2の方が小さいか等しければ真。
645     friend bool operator>=(const char* str1, const String& str2) {
646     return str2.compareTo(str1) <= 0;
647     }
648    
649     // public utilities
650    
651     // 2バイト文字の最初の1バイトかどうかを判定する。
652     // 引数:
653     // 判定するバイト。
654     // 返値:
655     // 2バイト文字の最初の1バイトであれば真。
656     static bool isLeadByte(char ch) {
657     #ifdef _INC_WINDOWS
658     return ::IsDBCSLeadByte(ch) != 0;
659     #else
660     return (ch & 0x80) != 0;
661     #endif
662     }
663     };
664    
665     }
666    
667     #endif//_YCL_STRING_H_
668    
669     /*
670     * $Changes
671     * $Log: not supported by cvs2svn $
672     * Revision 1.2 2003/11/19 10:16:54 sugoroku
673     * lastIndexOfの1文字版にバグがあったので修正
674     *
675     * Revision 1.1.1.1 2003/05/26 15:32:07 sugoroku
676     * 新規作成
677     *
678     */

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26