aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools/launcher/util/data_parser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/launcher/util/data_parser.cc')
-rw-r--r--src/tools/launcher/util/data_parser.cc105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/tools/launcher/util/data_parser.cc b/src/tools/launcher/util/data_parser.cc
new file mode 100644
index 0000000000..98c8b1daf6
--- /dev/null
+++ b/src/tools/launcher/util/data_parser.cc
@@ -0,0 +1,105 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// 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 <fstream>
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "src/tools/launcher/util/data_parser.h"
+#include "src/tools/launcher/util/launcher_util.h"
+
+namespace bazel {
+namespace launcher {
+
+using std::ifstream;
+using std::ios;
+using std::make_unique;
+using std::string;
+using std::unique_ptr;
+
+int64_t LaunchDataParser::ReadDataSize(ifstream* binary) {
+ int64_t data_size;
+ binary->seekg(0 - sizeof(data_size), ios::end);
+ binary->read(reinterpret_cast<char*>(&data_size), sizeof(data_size));
+ return data_size;
+}
+
+void LaunchDataParser::ReadLaunchData(ifstream* binary, char* launch_data,
+ int64_t data_size) {
+ binary->seekg(0 - data_size - sizeof(data_size), ios::end);
+ binary->read(launch_data, data_size);
+}
+
+bool LaunchDataParser::ParseLaunchData(LaunchInfo* launch_info,
+ const char* launch_data,
+ int64_t data_size) {
+ int64_t start, end, equal;
+ start = 0;
+ while (start < data_size) {
+ // Move start to point to the next non-null character.
+ while (launch_data[start] == '\0' && start < data_size) {
+ start++;
+ }
+ // Move end to the next null character or end of the string,
+ // also find the first equal symbol appears.
+ end = start;
+ equal = -1;
+ while (launch_data[end] != '\0' && end < data_size) {
+ if (equal == -1 && launch_data[end] == '=') {
+ equal = end;
+ }
+ end++;
+ }
+ if (equal == -1) {
+ PrintError("Cannot find equal symbol in line: %s",
+ string(launch_data + start, end - start).c_str());
+ return false;
+ } else if (start == equal) {
+ PrintError("Key is empty string in line: %s",
+ string(launch_data + start, end - start).c_str());
+ return false;
+ } else {
+ string key(launch_data + start, equal - start);
+ string value(launch_data + equal + 1, end - equal - 1);
+ if (launch_info->find(key) != launch_info->end()) {
+ PrintError("Duplicated launch info key: %s", key.c_str());
+ return false;
+ }
+ launch_info->insert(make_pair(key, value));
+ }
+ start = end + 1;
+ }
+ return true;
+}
+
+bool LaunchDataParser::GetLaunchInfo(const string& binary_path,
+ LaunchInfo* launch_info) {
+ unique_ptr<ifstream> binary =
+ make_unique<ifstream>(binary_path, ios::binary | ios::in);
+ int64_t data_size = ReadDataSize(binary.get());
+ if (data_size == 0) {
+ PrintError("No data appended, cannot launch anything!");
+ return false;
+ }
+ unique_ptr<char[]> launch_data(new char[data_size]);
+ ReadLaunchData(binary.get(), launch_data.get(), data_size);
+ if (!ParseLaunchData(launch_info, launch_data.get(), data_size)) {
+ return false;
+ }
+ return true;
+}
+
+} // namespace launcher
+} // namespace bazel