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 <sstream>
00026 #include <iomanip>
00027
00028 using namespace std;
00029 using namespace Barry::Protocol;
00030
00031 namespace Barry {
00032
00033
00034
00035
00036 RecordStateTable::RecordStateTable()
00037 : m_LastNewRecordId(1)
00038 {
00039 }
00040
00041 RecordStateTable::~RecordStateTable()
00042 {
00043 }
00044
00045 const unsigned char* RecordStateTable::ParseField(const unsigned char *begin,
00046 const unsigned char *end)
00047 {
00048 const RecordStateTableField *field = (const RecordStateTableField *) begin;
00049
00050
00051 begin += sizeof(RecordStateTableField);
00052 if( begin > end )
00053 return begin;
00054
00055 State state;
00056 state.Index = btohs(field->index);
00057 state.RecordId = btohl(field->uniqueId);
00058 state.Dirty = (field->flags & BARRY_RSTF_DIRTY) != 0;
00059 state.RecType = field->rectype;
00060 state.Unknown2.assign((const char*)field->unknown2, sizeof(field->unknown2));
00061 StateMap[state.Index] = state;
00062
00063 return begin;
00064 }
00065
00066 void RecordStateTable::Parse(const Data &data)
00067 {
00068 size_t offset = 12;
00069
00070 if( offset >= data.GetSize() )
00071 return;
00072
00073 const unsigned char *begin = data.GetData() + offset;
00074 const unsigned char *end = data.GetData() + data.GetSize();
00075
00076 while( begin < end )
00077 begin = ParseField(begin, end);
00078 }
00079
00080 void RecordStateTable::Clear()
00081 {
00082 StateMap.clear();
00083 m_LastNewRecordId = 1;
00084 }
00085
00086
00087
00088
00089 bool RecordStateTable::GetIndex(uint32_t RecordId, IndexType *pFoundIndex) const
00090 {
00091 StateMapType::const_iterator i = StateMap.begin();
00092 for( ; i != StateMap.end(); ++i ) {
00093 if( i->second.RecordId == RecordId ) {
00094 if( pFoundIndex )
00095 *pFoundIndex = i->first;
00096 return true;
00097 }
00098 }
00099 return false;
00100 }
00101
00102
00103
00104 uint32_t RecordStateTable::MakeNewRecordId() const
00105 {
00106
00107 m_LastNewRecordId++;
00108
00109
00110 StateMapType::const_iterator i = StateMap.begin();
00111 while( i != StateMap.end() ) {
00112 if( m_LastNewRecordId == i->second.RecordId ) {
00113 m_LastNewRecordId++;
00114 i = StateMap.begin();
00115 }
00116 else {
00117 ++i;
00118 }
00119 }
00120 return m_LastNewRecordId;
00121 }
00122
00123 void RecordStateTable::Dump(std::ostream &os) const
00124 {
00125 ios::fmtflags oldflags = os.setf(ios::right);
00126 char fill = os.fill(' ');
00127 bool bPrintAscii = Data::PrintAscii();
00128 Data::PrintAscii(false);
00129
00130 os << " Index RecordId Dirty RecType" << endl;
00131 os << "------- ---------- ----- -------" << endl;
00132
00133 StateMapType::const_iterator b, e = StateMap.end();
00134 for( b = StateMap.begin(); b != e ; ++b ) {
00135 const State &state = b->second;
00136
00137 os.fill(' ');
00138 os << setbase(10) << setw(7) << state.Index;
00139 os << " 0x" << setbase(16) << setfill('0') << setw(8) << state.RecordId;
00140 os << " " << setfill(' ') << setw(5) << (state.Dirty ? "yes" : "no");
00141 os << " 0x" << setbase(16) << setfill('0') << setw(2) << state.RecType;
00142 os << " " << Data(state.Unknown2.data(), state.Unknown2.size());
00143 }
00144
00145
00146 os.flags(oldflags);
00147 os.fill(fill);
00148 Data::PrintAscii(bPrintAscii);
00149 }
00150
00151
00152 }
00153