Commit c6b9aa9a authored by Holcomb, Andrew's avatar Holcomb, Andrew
Browse files

Add hand-coded classes

parent 9ee1a64b
Loading
Loading
Loading
Loading

ArrayContainer.cpp

0 → 100644
+1015 −0

File added.

Preview size limit exceeded, changes collapsed.

ArrayContainer.h

0 → 100644
+176 −0
Original line number Diff line number Diff line
#ifndef ENDF_GND_ARRAYCONTAINER_H
#define ENDF_GND_ARRAYCONTAINER_H

#include "Container.h"
#include <memory>
#include "ValuesContainer.h"
#include <vector>

namespace endfgnd
{
class ArrayContainer
    : public Container /*, public ContainerHelper<ArrayContainer,"array">*/
{
  public:
    enum class COMPRESSION
    {
        NONE      = 0,
        DIAGONAL  = 1,
        FLATTENED = 2,
        EMBEDDED  = 3
    };

    enum class PERMUTATION
    {
        NONE    = 0,
        PLUS_1  = 1,
        MINUS_1 = -1
    };

    enum class STORAGE
    {
        ROW_MAJOR    = 0,
        COLUMN_MAJOR = 1
    };

    enum TRIANGULAR
    {
        NONE  = 0,
        UPPER = 1,
        LOWER = 2
    };

    ArrayContainer()
        : Container("array")
    {
        compressScheme   = COMPRESSION::NONE;
        triangularScheme = TRIANGULAR::NONE;
        permutScheme     = PERMUTATION::NONE;
        storeOrder       = STORAGE::ROW_MAJOR;
        shape            = NULL;
    }

    ArrayContainer(const ArrayContainer& orig);
    virtual ~ArrayContainer() {}

    /**
     * Read the information from an element.
     * The element is expected to be an element with tag name text
     *
     * @param val the element from which to read the attribute values
     */
    virtual void readFromElement(std::shared_ptr<const Element> val,
                                 ContainerRepository*           repo = NULL);

    /**
     * Write the string description of this object.
     * @return string description of this object.
     */
    virtual std::string toString(const std::string& indent = "") const;

    /**
     * Save the data to the element.
     * A new element with tag name text is added to val
     * @param val the element to save the data to
     */
    virtual void saveToElement(std::shared_ptr<Element> val) const;

    /**
     * Get the number of dimensions
     * @return the number of dimensions
     */
    virtual UInteger32 getNumDim() const
    {
        if (shape == NULL)
            return 0;
        return (int)shape->getSize();
    }

    /**
     * Return the size of the indicated dimension
     * @param dim the size of the indicated dimension
     * @return
     */
    virtual Integer32 getSize(int dim) const
    {
        if (shape == NULL || dim < 0 || dim >= shape->getSize())
            return 0;
        return shape->getValue(dim);
    }

    /**
     * Set the shape
     * @param shape the new shape
     */
    virtual void setShape(std::shared_ptr<ValuesContainer<UInteger32>> s)
    {
        shape = s;
    }

    virtual bool checkValidContent() const;

    virtual std::shared_ptr<const ValuesContainer<UInteger32>> getOffset() const
    {
        return offset;
    }

    template<class T>
    T getValue(const std::vector<Integer32> indices) const
    {
        T         def = getDefaultValue<T>();
        Integer32 index;
        int       factor;

        std::shared_ptr<const ValuesContainerHolder> v
            = getValuesCont(indices, index, factor);
        if (v == NULL)
            return def;

        std::shared_ptr<const ValuesContainer<T>> val = NULL;
        v->getContainer<T>(val);
        if (val == NULL)
        {
            throw gnd_error("The array data are not of the desired type ");
        }

        if (index < 0 || index >= val->getSize())
        {
            return def;
        }

        T dd = val->getValue(index);
        dd *= factor;

        return dd;
    }

    virtual Container* getCopy() const { return new ArrayContainer(*this); }

  protected:
    std::shared_ptr<ValuesContainerHolder>
    getValuesCont(const std::vector<Integer32> indices,
                  Integer32&                   index,
                  int&                         factor) const;

    std::shared_ptr<ValuesContainer<UInteger32>> shape;

    COMPRESSION compressScheme;

    TRIANGULAR triangularScheme;

    PERMUTATION permutScheme;

    STORAGE storeOrder;

    std::shared_ptr<ValuesContainer<UInteger32>> offset; // only used for
                                                         // embedded

    /** The values container in this array */
    std::vector<std::shared_ptr<ValuesContainerHolder>> values;

    /** The array  container in this array */
    std::vector<std::shared_ptr<ArrayContainer>> arrays;
};
} // namespace endfgnd

#endif /* ENDF_GND_ARRAYCONTAINER_H */

Container.cpp

0 → 100644
+89 −0
Original line number Diff line number Diff line
#include "Container.h"
#include <sstream>

void endfgnd::Container::readFromElement(
    std::shared_ptr<const endfgnd::Element> val, ContainerRepository* repo)
{
    if (val == NULL)
        return;

    // set the index, default is -1 if not present
    index = -1;
    std::shared_ptr<const endfgnd::Attribute> attr
        = val->getAttribute("index");
    if (attr != NULL)
    {
        std::string v = attr->getValue();
        index         = std::atoi(v.c_str());
    }

    // set the label default is  an empty string
    attr = val->getAttribute("label");
    label.clear();
    if (attr != NULL)
        setLabel(attr->getValue());

    // get the value data, which expects two attributes: valueType and value.
    // If valueType is not present, Float64 is assumed.
    // Default value is NULL
    std::string type;
    attr = val->getAttribute("valueType");
    if (attr != NULL)
        type.append(attr->getValue());

    attr = val->getAttribute("value");
    if (attr != NULL)
    {
        if (value == NULL)
            value = std::make_shared<ValueData>();
        attr->getValueData(type, *value);
    }
    else
    {
        value = NULL;
    }
}

std::string endfgnd::Container::toString(const std::string& indent) const
{
    std::ostringstream out;
    if (!label.empty())
        out << " label=" << label << " ";
    out << " index=" << index << " ";
    if (value != NULL)
    {
        if (value->getTypeName() != NULL
            && value->getTypeName()->compare("") != 0)
        {
            out << " valueType=" << index << " ";
        }
        std::string tmp;
        value->saveDataAsString(tmp);
        out << " value=" << tmp;
    }
    return out.str();
}

void endfgnd::Container::saveToElement(std::shared_ptr<endfgnd::Element> val) const
{
    std::shared_ptr<endfgnd::Attribute> attr;
    if (!label.empty())
    {
        attr = val->addAttribute("label");
        attr->setValue(label);
    }
    attr = val->addAttribute("index");
    attr->setValue(std::to_string(index));

    if (value != NULL)
    {
        if (value->getTypeName() != NULL
            && value->getTypeName()->compare("") != 0)
        {
            attr = val->addAttribute("valueType");
            attr->setValue(*value->getTypeName());
        }
        attr = val->addAttribute("value");
        attr->setValue(*value);
    }
}

Container.h

0 → 100644
+271 −0
Original line number Diff line number Diff line

#ifndef ENDF_GND_CONTAINER_H
#define ENDF_GND_CONTAINER_H

#include <string>
#include "EndfDocument.h"
#include "Definitions.h"
#include <memory>
#include <unordered_map>

/** The base container class */
namespace endfgnd
{
// forward declaration of Container, so ContainerRepository can keep track of
// them
class Container;

/**
 * A class that saves instances of a container.
 * If an XML element was already converted to a GNDS container, it will be
 * saved here (indexed by the element object). This will avoid having to
 * convert the element to a GND container many times, but still allow classes
 * to be constant if retrieving container data.
 */
class ContainerRepository
{
  public:
    ContainerRepository() {}
    ContainerRepository(const ContainerRepository& orig) {}
    virtual ~ContainerRepository() {}

    /**
     * Add a class to the  repository,
     * The class is expected to be a child of Container
     *
     * @param ele the element with whom the object is associated
     * @param val the object to store
     */
    template<class T>
    void add(std::shared_ptr<const Element> ele, std::shared_ptr<T> val)
    {
        if (ele == NULL || val == NULL)
            return;
        ElementKey key(ele);
        mappedContainers[key] = val;
    }

    /**
     * Check whether an object of the desired type was already retrieved from
     * the indicated element.
     *
     * @param ele the element for which to get the container data
     * @return  the container data if found, NULL otherwise
     */
    template<class T>
    std::shared_ptr<T> get(std::shared_ptr<const Element> ele) const
    {
        if (ele == NULL)
            return NULL;
        ElementKey key(ele);
        auto       it = mappedContainers.find(key);
        if (it == mappedContainers.end())
            return NULL;
        std::shared_ptr<endfgnd::Container> cont = it->second;

        return std::dynamic_pointer_cast<T>(cont);
    }

  private:
    /** The map between Container object and the Element */
    std::unordered_map<endfgnd::ElementKey, std::shared_ptr<endfgnd::Container>>
        mappedContainers;
};

/**
 * The base class for all containers in the general data container objects.
 * A container optionally has:
 * <ul>
 *  <li>An integer index. Note: this might by deprecated in the new GNDS in
 * favor of relying on document order but is retained in this class for now. I
 * is used in some unit tests in child containers to ensure that the base
 * containers are read. </li> <li> A string label. <li> A ValueData object that
 * allows to associate certain float or integer values (or any other type
 * allowed in ValueData) with the container</li>
 * </ul>
 * The base class holds these three optional values and also has the
 * functionality to read/save to an Element.
 *
 * In addition the container has a name, which is in most cases used to give
 * the name of the element in which the container information is contained.
 *
 * At one point GNDS discussed to have an attribute href and a link to a
 * different element containing the same information. This is still reflected
 * in the Container class: If an attribute of href is present, all information
 * in the element is ignored and the information is instead retrieved from the
 * element pointed to by href.
 */
class Container
{
  public:
    explicit Container(const std::string& name)
        : index(0)
        , value(NULL)
        , containerName(name)
    {
    }
    Container(const Container& orig)
        : containerName(orig.containerName)
    {
        index = orig.index;
        label.append(orig.label);
        value = NULL;
        if (orig.value != NULL)
            value = std::make_shared<ValueData>(*orig.value);
    }
    virtual ~Container() {}

    /**
     * Get the label for this container
     * @return  the label for this container
     */
    virtual const UTF8Text& getLabel() const { return label; }

    /**
     * Get the index for this container
     * @return the index
     */
    virtual Integer32 getIndex() const { return index; }

    /**
     * Set the label for this container
     * @param the label for this container
     */
    virtual void setLabel(const UTF8Text& l)
    {
        label.clear();
        label.append(l);
    }

    /**
     * Set the label  for this container
     * @param the label for this container
     */
    virtual void setIndex(Integer32 i) { index = i; }

    /**
     * Get the value of the container if it is a function container
     * @return the value  of the container
     */
    virtual const std::shared_ptr<const ValueData> getValueData() const
    {
        return value;
    }

    /**
     * Set the value object of the container if it is a function container
     * @param v the value  of the container
     */
    virtual void setValueData(std::shared_ptr<ValueData>& v)
    {
        value = v;
        v     = NULL;
    }

    /**
     * Read the information from an element.         *
     * Please note: The base class will not save into ContainerRepository, as
     * it would not reflect the correct type for the child class
     *
     * @param val the element from which to read the data
     * @param repo the ContainerRepository in which to store the data, see note
     * above.
     */
    virtual void readFromElement(std::shared_ptr<const endfgnd::Element> val,
                                 ContainerRepository* repo = NULL);

    /**
     * Save the data to the element.
     * We set the attribute values
     * @param val the element to save the data to
     */
    virtual void saveToElement(std::shared_ptr<endfgnd::Element> val) const;

    /**
     * Write the string description of this object.
     * @return string description of this object.
     */
    virtual std::string toString(const std::string& indent = "") const;

    /**
     * The base name for the container.
     * If saving new data, it is always possible to make a new element by this
     * name and save the container information into it.
     *
     * @return the base container name
     */
    virtual std::string getElementName() const { return containerName; }

    /**
     * Since the element in which the container information is contained does
     * not always have to be named the same, this function tests whether the
     * element name is one of the alternate names expected by this container.
     *
     * In the base class, the only acceptable name is the one returned by
     * getElementName
     *
     * @param val the string to test
     * @return  true if val is one of the acceptable names for this container,
     * false otherwise
     */
    virtual bool isAceptableName(const std::string& val) const
    {
        if (val.compare(containerName) == 0)
            return true;
        return false;
    }

    /**
     * Get a copy of this container.
     *
     * @return a copy of this container.
     */
    virtual Container* getCopy() const { return new Container(*this); }

    /**
     * Read an object of type T from element ele.
     * If ele itself is a link, the data are instead read from the linked
     * element If repo is not NULL, container data are added to the repository
     * with the element the data are read from (not the link)
     *
     * @param ele the element from which to read the data
     * @param repo if given, the repository in which to save instantiated
     * versions of the element information
     * @return  an object of type T
     */
    template<class T>
    std::shared_ptr<T>
    getDataFromRepo(std::shared_ptr<const endfgnd::Element>& ele,
                    ContainerRepository*                     repo)
    {
        std::shared_ptr<T> container = NULL;

        if (repo != NULL)
        {
            container = repo->get<T>(ele);
        }
        if (container == NULL)
        {
            container = std::make_shared<T>();
            container->readFromElement(ele, repo);
            if (repo != NULL)
                repo->add<T>(ele, container);
        }

        return container;
    }

  protected:
    /** The value for index */
    Integer32 index;

    /** The label for this container */
    UTF8Text label;

    std::shared_ptr<ValueData> value;

    std::string containerName;
};
} // namespace endfgnd

#endif /* ENDF_GND_CONTAINER_H */

Definitions.h

0 → 100644
+965 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading