You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
5.5 KiB

/***************************************************************************
ksmatrixascii.cpp
-------------------
begin : Wed Feb 9 2000
copyright : (C) 2000 by Kamil Dobkowski
email : kamildbk@friko.onet.pl
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "ksmatrixascii.h"
#include <qtextstream.h>
#include <qdatetime.h>
#include <qstring.h>
#include <qregexp.h>
#include <memory>
//-------------------------------------------------------------------------//
KSMatrixASCII::KSMatrixASCII()
{
}
//-------------------------------------------------------------------------//
KSMatrixASCII::~KSMatrixASCII()
{
}
//-------------------------------------------------------------------------//
bool KSMatrixASCII::check( QDataStream &is )
{
KSMatrix *check = read_header(is);
if ( !check ) return false;
delete check;
return true;
}
//-------------------------------------------------------------------------//
KSHeadersList* KSMatrixASCII::headers( QDataStream& is )
{
KSHeadersList *result = new KSHeadersList();
KSMatrix *hdr = NULL;
int untitled_nr = 0;
while( (hdr=read_header(is)) ) {
QCString name = hdr->name();
if ( name.isEmpty() ) hdr->setName( name.sprintf("untitled_%d",untitled_nr++) );
result->push_back( hdr );
}
return result;
}
//-------------------------------------------------------------------------//
KSMatrix* KSMatrixASCII::load( QDataStream& is, const QString& matrixname )
{
auto_ptr<KSMatrix> m;
int untitled_nr = 0;
while ( !is.atEnd() ) {
int dataPos;
auto_ptr<KSMatrix> h(read_header(is,&dataPos));
QCString name = h->name();
if ( name.isEmpty() ) h->setName( name.sprintf("untitled_%d",untitled_nr++) );
if ( QString(name) == matrixname ) { is.device()->at(dataPos); m = h; break; }
}
if ( is.atEnd() ) return NULL;
int rows = m->rows();
int cols = m->cols();
// remember that header has data set to NULL while rows and cols are sot to non-zero
m->resize( 0, 0 );
m->resize( rows, cols );
double value;
QString str;
QTextStream in(is.device());
in.setEncoding( QTextStream::Latin1 );
for( int row=0; row<rows; row++ ) {
str = in.readLine();
QTextIStream line(&str);
for( int col=0; col<cols; col++ ) {
value = 0.0; line >> value; m->setValue( row, col, value );
}
}
return m.release();
}
//-------------------------------------------------------------------------//
void KSMatrixASCII::save( QDataStream& os, QSMatrix *m, const QString& matrixname )
{
QTextStream out(os.device());
out.precision(9);
out.setEncoding( QTextStream::Latin1 );
out << QString("# Created by "PACKAGE" "VERSION" ") + QDateTime::currentDateTime().toString() << endl;
out << "# name: " << matrixname << endl;
out << "# type: matrix" << endl;
out << "# rows: " << m->rows() << endl;
out << "# columns: " << m->cols() << endl;
for( int row=0; row<m->rows(); row++ ) {
for( int col=0; col<m->cols(); col++ ) out << " " << m->value(row,col);
out << endl;
}
}
//-------------------------------------------------------------------------//
KSMatrix *KSMatrixASCII::read_header( QDataStream& is, int* data_pos )
{
int pos = 0;
QString str;
QTextStream in(is.device());
in.setEncoding( QTextStream::Latin1 );
//
// Search a name
//
QString name;
while( str.length() == 0 ) {
if ( in.device()->atEnd() ) return NULL;
pos = in.device()->at();
str = in.readLine();
str = str.simplifyWhiteSpace();
if ( str[0] == '#' ) {
if ( str.left(7) == "# name:" ) {
int end = str.find( ' ', 8 );
if ( end == -1 ) end = str.length()-1;
name = str.mid( 7, end-7+1 );
}
str.truncate(0);
}
}
if ( data_pos ) *data_pos = pos; in.device()->at( pos );
int rows = -1;
int cols = -1;
//
// try to determine a number of rows.
//
int cpos = 0;
int ppos = 0;
double value;
QTextIStream line(&str);
cpos = line.device()->at();
do {
ppos = cpos;
line >> value; cols++;
cpos = line.device()->at();
} while ( ppos != cpos );
//
// try to determine a number of columns.
//
QRegExp num("\\s*[\\+\\-\\.]?[0-9]+");
do {
rows++;
pos = in.device()->at();
str = in.readLine();
} while ( num.match(str) == 0 );
in.device()->at(pos); // move to the begining of the last line
//
// Return a matrix header
//
if ( cols == 0 || rows == 0 ) return NULL;
KSMatrix *result = KSMatrix::create(EDouble);
result->setName(name);
result->setRawData( NULL, rows, cols );
return result;
}