r_folder.cc

Go to the documentation of this file.
00001 ///
00002 /// \file       r_folder.cc
00003 ///             Record parsing class for the folders database.
00004 ///
00005 
00006 /*
00007     Copyright (C) 2005-2010, 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_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 // Folder Class, static members
00041 
00042 //
00043 // Note! These functions currently only pass the same values through.
00044 //       In actuality, these are technically two different values:
00045 //       one on the raw protocol side, and the other part of the
00046 //       guaranteed Barry API.  If the Blackberry ever changes the
00047 //       meanings for these codes, do the translation here.
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 // Folder Class
00064 
00065 // Folder Field Codes
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         // advance and check size
00102         begin += COMMON_FIELD_HEADER_SIZE + btohs(field->size);
00103         if( begin > end )       // if begin==end, we are ok
00104                 return begin;
00105 
00106         if( !btohs(field->size) )   // if field has no size, something's up
00107                 return begin;
00108 
00109         // cycle through the type table
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;   // done!
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         // handle special cases
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];       // two's complement
00137                 return begin;
00138         case FFC_LEVEL:
00139                 Level = field->u.raw[0];
00140                 return begin;
00141         }
00142 
00143         // if still not handled, add to the Unknowns list
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         // return new pointer for next field
00150         return begin;
00151 }
00152 
00153 void Folder::ParseHeader(const Data &data, size_t &offset)
00154 {
00155         // no header in Folder records
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 //      static const char *FolderStatusString[] = { "Orphan", "Unfiled", "Filed" };
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 } // namespace Barry
00194 

Generated on 29 Mar 2010 for Barry by  doxygen 1.6.1