Russian Qt Forum
Декабрь 20, 2024, 11:27 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: QBitArray есть вопрос?  (Прочитано 14556 раз)
sne
Гость
« Ответ #15 : Март 17, 2010, 10:57 »

Код:
#ifndef BITARRAYEXT_H
#define BITARRAYEXT_H

#include <QtCore/QBitArray>

class QString;
class QBitArray;
class QByteArray;

class BitArrayExt
{
public:
    inline BitArrayExt() {}
    explicit inline BitArrayExt(const QBitArray &other) { m_bits = other; }
    inline BitArrayExt(int size, bool value = false) { m_bits.fill(value, size); }
    inline BitArrayExt(const BitArrayExt &other) { m_bits = other.m_bits; }
    inline BitArrayExt &operator=(const BitArrayExt &other) { m_bits = other.m_bits; return *this; }

    static BitArrayExt fromByteArray(const QByteArray &bytes);
    static BitArrayExt fromChar(const char ch);
    static BitArrayExt fromShort(const qint16 val);
    static BitArrayExt fromInt32(const qint32 val);
    static BitArrayExt fromInt64(const qint64 val);
    inline QBitArray toBitArray() { return m_bits; }
    QString toString();

private:
    QBitArray m_bits;
};

#endif // BITARRAYEXT_H

Код:
#include "bitarrayext.h"
#include <QtCore/QString>
#include <QtCore/QByteArray>

BitArrayExt BitArrayExt::fromByteArray(const QByteArray &bytes)
{
    QBitArray bits;

    foreach (char ch, bytes) {
        int inc_size = sizeof(char) * 8;
        int base_size = bits.size();

        bits.resize(bits.size() + inc_size);
        for (int i = 0; i < inc_size; i++) {
            bits[base_size + i] = ((ch & (1 << i)) >> i);
        }
    }

    return BitArrayExt(bits);
}

BitArrayExt BitArrayExt::fromChar(const char ch)
{
    return fromByteArray(QByteArray(&ch, sizeof(char)));
}

BitArrayExt BitArrayExt::fromShort(qint16 val)
{
    return fromByteArray(QByteArray(reinterpret_cast<char *>(&val), sizeof(qint16)));
}

BitArrayExt BitArrayExt::fromInt32(qint32 val)
{
    return fromByteArray(QByteArray(reinterpret_cast<char *>(&val), sizeof(qint32)));
}

BitArrayExt BitArrayExt::fromInt64(qint64 val)
{
    return fromByteArray(QByteArray(reinterpret_cast<char *>(&val), sizeof(qint64)));
}

QString BitArrayExt::toString()
{
    QString s;

    for (int i = 0; i < m_bits.size(); i++)
        s += m_bits.at(i) ? '1' : '0';

    return s;
}

Может быть кому пригодится.
Записан
p166
Гость
« Ответ #16 : Март 18, 2010, 15:19 »

Вот два примера по использованию битовых масок.
1 - getRights() - возвращает ulong где первые 8 бит являются флагами
2 - setRights(ulong rights) - читает 8 бит ulong и вывешивает соответствующие флаги.
Для наглядности работа функций реализована немного по разному.

Код:
ulong WFIL_req::getRights()
{
    ulong rights=0;

    if (ui->cb0->isChecked()) rights |= 1<<0; else rights |= 0<<0;
    if (ui->cb1->isChecked()) rights |= 1<<1; else rights |= 0<<1;
    if (ui->cb2->isChecked()) rights |= 1<<2; else rights |= 0<<2;
    if (ui->cb3->isChecked()) rights |= 1<<3; else rights |= 0<<3;
    if (ui->cb4->isChecked()) rights |= 1<<4; else rights |= 0<<4;
    if (ui->cb5->isChecked()) rights |= 1<<5; else rights |= 0<<5;
    if (ui->cb6->isChecked()) rights |= 1<<6; else rights |= 0<<6;
    if (ui->cb7->isChecked()) rights |= 1<<7; else rights |= 0<<7;
    if (ui->cb8->isChecked()) rights |= 1<<8; else rights |= 0<<8;

    return rights;
}

void WFIL_req::setRights(ulong rights)
{
    if (rights&0x1) ui->cb0->setChecked(true); else ui->cb0->setChecked(false);
    rights >>= 1;
    if (rights&0x1) ui->cb1->setChecked(true); else ui->cb1->setChecked(false);
    rights >>= 1;
    if (rights&0x1) ui->cb2->setChecked(true); else ui->cb2->setChecked(false);
    rights >>= 1;
    if (rights&0x1) ui->cb3->setChecked(true); else ui->cb3->setChecked(false);
    rights >>= 1;
    if (rights&0x1) ui->cb4->setChecked(true); else ui->cb4->setChecked(false);
    rights >>= 1;
    if (rights&0x1) ui->cb5->setChecked(true); else ui->cb5->setChecked(false);
    rights >>= 1;
    if (rights&0x1) ui->cb6->setChecked(true); else ui->cb6->setChecked(false);
    rights >>= 1;
    if (rights&0x1) ui->cb7->setChecked(true); else ui->cb7->setChecked(false);
    rights >>= 1;
    if (rights&0x1) ui->cb8->setChecked(true); else ui->cb8->setChecked(false);
}
Записан
voronElf
Гость
« Ответ #17 : Март 19, 2010, 07:16 »

p166, не сочтите за наезд, но не проще ли вместо маски в 0х01 везде прописать константы с нужным битом (0х01, 0x02, 0x04 ...) ?
нагляднее и на операциях сдвига экономия ...

Код:
rights |= 0x01;
rights |= 0x02;
rights |= 0x04;
rights |= 0x08;
rights |= 0x10;
...

if (rights & 0x01) ...
if (rights & 0x02) ...
if (rights & 0x04) ...
if (rights & 0x10) ...
Записан
p166
Гость
« Ответ #18 : Март 19, 2010, 14:14 »

voronElf, полностью согласен с тобой, но как я писал выше:
Цитировать
Для наглядности работа функций реализована немного по разному.

Это удобно если читаешь биты в цикле, выглядит нагляднее и на операциях сдвига описаниях констант экономия ...
Улыбающийся

Код:
for (int i=0; i<sizeof(ulong)*8; i++)
{
   if (rights&0x1) {do ...}
   rights >>= 1;
}
PS: isnt it?

PS2: поправился Улыбающийся
« Последнее редактирование: Март 20, 2010, 13:09 от p166 » Записан
voronElf
Гость
« Ответ #19 : Март 19, 2010, 14:27 »

в цикле да, согласен

ПС: sizeof(ulong) возвращает количество битов ? не знал ....
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.1 секунд. Запросов: 20.