Click here to Skip to main content
15,894,405 members
Articles / Desktop Programming / MFC

Introduction to ACF (Another C++ Framework)

Rate me:
Please Sign up or sign in to vote.
4.86/5 (36 votes)
27 May 200411 min read 136.3K   739   49  
This article introduces ACF, a C++ framework which brings the .NET framework to standard C++.
//---------------------------------------------------------------------
//
// Copyright (C) 2004 Yingle Jia
//
// Permission to copy, use, modify, sell and distribute this software is 
// granted provided this copyright notice appears in all copies. 
// This software is provided "as is" without express or implied warranty, 
// and with no claim as to its suitability for any purpose.
//

#include "stdafx.h"

namespace Acf {

namespace Internal {

class __ConsoleStream : public Stream
{
// Fields
private:
    intptr_t _handle;
    bool _canRead;
    bool _canWrite;

// Constructors
public:
    __ConsoleStream(intptr_t handle, FileAccess access)
    {
        this->_handle = handle;
        this->_canRead = (access == FileAccess::Read);
        this->_canWrite = (access == FileAccess::Write);
    }

// Destructor
private:
    virtual ~__ConsoleStream()
    {
        Close();
    }

// Properties
public:
    override bool get_CanRead()
    {
        return this->_canRead;
    }
    override bool get_CanWrite()
    {
        return this->_canWrite;
    }
    override bool get_CanSeek()
    {
        return false;
    }
    override int64 get_Length()
    {
        throw InvalidOperationException();
        return 0;
    }
    override int64 get_Position()
    {
        throw InvalidOperationException();
        return 0;
    }
    override void set_Position(int64 value)
    {
        throw InvalidOperationException();
    }

// Methods
public:
    override void SetLength(int64 value)
    {
        throw InvalidOperationException();
    }

    override int64 Seek(int64 offset, SeekOrigin origin)
    {
        throw InvalidOperationException();
        return 0;
    }

    override int Read(Array<byte>* buffer, int offset, int count)
    {
        if (buffer == null)
            throw ArgumentNullException();
        if (offset < 0 || count < 0)
            throw ArgumentOutOfRangeException();
        if (offset + count > buffer->Length)
            throw ArgumentException();
        if (!this->_canRead)
           throw InvalidOperationException();

        int numBytesRead = 0;

        bool ret = Pal::ReadFile(this->_handle, buffer->GetItemAddress(offset), 
            count, &numBytesRead);
        if (!ret)
            throw InvalidOperationException();

        return numBytesRead;
    }

    override void Write(Array<byte>* buffer, int offset, int count)
    {
        Acf::VerifyArrayRange(buffer, offset, count);

        if (!this->_canWrite)
           throw InvalidOperationException();

        if (count != 0)
        {
            int written = 0;

            bool ret = Pal::WriteFile(this->_handle, buffer->GetItemAddress(offset), 
                count, &written);

            if (!ret)
                throw InvalidOperationException();
        }
    }

    override void Flush()
    {
        if (this->_handle == Pal::InvalidHandle)
            throw InvalidOperationException();
        if (!this->CanWrite)
            throw InvalidOperationException();
    }

