r-lib / xml2
1
#ifndef __XML2_XML2_TYPES__
2
#define __XML2_XML2_TYPES__
3

4
#include <libxml/tree.h>
5
#define R_NO_REMAP
6
#include <Rinternals.h>
7

8
template <typename T> class XPtr {
9
  protected:
10
  SEXP data_;
11

12
  public:
13 1
  XPtr(SEXP x) : data_(x) {
14 1
    if (TYPEOF(data_) != EXTPTRSXP) {
15 0
      Rf_error("Expecting an external pointer: [type=%s]", Rf_type2char(TYPEOF(data_)));
16
    }
17 1
    R_PreserveObject(data_);
18
  }
19

20 1
  XPtr(T* p) {
21 1
    data_ = R_MakeExternalPtr((void *) p, R_NilValue, R_NilValue);
22 1
    R_PreserveObject(data_);
23
  }
24

25 1
  operator SEXP() const { return data_; }
26

27 1
  T* get() const {
28 1
    return (T*)(R_ExternalPtrAddr(data_));
29
  }
30

31 1
  T* checked_get() const {
32 1
    T* ptr = get();
33 1
    if (ptr == NULL) {
34 1
      Rf_error("external pointer is not valid");
35
    }
36 1
    return ptr;
37
  }
38

39 1
  operator T*() {
40 1
    return checked_get();
41
  }
42

43 1
  T* operator->() const {
44 1
    return checked_get();
45
  }
46

47 1
  ~XPtr() {
48 1
    R_ReleaseObject(data_);
49
  }
50
};
51

52

53 1
class XPtrDoc : public ::XPtr<xmlDoc> {
54 1
  static void finalizeXPtrDoc(SEXP p) {
55 1
    if (TYPEOF(p) != EXTPTRSXP) {
56 0
      return;
57
    }
58

59 1
    xmlDoc* ptr = (xmlDoc*) R_ExternalPtrAddr(p);
60

61 1
    if (ptr == NULL) {
62 0
      return;
63
    }
64

65 1
    R_ClearExternalPtr(p);
66

67 1
    xmlFreeDoc(ptr);
68
  }
69

70
  public:
71 1
  XPtrDoc(xmlDoc* p) : ::XPtr<xmlDoc>(p) {
72 1
    R_RegisterCFinalizerEx(data_, finalizeXPtrDoc, (Rboolean) false);
73
  }
74

75 1
  XPtrDoc(SEXP x) : ::XPtr<xmlDoc>(x) {}
76
};
77

78
typedef ::XPtr<xmlNode> XPtrNode;
79
typedef ::XPtr<xmlNs> XPtrNs;
80

81
#endif

Read our documentation on viewing source code .

Loading