QT6 源(55)篇五:存储 c 语言字符串的类 QByteArray 的源码阅读

(6)

#ifndef QBYTEARRAY_H
#define QBYTEARRAY_H

#include <QtCore/qrefcount.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qarraydata.h>
#include <QtCore/qarraydatapointer.h>
#include <QtCore/qcontainerfwd.h>
#include <QtCore/qbytearrayalgorithms.h>
#include <QtCore/qbytearrayview.h>

#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

#include <string>
#include <iterator>

#ifndef QT5_NULL_STRINGS
// Would ideally be off, but in practice breaks too much (Qt 6.0).
#define QT5_NULL_STRINGS 1
#endif

#ifdef truncate
#error qbytearray.h must be included before any header file that defines truncate
#endif

#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
Q_FORWARD_DECLARE_CF_TYPE(CFData);
Q_FORWARD_DECLARE_OBJC_CLASS(NSData);
#endif

QT_BEGIN_NAMESPACE  //说明本类定义于 QT 的全局命名空间

class QString;
class QDataStream;

/*
struct QArrayData
{   QBasicAtomicInt ref_ ;
    ArrayOptions    flags;
    qsizetype       alloc;

    static void *   allocate(...) noexcept;
    static void   deallocate(...) noexcept;
};

template <class T>
struct QTypedArrayData : QArrayData {  }; //本类无数据成员

template <class T>
struct QArrayDataPointer //上面的注释给出了学习与阅读本头文件的因缘
{
    Data * d  ; //Data = QTypedArrayData<T> 包含了申请释放内存的成员方法
    T    * ptr; //真正的堆区中的数据起点
    qsizetype size;
};

class QString
{   typedef QTypedArrayData<char16_t> Data; //一个类型定义

    DataPointer d;
  //DataPointer = QStringPrivate = QArrayDataPointer<char16_t>;
}; 本注释用于解释本 QByteArray 类的数据结构的组成
*/

using QByteArrayData = QArrayDataPointer<char>; //类型起别名,这似乎是个指针类型

#  define QByteArrayLiteral(str) \
    (QByteArray(QByteArrayData(nullptr, const_cast<char *>(str), sizeof(str) - 1))) \
    /**/

class Q_CORE_EXPORT QByteArray //本类的真正的数据成员,就是一个指针
{
public:
    using DataPointer = QByteArrayData; //看起来是指针类型

private:
    DataPointer d; //本类的数据成员,这是一个指针

    static const char _empty; //本类的静态数据成员

    typedef QTypedArrayData<char> Data; //概略定义在上面,这是类型定义,关于内存分配
public:

    enum Base64Option {
        Base64Encoding = 0,
        Base64UrlEncoding = 1,

        KeepTrailingEquals = 0,
        OmitTrailingEquals = 2,

        IgnoreBase64DecodingErrors = 0,
        AbortOnBase64DecodingErrors = 4,
    };
    Q_DECLARE_FLAGS(Base64Options, Base64Option)
    // Base64Options = QFlags<Base64Option>

    enum class Base64DecodingStatus {
        Ok,
        IllegalInputLength,
        IllegalCharacter,
        IllegalPadding,
    };

    inline constexpr QByteArray() noexcept {} //默认的构造函数

    //Constructs a byte array containing the first size bytes of array data.
    //If data is 0, a null byte array is constructed.   指向以'\0'结尾的字符串
    //If size is negative, data is assumed to point to a '\0'-terminated string and
    //its length is determined dynamically.
    //QByteArray makes a deep copy of the string data. 深复制
    QByteArray(const char * data, qsizetype size = -1);

    //Constructs a byte array of size size with every byte set to c.
    QByteArray(qsizetype size, char c);

    QByteArray(qsizetype size, Qt::Initialization); //没有关于 Qt::Initialization的注释

    explicit inline QByteArray(const DataPointer & dd) : d(dd) { } //有参构造

    inline QByteArray(const QByteArray & a) noexcept : d(a.d) {} //copy 构造函数

    inline QByteArray(QByteArray && other)  noexcept // 移动构造函数
    { qSwap(d, other.d); }

    QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QByteArray)

    inline ~QByteArray(){}
