| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Как Вы обычно передаете stream разрабатывая парсер |
| Автор: EvilsInterrupt 22.6.2013, 13:57 | ||||
| При разработке класса по работе с каким-либо форматом файла мы часто пользуемся стримами чтобы читать\писать из\в файл. До сих пор использую способ передачи базового класса стрима по ссылке в конструктор класса. Мне перестает нравиться по разным причинам и хочу узнать опыт других разработчиков, послушать их идиомы и методы. Чтобы не было слишком излишне абстрактно возьмем задачу по разработке класса по работе с форматом "Super Format", ниже в коде приведены декларации заголовков. Также давайте напишем, который должен хранить и возвращать эти заголовки пользовательскому коду.
Задача: Как-либо передать данные из\ в стрим во внутренние приватные члены firstHeader и secondHeaders. Другими словами как организовать работу со стримом, чтобы писать и записывать данные в эти приватные заголовки? Пока вижу такие варианты:
Возможно Вы предложите еще, не стесняйтесь ) |
| Автор: mes 22.6.2013, 18:37 |
stream<<any_format(image) |
| Автор: EvilsInterrupt 22.6.2013, 19:27 |
Я отказался от такого варианта, т.к. менее читабелен чем read()/write() . |
| Автор: volatile 22.6.2013, 20:01 |
| 1, как это менее читабелен? Это же устоявшаяся практика в С++... 2. Как это вы пишете по константной ссылке? И развивая мысль, если же возвращать не контантную ссылку, то смысла делать члены приватными - лишняя трата времени. все равно у всех полный доступ 3. В общем в С++, есть устоявшаяся практика, делать глобальный оператор<<, и объявлять его дружественным (friend). для доступа непосредственно к приватным членам. Все остальные модификации (по крайней мере для вашего примера) - суть одно и тоже, записанное разными способами. Так зачем голову морочить себе и другим? Лучше идти обычным путем. |
| Автор: volatile 22.6.2013, 21:21 |
EvilsInterrupt, ну хорошо, делайте как принято у вас. Принциаиальной выгоды от какого-то определенного способа нет. Главное здесь - делать однообразно, а не придумывать каждый раз новое седло к старому велосипеду. |
| Автор: EvilsInterrupt 22.6.2013, 21:33 |
Вопрос не в том делать мне или не делать как у меня принято в компании. Вопрос в другом. Есть. Столкнулся с тем, что мне стало сложно добавить новый код. У меня класс по работе с форматом принимает ссылку в конструкторе. Это приводит к тому, что после класс заполнить данными из другого стрима уже невозможно. Сейчас приходится рефакторить, вот если бы кто подсказал ранее!!! Да в процессе рефакторинга, сначала передавал стрим с помощью boost::shared_ptr, но это оказалось излишним. Вот и хочется узнать кто как делает, чтобы уменьшить количество лишних телодвижений. |
| Автор: volatile 23.6.2013, 00:26 | ||
Вот кстати, именно поэтому и не нужно изобретать велосипеды. |
| Автор: mes 23.6.2013, 03:14 | ||||||||
подсказка: в моем примере трое участников вместо двух..
нет прямой связи друзей с применением оператора.. Кстати чем так сильно отличается дружественная функция, от обычного метода ?! Добавлено @ 03:24
так вроде ж: http://forum.vingrad.ru/forum/topic-336639/unread-1.html |
| Автор: EvilsInterrupt 23.6.2013, 08:51 | ||||
Это был формат PE, а я сейчас ковыряюсь с другим форматом, хоть и не хочется, но трудящиеся просят )
Дело в том, что в public попадает то что очень редко будет меняться, а в привате автор кода имеет право переколбасить в любой момент наплевав на любое мнение. Если же сделать дружественную функцию, то в ней возникнет соблазн заюзать "по-быстрому" вон-ту функцию, но возникает лишняя зависимость, которую приходится учитывать если автор кода поменял сигнатуру исопользуемой функции или вообще удалил. Все-таки паблик на то и паблик, чтобы сказать пользователям класса "Вот методы, которые постараюсь менять в самых экстренных случаях" |
| Автор: volatile 23.6.2013, 09:04 | ||
Ну запишите эту дружественную функцию в самом определении класа. (часто так и делают, кстати.) И считайте что она не дружественная, а обычный метод. Проблема, имхо, у вас в голове. |
| Автор: EvilsInterrupt 23.6.2013, 11:40 |
Тут Вы правы из-за желания написать хорошо иногда вхожу в ступор, вместо того чтобы просто написать и посмотреть как оно на практике будет выглядеть. volatile, Попробую показать свое понимание дружеских функций, возможно вы увидите ошибки в рассуждениях и укажите на них. Сразу скажу, что опыт применения дружеских функций маленький и поэтому вполне возможно что вы все-таки ошибки увидите! Далее следуют мои мысли, а не цитаты из учебников, поэтому не следует говорить "где же вы такого по-набирались?". Чисто технически пользовательский код не может видеть приватную часть другого класса. Но это можно организовать объявив в объявлении класса эту функцию дружественной. Получается вроде входит в namespace класса и в тоже время видит все его внутреннее состояние словно это метод класса. Однако при реализации такой функции нужны лишь часть а не весь функционал класса и получается своего рода "дыра". Во время написании такой функции программист отчетливо понимает как и что он пишет и зачем. Но проходит время, к этой функции обращается уже другой программист, который не знает всех деталей и нюансов класса. Который между прочим за это время тоже мог измениться. Для решения задачи из-за чего пришлось обратиться к модификации этой дружественной функции программист может обратиться к тому функционалу класса, который лучше всего не трогать! Да, спустя время юнит-тесты, интеграционные тесты или гневный пользователь все-таки ему скажет о неправильности его действий, но ведь это время! По этой причине я делю код на интерфейсный и детали. Детали я изменяю как хочу и когда хочу, никто мне в этом ни указ, главное чтобы работало! А вот интерфейсный стараюсь не менять, иначе пользовательский код придется менять. Очень жалею что нету C++ конструкции, чтобы пометить какой-либо интерфейсный код меткой "depricated", разве что pragma для MSVS но это не портабельно! Т.е. мое отношение к дружественным функциям такое, что лучше избегать их, иначе кто-то заюзает детали класса, а тебе потом собирать "артефакты" или помогать пофиксить код. |
| Автор: mes 23.6.2013, 12:36 | ||||||||||||
и
все это относится и к методу...
1. операторы относятся тоже к интерфейсу 2. где тут проблема с дружественными функциями ?! 3. оператор << может быть вполне и не дружественным.. вместо подобных рассуждений, думаю не плохо было бы задать себе вопрос, в чем же прелесть дружественных функций, и сразу станет понятно когда стоит ич применять, а когда нет.. Добавлено через 2 минуты и 31 секунду
конечно, если от их применения ни красоты, ни эффективности не добавляется... Добавлено через 4 минуты и 14 секунд
EvilsInterrupt, или сделайте метод вывода в поток, и заюзайте его в операторе - будут и овцы сыты и волки целы- Добавлено через 9 минут и 32 секунды
1. public методы могут быть у private-классов.. 2. интерфейс бывает и protected, и на него распространяются те же требования.. Добавлено через 11 минут и 48 секунд это вобще отдельная тема, гораздо шире, чем публик-методы.. и кстати дружественные функции как раз и придуманы для уменьшения зависимостей и укрепления интерфейса |
| Автор: EvilsInterrupt 23.6.2013, 12:53 | ||
Эти рассуждения как раз и были высказаны, чтобы ответить на этот вопрос. Я не однократно задавался этим вопросом и не понимаю в чем их крутость? Однако имеется только одно пояснение, которое я нашел зачем эти дружественные были введены в язык и оно написано в книге Страуструпа про Дизайн и Эволюцию языка. Ок, спрошу у Вас: как вы понимаете в чем прелесть возможности объявить функцию\метод дружественной? |
| Автор: mes 23.6.2013, 12:58 | ||
1. в том, что родной класс может быть не первым аргументом (this), уступив это место чужому 2. в том, что можно связать два класса, без лишней публикации деталей. |
| Автор: mes 23.6.2013, 13:16 | ||
3.6.2 ? оно и есть |
| Автор: EvilsInterrupt 23.6.2013, 13:23 |
| mes, Да, оно самое! ;) Кроме него больше не видел ни одного пояснения. Но то что приведено, на столько мало. Что невозможно сразу сформировать свое мнение о дружественных. Приходится ждать появления опыта и отказаться до момента его появления ) |
| Автор: mes 23.6.2013, 13:54 | ||
тот же метод, но снаружи класса, что позволяет больше свобод при перегрузке.. Проблема понимания наверняка заключается в том, что еше не осознали прелесть перегрузки... |
| Автор: volatile 23.6.2013, 13:55 | ||
Ваша ошибка в понимании дружественных ф-ий, имхо в том что вы считаете что дружественная функция имеет отношение к пользовательскому коду. Дружественая функция - это продолжение класса. Можно считать их теми-же методами, только с другим синтаксисом вызова. Вот и все. |
| Автор: EvilsInterrupt 23.6.2013, 13:58 | ||
Да, именно так и считаю. А как иначе если она видна пользовательскому коду и не спрятана в private и namespace detailed ? |
| Автор: mes 23.6.2013, 14:00 |
Вы путатете понятия "интерфейс (библиотеки)" и "пользовательский код" Добавлено через 45 секунд для пользователя все равно, дружественная ли функция, или нет... |
| Автор: EvilsInterrupt 23.6.2013, 14:21 | ||
Судя по всему, собравшиеся mes и volatile предпочли бы такой вариант:
Верно? |
| Автор: mes 23.6.2013, 15:11 |
от лица mes : не совсем или даже совсем не.. |
| Автор: EvilsInterrupt 23.6.2013, 16:58 |
Ок, а какой тогда код был бы? Задача маленькая, думаю займет у вас не более 5 мин. ;) |
| Автор: mes 23.6.2013, 17:31 | ||
для приведенного куска, аддптировано под write/read
|
| Автор: EvilsInterrupt 23.6.2013, 17:41 |
| mes, Если не секрет, то почему так? Я видел подобный способ на http://stackoverflow.com/ , но меня он отталкиваем тем что похож на процедурный подход. |
| Автор: mes 23.6.2013, 18:06 |
а вы наверное считаете, что запихнув все в классы получите ооп-подход замените read/write на операторы и будет вам счастие А по сути в вашем примере чрезмерная инкапсуляция, которая прячет важные сущности, не принося никакой пользы этим, зато сложностей и зависимостей добавляет кучу Добавлено через 10 минут и 8 секунд и да : крылья...ноги...главное хвост! © |
| Автор: EvilsInterrupt 23.6.2013, 18:19 | ||
| mes, Приведу твой код, тут:
все верно? ;) |
| Автор: mes 23.6.2013, 18:51 | ||
наполовину...
это использование не по назначению потока (mistreatment).. Такое можно проделывать со своим потоком, в котором Вы уверены.. Но оставлять такое поведение пользователю недопустимо.. Это место требует обязательной разгрузки через сущность.. Добавлено @ 18:56 т.е. сами header`ы у Вас вполне потоко-подходящие, а вот image нет.. Проблема в image в том, что с одной стороны вы пытаетесь сохранить структуру файла, а с другой предоставить ее как набор данных удобных пользователю.. Это две разные задачи и поэтому нежелательна реализация одной сущностью.. |
| Автор: EvilsInterrupt 23.6.2013, 19:08 |
Так у меня есть для этого операции первоначальных позиций для потоковых get/put указателей. Или Вы не об этом? Добавлено через 9 минут и 22 секунды Наверное Вы про аналог sentry ? |
| Автор: mes 23.6.2013, 19:45 |
я о stream`e как о концепте последовательного очередного доступа.. работа с image предполагает (в приведенном примере) произвольный доступ. |
| Автор: EvilsInterrupt 23.6.2013, 20:17 |
Я кажется понял о чем Вы. Потоки в идеале не имеют конца и операций произвольного перемещения указателя. То что применяется у меня в примерах это по сути Blob из мира Java. Однако хочу заметить, что далеко не все С++ программисты с этим согласны и приводят в пример std::fstream где вполне можно перемещать указатель куда хочешь с помощью seekg()/seekp() ;) Но я с Вашим примером не согласен и вот почему. Мне он кажется не объектно ориентированным. ООП мысль ставит во главу разработки "объекты", понимая под ними Абстрактные Типы Данных, т.е. набор данных и взаимосвязанных операций оперирующих с этим данными. Исходя из этого SFImage содержащий данные FileHeader, SecondHeaders , но не содержащий взаимосвязанных операций read()/write() не может являться объектом. Это просто некий storage, своего рода "коробка". В ООП на мой взгляд, если правильно понял Г.Буча объекты более интеллектуальны и именно поэтому read()/write() , которые Вы вынесли за пределы класса нужно вернуть обратно в пределы класса ;) |
| Автор: mes 23.6.2013, 20:47 | ||||||||
начну с конца :
следует поправить : мы вынесли за пределы SFImage методы read(N_Header).. разницы нет по сути , находится ли read в классе или вне его.. Разница есть в каком классе он находится ) Я против когда read для N_Header, находится в приватной области SFImage
не все объекты должны/могут быть интеллектуальны.. более того объект не должен выходить за рамки своих полномочий.. впрочем со своими обязанностями он действительно должен справляться хорошо.. Но вот опять же со "своими"
Ни в коем случае! ооп не определяется словом "содержит" ..Более того "содержит" уступает свое главенство "использует"..
А вот тут правильно.. обратите на последнее : операции оперирующие этими данными.. Т.е. операции производятся над данными , над объектами и уж само определение говорит, что они (операции) могут выходить за рамки обьекта |
| Автор: mes 23.6.2013, 21:10 | ||||
во первых std далеко не идеал... исторически так сложилось.. во вторых fstream, это конкретная разновидность стрима, а частный случай, как известно не определяет общий в третьих я не против подобного неправомерного использования, если оно локально, и не навязывает свое поведение/логику пользователю.. Добавлено через 2 минуты и 3 секунды
Да, если предоставляете поток пользователю, он должен быть похож на поток |
| Автор: EvilsInterrupt 24.6.2013, 10:35 | ||
Прошу простить за назойливость, но не могли бы выразить эту мысль другими словами? Почему противоречивы задачи сохранения структуры данных файла и предоставления в удобном виде? Почти любой современный парсер чего-либо он в любом случае должен оставлять данные именно в том виде в каком подразумевает фомат этих данных, которые он парсил. Ну а стремление предоставить в удобном виде по-моему это стремление любого программиста, иначе зачем писать гуан-код? |
| Автор: mes 24.6.2013, 18:57 |
определитесь, что есть для вас image ? структура данных, считанная с потока или набор функций применяемых к структуре(файла) определенного формата ? Добавлено через 1 минуту и 15 секунд хм.. дежавю |
| Автор: mes 2.7.2013, 19:43 |
| EvilsInterrupt, продолжим поступенечно ? можно ли условно свести формат к одному оглавлению и к набору данных для секций ? |
| Автор: EvilsInterrupt 3.7.2013, 09:08 |
| mes, Прежде чем продолжим обсуждение про формат хотел бы знать точно что Вашу терминологию понимаю. Является ли функция объявленная и определенная вне класса частью интерфейса класса? Есть две ситуации, когда такую функцию пишет : 1) Автор класса 2) Программист-пользователь |
| Автор: Guinness 3.7.2013, 09:31 | ||
В том же пространстве имен, что и класс или нет? |
| Автор: EvilsInterrupt 3.7.2013, 11:27 |
| Guinness, В моем случае, мне кажется разницы никакой. Вопрос возник из-за прежних постов, где mes показал пример кода, в котором функция не объявленная в объекте работает с ним и при этом я понял что он считает такую функцию частью интерфейса объекта. Мне просто хочется уточнить и еще раз убедиться, что я ничего не напутал и что так оно и есть. До его примера я функции вне объекта считал функциями расширяющие интерфейс объекта, а не его частью. |
| Автор: Guinness 3.7.2013, 11:57 |
| EvilsInterrupt, ну собственно так оно и есть. У Саттера была глава, где он заострял внимание на то, что такое интерфейс, попутно рассказав как работает поиск Кенига. И там есть зависимость от того, где Вы объявляете функцию, внутри какого пространства имен. Вот в Си, например, нет методов(членов функций) для структур. Но мы ведь считаем все функции в хидере структуры её интерфейсом, если они принимают указатель на структуру. |
| Автор: EvilsInterrupt 3.7.2013, 12:04 | ||
Вы про Argument Depend Lookup ?
А как это влияет на интерфейс? Технически язык может позволять очень многое но это не означает что мы(программисты) должны разрабатывать как позволяет язык. Не знаю кто и где сказал, но есть разработка с помощью языка и есть как его величество язык позволит То как работает ADL это-то понятно, но это же не значит что объект имеет метод если он с ним в одном и том же пространстве имен. Добавлено через 12 минут и 14 секунд Guinness, Спасибо за Саттера! Нашел то о чем ты говоришь. Это книга "Стандарты программирования на С++. 101 правило и рекомендации". Почитал сначала Правило №57 на стр.116 по началу был не согласен, но после Правила №44 стр. 93 понял, что выгодней считать свободные функции работающие с объектом, НО в пределах того пространства имен в котором объявлен объект. |
| Автор: Guinness 3.7.2013, 12:26 | ||
Если в одном пространстве имён, то скорее всего он разрабатывался вместе с классом и является частью его интерфейса. Потому что разработчик данного класса разработал эту функцию для того, чтобы Вы её использовали при работе с классом, к которому она относится. Разве это не будет интерфейсом класса? В объектных языках, таких как Java, такое невозможно , т.к. там нельзя создать функцию отдельно от класса. В Си, как я указал выше, это удинственная возможность ООП. Ну а С++ нечто среднее, и поэтому здесь интерфейс класса - это и то, что им является в Java, и то, что в Си. Это мое мнение) |
| Автор: EvilsInterrupt 3.7.2013, 12:39 | ||||
Вот! Об этом же и Гради Буч говорит. Java и насколько понимаю и C# тоже думают о функции вне класса что и я, пока думаю, но после Саттера что-то вера в это колеблется Думаю вопрос исчерпан, я достаточно гибок, как говорят: "Хоть горшком назови, только в печь не ставь". Мне никак не повредит если я буду считать интерфейсом то как его понимает Саттер, главное чтобы спустя время я осознал что так писать легче, а не труднее ;) Остается уточнить у mes:
Что есть "оглавление" в Вашем понимании ? |
| Автор: mes 3.7.2013, 19:20 | ||||||
немножко наоборот, интерфейс класса является частью , или частным случаем... Добавлено через 1 минуту и 29 секунд
А если функция мультиметод ? Добавлено через 5 минут и 47 секунд да это из той же оперы.. посмотрите например какую нибудь (бустовскую) библиотеку по сериализации, как они находят serialize и не жалуются снаружи она описанна или внутри .. Добавлено через 8 минут и 43 секунды и да уже несколько раз говорил и еще раз повторю.. Абсолютно не важно как описаны функции, важно какие операции предоставляет обьект.. И я возмутился не из за того, что функции были членами класса, а из за того что были приватными членами, хотя именно эти операции и характеризуют взаимодействие с объектом(форматом) Добавлено через 9 минут и 47 секунд header Добавлено через 14 минут и 21 секунду
Имхо, не С++ что то среднее, а в ява все пообрезали, чтоб своими несмышленными мыслями за пределы клеток не дай бог не упорхнули |
| Автор: mes 3.7.2013, 19:39 | ||
просто сила связи падает.. чем нужно большее сцепление, тем ближе к телу рассполагаем и наоборот функция даже не работающая напрямую с объектом всего равно входит в тематическую группу интерфейса, если она логически с ним связанна.. |
| Автор: EvilsInterrupt 7.7.2013, 10:53 | ||
| При добавлении новой фичи в мою существующую утилиту, которая решает некоторые мои проблемы и моих знакомых я столкнулся с тем, что мне сложно ее добавлять. После размышлений пришел к выводу что "узким местом" являет код по работе с PE форматом. В виду того что это формат бинарного файла очень сложный, то мне бы хотелось послушать, а как другие программеры пишут код по работе с бинарными файлами? Вообщем суть темы обсудить\получить новые навыки по удобной работе с форматами бинарных файлов. Чтобы не усложнять я ввожу придуманный с головы формат, назову его SuperFormat, который обладает теми характеристиками, что встречаются в реальных форматах исполняемых файлах. Опишу и дополню первоначальную задачу поста. Цель: Разработка класса\библиотеки по работе с форматом файла. Нужно читать\писать из файла этого формата. Условно назовем формат файла SuperFormat. Некоторые нюансы формата: 1) Существует разные вариации для 32 и 64 бита. 2) Все заголовки(структуры) используемые в формате имеют одинаковый набор структур и названий полей в структурах для обоих режимов. Отличия в том, что в некоторых типов полей uint32_t или uint64_t зависит от битности файла. 3) Расположение некоторых заголовков в файле можно узнать только прочитав некоторые другие заголовки Формат описывается следующими структурами:
Требования к коду: Писать обобщенно независимо от битности формата. У меня пока это достигнуто с помощью C++ идиомы traits. P.S.: Подобные вещи встречаются на практике. К примеру если посмотреть в WinNt.h хидер идущий с MSVS то можно увидеть структуры IMAGE_NT_HEADERS32 и IMAGE_NT_HEADERS64. Эти структуры имеют один и тот же набор полей и имен этих полей, но некоторые поля отличаются типом. Эти структуры описывают PE32\PE32+ форматы. Но точно такая же ситуация и с Elf, Mach-O. |
| Автор: mes 7.7.2013, 17:26 | ||||||
| EvilsInterrupt, вот опять ставите мелочи во главу угла... У вас есть уже готовый (распланированный) и удобный концепт для варианта с одной архитектурой ? если нет, то не думаю, что стоит на этом заморачиваться, хотя бы по проблеме того, что не понятно на каком уровне нужно производить селекцию подходящего типа..
как минимум если используете трайтс, то логически его использовальзовать для всех структур-хэдеров, а не только тех, которые нравятсая.. т.е.
выглядит необоснованно однобоко, в отличии от
кстати концепт traits, подразумевает передачу этого traits, как шаблонный параметр.. вроде у Вас по другому... это не имеет значения, кроме как путаницы.. и так сбоку помимо traits есть еще if_-селекция.. |
| Автор: EvilsInterrupt 7.7.2013, 18:36 |
Ну если присмотреть к объявлению FirstHeader_t, то видно что от битности не зависит! Смысл его загонять в traits-типы? Не те что нравятся, а те что нуждаются в этом обобщении! Как я уже привел выше FirstHeader_t в этом обобщении не нуждается. Зато типы SecondHeader32_t и SecondHeader64_t к общему SecondHeader_t нуждаются! P.S.: Ну как вся наша жизнь состоит из мелочей! ;) Куда уж без них? |
| Автор: EvilsInterrupt 7.7.2013, 20:35 |
ВЫ об идиоме упомянули http://en.wikibooks.org/w/index.php?title=More_C%2B%2B_Idioms/Type_Selection&printable=yes ? |
| Автор: mes 7.7.2013, 23:17 | ||||
да об ней Добавлено через 5 минут и 18 секунд
мелочи хороши когда имеете общее представление, а так не имея хорошего концепта уделять вниманию, каким способом выбирать тип для описания - имхо излишне..
это с вашей точки зрения, а не с точки зрения Traits.. Так к примеру если придется добавить третью архитектуру, то вполне возможно там будет отличаться.. именно в этом идея трайтс... а так нагородили лишних сущностей без сильной надобности.. |
| Автор: mes 7.7.2013, 23:35 |
| вот пример на скорую руку : http://codepad.org/fJ5HPr0u |
| Автор: SenkraD 8.7.2013, 10:30 |
| а не могли б код сюда выложить? унекоторых на работе не все сайты открыты |
| Автор: EvilsInterrupt 8.7.2013, 11:29 | ||||
Не думаю, что mes обидится если выполню просьбу вместо него. Вот:
|
| Автор: mes 8.7.2013, 13:44 | ||||
в итоге селекция типа должна разрешиться через обозначенный формат, например
|
| Автор: EvilsInterrupt 9.7.2013, 12:32 | ||
Я правильно понял, что применяя термин "удобный концепт" Вы вкладываете "интерфейс будущей библиотеки"? |
| Автор: mes 9.7.2013, 18:07 |
| не совсем.. концепт это та идея, что связывает интерфейс с имплементацией.. например хотим разработать класс фигура.. для начала нам нужно определитъся, что все таки от фигуры требуется и что она будет предоставлять.. будем ли мы ее рисовать, изменять, совмещать, сохранять ? и кто она является по сути : строчка, число, свойство, структура даныных, объект ? когда мы знаем, что мы строим, можем думая об интерфейсе приступатъ к реализации.. Добавлено через 5 минут и 39 секунд к примеру для обсуждаемого формата (как библиотечной сущности) я предполагаю чтение произвольной записи, и построение изображения на основе считанного, и возможно комбинирование данных... Добавлено через 6 минут и 18 секунд image |
| Автор: mes 9.7.2013, 22:14 |
т.е. я исхожу из предположения, что перечисленное далее должно быть либо реализованно, либо иметь возможность быть реализованным.. но с моей колокольни эти и другие назначения как за туманом и трудно определить их обоснованность.. |