Line data Source code
1 : /* 2 : * Copyright (C) 2004-2025 Savoir-faire Linux Inc. 3 : * 4 : * This program is free software: you can redistribute it and/or modify 5 : * it under the terms of the GNU General Public License as published by 6 : * the Free Software Foundation, either version 3 of the License, or 7 : * (at your option) any later version. 8 : * 9 : * This program is distributed in the hope that it will be useful, 10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 : * GNU General Public License for more details. 13 : * 14 : * You should have received a copy of the GNU General Public License 15 : * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 : */ 17 : #include "vcard.h" 18 : #include "string_utils.h" 19 : #include "fileutils.h" 20 : 21 : #include <fstream> 22 : #include <filesystem> 23 : #include <map> 24 : 25 : namespace jami { 26 : namespace vCard { 27 : 28 : namespace utils { 29 : 30 : VCardData 31 101 : toMap(std::string_view content) 32 : { 33 101 : VCardData vCard; 34 : 35 101 : std::string_view line; 36 243 : while (jami::getline(content, line)) { 37 142 : if (line.size()) { 38 142 : const auto dblptPos = line.find(':'); 39 142 : if (dblptPos == std::string::npos) 40 26 : continue; 41 116 : vCard.emplace(line.substr(0, dblptPos), line.substr(dblptPos + 1)); 42 : } 43 : } 44 202 : return vCard; 45 0 : } 46 : 47 : VCardData 48 0 : initVcard() 49 : { 50 : return { 51 0 : {std::string(Property::VCARD_VERSION), "2.1"}, 52 0 : {std::string(Property::FORMATTED_NAME), ""}, 53 0 : {std::string(Property::PHOTO_PNG), ""}, 54 0 : }; 55 : } 56 : 57 : std::string 58 0 : toString(const VCardData& vCard) 59 : { 60 0 : size_t estimatedSize = 0; 61 0 : for (const auto& [key, value] : vCard) { 62 0 : if (Delimiter::BEGIN_TOKEN_KEY == key || Delimiter::END_TOKEN_KEY == key) 63 0 : continue; 64 0 : estimatedSize += key.size() + value.size() + 2; 65 : } 66 0 : std::string result; 67 0 : result.reserve(estimatedSize + Delimiter::BEGIN_TOKEN.size() + Delimiter::END_LINE_TOKEN.size() 68 0 : + Delimiter::END_TOKEN.size() + Delimiter::END_LINE_TOKEN.size()); 69 : 70 0 : result += Delimiter::BEGIN_TOKEN; 71 0 : result += Delimiter::END_LINE_TOKEN; 72 : 73 0 : for (const auto& [key, value] : vCard) { 74 0 : if (Delimiter::BEGIN_TOKEN_KEY == key || Delimiter::END_TOKEN_KEY == key) 75 0 : continue; 76 0 : result += key + ':' + value + '\n'; 77 : } 78 : 79 0 : result += Delimiter::END_TOKEN; 80 0 : result += Delimiter::END_LINE_TOKEN; 81 : 82 0 : return result; 83 0 : } 84 : 85 : void 86 0 : save(const VCardData& vCard, const std::filesystem::path& path, const std::filesystem::path& pathLink) 87 : { 88 0 : std::filesystem::path tmpPath = path; 89 0 : tmpPath += ".tmp"; 90 0 : std::ofstream file(tmpPath); 91 0 : if (file.is_open()) { 92 0 : file << vCard::utils::toString(vCard); 93 0 : file.close(); 94 0 : std::filesystem::rename(tmpPath, path); 95 0 : fileutils::createFileLink(pathLink, path, true); 96 : } 97 0 : } 98 : 99 : void 100 0 : removeByKey(VCardData& vCard, std::string_view key) 101 : { 102 0 : for (auto it = vCard.begin(); it != vCard.end();) { 103 0 : if (jami::starts_with(it->first, key)) { 104 0 : it = vCard.erase(it); 105 : } else { 106 0 : ++it; 107 : } 108 : } 109 0 : } 110 : 111 : } // namespace utils 112 : } // namespace vCard 113 : } // namespace jami