Free Electron
nethost_loader.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifdef _WIN32
8 #include <windows.h>
9 #else
10 #include <dlfcn.h>
11 #endif
12 
13 #include <cstdio>
14 #include <stdlib.h>
15 #include <cstring>
16 #include <typeinfo>
17 
18 #define FE_SPACE_VERBOSE FALSE
19 
20 typedef int (FnFeAccessSpace)
21  (const char*,const char*);
22 typedef int (FnFeSpaceStart)
23  (int);
24 typedef int (FnFeSpaceStop)
25  (int);
26 typedef int (FnFeSpaceWaitForConnection)
27  (int);
28 typedef int (FnFeSpaceFlush)
29  (int);
30 typedef int (FnFeSpaceWaitForUpdate)
31  (int,int*,int*);
32 typedef int (FnFeSpaceLockAfterUpdate)
33  (int,int*,int*);
34 typedef int (FnFeSpaceLock)
35  (int);
36 typedef int (FnFeSpaceUnlock)
37  (int);
38 typedef int (FnFeSpaceSetStateBools)
39  (int,const char*,const char*,const bool*,int);
40 typedef int (FnFeSpaceGetStateBools)
41  (int,const char*,const char*,bool*,int,bool);
42 typedef int (FnFeSpaceSetStateInts)
43  (int,const char*,const char*,const int*,int);
44 typedef int (FnFeSpaceGetStateInts)
45  (int,const char*,const char*,int*,int,bool);
46 typedef int (FnFeSpaceSetStateFloats)
47  (int,const char*,const char*,const float*,int);
48 typedef int (FnFeSpaceGetStateFloats)
49  (int,const char*,const char*,float*,int,bool);
50 typedef int (FnFeSpaceSetStateString)
51  (int,const char*,const char*,const char*);
52 typedef char* (FnFeSpaceGetStateString)
53  (int,const char*,const char*,bool);
54 typedef int (FnFeSpaceSetStateBytes)
55  (int,const char*,const char*,const unsigned char*,int);
56 typedef unsigned char* (FnFeSpaceGetStateBytes)
57  (int,const char*,const char*,bool,int*);
58 typedef int (FnFeSpaceSendMessageString)
59  (int,const char*,const char*);
60 typedef char* (FnFeSpaceNextMessageString)
61  (int,const char*);
62 typedef int (FnFeFreeString)
63  (const char*);
64 
65 inline FnFeAccessSpace*& fpFeAccessSpace(void)
66 {
67  static FnFeAccessSpace* s_fpFeAccessSpace=NULL;
68  return s_fpFeAccessSpace;
69 }
70 
71 inline FnFeSpaceStart*& fpFeSpaceStart(void)
72 {
73  static FnFeSpaceStart* s_fpFeSpaceStart=NULL;
74  return s_fpFeSpaceStart;
75 }
76 
77 inline FnFeSpaceStop*& fpFeSpaceStop(void)
78 {
79  static FnFeSpaceStop* s_fpFeSpaceStop=NULL;
80  return s_fpFeSpaceStop;
81 }
82 
83 inline FnFeSpaceWaitForConnection*& fpFeSpaceWaitForConnection(void)
84 {
85  static FnFeSpaceWaitForConnection* s_fpFeSpaceWaitForConnection=NULL;
86  return s_fpFeSpaceWaitForConnection;
87 }
88 
89 inline FnFeSpaceFlush*& fpFeSpaceFlush(void)
90 {
91  static FnFeSpaceFlush* s_fpFeSpaceFlush=NULL;
92  return s_fpFeSpaceFlush;
93 }
94 
95 inline FnFeSpaceWaitForUpdate*& fpFeSpaceWaitForUpdate(void)
96 {
97  static FnFeSpaceWaitForUpdate* s_fpFeSpaceWaitForUpdate=NULL;
98  return s_fpFeSpaceWaitForUpdate;
99 }
100 
101 inline FnFeSpaceLockAfterUpdate*& fpFeSpaceLockAfterUpdate(void)
102 {
103  static FnFeSpaceLockAfterUpdate* s_fpFeSpaceLockAfterUpdate=NULL;
104  return s_fpFeSpaceLockAfterUpdate;
105 }
106 
107 inline FnFeSpaceLock*& fpFeSpaceLock(void)
108 {
109  static FnFeSpaceLock* s_fpFeSpaceLock=NULL;
110  return s_fpFeSpaceLock;
111 }
112 
113 inline FnFeSpaceUnlock*& fpFeSpaceUnlock(void)
114 {
115  static FnFeSpaceUnlock* s_fpFeSpaceUnlock=NULL;
116  return s_fpFeSpaceUnlock;
117 }
118 
119 inline FnFeSpaceSetStateBools*& fpFeSpaceSetStateBools(void)
120 {
121  static FnFeSpaceSetStateBools* s_fpFeSpaceSetStateBools=NULL;
122  return s_fpFeSpaceSetStateBools;
123 }
124 
125 inline FnFeSpaceGetStateBools*& fpFeSpaceGetStateBools(void)
126 {
127  static FnFeSpaceGetStateBools* s_fpFeSpaceGetStateBool=NULL;
128  return s_fpFeSpaceGetStateBool;
129 }
130 
131 inline FnFeSpaceSetStateInts*& fpFeSpaceSetStateInts(void)
132 {
133  static FnFeSpaceSetStateInts* s_fpFeSpaceSetStateInts=NULL;
134  return s_fpFeSpaceSetStateInts;
135 }
136 
137 inline FnFeSpaceGetStateInts*& fpFeSpaceGetStateInts(void)
138 {
139  static FnFeSpaceGetStateInts* s_fpFeSpaceGetStateInts=NULL;
140  return s_fpFeSpaceGetStateInts;
141 }
142 
143 inline FnFeSpaceSetStateFloats*& fpFeSpaceSetStateFloats(void)
144 {
145  static FnFeSpaceSetStateFloats* s_fpFeSpaceSetStateFloats=NULL;
146  return s_fpFeSpaceSetStateFloats;
147 }
148 
149 inline FnFeSpaceGetStateFloats*& fpFeSpaceGetStateFloats(void)
150 {
151  static FnFeSpaceGetStateFloats* s_fpFeSpaceGetStateFloats=NULL;
152  return s_fpFeSpaceGetStateFloats;
153 }
154 
155 inline FnFeSpaceSetStateString*& fpFeSpaceSetStateString(void)
156 {
157  static FnFeSpaceSetStateString* s_fpFeSpaceSetStateString=NULL;
158  return s_fpFeSpaceSetStateString;
159 }
160 
161 inline FnFeSpaceGetStateString*& fpFeSpaceGetStateString(void)
162 {
163  static FnFeSpaceGetStateString* s_fpFeSpaceGetStateString=NULL;
164  return s_fpFeSpaceGetStateString;
165 }
166 
167 inline FnFeSpaceSetStateBytes*& fpFeSpaceSetStateBytes(void)
168 {
169  static FnFeSpaceSetStateBytes* s_fpFeSpaceSetStateBytes=NULL;
170  return s_fpFeSpaceSetStateBytes;
171 }
172 
173 inline FnFeSpaceGetStateBytes*& fpFeSpaceGetStateBytes(void)
174 {
175  static FnFeSpaceGetStateBytes* s_fpFeSpaceGetStateBytes=NULL;
176  return s_fpFeSpaceGetStateBytes;
177 }
178 
179 inline FnFeSpaceSendMessageString*& fpFeSpaceSendMessageString(void)
180 {
181  static FnFeSpaceSendMessageString* s_fpFeSpaceSendMessageString=NULL;
182  return s_fpFeSpaceSendMessageString;
183 }
184 
185 inline FnFeSpaceNextMessageString*& fpFeSpaceNextMessageString(void)
186 {
187  static FnFeSpaceNextMessageString* s_fpFeSpaceNextMessageString=NULL;
188  return s_fpFeSpaceNextMessageString;
189 }
190 
191 inline FnFeFreeString*& fpFeFreeString(void)
192 {
193  static FnFeFreeString* s_fpFeFreeString=NULL;
194  return s_fpFeFreeString;
195 }
196 
197 #ifdef _WIN32
198 inline void* fe_nethost_dlsym(HINSTANCE a_handle,const char* a_symbol)
199 {
200  return GetProcAddress(a_handle,a_symbol);
201 }
202 #else
203 inline void* fe_nethost_dlsym(void* a_handle,const char* a_symbol)
204 {
205  return dlsym(a_handle,a_symbol);
206 }
207 #endif
208 
209 inline int fe_nethost_nethost_loader_init(void)
210 {
211  const int size(4096);
212  char suffix[size];
213  suffix[0]=0;
214 
215 #ifdef FE_BINARY_SUFFIX
216  #define AS_STRING2(x) #x
217  #define AS_STRING(x) AS_STRING2(x)
218 
219  strncpy(suffix,AS_STRING(FE_BINARY_SUFFIX),size);
220 #endif
221 
222 #ifdef _WIN32
223  char val[size];
224  const unsigned long cp=
225  GetEnvironmentVariable("FE_BINARY_SUFFIX", val, size);
226  if(cp)
227  {
228  strncpy(suffix,val,size);
229  }
230 
231  char filename[size+100];
232  snprintf(filename,size,"fexNetworkHostDL%s.dll",suffix);
233 
234  HINSTANCE handle=LoadLibrary(filename);
235 
236  if(!handle)
237  {
238  printf("fe_nethost_nethost_loader_init LoadLibrary \"%s\" failed\n",
239  filename);
240  exit(1);
241  }
242 #else
243  const char* cp=getenv("FE_BINARY_SUFFIX");
244  if(cp)
245  {
246  strncpy(suffix,cp,size);
247  }
248 
249  char filename[size+100];
250  snprintf(filename,size,"libfexNetworkHostDL%s.so",suffix);
251 
252  dlerror();
253  void* handle=dlopen(filename,RTLD_NOW);
254  if(!handle)
255  {
256  printf("fe_nethost_nethost_loader_init dlopen \"%s\" failed\n %s\n",
257  filename,dlerror());
258  exit(1);
259  }
260 #endif
261 
262 #pragma GCC diagnostic push
263 #pragma GCC diagnostic ignored "-Wconditionally-supported"
264 
265  fpFeAccessSpace()=(FnFeAccessSpace*)
266  fe_nethost_dlsym(handle,"fe_nethost_access_space");
267  fpFeSpaceStart()=(FnFeSpaceStart*)
268  fe_nethost_dlsym(handle,"fe_nethost_space_start");
269  fpFeSpaceStop()=(FnFeSpaceStop*)
270  fe_nethost_dlsym(handle,"fe_nethost_space_stop");
271  fpFeSpaceWaitForConnection()=(FnFeSpaceWaitForConnection*)
272  fe_nethost_dlsym(handle,"fe_nethost_space_wait_for_connection");
273  fpFeSpaceFlush()=(FnFeSpaceFlush*)
274  fe_nethost_dlsym(handle,"fe_nethost_space_flush");
275  fpFeSpaceWaitForUpdate()=(FnFeSpaceWaitForUpdate*)
276  fe_nethost_dlsym(handle,"fe_nethost_space_wait_for_update");
277  fpFeSpaceLockAfterUpdate()=(FnFeSpaceLockAfterUpdate*)
278  fe_nethost_dlsym(handle,"fe_nethost_space_lock_after_update");
279  fpFeSpaceLock()=(FnFeSpaceLock*)
280  fe_nethost_dlsym(handle,"fe_nethost_space_lock");
281  fpFeSpaceUnlock()=(FnFeSpaceUnlock*)
282  fe_nethost_dlsym(handle,"fe_nethost_space_unlock");
283  fpFeSpaceSetStateBools()=(FnFeSpaceSetStateBools*)
284  fe_nethost_dlsym(handle,"fe_nethost_space_set_state_bools");
285  fpFeSpaceGetStateBools()=(FnFeSpaceGetStateBools*)
286  fe_nethost_dlsym(handle,"fe_nethost_space_get_state_bools");
287  fpFeSpaceSetStateInts()=(FnFeSpaceSetStateInts*)
288  fe_nethost_dlsym(handle,"fe_nethost_space_set_state_ints");
289  fpFeSpaceGetStateInts()=(FnFeSpaceGetStateInts*)
290  fe_nethost_dlsym(handle,"fe_nethost_space_get_state_ints");
291  fpFeSpaceSetStateFloats()=(FnFeSpaceSetStateFloats*)
292  fe_nethost_dlsym(handle,"fe_nethost_space_set_state_floats");
293  fpFeSpaceGetStateFloats()=(FnFeSpaceGetStateFloats*)
294  fe_nethost_dlsym(handle,"fe_nethost_space_get_state_floats");
295  fpFeSpaceSetStateString()=(FnFeSpaceSetStateString*)
296  fe_nethost_dlsym(handle,"fe_nethost_space_set_state_string");
297  fpFeSpaceGetStateString()=(FnFeSpaceGetStateString*)
298  fe_nethost_dlsym(handle,"fe_nethost_space_get_state_string");
299  fpFeSpaceSetStateBytes()=(FnFeSpaceSetStateBytes*)
300  fe_nethost_dlsym(handle,"fe_nethost_space_set_state_bytes");
301  fpFeSpaceGetStateBytes()=(FnFeSpaceGetStateBytes*)
302  fe_nethost_dlsym(handle,"fe_nethost_space_get_state_bytes");
303  fpFeSpaceSendMessageString()=(FnFeSpaceSendMessageString*)
304  fe_nethost_dlsym(handle,"fe_nethost_space_send_message_string");
305  fpFeSpaceNextMessageString()=(FnFeSpaceNextMessageString*)
306  fe_nethost_dlsym(handle,"fe_nethost_space_next_message_string");
307  fpFeFreeString()=(FnFeFreeString*)
308  fe_nethost_dlsym(handle,"fe_nethost_free_string");
309 
310 #pragma GCC diagnostic pop
311 
312  return 0;
313 }
314 
315 inline int fe_nethost_access_space(const char* a_name,const char* a_implementation)
316 {
317  if(!fpFeAccessSpace())
318  {
319  fe_nethost_nethost_loader_init();
320  }
321 
322  return fpFeAccessSpace() &&
323  fpFeAccessSpace()(a_name,a_implementation);
324 }
325 
326 inline int fe_nethost_access_space(const char* a_name)
327 {
328  return fe_nethost_access_space(a_name,"*.NetworkCatalog");
329 }
330 
331 inline int fe_nethost_space_start(int a_spaceIndex)
332 {
333  return fpFeSpaceStart() && fpFeSpaceStart()(a_spaceIndex);
334 }
335 
336 inline int fe_nethost_space_stop(int a_spaceIndex)
337 {
338  return fpFeSpaceStop() && fpFeSpaceStop()(a_spaceIndex);
339 }
340 
341 inline int fe_nethost_space_wait_for_connection(int a_spaceIndex)
342 {
343  return fpFeSpaceWaitForConnection() &&
344  fpFeSpaceWaitForConnection()(a_spaceIndex);
345 }
346 
347 inline int fe_nethost_space_flush(int a_spaceIndex)
348 {
349  return fpFeSpaceFlush() && fpFeSpaceFlush()(a_spaceIndex);
350 }
351 
352 inline int fe_nethost_space_wait_for_update(int a_spaceIndex,
353  int* a_pFlushCount,int* a_pSpins)
354 {
355  return fpFeSpaceWaitForUpdate() &&
356  fpFeSpaceWaitForUpdate()(a_spaceIndex,a_pFlushCount,a_pSpins);
357 }
358 
359 inline int fe_nethost_space_lock_after_update(int a_spaceIndex,
360  int* a_pFlushCount,int* a_pSpins)
361 {
362  return fpFeSpaceLockAfterUpdate() &&
363  fpFeSpaceLockAfterUpdate()(a_spaceIndex,
364  a_pFlushCount,a_pSpins);
365 }
366 
367 inline int fe_nethost_space_lock(int a_spaceIndex)
368 {
369  return fpFeSpaceLock() && fpFeSpaceLock()(a_spaceIndex);
370 }
371 
372 inline int fe_nethost_space_unlock(int a_spaceIndex)
373 {
374  return fpFeSpaceUnlock() && fpFeSpaceUnlock()(a_spaceIndex);
375 }
376 
377 template <class T>
378 int fe_nethost_space_set_state(int a_spaceIndex,
379  const char* a_key,const char* a_property,const T* a_values,int a_count)
380 {
381 #if FE_SPACE_VERBOSE
382  printf("fe_nethost_space_set_state<%s *> %d \"%s\" \"%s\" %d (NOP)\n",
383  typeid(T).name(),a_spaceIndex,a_key,a_property,a_count);
384 #endif
385  return 0;
386 }
387 
388 template <class T>
389 int fe_nethost_space_set_state(int a_spaceIndex,
390  const char* a_key,const char* a_property,const T a_value)
391 {
392 #if FE_SPACE_VERBOSE
393  printf("fe_nethost_space_set_state<%s> %d \"%s\" \"%s\"\n",
394  typeid(T).name(),a_spaceIndex,a_key,a_property);
395 #endif
396  return fe_nethost_space_set_state(a_spaceIndex,a_key,a_property,&a_value,1);
397 }
398 
399 template <class T>
400 int fe_nethost_space_set_state(int a_spaceIndex,
401  const char* a_key,const T a_value)
402 {
403 #if FE_SPACE_VERBOSE
404  printf("fe_nethost_space_set_state<%s> %d \"%s\"\n",
405  typeid(T).name(),a_spaceIndex,a_key);
406 #endif
407  return fe_nethost_space_set_state<T>(a_spaceIndex,a_key,"value",a_value);
408 }
409 
410 template <class T>
411 int fe_nethost_space_set_state(int a_spaceIndex,
412  const char* a_key,T* a_value)
413 {
414 #if FE_SPACE_VERBOSE
415  printf("fe_nethost_space_set_state<%s *> %d \"%s\"\n",
416  typeid(T).name(),a_spaceIndex,a_key);
417 #endif
418  return fe_nethost_space_set_state<const T*>(a_spaceIndex,a_key,"value",a_value);
419 }
420 
421 template <class T>
422 int fe_nethost_space_set_state(int a_spaceIndex,
423  const char* a_key,const T* a_values,int a_count)
424 {
425 #if FE_SPACE_VERBOSE
426  printf("fe_nethost_space_set_state<%s *> %d \"%s\" %d\n",
427  typeid(T).name(),a_spaceIndex,a_key,a_count);
428 #endif
429  return fe_nethost_space_set_state(a_spaceIndex,a_key,"value",
430  a_values,a_count);
431 }
432 
433 template <class T>
434 int fe_nethost_space_get_state(int a_spaceIndex,
435  const char* a_key,const char* a_property,T a_value,int a_size,bool a_safe)
436 {
437 #if FE_SPACE_VERBOSE
438  printf("fe_nethost_space_get_state<%s> \"%s\" \"%s\" (NOP)\n",
439  typeid(T).name(),a_key,a_property);
440 #endif
441  return 0;
442 }
443 
444 template <class T>
445 int fe_nethost_space_get_state(int a_spaceIndex,
446  const char* a_key,T a_value,int a_size,bool a_safe)
447 {
448  return fe_nethost_space_get_state(a_spaceIndex,a_key,"value",
449  a_value,a_size,a_safe);
450 }
451 
452 template <class T>
453 int fe_nethost_space_get_state_dynamic(int a_spaceIndex,
454  const char* a_key,const char* a_property,T* a_pPointer,bool a_safe)
455 {
456 #if FE_SPACE_VERBOSE
457  printf("fe_nethost_space_get_state_dynamic<%s> \"%s\" \"%s\" (NOP)\n",
458  typeid(T).name(),a_key,a_property);
459 #endif
460  return 0;
461 }
462 
463 template <class T>
464 int fe_nethost_space_get_state(int a_spaceIndex,
465  const char* a_key,const char* a_property,
466  T* a_values,int a_count,bool a_safe)
467 {
468 #if FE_SPACE_VERBOSE
469  printf("fe_nethost_space_get_state<%s> \"%s\" \"%s\" (NOP)\n",
470  typeid(T).name(),a_key,a_property);
471 #endif
472  return 0;
473 }
474 
475 template <class T>
476 int fe_nethost_space_get_state(int a_spaceIndex,
477  const char* a_key,T* a_values,int a_count,bool a_safe)
478 {
479  return fe_nethost_space_get_state(a_spaceIndex,a_key,"value",
480  a_values,a_count,a_safe);
481 }
482 
483 template <class T>
484 int fe_nethost_space_send_message(int a_spaceIndex,
485  const char* a_key,const T a_value)
486 {
487 #if FE_SPACE_VERBOSE
488  printf("fe_nethost_space_send_message<%s> \"%s\" (NOP)\n",
489  typeid(T).name(),a_key);
490 #endif
491  return 0;
492 }
493 
494 template <class T>
495 T* fe_nethost_space_next_message(int a_spaceIndex,const char* a_key)
496 {
497 #if FE_SPACE_VERBOSE
498  printf("fe_nethost_space_next_message<%s> \"%s\" (NOP)\n",
499  typeid(T).name(),a_key);
500 #endif
501  return 0;
502 }
503 
504 //* bools
505 template <>
506 int fe_nethost_space_set_state(int a_spaceIndex,
507  const char* a_key,const char* a_property,const bool* a_values,int a_count)
508 {
509  return fpFeSpaceSetStateBools() &&
510  fpFeSpaceSetStateBools()(a_spaceIndex,a_key,a_property,
511  a_values,a_count);
512 }
513 
514 template <>
515 int fe_nethost_space_get_state(int a_spaceIndex,
516  const char* a_key,const char* a_property,
517  bool* a_values,int a_count,bool a_safe)
518 {
519  return fpFeSpaceGetStateBools() &&
520  fpFeSpaceGetStateBools()(a_spaceIndex,a_key,a_property,
521  a_values,a_count,a_safe);
522 }
523 
524 //* ints
525 template <>
526 int fe_nethost_space_set_state(int a_spaceIndex,
527  const char* a_key,const char* a_property,const int* a_values,int a_count)
528 {
529  return fpFeSpaceSetStateInts() &&
530  fpFeSpaceSetStateInts()(a_spaceIndex,a_key,a_property,
531  a_values,a_count);
532 }
533 
534 template <>
535 int fe_nethost_space_get_state(int a_spaceIndex,
536  const char* a_key,const char* a_property,
537  int* a_values,int a_count,bool a_safe)
538 {
539  return fpFeSpaceGetStateInts() &&
540  fpFeSpaceGetStateInts()(a_spaceIndex,a_key,a_property,
541  a_values,a_count,a_safe);
542 }
543 
544 //* floats
545 template <>
546 int fe_nethost_space_set_state(int a_spaceIndex,
547  const char* a_key,const char* a_property,const float* a_values,int a_count)
548 {
549  return fpFeSpaceSetStateFloats() &&
550  fpFeSpaceSetStateFloats()(a_spaceIndex,a_key,a_property,
551  a_values,a_count);
552 }
553 
554 template <>
555 int fe_nethost_space_get_state(int a_spaceIndex,
556  const char* a_key,const char* a_property,
557  float* a_values,int a_count,bool a_safe)
558 {
559  return fpFeSpaceGetStateFloats() &&
560  fpFeSpaceGetStateFloats()(a_spaceIndex,a_key,a_property,
561  a_values,a_count,a_safe);
562 }
563 
564 //* string
565 template <>
566 int fe_nethost_space_set_state(int a_spaceIndex,
567  const char* a_key,const char* a_property,const char* a_value)
568 {
569 #if FE_SPACE_VERBOSE
570  printf("fe_nethost_space_set_state<const char*> %d \"%s\" \"%s\" \"%s\"\n",
571  a_spaceIndex,a_key,a_property,a_value);
572 #endif
573  return fpFeSpaceSetStateString() &&
574  fpFeSpaceSetStateString()(a_spaceIndex,a_key,a_property,
575  a_value);
576 }
577 
578 template <>
579 int fe_nethost_space_get_state(int a_spaceIndex,
580  const char* a_key,const char* a_property,
581  char* a_value,int a_size,bool a_safe)
582 {
583  if(!fpFeSpaceGetStateString())
584  {
585  return 0;
586  }
587 
588  char* buffer=
589  fpFeSpaceGetStateString()(a_spaceIndex,a_key,a_property,a_safe);
590  if(!buffer)
591  {
592  return 0;
593  }
594 
595  strncpy(a_value,buffer,a_size-1);
596  a_value[a_size-1]=0;
597 
598  free(buffer);
599  return 1;
600 }
601 
602 template <>
603 int fe_nethost_space_get_state_dynamic(int a_spaceIndex,
604  const char* a_key,const char* a_property,
605  char** a_pValue,bool a_safe)
606 {
607  *a_pValue=NULL;
608 
609  if(!fpFeSpaceGetStateString())
610  {
611  return 0;
612  }
613 
614  char* buffer=
615  fpFeSpaceGetStateString()(a_spaceIndex,a_key,a_property,a_safe);
616 #if FE_SPACE_VERBOSE
617  printf("fe_nethost_space_get_state_dynamic<char*> buffer \"%s\"\n",
618  buffer);
619 #endif
620  if(!buffer)
621  {
622  return 0;
623  }
624 
625  *a_pValue=strdup(buffer);
626 
627  return strlen(*a_pValue);
628 }
629 
630 //* bytes
631 template <>
632 int fe_nethost_space_set_state(int a_spaceIndex,
633  const char* a_key,const char* a_property,
634  const unsigned char* a_value,int a_size)
635 {
636 #if FE_SPACE_VERBOSE
637  printf("fe_nethost_space_set_state<const uchar*> %d \"%s\" \"%s\"\n",
638  a_spaceIndex,a_key,a_property);
639 #endif
640 
641  return fpFeSpaceSetStateBytes() &&
642  fpFeSpaceSetStateBytes()(a_spaceIndex,a_key,a_property,
643  a_value,a_size);
644 }
645 
646 template <>
647 int fe_nethost_space_get_state(int a_spaceIndex,
648  const char* a_key,const char* a_property,
649  unsigned char* a_value,int a_size,bool a_safe)
650 {
651  if(!fpFeSpaceGetStateBytes())
652  {
653  return 0;
654  }
655 
656  int bytesRead(0);
657  unsigned char* buffer=fpFeSpaceGetStateBytes()(
658  a_spaceIndex,a_key,a_property,a_safe,&bytesRead);
659  if(!buffer)
660  {
661  return 0;
662  }
663 
664  int bytesCopied=a_size<bytesRead? a_size: bytesRead;
665  memcpy(a_value,buffer,bytesCopied);
666 
667  free(buffer);
668  return bytesCopied;
669 }
670 
671 template <>
672 int fe_nethost_space_get_state_dynamic(int a_spaceIndex,
673  const char* a_key,const char* a_property,
674  unsigned char** a_pValue,bool a_safe)
675 {
676  *a_pValue=NULL;
677 
678  if(!fpFeSpaceGetStateBytes())
679  {
680  return 0;
681  }
682 
683  int bytesRead(0);
684  unsigned char* buffer=fpFeSpaceGetStateBytes()(
685  a_spaceIndex,a_key,a_property,a_safe,&bytesRead);
686  if(!buffer)
687  {
688  return 0;
689  }
690 
691  *a_pValue=(unsigned char*)malloc(bytesRead);
692  memcpy(*a_pValue,buffer,bytesRead);
693 
694  return bytesRead;
695 }
696 
697 //* message
698 template <>
699 int fe_nethost_space_send_message(int a_spaceIndex,
700  const char* a_key,const char* a_value)
701 {
702  return fpFeSpaceSendMessageString() &&
703  fpFeSpaceSendMessageString()(a_spaceIndex,a_key,a_value);
704 }
705 
706 template <>
707 char* fe_nethost_space_next_message(int a_spaceIndex,const char* a_key)
708 {
709  if(!fpFeSpaceNextMessageString())
710  {
711  return NULL;
712  }
713 
714  return fpFeSpaceNextMessageString()(a_spaceIndex,a_key);
715 }
716 
717 namespace feSym
718 {
719 
720 class Space
721 {
722  public:
723 
724  template <class T>
725  class ScopedBuffer
726  {
727  public:
728  ScopedBuffer(T a_pBuffer,int a_size):
729  m_pBuffer(a_pBuffer),
730  m_size(a_size),
731  m_pCount(&m_countBacking),
732  m_countBacking(1) {}
733 
734  ScopedBuffer(const ScopedBuffer<T>& a_rOther):
735  m_pBuffer(a_rOther.m_pBuffer),
736  m_size(a_rOther.m_size),
737  m_pCount(a_rOther.m_pCount),
738  m_countBacking(-1)
739  { (*m_pCount)++; }
740 
741  ~ScopedBuffer(void)
742  {
743  if(!(--(*m_pCount))) free(m_pBuffer);
744  }
745 
746  const T data(void) const { return m_pBuffer; }
747  int size(void) const { return m_size; }
748 
749  private:
750  T m_pBuffer;
751  int m_size;
752  int* m_pCount;
753  int m_countBacking;
754  };
755 
756  class Atomic
757  {
758  public:
759  Atomic(Space& a_rSpace):
760  m_rSpace(a_rSpace)
761  {
762  if(!m_rSpace.lock())
763  {
764  printf("Space::Atomic::Atomic failed to lock\n");
765  }
766  }
767  Atomic(Space& a_rSpace,int& a_rFlushCount):
768  m_rSpace(a_rSpace)
769  {
770  if(!m_rSpace.lockAfterUpdate(a_rFlushCount,m_spinCount))
771  {
772  printf("Space::Atomic::Atomic failed to lock\n");
773  }
774  }
775  ~Atomic(void)
776  {
777  if(!m_rSpace.unlock())
778  {
779  printf("Space::Atomic::~Atomic failed to unlock\n");
780  }
781  }
782 
783  template <class T>
784  int getState(const char* a_key,const char* a_property,
785  T a_value,int a_size) const
786  { return m_rSpace.getStateUnsafe(a_key,a_property,
787  a_value,a_size); }
788 
789  template <class T>
790  int getState(const char* a_key,T a_value,int a_size) const
791  { return getState(a_key,"value",a_value,a_size); }
792 
793  template <class T>
794  ScopedBuffer<T> getStateScoped(const char* a_key,
795  const char* a_property) const
796  { return m_rSpace.getStateScopedUnsafe<T>(a_key,a_property); }
797 
798  template <class T>
799  ScopedBuffer<T> getStateScoped(const char* a_key) const
800  { return getStateScoped<T>(a_key,"value"); }
801 
802  int spinCount(void) const
803  { return m_spinCount; }
804 
805  private:
806  Space& m_rSpace;
807  int m_spinCount;
808  };
809 
810  Space(int a_spaceIndex):
811  m_spaceIndex(a_spaceIndex) {}
812 
813  int start(void) { return fe_nethost_space_start(m_spaceIndex); }
814  int stop(void) { return fe_nethost_space_stop(m_spaceIndex); }
815 
816  int waitForConnection(void)
817  { return fe_nethost_space_wait_for_connection(m_spaceIndex); }
818 
819  int flush(void) { return fe_nethost_space_flush(m_spaceIndex); }
820 
821  int lock(void) { return fe_nethost_space_lock(m_spaceIndex); }
822  int unlock(void) { return fe_nethost_space_unlock(m_spaceIndex); }
823 
824  int waitForUpdate(int& a_rFlushCount,int& a_rSpins)
825  { return fe_nethost_space_wait_for_update(m_spaceIndex,
826  &a_rFlushCount,&a_rSpins); }
827  int waitForUpdate(int& a_rFlushCount)
828  { int spinCount(0);
829  return fe_nethost_space_wait_for_update(m_spaceIndex,
830  &a_rFlushCount,&spinCount); }
831 
832  int lockAfterUpdate(int& a_rFlushCount,int& a_rSpins)
833  { return fe_nethost_space_lock_after_update(m_spaceIndex,
834  &a_rFlushCount,&a_rSpins); }
835  int lockAfterUpdate(int& a_rFlushCount)
836  { int spinCount(0);
837  return fe_nethost_space_lock_after_update(m_spaceIndex,
838  &a_rFlushCount,&spinCount); }
839 
840  template <class T>
841  int setState(const char* a_key,const char* a_property,const T a_value)
842  { return fe_nethost_space_set_state(m_spaceIndex,a_key,a_property,
843  a_value); }
844 
845  template <class T>
846  int setState(const char* a_key,const T a_value)
847  { return fe_nethost_space_set_state(m_spaceIndex,a_key,a_value); }
848 
849  template <class T>
850  int setState(const char* a_key,const char* a_property,
851  const T a_value,int a_size)
852  { return fe_nethost_space_set_state(m_spaceIndex,a_key,a_property,
853  a_value,a_size); }
854 
855  template <class T>
856  int setState(const char* a_key,const T a_value,int a_size)
857  { return fe_nethost_space_set_state(m_spaceIndex,a_key,
858  a_value,a_size); }
859 
860  template <class T>
861  int getState(const char* a_key,const char* a_property,
862  T a_value,int a_size) const
863  { return fe_nethost_space_get_state(m_spaceIndex,a_key,a_property,
864  a_value,a_size,true); }
865 
866  template <class T>
867  int getState(const char* a_key,T a_value,int a_size) const
868  { return fe_nethost_space_get_state(m_spaceIndex,a_key,
869  a_value,a_size,true); }
870 
871  template <class T>
872  int getStateUnsafe(const char* a_key,const char* a_property,
873  T a_value,int a_size) const
874  { return fe_nethost_space_get_state(m_spaceIndex,
875  a_key,a_property,a_value,a_size,false); }
876 
877  template <class T>
878  ScopedBuffer<T> getStateScoped(const char* a_key,
879  const char* a_property) const
880  {
881  T pPointer(NULL);
882  const int size=
883  fe_nethost_space_get_state_dynamic<T>(m_spaceIndex,
884  a_key,a_property,&pPointer,true);
885  return ScopedBuffer<T>(pPointer,size);
886  }
887 
888  template <class T>
889  ScopedBuffer<T> getStateScoped(const char* a_key) const
890  { return getStateScoped<T>(a_key,"value"); }
891 
892  template <class T>
893  ScopedBuffer<T> getStateScopedUnsafe(const char* a_key,
894  const char* a_property) const
895  {
896  T pPointer(NULL);
897  const int size=
898  fe_nethost_space_get_state_dynamic<T>(m_spaceIndex,
899  a_key,a_property,&pPointer,false);
900  return ScopedBuffer<T>(pPointer,size);
901  }
902 
903  template <class T>
904  ScopedBuffer<T> getStateScopedUnsafe(const char* a_key) const
905  { return getStateScopedUnsafe<T>(a_key,"value"); }
906 
907  template <class T>
908  int sendMessage(const char* a_key,const T* a_value)
909  { return fe_nethost_space_send_message(m_spaceIndex,
910  a_key,a_value); }
911 
912  private:
913  int m_spaceIndex;
914 };
915 
916 inline Space accessSpace(const char* a_name,
917  const char* a_implementation="*.NetworkCatalog")
918 {
919  return Space(fe_nethost_access_space(a_name,a_implementation));
920 }
921 
922 }
U32 size(const DenseVector< T > &lhs)
Return number of elements.
Definition: DenseVector.h:587
Definition: nethost_loader.h:717