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 #include "record.h"
00023 #include "record-internal.h"
00024 #include "data.h"
00025 #include "protocol.h"
00026 #include "debug.h"
00027
00028 using namespace std;
00029 using namespace Barry::Protocol;
00030
00031 namespace Barry {
00032
00033
00034
00035
00036 DatabaseDatabase::DatabaseDatabase()
00037 {
00038 }
00039
00040 DatabaseDatabase::~DatabaseDatabase()
00041 {
00042 }
00043
00044 template <class RecordType, class FieldType>
00045 void DatabaseDatabase::ParseRec(const RecordType &rec, const unsigned char *end)
00046 {
00047 }
00048
00049 template <class FieldType>
00050 const unsigned char* DatabaseDatabase::ParseField(const unsigned char *begin,
00051 const unsigned char *end)
00052 {
00053
00054 const unsigned char *headend = begin + sizeof(FieldType);
00055 if( headend > end )
00056 return headend;
00057
00058
00059 const FieldType *field = (const FieldType *) begin;
00060
00061
00062 begin += sizeof(FieldType) - sizeof(field->name) + ConvertHtoB(field->nameSize);
00063 if( begin > end )
00064 return begin;
00065
00066 if( !ConvertHtoB(field->nameSize) )
00067 return begin;
00068
00069 Database db;
00070 db.Number = ConvertHtoB(field->dbNumber);
00071 db.RecordCount = ConvertHtoB(field->dbRecordCount);
00072 db.Name.assign((const char *)field->name, ConvertHtoB(field->nameSize) - 1);
00073 Databases.push_back(db);
00074 return begin;
00075 }
00076
00077 void DatabaseDatabase::Parse(const Data &data)
00078 {
00079
00080 if( data.GetSize() < (SB_PACKET_DBACCESS_HEADER_SIZE + 1) )
00081 return;
00082
00083 MAKE_PACKET(pack, data);
00084 const unsigned char *begin = 0;
00085 const unsigned char *end = data.GetData() + data.GetSize();
00086
00087 switch( pack->u.db.u.response.operation )
00088 {
00089 case SB_DBOP_GET_DBDB:
00090
00091 if( data.GetSize() > SB_PACKET_DBDB_HEADER_SIZE ) {
00092 begin = (const unsigned char *)
00093 &pack->u.db.u.response.u.dbdb.field[0];
00094
00095
00096
00097 while( begin < end )
00098 begin = ParseField<DBDBField>(begin, end);
00099 }
00100 else
00101 dout("DatabaseDatabase: not enough data for parsing");
00102 break;
00103
00104 case SB_DBOP_OLD_GET_DBDB:
00105
00106 if( data.GetSize() > SB_PACKET_OLD_DBDB_HEADER_SIZE ) {
00107 begin = (const unsigned char *)
00108 &pack->u.db.u.response.u.old_dbdb.field[0];
00109
00110
00111
00112 while( begin < end )
00113 begin = ParseField<OldDBDBField>(begin, end);
00114 }
00115 else
00116 dout("DatabaseDatabase: not enough data for parsing");
00117 break;
00118
00119 default:
00120
00121 dout("Unknown protocol");
00122 break;
00123 }
00124
00125
00126 }
00127
00128 void DatabaseDatabase::Clear()
00129 {
00130 Databases.clear();
00131 }
00132
00133 bool DatabaseDatabase::GetDBNumber(const std::string &name,
00134 unsigned int &number) const
00135 {
00136 DatabaseArrayType::const_iterator b = Databases.begin();
00137 for( ; b != Databases.end(); b++ )
00138 if( b->Name == name ) {
00139 number = b->Number;
00140 return true;
00141 }
00142 return false;
00143 }
00144
00145 bool DatabaseDatabase::GetDBName(unsigned int number,
00146 std::string &name) const
00147 {
00148 DatabaseArrayType::const_iterator b = Databases.begin();
00149 for( ; b != Databases.end(); b++ )
00150 if( b->Number == number ) {
00151 name = b->Name;
00152 return true;
00153 }
00154 return false;
00155 }
00156
00157 void DatabaseDatabase::Dump(std::ostream &os) const
00158 {
00159 DatabaseArrayType::const_iterator b = Databases.begin();
00160 os << "Database database:\n";
00161 for( ; b != Databases.end(); b++ ) {
00162 os << " Database: 0x" << setbase(16) << b->Number
00163 << " '" << b->Name << "' (records: "
00164 << setbase(10) << b->RecordCount << ")\n";
00165 }
00166 }
00167
00168 }
00169