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