Spec-Zone.ru › Ruby 2.7

Marshal Формат

Формат Marshal используется для сериализации объектов Ruby. Формат может хранить произвольные объекты с помощью трёх механизмов пользовательских расширений.

Для получения документации по использованию Marshal для сериализации и десериализации объектов, обратитесь к модулю Marshal.

В данном документе сериализованный набор объектов называется потоком. Реализация Ruby может загрузить набор объектов из String, IO или объекта, который реализует метод getc.

Формат потока

Первые два байта потока содержат основной и дополнительный версии, каждый как одиночный байт, кодирующий цифру. Реализация в Ruby имеет версию 4.8 (хранится как “x04x08”) и поддерживается Ruby 1.8.0 и более новыми версиями.

Разные основные версии формата Marshal несовместимы и не могут быть поняты другими основными версиями. Меньшие дополнительные версии формата могут быть поняты более новыми дополнительными версиями. Формат 4.7 может быть загружен реализацией 4.8, но формат 4.8 не может быть загружен реализацией 4.7.

После байтов версии следует поток, описывающий сериализованный объект. Поток содержит вложенные объекты (так же, как и объект Ruby), но объекты в потоке не обязательно имеют прямое отображение в модель объекта Ruby.

Каждый объект в потоке описывается байтом, указывающим его тип, за которым следует один или несколько байтов, описывающих объект. Когда ниже упоминается «объект», это означает любой из типов ниже, который определяет объект Ruby.

true, false, nil

Эти объекты имеют длину в один байт. «T» представляет true, «F» представляет false, а «0» представляет nil.

Fixnum и long

«i» представляет собой знаковое 32-битное значение, использующее упакованный формат. После типа следуют от одного до пяти байтов. Загруженное значение всегда будет Fixnum. На 32-битных платформах (где точность Fixnum меньше 32 бит) загрузка больших значений вызовет переполнение в CRuby.

Тип Fixnum используется для представления как объектов Ruby Fixnum, так и размеров сериализованных массивов, хэшей, переменных экземпляра и других типов. В следующих разделах «long» будет означать формат, описанный ниже, который поддерживает полную 32-битную точность.

Первый байт имеет следующие специальные значения:

“x00”

Значение целого числа равно 0. Следующих байтов нет.

“x01”

Общий размер целого числа составляет два байта. Следующий байт — положительное целое число в диапазоне от 0 до 255. Только значения от 123 до 255 должны быть представлены таким образом, чтобы сохранить байты.

“xff”

Общий размер целого числа составляет два байта. Следующий байт — отрицательное целое число в диапазоне от -1 до -256.

“x02”

Общий размер целого числа составляет три байта. Следующие два байта — положительное целое число в формате little-endian.

“xfe”

Общий размер целого числа составляет три байта. Следующие два байта — отрицательное целое число в формате little-endian.

“x03”

Общий размер целого числа составляет четыре байта. Следующие три байта — положительное целое число в формате little-endian.

“xfd”

Общий размер целого числа составляет два байта. Следующие три байта — отрицательное целое число в формате little-endian.

“x04”

Общий размер целого числа составляет пять байтов. Следующие четыре байта — положительное целое число в формате little-endian. Для совместимости с 32-битным Ruby должны использоваться только Fixnum меньше 1073741824. Для размеров объектов потока может использоваться полная точность.

“xfc”

Общий размер целого числа составляет два байта. Следующие четыре байта — отрицательное целое число в формате little-endian. Для совместимости с 32-битным Ruby должны использоваться только Fixnum больше -10737341824. Для размеров объектов потока может использоваться полная точность.

В противном случае первый байт является знаковым расширенным 8-битным значением со смещением. Если значение положительное, значение определяется вычитанием 5 из значения. Если значение отрицательное, значение определяется добавлением 5 к значению.

Для многих значений существует несколько представлений. CRuby всегда выводит кратчайшее возможное представление.

Символы и последовательность байтов

«:” представляет собой реальный символ. Реальный символ содержит данные, необходимые для определения символа для остальной части потока, так как последующие появления в потоке вместо этого будут ссылками (ссылка на символ) на этот символ. Ссылка — это 32-битное значение с нулевым индексом (так что первое появление :hello равно 0).

После байта типа следует последовательность байтов, которая состоит из целого числа, указывающего количество байтов в последовательности, за которым следует столько байтов данных. Последовательности байтов не имеют кодировки.

Например, следующий поток содержит символ Symbol :hello:

"\x04\x08:\x0ahello"

«;” представляет собой ссылку на Symbol, которая ссылается на ранее определённый Symbol. После байта типа следует целое число, содержащее индекс в таблице поиска для связанного (ссылочного) Symbol.

Например, следующий поток содержит [:hello, :hello]:

"\x04\b[\a:\nhello;\x00"

Когда ниже упоминается «символ», это может быть либо реальный символ, либо ссылка на символ.

Ссылки на Object

Отдельно от, но схоже с ссылками на символы, поток содержит только одну копию каждого объекта (как определяется object_id) для всех объектов, кроме true, false, nil, Fixnum и Symbols (которые хранятся отдельно, как описано выше). Будет храниться 32-битное значение с индексом 1, и оно будет повторно использоваться при повторной встрече объекта. (У первого объекта есть индекс 1).

«@» представляет ссылку на объект. После байта типа следует целое число, указывающее индекс объекта.

Например, следующий поток содержит массив Array того же объекта "hello" дважды:

"\004\b[\a\"\nhello@\006"

Переменные экземпляра

«I» указывает, что после следующего объекта следуют переменные экземпляра. После байта типа следует объект. После объекта следует длина, указывающая количество переменных экземпляра для объекта. После длины следует набор пар имя-значение. Имена являются символами, а значения — объектами. Символы должны быть именами переменных экземпляра (:@name).

