1 /*
2 * Copyright (C) 2025 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <charconv>
18
19 #include "debug.h"
20 #include "Parser.h"
21
skip(const char c)22 Parser& Parser::skip(const char c) {
23 if (mBegin) {
24 if (c == ' ') {
25 while ((mBegin != mEnd) && (*mBegin <= ' ')) {
26 ++mBegin;
27 }
28 } else if ((mBegin != mEnd) && (*mBegin == c)) {
29 ++mBegin;
30 } else {
31 mBegin = FAILURE(nullptr);
32 }
33 }
34
35 return *this;
36 }
37
skip(const char * s)38 Parser& Parser::skip(const char* s) {
39 if (mBegin) {
40 while (mBegin != mEnd) {
41 const char c = *s;
42 if (!c) {
43 return *this;
44 } else if (c == *mBegin) {
45 ++mBegin;
46 ++s;
47 } else {
48 mBegin = FAILURE(nullptr);
49 return *this;
50 }
51 }
52
53 if (*s) {
54 mBegin = FAILURE(nullptr);
55 }
56 }
57
58 return *this;
59 }
60
operator ()(char * result)61 Parser& Parser::operator()(char* result) {
62 if (mBegin) {
63 if (mBegin != mEnd) {
64 *result = *mBegin;
65 ++mBegin;
66 } else {
67 mBegin = FAILURE(nullptr);
68 }
69 }
70
71 return *this;
72 }
73
operator ()(int * result,const int base)74 Parser& Parser::operator()(int* result, const int base) {
75 if (mBegin) {
76 if (mBegin != mEnd) {
77 const auto [unconsumed, ec] =
78 std::from_chars(mBegin, mEnd, *result, base);
79 if (ec == std::errc()) {
80 mBegin = unconsumed;
81 } else {
82 mBegin = FAILURE(nullptr);
83 }
84 } else {
85 mBegin = FAILURE(nullptr);
86 }
87 }
88
89 return *this;
90 }
91
operator ()(std::string_view * result,const char end)92 Parser& Parser::operator()(std::string_view* result, const char end) {
93 if (mBegin) {
94 for (const char* i = mBegin; i != mEnd; ++i) {
95 if (*i == end) {
96 *result = std::string_view(mBegin, i - mBegin);
97 mBegin = i + 1;
98 return *this;
99 }
100 }
101
102 mBegin = FAILURE(nullptr);
103 }
104
105 return *this;
106 }
107
operator ()(std::string * result,const char end)108 Parser& Parser::operator()(std::string* result, const char end) {
109 std::string_view view;
110 if ((*this)(&view, end).matchSoFar()) {
111 *result = std::string(view.data(), view.size());
112 }
113 return *this;
114 }
115
remaining()116 std::string_view Parser::remaining() {
117 const char* begin = mBegin;
118 if (begin) {
119 mBegin = mEnd;
120 return std::string_view(begin, mEnd - begin);
121 } else {
122 return {};
123 }
124 }
125
remainingAsString()126 std::string Parser::remainingAsString() {
127 std::string_view rem = remaining();
128 return std::string(rem.data(), rem.size());
129 }
130
consumed() const131 int Parser::consumed() const {
132 return mBegin ? int(mBegin - mImmutableBegin) : -1;
133 }
134