/*  以宏定义的形式实现了 移动赋值运算符函数
#define QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(Class) \
    Class &operator=(Class &&other) noexcept { \
        swap(other); \
        return *this; \
    }
*/


    QByteArray & operator=(const QByteArray &) noexcept; //copy赋值运算符函数

    QByteArray & operator=(const char * str);
    //说明本 QByteArray 类直接接受 c 语言风格字符串的赋值

    //QArrayDataPointer<char> d; 这是本类唯一的数据成员
    inline void swap(QByteArray & other) noexcept { d.swap(other.d); }

    //Returns the number of bytes in this byte array.
    //The last byte in the byte array is at position size() - 1.
    //In addition, QByteArray ensures that the byte at position size() is always '\0',
    //so that you can use the return value of data() and constData() as
    //arguments to functions that expect '\0'-terminated strings.
    //If the QByteArray object was created from a raw data that didn't include the
    //trailing '\0'-termination byte,
    //then QByteArray doesn't add it automatically unless a deep copy is created.
    inline qsizetype size  () const { return d->size; }

    inline qsizetype count () const { return size(); }

    inline qsizetype length() const { return size(); }
    //综上,可见这三个函数是等价的,只是换个名字而已。返回本容器里实际包含的字节数

    void resize(qsizetype size); //Sets the size of the byte array to size bytes.
    //If size is greater than the current size,
    //the byte array is extended to make it size bytes with the extra
    //bytes added to the end. The new bytes are uninitialized.
    //If size is less than the current size,
    //bytes beyond position size are excluded from the byte array.
    //Note: While resize() will grow the capacity if needed,
    //it never shrinks capacity. To shed excess capacity, use squeeze().

    inline void squeeze()               //从不需要调用本函数
    {
        if (!d.isMutable())      return;

        if (d->needsDetach() || size() < capacity())
            reallocData(size(), QArrayData::KeepSize);
        if (d->constAllocatedCapacity())
            d->clearFlag(Data::CapacityReserved);
    }                 //tuning调子;音调   fine细粒的;细微的;细小的;敏锐的
    //Releases any memory not required to store the array's data.
    //The sole purpose of this function is to provide a means of
    //fine tuning微调 QByteArray's memory usage.
    //In general, you will rarely ever need to call this function.

    inline void reserve(qsizetype size) //从不需要调用本函数
    {
        if (d->needsDetach() || asize > capacity() - d->freeSpaceAtBegin())
            reallocData(qMax(size(), asize), QArrayData::KeepSize);
        if (d->constAllocatedCapacity())
            d->setFlag(Data::CapacityReserved);
    }
    //Attempts to allocate memory for at least size bytes.
    //If you know in advance how large the byte array will be,
    //you can call this function,
    //and if you call resize() often you are likely to get better performance.
    //The sole purpose of this function is to provide a means of
    //fine tuning QByteArray's memory usage.
    //In general, you will rarely ever need to call this function.

    bool isNull() const; //以下成员函数的排列顺序是先读取属性后设置写入

    inline bool isEmpty() const { return size() == 0; } //多用这个

    inline qsizetype capacity() const //从不需要调用本函数
    { return qsizetype(d->constAllocatedCapacity()); }
    //Returns the maximum number of bytes that can be stored in the
    //byte array without forcing a reallocation.
    //The sole purpose of this function is to provide a means of
    //fine tuning QByteArray's memory usage.
    //In general, you will rarely ever need to call this function.
    //If you want to know how many bytes are in the byte array, call size().

    inline DataPointer & data_ptr() { return d; } //返回本类中封装的数据成员给外界用
    //QArrayDataPointer<char> d;

    inline char * data() //返回堆区中的字节数组的起点
    {
        detach();
        Q_ASSERT(d.data());
        return d.data();
    }
/*
template <class T>
struct QArrayDataPointer
{
    Data * d  ; //Data = QTypedArrayData<T> 包含了申请释放内存的成员方法
    T    * ptr; //真正的堆区中的数据起点
    qsizetype size;

    T * data() { return ptr; }
};
*/
    inline const char * data() const
    {
#if QT5_NULL_STRINGS == 1
        return d.data() ? d.data() : &_empty;
#else
        return d.data();
#endif
    }

#ifndef QT_NO_CAST_FROM_BYTEARRAY //类型转换运算符函数。经本函数可以默认转换为 const char *
    inline operator const char *() const { return data(); }
    inline operator const void *() const { return data(); }
