⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 record.cpp

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.7平台上编译为嵌入式图形界面操作系统。
💻 CPP
字号:
/************************************************************************ Copyright (C) 2000-2002 Trolltech AS.  All rights reserved.**** This file is part of the Qtopia Environment.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/// the next few lines have to come first#include <qtopia/qpeglobal.h>#ifdef Q_OS_WIN32#include <objbase.h>#elseextern "C" {#include <uuid/uuid.h>#define UUID_H_INCLUDED}#endif#include "record.h"#include <qtopia/quuid.h>#include <qtopia/timeconversion.h>//using namespace qpe;/*?  \class Record  \internal  \brief The Record class is a record in the Database.    The Record class represents one record stored (or to be stored in  the Qt Palmtop Database. The class is optimised for fast reading and  writing. A record can consist of a series of fields, represented by  integer keys. Each field is stored with a type information, and  typechecking is done when reading the fields.*//*?  \enum Record::FieldType  \value UndefinedType Indicated the field does not exist in this record  \value BoolType This field contains a boolean  \value IntType the field contains an integer  \value DateType the field contains a Date  \value DateTimeType the field contains a datetime  \value StringType the field contains a string  \endenum    The type of a field can be queried with the typeof() method.*//*?  will create an empty record.*/Record::Record(){    mIndex = -1;    initEmpty();}Record::~Record(){}void Record::initEmpty(){    data.resize( sizeof( RecordHeader ) );    memset( data.data(), 0, data.size() );    uid();}QUuid Record::generateUuid(){#if defined(Q_WS_WIN32)    GUID guid;    HRESULT h = CoCreateGuid( &guid );    if ( h != S_OK ) {	qWarning(" could not create a Uuid" );	return QUuid();    }    return QUuid( guid );#else#if QT_VERSION < 0x030000    uuid_t uuid;    uuid_generate( uuid );    return QUuid( uuid );#else    return QUuid();#endif#endif}/*?  returns the type of the fiels \a fieldId.*/Record::FieldType Record::typeOf( int fieldId ){    AttributeEntry *attr = findAttribute( fieldId );    if ( !attr )	return UndefinedType;    return (FieldType)attr->type();}Record::AttributeEntry *Record::findAttribute( int id ) const{    RecordHeader *h = header();    if ( h ) {	AttributeEntry *attr = firstAttribute();	//qDebug("looking for attr %d total=%d", id, h->numAttributes() );	for ( int i = 0; i < h->numAttributes(); i ++ ) {	    //qDebug("attribute = [ %d, %d, %x]", attr->id(), attr->type(), attr->offsetOrData() );	    if ( attr->id() == id ) {		//qDebug("found" );		return attr;	    }	    attr++;	}    }    return 0;}Record::AttributeEntry *Record::findAttribute( int id, bool add ){    RecordHeader *h = header();    AttributeEntry *attr = firstAttribute();    for ( int i = 0; i < h->numAttributes(); i ++ ) {	if ( attr->id() == id )	    return attr;	attr++;    }    if ( add ) {	// add the new attribute	// first make space for the attribute	int insertPoint = dataOffset();	insertBytes( insertPoint, sizeof( AttributeEntry ) );	AttributeEntry *attr = (AttributeEntry *)( data.data() + insertPoint );	attr->setId( id );	attr->setType( UndefinedType );	attr->setOffsetOrData( 0 );	header()->setNumAttributes( header()->numAttributes() + 1 );	//qDebug("added attribute, now have %d", header()->numAttributes() );	return attr;    }    return 0;}/*?  Sets the set of categories to which the Record belongs to \a v.*/void Record::setCategories( const QArray<int> &v ){    uint num = v.count();    RecordHeader *h = header();    if ( h->numCategories() > num ) {	removeBytes( categoryOffset(), sizeof(int) * (h->numCategories() - num ) );    } else if ( h->numCategories() < num ) {	qDebug("insertBytes in categories");	insertBytes( categoryOffset(), sizeof(int) * (num - h->numCategories() ) );    }    int *ncat = (int *) ( data.data() + categoryOffset() );    for ( int i = 0;  i < num; i++ ) 	ncat[i] = htonl( v[i] );    catsDirty = TRUE;}/*?  Sets the record to belong only to the category with the id \a single.*/void Record::setCategories( int single ){    QArray<int> cats;    cats.resize( 1 );    cats[0] = single;    setCategories( cats );    catsDirty = TRUE;}/*?  returns the list of categories the record belongs to*/QArray<int> Record::categories() const{    RecordHeader *h = header();    uint num = h->numCategories();    QArray<int> cats;    cats.resize( num );    int *ncat = (int *) ( data.data() + categoryOffset() );    for ( int i = 0; i < num; i++ ) 	cats[i] = ntohl( ncat[i] );    return cats;}/*?  Returns the unique Id for this record. In case it doesn't exist, a new unique Id  will be created.*/QUuid Record::uid() const{    return header()->uid();}/*?  Compare this record with \a other. The default implementation  compares the values of the field index 0.*/int Record::compare( const Record &other ) const{    AttributeEntry *thisAttr = findAttribute( 0 );    AttributeEntry *otherAttr = other.findAttribute( 0 );    if ( !thisAttr && !otherAttr )	return 0;    if ( !thisAttr )	return 1;    if ( !otherAttr )	return -1;    if ( thisAttr->type() != otherAttr->type() )	return 0;    switch( thisAttr->type() ) {	case UndefinedType:	    return 0;	case BoolType:	    return ( thisAttr->offsetOrData() == 0 ) - ( otherAttr->offsetOrData() == 0 );	case IntType:	case DateType:	case DateTimeType:	    return ( thisAttr->offsetOrData() - otherAttr->offsetOrData() );	case StringType: {	    QString thisstr = stringField( 0 );	    QString otherstr = other.stringField( 0 );	    return thisstr.compare( otherstr );	}    }    return 0;}/*?  Returns the date stored in the field \a id. If the field is not of type Date, *\a ok  will be FALSE.  Returns an invalid date if the field does not exist.*/QDate Record::dateField( int id, bool *ok ) const{    AttributeEntry *attr = findAttribute( id );    if ( attr && attr->type() == DateType ) {	if ( ok ) *ok = TRUE;	uint date = attr->offsetOrData();	return TimeConversion::fromUTC( attr->offsetOrData() ).date();    }    if ( ok ) *ok = !attr; // ok is true if we didn't find an entry    return QDate();}/*?  Returns the datetime stored in the field \a id. If the field is not of type DateTime,  *\a ok will be FALSE.  Returns an invalid datetime if the field does not exist.*/QDateTime Record::dateTimeField( int id, bool *ok ) const{    AttributeEntry *attr = findAttribute( id );    if ( attr && attr->type() == DateTimeType ) {	if ( ok ) *ok = TRUE;	return TimeConversion::fromUTC( attr->offsetOrData() );    }    if ( ok ) *ok = !attr; // ok is true if we didn't find an entry    return QDateTime();}/*?  Returns the integer stored in the field \a id. If the field is not of type Int,  *\a ok will be FALSE.  Returns 0 if the field does not exist.*/int Record::intField( int id, bool *ok ) const{    AttributeEntry *attr = findAttribute( id );    if ( attr && attr->type() == IntType ) {	if ( ok ) *ok = TRUE;	return attr->offsetOrData();    }    if ( ok ) *ok = !attr; // ok is true if we didn't find an entry    return 0;}/*?  Returns the string stored in the field \a id. If the field is not of type String,  *\a ok will be false.  Returns a null string if the field does not exist.*/QString Record::stringField( int id, bool *ok ) const{    AttributeEntry *attr = findAttribute( id );    //qDebug("looking for string, attr=%d, field found = [%d, %d, %d]", id, attr->id(), attr->type(), attr->offsetOrData() );    if ( attr && attr->type() == StringType ) {	if ( ok ) *ok = TRUE;	int off = dataOffset() + attr->offsetOrData();	//qDebug("string at offset %x", off );	//qDebug("data at offset = %x", 	//       *((int *)(data.data()+off))	//    );	int bytesRemaining = data.size() - off;	if ( bytesRemaining > 4 ) {	    uint len = ntohl( *((int *) (data.data() + off )) );	    if ( len*sizeof(QChar) <= (uint)bytesRemaining - 4 ) {		QString str;		str.setUnicode( (QChar *)(data.data() + off + 4), len );		//qDebug("string is %s, len should be %d", str.latin1(), len );		// ### take care of byte ordering		return str;	    }	}    }    if ( ok ) *ok = !attr; // ok is true if we didn't find an entry    return QString::null;  }/*?  Returns the boolean stored in the field \a id. If the field is not of type Bool,  *\a ok, will be FALSE.  Returns TRUE if the field does not exist.*/bool Record::boolField( int id, bool *ok ) const{    AttributeEntry *attr = findAttribute( id );    if ( attr && attr->type() == BoolType ) {	if ( ok ) *ok = TRUE;	return (bool) attr->offsetOrData();    }    if ( ok ) *ok = !attr; // ok is true if we didn't find an entry    return TRUE;}/*?  Sets the field \a attrId to \a date. The type is set to Date by this call.*/void Record::setDateField( int attrId, const QDate &date ){    AttributeEntry *attr = findAttribute( attrId, TRUE );    attr->setType( DateType );    attr->setOffsetOrData( TimeConversion::toUTC( date ) );}/*?  Sets the field \a attrId to date and time \a dt. The type is set to DateTime by this call.*/void Record::setDateTimeField( int attrId, const QDateTime &dt ) {    AttributeEntry *attr = findAttribute( attrId, TRUE );    attr->setType( DateTimeType );    attr->setOffsetOrData( TimeConversion::toUTC( dt ) );    }/*?  Sets the field \a attrId to the integer \a i. The type is set to Integer by this call.*/void Record::setIntField( int attrId, int i ){    AttributeEntry *attr = findAttribute( attrId, TRUE );    attr->setType( IntType );    attr->setOffsetOrData( i );}/*?  Sets the field \a attrId to the string \a str. The type is set to String by this call.*/void Record::setStringField( int attrId, const QString &str ){    AttributeEntry *attr = findAttribute( attrId, TRUE );    if ( attr->type() == StringType ) {	// delete old string	int off = dataOffset() + attr->offsetOrData();	int len = ntohl( *((int *)(data.data() + off ) ) )*sizeof(QChar) + 4;	//qDebug("deleting old string, removing %d bytes at %d", len, off );	removeBytes( off, len );    }    attr->setType( StringType );    // add new string    int len = str.length()*sizeof( QChar ) + 4;    int point = data.size();    data.resize( point + len );    int *nstrlen = (int *)(data.data() + point);    *nstrlen = htonl( str.length() );    char *d = (data.data() + point + 4);    memcpy( d, str.unicode(), str.length() *sizeof( QChar ) );    attr->setOffsetOrData( point - dataOffset() );}/*?  Sets the field \a attrId to the boolean \a b. The type is set to Bool by this call.*/void Record::setBoolField( int attrId, bool b ){    AttributeEntry *attr = findAttribute( attrId, TRUE );    attr->setType( BoolType );    attr->setOffsetOrData( (int)b );    }void Record::insertBytes( int point, uint bytes ){    if ( bytes == 0 )	return;    int size = data.size() - point;    data.resize( data.size() + bytes );    memmove( data.data() + point + bytes, data.data() + point, size );#ifdef RECORD_DEBUG    memset( data.data() + point, 0xde, bytes );#endif    }void Record::removeBytes( int point, uint bytes ){    if ( bytes == 0 )	return;    int size = data.size() - point - bytes;    memmove( data.data() + bytes, data.data() + point + bytes, size );            data.resize( data.size() - bytes );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -