// 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 #include #include #include #include "src/main/cpp/util/strings.h" #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; using std::wstring; int64_t LaunchDataParser::ReadDataSize(ifstream* binary) { int64_t data_size; binary->seekg(0 - sizeof(data_size), ios::end); binary->read(reinterpret_cast(&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(L"Cannot find equal symbol in line: %hs", string(launch_data + start, end - start).c_str()); return false; } else if (start == equal) { PrintError(L"Key is empty string in line: %hs", 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(L"Duplicated launch info key: %hs", key.c_str()); return false; } launch_info->insert(make_pair(key, blaze_util::CstringToWstring(value))); } start = end + 1; } return true; } bool LaunchDataParser::GetLaunchInfo(const wstring& binary_path, LaunchInfo* launch_info) { unique_ptr binary = make_unique(binary_path, ios::binary | ios::in); int64_t data_size = ReadDataSize(binary.get()); if (data_size == 0) { PrintError(L"No data appended, cannot launch anything!"); return false; } unique_ptr 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