#endif

    inline const char * constData() const { return data(); }

    QByteArray & fill(char c, qsizetype size = -1);
    //Sets every byte in the byte array to ch.
    //If size is different from -1 (the default),
    //the byte array is resized to size size beforehand.操作前


    inline void detach() //这个函数没有注释,是为了分离共享,准备写入数据
    {
        if (d->needsDetach())
            reallocData(size(), QArrayData::KeepSize);
    }

    inline bool isDetached() const { return !d->isShared(); }

    inline bool isSharedWith(const QByteArray & other) const //共享即是严格等价
    { return data() == other.data() && size() == other.size(); }

    //Returns true if this byte array contains only ASCII uppercase letters,
    //otherwise returns false.
    bool isUpper() const;

    bool isLower() const;
    //Returns true if this byte array contains only lowercase ASCII letters,
    //otherwise returns false.

    void clear();
    //Clears the contents of the byte array and makes it null.

    inline char at(qsizetype i) const
    {
        Q_ASSERT(size_t(i) < size_t(size()));
        return d.data()[i];
    }

    inline char operator[](qsizetype i) const
    {
        Q_ASSERT(size_t(i) < size_t(size()));
        return d.data()[i];
    }

    [[nodiscard]] inline char & operator[](qsizetype i)
    {
        Q_ASSERT(i >= 0 && i < size());
        return data()[i];
    }


    [[nodiscard]]        char   front() const { return at(0); } //首字符
    [[nodiscard]] inline char & front()       { return operator[](0); } //尾字符

    [[nodiscard]]        char   back() const { return at(size() - 1); }
    [[nodiscard]] inline char & back()       { return operator[](size() - 1); }

    [[nodiscard]] QByteArray first(qsizetype n) const //取开头的 n 个字符
    {   Q_ASSERT(n >= 0);   Q_ASSERT(n <= size());
        return QByteArray(data(), n);
    }

    [[nodiscard]] QByteArray last(qsizetype n)  const //取末尾的 n 个字符
    {   Q_ASSERT(n >= 0);   Q_ASSERT(n <= size());
        return QByteArray(data() + size() - n, n);
    }

    [[nodiscard]] QByteArray sliced(qsizetype pos) const //取下标 pos 开始的所有剩余字符
    {   Q_ASSERT(pos >= 0); Q_ASSERT(pos <= size());
        return QByteArray(data() + pos, size() - pos);
    }

    [[nodiscard]] QByteArray sliced(qsizetype pos, qsizetype n) const
    {   Q_ASSERT(pos >= 0); Q_ASSERT(n >= 0);           //取下标 pos 开始的 n 个字符
        Q_ASSERT(size_t(pos) + size_t(n) <= size_t(size()));
        return QByteArray(data() + pos, n);
    }

    [[nodiscard]] QByteArray chopped(qsizetype len) const //扔掉末尾的 n 个字符
    {   Q_ASSERT(len >= 0); Q_ASSERT(len <= size());
        return first(size() - len);
    }

    void chop    (qsizetype n  ); //返回值不一样,修改的是自己,扔掉末尾的 n 个字符

    void truncate(qsizetype pos);  //修改本字符串,扔掉下标 pos 开始的所有字符


    //If you know that len cannot be out of bounds,
    //use first() instead in new code, because it is faster.
    [[nodiscard]] QByteArray left (qsizetype len) const; //= first(),first 更好
    [[nodiscard]] QByteArray right(qsizetype len) const; //= last (),last  更好
    [[nodiscard]] QByteArray mid(qsizetype index, qsizetype len = -1) const;
                                                         //= sliced() sliced 更好

    bool startsWith(char c) const { return size() > 0 && front() == c; }

    bool startsWith(QByteArrayView bv) const
    { return QtPrivate::startsWith(qToByteArrayViewIgnoringNull(*this), bv); }

    bool endsWith  (char c) const { return size() > 0 && back () == c; }

    bool endsWith(QByteArrayView bv) const
    { return QtPrivate::endsWith(qToByteArrayViewIgnoringNull(*this), bv); }

    //Returns the index position of the start of the first occurrence of the
    //byte c in this byte array, searching forward from index position from.
    //Returns -1 if no match is found. 从下标 from开始正向查找字符 c所在的下标,找不到返 -1
    qsizetype indexOf(char c, qsizetype from = 0) const;

    qsizetype indexOf(QByteArrayView bv, qsizetype from = 0) const
    { return QtPrivate::findByteArray(qToByteArrayViewIgnoringNull(*this), from, bv); }

    //Returns the index position of the start of the last occurrence of
    //byte c in this byte array, searching backward from index position from.
    //If from is -1 (the default),  从下标 from开始逆向查找字符 c所在的下标,找不到返 -1
    //the search starts at the last byte (at index size() - 1).
    //Returns -1 if no match is found.
    qsizetype lastIndexOf(char c, qsizetype from = -1) const;

    qsizetype lastIndexOf(QByteArrayView bv) const
    { return lastIndexOf(bv, size()); }

    qsizetype lastIndexOf(QByteArrayView bv, qsizetype from) const
    { return QtPrivate::lastIndexOf(qToByteArrayViewIgnoringNull(*this), from, bv); }

    inline bool contains(char           c ) const { return indexOf(c ) != -1; }
    inline bool contains(QByteArrayView bv) const { return indexOf(bv) != -1; }

    qsizetype count(char c) const; //返回字符串里字符 c 出现的次数
    //Returns the number of occurrences of byte c in the byte array.

    qsizetype count(QByteArrayView bv) const
    { return QtPrivate::count(qToByteArrayViewIgnoringNull(*this), bv); }

    inline int compare(QByteArrayView a, //看不懂,也不了解 QByteArrayView,略
                       Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
    {
        return cs == Qt::CaseSensitive ? QtPrivate::compareMemory(*this, a) :
                   qstrnicmp(data(), size(), a.data(), a.size());
    }

    typedef       char *       iterator; //本容器里的迭代器很简单,直接就是未封装的裸指针
    typedef                    iterator   Iterator;

    typedef const char * const_iterator;
    typedef              const_iterator ConstIterator;

    typedef std::reverse_iterator<iterator>             reverse_iterator;
    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

    inline       iterator      begin()       { return data(); } //返回指向字节的裸指针
    inline const_iterator      begin() const { return data(); }
    inline const_iterator     cbegin() const { return data(); }
    inline const_iterator constBegin() const { return data(); }

    inline       iterator      end()       { return data() + size(); }
    inline const_iterator      end() const { return data() + size(); }
    inline const_iterator     cend() const { return data() + size(); }
    inline const_iterator constEnd() const { return data() + size(); }

          reverse_iterator  rbegin()
    { return reverse_iterator(end()); }

    const_reverse_iterator  rbegin() const
    { return const_reverse_iterator(end()); }

    const_reverse_iterator crbegin() const
    { return const_reverse_iterator(end()); }

           reverse_iterator rend()
    { return reverse_iterator(begin()); }

    const_reverse_iterator  rend() const
    { return const_reverse_iterator(begin()); }

    const_reverse_iterator crend() const
    { return const_reverse_iterator(begin()); }

    //将字节数组拆分为子数组,只要 sep出现,并返回这些数组的列表。
    //如果字节数组中没有任何地方与 sep 匹配,则 split()返回一个包含该字节数组的单元素列表。
    //拆分后的子字符串里都不再包含 sep 字符。"12abcade" -> "12" "bc" "de"
    QList<QByteArray> split(char sep) const;

    [[nodiscard]] QByteArray repeated(qsizetype times) const;
    //Returns a copy of this byte array repeated the specified number of times.
    //If times is less than 1, an empty byte array is returned.


//经测试,这些成员函数都存在 ,  #if 成立
//说明 QByteArray 类型的数据可以和 QString 类型的数据直接比较
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
    QT_ASCII_CAST_WARN inline bool operator==(const QString &s2) const;
    QT_ASCII_CAST_WARN inline bool operator!=(const QString &s2) const;
    QT_ASCII_CAST_WARN inline bool operator< (const QString &s2) const;
    QT_ASCII_CAST_WARN inline bool operator> (const QString &s2) const;
    QT_ASCII_CAST_WARN inline bool operator<=(const QString &s2) const;
    QT_ASCII_CAST_WARN inline bool operator>=(const QString &s2) const;
#endif


    friend inline //全局的运算符类友元函数
    bool operator==(const QByteArray &a1, const QByteArray & a2) noexcept
    { return QByteArrayView(a1) == QByteArrayView(a2); }

    friend inline  //左值引用形式的比较
    bool operator==(const QByteArray & a1, const char       * a2) noexcept
    { return a2 ? QtPrivate::compareMemory(a1, a2) == 0 : a1.isEmpty(); }

    friend inline  //左值引用形式的比较
    bool operator==(const char      * a1, const QByteArray & a2) noexcept
    { return a1 ? QtPrivate::compareMemory(a1, a2) == 0 : a2.isEmpty(); }

    friend inline  //左值引用形式的比较
    bool operator!=(const QByteArray & a1, const QByteArray & a2) noexcept
    { return !(a1==a2); }

    friend inline  //左值引用形式的比较
    bool operator!=(const QByteArray & a1, const char *a2) noexcept
    { return a2 ? QtPrivate::compareMemory(a1, a2) != 0 : !a1.isEmpty(); }

    friend inline
    bool operator!=(const char * a1, const QByteArray & a2) noexcept
    { return a1 ? QtPrivate::compareMemory(a1, a2) != 0 : !a2.isEmpty(); }

    friend inline
    bool operator<(const QByteArray &a1, const QByteArray &a2) noexcept
    { return QtPrivate::compareMemory(QByteArrayView(a1), QByteArrayView(a2)) < 0; }

    friend inline
    bool operator<(const QByteArray &a1, const char * a2) noexcept
    { return QtPrivate::compareMemory(a1, a2) < 0; }

    friend inline
    bool operator<(const char *a1, const QByteArray &a2) noexcept
    { return QtPrivate::compareMemory(a1, a2) < 0; }

    friend inline
    bool operator<=(const QByteArray &a1, const QByteArray &a2) noexcept
    { return QtPrivate::compareMemory(QByteArrayView(a1), QByteArrayView(a2)) <= 0; }

    friend inline
    bool operator<=(const QByteArray &a1, const char *a2) noexcept
    { return QtPrivate::compareMemory(a1, a2) <= 0; }

    friend inline
    bool operator<=(const char *a1, const QByteArray &a2) noexcept
    { return QtPrivate::compareMemory(a1, a2) <= 0; }

    friend inline
    bool operator>(const QByteArray &a1, const QByteArray &a2) noexcept
    { return QtPrivate::compareMemory(QByteArrayView(a1), QByteArrayView(a2)) > 0; }

    friend inline
    bool operator>(const QByteArray &a1, const char *a2) noexcept
    { return QtPrivate::compareMemory(a1, a2) > 0; }

    friend inline
    bool operator>(const char *a1, const QByteArray &a2) noexcept
    { return QtPrivate::compareMemory(a1, a2) > 0; }

    friend inline
    bool operator>=(const QByteArray &a1, const QByteArray &a2) noexcept
    { return QtPrivate::compareMemory(QByteArrayView(a1), QByteArrayView(a2)) >= 0; }

    friend inline
    bool operator>=(const QByteArray &a1, const char *a2) noexcept
    { return QtPrivate::compareMemory(a1, a2) >= 0; }

    friend inline
    bool operator>=(const char *a1, const QByteArray &a2) noexcept
    { return QtPrivate::compareMemory(a1, a2) >= 0; }

    // Check isEmpty() instead of isNull() for backwards compatibility.
    friend inline  //以下这些是处理与  std::nullptr_t  的比较
    bool operator==(const QByteArray &a1, std::nullptr_t) noexcept
    { return a1.isEmpty(); }

    friend inline //与 std::nullptr_t 的比较更关注于相等或不等的比较
    bool operator!=(const QByteArray &a1, std::nullptr_t) noexcept
    { return !a1.isEmpty(); }

    friend inline
    bool operator< (const QByteArray &  , std::nullptr_t) noexcept
    { return false; }

    friend inline
    bool operator> (const QByteArray &a1, std::nullptr_t) noexcept
    { return !a1.isEmpty(); }

    friend inline
    bool operator<=(const QByteArray &a1, std::nullptr_t) noexcept
    { return a1.isEmpty(); }

    friend inline
    bool operator>=(const QByteArray &  , std::nullptr_t) noexcept
    { return true; }

    friend inline
    bool operator==(std::nullptr_t, const QByteArray &a2) noexcept
    { return a2 == nullptr; }

    friend inline
    bool operator!=(std::nullptr_t, const QByteArray &a2) noexcept
    { return a2 != nullptr; }

    friend inline
    bool operator< (std::nullptr_t, const QByteArray &a2) noexcept
    { return a2 >  nullptr; }

    friend inline
    bool operator> (std::nullptr_t, const QByteArray &a2) noexcept
    { return a2 <  nullptr; }

    friend inline
    bool operator<=(std::nullptr_t, const QByteArray &a2) noexcept
    { return a2 >= nullptr; }

    friend inline
    bool operator>=(std::nullptr_t, const QByteArray &a2) noexcept
    { return a2 <= nullptr; }


#if !defined(Q_CLANG_QDOC)  //这些函数都是存在的
    //Returns a copy of the byte array in which each
    //ASCII uppercase letter converted to lowercase.
    [[nodiscard]] QByteArray toLower() const & //小写字符不动,把大写变成小写
    { return toLower_helper(*this); }

    [[nodiscard]] QByteArray toLower() &&
    { return toLower_helper(*this); }

    //Returns a copy of the byte array in which each
    //ASCII lowercase letter converted to uppercase.
    [[nodiscard]] QByteArray toUpper() const & //全部返回大写字符
    { return toUpper_helper(*this); }

    [[nodiscard]] QByteArray toUpper() &&
    { return toUpper_helper(*this); }

    //const &表示这是一个常量引用限定符,说明这个函数是左值引用的常量成员函数。
    //这意味着该函数只能被左值对象调用,并且不会修改对象的状态。
    //同时,const保证函数内部不会修改成员变量。
    [[nodiscard]] QByteArray trimmed() const &
    { return trimmed_helper(*this); }

    //Returns a copy of this byte array with spacing characters removed from
    //the start and end.
    //The spacing characters are those for which the standard C++ isspace()
    //function returns true in the C locale;
    //these are the ASCII characters tabulation '\t', line feed '\n',
    //carriage return '\r', vertical tabulation '\v',
    //form feed '\f', and space ' '.
    [[nodiscard]] QByteArray trimmed() &&
    { return trimmed_helper(*this); }

    //Returns a copy of this byte array that has spacing characters removed from
    //the start and end, and in which each sequence of internal spacing characters
    //is replaced with a single space.
    [[nodiscard]] QByteArray simplified() const &
    { return simplified_helper(*this); }

    [[nodiscard]] QByteArray simplified() &&
    { return simplified_helper(*this); }
#else
    [[nodiscard]] QByteArray toLower() const;
    [[nodiscard]] QByteArray toUpper() const;
    [[nodiscard]] QByteArray trimmed() const;
    [[nodiscard]] QByteArray simplified() const;
#endif

    //返回一个大小为 width 的字节数组,其中包含这个字节数组,并用 fill 字符填充。
    //如果 truncate是 false,且 byte 数组的 size()大于 width,
    //则返回的 byte 数组是此 byte 数组的副本。
    //如果 truncate为true,且byte 数组的 size()大于 width,
    //则删除位置 width 之后的 byte 数组副本中的任何字节,并返回副本。
    [[nodiscard]] QByteArray leftJustified (qsizetype width,
                            char fill = ' ', bool truncate = false) const;
    //返回一个指定长度的新字节数组,原内容左对齐,右侧填充指定的字符,默认是空格。
    //函数可能有参数指定填充字符和是否截断原内容。
    //当原数组长度小于width时,右侧填充fill字符;
    //如果原长度超过width,是否截取取决于truncate参数是否为true。

    //Returns a byte array of size width that contains the fill byte followed by
    //this byte array.
    //If truncate is false and the size of the byte array is more than width,
    //then the returned byte array is a copy of this byte array.
    //If truncate is true and the size of the byte array is more than width,
    //then the resulting byte array is truncated at position width.
    [[nodiscard]] QByteArray rightJustified(qsizetype width,
                            char fill = ' ', bool truncate = false) const;
    //通常用于将字符串右对齐,可能是在填充字符的情况下。
    //比如,将字符串调整到指定长度,右侧对齐,左侧填充空格或其他字符。


    //Returns the byte array converted to a short using base base,
    //which is ten by default. Bases 0 and 2 through 36 are supported,
    //using letters for digits beyond 9; A is ten, B is eleven and so on.
    //If base is 0, the base is determined automatically using the following rules:
    //If the byte array begins with "0x", it is assumed to be hexadecimal;
    //otherwise, if it begins with "0", it is assumed to be octal;
    //otherwise it is assumed to be decimal.
    //Returns 0 if the conversion fails.
    //If ok is not nullptr, failure is reported by setting *ok to false,
    //and success by setting *ok to true.
    //Note: The conversion of the number is performed in the default C locale,
    //regardless of the user's locale.
    //Use QLocale to perform locale-aware conversions between numbers and strings.
    //经测试, 形参 base 指出字符串里的文本的数据进制。这些函数的输出结果都是 10进制
    short      toShort    (bool *ok = nullptr, int base = 10) const;
    ushort     toUShort   (bool *ok = nullptr, int base = 10) const;
    int        toInt      (bool *ok = nullptr, int base = 10) const;
    uint       toUInt     (bool *ok = nullptr, int base = 10) const;
    long       toLong     (bool *ok = nullptr, int base = 10) const;
    ulong      toULong    (bool *ok = nullptr, int base = 10) const;
    qlonglong  toLongLong (bool *ok = nullptr, int base = 10) const;
    qulonglong toULongLong(bool *ok = nullptr, int base = 10) const;

    //Warning: The QByteArray content may only contain valid numerical characters
    //which includes the plus/minus sign,
    //the character e used in scientific notation, and the decimal point.
    //Including the unit or additional characters leads to a conversion error.
    //This function ignores leading and trailing whitespace.
    float      toFloat    (bool *ok       = nullptr) const;
    double     toDouble   (bool *ok       = nullptr) const;

    QByteArray toHex      (char separator = '\0'   ) const;
    //Returns a hex encoded copy of the byte array.
    //The hex encoding uses the numbers 0-9 and the letters a-f.
    //If separator is not '\0',
    //the separator character is inserted between the hex bytes.
    //本函把字符数组中的字符的 ascii码转换为十六进制输出,并以形参字符 separator间隔每个字符

    QByteArray toBase64(Base64Options options = Base64Encoding) const;
    QByteArray toPercentEncoding(const QByteArray &exclude = QByteArray(),
                                 const QByteArray &include = QByteArray(),
                                 char percent = '%') const;
    //Returns a URI/URL-style percent-encoded copy of this byte array.
    //The percent parameter allows you to override the default '%' character for
    //another.   By default, this function will encode all bytes that are not
    //one of the following:
    //ALPHA ("a" to "z" and "A" to "Z") / DIGIT (0 to 9) / "-" / "." / "_" / "~"
    //To prevent bytes from being encoded pass them to exclude.
    //To force bytes to be encoded pass them to include.
    //The percent character is always encoded.  不懂,先记录下

    [[nodiscard]] static QByteArray fromRawData(const char *data, qsizetype size)
    {
        return QByteArray(DataPointer(nullptr, const_cast<char *>(data), size));
    }

    [[nodiscard]] static QByteArray       fromPercentEncoding(
        const QByteArray &pctEncoded, char percent = '%');

    class FromBase64Result;
    [[nodiscard]] static FromBase64Result fromBase64Encoding(
        QByteArray &&base64, Base64Options options = Base64Encoding);

    [[nodiscard]] static FromBase64Result fromBase64Encoding(
        const QByteArray &base64, Base64Options options = Base64Encoding);

    [[nodiscard]] static QByteArray fromBase64(
        const QByteArray &base64, Base64Options options = Base64Encoding);

    [[nodiscard]] static QByteArray fromHex(const QByteArray &hexEncoded);
    //Returns a decoded copy of the hex encoded array hexEncoded.
    //Input is not checked for validity;
    //invalid characters in the input are skipped,
    //enabling the decoding process to continue with subsequent characters.
    //For example:
    //      QByteArray text = QByteArray::fromHex("517420697320677265617421");
    //                 text.data();   // returns "Qt is great!"
    //本静态函数把形参中的字符作为 16进制的 ascii码转换为对应的字符,存储在字节数组中返回

    //number()系列把形参 1中的十进制数按形参 2的进制转换后,作为字符串输出
    [[nodiscard]] static QByteArray number(int       , int base = 10);
    [[nodiscard]] static QByteArray number(uint      , int base = 10);
    [[nodiscard]] static QByteArray number(long      , int base = 10);
    [[nodiscard]] static QByteArray number(ulong     , int base = 10);
    [[nodiscard]] static QByteArray number(qlonglong , int base = 10);
    [[nodiscard]] static QByteArray number(qulonglong, int base = 10);
    [[nodiscard]] static QByteArray number(double    , char format = 'g',
                                           int precision = 6);
    //eturns a byte-array representing the floating-point number n as text.
    //Returns a byte array containing a string representing n,
    //with a given format and precision,
    //with the same meanings as for QString::number(double, char, int).
    //For example:
    //QByteArray ba = QByteArray::number(12.3456, 'E', 3);
    //           ba == 1.235E+01

    static inline QByteArray fromStdString(const std::string &s)
    { return QByteArray(s.data(), qsizetype(s.size())); }

    inline std::string         toStdString() const
    { return std::string(constData(), length()); }

    //这些函数没有静态函数好用,自然
    inline QByteArray &setNumsetNum(ushort n, int base = 10)
    { return setNum(qulonglong(n), base); }

    inline QByteArray &setNum(short n, int base = 10)
    { return setNum(qlonglong(n) , base); }

    inline QByteArray &setNum( int  n, int base = 10)
    { return setNum(qlonglong(n), base); }

    inline QByteArray &setNum(uint  n, int base = 10)
    { return setNum(qulonglong(n), base); }

    inline QByteArray &setNum( long n, int base = 10)
    { return setNum(qlonglong(n), base); }

    inline QByteArray &setNum(ulong n, int base = 10)
    { return setNum(qulonglong(n), base); }

           QByteArray &setNum(qlonglong , int base = 10);
           QByteArray &setNum(qulonglong, int base = 10);

    inline QByteArray &setNum(float n, char format, int precision = 6)
    { return setNum(double(n), format, precision); }

           QByteArray &setNum(double, char format = 'g', int precision = 6);

           QByteArray &setRawData(const char *a, qsizetype n);


#if defined(Q_OS_DARWIN) || 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;
    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


    QByteArray & prepend(char c) //Prepends the byte c to this byte array.
    { return insert(0, QByteArrayView(&c, 1)); }

    inline     //Prepends count copies of byte c to this byte array.
    QByteArray & prepend(qsizetype count, char c)
    { return insert(0, n, ch); }

    //Prepends the '\0'-terminated string s to this byte array.
    QByteArray & prepend(const char * s)
    { return insert(0, QByteArrayView(s, qsizetype(qstrlen(s)))); }

    QByteArray & prepend(const char * s, qsizetype len)
    { return insert(0, QByteArrayView(s, len)); }
    //Prepends len bytes starting at str to this byte array.
    //The bytes prepended may include '\0' bytes.

    QByteArray & prepend(const QByteArray &a);

    QByteArray & prepend(QByteArrayView a)
    { return insert(0, a); }

    QByteArray & append(char c);

    inline
    QByteArray & append(qsizetype count, char c)
    { return insert(size(), n, ch); }

    QByteArray & append(const char *s)
    { return append(QByteArrayView(s, qsizetype(qstrlen(s)))); }

    QByteArray & append(const char *s, qsizetype len)
    { return append(QByteArrayView(s, len)); }

    QByteArray & append(const QByteArray &a);

    QByteArray & append(QByteArrayView a)
    { return insert(size(), a); }

    QByteArray &operator+=(char c)
    { return append(c); }

    QByteArray &operator+=(const char *s)
    { return append(s); }

    QByteArray &operator+=(const QByteArray &a)
    { return append(a); }

    QByteArray &operator+=(QByteArrayView a)
    { return append(a); }



    QByteArray & insert(qsizetype i, QByteArrayView data);

    QByteArray & insert(qsizetype i, char c)
    { return insert(i, QByteArrayView(&c, 1)); }

    QByteArray & insert(qsizetype i, qsizetype count, char c);

    inline
    QByteArray & insert(qsizetype i, const char * s)
    { return insert(i, QByteArrayView(s)); }

    //Inserts len bytes, starting at s, at position i in the byte array.
    //This array grows to accommodate the insertion.
    //If i is beyond the end of the array,
    //the array is first extended with space characters to reach this i.
    QByteArray & insert(qsizetype i, const char * s, qsizetype len)
    { return insert(i, QByteArrayView(s, len)); }

    inline
    QByteArray & insert(qsizetype i, const QByteArray & data)
    { return insert(i, QByteArrayView(data)); }


    QByteArray & replace(qsizetype index, qsizetype len, QByteArrayView s);

    QByteArray & replace(char before, QByteArrayView after)
    { return replace(QByteArrayView(&before, 1), after); }

    QByteArray & replace(QByteArrayView before, QByteArrayView after);

    //Replaces every occurrence of the byte before with the byte after.
    QByteArray & replace(char before, char after);

    //Replaces len bytes from index position pos with alen bytes starting at
    //position after. The bytes inserted may include '\0' bytes.
    QByteArray & replace(qsizetype index, qsizetype len,
                         const char * s , qsizetype alen)
    { return replace(index, len, QByteArrayView(s, alen)); }

    QByteArray & replace(const char * before, qsizetype bsize,
                         const char * after , qsizetype asize)
    { return replace(QByteArrayView(before, bsize), QByteArrayView(after, asize)); }
    //Replaces every occurrence of the bsize bytes starting at before with the
    //asize bytes starting at after.
    //Since the sizes of the strings are given by bsize and asize,
    //they may contain '\0' bytes and do not need to be '\0'-terminated.


    //Removes len bytes from the array, starting at index position pos,
    //and returns a reference to the array.
    //If pos is out of range, nothing happens.
    //If pos is valid, but pos + len is larger than the size of the array,
    //the array is truncated at position pos.
    //Element removal will preserve the array's capacity and not reduce the
    //amount of allocated memory.
    //To shed extra capacity and free as much memory as possible,
    //call squeeze() after the last change to the array's size.
    QByteArray & remove(qsizetype index, qsizetype len);

    template <typename Predicate> //带断言的删除
    QByteArray & removeIf(Predicate pred)
    {
        QtPrivate::sequential_erase_if(*this, pred);
        return *this;
    }


    // stl compatibility  与 STL 的兼容
    typedef qsizetype 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)  //为了兼容,实际上本 QT写的  append  prepend 就很好
    { append(c); }

    void push_back(const char * s)
    { append(s); }

    void push_back(const QByteArray & a)
    { append(a); }

    void push_back(QByteArrayView a)
    { append(a); }

    void push_front(char c)
    { prepend(c); }

    void push_front(const char * c)
    { prepend(c); }

    void push_front(const QByteArray & a)
    { prepend(a); }

    void push_front(QByteArrayView a)
    { prepend(a); }

    void shrink_to_fit() { squeeze(); }

    iterator erase(const_iterator first, const_iterator last);
    //这个函数的使用,要使用迭代器作为参数

