Line data Source code
1 :
2 : #include "object_match.hpp"
3 : #include "builder.hpp"
4 :
5 : namespace wfc{ namespace jsonrpc{
6 :
7 66 : object_match::object_match( const std::shared_ptr<ibuilder>& builder )
8 66 : : _builder(builder)
9 : {
10 66 : }
11 :
12 66 : bool object_match::configure(const char* beg, const char* end, json::json_error& err)
13 : {
14 : typedef std::pair<const char*, const char*> field_pair_t;
15 : typedef std::pair<field_pair_t, field_pair_t> member_pair_t;
16 : typedef std::vector< member_pair_t > member_list_t;
17 : typedef json::iterator_pair<field_pair_t> field_json;
18 : typedef json::dict< std::vector< json::field< field_json, field_json > >, 10 > object_json;
19 :
20 66 : member_list_t member_list;
21 66 : object_json::serializer()(member_list, beg, end, &err);
22 66 : if (err)
23 0 : return false;
24 :
25 66 : _matchers.clear();
26 178 : for (auto p : member_list)
27 : {
28 112 : const char* beg_name = p.first.first;
29 112 : const char* beg_value = p.second.first;
30 :
31 112 : auto name = _builder->build_name();
32 112 : if ( name==nullptr || err) return false;
33 :
34 112 : if ( !name->configure(beg_name, end, err) )
35 0 : return false;
36 :
37 224 : auto val = _builder->build_value(beg_value, end, err);
38 112 : if ( val==nullptr || err) return false;
39 112 : if ( !val->configure(beg_value, end, err) )
40 0 : return false;
41 :
42 112 : _matchers.push_back( std::make_pair(name, val) );
43 112 : }
44 66 : return true;
45 : }
46 :
47 66 : bool object_match::match(const char* beg, const char* end, json::json_error& err)
48 : {
49 : typedef std::pair<const char*, const char*> field_pair_t;
50 : typedef std::pair<field_pair_t, field_pair_t> member_pair_t;
51 : typedef std::vector< member_pair_t > member_list_t;
52 : typedef json::iterator_pair<field_pair_t> field_json;
53 : typedef json::dict< std::vector< json::field< field_json, field_json > >, 10 > object_json;
54 :
55 66 : if ( _matchers.empty() )
56 0 : return true;
57 :
58 66 : if (!json::parser::is_object(beg,end))
59 0 : return false;
60 :
61 66 : member_list_t member_list;
62 66 : object_json::serializer()(member_list, beg, end, &err);
63 66 : if (err)
64 0 : return false;
65 :
66 : // Нужно совпадение всех
67 138 : for (auto m : _matchers)
68 : {
69 102 : bool matched = false;
70 : // Проверяем все поля входящего объекта
71 172 : for ( auto j : member_list )
72 : {
73 142 : const char* jname = j.first.first;
74 142 : const char* jvalue = j.second.first;
75 :
76 142 : if ( !m.first->match(jname, end, err) )
77 : {
78 44 : if (err) return false;
79 44 : continue;
80 : }
81 :
82 98 : if ( !m.second->match(jvalue, end, err) )
83 : {
84 26 : if (err) return false;
85 26 : continue;
86 : }
87 72 : matched = true;
88 72 : break;
89 : }
90 :
91 102 : if ( !matched )
92 : {
93 : // Нет ни одного совпадения во входящем объекте
94 30 : return false;
95 : }
96 72 : }
97 : // Найдено
98 36 : return true;
99 : }
100 :
101 :
102 : }}
|