Skip to content

Commit

Permalink
Implement implicit sharing for QgsField
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed May 1, 2015
1 parent 853e913 commit 77e339e
Show file tree
Hide file tree
Showing 5 changed files with 269 additions and 68 deletions.
18 changes: 11 additions & 7 deletions python/core/qgsfield.sip
Expand Up @@ -34,6 +34,10 @@ public:
int prec = 0,
QString comment = QString() );

/** Copy constructor
*/
QgsField( const QgsField& other );

//! Destructor
~QgsField();

Expand Down Expand Up @@ -75,9 +79,9 @@ public:

/**
Set the field name.
@param nam Name of the field
@param name Name of the field
*/
void setName( const QString & nam );
void setName( const QString& name );

/**
Set variant type.
Expand All @@ -86,9 +90,9 @@ public:

/**
Set the field type.
@param typ Field type
@param typeName Field type
*/
void setTypeName( const QString & typ );
void setTypeName( const QString& typeName );

/**
Set the field length.
Expand All @@ -98,15 +102,15 @@ public:

/**
Set the field precision.
@param prec Precision of the field
@param precision Precision of the field
*/
void setPrecision( int prec );
void setPrecision( int precision );


/**
Set the field comment
*/
void setComment( const QString & comment );
void setComment( const QString& comment );

/** Formats string for display*/
QString displayString( const QVariant& v ) const;
Expand Down
67 changes: 35 additions & 32 deletions src/core/qgsfield.cpp
Expand Up @@ -34,9 +34,14 @@ QgsField::QgsField( QString nam, QString typ, int len, int prec, bool num,
#endif

QgsField::QgsField( QString name, QVariant::Type type, QString typeName, int len, int prec, QString comment )
: mName( name ), mType( type ), mTypeName( typeName )
, mLength( len ), mPrecision( prec ), mComment( comment )
{
d = new QgsField::FieldData( name, type, typeName, len, prec, comment );
}

QgsField::QgsField( const QgsField &other )
: d( other.d )
{

}


Expand All @@ -46,73 +51,71 @@ QgsField::~QgsField()

bool QgsField::operator==( const QgsField& other ) const
{
return (( mName == other.mName ) && ( mType == other.mType )
&& ( mLength == other.mLength ) && ( mPrecision == other.mPrecision ) );
return *( other.d ) == *d;
}

bool QgsField::operator!=( const QgsField& other ) const
{
return !( *this == other );
}


const QString & QgsField::name() const
{
return mName;
return d->name;
}

QVariant::Type QgsField::type() const
{
return mType;
return d->type;
}

const QString & QgsField::typeName() const
{
return mTypeName;
return d->typeName;
}

int QgsField::length() const
{
return mLength;
return d->length;
}

int QgsField::precision() const
{
return mPrecision;
return d->precision;
}

const QString & QgsField::comment() const
{
return mComment;
return d->comment;
}

void QgsField::setName( const QString & nam )
void QgsField::setName( const QString& name )
{
mName = nam;
d->name = name;
}

void QgsField::setType( QVariant::Type type )
{
mType = type;
d->type = type;
}

void QgsField::setTypeName( const QString & typeName )
void QgsField::setTypeName( const QString& typeName )
{
mTypeName = typeName;
d->typeName = typeName;
}

void QgsField::setLength( int len )
{
mLength = len;
d->length = len;
}
void QgsField::setPrecision( int prec )
void QgsField::setPrecision( int precision )
{
mPrecision = prec;
d->precision = precision;
}

void QgsField::setComment( const QString & comment )
void QgsField::setComment( const QString& comment )
{
mComment = comment;
d->comment = comment;
}

QString QgsField::displayString( const QVariant& v ) const
Expand All @@ -123,8 +126,8 @@ QString QgsField::displayString( const QVariant& v ) const
return settings.value( "qgis/nullValue", "NULL" ).toString();
}

if ( mType == QVariant::Double && mPrecision > 0 )
return QString::number( v.toDouble(), 'f', mPrecision );
if ( d->type == QVariant::Double && d->precision > 0 )
return QString::number( v.toDouble(), 'f', d->precision );

