]> git.mxchange.org Git - flightgear.git/blob - src/Network/props.cxx
f249f23b8524a8e49e81c91ef08b8a34fcdeba59
[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 FG_USING_STD(cout);
39 FG_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                 path = child->getPath();
159             } else {
160                 tokens[1] += " Not Found\n";
161                 io->writestring( tokens[1].c_str() );
162             }
163         }
164     } else if ( command == "pwd" ) {
165         string ttt = node->getPath();
166         if ( ttt == "" ) {
167             ttt = "/";
168         }
169         ttt += "\n";
170         io->writestring( ttt.c_str() );
171     } else if ( command == "get" || command == "show" ) {
172         if ( tokens.size() <= 1 ) {
173             // do nothing
174         } else {
175             string ttt = "debug = '" + tokens[1] + "'\n";
176             io->writestring( ttt.c_str() );
177
178             string value = node->getStringValue ( tokens[1], "" );
179             string tmp = tokens[1] + " = '" + value + "' (";
180             tmp += getValueTypeString( node->getValue( tokens[1] ) );
181             tmp += ")\n";
182  
183             io->writestring( tmp.c_str() );
184         }
185     } else if ( command == "set" ) {
186         if ( tokens.size() <= 2 ) {
187             // do nothing
188         } else {
189             node->getValue( tokens[1], true )->setStringValue(tokens[2]);
190
191             // now fetch and write out the new value as confirmation
192             // of the change
193             string value = node->getStringValue ( tokens[1], "" );
194             string tmp = tokens[1] + " = '" + value + "' (";
195             tmp += getValueTypeString( node->getValue( tokens[1] ) );
196             tmp += ")\n";
197  
198             io->writestring( tmp.c_str() );
199         }
200     } else if ( command == "quit" ) {
201         close();
202     } else {
203         io->writestring( "\n" );
204         io->writestring( "Valid commands are:\n" );
205         io->writestring( "\n" );
206         io->writestring( "help             show help message\n" );
207         io->writestring( "ls               list current directory\n" );
208         io->writestring( "dump             dump current state (in xml)\n" );
209         io->writestring( "cd <dir>         cd to a directory, '..' to move back\n" );
210         io->writestring( "pwd              display your current path\n" );
211         io->writestring( "get <var>        show the value of a parameter\n" );
212         io->writestring( "show <var>       synonym for get\n" );
213         io->writestring( "set <var> <val>  set <var> to a new <val>\n" );
214         io->writestring( "quit             terminate connection\n" );
215         io->writestring( "\n" );
216     }
217
218     string prompt = node->getPath();
219     if ( prompt == "" ) {
220         prompt = "/";
221     }
222     prompt += "> ";
223     io->writestring( prompt.c_str() );
224
225     return true;
226 }
227
228
229 // process work for this port
230 bool FGProps::process() {
231     SGIOChannel *io = get_io_channel();
232
233     // cout << "processing incoming props command" << endl;
234
235     if ( get_direction() == SG_IO_BI ) {
236         // cout << "  (bi directional)" << endl;
237         while ( io->readline( buf, max_cmd_len ) > 0 ) {
238             FG_LOG( FG_IO, FG_ALERT, "Success reading data." );
239             process_command( buf );
240         }
241     } else {
242         FG_LOG( FG_IO, FG_ALERT, 
243                 "in or out direction not supported for FGProps." );
244     }
245
246     return true;
247 }
248
249
250 // close the channel
251 bool FGProps::close() {
252     SGIOChannel *io = get_io_channel();
253
254     set_enabled( false );
255
256     if ( ! io->close() ) {
257         return false;
258     }
259
260     cout << "successfully closed channel\n";
261
262     return true;
263 }