COOPY » Guide
version 0.6.5
|
00001 #include <stdio.h> 00002 #include <stdlib.h> 00003 00004 #include <coopy/CsvWrite.h> 00005 #include <coopy/CsvSheet.h> 00006 #include <coopy/NameSniffer.h> 00007 00008 using namespace coopy::store; 00009 using namespace coopy::cmp; 00010 using namespace std; 00011 00012 int CsvFile::write(const DataSheet& src, const char *fname) { 00013 Property p; 00014 p.put("file",fname); 00015 return write(src,p); 00016 } 00017 00018 static int write(const DataSheet& src, const Property& config, 00019 string *output) { 00020 dbg_printf("Writing a %dx%d csv file: options %s\n", src.width(), src.height(), 00021 config.toString().c_str()); 00022 std::string fname = config.get("file",PolyValue::makeString("-")).asString(); 00023 SheetStyle style; 00024 FILE *fp = NULL; 00025 if (!output) { 00026 if (fname=="-") { 00027 fp = stdout; 00028 //SheetStyle style; 00029 //std::string result = src.encode(style); 00030 //printf("%s",result.c_str()); 00031 } else { 00032 bool append = config.get("append", 00033 PolyValue::makeBoolean(false)).asBoolean(); 00034 fp = fopen(fname.c_str(),append?"ab":"wb"); 00035 if (!fp) { 00036 fprintf(stderr,"CsvFile: could not open %s\n", fname.c_str()); 00037 exit(1); 00038 } 00039 style.setFromFilename(fname.c_str()); 00040 } 00041 } 00042 style.setFromProperty(config); 00043 bool wantHeader = true; 00044 bool wantFakeHeader = false; 00045 if (config.check("header")) { 00046 int n = config.get("header").asInt(); 00047 if (n<0) { 00048 wantHeader = false; 00049 } else { 00050 wantFakeHeader = true; 00051 } 00052 } 00053 bool markHeader = config.get("mark_header", 00054 PolyValue::makeBoolean(false)).asBoolean(); 00055 if (wantHeader) { 00056 CompareFlags flags; 00057 NameSniffer sniffer(src,flags); 00058 if (!sniffer.isEmbedded()) { 00059 if (wantFakeHeader||!sniffer.isFake()) { 00060 CsvSheet header; 00061 header.resize(src.width(),1,""); 00062 for (int i=0; i<src.width(); i++) { 00063 header.cell(i,0) = sniffer.suggestColumnName(i); 00064 } 00065 bool skip_header = false; 00066 if (!markHeader) { 00067 int matches = 0; 00068 for (int j=0; j<src.width(); j++) { 00069 for (int k=0; k<3&&k<src.height(); k++) { 00070 string alt = src.cellString(j,k); 00071 if (alt==header.cellString(j,0)) { 00072 matches++; 00073 break; 00074 } 00075 } 00076 } 00077 dbg_printf("inplace column name matches: %d of %d\n", matches, 00078 src.width()); 00079 if (matches>=1 && matches>=src.width()*0.75) { 00080 skip_header = true; 00081 } 00082 } 00083 std::string result = ""; 00084 if (!skip_header) { 00085 result = header.encode(style); 00086 if (markHeader) { 00087 int len = result.length(); 00088 len--; 00089 while (len>0 && result[len-1]=='\r') { 00090 len--; 00091 } 00092 if (len<4) len = 4; 00093 if (len>79) len = 79; 00094 for (int i=0; i<len; i++) { 00095 result += '-'; 00096 } 00097 result += "\r\n"; 00098 style.setMarkHeader(false); 00099 } 00100 } 00101 if (fp) { 00102 fwrite(result.c_str(),1,result.length(),fp); 00103 } else { 00104 *output += result; 00105 } 00106 } 00107 } 00108 } 00109 00110 std::string result = src.encode(style); 00111 if (fp) { 00112 fwrite(result.c_str(),1,result.length(),fp); 00113 if (fp!=stdout) { 00114 fclose(fp); 00115 fp = NULL; 00116 } 00117 } else { 00118 *output += result; 00119 } 00120 return 0; 00121 } 00122 00123 00124 int CsvFile::write(const DataSheet& src, const Property& config) { 00125 return ::write(src,config,NULL); 00126 } 00127 00128 string CsvFile::writeString(const DataSheet& src, const Property& config) { 00129 string result; 00130 int r = ::write(src,config,&result); 00131 return result; 00132 }