Keyple Util C++ Library 2.3.0.5-SNAPSHOT
Reference Terminal Reader API for C++
ByteArrayUtil.cpp
Go to the documentation of this file.
1/**************************************************************************************************
2 * Copyright (c) 2023 Calypso Networks Association https://calypsonet.org/ *
3 * *
4 * See the NOTICE file(s) distributed with this work for additional information regarding *
5 * copyright ownership. *
6 * *
7 * This program and the accompanying materials are made available under the terms of the Eclipse *
8 * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 *
9 * *
10 * SPDX-License-Identifier: EPL-2.0 *
11 **************************************************************************************************/
12
13#include "ByteArrayUtil.h"
14
15/* Keyple Core Util */
16#include "Character.h"
17#include "HexUtil.h"
19#include "KeypleAssert.h"
21#include "Pattern.h"
22#include "StringBuilder.h"
23#include "System.h"
24
25namespace keyple {
26namespace core {
27namespace util {
28
29using namespace keyple::core::util::cpp;
31
32const std::vector<uint8_t> ByteArrayUtil::extractBytes(const std::vector<uint8_t>& src,
33 const int bitOffset,
34 const int nbBytes)
35{
36 if (bitOffset < 0) {
37 throw ArrayIndexOutOfBoundsException("negative index");
38 }
39
40 if (nbBytes < 0) {
41 throw NegativeArraySizeException("negative array size");
42 }
43
44 const int byteOffset = bitOffset / 8;
45 int lBitOffset = bitOffset % 8;
46
47 if (byteOffset >= static_cast<int>((src.size() - (lBitOffset ? 1 : 0)))) {
48 throw ArrayIndexOutOfBoundsException("pos + offset > src size");
49 }
50
51 std::vector<uint8_t> dest(nbBytes);
52
53 if (lBitOffset == 0) {
54 System::arraycopy(src, byteOffset, dest, 0, nbBytes);
55 } else {
56 const int rightShift = 8 - bitOffset;
57 for (int i = 0, j = byteOffset; j < byteOffset + nbBytes; i++, j++) {
58 dest[i] = ((src[j] << lBitOffset) | ((src[j + 1] & 0xFF) >> rightShift));
59 }
60 }
61
62 return dest;
63}
64
65const std::vector<uint8_t> ByteArrayUtil::extractBytes(const uint64_t src, const int nbBytes)
66{
67 if (nbBytes < 0) {
68 throw NegativeArraySizeException("negative array size");
69 }
70
71 std::vector<uint8_t> data(nbBytes);
72 int shift = 0;
73 int i = nbBytes - 1;
74
75 while (i >= 0) {
76 data[i] = ((src >> shift) & 0xFF);
77 shift += 8;
78 i--;
79 }
80
81 return data;
82}
83
84uint16_t ByteArrayUtil::extractShort(const std::vector<uint8_t>& src, const int offset)
85{
86 if (offset < 0 || offset > static_cast<int>(src.size() - 2)) {
87 throw ArrayIndexOutOfBoundsException("offset not in range [0...(src.size() - 2)");
88 }
89
90 return ((src[offset] & 0xFF) << 8) | (src[offset + 1] & 0xFF);
91}
92
93uint32_t ByteArrayUtil::extractInt(const std::vector<uint8_t>& src,
94 const int offset,
95 const int nbBytes,
96 const bool isSigned)
97{
98 if (offset < 0) {
99
100 throw ArrayIndexOutOfBoundsException("negative offset");
101 }
102
103 if ((offset + nbBytes) > static_cast<int>(src.size())) {
104
105 throw ArrayIndexOutOfBoundsException("offset + nbBytes > src size");
106 }
107
108 /* C++ - doesn't make sense to have nbBytes > int size */
109 if (nbBytes > 4) {
110
111 throw IllegalArgumentException("nbBytes can't be bigger than 4");
112 }
113
114 uint32_t val = 0;
115 uint32_t complement = 0xFFFFFFFF;
116 int lOffset = offset;
117 int lNbBytes = nbBytes;
118 bool negative = false;
119
120 /* Check MSB byte negativeness */
121 negative = src[lOffset] > 0x7F;
122
123 /* Get value */
124 while (lNbBytes > 0) {
125
126 val |= ((src[lOffset++] & 0xFF) << (8 * (--lNbBytes)));
127 complement &= ~(0xFF << 8 * lNbBytes);
128 }
129
130 /* If signed, add complement */
131 if (isSigned && negative) {
132
133 val |= complement;
134 }
135
136 return (uint32_t)val;
137}
138
139uint64_t ByteArrayUtil::extractLong(const std::vector<uint8_t>& src,
140 const int offset,
141 const int nbBytes,
142 const bool isSigned)
143{
144 int lOffset = offset;
145 int lNbBytes = nbBytes;
146
147
148 if (lOffset < 0 || lOffset > static_cast<int>(src.size() - lNbBytes)) {
149 throw ArrayIndexOutOfBoundsException("offset not in range [0...(src.size() - nbBytes)");
150 }
151
152 uint64_t val = 0L;
153 uint64_t complement = 0xFFFFFFFFFFFFFFFF;
154 bool negative = false;
155
156 /* Get value */
157 while (lNbBytes > 0) {
158 /* Check MSB byte negativeness */
159 negative = negative ? true : ((src[lOffset] & 0xFF) > 0x7F ? true : false);
160 val |= (((uint64_t)(src[lOffset++] & 0xFF)) << (8 * (--lNbBytes)));
161 complement &= ~(((uint64_t)0xFF) << 8 * lNbBytes);
162 }
163
164 /* If signed, add complement */
165 if (isSigned && negative) {
166 val |= complement;
167 }
168
169 return (uint64_t)val;
170}
171
172void ByteArrayUtil::copyBytes(const uint64_t src,
173 std::vector<uint8_t>& dest,
174 const int offset,
175 const int nbBytes)
176{
177 if (offset < 0 || offset > static_cast<int>(dest.size() - nbBytes)) {
178 throw ArrayIndexOutOfBoundsException("offset not in range [0...(dest.size() - nbBytes)");
179 }
180
181 System::arraycopy(extractBytes(src, nbBytes), 0, dest, offset, nbBytes);
182}
183
184bool ByteArrayUtil::isValidHexString(const std::string& hex)
185{
186 return HexUtil::isValid(hex);
187}
188
189const std::string ByteArrayUtil::normalizeHexString(const std::string& hex)
190{
191 if (hex.length() % 2 != 0) {
192 return "0" + hex;
193 }
194
195 return hex;
196}
197
198std::vector<uint8_t> ByteArrayUtil::fromHex(const std::string& hex)
199{
200 Assert::getInstance().notEmpty(hex, "hex").isEqual(hex.length() % 2, 0, "hex size");
201
202 return HexUtil::toByteArray(hex);
203}
204
205const std::string ByteArrayUtil::toHex(const std::vector<uint8_t>& src)
206{
207 if (src.empty()) {
208 return "";
209 }
210
211 return HexUtil::toHex(src);
212}
213
214int ByteArrayUtil::twoBytesToInt(const std::vector<uint8_t>& bytes, const int offset)
215{
216 return extractInt(bytes, offset, 2, false);
217}
218
219int ByteArrayUtil::twoBytesSignedToInt(const std::vector<uint8_t>& bytes, const int offset)
220{
221 return extractInt(bytes, offset, 2, true);
222}
223
224int ByteArrayUtil::threeBytesToInt(const std::vector<uint8_t>& bytes, const int offset)
225{
226 return extractInt(bytes, offset, 3, false);
227}
228
229int ByteArrayUtil::threeBytesSignedToInt(const std::vector<uint8_t>& bytes, const int offset)
230{
231 return extractInt(bytes, offset, 3, true);
232}
233
234int ByteArrayUtil::fourBytesToInt(const std::vector<uint8_t>& bytes, const int offset)
235{
236 return extractInt(bytes, offset, 4, true);
237}
238
239}
240}
241}
static Assert & getInstance()
Assert & notEmpty(const std::string &obj, const std::string &name)
Assert & isEqual(const size_t number, const size_t value, const std::string &name)
static bool isValidHexString(const std::string &hex)
static uint32_t extractInt(const std::vector< uint8_t > &src, const int offset, const int nbBytes, const bool isSigned)
static const std::string normalizeHexString(const std::string &hex)
static int threeBytesToInt(const std::vector< uint8_t > &bytes, const int offset)
static int fourBytesToInt(const std::vector< uint8_t > &bytes, const int offset)
static int twoBytesSignedToInt(const std::vector< uint8_t > &bytes, const int offset)
static const std::string toHex(const std::vector< uint8_t > &src)
static std::vector< uint8_t > fromHex(const std::string &hex)
static int threeBytesSignedToInt(const std::vector< uint8_t > &bytes, const int offset)
static uint16_t extractShort(const std::vector< uint8_t > &src, const int offset)
static int twoBytesToInt(const std::vector< uint8_t > &bytes, const int offset)
static const std::vector< uint8_t > extractBytes(const std::vector< uint8_t > &src, const int bitOffset, const int nbBytes)
static void copyBytes(const uint64_t src, std::vector< uint8_t > &dest, const int offset, const int nbBytes)
static uint64_t extractLong(const std::vector< uint8_t > &src, const int offset, const int nbBytes, const bool isSigned)
static const std::vector< uint8_t > toByteArray(const std::string &hex)
Definition: HexUtil.cpp:81
static const std::string toHex(const std::vector< uint8_t > &tab)
Definition: HexUtil.cpp:145
static bool isValid(const std::string &hex)
Definition: HexUtil.cpp:66
static void arraycopy(const std::vector< char > &src, size_t srcPos, std::vector< char > &dest, size_t destPos, size_t length)
Definition: System.h:58