diff options
Diffstat (limited to 'src/jaegertracing/thrift/lib/delphi/src/Thrift.Utils.pas')
-rw-r--r-- | src/jaegertracing/thrift/lib/delphi/src/Thrift.Utils.pas | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/src/jaegertracing/thrift/lib/delphi/src/Thrift.Utils.pas b/src/jaegertracing/thrift/lib/delphi/src/Thrift.Utils.pas new file mode 100644 index 000000000..ede265646 --- /dev/null +++ b/src/jaegertracing/thrift/lib/delphi/src/Thrift.Utils.pas @@ -0,0 +1,336 @@ +(* + * 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. + *) + +unit Thrift.Utils; + +interface + +{$I Thrift.Defines.inc} + +uses + {$IFDEF OLD_UNIT_NAMES} + Classes, Windows, SysUtils, Character, SyncObjs, TypInfo, Rtti; + {$ELSE} + System.Classes, Winapi.Windows, System.SysUtils, System.Character, + System.SyncObjs, System.TypInfo, System.Rtti; + {$ENDIF} + +type + ISupportsToString = interface + ['{AF71C350-E0CD-4E94-B77C-0310DC8227FF}'] + function ToString : string; + end; + + + IOverlappedHelper = interface + ['{A1832EFA-2E02-4884-8F09-F0A0277157FA}'] + function Overlapped : TOverlapped; + function OverlappedPtr : POverlapped; + function WaitHandle : THandle; + function WaitFor(dwTimeout: DWORD) : DWORD; + end; + + TOverlappedHelperImpl = class( TInterfacedObject, IOverlappedHelper) + strict protected + FOverlapped : TOverlapped; + FEvent : TEvent; + + // IOverlappedHelper + function Overlapped : TOverlapped; + function OverlappedPtr : POverlapped; + function WaitHandle : THandle; + function WaitFor(dwTimeout: DWORD) : DWORD; + public + constructor Create; + destructor Destroy; override; + end; + + + TThriftStringBuilder = class( TStringBuilder) + public + function Append(const Value: TBytes): TStringBuilder; overload; + function Append(const Value: ISupportsToString): TStringBuilder; overload; + end; + + + Base64Utils = class sealed + public + class function Encode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer; static; + class function Decode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer; static; + end; + + + CharUtils = class sealed + public + class function IsHighSurrogate( const c : Char) : Boolean; static; inline; + class function IsLowSurrogate( const c : Char) : Boolean; static; inline; + end; + + EnumUtils<T> = class sealed + public + class function ToString(const value : Integer) : string; reintroduce; static; inline; + end; + + StringUtils<T> = class sealed + public + class function ToString(const value : T) : string; reintroduce; static; inline; + end; + + +const + THRIFT_MIMETYPE = 'application/x-thrift'; + +{$IFDEF Win64} +function InterlockedExchangeAdd64( var Addend : Int64; Value : Int64) : Int64; +{$ENDIF} + + +implementation + +{ TOverlappedHelperImpl } + +constructor TOverlappedHelperImpl.Create; +begin + inherited Create; + FillChar( FOverlapped, SizeOf(FOverlapped), 0); + FEvent := TEvent.Create( nil, TRUE, FALSE, ''); // always ManualReset, see MSDN + FOverlapped.hEvent := FEvent.Handle; +end; + + + +destructor TOverlappedHelperImpl.Destroy; +begin + try + FOverlapped.hEvent := 0; + FreeAndNil( FEvent); + + finally + inherited Destroy; + end; + +end; + + +function TOverlappedHelperImpl.Overlapped : TOverlapped; +begin + result := FOverlapped; +end; + + +function TOverlappedHelperImpl.OverlappedPtr : POverlapped; +begin + result := @FOverlapped; +end; + + +function TOverlappedHelperImpl.WaitHandle : THandle; +begin + result := FOverlapped.hEvent; +end; + + +function TOverlappedHelperImpl.WaitFor( dwTimeout : DWORD) : DWORD; +begin + result := WaitForSingleObject( FOverlapped.hEvent, dwTimeout); +end; + + +{ Base64Utils } + +class function Base64Utils.Encode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer; +const ENCODE_TABLE : PAnsiChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +begin + ASSERT( len in [1..3]); + dst[dstOff] := Byte( ENCODE_TABLE[ (src[srcOff] shr 2) and $3F]); + case len of + 3 : begin + Inc(dstOff); + dst[dstOff] := Byte( ENCODE_TABLE[ ((src[srcOff] shl 4) and $30) or ((src[srcOff + 1] shr 4) and $0F)]); + Inc(dstOff); + dst[dstOff] := Byte( ENCODE_TABLE[ ((src[srcOff + 1] shl 2) and $3C) or ((src[srcOff + 2] shr 6) and $03)]); + Inc(dstOff); + dst[dstOff] := Byte( ENCODE_TABLE[ src[srcOff + 2] and $3F]); + result := 4; + end; + + 2 : begin + Inc(dstOff); + dst[dstOff] := Byte( ENCODE_TABLE[ ((src[srcOff] shl 4) and $30) or ((src[srcOff + 1] shr 4) and $0F)]); + Inc(dstOff); + dst[dstOff] := Byte( ENCODE_TABLE[ (src[srcOff + 1] shl 2) and $3C]); + result := 3; + end; + + 1 : begin + Inc(dstOff); + dst[dstOff] := Byte( ENCODE_TABLE[ (src[srcOff] shl 4) and $30]); + result := 2; + end; + + else + ASSERT( FALSE); + result := 0; // because invalid call + end; +end; + + +class function Base64Utils.Decode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer; +const DECODE_TABLE : array[0..$FF] of Integer + = ( -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, + 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, + 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, + -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, + 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ); +begin + ASSERT( len in [1..4]); + result := 1; + dst[dstOff] := ((DECODE_TABLE[src[srcOff] and $0FF] shl 2) + or (DECODE_TABLE[src[srcOff + 1] and $0FF] shr 4)); + + if (len > 2) then begin + Inc( result); + Inc( dstOff); + dst[dstOff] := (((DECODE_TABLE[src[srcOff + 1] and $0FF] shl 4) and $F0) + or (DECODE_TABLE[src[srcOff + 2] and $0FF] shr 2)); + + if (len > 3) then begin + Inc( result); + Inc( dstOff); + dst[dstOff] := (((DECODE_TABLE[src[srcOff + 2] and $0FF] shl 6) and $C0) + or DECODE_TABLE[src[srcOff + 3] and $0FF]); + end; + end; +end; + + +class function CharUtils.IsHighSurrogate( const c : Char) : Boolean; +begin + {$IF CompilerVersion < 25.0} + {$IFDEF OLD_UNIT_NAMES} + result := Character.IsHighSurrogate(c); + {$ELSE} + result := System.Character.IsHighSurrogate(c); + {$ENDIF} + {$ELSE} + result := c.IsHighSurrogate(); + {$IFEND} +end; + + +class function CharUtils.IsLowSurrogate( const c : Char) : Boolean; +begin + {$IF CompilerVersion < 25.0} + {$IFDEF OLD_UNIT_NAMES} + result := Character.IsLowSurrogate(c); + {$ELSE} + result := System.Character.IsLowSurrogate(c); + {$ENDIF} + {$ELSE} + result := c.IsLowSurrogate(); + {$IFEND} +end; + + +{$IFDEF Win64} + +function InterlockedCompareExchange64( var Target : Int64; Exchange, Comparand : Int64) : Int64; inline; +begin + {$IFDEF OLD_UNIT_NAMES} + result := Windows.InterlockedCompareExchange64( Target, Exchange, Comparand); + {$ELSE} + result := WinApi.Windows.InterlockedCompareExchange64( Target, Exchange, Comparand); + {$ENDIF} +end; + + +function InterlockedExchangeAdd64( var Addend : Int64; Value : Int64) : Int64; +var old : Int64; +begin + repeat + Old := Addend; + until (InterlockedCompareExchange64( Addend, Old + Value, Old) = Old); + result := Old; +end; + +{$ENDIF} + + +{ EnumUtils<T> } + +class function EnumUtils<T>.ToString(const value : Integer) : string; +var pType : PTypeInfo; +begin + pType := PTypeInfo(TypeInfo(T)); + if Assigned(pType) and (pType^.Kind = tkEnumeration) + then result := GetEnumName(pType,value) + else result := IntToStr(Ord(value)); +end; + + +{ StringUtils<T> } + +class function StringUtils<T>.ToString(const value : T) : string; +type PInterface = ^IInterface; +var pType : PTypeInfo; + stos : ISupportsToString; + pIntf : PInterface; // Workaround: Rio does not allow the direct typecast +begin + pType := PTypeInfo(TypeInfo(T)); + if Assigned(pType) then begin + case pType^.Kind of + tkInterface : begin + pIntf := PInterface(@value); + if Supports( pIntf^, ISupportsToString, stos) then begin + result := stos.toString; + Exit; + end; + end; + end; + end; + + result := TValue.From<T>(value).ToString; +end; + + +{ TThriftStringBuilder } + +function TThriftStringBuilder.Append(const Value: TBytes): TStringBuilder; +begin + Result := Append( string( RawByteString(Value)) ); +end; + +function TThriftStringBuilder.Append( const Value: ISupportsToString): TStringBuilder; +begin + Result := Append( Value.ToString ); +end; + + +end. |