FieldStringArray.cpp

Go to the documentation of this file.
00001 // Copyright CERN 2012 - Developed in collaboration with GSI
00002 
00003 #include <fesa-core/DataStore/FieldStringArray.h>
00004 
00005 #include <fesa-core/Synchronization/AbstractMultiplexingManager.h>
00006 #include <fesa-core/Synchronization/MultiplexingContext.h>
00007 #include <fesa-core/Utilities/ParserElements.h>
00008 #include <fesa-core/Utilities/StringUtilities.h>
00009 #include <fesa-core/Exception/FesaException.h>
00010 
00011 #include <cstring>
00012 
00013 
00014 namespace fesa
00015 {
00016 
00017 FieldStringArray::FieldStringArray(const std::string& fieldName, const FieldCategory fieldCategory, bool multiplexed,
00018                                    bool multiMultiplexed, bool persistent, DataIntegrity bufferType,
00019                                    DataStore* pDataStore, int32_t arrayLength, int32_t stringLength) :
00020     AbstractField(fieldName, fieldCategory, multiplexed, multiMultiplexed, persistent, bufferType, pDataStore),
00021     maxSize1_(arrayLength),
00022     maxSize2_(stringLength),
00023     pointers_(NULL)
00024 {
00025 }
00026 
00027 FieldStringArray::~FieldStringArray()
00028 {
00029     int32_t depth = 1;
00030 
00031     if (this->multiplexingManager_)
00032     {
00033         depth = this->multiplexingManager_->getDepth();
00034     }
00035 
00036     for (int32_t i = 0; i < depth; i++)
00037     {
00038         for (int32_t k = 0; k < buffer_; k++)
00039         {
00040             delete pointers_[i][k];
00041         }
00042         delete pointers_[i];
00043     }
00044     delete pointers_;
00045 }
00046 
00047 void FieldStringArray::initialize(FieldElement& fieldElement)
00048 {
00049     if (fieldElement.dimension1_ > 0)
00050     {
00051         this->maxSize1_ = fieldElement.dimension1_;
00052 
00053     }
00054     if (fieldElement.dimension2_ > 0)
00055     {
00056         this->maxSize2_ = fieldElement.dimension2_;
00057 
00058     }
00059 
00060 }
00061 
00062 uint32_t FieldStringArray::getFieldValueSize()
00063 {
00064     if (valueSize_ == 0)
00065     {
00066         // add + 1 to the maxSize2_ for the '\0' character
00067         valueSize_ = static_cast<uint32_t>(sizeof(FieldValue<char*[]>)) + static_cast<uint32_t>(sizeof(char)) * (this->maxSize1_) * (this->maxSize2_ + 1)
00068             * buffer_;
00069     }
00070     return valueSize_;
00071 }
00072 
00073 void FieldStringArray::setFieldValueAddress(char* pFV, bool initFieldsFlag)
00074 {
00075     int32_t depth = 1;
00076 
00077     if (this->multiplexingManager_)
00078     {
00079         depth = this->multiplexingManager_->getDepth();
00080     }
00081 
00082     //attach field to provided memory
00083     this->fieldValue_ = (FieldValue<char *[]>*) pFV;
00084 
00085     // allocate the table of pointers
00086     pointers_ = (char****) new char***[depth];
00087 
00088     for (int32_t i = 0; i < depth; i++)
00089     {
00090         pointers_[i] = (char***) new char**[buffer_];
00091         for (int32_t k = 0; k < buffer_; k++)
00092         {
00093             pointers_[i][k] = (char **) new char*[maxSize1_];
00094         }
00095 
00096         if (initFieldsFlag)
00097             new (pFV) FieldValue<char *[]> (buffer_, maxSize1_);
00098 
00099         pFV += sizeof(FieldValue<char *[]>);
00100 
00101         for (int32_t k = 0; k < buffer_; k++)
00102         {
00103             for (uint32_t j = 0; j < this->maxSize1_; j++)
00104             {
00105                 pointers_[i][k][j] = pFV;
00106                 pFV += (sizeof(char) * (this->maxSize2_ + 1));
00107             }
00108         }
00109     }
00110 }
00111 
00112 FieldValue<char *[]>* FieldStringArray::getFieldValue(int32_t slot)
00113 {
00114 
00115     char* address = (char*) this->fieldValue_;
00116     address += valueSize_ * slot;
00117     return (FieldValue<char *[]>*) address;
00118 
00119 }
00120 
00121 void FieldStringArray::copyValue(uint32_t slot, std::string& str)
00122 {
00123     // Copy the string into a temp string because the original one cannot be modified because
00124     // it is used to populate the other slots if the filed is multiplexed.
00125     std::string arrayTmp = str;
00126 
00127     StringUtilities::removeBrackets(arrayTmp);
00128     std::vector<std::string> tokens;
00129 
00130     StringUtilities::getElements(arrayTmp, tokens);
00131 
00132     FieldValue<char *[]>* pFV = this->getFieldValue(slot);
00133 
00134     if(tokens.size() > maxSize1_)
00135         throw FesaException(__FILE__, __LINE__, FesaErrorValueExceedsLimits.c_str(),str.c_str(),name_.c_str());
00136 
00137     pFV->setPendingCurrentSize (static_cast<uint32_t>(tokens.size()));
00138     pFV->setActiveCurrentSize (static_cast<uint32_t>(tokens.size()));
00139 
00140     for (uint32_t j = 0; j < maxSize1_; j++)
00141     {
00142         if (tokens.size() > j)
00143         {
00144             if (maxSize2_ < tokens[j].size())
00145                 throw FesaException(__FILE__, __LINE__, FesaErrorValueExceedsLimits.c_str(),str.c_str(),name_.c_str());
00146 
00147             int32_t size = static_cast<uint32_t>(tokens[j].size());
00148 
00149             std::memcpy(pointers_[slot][pFV->activeBuffer()][j], tokens[j].c_str(), size * sizeof(char));
00150             pointers_[slot][pFV->activeBuffer()][j][size] = '\0';
00151 
00152             std::memcpy(pointers_[slot][pFV->pendingBuffer()][j], tokens[j].c_str(), size * sizeof(char));
00153             pointers_[slot][pFV->pendingBuffer()][j][size] = '\0';
00154         }
00155         else
00156         {
00157             pointers_[slot][pFV->activeBuffer()][j][0] = '\0';
00158             pointers_[slot][pFV->pendingBuffer()][j][0] = '\0';
00159         }
00160     }
00161 }
00162 
00163 void FieldStringArray::getValueToStore(int32_t slot, std::string& value)
00164 {
00165     value = "{";
00166 
00167     FieldValue<char *[]>* pFV = this->getFieldValue(slot);
00168 
00169     uint32_t currentSize = pFV->getActiveCurrentSize();
00170 
00171     for (uint32_t j = 0; j < currentSize; j++)
00172     {
00173         if (pFV->hasPendingChanged() || pFV->isToBeSync())
00174         {
00175             value += pointers_[slot][pFV->pendingBuffer()][j];
00176         }
00177         else
00178         {
00179             value += pointers_[slot][pFV->activeBuffer()][j];
00180         }
00181         if (j != currentSize - 1)
00182             value += ",";
00183     }
00184     value += "}";
00185 }
00186 
00187 void FieldStringArray::getMaxSize(uint32_t& size1, uint32_t& size2) {
00188     size1 = this->maxSize1_;
00189     size2 = this->maxSize2_;
00190 
00191 }
00192 
00193 uint32_t  FieldStringArray::getSize(MultiplexingContext* context)
00194 {
00195     // throw exception in case of NoneContext and multiplexed field.
00196     if (this->multiplexingManager_ && context->getType() == MultiplexingContext::NoneCtxt)
00197         throw FesaException(__FILE__, __LINE__, FesaErrorNoneContextforMuxedField.c_str(),
00198                             this->name_.c_str());
00199     // Retrieve the right FieldValue according to the slot
00200     uint32_t slot = (this->multiplexingManager_ == NULL) ? 0
00201         : this->multiplexingManager_->getSlot(*context);
00202     FieldValue<char *[]>* pFV = this->getFieldValue(slot);
00203     // Return the current size get from the Active buffer
00204     return pFV->getActiveCurrentSize();
00205 }
00206 
00207 } // fesa

Generated on 18 Jan 2013 for Fesa by  doxygen 1.6.1