Annotation of parser3/src/main/pa_string.C, revision 1.8
1.4 paf 1: /*
1.8 ! paf 2: $Id: pa_string.C,v 1.7 2001/01/27 10:02:59 paf Exp $
1.4 paf 3: */
4:
1.1 paf 5: #include <string.h>
6:
7: #include "pa_pool.h"
1.5 paf 8: #include "pa_hash.h"
1.1 paf 9:
10: void *String::operator new(size_t size, Pool *apool) {
1.5 paf 11: return apool->malloc(size);
1.1 paf 12: }
13:
1.2 paf 14: void String::construct(Pool *apool) {
1.1 paf 15: pool=apool;
1.2 paf 16: head.count=curr_chunk_rows=CR_PREALLOCATED_COUNT;
1.5 paf 17: append_here=head.rows;
1.2 paf 18: head.preallocated_link=0;
1.5 paf 19: link_row=&head.rows[curr_chunk_rows];
1.8 ! paf 20: fused_rows=fsize=0;
1.1 paf 21: }
22:
23: void String::expand() {
1.8 ! paf 24: curr_chunk_rows+=curr_chunk_rows*CR_GROW_PERCENT/100;
1.2 paf 25: Chunk *chunk=static_cast<Chunk *>(
1.8 ! paf 26: pool->malloc(sizeof(Chunk::Row)*curr_chunk_rows+sizeof(Chunk *)));
1.2 paf 27: chunk->count=curr_chunk_rows;
28: link_row->link=chunk;
1.5 paf 29: append_here=chunk->rows;
30: link_row=&chunk->rows[curr_chunk_rows];
1.8 ! paf 31: link_row->link=0;
1.1 paf 32: }
33:
1.8 ! paf 34: String::String(String& src) {
! 35: pool=src.pool;
! 36: head.count=CR_PREALLOCATED_COUNT;
! 37:
! 38: int src_used_rows=src.used_rows();
! 39: if(src_used_rows<=head.count) {
! 40: // new rows fit into preallocated area
! 41: curr_chunk_rows=head.count;
! 42: memcpy(head.rows, src.head.rows, sizeof(Chunk::Row)*src_used_rows);
! 43: append_here=&head.rows[src_used_rows];
! 44: head.preallocated_link=0;
! 45: link_row=&head.rows[curr_chunk_rows];
! 46: } else {
! 47: // warning:
! 48: // heavy relies on the fact
! 49: // that preallocated area is the same for all strings
! 50: //
! 51: // info:
! 52: // allocating only enough mem to fit src string rows
! 53: // next append would allocate a new chunk
! 54: //
! 55: // new rows don't fit into preallocated area: splitting into two chunks
! 56: // preallocated chunk src to constructing head
! 57: memcpy(head.rows, src.head.rows, sizeof(Chunk::Row)*head.count);
! 58: // remaining rows into new_chunk
! 59: curr_chunk_rows=src_used_rows-head.count;
! 60: Chunk *new_chunk=static_cast<Chunk *>(
! 61: pool->malloc(sizeof(Chunk::Row)*curr_chunk_rows+sizeof(Chunk *)));
! 62: new_chunk->count=curr_chunk_rows;
! 63: head.preallocated_link=new_chunk;
! 64: append_here=link_row=&new_chunk->rows[curr_chunk_rows];
! 65:
! 66: Chunk *old_chunk=src.head.preallocated_link;
! 67: Chunk::Row *new_rows=new_chunk->rows;
! 68: int rows_left_to_copy=curr_chunk_rows;
! 69: while(true) {
! 70: int old_count=old_chunk->count;
! 71: Chunk *next_chunk=old_chunk->rows[old_count].link;
! 72: if(next_chunk) {
! 73: // not last source chunk
! 74: // taking it all
! 75: memcpy(new_rows, old_chunk->rows, sizeof(Chunk::Row)*old_count);
! 76: new_rows+=old_count;
! 77: rows_left_to_copy-=old_count;
! 78:
! 79: old_chunk=next_chunk;
! 80: } else {
! 81: // the last source chunk
! 82: // taking only those rows of chunk that _left_to_copy
! 83: memcpy(new_rows, old_chunk->rows, sizeof(Chunk::Row)*rows_left_to_copy);
! 84: break;
! 85: }
! 86: }
1.5 paf 87: }
1.8 ! paf 88: link_row->link=0;
! 89: fused_rows=src_used_rows;
! 90: fsize=src.fsize;
1.5 paf 91: }
92:
1.1 paf 93: String& String::operator += (char *src) {
94: if(chunk_is_full())
95: expand();
96:
97: append_here->item.ptr=src;
1.8 ! paf 98: fsize+=append_here->item.size=strlen(src);
! 99: append_here++; fused_rows++;
1.1 paf 100:
101: return *this;
102: }
103:
104: char *String::c_str() {
1.5 paf 105: char *result=static_cast<char *>(pool->malloc(size()+1));
1.1 paf 106:
107: char *copy_here=result;
1.2 paf 108: Chunk *chunk=&head;
109: do {
1.5 paf 110: Chunk::Row *row=chunk->rows;
1.2 paf 111: for(int i=0; i<chunk->count; i++) {
1.1 paf 112: if(row==append_here)
113: goto break2;
114:
115: memcpy(copy_here, row->item.ptr, row->item.size);
116: copy_here+=row->item.size;
117: row++;
118: }
1.2 paf 119: chunk=row->link;
120: } while(chunk);
1.1 paf 121: break2:
122: *copy_here=0;
123: return result;
124: }
125:
1.7 paf 126: uint String::hash_code() {
127: uint result=0;
1.5 paf 128:
129: Chunk *chunk=&head;
130: do {
131: Chunk::Row *row=chunk->rows;
132: for(int i=0; i<chunk->count; i++) {
133: if(row==append_here)
134: goto break2;
135:
1.6 paf 136: result=Hash::generic_code(result, row->item.ptr, row->item.size);
1.5 paf 137: row++;
138: }
139: chunk=row->link;
140: } while(chunk);
141: break2:
142: return result;
143: }
144:
145: bool String::operator == (String& src) {
1.8 ! paf 146: if(size() != src.size())
! 147: return false;
! 148:
! 149: // FIX: 0 approach!
! 150: // use: in Hash it's "this" that has less chunks
! 151: if(head.rows[0].item.size==src.head.rows[0].item.size)
! 152: if(memcmp(head.rows[0].item.ptr, src.head.rows[0].item.ptr, head.rows[0].item.size)==0)
! 153: return true;
1.5 paf 154: return false;
155: }
E-mail: