Как ни странно, по крайней мере, поскольку на самом деле все на самом деле предназначено для работы, ничто из этого не должно напрямую затрагивать iostreams и/или streambufs.
Я бы подумал о iostream как о классе состязания. Iostream имеет streambuf, который обеспечивает буферный интерфейс для какого-то внешнего источника/приемника данных. Он также имеет локаль, которая обрабатывает все форматирование. Iostream - это немного больше, чем руководитель детской площадки, который держит этих двух, играющих вместе красиво (так сказать). Поскольку вы имеете дело с форматированием данных, все это (или должно быть) обработано в локали.
Локаль не является монолитной, хотя - она состоит из ряда facet
s, каждая из которых посвящена одной части форматирования данных. В этом случае часть, которую вы, вероятно, заботитесь, это фасет codecvt
, который используется (почти исключительно) для перевода между внешним и внутренним представлениями данных, которые считываются/записываются в iostreams.
Для лучшего или худшего, однако, язык может содержать только один codecvt facet за раз, а не цепочку из них, как вы созерцаете. Таким образом, то, что вам действительно нужно/нужно, является классом-оболочкой, который предоставляет кодеквт в качестве внешнего интерфейса, но позволяет вам привязать произвольный набор преобразований к данным во время ввода-вывода.
Для преобразования utf-to-utf Boost.locale предоставляет функцию utf_to_utf и код оболочки codecvt, поэтому эта часть преобразования проста и понятна.
Чтобы никто не предполагал, что такие вещи выполняются с помощью ICU, я добавлю, что Boost.Locale в значительной степени является оберткой вокруг ICU, так что это более или менее тот же ответ, но в форме, которая гораздо более дружелюбна к C++ (тогда как ICU сам по себе довольно похож на Java, и все, кроме откровенно враждебного C++).
Другая сторона заключается в том, что запись гранта codecvt добавляет большую сложность к довольно простой задаче. Фильтрующий streambuf (для одного примера), как правило, является лотом проще для записи. Это все еще не так просто, как хотелось бы, но не так плохо, как грань codecvt. Как уже упоминалось в @Flexo, библиотека Boost iostreams уже включает фильтр streambuf, который выполняет сжатие ZIP. Выполнение примерно одинакового с lzma (или lzh, арифметика и т. Д.) Относительно легкое, по крайней мере, предполагая, что у вас есть функции сжатия, которые просты в использовании (вы в основном просто снабжаете их буфером ввода, и они снабжают буфер Результаты).
Вы видели библиотеку [boost iostreams] (http://www.boost.org/libs/iostreams)? У этого уже есть сжимающие фильтры (хотя не lzma AFAIK), а механика для удобного написания пользовательских фильтров. – Flexo
Я посмотрю. –
Кажется, вам следует изучить концепцию манипуляторов потока.Найдите SO для этого, здесь есть пример http://stackoverflow.com/questions/799599/c-custom-stream-manipulator-that-changes-next-item-on-stream или здесь http://stackoverflow.com/ Вопросы/535444/custom-manipulator-for-c-iostream –