winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

YamlWrapper.h (4894B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #pragma once
      4 #include <yaml.h>
      5 #include "winget/Yaml.h"
      6 #include "AppInstallerLanguageUtilities.h"
      7 #include "AppInstallerSHA256.h"
      8 
      9 #include <iostream>
     10 #include <string_view>
     11 #include <vector>
     12 
     13 
     14 namespace AppInstaller::YAML::Wrapper
     15 {
     16     // A libyaml yaml_document_t.
     17     // A parsed document, created by the Parser.
     18     struct Document
     19     {
     20         // Initializes the document.
     21         Document(bool init = false);
     22 
     23         Document(const Document&) = delete;
     24         Document& operator=(const Document&) = delete;
     25 
     26         Document(Document&&) noexcept = default;
     27         Document& operator=(Document&&) noexcept = delete;
     28 
     29         ~Document();
     30 
     31         yaml_document_t* operator&() { return &m_document; }
     32 
     33         // Indicates that the document should not be deleted, as
     34         // it has been handed off to the emitter.
     35         void Detach() { m_token = false; }
     36 
     37         // Determines whether the document has a root node.
     38         bool HasRoot();
     39 
     40         // Gets the root node of the document, if it has one.
     41         Node GetRoot();
     42 
     43         // Adds a scalar node to the document.
     44         int AddScalar(std::string_view value, ScalarStyle style = ScalarStyle::Any);
     45 
     46         // Adds a sequence node to the document.
     47         int AddSequence();
     48 
     49         // Adds a mapping node to the document.
     50         int AddMapping();
     51 
     52         // Appends a node to the end of the sequence.
     53         void AppendSequenceItem(int sequence, int item);
     54 
     55         // Adds a pair to the mapping.
     56         void AppendMappingPair(int mapping, int key, int value);
     57 
     58     private:
     59         // Gets the node referenced by the index.
     60         yaml_node_t* GetNode(yaml_node_item_t index);
     61 
     62         DestructionToken m_token;
     63         yaml_document_t m_document;
     64     };
     65 
     66     // A libyaml yaml_parser_t.
     67     // The core parser construct for reading bytes directly.
     68     struct Parser
     69     {
     70         Parser(std::string_view input);
     71         Parser(std::istream& input, Utility::SHA256::HashBuffer* hashOut = nullptr);
     72 
     73         Parser(const Parser&) = delete;
     74         Parser& operator=(const Parser&) = delete;
     75 
     76         Parser(Parser&&) noexcept = default;
     77         Parser& operator=(Parser&&) noexcept = delete;
     78 
     79         ~Parser();
     80 
     81         yaml_parser_t* operator&() { return &m_parser; }
     82 
     83         // Loads the next document from the input, if one exists.
     84         Document Load();
     85 
     86         // Retrieves the input that was used to create the parser with the correct encoding scheme.
     87         const std::string& GetEncodedInput() const { return m_input; }
     88 
     89     private:
     90         // Determines the type of encoding in use, transforming the input as necessary.
     91         void PrepareInput();
     92 
     93         DestructionToken m_token;
     94         yaml_parser_t m_parser;
     95         std::string m_input;
     96     };
     97 
     98     // A libyaml yaml_event_t.
     99     // The generic event type for.
    100     struct Event
    101     {
    102         Event(const Event&) = delete;
    103         Event& operator=(const Event&) = delete;
    104 
    105         Event(Event&&) noexcept = default;
    106         Event& operator=(Event&&) noexcept = delete;
    107 
    108         ~Event();
    109 
    110         yaml_event_t* operator&() { return &m_event; }
    111 
    112         // Indicates that the event should not be deleted, as
    113         // it has been handed off to the emitter.
    114         void Detach() { m_token = false; }
    115 
    116         // Event creation functions.
    117         static Event StreamStart();
    118         static Event StreamEnd();
    119         static Event DocumentStart();
    120         static Event DocumentEnd();
    121         static Event SequenceStart();
    122         static Event SequenceEnd();
    123         static Event MappingStart();
    124         static Event MappingEnd();
    125 
    126     private:
    127         Event() = default;
    128 
    129         DestructionToken m_token;
    130         yaml_event_t m_event = {};
    131     };
    132 
    133     // A libyaml yaml_emitter_t.
    134     // Allows YAML to be written out.
    135     struct Emitter
    136     {
    137         Emitter(std::ostream& output);
    138 
    139         Emitter(const Emitter&) = delete;
    140         Emitter& operator=(const Emitter&) = delete;
    141 
    142         Emitter(Emitter&&) noexcept = default;
    143         Emitter& operator=(Emitter&&) noexcept = delete;
    144 
    145         ~Emitter();
    146 
    147         yaml_emitter_t* operator&() { return &m_emitter; }
    148 
    149         // Emits and event.
    150         void Emit(Event& event);
    151         void Emit(Event&& event);
    152 
    153         // Dumps a document to the emitter.
    154         void Dump(Document& document);
    155 
    156         // Flushes the emitter.
    157         void Flush();
    158 
    159     private:
    160         static int StreamWriteHandler(
    161             void* data,
    162             unsigned char* buffer,
    163             size_t size);
    164 
    165         void ThrowError();
    166 
    167         DestructionToken m_token;
    168         yaml_emitter_t m_emitter;
    169         std::ostream* m_outputStream = nullptr;
    170     };
    171 }