Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifdef HAVE_CONFIG_H
00032 # include <config.h>
00033 #endif
00034
00035 #ifdef HAVE_UNISTD_H
00036 # include <unistd.h>
00037 #endif
00038
00039 #ifdef HAVE_STRING_H
00040 # include <string.h>
00041 #endif
00042
00043 #ifdef HAVE_STDIO_H
00044 # include <stdio.h>
00045 #endif
00046
00047 #ifdef HAVE_IOSTREAM
00048 # include <iostream>
00049 #endif
00050
00051 #ifdef HAVE_FSTREAM
00052 # include <fstream>
00053 #endif
00054
00055 #include "csvimport.h"
00056 #include <structs.h>
00057 #include <file.h>
00058
00066 void
00067 CSVImport::cleanupValue (std::string& str) {
00068 if (str.length() == 0) return;
00069
00070 if (str.at (0) == '"')
00071 str = str.erase (0, 1);
00072
00073 if (str.at (str.length() - 1) == '"')
00074 str = str.erase (str.length() - 1, 1);
00075
00076 std::string::size_type pos = 0;
00077
00078 while ( ( pos = str.find ("\"\"", pos) ) != std::string::npos ) {
00079 str.erase (pos, 1);
00080
00081 if (pos + 1 < str.length() )
00082 pos++;
00083 }
00084 }
00085
00093 void
00094 CSVImport::logError (unsigned long lno, const std::string& errmsg) {
00095 if (verbose) {
00096 std::cout << 'e';
00097 std::cout.flush();
00098 }
00099
00100 LogEntry tmp;
00101 tmp.lineno = lno;
00102 tmp.message = errmsg;
00103 logs.push_back (tmp);
00104 had_errors = true;
00105 num_errors++;
00106 }
00107
00121 CSVImport::CSVImport (std::string src, std::string dst, char sep, bool verb) throw (std::runtime_error) :
00122 srcfile (src),
00123 dstfile (dst),
00124 separator (sep),
00125 verbose (verb),
00126 had_errors (false),
00127 num_errors (0) {
00128 if (access (srcfile.c_str(), R_OK | F_OK) == -1)
00129 throw std::runtime_error ("Cannot access " + srcfile);
00130 }
00131
00137 void
00138 CSVImport::import (const char* pw) throw (std::exception) {
00139 std::ifstream csvfile (srcfile.c_str() );
00140
00141 if (!csvfile)
00142 throw std::runtime_error ("Cannot open " + srcfile);
00143
00144
00145
00146 const int max_len = YAPET::NAME_SIZE +
00147 YAPET::HOST_SIZE +
00148 YAPET::USERNAME_SIZE +
00149 YAPET::PASSWORD_SIZE +
00150 YAPET::COMMENT_SIZE +
00151
00152 NUM_SEPARATORS;
00153
00154 const unsigned int num_fields = NUM_SEPARATORS + 1;
00155 char num_fields_str[5];
00156 snprintf (num_fields_str, 5, "%u", num_fields);
00157 YAPET::Key key (pw);
00158 YAPET::File yapetfile (dstfile, key, true);
00159 std::list<YAPET::PartDec> list;
00160 char line[max_len];
00161
00162 unsigned long lineno = 0;
00163
00164 bool inquote = false;
00165
00166 std::string field_values[num_fields];
00167
00168 int current_field = 0;
00169
00170 int num_sep_found = 0;
00171
00172 std::string::size_type it = 0;
00173
00174 while (csvfile.getline (line, max_len) ) {
00175 lineno++;
00176 std::string l (line);
00177
00178 std::string::size_type last_sep = 0;
00179
00180 if (!inquote) {
00181 current_field = 0;
00182 num_sep_found = 0;
00183
00184 for (unsigned int i = 0; i < num_fields; i++)
00185 field_values[i].clear();
00186 }
00187
00188
00189 bool scan_error = false;
00190
00191 for (it = 0; it < l.length(); it++) {
00192
00193 if (l.at (it) == '"') {
00194 inquote = !inquote;
00195 }
00196
00197 if (!inquote && (l.at (it) == separator) ) {
00198 num_sep_found++;
00199
00200 if (num_sep_found > NUM_SEPARATORS) {
00201 std::string tmp ("Too many fields. Expected ");
00202 tmp += num_fields_str;
00203 tmp += " fields.";
00204 logError (lineno, tmp );
00205 scan_error = true;
00206 break;
00207 }
00208
00209 field_values[current_field] = l.substr (last_sep, it - last_sep);
00210 cleanupValue (field_values[current_field]);
00211 last_sep = it + 1;
00212 current_field++;
00213 }
00214 }
00215
00216 if (scan_error) continue;
00217
00218
00219
00220 if (it > last_sep) {
00221 field_values[current_field] = l.substr (last_sep, it - last_sep);
00222 cleanupValue (field_values[current_field]);
00223 }
00224
00225 if (!inquote && (num_sep_found < NUM_SEPARATORS) ) {
00226 std::string tmp ("Too few fields. Expected ");
00227 tmp += num_fields_str;
00228 tmp += " fields.";
00229 logError (lineno, tmp );
00230 continue;
00231 }
00232
00233 if (!inquote && (num_sep_found == NUM_SEPARATORS) ) {
00234 YAPET::Record<YAPET::PasswordRecord> record;
00235 YAPET::PasswordRecord *ptr_rec = record;
00236 strncpy ( (char*) ptr_rec->name, field_values[0].c_str(), YAPET::NAME_SIZE);
00237 strncpy ( (char*) ptr_rec->host, field_values[1].c_str(), YAPET::HOST_SIZE);
00238 strncpy ( (char*) ptr_rec->username, field_values[2].c_str(), YAPET::USERNAME_SIZE);
00239 strncpy ( (char*) ptr_rec->password, field_values[3].c_str(), YAPET::PASSWORD_SIZE);
00240 strncpy ( (char*) ptr_rec->comment, field_values[4].c_str(), YAPET::COMMENT_SIZE);
00241 list.push_back (YAPET::PartDec (record, key) );
00242
00243 if (verbose) {
00244 std::cout << ".";
00245 std::cout.flush();
00246 }
00247 }
00248 }
00249
00250 if (verbose) std::cout << std::endl;
00251
00252 yapetfile.save (list);
00253 csvfile.close();
00254 }
00255
00259 void
00260 CSVImport::printLog() const {
00261 if (logs.size() == 0) return;
00262
00263 std::list<LogEntry>::const_iterator it = logs.begin();
00264
00265 while (it != logs.end() ) {
00266 std::cout << "Line " << (*it).lineno << ": " << (*it).message << std::endl;
00267 it++;
00268 }
00269 }