    override void Close()
    {
        this->_handle = Pal::InvalidHandle;
        this->_canRead = false;
        this->_canWrite = false;
    }
};

} // namespace Internal

using namespace Acf::Text;

/*static*/ TextReaderPtr Console::_in = null;
/*static*/ TextWriterPtr Console::_out = null;
/*static*/ TextWriterPtr Console::_err = null;

// The buffer size is not important since we'll not buffer console I/O, 
// just make sure we use a minimum buffer size.
const int ConsoleBufferSize = 128;

ObjectPtr _consoleLock = new Object();

/*static*/ TextReaderPtr Console::get_In()
{
    if (Console::_in == null)
    {
        LOCK (_consoleLock)
        {
            if (Console::_in == null)
            {
                StreamPtr stream = OpenStandardInput();
                EncodingPtr enc = new CodePageEncoding(Pal::GetConsoleInputCodePage());

                StreamReaderPtr reader = new StreamReader(stream, enc, false, ConsoleBufferSize);
                Console::_in = reader;
            }
        }
    }

    return Console::_in;
}

/*static*/ TextWriterPtr Console::get_Out()
{
    if (Console::_out == null)
    {
        LOCK (_consoleLock)
        {
            if (Console::_out == null)
            {
                StreamPtr stream = OpenStandardOutput();
                EncodingPtr enc = new CodePageEncoding(Pal::GetConsoleOutputCodePage());

                StreamWriterPtr writer = new StreamWriter(stream, enc, ConsoleBufferSize);
                writer->AutoFlush = true;

                Console::_out = writer;
            }
        }
    }

    return Console::_out;
}

/*static*/ TextWriterPtr Console::get_Err()
{
    if (Console::_err == null)
    {
        LOCK (_consoleLock)
        {
            if (Console::_err == null)
            {
                StreamPtr stream = OpenStandardError();
                EncodingPtr enc = new CodePageEncoding(Pal::GetConsoleOutputCodePage());

                StreamWriterPtr writer = new StreamWriter(stream, enc, ConsoleBufferSize);
                writer->AutoFlush = true;

                Console::_err = writer;
            }
        }
    }

    return Console::_err;
}

/*static*/ void Console::SetIn(TextReader* newIn)
{
    if (newIn == null)
        throw ArgumentNullException();

    Console::_in = newIn;
}

/*static*/ void Console::SetOut(TextWriter* newOut)
{
    if (newOut == null)
        throw ArgumentNullException();

    Console::_out = newOut;
}

/*static*/ void Console::SetErr(TextWriter* newErr)
{
    if (newErr == null)
        throw ArgumentNullException();

    Console::_err = newErr;
}

inline StreamPtr OpenStdStream(int stdHandle, FileAccess access)
{
    intptr_t handle = Pal::GetStdHandle(stdHandle);

    if (handle == Pal::InvalidHandle || handle == null)
        throw InvalidOperationException();

    return new __ConsoleStream(handle, access);
}

/*static*/ StreamPtr Console::OpenStandardInput()
{
    return OpenStdStream(Pal::StdHandleIn, FileAccess::Read);
}

/*static*/ StreamPtr Console::OpenStandardOutput()
{
    return OpenStdStream(Pal::StdHandleOut, FileAccess::Write);
}

/*static*/ StreamPtr Console::OpenStandardError()
{
    return OpenStdStream(Pal::StdHandleErr, FileAccess::Write);
}

/*static*/ int Console::Read()
{
    TextReader* in = get_In();
    LOCK (in)
        return in->Read();
}

/*static*/ StringPtr Console::ReadLine()
{
    TextReader* in = get_In();
    LOCK (in)
        return in->ReadLine();
}

/*static*/ void Console::Write(bool value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(value);
}

/*static*/ void Console::Write(wchar_t value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(value);
}

/*static*/ void Console::Write(int value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(value);
}

/*static*/ void Console::Write(uint value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(value);
}

/*static*/ void Console::Write(int64 value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(value);
}

/*static*/ void Console::Write(uint64 value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(value);
}

/*static*/ void Console::Write(float value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(value);
}

/*static*/ void Console::Write(double value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(value);
}

/*static*/ void Console::Write(Array<wchar_t>* buffer)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(buffer);
}

/*static*/ void Console::Write(Array<wchar_t>* buffer, int index, int count)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(buffer, index, count);
}

/*static*/ void Console::Write(Object* value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(value);
}

/*static*/ void Console::Write(String* value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(value);
}

/*static*/ void Console::Write(const wchar_t* value)
{
    StringPtr s = new String(value);

    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(s);
}

/*static*/ void Console::Write(String* format, Object* arg0)
{
    StringPtr s = String::Format(format, arg0);

    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(s);
}

/*static*/ void Console::Write(String* format, Object* arg0, Object* arg1)
{
    StringPtr s = String::Format(format, arg0, arg1);

    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(s);
}

