File indexing completed on 2024-04-28 04:40:01

0001 #ifndef LEOUTPUTSTREAM_H
0002 #define LEOUTPUTSTREAM_H
0003 
0004 #include "leinputstream.h"
0005 
0006 class LEOutputStream {
0007 private:
0008     QIODevice* output;
0009     QDataStream data;
0010 
0011     qint8 bitfieldpos;
0012     quint8 bitfield;
0013 
0014     void writeBits(quint8 n, quint8 v) {
0015         bitfield = v << bitfieldpos | bitfield;
0016         bitfieldpos += n;
0017         if (bitfieldpos == 8) {
0018             data << bitfield;
0019             bitfield = 0;
0020             bitfieldpos = 0;
0021         } else if (bitfieldpos > 8) {
0022             throw IOException("Bitfield does not have enough bits left.");
0023         }
0024     }
0025 
0026     void checkForLeftOverBits() const {
0027         if (bitfieldpos != 0) {
0028             throw IOException(
0029                 "Cannot read this type halfway through a bit operation.");
0030         }
0031     }
0032 
0033 public:
0034 
0035     LEOutputStream(QIODevice* out) :output(out), data(out) {
0036         bitfield = 0;
0037         bitfieldpos = 0;
0038         data.setByteOrder(QDataStream::LittleEndian);
0039     }
0040 
0041     void writebit(bool v) {
0042         writeBits(1, (v) ?1 :0);
0043     }
0044 
0045     void writeuint2(quint8 v) {
0046         writeBits(2, v);
0047     }
0048 
0049     void writeuint3(quint8 v) {
0050         writeBits(3, v);
0051     }
0052 
0053     void writeuint4(quint8 v) {
0054         writeBits(4, v);
0055     }
0056 
0057     void writeuint5(quint8 v) {
0058         writeBits(5, v);
0059     }
0060 
0061     void writeuint6(quint8 v) {
0062         writeBits(6, v);
0063     }
0064 
0065     void writeuint7(quint8 v) {
0066         writeBits(7, v);
0067     }
0068 
0069     void writeuint9(quint16 v) {
0070         data << (quint8) v;
0071         writeBits(1, v >> 8);
0072     }
0073 
0074     void writeuint12(quint16 v) {
0075         writeBits(4, v);
0076         data << (quint8)(v >> 4);
0077     }
0078 
0079     void writeuint13(quint16 v) {
0080         writeBits(5, v);
0081         data << (quint8)(v >> 5);
0082     }
0083 
0084     void writeuint14(quint16 v) {
0085         if (bitfieldpos == 0) {
0086             data << (quint8) v;
0087             writeBits(6, v >> 8);
0088         } else if (bitfieldpos == 2) {
0089             writeBits(6, v);
0090             data << (quint8)(v >> 6);
0091         } else {
0092             throw IOException(
0093                 "Cannot write this type halfway through a bit operation.");
0094         }
0095     }
0096 
0097     void writeuint15(quint16 v) {
0098         // we assume there are 7 bits left
0099         writeBits(7, v);
0100         data << (quint8)(v >> 7);
0101     }
0102 
0103     void writeuint20(quint32 v) {
0104         if (bitfieldpos == 0) {
0105             data << (quint8) v;
0106             data << (quint8)(v >> 8);
0107             writeBits(4, v >> 16);
0108         } else if (bitfieldpos == 4) {
0109             writeBits(4, v);
0110             data << (quint8)(v >> 4);
0111             data << (quint8)(v >> 12);
0112         } else {
0113             throw IOException(
0114                 "Cannot write this type halfway through a bit operation.");
0115         }
0116     }
0117 
0118     void writeuint30(quint32 v) {
0119         checkForLeftOverBits();
0120         data << (quint8) v;
0121         data << (quint8)(v >> 8);
0122         data << (quint8)(v >> 16);
0123         writeBits(6, v >> 24);
0124     }
0125 
0126     void writeuint8(quint8 v) {
0127         checkForLeftOverBits();
0128         data << v;
0129     }
0130 
0131     void writeint16(qint16 v) {
0132         checkForLeftOverBits();
0133         data << v;
0134     }
0135 
0136     void writeuint16(quint16 v) {
0137         checkForLeftOverBits();
0138         data << v;
0139     }
0140 
0141     void writeuint32(quint32 v) {
0142         checkForLeftOverBits();
0143         data << v;
0144     }
0145 
0146     void writeint32(qint32 v) {
0147         checkForLeftOverBits();
0148         data << v;
0149     }
0150 
0151     void writeBytes(const QByteArray& b) {
0152         int offset = 0;
0153         int todo = b.size();
0154         do {
0155             int nwritten = data.writeRawData(b.data() + offset, todo);
0156             if (nwritten == -1) return; //TODO report error
0157             todo -= nwritten;
0158             offset += nwritten;
0159         } while (todo > 0);
0160     }
0161 
0162     quint64 getPosition() const { return output->pos(); }
0163 };
0164 
0165 #endif