/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#define __STDC_WANT_LIB_EXT1__ 1
#include <log4cxx/logstring.h>
#include <log4cxx/helpers/exception.h>
#include <string.h>
#include <string>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/helpers/pool.h>
#include <apr_errno.h>

using namespace LOG4CXX_NS;
using namespace LOG4CXX_NS::helpers;

Exception::Exception(const LogString& msg1)
{
	LOG4CXX_ENCODE_CHAR(m, msg1);
	size_t len = m.size();

	if (len > MSG_SIZE)
	{
		len = MSG_SIZE;
	}

#if defined(__STDC_LIB_EXT1__) || defined(__STDC_SECURE_LIB__)
	memcpy_s(msg, sizeof msg, m.data(), len);
#else
	memcpy(msg, m.data(), len);
#endif
	msg[len] = 0;
}

Exception::Exception(const char* m)
{
#if defined(__STDC_LIB_EXT1__) || defined(__STDC_SECURE_LIB__)
	strncpy_s(msg, sizeof msg, m, MSG_SIZE);
#else
	strncpy(msg, m, MSG_SIZE);
#endif
	msg[MSG_SIZE] = 0;
}


Exception::Exception(const Exception& src) : std::exception()
{
#if defined(__STDC_LIB_EXT1__) || defined(__STDC_SECURE_LIB__)
	strcpy_s(msg, sizeof msg, src.msg);
#else
	strncpy(msg, src.msg, MSG_SIZE);
	msg[MSG_SIZE] = 0;
#endif
}

Exception& Exception::operator=(const Exception& src)
{
#if defined(__STDC_LIB_EXT1__) || defined(__STDC_SECURE_LIB__)
	strcpy_s(msg, sizeof msg, src.msg);
#else
	strncpy(msg, src.msg, MSG_SIZE);
	msg[MSG_SIZE] = 0;
#endif
	return *this;
}

const char* Exception::what() const throw()
{
	return msg;
}

RuntimeException::RuntimeException(log4cxx_status_t stat)
	: Exception(formatMessage(stat))
{
}

RuntimeException::RuntimeException(const LogString& msg1)
	: Exception(msg1)
{
}

RuntimeException::RuntimeException(const RuntimeException& src)
	: Exception(src)
{
}

RuntimeException& RuntimeException::operator=(const RuntimeException& src)
{
	Exception::operator=(src);
	return *this;
}

LogString RuntimeException::formatMessage(log4cxx_status_t stat)
{
	LogString s(LOG4CXX_STR("RuntimeException: return code = "));
	Pool p;
	StringHelper::toString(stat, p, s);
	return s;
}

NullPointerException::NullPointerException(const LogString& msg1)
	: RuntimeException(msg1)
{
}

NullPointerException::NullPointerException(const NullPointerException& src)
	: RuntimeException(src)
{
}

NullPointerException& NullPointerException::operator=(const NullPointerException& src)
{
	RuntimeException::operator=(src);
	return *this;
}

IllegalArgumentException::IllegalArgumentException(const LogString& msg1)
	: RuntimeException(msg1)
{
}

IllegalArgumentException::IllegalArgumentException(const IllegalArgumentException& src)
	: RuntimeException(src)
{
}

IllegalArgumentException& IllegalArgumentException::operator=(const IllegalArgumentException& src)
{
	RuntimeException::operator=(src);
	return *this;
}

IOException::IOException()
	: Exception(LOG4CXX_STR("IO exception"))
{
}

IOException::IOException(log4cxx_status_t stat)
	: Exception(formatMessage(stat))
{
}


IOException::IOException(const LogString& msg1)
	: Exception(msg1)
{
}

IOException::IOException(const IOException& src)
	: Exception(src)
{
}

IOException& IOException::operator=(const IOException& src)
{
	Exception::operator=(src);
	return *this;
}

LogString IOException::formatMessage(log4cxx_status_t stat)
{
	char err_buff[1024];
	LogString s(LOG4CXX_STR("IO Exception : status code = "));
	Pool p;
	StringHelper::toString(stat, p, s);
	s.append(LOG4CXX_STR("("));
	apr_strerror(stat, err_buff, sizeof(err_buff));
	std::string sMsg = err_buff;
	LOG4CXX_DECODE_CHAR(lsMsg, sMsg);
	s.append(lsMsg);
	s.append(LOG4CXX_STR(")"));
	return s;
}


MissingResourceException::MissingResourceException(const LogString& key)
	: Exception(formatMessage(key))
{
}


MissingResourceException::MissingResourceException(const MissingResourceException& src)
	: Exception(src)
{
}

MissingResourceException& MissingResourceException::operator=(const MissingResourceException& src)
{
	Exception::operator=(src);
	return *this;
}

LogString MissingResourceException::formatMessage(const LogString& key)
{
	LogString s(LOG4CXX_STR("MissingResourceException: resource key = \""));
	s.append(key);
	s.append(LOG4CXX_STR("\"."));
	return s;
}

PoolException::PoolException(log4cxx_status_t stat)
	: Exception(formatMessage(stat))
{
}

PoolException::PoolException(const PoolException& src)
	: Exception(src)
{
}

PoolException& PoolException::operator=(const PoolException& src)
{
	Exception::operator=(src);
	return *this;
}

LogString PoolException::formatMessage(log4cxx_status_t)
{
	return LOG4CXX_STR("Pool exception");
}


TranscoderException::TranscoderException(log4cxx_status_t stat)
	: Exception(formatMessage(stat))
{
}

TranscoderException::TranscoderException(const TranscoderException& src)
	: Exception(src)
{
}

TranscoderException& TranscoderException::operator=(const TranscoderException& src)
{
	Exception::operator=(src);
	return *this;
}

LogString TranscoderException::formatMessage(log4cxx_status_t)
{
	return LOG4CXX_STR("Transcoder exception");
}


InterruptedException::InterruptedException() : Exception(LOG4CXX_STR("Thread was interrupted"))
{
}

InterruptedException::InterruptedException(log4cxx_status_t stat)
	: Exception(formatMessage(stat))
{
}

InterruptedException::InterruptedException(const InterruptedException& src)
	: Exception(src)
{
}

InterruptedException& InterruptedException::operator=(const InterruptedException& src)
{
	Exception::operator=(src);
	return *this;
}

LogString InterruptedException::formatMessage(log4cxx_status_t stat)
{
	LogString s(LOG4CXX_STR("InterruptedException: stat = "));
	Pool p;
	StringHelper::toString(stat, p, s);
	return s;
}

ThreadException::ThreadException(log4cxx_status_t stat)
	: Exception(formatMessage(stat))
{
}

ThreadException::ThreadException(const LogString& msg)
	: Exception(msg)
{
}

ThreadException::ThreadException(const ThreadException& src)
	: Exception(src)
{
}

ThreadException& ThreadException::operator=(const ThreadException& src)
{
	Exception::operator=(src);
	return *this;
}

LogString ThreadException::formatMessage(log4cxx_status_t stat)
{
	LogString s(LOG4CXX_STR("Thread exception: stat = "));
	Pool p;
	StringHelper::toString(stat, p, s);
	return s;
}

IllegalMonitorStateException::IllegalMonitorStateException(const LogString& msg1)
	: Exception(msg1)
{
}

IllegalMonitorStateException::IllegalMonitorStateException(const IllegalMonitorStateException& src)
	: Exception(src)
{
}

IllegalMonitorStateException& IllegalMonitorStateException::operator=(const IllegalMonitorStateException& src)
{
	Exception::operator=(src);
	return *this;
}

InstantiationException::InstantiationException(const LogString& msg1)
	: Exception(msg1)
{
}

InstantiationException::InstantiationException(const InstantiationException& src)
	: Exception(src)
{
}

InstantiationException& InstantiationException::operator=(const InstantiationException& src)
{
	Exception::operator=(src);
	return *this;
}

ClassNotFoundException::ClassNotFoundException(const LogString& className)
	: Exception(formatMessage(className))
{
}

ClassNotFoundException::ClassNotFoundException(const ClassNotFoundException& src)
	: Exception(src)
{
}


ClassNotFoundException& ClassNotFoundException::operator=(const ClassNotFoundException& src)
{
	Exception::operator=(src);
	return *this;
}

LogString ClassNotFoundException::formatMessage(const LogString& className)
{
	LogString s(LOG4CXX_STR("Class not found: "));
	s.append(className);
	return s;
}


NoSuchElementException::NoSuchElementException()
	: Exception(LOG4CXX_STR("No such element"))
{
}

NoSuchElementException::NoSuchElementException(const NoSuchElementException& src)
	: Exception(src)
{
}

NoSuchElementException& NoSuchElementException::operator=(const NoSuchElementException& src)
{
	Exception::operator=(src);
	return *this;
}


IllegalStateException::IllegalStateException()
	: Exception(LOG4CXX_STR("Illegal state"))
{
}

IllegalStateException::IllegalStateException(const IllegalStateException& src)
	: Exception(src)
{
}

IllegalStateException& IllegalStateException::operator=(const IllegalStateException& src)
{
	Exception::operator=(src);
	return *this;
}

SocketException::SocketException(const LogString& msg) : IOException(msg)
{
}

SocketException::SocketException(log4cxx_status_t status) : IOException(status)
{
}

SocketException::SocketException(const SocketException& src)
	: IOException(src)
{
}

SocketException& SocketException::operator=(const SocketException& src)
{
	IOException::operator=(src);
	return *this;
}

ConnectException::ConnectException(log4cxx_status_t status) : SocketException(status)
{
}

ConnectException::ConnectException(const ConnectException& src)
	: SocketException(src)
{
}

ConnectException& ConnectException::operator=(const ConnectException& src)
{
	SocketException::operator=(src);
	return *this;
}

ClosedChannelException::ClosedChannelException() : SocketException(LOG4CXX_STR("Attempt to write to closed socket"))
{
}

ClosedChannelException::ClosedChannelException(const ClosedChannelException& src)
	: SocketException(src)
{
}

ClosedChannelException& ClosedChannelException::operator=(const ClosedChannelException& src)
{
	SocketException::operator=(src);
	return *this;
}

BindException::BindException(log4cxx_status_t status) : SocketException(status)
{
}

BindException::BindException(const BindException& src)
	: SocketException(src)
{
}

BindException& BindException::operator=(const BindException& src)
{
	SocketException::operator=(src);
	return *this;
}

InterruptedIOException::InterruptedIOException(const LogString& msg) : IOException(msg)
{
}

InterruptedIOException::InterruptedIOException(const InterruptedIOException& src)
	: IOException(src)
{
}

InterruptedIOException& InterruptedIOException::operator=(const InterruptedIOException& src)
{
	IOException::operator=(src);
	return *this;
}

SocketTimeoutException::SocketTimeoutException()
	: InterruptedIOException(LOG4CXX_STR("SocketTimeoutException"))
{
}

SocketTimeoutException::SocketTimeoutException(const SocketTimeoutException& src)
	: InterruptedIOException(src)
{
}

SocketTimeoutException& SocketTimeoutException::operator=(const SocketTimeoutException& src)
{
	InterruptedIOException::operator=(src);
	return *this;
}
