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 <ostream>
30#include <streambuf>
31#include <cstring>
32#include <limits>
33
34namespace std {
35// Defined in bionic/libstdc++/src/one_time_construction.cpp
36
37ostream::ostream() { }
38
39ostream::~ostream() { }
40
41ostream& ostream::operator<<(const char_type *str) {
42    if (this->rdbuf() && str) {
43        this->rdbuf()->sputn(str, strlen(str));
44    }
45    return *this;
46}
47
48ostream& ostream::operator<<(char_type c) {
49    // TODO: Should format according to flags.
50    return put(c);
51}
52
53ostream& ostream::operator<<(bool val) {
54    // TODO: Should format according to flags (e.g write "true" or "false").
55    return put(val?'1':'0');
56}
57
58// 64 bits int in octal is 22 digits. There is one for the sign and 2
59// for the format specifier + 1 for the terminating \0. A total of 26
60// chars should be enough to hold any integer representation.
61static const size_t kNumSize = 26;
62ostream& ostream::operator<<(int val) {
63    const char *fmt = "%d";
64    char buf[kNumSize];
65    int size = snprintf(buf, kNumSize, fmt, val);
66    return write(buf, size);
67}
68
69ostream& ostream::operator<<(unsigned int val) {
70    const char *fmt = "%u";
71    char buf[kNumSize];
72    int size = snprintf(buf, kNumSize, fmt, val);
73    return write(buf, size);
74}
75
76ostream& ostream::operator<<(long int val) {
77    const char *fmt = "%ld";
78    char buf[kNumSize];
79    int size = snprintf(buf, kNumSize, fmt, val);
80    return write(buf, size);
81}
82
83ostream& ostream::operator<<(unsigned long int val) {
84    const char *fmt = "%lu";
85    char buf[kNumSize];
86    int size = snprintf(buf, kNumSize, fmt, val);
87    return write(buf, size);
88}
89
90ostream& ostream::operator<<(long long int val) {
91    const char *fmt = "%lld";
92    char buf[kNumSize];
93    int size = snprintf(buf, kNumSize, fmt, val);
94    return write(buf, size);
95}
96
97ostream& ostream::operator<<(unsigned long long int val) {
98    const char *fmt = "%llu";
99    char buf[kNumSize];
100    int size = snprintf(buf, kNumSize, fmt, val);
101    return write(buf, size);
102}
103
104// Double max 1.7976931348623157E+308 = 23 < kNumSize so we reuse it.
105ostream& ostream::operator<<(double val) {
106    const char *fmt = "%.*e";
107    char buf[kNumSize];
108    int size = snprintf(buf, kNumSize, fmt, precision(), val);
109    return write(buf, size);
110}
111
112ostream& ostream::operator<<(float val) {
113    const char *fmt = "%.*e";
114    char buf[kNumSize];
115    int size = snprintf(buf, kNumSize, fmt, precision(), val);
116    return write(buf, size);
117}
118
119ostream& ostream::operator<<(const void *p) {
120    const char *fmt = "%p";
121    char buf[kNumSize];
122    int size = snprintf(buf, kNumSize, fmt, p);
123    return write(buf, size);
124}
125
126ostream& ostream::write_formatted(const char_type *str, streamsize num) {
127    // TODO: Should format the string according to the flags.
128    return write(str, num);
129}
130
131ostream& ostream::put(char_type c) {
132    if (this->rdbuf()) {
133        this->rdbuf()->sputn(&c, 1);
134    }
135    return *this;
136}
137
138ostream& ostream::write(const char_type *str, streamsize num) {
139    if (this->rdbuf()) {
140        this->rdbuf()->sputn(str, num);
141    }
142    return *this;
143}
144
145ostream& ostream::flush() {
146    if (this->rdbuf()) {
147        // TODO: if pubsync returns -1 should mark this stream as
148        // 'bad'.
149        this->rdbuf()->pubsync();
150    }
151    return *this;
152}
153
154}  // namespace std
155