• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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