Instrument Neutral Distributed Interface INDI  2.0.2
indipropertyview.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2021 by Pawel Soja <kernel32.pl@gmail.com>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #pragma once
20 
21 #include "indiapi.h"
22 #include "indidevapi.h"
23 #include "indiwidgettraits.h"
24 #include "indiwidgetview.h"
25 
26 #include <string>
27 #include <cstring>
28 #include <cstdarg>
29 #include <cstdlib>
30 #include <type_traits>
31 
32 namespace INDI
33 {
34 
35 template <typename> struct WidgetView;
36 template <typename> struct PropertyView;
37 
43 
49 
50 #define PROPERTYVIEW_BASE_ACCESS public
51 // don't use direct access to low-level property
52 //#define PROPERTYVIEW_BASE_ACCESS protected // future
53 
81 template <typename T>
83 {
84  using Type = T;
87 
88  friend class Property;
89  friend class PropertyPrivate;
90  friend class BaseDevice;
91  friend class DefaultDevice;
92  template <typename>
93  friend struct WidgetView;
94 
95  template <typename X, typename Needed>
96  using enable_if_is_same_t = typename std::enable_if<std::is_same<X, Needed>::value, bool>::type;
97  public:
98  PropertyView();
99 
100  // #PS: do not delete items, they may be on the stack.
101  //~PropertyView() { for(auto &p: *this) {p.clear();} free(widget()); }
102 
103  public:
104  void setDeviceName(const char *name); /* outside implementation */
105  void setDeviceName(const std::string &name); /* outside implementation */
106 
107  void setName(const char *name); /* outside implementation */
108  void setName(const std::string &name); /* outside implementation */
109 
110  void setLabel(const char *label); /* outside implementation */
111  void setLabel(const std::string &label); /* outside implementation */
112 
113  void setGroupName(const char *name); /* outside implementation */
114  void setGroupName(const std::string &name); /* outside implementation */
115 
116  void setPermission(IPerm permission); /* outside implementation */
117  void setTimeout(double timeout); /* outside implementation */
118  void setState(IPState state);
119 
120  void setTimestamp(const char *timestamp); /* outside implementation */
121  void setTimestamp(const std::string &timestamp); /* outside implementation */
122 
123  void setAux(void *user); /* outside implementation */
124  void setWidgets(WidgetType *w, size_t count); /* outside implementation */
125 
126  template <size_t N>
127  void setWidgets(WidgetType (&w)[N]); /* outside implementation */
128 
129  public: // only for ISwitch
130  void setRule(ISRule rule); /* outside implementation */
131  bool setRule(const std::string &rule); /* outside implementation */
132 
133  template <typename X = T, enable_if_is_same_t<X, ISwitch> = true>
134  void reset()
135  {
136  IUResetSwitch(this);
137  }
138 
139  template <typename X = T, enable_if_is_same_t<X, ISwitch> = true>
141  {
142  return static_cast<WidgetType *>(IUFindOnSwitch(this));
143  }
144 
145  template <typename X = T, enable_if_is_same_t<X, ISwitch> = true>
146  int findOnSwitchIndex() const
147  {
148  return IUFindOnSwitchIndex(this);
149  }
150 
151  public: // only for INumber
152  template <typename X = T, enable_if_is_same_t<X, INumber> = true>
153  void updateMinMax(); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
154 
155  public: //getters
156  const char *getDeviceName() const
157  {
158  return this->device;
159  }
160  const char *getName() const
161  {
162  return this->name;
163  }
164  const char *getLabel() const
165  {
166  return this->label;
167  }
168  const char *getGroupName() const
169  {
170  return this->group;
171  }
172 
173  IPerm getPermission() const; /* outside implementation */
174  const char *getPermissionAsString() const
175  {
176  return permStr(getPermission());
177  }
178 
179  ISRule getRule() const; /* outside implementation */
180  const char * getRuleAsString() const
181  {
182  return ruleStr(getRule());
183  }
184 
185  double getTimeout() const; /* outside implementation */
187  {
188  return this->s;
189  }
190  const char *getStateAsString() const
191  {
192  return pstateStr(getState());
193  }
194 
195  const char *getTimestamp() const
196  {
197  return this->timestamp;
198  }
199  void *getAux() const
200  {
201  return this->aux;
202  }
203 
204  int count() const; /* outside implementation */
205  WidgetType *widget() const; /* outside implementation */
206 
207  WidgetType *findWidgetByName(const char *name) const; /* outside implementation */
208 
209  public: //tests
210  bool isEmpty() const
211  {
212  return widget() == nullptr || count() == 0;
213  }
214 
215  bool isNameMatch(const char *otherName) const
216  {
217  return !strcmp(getName(), otherName);
218  }
219  bool isNameMatch(const std::string &otherName) const
220  {
221  return getName() == otherName;
222  }
223 
224  bool isLabelMatch(const char *otherLabel) const
225  {
226  return !strcmp(getLabel(), otherLabel);
227  }
228  bool isLabelMatch(const std::string &otherLabel) const
229  {
230  return getLabel() == otherLabel;
231  }
232 
233  public: // only driver side
234  void save(FILE *f) const; /* outside implementation */
235 
236  void vapply(const char *format, va_list args)
237  const; /* outside implementation - only driver side, see indipropertyview_driver.cpp */
238  void vdefine(const char *format, va_list args)
239  const; /* outside implementation - only driver side, see indipropertyview_driver.cpp */
240 
241  void apply(const char *format, ...) const ATTRIBUTE_FORMAT_PRINTF(2,
242  3); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
243  void define(const char *format, ...) const ATTRIBUTE_FORMAT_PRINTF(2,
244  3); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
245 
246  void apply() const
247  {
248  apply(nullptr);
249  }
250  void define() const
251  {
252  define(nullptr);
253  }
254 
255  public:
256  template <typename X = T, enable_if_is_same_t<X, IText> = true>
257  void fill(
258  const char *device, const char *name, const char *label, const char *group,
259  IPerm permission, double timeout, IPState state
260  ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
261 
262  template <typename X = T, enable_if_is_same_t<X, INumber> = true>
263  void fill(
264  const char *device, const char *name, const char *label, const char *group,
265  IPerm permission, double timeout, IPState state
266  ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
267 
268  template <typename X = T, enable_if_is_same_t<X, ISwitch> = true>
269  void fill(
270  const char *device, const char *name, const char *label, const char *group,
271  IPerm permission, ISRule rule, double timeout, IPState state
272  ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
273 
274  template <typename X = T, enable_if_is_same_t<X, ILight> = true>
275  void fill(
276  const char *device, const char *name, const char *label, const char *group,
277  IPState state
278  ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
279 
280  template <typename X = T, enable_if_is_same_t<X, IBLOB> = true>
281  void fill(
282  const char *device, const char *name, const char *label, const char *group,
283  IPerm permission, double timeout, IPState state
284  ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
285 
286  public:
287  template <typename X = T, enable_if_is_same_t<X, IText> = true>
288  bool update(const char * const texts[], const char * const names[], int n);
289  /* outside implementation - only driver side, see indipropertyview_driver.cpp */
290 
291  template <typename X = T, enable_if_is_same_t<X, INumber> = true>
292  bool update(const double values[], const char * const names[], int n);
293  /* outside implementation - only driver side, see indipropertyview_driver.cpp */
294 
295  template <typename X = T, enable_if_is_same_t<X, ISwitch> = true>
296  bool update(const ISState states[], const char * const names[], int n);
297  /* outside implementation - only driver side, see indipropertyview_driver.cpp */
298 
299  /*
300  template <typename X = T, enable_if_is_same_t<X, ILight> = true>
301  bool update(..., const char * const names[], int n);
302  */
303 
304  template <typename X = T, enable_if_is_same_t<X, IBLOB> = true>
305  bool update(
306  const int sizes[], const int blobsizes[], const char * const blobs[], const char * const formats[],
307  const char * const names[], int n
308  ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
309 
310 
311  public:
312  WidgetType *begin() const
313  {
314  return widget();
315  }
316  WidgetType *end() const
317  {
318  return widget() + count();
319  }
320 
321  WidgetType *at(size_t index) const
322  {
323  return widget() + index;
324  }
325  public:
326  void clear()
327  {
328  for(auto &p : *this)
329  {
330  p.clear();
331  }
332  //free(widget()); // #PS: do not delete items, they may be on the stack.
333  memset(this, 0, sizeof(*this));
334  }
335  public: // internal use only
337  {
338  return static_cast<PropertyView<T>*>(raw);
339  }
341  {
342  return this;
343  }
344 };
345 
346 template <typename>
347 struct WidgetView;
348 
349 template <>
351 {
352  using Type = IText;
353  template <typename> friend struct PropertyView;
354 
355  public:
357  {
358  memset(this, 0, sizeof(*this));
359  }
360  WidgetView(const WidgetView &other): Type(other)
361  {
362  this->text = nullptr;
363  setText(other.text);
364  }
365  WidgetView(WidgetView &&other): Type(other)
366  {
367  memset(static_cast<Type*>(&other), 0, sizeof(other));
368  }
370  {
371  return *this = WidgetView(other);
372  }
374  {
375  std::swap(static_cast<Type &>(other), static_cast<Type &>(*this));
376  return *this;
377  }
379  {
380  free(this->text);
381  }
382  void clear()
383  {
384  free(this->text);
385  memset(this, 0, sizeof(*this));
386  }
387  // bool isNull() const { return reinterpret_cast<const void*>(this) == nullptr; }
388 
389  public: // setters
391  {
392  this->tvp = parent;
393  }
395  {
396  this->tvp = static_cast<ITextVectorProperty*>(parent);
397  }
398 
399  void setName(const char *name)
400  {
401  INDI::strlcpy(this->name, name);
402  }
403  void setName(const std::string &name)
404  {
405  setName(name.data());
406  }
407 
408  void setLabel(const char *label)
409  {
410  INDI::strlcpy(this->label, label);
411  }
412  void setLabel(const std::string &label)
413  {
414  setLabel(label.data());
415  }
416 
417  //void setText(const char *text) { free(this->text); this->text = strndup(text, strlen(text)); }
418  void setText(const char *text, size_t size)
419  {
420  INDI::strlcpy(this->text = static_cast<char*>(realloc(this->text, size + 1)), text, size + 1);
421  }
422  void setText(const char *text)
423  {
424  setText(text, strlen(text));
425  }
426  void setText(const std::string &text)
427  {
428  setText(text.data(), text.size());
429  }
430 
431  void setAux(void *user)
432  {
433  this->aux0 = user;
434  }
435  // don't use any other aux!
436 
437  public: //getters
438  const char *getName() const
439  {
440  return this->name;
441  }
442  const char *getLabel() const
443  {
444  return this->label;
445  }
446  const char *getText() const
447  {
448  return this->text ? this->text : "";
449  }
450 
451  void *getAux() const
452  {
453  return this->aux0;
454  }
455 
456  public: //tests
457  bool isNameMatch(const char *otherName) const
458  {
459  return !strcmp(getName(), otherName);
460  }
461  bool isNameMatch(const std::string &otherName) const
462  {
463  return getName() == otherName;
464  }
465 
466  bool isLabelMatch(const char *otherLabel) const
467  {
468  return !strcmp(getLabel(), otherLabel);
469  }
470  bool isLabelMatch(const std::string &otherLabel) const
471  {
472  return getLabel() == otherLabel;
473  }
474 
475  public:
476  void fill(const char *name, const char *label, const char *initialText)
477  ; /* outside implementation - only driver side, see indipropertyview_driver.cpp */
478 
479  void fill(const std::string &name, const std::string &label, const std::string &initialText)
480  {
481  fill(name.c_str(), label.c_str(), initialText.c_str());
482  }
483 };
484 
485 template <>
487 {
488  using Type = INumber;
489  template <typename> friend struct PropertyView;
490 
491  public:
493  {
494  memset(this, 0, sizeof(*this));
495  }
496  WidgetView(const WidgetView &other): Type(other) { }
497  WidgetView(WidgetView &&other): Type(other)
498  {
499  memset(static_cast<Type*>(&other), 0, sizeof(other));
500  }
502  {
503  return *this = WidgetView(other);
504  }
506  {
507  std::swap(static_cast<Type &>(other), static_cast<Type &>(*this));
508  return *this;
509  }
511  void clear()
512  {
513  memset(this, 0, sizeof(*this));
514  }
515  // bool isNull() const { return reinterpret_cast<const void*>(this) == nullptr; }
516 
517  public: // setters
519  {
520  this->nvp = parent;
521  }
523  {
524  this->nvp = static_cast<INumberVectorProperty*>(parent);
525  }
526 
527  void setName(const char *name)
528  {
529  INDI::strlcpy(this->name, name);
530  }
531  void setName(const std::string &name)
532  {
533  setName(name.data());
534  }
535 
536  void setLabel(const char *label)
537  {
538  INDI::strlcpy(this->label, label);
539  }
540  void setLabel(const std::string &label)
541  {
542  setLabel(label.data());
543  }
544 
545  void setFormat(const char *format)
546  {
547  INDI::strlcpy(this->format, format);
548  }
549  void setFormat(const std::string &format)
550  {
551  setLabel(format.data());
552  }
553 
554  void setMin(double min)
555  {
556  this->min = min;
557  }
558  void setMax(double max)
559  {
560  this->max = max;
561  }
562  void setMinMax(double min, double max)
563  {
564  setMin(min);
565  setMax(max);
566  }
567  void setStep(double step)
568  {
569  this->step = step;
570  }
571  void setValue(double value)
572  {
573  this->value = value;
574  }
575 
576  void setAux(void *user)
577  {
578  this->aux0 = user;
579  }
580  // don't use any other aux!
581 
582  public: //getters
583  const char *getName() const
584  {
585  return this->name;
586  }
587  const char *getLabel() const
588  {
589  return this->label;
590  }
591  const char *getFormat() const
592  {
593  return this->format;
594  }
595 
596  double getMin() const
597  {
598  return this->min;
599  }
600  double getMax() const
601  {
602  return this->max;
603  }
604  double getStep() const
605  {
606  return this->step;
607  }
608  double getValue() const
609  {
610  return this->value;
611  }
612 
613  void *getAux() const
614  {
615  return this->aux0;
616  }
617 
618  public: //tests
619  bool isNameMatch(const char *otherName) const
620  {
621  return !strcmp(getName(), otherName);
622  }
623  bool isNameMatch(const std::string &otherName) const
624  {
625  return getName() == otherName;
626  }
627 
628  bool isLabelMatch(const char *otherLabel) const
629  {
630  return !strcmp(getLabel(), otherLabel);
631  }
632  bool isLabelMatch(const std::string &otherLabel) const
633  {
634  return getLabel() == otherLabel;
635  }
636 
637  public:
638  void fill(const char *name, const char *label, const char *format,
639  double min, double max, double step, double value)
640  ; /* outside implementation - only driver side, see indipropertyview_driver.cpp */
641 
642  void fill(const std::string &name, const std::string &label, const std::string &format,
643  double min, double max, double step, double value)
644  {
645  fill(name.c_str(), label.c_str(), format.c_str(), min, max, step, value);
646  }
647 };
648 
649 template <>
651 {
652  using Type = ISwitch;
653  template <typename> friend struct PropertyView;
654 
655  public:
657  {
658  memset(this, 0, sizeof(*this));
659  }
660  WidgetView(const WidgetView &other): Type(other) { }
661  WidgetView(WidgetView &&other): Type(other)
662  {
663  memset(static_cast<Type*>(&other), 0, sizeof(other));
664  }
666  {
667  return *this = WidgetView(other);
668  }
670  {
671  std::swap(static_cast<Type &>(other), static_cast<Type &>(*this));
672  return *this;
673  }
675  void clear()
676  {
677  memset(this, 0, sizeof(*this));
678  }
679  // bool isNull() const { return reinterpret_cast<const void*>(this) == nullptr; }
680 
681  public: // setters
683  {
684  this->svp = parent;
685  }
687  {
688  this->svp = static_cast<ISwitchVectorProperty*>(parent);
689  }
690 
691  void setName(const char *name)
692  {
693  INDI::strlcpy(this->name, name);
694  }
695  void setName(const std::string &name)
696  {
697  setName(name.data());
698  }
699 
700  void setLabel(const char *label)
701  {
702  INDI::strlcpy(this->label, label);
703  }
704  void setLabel(const std::string &label)
705  {
706  setLabel(label.data());
707  }
708 
709  void setState(const ISState &state)
710  {
711  this->s = state;
712  }
713  bool setState(const std::string &state)
714  {
715  return crackISState(state.data(), &this->s) == 0;
716  }
717 
718  void setAux(void *user)
719  {
720  this->aux = user;
721  }
722  // don't use any other aux!
723 
724  public: //getters
725  const char *getName() const
726  {
727  return this->name;
728  }
729  const char *getLabel() const
730  {
731  return this->label;
732  }
733 
735  {
736  return this->s;
737  }
738  const char *getStateAsString() const
739  {
740  return sstateStr(getState());
741  }
742 
743  void *getAux() const
744  {
745  return this->aux;
746  }
747 
748 
749  public: //tests
750  bool isNameMatch(const char *otherName) const
751  {
752  return !strcmp(getName(), otherName);
753  }
754  bool isNameMatch(const std::string &otherName) const
755  {
756  return getName() == otherName;
757  }
758 
759  bool isLabelMatch(const char *otherLabel) const
760  {
761  return !strcmp(getLabel(), otherLabel);
762  }
763  bool isLabelMatch(const std::string &otherLabel) const
764  {
765  return getLabel() == otherLabel;
766  }
767 
768  public:
769  void fill(const char *name, const char *label, ISState state = ISS_OFF)
770  ; /* outside implementation - only driver side, see indipropertyview_driver.cpp */
771 
772  void fill(const std::string &name, const std::string &label, ISState state = ISS_OFF)
773  {
774  fill(name.c_str(), label.c_str(), state);
775  }
776 };
777 
778 template <>
780 {
781  using Type = ILight;
782  template <typename> friend struct PropertyView;
783 
784  public:
786  {
787  memset(this, 0, sizeof(*this));
788  }
789  WidgetView(const WidgetView &other): Type(other) { }
790  WidgetView(WidgetView &&other): Type(other)
791  {
792  memset(static_cast<Type*>(&other), 0, sizeof(other));
793  }
795  {
796  return *this = WidgetView(other);
797  }
799  {
800  std::swap(static_cast<Type &>(other), static_cast<Type &>(*this));
801  return *this;
802  }
804  void clear()
805  {
806  memset(this, 0, sizeof(*this));
807  }
808  // bool isNull() const { return reinterpret_cast<const void*>(this) == nullptr; }
809 
810  public: // setters
812  {
813  this->lvp = parent;
814  }
816  {
817  this->lvp = static_cast<ILightVectorProperty*>(parent);
818  }
819 
820  void setName(const char *name)
821  {
822  INDI::strlcpy(this->name, name);
823  }
824  void setName(const std::string &name)
825  {
826  setName(name.data());
827  }
828 
829  void setLabel(const char *label)
830  {
831  INDI::strlcpy(this->label, label);
832  }
833  void setLabel(const std::string &label)
834  {
835  setLabel(label.data());
836  }
837 
838  void setState(const IPState &state)
839  {
840  this->s = state;
841  }
842  bool setState(const std::string &state)
843  {
844  return crackIPState(state.data(), &this->s) == 0;
845  }
846 
847  void setAux(void *user)
848  {
849  this->aux = user;
850  }
851  // don't use any other aux!
852 
853  public: //getters
854  const char *getName() const
855  {
856  return this->name;
857  }
858  const char *getLabel() const
859  {
860  return this->label;
861  }
862 
864  {
865  return this->s;
866  }
867  const char *getStateAsString() const
868  {
869  return pstateStr(getState());
870  }
871 
872  void *getAux() const
873  {
874  return this->aux;
875  }
876 
877 
878  public: //tests
879  bool isNameMatch(const char *otherName) const
880  {
881  return !strcmp(getName(), otherName);
882  }
883  bool isNameMatch(const std::string &otherName) const
884  {
885  return getName() == otherName;
886  }
887 
888  bool isLabelMatch(const char *otherLabel) const
889  {
890  return !strcmp(getLabel(), otherLabel);
891  }
892  bool isLabelMatch(const std::string &otherLabel) const
893  {
894  return getLabel() == otherLabel;
895  }
896 
897  public:
898  void fill(const char *name, const char *label, IPState state = IPS_OK)
899  ; /* outside implementation - only driver side, see indipropertyview_driver.cpp */
900 
901  void fill(const std::string &name, const std::string &&label, IPState state = IPS_OK)
902  {
903  fill(name.c_str(), label.c_str(), state);
904  }
905 };
906 
907 template <>
909 {
910  using Type = IBLOB;
911  template <typename> friend struct PropertyView;
912 
913  public:
915  {
916  memset(this, 0, sizeof(*this));
917  }
918  WidgetView(const WidgetView &other): Type(other) { }
919  WidgetView(WidgetView &&other): Type(other)
920  {
921  memset(static_cast<Type*>(&other), 0, sizeof(other));
922  }
924  {
925  return *this = WidgetView(other);
926  }
928  {
929  std::swap(static_cast<Type &>(other), static_cast<Type &>(*this));
930  return *this;
931  }
932  ~WidgetView() { /* free(this->blob); */ }
933  void clear()
934  {
935  /* free(this->blob); */ memset(this, 0, sizeof(*this));
936  }
937  // bool isNull() const { return reinterpret_cast<const void*>(this) == nullptr; }
938 
939  public: // setters
941  {
942  this->bvp = parent;
943  }
945  {
946  this->bvp = static_cast<IBLOBVectorProperty*>(parent);
947  }
948 
949  void setName(const char *name)
950  {
951  INDI::strlcpy(this->name, name);
952  }
953  void setName(const std::string &name)
954  {
955  setName(name.data());
956  }
957 
958  void setLabel(const char *label)
959  {
960  INDI::strlcpy(this->label, label);
961  }
962  void setLabel(const std::string &label)
963  {
964  setLabel(label.data());
965  }
966 
967  void setFormat(const char *format)
968  {
969  INDI::strlcpy(this->format, format);
970  }
971  void setFormat(const std::string &format)
972  {
973  setLabel(format.data());
974  }
975 
976  void setBlob(void *blob)
977  {
978  this->blob = blob;
979  }
980  void setBlobLen(int size)
981  {
982  this->bloblen = size;
983  }
984  void setSize(int size)
985  {
986  this->size = size;
987  }
988 
989  void setAux(void *user)
990  {
991  this->aux0 = user;
992  }
993  // don't use any other aux!
994 
995  public: //getters
996  const char *getName() const
997  {
998  return this->name;
999  }
1000  const char *getLabel() const
1001  {
1002  return this->label;
1003  }
1004  const char *getFormat() const
1005  {
1006  return this->format;
1007  }
1008  void *getBlob()
1009  {
1010  return this->blob;
1011  }
1012  const void *getBlob() const
1013  {
1014  return this->blob;
1015  }
1016  std::string getBlobAsString() const
1017  {
1018  return std::string(static_cast<const char*>(this->blob), this->bloblen);
1019  }
1020  int getBlobLen() const
1021  {
1022  return this->bloblen;
1023  }
1024  int getSize() const
1025  {
1026  return this->size;
1027  }
1028 
1029  void *getAux() const
1030  {
1031  return this->aux0;
1032  }
1033 
1034  public: //tests
1035  bool isNameMatch(const char *otherName) const
1036  {
1037  return !strcmp(getName(), otherName);
1038  }
1039  bool isNameMatch(const std::string &otherName) const
1040  {
1041  return getName() == otherName;
1042  }
1043 
1044  bool isLabelMatch(const char *otherLabel) const
1045  {
1046  return !strcmp(getLabel(), otherLabel);
1047  }
1048  bool isLabelMatch(const std::string &otherLabel) const
1049  {
1050  return getLabel() == otherLabel;
1051  }
1052 
1053  public:
1054  void fill(const char *name, const char *label, const char *format)
1055  ; /* outside implementation - only driver side, see indipropertyview_driver.cpp */
1056 
1057  void fill(const std::string &name, const std::string &label, const std::string &format)
1058  {
1059  fill(name.c_str(), label.c_str(), format.c_str());
1060  }
1061 
1062  public: // internal use only
1063  static WidgetView<Type> *cast(Type *blob)
1064  {
1065  return static_cast<WidgetView<Type>*>(blob);
1066  }
1068  {
1069  return this;
1070  }
1071 };
1072 
1073 
1074 
1075 
1076 /* outside implementation */
1077 template <typename T>
1079 {
1080  memset(this, 0, sizeof(*this));
1081 }
1082 
1083 template <typename T>
1084 inline void PropertyView<T>::setDeviceName(const char *name)
1085 {
1086  INDI::strlcpy(this->device, name);
1087 }
1088 
1089 template <typename T>
1090 inline void PropertyView<T>::setDeviceName(const std::string &name)
1091 {
1092  setDeviceName(name.data());
1093 }
1094 
1095 template <typename T>
1096 inline void PropertyView<T>::setName(const char *name)
1097 {
1098  INDI::strlcpy(this->name, name);
1099 }
1100 
1101 template <typename T>
1102 inline void PropertyView<T>::setName(const std::string &name)
1103 {
1104  setName(name.data());
1105 }
1106 
1107 template <typename T>
1108 inline void PropertyView<T>::setLabel(const char *label)
1109 {
1110  INDI::strlcpy(this->label, label);
1111 }
1112 
1113 template <typename T>
1114 inline void PropertyView<T>::setLabel(const std::string &label)
1115 {
1116  setLabel(label.data());
1117 }
1118 
1119 template <typename T>
1120 inline void PropertyView<T>::setGroupName(const char *name)
1121 {
1122  INDI::strlcpy(this->group, name);
1123 }
1124 
1125 template <typename T>
1126 inline void PropertyView<T>::setGroupName(const std::string &name)
1127 {
1128  setGroupName(name.data());
1129 }
1130 
1131 template <typename T>
1133 {
1134  this->s = state;
1135 }
1136 
1137 template <typename T>
1138 inline void PropertyView<T>::setTimestamp(const char *timestamp)
1139 {
1140  INDI::strlcpy(this->timestamp, timestamp);
1141 }
1142 
1143 template <typename T>
1144 inline void PropertyView<T>::setTimestamp(const std::string &timestamp)
1145 {
1146  setTimestamp(timestamp.data());
1147 }
1148 
1149 template <typename T>
1150 template <size_t N>
1152 {
1153  setWidgets(static_cast<WidgetType*>(w), N);
1154 }
1155 
1156 template <typename T>
1157 inline void PropertyView<T>::setAux(void *user)
1158 {
1159  this->aux = user;
1160 }
1161 
1162 template <>
1163 inline void PropertyView<IText>::save(FILE *f) const
1164 {
1165  IUSaveConfigText(f, this);
1166 }
1167 
1168 template <>
1169 inline void PropertyView<INumber>::save(FILE *f) const
1170 {
1171  IUSaveConfigNumber(f, this);
1172 }
1173 
1174 template <>
1175 inline void PropertyView<ISwitch>::save(FILE *f) const
1176 {
1177  IUSaveConfigSwitch(f, this);
1178 }
1179 
1180 template <>
1181 inline void PropertyView<ILight>::save(FILE *f) const
1182 {
1183  (void)f; /* IUSaveConfigLight(f, this); */
1184 }
1185 
1186 template <>
1187 inline void PropertyView<IBLOB>::save(FILE *f) const
1188 {
1189  IUSaveConfigBLOB(f, this);
1190 }
1191 
1192 template <typename T>
1193 inline void PropertyView<T>::setTimeout(double timeout)
1194 {
1195  this->timeout = timeout;
1196 }
1197 
1198 template <>
1200 { }
1201 
1202 template <typename T>
1203 inline void PropertyView<T>::setPermission(IPerm permission)
1204 {
1205  this->p = permission;
1206 }
1207 
1208 template <>
1210 { }
1211 
1212 template <typename T>
1214 { }
1215 
1216 template <>
1218 {
1219  this->r = rule;
1220 }
1221 
1222 template <typename T>
1223 inline bool PropertyView<T>::setRule(const std::string &)
1224 {
1225  return false;
1226 }
1227 
1228 template <>
1229 inline bool PropertyView<ISwitch>::setRule(const std::string &rule)
1230 {
1231  return crackISRule(rule.data(), &this->r) == 0;
1232 }
1233 
1234 template <typename T>
1236 {
1237  return nullptr;
1238 }
1239 
1240 template <>
1242 {
1243  return static_cast<WidgetView<IText> *>(IUFindText(this, name));
1244 }
1245 
1246 template <>
1248 {
1249  return static_cast<WidgetView<INumber> *>(IUFindNumber(this, name));
1250 }
1251 
1252 template <>
1254 {
1255  return static_cast<WidgetView<ISwitch> *>(IUFindSwitch(this, name));
1256 }
1257 
1258 template <>
1260 {
1261  return static_cast<WidgetView<ILight> *>(IUFindLight(this, name));
1262 }
1263 
1264 template <>
1266 {
1267  return static_cast<WidgetView<IBLOB> *>(IUFindBLOB(this, name));
1268 }
1269 
1270 template <typename T>
1272 {
1273  return this->p;
1274 }
1275 
1276 template <>
1278 {
1279  return IP_RO;
1280 }
1281 
1282 template <typename T>
1284 {
1285  return ISR_NOFMANY;
1286 }
1287 
1288 template <>
1290 {
1291  return this->r;
1292 }
1293 
1294 template <typename T>
1295 inline double PropertyView<T>::getTimeout() const
1296 {
1297  return this->timeout;
1298 }
1299 
1300 template <>
1302 {
1303  return 0;
1304 }
1305 
1306 template <>
1307 inline void PropertyView<IText>::setWidgets(WidgetType *w, size_t size)
1308 {
1309  this->tp = w;
1310  this->ntp = int(size);
1311 }
1312 
1313 template <>
1314 inline void PropertyView<INumber>::setWidgets(WidgetType *w, size_t size)
1315 {
1316  this->np = w;
1317  this->nnp = int(size);
1318 }
1319 
1320 template <>
1321 inline void PropertyView<ISwitch>::setWidgets(WidgetType *w, size_t size)
1322 {
1323  this->sp = w;
1324  this->nsp = int(size);
1325 }
1326 
1327 template <>
1328 inline void PropertyView<ILight>::setWidgets(WidgetType *w, size_t size)
1329 {
1330  this->lp = w;
1331  this->nlp = int(size);
1332 }
1333 
1334 template <>
1335 inline void PropertyView<IBLOB>::setWidgets(WidgetType *w, size_t size)
1336 {
1337  this->bp = w;
1338  this->nbp = int(size);
1339 }
1340 
1341 template <>
1342 inline int PropertyView<IText>::count() const
1343 {
1344  return this->ntp;
1345 }
1346 
1347 template <>
1349 {
1350  return this->nnp;
1351 }
1352 
1353 template <>
1355 {
1356  return this->nsp;
1357 }
1358 
1359 template <>
1361 {
1362  return this->nlp;
1363 }
1364 
1365 template <>
1366 inline int PropertyView<IBLOB>::count() const
1367 {
1368  return this->nbp;
1369 }
1370 
1371 template <>
1373 {
1374  return static_cast<WidgetType*>(this->tp);
1375 }
1376 
1377 template <>
1379 {
1380  return static_cast<WidgetType*>(this->np);
1381 }
1382 
1383 template <>
1385 {
1386  return static_cast<WidgetType*>(this->sp);
1387 }
1388 
1389 template <>
1391 {
1392  return static_cast<WidgetType*>(this->lp);
1393 }
1394 
1395 template <>
1397 {
1398  return static_cast<WidgetType*>(this->bp);
1399 }
1400 
1401 }
hid_device * device
Class to provide basic INDI device functionality.
Definition: basedevice.h:52
Class to provide extended functionality for devices in addition to the functionality provided by INDI...
Provides generic container for INDI properties.
Definition: indiproperty.h:48
double max(void)
double min(void)
Constants and Data structure definitions for the interface to the reference INDI C API implementation...
ISState
Switch state.
Definition: indiapi.h:150
@ ISS_OFF
Definition: indiapi.h:151
struct _IBLOB IBLOB
IPerm
Permission hint, with respect to client.
Definition: indiapi.h:183
@ IP_RO
Definition: indiapi.h:184
IPState
Property state.
Definition: indiapi.h:160
@ IPS_OK
Definition: indiapi.h:162
struct _INumber INumber
ISRule
Switch vector rule hint.
Definition: indiapi.h:172
@ ISR_NOFMANY
Definition: indiapi.h:175
struct _ISwitch ISwitch
struct _ILight ILight
struct _IText IText
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
Definition: indidevapi.c:25
const char * ruleStr(ISRule r)
Definition: indidevapi.c:660
INumber * IUFindNumber(const INumberVectorProperty *nvp, const char *name)
Find an INumber member in a number text property.
Definition: indidevapi.c:66
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
Definition: indidevapi.c:128
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition: indidevapi.c:148
ISwitch * IUFindOnSwitch(const ISwitchVectorProperty *svp)
Returns the first ON switch it finds in the vector switch property.
Definition: indidevapi.c:108
void IUSaveConfigBLOB(FILE *fp, const IBLOBVectorProperty *bvp)
Add a BLOB vector property value to the configuration file.
Definition: indidevapi.c:30
void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
Definition: indidevapi.c:15
const char * pstateStr(IPState s)
Definition: indidevapi.c:628
void IUSaveConfigText(FILE *fp, const ITextVectorProperty *tvp)
Add a text vector property value to the configuration file.
Definition: indidevapi.c:20
int crackIPState(const char *str, IPState *ip)
Extract property state (Idle, OK, Busy, Alert) from the supplied string.
Definition: indidevapi.c:576
IBLOB * IUFindBLOB(const IBLOBVectorProperty *bvp, const char *name)
Find an IBLOB member in a vector BLOB property.
Definition: indidevapi.c:96
IText * IUFindText(const ITextVectorProperty *tvp, const char *name)
Find an IText member in a vector text property.
Definition: indidevapi.c:56
ILight * IUFindLight(const ILightVectorProperty *lvp, const char *name)
Find an ILight member in a vector Light property.
Definition: indidevapi.c:86
int crackISRule(const char *str, ISRule *ip)
Extract switch rule (OneOfMany, OnlyOne..etc) from the supplied string.
Definition: indidevapi.c:615
const char * sstateStr(ISState s)
Definition: indidevapi.c:646
const char * permStr(IPerm p)
Definition: indidevapi.c:676
int crackISState(const char *str, ISState *ip)
Extract switch state (On or Off) from the supplied string.
Definition: indidevapi.c:591
ISwitch * IUFindSwitch(const ISwitchVectorProperty *svp, const char *name)
Find an ISwitch member in a vector switch property.
Definition: indidevapi.c:76
Interface to the reference INDI C API device implementation on the Device Driver side.
#define ATTRIBUTE_FORMAT_PRINTF(A, B)
Definition: indidevapi.h:139
#define PROPERTYVIEW_BASE_ACCESS
Namespace to encapsulate INDI client, drivers, and mediator classes.
WidgetView< ISwitch > WidgetViewSwitch
PropertyView< IBLOB > PropertyViewBlob
WidgetView< ILight > WidgetViewLight
WidgetView< IText > WidgetViewText
PropertyView< ISwitch > PropertyViewSwitch
PropertyView< ILight > PropertyViewLight
WidgetView< IBLOB > WidgetViewBlob
PropertyView< INumber > PropertyViewNumber
PropertyView< IText > PropertyViewText
WidgetView< INumber > WidgetViewNumber
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.h:23663
__le16 type
Definition: pwc-ioctl.h:0
One Blob (Binary Large Object) descriptor.
One light descriptor.
Provides decorator for Low-Level IXXXVectorProperty/IXXX.
bool isNameMatch(const std::string &otherName) const
WidgetType * findOnSwitch() const
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
WidgetType * begin() const
void fill(const char *device, const char *name, const char *label, const char *group, IPState state)
const char * getName() const
PropertyType * cast()
const char * getPermissionAsString() const
const char * getGroupName() const
void void void apply() const
const char * getStateAsString() const
bool isLabelMatch(const std::string &otherLabel) const
void setTimestamp(const char *timestamp)
WidgetType * end() const
void setDeviceName(const char *name)
IPState getState() const
int count() const
void setName(const char *name)
double getTimeout() const
const char * getTimestamp() const
const char * getDeviceName() const
bool update(const char *const texts[], const char *const names[], int n)
const char * getRuleAsString() const
bool isNameMatch(const char *otherName) const
int findOnSwitchIndex() const
void setTimeout(double timeout)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
IPerm getPermission() const
WidgetType * at(size_t index) const
void vdefine(const char *format, va_list args) const
void setPermission(IPerm permission)
void setAux(void *user)
WidgetType * widget() const
static PropertyView< T > * cast(PropertyType *raw)
bool update(const double values[], const char *const names[], int n)
bool update(const ISState states[], const char *const names[], int n)
void * getAux() const
void setState(IPState state)
void setRule(ISRule rule)
bool update(const int sizes[], const int blobsizes[], const char *const blobs[], const char *const formats[], const char *const names[], int n)
void save(FILE *f) const
void setGroupName(const char *name)
void setLabel(const char *label)
const char * getLabel() const
typename WidgetTraits< T >::PropertyType PropertyType
WidgetType * findWidgetByName(const char *name) const
typename std::enable_if< std::is_same< X, Needed >::value, bool >::type enable_if_is_same_t
void setWidgets(WidgetType *w, size_t count)
ISRule getRule() const
void vapply(const char *format, va_list args) const
bool isLabelMatch(const char *otherLabel) const
bool isNameMatch(const std::string &otherName) const
bool isNameMatch(const char *otherName) const
void setFormat(const std::string &format)
WidgetView & operator=(const WidgetView &other)
WidgetView & operator=(WidgetView &&other)
void fill(const std::string &name, const std::string &label, const std::string &format)
const void * getBlob() const
WidgetView(WidgetView &&other)
const char * getName() const
void setFormat(const char *format)
void setParent(IBLOBVectorProperty *parent)
void setLabel(const char *label)
bool isLabelMatch(const std::string &otherLabel) const
bool isLabelMatch(const char *otherLabel) const
void setName(const std::string &name)
static WidgetView< Type > * cast(Type *blob)
WidgetView(const WidgetView &other)
void setName(const char *name)
std::string getBlobAsString() const
void setParent(PropertyView< Type > *parent)
const char * getLabel() const
const char * getFormat() const
void setLabel(const std::string &label)
bool isNameMatch(const char *otherName) const
bool isNameMatch(const std::string &otherName) const
WidgetView & operator=(WidgetView &&other)
void setName(const char *name)
const char * getStateAsString() const
WidgetView & operator=(const WidgetView &other)
void setLabel(const std::string &label)
WidgetView(const WidgetView &other)
void setParent(ILightVectorProperty *parent)
void setState(const IPState &state)
bool isLabelMatch(const char *otherLabel) const
const char * getName() const
bool setState(const std::string &state)
void setName(const std::string &name)
void setLabel(const char *label)
bool isLabelMatch(const std::string &otherLabel) const
WidgetView(WidgetView &&other)
void fill(const std::string &name, const std::string &&label, IPState state=IPS_OK)
const char * getLabel() const
void setParent(PropertyView< Type > *parent)
const char * getLabel() const
bool isNameMatch(const char *otherName) const
WidgetView(WidgetView &&other)
void setParent(INumberVectorProperty *parent)
WidgetView(const WidgetView &other)
const char * getFormat() const
void setName(const char *name)
WidgetView & operator=(WidgetView &&other)
void setMinMax(double min, double max)
bool isLabelMatch(const char *otherLabel) const
void setName(const std::string &name)
const char * getName() const
bool isNameMatch(const std::string &otherName) const
void setFormat(const std::string &format)
void setParent(PropertyView< Type > *parent)
void setLabel(const std::string &label)
WidgetView & operator=(const WidgetView &other)
void setFormat(const char *format)
void fill(const std::string &name, const std::string &label, const std::string &format, double min, double max, double step, double value)
bool isLabelMatch(const std::string &otherLabel) const
void setLabel(const char *label)
WidgetView & operator=(const WidgetView &other)
const char * getName() const
void setParent(PropertyView< Type > *parent)
void setParent(ISwitchVectorProperty *parent)
const char * getStateAsString() const
bool isNameMatch(const char *otherName) const
void setLabel(const char *label)
void fill(const std::string &name, const std::string &label, ISState state=ISS_OFF)
WidgetView(const WidgetView &other)
void setName(const char *name)
bool isLabelMatch(const std::string &otherLabel) const
bool setState(const std::string &state)
void setState(const ISState &state)
WidgetView & operator=(WidgetView &&other)
bool isNameMatch(const std::string &otherName) const
const char * getLabel() const
void setName(const std::string &name)
void setLabel(const std::string &label)
WidgetView(WidgetView &&other)
bool isLabelMatch(const char *otherLabel) const
void fill(const std::string &name, const std::string &label, const std::string &initialText)
WidgetView(const WidgetView &other)
bool isLabelMatch(const std::string &otherLabel) const
bool isNameMatch(const std::string &otherName) const
WidgetView & operator=(const WidgetView &other)
const char * getName() const
void setText(const char *text)
WidgetView(WidgetView &&other)
void setLabel(const std::string &label)
const char * getLabel() const
void setName(const char *name)
void setText(const std::string &text)
void setText(const char *text, size_t size)
void setParent(ITextVectorProperty *parent)
void setLabel(const char *label)
void setName(const std::string &name)
bool isLabelMatch(const char *otherLabel) const
WidgetView & operator=(WidgetView &&other)
void setParent(PropertyView< Type > *parent)
bool isNameMatch(const char *otherName) const
const char * getText() const
One number descriptor.
One switch descriptor.
One text descriptor.
Holds the connection type.
BLOB (Binary Large Object) vector property descriptor.
Definition: indiapi.h:471
Light vector property descriptor.
Definition: indiapi.h:417
Number vector property descriptor.
Definition: indiapi.h:319
Switch vector property descriptor.
Definition: indiapi.h:367
Text vector property descriptor.
Definition: indiapi.h:246