r_folder.cc
Go to the documentation of this file.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 "iconv.h"
00030 #include <ostream>
00031 #include <iomanip>
00032
00033 using namespace std;
00034 using namespace Barry::Protocol;
00035
00036 namespace Barry {
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 Folder::FolderType Folder::TypeProto2Rec(uint8_t t)
00051 {
00052 return (FolderType)t;
00053 }
00054
00055 uint8_t Folder::TypeRec2Proto(FolderType t)
00056 {
00057 return t;
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067 #define FFC_NUMBER 0x0a
00068 #define FFC_LEVEL 0x0b
00069 #define FFC_NAME 0x0c
00070 #define FFC_ADDRESS1 0x0d
00071 #define FFC_ADDRESS2 0x0e
00072 #define FFC_TYPE 0x0f
00073 #define FFC_END 0xffff
00074
00075 #define INVALID -1
00076
00077 #define SEPARATOR 0x2f
00078 #define ROOT_SEPARATOR 0x3a
00079
00080 static FieldLink<Folder> FolderFieldLinks[] = {
00081 { FFC_NAME, "FolderName", 0, 0, &Folder::Name, 0, 0, 0, 0, true },
00082 { FFC_END, "End of List", 0, 0, 0, 0, 0, 0, 0, false },
00083 };
00084
00085 Folder::Folder()
00086 {
00087 Clear();
00088 }
00089
00090
00091 Folder::~Folder()
00092 {
00093 }
00094
00095 const unsigned char* Folder::ParseField(const unsigned char *begin,
00096 const unsigned char *end,
00097 const IConverter *ic)
00098 {
00099 const CommonField *field = (const CommonField *) begin;
00100
00101
00102 begin += COMMON_FIELD_HEADER_SIZE + btohs(field->size);
00103 if( begin > end )
00104 return begin;
00105
00106 if( !btohs(field->size) )
00107 return begin;
00108
00109
00110 for( FieldLink<Folder> *b = FolderFieldLinks;
00111 b->type != FFC_END;
00112 b++ )
00113 {
00114 if( b->type == field->type ) {
00115 if( b->strMember ) {
00116 std::string &s = this->*(b->strMember);
00117 s = ParseFieldString(field);
00118 if( b->iconvNeeded && ic )
00119 s = ic->FromBB(s);
00120 return begin;
00121 }
00122 else if( b->timeMember && btohs(field->size) == 4 ) {
00123 time_t &t = this->*(b->timeMember);
00124 t = min2time(field->u.min1900);
00125 return begin;
00126 }
00127 }
00128 }
00129
00130 switch( field->type )
00131 {
00132 case FFC_TYPE:
00133 Type = TypeProto2Rec(field->u.raw[0]);
00134 return begin;
00135 case FFC_NUMBER:
00136 Number = field->u.raw[0];
00137 return begin;
00138 case FFC_LEVEL:
00139 Level = field->u.raw[0];
00140 return begin;
00141 }
00142
00143
00144 UnknownField uf;
00145 uf.type = field->type;
00146 uf.data.assign((const char*)field->u.raw, btohs(field->size));
00147 Unknowns.push_back(uf);
00148
00149
00150 return begin;
00151 }
00152
00153 void Folder::ParseHeader(const Data &data, size_t &offset)
00154 {
00155
00156 }
00157
00158 void Folder::ParseFields(const Data &data, size_t &offset, const IConverter *ic)
00159 {
00160 const unsigned char *finish = ParseCommonFields(*this,
00161 data.GetData() + offset, data.GetData() + data.GetSize(), ic);
00162 offset += finish - (data.GetData() + offset);
00163 }
00164
00165 void Folder::Clear()
00166 {
00167 Name.clear();
00168 Unknowns.clear();
00169 Type = FolderSubtree;
00170 }
00171
00172 void Folder::Dump(std::ostream &os) const
00173 {
00174 static const char *FolderTypeString[] = { "Subtree", "Deleted", "Inbox", "Outbox", "Sent", "Other"};
00175
00176
00177 os << "Folder Records\n\n";
00178 os << "Folder Name: " << Name << "\n";
00179 os << "Folder Type: ";
00180 if( Type < FolderDraft )
00181 os << FolderTypeString[Type] << "\n";
00182 else if( Type == FolderDraft )
00183 os << "Draft\n";
00184 else
00185 os << "Unknown (" << std::hex << Type << ")\n";
00186 os << "Folder Number: " << std::dec << Number << "\n";
00187 os << "Folder Level: " << std::dec << Level << "\n";
00188 os << "\n";
00189 os << Unknowns;
00190 os << "\n\n";
00191 }
00192
00193 }
00194