• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Amber Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/descriptor_set_and_binding_parser.h"
16 
17 #include <cctype>
18 #include <iostream>
19 #include <limits>
20 
21 #include "src/tokenizer.h"
22 
23 namespace amber {
24 
25 DescriptorSetAndBindingParser::DescriptorSetAndBindingParser() = default;
26 
27 DescriptorSetAndBindingParser::~DescriptorSetAndBindingParser() = default;
28 
Parse(const std::string & buffer_id)29 Result DescriptorSetAndBindingParser::Parse(const std::string& buffer_id) {
30   size_t idx = 0;
31 
32   // Pipeline name
33   if (!std::isdigit(buffer_id[idx]) && std::isalpha(buffer_id[idx]) &&
34       buffer_id[idx] != ':' && buffer_id[idx] != '-') {
35     idx++;
36     while (idx < buffer_id.size() && buffer_id[idx] != ':')
37       idx++;
38 
39     pipeline_name_ = buffer_id.substr(0, idx);
40 
41     // Move past the :
42     idx += 1;
43   }
44   if (idx >= buffer_id.size())
45     return Result("Invalid buffer id: " + buffer_id);
46 
47   Tokenizer t(buffer_id.substr(idx));
48   auto token = t.NextToken();
49   if (token->IsInteger()) {
50     if (token->AsInt32() < 0) {
51       return Result(
52           "Descriptor set and binding for a buffer must be non-negative "
53           "integer, but you gave: " +
54           token->ToOriginalString());
55     }
56 
57     uint32_t val = token->AsUint32();
58     token = t.NextToken();
59     if (token->IsEOS() || token->IsEOL()) {
60       descriptor_set_ = 0;
61       binding_ = val;
62       return {};
63     }
64 
65     descriptor_set_ = val;
66   }
67 
68   if (!token->IsIdentifier())
69     return Result("Invalid buffer id: " + buffer_id);
70 
71   auto& str = token->AsString();
72   if (str.size() < 2 || str[0] != ':')
73     return Result("Invalid buffer id: " + buffer_id);
74 
75   auto substr = str.substr(1, str.size());
76   // Validate all characters are integers.
77   for (size_t i = 0; i < substr.size(); ++i) {
78     if (substr[i] < '0' || substr[i] > '9') {
79       return Result(
80           "Binding for a buffer must be non-negative integer, "
81           "but you gave: " +
82           substr);
83     }
84   }
85 
86   uint64_t binding_val = strtoul(substr.c_str(), nullptr, 10);
87   if (binding_val > std::numeric_limits<uint32_t>::max())
88     return Result("binding value too large in probe ssbo command: " +
89                   token->ToOriginalString());
90   if (static_cast<int32_t>(binding_val) < 0) {
91     return Result(
92         "Binding for a buffer must be non-negative integer, but you gave: " +
93         token->ToOriginalString());
94   }
95 
96   binding_ = static_cast<uint32_t>(binding_val);
97   return {};
98 }
99 
100 }  // namespace amber
101