Страница 14 из 18
cJSON: Формат полей для вложенных структур
Добавлено: 30 Декабрь 2022, 0:43
Игорь Столяров
Дед Пахом писал(а): ↑30 Декабрь 2022, 0:24
А без загрузки содержимого файлов из json в очередь прямо-таки нельзя обойтись?
Вопрос унификации обработки списков с файлами.
Если для каждого вида списка писать ручной распарс JSON с сохранением файлов - то наверно можно.
Но мы делаем класс который трансформирует произвольный пакет JSON в переданный Group (+ несколько Queue).
И далее уже полученная структура разбирается по спискам и файлам в зависимости от её типа ... Что логично.
И мне технологическое решение бабахать содержание (возможно) мегабайтных файлов в поля ANY QUEUE - кажется так себе.
Здесь как-то логичней выглядит работа с указателями на строки, о чём я впрочем, говорил изначально ...
Да, это можно сейчас делать в AutoCB(), но опять всё вручную по каждому имени тега ....
cJSON: Формат полей для вложенных структур
Добавлено: 30 Декабрь 2022, 7:55
Игорь Столяров
Дед Пахом писал(а): ↑29 Декабрь 2022, 23:33
В FindCB можно задать правило "auto" по маске.
Нельзя. Если тип поля ANY, то его имя в FindCB() вообще не доступно.
Код: Выделить всё
MyQueue Queue
...
fileinbase64_01 Any
fileinbase64_02 Any
...
end
...
rh.FindCB Procedure(String pFldName, *typCJsonFieldRule pRule)
Code
If Sub(pFldName,1,12) = 'fileinbase64' ! Для полей ANY включить загрузку из Base64 в AutoCB()
! МЫ СЮДА НИКОГДА НЕ ПОПАДАЕМ
pRule.Auto = True
end
cJSON: Формат полей для вложенных структур
Добавлено: 30 Декабрь 2022, 9:25
Игорь Столяров
Добрый день !
Вопрос. Можно ли добавить для метода AutoCB() параметр pFldRef с ссылкой на текущее поле Group / Queue ?
Она у Вас всегда расчитывается при переборе полей в методах ToGroup() / ToQueue() как fldRef &= WHAT(grp, pFieldNumber).
Что бы можно было напрямую записывать значение в текущее поле структуры. Что-то вроде:
Код: Выделить всё
rh.AutoCB Procedure(String pFldName, cJSON pItem , Any pFldRef)
Code
If Sub(pFldName,1,12) = 'FILEINBASE64' then pFldRef = printf('%w', pItem.GetStringValue()).
или (если не хотите менять протип метода) вынести fldRef в класс и тогда:
Код: Выделить всё
rh.AutoCB Procedure(String pFldName, cJSON pItem)
Code
If Sub(pFldName,1,12) = 'FILEINBASE64' then pItem.FldRef = printf('%w', pItem.GetStringValue()).
Потому, что иначе можно получать значение тега только в поле с конкретным именем (как в примере Persons.Photo = ...).
Спасибо.
cJSON: Формат полей для вложенных структур
Добавлено: 30 Декабрь 2022, 11:13
finsoftrz
Игорь Столяров писал(а): ↑30 Декабрь 2022, 0:43
Дед Пахом писал(а): ↑30 Декабрь 2022, 0:24
А без загрузки содержимого файлов из json в очередь прямо-таки нельзя обойтись?
Вопрос унификации обработки списков с файлами.
Если для каждого вида списка писать ручной распарс JSON с сохранением файлов - то наверно можно.
Но мы делаем класс который трансформирует произвольный пакет JSON в переданный Group (+ несколько Queue).
И далее уже полученная структура разбирается по спискам и файлам в зависимости от её типа ... Что логично.
Сорри, вопрос из зала. А можно озвучить на практическом примере, что такое вид списка, что приходит в json и что сохраняется в файлы. Заодно, что такое файл...
cJSON: Формат полей для вложенных структур
Добавлено: 30 Декабрь 2022, 11:27
Дед Пахом
Игорь Столяров писал(а): ↑30 Декабрь 2022, 7:55
Нельзя. Если тип поля ANY, то его имя в FindCB() вообще не доступно.
Можно. Тут некоторая путаница, признаю.
В случае json::CreateObject() имена полей по умолчанию преобразуются в lowercase, в таком виде они попадают в FindCB.
В случае ToGroup() регистр не играет роли, поэтому имена полей передаются в FindCB как есть, то есть в uppercase (то что возвращает WHO).
Предлагайте решение.
cJSON: Формат полей для вложенных структур
Добавлено: 30 Декабрь 2022, 11:35
Дед Пахом
Игорь Столяров писал(а): ↑30 Декабрь 2022, 9:25
Вопрос. Можно ли добавить для метода AutoCB() параметр pFldRef с ссылкой на текущее поле Group / Queue ?
Для этого служит ApplyCB, или я чего-то не понял.
cJSON: Формат полей для вложенных структур
Добавлено: 30 Декабрь 2022, 11:45
Дед Пахом
Дед Пахом писал(а): ↑30 Декабрь 2022, 11:27
Тут некоторая путаница
Хотя это поведение описано в документации.
cJSON: Формат полей для вложенных структур
Добавлено: 30 Декабрь 2022, 11:55
Игорь Столяров
Дед Пахом писал(а): ↑30 Декабрь 2022, 11:35
Для этого служит ApplyCB, или я чего-то не понял.
Насколько я вижу ApplyCB() отрабатывает в json::CreateArray() и т.д. - т.е. при записи JSON.
А при загрузке из JSON в ToGroup() / ToQueue() этот метод не работает ...
(хотя я конечно мог запутаться где в каком регистре наименование полей указывать)
cJSON: Формат полей для вложенных структур
Добавлено: 30 Декабрь 2022, 11:58
Дед Пахом
Игорь Столяров писал(а): ↑30 Декабрь 2022, 11:55
А при загрузке из JSON в ToGroup() / ToQueue() этот метод не работает ...
Работает, если это поле не "auto".
cJSON: Формат полей для вложенных структур
Добавлено: 30 Декабрь 2022, 11:59
Игорь Столяров
Дед Пахом писал(а): ↑30 Декабрь 2022, 11:58
если это поле не "auto"
Понял. Ситуация пошла по сценарию фильма "33 несчастья".
cJSON: Формат полей для вложенных структур
Добавлено: 30 Декабрь 2022, 12:02
Дед Пахом
Если поле ANY, то fldRef на него бесполезен: присваивание fldRef = 'что-то' на самом деле пишет в поле мусор. Поэтому, собственно, "auto" и нужно.
cJSON: Формат полей для вложенных структур
Добавлено: 30 Декабрь 2022, 12:34
Игорь Столяров
Дед Пахом писал(а): ↑30 Декабрь 2022, 12:02
Если поле ANY, то fldRef на него бесполезен
Т.е. получение данных в поле ANY можно только в конкретную структуру с заранее известным наименованием полей ...
Ну, тогда во всём примере с загрузкой файла из тега JSON в поле ANY нет никакого смысла. Просто потеря времени.
Ладно. Будем пробовать работать через указатели на строки.
cJSON: Формат полей для вложенных структур
Добавлено: 30 Декабрь 2022, 16:11
Игорь Столяров
Дед Пахом писал(а): ↑30 Декабрь 2022, 11:27
Предлагайте решение.
Можно ли как-то реализовать простое действие: получить в поле с типом &String значение тега ?
Т.е. хотелось бы сделать что-то вроде:
Код: Выделить всё
MyJSon cJSONFactory
Root &cJson
MyGroup Group
Field01 &String
end
Code
Root &= MyJSon.ParseFile('File.json')
If Not (Root &= Null)
If Root.ToGroup(MyGroup,,'[{{"name":"Field01","IsStringRef":true,"IsBase64":true}]')
If Not (MyGroup.Field01 &= Null)
Message(MyGroup.Field01)
Dispose(MyGroup.Field01)
end
Root.Delete()
end
end
Несмотря на все присутствующие методы и навороты сделать такое простое действие сейчас нельзя.
В rh.AutoCB() - нет ссылки на текущее поле, а в rh.ApplyCB() нет доступа к классу для получения значения из Root.GetStringRef()
cJSON: Формат полей для вложенных структур
Добавлено: 30 Декабрь 2022, 16:39
Дед Пахом
Как-то противоречиво. Если Вы указали "IsBase64":true, то хотите получить в Field01 base64-декодированное содержимое. С другой стороны, Вы хотите получить закодированное содержимое "из Root.GetStringRef()".
Игорь Столяров писал(а): ↑30 Декабрь 2022, 16:11
rh.ApplyCB() нет доступа к классу для получения значения из Root.GetStringRef()
В ApplyCB есть значение тега (в случае "IsBase64":true декодированное), что мешает сделать NEW STRING(LEN(CLIP(pValue)) и присвоить значение? Если Вы хотите присвоить именно ссылку на строку в теге, то я предвижу, что случится: куча ссылок на одну и ту же область памяти, тут явный DISPOSE, там неявный в деструкторе...
cJSON: Формат полей для вложенных структур
Добавлено: 30 Декабрь 2022, 17:30
Игорь Столяров
Дед Пахом писал(а): ↑30 Декабрь 2022, 16:39
что мешает сделать NEW STRING(LEN(CLIP(pValue)) и присвоить значение
Было бы идеально (собственно я с этого варианта и начал). Но всё вываливается.
Что здесь указатель на текущее обрабатываемое поле группы ? Посмотрите пожалуйста:
Код: Выделить всё
MyGroup Group ! Где-то далеко в тридевятой процедуре, имён полей у нас нет
Photo &String
end
...
rh.ApplyCB PROCEDURE(STRING pFldName, *typCJsonFieldRule pRule, ? pValue)
Code
If pFldName = 'photo'
??? &= NEW STRING(LEN(CLIP(pValue)) ! Как получить поле ? Только по имени pFldName этого сделать нельзя
??? = pValue ! Номера поля - для What() у меня нет.
end
RETURN pValue
Может я чего-то не понимаю ? Именно поэтому я сегодня просил явно передать в методы указатель на текущее поле.