Skip to content

Commit 98e861a

Browse files
authored
Backport feature #8761 - Add API method Util::convert (#8897)
1 parent a44b888 commit 98e861a

5 files changed

Lines changed: 103 additions & 3 deletions

File tree

src/include/firebird/FirebirdInterface.idl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,10 @@ version: // 4.0 Beta1 => 4.0 Beta2
12191219
uint* fractions, uint timeZoneBufferLength, string timeZoneBuffer);
12201220
void decodeTimeStampTzEx(Status status, const ISC_TIMESTAMP_TZ_EX* timeStampTz, uint* year, uint* month, uint* day,
12211221
uint* hours, uint* minutes, uint* seconds, uint* fractions, uint timeZoneBufferLength, string timeZoneBuffer);
1222+
1223+
version: // 4.0.6 => 4.0.7
1224+
void convert(Status status, uint sourceType, uint sourceScale, uint sourceLength, const void* source,
1225+
uint targetType, uint targetScale, uint targetLength, void* target);
12221226
}
12231227

12241228
interface OffsetsCallback : Versioned

src/include/firebird/IdlFbInterfaces.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4542,6 +4542,7 @@ namespace Firebird
45424542
IInt128* (CLOOP_CARG *getInt128)(IUtil* self, IStatus* status) throw();
45434543
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) throw();
45444544
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) throw();
4545+
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) throw();
45454546
};
45464547

45474548
protected:
@@ -4555,7 +4556,7 @@ namespace Firebird
45554556
}
45564557

45574558
public:
4558-
static const unsigned VERSION = 4;
4559+
static const unsigned VERSION = 5;
45594560

45604561
template <typename StatusType> void getFbVersion(StatusType* status, IAttachment* att, IVersionCallback* callback)
45614562
{
@@ -4762,6 +4763,19 @@ namespace Firebird
47624763
static_cast<VTable*>(this->cloopVTable)->decodeTimeStampTzEx(this, status, timeStampTz, year, month, day, hours, minutes, seconds, fractions, timeZoneBufferLength, timeZoneBuffer);
47634764
StatusType::checkException(status);
47644765
}
4766+
4767+
template <typename StatusType> void convert(StatusType* status, unsigned sourceType, unsigned sourceScale, unsigned sourceLength, const void* source, unsigned targetType, unsigned targetScale, unsigned targetLength, void* target)
4768+
{
4769+
if (cloopVTable->version < 5)
4770+
{
4771+
StatusType::setVersionError(status, "IUtil", cloopVTable->version, 5);
4772+
StatusType::checkException(status);
4773+
return;
4774+
}
4775+
StatusType::clearException(status);
4776+
static_cast<VTable*>(this->cloopVTable)->convert(this, status, sourceType, sourceScale, sourceLength, source, targetType, targetScale, targetLength, target);
4777+
StatusType::checkException(status);
4778+
}
47654779
};
47664780

47674781
class IOffsetsCallback : public IVersioned
@@ -15457,6 +15471,7 @@ namespace Firebird
1545715471
this->getInt128 = &Name::cloopgetInt128Dispatcher;
1545815472
this->decodeTimeTzEx = &Name::cloopdecodeTimeTzExDispatcher;
1545915473
this->decodeTimeStampTzEx = &Name::cloopdecodeTimeStampTzExDispatcher;
15474+
this->convert = &Name::cloopconvertDispatcher;
1546015475
}
1546115476
} vTable;
1546215477

@@ -15768,6 +15783,20 @@ namespace Firebird
1576815783
StatusType::catchException(&status2);
1576915784
}
1577015785
}
15786+
15787+
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) throw()
15788+
{
15789+
StatusType status2(status);
15790+
15791+
try
15792+
{
15793+
static_cast<Name*>(self)->Name::convert(&status2, sourceType, sourceScale, sourceLength, source, targetType, targetScale, targetLength, target);
15794+
}
15795+
catch (...)
15796+
{
15797+
StatusType::catchException(&status2);
15798+
}
15799+
}
1577115800
};
1577215801

1577315802
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IUtil> > >
@@ -15805,6 +15834,7 @@ namespace Firebird
1580515834
virtual IInt128* getInt128(StatusType* status) = 0;
1580615835
virtual void decodeTimeTzEx(StatusType* status, const ISC_TIME_TZ_EX* timeTz, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions, unsigned timeZoneBufferLength, char* timeZoneBuffer) = 0;
1580715836
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;
15837+
virtual void convert(StatusType* status, unsigned sourceType, unsigned sourceScale, unsigned sourceLength, const void* source, unsigned targetType, unsigned targetScale, unsigned targetLength, void* target) = 0;
1580815838
};
1580915839

1581015840
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
@@ -557,6 +557,7 @@ ISC_TIMESTAMP_TZ_EX = record
557557
IUtil_getInt128Ptr = function(this: IUtil; status: IStatus): IInt128; cdecl;
558558
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;
559559
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;
560+
IUtil_convertPtr = procedure(this: IUtil; status: IStatus; sourceType: Cardinal; sourceScale: Cardinal; sourceLength: Cardinal; source: Pointer; targetType: Cardinal; targetScale: Cardinal; targetLength: Cardinal; target: Pointer); cdecl;
560561
IOffsetsCallback_setOffsetPtr = procedure(this: IOffsetsCallback; status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal); cdecl;
561562
IXpbBuilder_clearPtr = procedure(this: IXpbBuilder; status: IStatus); cdecl;
562563
IXpbBuilder_removeCurrentPtr = procedure(this: IXpbBuilder; status: IStatus); cdecl;
@@ -2723,10 +2724,11 @@ UtilVTable = class(VersionedVTable)
27232724
getInt128: IUtil_getInt128Ptr;
27242725
decodeTimeTzEx: IUtil_decodeTimeTzExPtr;
27252726
decodeTimeStampTzEx: IUtil_decodeTimeStampTzExPtr;
2727+
convert: IUtil_convertPtr;
27262728
end;
27272729

27282730
IUtil = class(IVersioned)
2729-
const VERSION = 4;
2731+
const VERSION = 5;
27302732

27312733
procedure getFbVersion(status: IStatus; att: IAttachment; callback: IVersionCallback);
27322734
procedure loadBlob(status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean);
@@ -2750,6 +2752,7 @@ IUtil = class(IVersioned)
27502752
function getInt128(status: IStatus): IInt128;
27512753
procedure decodeTimeTzEx(status: IStatus; timeTz: ISC_TIME_TZ_EXPtr; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr; timeZoneBufferLength: Cardinal; timeZoneBuffer: PAnsiChar);
27522754
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);
2755+
procedure convert(status: IStatus; sourceType: Cardinal; sourceScale: Cardinal; sourceLength: Cardinal; source: Pointer; targetType: Cardinal; targetScale: Cardinal; targetLength: Cardinal; target: Pointer);
27532756
end;
27542757

27552758
IUtilImpl = class(IUtil)
@@ -2777,6 +2780,7 @@ IUtilImpl = class(IUtil)
27772780
function getInt128(status: IStatus): IInt128; virtual; abstract;
27782781
procedure decodeTimeTzEx(status: IStatus; timeTz: ISC_TIME_TZ_EXPtr; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr; timeZoneBufferLength: Cardinal; timeZoneBuffer: PAnsiChar); virtual; abstract;
27792782
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;
2783+
procedure convert(status: IStatus; sourceType: Cardinal; sourceScale: Cardinal; sourceLength: Cardinal; source: Pointer; targetType: Cardinal; targetScale: Cardinal; targetLength: Cardinal; target: Pointer); virtual; abstract;
27802784
end;
27812785

27822786
OffsetsCallbackVTable = class(VersionedVTable)
@@ -8383,6 +8387,17 @@ procedure IUtil.decodeTimeStampTzEx(status: IStatus; timeStampTz: ISC_TIMESTAMP_
83838387
FbException.checkException(status);
83848388
end;
83858389

8390+
procedure IUtil.convert(status: IStatus; sourceType: Cardinal; sourceScale: Cardinal; sourceLength: Cardinal; source: Pointer; targetType: Cardinal; targetScale: Cardinal; targetLength: Cardinal; target: Pointer);
8391+
begin
8392+
if (vTable.version < 5) then begin
8393+
FbException.setVersionError(status, 'IUtil', vTable.version, 5);
8394+
end
8395+
else begin
8396+
UtilVTable(vTable).convert(Self, status, sourceType, sourceScale, sourceLength, source, targetType, targetScale, targetLength, target);
8397+
end;
8398+
FbException.checkException(status);
8399+
end;
8400+
83868401
procedure IOffsetsCallback.setOffset(status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal);
83878402
begin
83888403
OffsetsCallbackVTable(vTable).setOffset(Self, status, index, offset, nullOffset);
@@ -14013,6 +14028,15 @@ procedure IUtilImpl_decodeTimeStampTzExDispatcher(this: IUtil; status: IStatus;
1401314028
end
1401414029
end;
1401514030

14031+
procedure IUtilImpl_convertDispatcher(this: IUtil; status: IStatus; sourceType: Cardinal; sourceScale: Cardinal; sourceLength: Cardinal; source: Pointer; targetType: Cardinal; targetScale: Cardinal; targetLength: Cardinal; target: Pointer); cdecl;
14032+
begin
14033+
try
14034+
IUtilImpl(this).convert(status, sourceType, sourceScale, sourceLength, source, targetType, targetScale, targetLength, target);
14035+
except
14036+
on e: Exception do FbException.catchException(status, e);
14037+
end
14038+
end;
14039+
1401614040
var
1401714041
IUtilImpl_vTable: UtilVTable;
1401814042

@@ -16901,7 +16925,7 @@ initialization
1690116925
IVersionCallbackImpl_vTable.callback := @IVersionCallbackImpl_callbackDispatcher;
1690216926

1690316927
IUtilImpl_vTable := UtilVTable.create;
16904-
IUtilImpl_vTable.version := 4;
16928+
IUtilImpl_vTable.version := 5;
1690516929
IUtilImpl_vTable.getFbVersion := @IUtilImpl_getFbVersionDispatcher;
1690616930
IUtilImpl_vTable.loadBlob := @IUtilImpl_loadBlobDispatcher;
1690716931
IUtilImpl_vTable.dumpBlob := @IUtilImpl_dumpBlobDispatcher;
@@ -16924,6 +16948,7 @@ initialization
1692416948
IUtilImpl_vTable.getInt128 := @IUtilImpl_getInt128Dispatcher;
1692516949
IUtilImpl_vTable.decodeTimeTzEx := @IUtilImpl_decodeTimeTzExDispatcher;
1692616950
IUtilImpl_vTable.decodeTimeStampTzEx := @IUtilImpl_decodeTimeStampTzExDispatcher;
16951+
IUtilImpl_vTable.convert := @IUtilImpl_convertDispatcher;
1692716952

1692816953
IOffsetsCallbackImpl_vTable := OffsetsCallbackVTable.create;
1692916954
IOffsetsCallbackImpl_vTable.version := 2;

src/yvalve/YObjects.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,10 @@ class UtilInterface FB_FINAL :
708708
void decodeTimeStampTzEx(Firebird::CheckStatusWrapper* status, const ISC_TIMESTAMP_TZ_EX* timeStampEx,
709709
unsigned* year, unsigned* month, unsigned* day, unsigned* hours, unsigned* minutes, unsigned* seconds,
710710
unsigned* fractions, unsigned timeZoneBufferLength, char* timeZoneBuffer);
711+
712+
void convert(Firebird::CheckStatusWrapper* status,
713+
unsigned sourceType, unsigned sourceScale, unsigned sourceLength, const void* source,
714+
unsigned targetType, unsigned targetScale, unsigned targetLength, void* target);
711715
};
712716

713717
} // namespace Why

src/yvalve/utl.cpp

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

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

0 commit comments

Comments
 (0)