r_memo.cc

Go to the documentation of this file.
00001 ///
00002 /// \file       r_memo.cc
00003 ///             Record parsing class for the memo database.
00004 ///
00005 
00006 /*
00007     Copyright (C) 2005-2009, Net Direct Inc. (http://www.netdirect.ca/)
00008     Copyright (C) 2007, Brian Edginton
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 "r_memo.h"
00024 #include "record-internal.h"
00025 #include "protostructs.h"
00026 #include "data.h"
00027 #include "time.h"
00028 #include "iconv.h"
00029 #include <ostream>
00030 #include <iomanip>
00031 
00032 using namespace std;
00033 using namespace Barry::Protocol;
00034 
00035 namespace Barry {
00036 
00037 ///////////////////////////////////////////////////////////////////////////////
00038 // Memo Class
00039 
00040 // Memo Field Codes
00041 #define MEMFC_TITLE             0x01
00042 #define MEMFC_BODY              0x02
00043 #define MEMFC_MEMO_TYPE         0x03
00044 #define MEMFC_CATEGORY          0x04
00045 #define MEMFC_END               0xffff
00046 
00047 static FieldLink<Memo> MemoFieldLinks[] = {
00048     { MEMFC_TITLE,     "Title",       0, 0, &Memo::Title, 0, 0, 0, 0, true },
00049     { MEMFC_BODY,      "Body",        0, 0, &Memo::Body, 0, 0, 0, 0, true },
00050     { MEMFC_CATEGORY,  "Category",    0, 0, &Memo::Category, 0, 0, 0, 0, true },
00051     { MEMFC_END,       "End of List", 0, 0, 0, 0, 0, 0, 0, false }
00052 };
00053 
00054 Memo::Memo()
00055 {
00056         Clear();
00057 }
00058 
00059 Memo::~Memo()
00060 {
00061 }
00062 
00063 const unsigned char* Memo::ParseField(const unsigned char *begin,
00064                                       const unsigned char *end,
00065                                       const IConverter *ic)
00066 {
00067         const CommonField *field = (const CommonField *) begin;
00068 
00069         // advance and check size
00070         begin += COMMON_FIELD_HEADER_SIZE + btohs(field->size);
00071         if( begin > end )       // if begin==end, we are ok
00072                 return begin;
00073 
00074         if( !btohs(field->size) )   // if field has no size, something's up
00075                 return begin;
00076 
00077         if( field->type == MEMFC_MEMO_TYPE ) {
00078                 if( ( MemoType = field->u.raw[0] ) != 'm' ) {
00079                         throw Error( "Memo::ParseField: MemoType is not 'm'" );
00080                 }
00081         return begin;
00082         }
00083 
00084 
00085         // cycle through the type table
00086         for(    FieldLink<Memo> *b = MemoFieldLinks;
00087                 b->type != MEMFC_END;
00088                 b++ )
00089         {
00090                 if( b->type == field->type ) {
00091                         if( b->strMember ) {
00092                                 std::string &s = this->*(b->strMember);
00093                                 s = ParseFieldString(field);
00094                                 if( b->iconvNeeded && ic )
00095                                         s = ic->FromBB(s);
00096                                 return begin;   // done!
00097                         }
00098                         else if( b->timeMember && btohs(field->size) == 4 ) {
00099                                 time_t &t = this->*(b->timeMember);
00100                                 t = min2time(field->u.min1900);
00101                                 return begin;
00102                         }
00103                 }
00104         }
00105 
00106         // if still not handled, add to the Unknowns list
00107         UnknownField uf;
00108         uf.type = field->type;
00109         uf.data.assign((const char*)field->u.raw, btohs(field->size));
00110         Unknowns.push_back(uf);
00111 
00112         // return new pointer for next field
00113         return begin;
00114 }
00115 
00116 void Memo::ParseHeader(const Data &data, size_t &offset)
00117 {
00118         // no header in Memo records
00119 }
00120 
00121 void Memo::ParseFields(const Data &data, size_t &offset, const IConverter *ic)
00122 {
00123         const unsigned char *finish = ParseCommonFields(*this,
00124                 data.GetData() + offset, data.GetData() + data.GetSize(), ic);
00125         offset += finish - (data.GetData() + offset);
00126 }
00127 
00128 
00129 void Memo::Dump(std::ostream &os) const
00130 {
00131         os << "Memo entry: 0x" << setbase(16) << RecordId
00132            << " (" << (unsigned int)RecType << ")\n";
00133         os << "    Title: " << Title << "\n";
00134         os << "    Body: " << Body << "\n";
00135         os << "    Category: " << Category << "\n";
00136 
00137         os << Unknowns;
00138         os << "\n\n";
00139 }
00140 
00141 void Memo::Clear()
00142 {
00143         Title.clear();
00144         Body.clear();
00145         Category.clear();
00146 
00147         MemoType = 0;
00148 
00149         Unknowns.clear();
00150 }
00151 
00152 } // namespace Barry
00153 

Generated on Mon Jan 12 10:51:13 2009 for Barry by  doxygen 1.5.7.1