COOPY » Guide  version 0.6.5
/home/paulfitz/cvs/coopy_scm/coopy/src/libcoopy_core/DataSheet.cpp
Go to the documentation of this file.
00001 
00002 #include <coopy/DataSheet.h>
00003 #include <coopy/Sha1Generator.h>
00004 #include <coopy/SheetSchema.h>
00005 
00006 using namespace coopy::store;
00007 
00008 DataSheet::~DataSheet() {
00009   setMeta(NULL);
00010 }
00011 
00012 SheetSchema *DataSheet::getMeta() const {
00013   //printf("Meta data? %ld %s\n", (long int) this, meta_hint?"yes":"no");
00014   return meta_hint;
00015 }
00016 
00017 
00018 void DataSheet::setMeta(SheetSchema *hint) {
00019   if (meta_hint) {
00020     delete meta_hint;
00021     meta_hint = NULL;
00022   }
00023   meta_hint = hint;
00024   /*
00025   if (hint) {
00026     printf("Set some meta data! %ld %s\n", 
00027            (long int) this,
00028            hint->toString().c_str());
00029   }
00030   */
00031 }
00032 
00033 std::string DataSheet::encode(const SheetStyle& style) const {
00034   std::string delim = style.getDelimiter();
00035   std::string eol = style.getEol();
00036   std::string result = "";
00037   int last = height()-1;
00038   for (int y=0;y<height();y++) {
00039     std::string line = "";
00040     for (int x=0;x<width();x++) {
00041       if (x>0) {
00042         line += delim;
00043       }
00044       line += encodeCell(cellSummary(x,y),style);
00045     }
00046     int len = line.length();
00047     if (style.shouldEolAtEof()||y!=last) {
00048       line += eol;
00049     }
00050     if (style.shouldMarkHeader()) {
00051       SheetSchema *schema = getSchema();
00052       if (schema!=NULL) {
00053         if (schema->headerHeight()>=0) {
00054           if (schema->headerHeight()==y) {
00055             if (len<3) len = 3;
00056             if (len>79) len = 79;
00057             for (int i=0; i<len; i++) {
00058               line += '-';
00059             }
00060             line += eol;
00061           }
00062         }
00063       }
00064     }
00065     result += line;
00066   }
00067   return result;
00068 }
00069 
00070 std::string DataSheet::encodeCell(const SheetCell& c, 
00071                                   const SheetStyle& style) {
00072   std::string str = c.text;
00073   std::string delim = style.getDelimiter();
00074   bool need_quote = false;
00075   for (size_t i=0; i<str.length(); i++) {
00076     char ch = str[i];
00077     if (ch=='"'||ch=='\''||ch==delim[0]||ch=='\r'||ch=='\n'||ch=='\t'||ch==' ') {
00078       need_quote = true;
00079       break;
00080     }
00081   }
00082   std::string nil = style.getNullToken();
00083   /*
00084   if (str==nil) {
00085     need_quote = !c.escaped;
00086   }
00087   */
00088   //printf("encoding [%s] [%d]\n", str.c_str(), c.escaped);
00089   if (str=="" && c.escaped) {
00090     if (style.haveNullToken()) {
00091       return style.getNullToken();
00092     }
00093   }
00094   std::string result = "";
00095   if (!c.escaped) {
00096     if (style.quoteCollidingText()) {
00097       int score = 0;
00098       for (score=0; score<(int)str.length(); score++) {
00099         if (str[score]!='_') {
00100           break;
00101         }
00102       }
00103       if (str.substr(score,str.length())==nil) {
00104         str = std::string("_") + str;
00105       }
00106     }
00107   }
00108   if (need_quote) { result += '"'; }
00109   std::string line_buf = "";
00110   for (size_t i=0; i<str.length(); i++) {
00111     char ch = str[i];
00112     if (ch=='"') {
00113       result += '"';
00114     }
00115     if (ch!='\r'&&ch!='\n') {
00116       if (line_buf.length()>0) {
00117         result += line_buf;
00118         line_buf = "";
00119       }
00120       result += ch;
00121     } else {
00122       if (style.shouldTrimEnd()) {
00123         line_buf+=ch;
00124       } else {
00125         result+=ch;
00126       }
00127     }
00128   }
00129   if (need_quote) { result += '"'; }
00130   return result;
00131 }
00132 
00133 
00134 bool DataSheet::copyData(const DataSheet& src) {
00135   if (!canWrite()) {
00136     fprintf(stderr,"Copy failed, cannot write to target\n");
00137     return false;
00138   }
00139   if (width()!=src.width()||height()!=src.height()) {
00140     if (canResize()) {
00141       resize(src.width(),src.height());
00142     }
00143   }
00144   if (width()!=src.width()||height()!=src.height()) {
00145     fprintf(stderr,"Copy failed, src and target are not the same size\n");
00146     return false;
00147   }
00148   for (int i=0; i<src.height(); i++) {
00149     for (int j=0; j<src.width(); j++) {
00150       setCell(j,i,src.getCell(j,i));
00151     }
00152   }
00153   return true;
00154 }
00155 
00156 bool DataSheet::applyRowCache(const RowCache& cache, int row, 
00157                               SheetCell *result) {
00158   //printf("Apply row %d\n", row);
00159   if (row==-1) {
00160     fprintf(stderr,"Sheet requires a row\n");
00161     return false;
00162   }
00163   while (row>=height()) {
00164     insertRow(RowRef(-1));
00165     //dbg_printf("adding row.. %d\n", height());
00166   }
00167   for (int i=0; i<(int)cache.cells.size(); i++) {
00168     if (cache.flags[i]) {
00169       //printf("SET CELL TO %s\n", cache.cells[i].toString().c_str());
00170       setCell(i,row,cache.cells[i]);
00171     }
00172   }
00173   if (result) {
00174     *result = SheetCell();
00175   }
00176   return true;
00177 }
00178 
00179 
00180 Poly<SheetRow> DataSheet::insertRow() {
00181   if (isSequential()) {
00182     Poly<SheetRow> row = insertRowOrdered(RowRef(-1));
00183     return row;
00184   }
00185   SheetRow *row = new CacheSheetRow(this);
00186   COOPY_ASSERT(row);
00187   return Poly<SheetRow>(row,true);
00188 }
00189 
00190 Poly<SheetRow> DataSheet::insertRowOrdered(const RowRef& base) {
00191   RowRef at = insertRow(base);
00192   OrderedSheetRow *row = new OrderedSheetRow(this,at.getIndex());
00193   COOPY_ASSERT(row);
00194   return Poly<SheetRow>(row,true);
00195 }
00196 
00197 std::string DataSheet::getHash(bool cache) const {
00198   DataSheet *mod = (DataSheet *)this;
00199   if (!cache) mod->hash_cache = "";
00200   if (hash_cache!="") {
00201     dbg_printf("(sha1 %ld %s %s)\n", (long int)this, hash_cache.c_str(), desc().c_str());
00202     return hash_cache;
00203   }
00204   mod->hash_cache = mod->getRawHash();
00205   if (hash_cache!="") {
00206     dbg_printf("(raw sha1 %ld %s %s)\n", (long int)this, hash_cache.c_str(), desc().c_str());
00207     return hash_cache;
00208   }
00209   dbg_printf("Computing sha1\n");
00210   Sha1Generator sha1;
00211   for (int y=0;y<height();y++) {
00212     std::string txt;
00213     for (int x=0;x<width();x++) {
00214       SheetCell cell = cellSummary(x,y);
00215       if (cell.escaped) {
00216         txt += "N";
00217       } else {
00218         txt += "X";
00219         txt += cell.text;
00220       }
00221     }
00222     sha1.add(txt);
00223   }
00224   std::string key = sha1.finish();
00225   dbg_printf("sha1 %ld %s %s\n", (long int)this, key.c_str(), desc().c_str());
00226   if (cache) {
00227     mod->hash_cache = key;
00228   }
00229   return key;
00230 }
00231 
00232 
00233 
00234 bool OrderedSheetRow::invent(int x) {
00235   dbg_printf("\n\n*** Maxes need to get cached! Hop to it! %s:%d\n\n\n", __FILE__, __LINE__);
00236   
00237   int top = -1;
00238   for (int i=0; i<sheet->height(); i++) {
00239     SheetCell v = sheet->cellSummary(x,i);
00240     int v2 = v.asInt();
00241     if (v2>top) top = v2;
00242   }
00243 
00244   return sheet->cellSummary(x,y,SheetCell(top+1));
00245 }
00246 
00247 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines