[C/C++] YAML

Alexandria·2024년 3월 4일
0

C lang

목록 보기
12/14
post-thumbnail

1. 환경

YAML을 읽고 쓰기 편리한 라이브러리이다.

소스를 다운받고 공유 라이브러리 형태로 컴파일해본다.

$ sudo apt -y install cmake
$ git clone https://github.com/jbeder/yaml-cpp.git
$ cd yaml-cpp/
$ mkdir build
$ cd build
$ cmake -DYAML_BUILD_SHARED_LIBS=ON ..
$ make && sudo make install
$ cd ../
$ sudo cp -r include/yaml-cpp /usr/local/include
$ rm -rf build/

arm으로 컴파일하려면 다음과 같이 cmake를 실행한다.

$ cmake ../ -DCMAKE_FIND_ROOT_PATH=/ -DCMAKE_CXX_COMPILER=/usr/bin/aarch64-linux-gnu-g++ -DYAML_BUILD_SHARED_LIBS=ON

컴파일 시 libyaml-cpp.so를 링킹하여 컴파일한다.

2. 파싱

addresses와 같이 배열은 Sequence 타입, dhcp4나 gateway4와 같이 값만 있다면 Scalar, 그 외 network나 ethernets와 같이 하위 키가 또 있다면 Map으로 타입이 정의된다.

재귀 형식으로 데이터를 파싱해보자.

#include <yaml-cpp/yaml.h>
#include <iostream>

void ParsingYAMLFile(YAML::Node Node) {
    for (YAML::iterator iter = Node.begin(); iter != Node.end(); ++iter)
    {
        std::cout << "KEY\t\t" << iter->first << std::endl;
        if (iter->second.IsMap()) ParsingYAMLFile(iter->second);
        else if (iter->second.IsScalar()) std::cout << "Value\t\t" << iter->second << std::endl;
        else if (iter->second.IsSequence())
        {
            for (std::size_t idx = 0; idx < iter->second.size(); idx++) std::cout << "Sequence [" << idx << "]\t" << iter->second[idx] << std::endl;
        }
    }
}

int main(void) {
    YAML::Node Node = YAML::LoadFile("example1.yaml");
    ParsingYAMLFile(Node);
    return 0;
}

혹은 Map의 이름으로 접근할 수 있다.

#include <yaml-cpp/yaml.h>
#include <iostream>

int main(void) {
    YAML::Node Node = YAML::LoadFile("example1.yaml");
    std::cout << std::endl;
    std::cout << "[network]" << std::endl;
    std::cout << Node["network"] << std::endl;
    std::cout << "[ethernets]" << std::endl;
    std::cout << Node["network"]["ethernets"] << std::endl;
    std::cout << "[enp1s0]" << std::endl;
    std::cout << Node["network"]["ethernets"]["enp1s0"] << std::endl;
    std::cout << "[dhcp4]" << std::endl;
    std::cout << Node["network"]["ethernets"]["enp1s0"]["dhcp4"] << std::endl;
    return 0;
}

as를 이용하여 데이터 타입을 변환할 수 있다.

#include <yaml-cpp/yaml.h>
#include <iostream>

int main(void) {
    YAML::Node Node = YAML::LoadFile("example1.yaml");
    std::cout << ((Node["network"]["ethernets"]["enp1s0"]["dhcp4"].as<bool>()) ? "dhcp is true" : "dhcp is false") << std::endl;
    std::cout << Node["network"]["ethernets"]["enp1s0"]["dhcp4"].as<bool>() << std::endl;
    std::cout << Node["network"]["ethernets"]["enp1s0"]["dhcp4"].as<std::string>() << std::endl;
    return 0;
}

3. YAML 생성

Map을 작성하려면 BeginMap으로 시작 후 EndMap으로 끝나게 사용하며

배열은 BeginSeqEndSeq를 이용한다.

#include <yaml-cpp/yaml.h>
#include <iostream>
#include <fstream>

int main(void) {
    std::ofstream writeFile("example2.yaml");
    YAML::Emitter Emitter;
    Emitter << YAML::BeginMap;
        Emitter << YAML::Key << "network" << YAML::Value;
        Emitter << YAML::BeginMap;
            Emitter << YAML::Key << "ethernets" << YAML::Value;
            Emitter << YAML::BeginMap;
                Emitter << YAML::Key << "enp1s0" << YAML::Value;
                Emitter << YAML::BeginMap;
                    Emitter << YAML::Key << "addresses" << YAML::Value << YAML::Flow << YAML::BeginSeq << "192.168.2.1/24" << YAML::EndSeq;
                    Emitter << YAML::Key << "gateway4" << YAML::Value << "192.168.2.1";
                    Emitter << YAML::Key << "nameservers" << YAML::Value;
                        Emitter << YAML::BeginMap;
                        Emitter << YAML::Key << "addresses" << YAML::Value << YAML::Flow << YAML::BeginSeq << "168.126.63.1" << "168.126.63.2" << YAML::EndSeq;
                        Emitter << YAML::EndMap;
                Emitter << YAML::Key << "dhcp4" << YAML::Value << "false";
                Emitter << YAML::EndMap;

                Emitter << YAML::Key << "enp2s0" << YAML::Value;
                Emitter << YAML::BeginMap;
                    Emitter << YAML::Key << "addresses" << YAML::Value << YAML::Flow << YAML::BeginSeq << "192.168.1.1/24" << YAML::EndSeq;
                    Emitter << YAML::Key << "dhcp4" << YAML::Value << "false";
                Emitter << YAML::EndMap;
            Emitter << YAML::EndMap;
        Emitter << YAML::EndMap;
    Emitter << YAML::EndMap;

    writeFile << Emitter.c_str();
    writeFile.close();
    return 0;
}
profile
IT 도서관

0개의 댓글

관련 채용 정보