00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
00039
00040
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
00070 begin += COMMON_FIELD_HEADER_SIZE + btohs(field->size);
00071 if( begin > end )
00072 return begin;
00073
00074 if( !btohs(field->size) )
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
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;
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
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
00113 return begin;
00114 }
00115
00116 void Memo::ParseHeader(const Data &data, size_t &offset)
00117 {
00118
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 }
00153