]> git.mxchange.org Git - flightgear.git/blob - src/Network/props.cxx
1a42c8d62f536f03c7ea64b815c92222efa53f20
[flightgear.git] / src / Network / props.cxx
1 // props.hxx -- FGFS property manager interaction class
2 //
3 // Written by Curtis Olson, started September 2000.
4 //
5 // Copyright (C) 2000  Curtis L. Olson - curt@flightgear.org
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // $Id$
22
23
24 #include <Main/globals.hxx>
25
26 #include <simgear/compiler.h>
27 #include <simgear/debug/logstream.hxx>
28 #include <simgear/io/iochannel.hxx>
29 #include <simgear/math/sg_types.hxx>
30 #include <simgear/misc/props.hxx>
31
32 #include <stdlib.h>             // atoi() atof()
33
34 #include <strstream>
35
36 #include "props.hxx"
37
38 SG_USING_STD(cout);
39 SG_USING_STD(istrstream);
40
41 FGProps::FGProps() {
42 }
43
44 FGProps::~FGProps() {
45 }
46
47
48 // open hailing frequencies
49 bool FGProps::open() {
50     path = "/";
51
52     if ( is_enabled() ) {
53         FG_LOG( FG_IO, FG_ALERT, "This shouldn't happen, but the channel " 
54                 << "is already in use, ignoring" );
55         return false;
56     }
57
58     SGIOChannel *io = get_io_channel();
59
60     if ( ! io->open( get_direction() ) ) {
61         FG_LOG( FG_IO, FG_ALERT, "Error opening channel communication layer." );
62         return false;
63     }
64
65     set_enabled( true );
66     FG_LOG( FG_IO, FG_INFO, "Opening properties channel communication layer." );
67
68     return true;
69 }
70
71
72 // return a human readable form of the value "type"
73 static string getValueTypeString( const SGValue *v ) {
74     string result;
75
76     if ( v == NULL ) {
77         return "unknown";
78     }
79
80     SGValue::Type type = v->getType();
81     if ( type == SGValue::UNKNOWN ) {
82         result = "unknown";
83     } else if ( type == SGValue::BOOL ) {
84         result = "bool";
85     } else if ( type == SGValue::INT ) {
86         result = "int";
87     } else if ( type == SGValue::FLOAT ) {
88         result = "float";
89     } else if ( type == SGValue::DOUBLE ) {
90         result = "double";
91     } else if ( type == SGValue::STRING ) {
92         result = "string";
93     }
94
95     return result;
96 }
97
98
99 bool FGProps::process_command( const char *cmd ) {
100     SGIOChannel *io = get_io_channel();
101
102     cout << "processing command = " << cmd;
103     string_list tokens;
104     tokens.clear();
105
106     istrstream in(cmd);
107     
108     while ( !in.eof() ) {
109         string token;
110         in >> token;
111         tokens.push_back( token );
112     }
113
114     string command = tokens[0];
115
116     SGPropertyNode * node = globals->get_props()->getNode(path);
117
118     if ( command == "ls" ) {
119         for (int i = 0; i < (int)node->nChildren(); i++) {
120             SGPropertyNode * child = node->getChild(i);
121             string name = child->getName();
122             string line = name;
123             if ( child->nChildren() > 0 ) {
124                 line += "/\n";
125             } else {
126                 string value = node->getStringValue ( name, "" );
127                 line += " =\t'" + value + "'\t(";
128                 line += getValueTypeString( node->getValue( name ) );
129                 line += ")\n";
130             }
131             io->writestring( line.c_str() );
132         }
133     } else if ( command == "dump" ) {
134         strstream buf;
135         if ( tokens.size() <= 1 ) {
136             writeProperties ( buf, node);
137             io->writestring( buf.str() );
138         }
139         else {
140             SGPropertyNode *child = node->getNode(tokens[1]);
141             if ( child ) {
142                 writeProperties ( buf, child );
143                 io->writestring( buf.str() );
144             } else {
145                 tokens[1] += " Not Found\n";
146                 io->writestring( tokens[1].c_str() );
147             }
148         }
149     } else if ( command == "cd" ) {
150         // string tmp = "current path = " + node.getPath() + "\n";
151         // io->writestring( tmp.c_str() );
152
153         if ( tokens.size() <= 1 ) {
154             // do nothing
155         } else {
156             SGPropertyNode *child = node->getNode(tokens[1]);
157             if ( child ) {
158                 node = child;
159                 path = node->getPath();
160             } else {
161                 tokens[1] += " Not Found\n";
162                 io->writestring( tokens[1].c_str() );
163             }
164         }
165     } else if ( command == "pwd" ) {
166         string ttt = node->getPath();
167         if ( ttt == "" ) {
168             ttt = "/";
169         }
170         ttt += "\n";
171         io->writestring( ttt.c_str() );
172     } else if ( command == "get" || command == "show" ) {
173         if ( tokens.size() <= 1 ) {
174             // do nothing
175         } else {
176             string ttt = "debug = '" + tokens[1] + "'\n";
177             io->writestring( ttt.c_str() );
178
179             string value = node->getStringValue ( tokens[1], "" );
180             string tmp = tokens[1] + " = '" + value + "' (";
181             tmp += getValueTypeString( node->getValue( tokens[1] ) );
182             tmp += ")\n";
183  
184             io->writestring( tmp.c_str() );
185         }
186     } else if ( command == "set" ) {
187         if ( tokens.size() <= 2 ) {
188             // do nothing
189         } else {
190             node->getValue( tokens[1], true )->setStringValue(tokens[2]);
191
192             // now fetch and write out the new value as confirmation
193             // of the change
194             string value = node->getStringValue ( tokens[1], "" );
195             string tmp = tokens[1] + " = '" + value + "' (";
196             tmp += getValueTypeString( node->getValue( tokens[1] ) );
197             tmp += ")\n";
198  
199             io->writestring( tmp.c_str() );
200         }
201     } else if ( command == "quit" ) {
202         close();
203     } else {
204         io->writestring( "\n" );
205         io->writestring( "Valid commands are:\n" );
206         io->writestring( "\n" );
207         io->writestring( "help             show help message\n" );
208         io->writestring( "ls               list current directory\n" );
209         io->writestring( "dump             dump current state (in xml)\n" );
210         io->writestring( "cd <dir>         cd to a directory, '..' to move back\n" );
211         io->writestring( "pwd              display your current path\n" );
212         io->writestring( "get <var>        show the value of a parameter\n" );
213         io->writestring( "show <var>       synonym for get\n" );
214         io->writestring( "set <var> <val>  set <var> to a new <val>\n" );
215         io->writestring( "quit             terminate connection\n" );
216         io->writestring( "\n" );
217     }
218
219     string prompt = node->getPath();
220     if ( prompt == "" ) {
221         prompt = "/";
222     }
223     prompt += "> ";
224     io->writestring( prompt.c_str() );
225
226     return true;
227 }
228
229
230 // process work for this port
231 bool FGProps::process() {
232     SGIOChannel *io = get_io_channel();
233
234     // cout << "processing incoming props command" << endl;
235
236     if ( get_direction() == SG_IO_BI ) {
237         // cout << "  (bi directional)" << endl;
238         while ( io->readline( buf, max_cmd_len ) > 0 ) {
239             FG_LOG( FG_IO, FG_ALERT, "Success reading data." );
240             process_command( buf );
241         }
242     } else {
243         FG_LOG( FG_IO, FG_ALERT, 
244                 "in or out direction not supported for FGProps." );
245     }
246
247     return true;
248 }
249
250
251 // close the channel
252 bool FGProps::close() {
253     SGIOChannel *io = get_io_channel();
254
255     set_enabled( false );
256
257     if ( ! io->close() ) {
258         return false;
259     }
260
261     cout << "successfully closed channel\n";
262
263     return true;
264 }