Страница 11 из 18
					
				cJSON: Формат полей для вложенных структур
				Добавлено: 14 Декабрь 2022, 15:58
				 Дед Пахом
				Да, эту возможность надо добавить.
			 
			
					
				cJSON: Формат полей для вложенных структур
				Добавлено: 14 Декабрь 2022, 18:18
				 Дед Пахом
				Утром в газете, вечером в куплете! Вышла v1.31, есть пример использования.
			 
			
					
				cJSON: Формат полей для вложенных структур
				Добавлено: 14 Декабрь 2022, 18:58
				 Игорь Столяров
				Спасибо ! Буду тестировать.  
 
Можно ли совсем оборзеть от счастья и спросить про расмотрение опций обмена файлами в BASE64 ? 

У нас несколько направлений упёрлось именно в эту стену.
 
			 
			
					
				cJSON: Формат полей для вложенных структур
				Добавлено: 14 Декабрь 2022, 20:33
				 Дед Пахом
				Завтра base64 добавлю, если с 1.31 всё норм.
			 
			
					
				cJSON: Формат полей для вложенных структур
				Добавлено: 15 Декабрь 2022, 0:20
				 Игорь Столяров
				В базовых операциях всё работает, под нагрузкой проверим в бою.  
 
Мы можем теперь выгружать любое поле Queue в SimpleArray. OK !
Но правильно ли я понимаю, что загрузка SimpleArray методами ToQueue / ToGroup всегда
выполняется только в первое поле Queue и FieldNumber здесь не работает ? 
Это абсолютно не напрягает, просто что бы у меня была полная картина происходящего.
И очень хорошо, что нет контроля на одно поле в загружаемой Queue.
Например, можно в первое поле загрузить коды и дальше получить в другие поля из БД их описание и т.д.  

 
			 
			
					
				cJSON: Формат полей для вложенных структур
				Добавлено: 15 Декабрь 2022, 19:11
				 Дед Пахом
				Вышла v1.32.
Добавил загрузку массивов в поле очереди, а также поддержку base64. Подробности в readme и примерах.
			 
			
					
				cJSON: Формат полей для вложенных структур
				Добавлено: 15 Декабрь 2022, 20:16
				 Игорь Столяров
				Дед Пахом писал(а): 15 Декабрь 2022, 19:11
а также поддержку base64
 
Конвертация в BASE64 - это инструмент для обмена бинарными данными, а не цель.
Если позволите, вопрос по загрузке. Мне пришёл JSON с неким файлом в теге BASE64.
Что бы выполнить: 
Код: Выделить всё
    CLEAR(Person)
    IF jPerson.ToGroup(Person,,'{{"name":"BinaryData","isbase64":true}')
      printd('Name: %s, BinaryData: %s', Person.Name, Person.BinaryData)
    END
Сначала нужно (как-то) угадать размер поля Name в группе и выделить под него память ?
А у Вас ведь есть прекрасная реализация загрузки данных неопределённого размера: fileContent &= json::LoadFile('test.json')
По выгрузке. Самая рутинная часть - это формирование структур с загрузкой файлов и освобождение памяти.
Можно вообще убрать работу с указателями передав в класс имя выгружаемого файла. 
А добавление "isbase64" уберёт всего лишь один вызов процедуры, но добавит в проект целый класс ...
Я понимаю, "Что Ваши ожидания - это Ваши проблемы" (C) Аршавин.
Но когда я рассказывал об обмене файлами - то исходил из возможности практического применения. 

Извините за мнение: но в такой реализации использовать загрузку файлов нельзя, а выгрузку нет смысла.
 
			 
			
					
				cJSON: Формат полей для вложенных структур
				Добавлено: 15 Декабрь 2022, 21:08
				 Дед Пахом
				Вся проблема в том, что Вы всё на свете хотите запихать в одну мегаструктуру.
Есть загруженный объект json посредством jParser.Parse(). В нём всё есть. В нём всё легко найти. Нет, надо его засунуть в группу с десятком вложенных групп и очередей. Чтобы что?
По поводу практического применения.
Person.BinaryData &= json::LoadFile('test.json') чем не устраивает?
			 
			
					
				cJSON: Формат полей для вложенных структур
				Добавлено: 15 Декабрь 2022, 22:06
				 Игорь Столяров
				Дед Пахом писал(а): 15 Декабрь 2022, 21:08
Person.BinaryData &= json::LoadFile('test.json') чем не устраивает?
 
Это про выгрузку. Да, сейчас именно так и делается:
Код: Выделить всё
  Person.BinaryData &= json::IsLoadFile('test.json')  ! Загрузить файл в BASE64
json::IsLoadFile Procedure(String xFilename) !, *String
xContent    &String
xBuffer     &IDynStr
  Code
  xContent &= json::LoadFile(xFilename)
  If Not (xContent &= Null)
     xBuffer &= NewDynStr()
     If Not (xBuffer &= Null)
        xBuffer.Cat(ToBase64(xContent))  ! Содержимое файла в BASE64
        Dispose(xContent)                ! Пересоздать строку
        xContent &= New(String(xBuffer.StrLen()))
        xBuffer.CopyTo(xContent)
        xBuffer.Kill
        DisposeDynStr(xBuffer)
     end
  end
  Return xContent
Здесь всё хорошо, но остаётся список указателей, которые нужно потом прокручивать и чистить.
И когда создаём пакет для отправки 20-30 документов - всё это загружается в память и только потом передаётся в метод ...
Почему бы это не свернуть внутрь класса, просто указав для тега имя файла и опцию выгрузки в Base64 ?
Про загрузку. Нет я не хочу всё засунуть в одну мегаструктуру. 

 Их просто не существует.
Есть элементарный пакет с заголовком и списком файлов в пакете (в реале немного сложнее - несколько списков файлов).
Я хочу выполнить ToGroup() и получить данные пакета и список указателей на строки с бинарными данными
из тегов в BASE64 (размер которых не известен даже Богу !). И это всё - дальше мы сами обработаем эти строки.
Полностью с Вами согласен, что можно:
- распарсить JSON, 
- найти в ней список (массив), 
- перебирать в массиве записи по одной,
- находить тег с содержанием в BASE64 : jFileContents &= jRoot.FindObjectItem('file1')
- загружать этот тег в указатель (строку): jFileContents.GetStringRef()
- создавать указатель (строку) и извлекать в неё бинарное содержимое из BASE64,
- очищать память c содержанием в BASE64.
И так для каждого файла в списке и для каждого списка в группе ... Вот где беда. 

 
			 
			
					
				cJSON: Формат полей для вложенных структур
				Добавлено: 15 Декабрь 2022, 22:44
				 Дед Пахом
				Игорь Столяров писал(а): 15 Декабрь 2022, 22:06
json::IsLoadFile Procedure(String xFilename) !, *String
 
Всё намного проще, если учесть, что размер строки base64 больше размера исходной строки ровно в 4/3.
Игорь Столяров писал(а): 15 Декабрь 2022, 22:06
из тегов в BASE64 (размер которых не известен даже Богу !).
 
Да вообще-то это справедливо почти для всего (кроме имён файлов). Допустим, есть поле Фамилия, мы заложились на string(20). Тут прилетает пакет с информацией о гражданине Щекочихине-Крестовоздвиженском... Я к тому, что в некоторых (некоторых!) случаях можно заранее знать максимальный размер данных. Например, многие сайты ограничивают размер загружаемых фотографий (1Мб, 2Мб...).
Игорь Столяров писал(а): 15 Декабрь 2022, 22:06
Полностью с Вами согласен, что можно:
- распарсить JSON,
- найти в ней список (массив),
......................
 
Это вот всё прекрасно заворачивается в процедуру.
Причём если использовать JSONPath, то можно сразу получить все указатели на теги с содержанием в BASE64.
 
			 
			
					
				cJSON: Формат полей для вложенных структур
				Добавлено: 15 Декабрь 2022, 23:25
				 Игорь Столяров
				Дед Пахом писал(а): 15 Декабрь 2022, 22:44
размер строки base64 больше размера исходной строки ровно в 4/3
 
Там ещё хвостик дополняется. Возможно поэтому он отличается в LibCurlMail от всех других способов.
Но раскодируется всё без проблем.
Дед Пахом писал(а): 15 Декабрь 2022, 22:44
Я к тому, что в некоторых (некоторых!) случаях можно заранее знать максимальный размер данных.
 
Можно. Но вопрос другой: хотим ли вздрагивать от каждого звонка, что где-то что-то не влезло в String(N) ?
Дед Пахом писал(а): 15 Декабрь 2022, 22:44
то можно сразу получить все указатели на теги с содержанием в BASE64
 
Были бы указатели. А сваливать в одну кучу смысла нет - смысл данных зависит от контекста.
Какие-то файлы с документами, в других сертификаты, есть протоколы и листинги ... и т.д.
 
			 
			
					
				cJSON: Формат полей для вложенных структур
				Добавлено: 15 Декабрь 2022, 23:31
				 Дед Пахом
				Игорь Столяров писал(а): 15 Декабрь 2022, 23:25
Можно. Но вопрос другой: хотим ли вздрагивать от каждого звонка, что где-то что-то не влезло в String(N) ?
 
Вот. В пределе приходим к выводу, что все поля надо делать динамическими.
Игорь Столяров писал(а): 15 Декабрь 2022, 23:25
Были бы указатели. А сваливать в одну кучу смысла нет - смысл данных зависит от контекста.
 
Ну так просто контекст надо передать в JSONPath.
 
			 
			
					
				cJSON: Формат полей для вложенных структур
				Добавлено: 16 Декабрь 2022, 7:42
				 Игорь Столяров
				Дед Пахом писал(а): 15 Декабрь 2022, 23:31
приходим к выводу, что все поля надо делать динамическими
 
ЗАГРУЗКА. Да, полностью с Вами согласен.
Должен возвращаться указатель как в fileContent &= json::LoadFile('test.json')
Потому, что такой вариант загрузки имеет только академически-декларативный смысл, но не практический:
Код: Выделить всё
!BinaryData &String    ! Ожидания :)
BinaryData String(20)  ! Реальность :(
...
    IF jPerson.ToGroup(Person,,'{{"name":"BinaryData","isbase64":true}')
      printd('Name: %s, BinaryData: %s', Person.Name, Person.BinaryData)
    END
ВЫГРУЗКА. Вопрос: где бедный программист на Clarion вообще может взять некие бинарные данные ?
Два варианта: BLOB и FILE. Поэтому я и топил за опцию (уже боюсь называть имя), которая просто
по имени файла запишет его содержание в тег BASE64. Всё. Абсолютно понятное и очевидное действие.
И не надо здесь решать никому не нужные задачи с выделением и зачисткой памяти. Вот ! 

 
			 
			
					
				cJSON: Формат полей для вложенных структур
				Добавлено: 16 Декабрь 2022, 19:24
				 Дед Пахом
				Вышла v1.33.
Правило "IsFile" указывает, что в поле - имя файла, который надо загрузить. Примерно так:
{"name":"Photo","isfile":true,"isbase64":true}
			 
			
					
				cJSON: Формат полей для вложенных структур
				Добавлено: 17 Декабрь 2022, 11:00
				 Игорь Столяров
				Дед Пахом писал(а): 16 Декабрь 2022, 19:24
{"name":"Photo","isfile":true,"isbase64":true}
 
Большое спасибо ! Это меняет всё. Теперь работа с ВЫГРУЗКОЙ файлов приобрела законченный вид.
Отдельное спасибо - за метод, я о таких возможностях даже не знал. 
Оказывается, что все действия с файлом (указание места, проверка наличия, архивация и т.д.) 
теперь можно делать в одном месте ... Сторонние сервисы BASE64 понимают и принимают. 
Код: Выделить всё
rh.ApplyCB Procedure(String pFldName, *typCJsonFieldRule pRule, ? pValue)
fContent   &String, Auto
fName      CString(File:MaxFileName), Auto
  Code
  If Sub(pFldName,1,6) = 'base64' and Clip(pValue) <> ''
     fName = LongPath(System{Prop:DataPath}) & 'Image\' & Clip(pValue)
     If Exists(fName)
        fContent &= json::LoadFile(fName)
        pValue    = fContent
        Dispose(fContent)
     end
  end
  Return pValue
P/S: Очень обидно удалять огромное кол-во своего отлаженного кода для выгрузки файлов ...