BEAST/BSE - Better Audio System and Sound Engine  0.9.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
sficxx.hh
Go to the documentation of this file.
1  // Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
2 #ifndef __SFI_CXX_H__
3 #define __SFI_CXX_H__
4 #include <sfi/sfi.hh>
5 #include <string>
6 #include <string.h>
7 #include <new>
8 
10 namespace Sfi {
11 typedef SfiBool Bool; // FIXME: use bool instead?
12 typedef SfiInt Int;
13 typedef SfiNum Num;
14 typedef SfiReal Real;
15 class String {
16  char *cstring;
17  int cmp (const char *ostring) const
18  {
19  if (cstring && ostring)
20  return strcmp (cstring, ostring);
21  else if (cstring)
22  return +SFI_MAXINT;
23  else
24  return ostring ? SFI_MININT : 0;
25  }
26 public:
27  String()
28  {
29  cstring = g_strdup ("");
30  }
31  String (const String &s)
32  {
33  cstring = g_strdup (s.cstring);
34  }
35  String (const std::string &s)
36  {
37  cstring = g_strdup (s.c_str());
38  }
39  String (const char *cstr)
40  {
41  cstring = g_strdup (cstr ? cstr : "");
42  }
43  String& operator= (const std::string &s)
44  {
45  g_free (cstring);
46  cstring = g_strdup (s.c_str());
47  return *this;
48  }
49  String& operator= (const gchar *cstr)
50  {
51  if (cstr != cstring)
52  {
53  g_free (cstring);
54  cstring = g_strdup (cstr ? cstr : "");
55  }
56  return *this;
57  }
58  String& operator= (const String &s)
59  {
60  if (s.cstring != cstring)
61  {
62  g_free (cstring);
63  cstring = g_strdup (s.cstring);
64  }
65  return *this;
66  }
67  const char* c_str() const
68  {
69  return cstring;
70  }
71  String& operator+= (const gchar *cstr)
72  {
73  char *old = cstring;
74  cstring = g_strconcat (old ? old : "", cstr, NULL);
75  g_free (old);
76  return *this;
77  }
78  String& operator+= (const String &src)
79  {
80  char *old = cstring;
81  cstring = g_strconcat (old ? old : "", src.cstring, NULL);
82  g_free (old);
83  return *this;
84  }
85  String& operator+= (const std::string &src)
86  {
87  char *old = cstring;
88  cstring = g_strconcat (old ? old : "", src.c_str(), NULL);
89  g_free (old);
90  return *this;
91  }
92  String operator+ (const gchar *cstr)
93  {
94  return String (cstring) += cstr;
95  }
96  String operator+ (const String &src)
97  {
98  return String (cstring) += src;
99  }
100  String operator+ (const std::string &src)
101  {
102  return String (cstring) += src;
103  }
104  bool operator< (const char *src) const { return cmp (src) < 0; }
105  bool operator<= (const char *src) const { return cmp (src) <= 0; }
106  bool operator> (const char *src) const { return cmp (src) > 0; }
107  bool operator>= (const char *src) const { return cmp (src) >= 0; }
108  bool operator!= (const char *src) const { return cmp (src) != 0; }
109  bool operator== (const char *src) const { return cmp (src) == 0; }
110  bool operator< (const String &s) const { return cmp (s.cstring) < 0; }
111  bool operator<= (const String &s) const { return cmp (s.cstring) <= 0; }
112  bool operator> (const String &s) const { return cmp (s.cstring) > 0; }
113  bool operator>= (const String &s) const { return cmp (s.cstring) >= 0; }
114  bool operator!= (const String &s) const { return cmp (s.cstring) != 0; }
115  bool operator== (const String &s) const { return cmp (s.cstring) == 0; }
116  bool operator< (const std::string &s) const { return cmp (s.c_str()) < 0; }
117  bool operator<= (const std::string &s) const { return cmp (s.c_str()) <= 0; }
118  bool operator> (const std::string &s) const { return cmp (s.c_str()) > 0; }
119  bool operator>= (const std::string &s) const { return cmp (s.c_str()) >= 0; }
120  bool operator!= (const std::string &s) const { return cmp (s.c_str()) != 0; }
121  bool operator== (const std::string &s) const { return cmp (s.c_str()) == 0; }
122  unsigned int length()
123  {
124  return cstring ? strlen (cstring) : 0;
125  }
126  ~String()
127  {
128  g_free (cstring);
129  }
130  /* provide GValue accessors */
131  static String value_get_string (const GValue *value)
132  {
133  return sfi_value_get_string (value);
134  }
135  static void value_set_string (GValue *value,
136  const String& str)
137  {
138  sfi_value_set_string (value, str.c_str());
139  }
140 };
141 
142 struct GNewable {
143  gpointer operator new (size_t s)
144  {
145  return g_malloc0 (s);
146  }
147  void operator delete (gpointer mem)
148  {
149  g_free (mem);
150  }
151  gpointer operator new[] (size_t s)
152  {
153  return g_malloc0 (s);
154  }
155  void operator delete[] (gpointer mem)
156  {
157  g_free (mem);
158  }
159 };
160 
161 typedef enum {
162  INIT_NULL,
163  INIT_EMPTY,
164  INIT_DEFAULT,
165 } InitializationType;
166 
167 template<typename Type>
169  Type *record;
170  typedef Type BoxedType;
171 public:
172  RecordHandle (InitializationType t = INIT_NULL)
173  {
174  record = NULL;
175  if (t == INIT_DEFAULT || t == INIT_EMPTY)
176  record = new Type();
177  }
178  RecordHandle (const RecordHandle &rh)
179  {
180  if (rh.record)
181  record = new Type (*rh.record);
182  else
183  record = NULL;
184  }
185  RecordHandle (const Type &rec)
186  {
187  record = new Type (rec);
188  }
189  RecordHandle& operator= (const Type &rec)
190  {
191  if (record != &rec)
192  {
193  delete record;
194  record = new Type (rec);
195  }
196  return *this;
197  }
198  void set_boxed (Type *rec)
199  {
200  delete record;
201  if (rec)
202  record = new Type (*rec);
203  else
204  record = NULL;
205  }
206  void take (Type *rec)
207  {
208  delete record;
209  record = rec;
210  }
211  Type* steal ()
212  {
213  Type *t = record;
214  record = NULL;
215  return t;
216  }
217  Type* c_ptr() const
218  {
219  return record;
220  }
221  RecordHandle& operator= (const RecordHandle &src)
222  {
223  if (record != src.record)
224  {
225  delete record;
226  if (src.record)
227  record = new Type (*src.record);
228  else
229  record = NULL;
230  }
231  return *this;
232  }
233  ~RecordHandle()
234  {
235  delete record;
236  }
237  Type*
238  operator-> ()
239  {
240  return record;
241  }
242  const Type*
243  operator-> () const
244  {
245  return record;
246  }
247  Type&
248  operator* ()
249  {
250  return *record;
251  }
252  const Type&
253  operator* () const
254  {
255  return *record;
256  }
257  Type& operator[] (unsigned int index)
258  {
259  if (index)
260  g_critical ("%s: invalid array subscript: %u", G_STRFUNC, index);
261  return *(index ? NULL : record);
262  }
263  bool is_null() const
264  {
265  return !record;
266  }
267  operator bool () const
268  {
269  return !is_null();
270  }
271  static gpointer
272  boxed_copy (gpointer data)
273  {
274  if (data)
275  {
276  Type *r = reinterpret_cast<Type*> (data);
277  RecordHandle rh (*r);
278  return rh.steal();
279  }
280  return NULL;
281  }
282  static void
283  boxed_free (gpointer data)
284  {
285  if (data)
286  {
287  Type *r = reinterpret_cast<Type*> (data);
288  RecordHandle rh;
289  rh.take (r);
290  }
291  }
292  static RecordHandle
293  value_get_boxed (const GValue *value)
294  {
295  if (SFI_VALUE_HOLDS_REC (value))
296  {
297  SfiRec *rec = sfi_value_get_rec (value);
298  RecordHandle rh = Type::from_rec (rec);
299  return rh;
300  }
301  else
302  {
303  Type *boxed = reinterpret_cast<Type*> (g_value_get_boxed (value));
304  if (boxed)
305  return *boxed;
306  else
307  return INIT_NULL;
308  }
309  }
310  static void
311  value_set_boxed (GValue *value,
312  const RecordHandle &self)
313  {
314  if (SFI_VALUE_HOLDS_REC (value))
315  {
316  SfiRec *rec = Type::to_rec (self);
317  sfi_value_take_rec (value, rec);
318  }
319  else
320  g_value_set_boxed (value, self.c_ptr());
321  }
322 };
323 
324 template<typename Type>
325 class Sequence {
326 public:
327  typedef Type* iterator;
328  typedef const Type* const_iterator;
329  struct CSeq {
330  unsigned int n_elements;
331  Type *elements;
332  };
333  typedef CSeq BoxedType;
334 private:
335  CSeq *cseq;
336 public:
337  Sequence (unsigned int n = 0)
338  {
339  cseq = g_new0 (CSeq, 1);
340  resize (n);
341  }
342  Sequence (const Sequence &sh)
343  {
344  cseq = g_new0 (CSeq, 1);
345  *this = sh;
346  }
347  Sequence (const BoxedType &cs)
348  {
349  cseq = g_new0 (CSeq, 1);
350  set_boxed (&cs);
351  }
352  iterator
353  begin()
354  {
355  return cseq->elements;
356  }
357  const_iterator
358  begin() const
359  {
360  return cseq->elements;
361  }
362  iterator
363  end()
364  {
365  return cseq->elements + cseq->n_elements;
366  }
367  const_iterator
368  end() const
369  {
370  return cseq->elements + cseq->n_elements;
371  }
372  void
373  take (CSeq *cs)
374  {
375  resize (0);
376  if (cs)
377  {
378  g_free (cseq->elements);
379  g_free (cseq);
380  cseq = cs;
381  /* a take(); steal(); sequence needs to preserve pointer */
382  }
383  }
384  CSeq*
385  steal ()
386  {
387  CSeq *cs = cseq;
388  cseq = g_new0 (CSeq, 1);
389  resize (0);
390  /* a take(); steal(); sequence needs to preserve pointer */
391  return cs;
392  }
393  CSeq*
394  c_ptr() const
395  {
396  return cseq;
397  }
398  void
399  resize (unsigned int n)
400  {
401  guint i;
402  // Note that this does *not* use an explicit copy-constructor call to relocate existing elements
403  for (i = n; i < length(); i++)
404  cseq->elements[i].~Type();
405  i = cseq->n_elements;
406  cseq->n_elements = n;
407  cseq->elements = g_renew (Type, cseq->elements, cseq->n_elements);
408  for (; i < length(); i++)
409  new (cseq->elements + i) Type ();
410  }
411  Type&
412  operator[] (unsigned int index)
413  {
414  if (index >= cseq->n_elements)
415  g_critical ("%s: invalid array subscript: %u", G_STRFUNC, index);
416  return cseq->elements[index];
417  }
418  const Type&
419  operator[] (unsigned int index) const
420  {
421  if (index >= cseq->n_elements)
422  g_critical ("%s: invalid array subscript: %u", G_STRFUNC, index);
423  return cseq->elements[index];
424  }
425  Sequence&
426  operator+= (const Type &elm)
427  {
428  // Note that this does *not* use an explicit copy-constructor call to relocate existing elements
429  guint i = cseq->n_elements++;
430  cseq->elements = g_renew (Type, cseq->elements, cseq->n_elements);
431  new (cseq->elements + i) Type (elm);
432  return *this;
433  }
434  void
435  set_boxed (const CSeq *cs)
436  {
437  if (cseq == cs)
438  return;
439  resize (0);
440  if (!cs)
441  return;
442  cseq->n_elements = cs->n_elements;
443  cseq->elements = g_renew (Type, cseq->elements, cseq->n_elements);
444  for (guint i = 0; i < length(); i++)
445  new (cseq->elements + i) Type (cs->elements[i]);
446  }
447  Sequence&
448  operator= (const Sequence &sh)
449  {
450  set_boxed (sh.cseq);
451  return *this;
452  }
453  unsigned int
454  length() const
455  {
456  return cseq ? cseq->n_elements : 0;
457  }
458  ~Sequence()
459  {
460  resize (0);
461  g_free (cseq->elements);
462  g_free (cseq);
463  }
464  static gpointer
465  boxed_copy (gpointer data)
466  {
467  if (data)
468  {
469  CSeq *cs = reinterpret_cast<CSeq*> (data);
470  Sequence s (*cs);
471  return s.steal();
472  }
473  return NULL;
474  }
475  static void
476  boxed_free (gpointer data)
477  {
478  if (data)
479  {
480  CSeq *cs = reinterpret_cast<CSeq*> (data);
481  Sequence s;
482  s.take (cs);
483  }
484  }
485 };
486 template<typename SeqType> SeqType
487 cxx_value_get_boxed_sequence (const GValue *value)
488 {
489  if (SFI_VALUE_HOLDS_SEQ (value))
490  {
491  SfiSeq *seq = sfi_value_get_seq (value);
492  return SeqType::from_seq (seq);
493  }
494  else
495  {
496  typename SeqType::CSeq *boxed = reinterpret_cast<typename SeqType::CSeq*> (g_value_get_boxed (value));
497  if (boxed)
498  {
499  SeqType sh;
500  sh.set_boxed (boxed);
501  return sh;
502  }
503  else
504  return SeqType();
505  }
506 }
507 template<typename SeqType> void
508 cxx_value_set_boxed_sequence (GValue *value,
509  const SeqType &self)
510 {
511  if (SFI_VALUE_HOLDS_SEQ (value))
512  {
513  SfiSeq *seq = SeqType::to_seq (self);
514  sfi_value_take_seq (value, seq);
515  }
516  else
517  g_value_set_boxed (value, self.c_ptr());
518 }
519 
520 class FBlock {
521  SfiFBlock *block;
522 public:
523  typedef float* iterator;
524  typedef const float* const_iterator;
525  FBlock (unsigned int length = 0)
526  {
527  block = sfi_fblock_new_sized (length);
528  }
529  FBlock (SfiFBlock &fblock)
530  {
531  block = NULL;
532  *this = fblock;
533  }
534  FBlock (unsigned int length,
535  const float *values)
536  {
537  block = sfi_fblock_new();
538  sfi_fblock_append (block, length, values);
539  }
540  FBlock (const FBlock &fb)
541  {
542  if (fb.block)
543  block = sfi_fblock_ref (fb.block);
544  else
545  block = sfi_fblock_new();
546  }
547  iterator
548  begin()
549  {
550  return block ? block->values : NULL;
551  }
552  const_iterator
553  begin() const
554  {
555  return block ? block->values : NULL;
556  }
557  iterator
558  end()
559  {
560  return block ? block->values + block->n_values : NULL;
561  }
562  const_iterator
563  end() const
564  {
565  return block ? block->values + block->n_values : NULL;
566  }
567  FBlock&
568  operator= (SfiFBlock &fb)
569  {
570  if (block != &fb)
571  {
572  if (block)
573  sfi_fblock_unref (block);
574  block = &fb;
575  if (block)
576  sfi_fblock_ref (block);
577  }
578  return *this;
579  }
580  FBlock&
581  operator= (const FBlock &s)
582  {
583  if (block != s.block)
584  {
585  if (block)
586  sfi_fblock_unref (block);
587  block = s.block;
588  if (block)
589  sfi_fblock_ref (block);
590  }
591  return *this;
592  }
593  SfiFBlock*
594  fblock()
595  {
596  return block;
597  }
598  ~FBlock()
599  {
600  if (block)
601  sfi_fblock_unref (block);
602  }
603  void
604  ref ()
605  {
606  if (!block)
607  block = sfi_fblock_new();
608  sfi_fblock_ref (block);
609  }
610  void
611  unref ()
612  {
613  g_return_if_fail (block != NULL && block->ref_count > 1);
614  sfi_fblock_unref (block);
615  }
616  void
617  resize (unsigned int length)
618  {
619  if (block)
620  sfi_fblock_resize (block, length);
621  else
622  block = sfi_fblock_new_sized (length);
623  }
624  void
625  take (SfiFBlock *fb)
626  {
627  if (block)
628  sfi_fblock_unref (block);
629  block = fb;
630  }
631  FBlock
632  copy_deep()
633  {
634  if (block)
635  return FBlock (block->n_values, block->values);
636  else
637  return FBlock (0);
638  }
639  FBlock
640  copy_shallow()
641  {
642  return FBlock (*this);
643  }
644  void
645  append (unsigned int length,
646  const float *values)
647  {
648  if (!block)
649  block = sfi_fblock_new();
650  sfi_fblock_append (block, length, values);
651  }
652  void
653  append (float f)
654  {
655  append (1, &f);
656  }
657  unsigned int
658  length()
659  {
660  return block ? block->n_values : 0;
661  }
662  const float*
663  get()
664  {
665  return block ? block->values : NULL;
666  }
667  static FBlock
668  value_get_fblock (const GValue *value)
669  {
670  SfiFBlock *fb = sfi_value_get_fblock (value);
671  FBlock self (0);
672  if (fb)
673  self.take (sfi_fblock_ref (fb));
674  return self;
675  }
676  static void
677  value_set_fblock (GValue *value,
678  const FBlock &self)
679  {
680  sfi_value_set_fblock (value, self.block);
681  }
682 };
683 
684 class BBlock {
685  SfiBBlock *block;
686 public:
687  BBlock (unsigned int length = 0)
688  {
689  block = sfi_bblock_new_sized (length);
690  }
691  BBlock (SfiBBlock &bblock)
692  {
693  block = NULL;
694  *this = bblock;
695  }
696  BBlock (unsigned int length,
697  const guint8 *bytes)
698  {
699  block = sfi_bblock_new();
700  sfi_bblock_append (block, length, bytes);
701  }
702  BBlock (const BBlock &bb)
703  {
704  if (bb.block)
705  block = sfi_bblock_ref (bb.block);
706  else
707  block = sfi_bblock_new();
708  }
709  BBlock&
710  operator= (SfiBBlock &bb)
711  {
712  if (block != &bb)
713  {
714  if (block)
715  sfi_bblock_unref (block);
716  block = &bb;
717  if (block)
718  sfi_bblock_ref (block);
719  }
720  return *this;
721  }
722  BBlock&
723  operator= (const BBlock &s)
724  {
725  if (block != s.block)
726  {
727  if (block)
728  sfi_bblock_unref (block);
729  block = s.block;
730  if (block)
731  sfi_bblock_ref (block);
732  }
733  return *this;
734  }
735  SfiBBlock* bblock()
736  {
737  return block;
738  }
739  ~BBlock()
740  {
741  if (block)
742  sfi_bblock_unref (block);
743  }
744  void
745  ref ()
746  {
747  if (!block)
748  block = sfi_bblock_new();
749  sfi_bblock_ref (block);
750  }
751  void
752  unref ()
753  {
754  g_return_if_fail (block != NULL && block->ref_count > 1);
755  sfi_bblock_unref (block);
756  }
757  void resize (unsigned int length)
758  {
759  if (block)
760  sfi_bblock_resize (block, length);
761  else
762  block = sfi_bblock_new_sized (length);
763  }
764  void
765  take (SfiBBlock *bb)
766  {
767  if (block)
768  sfi_bblock_unref (block);
769  block = bb;
770  }
771  BBlock copy_deep()
772  {
773  if (block)
774  return BBlock (block->n_bytes, block->bytes);
775  else
776  return BBlock (0);
777  }
778  BBlock copy_shallow()
779  {
780  return BBlock (*this);
781  }
782  void append (unsigned int length,
783  const guint8 *bytes)
784  {
785  if (!block)
786  block = sfi_bblock_new();
787  sfi_bblock_append (block, length, bytes);
788  }
789  void append (guint8 b)
790  {
791  append (1, &b);
792  }
793  unsigned int length()
794  {
795  return block ? block->n_bytes : 0;
796  }
797  const guint8* get()
798  {
799  return block ? block->bytes : NULL;
800  }
801  static BBlock value_get_bblock (const GValue *value)
802  {
803  SfiBBlock *bb = sfi_value_get_bblock (value);
804  BBlock self (0);
805  if (bb)
806  self.take (sfi_bblock_ref (bb));
807  return self;
808  }
809  static void value_set_bblock (GValue *value,
810  const BBlock &self)
811  {
812  sfi_value_set_bblock (value, self.block);
813  }
814 };
815 
816 class Rec {
817  SfiRec *crec;
818 public:
819  Rec ()
820  {
821  crec = NULL;
822  }
823  Rec (SfiRec &sr)
824  {
825  crec = NULL;
826  *this = sr;
827  }
828  Rec (const Rec &rr)
829  {
830  if (rr.crec)
831  crec = sfi_rec_ref (rr.crec);
832  else
833  crec = NULL;
834  }
835  void clear ()
836  {
837  if (crec)
838  sfi_rec_clear (crec);
839  }
840  Rec&
841  operator= (SfiRec &sr)
842  {
843  if (crec != &sr)
844  {
845  if (crec)
846  sfi_rec_unref (crec);
847  crec = &sr;
848  if (crec)
849  sfi_rec_ref (crec);
850  }
851  return *this;
852  }
853  Rec&
854  operator= (const Rec &rr)
855  {
856  if (crec != rr.crec)
857  {
858  if (crec)
859  sfi_rec_unref (crec);
860  crec = rr.crec;
861  if (crec)
862  sfi_rec_ref (crec);
863  }
864  return *this;
865  }
866  SfiRec* rec()
867  {
868  return crec;
869  }
870  ~Rec()
871  {
872  if (crec)
873  sfi_rec_unref (crec);
874  }
875  void
876  ref ()
877  {
878  if (!crec)
879  crec = sfi_rec_new();
880  sfi_rec_ref (crec);
881  }
882  void
883  unref ()
884  {
885  g_return_if_fail (crec != NULL && crec->ref_count > 1);
886  sfi_rec_unref (crec);
887  }
888  void
889  take (SfiRec *sr)
890  {
891  if (crec)
892  sfi_rec_unref (crec);
893  crec = sr;
894  }
895  Rec copy_deep()
896  {
897  if (crec)
898  return Rec (*sfi_rec_copy_deep (crec));
899  else
900  return Rec ();
901  }
902  Rec copy_shallow()
903  {
904  return Rec (*this);
905  }
906  void set (const gchar *field_name,
907  const GValue *value)
908  {
909  if (!crec)
910  crec = sfi_rec_new();
911  sfi_rec_set (crec, field_name, value);
912  }
913  unsigned int length()
914  {
915  return crec ? crec->n_fields : 0;
916  }
917  GValue* get (const gchar *name)
918  {
919  return crec ? sfi_rec_get (crec, name) : NULL;
920  }
921  static Rec value_get_rec (const GValue *value)
922  {
923  SfiRec *sr = sfi_value_get_rec (value);
924  Rec self;
925  if (sr)
926  self.take (sfi_rec_ref (sr));
927  return self;
928  }
929  static void value_set_rec (GValue *value,
930  const Rec &self)
931  {
932  sfi_value_set_rec (value, self.crec);
933  }
934 };
935 
937  GObject *cobj;
938 public:
939  ObjectHandle ()
940  {
941  cobj = NULL;
942  }
943  ObjectHandle (GObject &object)
944  {
945  cobj = NULL;
946  *this = object;
947  }
948  ObjectHandle (const ObjectHandle &oh)
949  {
950  if (oh.cobj)
951  cobj = (GObject*) g_object_ref (oh.cobj);
952  else
953  cobj = NULL;
954  }
955  ~ObjectHandle()
956  {
957  if (cobj)
958  g_object_unref (cobj);
959  }
960  ObjectHandle& operator= (GObject &object)
961  {
962  if (cobj != &object)
963  {
964  if (cobj)
965  g_object_unref (cobj);
966  cobj = &object;
967  if (cobj)
968  g_object_ref (cobj);
969  }
970  return *this;
971  }
972  ObjectHandle& operator= (const ObjectHandle &oh)
973  {
974  if (cobj != oh.cobj)
975  {
976  if (cobj)
977  g_object_unref (cobj);
978  cobj = oh.cobj;
979  if (cobj)
980  g_object_ref (cobj);
981  }
982  return *this;
983  }
984  GObject* object()
985  {
986  return cobj;
987  }
988  void
989  ref ()
990  {
991  g_return_if_fail (cobj != NULL && cobj->ref_count > 0);
992  g_object_ref (cobj);
993  }
994  void
995  unref ()
996  {
997  g_return_if_fail (cobj != NULL && cobj->ref_count > 1);
998  g_object_unref (cobj);
999  }
1000  void
1001  take (GObject *object)
1002  {
1003  if (cobj)
1004  g_object_unref (cobj);
1005  cobj = object;
1006  }
1007  ObjectHandle copy_deep()
1008  {
1009  if (cobj)
1010  return ObjectHandle (*cobj);
1011  else
1012  return ObjectHandle ();
1013  }
1014  ObjectHandle copy_shallow()
1015  {
1016  return ObjectHandle (*this);
1017  }
1018  static ObjectHandle value_get (const GValue *value)
1019  {
1020  GObject *object = (GObject*) g_value_get_object (value);
1021  ObjectHandle self;
1022  if (object)
1023  self.take ((GObject*) g_object_ref (object));
1024  return self;
1025  }
1026  static void value_set (GValue *value,
1027  const ObjectHandle &self)
1028  {
1029  g_value_set_object (value, self.cobj);
1030  }
1031 };
1032 
1033 template<typename Type> void
1034 cxx_boxed_to_rec (const GValue *src_value,
1035  GValue *dest_value)
1036 {
1037  SfiRec *rec = NULL;
1038  gpointer boxed = g_value_get_boxed (src_value);
1039  if (boxed)
1040  {
1041  Type *t = reinterpret_cast<Type*> (boxed);
1042  rec = Type::to_rec (*t);
1043  }
1044  sfi_value_take_rec (dest_value, rec);
1045 }
1046 
1047 template<typename Type> void
1048 cxx_boxed_from_rec (const GValue *src_value,
1049  GValue *dest_value)
1050 {
1051  gpointer boxed = NULL;
1052  SfiRec *rec = sfi_value_get_rec (src_value);
1053  if (rec)
1054  {
1055  RecordHandle<Type> rh = Type::from_rec (rec);
1056  Type *t = rh.steal();
1057  boxed = t;
1058  }
1059  g_value_take_boxed (dest_value, boxed);
1060 }
1061 
1062 template<typename SeqType> void
1063 cxx_boxed_to_seq (const GValue *src_value,
1064  GValue *dest_value)
1065 {
1066  SfiSeq *seq = NULL;
1067  gpointer boxed = g_value_get_boxed (src_value);
1068  if (boxed)
1069  {
1070  typename SeqType::CSeq *t = reinterpret_cast<typename SeqType::CSeq*> (boxed);
1071  SeqType cxxseq;
1072  cxxseq.take(t); /* temporarily re-own */
1073  seq = SeqType::to_seq (cxxseq);
1074  cxxseq.steal(); /* get back */
1075  }
1076  sfi_value_take_seq (dest_value, seq);
1077 }
1078 
1079 template<typename SeqType> void
1080 cxx_boxed_from_seq (const GValue *src_value,
1081  GValue *dest_value)
1082 {
1083  gpointer boxed = NULL;
1084  SfiSeq *seq = sfi_value_get_seq (src_value);
1085  if (seq)
1086  {
1087  SeqType sh = SeqType::from_seq (seq);
1088  typename SeqType::CSeq *t = sh.steal();
1089  boxed = t;
1090  }
1091  g_value_take_boxed (dest_value, boxed);
1092 }
1093 
1094 template<typename Type> RecordHandle<Type>
1095 cxx_value_get_rec (const GValue *value)
1096 {
1097  SfiRec *rec = sfi_value_get_rec (value);
1098  if (rec)
1099  return Type::from_rec (rec);
1100  else
1101  return INIT_NULL;
1102 }
1103 
1104 template<typename Type> void
1105 cxx_value_set_rec (GValue *value,
1106  const RecordHandle<Type> &self)
1107 {
1108  if (self)
1109  sfi_value_take_rec (value, Type::to_rec (self));
1110  else
1111  sfi_value_set_rec (value, NULL);
1112 }
1113 
1114 template<typename SeqType> SeqType
1115 cxx_value_get_seq (const GValue *value)
1116 {
1117  SfiSeq *seq = sfi_value_get_seq (value);
1118  if (seq)
1119  return SeqType::from_seq (seq);
1120  else
1121  return SeqType();
1122 }
1123 
1124 template<typename SeqType> void
1125 cxx_value_set_seq (GValue *value,
1126  const SeqType &self)
1127 {
1128  sfi_value_take_seq (value, SeqType::to_seq (self));
1129 }
1130 
1131 // == C++ Auxillaries ==
1132 struct Init { // stolen from Rapicorn
1133  explicit Init (void (*f) ()) { f(); }
1134 };
1135 
1136 } // Sfi
1137 
1138 #endif /* __SFI_CXX_H__ */
1139 
1140 /* vim:set ts=8 sts=2 sw=2: */
Definition: sficxx.hh:816
Definition: sficxx.hh:15
Definition: sficxx.hh:684
Definition: sficxx.hh:329
strlen
Definition: sficxx.hh:325
strcmp
Definition: sficxx.hh:520
Definition: sficxx.hh:1132
Definition: sficxx.hh:168
Definition: sficxx.hh:936
Definition: sficxx.hh:142