Go to the documentation of this file.00001 #include "DataFormats/Common/interface/RefCore.h"
00002 #include "FWCore/Utilities/interface/EDMException.h"
00003 #include "FWCore/Utilities/interface/TypeID.h"
00004 #include <cassert>
00005 #include <iostream>
00006 #include <ostream>
00007
00008 static
00009 void throwInvalidRefFromNullOrInvalidRef(const edm::TypeID& id) {
00010 throw edm::Exception(edm::errors::InvalidReference,
00011 "BadRefCore")
00012 << "RefCore: Request to resolve a null or invalid reference to a product of type '"
00013 << id
00014 << "' has been detected.\n"
00015 << "Please modify the calling code to test validity before dereferencing.\n";
00016 }
00017
00018 static
00019 void throwInvalidRefFromNoCache(const edm::TypeID& id, edm::ProductID const& prodID) {
00020 throw edm::Exception(edm::errors::InvalidReference,
00021 "BadRefCore")
00022 << "RefCore: A request to resolve a reference to a product of type '"
00023 << id
00024 << "' with ProductID '" << prodID
00025 << "' cannot be satisfied.\n"
00026 << "The reference has neither a valid product pointer nor an EDProductGetter.\n"
00027 << "The calling code must be modified to establish a functioning EDProducterGetter\n"
00028 << "for the context in which this call is mode\n";
00029
00030 }
00031
00032 namespace edm {
00033
00034 RefCore::RefCore(ProductID const& theId, void const* prodPtr, EDProductGetter const* prodGetter, bool transient) :
00035 cachePtr_(prodPtr?prodPtr:prodGetter),
00036 processIndex_(theId.processIndex()),
00037 productIndex_(theId.productIndex()),
00038 transient_(transient,prodPtr!=0 || prodGetter==0)
00039 {}
00040
00041 EDProduct const*
00042 RefCore::getProductPtr(std::type_info const& type) const {
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 ProductID tId = id();
00058 assert (!isTransient());
00059 if (!tId.isValid()) {
00060 throwInvalidRefFromNullOrInvalidRef(TypeID(type));
00061 }
00062
00063
00064 if (cachePtr_ == 0) {
00065 throwInvalidRefFromNoCache(TypeID(type),tId);
00066 }
00067 EDProduct const* product = productGetter()->getIt(tId);
00068 if ( 0 == product) {
00069 productNotFoundException(type);
00070 }
00071 return product;
00072 }
00073
00074 void
00075 RefCore::productNotFoundException(std::type_info const& type) const {
00076 throw edm::Exception(errors::ProductNotFound)
00077 << "RefCore: A request to resolve a reference to a product of type '"
00078 << TypeID(type)
00079 << "' with ProductID '" << id() << "'"
00080 << "\ncan not be satisfied because the product cannot be found."
00081 << "\nProbably the branch containing the product is not stored in the input file.\n";
00082 }
00083
00084 void
00085 RefCore::wrongTypeException(std::type_info const& expectedType, std::type_info const& actualType) const {
00086 throw edm::Exception(errors::InvalidReference,"WrongType")
00087 << "RefCore: A request to convert a contained product of type '"
00088 << TypeID(actualType) << "'\n"
00089 << " to type '" << TypeID(expectedType) << "'"
00090 << "\nfor ProductID '" << id()
00091 << "' can not be satisfied\n";
00092 }
00093
00094 void
00095 RefCore::nullPointerForTransientException(std::type_info const& type) const {
00096 throw edm::Exception(errors::InvalidReference)
00097 << "RefCore: A request to resolve a transient reference to a product of type: "
00098 << TypeID(type)
00099 << "\ncan not be satisfied because the pointer to the product is null.\n";
00100 }
00101
00102 bool
00103 RefCore::isAvailable() const {
00104 ProductID tId = id();
00105 return productPtr() != 0 || (tId.isValid() && productGetter() != 0 && 0 != productGetter()->getIt(tId));
00106 }
00107
00108 void
00109 RefCore::setProductGetter(EDProductGetter const* prodGetter) const {
00110 cachePtr_ = prodGetter;
00111 setCacheIsProductPtr(false);
00112 }
00113
00114 void
00115 RefCore::pushBackItem(RefCore const& productToBeInserted, bool checkPointer) {
00116 if (productToBeInserted.isNull() && !productToBeInserted.isTransient()) {
00117 throw edm::Exception(errors::InvalidReference,"Inconsistency")
00118 << "RefCore::pushBackItem: Ref or Ptr has invalid (zero) product ID, so it cannot be added to RefVector (PtrVector). "
00119 << "id should be (" << id() << ")\n";
00120 }
00121 if (isNonnull()) {
00122 if (isTransient() != productToBeInserted.isTransient()) {
00123 if (productToBeInserted.isTransient()) {
00124 throw edm::Exception(errors::InvalidReference,"Inconsistency")
00125 << "RefCore::pushBackItem: Transient Ref or Ptr cannot be added to persistable RefVector (PtrVector). "
00126 << "id should be (" << id() << ")\n";
00127 } else {
00128 throw edm::Exception(errors::InvalidReference,"Inconsistency")
00129 << "RefCore::pushBackItem: Persistable Ref or Ptr cannot be added to transient RefVector (PtrVector). "
00130 << "id is (" << productToBeInserted.id() << ")\n";
00131 }
00132 }
00133 if (!productToBeInserted.isTransient() && id() != productToBeInserted.id()) {
00134 throw edm::Exception(errors::InvalidReference,"Inconsistency")
00135 << "RefCore::pushBackItem: Ref or Ptr is inconsistent with RefVector (PtrVector)"
00136 << "id = (" << productToBeInserted.id() << ") should be (" << id() << ")\n";
00137 }
00138 if (productToBeInserted.isTransient() && checkPointer && productToBeInserted.isNonnull() && productToBeInserted != *this) {
00139 throw edm::Exception(errors::InvalidReference,"Inconsistency")
00140 << "RefCore::pushBackItem: Ref points into different collection than the RefVector.\n";
00141 }
00142 } else {
00143 if (productToBeInserted.isTransient()) {
00144 setTransient();
00145 }
00146 if (productToBeInserted.isNonnull()) {
00147 setId(productToBeInserted.id());
00148 }
00149 }
00150
00151
00152
00153 if (productPtr() == 0 && productToBeInserted.productPtr() != 0) {
00154 setProductPtr(productToBeInserted.productPtr());
00155 } else if (productPtr() == 0 && productGetter() == 0 && productToBeInserted.productGetter() != 0) {
00156 setProductGetter(productToBeInserted.productGetter());
00157 }
00158 }
00159
00160 }