Форум программистов, компьютерный форум CyberForum.ru

SAX json парсер - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Временное блокирование работы WinAPI на win XP http://www.cyberforum.ru/cpp/thread917400.html
Есть программы, которые используют WinAPI, а именно получение некоторой информации о железе и работа с системным звуковым микшером (баланс, громкость). Проверялось все пока под win XP. И выяснилась странная вещь, проявляющаяся видимо преимущественно на материнках Gigabyte. Периодически выполнение данных вызовов чем то блокируется на какое то время, причем программе сообщается что все впорядке,...
C++ Автоматическое преобразование китайского кода в нормальный У меня есть огромный шмат кода примерно такого вида: if (x < 10 && y > 0 && z != 0) return 1; if (x < 10 && (y > 0 || z < 100)) return 2; if (x > 9 && y == 0) return 3; return 4; где x, y, z - целые неотрицательные числа. Очевидно, что запись можно оптимизировать. Например: if (x < 10) { http://www.cyberforum.ru/cpp/thread915063.html
C++ Передача типа указателя на функцию
Всем привет. Недавно в теме начинающих возник вопрос, а можно ли передать тип (указатель на функцию) без использования typedef: typedef void (*func)(void); func f = va_arg(vl,func); Конкретно речь идет о втором аргументе макроса va_arg (из <cstdarg>). Первое, что пришло на ум, это использование decltype. Но всё же эта фишка C++11. А есть ли решение в старом стиле? Заранее спасибо.
C++ Компиляция exe
Как скомпилировать .exe чтобы он работал на других машинах, писал с использованием OpenGL от этого проблемы при работе с другими машинами подскажите пожалуйста:wall:
C++ екзешный файл. нужно исправить и перепаковать http://www.cyberforum.ru/cpp/thread911678.html
описываю проблему. есть exe файл (тест для проверки знаний), слышал что с ним можно что-то сделать чтобы были отмечены правильные ответы, или правильный ответ был всегда на первом месте. вопрос стоИт в том сколько это будет стоить в денежном экриваленте? и сколько по времени ето займет? сам exe весит 4мб.
C++ RAD Studio XE3 C++ Здравствуйте! Можете, пожалуйста, подкинуть уроки, сайты для изучения этой среды программирования? подробнее

Показать сообщение отдельно
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3

SAX json парсер - C++

05.07.2013, 22:46. Просмотров 4644. Ответов 6
Метки (Все метки)

Вечер добрый.
Есть задача реализовать SAX-парсер JSON-a (парсинг не во временные переменные, а сразу в текущие, на которые указатели/ссылки сохранены в некий контекст в классе). Задача парсить не просто примитивные типы и контейнеры, но и сложные/составные типы.

Нечто вроде такого

C++
1
2
3
4
5
6
struct A
{
   int a;
   std::vector<int> b;
   std::string c;
};
Должно переводиться в json и обратно
C++
1
2
3
4
5
const std::string json = "{\"A\":{\"a\":1,\"b\":{1,2},\"c\":\"string\"}}";
A a;
statement stmt;
stmt.use(a);
stmt.deserialize(json);
Я сделал данный кейс через fusion (сделано по аналогу SOCI, но там нет парсинга СРАЗУ в сложные типы). Капитально приходится испытывать сложности с составными объектами, я выбрал вариант, когда просто биндятся simple/container/conversion типы, который находятся в структуре (страдает время компиляции, для каждого объекта приходится создавать новый statement, причем динамически, ибо хранятся указатели (это проще, постольку поскольку, конструктор копирования реализовывать несколько сложнее), уходит довольно много памяти (допустим для примера из сериализации/десериализации двух структур + массива интов + boost::gregorian::date уходит примерно 271к байт, терпимо, но не слишком круто)).
Пример:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct other
{
   std::string name;
   unsigned int age;
   bool flag;
   double number;
 
   struct name_key { static const char* name() { return "name"; }};
   struct age_key { static const char* name() { return "age"; }};
   struct flag_key { static const char* name() { return "flag"; }};
   struct number_key { static const char* name() { return "number"; }};
};
 
BOOST_FUSION_ADAPT_ASSOC_STRUCT(
      other,
      (std::string, name, other::name_key)
      (unsigned int, age, other::age_key)
      (bool, flag, other::flag_key)
      (double, number, other::number_key)
);
структура становится fusion_sequence и через код вроде этого ее можно обойти

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
template<typename Next, typename Last>
struct traverse_types
{
   template<typename Object>
   static void traverse_helper(statement& stmt, Object& object, const std::string& name)
   {
      typedef typename get_exchange_type<Object>::type type;
      stmt.add_field(name, new type(object, name));
   }
   template<typename Object>
   static void apply(statement& stmt, Object& object)
   {
      typedef typename boost::fusion::result_of::key_of<Next>::type key_t;
      typedef typename boost::fusion::result_of::next<Next>::type next_t;
      typedef typename boost::fusion::result_of::at_key<Object, key_t>::type value_ref_t;
      typedef typename boost::remove_reference<value_ref_t>::type value_t;
      traverse_helper(stmt, boost::fusion::at_key<key_t>(object), key_t::name());
      traverse_types<next_t, Last>::apply(stmt, object);
   }
};
 
template<typename Last>
struct traverse_types<Last, Last>
{
   template<typename Object>
   static void apply(statement&, Object&)
   {
   }
};
// в конкретном классе use/into
 static void traverse(statement& stmt, T& object)
 {
    traverse_types<typename boost::fusion::result_of::begin<T>::type,
      typename boost::fusion::result_of::end<T>::type>::
      apply(stmt, object);
};
Где get_exchange_type некий шаблон, который просто typedef-ит нужный into/use тип.

C++
1
2
3
4
5
6
7
8
9
template<typename T>
struct get_exchange_type
{
   typedef typename exchange_traits<T>::type_tag tag;
   typedef typename boost::mpl::if_<typename boost::is_same<tag, basic_tag>::type, into_type<T>,
           typename boost::mpl::if_<typename boost::is_same<tag, container_tag>::type, container_into_type<T>,
           typename boost::mpl::if_<typename boost::is_same<tag, conversion_tag>::type, conversion_into_type<T>,
           user_into_type<T>>::type>::type>::type type;
};
C++
1
2
3
4
5
6
7
8
9
template<typename T>
struct get_exchange_type<const T>
{
   typedef typename exchange_traits<T>::type_tag tag;
   typedef typename boost::mpl::if_<typename boost::is_same<tag, basic_tag>::type, use_type<T>,
           typename boost::mpl::if_<typename boost::is_same<tag, container_tag>::type, container_use_type<T>,
           typename boost::mpl::if_<typename boost::is_same<tag, conversion_tag>::type, conversion_use_type<T>,
           user_use_type<T>>::type>::type>::type type;
};
Перегрузка для statement/writer реализована на тегах
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
template<typename T>
struct type_conversion;
 
struct basic_tag {};
struct user_tag {};
struct container_tag {};
struct conversion_tag {};
 
template<typename T>
struct has_type_conversion
{
   typedef char no;
   typedef char yes[2];
 
   template<typename U>
   static yes& test(typename type_conversion<U>::base_type*);
   template<typename>
   static no& test(...);
 
   static const bool value = sizeof(test<T>(0)) == sizeof(yes);
   typedef boost::mpl::bool_<value> type;
};
 
template<typename T>
struct exchange_traits
{
   typedef typename has_type_conversion<T>::type conversion;
   typedef typename boost::mpl::if_<conversion, conversion_tag, user_tag>::type type_tag;
   template<typename U, typename = void>
   struct get_type
   {
      enum { x_type = x_object };
   };
   template<typename U>
   struct get_type<U, typename boost::enable_if<typename has_type_conversion<U>::type>::type>
   {
      enum { x_type = exchange_traits<typename type_conversion<U>::base_type>::x_type };
   };
   enum
   {
      x_type = get_type<T>::x_type
   };
};
Дальше идут специализации для basic типов / контейнеров.

Есть возможность сделать интроспекцию/отражение в С++ проще, чем сделано на данный момент? Если данный вопрос нужно перенести в С++ для экспертов/boost - скажите, перенесу. Спасибо.
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru