Diff for /parser3/src/main/pa_string.C between versions 1.31 and 1.43

version 1.31, 2001/02/22 12:43:55 version 1.43, 2001/03/18 20:31:27
Line 1 Line 1
 /*  /*
   $Id$          Parser
           Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
           Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
   
           $Id$
 */  */
   
 #include <string.h>  #include <string.h>
Line 11 Line 15
   
 // String  // String
   
 String::String(Pool& apool) :  String::String(Pool& apool, const char *src, bool tainted) :
         Pooled(apool) {          Pooled(apool) {
         last_chunk=&head;          last_chunk=&head;
         head.count=CR_PREALLOCATED_COUNT;          head.count=CR_PREALLOCATED_COUNT;
Line 19  String::String(Pool& apool) : Line 23  String::String(Pool& apool) :
         head.preallocated_link=0;          head.preallocated_link=0;
         link_row=&head.rows[head.count];          link_row=&head.rows[head.count];
         fused_rows=fsize=0;          fused_rows=fsize=0;
   
           if(src)
                   if(tainted)
                           APPEND_TAINTED(src, 0, 0, 0);
                   else
                           APPEND(src, 0, 0, 0);
 }  }
   
 void String::expand() {  void String::expand() {
Line 32  void String::expand() { Line 42  void String::expand() {
         link_row->link=0;          link_row->link=0;
 }  }
   
 String::String(const String& src) :  String::String(const String& src) :     Pooled(src.pool()) {
         Pooled(src.pool()) {  
         head.count=CR_PREALLOCATED_COUNT;          head.count=CR_PREALLOCATED_COUNT;
                   
         int src_used_rows=src.used_rows();          int src_used_rows=src.used_rows();
Line 90  String::String(const String& src) : Line 99  String::String(const String& src) :
         fsize=src.fsize;          fsize=src.fsize;
 }  }
   
 String& String::operator += (const String& src) {  String& String::append(const String& src, Untaint_lang lang, bool forced) {
         int src_used_rows=src.used_rows();          int src_used_rows=src.used_rows();
         int dst_free_rows=link_row-append_here;          int dst_free_rows=link_row-append_here;
                   
         if(src_used_rows<=dst_free_rows) {          if(src_used_rows<=dst_free_rows) {
                 // all new rows fit into last chunk                  // all new rows fit into last chunk
                 memcpy(append_here, src.head.rows, sizeof(Chunk::Row)*src_used_rows);                  memcpy(append_here, src.head.rows, sizeof(Chunk::Row)*src_used_rows);
                   set_lang(append_here, lang, forced, src_used_rows);
                 append_here+=src_used_rows;                  append_here+=src_used_rows;
         } else {          } else {
                 // not all new rows fit into last chunk: shrinking it to used part,                  // not all new rows fit into last chunk: shrinking it to used part,
Line 121  String& String::operator += (const Strin Line 131  String& String::operator += (const Strin
                                 // not last source chunk                                  // not last source chunk
                                 // taking it all                                  // taking it all
                                 memcpy(new_rows, old_chunk->rows, sizeof(Chunk::Row)*old_count);                                  memcpy(new_rows, old_chunk->rows, sizeof(Chunk::Row)*old_count);
                                   set_lang(new_rows, lang, forced, old_count);
                                 new_rows+=old_count;                                  new_rows+=old_count;
                                 rows_left_to_copy-=old_count;                                  rows_left_to_copy-=old_count;
   
Line 129  String& String::operator += (const Strin Line 140  String& String::operator += (const Strin
                                 // the last source chunk                                  // the last source chunk
                                 // taking only those rows of chunk that _left_to_copy                                  // taking only those rows of chunk that _left_to_copy
                                 memcpy(new_rows, old_chunk->rows, sizeof(Chunk::Row)*rows_left_to_copy);                                  memcpy(new_rows, old_chunk->rows, sizeof(Chunk::Row)*rows_left_to_copy);
                                   set_lang(new_rows, lang, forced, rows_left_to_copy);
                                 break;                                  break;
                         }                          }
                 }                  }
Line 139  String& String::operator += (const Strin Line 151  String& String::operator += (const Strin
   
         return *this;          return *this;
 }  }
   void String::set_lang(Chunk::Row *row, Untaint_lang lang, bool forced, size_t size) {
           if(lang==PASS_APPENDED)
                   return;
   
           while(size--) {
                   Untaint_lang& item_lang=(row++)->item.lang;
                   if(item_lang==YES || forced) // tainted? need untaint language assignment
                           item_lang=lang;  // assign untaint language
           }
   }
   
   /*void String::change_lang(Untaint_lang lang) {
           Chunk *chunk=&head; 
           do {
                   Chunk::Row *row=chunk->rows;
                   for(int i=0; i<chunk->count; i++) {
                           if(row==append_here)
                                   goto break2;
   
                           row->item.lang=lang;
                           row++;
                   }
                   chunk=row->link;
           } while(chunk);
   break2:
           return;
   }
   */
 String& String::real_append(STRING_APPEND_PARAMS) {  String& String::real_append(STRING_APPEND_PARAMS) {
         if(!src)          if(!src)
                 return *this;                  return *this;
Line 153  String& String::real_append(STRING_APPEN Line 192  String& String::real_append(STRING_APPEN
   
         append_here->item.ptr=src;          append_here->item.ptr=src;
         fsize+=append_here->item.size=size;          fsize+=append_here->item.size=size;
           append_here->item.lang=tainted?YES:NO;
 #ifndef NO_STRING_ORIGIN  #ifndef NO_STRING_ORIGIN
         append_here->item.origin.file=file;          append_here->item.origin.file=file;
         append_here->item.origin.line=line;          append_here->item.origin.line=line;
Line 162  String& String::real_append(STRING_APPEN Line 202  String& String::real_append(STRING_APPEN
         return *this;          return *this;
 }  }
   
 char *String::cstr() const {  
         char *result=static_cast<char *>(malloc(size()+1));  
   
         char *copy_here=result;  
         const Chunk *chunk=&head;   
         do {  
                 const Chunk::Row *row=chunk->rows;  
                 for(int i=0; i<chunk->count; i++) {  
                         if(row==append_here)  
                                 goto break2;  
   
                         memcpy(copy_here, row->item.ptr, row->item.size);  
                         copy_here+=row->item.size;  
                         row++;  
                 }  
                 chunk=row->link;  
         } while(chunk);  
 break2:  
         *copy_here=0;  
         return result;  
 }  
   
 uint String::hash_code() const {  uint String::hash_code() const {
         uint result=0;          uint result=0;
   
Line 203  break2: Line 221  break2:
         return result;          return result;
 }  }
   
 bool String::operator == (const String& src) const {  int String::cmp(const String& src) const {
         if(size() != src.size())  
                 return false;  
   
         const Chunk *a_chunk=&head;          const Chunk *a_chunk=&head;
         const Chunk *b_chunk=&src.head;          const Chunk *b_chunk=&src.head;
         const Chunk::Row *a_row=a_chunk->rows;          const Chunk::Row *a_row=a_chunk->rows;
Line 219  bool String::operator == (const String& Line 234  bool String::operator == (const String&
         int b_countdown=b_chunk->count;          int b_countdown=b_chunk->count;
         bool a_break=false;          bool a_break=false;
         bool b_break=false;          bool b_break=false;
           int result;
         while(true) {          while(true) {
                   a_break=a_row==a_end;
                   b_break=b_row==b_end;
                   if(a_break || b_break)
                           break;
   
                 int size_diff=                  int size_diff=
                         (a_row->item.size-a_offset)-                          (a_row->item.size-a_offset)-
                         (b_row->item.size-b_offset);                          (b_row->item.size-b_offset);
   
                 if(size_diff==0) { // a has same size as b                  if(size_diff==0) { // a has same size as b
                         if(memcmp(a_row->item.ptr+a_offset, b_row->item.ptr+b_offset, a_row->item.size-a_offset)!=0)                          result=memcmp(a_row->item.ptr+a_offset, b_row->item.ptr+b_offset, a_row->item.size-a_offset);
                                 return false;                          if(result)
                                   return result;
                         a_row++; a_countdown--; a_offset=0;                          a_row++; a_countdown--; a_offset=0;
                         b_row++; b_countdown--; b_offset=0;                          b_row++; b_countdown--; b_offset=0;
                 } else if (size_diff>0) { // a longer                  } else if (size_diff>0) { // a longer
                         if(memcmp(a_row->item.ptr+a_offset, b_row->item.ptr+b_offset, b_row->item.size-b_offset)!=0)                          result=memcmp(a_row->item.ptr+a_offset, b_row->item.ptr+b_offset, b_row->item.size-b_offset);
                                 return false;                          if(result)
                                   return result;
                         a_offset+=b_row->item.size-b_offset;                          a_offset+=b_row->item.size-b_offset;
                         b_row++; b_countdown--; b_offset=0;                          b_row++; b_countdown--; b_offset=0;
                 } else { // b longer                  } else { // b longer
                         if(memcmp(a_row->item.ptr+a_offset, b_row->item.ptr+b_offset, a_row->item.size-a_offset)!=0)                          result=memcmp(a_row->item.ptr+a_offset, b_row->item.ptr+b_offset, a_row->item.size-a_offset);
                                 return false;                          if(result)
                                   return result;
                         b_offset+=a_row->item.size-a_offset;                          b_offset+=a_row->item.size-a_offset;
                         a_row++; a_countdown--; a_offset=0;                          a_row++; a_countdown--; a_offset=0;
                 }                  }
   
                 a_break=a_row==a_end;  
                 b_break=b_row==b_end;  
                 if(a_break || b_break)  
                         break;  
   
                 if(!a_countdown) {                  if(!a_countdown) {
                         a_chunk=a_row->link;                          a_chunk=a_row->link;
                         a_row=a_chunk->rows;                          a_row=a_chunk->rows;
Line 257  bool String::operator == (const String& Line 276  bool String::operator == (const String&
                         b_countdown=b_chunk->count;                          b_countdown=b_chunk->count;
                 }                  }
         }          }
         return a_break==b_break;          if(a_break==b_break) // ended simultaneously
                   result=0;
           else if(a_break) // first bytes equal, but a ended before b
                   result=-1;
           else
                   result=+1;
           return result;
 }  }
   
 bool String::operator == (char* b_ptr) const {  bool String::operator == (const char* b_ptr) const {
         size_t b_size=b_ptr?strlen(b_ptr):0;          size_t b_size=b_ptr?strlen(b_ptr):0;
         if(size() != b_size)          if(size() != b_size)
                 return false;                  return false;

Removed from v.1.31  
changed lines
  Added in v.1.43


E-mail: