reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

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 }