[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: koffice/filters/kspread/excel
From: Marijn Kruisselbrink <m.kruisselbrink () student ! tue ! nl>
Date: 2010-08-29 20:53:59
Message-ID: 20100829205359.ACC28AC883 () svn ! kde ! org
[Download RAW message or body]
SVN commit 1169647 by mkruisselbrink:
make CFBWriter's streams be random access; writing xls files needs random access \
streams to update previously written records
M +61 -1 export/CFBWriter.cpp
M +2 -0 export/CFBWriter.h
M +20 -0 sidewinder/XlsRecordOutputStream.cpp
M +11 -0 sidewinder/XlsRecordOutputStream.h
--- trunk/koffice/filters/kspread/excel/export/CFBWriter.cpp #1169646:1169647
@@ -80,9 +80,12 @@
virtual ~StreamIODevice();
virtual void close();
virtual bool open(OpenMode mode);
+ virtual qint64 size() const;
protected:
virtual qint64 writeData(const char *data, qint64 len);
virtual qint64 readData(char *data, qint64 maxlen);
+ void appendData(const char *data, qint64 len);
+ qint64 internalWriteData(const char* data, qint64 len, qint64 pos);
private:
DirectoryEntry& m_entry;
CFBWriter& m_writer;
@@ -133,8 +136,13 @@
return false;
}
-qint64 CFBWriter::StreamIODevice::writeData(const char *data, qint64 len)
+qint64 CFBWriter::StreamIODevice::size() const
{
+ return m_entry.streamSize + m_buffer.size();
+}
+
+void CFBWriter::StreamIODevice::appendData(const char *data, qint64 len)
+{
m_buffer.append(data, len);
while (m_buffer.size() > 4096) {
QByteArray sector = m_buffer.left(4096);
@@ -145,9 +153,48 @@
}
m_entry.streamSize += 4096;
}
+}
+
+qint64 CFBWriter::StreamIODevice::writeData(const char *data, qint64 len)
+{
+ qint64 bytesWritten = 0;
+ qint64 curPos = pos();
+ while (bytesWritten < len) {
+ bytesWritten += internalWriteData(data + bytesWritten, len - bytesWritten, \
curPos + bytesWritten); + }
return len;
}
+qint64 CFBWriter::StreamIODevice::internalWriteData(const char *data, qint64 len, \
qint64 pos) +{
+ Q_ASSERT(pos >= 0 && pos <= size());
+ if (pos == size()) {
+ appendData(data, len);
+ return len;
+ } else {
+ if (pos + len > size()) {
+ len = size() - pos;
+ }
+ qint64 bufferStart = m_entry.streamSize;
+ if (pos < bufferStart) {
+ unsigned sectorIndex = pos/4096;
+ unsigned sector = m_entry.firstSector;
+ while (sectorIndex--) {
+ sector = m_writer.m_fat[sector];
+ }
+ unsigned sectorOffset = pos%4096;
+ if (sectorOffset + len > 4096) {
+ len = 4096 - sectorOffset;
+ }
+ m_writer.writeData(sector, sectorOffset, QByteArray::fromRawData(data, \
len)); + } else {
+ // len has already been adjusted to be fully inside the buffer, so just \
overwrite what is in the buffer with the subset of data we have + \
m_buffer.replace(pos - bufferStart, len, QByteArray::fromRawData(data, len)); + \
} + return len;
+ }
+}
+
qint64 CFBWriter::StreamIODevice::readData(char *data, qint64 maxlen)
{
Q_UNUSED(data);
@@ -337,6 +384,19 @@
m_miniFatDataStream = new StreamIODevice(*this, m_entries[0]);
}
+void CFBWriter::writeData(unsigned sector, unsigned sectorOffset, const QByteArray \
&data) +{
+ Q_ASSERT(m_device);
+ Q_ASSERT(m_device->isOpen());
+ Q_ASSERT(m_device->isWritable());
+ Q_ASSERT(!m_device->isSequential());
+ Q_ASSERT(sector < unsigned(m_fat.size()));
+ Q_ASSERT(sectorOffset + data.length() <= 4096);
+
+ m_device->seek((sector + 1) * 4096 + sectorOffset);
+ m_device->write(data);
+}
+
unsigned CFBWriter::writeSector(const QByteArray &data, unsigned previousSector)
{
Q_ASSERT(m_device);
--- trunk/koffice/filters/kspread/excel/export/CFBWriter.h #1169646:1169647
@@ -48,6 +48,8 @@
unsigned writeMiniSector(const QByteArray& data, unsigned previousSector = -1);
+ void writeData(unsigned sector, unsigned sectorOffset, const QByteArray& data);
+
unsigned fatSectorCount() const;
QList<unsigned> m_difat;
--- trunk/koffice/filters/kspread/excel/sidewinder/XlsRecordOutputStream.cpp \
#1169646:1169647 @@ -32,9 +32,15 @@
{
Q_ASSERT(device->isOpen());
Q_ASSERT(device->isWritable());
+ Q_ASSERT(!device->isSequential());
m_dataStream.setByteOrder(QDataStream::LittleEndian);
}
+qint64 XlsRecordOutputStream::pos() const
+{
+ return m_dataStream.device()->pos();
+}
+
void XlsRecordOutputStream::writeRecord(const Record& record)
{
startRecord(record.rtti());
@@ -42,6 +48,20 @@
endRecord();
}
+void XlsRecordOutputStream::writeRecord(Record& record)
+{
+ record.setPosition(pos());
+ writeRecord(const_cast<const Record&>(record));
+}
+
+void XlsRecordOutputStream::rewriteRecord(const Record& record)
+{
+ qint64 oldPos = pos();
+ m_dataStream.device()->seek(record.position());
+ writeRecord(record);
+ m_dataStream.device()->seek(oldPos);
+}
+
void XlsRecordOutputStream::startRecord(unsigned recordType)
{
Q_ASSERT(m_currentRecord == NORECORD);
--- trunk/koffice/filters/kspread/excel/sidewinder/XlsRecordOutputStream.h \
#1169646:1169647 @@ -34,7 +34,16 @@
public:
XlsRecordOutputStream(QIODevice* device);
+ /**
+ * Writes a record, updates the records position to the position it is saved to \
in the file. + */
+ void writeRecord(Record& record);
void writeRecord(const Record& record);
+ /**
+ * Rewrites the given record at its recordPosition by first seeking there, and \
then going back to where the output device was first. + */
+ void rewriteRecord(const Record& record);
+
void startRecord(unsigned recordType);
void endRecord();
@@ -44,6 +53,8 @@
void writeUnicodeStringWithFlags(const QString& value);
void writeByteString(const QString& value);
void writeBlob(const QByteArray& value);
+
+ qint64 pos() const;
private:
QDataStream m_dataStream;
unsigned m_currentRecord;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic