Beispiel #1
0
    string RepositoryXL::storeObject(
        const string &objectIDRaw,
        const shared_ptr<Object> &object,
        bool overwrite,
        boost::shared_ptr<ValueObject> valueObject) {

            shared_ptr<CallingRange> callingRange = getCallingRange();
            string objectID = callingRange->initializeID(objectIDRaw);
            if (objectIDRaw.empty() && valueObject)
                valueObject->setProperty("OBJECTID", objectID);

            shared_ptr<ObjectWrapperXL> objectWrapperXL;
            ObjectMap::const_iterator result = objectMap_.find(objectID);
            if (result == objectMap_.end()) {
                objectWrapperXL = shared_ptr<ObjectWrapperXL> (
                    new ObjectWrapperXL(objectID, object, callingRange));
                objectMap_[objectID] = objectWrapperXL;
                callingRange->registerObject(objectID, objectWrapperXL);
            } else {
                objectWrapperXL = boost::static_pointer_cast<ObjectWrapperXL>(result->second);
                if (objectWrapperXL->callerKey() != callingRange->key()) {
                    OH_REQUIRE(overwrite, "Cannot create object with ID '" << objectID <<
                        "' in cell " << callingRange->addressString() <<
                        " because an object with that ID already resides in cell " <<
                        objectWrapperXL->callerAddress());
                    objectWrapperXL->resetCaller(callingRange);
                    callingRange->registerObject(objectID, objectWrapperXL);
                }
                objectWrapperXL->reset(object);
            }

            registerObserver(objectWrapperXL);
            return objectWrapperXL->idFull();
    }
    const CurveClass *get(const QuantLib::Extrapolator *extrapolator) const {

        const CurveClass *ret = dynamic_cast<const CurveClass*>(extrapolator);
        OH_REQUIRE(ret, "Unable to convert from type " << typeid(extrapolator).name()
                   << " to type " << typeid(CurveClass).name());
        return ret;
    }
Beispiel #3
0
 shared_ptr<CallingRange> RepositoryXL::getCallingRange() {
     string callerName = FunctionCall::instance().callerName();
     if (callerName == "VBA") {
         // Called from VBA - check whether the corresponding calling range
         // object exists and create it if not.
         RangeMap::const_iterator i = callingRanges_.find(callerName);
         if (i == callingRanges_.end()) {
             shared_ptr<CallingRange> callingRange(new CallingRange);
             callingRanges_[callingRange->key()] = callingRange;
             return callingRange;
         } else {
             return i->second;
         }
         // Called from a worksheet formula
     } else if (callerName.empty()) {
         // Calling range not yet named - create a new CallingRange object
         shared_ptr<CallingRange> callingRange(new CallingRange);
         callingRanges_[callingRange->key()] = callingRange;
         return callingRange;
     } else {
         // Calling range already named - return associated CallingRange object
         RangeMap::const_iterator i = callingRanges_.find(callerName);
         OH_REQUIRE(i != callingRanges_.end(), "No calling range named " << callerName);
         return i->second;
     }
 }
Beispiel #4
0
    std::string CallingRange::getKeyCount() {
        static const int KEY_BASE = 16;
        static const double KEY_MAX = pow((double)KEY_BASE, KEY_WIDTH);

        OH_REQUIRE(keyCount_ < KEY_MAX, "CallingRange::getKeyCount() : max key value exceeded");
        std::ostringstream s;
        s << '_' << std::setw(KEY_WIDTH) << std::setfill('0') << std::setbase(KEY_BASE) << keyCount_++;
        return s.str();
    }
Beispiel #5
0
XLL_DEC OPER *ohFilter(
        OPER *xInput,
        OPER *flags) {

    // declare a shared pointer to the Function Call object

    boost::shared_ptr<ObjectHandler::FunctionCall> functionCall;

    try {

        // instantiate the Function Call object
    
        functionCall = boost::shared_ptr<ObjectHandler::FunctionCall>(
            new ObjectHandler::FunctionCall("ohFilter"));

        // convert input datatypes to C++ datatypes

        std::vector<bool> flagsCpp = ObjectHandler::operToVector<bool>(*flags, "flags");

        const OPER *xMulti;
        ObjectHandler::Xloper xTemp;
        if (xInput->xltype == xltypeMulti) {
            xMulti = xInput;
        } else {
            Excel(xlCoerce, &xTemp, 2, xInput, TempInt(xltypeMulti));
            xMulti = &xTemp;
        }

        int sizeInput = xMulti->val.array.rows * xMulti->val.array.columns;
        OH_REQUIRE(sizeInput == flagsCpp.size(),
            "size mismatch between value vector (" << sizeInput << 
            ") and flag vector (" << flagsCpp.size() << ")");


        static OPER xRet;
        xRet.val.array.rows = count(flagsCpp.begin(), flagsCpp.end(), true);
        xRet.val.array.columns = 1;
        xRet.val.array.lparray = new OPER[xRet.val.array.rows]; 
        xRet.xltype = xltypeMulti | xlbitDLLFree;

        int idx = 0;
        for (int i=0; i<sizeInput; i++) {
            if (flagsCpp[i]) {
                operToOper(&xRet.val.array.lparray[idx++], &xMulti->val.array.lparray[i]);
            }
        }

        return &xRet;

    } catch (const std::exception &e) {
        ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall);
        return 0;
    }
}
Beispiel #6
0
    std::string CallingRange::initializeID(const std::string &objectID) {

        static const std::string anonPrefix("obj");
        static const std::string ANONPREFIX("OBJ");

        if (objectID.empty()) {
            if (callerType_ == CallerType::Cell) {
                return anonPrefix + key_;
            } else {
                OH_FAIL("Null string specified for object ID");
            }
        }

        OH_REQUIRE(objectID.find(counterDelimiter, 0) == std::string::npos,
            objectID << " is an invalid ID: cannot contain " << counterDelimiter);
        std::string ID = boost::algorithm::to_upper_copy(objectID);
        OH_REQUIRE(ID.rfind(ANONPREFIX, ANONPREFIX.size() - 1) == std::string::npos,
            objectID << " is an invalid ID: cannot start with " << anonPrefix);

        return objectID;
    }
    CallingRange::CallingRange() 
        : updateCount_(0), callerType_(FunctionCall::instance().callerType()) {

        if (callerType_ == CallerType::Cell) {
            // name the calling range
            key_ = getKeyCount();
            XLOPER xRet;
            Excel(xlfSetName, &xRet, 2, TempStrStl(key_), FunctionCall::instance().callerReference());
            OH_REQUIRE(xRet.xltype == xltypeBool && xRet.val.boolean, "Error on call to xlfSetName");
        } else {
            key_ = "VBA";
        }
    }
    QuantLib::Array operToQlArray(const OPER &xVector, 
            const std::string paramName) {
        OPER xTemp;
        bool excelToFree = false;
        bool xllToFree = false;
        try {
            OH_REQUIRE(!(xVector.xltype & xltypeErr), 
                "input value '" << paramName << "' has type=error");
            if (xVector.xltype & (xltypeMissing | xltypeNil))
                return QuantLib::Array();

            const OPER *xMulti;

            if (xVector.xltype == xltypeMulti) {
                xMulti = &xVector;
            } else if (xVector.xltype == xltypeStr) {
                splitOper(&xVector, &xTemp);
                xMulti = &xTemp;
                xllToFree = true;
            } else {
                Excel(xlCoerce, &xTemp, 2, &xVector, TempInt(xltypeMulti));
                xMulti = &xTemp;
                excelToFree = true;
            }

            int size = xMulti->val.array.rows * xMulti->val.array.columns;
            QuantLib::Array a(size);
            for (int i=0; i<size; ++i) {
                a[i] = ObjectHandler::convert2<double>(ObjectHandler::ConvertOper(xMulti->val.array.lparray[i]));
            }

            if (excelToFree) {
                Excel(xlFree, 0, 1, &xTemp);
            } else if (xllToFree) {
                freeOper(&xTemp);
            }

            return a;
        } catch (const std::exception &e) {
            if (excelToFree) {
                Excel(xlFree, 0, 1, &xTemp);
            } else if (xllToFree) {
                freeOper(&xTemp);
            }
            OH_FAIL("operToVector: error converting parameter '" << paramName << "' : " << e.what());
        }
    }
