/*************************************************************************** * Copyright (C) 2008 by Oliver Groß * * z.o.gross@gmx.de * * * * 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. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "ccrosspackage.h" #include "cnonogram.h" #include #include namespace libqnono { //public: CCrossPackage::CCrossPackage() : m_File(NULL), m_headersOnly(false) {} CCrossPackage::~CCrossPackage() { close(); foreach (CNonogram * i, m_PictureList) { delete i; } } bool CCrossPackage::open() { close(); if (m_FileName.isEmpty()) return false; qDebug("opening file: %s", m_FileName.toAscii().data()); m_File = new QFile(m_FileName); if (!m_File->open(QIODevice::ReadOnly)) { delete m_File; m_File = NULL; return false; } return true; } void CCrossPackage::close() { if (m_File) { m_File->close(); delete m_File; m_File = NULL; } } bool CCrossPackage::doReadHeader() { QDataStream in(m_File); in.setVersion(QDataStream::Qt_4_0); QString stringBuffer; QSize sizeBuffer; qDebug("reading header"); if (in.atEnd()) { qCritical("invalid package file - no header"); close(); return false; } in >> stringBuffer; if ((stringBuffer != "QCROSSPACKAGE")) { qCritical("invalid package file - invalid header: %s", stringBuffer.toAscii().data()); close(); return false; } if (in.atEnd()) { qCritical("invalid package file - no package name"); close(); return false; } in >> stringBuffer; if (stringBuffer.isEmpty()) { qCritical("invalid package file - invalid package name"); close(); return false; } m_Name = stringBuffer; m_headersOnly = true; return true; } bool CCrossPackage::doReadData() { if (!m_File) return false; m_PictureList.clear(); QDataStream in(m_File); in.setVersion(QDataStream::Qt_4_0); CNonogram * newPicture = NULL; qint32 pictureCount = 0; if (in.atEnd()) { qCritical("invalid package file - no picture count"); close(); return false; } in >> pictureCount; int i; for (i = 0; i < pictureCount && !in.atEnd(); i++) { newPicture = new CNonogram(); if (!newPicture->readFromStream(in)) { qCritical("invalid package file - invalid picture"); delete newPicture; close(); return false; } m_PictureList << newPicture; } if (i < pictureCount) qWarning("damaged package file - invalid picture count"); m_headersOnly = false; return true; } CNonogram * CCrossPackage::takePicture(int ndx) { loadPictures(); CNonogram * result = m_PictureList.takeAt(ndx); unloadPictures(); return result; } bool CCrossPackage::loadPictures() { if (!m_headersOnly) return true; if (!open() || !doReadHeader() || !doReadData()) { close(); return false; } close(); return true; } void CCrossPackage::unloadPictures() { if (!m_PictureList.empty()) { foreach (CNonogram * i, m_PictureList) { delete i; } m_PictureList.clear(); m_headersOnly = true; } } bool CCrossPackage::save() { Q_ASSERT(!m_headersOnly); QFile file(m_FileName); if (!file.open(QIODevice::WriteOnly)) return false; QDataStream out(&file); out.setVersion(QDataStream::Qt_4_0); out << QString("QCROSSPACKAGE"); out << m_Name; out << (qint32)(m_PictureList.size()); foreach (CNonogram * i, m_PictureList) i->writeToStream(out); file.close(); return true; } CCrossPackage * CCrossPackage::read(QString fileName) { CCrossPackage *p = new CCrossPackage(); p->setFileName(fileName); if (!p->open() || !p->doReadHeader() || !p->doReadData()) { delete p; return NULL; } p->close(); return p; } CCrossPackage * CCrossPackage::readHeader(QString fileName) { CCrossPackage *p = new CCrossPackage(); p->setFileName(fileName); if (!p->open() || !p->doReadHeader()) { delete p; return NULL; } p->close(); return p; } }