Распаковка двоичных данных GZip через ХранилищеЗначения

orevalord 7 1

Метод распаковки двоичных данных HTTP ответа сжатых GZip через ХранилищеЗначения

// Выполняет декомпрессию GZip путем «обертывания» DEFLATE-данных в формат
// «Хранилища значения» 1С.
//
// Параметры:
//  * СжатыеДвоичныеДанные - ДвоичныеДанные - исходный GZip-архив.
//  * Кодировка - КодировкаТекста, Неопределено - кодировка для преобразования
//    результата в строку (если применимо)
//
// Возвращаемое значение:
//  * ДвоичныеДанные - распакованные двоичные данные
//  * Строка - распакованная данные строкой в заданной кодировке
//
&НаСервереБезКонтекста
Функция ЧтениеGZipЧерезХранилищеЗначения(СжатыеДвоичныеДанные, Кодировка = Неопределено) Экспорт

	// Извлекаем чистый DEFLATE-поток: вычитаем служебные 10 байт заголовка и 8 байт подвала GZIP (RFC 1952)
	РазмерGZip = СжатыеДвоичныеДанные.Размер() - 18;

	// Инициализируем буфер: чистый DEFLATE + 104 байта системной обвязки 1С (заполняется нулями)
	Буфер = Новый БуферДвоичныхДанных(РазмерGZip + 104);

	// Сборка 92-байтного модифицированного заголовка структуры Хранилища Значений:
	// Часть 1 (18 байт): Сигнатура сжатия 1С (0201534B6FF4888DC14EA0D5EBB6BDA0A70D)
	// Часть 2 (5 байт):  Заголовок RFC 1951 для несжатого блока метаданных (005100AEFF)
	// Часть 3 (69 байт): Системный GUID и манифест типа ДвоичныеДанные (3D00000000...)
	Метаданные1С = "0201534B6FF4888DC14EA0D5EBB6BDA0A70D" 
	             + "005100AEFF"                         
	             + "3D00000000000000EFBBBF7B2223222C38373132363230302D336539382D343465302D623933312D6363623164376564633439372C0D0A7B312C0D0A7B307D0D0A7D0D0A7D";

	// Записываем собранную шапку (смещение 0, длина 92). Блок размеров (смещения 92-103) остается нулевым.
	Буфер.Записать(0, ПолучитьБуферДвоичныхДанныхИзHexСтроки(Метаданные1С), 92);

	ПотокGZip = СжатыеДвоичныеДанные.ОткрытьПотокДляЧтения();

	// Пропускаем 10 байт заголовка GZIP и копируем DEFLATE на позицию 104 (сразу за структурами 1С)
	ПотокGZip.Перейти(10, ПозицияВПотоке.Начало);
	ПотокGZip.Прочитать(Буфер, 104, РазмерGZip);

	// Часть 4 (12б, смещения 92-103): Технологический блок размеров 1С [4б нулей + 4б размер + 4б нулей].
	// Пропускаем 4 байта CRC32 в хвосте GZIP и считываем 4 байта ISIZE (размер оригинала) на позицию 96.
	ПотокGZip.Перейти(4, ПозицияВПотоке.Текущая);
	ПотокGZip.Прочитать(Буфер, 96, 4);
	ПотокGZip.Закрыть();
	
	// Преобразование подготовленного бинарного массива через Base64 в объект ХранилищеЗначения
	ДанныеХранилища = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(Буфер);
	
	Результат = XMLЗначение(Тип("ХранилищеЗначения"), Base64Строка(ДанныеХранилища)).Получить();
	
	Если ТипЗнч(Кодировка) = Тип("КодировкаТекста") Тогда
		Результат = ПолучитьСтрокуИзДвоичныхДанных(Результат, Кодировка);
	КонецЕсли;
	
	Возврат Результат;

КонецФункции
0

См. также

Преобразование Хранилище Значения в Двоичные данные и обратно

ПоместитьВХранилище (БСП)

ВыгрузитьТекущуюОбластьДанныхВоВременноеХранилище (БСП)

ХранилищеФайлаИзИнформационнойБазы (БСП)

ИзвлечьТекст (БСП)

ПоместитьМанифестКонфигурацииВоВременноеХранилище (БСП)

Отправить двоичные данные в телеграм (zip/pdf/gif)

ТекстВДвоичныхДанных (БСП)

ДвоичныеДанныеФайла (БСП)

Модератору