LV2 Toolkit  1.2.0
atom.hpp
1 /*
2  atom.hpp - support file for writing LV2 plugins in C++
3  Copyright (C) 2012 Michael Fisher <mfisher31@gmail.com>
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA
18 */
19 
25 #ifndef LVTK_ATOM_HPP
26 #define LVTK_ATOM_HPP
27 
28 #include <string>
29 
30 #include <lv2/lv2plug.in/ns/ext/atom/atom.h>
31 #include <lv2/lv2plug.in/ns/ext/atom/forge.h>
32 #include <lv2/lv2plug.in/ns/ext/atom/util.h>
33 
34 namespace lvtk {
35 
37  typedef LV2_Atom_Event AtomEvent;
38  typedef LV2_Atom_Property_Body PropertyBody;
39  typedef LV2_Atom_Forge_Frame ForgeFrame;
40  typedef LV2_Atom_Forge_Ref ForgeRef;
41  typedef LV2_Atom_Object_Query ObjectQuery;
42 
43 
46  struct AtomObject
47  {
49  AtomObject (const void* atom) : p_obj ((LV2_Atom_Object*) atom) { }
50 
52  AtomObject (ForgeRef ref) : p_obj ((LV2_Atom_Object*) ref) { }
53 
54  AtomObject (const AtomObject& other) : p_obj (other.p_obj) { }
55 
57  inline uint32_t
58  otype() const
59  {
60  return p_obj->body.otype;
61  }
62 
64  inline uint32_t
65  id() const
66  {
67  return p_obj->body.id;
68  }
69 
71  inline uint32_t
72  total_size() const
73  {
74  return lv2_atom_total_size ((LV2_Atom*) p_obj);
75  }
76 
88  inline void
89  query (ObjectQuery& query)
90  {
91  lv2_atom_object_query (p_obj, &query);
92  }
93 
95  inline LV2_Atom_Object* cobj() const { return p_obj; }
96 
98  inline operator LV2_Atom_Object*() { return p_obj; }
99 
101  inline AtomObject&
102  operator= (const AtomObject& other)
103  {
104  p_obj = other.p_obj;
105  return *this;
106  }
107 
109  class iterator
110  {
111  public:
112 
113  iterator (LV2_Atom_Object* o, LV2_Atom_Property_Body* i)
114  : index (i), obj (o) { }
115 
116  const PropertyBody& operator*() const { assert (index); return *index; }
117  const PropertyBody* operator->() const { assert (index); return index; }
118 
119  iterator& operator++()
120  {
121  index = lv2_atom_object_next (index);
122  if (lv2_atom_object_is_end (&obj->body, obj->atom.size, index))
123  index = 0;
124  return *this;
125  }
126 
127  iterator operator++(int)
128  {
129  iterator ret (obj, index);
130  ++(*this);
131  return ret;
132  }
133 
134  bool operator== (const iterator& other) const { return index == other.index; }
135  bool operator!= (const iterator& other) const { return index != other.index; }
136 
137  private:
138 
139  friend class AtomObject;
140  LV2_Atom_Property_Body* index;
141  LV2_Atom_Object* obj;
142 
143  };
144 
145  iterator begin() const { return iterator (p_obj, lv2_atom_object_begin (&p_obj->body)); }
146  iterator end() const { return iterator (p_obj, 0); }
147 
148  private:
149 
150  LV2_Atom_Object* p_obj;
151 
152  };
153 
154 
157  struct Atom
158  {
160  Atom () : p_atom (0) { }
161 
163  Atom (const void* atom) : p_atom ((LV2_Atom*) atom) { }
164 
166  Atom (ForgeRef ref) : p_atom ((LV2_Atom*) ref) { }
167 
169  Atom (AtomEvent* ev) : p_atom (&ev->body) { }
170 
172  inline static uint32_t
173  pad_size (uint32_t size)
174  {
175  return lv2_atom_pad_size (size);
176  }
177 
179  inline bool
181  {
182  return lv2_atom_is_null (p_atom);
183  }
184 
186  inline void*
187  body() const
188  {
189  return LV2_ATOM_BODY (p_atom);
190  }
191 
193  inline bool
194  as_bool() const
195  {
196  return ((LV2_Atom_Bool*)p_atom)->body > 0;
197  }
198 
200  inline float
201  as_float() const
202  {
203  return ((LV2_Atom_Float*)p_atom)->body;
204  }
205 
207  const AtomObject
208  as_object() const {
209  return AtomObject ((LV2_Atom_Object* ) p_atom);
210  }
211 
213  inline const char*
214  as_string() const
215  {
216  return (const char*) LV2_ATOM_BODY (p_atom);
217  }
218 
220  inline int32_t
221  as_int() const
222  {
223  return ((LV2_Atom_Int*)p_atom)->body;
224  }
225 
227  inline int64_t
228  as_long() const
229  {
230  return ((LV2_Atom_Long*)p_atom)->body;
231  }
232 
234  inline uint32_t
235  as_urid() const
236  {
237  return ((LV2_Atom_URID*)p_atom)->body;
238  }
241  inline uint32_t
242  type() const
243  {
244  return p_atom->type;
245  }
246 
248  inline uint32_t
249  total_size() const
250  {
251  return lv2_atom_total_size (p_atom);
252  }
253 
255  inline uint32_t
256  size() const
257  {
258  return p_atom->size;
259  }
260 
262  inline const LV2_Atom*
263  cobj() const
264  {
265  return p_atom;
266  }
267 
269  inline operator const LV2_Atom*() { return cobj(); }
270 
272  inline Atom&
273  operator= (const Atom& other)
274  {
275  p_atom = other.p_atom;
276  return *this;
277  }
278 
280  inline bool
281  operator== (Atom& other)
282  {
283  return lv2_atom_equals (cobj(), other.cobj());
284  }
285 
286  private:
287 
288  const LV2_Atom* p_atom;
289  friend class AtomObject;
290 
291  };
292 
293 
296  {
297  typedef AtomEvent* pointer;
298  typedef AtomEvent& reference;
299  typedef const AtomEvent* const_pointer;
300  typedef const AtomEvent& const_reference;
301 
304  AtomSequence (const void* seq) : p_seq ((LV2_Atom_Sequence*) seq) { }
305 
308  AtomSequence (LV2_Atom_Sequence* seq) : p_seq (seq) { }
309 
311  AtomSequence (ForgeRef ref) : p_seq ((LV2_Atom_Sequence*) ref) { }
312 
314  inline uint32_t
315  pad() const
316  {
317  return p_seq->body.pad;
318  }
319 
321  inline uint32_t
322  size() const
323  {
324  return p_seq->atom.size;
325  }
326 
328  inline uint32_t
329  unit() const
330  {
331  return p_seq->body.unit;
332  }
333 
335  inline LV2_Atom_Sequence*
337  {
338  return p_seq;
339  }
340 
342  inline operator bool() const { return p_seq != 0; }
343 
345  inline operator LV2_Atom_Sequence*() const { return p_seq; }
346 
348  inline operator uint8_t*() const { return (uint8_t*) p_seq; }
349 
352  inline void
353  append (const AtomEvent& ev)
354  {
355  if (AtomEvent* pos = lv2_atom_sequence_end (&p_seq->body, p_seq->atom.size))
356  {
357  memcpy (pos, &ev, sizeof (AtomEvent));
358  memcpy (pos + 1, LV2_ATOM_BODY_CONST (&ev.body), ev.body.size);
359  ((LV2_Atom*) p_seq)->size += sizeof (LV2_Atom_Event) + lv2_atom_pad_size (ev.body.size);
360  }
361  }
362 
365  inline void
366  insert (const AtomEvent& ev)
367  {
368  const uint32_t evsize = sizeof (LV2_Atom_Event) + lv2_atom_pad_size (ev.body.size);
369  AtomEvent* pos = lv2_atom_sequence_end (&p_seq->body, p_seq->atom.size);
370  LV2_ATOM_SEQUENCE_FOREACH (p_seq, iter)
371  {
372  if (iter->time.frames > ev.time.frames)
373  {
374  memmove ((uint8_t*)iter + evsize, iter,
375  (uint8_t*)pos - (uint8_t*)iter);
376  pos = iter;
377  break;
378  }
379  }
380 
381  if (pos)
382  {
383  memcpy (pos, &ev, sizeof (AtomEvent));
384  memcpy (pos + 1, LV2_ATOM_BODY_CONST (&ev.body), ev.body.size);
385  ((LV2_Atom*) p_seq)->size += evsize;
386  }
387  }
388 
390  class iterator
391  {
392  public:
393 
394  iterator (LV2_Atom_Sequence *seq, AtomEvent* ev) : p_event (ev), p_seq (seq) { }
395  AtomEvent& operator*() { return *p_event; }
396  const AtomEvent* operator->() const { return p_event; }
397 
398  iterator& operator++()
399  {
400  p_event = lv2_atom_sequence_next (p_event);
401  return *this;
402  }
403 
404  iterator operator++(int)
405  {
406  iterator res (p_seq, p_event);
407  ++(*this);
408  return res;
409  }
410 
411  inline bool operator== (const iterator& other) const { return p_event == other.p_event; }
412  inline bool operator!= (const iterator& other) const { return p_event != other.p_event; }
413 
414  private:
415 
416  friend class AtomSequence;
417  LV2_Atom_Event* p_event;
418  LV2_Atom_Sequence* p_seq;
419  };
420 
422  inline iterator begin() const { return iterator (p_seq, lv2_atom_sequence_begin (&p_seq->body)); }
423 
425  inline iterator end() const { return iterator (p_seq, lv2_atom_sequence_end (&p_seq->body, p_seq->atom.size)); }
426 
427  private:
428 
429  LV2_Atom_Sequence* p_seq;
430 
431  };
432 
433 
435  class AtomForge : public LV2_Atom_Forge
436  {
437  public:
438 
444  AtomForge() { }
445 
448  AtomForge (LV2_URID_Map* map)
449  {
450  init (map);
451  }
452 
456  inline void
457  init (LV2_URID_Map* map)
458  {
459  lv2_atom_forge_init (this, map);
460  }
461 
465  inline LV2_Atom_Forge*
467  {
468  return (LV2_Atom_Forge*) this;
469  }
470 
472  inline ForgeRef
473  sequence_head (ForgeFrame& frame, uint32_t unit)
474  {
475  return lv2_atom_forge_sequence_head (this, &frame, unit);
476  }
477 
478  inline operator LV2_Atom_Forge* () { return cobj(); }
479 
485  inline void
486  set_buffer (uint8_t* buf, uint32_t size)
487  {
488  lv2_atom_forge_set_buffer (this, buf, size);
489  }
490 
492  inline ForgeRef
493  beat_time (double beats)
494  {
495  return lv2_atom_forge_beat_time (this, beats);
496  }
497 
501  inline ForgeRef
502  frame_time (int64_t frames)
503  {
504  return lv2_atom_forge_frame_time (this, frames);
505  }
506 
511  inline ForgeRef
512  property_head (uint32_t key, uint32_t context)
513  {
514  return lv2_atom_forge_property_head (this, key, context);
515  }
516 
520  inline void
521  pop (ForgeFrame& frame)
522  {
523  lv2_atom_forge_pop (this, &frame);
524  }
525 
532  inline ForgeRef
533  write_atom (uint32_t size, uint32_t type)
534  {
535  return lv2_atom_forge_atom (this, size, type);
536  }
537 
543  inline ForgeRef
544  write_path (const std::string& path)
545  {
546  return lv2_atom_forge_path (this, path.c_str(), path.size());
547  }
548 
556  inline ForgeRef
557  write_resource (ForgeFrame& frame, uint32_t id, uint32_t otype)
558  {
559  return lv2_atom_forge_resource (this, &frame, id, otype);
560  }
561 
567  inline ForgeRef
568  write_blank (ForgeFrame& frame, uint32_t id, uint32_t otype)
569  {
570  return lv2_atom_forge_blank (this, &frame, id, otype);
571  }
572 
576  inline ForgeRef
577  write_bool (const bool val)
578  {
579  return lv2_atom_forge_bool (this, val);
580  }
581 
585  inline ForgeRef
586  write_int (const int val)
587  {
588  return lv2_atom_forge_int (this, val);
589  }
590 
594  inline ForgeRef
595  write_float (const float val)
596  {
597  return lv2_atom_forge_float (this, val);
598  }
599 
603  inline ForgeRef
604  write_long (const int64_t val)
605  {
606  return lv2_atom_forge_long (this, val);
607  }
608 
612  inline ForgeRef
613  write_string (const char* str)
614  {
615  return lv2_atom_forge_string (this, str, strlen (str));
616  }
617 
621  inline ForgeRef
622  write_uri (const char* uri)
623  {
624  return lv2_atom_forge_uri (this, uri, strlen (uri));
625  }
626 
631  inline ForgeRef
632  write_raw (const void* data, uint32_t size)
633  {
634  return lv2_atom_forge_raw (this, data, size);
635  }
636 
640  inline ForgeRef
641  write_urid (LV2_URID id)
642  {
643  return lv2_atom_forge_urid (this, id);
644  }
645  };
646 
647 
650  {
651  public:
652 
653  inline AtomVector (ForgeRef ref) : vec ((LV2_Atom_Vector*) ref) { }
654  ~AtomVector() { }
655 
656  inline size_t size() const { return vec->atom.size / vec->body.child_size; }
657  inline uint32_t child_size() const { return vec->body.child_size; }
658  inline uint32_t child_type() const { return vec->body.child_type; }
659 
660  inline operator LV2_Atom_Vector* () const { return vec; }
661 
663  class iterator
664  {
665  public:
666 
667  iterator& operator++()
668  {
669  offset += vec->body.child_size;
670 
671  if (vec && offset >= vec->atom.size)
672  offset = vec->atom.size;
673 
674  return *this;
675  }
676 
677  iterator operator++(int)
678  {
679  iterator it (vec, offset);
680  ++(*this);
681  return it;
682  }
683 
684  inline bool operator== (const iterator& other) const { return vec == other.vec && offset == other.offset; }
685  inline bool operator!= (const iterator& other) const { return vec != other.vec && offset != other.offset; }
686 
688  inline iterator& operator= (const iterator& other)
689  {
690  this->vec = other.vec;
691  this->offset = other.offset;
692  return *this;
693  }
694 
695  private:
696  friend class AtomVector;
697  iterator (LV2_Atom_Vector *v, uint32_t os = 0) : vec (v), offset (os) { }
698  LV2_Atom_Vector* vec;
699  uint32_t offset;
700  };
701 
703  iterator begin() const { return iterator (vec); }
704 
706  iterator end() const { return iterator (vec, vec->atom.size); }
707 
708  private:
709  LV2_Atom_Vector* vec;
710 
711  };
712 
713 } /* namespace lvtk */
714 
715 #endif /* LVTK_ATOM_HPP */
ForgeRef write_urid(LV2_URID id)
Definition: atom.hpp:641
uint32_t size() const
Definition: atom.hpp:256
uint32_t type() const
Definition: atom.hpp:242
iterator begin() const
Definition: atom.hpp:422
int32_t as_int() const
Definition: atom.hpp:221
AtomObject(const void *atom)
Definition: atom.hpp:49
ForgeRef write_raw(const void *data, uint32_t size)
Definition: atom.hpp:632
bool is_null()
Definition: atom.hpp:180
AtomForge()
Definition: atom.hpp:444
const AtomObject as_object() const
Definition: atom.hpp:208
uint32_t id() const
Definition: atom.hpp:65
LV2_Atom_Forge * cobj()
Definition: atom.hpp:466
uint32_t unit() const
Definition: atom.hpp:329
void * body() const
Definition: atom.hpp:187
void set_buffer(uint8_t *buf, uint32_t size)
Definition: atom.hpp:486
iterator end() const
Definition: atom.hpp:706
ForgeRef write_resource(ForgeFrame &frame, uint32_t id, uint32_t otype)
Definition: atom.hpp:557
Atom()
Definition: atom.hpp:160
int64_t as_long() const
Definition: atom.hpp:228
AtomSequence(LV2_Atom_Sequence *seq)
Definition: atom.hpp:308
void insert(const AtomEvent &ev)
Definition: atom.hpp:366
Definition: atom.hpp:390
AtomSequence(ForgeRef ref)
Definition: atom.hpp:311
AtomSequence(const void *seq)
Definition: atom.hpp:304
float as_float() const
Definition: atom.hpp:201
LV2_Atom_Sequence * cobj()
Definition: atom.hpp:336
const char * as_string() const
Definition: atom.hpp:214
AtomForge(LV2_URID_Map *map)
Definition: atom.hpp:448
void init(LV2_URID_Map *map)
Definition: atom.hpp:457
LV2_Atom_Object * cobj() const
Definition: atom.hpp:95
LV2_Atom_Event AtomEvent
Definition: atom.hpp:37
ForgeRef sequence_head(ForgeFrame &frame, uint32_t unit)
Definition: atom.hpp:473
Definition: atom.hpp:435
Definition: atom.hpp:663
ForgeRef write_uri(const char *uri)
Definition: atom.hpp:622
ForgeRef property_head(uint32_t key, uint32_t context)
Definition: atom.hpp:512
Definition: atom.hpp:46
ForgeRef write_atom(uint32_t size, uint32_t type)
Definition: atom.hpp:533
static uint32_t pad_size(uint32_t size)
Definition: atom.hpp:173
Atom(AtomEvent *ev)
Definition: atom.hpp:169
ForgeRef write_string(const char *str)
Definition: atom.hpp:613
ForgeRef frame_time(int64_t frames)
Definition: atom.hpp:502
ForgeRef write_long(const int64_t val)
Definition: atom.hpp:604
const LV2_Atom * cobj() const
Definition: atom.hpp:263
Definition: feature.hpp:34
void pop(ForgeFrame &frame)
Definition: atom.hpp:521
void append(const AtomEvent &ev)
Definition: atom.hpp:353
uint32_t as_urid() const
Definition: atom.hpp:235
void query(ObjectQuery &query)
Definition: atom.hpp:89
ForgeRef write_int(const int val)
Definition: atom.hpp:586
Definition: atom.hpp:649
iterator begin() const
Definition: atom.hpp:703
uint32_t total_size() const
Definition: atom.hpp:72
bool as_bool() const
Definition: atom.hpp:194
ForgeRef write_bool(const bool val)
Definition: atom.hpp:577
ForgeRef write_path(const std::string &path)
Definition: atom.hpp:544
ForgeRef beat_time(double beats)
Definition: atom.hpp:493
uint32_t pad() const
Definition: atom.hpp:315
Definition: atom.hpp:109
uint32_t total_size() const
Definition: atom.hpp:249
Atom(const void *atom)
Definition: atom.hpp:163
Definition: atom.hpp:295
Definition: atom.hpp:157
Atom(ForgeRef ref)
Definition: atom.hpp:166
uint32_t otype() const
Definition: atom.hpp:58
uint32_t size() const
Definition: atom.hpp:322
AtomObject(ForgeRef ref)
Definition: atom.hpp:52
iterator end() const
Definition: atom.hpp:425
ForgeRef write_float(const float val)
Definition: atom.hpp:595
ForgeRef write_blank(ForgeFrame &frame, uint32_t id, uint32_t otype)
Definition: atom.hpp:568