Files
commandergenius/project/jni/stlport/src/iostream.cpp
T
2010-12-21 14:41:51 +00:00

539 lines
15 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Copyright (c) 1999
* Silicon Graphics Computer Systems, Inc.
*
* Copyright (c) 1999
* Boris Fomitchev
*
* This material is provided "as is", with absolutely no warranty expressed
* or implied. Any use is at your own risk.
*
* Permission to use or copy this software for any purpose is hereby granted
* without fee, provided the above notices are retained on all copies.
* Permission to modify the code and to distribute modified code is granted,
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*
*/
#include "stlport_prefix.h"
#include <istream>
#include <fstream>
#if defined (_STLP_MSVC) || defined (__MWERKS__) || defined (__ICL) || defined (__ISCPP__)
# define _STLP_USE_NOT_INIT_SEGMENT
# include <iostream>
#endif
#include "stdio_streambuf.h"
#include "aligned_buffer.h"
#include "_stdio_file.h"
#include "c_locale.h"
// boris : note this is repeated in <iostream>
#ifndef _STLP_USE_NAMESPACES
// in case of SGI iostreams, we have to rename our streams not to clash with those
// provided in native lib
# define cin _STLP_cin
# define cout _STLP_cout
# define cerr _STLP_cerr
# define clog _STLP_clog
#endif
_STLP_BEGIN_NAMESPACE
#if defined (__BORLANDC__) && ! defined (_STLP_USE_GLIBC)
using _STLP_VENDOR_CSTD::_streams;
#endif
// This file handles iostream initialization. It is inherently
// nonportable, since the C++ language definition provides no mechanism
// for controlling order of initialization of nonlocal objects.
// Initialization has three parts, which must be performed in the following
// order:
// (1) Initialize the locale system
// (2) Call the constructors for the eight global stream objects.
// (3) Create streambufs for the global stream objects, and initialize
// the stream objects by calling the init() member function.
#if defined (ANDROID_NO_COUT)
#include <android/log.h>
/* Outputting anything to cout/cerr WILL CRASH YOUR PROGRAM on specific devices -
x5a/x6d Android 2.1 tablet, and some other tablets,
however the same code runs on my HTC Evo without problem.
So I've just disabled cin/cout/cerr altogether.
*/
long ios_base::Init::_S_count = 0;
// by default, those are synced
bool ios_base::_S_was_synced = true;
ios_base::Init::Init() {
if (_S_count++ == 0) {
_Locale_init();
//ios_base::_S_initialize();
_Filebuf_base::_S_initialize();
}
}
ios_base::Init::~Init() {
if (--_S_count == 0) {
//ios_base::_S_uninitialize();
_Locale_final();
}
}
class _android_debugbuf: public streambuf
{
public:
_android_debugbuf()
{
pos = 0;
buf[0] = 0;
}
protected:
virtual int overflow(int c = EOF)
{
if (EOF == c)
{
return '\0'; // returning EOF indicates an error
}
else
{
outputchar(c);
return c;
}
};
// we dont do input so always return EOF
virtual int uflow() {return EOF;}
// we dont do input so always return 0 chars read
virtual int xsgetn(char *, int) {return 0;}
// Calls outputchar() for each character.
virtual int xsputn(const char *s, int n)
{
for (int i = 0; i < n; ++i)
{
outputchar(s[i]);
}
return n;// we always process all of the chars
};
private:
// the buffer
char buf[256];
int pos;
void outputchar(char c)
{
// TODO: mutex
if( pos >= sizeof(buf)-1 || c == '\n' || c == '\r' || c == 0 )
{
buf[pos] = 0;
__android_log_print(ANDROID_LOG_INFO, "libSDL", "%s", buf);
pos = 0;
buf[pos] = 0;
return;
};
buf[pos] = c;
pos++;
};
};
class debugbufinit
{
static unsigned int count;
public:
debugbufinit();
// Our destructor is not virtual. It is important that objects of this class have no
// memory footprint. We will end up with one object of this class per translation
// unit (.cp file). If this class has any virtual member functions then objects of
// this class would have v tables in memory. Since this is not intended to be a
// base class for other class, there is no need to be virtual.
~debugbufinit();
};
static filebuf*
_Stl_create_filebuf(int f, ios_base::openmode mode ) {
basic_filebuf<char, char_traits<char> >* result =
new basic_filebuf<char, char_traits<char> >();
_STLP_TRY {
result->_M_open(f, mode);
}
_STLP_CATCH_ALL {}
if (!result->is_open()) {
delete result;
result = 0;
}
return result;
}
static ios_base::Init _IosInit;
bool _STLP_CALL ios_base::sync_with_stdio(bool sync)
{
}
_STLP_DECLSPEC istream cin(_Stl_create_filebuf(0, ios_base::in));
_STLP_DECLSPEC ostream cout(new _android_debugbuf());
_STLP_DECLSPEC ostream cerr(new _android_debugbuf());
_STLP_DECLSPEC ostream clog(new _android_debugbuf());
#else
#if defined (_STLP_USE_NOT_INIT_SEGMENT)
// Definitions of the eight global I/O objects that are declared in
// <iostream>. For some compilers we use pragmas to put the global I/O
// objects into an initialization segment that will not
// be executed. We then explicitly invoke the constructors
// with placement new in ios_base::_S_initialize()
# if defined (__MWERKS__)
# pragma suppress_init_code on
# else
# pragma init_seg("STLPORT_NO_INIT")
# endif
_STLP_DECLSPEC istream cin(0);
# ifdef _STLP_REDIRECT_STDSTREAMS
_STLP_DECLSPEC ofstream cout;
_STLP_DECLSPEC ofstream cerr;
_STLP_DECLSPEC ofstream clog;
# else
_STLP_DECLSPEC ostream cout(0);
_STLP_DECLSPEC ostream cerr(0);
_STLP_DECLSPEC ostream clog(0);
# endif
# ifndef _STLP_NO_WCHAR_T
_STLP_DECLSPEC wistream wcin(0);
_STLP_DECLSPEC wostream wcout(0);
_STLP_DECLSPEC wostream wcerr(0);
_STLP_DECLSPEC wostream wclog(0);
# endif
# if defined (__MWERKS__)
# pragma suppress_init_code off
# endif
#else
// Definitions of the eight global I/O objects that are declared in
// <iostream>. Disgusting hack: we deliberately define them with the
// wrong types so that the constructors don't get run automatically.
// We need special tricks to make sure that these objects are struct-
// aligned rather than byte-aligned.
// This is not portable. Declaring a variable with different types in
// two translations units is "undefined", according to the C++ standard.
// Most compilers, however, silently accept this instead of diagnosing
// it as an error.
# ifndef __DMC__
_STLP_DECLSPEC _Stl_aligned_buffer<istream> cin;
_STLP_DECLSPEC _Stl_aligned_buffer<ostream> cout;
_STLP_DECLSPEC _Stl_aligned_buffer<ostream> cerr;
_STLP_DECLSPEC _Stl_aligned_buffer<ostream> clog;
# else
_Stl_aligned_buffer<istream> cin;
_Stl_aligned_buffer<ostream> cout;
_Stl_aligned_buffer<ostream> cerr;
_Stl_aligned_buffer<ostream> clog;
# pragma alias("?cin@std@@3V?$basic_istream@std@DV?$char_traits@std@D@1@@1@A", "?cin@std@@3T?$_Stl_aligned_buffer@std@V?$basic_istream@std@DV?$char_traits@std@D@1@@1@@1@A")
# pragma alias("?cout@std@@3V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@A", "?cout@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@@1@A")
# pragma alias("?cerr@std@@3V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@A", "?cerr@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@@1@A")
# pragma alias("?clog@std@@3V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@A", "?clog@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@@1@A")
# endif
# ifndef _STLP_NO_WCHAR_T
# ifndef __DMC__
_STLP_DECLSPEC _Stl_aligned_buffer<wistream> wcin;
_STLP_DECLSPEC _Stl_aligned_buffer<wostream> wcout;
_STLP_DECLSPEC _Stl_aligned_buffer<wostream> wcerr;
_STLP_DECLSPEC _Stl_aligned_buffer<wostream> wclog;
# else
_Stl_aligned_buffer<wistream> wcin;
_Stl_aligned_buffer<wostream> wcout;
_Stl_aligned_buffer<wostream> wcerr;
_Stl_aligned_buffer<wostream> wclog;
# pragma alias("?wcin@std@@3V?$basic_istream@std@_YV?$char_traits@std@_Y@1@@1@A", "?wcin@std@@3T?$_Stl_aligned_buffer@std@V?$basic_istream@std@_YV?$char_traits@std@_Y@1@@1@@1@A")
# pragma alias("?wcout@std@@3V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@A", "?wcout@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@@1@A")
# pragma alias("?wcerr@std@@3V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@A", "?wcerr@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@@1@A")
# pragma alias("?wclog@std@@3V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@A", "?wclog@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@@1@A")
# endif
# endif
#endif /* STL_MSVC || __MWERKS__ */
// Member functions from class ios_base and ios_base::Init
long ios_base::Init::_S_count = 0;
// by default, those are synced
bool ios_base::_S_was_synced = true;
ios_base::Init::Init() {
if (_S_count++ == 0) {
_Locale_init();
ios_base::_S_initialize();
_Filebuf_base::_S_initialize();
}
}
ios_base::Init::~Init() {
if (--_S_count == 0) {
ios_base::_S_uninitialize();
_Locale_final();
}
}
static filebuf*
_Stl_create_filebuf(FILE* f, ios_base::openmode mode ) {
basic_filebuf<char, char_traits<char> >* result =
new basic_filebuf<char, char_traits<char> >();
_STLP_TRY {
result->_M_open(_FILE_fd(f), mode);
}
_STLP_CATCH_ALL {}
if (!result->is_open()) {
delete result;
result = 0;
}
return result;
}
#if !defined (_STLP_NO_WCHAR_T)
static wfilebuf*
_Stl_create_wfilebuf(FILE* f, ios_base::openmode mode) {
basic_filebuf<wchar_t, char_traits<wchar_t> >* result =
new basic_filebuf<wchar_t, char_traits<wchar_t> >();
_STLP_TRY {
result->_M_open(_FILE_fd(f), mode);
}
_STLP_CATCH_ALL {}
if (!result->is_open()) {
delete result;
result = 0;
}
return result;
}
#endif
void _STLP_CALL ios_base::_S_initialize() {
#if !defined (_STLP_HAS_NO_NAMESPACES) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE)
using _STLP_PRIV stdio_istreambuf;
using _STLP_PRIV stdio_ostreambuf;
#endif
_STLP_TRY {
istream* ptr_cin = new(static_cast<void*>(&cin)) istream(0);
# ifdef _STLP_REDIRECT_STDSTREAMS
ofstream* ptr_cout = new(static_cast<void*>(&cout)) ofstream;
ofstream* ptr_cerr = new(static_cast<void*>(&cerr)) ofstream;
ofstream* ptr_clog = new(static_cast<void*>(&clog)) ofstream;
// Initialize the four narrow stream objects.
if (_S_was_synced) {
ptr_cin->init(new stdio_istreambuf(stdin));
ptr_cout->open("/stdout.txt", ios::out);
ptr_cerr->open("/stderr.txt", ios::out);
ptr_clog->open("/stdlog.txt", ios::out);
} else {
ptr_cin->init(_Stl_create_filebuf(stdin, ios_base::in));
ptr_cin->init(_Stl_create_filebuf(stdout, ios_base::out));
ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
}
ptr_cin->tie(ptr_cout);
ptr_cerr->setf(ios_base::unitbuf);
# else
ostream* ptr_cout = new(static_cast<void*>(&cout)) ostream(0);
ostream* ptr_cerr = new(static_cast<void*>(&cerr)) ostream(0);
ostream* ptr_clog = new(static_cast<void*>(&clog)) ostream(0);
// Initialize the four narrow stream objects.
if (_S_was_synced) {
ptr_cin->init(new stdio_istreambuf(stdin));
ptr_cout->init(new stdio_ostreambuf(stdout));
ptr_cerr->init(new stdio_ostreambuf(stderr));
ptr_clog->init(new stdio_ostreambuf(stderr));
} else {
ptr_cin->init(_Stl_create_filebuf(stdin, ios_base::in));
ptr_cin->init(_Stl_create_filebuf(stdout, ios_base::out));
ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
}
ptr_cin->tie(ptr_cout);
ptr_cerr->setf(ios_base::unitbuf);
# endif /* _STLP_REDIRECT_STDSTREAMS */
# ifndef _STLP_NO_WCHAR_T
// Run constructors for the four wide stream objects.
wistream* ptr_wcin = new(&wcin) wistream(0);
wostream* ptr_wcout = new(&wcout) wostream(0);
wostream* ptr_wcerr = new(&wcerr) wostream(0);
wostream* ptr_wclog = new(&wclog) wostream(0);
wfilebuf* win = _Stl_create_wfilebuf(stdin, ios_base::in);
wfilebuf* wout = _Stl_create_wfilebuf(stdout, ios_base::out);
wfilebuf* werr = _Stl_create_wfilebuf(stderr, ios_base::out);
wfilebuf* wlog = _Stl_create_wfilebuf(stderr, ios_base::out);
ptr_wcin->init(win);
ptr_wcout->init(wout);
ptr_wcerr->init(werr);
ptr_wclog->init(wlog);
ptr_wcin->tie(ptr_wcout);
ptr_wcerr->setf(ios_base::unitbuf);
# endif /* _STLP_NO_WCHAR_T */
}
_STLP_CATCH_ALL {}
}
void _STLP_CALL ios_base::_S_uninitialize() {
// Note that destroying output streambufs flushes the buffers.
istream* ptr_cin = &cin;
ostream* ptr_cout = &cout;
ostream* ptr_cerr = &cerr;
ostream* ptr_clog = &clog;
#ifndef _STLP_NO_WCHAR_T
wistream* ptr_wcin = &wcin;
wostream* ptr_wcout = &wcout;
wostream* ptr_wcerr = &wcerr;
wostream* ptr_wclog = &wclog;
#endif
// we don't want any exceptions being thrown here
ptr_cin->exceptions(0);
ptr_cout->exceptions(0);
ptr_cerr->exceptions(0);
ptr_clog->exceptions(0);
delete ptr_cin->rdbuf(0);
delete ptr_cout->rdbuf(0);
delete ptr_cerr->rdbuf(0);
delete ptr_clog->rdbuf(0);
_Destroy(ptr_cin);
_Destroy(ptr_cout);
_Destroy(ptr_cerr);
_Destroy(ptr_clog);
#ifndef _STLP_NO_WCHAR_T
// we don't want any exceptions being thrown here
ptr_wcin->exceptions(0);
ptr_wcout->exceptions(0);
ptr_wcerr->exceptions(0);
ptr_wclog->exceptions(0);
delete ptr_wcin->rdbuf(0);
delete ptr_wcout->rdbuf(0);
delete ptr_wcerr->rdbuf(0);
delete ptr_wclog->rdbuf(0);
_Destroy(ptr_wcin);
_Destroy(ptr_wcout);
_Destroy(ptr_wcerr);
_Destroy(ptr_wclog);
#endif
}
bool _STLP_CALL ios_base::sync_with_stdio(bool sync) {
# if !defined (_STLP_HAS_NO_NAMESPACES) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE)
using _STLP_PRIV stdio_istreambuf;
using _STLP_PRIV stdio_ostreambuf;
# endif
bool was_synced = _S_was_synced;
// if by any chance we got there before std streams initialization,
// just set the sync flag and exit
if (Init::_S_count == 0) {
_S_was_synced = sync;
return was_synced;
}
istream* ptr_cin = &cin;
ostream* ptr_cout = &cout;
ostream* ptr_cerr = &cerr;
ostream* ptr_clog = &clog;
streambuf* old_cin = ptr_cin->rdbuf();
streambuf* old_cout = ptr_cout->rdbuf();
streambuf* old_cerr = ptr_cerr->rdbuf();
streambuf* old_clog = ptr_clog->rdbuf();
streambuf* new_cin = 0;
streambuf* new_cout = 0;
streambuf* new_cerr = 0;
streambuf* new_clog = 0;
_STLP_TRY {
if (sync && !was_synced) {
new_cin = new stdio_istreambuf(stdin);
new_cout = new stdio_ostreambuf(stdout);
new_cerr = new stdio_ostreambuf(stderr);
new_clog = new stdio_ostreambuf(stderr);
}
else if (!sync && was_synced) {
new_cin = _Stl_create_filebuf(stdin, ios_base::in);
new_cout = _Stl_create_filebuf(stdout, ios_base::out);
new_cerr = _Stl_create_filebuf(stderr, ios_base::out);
new_clog = _Stl_create_filebuf(stderr, ios_base::out);
}
}
_STLP_CATCH_ALL {}
if (new_cin && new_cout && new_cerr && new_clog) {
ptr_cin->rdbuf(new_cin);
ptr_cout->rdbuf(new_cout);
ptr_cerr->rdbuf(new_cerr);
ptr_clog->rdbuf(new_clog);
delete old_cin;
delete old_cout;
delete old_cerr;
delete old_clog;
}
else {
delete new_cin;
delete new_cout;
delete new_cerr;
delete new_clog;
}
return was_synced;
}
#endif /* ANDROID */
_STLP_END_NAMESPACE
// Local Variables:
// mode:C++
// End: