blob: 962ef54a721c3fb1529f089a8ae720521bed58de [file] [log] [blame]
Jens Geyerd5436f52014-10-03 19:50:38 +02001(*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *)
19
20unit Thrift.Utils;
21
22interface
23
Nick4f5229e2016-04-14 16:43:22 +030024{$IF CompilerVersion >= 23.0}
25 {$LEGACYIFEND ON}
26{$IFEND}
27
Jens Geyerd5436f52014-10-03 19:50:38 +020028uses
Nick4f5229e2016-04-14 16:43:22 +030029{$IF CompilerVersion < 23.0}
Jens Geyer71070432016-01-29 10:08:39 +010030 Classes, Windows, SysUtils, Character, SyncObjs;
Nick4f5229e2016-04-14 16:43:22 +030031{$ELSE}
32 System.Classes, Winapi.Windows, System.SysUtils, System.Character, System.SyncObjs;
33{$IFEND}
Jens Geyerd5436f52014-10-03 19:50:38 +020034
35type
36 IOverlappedHelper = interface
37 ['{A1832EFA-2E02-4884-8F09-F0A0277157FA}']
38 function Overlapped : TOverlapped;
39 function OverlappedPtr : POverlapped;
40 function WaitHandle : THandle;
41 function WaitFor(dwTimeout: DWORD) : DWORD;
42 end;
43
44 TOverlappedHelperImpl = class( TInterfacedObject, IOverlappedHelper)
45 strict protected
46 FOverlapped : TOverlapped;
47 FEvent : TEvent;
48
49 // IOverlappedHelper
50 function Overlapped : TOverlapped;
51 function OverlappedPtr : POverlapped;
52 function WaitHandle : THandle;
53 function WaitFor(dwTimeout: DWORD) : DWORD;
54 public
55 constructor Create;
56 destructor Destroy; override;
57 end;
58
59
Jens Geyerd8bddbc2014-12-14 00:41:33 +010060 Base64Utils = class sealed
61 public
62 class function Encode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer; static;
63 class function Decode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer; static;
64 end;
65
66
Jens Geyer71070432016-01-29 10:08:39 +010067 CharUtils = class sealed
68 public
69 class function IsHighSurrogate( const c : Char) : Boolean; static; inline;
70 class function IsLowSurrogate( const c : Char) : Boolean; static; inline;
71 end;
72
73
74
Jens Geyerd5436f52014-10-03 19:50:38 +020075implementation
76
Jens Geyerd5436f52014-10-03 19:50:38 +020077{ TOverlappedHelperImpl }
78
79constructor TOverlappedHelperImpl.Create;
80begin
81 inherited Create;
82 FillChar( FOverlapped, SizeOf(FOverlapped), 0);
83 FEvent := TEvent.Create( nil, TRUE, FALSE, ''); // always ManualReset, see MSDN
84 FOverlapped.hEvent := FEvent.Handle;
85end;
86
87
88
89destructor TOverlappedHelperImpl.Destroy;
90begin
91 try
92 FOverlapped.hEvent := 0;
93 FreeAndNil( FEvent);
94
95 finally
96 inherited Destroy;
97 end;
98
99end;
100
101
102function TOverlappedHelperImpl.Overlapped : TOverlapped;
103begin
104 result := FOverlapped;
105end;
106
107
108function TOverlappedHelperImpl.OverlappedPtr : POverlapped;
109begin
110 result := @FOverlapped;
111end;
112
113
114function TOverlappedHelperImpl.WaitHandle : THandle;
115begin
116 result := FOverlapped.hEvent;
117end;
118
119
120function TOverlappedHelperImpl.WaitFor( dwTimeout : DWORD) : DWORD;
121begin
122 result := WaitForSingleObject( FOverlapped.hEvent, dwTimeout);
123end;
124
125
Jens Geyerd8bddbc2014-12-14 00:41:33 +0100126{ Base64Utils }
127
128class function Base64Utils.Encode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer;
129const ENCODE_TABLE : PAnsiChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
130begin
131 ASSERT( len in [1..3]);
132 dst[dstOff] := Byte( ENCODE_TABLE[ (src[srcOff] shr 2) and $3F]);
133 case len of
134 3 : begin
135 Inc(dstOff);
136 dst[dstOff] := Byte( ENCODE_TABLE[ ((src[srcOff] shl 4) and $30) or ((src[srcOff + 1] shr 4) and $0F)]);
137 Inc(dstOff);
138 dst[dstOff] := Byte( ENCODE_TABLE[ ((src[srcOff + 1] shl 2) and $3C) or ((src[srcOff + 2] shr 6) and $03)]);
139 Inc(dstOff);
140 dst[dstOff] := Byte( ENCODE_TABLE[ src[srcOff + 2] and $3F]);
141 result := 4;
142 end;
143
144 2 : begin
145 Inc(dstOff);
146 dst[dstOff] := Byte( ENCODE_TABLE[ ((src[srcOff] shl 4) and $30) or ((src[srcOff + 1] shr 4) and $0F)]);
147 Inc(dstOff);
148 dst[dstOff] := Byte( ENCODE_TABLE[ (src[srcOff + 1] shl 2) and $3C]);
149 result := 3;
150 end;
151
152 1 : begin
153 Inc(dstOff);
154 dst[dstOff] := Byte( ENCODE_TABLE[ (src[srcOff] shl 4) and $30]);
155 result := 2;
156 end;
157
158 else
159 ASSERT( FALSE);
Jens Geyer9f9535c2014-12-14 04:16:05 +0100160 result := 0; // because invalid call
Jens Geyerd8bddbc2014-12-14 00:41:33 +0100161 end;
162end;
163
164
165class function Base64Utils.Decode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer;
166const DECODE_TABLE : array[0..$FF] of Integer
167 = ( -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
168 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
169 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
170 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,
171 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
172 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
173 -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
174 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,
175 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
176 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
177 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
178 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
179 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
180 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
181 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
182 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 );
183begin
184 ASSERT( len in [1..4]);
185 result := 1;
186 dst[dstOff] := ((DECODE_TABLE[src[srcOff] and $0FF] shl 2)
187 or (DECODE_TABLE[src[srcOff + 1] and $0FF] shr 4));
188
189 if (len > 2) then begin
190 Inc( result);
191 Inc( dstOff);
192 dst[dstOff] := (((DECODE_TABLE[src[srcOff + 1] and $0FF] shl 4) and $F0)
193 or (DECODE_TABLE[src[srcOff + 2] and $0FF] shr 2));
194
195 if (len > 3) then begin
196 Inc( result);
197 Inc( dstOff);
198 dst[dstOff] := (((DECODE_TABLE[src[srcOff + 2] and $0FF] shl 6) and $C0)
199 or DECODE_TABLE[src[srcOff + 3] and $0FF]);
200 end;
201 end;
202end;
Jens Geyerd5436f52014-10-03 19:50:38 +0200203
204
Jens Geyer71070432016-01-29 10:08:39 +0100205class function CharUtils.IsHighSurrogate( const c : Char) : Boolean;
206begin
207 {$IF RTLVersion >= 28.0} // XE7+
208 result := c.IsHighSurrogate();
209 {$ELSE}
Nick4f5229e2016-04-14 16:43:22 +0300210 {$IF CompilerVersion < 23.0}
211 result := Character.IsHighSurrogate( c);
212 {$ELSE}
213 result := c.IsHighSurrogate;
214 {$IFEND}
Jens Geyer71070432016-01-29 10:08:39 +0100215 {$IFEND}
216end;
217
218
219class function CharUtils.IsLowSurrogate( const c : Char) : Boolean;
220begin
221 {$IF RTLVersion >= 28.0} // XE7+
222 result := c.IsLowSurrogate();
223 {$ELSE}
Nick4f5229e2016-04-14 16:43:22 +0300224 {$IF CompilerVersion < 23.0}
225 result := Character.IsLowSurrogate( c);
226 {$ELSE}
227 result := c.IsLowSurrogate;
228 {$IFEND}
Jens Geyer71070432016-01-29 10:08:39 +0100229 {$IFEND}
230end;
231
232
233
234
Jens Geyerd5436f52014-10-03 19:50:38 +0200235end.