1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4 
5 #include <Properties.h>
6 #include <Util.h>
7 #include <Ice/Initialize.h>
8 #include <Ice/Properties.h>
9 
10 using namespace std;
11 using namespace IceRuby;
12 
13 static VALUE _propertiesClass;
14 
15 extern "C"
16 void
IceRuby_Properties_free(Ice::PropertiesPtr * p)17 IceRuby_Properties_free(Ice::PropertiesPtr* p)
18 {
19     assert(p);
20     delete p;
21 }
22 
23 extern "C"
24 VALUE
IceRuby_createProperties(int argc,VALUE * argv,VALUE)25 IceRuby_createProperties(int argc, VALUE* argv, VALUE /*self*/)
26 {
27     ICE_RUBY_TRY
28     {
29         Ice::StringSeq seq;
30         if(argc >= 1 && !NIL_P(argv[0]) && !arrayToStringSeq(argv[0], seq))
31         {
32             throw RubyException(rb_eTypeError, "invalid array argument to Ice::createProperties");
33         }
34 
35         Ice::PropertiesPtr defaults;
36         if(argc == 2)
37         {
38             if(!NIL_P(argv[1]) && callRuby(rb_obj_is_instance_of, argv[1], _propertiesClass) == Qfalse)
39             {
40                 throw RubyException(rb_eTypeError, "invalid properties argument to Ice::createProperties");
41             }
42             defaults = getProperties(argv[1]);
43         }
44 
45         //
46         // Insert the program name (stored in the Ruby global variable $0) as the first
47         // element of the sequence.
48         //
49         volatile VALUE progName = callRuby(rb_gv_get, "$0");
50         seq.insert(seq.begin(), getString(progName));
51 
52         Ice::PropertiesPtr obj;
53         if(argc >= 1)
54         {
55             obj = Ice::createProperties(seq, defaults);
56         }
57         else
58         {
59             obj = Ice::createProperties();
60         }
61 
62         //
63         // Replace the contents of the given argument list with the filtered arguments.
64         //
65         if(argc > 0 && !NIL_P(argv[0]))
66         {
67             callRuby(rb_ary_clear, argv[0]);
68 
69             //
70             // We start at index 1 in order to skip the element that we inserted earlier.
71             //
72             for(Ice::StringSeq::size_type i = 1; i < seq.size(); ++i)
73             {
74                 volatile VALUE str = createString(seq[i]);
75                 callRuby(rb_ary_push, argv[0], str);
76             }
77         }
78 
79         return createProperties(obj);
80     }
81     ICE_RUBY_CATCH
82     return Qnil;
83 }
84 
85 extern "C"
86 VALUE
IceRuby_Properties_getProperty(VALUE self,VALUE key)87 IceRuby_Properties_getProperty(VALUE self, VALUE key)
88 {
89     ICE_RUBY_TRY
90     {
91         Ice::PropertiesPtr p = getProperties(self);
92         string k = getString(key);
93         string v = p->getProperty(k);
94         return createString(v);
95     }
96     ICE_RUBY_CATCH
97     return Qnil;
98 }
99 
100 extern "C"
101 VALUE
IceRuby_Properties_getPropertyWithDefault(VALUE self,VALUE key,VALUE def)102 IceRuby_Properties_getPropertyWithDefault(VALUE self, VALUE key, VALUE def)
103 {
104     ICE_RUBY_TRY
105     {
106         Ice::PropertiesPtr p = getProperties(self);
107         string k = getString(key);
108         string d = getString(def);
109         string v = p->getPropertyWithDefault(k, d);
110         return createString(v);
111     }
112     ICE_RUBY_CATCH
113     return Qnil;
114 }
115 
116 extern "C"
117 VALUE
IceRuby_Properties_getPropertyAsInt(VALUE self,VALUE key)118 IceRuby_Properties_getPropertyAsInt(VALUE self, VALUE key)
119 {
120     ICE_RUBY_TRY
121     {
122         Ice::PropertiesPtr p = getProperties(self);
123         string k = getString(key);
124         Ice::Int v = p->getPropertyAsInt(k);
125         return INT2FIX(v);
126     }
127     ICE_RUBY_CATCH
128     return Qnil;
129 }
130 
131 extern "C"
132 VALUE
IceRuby_Properties_getPropertyAsIntWithDefault(VALUE self,VALUE key,VALUE def)133 IceRuby_Properties_getPropertyAsIntWithDefault(VALUE self, VALUE key, VALUE def)
134 {
135     ICE_RUBY_TRY
136     {
137         Ice::PropertiesPtr p = getProperties(self);
138         string k = getString(key);
139         Ice::Int d = getInteger(def);
140         Ice::Int v = p->getPropertyAsIntWithDefault(k, d);
141         return INT2FIX(v);
142     }
143     ICE_RUBY_CATCH
144     return Qnil;
145 }
146 
147 extern "C"
148 VALUE
IceRuby_Properties_getPropertyAsList(VALUE self,VALUE key)149 IceRuby_Properties_getPropertyAsList(VALUE self, VALUE key)
150 {
151     ICE_RUBY_TRY
152     {
153         Ice::PropertiesPtr p = getProperties(self);
154         string k = getString(key);
155         Ice::StringSeq v = p->getPropertyAsList(k);
156         return stringSeqToArray(v);
157     }
158     ICE_RUBY_CATCH
159     return Qnil;
160 }
161 
162 extern "C"
163 VALUE
IceRuby_Properties_getPropertyAsListWithDefault(VALUE self,VALUE key,VALUE def)164 IceRuby_Properties_getPropertyAsListWithDefault(VALUE self, VALUE key, VALUE def)
165 {
166     ICE_RUBY_TRY
167     {
168         Ice::PropertiesPtr p = getProperties(self);
169         string k = getString(key);
170         Ice::StringSeq d;
171         if(!arrayToStringSeq(def, d))
172         {
173             throw RubyException(rb_eTypeError, "invalid array argument to Ice::getPropertyAsListWithDefault");
174         }
175         Ice::StringSeq v = p->getPropertyAsListWithDefault(k, d);
176         return stringSeqToArray(v);
177     }
178     ICE_RUBY_CATCH
179     return Qnil;
180 }
181 
182 extern "C"
183 VALUE
IceRuby_Properties_getPropertiesForPrefix(VALUE self,VALUE prefix)184 IceRuby_Properties_getPropertiesForPrefix(VALUE self, VALUE prefix)
185 {
186     ICE_RUBY_TRY
187     {
188         Ice::PropertiesPtr p = getProperties(self);
189         string pfx = getString(prefix);
190         Ice::PropertyDict dict = p->getPropertiesForPrefix(pfx);
191         volatile VALUE result = callRuby(rb_hash_new);
192         for(Ice::PropertyDict::const_iterator q = dict.begin(); q != dict.end(); ++q)
193         {
194             volatile VALUE key = createString(q->first);
195             volatile VALUE value = createString(q->second);
196             callRuby(rb_hash_aset, result, key, value);
197         }
198         return result;
199     }
200     ICE_RUBY_CATCH
201     return Qnil;
202 }
203 
204 extern "C"
205 VALUE
IceRuby_Properties_setProperty(VALUE self,VALUE key,VALUE value)206 IceRuby_Properties_setProperty(VALUE self, VALUE key, VALUE value)
207 {
208     ICE_RUBY_TRY
209     {
210         Ice::PropertiesPtr p = getProperties(self);
211         string k = getString(key);
212         string v = getString(value);
213         p->setProperty(k, v);
214     }
215     ICE_RUBY_CATCH
216     return Qnil;
217 }
218 
219 extern "C"
220 VALUE
IceRuby_Properties_getCommandLineOptions(VALUE self)221 IceRuby_Properties_getCommandLineOptions(VALUE self)
222 {
223     ICE_RUBY_TRY
224     {
225         Ice::PropertiesPtr p = getProperties(self);
226         Ice::StringSeq options = p->getCommandLineOptions();
227         return stringSeqToArray(options);
228     }
229     ICE_RUBY_CATCH
230     return Qnil;
231 }
232 
233 extern "C"
234 VALUE
IceRuby_Properties_parseCommandLineOptions(VALUE self,VALUE prefix,VALUE options)235 IceRuby_Properties_parseCommandLineOptions(VALUE self, VALUE prefix, VALUE options)
236 {
237     ICE_RUBY_TRY
238     {
239         Ice::PropertiesPtr p = getProperties(self);
240         string pfx = getString(prefix);
241         Ice::StringSeq seq;
242         if(!arrayToStringSeq(options, seq))
243         {
244             throw RubyException(rb_eTypeError, "invalid array argument to Ice::parseCommandLineOptions");
245         }
246         Ice::StringSeq filtered = p->parseCommandLineOptions(pfx, seq);
247         return stringSeqToArray(filtered);
248     }
249     ICE_RUBY_CATCH
250     return Qnil;
251 }
252 
253 extern "C"
254 VALUE
IceRuby_Properties_parseIceCommandLineOptions(VALUE self,VALUE options)255 IceRuby_Properties_parseIceCommandLineOptions(VALUE self, VALUE options)
256 {
257     ICE_RUBY_TRY
258     {
259         Ice::PropertiesPtr p = getProperties(self);
260         Ice::StringSeq seq;
261         if(!arrayToStringSeq(options, seq))
262         {
263             throw RubyException(rb_eTypeError, "invalid array argument to Ice::parseIceCommandLineOptions");
264         }
265         Ice::StringSeq filtered = p->parseIceCommandLineOptions(seq);
266         return stringSeqToArray(filtered);
267     }
268     ICE_RUBY_CATCH
269     return Qnil;
270 }
271 
272 extern "C"
273 VALUE
IceRuby_Properties_load(VALUE self,VALUE file)274 IceRuby_Properties_load(VALUE self, VALUE file)
275 {
276     ICE_RUBY_TRY
277     {
278         Ice::PropertiesPtr p = getProperties(self);
279         string f = getString(file);
280         p->load(f);
281     }
282     ICE_RUBY_CATCH
283     return Qnil;
284 }
285 
286 extern "C"
287 VALUE
IceRuby_Properties_clone(VALUE self)288 IceRuby_Properties_clone(VALUE self)
289 {
290     ICE_RUBY_TRY
291     {
292         Ice::PropertiesPtr p = getProperties(self);
293         Ice::PropertiesPtr props = p->clone();
294         return createProperties(props);
295     }
296     ICE_RUBY_CATCH
297     return Qnil;
298 }
299 
300 extern "C"
301 VALUE
IceRuby_Properties_to_s(VALUE self)302 IceRuby_Properties_to_s(VALUE self)
303 {
304     ICE_RUBY_TRY
305     {
306         Ice::PropertiesPtr p = getProperties(self);
307         Ice::PropertyDict dict = p->getPropertiesForPrefix("");
308         string str;
309         for(Ice::PropertyDict::const_iterator q = dict.begin(); q != dict.end(); ++q)
310         {
311             if(q != dict.begin())
312             {
313                 str.append("\n");
314             }
315             str.append(q->first + "=" + q->second);
316         }
317         return createString(str);
318     }
319     ICE_RUBY_CATCH
320     return Qnil;
321 }
322 
323 void
initProperties(VALUE iceModule)324 IceRuby::initProperties(VALUE iceModule)
325 {
326     rb_define_module_function(iceModule, "createProperties", CAST_METHOD(IceRuby_createProperties), -1);
327 
328     _propertiesClass = rb_define_class_under(iceModule, "PropertiesI", rb_cObject);
329     rb_define_method(_propertiesClass, "getProperty", CAST_METHOD(IceRuby_Properties_getProperty), 1);
330     rb_define_method(_propertiesClass, "getPropertyWithDefault",
331                      CAST_METHOD(IceRuby_Properties_getPropertyWithDefault), 2);
332     rb_define_method(_propertiesClass, "getPropertyAsInt", CAST_METHOD(IceRuby_Properties_getPropertyAsInt), 1);
333     rb_define_method(_propertiesClass, "getPropertyAsIntWithDefault",
334                      CAST_METHOD(IceRuby_Properties_getPropertyAsIntWithDefault), 2);
335     rb_define_method(_propertiesClass, "getPropertyAsList", CAST_METHOD(IceRuby_Properties_getPropertyAsList), 1);
336     rb_define_method(_propertiesClass, "getPropertyAsListWithDefault",
337                      CAST_METHOD(IceRuby_Properties_getPropertyAsListWithDefault), 2);
338     rb_define_method(_propertiesClass, "getPropertiesForPrefix",
339                      CAST_METHOD(IceRuby_Properties_getPropertiesForPrefix), 1);
340     rb_define_method(_propertiesClass, "setProperty", CAST_METHOD(IceRuby_Properties_setProperty), 2);
341     rb_define_method(_propertiesClass, "getCommandLineOptions", CAST_METHOD(IceRuby_Properties_getCommandLineOptions),
342                      0);
343     rb_define_method(_propertiesClass, "parseCommandLineOptions",
344                      CAST_METHOD(IceRuby_Properties_parseCommandLineOptions), 2);
345     rb_define_method(_propertiesClass, "parseIceCommandLineOptions",
346                      CAST_METHOD(IceRuby_Properties_parseIceCommandLineOptions), 1);
347     rb_define_method(_propertiesClass, "load", CAST_METHOD(IceRuby_Properties_load), 1);
348     rb_define_method(_propertiesClass, "clone", CAST_METHOD(IceRuby_Properties_clone), 0);
349     rb_define_method(_propertiesClass, "to_s", CAST_METHOD(IceRuby_Properties_to_s), 0);
350 }
351 
352 Ice::PropertiesPtr
getProperties(VALUE v)353 IceRuby::getProperties(VALUE v)
354 {
355     Ice::PropertiesPtr* p = reinterpret_cast<Ice::PropertiesPtr*>(DATA_PTR(v));
356     assert(p);
357     return *p;
358 }
359 
360 VALUE
createProperties(const Ice::PropertiesPtr & p)361 IceRuby::createProperties(const Ice::PropertiesPtr& p)
362 {
363     return Data_Wrap_Struct(_propertiesClass, 0, IceRuby_Properties_free, new Ice::PropertiesPtr(p));
364 }
365