Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(963)

Side by Side Diff: experimental/webgtt/parser.cc

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « experimental/webgtt/parser.h ('k') | experimental/webgtt/taskmap.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Native Client Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be found
3 // in the LICENSE file.
4
5 #include "webgtt/parser.h"
6
7 #include <boost/bind.hpp>
8
9 #include <cassert>
10 #include <cctype>
11 #include <cmath>
12 #include <cstdlib>
13 #include <cstring>
14 #include <string>
15 #include <vector>
16
17 #include "webgtt/graph.h"
18 #include "webgtt/taskmap.h"
19
20 /// The sentinel/delimiter string that is used in the message format.
21 const char kSentinel[] = "::";
22
23 namespace webgtt {
24
25 Parser::Parser(const std::string& message)
26 : message_(message),
27 is_valid_(false),
28 task_ID_(kInvalidValue) {}
29
30 /// This function decodes the message. A valid message is of the form:
31 /// "kSentinel<adjacency_matrix_>kSentinel<task_ID_>kSentinel<args_>kSentinel"
32 /// If at any stage during the decoding process, the message is found to be
33 /// invalid (not conforming to the above format), parsing is aborted, and the
34 /// is_valid_ bit contains false. Upon successful completion of the decoding
35 /// process, the is_valid_ bit is set to true.
36 bool Parser::DecodeMessage() {
37 assert(!is_valid_);
38
39 const size_t message_length = message_.size();
40 // We start parsing from the beginning of the message.
41 int parse_position = 0;
42
43 // The shortest valid message is for a coloring request on a graph with
44 // exactly one vertex, which would look like:
45 // "<kSentinel>0<kSentinel>0<kSentinel>"
46 if (message_length < 2 + (3 * strlen(kSentinel))) {
47 return false;
48 }
49 // Look for the first sentinel.
50 if (message_.substr(0, strlen(kSentinel)).compare(kSentinel) != 0) {
51 return false;
52 }
53 // Skip over the sentinel that we just found, and continue parsing.
54 parse_position += strlen(kSentinel);
55
56 std::string adjacency_matrix = GetNextChunk(message_, &parse_position);
57 if (adjacency_matrix.compare(kSentinel) == 0) {
58 return false;
59 }
60 // adjacency_matrix should be in CSV format; obtain the positions of commas.
61 std::vector<int> comma_positions = GetCommaPositions(adjacency_matrix);
62 // There should be a total of (number_of_vertices)^2 - 1 commas, since
63 // adjacency_matrix is a square matrix.
64 int number_of_vertices = sqrt(comma_positions.size() + 1);
65 if (static_cast<int>(comma_positions.size()) !=
66 (number_of_vertices * number_of_vertices) - 1) {
67 return false;
68 }
69 // Decode the adjacency matrix
70 int adj_position = 0;
71 for (int i = 1; i <= number_of_vertices; ++i) {
72 int next_comma_position;
73 // There is no comma at the end
74 if (i == number_of_vertices) {
75 next_comma_position = adjacency_matrix.size();
76 } else {
77 next_comma_position = comma_positions[(i * number_of_vertices) - 1];
78 }
79
80 std::vector<int> row = DecodeCSV(adjacency_matrix.substr(adj_position,
81 next_comma_position - adj_position));
82 for (size_t j = 0; j < row.size(); ++j) {
83 if (row[j] == kInvalidValue) {
84 return false;
85 }
86 }
87 adjacency_matrix_.push_back(row);
88 adj_position = next_comma_position + 1;
89 }
90 comma_positions.clear();
91 // Construct the graph
92 graph::Graph input_graph(number_of_vertices, adjacency_matrix_);
93
94 std::string task_ID = GetNextChunk(message_, &parse_position);
95 if (task_ID.compare(kSentinel) == 0) {
96 return false;
97 }
98 if (StringToInteger(task_ID) == kInvalidValue) {
99 return false;
100 }
101 task_ID_ = StringToInteger(task_ID);
102
103 std::string args = "";
104 if (parse_position != static_cast<int>(message_length)) {
105 // There may be some arguments.
106 args = GetNextChunk(message_, &parse_position);
107 if (args.compare(kSentinel) == 0) {
108 return false;
109 }
110 }
111 if (!args.empty()) {
112 // args should be in CSV format; decode it.
113 args_ = DecodeCSV(args);
114 for (size_t i = 0; i < args_.size(); ++i) {
115 if (args_[i] == kInvalidValue) {
116 return false;
117 }
118 }
119 }
120 int number_of_arguments = static_cast<int>(args_.size());
121 // Append enough dummy elements (zeros) to the end of args_, if necessary.
122 if (number_of_arguments < kMaxArgs) {
123 args_.insert(args_.end(), kMaxArgs - number_of_arguments, 0);
124 }
125
126 // Obtain the task_map_ lookup.
127 TaskMap task_map_object(input_graph, args_);
128 task_map_ = task_map_object.task_map();
129
130 // Perform final validation checks.
131 if (task_ID_ >= static_cast<int>(task_map_.size())) {
132 return false;
133 }
134 if (number_of_arguments != task_map_[task_ID_].number_of_arguments) {
135 return false;
136 }
137
138 is_valid_ = true;
139 return true;
140 }
141
142 std::string Parser::GetResponse() const {
143 assert(is_valid_);
144 return task_map_[task_ID_].function_to_call();
145 }
146
147 std::vector<int> DecodeCSV(const std::string& message) {
148 std::vector<int> answer;
149 std::vector<int> comma_positions = GetCommaPositions(message);
150 int parse_position = 0;
151 for (size_t i = 0; i < comma_positions.size() + 1; ++i) {
152 int next_comma_position;
153 // There is no comma at the end of the list.
154 if (i == comma_positions.size()) {
155 next_comma_position = message.size();
156 } else {
157 next_comma_position = comma_positions[i];
158 }
159 std::string entry = message.substr(parse_position,
160 next_comma_position - parse_position);
161 answer.push_back(StringToInteger(entry));
162 parse_position = next_comma_position + 1;
163 }
164 return answer;
165 }
166
167 std::string GetNextChunk(const std::string& message, int* parse_position) {
168 assert(*parse_position < static_cast<int>(message.size()));
169 unsigned int next_sentinel_position = message.find(kSentinel,
170 *parse_position);
171 if (next_sentinel_position == std::string::npos) {
172 std::string ret_val(kSentinel);
173 return ret_val; // Return the sentinel string itself indicating error.
174 }
175 std::string next_chunk = message.substr(*parse_position,
176 next_sentinel_position - *parse_position);
177 // Update the position to continue parsing from (skip over the sentinel).
178 *parse_position = next_sentinel_position + strlen(kSentinel);
179 return next_chunk;
180 }
181
182 std::vector<int> GetCommaPositions(const std::string& message) {
183 std::vector<int> comma_positions;
184 for (std::string temp = message; temp.find(',') != std::string::npos;
185 temp.replace(temp.find(','), 1, 1, '.')) {
186 comma_positions.push_back(temp.find(','));
187 }
188 return comma_positions;
189 }
190
191 int StringToInteger(const std::string& message) {
192 if (message.empty()) {
193 return kInvalidValue;
194 }
195 if (!isdigit(message[0])) {
196 return kInvalidValue;
197 }
198 return atoi(message.c_str());
199 }
200
201 } // namespace webgtt
OLDNEW
« no previous file with comments | « experimental/webgtt/parser.h ('k') | experimental/webgtt/taskmap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698