1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// found in the LICENSE file. 4f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "mojo/public/cpp/bindings/tests/validation_test_input_parser.h" 6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <assert.h> 8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <stdio.h> 9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <string.h> 10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <limits> 12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <map> 13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <set> 14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <utility> 15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "mojo/public/c/system/macros.h" 17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace mojo { 19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace test { 20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace { 21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class ValidationTestInputParser { 23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public: 24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ValidationTestInputParser(const std::string& input, 25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<uint8_t>* data, 26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t* num_handles, 27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::string* error_message); 28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ~ValidationTestInputParser(); 29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool Run(); 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private: 33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) struct DataType; 34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) typedef std::pair<const char*, const char*> Range; 36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) typedef bool (ValidationTestInputParser::*ParseDataFunc)( 38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const DataType& type, const std::string& value_string); 39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) struct DataType { 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char* name; 42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t name_size; 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t data_size; 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ParseDataFunc parse_data_func; 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) }; 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // A dist4/8 item that hasn't been matched with an anchr item. 48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) struct PendingDistanceItem { 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Where this data item is located in |data_|. 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t pos; 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Either 4 or 8 (bytes). 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t data_size; 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) }; 54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool GetNextItem(Range* range); 56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool ParseItem(const Range& range); 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool ParseUnsignedInteger(const DataType& type, 60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& value_string); 61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool ParseSignedInteger(const DataType& type, 62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& value_string); 63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool ParseFloat(const DataType& type, const std::string& value_string); 64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool ParseDouble(const DataType& type, const std::string& value_string); 65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool ParseBinarySequence(const DataType& type, 66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& value_string); 67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool ParseDistance(const DataType& type, const std::string& value_string); 68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool ParseAnchor(const DataType& type, const std::string& value_string); 69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool ParseHandles(const DataType& type, const std::string& value_string); 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool StartsWith(const Range& range, const char* prefix, size_t prefix_length); 72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool ConvertToUnsignedInteger(const std::string& value_string, 74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) unsigned long long int* value); 75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) template <typename T> 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void AppendData(T data) { 78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t pos = data_->size(); 79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) data_->resize(pos + sizeof(T)); 80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) memcpy(&(*data_)[pos], &data, sizeof(T)); 81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) template <typename TargetType, typename InputType> 84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool ConvertAndAppendData(InputType value) { 85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (value > std::numeric_limits<TargetType>::max() || 86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) value < std::numeric_limits<TargetType>::min()) { 87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AppendData(static_cast<TargetType>(value)); 90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) template <typename TargetType, typename InputType> 94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool ConvertAndFillData(size_t pos, InputType value) { 95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (value > std::numeric_limits<TargetType>::max() || 96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) value < std::numeric_limits<TargetType>::min()) { 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) TargetType target_value = static_cast<TargetType>(value); 100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) assert(pos + sizeof(TargetType) <= data_->size()); 101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) memcpy(&(*data_)[pos], &target_value, sizeof(TargetType)); 102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) static const DataType kDataTypes[]; 106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) static const size_t kDataTypeCount; 107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& input_; 109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t input_cursor_; 110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<uint8_t>* data_; 112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t* num_handles_; 113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::string* error_message_; 114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::map<std::string, PendingDistanceItem> pending_distance_items_; 116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::set<std::string> anchors_; 117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}; 118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define DATA_TYPE(name, data_size, parse_data_func) \ 120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) {name, sizeof(name) - 1, data_size, parse_data_func} 121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const ValidationTestInputParser::DataType 123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ValidationTestInputParser::kDataTypes[] = { 124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DATA_TYPE("[u1]", 1, &ValidationTestInputParser::ParseUnsignedInteger), 125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DATA_TYPE("[u2]", 2, &ValidationTestInputParser::ParseUnsignedInteger), 126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DATA_TYPE("[u4]", 4, &ValidationTestInputParser::ParseUnsignedInteger), 127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DATA_TYPE("[u8]", 8, &ValidationTestInputParser::ParseUnsignedInteger), 128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DATA_TYPE("[s1]", 1, &ValidationTestInputParser::ParseSignedInteger), 129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DATA_TYPE("[s2]", 2, &ValidationTestInputParser::ParseSignedInteger), 130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DATA_TYPE("[s4]", 4, &ValidationTestInputParser::ParseSignedInteger), 131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DATA_TYPE("[s8]", 8, &ValidationTestInputParser::ParseSignedInteger), 132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DATA_TYPE("[b]", 1, &ValidationTestInputParser::ParseBinarySequence), 133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DATA_TYPE("[f]", 4, &ValidationTestInputParser::ParseFloat), 134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DATA_TYPE("[d]", 8, &ValidationTestInputParser::ParseDouble), 135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DATA_TYPE("[dist4]", 4, &ValidationTestInputParser::ParseDistance), 136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DATA_TYPE("[dist8]", 8, &ValidationTestInputParser::ParseDistance), 137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DATA_TYPE("[anchr]", 0, &ValidationTestInputParser::ParseAnchor), 138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DATA_TYPE("[handles]", 0, &ValidationTestInputParser::ParseHandles) 139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}; 140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const size_t ValidationTestInputParser::kDataTypeCount = 142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sizeof(ValidationTestInputParser::kDataTypes) / 143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sizeof(ValidationTestInputParser::kDataTypes[0]); 144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)ValidationTestInputParser::ValidationTestInputParser( 146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& input, 147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<uint8_t>* data, 148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t* num_handles, 149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::string* error_message) 150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) : input_(input), 151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) input_cursor_(0), 152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) data_(data), 153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) num_handles_(num_handles), 154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error_message_(error_message) { 155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) assert(data_); 156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) assert(num_handles_); 157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) assert(error_message_); 158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) data_->clear(); 159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *num_handles_ = 0; 160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error_message_->clear(); 161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)ValidationTestInputParser::~ValidationTestInputParser() { 164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool ValidationTestInputParser::Run() { 167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Range range; 168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool result = true; 169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) while (result && GetNextItem(&range)) 170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) result = ParseItem(range); 171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!result) { 173f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *error_message_ = "Error occurred when parsing " + 174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::string(range.first, range.second); 175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else if (!pending_distance_items_.empty()) { 176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // We have parsed all the contents in |input_| successfully, but there are 177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // unmatched dist4/8 items. 178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *error_message_ = "Error occurred when matching [dist4/8] and [anchr]."; 179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) result = false; 180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!result) { 182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) data_->clear(); 183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *num_handles_ = 0; 184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) assert(error_message_->empty()); 186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return result; 189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool ValidationTestInputParser::GetNextItem(Range* range) { 192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char kWhitespaceChars[] = " \t\n\r"; 193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char kItemDelimiters[] = " \t\n\r/"; 194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char kEndOfLineChars[] = "\n\r"; 195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) while (true) { 196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Skip leading whitespaces. 197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // If there are no non-whitespace characters left, |input_cursor_| will be 198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // set to std::npos. 199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) input_cursor_ = input_.find_first_not_of(kWhitespaceChars, input_cursor_); 200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (input_cursor_ >= input_.size()) 202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (StartsWith(Range(&input_[0] + input_cursor_, 205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &input_[0] + input_.size()), 206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "//", 2)) { 207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Skip contents until the end of the line. 208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) input_cursor_ = input_.find_first_of(kEndOfLineChars, input_cursor_); 209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) range->first = &input_[0] + input_cursor_; 211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) input_cursor_ = input_.find_first_of(kItemDelimiters, input_cursor_); 212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) range->second = input_cursor_ >= input_.size() ? 213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &input_[0] + input_.size() : &input_[0] + input_cursor_; 214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool ValidationTestInputParser::ParseItem(const Range& range) { 221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (size_t i = 0; i < kDataTypeCount; ++i) { 222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (StartsWith(range, kDataTypes[i].name, kDataTypes[i].name_size)) { 223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return (this->*kDataTypes[i].parse_data_func)( 224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) kDataTypes[i], 225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::string(range.first + kDataTypes[i].name_size, range.second)); 226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // "[u1]" is optional. 230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ParseUnsignedInteger(kDataTypes[0], 231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::string(range.first, range.second)); 232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 234f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool ValidationTestInputParser::ParseUnsignedInteger( 235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const DataType& type, const std::string& value_string) { 236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) unsigned long long int value; 237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!ConvertToUnsignedInteger(value_string, &value)) 238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) switch (type.data_size) { 241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case 1: 242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ConvertAndAppendData<uint8_t>(value); 243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case 2: 244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ConvertAndAppendData<uint16_t>(value); 245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case 4: 246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ConvertAndAppendData<uint32_t>(value); 247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case 8: 248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ConvertAndAppendData<uint64_t>(value); 249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) default: 250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) assert(false); 251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool ValidationTestInputParser::ParseSignedInteger( 256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const DataType& type, const std::string& value_string) { 257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) long long int value; 258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (sscanf(value_string.c_str(), "%lli", &value) != 1) 259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) switch (type.data_size) { 262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case 1: 263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ConvertAndAppendData<int8_t>(value); 264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case 2: 265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ConvertAndAppendData<int16_t>(value); 266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case 4: 267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ConvertAndAppendData<int32_t>(value); 268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case 8: 269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ConvertAndAppendData<int64_t>(value); 270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) default: 271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) assert(false); 272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool ValidationTestInputParser::ParseFloat( 277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const DataType& type, const std::string& value_string) { 278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MOJO_COMPILE_ASSERT(sizeof(float) == 4, float_size_is_not_4); 279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) float value; 281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (sscanf(value_string.c_str(), "%f", &value) != 1) 282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AppendData(value); 285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool ValidationTestInputParser::ParseDouble(const DataType& type, 289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& value_string) { 290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MOJO_COMPILE_ASSERT(sizeof(double) == 8, double_size_is_not_8); 291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) double value; 293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (sscanf(value_string.c_str(), "%lf", &value) != 1) 294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AppendData(value); 297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool ValidationTestInputParser::ParseBinarySequence( 301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const DataType& type, const std::string& value_string) { 302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (value_string.size() != 8) 303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) uint8_t value = 0; 306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (std::string::const_iterator iter = value_string.begin(); 307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) iter != value_string.end(); 308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ++iter) { 309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) value <<= 1; 310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (*iter == '1') 311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) value++; 312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) else if (*iter != '0') 313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AppendData(value); 316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool ValidationTestInputParser::ParseDistance(const DataType& type, 320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& value_string) { 321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (pending_distance_items_.find(value_string) != 322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) pending_distance_items_.end()) 323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 325f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) PendingDistanceItem item = {data_->size(), type.data_size}; 326f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) data_->resize(data_->size() + type.data_size); 327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) pending_distance_items_[value_string] = item; 328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool ValidationTestInputParser::ParseAnchor(const DataType& type, 333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& value_string) { 334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (anchors_.find(value_string) != anchors_.end()) 335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) anchors_.insert(value_string); 337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::map<std::string, PendingDistanceItem>::iterator iter = 339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) pending_distance_items_.find(value_string); 340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (iter == pending_distance_items_.end()) 341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 343f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) PendingDistanceItem dist_item = iter->second; 344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) pending_distance_items_.erase(iter); 345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 346f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t distance = data_->size() - dist_item.pos; 347f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) switch (dist_item.data_size) { 348f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case 4: 349f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ConvertAndFillData<uint32_t>(dist_item.pos, distance); 350f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case 8: 351f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ConvertAndFillData<uint64_t>(dist_item.pos, distance); 352f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) default: 353f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) assert(false); 354f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 355f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 356f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 357f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 358f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool ValidationTestInputParser::ParseHandles(const DataType& type, 359f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& value_string) { 360f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // It should be the first item. 361f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!data_->empty()) 362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 363f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 364f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) unsigned long long int value; 365f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!ConvertToUnsignedInteger(value_string, &value)) 366f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 367f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 368f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (value > std::numeric_limits<size_t>::max()) 369f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 370f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 371f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *num_handles_ = static_cast<size_t>(value); 372f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 373f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 374f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 375f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool ValidationTestInputParser::StartsWith(const Range& range, 376f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char* prefix, 377f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t prefix_length) { 378f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (static_cast<size_t>(range.second - range.first) < prefix_length) 379f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 380f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 381f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return memcmp(range.first, prefix, prefix_length) == 0; 382f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 383f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 384f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool ValidationTestInputParser::ConvertToUnsignedInteger( 385f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& value_string, 386f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) unsigned long long int* value) { 387f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char* format = NULL; 388f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (value_string.find_first_of("xX") != std::string::npos) 389f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) format = "%llx"; 390f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) else 391f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) format = "%llu"; 392f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return sscanf(value_string.c_str(), format, value) == 1; 393f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 394f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 395f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} // namespace 396f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 397f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool ParseValidationTestInput(const std::string& input, 398f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<uint8_t>* data, 399f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t* num_handles, 400f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::string* error_message) { 401f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ValidationTestInputParser parser(input, data, num_handles, error_message); 402f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return parser.Run(); 403f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 404f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 405f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} // namespace test 406f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} // namespace mojo 407