Annotation of parser3/src/main/pa_string.C, revision 1.17
1.4 paf 1: /*
1.17 ! paf 2: $Id: pa_string.C,v 1.16 2001/01/29 22:34:58 paf Exp $
1.4 paf 3: */
4:
1.1 paf 5: #include <string.h>
6:
1.13 paf 7: #include "pa_pool.h"
1.12 paf 8: #include "pa_string.h"
1.5 paf 9: #include "pa_hash.h"
1.1 paf 10:
1.15 paf 11: String::String(Pool& apool) :
1.17 ! paf 12: Pooled(apool) {
1.2 paf 13: head.count=curr_chunk_rows=CR_PREALLOCATED_COUNT;
1.5 paf 14: append_here=head.rows;
1.2 paf 15: head.preallocated_link=0;
1.5 paf 16: link_row=&head.rows[curr_chunk_rows];
1.8 paf 17: fused_rows=fsize=0;
1.1 paf 18: }
19:
20: void String::expand() {
1.8 paf 21: curr_chunk_rows+=curr_chunk_rows*CR_GROW_PERCENT/100;
1.2 paf 22: Chunk *chunk=static_cast<Chunk *>(
1.15 paf 23: pool.malloc(sizeof(int)+sizeof(Chunk::Row)*curr_chunk_rows+sizeof(Chunk *)));
1.2 paf 24: chunk->count=curr_chunk_rows;
25: link_row->link=chunk;
1.5 paf 26: append_here=chunk->rows;
27: link_row=&chunk->rows[curr_chunk_rows];
1.8 paf 28: link_row->link=0;
1.1 paf 29: }
30:
1.16 paf 31: String::String(const String& src) :
1.17 ! paf 32: Pooled(src.pool) {
1.8 paf 33: head.count=CR_PREALLOCATED_COUNT;
34:
35: int src_used_rows=src.used_rows();
36: if(src_used_rows<=head.count) {
1.10 paf 37: // all new rows fit into preallocated area
1.8 paf 38: curr_chunk_rows=head.count;
39: memcpy(head.rows, src.head.rows, sizeof(Chunk::Row)*src_used_rows);
40: append_here=&head.rows[src_used_rows];
41: link_row=&head.rows[curr_chunk_rows];
42: } else {
43: // warning:
1.10 paf 44: // heavily relies on the fact
45: // "preallocated area is the same for all strings"
1.8 paf 46: //
47: // info:
48: // allocating only enough mem to fit src string rows
49: // next append would allocate a new chunk
50: //
51: // new rows don't fit into preallocated area: splitting into two chunks
52: // preallocated chunk src to constructing head
53: memcpy(head.rows, src.head.rows, sizeof(Chunk::Row)*head.count);
54: // remaining rows into new_chunk
55: curr_chunk_rows=src_used_rows-head.count;
56: Chunk *new_chunk=static_cast<Chunk *>(
1.15 paf 57: pool.malloc(sizeof(int)+sizeof(Chunk::Row)*curr_chunk_rows+sizeof(Chunk *)));
1.8 paf 58: new_chunk->count=curr_chunk_rows;
59: head.preallocated_link=new_chunk;
60: append_here=link_row=&new_chunk->rows[curr_chunk_rows];
61:
62: Chunk *old_chunk=src.head.preallocated_link;
63: Chunk::Row *new_rows=new_chunk->rows;
64: int rows_left_to_copy=curr_chunk_rows;
65: while(true) {
66: int old_count=old_chunk->count;
67: Chunk *next_chunk=old_chunk->rows[old_count].link;
68: if(next_chunk) {
69: // not last source chunk
70: // taking it all
71: memcpy(new_rows, old_chunk->rows, sizeof(Chunk::Row)*old_count);
72: new_rows+=old_count;
73: rows_left_to_copy-=old_count;
74:
75: old_chunk=next_chunk;
76: } else {
77: // the last source chunk
78: // taking only those rows of chunk that _left_to_copy
79: memcpy(new_rows, old_chunk->rows, sizeof(Chunk::Row)*rows_left_to_copy);
80: break;
81: }
82: }
1.5 paf 83: }
1.8 paf 84: link_row->link=0;
85: fused_rows=src_used_rows;
86: fsize=src.fsize;
1.5 paf 87: }
88:
1.13 paf 89: String& String::real_append(STRING_APPEND_PARAMS) {
1.9 paf 90: if(!src)
91: return *this;
92: int len=strlen(src);
93: if(!len)
94: return *this;
95:
1.1 paf 96: if(chunk_is_full())
97: expand();
98:
99: append_here->item.ptr=src;
1.9 paf 100: fsize+=append_here->item.size=len;
1.13 paf 101: #ifndef NO_STRING_ORIGIN
1.14 paf 102: append_here->item.origin.file=file;
103: append_here->item.origin.line=line;
1.13 paf 104: #endif
1.8 paf 105: append_here++; fused_rows++;
1.1 paf 106:
107: return *this;
108: }
109:
1.16 paf 110: char *String::cstr() const {
1.15 paf 111: char *result=static_cast<char *>(pool.malloc(size()+1));
1.1 paf 112:
113: char *copy_here=result;
1.16 paf 114: const Chunk *chunk=&head;
1.2 paf 115: do {
1.16 paf 116: const Chunk::Row *row=chunk->rows;
1.2 paf 117: for(int i=0; i<chunk->count; i++) {
1.1 paf 118: if(row==append_here)
119: goto break2;
120:
121: memcpy(copy_here, row->item.ptr, row->item.size);
122: copy_here+=row->item.size;
123: row++;
124: }
1.2 paf 125: chunk=row->link;
126: } while(chunk);
1.1 paf 127: break2:
128: *copy_here=0;
129: return result;
130: }
131:
1.16 paf 132: uint String::hash_code() const {
1.7 paf 133: uint result=0;
1.5 paf 134:
1.16 paf 135: const Chunk *chunk=&head;
1.5 paf 136: do {
1.16 paf 137: const Chunk::Row *row=chunk->rows;
1.5 paf 138: for(int i=0; i<chunk->count; i++) {
139: if(row==append_here)
140: goto break2;
141:
1.6 paf 142: result=Hash::generic_code(result, row->item.ptr, row->item.size);
1.5 paf 143: row++;
144: }
145: chunk=row->link;
146: } while(chunk);
147: break2:
148: return result;
149: }
150:
1.16 paf 151: bool String::operator == (const String& src) const {
1.8 paf 152: if(size() != src.size())
153: return false;
154:
1.16 paf 155: const Chunk *a_chunk=&head;
156: const Chunk *b_chunk=&src.head;
157: const Chunk::Row *a_row=a_chunk->rows;
158: const Chunk::Row *b_row=b_chunk->rows;
1.9 paf 159: int a_offset=0;
160: int b_offset=0;
161: Chunk::Row *a_end=append_here;
162: Chunk::Row *b_end=src.append_here;
1.11 paf 163: int a_countdown=a_chunk->count;
164: int b_countdown=b_chunk->count;
1.9 paf 165: bool a_break=false;
166: bool b_break=false;
167: while(true) {
168: int size_diff=
169: (a_row->item.size-a_offset)-
170: (b_row->item.size-b_offset);
171:
172: if(size_diff==0) { // a has same size as b
173: if(memcmp(a_row->item.ptr+a_offset, b_row->item.ptr+b_offset, a_row->item.size-a_offset)!=0)
174: return false;
1.11 paf 175: a_row++; a_countdown--; a_offset=0;
176: b_row++; b_countdown--; b_offset=0;
1.9 paf 177: } else if (size_diff>0) { // a longer
178: if(memcmp(a_row->item.ptr+a_offset, b_row->item.ptr+b_offset, b_row->item.size-b_offset)!=0)
179: return false;
180: a_offset+=b_row->item.size-b_offset;
1.11 paf 181: b_row++; b_countdown--; b_offset=0;
1.9 paf 182: } else { // b longer
183: if(memcmp(a_row->item.ptr+a_offset, b_row->item.ptr+b_offset, a_row->item.size-a_offset)!=0)
184: return false;
185: b_offset+=a_row->item.size-a_offset;
1.11 paf 186: a_row++; a_countdown--; a_offset=0;
1.9 paf 187: }
188:
189: a_break=a_row==a_end;
190: b_break=b_row==b_end;
191: if(a_break || b_break)
192: break;
193:
1.11 paf 194: if(!a_countdown) {
1.9 paf 195: a_chunk=a_row->link;
196: a_row=a_chunk->rows;
1.11 paf 197: a_countdown=a_chunk->count;
1.9 paf 198: }
1.11 paf 199: if(!b_countdown) {
1.9 paf 200: b_chunk=b_row->link;
201: b_row=b_chunk->rows;
1.11 paf 202: b_countdown=b_chunk->count;
1.9 paf 203: }
204: }
205: return a_break==b_break;
1.5 paf 206: }
E-mail: