1/* 2 * Copyright (C) 2015, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "code_writer.h" 18 19#include <iostream> 20#include <stdarg.h> 21 22#include <android-base/stringprintf.h> 23 24using std::cerr; 25using std::endl; 26 27namespace android { 28namespace aidl { 29 30namespace { 31 32class StringCodeWriter : public CodeWriter { 33 public: 34 StringCodeWriter(std::string* output_buffer) : output_(output_buffer) {} 35 virtual ~StringCodeWriter() = default; 36 37 bool Write(const char* format, ...) override { 38 va_list ap; 39 va_start(ap, format); 40 android::base::StringAppendV(output_, format, ap); 41 va_end(ap); 42 return true; 43 } 44 45 bool Close() override { return true; } 46 47 private: 48 std::string* output_; 49}; // class StringCodeWriter 50 51class FileCodeWriter : public CodeWriter { 52 public: 53 FileCodeWriter(FILE* output_file, bool close_on_destruction) 54 : output_(output_file), 55 close_on_destruction_(close_on_destruction) {} 56 virtual ~FileCodeWriter() { 57 if (close_on_destruction_ && output_ != nullptr) { 58 fclose(output_); 59 } 60 } 61 62 bool Write(const char* format, ...) override { 63 bool success; 64 va_list ap; 65 va_start(ap, format); 66 success = vfprintf(output_, format, ap) >= 0; 67 va_end(ap); 68 no_error_ = no_error_ && success; 69 return success; 70 } 71 72 bool Close() override { 73 if (output_ != nullptr) { 74 no_error_ = fclose(output_) == 0 && no_error_; 75 output_ = nullptr; 76 } 77 return no_error_; 78 } 79 80 private: 81 bool no_error_ = true; 82 FILE* output_; 83 bool close_on_destruction_; 84}; // class StringCodeWriter 85 86} // namespace 87 88CodeWriterPtr GetFileWriter(const std::string& output_file) { 89 CodeWriterPtr result; 90 FILE* to = nullptr; 91 bool close_on_destruction = true; 92 if (output_file == "-") { 93 to = stdout; 94 close_on_destruction = false; 95 } else { 96 // open file in binary mode to ensure that the tool produces the 97 // same output on all platforms !! 98 to = fopen(output_file.c_str(), "wb"); 99 } 100 101 if (to != nullptr) { 102 result.reset(new FileCodeWriter(to, close_on_destruction)); 103 } else { 104 cerr << "unable to open " << output_file << " for write" << endl; 105 } 106 107 return result; 108} 109 110CodeWriterPtr GetStringWriter(std::string* output_buffer) { 111 return CodeWriterPtr(new StringCodeWriter(output_buffer)); 112} 113 114} // namespace aidl 115} // namespace android 116