BinaryWriter.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2006-2007 by Peter Dimov.
00004 
00005 This file is part of Calitko (http://www.calitko.org).
00006 
00007 Calitko is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 Calitko is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Calitko; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 */
00022 
00023 #include "Qt.h"
00024 #include "BinaryWriter.h"
00025 #include <iterator>
00026 
00027 using Utils::Encodings::BinaryWriter;
00028 using std::reverse_iterator;
00029 
00031 
00039 BinaryWriter::BinaryWriter (QByteArray *buffer, ByteOrder byteOrder,
00040                             bool autoGrow)
00041  :  d()
00042 {
00043     d.ownsBuffer    = false;
00044     d.buffer        = buffer;
00045     d.dataStart     = d.buffer->data();
00046     d.dataEnd       = d.dataStart + d.buffer->size();
00047     d.autoGrow      = autoGrow;
00048     // Make sure d.swapBytes and d.byteOrder are initialized:
00049     setByteOrder (byteOrder);
00050 }
00051 
00053 
00061 BinaryWriter::BinaryWriter (ByteOrder byteOrder, bool autoGrow)
00062  :  d()
00063 {
00064     d.ownsBuffer    = true;
00065     d.buffer        = new QByteArray();
00066     d.dataStart     = d.buffer->data();
00067     d.dataEnd       = d.dataStart + d.buffer->size();
00068     d.autoGrow      = autoGrow;
00069     // Make sure d.swapBytes and d.byteOrder are initialized:
00070     setByteOrder (byteOrder);
00071 }
00072 
00074 
00078 BinaryWriter::~BinaryWriter()
00079 {
00080     if (d.ownsBuffer)
00081         delete d.buffer;
00082 }
00083 
00085 
00097 void BinaryWriter::reserve (size_t count)
00098 {
00099     growBuffer (count, true);
00100     d.autoGrow = false;
00101 }
00102 
00104 
00109 inline
00110 void BinaryWriter::growBuffer (size_t count, bool force)
00111 {
00112     // Currently only owned buffers are growable.
00113     if ((d.autoGrow || force) && d.dataStart + count > d.dataEnd) {
00114         size_t written = bytesWritten();
00115         d.buffer->resize (written + count);
00116         d.dataStart = d.buffer->data() + written;
00117         d.dataEnd = d.dataStart + count;
00118     }
00119 }
00120 
00122 
00131 inline
00132 void BinaryWriter::doWrite (char *source, size_t count)
00133 {
00134     growBuffer (count); // Grow buffer if growable and necessary.
00135     // Only write if enough free bytes left:
00136     if (d.dataStart + count <= d.dataEnd) {
00137         if (d.swapBytes)
00138             qCopy (source, source + count,
00139                    reverse_iterator <char *> (d.dataStart + count));
00140         else
00141             qCopy (source, source + count, d.dataStart);
00142     }
00143     d.dataStart += count;
00144 }
00145 
00147 
00155 void BinaryWriter::writeByte (uchar value)
00156 {
00157     doWrite (reinterpret_cast <char *> (&value), sizeof (value));
00158 }
00159 
00161 
00169 void BinaryWriter::writeUInt16 (quint16 value)
00170 {
00171     doWrite (reinterpret_cast <char *> (&value), sizeof (value));
00172 }
00173 
00175 
00183 void BinaryWriter::writeUInt32 (quint32 value)
00184 {
00185     doWrite (reinterpret_cast <char *> (&value), sizeof (value));
00186 }
00187 
00189 
00197 void BinaryWriter::writeUInt64 (quint64 value)
00198 {
00199     doWrite (reinterpret_cast <char *> (&value), sizeof (value));
00200 }
00201 
00203 
00213 void BinaryWriter::writeBytes (const QByteArray &bytes)
00214 {
00215     size_t count = bytes.length();
00216     growBuffer (count); // Grow buffer if growable and necessary.
00217     char *end = d.dataStart + count;
00218     if (end <= d.dataEnd)
00219         qCopy (bytes.data(), bytes.data() + count, d.dataStart);
00220     d.dataStart = end;
00221 }
00222 
00224 
00236 void BinaryWriter::writeString (const QByteArray &string, char terminator)
00237 {
00238     size_t count = string.length();
00239     growBuffer (count + 1);
00240     // Write the string:
00241     writeBytes (string);
00242     // Write the ending zero:
00243     if (d.dataStart < d.dataEnd)
00244         *d.dataStart = terminator;
00245     // Advance past the zero or past the end:
00246     d.dataStart++;
00247 }
00248 
00250 
00254 void BinaryWriter::setByteOrder (ByteOrder byteOrder)
00255 {
00256     d.byteOrder = byteOrder;
00257     if (byteOrder == LittleEndian)
00258         d.swapBytes = QSysInfo::ByteOrder != QSysInfo::LittleEndian;
00259     else if (byteOrder == BigEndian)
00260         d.swapBytes = QSysInfo::ByteOrder != QSysInfo::BigEndian;
00261     else
00262         Q_ASSERT (false);
00263 }
00264 
00266 
00274 bool BinaryWriter::hasWrittenAll() const
00275 {
00276     return d.dataStart >= d.dataEnd;
00277 }
00278 
00280 
00289 bool BinaryWriter::hasWrittenPastEnd() const
00290 {
00291     return d.dataStart > d.dataEnd;
00292 }
00293 
00295 
00303 size_t BinaryWriter::bytesWritten() const
00304 {
00305     return d.dataStart - d.buffer->data();
00306 }