blob: 17131ef5175f6849ead02c78df397131a10aae11 [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
24uses
Jens Geyer71070432016-01-29 10:08:39 +010025 Classes, Windows, SysUtils, Character, SyncObjs;
Jens Geyerd5436f52014-10-03 19:50:38 +020026
27type
28 IOverlappedHelper = interface
29 ['{A1832EFA-2E02-4884-8F09-F0A0277157FA}']
30 function Overlapped : TOverlapped;
31 function OverlappedPtr : POverlapped;
32 function WaitHandle : THandle;
33 function WaitFor(dwTimeout: DWORD) : DWORD;
34 end;
35
36 TOverlappedHelperImpl = class( TInterfacedObject, IOverlappedHelper)
37 strict protected
38 FOverlapped : TOverlapped;
39 FEvent : TEvent;
40
41 // IOverlappedHelper
42 function Overlapped : TOverlapped;
43 function OverlappedPtr : POverlapped;
44 function WaitHandle : THandle;
45 function WaitFor(dwTimeout: DWORD) : DWORD;
46 public
47 constructor Create;
48 destructor Destroy; override;
49 end;
50
51
Jens Geyerd8bddbc2014-12-14 00:41:33 +010052 Base64Utils = class sealed
53 public
54 class function Encode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer; static;
55 class function Decode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer; static;
56 end;
57
58
Jens Geyer71070432016-01-29 10:08:39 +010059 CharUtils = class sealed
60 public
61 class function IsHighSurrogate( const c : Char) : Boolean; static; inline;
62 class function IsLowSurrogate( const c : Char) : Boolean; static; inline;
63 end;
64
65
66
Jens Geyerd5436f52014-10-03 19:50:38 +020067implementation
68
Jens Geyerd5436f52014-10-03 19:50:38 +020069{ TOverlappedHelperImpl }
70
71constructor TOverlappedHelperImpl.Create;
72begin
73 inherited Create;
74 FillChar( FOverlapped, SizeOf(FOverlapped), 0);
75 FEvent := TEvent.Create( nil, TRUE, FALSE, ''); // always ManualReset, see MSDN
76 FOverlapped.hEvent := FEvent.Handle;
77end;
78
79
80
81destructor TOverlappedHelperImpl.Destroy;
82begin
83 try
84 FOverlapped.hEvent := 0;
85 FreeAndNil( FEvent);
86
87 finally
88 inherited Destroy;
89 end;
90
91end;
92
93
94function TOverlappedHelperImpl.Overlapped : TOverlapped;
95begin
96 result := FOverlapped;
97end;
98
99
100function TOverlappedHelperImpl.OverlappedPtr : POverlapped;
101begin
102 result := @FOverlapped;
103end;
104
105
106function TOverlappedHelperImpl.WaitHandle : THandle;
107begin
108 result := FOverlapped.hEvent;
109end;
110
111
112function TOverlappedHelperImpl.WaitFor( dwTimeout : DWORD) : DWORD;
113begin
114 result := WaitForSingleObject( FOverlapped.hEvent, dwTimeout);
115end;
116
117
Jens Geyerd8bddbc2014-12-14 00:41:33 +0100118{ Base64Utils }
119
120class function Base64Utils.Encode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer;
121const ENCODE_TABLE : PAnsiChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
122begin
123 ASSERT( len in [1..3]);
124 dst[dstOff] := Byte( ENCODE_TABLE[ (src[srcOff] shr 2) and $3F]);
125 case len of
126 3 : begin
127 Inc(dstOff);
128 dst[dstOff] := Byte( ENCODE_TABLE[ ((src[srcOff] shl 4) and $30) or ((src[srcOff + 1] shr 4) and $0F)]);
129 Inc(dstOff);
130 dst[dstOff] := Byte( ENCODE_TABLE[ ((src[srcOff + 1] shl 2) and $3C) or ((src[srcOff + 2] shr 6) and $03)]);
131 Inc(dstOff);
132 dst[dstOff] := Byte( ENCODE_TABLE[ src[srcOff + 2] and $3F]);
133 result := 4;
134 end;
135
136 2 : begin
137 Inc(dstOff);
138 dst[dstOff] := Byte( ENCODE_TABLE[ ((src[srcOff] shl 4) and $30) or ((src[srcOff + 1] shr 4) and $0F)]);
139 Inc(dstOff);
140 dst[dstOff] := Byte( ENCODE_TABLE[ (src[srcOff + 1] shl 2) and $3C]);
141 result := 3;
142 end;
143
144 1 : begin
145 Inc(dstOff);
146 dst[dstOff] := Byte( ENCODE_TABLE[ (src[srcOff] shl 4) and $30]);
147 result := 2;
148 end;
149
150 else
151 ASSERT( FALSE);
Jens Geyer9f9535c2014-12-14 04:16:05 +0100152 result := 0; // because invalid call
Jens Geyerd8bddbc2014-12-14 00:41:33 +0100153 end;
154end;
155
156
157class function Base64Utils.Decode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer;
158const DECODE_TABLE : array[0..$FF] of Integer
159 = ( -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
160 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
161 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
162 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,
163 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
164 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
165 -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
166 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,
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,-1,-1,-1,-1,-1,
170 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
171 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
172 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
173 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
174 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 );
175begin
176 ASSERT( len in [1..4]);
177 result := 1;
178 dst[dstOff] := ((DECODE_TABLE[src[srcOff] and $0FF] shl 2)
179 or (DECODE_TABLE[src[srcOff + 1] and $0FF] shr 4));
180
181 if (len > 2) then begin
182 Inc( result);
183 Inc( dstOff);
184 dst[dstOff] := (((DECODE_TABLE[src[srcOff + 1] and $0FF] shl 4) and $F0)
185 or (DECODE_TABLE[src[srcOff + 2] and $0FF] shr 2));
186
187 if (len > 3) then begin
188 Inc( result);
189 Inc( dstOff);
190 dst[dstOff] := (((DECODE_TABLE[src[srcOff + 2] and $0FF] shl 6) and $C0)
191 or DECODE_TABLE[src[srcOff + 3] and $0FF]);
192 end;
193 end;
194end;
Jens Geyerd5436f52014-10-03 19:50:38 +0200195
196
Jens Geyer71070432016-01-29 10:08:39 +0100197class function CharUtils.IsHighSurrogate( const c : Char) : Boolean;
198begin
199 {$IF RTLVersion >= 28.0} // XE7+
200 result := c.IsHighSurrogate();
201 {$ELSE}
202 result := Character.IsHighSurrogate( c);
203 {$IFEND}
204end;
205
206
207class function CharUtils.IsLowSurrogate( const c : Char) : Boolean;
208begin
209 {$IF RTLVersion >= 28.0} // XE7+
210 result := c.IsLowSurrogate();
211 {$ELSE}
212 result := Character.IsLowSurrogate( c);
213 {$IFEND}
214end;
215
216
217
218
Jens Geyerd5436f52014-10-03 19:50:38 +0200219end.