Diff for /parser3/src/main/pa_table.C between versions 1.10 and 1.55

version 1.10, 2001/03/10 16:34:39 version 1.55, 2003/04/14 11:22:53
Line 1 Line 1
 /*  /** @file
         Parser          Parser: table class.
         Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)  
         Author: Alexander Petrosyan <paf@design.ru>  
   
         $Id$          Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com)
           Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
 */  */
   
 #include <stdlib.h>  static const char* IDENT_TABLE_C="$Date$";
   
   //#include <stdlib.h>
   
 #include "pa_table.h"  #include "pa_table.h"
 #include "pa_pool.h"  #include "pa_pool.h"
   #include "pa_exception.h"
   
 Table::Table(Request& arequest,   Table::Table(Pool& apool, 
                          char *afile, uint aline,                            const String *aorigin_string,
                          Array *acolumns,                            const Array *acolumns, 
                          int initial_rows) :                           int initial_rows) :
         Array(arequest.pool(), initial_rows),          Array(apool, initial_rows),
         request(arequest),  
           forigin_string(aorigin_string),
         fcurrent(0),          fcurrent(0),
         fcolumns(acolumns),           fcolumns(acolumns), 
         name2number(arequest.pool(), false) {          name2number(*NEW Hash(pool())) {
 #ifndef NO_STRING_ORIGIN  
         forigin.file=afile;  
         forigin.line=aline;  
 #endif  
   
         if(fcolumns)          if(fcolumns)
                 for(int i=0; i<fcolumns->size(); i++) {                  for(int i=0; i<fcolumns->size(); i++) {
                         String name(arequest.pool());                          const String& name=*fcolumns->get_string(i);
                         name.APPEND(fcolumns->get_cstr(i), 0, 0, 0);  
                         name2number.put(name, i+1);                          name2number.put(name, i+1);
                 }                  }
 }  }
   
 const Array &Table::at(int index) {  Table::Table(Pool& apool, const Table& source, Action_options& options) :
         if(index<0 || index>=size())          Array(apool, options.limit/*may be more than needed, no harm done*/),
                 THROW(0, 0,   
                         0,          forigin_string(source.forigin_string),
                         "table row index %d is out of range [0..%d]",           fcurrent(0),
                         index, size()-1);          fcolumns(source.fcolumns),
                   name2number(source.name2number) {
         return *static_cast<const Array *>(get(index));  
 }          append_array(source, options.offset, options.limit, options.reverse);
   }
 const char *Table::item(int index) {  
         const Array& row=at(fcurrent);  int Table::column_name2index(const String& column_name, bool bark) const {
         return row.get_cstr(index);          if(fcolumns) {// named
 }                  int result=name2number.get_int(column_name)-1; // -1 = column not found
                   if(bark && result<0)
 const char *Table::item(const String& column_name) {                          throw Exception("parser.runtime",
         int column_index;                                  &column_name,
         if(fcolumns) {  
                 int found_index=name2number.get_int(column_name);  
                 if(found_index)  
                         column_index=found_index-1;  
                 else  
                         THROW(0, 0,  
                                 &column_name,   
                                 "column not found");                                  "column not found");
         } else {                  return result;
                 column_index=atoi(column_name.cstr());          } else { // nameless
                   char *error_pos;
                   const char *cstr=column_name.cstr();
                   int result=(int)strtol(cstr, &error_pos, 0);
                   if(*error_pos/*not EOS*/) {
                           result=-1;
                           if(bark)
                                   throw Exception("parser.runtime",
                                           &column_name,
                                           "invalid column number");
                   }
                   return result;
           }
   }
   
   const String *Table::item(int column) const {
           if(valid(fcurrent)) {
                 const Array& row=at(fcurrent);                  const Array& row=at(fcurrent);
                 if(column_index<0 || column_index>=row.size())                  if(column>=0 && column<row.size()) // proper index?
                         return 0;                          return row.get_string(column);
                 /*  
                         request.exception().raise(0, 0,  
                                 &column_name,   
                                 "table column index %d is out of range [0..%d]",   
                                 column_index, row->size()-1);  
                                 */  
         }          }
           return 0; // it's OK we don't have row|column, just return nothing
   }
   
   bool Table::locate(Table::locate_func func, void *info, Table::Action_options& o) {
           int size=this->size();
           int row=o.offset;
           if(!size || !o.limit || row>=size)
                   return false;
           // max(limit)
           int m=o.reverse?
                   row
                   :size-row;
           if(!m)
                   return false;
           // fix o.limit
           if(o.limit<0 || o.limit>m)
                   o.limit=m;
   
           int saved_current=current();
           if(o.reverse) { // reverse
                   int to=max(0, row-o.limit);
                   for(; row>=to; --row) {
                           set_current(row);
   
                           if(func(*this, info))
                                   return true;
                   }
           } else { // forward
                   int to=min(row+o.limit, size);
                   for(; row<to; row++) {
                           set_current(row);
   
                           if(func(*this, info))
                                   return true;
                   }
           }
           set_current(saved_current);
   
           return false;
   }
   
   #ifndef DOXYGEN
   struct Locate_int_string_info {
           int column;
           const String* value;
   };
   #endif
   bool locate_int_string(Table& self, void* ainfo) {
           Locate_int_string_info& info=*static_cast<Locate_int_string_info*>(ainfo);
   
           const String *item_value=self.item(info.column);
           return item_value && *item_value==*info.value;
   }
   
   bool Table::locate(int column, const String& value,
                      Table::Action_options& options) {
           Locate_int_string_info info={column, &value};
           return locate(locate_int_string, &info, options);
   }
   
   bool Table::locate(const String& column, const String& value, 
                      Table::Action_options& options) {
           return locate(column_name2index(column, true), value, options);
   }
   
         return item(column_index);  void Table::offset(bool absolute, int offset) {
           if(size())
                   fcurrent=((absolute?0:fcurrent)+offset+size())%size();
 }  }

Removed from v.1.10  
changed lines
  Added in v.1.55


E-mail: