diff options
Diffstat (limited to 'src/tools/launcher/util/data_parser.cc')
-rw-r--r-- | src/tools/launcher/util/data_parser.cc | 105 |
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 |