Home | History | Annotate | Download | only in aidl
      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 
     24 using std::cerr;
     25 using std::endl;
     26 
     27 namespace android {
     28 namespace aidl {
     29 
     30 namespace {
     31 
     32 class StringCodeWriter : public CodeWriter {
     33  public:
     34   explicit 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 
     51 class 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 
     88 CodeWriterPtr 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 
    110 CodeWriterPtr GetStringWriter(std::string* output_buffer) {
    111   return CodeWriterPtr(new StringCodeWriter(output_buffer));
    112 }
    113 
    114 }  // namespace aidl
    115 }  // namespace android
    116