[RTL] Handle RtlReAllocateHeap failure in com_class_add_progid. CID 1223161
[reactos.git] / sdk / lib / rtl / largeint.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/rtl/largeint.c
5 * PURPOSE: Large integer operations
6 * PROGRAMMERS:
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include <rtl.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS *****************************************************************/
17
18 /* HACK: ld is too stupid to understand that we need the functions
19 when we export them, so we force it to be linked this way. */
20 #ifdef __GNUC__
21 #undef RtlUshortByteSwap
22 USHORT FASTCALL RtlUshortByteSwap(USHORT Source);
23 PVOID Dummy = RtlUshortByteSwap;
24 #endif
25
26 /*
27 * @implemented
28 */
29 LARGE_INTEGER
30 NTAPI
31 RtlConvertLongToLargeInteger (
32 LONG SignedInteger
33 )
34 {
35 LARGE_INTEGER RC;
36
37 RC.QuadPart = SignedInteger;
38
39 return RC;
40 }
41
42 /*
43 * @implemented
44 */
45 LARGE_INTEGER
46 NTAPI
47 RtlConvertUlongToLargeInteger (
48 ULONG UnsignedInteger
49 )
50 {
51 LARGE_INTEGER RC;
52
53 RC.QuadPart = UnsignedInteger;
54
55 return RC;
56 }
57
58 /*
59 * @implemented
60 */
61 LARGE_INTEGER
62 NTAPI
63 RtlEnlargedIntegerMultiply (
64 LONG Multiplicand,
65 LONG Multiplier
66 )
67 {
68 LARGE_INTEGER RC;
69
70 RC.QuadPart = (LONGLONG) Multiplicand * Multiplier;
71
72 return RC;
73 }
74
75 /*
76 * @implemented
77 */
78 ULONG
79 NTAPI
80 RtlEnlargedUnsignedDivide (
81 ULARGE_INTEGER Dividend,
82 ULONG Divisor,
83 PULONG Remainder
84 )
85 {
86 if (Remainder)
87 *Remainder = (ULONG)(Dividend.QuadPart % Divisor);
88
89 return (ULONG)(Dividend.QuadPart / Divisor);
90 }
91
92 /*
93 * @implemented
94 */
95 LARGE_INTEGER
96 NTAPI
97 RtlEnlargedUnsignedMultiply (
98 ULONG Multiplicand,
99 ULONG Multiplier
100 )
101 {
102 LARGE_INTEGER RC;
103
104 RC.QuadPart = (ULONGLONG) Multiplicand * Multiplier;
105
106 return RC;
107 }
108
109 /*
110 * @implemented
111 */
112 LARGE_INTEGER
113 NTAPI
114 RtlExtendedIntegerMultiply (
115 LARGE_INTEGER Multiplicand,
116 LONG Multiplier
117 )
118 {
119 LARGE_INTEGER RC;
120
121 RC.QuadPart = Multiplicand.QuadPart * Multiplier;
122
123 return RC;
124 }
125
126 /*
127 * @implemented
128 */
129 LARGE_INTEGER
130 NTAPI
131 RtlExtendedLargeIntegerDivide (
132 LARGE_INTEGER Dividend,
133 ULONG Divisor,
134 PULONG Remainder
135 )
136 {
137 LARGE_INTEGER RC;
138
139 if (Remainder)
140 *Remainder = (ULONG)(Dividend.QuadPart % Divisor);
141
142 RC.QuadPart = Dividend.QuadPart / Divisor;
143
144 return RC;
145 }
146
147
148 /******************************************************************************
149 * RtlExtendedMagicDivide
150 *
151 * Allows replacing a division by a longlong constant with a multiplication by
152 * the inverse constant.
153 *
154 * RETURNS
155 * (Dividend * MagicDivisor) >> (64 + ShiftCount)
156 *
157 * NOTES
158 * If the divisor of a division is constant, the constants MagicDivisor and
159 * shift must be chosen such that
160 * MagicDivisor = 2^(64 + ShiftCount) / Divisor.
161 *
162 * Then we have RtlExtendedMagicDivide(Dividend,MagicDivisor,ShiftCount) ==
163 * Dividend * MagicDivisor / 2^(64 + ShiftCount) == Dividend / Divisor.
164 *
165 * The Parameter MagicDivisor although defined as LONGLONG is used as
166 * ULONGLONG.
167 */
168
169 #define LOWER_32(A) ((A) & 0xffffffff)
170 #define UPPER_32(A) ((A) >> 32)
171
172 /*
173 * @implemented
174 */
175 LARGE_INTEGER NTAPI
176 RtlExtendedMagicDivide (LARGE_INTEGER Dividend,
177 LARGE_INTEGER MagicDivisor,
178 CCHAR ShiftCount)
179 {
180 ULONGLONG dividend_high;
181 ULONGLONG dividend_low;
182 ULONGLONG inverse_divisor_high;
183 ULONGLONG inverse_divisor_low;
184 ULONGLONG ah_bl;
185 ULONGLONG al_bh;
186 LARGE_INTEGER result;
187 BOOLEAN positive;
188
189 if (Dividend.QuadPart < 0)
190 {
191 dividend_high = UPPER_32((ULONGLONG) -Dividend.QuadPart);
192 dividend_low = LOWER_32((ULONGLONG) -Dividend.QuadPart);
193 positive = FALSE;
194 }
195 else
196 {
197 dividend_high = UPPER_32((ULONGLONG) Dividend.QuadPart);
198 dividend_low = LOWER_32((ULONGLONG) Dividend.QuadPart);
199 positive = TRUE;
200 }
201 inverse_divisor_high = UPPER_32((ULONGLONG) MagicDivisor.QuadPart);
202 inverse_divisor_low = LOWER_32((ULONGLONG) MagicDivisor.QuadPart);
203
204 ah_bl = dividend_high * inverse_divisor_low;
205 al_bh = dividend_low * inverse_divisor_high;
206
207 result.QuadPart =
208 (LONGLONG) ((dividend_high * inverse_divisor_high +
209 UPPER_32(ah_bl) +
210 UPPER_32(al_bh) +
211 UPPER_32(LOWER_32(ah_bl) + LOWER_32(al_bh) +
212 UPPER_32(dividend_low * inverse_divisor_low))) >> ShiftCount);
213 if (!positive)
214 {
215 result.QuadPart = -result.QuadPart;
216 }
217
218 return result;
219 }
220
221
222 /*
223 * @implemented
224 */
225 LARGE_INTEGER
226 NTAPI
227 RtlLargeIntegerAdd (
228 LARGE_INTEGER Addend1,
229 LARGE_INTEGER Addend2
230 )
231 {
232 LARGE_INTEGER RC;
233
234 RC.QuadPart = Addend1.QuadPart + Addend2.QuadPart;
235
236 return RC;
237 }
238
239 /*
240 * @implemented
241 */
242 LARGE_INTEGER
243 NTAPI
244 RtlLargeIntegerArithmeticShift (
245 LARGE_INTEGER LargeInteger,
246 CCHAR ShiftCount
247 )
248 {
249 LARGE_INTEGER RC;
250 CHAR Shift;
251
252 Shift = ShiftCount % 64;
253
254 if (Shift < 32)
255 {
256 RC.QuadPart = LargeInteger.QuadPart >> Shift;
257 }
258 else
259 {
260 /* copy the sign bit */
261 RC.u.HighPart = (LargeInteger.u.HighPart & 0x80000000);
262 RC.u.LowPart = LargeInteger.u.HighPart >> Shift;
263 }
264
265 return RC;
266 }
267
268 /*
269 * @implemented
270 */
271 LARGE_INTEGER
272 NTAPI
273 RtlLargeIntegerDivide (
274 LARGE_INTEGER Dividend,
275 LARGE_INTEGER Divisor,
276 PLARGE_INTEGER Remainder
277 )
278 {
279 LARGE_INTEGER RC;
280
281 if (Remainder)
282 Remainder->QuadPart = Dividend.QuadPart % Divisor.QuadPart;
283
284 RC.QuadPart = Dividend.QuadPart / Divisor.QuadPart;
285
286 return RC;
287 }
288
289 /*
290 * @implemented
291 */
292 LARGE_INTEGER
293 NTAPI
294 RtlLargeIntegerNegate (
295 LARGE_INTEGER Subtrahend
296 )
297 {
298 LARGE_INTEGER RC;
299
300 RC.QuadPart = - Subtrahend.QuadPart;
301
302 return RC;
303 }
304
305 /*
306 * @implemented
307 */
308 LARGE_INTEGER
309 NTAPI
310 RtlLargeIntegerShiftLeft (
311 LARGE_INTEGER LargeInteger,
312 CCHAR ShiftCount
313 )
314 {
315 LARGE_INTEGER RC;
316 CCHAR Shift;
317
318 Shift = ShiftCount % 64;
319 RC.QuadPart = LargeInteger.QuadPart << Shift;
320
321 return RC;
322 }
323
324 /*
325 * @implemented
326 */
327 LARGE_INTEGER
328 NTAPI
329 RtlLargeIntegerShiftRight (
330 LARGE_INTEGER LargeInteger,
331 CCHAR ShiftCount
332 )
333 {
334 LARGE_INTEGER RC;
335 CCHAR Shift;
336
337 Shift = ShiftCount % 64;
338 RC.QuadPart = LargeInteger.QuadPart >> Shift;
339
340 return RC;
341 }
342
343 /*
344 * @implemented
345 */
346 LARGE_INTEGER
347 NTAPI
348 RtlLargeIntegerSubtract (
349 LARGE_INTEGER Minuend,
350 LARGE_INTEGER Subtrahend
351 )
352 {
353 LARGE_INTEGER RC;
354
355 RC.QuadPart = Minuend.QuadPart - Subtrahend.QuadPart;
356
357 return RC;
358 }
359
360 /* EOF */