Глава V. Структурированные форматные схемы.
В данной главе мы рассматриваем структурированные форматные схемы - ASN.1, SGML, XML и аналоги. Мы намеренно отказались от использования для их описания слова "формат", потому что мы не можем говорить про формат как таковой, но про общие правила составления таких форматов.
V.1. Принципиальными отличиями рассматриваемых здесь форматных схем являются:
1. Иерархическая структурность построения. Каждый элемент данных (как элементарный, так и структурный) должен относиться к одному и только одному структурному элементу более высокого уровня (кроме случая, когда он единственный в посылке) и иметь в нём своё определённое место.
2. Следствием предыдущего является то, что каждый элемент имеет чётко определённую роль. Невозможно строить, например, как в предшествующем примере в главе III - "если в поле X бит 0 равен 0, то в байтах 8-15 находится поле Y; иначе, в 8-11 находится Z+, а в 12-15 - Z-". Для структуризованных форматных схем, если даже используются биты значений, то Y будет в одном месте, а пара {Z+,Z-} в другом, но более вероятно, что непередаваемые данные будут пропущены при генерации посылки и этих полей просто не будет. (С другой стороны, никто не мешает ввести такую интерпретацию, как описана в примере, уже над форматом посылки; но это будет примером плохого стиля реализации.)
3. Определяется внешняя спецификация структуры, которой должны следовать элементы всех уровней такой посылки. Для ASN.1 и XML они выглядят принципиально по-разному, но приводят к одному и тому же результату - спецификации структуры посылки, аналогичной грамматике - какие элементы могут присутствовать в каком другом элементе. Часто допустимо работать и без такой спецификации, но это считается "непромышленным" подходом, потому что отсутствуют средства надёжной верификации "синтаксиса" посылки, конверсии её в другие форматы, и т.д. В некоторых случаях (PER) кодирование и декодирование без такой спецификации невозможно.
4. Фактически в таких схемах можно говорить о двух "слоях", в каждом из которых свои определения лексики, синтаксиса и семантики. На нижнем уровне, лексическими элементами являются отдельные байты (но в некоторых представлениях, как PER, этот уровень сложнее), синтаксическими - тела элементарных посылок и указатели типов/размеров/etc.; семантика начинается с неструктурных элементов. На верхнем уровне, лексическими элементами являются неструктурные элементы, синтаксис определяет структуры согласно спецификации, а семантика начинается с понимания спецификации, кодирования и декодирования полных посылок.
5. Все структурные элементы должны быть явно закодированы. Исключаются подходы типа "со смещения 88 начинается AV-список"; вместо этого, должен присутствовать и быть явно закодированным элемент "AV-список параметров", внутри которого находятся параметры. (Но могут быть специфические оптимизации, которые нарушают это правило, при сохранении однозначности разбора.)
6. Размеры и расположение элементов нефиксированы. Нельзя предполагать, что конкретный элемент будет находиться в том месте, которое было увидено в каком-то случае; нельзя также предполагать его конкретный размер, за исключением особых случаев. Как следствие, невозможно предполагать выравнивание элементов и наличие незаполненных полей, предназначенных для выравнивания.
7. В эволюционном плане структура не может быть ограничена конкретной версией. Какова бы ни была сложность структуры, всегда найдётся вариант, как можно расширить структуру, добавив новое поле в последовательность существующих (таким образом, что отсутствие этого поля приводит к прежней структуре и совместимо со средствами, рассчитанными на предыдущую версию).
На этом заканчивается общее между разными схемами и начинаются различия.
V.2. В качестве первого важного примера рассмотрим XML. Не будем вдаваться в историю развития, детализировать апологетику и критику - этому посвящено достаточное количество ресурсов.
XML является доведенным до логического конца методом построения структурированного формата поверх общих принципов построения текстового формата. Посылка (называемая в XML документом) состоит из спецификации типа посылки (DTD) и корневого элемента (который должен быть единственным). Каждый элемент, от корневого до элементарных, синтаксически единообразно представляется своим названием и содержанием (хотя здесь есть широкие возможности исключения из этих принципов за счёт так называемых атрибутов элементов). Название элемента является именно его названием, а не определением типа (хотя можно так сделать, но бессмысленно). Содержание элементов и атрибутов должно быть представлено в текстовом виде или хотя бы закодировано для беспроблемного нахождения в тексте XML документа, для чего используется эскейпинг. Символами, которые обязательно эскейпятся в содержании элементов, являются '<', '>', '&' и управляющие символы ASCII, а в значениях атрибутов элементов - также применённые для этих атрибутов ограничители содержания (апострофы или кавычки). Альтернатива - элемент CDATA - имеет недопустимым элементом "]]". Кодировка текста, если явно не переопределена - Unicode в UTF-8 или UTF-16.
Например, структура клиента может выглядеть так:
<client>
<id value="123456"/>
<family-name>Пупкин</family-name>
<given-name>Василий</given-name>
<birth>1900-12-12</birth>
</client>
но может и так:
<client id="123456" family-name="Пупкин">
<given-name value="Василий"/>
<birth value="1900-12-12"/>
</client>
Принципиальным ограничением для выбора между элементом в составе структуры и атрибутом является возможность наличия более одного элемента с таким названием - базовый синтаксис XML запрещает наличие разных одноимённых атрибутов у одного элемента, но не возражает против одноимённых подэлементов. Однако, кроме этого, должны учитываться соображения совместимости, здравого смысла, POLA, эстетики и так далее. Выбор между значением одного элемента через атрибут или символьные данные (character data) решается аналогично через общие принципы и эффективность обработки (короткие данные можно представить атрибутом, но чем они длиннее, тем больше проблем с этим). Частое требование POLA - в атрибутах может передаваться только первичный ключ записи.
XML сам по себе не определяет, как именно будет храниться содержание элементов. Можно, например, передавать число в десятичном виде или шестнадцатиричном, записать цифры в обратном порядке или менять на буквы; передавать вместо текстового представления числа с плавающей точкой - байтовое представление в IEEE754, эскейпя через синтаксис entity непредставимые напрямую в тексте значения, и так далее. Поэтому, для представления элементарных значений рекомендуем принять без изменений принципы, описанные в главе IV ("Организация текстового протокола").
Вопрос избыточности представления данных в XML решается во многих случаях использованием дополнительного сжатия результата (например, через gzip).
V.3. ASN.1 (Abstract Syntax Notation number 1) - другой выдающийся пример структурной форматной схемы. Сама по себе ASN.1 достаточно сложно соотносится с другими форматами и форматными схемами; "чистая" ASN.1 это "общая теория всего" в представлении данных, при единственном однозначном требовании - структурности представления, и с набором элементарных типов данных в основе (хотя без ограничения ими). Реальное представление возникает при использовании конкретного набора правил кодирования (encoding rules). Набор стандартных типов данных и их правил представления в конкретном наборе правил кодирования выполняет две роли - собственно практическую и методологическую; последняя заключается в подаче хорошего примера представления данных. Например, рекомендация присутствия часового пояса (он же time zone) в типе данных GeneralizedTime является достаточным, чтобы задуматься о необходимости хранения и передачи такого параметра времени для устранения некорректных скрытых конверсий.
Самым тяжёлым в ASN.1 является необходимость использования, согласно рекомендованному пути реализации, описаний структуры данных, применённых типов данных, и т.д. согласно языку такого описания; этот язык тяжёл для понимания человека, имеет достаточно специфический нестандартный синтаксис, требует построения трансляторов для понимания компьютером. Многие реализации игнорируют это и пользуются более простыми средствами (особенно типично это для SNMP).
Практическое использование ASN.1 требует использования конкретного набора правил кодирования; на данный момент это как минимум следующие:
1. BER (Basic Encoding Rules) - двоичный формат представления, с побайтовой (пооктетной) подложкой представления, неоднозначный (много параметров, выбираемых реализацией).
Характерное приложение - SNMP.
2. CER (Canonic Encoding Rules) и DER (Distinguished Encoding Rules) - два разных, но сходных набора правил, определяющих единственное представление структуры данных в виде байтового потока. Оба являются уточнениями BER; правила декодирования BER полностью пригодны для CER и DER, правила кодирования CER и DER накладывают дополнительные ограничения, но не меняют основы правил.
Характерное приложение DER - X.509. Единственность представления приводит к возможности простого (без полного парсинга) сравнения элементов сертификатов на равенство.
3. PER (Packed Encoding Rules) - максимально экономное двоичное представление с элементарной единицей представления подложки - 1 бит.
Характерное приложение - H.323. В отличие от большинства других наборов правил кодирования, использовать PER без спецификации структуры данных невозможно.
4. XER (XML Encoding Rules) - текстовое представление в XML.
Представление в ASN.1 использует следующие типы данных:
Структурные типы принципиально сходны с ранее рассматривавшимися AV-списками, но характерным свойством ASN.1 является то, что в конкретном представлении согласно правилам кодирования передаются типы данных - элементов структурного типа, а не их названия. Название элемента сохраняется на уровне спецификации. Это общий принцип, активно используемый во всех стандартных форматах. С некоторыми натяжками, можно нарушить этот принцип, за счёт трюка - активного использования неявного тегирования контекстно-специфичными типами; это имеет смысл в том случае, когда конкретный набор данных структуры обычно содержит малую часть от всего возможного состава полей структуры. Но в этом случае спецификация всё равно определяет твёрдый порядок таких полей. Оборотной стороной является то, что передача произвольного списка параметров с их названиями требует как минимум выделенной подструктуры (типа set).
И элементарные, и структурные типы делятся на 4 класса - universal (общий); специфичный для данного контекста (context-specific); для применения (application); частный (private). В общий класс входят представления числа, строки, даты, etc.; их достаточно для подавляющего большинства применений. Класс типов для применения расширяет общий класс тем, что нужно конкретному применению, причём понятие "применения" здесь ближе всего к понятию "общая задача". Например, в SNMP это IP-адрес, счётчики. Контекстно-специфичный тип имеет значение только в пределах определённой грамматической позиции (структура определённого типа); пространства таких типов в разных грамматических позициях не пересекаются. Контекстно-специфичные типы ближе всего к понятию названия элемента, выраженного числом (номером типа).
Любой из неуниверсальных типов может определять свой специфичный тип данных с его представлениями, или использовать существующий, тегировав его собой (явно или неявно). Это позволяет создавать последовательности с необязательными элементами или AV-списки.
..................V.4. Использовать ли структурированную форматную схему?
Можно определить следующее правило: если нет суровой необходимости экономии ресурсов на представление (объём), кодирование и декодирование (соответственно, затраты процессора на собственно работу с данными и работу с метаданными), но есть потенциальная возможность введения новых требований и расширения формата, является желательным использовать структурированной форматной схемы как основы форматов данных протокола. Желательность здесь происходит из того, что, с одной стороны, в этих схемах уже решена основная (часто и подавляющая) часть вопросов представления, с другой стороны, заведомая неограниченная расширяемость позволяет следовать постоянно меняющимся внешним требованиям. На сейчас XML является одним из наиболее распространённых промышленных стандартов представления данных и для передачи по сети, и для локального хранения.
Copyright (C) 2010-2011 Valentin Nechayev. All rights reserved.