4747/*
4848 * <params>
4949 * <path>...</path>
50+ * <fields>
51+ * <field>...</field>
52+ * </fields>
5053 * </params>
5154 */
5255
5356/** XML nodes */
5457enum params_xml_nodes {
55- GEO_PATH = 1 ,
58+ GEO_PATH = 1 ,
59+ GEO_FIELDS = 2 ,
60+ GEO_FIELD = 3 ,
5661};
5762
63+ static const struct fds_xml_args fields_schema [] = {
64+ FDS_OPTS_ELEM (GEO_FIELD , "field" , FDS_OPTS_T_STRING , FDS_OPTS_P_MULTI ),
65+ FDS_OPTS_END
66+ };
67+
68+
5869/** Definition of the \<params\> node */
5970static const struct fds_xml_args args_params [] = {
6071 FDS_OPTS_ROOT ("params" ),
61- FDS_OPTS_ELEM (GEO_PATH , "path" , FDS_OPTS_T_STRING , 0 ),
72+ FDS_OPTS_ELEM (GEO_PATH , "path" , FDS_OPTS_T_STRING , 0 ),
73+ FDS_OPTS_NESTED (GEO_FIELDS , "fields" , fields_schema , FDS_OPTS_P_OPT ),
6274 FDS_OPTS_END
6375};
6476
77+ static int
78+ config_parser_fields (ipx_ctx_t * ctx , fds_xml_ctx_t * fields_ctx , struct geo_config * cfg )
79+ {
80+ size_t field_len ;
81+
82+ const struct fds_xml_cont * fields ;
83+ while (fds_xml_next (fields_ctx , & fields ) != FDS_EOC ) {
84+ assert (fields -> type == FDS_OPTS_T_STRING );
85+ field_len = strlen (fields -> ptr_string );
86+
87+ if (!strncasecmp (fields -> ptr_string , "continent" , field_len )) {
88+ cfg -> fields [GPARAM_CONT_CODE ] = 1 ;
89+ } else if (!strncasecmp (fields -> ptr_string , "country" , field_len )) {
90+ cfg -> fields [GPARAM_COUNTRY_CODE ] = 1 ;
91+ } else if (!strncasecmp (fields -> ptr_string , "city" , field_len )) {
92+ cfg -> fields [GPARAM_CITY_NAME ] = 1 ;
93+ } else if (!strncasecmp (fields -> ptr_string , "latitude" , field_len )) {
94+ cfg -> fields [GPARAM_LATITUDE ] = 1 ;
95+ } else if (!strncasecmp (fields -> ptr_string , "longitude" , field_len )) {
96+ cfg -> fields [GPARAM_LONGITUDE ] = 1 ;
97+ } else {
98+ IPX_CTX_ERROR (ctx , "Unknown field '%s'" , fields -> ptr_string );
99+ return IPX_ERR_FORMAT ;
100+ }
101+ }
102+
103+ return IPX_OK ;
104+ }
105+
65106/**
66107 * \brief Process \<params\> node
67108 * \param[in] ctx Plugin context
@@ -73,25 +114,41 @@ static const struct fds_xml_args args_params[] = {
73114static int
74115config_parser_root (ipx_ctx_t * ctx , fds_xml_ctx_t * root , struct geo_config * cfg )
75116{
76- (void ) ctx ;
77117 size_t path_len ;
118+ bool fields_found = false;
78119
79120 const struct fds_xml_cont * content ;
80121 while (fds_xml_next (root , & content ) != FDS_EOC ) {
81122 switch (content -> id ) {
82- case GEO_PATH :
83- assert (content -> type == FDS_OPTS_T_STRING );
84- path_len = strlen (content -> ptr_string );
85- cfg -> db_path = strndup (content -> ptr_string , path_len );
86- if (!cfg -> db_path ) {
87- IPX_CTX_ERROR (ctx , "Memory allocation error (%s:%d)" , __FILE__ , __LINE__ );
88- return IPX_ERR_FORMAT ;
89- }
90- break ;
91- default :
92- // Internal error
93- assert (false);
123+ case GEO_PATH :
124+ assert (content -> type == FDS_OPTS_T_STRING );
125+ path_len = strlen (content -> ptr_string );
126+ cfg -> db_path = strndup (content -> ptr_string , path_len );
127+ if (!cfg -> db_path ) {
128+ IPX_CTX_ERROR (ctx , "Memory allocation error (%s:%d)" , __FILE__ , __LINE__ );
129+ return IPX_ERR_FORMAT ;
130+ }
131+ break ;
132+
133+ case GEO_FIELDS :
134+ fields_found = true;
135+ assert (content -> type == FDS_OPTS_T_CONTEXT );
136+ if (config_parser_fields (ctx , content -> ptr_ctx , cfg ) != IPX_OK ) {
137+ return IPX_ERR_FORMAT ;
138+ }
139+ break ;
140+
141+ default :
142+ // Internal error
143+ assert (false);
94144 }
145+
146+ }
147+
148+ // No fields found, use default configuration
149+ if (fields_found == false) {
150+ cfg -> fields [GPARAM_COUNTRY_CODE ] = 1 ;
151+ cfg -> fields [GPARAM_CITY_NAME ] = 1 ;
95152 }
96153
97154 return IPX_OK ;
0 commit comments