yaml-cpp

FORK: A YAML parser and emitter in C++
git clone https://git.neptards.moe/neptards/yaml-cpp.git
Log | Files | Refs | README | LICENSE

simplekey.cpp (3208B)


      1 #include "scanner.h"
      2 #include "token.h"
      3 
      4 namespace YAML {
      5 struct Mark;
      6 
      7 Scanner::SimpleKey::SimpleKey(const Mark& mark_, std::size_t flowLevel_)
      8     : mark(mark_),
      9       flowLevel(flowLevel_),
     10       pIndent(nullptr),
     11       pMapStart(nullptr),
     12       pKey(nullptr) {}
     13 
     14 void Scanner::SimpleKey::Validate() {
     15   // Note: pIndent will *not* be garbage here;
     16   //       we "garbage collect" them so we can
     17   //       always refer to them
     18   if (pIndent)
     19     pIndent->status = IndentMarker::VALID;
     20   if (pMapStart)
     21     pMapStart->status = Token::VALID;
     22   if (pKey)
     23     pKey->status = Token::VALID;
     24 }
     25 
     26 void Scanner::SimpleKey::Invalidate() {
     27   if (pIndent)
     28     pIndent->status = IndentMarker::INVALID;
     29   if (pMapStart)
     30     pMapStart->status = Token::INVALID;
     31   if (pKey)
     32     pKey->status = Token::INVALID;
     33 }
     34 
     35 // CanInsertPotentialSimpleKey
     36 bool Scanner::CanInsertPotentialSimpleKey() const {
     37   if (!m_simpleKeyAllowed)
     38     return false;
     39 
     40   return !ExistsActiveSimpleKey();
     41 }
     42 
     43 // ExistsActiveSimpleKey
     44 // . Returns true if there's a potential simple key at our flow level
     45 //   (there's allowed at most one per flow level, i.e., at the start of the flow
     46 // start token)
     47 bool Scanner::ExistsActiveSimpleKey() const {
     48   if (m_simpleKeys.empty())
     49     return false;
     50 
     51   const SimpleKey& key = m_simpleKeys.top();
     52   return key.flowLevel == GetFlowLevel();
     53 }
     54 
     55 // InsertPotentialSimpleKey
     56 // . If we can, add a potential simple key to the queue,
     57 //   and save it on a stack.
     58 void Scanner::InsertPotentialSimpleKey() {
     59   if (!CanInsertPotentialSimpleKey())
     60     return;
     61 
     62   SimpleKey key(INPUT.mark(), GetFlowLevel());
     63 
     64   // first add a map start, if necessary
     65   if (InBlockContext()) {
     66     key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP);
     67     if (key.pIndent) {
     68       key.pIndent->status = IndentMarker::UNKNOWN;
     69       key.pMapStart = key.pIndent->pStartToken;
     70       key.pMapStart->status = Token::UNVERIFIED;
     71     }
     72   }
     73 
     74   // then add the (now unverified) key
     75   m_tokens.push(Token(Token::KEY, INPUT.mark()));
     76   key.pKey = &m_tokens.back();
     77   key.pKey->status = Token::UNVERIFIED;
     78 
     79   m_simpleKeys.push(key);
     80 }
     81 
     82 // InvalidateSimpleKey
     83 // . Automatically invalidate the simple key in our flow level
     84 void Scanner::InvalidateSimpleKey() {
     85   if (m_simpleKeys.empty())
     86     return;
     87 
     88   // grab top key
     89   SimpleKey& key = m_simpleKeys.top();
     90   if (key.flowLevel != GetFlowLevel())
     91     return;
     92 
     93   key.Invalidate();
     94   m_simpleKeys.pop();
     95 }
     96 
     97 // VerifySimpleKey
     98 // . Determines whether the latest simple key to be added is valid,
     99 //   and if so, makes it valid.
    100 bool Scanner::VerifySimpleKey() {
    101   if (m_simpleKeys.empty())
    102     return false;
    103 
    104   // grab top key
    105   SimpleKey key = m_simpleKeys.top();
    106 
    107   // only validate if we're in the correct flow level
    108   if (key.flowLevel != GetFlowLevel())
    109     return false;
    110 
    111   m_simpleKeys.pop();
    112 
    113   bool isValid = true;
    114 
    115   // needs to be less than 1024 characters and inline
    116   if (INPUT.line() != key.mark.line || INPUT.pos() - key.mark.pos > 1024)
    117     isValid = false;
    118 
    119   // invalidate key
    120   if (isValid)
    121     key.Validate();
    122   else
    123     key.Invalidate();
    124 
    125   return isValid;
    126 }
    127 
    128 void Scanner::PopAllSimpleKeys() {
    129   while (!m_simpleKeys.empty())
    130     m_simpleKeys.pop();
    131 }
    132 }  // namespace YAML