# mimeio.cc

Go to the documentation of this file.

    00001 ///
    00002 /// \file       mimeio.cc
    00003 ///             Storage, parser, builder classes for MIME objects
    00004 ///             (vcard, vevent, vtodo, vjournal)
    00005 ///
    00006
    00007 /*
    00008     Copyright (C) 2010-2011, Net Direct Inc. (http://www.netdirect.ca/)
    00009
    00010     This program is free software; you can redistribute it and/or modify
    00011     it under the terms of the GNU General Public License as published by
    00012     the Free Software Foundation; either version 2 of the License, or
    00013     (at your option) any later version.
    00014
    00015     This program is distributed in the hope that it will be useful,
    00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00018
    00019     See the GNU General Public License in the COPYING file at the
    00020     root directory of this project for more details.
    00021 */
    00022
    00023 #include "mimeio.h"
    00024 #include "vcard.h"
    00025 #include "vevent.h"
    00026 #include "vtodo.h"
    00027 #include "vjournal.h"
    00028 #include <iostream>
    00029 #include <fstream>
    00030 #include <strings.h>
    00031
    00032 using namespace std;
    00033
    00034 namespace Barry {
    00035
    00036 MimeBuilder::MimeBuilder(const std::string &filename)
    00037         : m_ifs( new std::ifstream(filename.c_str()) )
    00038         , m_is(*m_ifs)
    00039 {
    00040 }
    00041
    00042 MimeBuilder::MimeBuilder(std::istream &is)
    00043         : m_is(is)
    00044 {
    00045 }
    00046
    00047 bool MimeBuilder::BuildRecord(DBData &data, size_t &offset,
    00048                                 const IConverter *ic)
    00049 {
    00050         string vrec;
    00051         vector<string> types;
    00052         while( ReadMimeRecord(m_is, vrec, types) ) {
    00053                 if( !vrec.size() ) {
    00054                         // end of file
    00055                         return false;
    00056                 }
    00057                 else if( IsMember(Sync::vCard::GetVName(), types) ) {
    00058                         Sync::vCard vcard;
    00059                         SetDBData(vcard.ToBarry(vrec.c_str(), 0),
    00060                                 data, offset, ic);
    00061                         return true;
    00062                 }
    00063                 else if( IsMember(Sync::vCalendar::GetVName(), types) ) {
    00064                         Sync::vTimeConverter vtc;
    00065                         Sync::vCalendar vcal(vtc);
    00066                         SetDBData(vcal.ToBarry(vrec.c_str(), 0),
    00067                                 data, offset, ic);
    00068                         return true;
    00069                 }
    00070                 else if( IsMember(Sync::vTodo::GetVName(), types) ) {
    00071                         Sync::vTimeConverter vtc;
    00072                         Sync::vTodo vtodo(vtc);
    00073                         SetDBData(vtodo.ToBarry(vrec.c_str(), 0),
    00074                                 data, offset, ic);
    00075                         return true;
    00076                 }
    00077                 else if( IsMember(Sync::vJournal::GetVName(), types) ) {
    00078                         Sync::vJournal vjournal;
    00079                         SetDBData(vjournal.ToBarry(vrec.c_str(), 0),
    00080                                 data, offset, ic);
    00081                         return true;
    00082                 }
    00083                 else {
    00084                         // read the next one
    00085                 }
    00086         }
    00087
    00088         // end of file
    00089         return false;
    00090 }
    00091
    00092 bool MimeBuilder::FetchRecord(DBData &data, const IConverter *ic)
    00093 {
    00094         size_t offset = 0;
    00095         return BuildRecord(data, offset, ic);
    00096 }
    00097
    00098 bool MimeBuilder::EndOfFile() const
    00099 {
    00100         return !m_is;
    00101 }
    00102
    00103 // return false at end of file, true if a record was read
    00104 bool MimeBuilder::ReadMimeRecord(std::istream &is, std::string &vrec,
    00105                                 std::vector<std::string> &types)
    00106 {
    00107         vrec.clear();
    00108         types.clear();
    00109
    00110         string line;
    00111
    00112         // ignore whitespace
    00113         while( getline(is, line) ) {
    00114                 if( strcasecmp(line.substr(0, 6).c_str(), "BEGIN:") == 0 ) {
    00115                         vrec += line;
    00116                         vrec += "\n";
    00117                         types.push_back(line.substr(6));
    00118                         break;
    00119                 }
    00120         }
    00121
    00122         if( !vrec.size() )
    00123                 return false;
    00124
    00125         // load until end
    00126         int count = 0;
    00127         while( getline(is, line) ) {
    00128                 // end on blank lines
    00129                 if( !line.size() )
    00130                         return true;
    00131
    00132                 vrec += line;
    00133                 vrec += "\n";
    00134
    00135                 // pick up innermost BEGIN line
    00136                 if( strcasecmp(line.substr(0, 6).c_str(), "BEGIN:") == 0 ) {
    00137                         string type = line.substr(6);
    00138                         while( type.size() && type[type.size()-1] == '\r' ) {
    00139                                 type = type.substr(0, type.size()-1);
    00140                         }
    00141                         types.push_back(type);
    00142                 }
    00143
    00144                 // place an upper limit on the number of lines...
    00145                 // since a MIME data block shouldn't be more than
    00146                 // a few pages of lines!
    00147                 count++;
    00148                 if( count > 200 )
    00149                         return false;
    00150         }
    00151         // assume that end of file is the same as "blank line"
    00152         return true;
    00153 }
    00154
    00155 bool MimeBuilder::IsMember(const std::string &item,
    00156                         const std::vector<std::string> &types)
    00157 {
    00158         std::vector<std::string>::const_iterator i = types.begin();
    00159         for( ; i != types.end(); ++i ) {
    00160                 if( strcasecmp(i->c_str(), item.c_str()) == 0 )
    00161                         return true;
    00162         }
    00163         return false;
    00164 }
    00165
    00166 } // namespace Barry
    00167