private:
    void reallocData(qsizetype alloc, QArrayData::AllocationOption option);
    void reallocGrowData(qsizetype n);
    void expand(qsizetype 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 QString;  //友元类

    friend Q_CORE_EXPORT
    QByteArray qUncompress(const uchar *data, qsizetype nbytes);

}; //完结 class QByteArray

Q_DECLARE_OPERATORS_FOR_FLAGS(QByteArray::Base64Options)


#if !defined(QT_USE_QSTRINGBUILDER)  //定义了全局函数 + 运算符。本 if 有效,有这些函数
inline const QByteArray operator+(const QByteArray & a1, const QByteArray & a2)
{ return QByteArray(a1) += a2; }

inline const QByteArray operator+(const QByteArray & a1, const char * a2)
{ return QByteArray(a1) += a2; }

inline const QByteArray operator+(const QByteArray & a1, char a2)
{ return QByteArray(a1) += a2; }

inline const QByteArray operator+(const char * a1, const QByteArray & a2)
{ return QByteArray(a1) += a2; }

inline const QByteArray operator+(char a1, const QByteArray & a2)
{ return QByteArray(&a1, 1) += a2; }

#endif // QT_USE_QSTRINGBUILDER


//定义 <<、>> 运算符对本 QByteArray 类的支持
#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED)
Q_CORE_EXPORT QDataStream & operator<<(QDataStream &, const QByteArray &);
Q_CORE_EXPORT QDataStream & operator>>(QDataStream &,       QByteArray &);
#endif

