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

Generated on Wed Sep 24 21:27:32 2008 for Barry by  doxygen 1.5.1