serializer.cpp (2393B)
1 /* ReaPack: Package manager for REAPER 2 * Copyright (C) 2015-2025 Christian Fillion 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "serializer.hpp" 19 20 #include <boost/lexical_cast.hpp> 21 #include <sstream> 22 23 static const unsigned short VERSION = 1; 24 static const char FIELD_END = '\x20'; 25 static const char RECORD_END = ','; 26 27 auto Serializer::read(const std::string &input, const int userVersion) -> Data 28 { 29 m_userVersion = userVersion; 30 31 bool first = true; 32 std::istringstream stream(input); 33 34 Data out; 35 36 while(!stream.eof()) { 37 std::string line; 38 std::getline(stream, line, RECORD_END); 39 40 std::istringstream lineStream(line); 41 42 Record rec; 43 for(size_t i = 0; i < rec.size(); i++) { 44 if(lineStream.eof()) 45 return out; 46 47 std::string field; 48 std::getline(lineStream, field, FIELD_END); 49 50 int value; 51 52 try { 53 value = boost::lexical_cast<int>(field); 54 } 55 catch(const boost::bad_lexical_cast &) { 56 return out; // data is invalid! aborting. 57 } 58 59 rec[i] = value; 60 } 61 62 if(first) { 63 if(rec[0] != m_userVersion || rec[1] != VERSION) 64 return {}; 65 66 first = false; 67 } 68 else 69 out.push_back(rec); 70 } 71 72 return out; 73 } 74 75 std::string Serializer::write(const Data &data) const 76 { 77 if(!m_userVersion) 78 return {}; 79 80 std::ostringstream stream; 81 82 stream 83 << m_userVersion << FIELD_END 84 << VERSION << RECORD_END; 85 86 auto it = data.begin(); 87 88 while(true) { 89 const Record &rec = *it; 90 91 size_t j = 0; 92 while(true) { 93 stream << rec[j]; 94 95 if(++j < rec.size()) 96 stream << FIELD_END; 97 else 98 break; 99 } 100 101 it++; 102 103 if(it != data.end()) 104 stream << RECORD_END; 105 else 106 break; 107 } 108 109 return stream.str(); 110 }