17#include "ByteArrayUtil.h"
18#include "IndexOutOfBoundsException.h"
19#include "KeypleAssert.h"
27using namespace keyple::core::util;
28using namespace keyple::core::util::cpp;
29using namespace keyple::core::util::cpp::exception;
35 const std::map<const uint8_t, std::vector<uint8_t>>& sourceContent =
36 source->getAllRecordsContent();
38 for (
const auto& entry : sourceContent) {
39 mRecords.insert({entry.first, entry.second});
56 const auto it = mRecords.find(numRecord);
57 if (it == mRecords.end()) {
58 mLogger->warn(
"Record #% is not set\n", numRecord);
59 return std::vector<uint8_t>();
66 const uint8_t dataOffset,
67 const uint8_t dataLength)
const
69 Assert::getInstance().greaterOrEqual(dataOffset, 0,
"dataOffset")
70 .greaterOrEqual(dataLength, 1,
"dataLength");
72 const auto it = mRecords.find(numRecord);
73 if (it == mRecords.end()) {
74 mLogger->warn(
"Record #% is not set\n", numRecord);
75 return std::vector<uint8_t>();
78 const std::vector<uint8_t>& content = it->second;
79 if (dataOffset >=
static_cast<int>(content.size())) {
80 throw IndexOutOfBoundsException(
"Offset [" + std::to_string(dataOffset) +
"] >= " +
81 "content length [" + std::to_string(content.size()) +
"].");
84 const int toIndex = dataOffset + dataLength;
85 if (toIndex >
static_cast<int>(content.size())) {
86 throw IndexOutOfBoundsException(
"Offset [" + std::to_string(dataOffset) +
"] + " +
87 "Length [" + std::to_string(dataLength) +
"] = " +
88 "[" + std::to_string(toIndex) +
"] > " +
89 "content length [" + std::to_string(content.size()) +
"].");
92 return Arrays::copyOfRange(content, dataOffset, toIndex);
97 Assert::getInstance().greaterOrEqual(numCounter, 1,
"numCounter");
99 const auto it = mRecords.find(1);
100 if (it == mRecords.end()) {
101 mLogger->warn(
"Record #1 is not set\n");
105 const std::vector<uint8_t>& rec1 = it->second;
106 const int counterIndex = (numCounter - 1) * 3;
107 if (counterIndex >=
static_cast<int>(rec1.size())) {
108 mLogger->warn(
"Counter #% is not set (nb of actual counters = %)\n",
114 if (counterIndex + 3 >
static_cast<int>(rec1.size())) {
115 throw IndexOutOfBoundsException(
"Counter #" + std::to_string(numCounter) +
" " +
116 "has a truncated value (nb of actual counters = " +
117 std::to_string(rec1.size() / 3) +
").");
120 return std::make_shared<int>(ByteArrayUtil::threeBytesToInt(rec1, counterIndex));
125 std::map<const int, const int> result;
127 const auto it = mRecords.find(1);
129 if (it == mRecords.end()) {
130 mLogger->warn(
"Record #1 is not set\n");
134 const std::vector<uint8_t> rec1 = it->second;
135 const int length =
static_cast<int>(rec1.size() - (rec1.size() % 3));
136 for (
int i = 0, c = 1; i < length; i += 3, c++) {
137 result.insert({c, ByteArrayUtil::threeBytesToInt(rec1, i)});
145 mRecords.insert({numRecord, content});
154 const std::vector<uint8_t> content,
155 const uint8_t offset)
157 std::vector<uint8_t> newContent;
158 const int newLength =
static_cast<int>(offset + content.size());
160 const auto it = mRecords.find(numRecord);
161 if (it == mRecords.end()) {
162 newContent = std::vector<uint8_t>(newLength);
164 const std::vector<uint8_t> oldContent = it->second;
165 if (
static_cast<int>(oldContent.size()) <= offset) {
166 newContent = std::vector<uint8_t>(newLength);
167 System::arraycopy(oldContent, 0, newContent, 0, oldContent.size());
168 }
else if (
static_cast<int>(oldContent.size()) < newLength) {
169 newContent = std::vector<uint8_t>(newLength);
170 System::arraycopy(oldContent, 0, newContent, 0, offset);
172 newContent = oldContent;
176 System::arraycopy(content, 0, newContent, offset, content.size());
177 mRecords.insert({numRecord, newContent});
181 const std::vector<uint8_t> content,
182 const uint8_t offset)
184 std::vector<uint8_t> contentLeftPadded = content;
187 contentLeftPadded = std::vector<uint8_t>(offset + content.size());
188 System::arraycopy(content, 0, contentLeftPadded, offset, content.size());
191 const auto it = mRecords.find(numRecord);
192 if (it == mRecords.end()) {
193 mRecords.insert({numRecord, contentLeftPadded});
196 std::vector<uint8_t>& actualContent = it->second;
198 if (actualContent.size() < contentLeftPadded.size()) {
199 for (
int i = 0; i < static_cast<int>(actualContent.size()); i++) {
200 contentLeftPadded[i] |= actualContent[i];
203 mRecords.insert({numRecord, contentLeftPadded});
205 for (
int i = 0; i < static_cast<int>(contentLeftPadded.size()); i++) {
206 actualContent[i] |= contentLeftPadded[i];
214 std::vector<uint8_t> descendingKeys;
216 for (
auto it = mRecords.rbegin(); it != mRecords.rend(); ++it) {
217 descendingKeys.push_back(it->first);
220 for (
const auto& i : descendingKeys) {
221 mRecords.insert({
static_cast<uint8_t
>(i + 1), mRecords[i]});
224 mRecords.insert({
static_cast<uint8_t
>(1), content});
229 os <<
"FILE_DATA_ADAPTER: {"
230 <<
"RECORDS = " << fda.mRecords
const std::map< const int, const int > getAllCountersValue() const override
const std::shared_ptr< int > getContentAsCounterValue(const int numCounter) const override
void setCounter(const uint8_t numCounter, const std::vector< uint8_t > &content)
void fillContent(const uint8_t numRecord, const std::vector< uint8_t > content, const uint8_t offset)
const std::map< const uint8_t, std::vector< uint8_t > > & getAllRecordsContent() const override
void addCyclicContent(const std::vector< uint8_t > &content)
const std::vector< uint8_t > getContent() const override
void setContent(const uint8_t numRecord, const std::vector< uint8_t > &content)
std::ostream & operator<<(std::ostream &os, const std::shared_ptr< ApduRequestAdapter > ara)