Beispiel #9
0
inline void Observable::notifyObservers() {
    bool successful = true;
    for (iterator i=observers_.begin(); i!=observers_.end(); ++i) {
        try {
            (*i)->update();
        } catch (...) {
            // quite a dilemma. If we don't catch the exception,
            // other observers will not receive the notification
            // and might be left in an incorrect state. If we do
            // catch it and continue the loop (as we do here) we
            // lose the exception. The least evil might be to try
            // and notify all observers, while raising an
            // exception if something bad happened.
            successful = false;
        }
    }
    OH_REQUIRE(successful, "could not notify one or more observers");
}
Beispiel #10
0
    FunctionCall::FunctionCall(const std::string functionName) :
            functionName_(functionName), 
            callerDimensions_(CallerDimensions::Uninitialized),
            error_(false) {
        OH_REQUIRE(!instance_, "Multiple attempts to initialize global FunctionCall object");
        instance_ = this;

        Excel(xlfCaller, &xCaller_, 0);
        if (xCaller_->xltype == xltypeRef || xCaller_->xltype == xltypeSRef) {
            Excel(xlfReftext, &xReftext_, 1, &xCaller_);
            refStr_ = ConvertOper(xReftext_());
            callerType_ = CallerType::Cell;
        } else if (xCaller_->xltype & xltypeErr) {
            callerType_ = CallerType::VBA;
        } else if (xCaller_->xltype == xltypeMulti) {
            callerType_ = CallerType::Menu;
        } else {
            callerType_ = CallerType::Unknown;
        }
    }
Beispiel #11
0
    bool handleToObject(
        const boost::shared_ptr<ObjectHandler::Object> &in,
        boost::shared_ptr<ObjectTo> &out) {

        // FIXME gcc doesn't like this typedef
        //typedef RelinkableHandleImpl<ObjectFrom, LibraryFrom> HandleClass;
        //boost::shared_ptr<HandleClass> handle =
        //    boost::dynamic_pointer_cast<HandleClass>(in);
        boost::shared_ptr<RelinkableHandleImpl<ObjectFrom, LibraryFrom> > handle =
            boost::dynamic_pointer_cast<RelinkableHandleImpl<ObjectFrom, LibraryFrom> >(in);

        if (!handle) return false;

        out = boost::dynamic_pointer_cast<ObjectTo>(handle->object());
        OH_REQUIRE(out, "unable to convert reference from class '"
            << typeid(ObjectFrom).name()<< "' to class '"
            << typeid(ObjectTo).name() << "'");

        return true;
    }
Beispiel #12
0
    string RepositoryXL::retrieveError(const XLOPER *xRangeRef) {

        OH_REQUIRE(xRangeRef->xltype == xltypeRef || xRangeRef->xltype == xltypeSRef,
            "Input parameter is not a range reference.");
        Xloper xRangeText;
        Excel(xlfReftext, &xRangeText, 1, xRangeRef);
        string refStr = ConvertOper(xRangeText());
        string refStrUpper = boost::algorithm::to_upper_copy(refStr);

        ErrorMessageMap::const_iterator i = errorMessageMap_.find(refStrUpper);
        if (i != errorMessageMap_.end())
            return i->second->errorMessage();

        RangeReference selectionReference(refStrUpper);
        for (i = errorMessageMap_.begin(); i != errorMessageMap_.end(); ++i) {
            if (i->second->contains(selectionReference))
                return i->second->errorMessage();
        }

        return "";
    }
Beispiel #13
0
    std::vector<std::vector<T> > operToMatrixImpl(
        const ConvertOper &xMatrix, 
        const std::string &paramName) {

        try {
            if (xMatrix.missing()) return std::vector<std::vector<T> >();

            OH_REQUIRE(!xMatrix.error(), "input value has type=error");

            const OPER *xMulti;
            Xloper xCoerce;  // Freed automatically

            if (xMatrix->xltype == xltypeMulti)
                xMulti = xMatrix.get();
            else {
                Excel(xlCoerce, &xCoerce, 2, xMatrix.get(), TempInt(xltypeMulti));
                xMulti = &xCoerce;
            }

            std::vector<std::vector<T> > ret;
            ret.reserve(xMulti->val.array.rows);
            for (int i=0; i<xMulti->val.array.rows; ++i) {
                std::vector<T> row;
                row.reserve(xMulti->val.array.columns);
                for (int j=0; j<xMulti->val.array.columns; ++j) {
                    row.push_back(convert2<T>(ConvertOper(xMulti->val.array.lparray[i * xMulti->val.array.columns + j])));                
                }
                ret.push_back(row);
            }

            return ret;
        } catch (const std::exception &e) {
            OH_FAIL("operToMatrixImpl: error converting parameter '" << paramName 
                << "' to type '" << typeid(T).name() << "' : " << e.what());
        }
    }
Beispiel #14
0
 FunctionCall &FunctionCall::instance() {
     OH_REQUIRE(instance_, "Attempt to reference uninitialized FunctionCall object");
     return *instance_;
 }
Beispiel #15
0
    /*
    Parse the joint calendar ID.
    A JointCalendar ID is in a format such as
        JoinHolidays(UnitedStates::Settlement, UnitedKingdom::Exchange)
    - the initial string is either "JoinHolidays" or "JoinBusinessDays"
    - the parentheses contain a comma-delimited list of 2, 3 or 4 calendar IDs
    - a calendar ID can be in format "abcd" or "abcd::efgh"
    */
    void Create<QuantLib::Calendar>::parseID() {
        // strip out whitespace (NB ~50% of elapsed time spent here)
        static boost::regex regex_whitespace("\\s");
        std::string idStrip = boost::regex_replace(idUpper, regex_whitespace, "");

        // parse the ID (the other ~50%).
        static boost::regex jointCalendarID(
            "((?:JOINHOLIDAYS)|(?:JOINBUSINESSDAYS))\\((.+?),(.+?)(?:,(.+?))?(?:,(.+))?\\)");
        boost::smatch m;
        OH_REQUIRE(boost::regex_match(idStrip, m, jointCalendarID),
            "the string '" << idOriginal << "' is not a valid joint calendar identifier");

        // Derive the inputs to the JointCalendar constructor.

        // Add the calendar IDs to a set where they will be uniquely sorted.
        std::set<std::string> calendarIdSet;

        // Given that the regex succeeded, we're guaranteed :-) to have
        // m[1] - "JOINHOLIDAYS"/"JOINBUSINESSDAYS"
        // m[2] - the ID of the first calendar
        // m[3] - the ID of the second calendar
        if (m[1] == "JOINHOLIDAYS")
            jointCalendarRule = QuantLib::JointCalendarRule(QuantLib::JoinHolidays);
        else // "JOINBUSINESSDAYS"
            jointCalendarRule = QuantLib::JointCalendarRule(QuantLib::JoinBusinessDays);
        calendarIdSet.insert(m[2]);
        calendarIdSet.insert(m[3]);

        // we may have a 3rd or a 3rd & 4th calendar
        if (m[5].matched) {
            calendarIdSet.insert(m[4]);
            calendarIdSet.insert(m[5]);
        } else if (m[4].matched) {
            calendarIdSet.insert(m[4]);
        }

        // if the list of calendars contained duplicates,
        // we may end up with just one value, which is invalid
        OH_REQUIRE(calendarIdSet.size() > 1, "the string '" << idOriginal <<
            "' is not a valid joint calendar identifier");

        /*
        1) transfer the IDs from the set to a vector
        2) in the same loop, format a unique key "idFull" for the object,
           this will be the same as the ID provided by the user e.g.
             JoinHolidays(UnitedStates::Settlement, UnitedKingdom::Exchange)
           -> uppercase, no whitespace, IDs sorted alphabetically e.g.
             JOINHOLIDAYS(UNITEDKINGDOM::EXCHANGE,UNITEDSTATES::SETTLEMENT)
        */
        std::set<std::string>::const_iterator i = calendarIdSet.begin();
        std::ostringstream s;
        s << m[1] << "(" << *i;
        calendarIDs.push_back(*i);
        i++;
        while (i != calendarIdSet.end()) {
            calendarIDs.push_back(*i);
            s << "," << *i;
            i++;
        }
        s << ")";
        idFull = s.str();

    }
 // Retrieve the Caller pointer corresponding to a given InterpolatedYieldCurvePair
 const CallerBase *getCaller(InterpolatedYieldCurvePair tokenPair) const {
     CallerMap::const_iterator i = callerMap_.find(tokenPair);
     OH_REQUIRE(i!=callerMap_.end(), "Unable to retrieve caller for type " << tokenPair);
     return i->second;
 }
Beispiel #17
0
void validateReference(const XLOPER *xReference, const std::string &name) {
    OH_REQUIRE(xReference->xltype != xltypeErr && xReference->val.err != xlerrRef,
        "parameter '" << name << "' is not a valid range reference");
}
Beispiel #18
0
 const boost::shared_ptr<ObjectClass> &object() const {
     OH_REQUIRE(object_, "Attempt to retrieve null object reference");
     return object_;
 }