OnFile

OnFile

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
#ifndef DataFormats_Portable_interface_PortableHostCollectionReadRules_h
#define DataFormats_Portable_interface_PortableHostCollectionReadRules_h

#include <TGenericClassInfo.h>
#include <TVirtualObject.h>

#include "DataFormats/Portable/interface/PortableHostCollection.h"
#include "FWCore/Utilities/interface/concatenate.h"
#include "FWCore/Utilities/interface/stringize.h"

// read function for PortableHostCollection, called for every event
template <typename T>
static void readPortableHostCollection_v1(char *target, TVirtualObject *from_buffer) {
  // extract the actual types
  using Collection = T;
  using Layout = typename Collection::Layout;

  // valid only for PortableHostCollection<T>
  static_assert(std::is_same_v<Collection, PortableHostCollection<Layout>>);

  // proxy for the object being read from file
  struct OnFile {
    Layout &layout_;
  };

  // address in memory of the buffer containing the object being read from file
  char *address = static_cast<char *>(from_buffer->GetObject());
  // offset of the "layout_" data member
  static ptrdiff_t layout_offset = from_buffer->GetClass()->GetDataMemberOffset("layout_");
  // reference to the Layout object being read from file
  OnFile onfile = {*(Layout *)(address + layout_offset)};

  // pointer to the Collection object being constructed in memory
  Collection *newObj = (Collection *)target;

  // move the data from the on-file layout to the newly constructed object
  Collection::ROOTReadStreamer(newObj, onfile.layout_);
}

// read function for PortableHostCollection, called for every event
template <typename T>
static void readPortableHostMultiCollection_v1(char *target, TVirtualObject *from_buffer) {
  // extract the actual types
  using Collection = T;
  using Implementation = typename Collection::Implementation;

  // valid only for PortableHostCollection<T>
  //static_assert(std::is_same_v<Collection, PortableHostCollection<Layout>>);

  // proxy for the object being read from file
  struct OnFile {
    Implementation &impl_;
  };

  // address in memory of the buffer containing the object being read from file
  char *address = static_cast<char *>(from_buffer->GetObject());
  // offset of the "layout_" data member
  static ptrdiff_t impl_offset = from_buffer->GetClass()->GetDataMemberOffset("impl_");
  // reference to the Layout object being read from file
  OnFile onfile = {*(Implementation *)(address + impl_offset)};

  // pointer to the Collection object being constructed in memory
  Collection *newObj = (Collection *)target;

  // move the data from the on-file layout to the newly constructed object
  Collection::ROOTReadStreamer(newObj, onfile.impl_);
}

// put set_PortableHostCollection_read_rules in the ROOT namespace to let it forward declare GenerateInitInstance
namespace ROOT {

  // set the read rules for PortableHostCollection<T>;
  // this is called only once, when the dictionary is loaded.
  template <typename T>
  static bool set_PortableHostCollection_read_rules(std::string const &type) {
    // forward declaration
    TGenericClassInfo *GenerateInitInstance(T const *);

    // build the read rules
    std::vector<ROOT::Internal::TSchemaHelper> readrules(1);
    ROOT::Internal::TSchemaHelper &rule = readrules[0];
    rule.fTarget = "buffer_,layout_,view_";
    rule.fSourceClass = type;
    rule.fSource = type + "::Layout layout_;";
    rule.fCode = type + "::ROOTReadStreamer(newObj, onfile.layout_)";
    rule.fVersion = "[1-]";
    rule.fChecksum = "";
    rule.fInclude = "";
    rule.fEmbed = false;
    rule.fFunctionPtr = reinterpret_cast<void *>(::readPortableHostCollection_v1<T>);
    rule.fAttributes = "";

    // set the read rules
    TGenericClassInfo *instance = GenerateInitInstance((T const *)nullptr);
    instance->SetReadRules(readrules);

    return true;
  }

  // set the read rules for PortableHostMultiCollection<T>;
  // this is called only once, when the dictionary is loaded.
  template <typename T>
  static bool set_PortableHostMultiCollection_read_rules(std::string const &type) {
    // forward declaration
    TGenericClassInfo *GenerateInitInstance(T const *);

    // build the read rules
    std::vector<ROOT::Internal::TSchemaHelper> readrules(1);
    ROOT::Internal::TSchemaHelper &rule = readrules[0];
    rule.fTarget = "buffer_,impl_";
    rule.fSourceClass = type;
    rule.fSource = type + "::Implementation impl_;";
    rule.fCode = type + "::ROOTReadStreamer(newObj, onfile.impl_)";
    rule.fVersion = "[1-]";
    rule.fChecksum = "";
    rule.fInclude = "";
    rule.fEmbed = false;
    rule.fFunctionPtr = reinterpret_cast<void *>(::readPortableHostMultiCollection_v1<T>);
    rule.fAttributes = "";

    // set the read rules
    TGenericClassInfo *instance = GenerateInitInstance((T const *)nullptr);
    instance->SetReadRules(readrules);

    return true;
  }
}  // namespace ROOT

#define SET_PORTABLEHOSTCOLLECTION_READ_RULES(COLLECTION)                                                  \
  static bool EDM_CONCATENATE(set_PortableHostCollection_read_rules_done_at_, __LINE__) [[maybe_unused]] = \
      ROOT::set_PortableHostCollection_read_rules<COLLECTION>(EDM_STRINGIZE(COLLECTION))

#define SET_PORTABLEHOSTMULTICOLLECTION_READ_RULES(COLLECTION)                                                  \
  static bool EDM_CONCATENATE(set_PortableHostMultiCollection_read_rules_done_at_, __LINE__) [[maybe_unused]] = \
      ROOT::set_PortableHostMultiCollection_read_rules<COLLECTION>(EDM_STRINGIZE(COLLECTION))

#endif  // DataFormats_Portable_interface_PortableHostCollectionReadRules_h