#ifndef QT_NO_COMPRESS
Q_CORE_EXPORT QByteArray qCompress(const uchar* data,
                                   qsizetype nbytes, int compressionLevel = -1);

inline QByteArray qCompress(const QByteArray& data, int compressionLevel = -1)
{ return qCompress(
        reinterpret_cast<const uchar *>(data.constData()),
        data.size(), compressionLevel);
}

Q_CORE_EXPORT QByteArray qUncompress(const uchar* data, qsizetype nbytes);

inline QByteArray qUncompress(const QByteArray& data)
{ return qUncompress(
        reinterpret_cast<const uchar*>(data.constData()),
        data.size());
}
#endif

Q_DECLARE_SHARED(QByteArray)

class QByteArray::FromBase64Result
{
public:
    QByteArray decoded;
    QByteArray::Base64DecodingStatus decodingStatus;

    void swap(QByteArray::FromBase64Result &other) noexcept
    {
        decoded.swap(other.decoded);
        std::swap(decodingStatus, other.decodingStatus);
    }

    explicit operator bool() const noexcept { return decodingStatus == QByteArray::Base64DecodingStatus::Ok; }

#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(Q_QDOC)
    QByteArray &operator*() & noexcept { return decoded; }
    const QByteArray &operator*() const & noexcept { return decoded; }
    QByteArray &&operator*() && noexcept { return std::move(decoded); }
#else
    QByteArray &operator*() noexcept { return decoded; }
    const QByteArray &operator*() const noexcept { return decoded; }
#endif

