重写QDataStream操作符>> ()等价到C ++没有Qt [英] Rewrite QDataStream operator >> () equivalent into to C++ without Qt

查看:843
本文介绍了重写QDataStream操作符>> ()等价到C ++没有Qt的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下Qt C ++代码

I have the following Qt C++ code

// QByteArray data;
QDataStream ds(data.right(data.size()-start));
ds.setByteOrder(QDataStream::LittleEndian);

qint8 sz;
ds >> sz;

,并希望将其转换为没有Qt的普通C ++代码。我的第一个尝试是:

and want to transfer it into normal C++ code without Qt. My first attempt is:

// std::vector<char> data;
std::string ds( data.cbegin() , data.cbegin() + start );

我需要执行什么操作来模仿运算符>>(qint8)?

What operation do I need to perform to mimic the operator>>(qint8)?

推荐答案

首先, QByteArray QDataStream 和Qt的其他部分不多。您可以轻松地添加 qbytearray [.cpp | .h | _p.h] qdatastream [.cpp | .h | _p.h] / code>,以及一个全局头或两个,你应该能够编译它们没有剩下的Qt。这就是 qmake 的用法。注意, qmake 无需构建Qt,只有makefile和一些Qt源。

First of all, the dependencies between QByteArray and QDataStream and other parts of Qt aren't much. You can easily add the qbytearray[.cpp|.h|_p.h] and qdatastream[.cpp|.h|_p.h], along with a global header or two, and you should be able to compile them without rest of Qt. That's what qmake does, for example. Note that qmake gets built without Qt, only from a makefile and some Qt sources.

标准C ++库不具有 QDataStream 的功能。

Having said that, the standard C++ library doesn't come with functionality of a QDataStream.

A std: :string 不像 QByteArray ,也不像 QDataStream std :: vector< uint8_t> 是您需要存储原始数据以替换 QByteArray

A std::string is not like a QByteArray nor like a QDataStream. std::vector<uint8_t> is what you need to store the raw data in replacement of QByteArray.

您需要自行更换 QDataStream

例如:

#include <vector>
#include <memory>
#include <cstdint>
#include <cassert>

class QDataStream {
public:
    typedef std::vector<uint8_t> Storage;
    enum ByteOrder { BigEndian, LittleEndian };
    enum Status { Ok, ReadPastEnd };
private:
    std::shared_ptr<const Storage> m_ptr;
    const Storage * m_data;
    size_t m_idx;
    Status m_status;
    ByteOrder m_byteOrder, m_systemOrder;
    static ByteOrder systemByteOrder() {
        const uint32_t t = 1;
        return (reinterpret_cast<const uint8_t*>(&t)) ? LittleEndian : BigEndian;
    }
    bool has(size_t count) const { return m_idx + count <= m_data->size(); }
    template <typename T> QDataStream & read(T & i) {
        if (has(sizeof(T)) && Ok == m_status) {
            T result = *reinterpret_cast<const T*>(&(*m_data)[m_idx]);
            m_idx += sizeof(T);
            if (m_byteOrder != m_systemOrder) {
                T tmp = 0;
                for (uint8_t i = 0; i < sizeof(T); ++i) {
                    tmp = (tmp << 8) | (result & 0xFF);
                    result = result >> 8;
                }
                i = tmp;
            } else
                i = result;
        } else {
            m_status = ReadPastEnd;
        }
        return *this;
    }
public:
    QDataStream(const std::vector<uint8_t> * data) :
        m_data(data), m_idx(0), m_status(Ok),
        m_byteOrder(BigEndian), m_systemOrder(systemByteOrder()) {}
    QDataStream(std::shared_ptr<Storage> data) :
        m_ptr(data), m_data(m_ptr.get()), m_idx(0), m_status(Ok),
        m_byteOrder(BigEndian), m_systemOrder(systemByteOrder()) {}
    QDataStream(std::unique_ptr<Storage> && data) :
        m_ptr(data.release()), m_data(m_ptr.get()), m_idx(0), m_status(Ok),
        m_byteOrder(BigEndian), m_systemOrder(systemByteOrder()) {}
    QDataStream(Storage && data) :
        m_ptr(new Storage(std::move(data))), m_data(m_ptr.get()),
        m_idx(0), m_status(Ok), m_byteOrder(BigEndian), m_systemOrder(systemByteOrder()) {}
    bool atEnd() const { return m_idx == m_data->size(); }
    QDataStream & operator>>(int8_t & i) {
        return read(i);
    }
    QDataStream & operator>>(int16_t & i) {
        return read(i);
    }
    QDataStream & operator>>(int32_t & i) {
        return read(i);
    }
    QDataStream & operator>>(uint8_t & i) {
        return read(i);
    }
    QDataStream & operator>>(uint16_t & i) {
        return read(i);
    }
    QDataStream & operator>>(uint32_t & i) {
        return read(i);
    }
    void setByteOrder(ByteOrder b) { m_byteOrder = b; }
    ByteOrder byteOrder() const { return m_byteOrder; }
};

int main()
{
    std::vector<uint8_t> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    uint32_t val;
    QDataStream s_be(&v);
    s_be >> val;
    assert(val == 0x01020304); // big endian
    QDataStream s_le(&v);
    s_le.setByteOrder(QDataStream::LittleEndian);
    s_le >> val;
    assert(val == 0x04030201); // little endian
    return 0;
}

这篇关于重写QDataStream操作符&gt;&gt; ()等价到C ++没有Qt的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