Skip to content
This repository has been archived by the owner on Sep 1, 2022. It is now read-only.

Commit

Permalink
Merge pull request #247 from automatak/feature
Browse files Browse the repository at this point in the history
Feature
  • Loading branch information
jadamcrain committed Nov 1, 2018
2 parents a363363 + 38ccd4b commit e8c0e3c
Show file tree
Hide file tree
Showing 14 changed files with 379 additions and 192 deletions.
5 changes: 4 additions & 1 deletion cpp/libs/include/asiodnp3/DatabaseConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ class DatabaseConfig
frozenCounter(sizes.numFrozenCounter),
boStatus(sizes.numBinaryOutputStatus),
aoStatus(sizes.numAnalogOutputStatus),
timeAndInterval(sizes.numTimeAndInterval)
timeAndInterval(sizes.numTimeAndInterval),
octetString(sizes.numOctetString)
{
InitIndices(binary);
InitIndices(doubleBinary);
Expand All @@ -53,6 +54,7 @@ class DatabaseConfig
InitIndices(boStatus);
InitIndices(aoStatus);
InitIndices(timeAndInterval);
InitIndices(octetString);
}

const opendnp3::DatabaseSizes sizes;
Expand All @@ -65,6 +67,7 @@ class DatabaseConfig
openpal::Array<opendnp3::BOStatusConfig, uint16_t> boStatus;
openpal::Array<opendnp3::AOStatusConfig, uint16_t> aoStatus;
openpal::Array<opendnp3::TimeAndIntervalConfig, uint16_t> timeAndInterval;
openpal::Array<opendnp3::OctetStringConfig, uint16_t> octetString;

private:

