COOPY » Guide
version 0.6.5
|
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