Переносимый потокобайтный интерфейс для C ++ - PullRequest
3 голосов
/ 05 октября 2010

Я работаю над портативной библиотекой сжатия изображений C ++ с открытым исходным кодом . В настоящее время мой API работает путем обмена указателями на байтовые массивы с данными изображения. Я хотел бы поддерживать какой-то режим потоковой передачи для повышения производительности и потребления памяти.

Для этого я хотел бы знать, существует ли интерфейс или абстрактный базовый класс (часть стандартных библиотек C ++), который я могу использовать в качестве интерфейса для потока входных байтов, аналогично InputStream Java или C # Stream , Это может быть так просто:

 class inputstream 
 {
      public:
      virtual void readbytes(char*, size_t count) = 0;
 };

Я мог бы сам определить интерфейс, подобный этому, но тогда я требую, чтобы все внедрили какой-то адаптер для интерфейса с моим кодом и мой вкус обработки ошибок ввода-вывода, и я бы хотел этого избежать.

В идеале этот интерфейс или базовый класс уже были бы реализованы некоторыми существующими стандартными библиотеками C ++ для чтения файлов. Если это не базовый класс, он должен быть полностью абстрактным, чтобы мои пользователи могли подключаться к любому имеющемуся потоку данных (конкретному платформе, сокету и т. Д.). Я просмотрел в iostream, но не нашел ничего, что отвечало бы всем требованиям. Он должен быть как можно более легким: должна быть определена обработка ошибок, но нет необходимости искать поток.

Если такой вещи нет (чего я боюсь), есть ли что-то вроде существующей лучшей практики? Как указатель на функцию со стандартной подписью и контракт на обработку ошибок? Если есть креативные решения, которые будут работать и на Си, мне тоже интересно.

Редактировать: главное, чтобы методы read () базового класса были виртуальными.

Ответы [ 4 ]

4 голосов
/ 06 октября 2010

Если ваша библиотека принимает std::istream, она будет работать с файлами, буферами памяти и пользовательскими потоками.

Ваш источник путаницы заключается в том, что istream не имеет виртуальных членов, которые можно переопределить и настроить. Это связано с тем, что istream делегирует все настраиваемые функции std::streambuf, где вы найдете виртуальных членов.

Если вы хотите представить результаты сжатия в виде потока, вы должны извлечь из streambuf. И наоборот, вы можете принять istream для чтения и ostream для сохранения сжатых результатов в.

Принимая istream, ваш клиент может предоставить istream, созданный для любого streambuf, либо предоставленной библиотеки stringbuf или filebuf, либо пользовательской версии.

Так как вы не хотите работать с текстовыми данными, а с байтовыми потоками, возможно, лучше использовать streambuf напрямую, чем istream, чтобы обернуть его.

0 голосов
/ 05 октября 2010

Вы можете использовать обычный std::ifstream, который является не чем иным, как «потоком байтов».Извлечение байтов по умолчанию - байт на байт, и его можно использовать разными способами:

#include <fstream>
    using std::ifstream;

int main()
{
    ifstream stream;
    stream.open("example.jpg", ifstream::binary ); // open raw binary stream
    if( !stream ) // check if stream is ready to be read
        throw runtime_error( "Failed to open file..." );

    char byteBuffer;

    while( stream >> byteBuffer ) // read all bytes until read/extraction fails
    {
        // do something with the byte
    }
    stream.close();

    return 0;
}

Надеюсь, это поможет.Я понимаю, что не каждая платформа имеет символ байтового размера, но я уверен, что есть некоторый прием, который позволяет вам использовать объект iostream байтового элемента (по умолчанию char или wchar_t для широкогоклассы).

0 голосов
/ 05 октября 2010

std :: fstream звучит так, как будто это отвечает всем требованиям, несмотря на то, что вы чувствуете, что он не подходит, совершенно для меня. Конечно, у него есть поиск, но это не совсем тяжелый код.

0 голосов
/ 05 октября 2010

Посмотрите на струнный поток.Он делает то, что вам нужно

...