filters
dbase.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <qdatetime.h>
00023 #include <qdatastream.h>
00024 #include <qfile.h>
00025 #include <qstring.h>
00026 #include <qstringlist.h>
00027 #include <qptrlist.h>
00028
00029 #include <dbase.h>
00030
00031 DBase::DBase(): m_recordCount( 0 )
00032 {
00033 fields.setAutoDelete( true );
00034 }
00035
00036 DBase::~DBase()
00037 {
00038 fields.clear();
00039 close();
00040 }
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 bool DBase::load( const QString& filename )
00055 {
00056
00057 m_file.setName( filename );
00058 if( !m_file.open(IO_ReadOnly) )
00059 return false;
00060
00061 m_stream.setDevice( &m_file );
00062 m_stream.setByteOrder( QDataStream::LittleEndian );
00063
00064 unsigned filesize = m_file.size();
00065
00066
00067 Q_UINT8 ver;
00068 m_stream >> ver;
00069 m_version = ver & 0x7f;
00070
00071
00072 if ( m_version != 3 )
00073 return false;
00074
00075
00076 Q_UINT8 y, m, d;
00077 m_stream >> y >> m >> d;
00078
00079 m_lastUpdate.setYMD( y+1900, m, d );
00080
00081
00082 if( !m_lastUpdate.isValid() ) return false;
00083
00084
00085 Q_UINT32 norec;
00086 m_stream >> norec;
00087 m_recordCount = norec;
00088
00089
00090 Q_UINT16 header_length;
00091 m_stream >> header_length;
00092 m_headerLength = header_length;
00093
00094
00095 Q_UINT16 record_length;
00096 m_stream >> record_length;
00097 m_recordLength = record_length;
00098
00099
00100 Q_UINT8 dummy;
00101 for (int foo = 0; foo < 20; ++foo)
00102 m_stream >> dummy;
00103
00104
00105 if( filesize < m_headerLength + m_recordLength * m_recordCount )
00106 return false;
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 fields.clear();
00120 for( unsigned i = 1; i < m_headerLength/32; ++i )
00121 {
00122 DBaseField* field = new DBaseField;
00123
00124
00125 Q_UINT8 colname[12];
00126 for ( int j = 0; j < 11; ++j)
00127 m_stream >> colname[j];
00128 colname[11] = '\0';
00129 field->name = QString( (const char*) &colname[0] );
00130
00131
00132 Q_UINT8 coltype;
00133 m_stream >> coltype;
00134 switch( coltype )
00135 {
00136 case 'C': field->type = DBaseField::Character; break;
00137 case 'N': field->type = DBaseField::Numeric; break;
00138 case 'D': field->type = DBaseField::Date; break;
00139 case 'M': field->type = DBaseField::Memo; break;
00140 case 'L': field->type = DBaseField::Logical; break;
00141 default: field->type = DBaseField::Unknown; break;
00142 }
00143
00144
00145 Q_UINT32 addr;
00146 m_stream >> addr;
00147
00148
00149 Q_UINT8 colsize;
00150 m_stream >> colsize;
00151 field->length = colsize;
00152
00153
00154 Q_UINT8 decimals;
00155 m_stream >> decimals;
00156 field->decimals = decimals;
00157
00158
00159 Q_UINT8 dummy;
00160 for ( int foo = 0; foo < 14; ++foo )
00161 m_stream >> dummy;
00162
00163
00164 fields.append( field );
00165 }
00166
00167
00168 m_stream.device()->at( m_headerLength );
00169
00170 return true;
00171 }
00172
00173 QStringList DBase::readRecord( unsigned recno )
00174 {
00175 QStringList result;
00176
00177
00178 if( recno >= m_recordCount )
00179 {
00180 for( unsigned i=0; i<fields.count(); i++)
00181 result.append( "" );
00182 return result;
00183 }
00184
00185
00186 unsigned filepos = m_headerLength + recno * m_recordLength;
00187 m_stream.device()->at( filepos );
00188
00189
00190
00191 Q_UINT8 delmarker;
00192 m_stream >> delmarker;
00193 if( delmarker == 0x2a )
00194 return result;
00195
00196
00197 for( unsigned i=0; i<fields.count(); i++ )
00198 switch( fields.at(i)->type )
00199 {
00200
00201 case DBaseField::Numeric:
00202 case DBaseField::Character:
00203 {
00204 QString str;
00205 Q_UINT8 ch;
00206 for( unsigned j=0; j<fields.at(i)->length; j++ )
00207 { m_stream >> ch; str += QChar(ch); }
00208 result.append( str );
00209 } break;
00210
00211
00212 case DBaseField::Logical:
00213 {
00214 Q_UINT8 ch;
00215 m_stream >> ch;
00216 switch( ch )
00217 {
00218 case 'Y': case 'y': case 'T': case 't': result.append( "True" ); break;
00219 case 'N': case 'n': case 'F': case 'f': result.append( "False" ); break;
00220 default: result.append( "" ); break;
00221 }
00222 } break;
00223
00224
00225
00226 case DBaseField::Date:
00227 {
00228 QString str;
00229 Q_UINT8 ch;
00230 for( unsigned j=0; j<fields.at(i)->length; j++ )
00231 { m_stream >> ch; str += QChar(ch); }
00232 str.insert( 6, '-' );
00233 str.insert( 4, '-' );
00234 result.append( str );
00235 } break;
00236
00237
00238 case DBaseField::Unknown:
00239 case DBaseField::Memo:
00240 default:
00241 result.append( "" );
00242 break;
00243 }
00244
00245 return result;
00246 }
00247
00248 void DBase::close()
00249 {
00250 if( m_file.isOpen() ) m_file.close();
00251 }
|