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_folder.h"
00024 #include "record-internal.h"
00025 #include "protostructs.h"
00026 #include "data.h"
00027 #include "time.h"
00028 #include "debug.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
00042 #define FFC_NUMBER 0x0a
00043 #define FFC_LEVEL 0x0b
00044 #define FFC_NAME 0x0c
00045 #define FFC_ADDRESS1 0x0d
00046 #define FFC_ADDRESS2 0x0e
00047 #define FFC_TYPE 0x0f
00048 #define FFC_END 0xffff
00049
00050
00051 #define SUBTREE 0x00
00052 #define DELETED 0x01
00053 #define INBOX 0x02
00054 #define OUTBOX 0x03
00055 #define SENT 0x04
00056 #define OTHER 0x05
00057 #define DRAFT 0x0a
00058
00059
00060 #define ORPHAN 0x50
00061 #define UNFILED 0x51
00062 #define FILED 0x52
00063
00064 #define INVALID -1
00065
00066 #define SEPARATOR 0x2f
00067 #define ROOT_SEPARATOR 0x3a
00068
00069 FieldLink<Folder> FolderFieldLinks[] = {
00070 { FFC_NAME, "FolderName", 0, 0, &Folder::FolderName, 0, 0 },
00071 { FFC_END, "End of List", 0, 0, 0, 0, 0 },
00072 };
00073
00074 Folder::Folder()
00075 {
00076 Clear();
00077 }
00078
00079
00080 Folder::~Folder()
00081 {
00082 }
00083
00084 const unsigned char* Folder::ParseField(const unsigned char *begin,
00085 const unsigned char *end)
00086 {
00087 const CommonField *field = (const CommonField *) begin;
00088
00089
00090 begin += COMMON_FIELD_HEADER_SIZE + btohs(field->size);
00091 if( begin > end )
00092 return begin;
00093
00094 if( !btohs(field->size) )
00095 return begin;
00096
00097
00098 for( FieldLink<Folder> *b = FolderFieldLinks;
00099 b->type != FFC_END;
00100 b++ )
00101 {
00102 if( b->type == field->type ) {
00103 if( b->strMember ) {
00104 std::string &s = this->*(b->strMember);
00105 s = ParseFieldString(field);
00106 return begin;
00107 }
00108 else if( b->timeMember && btohs(field->size) == 4 ) {
00109 time_t &t = this->*(b->timeMember);
00110 t = min2time(field->u.min1900);
00111 return begin;
00112 }
00113 }
00114 }
00115
00116 switch( field->type )
00117 {
00118 case FFC_TYPE:
00119 FolderType = (FolderTypeEnum)field->u.raw[0];
00120 return begin;
00121 case FFC_NUMBER:
00122 FolderNumber = field->u.raw[0];
00123 return begin;
00124 case FFC_LEVEL:
00125 FolderLevel = field->u.raw[0];
00126 return begin;
00127 }
00128
00129
00130 UnknownField uf;
00131 uf.type = field->type;
00132 uf.data.assign((const char*)field->u.raw, btohs(field->size));
00133 Unknowns.push_back(uf);
00134
00135
00136 return begin;
00137 }
00138
00139 void Folder::ParseHeader(const Data &data, size_t &offset)
00140 {
00141
00142 }
00143
00144 void Folder::ParseFields(const Data &data, size_t &offset)
00145 {
00146 const unsigned char *finish = ParseCommonFields(*this,
00147 data.GetData() + offset, data.GetData() + data.GetSize());
00148 offset += finish - (data.GetData() + offset);
00149 }
00150
00151 void Folder::Clear()
00152 {
00153 FolderName.clear();
00154 Unknowns.clear();
00155 FolderType = FolderSubtree;
00156 }
00157
00158 void Folder::Dump(std::ostream &os) const
00159 {
00160 static const char *FolderTypeString[] = { "Subtree", "Deleted", "Inbox", "Outbox", "Sent", "Other"};
00161
00162
00163 os << "Folder Records\n\n";
00164 os << "Folder Name: " << FolderName << "\n";
00165 os << "Folder Type: ";
00166 if( FolderType < FolderDraft )
00167 os << FolderTypeString[FolderType] << "\n";
00168 else if( FolderType == FolderDraft )
00169 os << "Draft\n";
00170 else
00171 os << "Unknown (" << std::hex << FolderType << ")\n";
00172 os << "Folder Number: " << std::dec << FolderNumber << "\n";
00173 os << "Folder Level: " << std::dec << FolderLevel << "\n";
00174 os << "\n";
00175 os << Unknowns;
00176 os << "\n\n";
00177 }
00178
00179 }
00180