source: trunk/zoo-project/zoo-kernel/service_internal_mono.c @ 820

Last change on this file since 820 was 794, checked in by djay, 8 years ago

Add the initial C# language support.

  • Property svn:keywords set to Id
File size: 14.9 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 * ref. http://www.mono-project.com/docs/advanced/embedding/
5 *      http://www.mono-project.com/docs/advanced/pinvoke/
6 *      http://www.giorgosdimtsas.net/embedding-mono-in-your-c-application/
7 *
8 * Copyright (c) 2009-2013 GeoLabs SARL
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 * THE SOFTWARE.
27 */
28
29#include "service_internal_mono.h"
30#include "response_print.h"
31
32/**
33 * Load a Mono dll then run the static public method corresponding to the
34 * service by passing the conf, inputs and outputs parameters.
35 *
36 * @param main_conf the conf maps containing the main.cfg settings
37 * @param request the map containing the HTTP request
38 * @param s the service structure
39 * @param real_inputs the maps containing the inputs
40 * @param real_outputs the maps containing the outputs
41 */
42int zoo_mono_support(maps** main_conf,map* request,service* s,maps **real_inputs,maps **real_outputs){
43  maps* m=*main_conf;
44  maps* inputs=*real_inputs;
45  maps* outputs=*real_outputs;
46  char *ntmp=NULL;
47  map* tmp=getMap(request,"metapath");
48  char *classpath;
49  char *oclasspath;
50  int res=SERVICE_FAILED;
51  MonoAssembly* assembly;
52  MonoImage* monoImage;
53
54  char* libPath="/usr/lib";
55  char* etcPath="/etc";
56  map* libPathMap=getMapFromMaps(*main_conf,"mono","lib");
57  map* etcPathMap=getMapFromMaps(*main_conf,"mono","etc");
58  if(libPathMap!=NULL)
59    libPath=libPathMap->value;
60  if(etcPathMap!=NULL)
61    etcPath=etcPathMap->value;
62 
63  mono_set_dirs(libPath,etcPath);
64
65  map* configMap=getMapFromMaps(*main_conf,"mono","config");
66  if(configMap!=NULL)
67    mono_config_parse(configMap->value);
68  else
69    mono_config_parse(NULL);
70
71  MonoDomain* monoDomain = mono_jit_init_version("ZOO_Embedded_Domain",
72                                                 "v4.0.30319");
73
74  map* cwdMap=getMapFromMaps(*main_conf,"main","servicePath");
75  if(cwdMap==NULL)
76    cwdMap=getMapFromMaps(*main_conf,"lenv","cwd");
77 
78  char *zooAssembly=(char*)malloc((strlen(cwdMap->value)+11)*sizeof(char));
79  sprintf(zooAssembly,"%s/ZMaps.dll",cwdMap->value);
80  assembly = mono_domain_assembly_open(monoDomain,zooAssembly);
81  if(assembly==NULL){
82    setMapInMaps(*main_conf,"lenv","message",_("The ZMaps.dll assembly cannot be found!"));
83    return 4;
84  }
85  mono_add_internal_call ("ZOO_API::Translate", MonoTranslate);
86  mono_add_internal_call ("ZOO_API::UpdateStatus", MonoUpdateStatus);
87
88  monoImage = mono_assembly_get_image(assembly);
89  MonoClass *KeysList = mono_class_from_name(monoImage, "ZooGenerics", "KeysList");
90  MonoClass *ZMapsClass = mono_class_from_name(monoImage, "ZooGenerics", "ZMaps");
91  MonoMethod *ZMapsAdd = mono_class_get_method_from_name(ZMapsClass, "addToMaps", 2); 
92  MonoMethod *ZMapsGetMaps = mono_class_get_method_from_name(ZMapsClass, "getMaps", 1);
93  MonoClass *_ZMapsClass = mono_class_from_name(monoImage, "ZooGenerics", "_ZMaps");
94  MonoMethod *_ZMapsSetContent = mono_class_get_method_from_name(_ZMapsClass, "setContent", 1);
95  MonoMethod *_ZMapsSetChild = mono_class_get_method_from_name(_ZMapsClass, "setChild", 1);
96  MonoMethod *_ZMapsGetContent = mono_class_get_method_from_name(_ZMapsClass, "getContent", 0);
97  MonoMethod *_ZMapsGetChild = mono_class_get_method_from_name(_ZMapsClass, "getChild", 0);
98  MonoClass *ZMapClass = mono_class_from_name(monoImage, "ZooGenerics", "ZMap");
99  MonoMethod *ZMapGetMap = mono_class_get_method_from_name(ZMapClass, "getMap", 1);
100  MonoMethod *ZMapAdd = mono_class_get_method_from_name(ZMapClass, "addToMap", 2);
101  MonoMethod *ZMapDisplay = mono_class_get_method_from_name(ZMapClass, "display", 1);
102  MonoObject *exc=NULL;
103
104  MonoClass *classes[3]={_ZMapsClass,ZMapsClass,ZMapClass};
105  MonoMethod *methods[5]={ZMapsAdd,_ZMapsSetContent,_ZMapsSetChild,ZMapAdd,ZMapDisplay};
106
107  MonoMethod *ZMapsGetKeys = mono_class_get_method_from_name(ZMapsClass, "getKeys", 0);
108  MonoMethod *ZMapsGetKeysCount = mono_class_get_method_from_name(ZMapsClass, "getKeysCount", 0);
109  MonoMethod *ZMapsGetKey = mono_class_get_method_from_name(ZMapsClass, "getKey", 1);
110  MonoMethod *ZMapGetKeys = mono_class_get_method_from_name(ZMapClass, "getKeys", 0);
111  MonoClassField *ZMapKeys = mono_class_get_field_from_name(ZMapClass, "Keys");
112  MonoMethod *ZMapGetKeysCount = mono_class_get_method_from_name(ZMapClass, "getKeysCount", 0);
113  MonoMethod *ZMapGetKey = mono_class_get_method_from_name(ZMapClass, "getKey", 1);
114  MonoMethod *ZMapGetSize = mono_class_get_method_from_name(ZMapClass, "getSize", 0);
115  MonoMethod *ZMapGetMapAsBytes = mono_class_get_method_from_name(ZMapClass, "getMapAsBytes", 0);
116  MonoClass *oclasses[4]={_ZMapsClass,ZMapsClass,ZMapClass,KeysList};
117  MonoMethod *omethods[10]={ZMapsGetMaps,ZMapsGetKeysCount,ZMapsGetKey,ZMapGetMap,ZMapGetKeysCount,ZMapGetKey,_ZMapsGetContent,_ZMapsGetChild,ZMapGetSize,ZMapGetMapAsBytes};
118
119  for(int i=0;i<4;i++){
120    iclasses[i]=oclasses[i];
121    imethods[i]=omethods[i];
122  }
123  for(int i=4;i<10;i++)
124    imethods[i]=omethods[i];
125
126  void *args[3];
127
128  MonoObject * main=ZMapsFromMaps(monoDomain,classes,methods,&exc,m);
129
130  MonoObject * in=ZMapsFromMaps(monoDomain,classes,methods,&exc,inputs);
131
132  MonoObject * out=ZMapsFromMaps(monoDomain,classes,methods,&exc,outputs);
133
134  args [0] = main;
135  args [1] = in;
136  args [2] = out;
137
138  tmp=getMap(s->content,"serviceProvider");
139  char *sName=(char*)malloc((strlen(tmp->value)+strlen(cwdMap->value)+2)*sizeof(char));
140  sprintf(sName,"%s/%s",cwdMap->value,tmp->value);
141  MonoAssembly* serviceAssembly = mono_domain_assembly_open(monoDomain,sName);
142  if(serviceAssembly==NULL){
143    char *msg=(char*)malloc((strlen(_("Your service assembly: %s cannot be found!"))+strlen(tmp->value)+1)*sizeof(char));
144    sprintf(msg,_("Your service assembly %s cannot be found!"),tmp->value);
145    setMapInMaps(*main_conf,"lenv","message",msg);
146    free(msg);
147    return 4;
148  }
149
150  MonoImage* serviceImage = mono_assembly_get_image(serviceAssembly);
151
152  map* tmp1=getMap(s->content,"serviceNameSpace");
153  tmp=getMap(s->content,"serviceClass");
154  MonoClass *serviceClass = mono_class_from_name(serviceImage, tmp1->value, tmp->value);
155  if(serviceClass==NULL){
156    char *msg=(char*)malloc((strlen(_("Your service class method %s::%s cannot be found!"))+strlen(tmp1->value)+strlen(tmp->value)+1)*sizeof(char));
157    sprintf(msg,_("Your service class method %s::%s cannot be found!"),tmp1->value,tmp->value);
158    setMapInMaps(*main_conf,"lenv","message",msg);
159    free(msg);
160    return 4;
161  }
162  MonoMethod *serviceFunction = mono_class_get_method_from_name(serviceClass, s->name, 3);
163  if(serviceFunction==NULL){
164    char *msg=(char*)malloc((strlen(_("Your service static method %s cannot be found!"))+strlen(s->name)+1)*sizeof(char));
165    sprintf(msg,_("Your service static method %s cannot be found!"),s->name);
166    setMapInMaps(*main_conf,"lenv","message",msg);
167    free(msg);
168    return 4;
169  }
170  MonoObject *exception=NULL;
171  MonoObject *result = mono_runtime_invoke(serviceFunction,NULL,args,&exception);
172  res=*(int*)mono_object_unbox (result);
173  if(res==3){
174    freeMaps(&outputs);
175    free(outputs);
176    outputs=mapsFromZMaps(monoDomain,oclasses,omethods,args[2]);
177    *real_outputs=outputs;
178  }
179  freeMaps(&m);
180  free(m);
181  m=mapsFromZMaps(monoDomain,oclasses,omethods,args[0]);
182  *main_conf=m;
183  mono_jit_cleanup (monoDomain);
184  return res;
185}
186
187/**
188 * Create ZMaps from maps
189 * @param domain the Mono Domain
190 * @param classes the Mono classes required to create (_ZMaps,ZMaps and ZMap)
191 * @param methods the Mono methods required (ZMapsAdd, _ZMapsSetContent, _ZMapsSetChild, ZMapAdd and ZMapDisplay)
192 * @param m the maps to use as source to create the corresponding ZMaps
193 * @return MonoObject* to a new ZMap
194 */
195MonoObject* ZMapsFromMaps(MonoDomain* domain,MonoClass **classes,MonoMethod **methods,MonoObject **exc,maps* m){
196  MonoObject *res=mono_object_new(domain,classes[1]);
197  MonoMethod* constructorMethod = mono_class_get_method_from_name(classes[1],
198                                                                  ".ctor",
199                                                                  0);
200  mono_runtime_invoke(constructorMethod, res, NULL, exc);
201  MonoMethod* constructorMethod1 = mono_class_get_method_from_name(classes[0],
202                                                                   ".ctor",
203                                                                   0);
204 
205  while(m!=NULL){
206    MonoObject *tmpRes=mono_object_new(domain,classes[0]);
207    mono_runtime_invoke(constructorMethod1, tmpRes, NULL, exc);
208    void *values0 [1];
209    MonoObject* content = ZMapFromMap (domain,classes[2],methods,exc,m->content);
210    values0 [0] = content;
211    MonoObject *exception=NULL;
212    mono_runtime_invoke(methods[1],tmpRes,values0,&exception);
213    if(exception!=NULL)
214      {
215        fprintf(stderr,"ERROR : %s\n", mono_string_to_utf8(mono_object_to_string(exception, NULL)));
216        fflush(stderr);
217        return res;
218      }
219    if(m->child!=NULL){
220      void *values [1];
221      values [0] = ZMapsFromMaps (domain,classes,methods,exc,m->child);
222      mono_runtime_invoke(methods[2],tmpRes,values,exc);
223    }
224    void *values [2];
225    values [0] = mono_string_new (domain, m->name);
226    values [1] = tmpRes;
227    mono_runtime_invoke(methods[0],res,values,exc);
228    m=m->next;
229  }
230  return res;
231}
232
233/**
234 * Create ZMap from map
235 * @param domain the Mono Domain
236 * @param classes the Mono classes required to create (_ZMaps,ZMaps and ZMap)
237 * @param methods the Mono methods required (ZMapsAdd, _ZMapsSetContent, _ZMapsSetChild, ZMapAdd and ZMapDisplay)
238 * @param exc the Mono exception object
239 * @param m the map to use as source to create a new ZMap
240 * @return MonoObject* to a new ZMap
241 */
242MonoObject* ZMapFromMap(MonoDomain* domain,MonoClass *ZMapClass,MonoMethod **methods,MonoObject **exc,map* m){
243  MonoObject *res=mono_object_new(domain,ZMapClass);
244  MonoMethod* constructorMethod = mono_class_get_method_from_name(ZMapClass,
245                                                                  ".ctor",
246                                                                  0);
247  mono_runtime_invoke(constructorMethod, res, NULL, exc);
248  map* sizeMap=getMap(m,"size");
249  while(m!=NULL){
250    void *values [2];
251    MonoString* name = mono_string_new(domain, m->name);
252    MonoString* value;
253    if(sizeMap!=NULL && strcasecmp(m->name,"value")==0)
254      value = mono_string_new_len(domain, m->value,atoi(sizeMap->value));
255    else
256      value = mono_string_new(domain, m->value);
257    values [0] = name;
258    values [1] = value;
259    mono_runtime_invoke(methods[3],res,values,exc);
260    m=m->next;
261  }
262  return res;
263}
264
265/**
266 * Create maps from ZMaps
267 * @param domain the Mono Domain
268 * @param classes the Mono classes required to create (_ZMapsClass,ZMapsClass,ZMapClass,KeysList)
269 * @param methods the Mono methods required (ZMapsGetMaps,ZMapsGetKeysCount,ZMapsGetKey,ZMapGetMap,ZMapGetKeysCount,ZMapGetKey,_ZMapsGetContent,_ZMapsGetChild)
270 * @param m the ZMaps to use as source to create a new maps
271 * @return MonoObject* to a new ZMaps
272 */
273maps* mapsFromZMaps(MonoDomain* domain,MonoClass **classes,MonoMethod **methods,MonoObject* m){
274  maps* res=NULL;
275  if(m!=NULL){
276    MonoObject *exc=NULL;
277    MonoObject *okeys = mono_runtime_invoke(methods[1],m,NULL,&exc);
278    if(exc!=NULL)
279      {
280        fprintf(stderr,"ERROR : %s\n", mono_string_to_utf8(mono_object_to_string(exc, NULL)));
281        fflush(stderr);
282        return res;
283      }
284
285    int keyCount=*(int*)mono_object_unbox (okeys);
286    for(int i=0;i<keyCount;i++){
287      void* values[1];
288      values[0]=&i;
289      exc=NULL;
290      MonoObject *okey = (MonoString*) mono_runtime_invoke(methods[2],m,values,&exc);
291      char* key = mono_string_to_utf8(okey);
292      maps* tmp=createMaps(key);
293      values[0]=mono_string_new (domain, key);
294      MonoObject *content_ZMaps = (MonoString*) mono_runtime_invoke(methods[0],m,values,&exc);
295      MonoObject *content = mono_runtime_invoke(methods[6],content_ZMaps,NULL,&exc);
296      tmp->content=mapFromZMap(domain,classes,methods,content);
297      MonoObject *childs = mono_runtime_invoke(methods[7],content_ZMaps,NULL,&exc);
298      tmp->child=mapsFromZMaps(domain,classes,methods,childs);
299      if(res==NULL){
300        res=dupMaps(&tmp);
301      }else
302        addMapsToMaps(&res,tmp);
303      freeMaps(&tmp);
304      free(tmp);
305      mono_free(key);
306    }
307  }
308  return res;
309}
310
311/**
312 * Create map from ZMap
313 * @param domain the Mono Domain
314 * @param classes the Mono classes required (_ZMapsClass,ZMapsClass,ZMapClass,KeysList)
315 * @param methods the Mono methods required (ZMapsGetMaps,ZMapsGetKeysCount,ZMapsGetKey,ZMapGetMap,ZMapGetKeysCount,ZMapGetKey,_ZMapsGetContent,_ZMapsGetChild,ZMapGetSize)
316 * @param m the ZMap to use as source to create a new map
317 * @return MonoObject* to a new ZMap
318 */
319map* mapFromZMap(MonoDomain* domain,MonoClass **classes,MonoMethod **methods,MonoObject* m){
320  map* res=NULL;
321  if(m!=NULL){
322    MonoObject *exc = NULL;
323    MonoObject *okeys = mono_runtime_invoke(methods[4],m,NULL,&exc);
324    int keyCount=*(int*)mono_object_unbox (okeys);
325    MonoObject *osize = mono_runtime_invoke(methods[8],m,NULL,&exc);
326    int size=*(int*)mono_object_unbox (osize);
327    for(int i=0;i<keyCount;i++){
328      void* values[1];
329      values[0]=&i;
330      exc=NULL;
331      MonoObject *okey = (MonoString*) mono_runtime_invoke(methods[5],m,values,&exc);
332      char* key = mono_string_to_utf8(okey);
333      values[0]=mono_string_new (domain, key);
334      exc=NULL;
335      MonoObject *ovalue = (MonoString*) mono_runtime_invoke(methods[3],m,values,&exc);
336      char* value = mono_string_to_utf8(ovalue);
337      if(res==NULL)
338        res=createMap(key,value);
339      else
340        addToMap(res,key,value);
341    }
342  }
343  return res;
344}
345
346/**
347 * The translate function to search in zoo-services gettext domain for translating a string.
348 * @param str the string to be translated
349 * @return the translated string
350 */
351static MonoString* MonoTranslate(MonoString *str){
352  return mono_string_new (mono_domain_get(), mono_string_to_utf8(_(str)));
353}
354
355/**
356 * The updateStatus function to update the ongoing status of a ZOO-Service.
357 * @param m the main.cfg map
358 * @param str the message for the current step
359 * @param p the percentage of the
360 * @return the translated string
361 */
362static void MonoUpdateStatus(MonoObject* obj,MonoString *str,int* p){
363  MonoDomain* domain = mono_object_get_domain (obj);
364  maps *confMaps=mapsFromZMaps(domain,iclasses,imethods,obj);
365  setMapInMaps(confMaps,"lenv","message",mono_string_to_utf8(str));
366  int tmp=p;
367  if (p < 0 || p > 100){
368    tmp=-1;
369  }
370  char tmpStatus[5];
371  snprintf(tmpStatus, 4, "%d", tmp);
372  setMapInMaps(confMaps,"lenv","status",(char*)tmpStatus);
373  _updateStatus(confMaps);
374  freeMaps(&confMaps);
375  free(confMaps);
376  return;
377}
Note: See TracBrowser for help on using the repository browser.

Search

Context Navigation

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png