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-2011, 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 <iostream>
00031 #include <sstream>
00032 #include <iomanip>
00033 
00034 using namespace std;
00035 using namespace Barry::Protocol;
00036 
00037 namespace Barry {
00038 
00039 
00040 ///////////////////////////////////////////////////////////////////////////////
00041 // Folder Class, static members
00042 
00043 //
00044 // Note! These functions currently only pass the same values through.
00045 //       In actuality, these are technically two different values:
00046 //       one on the raw protocol side, and the other part of the
00047 //       guaranteed Barry API.  If the Blackberry ever changes the
00048 //       meanings for these codes, do the translation here.
00049 //
00050 
00051 Folder::FolderType Folder::TypeProto2Rec(uint8_t t)
00052 {
00053         return (FolderType)t;
00054 }
00055 
00056 uint8_t Folder::TypeRec2Proto(FolderType t)
00057 {
00058         return t;
00059 }
00060 
00061 
00062 
00063 ///////////////////////////////////////////////////////////////////////////////
00064 // Folder Class
00065 
00066 // Folder Field Codes
00067 
00068 #define FFC_NUMBER      0x0a
00069 #define FFC_LEVEL       0x0b
00070 #define FFC_NAME        0x0c
00071 #define FFC_ADDRESS1    0x0d
00072 #define FFC_ADDRESS2    0x0e
00073 #define FFC_TYPE        0x0f
00074 #define FFC_END         0xffff
00075 
00076 #define INVALID         -1
00077 
00078 #define SEPARATOR       0x2f
00079 #define ROOT_SEPARATOR  0x3a
00080 
00081 static FieldLink<Folder> FolderFieldLinks[] = {
00082     { FFC_NAME, "FolderName",  0, 0, &Folder::Name, 0, 0, 0, 0, true },
00083     { FFC_END,  "End of List", 0, 0, 0, 0, 0, 0, 0, false },
00084 };
00085 
00086 Folder::Folder()
00087 {
00088         Clear();
00089 }
00090 
00091 
00092 Folder::~Folder()
00093 {
00094 }
00095 
00096 const unsigned char* Folder::ParseField(const unsigned char *begin,
00097                                         const unsigned char *end,
00098                                         const IConverter *ic)
00099 {
00100         const CommonField *field = (const CommonField *) begin;
00101 
00102         // advance and check size
00103         begin += COMMON_FIELD_HEADER_SIZE + btohs(field->size);
00104         if( begin > end )       // if begin==end, we are ok
00105                 return begin;
00106 
00107         if( !btohs(field->size) )   // if field has no size, something's up
00108                 return begin;
00109 
00110         // cycle through the type table
00111         for(    FieldLink<Folder> *b = FolderFieldLinks;
00112                 b->type != FFC_END;
00113                 b++ )
00114         {
00115                 if( b->type == field->type ) {
00116                         if( b->strMember ) {
00117                                 std::string &s = this->*(b->strMember);
00118                                 s = ParseFieldString(field);
00119                                 if( b->iconvNeeded && ic )
00120                                         s = ic->FromBB(s);
00121                                 return begin;   // done!
00122                         }
00123                         else if( b->timeMember && btohs(field->size) == 4 ) {
00124                                 time_t &t = this->*(b->timeMember);
00125                                 t = min2time(field->u.min1900);
00126                                 return begin;
00127                         }
00128                 }
00129         }
00130         // handle special cases
00131         switch( field->type )
00132         {
00133         case FFC_TYPE:
00134                 Type = TypeProto2Rec(field->u.raw[0]);
00135                 return begin;
00136         case FFC_NUMBER:
00137                 Number = field->u.raw[0];       // two's complement
00138                 return begin;
00139         case FFC_LEVEL:
00140                 Level = field->u.raw[0];
00141                 return begin;
00142         }
00143 
00144         // if still not handled, add to the Unknowns list
00145         UnknownField uf;
00146         uf.type = field->type;
00147         uf.data.assign((const char*)field->u.raw, btohs(field->size));
00148         Unknowns.push_back(uf);
00149 
00150         // return new pointer for next field
00151         return begin;
00152 }
00153 
00154 void Folder::ParseHeader(const Data &data, size_t &offset)
00155 {
00156         // no header in Folder records
00157 }
00158 
00159 void Folder::ParseFields(const Data &data, size_t &offset, const IConverter *ic)
00160 {
00161         const unsigned char *finish = ParseCommonFields(*this,
00162                 data.GetData() + offset, data.GetData() + data.GetSize(), ic);
00163         offset += finish - (data.GetData() + offset);
00164 }
00165 
00166 void Folder::BuildHeader(Data &data, size_t &offset) const
00167 {
00168         // not yet implemented
00169 }
00170 
00171 void Folder::BuildFields(Data &data, size_t &offset, const IConverter *ic) const
00172 {
00173         // not yet implemented
00174 }
00175 
00176 void Folder::Clear()
00177 {
00178         RecType = GetDefaultRecType();
00179         RecordId = 0;
00180 
00181         Name.clear();
00182         Number = 0;
00183         Level = 0;
00184 
00185         Type = FolderSubtree;
00186 
00187         Unknowns.clear();
00188 }
00189 
00190 std::string Folder::GetDescription() const
00191 {
00192         ostringstream oss;
00193         oss << Name << " (" << Level << ")";
00194         return oss.str();
00195 }
00196 
00197 void Folder::Dump(std::ostream &os) const
00198 {
00199         static const char *FolderTypeString[] = { "Subtree", "Deleted", "Inbox", "Outbox", "Sent", "Other"};
00200 //      static const char *FolderStatusString[] = { "Orphan", "Unfiled", "Filed" };
00201 
00202         os << "Folder Records\n\n";
00203         os << "Folder Name: " << Name << "\n";
00204         os << "Folder Type: ";
00205         if( Type < FolderDraft )
00206                 os << FolderTypeString[Type] << "\n";
00207         else if( Type == FolderDraft )
00208                 os << "Draft\n";
00209         else
00210                 os << "Unknown (" << std::hex << Type << ")\n";
00211         os << "Folder Number: " << std::dec << Number << "\n";
00212         os << "Folder Level: " << std::dec << Level << "\n";
00213         os << "\n";
00214         os << Unknowns;
00215         os << "\n\n";
00216 }
00217 
00218 } // namespace Barry
00219 

Generated on Tue Mar 1 17:50:16 2011 for Barry by  doxygen 1.5.6