Значение в строку внутреннюю для сложных типов: как работает платформа или немного о декодировании base64 в текст через двоичные данные
Интересная особенность работы платформы со сложными типами при использовании метода ЗначениеВСтрокуВнутр, двоичные данные и новые методы платформы…
- Описание
- Подробнее
Описание
Добрый день всем!
Вот столкнулся с такой штукой, как «сериализация» фильтра компоновки данных с помощью метода «ЗначениеВСтрокуВнутр» платформы. Суть в том, что платформа сначала сериализует данный объект в XML, а затем этот XML кодирует в base64 и помещает в некий JSON-контейнер с типом и данными. Тип — это некий идентификатор, а данные — это тот самый закодированный в base64 сериализованный XML.
Рассуждать на тему того, почему 1С решили сделать таким образом, особого смысла нет — сделали — и слава Богу!* Но вот решил я все-таки декодировать base64-строку в текст и не нашел соответствующего метода платформы. В двоичные данные — пожалуйста, а в текст — нет. Но в последних релизах платформы объект «ДвоичныеДанные» оброс знатным функционалом, что просто не могло не обрадовать многих специалистов по 1С. В итоге родился такой вот замечательный код:
// Данные - это что-то, что было сериализовано с помощью "ЗначениеВСтрокуВнутр"
Поз = СтрНайти(Данные, "#base64");
ПС = Сред(Данные, поз+8);
Поз2 = СтрНайти(ПС, "}");
ПС = Лев(ПС, Поз2-1);
ЧД = Новый ЧтениеДанных(Base64Значение(ПС));
СтрокаXML = ЧД.ПрочитатьСимволы();У нас тут есть, допустим, какие-то данные, которые мы откуда-то взяли. Например:
Данные = ЗначениеВСтрокуВнутр(ОтборКомпоновкиДанных);В итоге у нас получилась какая-то такая строка:
{«#»,f6841c6b-6c71-4c82-ae9e-d08b49db326c,
{#base64:77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxGaWx0
ZXIgeG1sbnM9Imh0dHA6Ly92OC4xYy5ydS84LjEvZGF0YS1jb21wb3NpdGlvbi1z
eXN0ZW0vc2V0dGluZ3MiIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAx
L1hNTFNjaGVtYSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hN
TFNjaGVtYS1pbnN0YW5jZSI+DQoJPGl0ZW0geHNpOnR5cGU9IkZpbHRlckl0ZW1H
cm91cCI+DQoJCTxncm91cFR5cGU+QW5kR3JvdXA8L2dyb3VwVHlwZT4NCgkJPGl0
ZW0geHNpOnR5cGU9IkZpbHRlckl0ZW1Db21wYXJpc29uIj4NCgkJCTxsZWZ0IHht
bG5zOmRjc2Nvcj0iaHR0cDovL3Y4LjFjLnJ1LzguMS9kYXRhLWNvbXBvc2l0aW9u
LXN5c3RlbS9jb3JlIiB4c2k6dHlwZT0iZGNzY29yOkZpZWxkIj7QodGH0LXRgtCU
0YIu0JrQvtC0PC9sZWZ0Pg0KCQkJPGNvbXBhcmlzb25UeXBlPkNvbnRhaW5zPC9j
b21wYXJpc29uVHlwZT4NCgkJCTxyaWdodCB4c2k6dHlwZT0ieHM6c3RyaW5nIj4x
MDYuMDE8L3JpZ2h0Pg0KCQk8L2l0ZW0+DQoJCTxpdGVtIHhzaTp0eXBlPSJGaWx0
ZXJJdGVtQ29tcGFyaXNvbiI+DQoJCQk8bGVmdCB4bWxuczpkY3Njb3I9Imh0dHA6
Ly92OC4xYy5ydS84LjEvZGF0YS1jb21wb3NpdGlvbi1zeXN0ZW0vY29yZSIgeHNp
OnR5cGU9ImRjc2NvcjpGaWVsZCI+0KHRg9Cx0LrQvtC90YLQvtCU0YIxLlvQodC4
0LzQstC+0Lsg0J7QpNCgKyDQktC40LTRiyDQvdC+0LzQtdC90LrQu9Cw0YLRg9GA
0YsgXTwvbGVmdD4NCgkJCTxjb21wYXJpc29uVHlwZT5FcXVhbDwvY29tcGFyaXNv
blR5cGU+DQoJCQk8cmlnaHQgeG1sbnM6ZDRwMT0iaHR0cDovL3Y4LjFjLnJ1Lzgu
MS9kYXRhL2VudGVycHJpc2UvY3VycmVudC1jb25maWciIHhzaTp0eXBlPSJkNHAx
OkNhdGFsb2dSZWYu0L3RhNC+X9CX0L3QsNGH0LXQvdC40Y/QkNC90LDQu9C40YLQ
uNC60LgiPmE1Yzg2MjQwLWRmOTMtMTFlNS05NDU2LTAwMWU2NzU0ODlmNDwvcmln
aHQ+DQoJCTwvaXRlbT4NCgk8L2l0ZW0+DQo8L0ZpbHRlcj4=}
}
Дальше мы из этой строки получаем данные base64, которые обрамлены символами «{#base64:» и «}». Т.е. получаем все, что между этими символами.
После этого мы декодируем строку base64 в двоичные данные давно известной функцией. И вот из этих двоичных данных получить строку не так-то просто. Раньше можно было записать файл и потом прочитать его в виде текста. Но операции ввода-вывода достаточно затратны. В новой платформе (у меня 8.3.10.2168) появились функции работы с потоками двоичных данных. Мы здесь используем объект «ЧтениеДанных», который можно создать на основании двоичных данных, полученных с помощью функции «Base64Значение». У объекта «ЧтениеДанных» есть метод «ПрочитатьСимволы()», который без параметров просто возвращает нам в кодировке по-умолчению все символы из двоичных данных. Таким образом, в переменной «СтрокаXML» будет находиться следующее значение:
<?xml version=»1.0″ encoding=»UTF-8″?>
<Filter xmlns=»http://v8.1c.ru/8.1/data-composition-system/settings» xmlns:xs=»http://www.w3.org/2001/XMLSchema» xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance»>
<item xsi:type=»FilterItemGroup»>
<groupType>AndGroup</groupType>
<item xsi:type=»FilterItemComparison»>
<left xmlns:dcscor=»http://v8.1c.ru/8.1/data-composition-system/core» xsi:type=»dcscor:Field»>СчетДт.Код</left>
<comparisonType>Contains</comparisonType>
<right xsi:type=»xs:string»>106.01</right>
</item>
<item xsi:type=»FilterItemComparison»>
<left xmlns:dcscor=»http://v8.1c.ru/8.1/data-composition-system/core» xsi:type=»dcscor:Field»>СубконтоДт1.[Символ ОФР+ Виды номенклатуры ]</left>
<comparisonType>Equal</comparisonType>
<right xmlns:d4p1=»http://v8.1c.ru/8.1/data/enterprise/current-config» xsi:type=»d4p1:CatalogRef.нфо_ЗначенияАналитики»>a5c86240-df93-11e5-9456-001e675489f4</right>
</item>
</item>
</Filter>
Надеюсь, новый функционал платформы может быть полезен для оптимизации различных операций для работы со строками, находящимися в объекте ДвоичныеДанные.

