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