[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/eModbus/eModbus/master/src/CoilData.cpp [Back]  [Original]

// =================================================================================================
// eModbus: Copyright 2020, 2021 by Michael Harwerth, Bert Melis and the contributors to eModbus
//               MIT license - see license.md for details
// =================================================================================================

#include "CoilData.h"
#undef LOCAL_LOG_LEVEL
#include "Logging.h"

// Constructor: optional size in bits, optional initial value for all bits
// Maximum size is 2000 coils (=250 bytes)
CoilData::CoilData(uint16_t size, bool initValue) :
  CDsize(0),
  CDbyteSize(0), 
  CDbuffer(nullptr) {
  // Limit the size to 2000 (Modbus rules)
  if (size > 2000) size = 2000;
  // Do we have a size?
  if (size) {
    // Calculate number of bytes needed
    CDbyteSize = byteIndex(size - 1) + 1;
    // Allocate and init buffer
    CDbuffer = new uint8_t[CDbyteSize];
    memset(CDbuffer, initValue ? 0xFF : 0, CDbyteSize);
    if (initValue) {
      CDbuffer[CDbyteSize - 1] &= CDfilter[bitIndex(size - 1)];
    }
    CDsize = size;
  }
}

// Alternate constructor, taking a "1101..." bit image char array to init
CoilData::CoilData(const char *initVector) :
  CDsize(0),
  CDbyteSize(0), 
  CDbuffer(nullptr) {
  // Init with bit image array. 
  setVector(initVector);
}

// Destructor: take care of cleaning up
CoilData::~CoilData() {
  if (CDbuffer) {
    delete CDbuffer;
  }
}

// Assignment operator
CoilData& CoilData::operator=(const CoilData& m) {
  // Avoid self-assignment
  if (this == &m) return *this;
  // Remove old data
  if (CDbuffer) {
    delete CDbuffer;
  }
  // Are coils in source?
  if (m.CDsize > 0) {
    // Yes. Allocate new buffer and copy data
    CDbuffer = new uint8_t[m.CDbyteSize];
    memcpy(CDbuffer, m.CDbuffer, m.CDbyteSize);
    CDsize = m.CDsize;
    CDbyteSize = m.CDbyteSize;
  } else {
    // No, leave buffer empty
    CDsize = 0;
    CDbyteSize = 0;
    CDbuffer = nullptr;
  }
  return *this;
}

// Copy constructor
CoilData::CoilData(const CoilData& m) :
  CDsize(0),
  CDbyteSize(0), 
  CDbuffer(nullptr) {
  // Has the source coils at all?
  if (m.CDsize > 0) {
    // Yes. Allocate new buffer and copy data
    CDbuffer = new uint8_t[m.CDbyteSize];
    memcpy(CDbuffer, m.CDbuffer, m.CDbyteSize);
    CDsize = m.CDsize;
    CDbyteSize = m.CDbyteSize;
  }
}

#ifndef NO_MOVE
// Move constructor
CoilData::CoilData(CoilData&& m) {
  // Copy all data
  CDbuffer = m.CDbuffer;
  CDsize = m.CDsize;
  CDbyteSize = m.CDbyteSize;
  // Then clear source
  m.CDbuffer = nullptr;
  m.CDsize = 0;
  m.CDbyteSize = 0;
}

// Move assignment
CoilData& CoilData::operator=(CoilData&& m) {
  // Remove buffer, if already allocated
  if (CDbuffer) {
    delete CDbuffer;
  }
  // Are there coils in the source at all?
  if (m.CDsize > 0) {
    // Yes. Copy over all data
    CDbuffer = m.CDbuffer;
    CDsize = m.CDsize;
    CDbyteSize = m.CDbyteSize;
    // Then clear source
    m.CDbuffer = nullptr;
    m.CDsize = 0;
    m.CDbyteSize = 0;
  } else {
    // No, leave object empty.
    CDbuffer = nullptr;
    CDsize = 0;
    CDbyteSize = 0;
  }
  return *this;
}
#endif

// Comparison operators
bool CoilData::operator==(const CoilData& m) {
  // Self-compare is always true
  if (this == &m) return true;
  // Different sizes are never equal
  if (CDsize != m.CDsize) return false;
  // Compare the data
  if (CDsize > 0 && memcmp(CDbuffer, m.CDbuffer, CDbyteSize)) return false;
  return true;
}

// Inequality: invert the result of the equality comparison
bool CoilData::operator!=(const CoilData& m) {
  return !(*this == m);
}

// Assignment of a bit image char array to re-init
CoilData& CoilData::operator=(const char *initVector) {
  // setVector() may be unsuccessful - then data is deleted!
  setVector(initVector);
  return *this;
}

// If used as vector, return a complete slice
CoilData::operator vector const () {
  // Create new vector to return
  vector retval;
  if (CDsize > 0) {
    // Copy over all buffer content
      retval.assign(CDbuffer, CDbuffer + CDbyteSize);
  }
  // return the copy (or an empty vector)
  return retval;
}

// slice: return a CoilData object with coils shifted leftmost
// will return empty object if illegal parameters are detected
CoilData CoilData::slice(uint16_t start, uint16_t length) {
  CoilData retval;

  // Any slice of an empty coilset is an empty coilset ;)
  if (CDsize == 0) return retval;

  // If start is beyond the available coils, return empty slice
  if (start > CDsize) return retval;

  // length default is all up to the end
  if (length == 0) length = CDsize - start;

  // Does the requested slice fit in the buffer?
  if ((start + length) 

Web Proxy Viewer  |  New URL  |  Original Page