3 /// DatabaseDatabase record parser class
7 Copyright (C) 2005-2010, Net Direct Inc. (http://www.netdirect.ca/)
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU General Public License in the COPYING file at the
19 root directory of this project for more details.
23 #include "record-internal.h"
29 using namespace Barry::Protocol
;
33 ///////////////////////////////////////////////////////////////////////////////
34 // DatabaseDatabase class
36 DatabaseDatabase::DatabaseDatabase()
40 DatabaseDatabase::~DatabaseDatabase()
44 template <class RecordType
, class FieldType
>
45 void DatabaseDatabase::ParseRec(const RecordType
&rec
, const unsigned char *end
)
49 template <class FieldType
>
50 const unsigned char* DatabaseDatabase::ParseField(const unsigned char *begin
,
51 const unsigned char *end
)
53 // check if there is enough data for a header
54 const unsigned char *headend
= begin
+ sizeof(FieldType
);
59 const FieldType
*field
= (const FieldType
*) begin
;
61 // advance and check size
62 begin
+= sizeof(FieldType
) - sizeof(field
->name
) + ConvertHtoB(field
->nameSize
);
63 if( begin
> end
) // if begin==end, we are ok
66 if( !ConvertHtoB(field
->nameSize
) ) // if field has no size, something's up
70 db
.Number
= ConvertHtoB(field
->dbNumber
);
71 db
.RecordCount
= ConvertHtoB(field
->dbRecordCount
);
72 db
.Name
.assign((const char *)field
->name
, ConvertHtoB(field
->nameSize
) - 1);
73 Databases
.push_back(db
);
77 void DatabaseDatabase::Parse(const Data
&data
)
79 // check size to make sure we have up to the DBAccess operation byte
80 if( data
.GetSize() < (SB_PACKET_DBACCESS_HEADER_SIZE
+ 1) )
83 MAKE_PACKET(pack
, data
);
84 const unsigned char *begin
= 0;
85 const unsigned char *end
= data
.GetData() + data
.GetSize();
87 switch( pack
->u
.db
.u
.response
.operation
)
89 case SB_DBOP_GET_DBDB
:
90 // using the new protocol
91 if( data
.GetSize() > SB_PACKET_DBDB_HEADER_SIZE
) {
92 begin
= (const unsigned char *)
93 &pack
->u
.db
.u
.response
.u
.dbdb
.field
[0];
95 // this while check is ok, since ParseField checks
98 begin
= ParseField
<DBDBField
>(begin
, end
);
101 dout("DatabaseDatabase: not enough data for parsing");
104 case SB_DBOP_OLD_GET_DBDB
:
105 // using the old protocol
106 if( data
.GetSize() > SB_PACKET_OLD_DBDB_HEADER_SIZE
) {
107 begin
= (const unsigned char *)
108 &pack
->u
.db
.u
.response
.u
.old_dbdb
.field
[0];
110 // this while check is ok, since ParseField checks
113 begin
= ParseField
<OldDBDBField
>(begin
, end
);
116 dout("DatabaseDatabase: not enough data for parsing");
121 dout("Unknown protocol");
128 void DatabaseDatabase::Clear()
133 bool DatabaseDatabase::GetDBNumber(const std::string
&name
,
134 unsigned int &number
) const
136 DatabaseArrayType::const_iterator b
= Databases
.begin();
137 for( ; b
!= Databases
.end(); b
++ )
138 if( b
->Name
== name
) {
145 bool DatabaseDatabase::GetDBName(unsigned int number
,
146 std::string
&name
) const
148 DatabaseArrayType::const_iterator b
= Databases
.begin();
149 for( ; b
!= Databases
.end(); b
++ )
150 if( b
->Number
== number
) {
157 void DatabaseDatabase::Dump(std::ostream
&os
) const
159 DatabaseArrayType::const_iterator b
= Databases
.begin();
160 os
<< "Database database:\n";
161 for( ; b
!= Databases
.end(); b
++ ) {
162 os
<< " Database: 0x" << setbase(16) << b
->Number
163 << " '" << b
->Name
<< "' (records: "
164 << setbase(10) << b
->RecordCount
<< ")\n";