Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <ios_base.h>
     30 #include <cstdio>
     31 #include <new>  // for placement new.
     32 #include <iostream>  // For cout, cerr
     33 #include <ostream>
     34 #include <stdio_filebuf.h>
     35 #include <streambuf>
     36 
     37 // Defined in bionic/libstdc++/src/one_time_construction.cpp
     38 extern "C" int __cxa_guard_acquire(int volatile * gv);
     39 extern "C" void __cxa_guard_release(int volatile * gv);
     40 
     41 namespace std {
     42 int ios_base::Init::sGuard = 0;
     43 bool ios_base::Init::sDone = false;
     44 
     45 // Implementation of the ios_base, common stuff for all the streams.
     46 
     47 ios_base::ios_base()
     48     : mFlags(skipws | dec), mPrecision(6), mWidth(0) {}
     49 
     50 ios_base::~ios_base() {}
     51 
     52 ios_base::fmtflags ios_base::flags(fmtflags flags) {
     53     fmtflags prev = mFlags;
     54     mFlags = flags;
     55     return prev;
     56 }
     57 
     58 ios_base::fmtflags ios_base::setf(fmtflags flags) {
     59     fmtflags prev = mFlags;
     60     mFlags = flags;
     61     return prev;
     62 }
     63 
     64 ios_base::fmtflags ios_base::setf(fmtflags flags, fmtflags mask) {
     65     fmtflags prev = mFlags;
     66     mFlags &= ~mask;
     67     mFlags |= (flags & mask);
     68     return prev;
     69 }
     70 
     71 void ios_base::unsetf(fmtflags mask) {
     72     mFlags &= ~mask;
     73 }
     74 
     75 streamsize ios_base::precision(streamsize precision) {
     76     const streamsize prev = mPrecision;
     77     if (precision >= 0) {  // Not sure what a negative precision would mean.
     78         mPrecision = precision;
     79     }
     80     return prev;
     81 }
     82 
     83 streamsize ios_base::width(streamsize width) {
     84     const streamsize prev = mWidth;
     85     if (width >= 0) {  // Not sure what a negative width would mean.
     86         mWidth = width;
     87     }
     88     return prev;
     89 }
     90 
     91 // TODO: This is a temporary class used to illustrate how the
     92 // construction will happen.
     93 
     94 class std_filebuf: public streambuf {
     95   public:
     96     std_filebuf() {}
     97     virtual ~std_filebuf() {}
     98 };
     99 
    100 // Storage is declared in src/ios_globals.cpp
    101 extern android::stdio_filebuf stdio_filebuf_cout;
    102 extern android::stdio_filebuf stdio_filebuf_cerr;
    103 
    104 ios_base::Init::Init() {
    105     if (__cxa_guard_acquire(&sGuard) == 1) {
    106         if (!sDone) {
    107             // Create the global cout and cerr
    108             // structures. stdio_filebuf_cout/stdio_filebuf_cerr and
    109             // cout/cerr storage are in ios_globals.cpp.
    110             new (&stdio_filebuf_cout) android::stdio_filebuf(stdout);
    111             new (&stdio_filebuf_cerr) android::stdio_filebuf(stderr);
    112             new (&cout) ostream(&stdio_filebuf_cout);
    113             new (&cerr) ostream(&stdio_filebuf_cerr);
    114             sDone = true;
    115         }
    116         __cxa_guard_release(&sGuard);
    117     }
    118 }
    119 
    120 ios_base::Init::~Init() {
    121     cout.flush();
    122     cerr.flush();
    123 }
    124 
    125 }  // namespace std
    126