Home | History | Annotate | Download | only in incident_report
      1 /*
      2  * Copyright (C) 2016 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 "printer.h"
     18 
     19 #include <unistd.h>
     20 #include <stdlib.h>
     21 #include <string.h>
     22 #include <stdarg.h>
     23 
     24 #define INITIAL_BUF_SIZE (16*1024)
     25 
     26 char const* SPACES = "                                                            ";
     27 const int SPACE_COUNT = strlen(SPACES);
     28 
     29 Out::Out(int fd)
     30     :mOut(fd == STDOUT_FILENO ? stdout : fdopen(fd, "w")),
     31      mBufSize(INITIAL_BUF_SIZE),
     32      mBuf((char*)malloc(INITIAL_BUF_SIZE)),
     33      mIndent(0),
     34      mPendingIndent(false)
     35 {
     36 }
     37 
     38 Out::~Out()
     39 {
     40     fclose(mOut);
     41 }
     42 
     43 int
     44 Out::reallocate(int size)
     45 {
     46     if (size > mBufSize) {
     47         char* p = (char*)malloc(size);
     48         if (p != NULL) {
     49             free(mBuf);
     50             mBufSize = size;
     51             mBuf = p;
     52             return size;
     53         }
     54     }
     55     return mBufSize;
     56 }
     57 
     58 void
     59 Out::printf(const char* format, ...)
     60 {
     61     if (mPendingIndent) {
     62         print_indent();
     63         mPendingIndent = false;
     64     }
     65 
     66     int len;
     67 
     68     va_list args;
     69     va_start(args, format);
     70 
     71     len = vsnprintf(mBuf, mBufSize, format, args);
     72     va_end(args);
     73 
     74     va_start(args, format);
     75     len = vsnprintf(mBuf, mBufSize, format, args);
     76     va_end(args);
     77 
     78     if (len > 0) {
     79         if (mIndent == 0) {
     80             fwrite(mBuf, len, 1, mOut);
     81         } else {
     82             char* last = mBuf;
     83             char* p;
     84             do {
     85                 p = strchr(last, '\n');
     86                 int size = p != NULL ? p - last + 1 : strlen(last);
     87                 fwrite(last, size, 1, mOut);
     88                 if (p != NULL) {
     89                     if (p[1] == '\0') {
     90                         mPendingIndent = true;
     91                     } else {
     92                         print_indent();
     93                     }
     94                 }
     95                 last = p+1;
     96             } while (p != NULL);
     97         }
     98     }
     99 }
    100 
    101 void
    102 Out::indent()
    103 {
    104     mPendingIndent = true;
    105     mIndent += 2;
    106 }
    107 
    108 void
    109 Out::dedent()
    110 {
    111     if (mIndent > 0) {
    112         mIndent -= 2;
    113     }
    114 }
    115 
    116 void
    117 Out::print_indent()
    118 {
    119 #if 0
    120     fprintf(mOut, "[%d]", mIndent);
    121 #else
    122     int indent = mIndent;
    123     while (indent > SPACE_COUNT) {
    124         fwrite(SPACES, SPACE_COUNT, 1, mOut);
    125         indent -= SPACE_COUNT;
    126     }
    127     fwrite(SPACES + SPACE_COUNT - indent, indent, 1, mOut);
    128 #endif
    129 }
    130