读QT5.7源码(二)QByteArray

QByteArray 以QTypeArrayData<char>做底层做了聚合,实现了对字节为单位的数组的管理。


QT中是这样描述它的



QByteArray can be used to store both raw bytes (including '\0's) and traditional 8-bit '\0'-terminated strings. Using QByteArray is much moreconvenient than using const char *. Behind the scenes, it always ensures that the data is followed by a '\0' terminator, and uses implicit sharing (copy-on-write) to reduce memory usage and avoid needless copying of data.
In addition to QByteArray, Qt also provides the QString class to store string data. For most purposes, QString is the class you want to use. It stores 16-bit Unicode characters, making it easy to store non-ASCII/non-Latin-1 characters in your application. Furthermore, QString is used throughout in the Qt API. The two main cases where QByteArray is appropriate are when you need to store raw binary data, and when memory conservation is critical (e.g., with Qt for Embedded Linux).

QByteArray可以用来存放原始的二进制字节(包括‘\0’)或者8字节的以'\0'结尾的字符串,它比使用char*更方便,它总是认为数组是以‘\0’结束的,它使用写时拷贝机制来减少内存的使用量,在它之外QT提供了QString类来存储字符串数据,出于更多的目的,QString可能是你想要使用的,它储存16位的Unicode字符,使它很容易存放不属于ASCII或者拉丁字符的其他字符,QByteArray主要用于存放二进制数据,或者当内存使用受限的情况下,比如嵌入式Linux中编程

One way to initialize a QByteArray is simply to pass a const char * to its constructor. For example, the following code creates a byte array of size 5 containing the data "Hello":  

简单的初始化一个QByteArray可以传给他一个char*,例如下面创建了一个大小为5的数组,包含字符串Hello

  QByteArray ba("Hello");


