# vjournal.cc

    00001 //
    00002 // \file        vjournal.cc
    00003 //              Conversion routines for vjournals (VCALENDAR, etc)
    00004 //
    00005
    00006 /*
    00007     Copyright (C) 2008-2009, Nicolas VIVIEN
    00008     Copyright (C) 2006-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 "vjournal.h"
    00024 //#include "trace.h"
    00025 #include <stdint.h>
    00026 #include <glib.h>
    00027 #include <strings.h>
    00028 #include <sstream>
    00029
    00030 namespace Barry { namespace Sync {
    00031
    00032 //////////////////////////////////////////////////////////////////////////////
    00033 // vJournal
    00034
    00035 vJournal::vJournal()
    00036         : m_gJournalData(0)
    00037 {
    00038 }
    00039
    00040 vJournal::~vJournal()
    00041 {
    00042         if( m_gJournalData ) {
    00043                 g_free(m_gJournalData);
    00044         }
    00045 }
    00046
    00047 bool vJournal::HasMultipleVJournals() const
    00048 {
    00049         int count = 0;
    00050         b_VFormat *format = const_cast<b_VFormat*>(Format());
    00051         GList *attrs = format ? b_vformat_get_attributes(format) : 0;
    00052         for( ; attrs; attrs = attrs->next ) {
    00053                 b_VFormatAttribute *attr = (b_VFormatAttribute*) attrs->data;
    00054                 if( strcasecmp(b_vformat_attribute_get_name(attr), "BEGIN") == 0 &&
    00055                     strcasecmp(b_vformat_attribute_get_nth_value(attr, 0), "VJOURNAL") == 0 )
    00056                 {
    00057                         count++;
    00058                 }
    00059         }
    00060         return count > 1;
    00061 }
    00062
    00063
    00064 // Main conversion routine for converting from Barry::Memo to
    00065 // a vJournal string of data.
    00066 const std::string& vJournal::ToMemo(const Barry::Memo &memo)
    00067 {
    00068 //      Trace trace("vJournal::ToMemo");
    00069         std::ostringstream oss;
    00070         memo.Dump(oss);
    00071 //      trace.logf("ToMemo, initial Barry record: %s", oss.str().c_str());
    00072
    00073         // start fresh
    00074         Clear();
    00075         SetFormat( b_vformat_new() );
    00076         if( !Format() )
    00077                 throw ConvertError("resource error allocating vformat");
    00078
    00079         // store the Barry object we're working with
    00080         m_BarryMemo = memo;
    00081
    00082         // begin building vJournal data
    00083         AddAttr(NewAttr("PRODID", "-//OpenSync//NONSGML Barry Memo Record//EN"));
    00084         AddAttr(NewAttr("BEGIN", "VJOURNAL"));
    00085         AddAttr(NewAttr("SEQUENCE", "0"));
    00086         AddAttr(NewAttr("SUMMARY", memo.Title.c_str()));
    00087         AddAttr(NewAttr("DESCRIPTION", memo.Body.c_str()));
    00088         AddAttr(NewAttr("CATEGORIES", ToStringList(memo.Categories).c_str()));
    00089
    00090
    00091         // FIXME - add a truly globally unique "UID" string?
    00092
    00093         AddAttr(NewAttr("END", "VJOURNAL"));
    00094
    00095         // generate the raw VJOURNAL data
    00096         m_gJournalData = b_vformat_to_string(Format(), VFORMAT_NOTE);
    00097         m_vJournalData = m_gJournalData;
    00098
    00099 //      trace.logf("ToMemo, resulting vjournal data: %s", m_vJournalData.c_str());
    00100         return m_vJournalData;
    00101 }
    00102
    00103 // Main conversion routine for converting from vJournal data string
    00104 // to a Barry::Memo object.
    00105 const Barry::Memo& vJournal::ToBarry(const char *vjournal, uint32_t RecordId)
    00106 {
    00107         using namespace std;
    00108
    00109 //      Trace trace("vJournal::ToBarry");
    00110 //      trace.logf("ToBarry, working on vmemo data: %s", vjournal);
    00111
    00112         // we only handle vJournal data with one vmemo block
    00113         if( HasMultipleVJournals() )
    00114                 throw ConvertError("vCalendar data contains more than one VJOURNAL block, unsupported");
    00115
    00116         // start fresh
    00117         Clear();
    00118
    00119         // store the vJournal raw data
    00120         m_vJournalData = vjournal;
    00121
    00122         // create format parser structures
    00123         SetFormat( b_vformat_new_from_string(vjournal) );
    00124         if( !Format() )
    00125                 throw ConvertError("resource error allocating vjournal");
    00126
    00127         string title = GetAttr("SUMMARY", "/vjournal");
    00128 //      trace.logf("SUMMARY attr retrieved: %s", title.c_str());
    00129         if( title.size() == 0 ) {
    00130                 title = "<blank subject>";
    00131 //              trace.logf("ERROR: bad data, blank SUMMARY: %s", vjournal);
    00132         }
    00133
    00134         string body = GetAttr("DESCRIPTION", "/vjournal");
    00135 //      trace.logf("DESCRIPTION attr retrieved: %s", body.c_str());
    00136
    00137
    00138         //
    00139         // Now, run checks and convert into Barry object
    00140         //
    00141
    00142
    00143         Barry::Memo &rec = m_BarryMemo;
    00144         rec.SetIds(Barry::Memo::GetDefaultRecType(), RecordId);
    00145
    00146         rec.Title = title;
    00147         rec.Body = body;
    00148         rec.Categories = GetValueVector("CATEGORIES","/vjournal");
    00149
    00150         std::ostringstream oss;
    00151         m_BarryMemo.Dump(oss);
    00152 //      trace.logf("ToBarry, resulting Barry record: %s", oss.str().c_str());
    00153         return m_BarryMemo;
    00154 }
    00155
    00156 // Transfers ownership of m_gMemoData to the caller.
    00157 char* vJournal::ExtractVJournal()
    00158 {
    00159         char *ret = m_gJournalData;
    00160         m_gJournalData = 0;
    00161         return ret;
    00162 }
    00163
    00164 void vJournal::Clear()
    00165 {
    00166         vBase::Clear();
    00167         m_vJournalData.clear();
    00168         m_BarryMemo.Clear();
    00169
    00170         if( m_gJournalData ) {
    00171                 g_free(m_gJournalData);
    00172                 m_gJournalData = 0;
    00173         }
    00174 }
    00175
    00176 }} // namespace Barry::Sync
    00177