root/bdm/user_info.cpp @ 364

Revision 364, 12.0 kB (checked in by smidl, 15 years ago)

compile fixes

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