1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "tag_service.h"
17
18 #include "telephony_common_utils.h"
19
20 namespace OHOS {
21 namespace Telephony {
22 static const int CONTINUE = 0;
23 static const int FINISH = 1;
24 static const int ERROR = -1;
25 static const size_t FIRST = 0;
26 static const size_t SECOND = 1;
27 static const uint8_t BYTE_ZERO = 0;
28 constexpr size_t BUFF_SIZE = 3;
29 constexpr size_t CHAR_LEN = 2;
30
TagService(const std::string & data)31 TagService::TagService(const std::string &data)
32 {
33 if (data.empty() || data.size() % CHINESE_POS) {
34 return;
35 }
36 for (auto it = data.begin(); it != data.end(); it += CHINESE_POS) {
37 uint8_t res = 0;
38 std::from_chars(std::addressof(*it), std::addressof(*(it + CHINESE_POS)), res, HEX_TYPE);
39 data_.push_back(res);
40 }
41 }
42
TagService(const std::vector<uint8_t> & data)43 TagService::TagService(const std::vector<uint8_t> &data) : data_(data) {}
44
~TagService()45 TagService::~TagService() {}
46
GetTagCode() const47 int TagService::GetTagCode() const
48 {
49 TELEPHONY_LOGI("GetTagCode : %{public}s", tag_.c_str());
50 std::string tagTemp = tag_.c_str();
51 if (!IsValidHexValue(tagTemp)) {
52 TELEPHONY_LOGE("GetTagCode return ERR");
53 return ERR;
54 }
55 int i = std::stoi(tag_, nullptr, HEX_TYPE);
56 return i;
57 }
58
GetValue(std::vector<uint8_t> & result) const59 void TagService::GetValue(std::vector<uint8_t> &result) const
60 {
61 result.clear();
62 for (uint8_t i = 0; i < length_; ++i) {
63 result.push_back(data_.at(dataOffset_ + i));
64 }
65 }
66
GetLength() const67 uint8_t TagService::GetLength() const
68 {
69 return length_;
70 }
71
TagFunc(const uint8_t arg,const size_t order,std::string & tag)72 static int TagFunc(const uint8_t arg, const size_t order, std::string &tag)
73 {
74 switch (order) {
75 case FIRST:
76 if (arg == BYTE_ZERO || arg == UINT8_MAX) {
77 return ERROR;
78 } else {
79 char buff[BUFF_SIZE] = {BYTE_ZERO, BYTE_ZERO, BYTE_ZERO};
80 std::to_chars(buff, buff + CHAR_LEN, arg, TagService::HEX_TYPE);
81 tag.append(std::begin(buff), std::end(buff));
82 return FINISH;
83 }
84 default:
85 break;
86 }
87 return ERROR;
88 }
89
LengthFunc(const uint8_t arg,const size_t order,uint8_t & len)90 static int LengthFunc(const uint8_t arg, const size_t order, uint8_t &len)
91 {
92 switch (order) {
93 case FIRST:
94 if (arg < CHINESE_FLAG) {
95 len = arg;
96 return FINISH;
97 } else if (arg == UCS_FLAG) {
98 len = BYTE_ZERO;
99 return CONTINUE;
100 }
101 break;
102 case SECOND:
103 len = arg;
104 return FINISH;
105 default:
106 break;
107 }
108 return ERROR;
109 }
110
Next()111 bool TagService::Next()
112 {
113 TELEPHONY_LOGI("TagService::Next begin!!");
114 if (!hasNext_ || offset_ >= data_.size()) {
115 hasNext_ = false;
116 return false;
117 }
118 constexpr int INT_ZERO = 0;
119 /* parse tag */
120 tag_.clear();
121 size_t order = INT_ZERO;
122 for (; offset_ < data_.size(); ++offset_, ++order) {
123 const auto res = TagFunc(data_.at(offset_), order, tag_);
124 if (res < INT_ZERO) {
125 hasNext_ = false;
126 return hasNext_;
127 } else if (res > INT_ZERO) {
128 ++offset_;
129 break;
130 }
131 }
132 TELEPHONY_LOGI("TagService::Next for tag : %{public}s", tag_.c_str());
133 /* parse length */
134 if (offset_ >= data_.size()) {
135 hasNext_ = false;
136 return false;
137 }
138 length_ = INT_ZERO;
139 order = INT_ZERO;
140 for (; offset_ < data_.size(); ++offset_, ++order) {
141 const auto res = LengthFunc(data_.at(offset_), order, length_);
142 if (res < INT_ZERO) {
143 hasNext_ = false;
144 return hasNext_;
145 } else if (res > INT_ZERO) {
146 ++offset_;
147 break;
148 }
149 }
150 TELEPHONY_LOGI("TagService::Next for length : %{public}d", length_);
151 /* parse value */
152 dataOffset_ = offset_;
153 offset_ += static_cast<size_t>(length_);
154 if (offset_ > data_.size()) {
155 hasNext_ = false;
156 }
157 TELEPHONY_LOGI("TagService::Next for value : %{public}s",
158 SIMUtils::HexVecToHexStr(std::vector<uint8_t>(data_.begin() + dataOffset_, data_.begin() +
159 dataOffset_ + length_)).c_str());
160 return hasNext_;
161 }
162 } // namespace Telephony
163 } // namespace OHOS
164