Объект Object («o» тип, описанный ниже) использует тот же формат для своих переменных экземпляра, что и описанный здесь.

Для String и Regexp (описанных ниже) используется специальная переменная экземпляра :E, чтобы указать кодировку Encoding.

Расширенный

«e» указывает, что следующий объект расширен модулем. После байта типа следует объект. После объекта следует символ, содержащий имя модуля, которым расширен объект.

Array

«[» представляет собой массив Array. После байта типа следует целое число, указывающее количество объектов в массиве. После длины следуют указанные объекты.

Bignum

«l» представляет собой Bignum, состоящий из трёх частей:

знак

Один байт, содержащий «+» для положительного значения или «-» для отрицательного значения.

длина

Целое число, указывающее количество байтов данных Bignum, которые следуют за ним, разделённое на два. Умножьте длину на два, чтобы определить количество байтов данных, которые следуют за ней.

данные

Байты данных Bignum, представляющие число.

Следующий код Ruby позволит восстановить значение Bignum из массива байтов:

result = 0

bytes.each_with_index do |byte, exp|
 result += (byte * 2 ** (exp * 8))
end

Класс Class и модуль Module

«c» представляет объект Class, «m» — объект Module, а «M» — либо класс, либо модуль (это старый стиль для совместимости). Содержимое класса или модуля не включено, этот тип представляет только ссылку. После байта типа следует последовательность байтов, которая используется для поиска существующего класса или модуля соответственно.

Переменные экземпляра недопустимы для класса или модуля.

Если класс или модуль не существует, должно быть выброшено исключение.

Для типов «c» и «m» загруженный объект должен быть соответственно классом или модулем.

«d» представляет собой объект Data. (Data объекты — это указатели из расширений Ruby.) После байта типа следует символ, указывающий класс объекта Data, и объект, содержащий состояние объекта Data.

Для сохранения объекта Data Ruby вызывает _dump_data. Для загрузки объекта Data Ruby вызывает _load_data с состоянием объекта на вновь выделенном экземпляре.

Float

«f» представляет собой объект Float. После байта типа следует последовательность байтов, содержащая значение с плавающей запятой. Следующие значения являются специальными:

“inf”

Положительная бесконечность

“-inf”

Отрицательная бесконечность

“nan”

Не число

В противном случае последовательность байтов содержит C double (загружаемый с помощью strtod(3)). Более ранние дополнительные версии Marshal также хранили дополнительные биты мантиссы, чтобы обеспечить переносимость между платформами, но 4.8 не включает их. Смотрите

ruby-talk:69518

для некоторых объяснений.

Hash и Hash с заданным значением по умолчанию

«{» представляет объект Hash, в то время как «}» представляет объект Hash с установленным значением по умолчанию (Hash.new 0). После байта типа следует целое число, указывающее количество пар ключ-значение в Hash — размер. После размера следуют удвоенное количество объектов.

Для Hash со значением по умолчанию, значение по умолчанию следует за всеми парами.

Модуль Module и старый модуль Module

Object

«o» представляет собой объект, не имеющий другого специального формата (такого как пользовательский или встроенный формат). После байта типа следует символ, содержащий имя класса объекта. После имени класса следует целое число, указывающее количество имён и значений переменных экземпляра для объекта. После размера следуют удвоенные пары объектов.

Ключи в парах должны быть символами, содержащими имена переменных экземпляра.

Регулярное выражение

“/” обозначает регулярное выражение. После байта типа следует байтовая последовательность, содержащая исходный код регулярного выражения. После байта типа следует байт, содержащий параметры регулярного выражения (регистронезависимость и т. д.) в виде знакового 8-битного значения.

Регулярные выражения могут иметь кодировку, присоединенную через переменные экземпляра (см. выше). Если кодировка не прикреплена, эскапированные специальные символы regexp, отсутствующие в ruby 1.8, должны быть удалены: g-m, o-q, u, y, E, F, H-L, N-V, X, Y.

String

'“' представляет String. После байта типа следует байтовая последовательность, содержащая содержимое строки. При выгрузке из ruby 1.9 должна включаться переменная экземпляра кодировки (:E см. выше), если кодировка не двоичная.

Struct

“S” представляет Struct. После байта типа следует символ, содержащий имя структуры. После имени следует целое число, указывающее количество членов в структуре. После количества членов следуют удвоенное количество объектов. Каждый член представляет собой пару, содержащую символ имени члена и объект, представляющий значение этого члена.

Если имя структуры не соответствует подклассу Struct в работающей версии ruby, должно быть возбуждено исключение.

Если существует несоответствие между структурой в текущей версии ruby и количеством членов в сериализованной структуре, должно быть возбуждено исключение.

User Class

“C” представляет собой подкласс String, Regexp, Array или Hash. После байта типа следует символ, содержащий имя подкласса. После имени следует обернутый объект.

Пользовательское определение

“u” представляет объект с пользовательским форматом сериализации, использующим метод экземпляра _dump и метод класса _load. После байта типа следует символ, содержащий имя класса. После имени класса следует байтовая последовательность, содержащая пользовательское представление объекта.

Метод класса _load вызывается для класса со строкой, созданной из байтовой последовательности.

Пользовательский Marshal

“U” представляет объект с пользовательским форматом сериализации, использующим методы экземпляра marshal_dump и marshal_load. После байта типа следует символ, содержащий имя класса. После имени класса следует объект, содержащий данные.

При загрузке необходимо выделить новый экземпляр и вызвать метод marshal_load для экземпляра с данными.

Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API