Expand Down
6 changes: 3 additions & 3 deletions cpp/libs/include/asiopal/Executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ namespace asiopal
*
*/
class Executor final :
public openpal::IExecutor,
public std::enable_shared_from_this<Executor>,
private openpal::Uncopyable
public openpal::IExecutor,
public std::enable_shared_from_this<Executor>,
private openpal::Uncopyable
{

public:
Expand Down
56 changes: 54 additions & 2 deletions cpp/libs/include/opendnp3/app/OctetData.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,72 @@ class OctetData

const static uint8_t MAX_SIZE = 255;

/**
* Construct with a default value of [0x00] (length == 1)
*/
OctetData();

/**
* Construct from a c-style string
*
* strlen() is used internally to determine the length
*
* If the length is 0, the default value of [0x00] is assigned
* If the length is > 255, only the first 255 bytes are copied.
*
* The null terminator is NOT copied as part of buffer
*/
OctetData(const char* input);

/**
* Construct from read-only buffer slice
*
*
* If the length is 0, the default value of [0x00] is assigned
* If the length is > 255, only the first 255 bytes are copied.
*
* The null terminator is NOT copied as part of buffer
*/
OctetData(const openpal::RSlice& input);

inline uint8_t Size() const
{
return size;
}

bool Set(const openpal::RSlice&);

/**
* Set the octet data to the input buffer
*
* If the length is 0, the default value of [0x00] is assigned
* If the length is > 255, only the first 255 bytes are copied
*
* @param input the input data to copy into this object
*
* @return true if the input meets the length requirements, false otherwise
*/
bool Set(const openpal::RSlice& input);

/**
* Set the buffer equal to the supplied c-string
*
* If the length is 0, the default value of [0x00] is assigned
* If the length is > 255, only the first 255 bytes are copied
*
* @param input c-style string to copy into this object
*
* @return true if the input meets the length requirements, false otherwise
*/
bool Set(const char* input);

/**
* @return a view of the current data as a read-only slice
*/
openpal::RSlice ToRSlice() const;

private:

static openpal::RSlice ToSlice(const char* input);

openpal::StaticBuffer<MAX_SIZE> buffer;
uint8_t size;
};
Expand Down
25 changes: 25 additions & 0 deletions cpp/libs/include/opendnp3/app/OctetString.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,37 @@ class OctetString : public OctetData
{
public:

/**
* Construct with a default value of [0x00] (length == 1)
*/
OctetString() : OctetData()
{}

/**
* Copy construct from another OctetString
*/
OctetString(const OctetString& data) : OctetData(data)
{}

/**
* Construct from a c-style string
*
* strlen() is used internally to determine the length
*
* If the length is 0, the default value of [0x00] is assigned
* If the length is > 255, only the first 255 bytes are copied
*
* The null terminator is NOT copied as part of buffer
*/
OctetString(const char* input) : OctetData(input)
{}

/**
* Construct from read-only buffer slice
*
* If the length is 0, the default value of [0x00] is assigned
* If the length is > 255, only the first 255 bytes are copied
*/
OctetString(const openpal::RSlice& buffer) : OctetData(buffer)
{}

Expand Down
14 changes: 7 additions & 7 deletions cpp/libs/src/asiodnp3/LinkSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@
namespace asiodnp3
{
class LinkSession final :
public opendnp3::ILinkTx,
public asiopal::IChannelCallbacks,
private opendnp3::IFrameSink,
public std::enable_shared_from_this<LinkSession>,
public asiopal::IResource,
private ISessionAcceptor,
private openpal::Uncopyable
public opendnp3::ILinkTx,
public asiopal::IChannelCallbacks,
private opendnp3::IFrameSink,
public std::enable_shared_from_this<LinkSession>,
public asiopal::IResource,
private ISessionAcceptor,
private openpal::Uncopyable
{
public:

Expand Down
1 change: 1 addition & 0 deletions cpp/libs/src/asiodnp3/OutstationStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ OutstationStack::OutstationStack(
assign(config.dbConfig.boStatus, view.binaryOutputStatii);
assign(config.dbConfig.aoStatus, view.analogOutputStatii);
assign(config.dbConfig.timeAndInterval, view.timeAndIntervals);
assign(config.dbConfig.octetString, view.octetStrings);
}


Expand Down
6 changes: 3 additions & 3 deletions cpp/libs/src/asiodnp3/PrintingCommandCallback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ opendnp3::CommandCallbackT PrintingCommandCallback::Get()
{
std::cout
<< "Header: " << res.headerIndex
<< " Index: " << res.index
<< " State: " << CommandPointStateToString(res.state)
<< " Status: " << CommandStatusToString(res.status);
<< " Index: " << res.index
<< " State: " << CommandPointStateToString(res.state)
<< " Status: " << CommandStatusToString(res.status);
};
result.ForeachItem(print);
};
Expand Down
48 changes: 40 additions & 8 deletions cpp/libs/src/opendnp3/app/OctetData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@

#include <openpal/container/WSlice.h>
#include <openpal/util/Comparisons.h>
#include <openpal/util/Limits.h>

#include <cstring>

using namespace openpal;

Expand All @@ -33,29 +36,58 @@ OctetData::OctetData() : size(1)

}

OctetData::OctetData(const char* input) : OctetData(ToSlice(input))
{

}

OctetData::OctetData(const RSlice& input) :
size(openpal::Min<uint32_t>(MAX_SIZE, input.Size()))
size(input.IsEmpty() ? 1 : openpal::Min<uint32_t>(MAX_SIZE, input.Size()))
{
auto dest = buffer.GetWSlice();
input.Take(size).CopyTo(dest);
if (input.IsNotEmpty())
{
auto dest = buffer.GetWSlice();
input.Take(size).CopyTo(dest);
}
}

bool OctetData::Set(const openpal::RSlice& input)
{
if (input.Size() > MAX_SIZE) return false;
else
if (input.IsEmpty())
{
auto dest = buffer.GetWSlice();
input.CopyTo(dest);
return true;
this->size = 0;
this->buffer.GetWSlice()[0] = 0x00;
return false;
}

const bool is_oversized = input.Size() > MAX_SIZE;
const uint8_t usable_size = is_oversized ? MAX_SIZE : static_cast<uint8_t>(input.Size());

auto dest = this->buffer.GetWSlice();
input.Take(usable_size).CopyTo(dest);
this->size = usable_size;
return !is_oversized;
}


bool OctetData::Set(const char* input)
{
const size_t length = strlen(input);
return this->Set(openpal::RSlice(reinterpret_cast<const uint8_t*>(input), static_cast<uint32_t>(length > MAX_SIZE ? MAX_SIZE : length)));
}

openpal::RSlice OctetData::ToRSlice() const
{
return buffer.ToRSlice(size);
}

openpal::RSlice OctetData::ToSlice(const char* input)
{
const size_t length = strlen(input);
if (length == 0) return openpal::RSlice::Empty();
return openpal::RSlice(reinterpret_cast<const uint8_t*>(input), length > MAX_SIZE ? MAX_SIZE : static_cast<uint32_t>(length));
}

}


Expand Down
46 changes: 20 additions & 26 deletions cpp/libs/src/opendnp3/outstation/DatabaseBuffers.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,39 +227,33 @@ template <class T>
bool DatabaseBuffers::LoadType(HeaderWriter& writer)
{
auto range = ranges.Get<T>();
if (range.IsValid())
{
auto view = buffers.GetArrayView<T>();
if (!range.IsValid()) return true; // no data to load

bool spaceRemaining = true;
auto view = buffers.GetArrayView<T>();

// ... load values, manipulate the range
while (spaceRemaining && range.IsValid())
bool spaceRemaining = true;

// ... load values, manipulate the range
while (spaceRemaining && range.IsValid())
{
if (view[range.start].selection.selected)
{
if (view[range.start].selection.selected)
{
/// lookup the specific write function based on the reporting variation
auto writeFun = StaticWriters::Get(view[range.start].selection.variation);
/// lookup the specific write function based on the reporting variation
auto writeFun = StaticWriters::Get(view[range.start].selection.variation);

// start writing a header, the invoked function will advance the range appropriately
spaceRemaining = writeFun(view, writer, range);
}
else
{
// just skip over values that are not selected
range.Advance();
}
// start writing a header, the invoked function will advance the range appropriately
spaceRemaining = writeFun(view, writer, range);
}
else
{
// just skip over values that are not selected
range.Advance();
}
}

ranges.Set<T>(range);
ranges.Set<T>(range);

return spaceRemaining;
}
else
{
// no data to load
return true;
}
return spaceRemaining;
}

template <class Spec>
Expand Down

0 comments on commit e8c0e3c

Please sign in to comment.