void JSON_parser::process()

in cdk/parser/json_parser.cc [58:356]


void JSON_parser::process(Expr_base::Processor &prc) const
{
  rapidjson::Reader m_parser;

  /*
    Note: In-situ parsing could be faster but it would also destroy
    contents of m_json and we need it for error reporting.
  */

  rapidjson::GenericStringStream<rapidjson::UTF8<char>>
  ss(const_cast<char*>(m_json.data()));

  /*
    struct to be used as handler for rapidjson parser
  */
  struct Processor_cvt
  {

    struct processors
    {
      Processor *m_obj = nullptr;
      Processor::Any_prc* m_key = nullptr;
      Processor::Any_prc::List_prc* m_arr = nullptr;

      processors(Processor *obj)
      {
        m_obj = obj;
      }

      processors(Processor::Any_prc* key)
      {
        m_key = key;
      }

      processors(Processor::Any_prc::List_prc* arr)
      {
        m_arr = arr;
      }
    };

    std::stack<processors> m_stack;

    Processor_cvt (Processor &prc)
    {
      m_stack.push(&prc);
    }

    bool Null()
    {
      if (m_stack.empty())
        return false;

      if (m_stack.top().m_key)
      {
        m_stack.top().m_key->scalar()->null();
        m_stack.pop();
      }
      else if (m_stack.top().m_arr)
        m_stack.top().m_arr->list_el()->scalar()->null();
      return true;
    }

    bool Bool(bool b)
    {
      if (m_stack.empty())
        return false;


      if (m_stack.top().m_key)
      {
        m_stack.top().m_key->scalar()->yesno(b);
        m_stack.pop();
      }
      else if (m_stack.top().m_arr)
        m_stack.top().m_arr->list_el()->scalar()->yesno(b);
      else
        return false;

      return true;
    }

    bool Int(int i)
    {
      if (m_stack.empty())
        return false;


      if (m_stack.top().m_key)
      {
        m_stack.top().m_key->scalar()->num(static_cast<int64_t>(i));
        m_stack.pop();
      }
      else if (m_stack.top().m_arr)
        m_stack.top().m_arr->list_el()->scalar()->num(static_cast<int64_t>(i));
      else
        return false;

      return true;
    }

    bool Uint(unsigned u)
    {
      if (m_stack.empty())
        return false;


      if (m_stack.top().m_key)
      {
        m_stack.top().m_key->scalar()->num(static_cast<uint64_t>(u));
        m_stack.pop();
      }
      else if (m_stack.top().m_arr)
        m_stack.top().m_arr->list_el()->scalar()->num(static_cast<uint64_t>(u));
      else
        return false;

      return true;
    }

    bool Int64(int64_t i)
    {
      if (m_stack.empty())
        return false;


      if (m_stack.top().m_key)
      {
        m_stack.top().m_key->scalar()->num(i);
        m_stack.pop();
      }
      else if (m_stack.top().m_arr)
        m_stack.top().m_arr->list_el()->scalar()->num(i);
      else
        return false;

      return true;
    }

    bool Uint64(uint64_t u)
    {
      if (m_stack.empty())
        return false;


      if (m_stack.top().m_key)
      {
        m_stack.top().m_key->scalar()->num(u);
        m_stack.pop();
      }
      else if (m_stack.top().m_arr)
        m_stack.top().m_arr->list_el()->scalar()->num(u);
      else
        return false;
      return true;
    }

    bool Double(double d)
    {
      if (m_stack.empty())
        return false;


      if (m_stack.top().m_key)
      {
        m_stack.top().m_key->scalar()->num(d);
        m_stack.pop();
      }
      else if (m_stack.top().m_arr)
        m_stack.top().m_arr->list_el()->scalar()->num(d);
      else
        return false;
      return true;
    }

    bool RawNumber(const char* /*str*/,
                   rapidjson::SizeType /*length*/,
                   bool /*copy*/)
    {
      // not needed
        return false;
    }

    bool String(const char* str, rapidjson::SizeType length, bool /*copy*/)
    {
      if (m_stack.empty())
        return false;


      if (m_stack.top().m_key)
      {
        m_stack.top().m_key->scalar()->str(std::string(str, length));
        m_stack.pop();
      }
      else if (m_stack.top().m_arr)
        m_stack.top().m_arr->list_el()->scalar()->str(std::string(str, length));

      return true;
    }

    bool Key(const char* str, rapidjson::SizeType length, bool /*copy*/)
    {
      if (m_stack.empty())
        return false;

      if (m_stack.top().m_obj)
        m_stack.push(m_stack.top().m_obj->key_val(std::string(str, length)));
      else
        return false;

      return true;
    }

    bool StartObject()
    {
      if (m_stack.empty())
        return false;

      if(m_stack.top().m_key)
      {
        m_stack.push(m_stack.top().m_key->doc());
      }
      else if (m_stack.top().m_arr)
      {
        m_stack.push(m_stack.top().m_arr->list_el()->doc());
      }
      else if (!m_stack.top().m_obj)
        return false;

      m_stack.top().m_obj->doc_begin();

      return true;
    }


    bool EndObject(rapidjson::SizeType )
    {
      if(m_stack.empty())
        return false;

      if (m_stack.top().m_obj)
      {
        m_stack.top().m_obj->doc_end();
      }

      m_stack.pop(); // Pop obj

      if (!m_stack.empty() && m_stack.top().m_key)
        m_stack.pop(); // Pop key

      return true;
    }
    bool StartArray()
    {
      if (m_stack.empty() )
        return false;

      if (m_stack.top().m_key)
      {
        m_stack.push(m_stack.top().m_key->arr());
      }
      else if (m_stack.top().m_arr)
      {
        m_stack.push(m_stack.top().m_arr->list_el()->arr());
      }
      else return false;

      m_stack.top().m_arr->list_begin();

      return true;
    }

    bool EndArray(rapidjson::SizeType )
    {
      if (m_stack.empty() )
        return false;

      if (!m_stack.top().m_arr)
        return false;

      m_stack.top().m_arr->list_end();
      m_stack.pop();// Pop array
      if (!m_stack.empty() && m_stack.top().m_key)
        m_stack.pop();// pop key

      return true;
    }

  };

  Processor_cvt cvt(prc);

  auto error = m_parser.Parse<>(ss, cvt);
  if (error.IsError())
  {
    throw JSON_parser::Error(m_json,
                             error.Offset(),
                             rapidjson::GetParseError_En(error.Code()));
  }
}