Although the size() is 5, the byte array also maintains an extra '\0' character at the end so that if a function is used that asks for a pointer to the underlying data (e.g. a call to data()), the data pointed to is guaranteed to be '\0'-terminated.
QByteArray makes a deep copy of the const char * data, so you can modify it later without experiencing side effects. (If for performance reasons you don't want to take a deep copy of the character data, use QByteArray::fromRawData() instead.)
Another approach is to set the size of the array using resize() and to initialize the data byte per byte. QByteArray uses 0-based indexes, just like C++ arrays. To access the byte at a particular index position, you can use operator[](). On non-const byte arrays, operator[]() returns a reference to a byte that can be used on the left side of an assignment. For example:

虽然大小是5,但是ByteArray还是在它后面加了一个'\0',因此当使用一个函数(例如data() )获取数组的数据指针,那么返回的数据指针是以‘\0’结尾的。

QByteArray是对char*字符串的深拷贝,因此当修改了一个不会对另一个产生副作用,如果不想使用深拷贝,可以使用fromRawData来代替。

另一种方式是使用resize()设置数组的大小,或者一字节一字节的初始化数组,QByteArray使用基于0的索引,这点就像C++的数组,可以通过[]操作符来使用索引访问数组元素,非const的数组使用[]返回对一个字节的引用,可以用来做左值。

例子:




  QByteArray ba;
  ba.resize(5);
  ba[0] = 0x3c;
  ba[1] = 0xb8;
  ba[2] = 0x64;
  ba[3] = 0x18;
  ba[4] = 0xca;


For read-only access, an alternative syntax is to use at():
对于只读访问的情况,可以使用at()函数代替[]
  for (int i = 0; i < ba.size(); ++i) {
      if (ba.at(i) >= 'a' && ba.at(i) <= 'f')
          cout << "Found character in range [a-f]" << endl;
  }


at() can be faster than operator[](), because it never causes a deep copy to occur.
To extract many bytes at a time, use left(), right(), or mid().
A QByteArray can embed '\0' bytes. The size() function always returns the size of the whole array, including embedded '\0' bytes, but excluding the terminating '\0' added by QByteArray. For example:
at()要比[]操作符快,它从不引起深拷贝。

提取比较多的字节可以使用left(), right(), or mid().

QByteArray可以嵌入'\0',size()函数总是返回整个数组的大小,包括嵌入的'\0',但是不包括结尾附加的'\0'

  QByteArray ba1("ca\0r\0t");
  ba1.size();                     // Returns 2.
  ba1.constData();                // Returns "ca" with terminating \0.


  QByteArray ba2("ca\0r\0t", 3);
  ba2.size();                     // Returns 3.
  ba2.constData();                // Returns "ca\0" with terminating \0.


  QByteArray ba3("ca\0r\0t", 4);
  ba3.size();                     // Returns 4.
  ba3.constData();                // Returns "ca\0r" with terminating \0.


  const char cart[] = {'c', 'a', '\0', 'r', '\0', 't'};
  QByteArray ba4(QByteArray::fromRawData(cart, 6));
  ba4.size();                     // Returns 6.
  ba4.constData();                // Returns "ca\0r\0t" without terminating \0.


If you want to obtain the length of the data up to and excluding the first '\0' character, call qstrlen() on the byte array.

如果你想获取一直到第一个'\0'的数组的大小使用qstrlen()函数
After a call to resize(), newly allocated bytes have undefined values. To set all the bytes to a particular value, call fill().

当调用resize()函数后,新申请的字节是为定义的,将所有的字节设为一个特殊的值可以使用fill()函数
To obtain a pointer to the actual character data, call data() or constData(). These functions return a pointer to the beginning of the data. The pointer is guaranteed to remain valid until a non-const function is called on the QByteArray. It is also guaranteed that the data ends with a '\0' byte unless the QByteArray was created from a raw data. This '\0' byte is automatically provided by QByteArray and is not counted in size().

获取实际数组数据可以使用data()和constData函数,这两个函数返回数组起始字节的指针,这个指针一直有效直到一个非const的函数被调用,它同时保证数据已'\0'结束除非  QByteArray 是用一个原始数据初始化的,'\0‘由QByteArray自动提供,但是不在size()函数的计算范围内。



QByteArray provides the following basic functions for modifying the byte data: append(), prepend(), insert(), replace(), and remove(). For example:

修改数据的函数append(), prepend(), insert(), replace(), and remove()
  QByteArray x("and");
  x.prepend("rock ");         // x == "rock and"
  x.append(" roll");          // x == "rock and roll"
  x.replace(5, 3, "&");       // x == "rock & roll"


The replace() and remove() functions' first two arguments are the position from which to start erasing and the number of bytes that should be erased.
When you append() data to a non-empty array, the array will be reallocated and the new data copied to it. You can avoid this behavior by calling reserve(), which preallocates a certain amount of memory. You can also call capacity() to find out how much memory QByteArray actually allocated. Data appended to an empty array is not copied.
A frequent requirement is to remove whitespace characters from a byte array ('\n', '\t', ' ', etc.). If you want to remove whitespace from both ends of a QByteArray, use trimmed(). If you want to remove whitespace from both ends and replace multiple consecutive whitespaces with a single space character within the byte array, use simplified().
If you want to find all occurrences of a particular character or substring in a QByteArray, use indexOf() or lastIndexOf(). The former searches forward starting from a given index position, the latter searches backward. Both return the index position of the character or substring if they find it; otherwise, they return -1. For example, here's a typical loop that finds all occurrences of a particular substring:


  QByteArray ba("We must be <b>bold</b>, very <b>bold</b>");
  int j = 0;
  while ((j = ba.indexOf("<b>", j)) != -1) {
      cout << "Found <b> tag at index position " << j << endl;
      ++j;
  }


If you simply want to check whether a QByteArray contains a particular character or substring, use contains(). If you want to find out how many times a particular character or substring occurs in the byte array, use count(). If you want to replace all occurrences of a particular value with another, use one of the two-parameter replace() overloads.
QByteArrays can be compared using overloaded operators such as operator<(), operator<=(), operator==(), operator>=(), and so on. The comparison is based exclusively on the numeric values of the characters and is very fast, but is not what a human would expect. QString::localeAwareCompare() is a better choice for sorting user-interface strings.
For historical reasons, QByteArray distinguishes between a null byte array and an empty byte array. A null byte array is a byte array that is initialized using QByteArray's default constructor or by passing (const char *)0 to the constructor. An empty byte array is any byte array with size 0. A null byte array is always empty, but an empty byte array isn't necessarily null:


  QByteArray().isNull();          // returns true
  QByteArray().isEmpty();         // returns true


  QByteArray("").isNull();        // returns false
  QByteArray("").isEmpty();       // returns true


  QByteArray("abc").isNull();     // returns false
  QByteArray("abc").isEmpty();    // returns false


All functions except isNull() treat null byte arrays the same as empty byte arrays. For example, data() returns a pointer to a '\0' character for a null byte array (not a null pointer), and QByteArray() compares equal to QByteArray(""). We recommend that you always use isEmpty() and avoid isNull(). 
Notes on Locale 
Number-String Conversions
Functions that perform conversions between numeric data types and strings are performed in the C locale, irrespective of the user's locale settings. Use QString to perform locale-aware conversions between numbers and strings. 
8-bit Character Comparisons
In QByteArray, the notion of uppercase and lowercase and of which character is greater than or less than another character is locale dependent. This affects functions that support a case insensitive option or that compare or lowercase or uppercase their arguments. Case insensitive operations and comparisons will be accurate if both strings contain only ASCII characters. (If $LC_CTYPE is set, most Unix systems do "the right thing".) Functions that this affects include contains(), indexOf(), lastIndexOf(), operator<(), operator<=(), operator>(), operator>=(), toLower() and toUpper().
This issue does not apply to QStrings since they represent characters using Unicode.





class Q_CORE_EXPORT QByteArray
{
private:
    typedef QTypedArrayData<char> Data;

public:
    enum Base64Option {
        Base64Encoding = 0,
        Base64UrlEncoding = 1,

        KeepTrailingEquals = 0,
        OmitTrailingEquals = 2
    };
    Q_DECLARE_FLAGS(Base64Options, Base64Option)

    inline QByteArray() Q_DECL_NOTHROW;
    QByteArray(const char *, int size = -1);
    QByteArray(int size, char c);
    QByteArray(int size, Qt::Initialization);
    inline QByteArray(const QByteArray &) Q_DECL_NOTHROW;
    inline ~QByteArray();

    QByteArray &operator=(const QByteArray &) Q_DECL_NOTHROW;
    QByteArray &operator=(const char *str);
#ifdef Q_COMPILER_RVALUE_REFS
    inline QByteArray(QByteArray && other) Q_DECL_NOTHROW : d(other.d) { other.d = Data::sharedNull(); }
    inline QByteArray &operator=(QByteArray &&other) Q_DECL_NOTHROW
    { qSwap(d, other.d); return *this; }
#endif

 
三种构造方式,
 
    inline void swap(QByteArray &other) Q_DECL_NOTHROW
    { qSwap(d, other.d); }

    inline int size() const;
    bool isEmpty() const;
    void resize(int size);

    QByteArray &fill(char c, int size = -1);

    int capacity() const;
    void reserve(int size);
    void squeeze();
当前申请的空间大小   分配粒度
#ifndef QT_NO_CAST_FROM_BYTEARRAY
    operator const char *() const;
    operator const void *() const;
#endif
    char *data();
    const char *data() const;
    inline const char *constData() const;
    inline void detach();
    bool isDetached() const;
    inline bool isSharedWith(const QByteArray &other) const { return d == other.d; }
    void clear();

    char at(int i) const;
    char operator[](int i) const;
    char operator[](uint i) const;
    QByteRef operator[](int i);
    QByteRef operator[](uint i);

提供[]操作
    int indexOf(char c, int from = 0) const;
    int indexOf(const char *c, int from = 0) const;
    int indexOf(const QByteArray &a, int from = 0) const;
    int lastIndexOf(char c, int from = -1) const;
    int lastIndexOf(const char *c, int from = -1) const;
    int lastIndexOf(const QByteArray &a, int from = -1) const;

    bool contains(char c) const;
    bool contains(const char *a) const;
    bool contains(const QByteArray &a) const;
    int count(char c) const;
    int count(const char *a) const;
    int count(const QByteArray &a) const;

查找索引 及统计
    QByteArray left(int len) const Q_REQUIRED_RESULT;
    QByteArray right(int len) const Q_REQUIRED_RESULT;
    QByteArray mid(int index, int len = -1) const Q_REQUIRED_RESULT;

    bool startsWith(const QByteArray &a) const;
    bool startsWith(char c) const;
    bool startsWith(const char *c) const;

    bool endsWith(const QByteArray &a) const;
    bool endsWith(char c) const;
    bool endsWith(const char *c) const;

    void truncate(int pos);
    void chop(int n);

#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QSTRING_COMPAT_CPP)
#  if defined(Q_CC_GNU)
    // required due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61941
#    pragma push_macro("Q_REQUIRED_RESULT")
#    undef Q_REQUIRED_RESULT
#    define Q_REQUIRED_RESULT
#    define Q_REQUIRED_RESULT_pushed
#  endif
    Q_ALWAYS_INLINE QByteArray toLower() const & Q_REQUIRED_RESULT
    { return toLower_helper(*this); }
    Q_ALWAYS_INLINE QByteArray toLower() && Q_REQUIRED_RESULT
    { return toLower_helper(*this); }
    Q_ALWAYS_INLINE QByteArray toUpper() const & Q_REQUIRED_RESULT
    { return toUpper_helper(*this); }
    Q_ALWAYS_INLINE QByteArray toUpper() && Q_REQUIRED_RESULT
    { return toUpper_helper(*this); }
    Q_ALWAYS_INLINE QByteArray trimmed() const & Q_REQUIRED_RESULT
    { return trimmed_helper(*this); }
    Q_ALWAYS_INLINE QByteArray trimmed() && Q_REQUIRED_RESULT
    { return trimmed_helper(*this); }
    Q_ALWAYS_INLINE QByteArray simplified() const & Q_REQUIRED_RESULT
    { return simplified_helper(*this); }
    Q_ALWAYS_INLINE QByteArray simplified() && Q_REQUIRED_RESULT
    { return simplified_helper(*this); }
#  ifdef Q_REQUIRED_RESULT_pushed
#    pragma pop_macro("Q_REQUIRED_RESULT")
#  endif
#else
    QByteArray toLower() const Q_REQUIRED_RESULT;
    QByteArray toUpper() const Q_REQUIRED_RESULT;
    QByteArray trimmed() const Q_REQUIRED_RESULT;
    QByteArray simplified() const Q_REQUIRED_RESULT;
#endif

 
大小写转换
    QByteArray leftJustified(int width, char fill = ' ', bool truncate = false) const Q_REQUIRED_RESULT;
    QByteArray rightJustified(int width, char fill = ' ', bool truncate = false) const Q_REQUIRED_RESULT;

    QByteArray &prepend(char c);
    QByteArray &prepend(int count, char c);
    QByteArray &prepend(const char *s);
    QByteArray &prepend(const char *s, int len);
    QByteArray &prepend(const QByteArray &a);
    QByteArray &append(char c);
    QByteArray &append(int count, char c);
    QByteArray &append(const char *s);
    QByteArray &append(const char *s, int len);
    QByteArray &append(const QByteArray &a);
    QByteArray &insert(int i, char c);
    QByteArray &insert(int i, int count, char c);
    QByteArray &insert(int i, const char *s);
    QByteArray &insert(int i, const char *s, int len);
    QByteArray &insert(int i, const QByteArray &a);
    QByteArray &remove(int index, int len);
    QByteArray &replace(int index, int len, const char *s);
    QByteArray &replace(int index, int len, const char *s, int alen);
    QByteArray &replace(int index, int len, const QByteArray &s);
    QByteArray &replace(char before, const char *after);
    QByteArray &replace(char before, const QByteArray &after);
    QByteArray &replace(const char *before, const char *after);
    QByteArray &replace(const char *before, int bsize, const char *after, int asize);
    QByteArray &replace(const QByteArray &before, const QByteArray &after);
    QByteArray &replace(const QByteArray &before, const char *after);
    QByteArray &replace(const char *before, const QByteArray &after);
    QByteArray &replace(char before, char after);
    QByteArray &operator+=(char c);
    QByteArray &operator+=(const char *s);
    QByteArray &operator+=(const QByteArray &a);

    QList<QByteArray> split(char sep) const;

    QByteArray repeated(int times) const Q_REQUIRED_RESULT;

 
附加 替换 插入
 
#ifndef QT_NO_CAST_TO_ASCII
    QT_ASCII_CAST_WARN QByteArray &append(const QString &s);
    QT_ASCII_CAST_WARN QByteArray &insert(int i, const QString &s);
    QT_ASCII_CAST_WARN QByteArray &replace(const QString &before, const char *after);
    QT_ASCII_CAST_WARN QByteArray &replace(char c, const QString &after);
    QT_ASCII_CAST_WARN QByteArray &replace(const QString &before, const QByteArray &after);

    QT_ASCII_CAST_WARN QByteArray &operator+=(const QString &s);
    QT_ASCII_CAST_WARN int indexOf(const QString &s, int from = 0) const;
    QT_ASCII_CAST_WARN int lastIndexOf(const QString &s, int from = -1) const;
#endif
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
    inline QT_ASCII_CAST_WARN bool operator==(const QString &s2) const;
    inline QT_ASCII_CAST_WARN bool operator!=(const QString &s2) const;
    inline QT_ASCII_CAST_WARN bool operator<(const QString &s2) const;
    inline QT_ASCII_CAST_WARN bool operator>(const QString &s2) const;
    inline QT_ASCII_CAST_WARN bool operator<=(const QString &s2) const;
    inline QT_ASCII_CAST_WARN bool operator>=(const QString &s2) const;
#endif

和QString之间的操作
 
    short toShort(bool *ok = Q_NULLPTR, int base = 10) const;
    ushort toUShort(bool *ok = Q_NULLPTR, int base = 10) const;
    int toInt(bool *ok = Q_NULLPTR, int base = 10) const;
    uint toUInt(bool *ok = Q_NULLPTR, int base = 10) const;
    long toLong(bool *ok = Q_NULLPTR, int base = 10) const;
    ulong toULong(bool *ok = Q_NULLPTR, int base = 10) const;
    qlonglong toLongLong(bool *ok = Q_NULLPTR, int base = 10) const;
    qulonglong toULongLong(bool *ok = Q_NULLPTR, int base = 10) const;
    float toFloat(bool *ok = Q_NULLPTR) const;
    double toDouble(bool *ok = Q_NULLPTR) const;
    QByteArray toBase64(Base64Options options) const;
    QByteArray toBase64() const; // ### Qt6 merge with previous
    QByteArray toHex() const;
    QByteArray toPercentEncoding(const QByteArray &exclude = QByteArray(),
                                 const QByteArray &include = QByteArray(),
                                 char percent = '%') const;
 
数值转换
 
    QByteArray &setNum(short, int base = 10);
    QByteArray &setNum(ushort, int base = 10);
    QByteArray &setNum(int, int base = 10);
    QByteArray &setNum(uint, int base = 10);
    QByteArray &setNum(qlonglong, int base = 10);
    QByteArray &setNum(qulonglong, int base = 10);
    QByteArray &setNum(float, char f = 'g', int prec = 6);
    QByteArray &setNum(double, char f = 'g', int prec = 6);
    QByteArray &setRawData(const char *a, uint n); // ### Qt 6: use an int

    static QByteArray number(int, int base = 10) Q_REQUIRED_RESULT;
    static QByteArray number(uint, int base = 10) Q_REQUIRED_RESULT;
    static QByteArray number(qlonglong, int base = 10) Q_REQUIRED_RESULT;
    static QByteArray number(qulonglong, int base = 10) Q_REQUIRED_RESULT;
    static QByteArray number(double, char f = 'g', int prec = 6) Q_REQUIRED_RESULT;
    static QByteArray fromRawData(const char *, int size) Q_REQUIRED_RESULT;
    static QByteArray fromBase64(const QByteArray &base64, Base64Options options) Q_REQUIRED_RESULT;
    static QByteArray fromBase64(const QByteArray &base64) Q_REQUIRED_RESULT; // ### Qt6 merge with previous
    static QByteArray fromHex(const QByteArray &hexEncoded) Q_REQUIRED_RESULT;
    static QByteArray fromPercentEncoding(const QByteArray &pctEncoded, char percent = '%') Q_REQUIRED_RESULT;

#if defined(Q_OS_MAC) || defined(Q_QDOC)
    static QByteArray fromCFData(CFDataRef data);
    static QByteArray fromRawCFData(CFDataRef data);
    CFDataRef toCFData() const Q_DECL_CF_RETURNS_RETAINED;
    CFDataRef toRawCFData() const Q_DECL_CF_RETURNS_RETAINED;
#  if defined(__OBJC__) || defined(Q_QDOC)
    static QByteArray fromNSData(const NSData *data);
    static QByteArray fromRawNSData(const NSData *data);
    NSData *toNSData() const Q_DECL_NS_RETURNS_AUTORELEASED;
    NSData *toRawNSData() const Q_DECL_NS_RETURNS_AUTORELEASED;
#  endif
#endif

    typedef char *iterator;
    typedef const char *const_iterator;
    typedef iterator Iterator;
    typedef const_iterator ConstIterator;
    typedef std::reverse_iterator<iterator> reverse_iterator;
    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
    inline iterator begin();
    inline const_iterator begin() const;
    inline const_iterator cbegin() const;
    inline const_iterator constBegin() const;
    inline iterator end();
    inline const_iterator end() const;
    inline const_iterator cend() const;
    inline const_iterator constEnd() const;
    reverse_iterator rbegin() { return reverse_iterator(end()); }
    reverse_iterator rend() { return reverse_iterator(begin()); }
    const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
    const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
    const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
    const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
 
 
迭代器
 
    // stl compatibility
    typedef int size_type;
    typedef qptrdiff difference_type;
    typedef const char & const_reference;
    typedef char & reference;
    typedef char *pointer;
    typedef const char *const_pointer;
    typedef char value_type;
    void push_back(char c);
    void push_back(const char *c);
    void push_back(const QByteArray &a);
    void push_front(char c);
    void push_front(const char *c);
    void push_front(const QByteArray &a);
push操作
 
    static inline QByteArray fromStdString(const std::string &s);
    inline std::string toStdString() const;

    inline int count() const { return d->size; }
    int length() const { return d->size; }
    bool isNull() const;

    inline QByteArray(QByteArrayDataPtr dd)
        : d(static_cast<Data *>(dd.ptr))
    {
    }

private:
    operator QNoImplicitBoolCast() const;
    Data *d;
    void reallocData(uint alloc, Data::AllocationOptions options);
    void expand(int i);
    QByteArray nulTerminated() const;

    static QByteArray toLower_helper(const QByteArray &a);
    static QByteArray toLower_helper(QByteArray &a);
    static QByteArray toUpper_helper(const QByteArray &a);
    static QByteArray toUpper_helper(QByteArray &a);
    static QByteArray trimmed_helper(const QByteArray &a);
    static QByteArray trimmed_helper(QByteArray &a);
    static QByteArray simplified_helper(const QByteArray &a);
    static QByteArray simplified_helper(QByteArray &a);

    friend class QByteRef;
    friend class QString;
    friend Q_CORE_EXPORT QByteArray qUncompress(const uchar *data, int nbytes);
public:
    typedef Data * DataPtr;
    inline DataPtr &data_ptr() { return d; }
};


  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值