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