diff --git a/src/common/classes/Aligner.h b/src/common/classes/Aligner.h new file mode 100644 index 0000000000..c6f60c39a5 --- /dev/null +++ b/src/common/classes/Aligner.h @@ -0,0 +1,115 @@ +/* + * PROGRAM: JRD Access Method + * MODULE: Aligner.h + * DESCRIPTION: Aligner, OutAligner - templates to help + * with alignment on RISC machines. + * Should be used ONLY as temporary on-stack buffers! + * + * 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 Alexander Peshkoff + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2007 Alexander Peshkoff + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#ifndef CLASSES_ALIGN_H +#define CLASSES_ALIGN_H + +#include "../common/classes/array.h" + +namespace Firebird { + +// Aligns output parameter (i.e. transfers data in destructor). +template +class OutAligner { +private: + UCHAR* userBuffer; +#ifdef RISC_ALIGNMENT + Firebird::HalfStaticArray localBuffer; + ULONG bSize; + C* bPointer; +#endif + +public: + OutAligner(UCHAR* buf, ULONG len) : userBuffer(buf) +#ifdef RISC_ALIGNMENT + , bSize(len), bPointer(0) +#endif + { + fb_assert(len % sizeof(C) == 0); +#ifdef RISC_ALIGNMENT + if ((IPTR)userBuffer & (sizeof(C) - 1)) + { + bPointer = localBuffer.getBuffer(len / sizeof(C) + (bSize % sizeof(C) ? 1 : 0)); + } +#endif + } + + operator C*() + { + return +#ifdef RISC_ALIGNMENT + bPointer ? bPointer : +#endif + reinterpret_cast(userBuffer); + } + + ~OutAligner() + { +#ifdef RISC_ALIGNMENT + if (bPointer) + { + memcpy(userBuffer, bPointer, bSize); + } +#endif + } +}; + +// Aligns input parameter. +template +class Aligner { +private: +#ifdef RISC_ALIGNMENT + Firebird::HalfStaticArray localBuffer; +#endif + const C* bPointer; + +public: + Aligner(const UCHAR* buf, ULONG len) + { + fb_assert(len % sizeof(C) == 0); +#ifdef RISC_ALIGNMENT + if ((IPTR)buf & (sizeof(C) - 1)) + { + C* tempPointer = localBuffer.getBuffer(len / sizeof(C) + (len % sizeof(C) ? 1 : 0)); + memcpy(tempPointer, buf, len); + bPointer = tempPointer; + } + else +#endif + bPointer = reinterpret_cast(buf); + } + + operator const C*() + { + return bPointer; + } +}; + +} //namespace Firebird + +#endif // CLASSES_ALIGN_H