Program Listing for File createRequest.h

Return to documentation for file (src/copy/pv/createRequest.h)

/*createRequest.h*/
/*
 * Copyright information and license terms for this software can be
 * found in the file LICENSE that is included with the distribution
 */

#ifndef CREATEREQUEST_H
#define CREATEREQUEST_H
#include <string>
#include <sstream>
#include <vector>

#include <pv/pvData.h>
#include <pv/lock.h>
#include <pv/bitSet.h>

#include <shareLib.h>

namespace epics { namespace pvData {

class BitSet;

class epicsShareClass CreateRequest {
    public:
    POINTER_DEFINITIONS(CreateRequest);
    static CreateRequest::shared_pointer create();
    ~CreateRequest() {};
    PVStructure::shared_pointer createRequest(std::string const & request);
    std::string getMessage() {return message;}
protected:
    CreateRequest() {}
    std::string message;
};

epicsShareExtern
PVStructure::shared_pointer createRequest(std::string const & request);

class epicsShareClass PVRequestMapper {
public:
    enum mode_t {
        Mask,
        Slice,
    };

    PVRequestMapper();
    PVRequestMapper(const PVStructure& base,
                    const PVStructure& pvRequest,
                    mode_t mode = Mask);

    void reset();

    inline const StructureConstPtr& base() const { return typeBase; }
    inline const StructureConstPtr& requested() const { return typeRequested; }

    inline const BitSet& requestedMask() const { return maskRequested; }

    PVStructurePtr buildRequested() const;
    PVStructurePtr buildBase() const;

    void compute(const PVStructure& base,
                 const PVStructure& pvRequest,
                 mode_t mode = Mask);

    inline const std::string& warnings() const { return messages; }

    void copyBaseToRequested(
            const PVStructure& base,
            const BitSet& baseMask,
            PVStructure& request,
            BitSet& requestMask
    ) const;

    void copyBaseFromRequested(
            PVStructure& base,
            BitSet& baseMask,
            const PVStructure& request,
            const BitSet& requestMask
    ) const;

    inline void maskBaseToRequested(
            const BitSet& baseMask,
            BitSet& requestMask
            ) const
    { _mapMask(baseMask, requestMask, false); }

    inline void maskBaseFromRequested(
            BitSet& baseMask,
            const BitSet& requestMask
            ) const
    { _mapMask(requestMask, baseMask, true); }

    void swap(PVRequestMapper& other);

private:
    bool _compute(const PVStructure& base, const PVStructure& pvReq,
                  FieldBuilderPtr& builder, bool keepids, unsigned depth);

    void _map(const PVStructure& src,
              const BitSet& maskSrc,
              PVStructure& dest,
              BitSet& maskDest,
              bool dir_r2b) const;
    void _mapMask(const BitSet& maskSrc,
                  BitSet& maskDest,
                  bool dir_r2b) const;

    StructureConstPtr typeBase, typeRequested;
    BitSet maskRequested;
    // Map between field offsets of base and requested Structures.
    // Include all fields, both leaf and sub-structure.
    struct Mapping {
        size_t to; // offset in destination Structure
        BitSet tomask,   // if !leaf these are the other bits in the destination mask to changed
               frommask; // if !leaf these are the other bits in the source mask to be copied
        bool valid; // only true in (sparse) base -> requested mapping
        bool leaf; // not a (sub)Structure?
        Mapping() :valid(false) {}
        Mapping(size_t to, bool leaf) :to(to), valid(true), leaf(leaf) {}
    };
    typedef std::vector<Mapping> mapping_t;
    mapping_t base2req, req2base;

    std::string messages;

    mutable BitSet scratch; // avoid temporary allocs.  (we aren't re-entrant!)
};

}}

#endif /* CREATEREQUEST_H */