--- parser3/src/main/Attic/pa_array.C 2002/02/07 11:55:30 1.45 +++ parser3/src/main/Attic/pa_array.C 2002/08/06 14:23:23 1.51 @@ -1,18 +1,20 @@ /** @file Parser: array class. - Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) - Author: Alexander Petrosyan (http://paf.design.ru) - - $Id: pa_array.C,v 1.45 2002/02/07 11:55:30 paf Exp $ + Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) + Author: Alexandr Petrosian (http://paf.design.ru) */ +static const char* IDENT_ARRAY_C="$Date: 2002/08/06 14:23:23 $"; + #include "pa_pool.h" #include "pa_array.h" #include "pa_exception.h" #include "pa_common.h" -void Array::construct_new(int initial_rows) { +Array::Array(Pool& apool, int initial_rows) : Pooled(apool) { + initial_rows=max(initial_rows, CR_INITIAL_ROWS_DEFAULT); + head=tail=static_cast( malloc(sizeof(int)+sizeof(Chunk::Row)*initial_rows+sizeof(Chunk *), 19)); head->count=initial_rows; @@ -22,15 +24,6 @@ void Array::construct_new(int initial_ro fused_rows=0; } -Array::Array(Pool& apool, int initial_rows) : Pooled(apool) { - construct_new(max(initial_rows, CR_INITIAL_ROWS_DEFAULT)); -} - -Array::Array(const Array& source, int offset) : Pooled(source.pool()) { - construct_new(source.size()); - append_array(source, offset); -} - void Array::expand(int chunk_rows) { Chunk *chunk=tail=static_cast( malloc(sizeof(int)+sizeof(Chunk::Row)*chunk_rows+sizeof(Chunk *), 2)); @@ -54,7 +47,7 @@ Array& Array::operator += (Item *src) { Array::Item *Array::get(int index) const { if(!(index>=0 && index=0 && indexrows[index-base].item=item; } -Array& Array::append_array(const Array& src, int offset) { - int src_rows_to_copy=src.fused_rows-offset; +Array& Array::append_array(const Array& src, int offset, int limit) { + //if(((void*)&src)==(void*)0x6cf520) _asm int 3; + // fix limit + { + int m=src.fused_rows-offset; + if(!m) + return *this; + if(!limit || limit>m) + limit=m; + } + int last_chunk_rows_left=link_row-append_here; // our last chunk too small for src to fit? - if(src_rows_to_copy>last_chunk_rows_left) { + if(limit>last_chunk_rows_left) { // shrink last chunk to used rows tail->count-=last_chunk_rows_left; link_row=append_here; // append new src_used_rows-ed chunk - expand(src_rows_to_copy); + expand(limit); } + // prepare... Chunk *src_chunk=src.head; Chunk::Row *dest_rows=append_here; - int rows_left_to_copy=src.fused_rows; - int rows_left_to_skip=offset; + + // a little ahead of time, no harm done ['limit' destroyed later] + append_here+=limit; + fused_rows+=limit; + + // ...do it while(true) { int src_count=src_chunk->count; + int rows_to_copy_now=min(src_count-offset, limit); Chunk *next_chunk=src_chunk->rows[src_count].link; if(next_chunk) { // not last source chunk - // taking it all - int rows_to_copy_now=src_count-rows_left_to_skip; - if(rows_to_copy_now>0) - memcpy(dest_rows, src_chunk->rows+rows_left_to_skip, + if(rows_to_copy_now>0) { + memcpy(dest_rows, src_chunk->rows+offset, sizeof(Chunk::Row)*rows_to_copy_now); - else - rows_left_to_skip-=src_count; + if(!(limit-=rows_to_copy_now)) + break; + } else + offset-=src_count; dest_rows+=rows_to_copy_now; - rows_left_to_copy-=src_count; src_chunk=next_chunk; } else { // the last source chunk - // taking only those rows of chunk that _left_to_copy - int rows_to_copy_now=rows_left_to_copy-rows_left_to_skip; if(rows_to_copy_now>0) - memcpy(dest_rows, src_chunk->rows+rows_left_to_skip, + memcpy(dest_rows, src_chunk->rows+offset, sizeof(Chunk::Row)*rows_to_copy_now); break; } } - append_here+=src_rows_to_copy; - fused_rows+=src_rows_to_copy; return *this; }