/*static*/ void Console::Write(String* format, Object* arg0, Object* arg1, Object* arg2)
{
    StringPtr s = String::Format(format, arg0, arg1, arg2);

    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(s);
}

/*static*/ void Console::Write(String* format, Array<ObjectPtr>* args)
{
    StringPtr s = String::Format(format, args);

    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(s);
}

/*static*/ void Console::Write(const wchar_t* format, Object* arg0)
{
    StringPtr s = String::Format(format, arg0);

    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(s);
}

/*static*/ void Console::Write(const wchar_t* format, Object* arg0, Object* arg1)
{
    StringPtr s = String::Format(format, arg0, arg1);

    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(s);
}

/*static*/ void Console::Write(const wchar_t* format, Object* arg0, Object* arg1, Object* arg2)
{
    StringPtr s = String::Format(format, arg0, arg1, arg2);

    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(s);
}

/*static*/ void Console::Write(const wchar_t* format, Array<ObjectPtr>* args)
{
    StringPtr s = String::Format(format, args);

    TextWriter* out = get_Out();
    LOCK (out)
        out->Write(s);
}

/*static*/ void Console::WriteLine()
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine();
}

/*static*/ void Console::WriteLine(bool value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(value);
}

/*static*/ void Console::WriteLine(wchar_t value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(value);
}

/*static*/ void Console::WriteLine(int value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(value);
}

/*static*/ void Console::WriteLine(uint value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(value);
}

/*static*/ void Console::WriteLine(int64 value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(value);
}

/*static*/ void Console::WriteLine(uint64 value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(value);
}

/*static*/ void Console::WriteLine(float value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(value);
}

/*static*/ void Console::WriteLine(double value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(value);
}

/*static*/ void Console::WriteLine(Array<wchar_t>* buffer)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(buffer);
}

/*static*/ void Console::WriteLine(Array<wchar_t>* buffer, int index, int count)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(buffer, index, count);
}

/*static*/ void Console::WriteLine(Object* value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(value);
}

/*static*/ void Console::WriteLine(String* value)
{
    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(value);
}

/*static*/ void Console::WriteLine(const wchar_t* value)
{
    StringPtr s = new String(value);

    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(s);
}

/*static*/ void Console::WriteLine(String* format, Object* arg0)
{
    StringPtr s = String::Format(format, arg0);

    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(s);
}

/*static*/ void Console::WriteLine(String* format, Object* arg0, Object* arg1)
{
    StringPtr s = String::Format(format, arg0, arg1);

    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(s);
}

/*static*/ void Console::WriteLine(String* format, Object* arg0, Object* arg1, Object* arg2)
{
    StringPtr s = String::Format(format, arg0, arg1, arg2);

    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(s);
}

/*static*/ void Console::WriteLine(String* format, Array<ObjectPtr>* args)
{
    StringPtr s = String::Format(format, args);

    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(s);
}

/*static*/ void Console::WriteLine(const wchar_t* format, Object* arg0)
{
    StringPtr s = String::Format(format, arg0);

    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(s);
}

/*static*/ void Console::WriteLine(const wchar_t* format, Object* arg0, Object* arg1)
{
    StringPtr s = String::Format(format, arg0, arg1);

    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(s);
}

/*static*/ void Console::WriteLine(const wchar_t* format, Object* arg0, Object* arg1, Object* arg2)
{
    StringPtr s = String::Format(format, arg0, arg1, arg2);

    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(s);
}

/*static*/ void Console::WriteLine(const wchar_t* format, Array<ObjectPtr>* args)
{
    StringPtr s = String::Format(format, args);

    TextWriter* out = get_Out();
    LOCK (out)
        out->WriteLine(s);
}

} // namespace Acf

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
China China
Yingle Jia is a software engineer located in Beijing, China. He currently works at IBM CSDL (China Software Development Lab). His interests include C++/COM/C#/.NET/XML, etc. He likes coding and writing.

He is the creator of ACF (Another C++ Framework) project. See http://acfproj.sourceforge.net/.

He also has a blog at http://blogs.wwwcoder.com/yljia/

Comments and Discussions