ゆとりーなの日記

日記的な事を書いて行くと思はれる

Boost.Property_treeで暗号化したiniファイルを読んでみる

iniファイルでゲームのデータを管理してみようかしらと無謀な考えが頭をめぐった矢先にiniファイルだと暗号化したものとか読めないからキャラクタのデータとかには使えないねとか言われてました。そこでは独自にiniファイル的サムシングと解析するものを作ったほうがいいですと書かれていたんですが、そこは流石Boost。暗号化したiniファイルも解析できるじゃないですか。
早速ソースです。

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <exception>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/range/algorithm/transform.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/operations.hpp>
#include <boost/property_tree/ini_parser.hpp>

// 適当に復号フィルターを作る
class ango_filter : public boost::iostreams::input_filter {
 public:
  template <typename Source>
  int get(Source &src) {
    const int c = boost::iostreams::get(src);
    // EOFは素通り
    if (c == EOF) {
      return c;
    }
    // それ以外は復号
    const char t = c ^ 213;
    return t;
  }
};

int main() {
  {
    boost::filesystem::ifstream fin("test.ini", std::ios::in | std::ios::binary);
    std::vector<char> v(boost::filesystem::file_size("test.ini"));
    fin.read(v.data(), v.size());
    boost::filesystem::ofstream fout("test_ango.ini", std::ios::out | std::ios::binary);
    // 適当に排他的論理和で暗号化
    boost::transform(v, std::ostream_iterator<char>(fout), [](const char x) {return x ^ 213;});
  }
  boost::filesystem::ifstream fin("test_ango.ini", std::ios::in | std::ios::binary);
  boost::iostreams::filtering_istream s;
  s.push(ango_filter());
  s.push(fin);
  boost::property_tree::ptree pt;
  boost::property_tree::read_ini(s, pt);
  std::cout << pt.get<int>("Alice.Val") << "\n" << pt.get<std::string>("Alice.Str") << std::endl;
  return 0;
}

まぁネタとしてはboost::property_tree::read_iniにファイル名文字列ではなくstd::basic_istreamを取ってくれるものがあったので、Boost.Iostreamsと組み合わせればiniファイルをごにょごにょしたものは何でも読めるのではということです。gzip圧縮とかも出来ますから、圧縮暗号化したiniファイルの読み込みは割と簡単にいけるかと思います。はい。