    friend inline bool operator==(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept
    {
        if (lhs.decodingStatus != rhs.decodingStatus)
            return false;

        if (lhs.decodingStatus == QByteArray::Base64DecodingStatus::Ok && lhs.decoded != rhs.decoded)
            return false;

        return true;
    }

    friend inline bool operator!=(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept
    {
        return !(lhs == rhs);
    }
};

Q_DECLARE_SHARED(QByteArray::FromBase64Result)


Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_t qHash(const QByteArray::FromBase64Result &key, size_t seed = 0) noexcept;

template <typename T>
qsizetype erase(QByteArray &ba, const T &t)
{
    return QtPrivate::sequential_erase(ba, t);
}

template <typename Predicate>
qsizetype erase_if(QByteArray &ba, Predicate pred)
{
    return QtPrivate::sequential_erase_if(ba, pred);
}

//
// QByteArrayView members that require QByteArray:
//
QByteArray QByteArrayView::toByteArray() const
{
    return QByteArray(data(), size());
}

inline namespace QtLiterals {
inline QByteArray operator"" _qba(const char *str, size_t size) noexcept
{
    return QByteArray(QByteArrayData(nullptr, const_cast<char *>(str), qsizetype(size)));
}
} // QtLiterals

QT_END_NAMESPACE

#endif // QBYTEARRAY_H

(7)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值