return v.toString();
}
Expand All @@ -133,33 +136,33 @@ bool QgsField::convertCompatible( QVariant& v ) const
{
if ( v.isNull() )
{
v.convert( mType );
v.convert( d->type );
return true;
}

if ( mType == QVariant::Int && v.toInt() != v.toLongLong() )
if ( d->type == QVariant::Int && v.toInt() != v.toLongLong() )
{
v = QVariant( mType );
v = QVariant( d->type );
return false;
}

if ( !v.convert( mType ) )
if ( !v.convert( d->type ) )
{
v = QVariant( mType );
v = QVariant( d->type );
return false;
}

if ( mType == QVariant::Double && mPrecision > 0 )
if ( d->type == QVariant::Double && d->precision > 0 )
{
double s = qPow( 10, mPrecision );
double s = qPow( 10, d->precision );
double d = v.toDouble() * s;
v = QVariant(( d < 0 ? ceil( d - 0.5 ) : floor( d + 0.5 ) ) / s );
return true;
}

if ( mType == QVariant::String && mLength > 0 && v.toString().length() > mLength )
if ( d->type == QVariant::String && d->length > 0 && v.toString().length() > d->length )
{
v = v.toString().left( mLength );
v = v.toString().left( d->length );
return false;
}

Expand Down
100 changes: 71 additions & 29 deletions src/core/qgsfield.h
Expand Up @@ -19,6 +19,7 @@
#include <QString>
#include <QVariant>
#include <QVector>
#include <QSharedDataPointer>

typedef QList<int> QgsAttributeList;

Expand Down Expand Up @@ -52,14 +53,18 @@ class CORE_EXPORT QgsField
int prec = 0,
QString comment = QString() );

/** Copy constructor
*/
QgsField( const QgsField& other );

//! Destructor
~QgsField();

bool operator==( const QgsField& other ) const;
bool operator!=( const QgsField& other ) const;

//! Gets the name of the field
const QString & name() const;
const QString& name() const;

//! Gets variant type of the field as it will be retrieved from data source
QVariant::Type type() const;
Expand All @@ -70,16 +75,14 @@ class CORE_EXPORT QgsField
the data store reports it, with no attempt to standardize the value.
@return QString containing the field type
*/
const QString & typeName() const;

const QString& typeName() const;

/**
Gets the length of the field.
@return int containing the length of the field
*/
int length() const;


/**
Gets the precision of the field. Not all field types have a related precision.
@return int containing the precision or zero if not applicable to the field type.
Expand All @@ -89,13 +92,13 @@ class CORE_EXPORT QgsField
/**
Returns the field comment
*/
const QString & comment() const;
const QString& comment() const;

/**
Set the field name.
@param nam Name of the field
@param name Name of the field
*/
void setName( const QString & nam );
void setName( const QString& name );

/**
Set variant type.
Expand All @@ -104,9 +107,9 @@ class CORE_EXPORT QgsField

/**
Set the field type.
@param typ Field type
@param typeName Field type
*/
void setTypeName( const QString & typ );
void setTypeName( const QString& typeName );

/**
Set the field length.
Expand All @@ -116,15 +119,14 @@ class CORE_EXPORT QgsField

/**
Set the field precision.
@param prec Precision of the field
@param precision Precision of the field
*/
void setPrecision( int prec );

void setPrecision( int precision );

/**
Set the field comment
*/
void setComment( const QString & comment );
void setComment( const QString& comment );

/** Formats string for display*/
QString displayString( const QVariant& v ) const;
Expand All @@ -140,23 +142,63 @@ class CORE_EXPORT QgsField

private:

//! Name
QString mName;

//! Variant type
QVariant::Type mType;

//! Type name from provider
QString mTypeName;

//! Length
int mLength;

//! Precision
int mPrecision;
class FieldData : public QSharedData
{
public:

FieldData( QString name = QString(),
QVariant::Type type = QVariant::Invalid,
QString typeName = QString(),
int len = 0,
int prec = 0,
QString comment = QString() )
: name( name )
, type( type )
, typeName( typeName )
, length( len )
, precision( prec )
, comment( comment )
{}

FieldData( const FieldData& other )
: QSharedData( other )
, name( other.name )
, type( other.type )
, typeName( other.typeName )
, length( other.length )
, precision( other.precision )
, comment( other.comment )
{
}

~FieldData() {}

bool operator==( const FieldData& other ) const
{
return (( name == other.name ) && ( type == other.type )
&& ( length == other.length ) && ( precision == other.precision ) );
}

//! Name
QString name;

//! Variant type
QVariant::Type type;

//! Type name from provider
QString typeName;

//! Length
int length;

//! Precision
int precision;

//! Comment
QString comment;
};

//! Comment
QString mComment;
QSharedDataPointer<FieldData> d;

}; // class QgsField

Expand Down
1 change: 1 addition & 0 deletions tests/src/core/CMakeLists.txt
Expand Up @@ -83,6 +83,7 @@ ADD_QGIS_TEST(applicationtest testqgsapplication.cpp)
ADD_QGIS_TEST(diagramtest testqgsdiagram.cpp)
ADD_QGIS_TEST(diagramexpressiontest testqgsdiagramexpression.cpp)
ADD_QGIS_TEST(expressiontest testqgsexpression.cpp)
ADD_QGIS_TEST(fieldtest testqgsfield.cpp)
ADD_QGIS_TEST(scaleexpressiontest testqgsscaleexpression.cpp)
ADD_QGIS_TEST(filewritertest testqgsvectorfilewriter.cpp)
ADD_QGIS_TEST(projecttest testqgsproject.cpp)
Expand Down

0 comments on commit 77e339e

Please sign in to comment.