8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-27 20:43:03 +01:00
firebird-mirror/src/common/StatusArg.cpp

244 lines
5.9 KiB
C++
Raw Normal View History

/*
* PROGRAM: Firebird exceptions classes
* MODULE: StatusArg.cpp
* DESCRIPTION: Build status vector with variable number of elements
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.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.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Alex Peshkov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2008 Alex Peshkov <peshkoff at mail.ru>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
*
*/
#include "firebird.h"
#include "../common/StatusArg.h"
#include "../common/classes/fb_string.h"
#include "../common/classes/MetaName.h"
#include "../common/classes/alloc.h"
#include "fb_exception.h"
#include "gen/iberror.h"
#ifdef WIN_NT
#include <windows.h>
#else
#include <errno.h>
#endif
namespace Firebird {
namespace Arg {
2008-11-23 22:54:56 +01:00
Base::Base(ISC_STATUS k, ISC_STATUS c) :
implementation(FB_NEW(*getDefaultMemoryPool()) ImplBase(k, c))
{
}
2008-07-06 18:42:52 +02:00
StatusVector::ImplStatusVector::ImplStatusVector(const ISC_STATUS* s) throw() : Base::ImplBase(0, 0)
{
clear();
// special case - empty initialized status vector, no warnings
if (s[0] != isc_arg_gds || s[1] != 0 || s[2] != 0)
{
append(s, FB_NELEM(m_status_vector) - 1);
}
}
2008-11-23 22:54:56 +01:00
StatusVector::StatusVector(ISC_STATUS k, ISC_STATUS c) :
Base(FB_NEW(*getDefaultMemoryPool()) ImplStatusVector(k, c))
2008-12-05 02:20:14 +01:00
{
2008-10-31 12:14:37 +01:00
operator<<(*(static_cast<Base*>(this)));
}
2008-11-23 22:54:56 +01:00
StatusVector::StatusVector(const ISC_STATUS* s) :
Base(FB_NEW(*getDefaultMemoryPool()) ImplStatusVector(s))
{
}
2008-10-31 12:14:37 +01:00
2008-12-05 02:20:14 +01:00
StatusVector::StatusVector() :
2008-11-23 22:54:56 +01:00
Base(FB_NEW(*getDefaultMemoryPool()) ImplStatusVector(0, 0))
{
}
2008-10-31 12:14:37 +01:00
void StatusVector::ImplStatusVector::clear() throw()
2008-10-31 12:14:37 +01:00
{
m_length = 0;
m_warning = 0;
m_status_vector[0] = isc_arg_end;
2008-10-31 12:14:37 +01:00
}
void StatusVector::ImplStatusVector::append(const StatusVector& v) throw()
2008-07-10 17:46:41 +02:00
{
ImplStatusVector newVector(getKind(), getCode());
2008-07-11 04:37:23 +02:00
2008-07-10 17:46:41 +02:00
if (newVector.appendErrors(this))
2008-07-11 04:37:23 +02:00
{
if (newVector.appendErrors(v.implementation))
2008-07-11 04:37:23 +02:00
{
2008-07-10 17:46:41 +02:00
if (newVector.appendWarnings(this))
newVector.appendWarnings(v.implementation);
2008-07-11 04:37:23 +02:00
}
}
2008-12-05 02:20:14 +01:00
2008-07-10 17:46:41 +02:00
*this = newVector;
}
bool StatusVector::ImplStatusVector::appendErrors(const ImplBase* const v) throw()
2008-07-10 17:46:41 +02:00
{
return append(v->value(), v->firstWarning() ? v->firstWarning() : v->length());
2008-12-05 02:20:14 +01:00
}
2008-07-10 17:46:41 +02:00
bool StatusVector::ImplStatusVector::appendWarnings(const ImplBase* const v) throw()
2008-07-10 17:46:41 +02:00
{
if (! v->firstWarning())
2008-07-10 17:46:41 +02:00
return true;
return append(v->value() + v->firstWarning(), v->length() - v->firstWarning());
2008-12-05 02:20:14 +01:00
}
2008-07-10 17:46:41 +02:00
bool StatusVector::ImplStatusVector::append(const ISC_STATUS* const from, const int count) throw()
2008-07-10 17:46:41 +02:00
{
2009-06-04 11:32:08 +02:00
unsigned int copied = 0;
2008-07-11 04:37:23 +02:00
for (int i = 0; i < count; )
2008-07-10 17:46:41 +02:00
{
if (from[i] == isc_arg_end)
{
break;
}
i += (from[i] == isc_arg_cstring ? 3 : 2);
if (m_length + i > FB_NELEM(m_status_vector) - 1)
2008-07-10 17:46:41 +02:00
{
break;
}
copied = i;
2008-07-10 17:46:41 +02:00
}
2008-07-11 04:37:23 +02:00
2008-07-10 17:46:41 +02:00
memcpy(&m_status_vector[m_length], from, copied * sizeof(m_status_vector[0]));
m_length += copied;
m_status_vector[m_length] = isc_arg_end;
2008-07-11 04:37:23 +02:00
2009-06-05 12:24:39 +02:00
return copied == static_cast<unsigned int>(count);
2008-07-10 17:46:41 +02:00
}
void StatusVector::ImplStatusVector::shiftLeft(const Base& arg) throw()
{
if (m_length < FB_NELEM(m_status_vector) - 2)
{
m_status_vector[m_length++] = arg.getKind();
m_status_vector[m_length++] = arg.getCode();
m_status_vector[m_length] = isc_arg_end;
}
}
void StatusVector::ImplStatusVector::shiftLeft(const Warning& arg) throw()
2008-07-10 17:46:41 +02:00
{
2008-07-12 10:06:19 +02:00
const int cur = m_warning ? 0 : m_length;
shiftLeft(*static_cast<const Base*>(&arg));
2008-07-10 17:46:41 +02:00
if (cur && m_status_vector[cur] == isc_arg_warning)
m_warning = cur;
}
void StatusVector::ImplStatusVector::shiftLeft(const char* text) throw()
2008-07-10 17:46:41 +02:00
{
shiftLeft(Str(text));
2008-07-10 17:46:41 +02:00
}
void StatusVector::ImplStatusVector::shiftLeft(const AbstractString& text) throw()
2008-07-10 17:46:41 +02:00
{
shiftLeft(Str(text));
2008-07-10 17:46:41 +02:00
}
void StatusVector::ImplStatusVector::shiftLeft(const MetaName& text) throw()
2008-07-10 17:46:41 +02:00
{
shiftLeft(Str(text));
2008-07-10 17:46:41 +02:00
}
void StatusVector::raise() const
{
if (hasData())
{
status_exception::raise(*this);
}
status_exception::raise(Gds(isc_random) <<
Str("Attempt to raise empty exception"));
}
ISC_STATUS StatusVector::ImplStatusVector::copyTo(ISC_STATUS* dest) const throw()
{
if (hasData())
{
2009-06-04 11:32:08 +02:00
memcpy(dest, value(), (length() + 1u) * sizeof(ISC_STATUS));
}
else {
dest[0] = isc_arg_gds;
dest[1] = FB_SUCCESS;
dest[2] = isc_arg_end;
}
return dest[1];
}
2008-12-05 02:20:14 +01:00
Gds::Gds(ISC_STATUS s) throw() :
StatusVector(isc_arg_gds, s) { }
2008-12-05 02:20:14 +01:00
Num::Num(ISC_STATUS s) throw() :
Base(isc_arg_number, s) { }
2008-12-05 02:20:14 +01:00
Interpreted::Interpreted(const char* text) throw() :
StatusVector(isc_arg_interpreted, (ISC_STATUS)(IPTR) text) { }
2008-12-05 02:20:14 +01:00
Interpreted::Interpreted(const AbstractString& text) throw() :
StatusVector(isc_arg_interpreted, (ISC_STATUS)(IPTR) text.c_str()) { }
2008-12-05 02:20:14 +01:00
Unix::Unix(ISC_STATUS s) throw() :
Base(isc_arg_unix, s) { }
Mach::Mach(ISC_STATUS s) throw() :
Base(isc_arg_next_mach, s) { }
2008-12-05 02:20:14 +01:00
Windows::Windows(ISC_STATUS s) throw() :
Base(isc_arg_win32, s) { }
2008-12-05 02:20:14 +01:00
Warning::Warning(ISC_STATUS s) throw() :
StatusVector(isc_arg_warning, s) { }
2008-12-05 02:20:14 +01:00
Str::Str(const char* text) throw() :
Base(isc_arg_string, (ISC_STATUS)(IPTR) text) { }
2008-12-05 02:20:14 +01:00
Str::Str(const AbstractString& text) throw() :
Base(isc_arg_string, (ISC_STATUS)(IPTR) text.c_str()) { }
2008-12-05 02:20:14 +01:00
Str::Str(const MetaName& text) throw() :
Base(isc_arg_string, (ISC_STATUS)(IPTR) text.c_str()) { }
2008-12-05 02:20:14 +01:00
SqlState::SqlState(const char* text) throw() :
Base(isc_arg_sql_state, (ISC_STATUS)(IPTR) text) { }
2008-12-05 02:20:14 +01:00
SqlState::SqlState(const AbstractString& text) throw() :
Base(isc_arg_sql_state, (ISC_STATUS)(IPTR) text.c_str()) { }
2008-12-05 02:20:14 +01:00
OsError::OsError() throw() :
#ifdef WIN_NT
Base(isc_arg_win32, GetLastError()) { }
#else
Base(isc_arg_unix, errno) { }
#endif
} // namespace Arg
} // namespace Firebird