root/bdm/user_info.cpp @ 351

Revision 351, 8.9 kB (checked in by mido, 15 years ago)

par uprav v UI, nikoli finalni verze, presto je zahodno ji ulozit jako zalohu - uz behaji vsechny podstatne funkce vcetne nacitani Array<T>

  • Property svn:eol-style set to native
Line 
1//
2// C++ Implementation: itpp_ext
3//
4// Description:
5//
6//
7// Author: smidl <smidl@utia.cas.cz>, (C) 2008
8//
9// Copyright: See COPYING file that comes with this distribution
10//
11//
12
13#include "user_info.h"
14
15namespace bdm {
16
17
18///////////////////////// UI FILE /////////////////////////////////////////////
19
20
21UI_File::UI_File ( const string &file_name ) : file_name( file_name )
22{
23        setAutoConvert( true );
24}
25
26//! loads root element from a file
27void UI_File::load() 
28{
29        try
30        {
31                readFile( file_name.c_str()  );
32        }
33        catch ( FileIOException f ) 
34        {
35                it_error ( "UI error: file " + file_name + " not found." );
36        }
37        catch ( ParseException& P ) 
38        {
39                stringstream msg;
40                msg << "UI error: parsing ui_error """ << P.getError() << """ in file " << file_name << " on line " <<  P.getLine() << ".";
41                it_error ( msg.str() );
42        }       
43}
44
45
46//! save UserInfo to the file (typically with an XML extension)
47void UI_File::save()
48{
49        try
50        {
51                writeFile ( file_name.c_str()  );
52        }
53        catch ( FileIOException f ) 
54        {
55                it_error( "UI error: file " + file_name + " is inacessible." );
56        }               
57}       
58
59UI_File::operator Setting&()
60{
61        return getRoot();
62}
63///////////////////////// INTERNAL MAPPED_UI /////////////////////////////////////////////
64
65UI::Mapped_UI::String_To_UI_Map& UI::Mapped_UI::mapped_strings()
66{
67        static String_To_UI_Map var;
68        return var;
69}
70
71UI::Mapped_UI::Type_Info_To_String_Map& UI::Mapped_UI::mapped_type_infos()
72{
73        static Type_Info_To_String_Map var;
74        return var;
75}
76
77void UI::Mapped_UI::add_class( const string &class_name, const type_info * const class_type_info, const UI* const ui )
78{
79        pair< const string, const UI* const > new_pair = make_pair( class_name, ui );
80        mapped_strings().insert( new_pair );
81        mapped_type_infos().insert( make_pair( class_type_info, new_pair.first ) );
82}
83
84const UI& UI::Mapped_UI::retrieve_ui( const string &class_name )
85{
86        String_To_UI_Map::const_iterator iter = mapped_strings().find( class_name );
87        if( iter == mapped_strings().end()) 
88                it_error ( "UI error: class " + class_name + " was not properly registered. Use the macro ""UIREGISTER([class name]);"" within your code." );
89        return *iter->second;
90}       
91
92const string& UI::Mapped_UI::retrieve_class_name( const type_info * const class_type_info )
93{
94        Type_Info_To_String_Map::const_iterator iter = mapped_type_infos().find( class_type_info );
95        if( iter == mapped_type_infos().end()) 
96                it_error ( "UI error: class with RTTI name " + string(class_type_info->name()) + " was not properly registered. Use the macro ""UIREGISTER([class name]);"" within your code." );
97        return iter->second;
98}       
99
100///////////////////////// INTERNAL LINK EXPANDER /////////////////////////////////////////////
101
102UI::Link_Expander::Link_Expander( const Setting &potential_link )
103{
104        file = NULL;
105        result = &potential_link;
106
107        if( potential_link.getType() !=  Setting::TypeString )
108                return;
109
110        string link = (string) potential_link;
111        size_t aerobase = link.find('@');
112        if( aerobase != string::npos )
113        {
114                string file_name = link.substr( aerobase + 1, link.length() );
115                file = new UI_File( file_name );
116                file->load();
117                result = &(Setting&)(*file);
118                link = link.substr( 0, aerobase );
119        }
120        else
121                while ( !result->isRoot() ) 
122                        result = &result->getParent();
123
124        if( !result->exists( link ) )
125                ui_error( "linked Setting was not found", potential_link );
126
127        result = &(*result)[link];
128}
129
130UI::Link_Expander::~Link_Expander()
131{
132        if( file ) delete file;
133}
134
135const Setting& UI::Link_Expander::root() const
136{
137        return *result;
138}
139
140///////////////////////// UI /////////////////////////////////////////////
141
142
143
144//! This methods   - kvuli ukladani pole stringu, dat jen privatne?
145void UI::save( const string &str, Setting &element )
146{
147        Setting &root = element.add( Setting::TypeString );
148        root = str;
149}
150
151void UI::save( const mat &matrix, Setting &element, const string &name)
152{
153       
154        Setting &root = (name == "") ? element.add( Setting::TypeList )                                                 
155                                                                 : element.add( name, Setting::TypeList );             
156
157        Setting &cols = root.add( Setting::TypeInt );
158        cols = matrix.cols();
159
160        Setting &rows = root.add( Setting::TypeInt );
161        rows = matrix.rows();
162
163        Setting &elements = root.add( Setting::TypeArray );
164
165        // build matrix row-wise
166        for( int i=0; i<matrix.rows(); i++ ) 
167                for( int j=0; j<matrix.cols(); j++)
168                {
169                        Setting &new_field = elements.add(Setting::TypeFloat);
170                        new_field = matrix(i,j);
171                }
172}
173
174
175        //! This methods tries to save a double vec
176void UI::save( const ivec &vec, Setting &element, const string &name)
177{
178       
179        Setting &root = (name == "") ? element.add( Setting::TypeArray )                                                       
180                                                                 : element.add( name, Setting::TypeArray );             
181        for( int i=0; i<vec.length(); i++ ) 
182        {
183                Setting &new_field = root.add(Setting::TypeInt);
184                new_field = vec(i);
185        }
186}
187
188
189//! This methods tries to build a new double matrix
190
191void UI::from_setting( mat& matrix, const Setting &element )
192{
193        const Link_Expander link_expander( element );
194        const Setting &root = link_expander.root();
195
196        if( root.isNumber() )
197        {
198                matrix.set_size( 1, 1 );
199                matrix(0,0) = root;
200                return;
201        }
202
203        if( root.isList() )
204        {
205                if( root.getLength() != 3 )
206                        ui_error( "the setting supposed to represent a matrix element has wrong syntax", root );
207
208                Setting &cols_setting = root[0];
209                Setting &rows_setting = root[1];
210                Setting &elements = root[2];
211
212                ASSERT_UITYPE(cols_setting,TypeInt);
213                ASSERT_UITYPE(rows_setting,TypeInt);
214                ASSERT_UITYPE(elements,TypeArray);
215
216                int cols = cols_setting;
217                int rows = rows_setting;
218                                       
219                if( cols < 0 | rows < 0 )
220                        ui_error( "the dimensions of a matrix has to be non-negative", root );
221
222                if( elements.getLength() != cols * rows )
223                        ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements );
224
225                matrix.set_size( rows, cols );
226
227                if( cols == 0 || rows == 0 )
228                        return;
229
230                if( !elements[0].isNumber() )
231                        ui_error( "matrix elements have to be numbers", elements[0] );
232
233                // build matrix row-wise
234                int k = 0;
235                for( int i=0;i<rows;i++ ) 
236                        for( int j=0; j<cols; j++)
237                                matrix(i,j) = elements[k++];
238                return;
239        }
240
241        ui_error( "only numeric types or TypeList are supported as matrix values", root );
242}
243
244//! This methods tries to build a new integer vector
245void UI::from_setting( ivec &vec, const Setting &element )
246{
247        const Link_Expander link_expander( element );
248        const Setting &root = link_expander.root();
249
250        if( root.isNumber() )
251        {
252                ASSERT_UITYPE(root,TypeInt);
253                vec.set_length( 1 );
254                vec(0) = root;
255                return;
256        }
257
258        if( root.isList() )
259        {
260                if( root.getLength() != 3 )
261                        ui_error( "the setting supposed to represent a matrix element has wrong syntax", root );
262
263                Setting &cols_setting = root[0];
264                Setting &rows_setting = root[1];
265                Setting &elements = root[2];
266
267                ASSERT_UITYPE(cols_setting,TypeInt);
268                ASSERT_UITYPE(rows_setting,TypeInt);
269                ASSERT_UITYPE(elements,TypeArray);
270
271                int cols = cols_setting;
272                int rows = rows_setting;
273               
274                if( cols < 0 | rows < 0)
275                        ui_error( "the dimensions of a matrix has to be non-negative", root );
276
277                if( elements.getLength() != cols * rows )
278                        ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements );
279
280                if( cols != 1 & rows !=1)
281                        ui_error( "the vector length is invalid, it seems to be rather a matrix", elements );
282               
283                int len = rows * cols;
284                vec.set_length ( len );
285                if( len == 0 ) return;
286
287                ASSERT_UITYPE(elements[0],TypeInt);
288                for( int i=0; i<len; i++ ) 
289                        vec(i) = elements[i];
290                return;
291        }
292
293        if( root.isArray() )
294        {       
295                int len = root.getLength();
296                vec.set_length( len );
297                if( len == 0 ) return;
298
299                ASSERT_UITYPE(root[0],TypeInt);
300                for( int i=0; i < len; i++ ) 
301                        vec(i) = root[i];
302                return;
303        }
304
305        ui_error( "only numeric types, TypeArray or TypeList are supported as vector values", root );
306}
307
308
309void UI::from_setting( string &str, const Setting &element )
310{
311        ASSERT_UITYPE(element,TypeString);
312        str = (string) element;
313}
314
315
316///////////////////////// UI FILE /////////////////////////////////////////////
317        //! This methods tries to save an instance of type T (or some of its descendant types)
318        //! and build DOM tree accordingly. Then, it creates a new DOMNode named according class_name
319        //! and connecti it to the passed Setting as a new child node.
320const Setting* UI::pointer_to_child_setting( const Setting &element, const int index )
321{
322        if( !element.isList())
323                return NULL;
324
325        if( element.getLength() <= index )
326                return NULL;
327
328        return &element[index];
329}
330
331const Setting* UI::pointer_to_child_setting( const Setting &element, const string &name )
332{
333        if( !element.isGroup() )
334                return NULL;
335
336        if( !element.exists( name ) )
337                return NULL;
338
339        return &element[name];
340}
341
342const Setting& UI::reference_to_child_setting( const Setting &element, const int index )
343{
344        if( !element.isList())
345                ui_error( "only TypeList elements could be indexed by integers", element );
346
347        if( element.getLength() <= index )
348                ui_error( "there is not any child with index " + index, element );
349
350        return element[index];
351}
352
353const Setting& UI::reference_to_child_setting( const Setting &element, const string &name )
354{
355        ASSERT_UITYPE(element,TypeGroup);
356        if( !element.exists( name ) )
357                ui_error( "there is not any child named """ + name, element );
358        return element[name];
359}
360
361
362}
Note: See TracBrowser for help on using the browser.