read_ops.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #pragma once
  2. #include "reader.h"
  3. #include <util/generic/maybe.h>
  4. #include <util/generic/bt_exception.h>
  5. #include <util/generic/yexception.h>
  6. #include <util/system/yassert.h>
  7. /** Imperative recursive-descent parsing helpers.
  8. *
  9. * These functions help verify conditions and advance parser state.
  10. * For aggregate parsing functions, common precondition is to require Begin{X}
  11. * event prior to function invocation. Thus, parsers are composable by calling
  12. * sub-parser after dispatching on opening event, e.g.:
  13. *
  14. * if (reader.LastEvent().Type() == EEventType::BeginMap) {
  15. * ReadSomeMap(reader)
  16. * }
  17. *
  18. */
  19. namespace NYsonPull {
  20. namespace NReadOps {
  21. class TExpectationFailure: public TWithBackTrace<yexception> {
  22. };
  23. inline void Expect(const TEvent& got, EEventType expected) {
  24. Y_ENSURE_EX(
  25. got.Type() == expected,
  26. TExpectationFailure() << "expected " << expected << ", got " << got);
  27. }
  28. inline void Expect(const TScalar& got, EScalarType expected) {
  29. Y_ENSURE_EX(
  30. got.Type() == expected,
  31. TExpectationFailure() << "expected scalar " << expected << ", got " << got);
  32. }
  33. // ExpectBegin{X} functions verify that last event WAS X
  34. // SkipBegin{X} functions verify that next event WILL BE X and CONSUME it
  35. inline void ExpectBeginStream(TReader& reader) {
  36. Expect(reader.LastEvent(), EEventType::BeginStream);
  37. }
  38. inline void SkipBeginStream(TReader& reader) {
  39. Expect(reader.NextEvent(), EEventType::BeginStream);
  40. }
  41. inline void ExpectBeginMap(TReader& reader) {
  42. Expect(reader.LastEvent(), EEventType::BeginMap);
  43. }
  44. inline void SkipBeginMap(TReader& reader) {
  45. Expect(reader.NextEvent(), EEventType::BeginMap);
  46. }
  47. inline void ExpectBeginList(TReader& reader) {
  48. Expect(reader.LastEvent(), EEventType::BeginList);
  49. }
  50. inline void SkipBeginList(TReader& reader) {
  51. Expect(reader.NextEvent(), EEventType::BeginList);
  52. }
  53. inline bool ReadListItem(TReader& reader) {
  54. return reader.NextEvent().Type() != EEventType::EndList;
  55. }
  56. inline TMaybe<TStringBuf> ReadKey(TReader& reader) {
  57. const auto& event = reader.NextEvent();
  58. switch (event.Type()) {
  59. case EEventType::Key:
  60. return event.AsString();
  61. case EEventType::EndMap:
  62. return Nothing();
  63. default:
  64. ythrow yexception() << "Unexpected event: " << event;
  65. }
  66. }
  67. template <typename T = const TScalar&>
  68. inline T ReadScalar(TReader& reader);
  69. template <>
  70. inline const TScalar& ReadScalar<const TScalar&>(TReader& reader) {
  71. const auto& event = reader.NextEvent();
  72. Expect(event, EEventType::Scalar);
  73. return event.AsScalar();
  74. }
  75. template <>
  76. inline i64 ReadScalar<i64>(TReader& reader) {
  77. const auto& scalar = ReadScalar(reader);
  78. Expect(scalar, EScalarType::Int64);
  79. return scalar.AsInt64();
  80. }
  81. template <>
  82. inline ui64 ReadScalar<ui64>(TReader& reader) {
  83. const auto& scalar = ReadScalar(reader);
  84. Expect(scalar, EScalarType::UInt64);
  85. return scalar.AsUInt64();
  86. }
  87. template <>
  88. inline double ReadScalar<double>(TReader& reader) {
  89. const auto& scalar = ReadScalar(reader);
  90. Expect(scalar, EScalarType::Float64);
  91. return scalar.AsFloat64();
  92. }
  93. template <>
  94. inline TStringBuf ReadScalar<TStringBuf>(TReader& reader) {
  95. const auto& scalar = ReadScalar(reader);
  96. Expect(scalar, EScalarType::String);
  97. return scalar.AsString();
  98. }
  99. template <>
  100. inline TString ReadScalar<TString>(TReader& reader) {
  101. return TString(ReadScalar<TStringBuf>(reader));
  102. }
  103. template <>
  104. inline bool ReadScalar<bool>(TReader& reader) {
  105. const auto& scalar = ReadScalar(reader);
  106. Expect(scalar, EScalarType::Boolean);
  107. return scalar.AsBoolean();
  108. }
  109. // Skip value that was already started with `event`
  110. void SkipCurrentValue(const TEvent& event, TReader& reader);
  111. // Skip value that starts at `reader.next_event()`
  112. void SkipValue(TReader& reader);
  113. // Skip values with attributes, wait for map value
  114. void SkipControlRecords(TReader& reader);
  115. }
  116. }