c5ed30c0e985e98a86dc92ed6d680a01d54cbe5e
[platform/core/context/context-provider.git] / src / my-place / utils / UserPlacesTypes.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <set>
18 #include <iostream>
19 #include <iomanip>
20 #include <sstream>
21 #include <algorithm>
22 #include <Types.h>
23 #include "UserPlacesTypes.h"
24 #include "UserPlacesParams.h"
25 #include "DebugUtils.h"
26
27 #define __MAC_STRING_COMPONENTS_SEPARATOR ':'
28 #define __MAC_SET_STRING_DELIMITER ','
29
30 ctx::Mac::Mac(const std::string& str)
31 {
32         std::stringstream ss(str);
33         try {
34                 ss >> *this;
35         } catch (std::runtime_error &e) {
36                 _E("%s", e.what());
37         }
38 }
39
40 ctx::Mac::Mac(const char *str)
41 {
42         std::stringstream ss(str);
43         try {
44                 ss >> *this;
45         } catch (std::runtime_error &e) {
46                 _E("%s", e.what());
47         }
48 }
49
50 std::istream& ctx::operator>>(std::istream &input, ctx::Mac &mac)
51 {
52         int h;
53         char colon;
54         for (size_t i = 0; i < ctx::Mac::MAC_SIZE; i++) {
55                 input >> std::hex;
56                 input >> h;
57                 mac.c[i] = h;
58                 if (i + 1 >= ctx::Mac::MAC_SIZE)
59                         break;
60                 input >> colon;
61                 if (colon != __MAC_STRING_COMPONENTS_SEPARATOR)
62                         throw std::runtime_error("Invalid MAC format");
63         }
64         input >> std::dec;
65         return input;
66 }
67
68 std::ostream& ctx::operator<<(std::ostream &output, const ctx::Mac &mac)
69 {
70         size_t i = 0;
71         while (true) {
72                 output << std::hex << std::setfill('0') << std::setw(2);
73                 output << static_cast<int>(mac.c[i]);
74                 i++;
75                 if (i >= Mac::MAC_SIZE)
76                         break;
77                 output << __MAC_STRING_COMPONENTS_SEPARATOR;
78         }
79         output << std::dec;
80         return output;
81 }
82
83 ctx::Mac::operator std::string() const
84 {
85         std::stringstream ss;
86         ss << *this;
87         return ss.str();
88 }
89
90 bool ctx::operator==(const Mac &m1, const Mac &m2)
91 {
92         for (size_t i = 0; i < Mac::MAC_SIZE; i++) {
93                 if (m1.c[i] != m2.c[i])
94                         return false;
95         }
96         return true;
97 }
98
99 bool ctx::operator!=(const Mac &m1, const Mac &m2)
100 {
101         return !(m1 == m2);
102 }
103
104 bool ctx::operator<(const Mac &m1, const Mac &m2)
105 {
106         unsigned char c1, c2;
107         for (size_t i = 0; i < Mac::MAC_SIZE; i++) {
108                 c1 = m1.c[i];
109                 c2 = m2.c[i];
110                 if (c1 < c2)
111                         return true;
112                 if (c1 > c2)
113                         return false;
114         }
115         return false; // they are equal
116 }
117
118 std::istream& ctx::operator>>(std::istream &input, ctx::MacSet &macSet)
119 {
120         Mac mac;
121         char delimeter;
122         while (!input.eof()) {
123                 try {
124                         input >> mac;
125                 } catch (std::runtime_error &e) {
126                         _E("Cannot read macSet. Exception: %s", e.what());
127                         break;
128                 }
129                 macSet.insert(mac);
130                 if (input.eof())
131                         break;
132                 delimeter = input.get();
133                 if (delimeter != __MAC_SET_STRING_DELIMITER) {
134                         input.unget();
135                         break;
136                 }
137         }
138         return input;
139 }
140
141 std::ostream& ctx::operator<<(std::ostream &output, const ctx::MacSet &macSet)
142 {
143         std::vector<Mac> macVec(macSet.size());
144         std::copy(macSet.begin(), macSet.end(), macVec.begin());
145         std::sort(macVec.begin(), macVec.end());
146
147         bool first = true;
148         for (auto &mac: macVec) {
149                 if (first) {
150                         first = false;
151                 } else {
152                         output << __MAC_SET_STRING_DELIMITER;
153                 }
154                 output << mac;
155         }
156         return output;
157 }
158
159 void ctx::LocationEvent::log()
160 {
161         std::string time_str = DebugUtils::humanReadableDateTime(timestamp, "%T", 9);
162 #ifdef TIZEN_ENGINEER_MODE
163         _D("location lat=%.8f, lon=%.8f, acc=%.2f[m], time=%s, method=%d",
164                         coordinates.latitude,
165                         coordinates.longitude,
166                         coordinates.accuracy,
167                         time_str.c_str(),
168                         method);
169 #else /* TIZEN_ENGINEER_MODE */
170         _D("location lat=%.8f, lon=%.8f, acc=%.2f[m], time=%s",
171                         coordinates.latitude,
172                         coordinates.longitude,
173                         coordinates.accuracy,
174                         time_str.c_str());
175 #endif /* TIZEN_ENGINEER_MODE */
176 }
177
178 void ctx::Visit::setLocation(Location location_)
179 {
180         locationValid = true;
181         location = location_;
182 }
183
184 void ctx::Visit::printShort2Stream(std::ostream &out) const
185 {
186         // print only valid visits
187         if (interval.end != 0) {
188                 float duration = ((float) (interval.end - interval.start)) / 3600; // [h]
189                 out << "__VISIT " << duration << "h: ";
190                         out << DebugUtils::humanReadableDateTime(interval.start, "%m/%d %H:%M", 15) << " รท ";
191                         out << DebugUtils::humanReadableDateTime(interval.end, "%m/%d %H:%M", 15) << std::endl;
192         }
193 }
194
195 bool ctx::operator==(const ctx::Visit &v1, const ctx::Visit &v2)
196 {
197         return v1.interval.start == v2.interval.start
198                         && v1.interval.end == v2.interval.end
199                         && v1.categs == v2.categs
200                         && v1.location.latitude == v2.location.latitude
201                         && v1.location.longitude == v2.location.longitude
202                         && v1.location.accuracy == v2.location.accuracy
203                         && v1.locationValid == v2.locationValid
204                         && v1.macSet == v2.macSet;
205 }
206
207 ctx::MacSet ctx::macSetFromString(const std::string &str)
208 {
209         MacSet macSet;
210         std::stringstream ss;
211         ss << str;
212         ss >> macSet;
213         return macSet;
214 }
215
216 bool ctx::operator>(const Mac &m1, const Mac &m2)
217 {
218         return m2 < m1;
219 }
220
221 std::shared_ptr<ctx::MacSet> ctx::macSetFromMacs2Counts(const Macs2Counts &macs2Counts)
222 {
223         std::shared_ptr<MacSet> macSet(std::make_shared<MacSet>());
224         for (auto &macCount: macs2Counts) {
225                 macSet->insert(macCount.first);
226         }
227         return macSet;
228 }
229
230 std::shared_ptr<ctx::MacSet> ctx::macSetsUnion(const std::vector<std::shared_ptr<MacSet>> &macSets)
231 {
232         std::shared_ptr<MacSet> unionSet = std::make_shared<MacSet>();
233         for (std::shared_ptr<MacSet> macSet : macSets) {
234                 unionSet->insert(macSet->begin(), macSet->end());
235         }
236         return unionSet;
237 }
238
239 ctx::Interval::Interval(time_t start_, time_t end_) : start(start_), end(end_) {
240         if (end_ < start_)
241                 _E("Negative interval, start=%d, end=%d", start_, end_);
242 }