14#include "keyple/card/calypso/FileDataAdapter.hpp"
16#include "keyple/core/util/ByteArrayUtil.hpp"
17#include "keyple/core/util/KeypleAssert.hpp"
18#include "keyple/core/util/cpp/Arrays.hpp"
19#include "keyple/core/util/cpp/KeypleStd.hpp"
20#include "keyple/core/util/cpp/System.hpp"
21#include "keyple/core/util/cpp/exception/IndexOutOfBoundsException.hpp"
27using keyple::core::util::Assert;
28using keyple::core::util::ByteArrayUtil;
29using keyple::core::util::cpp::Arrays;
30using keyple::core::util::cpp::System;
31using keyple::core::util::cpp::exception::IndexOutOfBoundsException;
33FileDataAdapter::FileDataAdapter()
37FileDataAdapter::FileDataAdapter(
const std::shared_ptr<FileData>& source)
39 const std::map<const uint8_t, std::vector<uint8_t>>& sourceContent
40 = source->getAllRecordsContent();
42 for (
const auto& entry : sourceContent) {
43 mRecords.insert({entry.first, entry.second});
47const std::map<const std::uint8_t, std::vector<uint8_t>>&
48FileDataAdapter::getAllRecordsContent()
const
53std::vector<std::uint8_t>
54FileDataAdapter::getContent()
const
59std::vector<std::uint8_t>
60FileDataAdapter::getContent(std::uint8_t numRecord)
const
62 const auto it = mRecords.find(numRecord);
63 if (it == mRecords.end()) {
64 mLogger->warn(
"Record not set [rec=%]\n", numRecord);
65 return std::vector<std::uint8_t>();
71std::vector<std::uint8_t>
72FileDataAdapter::getContent(
73 std::uint8_t numRecord,
74 std::uint8_t dataOffset,
75 std::uint8_t dataLength)
const
78 .greaterOrEqual(dataOffset, 0,
"dataOffset")
79 .greaterOrEqual(dataLength, 1,
"dataLength");
81 const auto it = mRecords.find(numRecord);
82 if (it == mRecords.end()) {
83 mLogger->warn(
"Record not set [rec=%]\n", numRecord);
84 return std::vector<std::uint8_t>();
87 const std::vector<std::uint8_t>& content = it->second;
88 if (dataOffset >=
static_cast<int>(content.size())) {
89 throw IndexOutOfBoundsException(
90 "Offset [" + std::to_string(dataOffset) +
"] >= "
91 +
"content length [" + std::to_string(content.size()) +
"]");
94 const int toIndex = dataOffset + dataLength;
95 if (toIndex >
static_cast<int>(content.size())) {
96 throw IndexOutOfBoundsException(
97 "Offset [" + std::to_string(dataOffset) +
"] + " +
"Length ["
98 + std::to_string(dataLength) +
"] = " +
"["
99 + std::to_string(toIndex) +
"] > " +
"content length ["
100 + std::to_string(content.size()) +
"]");
103 return Arrays::copyOfRange(content, dataOffset, toIndex);
107FileDataAdapter::getContentAsCounterValue(
int numCounter)
const
109 Assert::getInstance().greaterOrEqual(numCounter, 1,
"numCounter");
111 const auto it = mRecords.find(1);
112 if (it == mRecords.end()) {
113 mLogger->warn(
"Record not set [rec=1]\n");
117 const std::vector<std::uint8_t>& rec1 = it->second;
118 const int counterIndex = (numCounter - 1) * 3;
119 if (counterIndex >=
static_cast<int>(rec1.size())) {
121 "Counter not set [counter=%, counterCount=%]\n",
127 if (counterIndex + 3 >
static_cast<int>(rec1.size())) {
128 throw IndexOutOfBoundsException(
129 "Counter #" + std::to_string(numCounter) +
" "
130 +
"has a truncated value (nb of actual counters = "
131 + std::to_string(rec1.size() / 3) +
")");
134 return std::make_shared<int>(
135 ByteArrayUtil::extractInt(rec1, counterIndex, 3,
false));
138std::map<const int, const int>
139FileDataAdapter::getAllCountersValue()
const
141 std::map<const int, const int> result;
143 const auto it = mRecords.find(1);
145 if (it == mRecords.end()) {
146 mLogger->warn(
"Record not set [rec=1]\n");
150 const std::vector<std::uint8_t> rec1 = it->second;
151 const int length =
static_cast<int>(rec1.size() - (rec1.size() % 3));
152 for (
int i = 0, c = 1; i < length; i += 3, c++) {
153 result.insert({c, ByteArrayUtil::extractInt(rec1, i, 3,
false)});
160FileDataAdapter::setContent(
161 std::uint8_t numRecord,
const std::vector<std::uint8_t>& content)
163 mRecords[numRecord] = content;
167FileDataAdapter::setCounter(
168 std::uint8_t numCounter,
const std::vector<std::uint8_t>& content)
170 setContent(1, content, (numCounter - 1) * 3);
174FileDataAdapter::setContent(
175 std::uint8_t numRecord,
176 const std::vector<std::uint8_t>& content,
179 std::vector<std::uint8_t> newContent;
180 const int newLength =
static_cast<int>(offset + content.size());
182 const auto it = mRecords.find(numRecord);
183 if (it == mRecords.end()) {
184 newContent = std::vector<std::uint8_t>(newLength);
187 const std::vector<std::uint8_t> oldContent = it->second;
188 if (
static_cast<int>(oldContent.size()) <= offset) {
189 newContent = std::vector<std::uint8_t>(newLength);
190 System::arraycopy(oldContent, 0, newContent, 0, oldContent.size());
192 }
else if (
static_cast<int>(oldContent.size()) < newLength) {
193 newContent = std::vector<std::uint8_t>(newLength);
194 System::arraycopy(oldContent, 0, newContent, 0, offset);
197 newContent = oldContent;
201 System::arraycopy(content, 0, newContent, offset, content.size());
203 mRecords[numRecord] = newContent;
207FileDataAdapter::fillContent(
208 std::uint8_t numRecord,
209 const std::vector<std::uint8_t>& content,
212 std::vector<uint8_t> contentLeftPadded = content;
215 contentLeftPadded = std::vector<std::uint8_t>(offset + content.size());
217 content, 0, contentLeftPadded, offset, content.size());
220 const auto it = mRecords.find(numRecord);
221 if (it == mRecords.end()) {
222 mRecords[numRecord] = contentLeftPadded;
228 std::vector<std::uint8_t>& actualContent = it->second;
230 if (actualContent.size() < contentLeftPadded.size()) {
231 for (
int i = 0; i < static_cast<int>(actualContent.size()); i++) {
232 contentLeftPadded[i] |= actualContent[i];
235 mRecords[numRecord] = contentLeftPadded;
237 for (
int i = 0; i < static_cast<int>(contentLeftPadded.size());
239 actualContent[i] |= contentLeftPadded[i];
246FileDataAdapter::addCyclicContent(
const std::vector<std::uint8_t>& content)
248 std::vector<std::uint8_t> descendingKeys;
250 for (
auto it = mRecords.rbegin(); it != mRecords.rend(); ++it) {
251 descendingKeys.push_back(it->first);
254 for (
const auto& i : descendingKeys) {
255 mRecords[
static_cast<uint8_t
>(i + 1)] = mRecords[i];
258 mRecords[
static_cast<std::uint8_t
>(1)] = content;
262operator<<(std::ostream& os,
const FileDataAdapter& fda)
264 os <<
"FILE_DATA_ADAPTER: {"
265 <<
"RECORDS = " << fda.mRecords <<
"}";
std::ostream & operator<<(std::ostream &os, const CalypsoCardAdapter &cca)