Skip to content

Commit c712473

Browse files
committed
Feature #8761 - Add API method Util::convert
1 parent 1214b46 commit c712473

File tree

5 files changed

+104
-3
lines changed

5 files changed

+104
-3
lines changed

src/include/firebird/FirebirdInterface.idl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,10 @@ version: // 5.0 => 6.0 Alpha1
12631263
uint stmtLength, const string creatDBstatement, uint dialect,
12641264
uint dpbLength, const uchar* dpb,
12651265
boolean* stmtIsCreateDb);
1266+
1267+
version: // 5.0 => 6.0 Alpha1
1268+
void convert(Status status, uint sourceType, uint sourceScale, uint sourceLength, const void* source,
1269+
uint targetType, uint targetScale, uint targetLength, void* target);
12661270
}
12671271

12681272
interface OffsetsCallback : Versioned

src/include/firebird/IdlFbInterfaces.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4815,7 +4815,7 @@ namespace Firebird
48154815
}
48164816
};
48174817

4818-
#define FIREBIRD_IUTIL_VERSION 5u
4818+
#define FIREBIRD_IUTIL_VERSION 6u
48194819

48204820
class IUtil : public IVersioned
48214821
{
@@ -4845,6 +4845,7 @@ namespace Firebird
48454845
void (CLOOP_CARG *decodeTimeTzEx)(IUtil* self, IStatus* status, const ISC_TIME_TZ_EX* timeTz, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions, unsigned timeZoneBufferLength, char* timeZoneBuffer) CLOOP_NOEXCEPT;
48464846
void (CLOOP_CARG *decodeTimeStampTzEx)(IUtil* self, IStatus* status, const ISC_TIMESTAMP_TZ_EX* timeStampTz, unsigned* year, unsigned* month, unsigned* day, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions, unsigned timeZoneBufferLength, char* timeZoneBuffer) CLOOP_NOEXCEPT;
48474847
IAttachment* (CLOOP_CARG *executeCreateDatabase2)(IUtil* self, IStatus* status, unsigned stmtLength, const char* creatDBstatement, unsigned dialect, unsigned dpbLength, const unsigned char* dpb, FB_BOOLEAN* stmtIsCreateDb) CLOOP_NOEXCEPT;
4848+
void (CLOOP_CARG *convert)(IUtil* self, IStatus* status, unsigned sourceType, unsigned sourceScale, unsigned sourceLength, const void* source, unsigned targetType, unsigned targetScale, unsigned targetLength, void* target) CLOOP_NOEXCEPT;
48484849
};
48494850

48504851
protected:
@@ -5079,6 +5080,19 @@ namespace Firebird
50795080
StatusType::checkException(status);
50805081
return ret;
50815082
}
5083+
5084+
template <typename StatusType> void convert(StatusType* status, unsigned sourceType, unsigned sourceScale, unsigned sourceLength, const void* source, unsigned targetType, unsigned targetScale, unsigned targetLength, void* target)
5085+
{
5086+
if (cloopVTable->version < 6)
5087+
{
5088+
StatusType::setVersionError(status, "IUtil", cloopVTable->version, 6);
5089+
StatusType::checkException(status);
5090+
return;
5091+
}
5092+
StatusType::clearException(status);
5093+
static_cast<VTable*>(this->cloopVTable)->convert(this, status, sourceType, sourceScale, sourceLength, source, targetType, targetScale, targetLength, target);
5094+
StatusType::checkException(status);
5095+
}
50825096
};
50835097

50845098
#define FIREBIRD_IOFFSETS_CALLBACK_VERSION 2u
@@ -16430,6 +16444,7 @@ namespace Firebird
1643016444
this->decodeTimeTzEx = &Name::cloopdecodeTimeTzExDispatcher;
1643116445
this->decodeTimeStampTzEx = &Name::cloopdecodeTimeStampTzExDispatcher;
1643216446
this->executeCreateDatabase2 = &Name::cloopexecuteCreateDatabase2Dispatcher;
16447+
this->convert = &Name::cloopconvertDispatcher;
1643316448
}
1643416449
} vTable;
1643516450

@@ -16756,6 +16771,20 @@ namespace Firebird
1675616771
return static_cast<IAttachment*>(0);
1675716772
}
1675816773
}
16774+
16775+
static void CLOOP_CARG cloopconvertDispatcher(IUtil* self, IStatus* status, unsigned sourceType, unsigned sourceScale, unsigned sourceLength, const void* source, unsigned targetType, unsigned targetScale, unsigned targetLength, void* target) CLOOP_NOEXCEPT
16776+
{
16777+
StatusType status2(status);
16778+
16779+
try
16780+
{
16781+
static_cast<Name*>(self)->Name::convert(&status2, sourceType, sourceScale, sourceLength, source, targetType, targetScale, targetLength, target);
16782+
}
16783+
catch (...)
16784+
{
16785+
StatusType::catchException(&status2);
16786+
}
16787+
}
1675916788
};
1676016789

1676116790
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IUtil> > >
@@ -16794,6 +16823,7 @@ namespace Firebird
1679416823
virtual void decodeTimeTzEx(StatusType* status, const ISC_TIME_TZ_EX* timeTz, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions, unsigned timeZoneBufferLength, char* timeZoneBuffer) = 0;
1679516824
virtual void decodeTimeStampTzEx(StatusType* status, const ISC_TIMESTAMP_TZ_EX* timeStampTz, unsigned* year, unsigned* month, unsigned* day, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions, unsigned timeZoneBufferLength, char* timeZoneBuffer) = 0;
1679616825
virtual IAttachment* executeCreateDatabase2(StatusType* status, unsigned stmtLength, const char* creatDBstatement, unsigned dialect, unsigned dpbLength, const unsigned char* dpb, FB_BOOLEAN* stmtIsCreateDb) = 0;
16826+
virtual void convert(StatusType* status, unsigned sourceType, unsigned sourceScale, unsigned sourceLength, const void* source, unsigned targetType, unsigned targetScale, unsigned targetLength, void* target) = 0;
1679716827
};
1679816828

1679916829
template <typename Name, typename StatusType, typename Base>

src/include/gen/Firebird.pas

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,7 @@ ISC_TIMESTAMP_TZ_EX = record
571571
IUtil_decodeTimeTzExPtr = procedure(this: IUtil; status: IStatus; timeTz: ISC_TIME_TZ_EXPtr; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr; timeZoneBufferLength: Cardinal; timeZoneBuffer: PAnsiChar); cdecl;
572572
IUtil_decodeTimeStampTzExPtr = procedure(this: IUtil; status: IStatus; timeStampTz: ISC_TIMESTAMP_TZ_EXPtr; year: CardinalPtr; month: CardinalPtr; day: CardinalPtr; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr; timeZoneBufferLength: Cardinal; timeZoneBuffer: PAnsiChar); cdecl;
573573
IUtil_executeCreateDatabase2Ptr = function(this: IUtil; status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; dpbLength: Cardinal; dpb: BytePtr; stmtIsCreateDb: BooleanPtr): IAttachment; cdecl;
574+
IUtil_convertPtr = procedure(this: IUtil; status: IStatus; sourceType: Cardinal; sourceScale: Cardinal; sourceLength: Cardinal; source: Pointer; targetType: Cardinal; targetScale: Cardinal; targetLength: Cardinal; target: Pointer); cdecl;
574575
IOffsetsCallback_setOffsetPtr = procedure(this: IOffsetsCallback; status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal); cdecl;
575576
IXpbBuilder_clearPtr = procedure(this: IXpbBuilder; status: IStatus); cdecl;
576577
IXpbBuilder_removeCurrentPtr = procedure(this: IXpbBuilder; status: IStatus); cdecl;
@@ -2811,10 +2812,11 @@ UtilVTable = class(VersionedVTable)
28112812
decodeTimeTzEx: IUtil_decodeTimeTzExPtr;
28122813
decodeTimeStampTzEx: IUtil_decodeTimeStampTzExPtr;
28132814
executeCreateDatabase2: IUtil_executeCreateDatabase2Ptr;
2815+
convert: IUtil_convertPtr;
28142816
end;
28152817

28162818
IUtil = class(IVersioned)
2817-
const VERSION = 5;
2819+
const VERSION = 6;
28182820

