[rkward-cvs] SF.net SVN: rkward:[3171] branches/2010_10_18_backend_restructuring_branch/ rkward

tfry at users.sourceforge.net tfry at users.sourceforge.net
Tue Nov 2 12:23:51 UTC 2010


Revision: 3171
          http://rkward.svn.sourceforge.net/rkward/?rev=3171&view=rev
Author:   tfry
Date:     2010-11-02 12:23:51 +0000 (Tue, 02 Nov 2010)

Log Message:
-----------
Use QVector / QStringList as internal storage for RData. This saves a whole lot of typing all over the place (more simplifications would be possible).
Also, this should make it a bit easier to serialize RData.

Modified Paths:
--------------
    branches/2010_10_18_backend_restructuring_branch/rkward/core/rfunctionobject.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/core/rfunctionobject.h
    branches/2010_10_18_backend_restructuring_branch/rkward/core/rkrownames.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/core/rkrownames.h
    branches/2010_10_18_backend_restructuring_branch/rkward/core/rkvariable.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/core/rkvariable.h
    branches/2010_10_18_backend_restructuring_branch/rkward/core/robject.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/core/robject.h
    branches/2010_10_18_backend_restructuring_branch/rkward/plugin/rkcomponentproperties.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rcommand.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rdata.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rdata.h
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrsupport.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrsupport.h
    branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkstructuregetter.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/scriptbackends/rkcomponentscripting.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/settings/rksettingsmoduler.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/windows/rkcommandlog.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/windows/rkhelpsearchwindow.cpp
    branches/2010_10_18_backend_restructuring_branch/rkward/windows/rkhelpsearchwindow.h
    branches/2010_10_18_backend_restructuring_branch/rkward/windows/rkworkplace.cpp

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/core/rfunctionobject.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/core/rfunctionobject.cpp	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/core/rfunctionobject.cpp	2010-11-02 12:23:51 UTC (rev 3171)
@@ -25,10 +25,6 @@
 RFunctionObject::RFunctionObject (RContainerObject *parent, const QString &name) : RObject (parent, name) {
 	RK_TRACE (OBJECTS);
 	type = Function;
-
-	argcount = 0;
-	argnames = 0;
-	argvalues = 0;
 }
 
 RFunctionObject::~RFunctionObject () {
@@ -39,7 +35,7 @@
 	RK_TRACE (OBJECTS);
 
 	QString ret;
-	for (unsigned int i = 0; i < argcount; ++i) {
+	for (int i = 0; i < argnames.size (); ++i) {
 		if (i) ret.append (", ");
 		ret.append (argnames[i]);
 		if (!argvalues[i].isEmpty ()) {
@@ -70,38 +66,17 @@
 	RData *argnames_data = new_data->getStructureVector ()[5];
 	RData *argvalues_data = new_data->getStructureVector ()[6];
 
-	unsigned int new_arglen = argnames_data->getDataLength (); 
 	RK_ASSERT (argnames_data->getDataType () == RData::StringVector);
 	RK_ASSERT (argvalues_data->getDataType () == RData::StringVector);
 
-	RK_ASSERT (new_arglen == argvalues_data->getDataLength ());
-	QString *new_argnames = argnames_data->getStringVector ();
-	QString *new_argvalues = argvalues_data->getStringVector ();
-	argnames_data->detachData ();
-	argvalues_data->detachData ();
+	QStringList new_argnames = argnames_data->getStringVector ();
+	QStringList new_argvalues = argvalues_data->getStringVector ();
+	RK_ASSERT (new_argnames.size () == new_argvalues.size ());
 
-	bool changed = false;
-	if (new_arglen != argcount) {
-		changed = true;
-	} else {
-		for (unsigned int i = 0; i < new_arglen; ++i) {
-			if (argnames[i] != new_argnames[i]) {
-				changed = true;
-				break;
-			}
-
-			if (argvalues[i] != new_argvalues[i]) {
-				changed = true;
-				break;
-			}
-		}
+	if ((new_argnames != argnames) || (new_argvalues != argvalues)) {
+		argnames = new_argnames;
+		argvalues = new_argvalues;
+		return true;
 	}
-
-	argcount = new_arglen;
-	delete [] argnames;
-	delete [] argvalues;
-	argnames = new_argnames;
-	argvalues = new_argvalues;
-
-	return changed;
+	return false;
 }

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/core/rfunctionobject.h
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/core/rfunctionobject.h	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/core/rfunctionobject.h	2010-11-02 12:23:51 UTC (rev 3171)
@@ -36,9 +36,8 @@
 	bool updateStructure (RData *new_data);
 	QString printArgs () const;
 protected:
-	unsigned int argcount;
-	QString *argnames;
-	QString *argvalues;
+	QStringList argnames;
+	QStringList argvalues;
 	bool updateArguments (RData *new_data);
 };
 

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/core/rkrownames.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/core/rkrownames.cpp	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/core/rkrownames.cpp	2010-11-02 12:23:51 UTC (rev 3171)
@@ -214,7 +214,7 @@
 	lockSyncing (false);
 }
 
-void RKRowNames::setCharacterFromR (int from_row, int to_row, QString *data) {
+void RKRowNames::setCharacterFromR (int from_row, int to_row, const QStringList &data) {
 	RK_TRACE (OBJECTS);
 
 	is_sequential_up_to_row = -1;

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/core/rkrownames.h
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/core/rkrownames.h	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/core/rkrownames.h	2010-11-02 12:23:51 UTC (rev 3171)
@@ -43,7 +43,7 @@
 	void insertRows (int row, int count);
 protected:
 /** Reimplemented to disable duplicate checks during the setText() calls within */
-	void setCharacterFromR (int from_row, int to_row, QString *data);
+	void setCharacterFromR (int from_row, int to_row, const QStringList &data);
 /** Reimplemented to assume sequential row number on initialization */
 	void beginEdit ();
 private:

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/core/rkvariable.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/core/rkvariable.cpp	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/core/rkvariable.cpp	2010-11-02 12:23:51 UTC (rev 3171)
@@ -158,13 +158,13 @@
 			setNumericFromR (0, getLength () - 1, cdata->getRealVector ());
 		} else if (cdata->getDataType () == RData::IntVector) {
 			unsigned int len = getLength ();
-			double *dd = new double[len];
+			QVector<double> dd;
+			dd.reserve (len);
 			for (unsigned int i = 0; i < len; ++i) {
 				if (cdata->getIntVector ()[i] == INT_MIN) dd[i] = NAN;
 				else dd[i] = (double) cdata->getIntVector ()[i];
 			}
 			setNumericFromR (0, getLength () - 1, dd);
-			delete [] dd;
 		}
 
 		// now set the invalid fields (only if they are still NAs in the R data)
@@ -206,7 +206,7 @@
 void RKVariable::setLength (int len) {
 	RK_TRACE (OBJECTS);
 	RK_ASSERT (!getLength ());	// should only be called once
-	RK_ASSERT (dimensions);
+	RK_ASSERT (!dimensions.isEmpty ());
 
 	dimensions[0] = len;
 }
@@ -514,9 +514,10 @@
 	return getText (row);
 }
 
-void RKVariable::setNumericFromR (int from_row, int to_row, double *numdata) {
+void RKVariable::setNumericFromR (int from_row, int to_row, const QVector<double> &numdata) {
 	RK_TRACE (OBJECTS);
 	RK_ASSERT (to_row < getLength ());
+	RK_ASSERT ((to_row - from_row) < numdata.size ());
 
 	if (getDataType () == DataCharacter) {
 		RK_ASSERT (false);		// asserting false to catch cases of this use for now. it's not really a problem, though
@@ -575,9 +576,10 @@
 	return ret;
 }
 
-void RKVariable::setCharacterFromR (int from_row, int to_row, QString *txtdata) {
+void RKVariable::setCharacterFromR (int from_row, int to_row, const QStringList &txtdata) {
 	RK_TRACE (OBJECTS);
 	RK_ASSERT (to_row < getLength ());
+	RK_ASSERT ((to_row - from_row) < txtdata.size ());
 
 	lockSyncing (true);
 	int i=0;

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/core/rkvariable.h
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/core/rkvariable.h	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/core/rkvariable.h	2010-11-02 12:23:51 UTC (rev 3171)
@@ -130,9 +130,9 @@
 /** Discards pending unsynced changes. */
 	void discardUnsyncedChanges ();
 /** like setNumeric, but sets chars. If internalStorage () is numeric, attempts to convert the given strings to numbers. I.e. the function behaves essentially like setText (), but operates on a range of cells. Code may assume that all data comes directly from R, is entirely valid in R. */
-	virtual void setCharacterFromR (int from_row, int to_row, QString *data);
+	virtual void setCharacterFromR (int from_row, int to_row, const QStringList &data);
 /** set numeric values in the given range. Assumes you provide enough values for the range. If internalStorage is String, all values will be converted to strings, so you should use this function only, if you know you are dealing with a numeric object. Code may assume that all data comes directly from R, is entirely valid in R. */
-	void setNumericFromR (int from_row, int to_row, double *data);
+	void setNumericFromR (int from_row, int to_row, const QVector<double> &data);
 /** reimplemented from RObject to change the internal data storage mode, if the var is being edited */
 	bool updateType (RData *new_data);
 /** Extended from RObject::EditData to actually contain data. */

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/core/robject.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/core/robject.cpp	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/core/robject.cpp	2010-11-02 12:23:51 UTC (rev 3171)
@@ -33,6 +33,10 @@
 
 #include "../debug.h"
 
+namespace RObjectPrivate {
+	QVector<qint32> dim_null (1, 0);
+}
+
 RObject::RObject (RContainerObject *parent, const QString &name) {
 	RK_TRACE (OBJECTS);
 	
@@ -40,18 +44,12 @@
 	RObject::name = name;
 	type = 0;
 	meta_map = 0;
-	classnames = 0;
-	num_classes = 0;
-	dimensions = new int[1];	// safe initialization
-	dimensions[0] = 0;
-	num_dimensions = 0;
+	dimensions = RObjectPrivate::dim_null;	// safe initialization
 }
 
 RObject::~RObject () {
 	RK_TRACE (OBJECTS);
 
-	delete [] dimensions;
-	delete [] classnames;
 	cancelOutstandingCommands ();
 }
 
@@ -139,11 +137,11 @@
 	}
 
 	if (isType (Container | Variable)) {
-		if (num_dimensions == 1) {
+		if (dimensions.size () == 1) {
 			ret.append ("<br><b>" + i18n ("Length: ") + QString::number (dimensions[0]));
-		} else if (num_dimensions > 1) {
+		} else if (dimensions.size () > 1) {
 			ret.append ("<br><b>" + i18n ("Dimensions: "));
-			for (unsigned int i=0; i < num_dimensions; ++i) {
+			for (int i=0; i < dimensions.size (); ++i) {
 				if (i) ret.append (", ");
 				ret.append (QString::number (dimensions[i]));
 			}
@@ -191,25 +189,13 @@
 
 QString RObject::makeClassString (const QString &sep) const {
 	RK_TRACE (OBJECTS);
-	QString ret;
-	bool first = true;
-	for (unsigned int i=0; i < numClasses (); ++i) {
-		if (first) first = false;
-		else ret.append (sep);
-		ret.append (getClassName (i));
-	}
-	return ret;
+	return (classnames.join (sep));
 }
 
 bool RObject::inherits (const QString &class_name) const {
 	RK_TRACE (OBJECTS);
 
-	for (unsigned int i=0; i < numClasses (); ++i) {
-		if (getClassName (i) == class_name) {
-			return true;
-		}
-	}
-	return false;
+	return (classnames.contains (class_name));
 }
 
 QString RObject::makeChildName (const QString &short_child_name, bool) const {
@@ -402,25 +388,12 @@
 
 	bool change = false;
 
-	unsigned int new_len = new_data->getDataLength ();
-	QString *new_classes = new_data->getStringVector ();
-	new_data->detachData ();
-
-	if (numClasses () != new_len) {
+	QStringList new_classes = new_data->getStringVector ();
+	if (new_classes != classnames) {
 		change = true;
-	} else {
-		for (unsigned int cn=0; cn < numClasses (); ++cn) {
-			if (classnames[cn] != new_classes[cn]) {
-				change = true;
-				break;
-			}
-		}
+		classnames = new_classes;
 	}
 
-	num_classes = new_len;
-	delete [] classnames;
-	classnames = new_classes;
-
 	return change;
 }
 
@@ -462,27 +435,19 @@
 	RK_ASSERT (new_data->getDataLength () >= 1);
 	RK_ASSERT (new_data->getDataType () == RData::IntVector);
 
-	bool changed = false;
-
-	unsigned int new_len = new_data->getDataLength ();
-	int *new_dimensions = new_data->getIntVector ();
-	new_data->detachData ();
-
-	if (num_dimensions != new_len) {
-		changed = true;
-	} else {
-		for (unsigned int d=0; d < num_dimensions; ++d) {
-			if (dimensions[d] != new_dimensions[d]) {
-				changed = true;
-				break;
+	QVector<qint32> new_dimensions = new_data->getIntVector ();
+	if (new_dimensions != dimensions) {
+		if (new_dimensions.isEmpty ()) {
+			if (dimensions != RObjectPrivate::dim_null) {
+				dimensions = RObjectPrivate::dim_null;
+				return true;
 			}
+		} else {
+			dimensions = new_dimensions;
+			return true;
 		}
 	}
-	delete [] dimensions;
-	num_dimensions = new_len;
-	dimensions = new_dimensions;
-
-	return true;
+	return false;
 }
 
 void RObject::rename (const QString &new_short_name) {

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/core/robject.h
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/core/robject.h	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/core/robject.h	2010-11-02 12:23:51 UTC (rev 3171)
@@ -118,17 +118,14 @@
 	void rename (const QString &new_short_name);
 	void remove (bool removed_in_workspace);
 
-	unsigned int numClasses () const { return num_classes; };
-	QString getClassName (int index) const { return classnames[index]; };
+	const QStringList &classNames () const { return classnames; };
 	QString makeClassString (const QString &sep) const;
 /** @param class_name the name of the class to check for
 @returns true, if the object has (among others) the given class, false otherwise */
 	bool inherits (const QString &class_name) const;
 
-/** get number of dimensions. For simplicity, In RKWard each object is considered to have at least one dimension (but that dimension may be 0 in length) */
-	unsigned int numDimensions () const { return num_dimensions; };
-/** get the length of the given dimension. The object is guaranteed to have at least 1 dimension, so calling getDimension (0) is always safe */
-	int getDimension (int index) const { return dimensions[index]; };
+/** get vector of dimensions. For simplicity, In RKWard each object is considered to have at least one dimension (but that dimension may be 0 in length) */
+	const QVector<qint32> &getDimensions () const { return dimensions; };
 /** short hand for getDimension (0). Meaningful for one-dimensional objects */
 	int getLength () const { return dimensions[0]; };
 
@@ -195,10 +192,8 @@
 	RContainerObject *parent;
 	QString name;
 	int type;
-	int *dimensions;
-	unsigned int num_dimensions;
-	QString *classnames;
-	unsigned int num_classes;
+	QVector<qint32> dimensions;
+	QStringList classnames;
 
 	virtual QString makeChildBaseName (const QString &short_child_name) const;
 

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/plugin/rkcomponentproperties.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/plugin/rkcomponentproperties.cpp	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/plugin/rkcomponentproperties.cpp	2010-11-02 12:23:51 UTC (rev 3171)
@@ -744,7 +744,7 @@
 
 	// first check dimensionality
 	if (dims > 0) {
-		if ((int) object->numDimensions () != dims) return false;
+		if (object->getDimensions ().size () != dims) return false;
 	}
 	int olength = object->getLength ();
 	if ((min_length > 0) && (olength < min_length)) return false;

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rcommand.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rcommand.cpp	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rcommand.cpp	2010-11-02 12:23:51 UTC (rev 3171)
@@ -178,7 +178,7 @@
 	id = from->_id;
 	status = from->status;
 	RK_ASSERT (status == 0);	// Initialization from an already touched command is not a real problem, but certainly no expected usage
-	RK_ASSERT (from->datatype == RData::NoData);
+	RK_ASSERT (from->getDataType () == RData::NoData);
 }
 
 RCommandProxy::RCommandProxy (const QString &command, int type) {
@@ -194,7 +194,7 @@
 RCommandProxy::~RCommandProxy () {
 	RK_TRACE (RBACKEND);
 
-	RK_ASSERT ((type & RCommand::Internal) || (datatype == RData::NoData));
+	RK_ASSERT ((type & RCommand::Internal) || (getDataType () == RData::NoData));
 }
 
 void RCommandProxy::mergeAndDelete (RCommand *to) {
@@ -204,6 +204,6 @@
 	RK_ASSERT (to->_type == type);
 
 	to->status = status;
-	to->setData (*this);
+	to->swallowData (*this);
 	delete this;
 }

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rdata.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rdata.cpp	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rdata.cpp	2010-11-02 12:23:51 UTC (rev 3171)
@@ -25,7 +25,6 @@
 	RK_TRACE (RBACKEND);
 	datatype = NoData;
 	data = 0;
-	length = 0; 
 }
 
 RData::~RData () {
@@ -34,93 +33,113 @@
 	discardData ();
 }
 
-double *RData::getRealVector () const {
-	return (static_cast<double *> (data));
+RData::RealStorage &RData::getRealVector () const {
+	return (*static_cast<RealStorage *> (data));
 }
 
-int *RData::getIntVector () const {
-	return (static_cast<int *> (data));
+RData::IntStorage &RData::getIntVector () const {
+	return (*static_cast<IntStorage *> (data));
 }
 
-QString *RData::getStringVector () const {
-	return (static_cast<QString *> (data));
+RData::StringStorage &RData::getStringVector () const {
+	return (*static_cast<StringStorage *> (data));
 }
 
-RData **RData::getStructureVector () const {
-	return (static_cast<RData **> (data));
+RData::RDataStorage &RData::getStructureVector () const {
+	return (*static_cast<RDataStorage *> (data));
 }
 
-void RData::detachData () {
-	data = 0;
-	length = 0;
-	datatype = NoData;
-}
-
 void RData::discardData () {
 	RK_TRACE (RBACKEND);
 
 	if (datatype == StructureVector) {
-		RData **sdata = getStructureVector ();
-		for (int i=length-1; i >= 0; --i) {
+		RDataStorage sdata = getStructureVector ();
+		for (int i=sdata.size ()-1; i >= 0; --i) {
 			delete (sdata[i]);
 		}
-		delete [] sdata;
+		delete (static_cast<RDataStorage *> (data));
 	} else if (datatype == IntVector) {
-		int *idata = getIntVector ();
-		delete [] idata;
+		delete (static_cast<IntStorage *> (data));
 	} else if (datatype == RealVector) {
-		double *rdata = getRealVector ();
-		delete [] rdata;
+		delete (static_cast<RealStorage *> (data));
 	} else if (datatype == StringVector) {
-		QString *stdata = getStringVector ();
-		delete [] stdata;
+		delete (static_cast<StringStorage *> (data));
 	} else {
 		RK_ASSERT (datatype == NoData);
 	}
 
-	detachData ();
+	data = 0;
+	datatype = RData::NoData;
 }
 
-void RData::setData (RData &from) {
+unsigned int RData::getDataLength() const {
+	if (datatype == RealVector) return (getRealVector ().size ());
+	if (datatype == IntVector) return (getIntVector ().size ());
+	if (datatype == StringVector) return (getStringVector ().size ());
+	if (datatype == StructureVector) return (getStructureVector ().size ());
+	return 0;
+}
+
+void RData::swallowData (RData &from) {
 	data = from.data;
-	length = from.length;
 	datatype = from.datatype;
 
-	from.detachData ();
+	from.data = 0;
+	from.datatype = RData::NoData;
 }
 
+void RData::setData (const RDataStorage &from) {
+	data = new RDataStorage (from);
+	datatype = RData::StructureVector;
+}
+
+void RData::setData (const IntStorage &from) {
+	data = new IntStorage (from);
+	datatype = RData::IntVector;
+}
+
+void RData::setData (const RealStorage &from) {
+	data = new RealStorage (from);
+	datatype = RData::RealVector;
+}
+
+void RData::setData (const StringStorage &from) {
+	data = new StringStorage (from);
+	datatype = RData::StringVector;
+}
+
 void RData::printStructure (const QString &prefix) {
 	switch (datatype) {
 		case NoData:
-			qDebug ("%s: NoData, length %d", prefix.toLatin1().data(), length);
+			qDebug ("%s: NoData, length %d", prefix.toLatin1().data(), getDataLength ());
 			break;
 		case IntVector:
-			qDebug ("%s: IntVector, length %d", prefix.toLatin1().data(), length);
-			for (unsigned int i = 0; i < length; ++i) {
+			qDebug ("%s: IntVector, length %d", prefix.toLatin1().data(), getDataLength ());
+			for (unsigned int i = 0; i < getDataLength (); ++i) {
 				qDebug ("%s%d: %d", prefix.toLatin1().data(), i, getIntVector ()[i]);
 			}
 			break;
 		case RealVector:
-			qDebug ("%s: RealVector, length %d", prefix.toLatin1().data(), length);
-			for (unsigned int i = 0; i < length; ++i) {
+			qDebug ("%s: RealVector, length %d", prefix.toLatin1().data(), getDataLength ());
+			for (unsigned int i = 0; i < getDataLength (); ++i) {
 				qDebug ("%s%d: %f", prefix.toLatin1().data(), i, getRealVector ()[i]);
 			}
 			break;
 		case StringVector:
-			qDebug ("%s: StringVector, length %d", prefix.toLatin1().data(), length);
-			for (unsigned int i = 0; i < length; ++i) {
+			qDebug ("%s: StringVector, length %d", prefix.toLatin1().data(), getDataLength ());
+			for (unsigned int i = 0; i < getDataLength (); ++i) {
 				qDebug ("%s%d: %s", prefix.toLatin1().data(), i, getStringVector ()[i].toLatin1().data());
 			}
 			break;
 		case StructureVector:
-			qDebug ("%s: StructureVector, length %d", prefix.toLatin1().data(), length);
-			for (unsigned int i = 0; i < length; ++i) {
+			qDebug ("%s: StructureVector, length %d", prefix.toLatin1().data(), getDataLength ());
+			for (unsigned int i = 0; i < getDataLength (); ++i) {
 				QString sub_prefix = prefix + QString::number (i);
 				getStructureVector ()[i]->printStructure (sub_prefix);
 			}
 			break;
 		default:
-			qDebug ("%s: INVALID %d, length %d", prefix.toLatin1().data(), datatype, length);
+			qDebug ("%s: INVALID %d, length %d", prefix.toLatin1().data(), datatype, getDataLength ());
 	}
 	qDebug ("%s: END\n\n", prefix.toLatin1 ().data());
 }

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rdata.h
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rdata.h	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rdata.h	2010-11-02 12:23:51 UTC (rev 3171)
@@ -2,7 +2,7 @@
                           rdata  -  description
                              -------------------
     begin                : Sun Oct 01 2006
-    copyright            : (C) 2006 by Thomas Friedrichsmeier
+    copyright            : (C) 2006, 2010 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -18,7 +18,9 @@
 #ifndef RDATA_H
 #define RDATA_H
 
-class QString;
+#include <QVector>
+#include <QStringList>
+
 /** Class to represent data (other than output/erros) passed from the R backend to the main thread. Data is usually a vector of type int, double or QString, but can also contain a hierarchy of RData*s. RCommand is a subclass of this */
 class RData {
 public:
@@ -32,32 +34,35 @@
 		NoData=4
 	};
 
+	typedef QVector<qint32> IntStorage;
+	typedef QVector<double> RealStorage;
+	typedef QVector<RData*> RDataStorage;
+	typedef QStringList StringStorage;
 /** returns the type of data contained */
-	RDataType getDataType () { return datatype; };
+	RDataType getDataType () const { return datatype; };
 /** returns the length (size) of the data array. @see RCommand::GetStringVector @see RCommand::GetRealVector @see RCommand::GetIntVector @see RCommand:GetStructure */
-	unsigned int getDataLength () { return length; };
-/** returns an array of double, if that is the type of data contained (else 0). The array is owned by the RCommand! @see RCommand::GetRealVector @see RData::detachData () @see RData::getDataLength () @see RData::getDataType () */
-	double *getRealVector () const;
-/** returns an array of int, if that is the type of data contained (else 0). The array is owned by the RCommand! @see RCommand::GetIntVector @see RData::detachData () @see RData::getDataLength () @see RData::getDataType () */
-	int *getIntVector () const;
-/** returns an array of QString, if that is the type of data contained (else 0). The array is owned by the RCommand! @see RCommand::GetStringVector @see RData::detachData () @see RData::getDataLength () @see RData::getDataType () */
-	QString *getStringVector () const;
-/** returns an array of RData*, if that is the type of data contained (else 0). The array is owned by the RCommand! @see RCommand::GetStructureVector @see RData::detachData () @see RData::getDataLength () @see RData::getDataType () */
-	RData **getStructureVector () const;
-/** The data contained in the RData structure is owned by RData, and will usually be deleted at the end of the lifetime of the RData object. If you want to keep the data, call detachData () to prevent this deletion. You will be responsible for deletion of the data yourself. */
-	void detachData ();
+	unsigned int getDataLength () const;
+/** returns an array of double, if that is the type of data contained (else 0). @see RCommand::GetRealVector @see RData::getDataLength () @see RData::getDataType () */
+	RealStorage &getRealVector () const;
+/** returns an array of int, if that is the type of data contained (else 0). @see RCommand::GetIntVector @see RData::getDataLength () @see RData::getDataType () */
+	IntStorage &getIntVector () const;
+/** returns an array of QString, if that is the type of data contained (else 0). @see RCommand::GetStringVector @see RData::getDataLength () @see RData::getDataType () */
+	StringStorage &getStringVector () const;
+/** returns an array of RData*, if that is the type of data contained (else 0). @see RCommand::GetStructureVector @see RData::getDataLength () @see RData::getDataType () */
+	RDataStorage &getStructureVector () const;
 	void discardData ();
 /** purely for debugging! */
 	void printStructure (const QString &prefix);
 
+	void setData (const RDataStorage &from);
+	void setData (const IntStorage &from);
+	void setData (const RealStorage &from);
+	void setData (const StringStorage &from);
 /** public for technical reasons only. Do not use! Move data from the given RData to this RData. The source RData is emptied! */
-	void setData (RData &from);
-/** public for technical reasons only. Do not use! */
+	void swallowData (RData &from);
+private:
 	RDataType datatype;
-/** public for technical reasons only. Do not use! */
 	void *data;
-/** public for technical reasons only. Do not use! */
-	unsigned int length;
 };
 
 #endif

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.cpp	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rembedinternal.cpp	2010-11-02 12:23:51 UTC (rev 3171)
@@ -426,30 +426,16 @@
 SEXP doShowEditFiles (SEXP files, SEXP titles, SEXP wtitle, SEXP del, RBackendRequest::RCallbackType edit) {
 	RK_TRACE (RBACKEND);
 
-	// this function would be much shorter, if SEXPToStringList would simply return a QStringList...
-	unsigned int files_count, titles_count;
-	QString *file_strings = RKRSupport::SEXPToStringList (files, &files_count);
-	QString *title_strings = RKRSupport::SEXPToStringList (titles, &titles_count);
+	QStringList file_strings = RKRSupport::SEXPToStringList (files);
+	QStringList title_strings = RKRSupport::SEXPToStringList (titles);
 	QString wtitle_string = RKRSupport::SEXPToString (wtitle);
 	bool del_files = RKRSupport::SEXPToInt (del, 0) != 0;
 
-	RK_ASSERT (files_count == titles_count);
-	RK_ASSERT (files_count >= 1);
+	RK_ASSERT (file_strings.size () == title_strings.size ());
+	RK_ASSERT (file_strings.size () >= 1);
 
-	files_count = titles_count = qMin (files_count, titles_count);
+	REditFilesHelper (file_strings, title_strings, wtitle_string, edit, del_files);
 
-	QStringList files_list;
-	QStringList titles_list;
-	for (unsigned int i = 0; i < files_count; ++i) {
-		files_list.append (file_strings[i]);
-		titles_list.append (title_strings[i]);
-	}
-
-	REditFilesHelper (files_list, titles_list, wtitle_string, edit, del_files);
-
-	delete [] file_strings;
-	delete [] title_strings;
-
 	return (R_NilValue);
 }
 
@@ -698,13 +684,7 @@
 SEXP doSubstackCall (SEXP call) {
 	RK_TRACE (RBACKEND);
 
-	unsigned int count;
-	QString *strings = RKRSupport::SEXPToStringList (call, &count);
-	QStringList list;
-	for (unsigned int i = 0; i < count; ++i) {
-		list.append (strings[i]);
-	}
-	delete [] strings;
+	QStringList list = RKRSupport::SEXPToStringList (call);
 
 	// handle symbol updates inline
 	if (list.count () == 2) {		// schedule symbol update for later
@@ -983,7 +963,6 @@
 	RKWardRError error = NoError;
 
 	int ctype = command->type;	// easier typing
-	RData retdata;
 
 	// running user commands is quite different from all other commands and should have been handled by RReadConsole
 	RK_ASSERT (!(ctype & RCommand::User));
@@ -1000,17 +979,14 @@
 			PROTECT (exp = runCommandInternalBase (parsed, &error));
 			if (error == NoError) {
 				if (ctype & RCommand::GetStringVector) {
-					retdata.datatype = RData::StringVector;
-					retdata.data = RKRSupport::SEXPToStringList (exp, &(retdata.length));
+					command->setData (RKRSupport::SEXPToStringList (exp));
 				} else if (ctype & RCommand::GetRealVector) {
-					retdata.datatype = RData::RealVector;
-					retdata.data = RKRSupport::SEXPToRealArray (exp, &(retdata.length));
+					command->setData (RKRSupport::SEXPToRealArray (exp));
 				} else if (ctype & RCommand::GetIntVector) {
-					retdata.datatype = RData::IntVector;
-					retdata.data = RKRSupport::SEXPToIntArray (exp, &(retdata.length));
+					command->setData (RKRSupport::SEXPToIntArray (exp));
 				} else if (ctype & RCommand::GetStructuredData) {
 					RData *dummy = RKRSupport::SEXPToRData (exp);
-					retdata.setData (*dummy);
+					command->swallowData (*dummy);
 					delete dummy;
 				}
 			}
@@ -1024,7 +1000,6 @@
 		if (!RInterface::backendIsLocked () || killed) processX11Events ();
 	}
 
-	command->setData (retdata);
 	// common error/status handling
 	if (error != NoError) {
 		command->status |= RCommand::WasTried | RCommand::Failed;

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrsupport.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrsupport.cpp	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrsupport.cpp	2010-11-02 12:23:51 UTC (rev 3171)
@@ -78,47 +78,45 @@
 QString RKRSupport::SEXPToString (SEXP from_exp) {
 	RK_TRACE (RBACKEND);
 
-	QString ret;
+	QStringList list = SEXPToStringList (from_exp);
 
-	unsigned int count;
-	QString *list = SEXPToStringList (from_exp, &count);
-
-	if (count >= 1) ret = list[0];
-	delete [] list;
-	return ret;
+	if (!list.isEmpty ()) return list[0];
+	return QString ();
 }
 
-QString *RKRSupport::SEXPToStringList (SEXP from_exp, unsigned int *count) {
+QStringList RKRSupport::SEXPToStringList (SEXP from_exp) {
 	RK_TRACE (RBACKEND);
 
 	// bad format? coerce the vector first
 	if (TYPEOF (from_exp) != STRSXP) {
 		SEXP strexp;
 		PROTECT (strexp = Rf_coerceVector (from_exp, STRSXP));
-		QString *list = SEXPToStringList (strexp, count);
+		QStringList list = SEXPToStringList (strexp);
 		UNPROTECT (1);
 		return list;
 	}
 
 	// format already good? Avoid coercion (and associated copying)
-	*count = Rf_length (from_exp);
-	QString *list = new QString[*count];
-	unsigned int i = 0;
-	for (; i < *count; ++i) {
+	int count = Rf_length (from_exp);
+	QStringList list;
+#if QT_VERSION >= 0x040700
+	list.reserve (count);
+#endif
+	for (int i = 0; i < count; ++i) {
 		SEXP dummy = STRING_ELT (from_exp, i);
 
 		if (TYPEOF (dummy) != CHARSXP) {
-			list[i] = QString ("not defined");	// can this ever happen?
+			list.append (QString ("not defined"));	// can this ever happen?
 		} else {
 			if (dummy == NA_STRING) {
-				list[i] = QString::null;
+				list.append (QString ());
 			} else {
 				if (IS_UTF8 (dummy)) {
-					list[i] = QString::fromUtf8 ((char *) STRING_PTR (dummy));
+					list.append (QString::fromUtf8 ((char *) STRING_PTR (dummy)));
 				} else if (IS_LATIN1 (dummy)) {
-					list[i] = QString::fromLatin1 ((char *) STRING_PTR (dummy));
+					list.append (QString::fromLatin1 ((char *) STRING_PTR (dummy)));
 				} else {
-					list[i] = RThread::this_pointer->current_locale_codec->toUnicode ((char *) STRING_PTR (dummy));
+					list.append (RThread::this_pointer->current_locale_codec->toUnicode ((char *) STRING_PTR (dummy)));
 				}
 			}
 		}
@@ -127,25 +125,25 @@
 	return list;
 }
 
-int *RKRSupport::SEXPToIntArray (SEXP from_exp, unsigned int *count) {
+RData::IntStorage RKRSupport::SEXPToIntArray (SEXP from_exp) {
 	RK_TRACE (RBACKEND);
 
-	int *integers;
+	RData::IntStorage integers;
 
 	// bad format? coerce the vector first
 	if (TYPEOF (from_exp) != INTSXP) {
 		SEXP intexp;
 		PROTECT (intexp = Rf_coerceVector (from_exp, INTSXP));
-		integers = SEXPToIntArray (intexp, count);
+		integers = SEXPToIntArray (intexp);
 		UNPROTECT (1);
 		return integers;
 	}
 
 	// format already good? Avoid coercion (and associated copying)
-	*count = Rf_length (from_exp);
-	integers = new int[*count];
-	for (unsigned int i = 0; i < *count; ++i) {
-		integers[i] = INTEGER (from_exp)[i];
+	unsigned int count = Rf_length (from_exp);
+	integers.reserve (count);
+	for (unsigned int i = 0; i < count; ++i) {
+		integers.append (INTEGER (from_exp)[i]);
 		if (integers[i] == R_NaInt) integers[i] = INT_MIN;		// this has no effect for now, but if R ever chnages it's R_NaInt, then it will
 	}
 	return integers;
@@ -155,34 +153,30 @@
 int RKRSupport::SEXPToInt (SEXP from_exp, int def_value) {
 	RK_TRACE (RBACKEND);
 
-	int ret = def_value;
-	unsigned int count;
-	int *integers = SEXPToIntArray (from_exp, &count);
-	if (count >= 1) ret = integers[0];
-	delete [] integers;
-
-	return ret;
+	RData::IntStorage integers = SEXPToIntArray (from_exp);
+	if (!integers.isEmpty ()) return integers[0];
+	return def_value;
 }
 
-double *RKRSupport::SEXPToRealArray (SEXP from_exp, unsigned int *count) {
+RData::RealStorage RKRSupport::SEXPToRealArray (SEXP from_exp) {
 	RK_TRACE (RBACKEND);
 
-	double *reals;
+	RData::RealStorage reals;
 
 	// bad format? coerce the vector first
 	if (TYPEOF (from_exp) != REALSXP) {
 		SEXP realexp;
 		PROTECT (realexp = Rf_coerceVector (from_exp, REALSXP));
-		reals = SEXPToRealArray (realexp, count);
+		reals = SEXPToRealArray (realexp);
 		UNPROTECT (1);
 		return reals;
 	}
 	
 	// format already good? Avoid coercion (and associated copying)
-	*count = Rf_length (from_exp);
-	reals = new double[*count];
-	for (unsigned int i = 0; i < *count; ++i) {
-		reals[i] = REAL (from_exp)[i];
+	unsigned int count = Rf_length (from_exp);
+	reals.reserve (count);
+	for (unsigned int i = 0; i < count; ++i) {
+		reals.append (REAL (from_exp)[i]);
 		if (R_IsNaN (reals[i]) || R_IsNA (reals[i]) ) reals[i] = RKGlobals::na_double;
 	}
 	return reals;
@@ -193,32 +187,28 @@
 
 	RData *data = new RData;
 
-	unsigned int count;
 	int type = TYPEOF (from_exp);
 	switch (type) {
 		case LGLSXP:
 		case INTSXP:
-			data->data = SEXPToIntArray (from_exp, &count);
-			data->datatype = RData::IntVector;
+			data->setData (SEXPToIntArray (from_exp));
 			break;
 		case REALSXP:
-			data->data = SEXPToRealArray (from_exp, &count);
-			data->datatype = RData::RealVector;
+			data->setData (SEXPToRealArray (from_exp));
 			break;
 		case VECSXP:
-			count = 0;
-			count = Rf_length (from_exp);
 			{
-				RData **structure_array = new RData*[count];
+				unsigned int count = Rf_length (from_exp);
+				RData::RDataStorage structure_array;
+				structure_array.reserve (count);
 				for (unsigned int i=0; i < count; ++i) {
 					SEXP subexp = VECTOR_ELT (from_exp, i);
 					//PROTECT (subexp);	// should already be protected as part of the parent from_exp
-					structure_array[i] = SEXPToRData (subexp);
+					structure_array.append (SEXPToRData (subexp));
 					//UNPROTECT (1);
 				}
-				data->data = structure_array;
+				data->setData (structure_array);
 			}
-			data->datatype = RData::StructureVector;
 			break;
 /*		case NILSXP:
 			data->data = 0;
@@ -230,16 +220,12 @@
 				delete data;
 				data = (RData*) R_ExternalPtrAddr (from_exp);
 				R_ClearExternalPtr (from_exp);
-				count = data->length;
 				break;
 			}
 		case STRSXP:
 		default:
-			data->data = SEXPToStringList (from_exp, &count);
-			data->datatype = RData::StringVector;
+			data->setData (SEXPToStringList (from_exp));
 	}
 
-	data->length = count;
-
 	return data;
 }

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrsupport.h
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrsupport.h	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkrsupport.h	2010-11-02 12:23:51 UTC (rev 3171)
@@ -34,12 +34,12 @@
 	SEXP callSimpleFun2 (SEXP fun, SEXP arg1, SEXP arg2, SEXP env);
 	bool callSimpleBool (SEXP fun, SEXP arg, SEXP env);
 
-	QString *SEXPToStringList (SEXP from_exp, unsigned int *count);
+	QStringList SEXPToStringList (SEXP from_exp);
 	QString SEXPToString (SEXP from_exp);
-	int *SEXPToIntArray (SEXP from_exp, unsigned int *count);
+	RData::IntStorage SEXPToIntArray (SEXP from_exp);
 	int SEXPToInt (SEXP from_exp, int def_value = INT_MIN);
-	double *SEXPToRealArray (SEXP from_exp, unsigned int *count);
-	RData *SEXPToRData (SEXP from_exp);
+	RData::RealStorage SEXPToRealArray (SEXP from_exp);
+	RData* SEXPToRData (SEXP from_exp);
 };
 
 #endif

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkstructuregetter.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkstructuregetter.cpp	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/rbackend/rkstructuregetter.cpp	2010-11-02 12:23:51 UTC (rev 3171)
@@ -84,10 +84,7 @@
 	envir_depth = INTEGER (envlevel)[0];
 
 	unsigned int count;
-	QString *name_dummy = RKRSupport::SEXPToStringList (name, &count);
-	RK_ASSERT (count == 1);
-	QString name_string = name_dummy[0];
-	delete [] name_dummy;
+	QString name_string = RKRSupport::SEXPToString (name);
 
 	// resolve namespace, if needed
 	if (Rf_isNull (namespacename)) {
@@ -187,11 +184,7 @@
 
 	// first field: get name
 	RData *namedata = new RData;
-	namedata->datatype = RData::StringVector;
-	namedata->length = 1;
-	QString *name_dummy = new QString[1];
-	name_dummy[0] = name;
-	namedata->data = name_dummy;
+	namedata->setData (QStringList (name));
 
 	// get classes
 	SEXP classes_s;
@@ -208,18 +201,15 @@
 		PROTECT (classes_s);
 	}
 
-	QString *classes = RKRSupport::SEXPToStringList (classes_s, &count);
-	unsigned int num_classes = count;
+	QStringList classes = RKRSupport::SEXPToStringList (classes_s);
 	UNPROTECT (1);	/* classes_s */
 
 	// store classes
 	RData *classdata = new RData;
-	classdata->datatype = RData::StringVector;
-	classdata->data = classes;
-	classdata->length = num_classes;
+	classdata->setData (classes);
 
 	// basic classification
-	for (unsigned int i = 0; i < num_classes; ++i) {
+	for (int i = classes.size () - 1; i >= 0; --i) {
 #warning: Using is.data.frame() may be more reliable (would need to be called only on List-objects, thus no major performance hit)
 		if (classes[i] == "data.frame") type |= RObject::DataFrame;
 	}
@@ -251,73 +241,54 @@
 
 	// get meta data, if any
 	RData *metadata = new RData;
-	metadata->datatype = RData::StringVector;
 	if (!Rf_isNull (Rf_getAttrib (value, meta_attrib))) {
 		type |= RObject::HasMetaObject;
 
 		SEXP meta_s = RKRSupport::callSimpleFun (get_meta_fun, value, R_GlobalEnv);
 		PROTECT (meta_s);
-		metadata->data = RKRSupport::SEXPToStringList (meta_s, &count);
-		metadata->length = count;
+		metadata->setData (RKRSupport::SEXPToStringList (meta_s));
 		UNPROTECT (1);	/* meta_s */
 	} else {
-		metadata->length = 1;
-		QString *meta_dummy = new QString[1];
-		meta_dummy[0] = "";
-		metadata->data = meta_dummy;
+		metadata->setData (QStringList (QString ("")));
 	}
 
 	// store type
 	RData *typedata = new RData;
-	typedata->datatype = RData::IntVector;
-	typedata->length = 1;
-	int *type_dummy = new int[1];
-	type_dummy[0] = type;
-	typedata->data = type_dummy;
+	typedata->setData (RData::IntStorage (1, type));
 
 	// get dims
-	int *dims;
-	unsigned int num_dims;
+	RData::IntStorage dims;
 	SEXP dims_s = RKRSupport::callSimpleFun (dims_fun, value, R_BaseEnv);
 	if (!Rf_isNull (dims_s)) {
-		dims = RKRSupport::SEXPToIntArray (dims_s, &num_dims);
+		dims = RKRSupport::SEXPToIntArray (dims_s);
 	} else {
-		num_dims = 1;
-
 		unsigned int len = Rf_length (value);
 		if ((len < 2) && (!is_function)) {		// suspicious. Maybe some kind of list
 			SEXP len_s = RKRSupport::callSimpleFun (length_fun, value, R_BaseEnv);
 			PROTECT (len_s);
 			if (Rf_isNull (len_s)) {
-				dims = new int[1];
-				dims[0] = len;
+				dims.append (len);
 			} else {
-				dims = RKRSupport::SEXPToIntArray (len_s, &num_dims);
+				dims = RKRSupport::SEXPToIntArray (len_s);
 			}
 			UNPROTECT (1); /* len_s */
 		} else {
-			dims = new int[1];
-			dims[0] = len;
+			dims.append (len);
 		}
 	}
 
 	// store dims
 	RData *dimdata = new RData;
-	dimdata->datatype = RData::IntVector;
-	dimdata->length = num_dims;
-	dimdata->data = dims;
+	dimdata->setData (dims);
 
 	// store everything we have so far
+	int storage_length = 5;
 	if (is_container) {
-		storage->length = 6;
+		storage_length = 6;
 	} else if (is_function) {
-		storage->length = 7;
-	} else {
-		storage->length = 5;
+		storage_length = 7;
 	}
-	storage->datatype = RData::StructureVector;
-	RData **res = new RData*[storage->length];
-	storage->data = res;
+	RData::RDataStorage res (storage_length, 0);
 	res[0] = namedata;
 	res[1] = typedata;
 	res[2] = classdata;
@@ -329,14 +300,7 @@
 		bool do_env = (is_environment && (++envir_depth < 2));
 		bool do_cont = is_container && (!is_environment);
 
-		RData *childdata = new RData;
-		childdata->datatype = RData::StructureVector;
-		childdata->length = 0;
-		childdata->data = 0;
-		res[5] = childdata;
-
 		// fetch list of child names
-		unsigned int childcount;
 		SEXP childnames_s;
 		if (do_env) {
 			childnames_s = R_lsInternal (value, (Rboolean) 1);
@@ -346,17 +310,12 @@
 			childnames_s = R_NilValue; // dummy
 		}
 		PROTECT (childnames_s);
-		QString *childnames = RKRSupport::SEXPToStringList (childnames_s, &childcount);
+		QStringList childnames = RKRSupport::SEXPToStringList (childnames_s);
+		unsigned int childcount = childnames.size ();
 
-		childdata->length = childcount;
-		RData **children = new RData*[childcount];
-		childdata->data = children;
-		childdata->length = childcount;
-		for (unsigned int i = 0; i < childcount; ++i) {		// in case there is an error while fetching one of the children, let's pre-initialize everything.
-			children[i] = new RData;
-			children[i]->data = 0;
-			children[i]->length = 0;
-			children[i]->datatype = RData::NoData;
+		RData::RDataStorage children (childcount, 0);
+		for (unsigned int i = 0; i < childcount; ++i) {
+			children[i] = new RData ();		// NOTE: RData-ctor pre-initalizes these to empty. Thus, we're safe even if there is an error while fetching one of the children.
 		}
 
 		if (do_env) {
@@ -367,7 +326,7 @@
 				REPROTECT (value = RKRSupport::callSimpleFun (as_environment_fun, value, R_GlobalEnv), value_index);
 			}
 			for (unsigned int i = 0; i < childcount; ++i) {
-				SEXP current_childname = Rf_install(CHAR(STRING_ELT(childnames_s, i)));
+				SEXP current_childname = Rf_install(CHAR(STRING_ELT(childnames_s, i)));		// ??? Why does simply using STRING_ELT(childnames_i, i) crash?
 				PROTECT (current_childname);
 				SEXP child = Rf_findVar (current_childname, value);
 				PROTECT (child);
@@ -381,7 +340,7 @@
 				}
 
 				getStructureSafe (child, childnames[i], child_misplaced, children[i]);
-				UNPROTECT (2); /* childname, child */
+				UNPROTECT (2); /* current_childname, child */
 			}
 		} else if (do_cont) {
 			RK_DO (qDebug ("recurse into list %s", name.toLatin1().data ()), RBACKEND, DL_DEBUG);
@@ -411,35 +370,34 @@
 			}
 		}
 		UNPROTECT (1);   /* childnames_s */
-		delete [] childnames;
-	} else if (is_function) {
-		RData *funargsdata = new RData;
-		funargsdata->datatype = RData::StringVector;
-		funargsdata->length = 0;
-		funargsdata->data = 0;
-		res[5] = funargsdata;
 
-		RData *funargvaluesdata = new RData;
-		funargvaluesdata->datatype = RData::StringVector;
-		funargvaluesdata->length = 0;
-		funargvaluesdata->data = 0;
-		res[6] = funargvaluesdata;
-
-// TODO: this is still the major bottleneck, but no idea, how to improve on this
+		RData *childdata = new RData;
+		childdata->setData (children);
+		res[5] = childdata;
+	} else if (is_function) {
+// TODO: get_formals_fun is still the major bottleneck, but no idea, how to improve on this
 		SEXP formals_s = RKRSupport::callSimpleFun (get_formals_fun, value, R_GlobalEnv);
 		PROTECT (formals_s);
 		// the default values
-		funargvaluesdata->data = RKRSupport::SEXPToStringList (formals_s, &(funargvaluesdata->length));
+		RData *funargvaluesdata = new RData;
+		funargvaluesdata->setData (RKRSupport::SEXPToStringList (formals_s));
 
 		// the argument names
 		SEXP names_s = Rf_getAttrib (formals_s, R_NamesSymbol);
 		PROTECT (names_s);
-		funargsdata->data = RKRSupport::SEXPToStringList (names_s, &(funargsdata->length));
+		RData *funargsdata = new RData;
+		funargsdata->setData (RKRSupport::SEXPToStringList (names_s));
 
 		UNPROTECT (2); /* names_s, formals_s */
+
+		res[5] = funargsdata;
+		res[6] = funargvaluesdata;
 	}
 
 	UNPROTECT (1); /* value */
+
+	RK_ASSERT (!res.contains (0));
+	storage->setData (res);
 }
 
 }	/* extern "C" */

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/scriptbackends/rkcomponentscripting.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/scriptbackends/rkcomponentscripting.cpp	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/scriptbackends/rkcomponentscripting.cpp	2010-11-02 12:23:51 UTC (rev 3171)
@@ -171,16 +171,12 @@
 		QVariantList ret;
 
 		QVariantList dims;
-		for (unsigned int i = 0; i < object->numDimensions (); ++i) {
-			dims.append (object->getDimension (i));
+		foreach (int dim, object->getDimensions ()) {
+			dims.append (dim);
 		}
 		ret.append (QVariant (dims));
 
-		QStringList classes;
-		for (unsigned int i = 0; i < object->numClasses (); ++i) {
-			classes.append (object->getClassName (i));
-		}
-		ret.append (QVariant (classes));
+		ret.append (QVariant (object->classNames ()));
 
 		ret.append (object->isType (RObject::DataFrame));
 		ret.append (object->isType (RObject::Matrix));

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/settings/rksettingsmoduler.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/settings/rksettingsmoduler.cpp	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/settings/rksettingsmoduler.cpp	2010-11-02 12:23:51 UTC (rev 3171)
@@ -418,7 +418,7 @@
 
 	if (command->getFlags () == SELECT_CRAN_MIRROR_COMMAND) {
 		if (command->succeeded ()) {
-			RK_ASSERT (command->getStringVector ());
+			RK_ASSERT (command->getDataLength () >= 1);
 			cran_mirror_input->setText (command->getStringVector ()[0]);
 		}
 	} else {

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/windows/rkcommandlog.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/windows/rkcommandlog.cpp	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/windows/rkcommandlog.cpp	2010-11-02 12:23:51 UTC (rev 3171)
@@ -70,6 +70,8 @@
 
 RKCommandLog::~RKCommandLog(){
 	RK_TRACE (APP);
+
+	RK_ASSERT (command_input_shown.isEmpty ());
 }
 
 void RKCommandLog::addInput (RCommand *command) {

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/windows/rkhelpsearchwindow.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/windows/rkhelpsearchwindow.cpp	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/windows/rkhelpsearchwindow.cpp	2010-11-02 12:23:51 UTC (rev 3171)
@@ -222,8 +222,7 @@
 		RK_ASSERT ((command->getDataLength () % 3) == 0);
 		RK_ASSERT (command->getDataType () == RData::StringVector);
 
-		results->setResults (command->getStringVector (), command->getDataLength () / 3);
-		command->detachData ();		// now owned by the model
+		results->setResults (command->getStringVector ());
 
 		for (int i = 0; i < COL_COUNT; ++i) results_view->resizeColumnToContents (i);
 		setEnabled(true);
@@ -247,22 +246,18 @@
 RKHelpSearchResultsModel::RKHelpSearchResultsModel (QObject *parent) : QAbstractTableModel (parent) {
 	RK_TRACE (APP);
 
-	results = 0;
 	result_count = 0;
 }
 
 RKHelpSearchResultsModel::~RKHelpSearchResultsModel () {
 	RK_TRACE (APP);
-
-	delete [] results;
 }
 
-void RKHelpSearchResultsModel::setResults (QString* new_results, int new_result_count) {
+void RKHelpSearchResultsModel::setResults (const QStringList &new_results) {
 	RK_TRACE (APP);
 
-	delete [] results;
 	results = new_results;
-	result_count = new_result_count;
+	result_count = results.size () / 3;
 
 	reset ();
 }
@@ -285,7 +280,7 @@
 	// easier typing
 	int row = index.row ();
 	int col = index.column ();
-	if (results) {
+	if (result_count) {
 		if (role == Qt::DisplayRole || role == Qt::ToolTipRole) {
 			if (row < result_count) {
 				if (col < COL_COUNT) {

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/windows/rkhelpsearchwindow.h
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/windows/rkhelpsearchwindow.h	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/windows/rkhelpsearchwindow.h	2010-11-02 12:23:51 UTC (rev 3171)
@@ -78,14 +78,14 @@
 	~RKHelpSearchResultsModel ();
 
 /** Set the results. The model will assume ownership of the results */
-	void setResults (QString* new_results, int new_result_count);
+	void setResults (const QStringList &new_results);
 
 	int rowCount (const QModelIndex& parent=QModelIndex()) const;
 	int columnCount (const QModelIndex& parent=QModelIndex()) const;
 	QVariant data (const QModelIndex& index, int role=Qt::DisplayRole) const;
 	QVariant headerData (int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const;
 private:
-	QString* results;
+	QStringList results;
 	int result_count;
 };
 

Modified: branches/2010_10_18_backend_restructuring_branch/rkward/windows/rkworkplace.cpp
===================================================================
--- branches/2010_10_18_backend_restructuring_branch/rkward/windows/rkworkplace.cpp	2010-11-02 09:11:13 UTC (rev 3170)
+++ branches/2010_10_18_backend_restructuring_branch/rkward/windows/rkworkplace.cpp	2010-11-02 12:23:51 UTC (rev 3171)
@@ -341,8 +341,8 @@
 		}
 
 		unsigned long size = 1;
-		for (unsigned int i = 0; i < iobj->numDimensions (); ++i) {
-			size *= iobj->getDimension (i);
+		foreach (int dim, iobj->getDimensions ()) {
+			size *= dim;
 		}
 		if ((RKSettingsModuleGeneral::warnLargeObjectThreshold () != 0) && (size > RKSettingsModuleGeneral::warnLargeObjectThreshold ())) {
 			if (KMessageBox::warningContinueCancel (view (), i18n ("You are about to edit object \"%1\", which is very large (%2 fields). RKWard is not optimized to handle very large objects in the built in data editor. This will use a lot of memory, and - depending on your system - might be very slow. For large objects it is generally recommended to edit using command line means or to split into smaller chunks before editing. On the other hand, if you have enough memory, or the data is simple enough (numeric data is easier to handle, than factor), editing may not be a problem at all. You can configure this warning (or turn it off entirely) under Settings->Configure RKWard->General.\nReally edit object?", iobj->getFullName (), size), i18n ("About to edit very large object")) != KMessageBox::Continue) {


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the rkward-tracker mailing list