OTest2
A C++ testing framework
testmarkinbin.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2020 Ondrej Starek
3  *
4  * This file is part of OTest2.
5  *
6  * OTest2 is free software: you can redistribute it and/or modify it under
7  * the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License,
9  * or (at your option) any later version.
10  *
11  * OTest2 is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14  * License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with OTest2. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <testmarkinbin.h>
21 
22 #include <algorithm>
23 #include <assert.h>
24 #include <boost/endian/conversion.hpp>
25 #include <cstdlib>
26 #include <initializer_list>
27 #include <limits>
28 #include <vector>
29 
30 #include <exctestmarkin.h>
31 #include "testmarkoutbintags.h"
32 
33 namespace OTest2 {
34 
36 
37 }
38 
40 
41 }
42 
43 TestMarkOutBinTag TestMarkInBin::readTag(
44  std::initializer_list<TestMarkOutBinTag> tags_) {
45  std::uint8_t rtag_;
46  readBinaryData(sizeof(rtag_), &rtag_);
47  if(std::find(
48  tags_.begin(),
49  tags_.end(),
50  static_cast<TestMarkOutBinTag>(rtag_)) == tags_.end())
51  throw ExcTestMarkIn("unexpected tag in the binary stream");
52  return static_cast<TestMarkOutBinTag>(rtag_);
53 }
54 
56  readTag({TestMarkOutBinTag::TYPE});
57 
58  std::uint8_t length_;
59  readBinaryData(sizeof(length_), &length_);
60  boost::endian::big_to_native_inplace(length_);
61  std::vector<std::uint8_t> buffer_(length_);
62  readBinaryData(length_, buffer_.data());
63  return std::string(buffer_.data(), buffer_.data() + length_);
64 }
65 
66 std::int64_t TestMarkInBin::readInt() {
67  auto tag_(readTag({
71  }));
72 
73  if(tag_ == TestMarkOutBinTag::INT_SHORT) {
74  std::uint8_t buffer_;
75  readBinaryData(sizeof(buffer_), &buffer_);
76  return static_cast<std::int64_t>(static_cast<std::int8_t>(buffer_));
77  }
78  else if(tag_ == TestMarkOutBinTag::INT_NORMAL) {
79  std::uint16_t buffer_;
80  readBinaryData(sizeof(buffer_), reinterpret_cast<std::uint8_t*>(&buffer_));
81  boost::endian::big_to_native_inplace(buffer_);
82  return static_cast<std::int64_t>(static_cast<std::int16_t>(buffer_));
83  }
84  else {
85  std::uint64_t buffer_;
86  readBinaryData(sizeof(buffer_), reinterpret_cast<std::uint8_t*>(&buffer_));
87  boost::endian::big_to_native_inplace(buffer_);
88  return static_cast<std::int64_t>(buffer_);
89  }
90 }
91 
92 long double TestMarkInBin::readFloat() {
93  readTag({TestMarkOutBinTag::FLOAT});
94 
95  std::uint8_t length_;
96  readBinaryData(sizeof(length_), &length_);
97  std::vector<std::uint8_t> buffer_(length_ + 1);
98  readBinaryData(length_, buffer_.data());
99  buffer_[length_] = 0; /* -- string terminator */
100 
101  char* end_(nullptr);
102  long double value_(
103  std::strtold(reinterpret_cast<const char*>(buffer_.data()), &end_));
104  if(reinterpret_cast<std::uint8_t*>(end_) != buffer_.data() + length_)
105  throw ExcTestMarkIn("invalid format of a floating point number");
106 
107  return value_;
108 }
109 
111  auto tag_(readTag({
115  }));
116 
117  std::uint64_t length_;
118  if(tag_ == TestMarkOutBinTag::STRING_SHORT) {
119  std::uint8_t buffer_;
120  readBinaryData(sizeof(buffer_), &buffer_);
121  length_ = buffer_;
122  }
123  else if(tag_ == TestMarkOutBinTag::STRING_NORMAL) {
124  std::uint16_t buffer_;
125  readBinaryData(sizeof(buffer_), reinterpret_cast<std::uint8_t*>(&buffer_));
126  boost::endian::big_to_native_inplace(buffer_);
127  length_ = buffer_;
128  }
129  else {
130  std::uint64_t buffer_;
131  readBinaryData(sizeof(buffer_), reinterpret_cast<std::uint8_t*>(&buffer_));
132  boost::endian::big_to_native_inplace(buffer_);
133  length_ = buffer_;
134  }
135  std::vector<std::uint8_t> str_(length_);
136  readBinaryData(length_, str_.data());
137  return std::string(str_.data(), str_.data() + length_);
138 }
139 
140 } /* -- namespace OTest2 */
OTest2::TestMarkOutBinTag
TestMarkOutBinTag
Definition: testmarkoutbintags.h:27
OTest2::TestMarkInBin::readFloat
virtual long double readFloat() override
Parse float following in the stream.
Definition: testmarkinbin.cpp:92
OTest2::TestMarkInBin::~TestMarkInBin
virtual ~TestMarkInBin()
Dtor.
Definition: testmarkinbin.cpp:39
testmarkinbin.h
OTest2::ExcTestMarkIn
An exception thrown from the testmark deserializer.
Definition: exctestmarkin.h:33
exctestmarkin.h
OTest2::TestMarkInBin::readInt
virtual std::int64_t readInt() override
Parse integer following in the stream.
Definition: testmarkinbin.cpp:66
OTest2::TestMarkOutBinTag::STRING_SHORT
@ STRING_SHORT
OTest2::TestMarkInBin::readTypeMark
virtual std::string readTypeMark() override
Parse type mark following in the stream.
Definition: testmarkinbin.cpp:55
OTest2::TestMarkOutBinTag::INT_NORMAL
@ INT_NORMAL
OTest2::TestMarkOutBinTag::INT_SHORT
@ INT_SHORT
OTest2
Definition: assertbean.h:25
OTest2::TestMarkInBin::TestMarkInBin
TestMarkInBin()
Ctor.
Definition: testmarkinbin.cpp:35
OTest2::TestMarkOutBinTag::INT_HUGE
@ INT_HUGE
OTest2::TestMarkOutBinTag::FLOAT
@ FLOAT
OTest2::TestMarkOutBinTag::STRING_NORMAL
@ STRING_NORMAL
OTest2::TestMarkInBin::readString
virtual std::string readString() override
Parse string following in the stream.
Definition: testmarkinbin.cpp:110
OTest2::TestMarkOutBinTag::TYPE
@ TYPE
testmarkoutbintags.h
OTest2::TestMarkOutBinTag::STRING_HUGE
@ STRING_HUGE