28192821
procedure getFbVersion(status: IStatus; att: IAttachment; callback: IVersionCallback);
28202822
procedure loadBlob(status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean);
@@ -2839,6 +2841,7 @@ IUtil = class(IVersioned)
28392841
procedure decodeTimeTzEx(status: IStatus; timeTz: ISC_TIME_TZ_EXPtr; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr; timeZoneBufferLength: Cardinal; timeZoneBuffer: PAnsiChar);
28402842
procedure decodeTimeStampTzEx(status: IStatus; timeStampTz: ISC_TIMESTAMP_TZ_EXPtr; year: CardinalPtr; month: CardinalPtr; day: CardinalPtr; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr; timeZoneBufferLength: Cardinal; timeZoneBuffer: PAnsiChar);
28412843
function executeCreateDatabase2(status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; dpbLength: Cardinal; dpb: BytePtr; stmtIsCreateDb: BooleanPtr): IAttachment;
2844+
procedure convert(status: IStatus; sourceType: Cardinal; sourceScale: Cardinal; sourceLength: Cardinal; source: Pointer; targetType: Cardinal; targetScale: Cardinal; targetLength: Cardinal; target: Pointer);
28422845
end;
28432846

28442847
IUtilImpl = class(IUtil)
@@ -2867,6 +2870,7 @@ IUtilImpl = class(IUtil)
28672870
procedure decodeTimeTzEx(status: IStatus; timeTz: ISC_TIME_TZ_EXPtr; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr; timeZoneBufferLength: Cardinal; timeZoneBuffer: PAnsiChar); virtual; abstract;
28682871
procedure decodeTimeStampTzEx(status: IStatus; timeStampTz: ISC_TIMESTAMP_TZ_EXPtr; year: CardinalPtr; month: CardinalPtr; day: CardinalPtr; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr; timeZoneBufferLength: Cardinal; timeZoneBuffer: PAnsiChar); virtual; abstract;
28692872
function executeCreateDatabase2(status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; dpbLength: Cardinal; dpb: BytePtr; stmtIsCreateDb: BooleanPtr): IAttachment; virtual; abstract;
2873+
procedure convert(status: IStatus; sourceType: Cardinal; sourceScale: Cardinal; sourceLength: Cardinal; source: Pointer; targetType: Cardinal; targetScale: Cardinal; targetLength: Cardinal; target: Pointer); virtual; abstract;
28702874
end;
28712875

28722876
OffsetsCallbackVTable = class(VersionedVTable)
@@ -8855,6 +8859,17 @@ function IUtil.executeCreateDatabase2(status: IStatus; stmtLength: Cardinal; cre
88558859
FbException.checkException(status);
88568860
end;
88578861

8862+
procedure IUtil.convert(status: IStatus; sourceType: Cardinal; sourceScale: Cardinal; sourceLength: Cardinal; source: Pointer; targetType: Cardinal; targetScale: Cardinal; targetLength: Cardinal; target: Pointer);
8863+
begin
8864+
if (vTable.version < 6) then begin
8865+
FbException.setVersionError(status, 'IUtil', vTable.version, 6);
8866+
end
8867+
else begin
8868+
UtilVTable(vTable).convert(Self, status, sourceType, sourceScale, sourceLength, source, targetType, targetScale, targetLength, target);
8869+
end;
8870+
FbException.checkException(status);
8871+
end;
8872+
88588873
procedure IOffsetsCallback.setOffset(status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal);
88598874
begin
88608875
OffsetsCallbackVTable(vTable).setOffset(Self, status, index, offset, nullOffset);
@@ -14881,6 +14896,15 @@ function IUtilImpl_executeCreateDatabase2Dispatcher(this: IUtil; status: IStatus
1488114896
end
1488214897
end;
1488314898

14899+
procedure IUtilImpl_convertDispatcher(this: IUtil; status: IStatus; sourceType: Cardinal; sourceScale: Cardinal; sourceLength: Cardinal; source: Pointer; targetType: Cardinal; targetScale: Cardinal; targetLength: Cardinal; target: Pointer); cdecl;
14900+
begin
14901+
try
14902+
IUtilImpl(this).convert(status, sourceType, sourceScale, sourceLength, source, targetType, targetScale, targetLength, target);
14903+
except
14904+
on e: Exception do FbException.catchException(status, e);
14905+
end
14906+
end;
14907+
1488414908
var
1488514909
IUtilImpl_vTable: UtilVTable;
1488614910

@@ -18199,7 +18223,7 @@ initialization
1819918223
IVersionCallbackImpl_vTable.callback := @IVersionCallbackImpl_callbackDispatcher;
1820018224

1820118225
IUtilImpl_vTable := UtilVTable.create;
18202-
IUtilImpl_vTable.version := 5;
18226+
IUtilImpl_vTable.version := 6;
1820318227
IUtilImpl_vTable.getFbVersion := @IUtilImpl_getFbVersionDispatcher;
1820418228
IUtilImpl_vTable.loadBlob := @IUtilImpl_loadBlobDispatcher;
1820518229
IUtilImpl_vTable.dumpBlob := @IUtilImpl_dumpBlobDispatcher;
@@ -18223,6 +18247,7 @@ initialization
1822318247
IUtilImpl_vTable.decodeTimeTzEx := @IUtilImpl_decodeTimeTzExDispatcher;
1822418248
IUtilImpl_vTable.decodeTimeStampTzEx := @IUtilImpl_decodeTimeStampTzExDispatcher;
1822518249
IUtilImpl_vTable.executeCreateDatabase2 := @IUtilImpl_executeCreateDatabase2Dispatcher;
18250+
IUtilImpl_vTable.convert := @IUtilImpl_convertDispatcher;
1822618251

1822718252
IOffsetsCallbackImpl_vTable := OffsetsCallbackVTable.create;
1822818253
IOffsetsCallbackImpl_vTable.version := 2;

src/yvalve/YObjects.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,11 @@ class UtilInterface final :
737737
void decodeTimeStampTzEx(Firebird::CheckStatusWrapper* status, const ISC_TIMESTAMP_TZ_EX* timeStampEx,
738738
unsigned* year, unsigned* month, unsigned* day, unsigned* hours, unsigned* minutes, unsigned* seconds,
739739
unsigned* fractions, unsigned timeZoneBufferLength, char* timeZoneBuffer) override;
740+
741+
void convert(Firebird::CheckStatusWrapper* status,
742+
unsigned sourceType, unsigned sourceScale, unsigned sourceLength, const void* source,
743+
unsigned targetType, unsigned targetScale, unsigned targetLength, void* target) override;
744+
740745
};
741746

742747
} // namespace Why

src/yvalve/utl.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,43 @@ void UtilInterface::encodeTimeStampTz(CheckStatusWrapper* status, ISC_TIMESTAMP_
798798
}
799799
}
800800

801+
void UtilInterface::convert(Firebird::CheckStatusWrapper* status,
802+
unsigned sourceType, unsigned sourceScale, unsigned sourceLength, const void* source,
803+
unsigned targetType, unsigned targetScale, unsigned targetLength, void* target)
804+
{
805+
dsc sourceDesc;
806+
memset(&sourceDesc, 0, sizeof(sourceDesc));
807+
sourceDesc.dsc_dtype = fb_utils::sqlTypeToDscType(sourceType);
808+
sourceDesc.dsc_scale = sourceScale;
809+
sourceDesc.dsc_length = sourceLength;
810+
if (sourceDesc.isText())
811+
sourceDesc.setTextType(CS_dynamic);
812+
sourceDesc.dsc_address = (UCHAR*) source;
813+
814+
dsc targetDesc;
815+
memset(&targetDesc, 0, sizeof(targetDesc));
816+
targetDesc.dsc_dtype = fb_utils::sqlTypeToDscType(targetType);
817+
targetDesc.dsc_scale = targetScale;
818+
targetDesc.dsc_length = targetLength;
819+
if (targetDesc.isText())
820+
targetDesc.setTextType(CS_dynamic);
821+
targetDesc.dsc_address = static_cast<UCHAR*>(target);
822+
823+
try
824+
{
825+
CVT_move(&sourceDesc, &targetDesc, 0,
826+
[](const Arg::StatusVector& status)
827+
{
828+
status.raise();
829+
}
830+
);
831+
}
832+
catch (const Exception& ex)
833+
{
834+
ex.stuffException(status);
835+
}
836+
}
837+
801838
ISC_DATE UtilInterface::encodeDate(unsigned year, unsigned month, unsigned day)
802839
{
803840
tm times;

0 commit comments

Comments
 (0)