Skip to content

Commit

Permalink
avoid throwing for n/a parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisHal committed May 27, 2024
1 parent 27e993b commit 9cc7f8c
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 39 deletions.
156 changes: 128 additions & 28 deletions hekatoolslib/PMparameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <iomanip>
#include <array>
#include <cassert>
#include "hkTree.h"
#include "PMparameters.h"
#include "time_handling.h"
#include "DatFile.h"
Expand Down Expand Up @@ -198,47 +199,113 @@ namespace hkLib {

void PMparameter::formatValueOnly(const hkTreeNode& node, std::ostream& ss) const
{
bool data_na{ false };
try {
switch (data_type) {
case Byte:
ss << int(node.getChar(offset));
{
auto c = node.extractValueOpt<char>(offset);
if (c) {
ss << int(*c);
}
else {
data_na = true;
}
}
break;
case Int16:
ss << node.extractValue<std::int16_t>(offset);
case Int16: {
auto v = node.extractValueOpt<std::int16_t>(offset);
if (v) {
ss << *v;
}
else {
data_na = true;
}
}
break;
case UInt16:
ss << node.extractUInt16(offset);
case UInt16: {
auto v = node.extractValueOpt<std::uint16_t>(offset);
if (v) {
ss << *v;
}
else {
data_na = true;
}
}
break;
case Set16: {
auto t = node.extractValue<std::uint16_t>(offset);
ss << 'b';
std::uint16_t u = 1U << 15;
while (u) {
if (t & u) {
ss << '1';
}
else {
ss << '0';
auto t = node.extractValueOpt<std::uint16_t>(offset);
if (!t) { data_na = true; }
else {
ss << 'b';
std::uint16_t u = 1U << 15;
while (u) {
if (*t & u) {
ss << '1';
}
else {
ss << '0';
}
u >>= 1;
}
u >>= 1;
}
}
break;
case Int32:
ss << node.extractInt32(offset);
{
auto v = node.extractValueOpt<std::int32_t>(offset);
if (v) {
ss << *v;
}
else {
data_na = true;
}
}
break;
case UInt32:
ss << node.extractValue<std::uint32_t>(offset);
{
auto v = node.extractValueOpt<std::uint32_t>(offset);
if (v) {
ss << *v;
}
else {
data_na = true;
}
}
break;
case LongReal:
ss << node.extractLongReal(offset);
{
auto v = node.extractValueOpt<double>(offset);
if (v) {
ss << *v;
}
else {
data_na = true;
}
}
break;
case DateTime:
ss << formatPMtimeUTC(node.extractLongReal(offset));
{
auto v = node.extractValueOpt<double>(offset);
if (v) {
ss << formatPMtimeUTC(*v);
}
else {
data_na = true;
}
}
break;
case InvLongReal:
ss << 1.0 / node.extractLongReal(offset);
break;
{
auto v = node.extractValueOpt<double>(offset);
if (v) {
ss << 1.0 / *v;
}
else {
data_na = true;
}
}
break;
case StringType:
ss << iso_8859_1_to_utf8(node.getString(offset));
break;
Expand All @@ -260,28 +327,58 @@ namespace hkLib {
case Boolean:
ss << std::boolalpha << bool(node.getChar(offset));
break;
case LongReal2:
ss << '(' << node.extractLongReal(offset) << ','
<< node.extractLongReal(offset + 8) << ')';
case LongReal2: {
auto a = node.extractValueOpt<double>(offset);
auto b = node.extractValueOpt<double>(offset + 8);
if (a && b) {
ss << '(' << *a << ','
<< *b << ')';
}
else {
data_na = true;
}
}
break;
case LongReal4:
case LongReal4: {
ss << "(";
for (std::size_t i = 0; i < 4; ++i) {
ss << node.extractLongReal(offset + 8 * i) << ",";
auto v = node.extractValueOpt<double>(offset + 8 * i);
if (v) {
ss << *v << ",";
}
else {
ss << "n/a";
break;
}
}
ss << ")";
}
break;
case LongReal8:
ss << "(";
for (std::size_t i = 0; i < 8; ++i) {
ss << node.extractLongReal(offset + 8 * i) << ",";
auto v = node.extractValueOpt<double>(offset + 8 * i);
if (v) {
ss << *v << ",";
}
else {
ss << "n/a";
break;
}
}
ss << ")";
break;
case LongReal16:
ss << "(";
for (std::size_t i = 0; i < 16; ++i) {
ss << node.extractLongReal(offset + 8 * i) << ",";
auto v = node.extractValueOpt<double>(offset + 8 * i);
if (v) {
ss << *v << ",";
}
else {
ss << "n/a";
break;
}
}
ss << ")";
break;
Expand Down Expand Up @@ -317,6 +414,9 @@ namespace hkLib {
(void)e;
ss << "n/a";
}
if (data_na) {
ss << "n/a";
};
}

void PMparameter::format(const hkTreeNode& node, std::ostream& ss) const
Expand Down
9 changes: 8 additions & 1 deletion hekatoolslib/PMparameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,14 @@ namespace hkLib {
template<std::size_t N>void formatUserParamDesc(const hkTreeNode& node, std::size_t offset, std::ostream& ss) const {
ss << "(name,unit):[";
for (std::size_t i = 0; i < N; ++i) {
ss << node.getUserParamDescr(offset + i * UserParamDescr::Size) << ';';
auto d = node.getUserParamDescr(offset + i * UserParamDescr::Size);
if (d) {
ss << *d << ';';
}
else {
ss << "n/a";
break;
}
}
ss << ']';
}
Expand Down
15 changes: 9 additions & 6 deletions hekatoolslib/hkTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,18 @@ namespace hkLib {
return Data[offset];
}

const UserParamDescr hkTreeNode::getUserParamDescr(std::size_t offset) const
const std::optional<UserParamDescr> hkTreeNode::getUserParamDescr(std::size_t offset) const
{
if (len < offset + UserParamDescr::Size) {
throw std::out_of_range("offset too large while accessing tree node");
//throw std::out_of_range("offset too large while accessing tree node");
return std::nullopt;
}
else {
return { UserParamDescr{
getString<UserParamDescr::SizeName>(offset),
getString<UserParamDescr::SizeUnit>(offset + UserParamDescr::SizeName) }
};
}
return {
getString<UserParamDescr::SizeName>(offset),
getString<UserParamDescr::SizeUnit>(offset + UserParamDescr::SizeName)
};
}

const std::string_view hkTreeNode::getString(std::size_t offset) const
Expand Down
23 changes: 19 additions & 4 deletions hekatoolslib/hkTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <ostream>
#include <vector>
#include <array>
#include <optional>
#include <string>
#include <string_view>
#include <algorithm>
Expand Down Expand Up @@ -234,8 +235,22 @@ namespace hkLib {
throw std::out_of_range("offset too large while accessing tree node");
}
return extractValueNoCheck<T>(offset);
}

};
/// <summary>
/// tries to extract a value from record data, swaps bytes if needed
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="offset"></param>
/// <returns>std::optional containing value if offset is valid</returns>
template<typename T> std::optional<T> extractValueOpt(std::size_t offset) const
{
if (len < offset + sizeof(T)) {
return std::nullopt;
}
else {
return extractValueNoCheck<T>(offset);
}
};
/// <summary>
/// extract a value from record data, swaps bytes if needed,
/// return default value
Expand Down Expand Up @@ -268,11 +283,11 @@ namespace hkLib {
}
char getChar(std::size_t offset) const;
const std::string_view getString(std::size_t offset) const;
const UserParamDescr getUserParamDescr(std::size_t offset) const;
const std::optional<UserParamDescr> getUserParamDescr(std::size_t offset) const;
template<std::size_t N> const std::string_view getString(std::size_t offset) const
{
if (len < offset + N) {
throw std::out_of_range("offset to large while accessing tree node");
return "n/a";
}
const auto* p = Data + offset;
if (p[N - 1]) {
Expand Down

0 comments on commit 9cc7f8c

Please sign in to comment.