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: