Apache GraphAr C++ Library
The C++ Library for Apache GraphAr
version_parser.cc
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #include <algorithm>
21 #include <iostream>
22 #include <regex> // NOLINT
23 #include <string>
24 
25 #include "graphar/version_parser.h"
26 
27 namespace graphar {
28 
29 // Helper function for parsing version string
30 bool is_whitespace(char ch) {
31  return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n';
32 }
33 
34 void trim(std::string& s) { // NOLINT
35  size_t trim_left = 0;
36  for (auto it = s.begin(); it != s.end(); ++it) {
37  if (!is_whitespace(*it)) {
38  break;
39  }
40  ++trim_left;
41  }
42 
43  if (trim_left == s.size()) {
44  s.clear();
45  } else {
46  size_t trim_right = 0;
47  for (auto it = s.rbegin(); it != s.rend(); ++it) {
48  if (!is_whitespace(*it)) {
49  break;
50  }
51  ++trim_right;
52  }
53 
54  if (trim_left > 0 || trim_right > 0) {
55  if (trim_left == 0) {
56  s.resize(s.size() - trim_right);
57  } else {
58  std::string copy(s.c_str() + trim_left,
59  s.size() - trim_left - trim_right);
60  s.swap(copy);
61  }
62  }
63  }
64 }
65 
66 int parserVersionImpl(const std::string& version_str) {
67  std::smatch match;
68  const std::regex version_regex("gar/v(\\d+).*");
69  if (std::regex_match(version_str, match, version_regex)) {
70  if (match.size() != 2) {
71  throw std::runtime_error("Invalid version string: " + version_str);
72  }
73  return std::stoi(match[1].str());
74  } else {
75  throw std::runtime_error("Invalid version string: " + version_str);
76  }
77 }
78 
79 std::vector<std::string> parseUserDefineTypesImpl(
80  const std::string& version_str) {
81  std::smatch match;
82  std::vector<std::string> user_define_types;
83  const std::regex user_define_types_regex("gar/v\\d+ *\\((.*)\\).*");
84  if (std::regex_match(version_str, match, user_define_types_regex)) {
85  if (match.size() != 2) {
86  throw std::runtime_error("Invalid version string: " + version_str);
87  }
88  std::string types_str = match[1].str();
89  size_t pos = 0;
90  while (pos != std::string::npos) {
91  size_t next_pos = types_str.find(',', pos);
92  std::string type = types_str.substr(pos, next_pos - pos);
93  trim(type);
94  if (!type.empty()) {
95  user_define_types.push_back(type);
96  }
97  if (next_pos != std::string::npos) {
98  pos = next_pos + 1;
99  } else {
100  pos = next_pos;
101  }
102  }
103  }
104  return user_define_types;
105 }
106 
107 Result<std::shared_ptr<const InfoVersion>> InfoVersion::Parse(
108  const std::string& version_str) noexcept {
109  std::shared_ptr<InfoVersion> version;
110  try {
111  version = std::make_shared<InfoVersion>(
112  parserVersionImpl(version_str), parseUserDefineTypesImpl(version_str));
113  } catch (const std::exception& e) {
114  return Status::Invalid("Invalid version string: ", version_str);
115  }
116  return version;
117 }
118 } // namespace graphar
static Result< std::shared_ptr< const InfoVersion > > Parse(const std::string &str) noexcept
static Status Invalid(Args &&... args)
Definition: status.h:188