Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core/StarJsonPath.cpp
blob: c03e883d95a9e2b44da61e156e20bd7d2c832c31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "StarJsonPath.hpp"

namespace Star {

namespace JsonPath {

  TypeHint parsePointer(String& buffer, String const& path, String::const_iterator& iterator, String::const_iterator end) {
    buffer.clear();

    if (*iterator != '/')
      throw ParsingException::format("Missing leading '/' in Json pointer \"{}\"", path);
    iterator++;

    while (iterator != end && *iterator != '/') {
      if (*iterator == '~') {
        ++iterator;
        if (iterator == end)
          throw ParsingException::format("Incomplete escape sequence in Json pointer \"{}\"", path);

        if (*iterator == '0')
          buffer.append('~');
        else if (*iterator == '1')
          buffer.append('/');
        else
          throw ParsingException::format("Invalid escape sequence in Json pointer \"{}\"", path);
        ++iterator;
      } else
        buffer.append(*iterator++);
    }

    Maybe<size_t> index = maybeLexicalCast<size_t>(buffer);
    if (index.isValid() || (buffer == "-" && iterator == end))
      return TypeHint::Array;
    return TypeHint::Object;
  }

  TypeHint parseQueryPath(String& buffer, String const& path, String::const_iterator& iterator, String::const_iterator end) {
    buffer.clear();

    if (*iterator == '.') {
      throw ParsingException::format("Entry starts with '.' in query path \"{}\"", path);

    } else if (*iterator == '[') {
      // Parse array number and ']'
      // Consume initial '['
      ++iterator;

      while (iterator != end && *iterator >= '0' && *iterator <= '9')
        buffer.append(*iterator++);

      if (iterator == end || *iterator != ']')
        throw ParsingException::format("Array has no trailing ']' or has invalid character in query path \"{}\"", path);

      // Consume trailing ']'
      ++iterator;

      // Consume trailing '.'
      if (iterator != end && *iterator == '.')
        ++iterator;

      return TypeHint::Array;

    } else {
      // Parse path up to next '.' or '['
      while (iterator != end && *iterator != '.' && *iterator != '[')
        buffer.append(*iterator++);

      // Consume single trailing '.' if it exists
      if (iterator != end && *iterator == '.')
        ++iterator;
      return TypeHint::Object;
    }
  }
}

}