// Copyright 2019 The Amber Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "src/descriptor_set_and_binding_parser.h" #include #include #include #include "src/tokenizer.h" namespace amber { DescriptorSetAndBindingParser::DescriptorSetAndBindingParser() = default; DescriptorSetAndBindingParser::~DescriptorSetAndBindingParser() = default; Result DescriptorSetAndBindingParser::Parse(const std::string& buffer_id) { size_t idx = 0; // Pipeline name if (!std::isdigit(buffer_id[idx]) && std::isalpha(buffer_id[idx]) && buffer_id[idx] != ':' && buffer_id[idx] != '-') { idx++; while (idx < buffer_id.size() && buffer_id[idx] != ':') idx++; pipeline_name_ = buffer_id.substr(0, idx); // Move past the : idx += 1; } if (idx >= buffer_id.size()) return Result("Invalid buffer id: " + buffer_id); Tokenizer t(buffer_id.substr(idx)); auto token = t.NextToken(); if (token->IsInteger()) { if (token->AsInt32() < 0) { return Result( "Descriptor set and binding for a buffer must be non-negative " "integer, but you gave: " + token->ToOriginalString()); } uint32_t val = token->AsUint32(); token = t.NextToken(); if (token->IsEOS() || token->IsEOL()) { descriptor_set_ = 0; binding_ = val; return {}; } descriptor_set_ = val; } if (!token->IsIdentifier()) return Result("Invalid buffer id: " + buffer_id); auto& str = token->AsString(); if (str.size() < 2 || str[0] != ':') return Result("Invalid buffer id: " + buffer_id); auto substr = str.substr(1, str.size()); // Validate all characters are integers. for (size_t i = 0; i < substr.size(); ++i) { if (substr[i] < '0' || substr[i] > '9') { return Result( "Binding for a buffer must be non-negative integer, " "but you gave: " + substr); } } uint64_t binding_val = strtoul(substr.c_str(), nullptr, 10); if (binding_val > std::numeric_limits::max()) return Result("binding value too large in probe ssbo command: " + token->ToOriginalString()); if (static_cast(binding_val) < 0) { return Result( "Binding for a buffer must be non-negative integer, but you gave: " + token->ToOriginalString()); } binding_ = static_cast(binding_val); return {}; } } // namespace amber