COOPY » Guide  version 0.6.5
/home/paulfitz/cvs/coopy_scm/coopy/src/libcoopy_core/CsvWrite.cpp
Go to the documentation of this file.
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 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines