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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Как можно читать данные из потока кусками по четыре бита ?  (Прочитано 6870 раз)
burunduk
Гость
« : Октябрь 25, 2005, 17:41 »

Формат файла так размечен и не могу придумать красивого решения. Есть идеи ?
Записан
QCasper
Гость
« Ответ #1 : Октябрь 25, 2005, 23:24 »

А если считывать побайтно, а потом разбивать пополам, не катит?
Записан
Larrikin
Гость
« Ответ #2 : Октябрь 26, 2005, 06:56 »

Код:

struct (
     unsigned field1 : 4;
     ) field;

Может так? Это структура блиной в 4 бита. Я сам не работал с битами, но у Кернигана Ричи написано именно так.
Записан
Dair
Гость
« Ответ #3 : Октябрь 26, 2005, 08:04 »

Цитата: "burunduk"
Формат файла так размечен и не могу придумать красивого решения. Есть идеи ?


я б сделал типа так:

Код:

class HalfByte {
  public:
    HalfByte();
    HalfByte( unsigned char v );
    HalfByte( const HalfByte& hb );
   
    const HalfByte& operator=(const HalfByte& hb );

    operator unsigned char() const { return data & 0x0F; }

  protected:
    unsigned char data;
};

class HalfByteStream: public QDataStream {
  public:
    ...
    HalfByteStream& operator>>(HalfByte& hb );
    HalfByteStream& operator<<(HalfByte hb );
};



ы?

да, из фалйа всё ж считывать побайтно, само собой.
Записан
burunduk
Гость
« Ответ #4 : Октябрь 26, 2005, 12:20 »

Идея мне понравилась, но только зачем нужен класс HalfByte ?  Половинку в четыре бита можно хранить и в стандартном типе - unsigned char.
Записан
Dair
Гость
« Ответ #5 : Октябрь 26, 2005, 12:24 »

Цитата: "burunduk"
Половинку в четыре бита можно хранить и в стандартном типе - unsigned char.


ну, это уже академически :-)

если перегружать оператор <<( unsigned char ) то возникнут проблемы при mixed reading.

А тут - отдельный тип и фсё.
Записан
burunduk
Гость
« Ответ #6 : Октябрь 26, 2005, 12:28 »

уже возникли :-)

Цитировать

если перегружать оператор <<( unsigned char ) то возникнут проблемы при mixed reading.
Записан
oktogen
Гость
« Ответ #7 : Ноябрь 29, 2005, 10:57 »

QBitArray(QT4).
Записан
Dendy
Гость
« Ответ #8 : Ноябрь 29, 2005, 23:06 »

Исправь, если неправильно понял.

Данные хранятся укомплектованно: 4 бита + 4 бита + 4 бита + ... .Ты хочешь считывать именно биты, а не байты (у которых полезная часть - младшая половина).

QBitArray тебе здесь не поможет, он нужен только для хранения данных, а не для потока. А QBuffer в свою очередь создаётся только на QByteArray.

Мои рассуждения:

Вариант раз:

Смотрим на интерфейс QIODevice и видим там непримечательную функцию ungetChar( char ), которая засунет символ обратно в поток. Идея такова: читаем байт, берём старшую половину, засовуем байт обратно. В следующий раз читаем байт, берём младшую половину и не засовуем обратно. Проблемы:
1. где хранить чётность нечётность уже прочитанных данных?
2. если поток небуферизированный, то ета функция может не работать.

Вариант два:

Наследуемся от QFile. Получаем IO Device для работы с 4-мя битами:

Код:
class My4BitDevice : public QFile
{
public:
  My4BitDevice() :
    odd( false )
  {
  }

  qint64 readData( char * data, qint64 maxSize )
  {
    int count = maxSize;
    while ( count )
    {
      if ( !odd )
      {
        int bytes = QFile::readData( &tmp, 1 );
        if ( bytes < 0 )
          return bytes;
        if ( bytes != 1 )
          return maxSize - count;
      }
      *data = !odd ? (tmp & 0x0f) : (tmp & 0xf0) >> 4;
      odd = !odd;
      data++;
      count--;
    }
    return maxSize - count;
  }

  bool odd;
  char tmp;
};


Ну чёта типа такого. Итак, теперь при считывании N байт мы на самом деле считаем N блоков по 4 бита. Результат будет такой: в каждом считанном байте младшая часть и будет наши 4 бита.
Пример использования:

Код:
  My4BitDevice dev( "myfile" ); // придумаете конструктор
  QByteArray bits = dev.read( 10 );


Выше мы считываем 10 блоков по 4 бита. Результат будет в младшей части каждого байта массива bits. Хотя я бы советовал юзать qint64 read( char * data, qint64 maxSize ), так можно получить еррор, если биты в файле кончились.

 Веселый
Записан
burunduk
Гость
« Ответ #9 : Ноябрь 30, 2005, 10:29 »

Всё правильно понял.
Да, действительно это наверное лучше, чем я уже реализовал и давно забыл :-)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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