VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c@ 107675

最後變更 在這個檔案從107675是 99404,由 vboxsync 提交於 2 年 前

Devices/EFI/FirmwareNew: Update to edk2-stable202302 and make it build, bugref:4643

  • 屬性 svn:eol-style 設為 native
檔案大小: 112.5 KB
 
1/** @file
2 This library provides helper functions to prevent integer overflow during
3 type conversion, addition, subtraction, and multiplication.
4
5 Copyright (c) 2017, Microsoft Corporation
6
7 All rights reserved.
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9
10**/
11
12#include <Base.h>
13#include <Library/SafeIntLib.h>
14#include <Library/BaseLib.h>
15
16//
17// Magnitude of MIN_INT64 as expressed by a UINT64 number.
18//
19#define MIN_INT64_MAGNITUDE (((UINT64)(- (MIN_INT64 + 1))) + 1)
20
21//
22// Conversion functions
23//
24// There are three reasons for having conversion functions:
25//
26// 1. We are converting from a signed type to an unsigned type of the same
27// size, or vice-versa.
28//
29// 2. We are converting to a smaller type, and we could therefore possibly
30// overflow.
31//
32// 3. We are converting to a bigger type, and we are signed and the type we are
33// converting to is unsigned.
34//
35
36/**
37 INT8 -> UINT8 conversion
38
39 Converts the value specified by Operand to a value specified by Result type
40 and stores the converted value into the caller allocated output buffer
41 specified by Result. The caller must pass in a Result buffer that is at
42 least as large as the Result type.
43
44 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
45
46 If the conversion results in an overflow or an underflow condition, then
47 Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
48
49 @param[in] Operand Operand to be converted to new type
50 @param[out] Result Pointer to the result of conversion
51
52 @retval RETURN_SUCCESS Successful conversion
53 @retval RETURN_BUFFER_TOO_SMALL Overflow
54 @retval RETURN_INVALID_PARAMETER Result is NULL
55**/
56RETURN_STATUS
57EFIAPI
58SafeInt8ToUint8 (
59 IN INT8 Operand,
60 OUT UINT8 *Result
61 )
62{
63 RETURN_STATUS Status;
64
65 if (Result == NULL) {
66 return RETURN_INVALID_PARAMETER;
67 }
68
69 if (Operand >= 0) {
70 *Result = (UINT8)Operand;
71 Status = RETURN_SUCCESS;
72 } else {
73 *Result = UINT8_ERROR;
74 Status = RETURN_BUFFER_TOO_SMALL;
75 }
76
77 return Status;
78}
79
80/**
81 INT8 -> CHAR8 conversion
82
83 Converts the value specified by Operand to a value specified by Result type
84 and stores the converted value into the caller allocated output buffer
85 specified by Result. The caller must pass in a Result buffer that is at
86 least as large as the Result type.
87
88 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
89
90 If the conversion results in an overflow or an underflow condition, then
91 Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
92
93 @param[in] Operand Operand to be converted to new type
94 @param[out] Result Pointer to the result of conversion
95
96 @retval RETURN_SUCCESS Successful conversion
97 @retval RETURN_BUFFER_TOO_SMALL Overflow
98 @retval RETURN_INVALID_PARAMETER Result is NULL
99**/
100RETURN_STATUS
101EFIAPI
102SafeInt8ToChar8 (
103 IN INT8 Operand,
104 OUT CHAR8 *Result
105 )
106{
107 RETURN_STATUS Status;
108
109 if (Result == NULL) {
110 return RETURN_INVALID_PARAMETER;
111 }
112
113 if (Operand >= 0) {
114 *Result = (CHAR8)Operand;
115 Status = RETURN_SUCCESS;
116 } else {
117 *Result = CHAR8_ERROR;
118 Status = RETURN_BUFFER_TOO_SMALL;
119 }
120
121 return Status;
122}
123
124/**
125 INT8 -> UINT16 conversion
126
127 Converts the value specified by Operand to a value specified by Result type
128 and stores the converted value into the caller allocated output buffer
129 specified by Result. The caller must pass in a Result buffer that is at
130 least as large as the Result type.
131
132 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
133
134 If the conversion results in an overflow or an underflow condition, then
135 Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
136
137 @param[in] Operand Operand to be converted to new type
138 @param[out] Result Pointer to the result of conversion
139
140 @retval RETURN_SUCCESS Successful conversion
141 @retval RETURN_BUFFER_TOO_SMALL Overflow
142 @retval RETURN_INVALID_PARAMETER Result is NULL
143**/
144RETURN_STATUS
145EFIAPI
146SafeInt8ToUint16 (
147 IN INT8 Operand,
148 OUT UINT16 *Result
149 )
150{
151 RETURN_STATUS Status;
152
153 if (Result == NULL) {
154 return RETURN_INVALID_PARAMETER;
155 }
156
157 if (Operand >= 0) {
158 *Result = (UINT16)Operand;
159 Status = RETURN_SUCCESS;
160 } else {
161 *Result = UINT16_ERROR;
162 Status = RETURN_BUFFER_TOO_SMALL;
163 }
164
165 return Status;
166}
167
168/**
169 INT8 -> UINT32 conversion
170
171 Converts the value specified by Operand to a value specified by Result type
172 and stores the converted value into the caller allocated output buffer
173 specified by Result. The caller must pass in a Result buffer that is at
174 least as large as the Result type.
175
176 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
177
178 If the conversion results in an overflow or an underflow condition, then
179 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
180
181 @param[in] Operand Operand to be converted to new type
182 @param[out] Result Pointer to the result of conversion
183
184 @retval RETURN_SUCCESS Successful conversion
185 @retval RETURN_BUFFER_TOO_SMALL Overflow
186 @retval RETURN_INVALID_PARAMETER Result is NULL
187**/
188RETURN_STATUS
189EFIAPI
190SafeInt8ToUint32 (
191 IN INT8 Operand,
192 OUT UINT32 *Result
193 )
194{
195 RETURN_STATUS Status;
196
197 if (Result == NULL) {
198 return RETURN_INVALID_PARAMETER;
199 }
200
201 if (Operand >= 0) {
202 *Result = (UINT32)Operand;
203 Status = RETURN_SUCCESS;
204 } else {
205 *Result = UINT32_ERROR;
206 Status = RETURN_BUFFER_TOO_SMALL;
207 }
208
209 return Status;
210}
211
212/**
213 INT8 -> UINTN conversion
214
215 Converts the value specified by Operand to a value specified by Result type
216 and stores the converted value into the caller allocated output buffer
217 specified by Result. The caller must pass in a Result buffer that is at
218 least as large as the Result type.
219
220 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
221
222 If the conversion results in an overflow or an underflow condition, then
223 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
224
225 @param[in] Operand Operand to be converted to new type
226 @param[out] Result Pointer to the result of conversion
227
228 @retval RETURN_SUCCESS Successful conversion
229 @retval RETURN_BUFFER_TOO_SMALL Overflow
230 @retval RETURN_INVALID_PARAMETER Result is NULL
231**/
232RETURN_STATUS
233EFIAPI
234SafeInt8ToUintn (
235 IN INT8 Operand,
236 OUT UINTN *Result
237 )
238{
239 RETURN_STATUS Status;
240
241 if (Result == NULL) {
242 return RETURN_INVALID_PARAMETER;
243 }
244
245 if (Operand >= 0) {
246 *Result = (UINTN)Operand;
247 Status = RETURN_SUCCESS;
248 } else {
249 *Result = UINTN_ERROR;
250 Status = RETURN_BUFFER_TOO_SMALL;
251 }
252
253 return Status;
254}
255
256/**
257 INT8 -> UINT64 conversion
258
259 Converts the value specified by Operand to a value specified by Result type
260 and stores the converted value into the caller allocated output buffer
261 specified by Result. The caller must pass in a Result buffer that is at
262 least as large as the Result type.
263
264 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
265
266 If the conversion results in an overflow or an underflow condition, then
267 Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
268
269 @param[in] Operand Operand to be converted to new type
270 @param[out] Result Pointer to the result of conversion
271
272 @retval RETURN_SUCCESS Successful conversion
273 @retval RETURN_BUFFER_TOO_SMALL Overflow
274 @retval RETURN_INVALID_PARAMETER Result is NULL
275**/
276RETURN_STATUS
277EFIAPI
278SafeInt8ToUint64 (
279 IN INT8 Operand,
280 OUT UINT64 *Result
281 )
282{
283 RETURN_STATUS Status;
284
285 if (Result == NULL) {
286 return RETURN_INVALID_PARAMETER;
287 }
288
289 if (Operand >= 0) {
290 *Result = (UINT64)Operand;
291 Status = RETURN_SUCCESS;
292 } else {
293 *Result = UINT64_ERROR;
294 Status = RETURN_BUFFER_TOO_SMALL;
295 }
296
297 return Status;
298}
299
300/**
301 UINT8 -> INT8 conversion
302
303 Converts the value specified by Operand to a value specified by Result type
304 and stores the converted value into the caller allocated output buffer
305 specified by Result. The caller must pass in a Result buffer that is at
306 least as large as the Result type.
307
308 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
309
310 If the conversion results in an overflow or an underflow condition, then
311 Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
312
313 @param[in] Operand Operand to be converted to new type
314 @param[out] Result Pointer to the result of conversion
315
316 @retval RETURN_SUCCESS Successful conversion
317 @retval RETURN_BUFFER_TOO_SMALL Overflow
318 @retval RETURN_INVALID_PARAMETER Result is NULL
319**/
320RETURN_STATUS
321EFIAPI
322SafeUint8ToInt8 (
323 IN UINT8 Operand,
324 OUT INT8 *Result
325 )
326{
327 RETURN_STATUS Status;
328
329 if (Result == NULL) {
330 return RETURN_INVALID_PARAMETER;
331 }
332
333 if (Operand <= MAX_INT8) {
334 *Result = (INT8)Operand;
335 Status = RETURN_SUCCESS;
336 } else {
337 *Result = INT8_ERROR;
338 Status = RETURN_BUFFER_TOO_SMALL;
339 }
340
341 return Status;
342}
343
344/**
345 UINT8 -> CHAR8 conversion
346
347 Converts the value specified by Operand to a value specified by Result type
348 and stores the converted value into the caller allocated output buffer
349 specified by Result. The caller must pass in a Result buffer that is at
350 least as large as the Result type.
351
352 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
353
354 If the conversion results in an overflow or an underflow condition, then
355 Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
356
357 @param[in] Operand Operand to be converted to new type
358 @param[out] Result Pointer to the result of conversion
359
360 @retval RETURN_SUCCESS Successful conversion
361 @retval RETURN_BUFFER_TOO_SMALL Overflow
362 @retval RETURN_INVALID_PARAMETER Result is NULL
363**/
364RETURN_STATUS
365EFIAPI
366SafeUint8ToChar8 (
367 IN UINT8 Operand,
368 OUT CHAR8 *Result
369 )
370{
371 RETURN_STATUS Status;
372
373 if (Result == NULL) {
374 return RETURN_INVALID_PARAMETER;
375 }
376
377 if (Operand <= MAX_INT8) {
378 *Result = (CHAR8)Operand;
379 Status = RETURN_SUCCESS;
380 } else {
381 *Result = CHAR8_ERROR;
382 Status = RETURN_BUFFER_TOO_SMALL;
383 }
384
385 return Status;
386}
387
388/**
389 INT16 -> INT8 conversion
390
391 Converts the value specified by Operand to a value specified by Result type
392 and stores the converted value into the caller allocated output buffer
393 specified by Result. The caller must pass in a Result buffer that is at
394 least as large as the Result type.
395
396 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
397
398 If the conversion results in an overflow or an underflow condition, then
399 Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
400
401 @param[in] Operand Operand to be converted to new type
402 @param[out] Result Pointer to the result of conversion
403
404 @retval RETURN_SUCCESS Successful conversion
405 @retval RETURN_BUFFER_TOO_SMALL Overflow
406 @retval RETURN_INVALID_PARAMETER Result is NULL
407**/
408RETURN_STATUS
409EFIAPI
410SafeInt16ToInt8 (
411 IN INT16 Operand,
412 OUT INT8 *Result
413 )
414{
415 RETURN_STATUS Status;
416
417 if (Result == NULL) {
418 return RETURN_INVALID_PARAMETER;
419 }
420
421 if ((Operand >= MIN_INT8) && (Operand <= MAX_INT8)) {
422 *Result = (INT8)Operand;
423 Status = RETURN_SUCCESS;
424 } else {
425 *Result = INT8_ERROR;
426 Status = RETURN_BUFFER_TOO_SMALL;
427 }
428
429 return Status;
430}
431
432/**
433 INT16 -> CHAR8 conversion
434
435 Converts the value specified by Operand to a value specified by Result type
436 and stores the converted value into the caller allocated output buffer
437 specified by Result. The caller must pass in a Result buffer that is at
438 least as large as the Result type.
439
440 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
441
442 If the conversion results in an overflow or an underflow condition, then
443 Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
444
445 @param[in] Operand Operand to be converted to new type
446 @param[out] Result Pointer to the result of conversion
447
448 @retval RETURN_SUCCESS Successful conversion
449 @retval RETURN_BUFFER_TOO_SMALL Overflow
450 @retval RETURN_INVALID_PARAMETER Result is NULL
451**/
452RETURN_STATUS
453EFIAPI
454SafeInt16ToChar8 (
455 IN INT16 Operand,
456 OUT CHAR8 *Result
457 )
458{
459 RETURN_STATUS Status;
460
461 if (Result == NULL) {
462 return RETURN_INVALID_PARAMETER;
463 }
464
465 if ((Operand >= 0) && (Operand <= MAX_INT8)) {
466 *Result = (CHAR8)Operand;
467 Status = RETURN_SUCCESS;
468 } else {
469 *Result = CHAR8_ERROR;
470 Status = RETURN_BUFFER_TOO_SMALL;
471 }
472
473 return Status;
474}
475
476/**
477 INT16 -> UINT8 conversion
478
479 Converts the value specified by Operand to a value specified by Result type
480 and stores the converted value into the caller allocated output buffer
481 specified by Result. The caller must pass in a Result buffer that is at
482 least as large as the Result type.
483
484 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
485
486 If the conversion results in an overflow or an underflow condition, then
487 Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
488
489 @param[in] Operand Operand to be converted to new type
490 @param[out] Result Pointer to the result of conversion
491
492 @retval RETURN_SUCCESS Successful conversion
493 @retval RETURN_BUFFER_TOO_SMALL Overflow
494 @retval RETURN_INVALID_PARAMETER Result is NULL
495**/
496RETURN_STATUS
497EFIAPI
498SafeInt16ToUint8 (
499 IN INT16 Operand,
500 OUT UINT8 *Result
501 )
502{
503 RETURN_STATUS Status;
504
505 if (Result == NULL) {
506 return RETURN_INVALID_PARAMETER;
507 }
508
509 if ((Operand >= 0) && (Operand <= MAX_UINT8)) {
510 *Result = (UINT8)Operand;
511 Status = RETURN_SUCCESS;
512 } else {
513 *Result = UINT8_ERROR;
514 Status = RETURN_BUFFER_TOO_SMALL;
515 }
516
517 return Status;
518}
519
520/**
521 INT16 -> UINT16 conversion
522
523 Converts the value specified by Operand to a value specified by Result type
524 and stores the converted value into the caller allocated output buffer
525 specified by Result. The caller must pass in a Result buffer that is at
526 least as large as the Result type.
527
528 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
529
530 If the conversion results in an overflow or an underflow condition, then
531 Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
532
533 @param[in] Operand Operand to be converted to new type
534 @param[out] Result Pointer to the result of conversion
535
536 @retval RETURN_SUCCESS Successful conversion
537 @retval RETURN_BUFFER_TOO_SMALL Overflow
538 @retval RETURN_INVALID_PARAMETER Result is NULL
539**/
540RETURN_STATUS
541EFIAPI
542SafeInt16ToUint16 (
543 IN INT16 Operand,
544 OUT UINT16 *Result
545 )
546{
547 RETURN_STATUS Status;
548
549 if (Result == NULL) {
550 return RETURN_INVALID_PARAMETER;
551 }
552
553 if (Operand >= 0) {
554 *Result = (UINT16)Operand;
555 Status = RETURN_SUCCESS;
556 } else {
557 *Result = UINT16_ERROR;
558 Status = RETURN_BUFFER_TOO_SMALL;
559 }
560
561 return Status;
562}
563
564/**
565 INT16 -> UINT32 conversion
566
567 Converts the value specified by Operand to a value specified by Result type
568 and stores the converted value into the caller allocated output buffer
569 specified by Result. The caller must pass in a Result buffer that is at
570 least as large as the Result type.
571
572 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
573
574 If the conversion results in an overflow or an underflow condition, then
575 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
576
577 @param[in] Operand Operand to be converted to new type
578 @param[out] Result Pointer to the result of conversion
579
580 @retval RETURN_SUCCESS Successful conversion
581 @retval RETURN_BUFFER_TOO_SMALL Overflow
582 @retval RETURN_INVALID_PARAMETER Result is NULL
583**/
584RETURN_STATUS
585EFIAPI
586SafeInt16ToUint32 (
587 IN INT16 Operand,
588 OUT UINT32 *Result
589 )
590{
591 RETURN_STATUS Status;
592
593 if (Result == NULL) {
594 return RETURN_INVALID_PARAMETER;
595 }
596
597 if (Operand >= 0) {
598 *Result = (UINT32)Operand;
599 Status = RETURN_SUCCESS;
600 } else {
601 *Result = UINT32_ERROR;
602 Status = RETURN_BUFFER_TOO_SMALL;
603 }
604
605 return Status;
606}
607
608/**
609 INT16 -> UINTN conversion
610
611 Converts the value specified by Operand to a value specified by Result type
612 and stores the converted value into the caller allocated output buffer
613 specified by Result. The caller must pass in a Result buffer that is at
614 least as large as the Result type.
615
616 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
617
618 If the conversion results in an overflow or an underflow condition, then
619 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
620
621 @param[in] Operand Operand to be converted to new type
622 @param[out] Result Pointer to the result of conversion
623
624 @retval RETURN_SUCCESS Successful conversion
625 @retval RETURN_BUFFER_TOO_SMALL Overflow
626 @retval RETURN_INVALID_PARAMETER Result is NULL
627**/
628RETURN_STATUS
629EFIAPI
630SafeInt16ToUintn (
631 IN INT16 Operand,
632 OUT UINTN *Result
633 )
634{
635 RETURN_STATUS Status;
636
637 if (Result == NULL) {
638 return RETURN_INVALID_PARAMETER;
639 }
640
641 if (Operand >= 0) {
642 *Result = (UINTN)Operand;
643 Status = RETURN_SUCCESS;
644 } else {
645 *Result = UINTN_ERROR;
646 Status = RETURN_BUFFER_TOO_SMALL;
647 }
648
649 return Status;
650}
651
652/**
653 INT16 -> UINT64 conversion
654
655 Converts the value specified by Operand to a value specified by Result type
656 and stores the converted value into the caller allocated output buffer
657 specified by Result. The caller must pass in a Result buffer that is at
658 least as large as the Result type.
659
660 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
661
662 If the conversion results in an overflow or an underflow condition, then
663 Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
664
665 @param[in] Operand Operand to be converted to new type
666 @param[out] Result Pointer to the result of conversion
667
668 @retval RETURN_SUCCESS Successful conversion
669 @retval RETURN_BUFFER_TOO_SMALL Overflow
670 @retval RETURN_INVALID_PARAMETER Result is NULL
671**/
672RETURN_STATUS
673EFIAPI
674SafeInt16ToUint64 (
675 IN INT16 Operand,
676 OUT UINT64 *Result
677 )
678{
679 RETURN_STATUS Status;
680
681 if (Result == NULL) {
682 return RETURN_INVALID_PARAMETER;
683 }
684
685 if (Operand >= 0) {
686 *Result = (UINT64)Operand;
687 Status = RETURN_SUCCESS;
688 } else {
689 *Result = UINT64_ERROR;
690 Status = RETURN_BUFFER_TOO_SMALL;
691 }
692
693 return Status;
694}
695
696/**
697 UINT16 -> INT8 conversion
698
699 Converts the value specified by Operand to a value specified by Result type
700 and stores the converted value into the caller allocated output buffer
701 specified by Result. The caller must pass in a Result buffer that is at
702 least as large as the Result type.
703
704 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
705
706 If the conversion results in an overflow or an underflow condition, then
707 Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
708
709 @param[in] Operand Operand to be converted to new type
710 @param[out] Result Pointer to the result of conversion
711
712 @retval RETURN_SUCCESS Successful conversion
713 @retval RETURN_BUFFER_TOO_SMALL Overflow
714 @retval RETURN_INVALID_PARAMETER Result is NULL
715**/
716RETURN_STATUS
717EFIAPI
718SafeUint16ToInt8 (
719 IN UINT16 Operand,
720 OUT INT8 *Result
721 )
722{
723 RETURN_STATUS Status;
724
725 if (Result == NULL) {
726 return RETURN_INVALID_PARAMETER;
727 }
728
729 if (Operand <= MAX_INT8) {
730 *Result = (INT8)Operand;
731 Status = RETURN_SUCCESS;
732 } else {
733 *Result = INT8_ERROR;
734 Status = RETURN_BUFFER_TOO_SMALL;
735 }
736
737 return Status;
738}
739
740/**
741 UINT16 -> CHAR8 conversion
742
743 Converts the value specified by Operand to a value specified by Result type
744 and stores the converted value into the caller allocated output buffer
745 specified by Result. The caller must pass in a Result buffer that is at
746 least as large as the Result type.
747
748 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
749
750 If the conversion results in an overflow or an underflow condition, then
751 Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
752
753 @param[in] Operand Operand to be converted to new type
754 @param[out] Result Pointer to the result of conversion
755
756 @retval RETURN_SUCCESS Successful conversion
757 @retval RETURN_BUFFER_TOO_SMALL Overflow
758 @retval RETURN_INVALID_PARAMETER Result is NULL
759**/
760RETURN_STATUS
761EFIAPI
762SafeUint16ToChar8 (
763 IN UINT16 Operand,
764 OUT CHAR8 *Result
765 )
766{
767 RETURN_STATUS Status;
768
769 if (Result == NULL) {
770 return RETURN_INVALID_PARAMETER;
771 }
772
773 if (Operand <= MAX_INT8) {
774 *Result = (INT8)Operand;
775 Status = RETURN_SUCCESS;
776 } else {
777 *Result = CHAR8_ERROR;
778 Status = RETURN_BUFFER_TOO_SMALL;
779 }
780
781 return Status;
782}
783
784/**
785 UINT16 -> UINT8 conversion
786
787 Converts the value specified by Operand to a value specified by Result type
788 and stores the converted value into the caller allocated output buffer
789 specified by Result. The caller must pass in a Result buffer that is at
790 least as large as the Result type.
791
792 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
793
794 If the conversion results in an overflow or an underflow condition, then
795 Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
796
797 @param[in] Operand Operand to be converted to new type
798 @param[out] Result Pointer to the result of conversion
799
800 @retval RETURN_SUCCESS Successful conversion
801 @retval RETURN_BUFFER_TOO_SMALL Overflow
802 @retval RETURN_INVALID_PARAMETER Result is NULL
803**/
804RETURN_STATUS
805EFIAPI
806SafeUint16ToUint8 (
807 IN UINT16 Operand,
808 OUT UINT8 *Result
809 )
810{
811 RETURN_STATUS Status;
812
813 if (Result == NULL) {
814 return RETURN_INVALID_PARAMETER;
815 }
816
817 if (Operand <= MAX_UINT8) {
818 *Result = (UINT8)Operand;
819 Status = RETURN_SUCCESS;
820 } else {
821 *Result = UINT8_ERROR;
822 Status = RETURN_BUFFER_TOO_SMALL;
823 }
824
825 return Status;
826}
827
828/**
829 UINT16 -> INT16 conversion
830
831 Converts the value specified by Operand to a value specified by Result type
832 and stores the converted value into the caller allocated output buffer
833 specified by Result. The caller must pass in a Result buffer that is at
834 least as large as the Result type.
835
836 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
837
838 If the conversion results in an overflow or an underflow condition, then
839 Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
840
841 @param[in] Operand Operand to be converted to new type
842 @param[out] Result Pointer to the result of conversion
843
844 @retval RETURN_SUCCESS Successful conversion
845 @retval RETURN_BUFFER_TOO_SMALL Overflow
846 @retval RETURN_INVALID_PARAMETER Result is NULL
847**/
848RETURN_STATUS
849EFIAPI
850SafeUint16ToInt16 (
851 IN UINT16 Operand,
852 OUT INT16 *Result
853 )
854{
855 RETURN_STATUS Status;
856
857 if (Result == NULL) {
858 return RETURN_INVALID_PARAMETER;
859 }
860
861 if (Operand <= MAX_INT16) {
862 *Result = (INT16)Operand;
863 Status = RETURN_SUCCESS;
864 } else {
865 *Result = INT16_ERROR;
866 Status = RETURN_BUFFER_TOO_SMALL;
867 }
868
869 return Status;
870}
871
872/**
873 INT32 -> INT8 conversion
874
875 Converts the value specified by Operand to a value specified by Result type
876 and stores the converted value into the caller allocated output buffer
877 specified by Result. The caller must pass in a Result buffer that is at
878 least as large as the Result type.
879
880 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
881
882 If the conversion results in an overflow or an underflow condition, then
883 Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
884
885 @param[in] Operand Operand to be converted to new type
886 @param[out] Result Pointer to the result of conversion
887
888 @retval RETURN_SUCCESS Successful conversion
889 @retval RETURN_BUFFER_TOO_SMALL Overflow
890 @retval RETURN_INVALID_PARAMETER Result is NULL
891**/
892RETURN_STATUS
893EFIAPI
894SafeInt32ToInt8 (
895 IN INT32 Operand,
896 OUT INT8 *Result
897 )
898{
899 RETURN_STATUS Status;
900
901 if (Result == NULL) {
902 return RETURN_INVALID_PARAMETER;
903 }
904
905 if ((Operand >= MIN_INT8) && (Operand <= MAX_INT8)) {
906 *Result = (INT8)Operand;
907 Status = RETURN_SUCCESS;
908 } else {
909 *Result = INT8_ERROR;
910 Status = RETURN_BUFFER_TOO_SMALL;
911 }
912
913 return Status;
914}
915
916/**
917 INT32 -> CHAR8 conversion
918
919 Converts the value specified by Operand to a value specified by Result type
920 and stores the converted value into the caller allocated output buffer
921 specified by Result. The caller must pass in a Result buffer that is at
922 least as large as the Result type.
923
924 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
925
926 If the conversion results in an overflow or an underflow condition, then
927 Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
928
929 @param[in] Operand Operand to be converted to new type
930 @param[out] Result Pointer to the result of conversion
931
932 @retval RETURN_SUCCESS Successful conversion
933 @retval RETURN_BUFFER_TOO_SMALL Overflow
934 @retval RETURN_INVALID_PARAMETER Result is NULL
935**/
936RETURN_STATUS
937EFIAPI
938SafeInt32ToChar8 (
939 IN INT32 Operand,
940 OUT CHAR8 *Result
941 )
942{
943 RETURN_STATUS Status;
944
945 if (Result == NULL) {
946 return RETURN_INVALID_PARAMETER;
947 }
948
949 if ((Operand >= 0) && (Operand <= MAX_INT8)) {
950 *Result = (CHAR8)Operand;
951 Status = RETURN_SUCCESS;
952 } else {
953 *Result = CHAR8_ERROR;
954 Status = RETURN_BUFFER_TOO_SMALL;
955 }
956
957 return Status;
958}
959
960/**
961 INT32 -> UINT8 conversion
962
963 Converts the value specified by Operand to a value specified by Result type
964 and stores the converted value into the caller allocated output buffer
965 specified by Result. The caller must pass in a Result buffer that is at
966 least as large as the Result type.
967
968 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
969
970 If the conversion results in an overflow or an underflow condition, then
971 Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
972
973 @param[in] Operand Operand to be converted to new type
974 @param[out] Result Pointer to the result of conversion
975
976 @retval RETURN_SUCCESS Successful conversion
977 @retval RETURN_BUFFER_TOO_SMALL Overflow
978 @retval RETURN_INVALID_PARAMETER Result is NULL
979**/
980RETURN_STATUS
981EFIAPI
982SafeInt32ToUint8 (
983 IN INT32 Operand,
984 OUT UINT8 *Result
985 )
986{
987 RETURN_STATUS Status;
988
989 if (Result == NULL) {
990 return RETURN_INVALID_PARAMETER;
991 }
992
993 if ((Operand >= 0) && (Operand <= MAX_UINT8)) {
994 *Result = (UINT8)Operand;
995 Status = RETURN_SUCCESS;
996 } else {
997 *Result = UINT8_ERROR;
998 Status = RETURN_BUFFER_TOO_SMALL;
999 }
1000
1001 return Status;
1002}
1003
1004/**
1005 INT32 -> INT16 conversion
1006
1007 Converts the value specified by Operand to a value specified by Result type
1008 and stores the converted value into the caller allocated output buffer
1009 specified by Result. The caller must pass in a Result buffer that is at
1010 least as large as the Result type.
1011
1012 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1013
1014 If the conversion results in an overflow or an underflow condition, then
1015 Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1016
1017 @param[in] Operand Operand to be converted to new type
1018 @param[out] Result Pointer to the result of conversion
1019
1020 @retval RETURN_SUCCESS Successful conversion
1021 @retval RETURN_BUFFER_TOO_SMALL Overflow
1022 @retval RETURN_INVALID_PARAMETER Result is NULL
1023**/
1024RETURN_STATUS
1025EFIAPI
1026SafeInt32ToInt16 (
1027 IN INT32 Operand,
1028 OUT INT16 *Result
1029 )
1030{
1031 RETURN_STATUS Status;
1032
1033 if (Result == NULL) {
1034 return RETURN_INVALID_PARAMETER;
1035 }
1036
1037 if ((Operand >= MIN_INT16) && (Operand <= MAX_INT16)) {
1038 *Result = (INT16)Operand;
1039 Status = RETURN_SUCCESS;
1040 } else {
1041 *Result = INT16_ERROR;
1042 Status = RETURN_BUFFER_TOO_SMALL;
1043 }
1044
1045 return Status;
1046}
1047
1048/**
1049 INT32 -> UINT16 conversion
1050
1051 Converts the value specified by Operand to a value specified by Result type
1052 and stores the converted value into the caller allocated output buffer
1053 specified by Result. The caller must pass in a Result buffer that is at
1054 least as large as the Result type.
1055
1056 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1057
1058 If the conversion results in an overflow or an underflow condition, then
1059 Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1060
1061 @param[in] Operand Operand to be converted to new type
1062 @param[out] Result Pointer to the result of conversion
1063
1064 @retval RETURN_SUCCESS Successful conversion
1065 @retval RETURN_BUFFER_TOO_SMALL Overflow
1066 @retval RETURN_INVALID_PARAMETER Result is NULL
1067**/
1068RETURN_STATUS
1069EFIAPI
1070SafeInt32ToUint16 (
1071 IN INT32 Operand,
1072 OUT UINT16 *Result
1073 )
1074{
1075 RETURN_STATUS Status;
1076
1077 if (Result == NULL) {
1078 return RETURN_INVALID_PARAMETER;
1079 }
1080
1081 if ((Operand >= 0) && (Operand <= MAX_UINT16)) {
1082 *Result = (UINT16)Operand;
1083 Status = RETURN_SUCCESS;
1084 } else {
1085 *Result = UINT16_ERROR;
1086 Status = RETURN_BUFFER_TOO_SMALL;
1087 }
1088
1089 return Status;
1090}
1091
1092/**
1093 INT32 -> UINT32 conversion
1094
1095 Converts the value specified by Operand to a value specified by Result type
1096 and stores the converted value into the caller allocated output buffer
1097 specified by Result. The caller must pass in a Result buffer that is at
1098 least as large as the Result type.
1099
1100 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1101
1102 If the conversion results in an overflow or an underflow condition, then
1103 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1104
1105 @param[in] Operand Operand to be converted to new type
1106 @param[out] Result Pointer to the result of conversion
1107
1108 @retval RETURN_SUCCESS Successful conversion
1109 @retval RETURN_BUFFER_TOO_SMALL Overflow
1110 @retval RETURN_INVALID_PARAMETER Result is NULL
1111**/
1112RETURN_STATUS
1113EFIAPI
1114SafeInt32ToUint32 (
1115 IN INT32 Operand,
1116 OUT UINT32 *Result
1117 )
1118{
1119 RETURN_STATUS Status;
1120
1121 if (Result == NULL) {
1122 return RETURN_INVALID_PARAMETER;
1123 }
1124
1125 if (Operand >= 0) {
1126 *Result = (UINT32)Operand;
1127 Status = RETURN_SUCCESS;
1128 } else {
1129 *Result = UINT32_ERROR;
1130 Status = RETURN_BUFFER_TOO_SMALL;
1131 }
1132
1133 return Status;
1134}
1135
1136/**
1137 INT32 -> UINT64 conversion
1138
1139 Converts the value specified by Operand to a value specified by Result type
1140 and stores the converted value into the caller allocated output buffer
1141 specified by Result. The caller must pass in a Result buffer that is at
1142 least as large as the Result type.
1143
1144 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1145
1146 If the conversion results in an overflow or an underflow condition, then
1147 Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1148
1149 @param[in] Operand Operand to be converted to new type
1150 @param[out] Result Pointer to the result of conversion
1151
1152 @retval RETURN_SUCCESS Successful conversion
1153 @retval RETURN_BUFFER_TOO_SMALL Overflow
1154 @retval RETURN_INVALID_PARAMETER Result is NULL
1155**/
1156RETURN_STATUS
1157EFIAPI
1158SafeInt32ToUint64 (
1159 IN INT32 Operand,
1160 OUT UINT64 *Result
1161 )
1162{
1163 RETURN_STATUS Status;
1164
1165 if (Result == NULL) {
1166 return RETURN_INVALID_PARAMETER;
1167 }
1168
1169 if (Operand >= 0) {
1170 *Result = (UINT64)Operand;
1171 Status = RETURN_SUCCESS;
1172 } else {
1173 *Result = UINT64_ERROR;
1174 Status = RETURN_BUFFER_TOO_SMALL;
1175 }
1176
1177 return Status;
1178}
1179
1180/**
1181 UINT32 -> INT8 conversion
1182
1183 Converts the value specified by Operand to a value specified by Result type
1184 and stores the converted value into the caller allocated output buffer
1185 specified by Result. The caller must pass in a Result buffer that is at
1186 least as large as the Result type.
1187
1188 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1189
1190 If the conversion results in an overflow or an underflow condition, then
1191 Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1192
1193 @param[in] Operand Operand to be converted to new type
1194 @param[out] Result Pointer to the result of conversion
1195
1196 @retval RETURN_SUCCESS Successful conversion
1197 @retval RETURN_BUFFER_TOO_SMALL Overflow
1198 @retval RETURN_INVALID_PARAMETER Result is NULL
1199**/
1200RETURN_STATUS
1201EFIAPI
1202SafeUint32ToInt8 (
1203 IN UINT32 Operand,
1204 OUT INT8 *Result
1205 )
1206{
1207 RETURN_STATUS Status;
1208
1209 if (Result == NULL) {
1210 return RETURN_INVALID_PARAMETER;
1211 }
1212
1213 if (Operand <= MAX_INT8) {
1214 *Result = (INT8)Operand;
1215 Status = RETURN_SUCCESS;
1216 } else {
1217 *Result = INT8_ERROR;
1218 Status = RETURN_BUFFER_TOO_SMALL;
1219 }
1220
1221 return Status;
1222}
1223
1224/**
1225 UINT32 -> CHAR8 conversion
1226
1227 Converts the value specified by Operand to a value specified by Result type
1228 and stores the converted value into the caller allocated output buffer
1229 specified by Result. The caller must pass in a Result buffer that is at
1230 least as large as the Result type.
1231
1232 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1233
1234 If the conversion results in an overflow or an underflow condition, then
1235 Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1236
1237 @param[in] Operand Operand to be converted to new type
1238 @param[out] Result Pointer to the result of conversion
1239
1240 @retval RETURN_SUCCESS Successful conversion
1241 @retval RETURN_BUFFER_TOO_SMALL Overflow
1242 @retval RETURN_INVALID_PARAMETER Result is NULL
1243**/
1244RETURN_STATUS
1245EFIAPI
1246SafeUint32ToChar8 (
1247 IN UINT32 Operand,
1248 OUT CHAR8 *Result
1249 )
1250{
1251 RETURN_STATUS Status;
1252
1253 if (Result == NULL) {
1254 return RETURN_INVALID_PARAMETER;
1255 }
1256
1257 if (Operand <= MAX_INT8) {
1258 *Result = (INT8)Operand;
1259 Status = RETURN_SUCCESS;
1260 } else {
1261 *Result = CHAR8_ERROR;
1262 Status = RETURN_BUFFER_TOO_SMALL;
1263 }
1264
1265 return Status;
1266}
1267
1268/**
1269 UINT32 -> UINT8 conversion
1270
1271 Converts the value specified by Operand to a value specified by Result type
1272 and stores the converted value into the caller allocated output buffer
1273 specified by Result. The caller must pass in a Result buffer that is at
1274 least as large as the Result type.
1275
1276 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1277
1278 If the conversion results in an overflow or an underflow condition, then
1279 Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1280
1281 @param[in] Operand Operand to be converted to new type
1282 @param[out] Result Pointer to the result of conversion
1283
1284 @retval RETURN_SUCCESS Successful conversion
1285 @retval RETURN_BUFFER_TOO_SMALL Overflow
1286 @retval RETURN_INVALID_PARAMETER Result is NULL
1287**/
1288RETURN_STATUS
1289EFIAPI
1290SafeUint32ToUint8 (
1291 IN UINT32 Operand,
1292 OUT UINT8 *Result
1293 )
1294{
1295 RETURN_STATUS Status;
1296
1297 if (Result == NULL) {
1298 return RETURN_INVALID_PARAMETER;
1299 }
1300
1301 if (Operand <= MAX_UINT8) {
1302 *Result = (UINT8)Operand;
1303 Status = RETURN_SUCCESS;
1304 } else {
1305 *Result = UINT8_ERROR;
1306 Status = RETURN_BUFFER_TOO_SMALL;
1307 }
1308
1309 return Status;
1310}
1311
1312/**
1313 UINT32 -> INT16 conversion
1314
1315 Converts the value specified by Operand to a value specified by Result type
1316 and stores the converted value into the caller allocated output buffer
1317 specified by Result. The caller must pass in a Result buffer that is at
1318 least as large as the Result type.
1319
1320 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1321
1322 If the conversion results in an overflow or an underflow condition, then
1323 Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1324
1325 @param[in] Operand Operand to be converted to new type
1326 @param[out] Result Pointer to the result of conversion
1327
1328 @retval RETURN_SUCCESS Successful conversion
1329 @retval RETURN_BUFFER_TOO_SMALL Overflow
1330 @retval RETURN_INVALID_PARAMETER Result is NULL
1331**/
1332RETURN_STATUS
1333EFIAPI
1334SafeUint32ToInt16 (
1335 IN UINT32 Operand,
1336 OUT INT16 *Result
1337 )
1338{
1339 RETURN_STATUS Status;
1340
1341 if (Result == NULL) {
1342 return RETURN_INVALID_PARAMETER;
1343 }
1344
1345 if (Operand <= MAX_INT16) {
1346 *Result = (INT16)Operand;
1347 Status = RETURN_SUCCESS;
1348 } else {
1349 *Result = INT16_ERROR;
1350 Status = RETURN_BUFFER_TOO_SMALL;
1351 }
1352
1353 return Status;
1354}
1355
1356/**
1357 UINT32 -> UINT16 conversion
1358
1359 Converts the value specified by Operand to a value specified by Result type
1360 and stores the converted value into the caller allocated output buffer
1361 specified by Result. The caller must pass in a Result buffer that is at
1362 least as large as the Result type.
1363
1364 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1365
1366 If the conversion results in an overflow or an underflow condition, then
1367 Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1368
1369 @param[in] Operand Operand to be converted to new type
1370 @param[out] Result Pointer to the result of conversion
1371
1372 @retval RETURN_SUCCESS Successful conversion
1373 @retval RETURN_BUFFER_TOO_SMALL Overflow
1374 @retval RETURN_INVALID_PARAMETER Result is NULL
1375**/
1376RETURN_STATUS
1377EFIAPI
1378SafeUint32ToUint16 (
1379 IN UINT32 Operand,
1380 OUT UINT16 *Result
1381 )
1382{
1383 RETURN_STATUS Status;
1384
1385 if (Result == NULL) {
1386 return RETURN_INVALID_PARAMETER;
1387 }
1388
1389 if (Operand <= MAX_UINT16) {
1390 *Result = (UINT16)Operand;
1391 Status = RETURN_SUCCESS;
1392 } else {
1393 *Result = UINT16_ERROR;
1394 Status = RETURN_BUFFER_TOO_SMALL;
1395 }
1396
1397 return Status;
1398}
1399
1400/**
1401 UINT32 -> INT32 conversion
1402
1403 Converts the value specified by Operand to a value specified by Result type
1404 and stores the converted value into the caller allocated output buffer
1405 specified by Result. The caller must pass in a Result buffer that is at
1406 least as large as the Result type.
1407
1408 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1409
1410 If the conversion results in an overflow or an underflow condition, then
1411 Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1412
1413 @param[in] Operand Operand to be converted to new type
1414 @param[out] Result Pointer to the result of conversion
1415
1416 @retval RETURN_SUCCESS Successful conversion
1417 @retval RETURN_BUFFER_TOO_SMALL Overflow
1418 @retval RETURN_INVALID_PARAMETER Result is NULL
1419**/
1420RETURN_STATUS
1421EFIAPI
1422SafeUint32ToInt32 (
1423 IN UINT32 Operand,
1424 OUT INT32 *Result
1425 )
1426{
1427 RETURN_STATUS Status;
1428
1429 if (Result == NULL) {
1430 return RETURN_INVALID_PARAMETER;
1431 }
1432
1433 if (Operand <= MAX_INT32) {
1434 *Result = (INT32)Operand;
1435 Status = RETURN_SUCCESS;
1436 } else {
1437 *Result = INT32_ERROR;
1438 Status = RETURN_BUFFER_TOO_SMALL;
1439 }
1440
1441 return Status;
1442}
1443
1444/**
1445 INTN -> INT8 conversion
1446
1447 Converts the value specified by Operand to a value specified by Result type
1448 and stores the converted value into the caller allocated output buffer
1449 specified by Result. The caller must pass in a Result buffer that is at
1450 least as large as the Result type.
1451
1452 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1453
1454 If the conversion results in an overflow or an underflow condition, then
1455 Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1456
1457 @param[in] Operand Operand to be converted to new type
1458 @param[out] Result Pointer to the result of conversion
1459
1460 @retval RETURN_SUCCESS Successful conversion
1461 @retval RETURN_BUFFER_TOO_SMALL Overflow
1462 @retval RETURN_INVALID_PARAMETER Result is NULL
1463**/
1464RETURN_STATUS
1465EFIAPI
1466SafeIntnToInt8 (
1467 IN INTN Operand,
1468 OUT INT8 *Result
1469 )
1470{
1471 RETURN_STATUS Status;
1472
1473 if (Result == NULL) {
1474 return RETURN_INVALID_PARAMETER;
1475 }
1476
1477 if ((Operand >= MIN_INT8) && (Operand <= MAX_INT8)) {
1478 *Result = (INT8)Operand;
1479 Status = RETURN_SUCCESS;
1480 } else {
1481 *Result = INT8_ERROR;
1482 Status = RETURN_BUFFER_TOO_SMALL;
1483 }
1484
1485 return Status;
1486}
1487
1488/**
1489 INTN -> CHAR8 conversion
1490
1491 Converts the value specified by Operand to a value specified by Result type
1492 and stores the converted value into the caller allocated output buffer
1493 specified by Result. The caller must pass in a Result buffer that is at
1494 least as large as the Result type.
1495
1496 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1497
1498 If the conversion results in an overflow or an underflow condition, then
1499 Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1500
1501 @param[in] Operand Operand to be converted to new type
1502 @param[out] Result Pointer to the result of conversion
1503
1504 @retval RETURN_SUCCESS Successful conversion
1505 @retval RETURN_BUFFER_TOO_SMALL Overflow
1506 @retval RETURN_INVALID_PARAMETER Result is NULL
1507**/
1508RETURN_STATUS
1509EFIAPI
1510SafeIntnToChar8 (
1511 IN INTN Operand,
1512 OUT CHAR8 *Result
1513 )
1514{
1515 RETURN_STATUS Status;
1516
1517 if (Result == NULL) {
1518 return RETURN_INVALID_PARAMETER;
1519 }
1520
1521 if ((Operand >= 0) && (Operand <= MAX_INT8)) {
1522 *Result = (CHAR8)Operand;
1523 Status = RETURN_SUCCESS;
1524 } else {
1525 *Result = CHAR8_ERROR;
1526 Status = RETURN_BUFFER_TOO_SMALL;
1527 }
1528
1529 return Status;
1530}
1531
1532/**
1533 INTN -> UINT8 conversion
1534
1535 Converts the value specified by Operand to a value specified by Result type
1536 and stores the converted value into the caller allocated output buffer
1537 specified by Result. The caller must pass in a Result buffer that is at
1538 least as large as the Result type.
1539
1540 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1541
1542 If the conversion results in an overflow or an underflow condition, then
1543 Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1544
1545 @param[in] Operand Operand to be converted to new type
1546 @param[out] Result Pointer to the result of conversion
1547
1548 @retval RETURN_SUCCESS Successful conversion
1549 @retval RETURN_BUFFER_TOO_SMALL Overflow
1550 @retval RETURN_INVALID_PARAMETER Result is NULL
1551**/
1552RETURN_STATUS
1553EFIAPI
1554SafeIntnToUint8 (
1555 IN INTN Operand,
1556 OUT UINT8 *Result
1557 )
1558{
1559 RETURN_STATUS Status;
1560
1561 if (Result == NULL) {
1562 return RETURN_INVALID_PARAMETER;
1563 }
1564
1565 if ((Operand >= 0) && (Operand <= MAX_UINT8)) {
1566 *Result = (UINT8)Operand;
1567 Status = RETURN_SUCCESS;
1568 } else {
1569 *Result = UINT8_ERROR;
1570 Status = RETURN_BUFFER_TOO_SMALL;
1571 }
1572
1573 return Status;
1574}
1575
1576/**
1577 INTN -> INT16 conversion
1578
1579 Converts the value specified by Operand to a value specified by Result type
1580 and stores the converted value into the caller allocated output buffer
1581 specified by Result. The caller must pass in a Result buffer that is at
1582 least as large as the Result type.
1583
1584 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1585
1586 If the conversion results in an overflow or an underflow condition, then
1587 Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1588
1589 @param[in] Operand Operand to be converted to new type
1590 @param[out] Result Pointer to the result of conversion
1591
1592 @retval RETURN_SUCCESS Successful conversion
1593 @retval RETURN_BUFFER_TOO_SMALL Overflow
1594 @retval RETURN_INVALID_PARAMETER Result is NULL
1595**/
1596RETURN_STATUS
1597EFIAPI
1598SafeIntnToInt16 (
1599 IN INTN Operand,
1600 OUT INT16 *Result
1601 )
1602{
1603 RETURN_STATUS Status;
1604
1605 if (Result == NULL) {
1606 return RETURN_INVALID_PARAMETER;
1607 }
1608
1609 if ((Operand >= MIN_INT16) && (Operand <= MAX_INT16)) {
1610 *Result = (INT16)Operand;
1611 Status = RETURN_SUCCESS;
1612 } else {
1613 *Result = INT16_ERROR;
1614 Status = RETURN_BUFFER_TOO_SMALL;
1615 }
1616
1617 return Status;
1618}
1619
1620/**
1621 INTN -> UINT16 conversion
1622
1623 Converts the value specified by Operand to a value specified by Result type
1624 and stores the converted value into the caller allocated output buffer
1625 specified by Result. The caller must pass in a Result buffer that is at
1626 least as large as the Result type.
1627
1628 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1629
1630 If the conversion results in an overflow or an underflow condition, then
1631 Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1632
1633 @param[in] Operand Operand to be converted to new type
1634 @param[out] Result Pointer to the result of conversion
1635
1636 @retval RETURN_SUCCESS Successful conversion
1637 @retval RETURN_BUFFER_TOO_SMALL Overflow
1638 @retval RETURN_INVALID_PARAMETER Result is NULL
1639**/
1640RETURN_STATUS
1641EFIAPI
1642SafeIntnToUint16 (
1643 IN INTN Operand,
1644 OUT UINT16 *Result
1645 )
1646{
1647 RETURN_STATUS Status;
1648
1649 if (Result == NULL) {
1650 return RETURN_INVALID_PARAMETER;
1651 }
1652
1653 if ((Operand >= 0) && (Operand <= MAX_UINT16)) {
1654 *Result = (UINT16)Operand;
1655 Status = RETURN_SUCCESS;
1656 } else {
1657 *Result = UINT16_ERROR;
1658 Status = RETURN_BUFFER_TOO_SMALL;
1659 }
1660
1661 return Status;
1662}
1663
1664/**
1665 INTN -> UINTN conversion
1666
1667 Converts the value specified by Operand to a value specified by Result type
1668 and stores the converted value into the caller allocated output buffer
1669 specified by Result. The caller must pass in a Result buffer that is at
1670 least as large as the Result type.
1671
1672 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1673
1674 If the conversion results in an overflow or an underflow condition, then
1675 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1676
1677 @param[in] Operand Operand to be converted to new type
1678 @param[out] Result Pointer to the result of conversion
1679
1680 @retval RETURN_SUCCESS Successful conversion
1681 @retval RETURN_BUFFER_TOO_SMALL Overflow
1682 @retval RETURN_INVALID_PARAMETER Result is NULL
1683**/
1684RETURN_STATUS
1685EFIAPI
1686SafeIntnToUintn (
1687 IN INTN Operand,
1688 OUT UINTN *Result
1689 )
1690{
1691 RETURN_STATUS Status;
1692
1693 if (Result == NULL) {
1694 return RETURN_INVALID_PARAMETER;
1695 }
1696
1697 if (Operand >= 0) {
1698 *Result = (UINTN)Operand;
1699 Status = RETURN_SUCCESS;
1700 } else {
1701 *Result = UINTN_ERROR;
1702 Status = RETURN_BUFFER_TOO_SMALL;
1703 }
1704
1705 return Status;
1706}
1707
1708/**
1709 INTN -> UINT64 conversion
1710
1711 Converts the value specified by Operand to a value specified by Result type
1712 and stores the converted value into the caller allocated output buffer
1713 specified by Result. The caller must pass in a Result buffer that is at
1714 least as large as the Result type.
1715
1716 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1717
1718 If the conversion results in an overflow or an underflow condition, then
1719 Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1720
1721 @param[in] Operand Operand to be converted to new type
1722 @param[out] Result Pointer to the result of conversion
1723
1724 @retval RETURN_SUCCESS Successful conversion
1725 @retval RETURN_BUFFER_TOO_SMALL Overflow
1726 @retval RETURN_INVALID_PARAMETER Result is NULL
1727**/
1728RETURN_STATUS
1729EFIAPI
1730SafeIntnToUint64 (
1731 IN INTN Operand,
1732 OUT UINT64 *Result
1733 )
1734{
1735 RETURN_STATUS Status;
1736
1737 if (Result == NULL) {
1738 return RETURN_INVALID_PARAMETER;
1739 }
1740
1741 if (Operand >= 0) {
1742 *Result = (UINT64)Operand;
1743 Status = RETURN_SUCCESS;
1744 } else {
1745 *Result = UINT64_ERROR;
1746 Status = RETURN_BUFFER_TOO_SMALL;
1747 }
1748
1749 return Status;
1750}
1751
1752/**
1753 UINTN -> INT8 conversion
1754
1755 Converts the value specified by Operand to a value specified by Result type
1756 and stores the converted value into the caller allocated output buffer
1757 specified by Result. The caller must pass in a Result buffer that is at
1758 least as large as the Result type.
1759
1760 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1761
1762 If the conversion results in an overflow or an underflow condition, then
1763 Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1764
1765 @param[in] Operand Operand to be converted to new type
1766 @param[out] Result Pointer to the result of conversion
1767
1768 @retval RETURN_SUCCESS Successful conversion
1769 @retval RETURN_BUFFER_TOO_SMALL Overflow
1770 @retval RETURN_INVALID_PARAMETER Result is NULL
1771**/
1772RETURN_STATUS
1773EFIAPI
1774SafeUintnToInt8 (
1775 IN UINTN Operand,
1776 OUT INT8 *Result
1777 )
1778{
1779 RETURN_STATUS Status;
1780
1781 if (Result == NULL) {
1782 return RETURN_INVALID_PARAMETER;
1783 }
1784
1785 if (Operand <= MAX_INT8) {
1786 *Result = (INT8)Operand;
1787 Status = RETURN_SUCCESS;
1788 } else {
1789 *Result = INT8_ERROR;
1790 Status = RETURN_BUFFER_TOO_SMALL;
1791 }
1792
1793 return Status;
1794}
1795
1796/**
1797 UINTN -> CHAR8 conversion
1798
1799 Converts the value specified by Operand to a value specified by Result type
1800 and stores the converted value into the caller allocated output buffer
1801 specified by Result. The caller must pass in a Result buffer that is at
1802 least as large as the Result type.
1803
1804 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1805
1806 If the conversion results in an overflow or an underflow condition, then
1807 Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1808
1809 @param[in] Operand Operand to be converted to new type
1810 @param[out] Result Pointer to the result of conversion
1811
1812 @retval RETURN_SUCCESS Successful conversion
1813 @retval RETURN_BUFFER_TOO_SMALL Overflow
1814 @retval RETURN_INVALID_PARAMETER Result is NULL
1815**/
1816RETURN_STATUS
1817EFIAPI
1818SafeUintnToChar8 (
1819 IN UINTN Operand,
1820 OUT CHAR8 *Result
1821 )
1822{
1823 RETURN_STATUS Status;
1824
1825 if (Result == NULL) {
1826 return RETURN_INVALID_PARAMETER;
1827 }
1828
1829 if (Operand <= MAX_INT8) {
1830 *Result = (INT8)Operand;
1831 Status = RETURN_SUCCESS;
1832 } else {
1833 *Result = CHAR8_ERROR;
1834 Status = RETURN_BUFFER_TOO_SMALL;
1835 }
1836
1837 return Status;
1838}
1839
1840/**
1841 UINTN -> UINT8 conversion
1842
1843 Converts the value specified by Operand to a value specified by Result type
1844 and stores the converted value into the caller allocated output buffer
1845 specified by Result. The caller must pass in a Result buffer that is at
1846 least as large as the Result type.
1847
1848 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1849
1850 If the conversion results in an overflow or an underflow condition, then
1851 Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1852
1853 @param[in] Operand Operand to be converted to new type
1854 @param[out] Result Pointer to the result of conversion
1855
1856 @retval RETURN_SUCCESS Successful conversion
1857 @retval RETURN_BUFFER_TOO_SMALL Overflow
1858 @retval RETURN_INVALID_PARAMETER Result is NULL
1859**/
1860RETURN_STATUS
1861EFIAPI
1862SafeUintnToUint8 (
1863 IN UINTN Operand,
1864 OUT UINT8 *Result
1865 )
1866{
1867 RETURN_STATUS Status;
1868
1869 if (Result == NULL) {
1870 return RETURN_INVALID_PARAMETER;
1871 }
1872
1873 if (Operand <= MAX_UINT8) {
1874 *Result = (UINT8)Operand;
1875 Status = RETURN_SUCCESS;
1876 } else {
1877 *Result = UINT8_ERROR;
1878 Status = RETURN_BUFFER_TOO_SMALL;
1879 }
1880
1881 return Status;
1882}
1883
1884/**
1885 UINTN -> INT16 conversion
1886
1887 Converts the value specified by Operand to a value specified by Result type
1888 and stores the converted value into the caller allocated output buffer
1889 specified by Result. The caller must pass in a Result buffer that is at
1890 least as large as the Result type.
1891
1892 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1893
1894 If the conversion results in an overflow or an underflow condition, then
1895 Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1896
1897 @param[in] Operand Operand to be converted to new type
1898 @param[out] Result Pointer to the result of conversion
1899
1900 @retval RETURN_SUCCESS Successful conversion
1901 @retval RETURN_BUFFER_TOO_SMALL Overflow
1902 @retval RETURN_INVALID_PARAMETER Result is NULL
1903**/
1904RETURN_STATUS
1905EFIAPI
1906SafeUintnToInt16 (
1907 IN UINTN Operand,
1908 OUT INT16 *Result
1909 )
1910{
1911 RETURN_STATUS Status;
1912
1913 if (Result == NULL) {
1914 return RETURN_INVALID_PARAMETER;
1915 }
1916
1917 if (Operand <= MAX_INT16) {
1918 *Result = (INT16)Operand;
1919 Status = RETURN_SUCCESS;
1920 } else {
1921 *Result = INT16_ERROR;
1922 Status = RETURN_BUFFER_TOO_SMALL;
1923 }
1924
1925 return Status;
1926}
1927
1928/**
1929 UINTN -> UINT16 conversion
1930
1931 Converts the value specified by Operand to a value specified by Result type
1932 and stores the converted value into the caller allocated output buffer
1933 specified by Result. The caller must pass in a Result buffer that is at
1934 least as large as the Result type.
1935
1936 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1937
1938 If the conversion results in an overflow or an underflow condition, then
1939 Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1940
1941 @param[in] Operand Operand to be converted to new type
1942 @param[out] Result Pointer to the result of conversion
1943
1944 @retval RETURN_SUCCESS Successful conversion
1945 @retval RETURN_BUFFER_TOO_SMALL Overflow
1946 @retval RETURN_INVALID_PARAMETER Result is NULL
1947**/
1948RETURN_STATUS
1949EFIAPI
1950SafeUintnToUint16 (
1951 IN UINTN Operand,
1952 OUT UINT16 *Result
1953 )
1954{
1955 RETURN_STATUS Status;
1956
1957 if (Result == NULL) {
1958 return RETURN_INVALID_PARAMETER;
1959 }
1960
1961 if (Operand <= MAX_UINT16) {
1962 *Result = (UINT16)Operand;
1963 Status = RETURN_SUCCESS;
1964 } else {
1965 *Result = UINT16_ERROR;
1966 Status = RETURN_BUFFER_TOO_SMALL;
1967 }
1968
1969 return Status;
1970}
1971
1972/**
1973 UINTN -> INT32 conversion
1974
1975 Converts the value specified by Operand to a value specified by Result type
1976 and stores the converted value into the caller allocated output buffer
1977 specified by Result. The caller must pass in a Result buffer that is at
1978 least as large as the Result type.
1979
1980 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
1981
1982 If the conversion results in an overflow or an underflow condition, then
1983 Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
1984
1985 @param[in] Operand Operand to be converted to new type
1986 @param[out] Result Pointer to the result of conversion
1987
1988 @retval RETURN_SUCCESS Successful conversion
1989 @retval RETURN_BUFFER_TOO_SMALL Overflow
1990 @retval RETURN_INVALID_PARAMETER Result is NULL
1991**/
1992RETURN_STATUS
1993EFIAPI
1994SafeUintnToInt32 (
1995 IN UINTN Operand,
1996 OUT INT32 *Result
1997 )
1998{
1999 RETURN_STATUS Status;
2000
2001 if (Result == NULL) {
2002 return RETURN_INVALID_PARAMETER;
2003 }
2004
2005 if (Operand <= MAX_INT32) {
2006 *Result = (INT32)Operand;
2007 Status = RETURN_SUCCESS;
2008 } else {
2009 *Result = INT32_ERROR;
2010 Status = RETURN_BUFFER_TOO_SMALL;
2011 }
2012
2013 return Status;
2014}
2015
2016/**
2017 UINTN -> INTN conversion
2018
2019 Converts the value specified by Operand to a value specified by Result type
2020 and stores the converted value into the caller allocated output buffer
2021 specified by Result. The caller must pass in a Result buffer that is at
2022 least as large as the Result type.
2023
2024 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2025
2026 If the conversion results in an overflow or an underflow condition, then
2027 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2028
2029 @param[in] Operand Operand to be converted to new type
2030 @param[out] Result Pointer to the result of conversion
2031
2032 @retval RETURN_SUCCESS Successful conversion
2033 @retval RETURN_BUFFER_TOO_SMALL Overflow
2034 @retval RETURN_INVALID_PARAMETER Result is NULL
2035**/
2036RETURN_STATUS
2037EFIAPI
2038SafeUintnToIntn (
2039 IN UINTN Operand,
2040 OUT INTN *Result
2041 )
2042{
2043 RETURN_STATUS Status;
2044
2045 if (Result == NULL) {
2046 return RETURN_INVALID_PARAMETER;
2047 }
2048
2049 if (Operand <= MAX_INTN) {
2050 *Result = (INTN)Operand;
2051 Status = RETURN_SUCCESS;
2052 } else {
2053 *Result = INTN_ERROR;
2054 Status = RETURN_BUFFER_TOO_SMALL;
2055 }
2056
2057 return Status;
2058}
2059
2060/**
2061 INT64 -> INT8 conversion
2062
2063 Converts the value specified by Operand to a value specified by Result type
2064 and stores the converted value into the caller allocated output buffer
2065 specified by Result. The caller must pass in a Result buffer that is at
2066 least as large as the Result type.
2067
2068 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2069
2070 If the conversion results in an overflow or an underflow condition, then
2071 Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2072
2073 @param[in] Operand Operand to be converted to new type
2074 @param[out] Result Pointer to the result of conversion
2075
2076 @retval RETURN_SUCCESS Successful conversion
2077 @retval RETURN_BUFFER_TOO_SMALL Overflow
2078 @retval RETURN_INVALID_PARAMETER Result is NULL
2079**/
2080RETURN_STATUS
2081EFIAPI
2082SafeInt64ToInt8 (
2083 IN INT64 Operand,
2084 OUT INT8 *Result
2085 )
2086{
2087 RETURN_STATUS Status;
2088
2089 if (Result == NULL) {
2090 return RETURN_INVALID_PARAMETER;
2091 }
2092
2093 if ((Operand >= MIN_INT8) && (Operand <= MAX_INT8)) {
2094 *Result = (INT8)Operand;
2095 Status = RETURN_SUCCESS;
2096 } else {
2097 *Result = INT8_ERROR;
2098 Status = RETURN_BUFFER_TOO_SMALL;
2099 }
2100
2101 return Status;
2102}
2103
2104/**
2105 INT64 -> CHAR8 conversion
2106
2107 Converts the value specified by Operand to a value specified by Result type
2108 and stores the converted value into the caller allocated output buffer
2109 specified by Result. The caller must pass in a Result buffer that is at
2110 least as large as the Result type.
2111
2112 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2113
2114 If the conversion results in an overflow or an underflow condition, then
2115 Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2116
2117 @param[in] Operand Operand to be converted to new type
2118 @param[out] Result Pointer to the result of conversion
2119
2120 @retval RETURN_SUCCESS Successful conversion
2121 @retval RETURN_BUFFER_TOO_SMALL Overflow
2122 @retval RETURN_INVALID_PARAMETER Result is NULL
2123**/
2124RETURN_STATUS
2125EFIAPI
2126SafeInt64ToChar8 (
2127 IN INT64 Operand,
2128 OUT CHAR8 *Result
2129 )
2130{
2131 RETURN_STATUS Status;
2132
2133 if (Result == NULL) {
2134 return RETURN_INVALID_PARAMETER;
2135 }
2136
2137 if ((Operand >= 0) && (Operand <= MAX_INT8)) {
2138 *Result = (CHAR8)Operand;
2139 Status = RETURN_SUCCESS;
2140 } else {
2141 *Result = CHAR8_ERROR;
2142 Status = RETURN_BUFFER_TOO_SMALL;
2143 }
2144
2145 return Status;
2146}
2147
2148/**
2149 INT64 -> UINT8 conversion
2150
2151 Converts the value specified by Operand to a value specified by Result type
2152 and stores the converted value into the caller allocated output buffer
2153 specified by Result. The caller must pass in a Result buffer that is at
2154 least as large as the Result type.
2155
2156 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2157
2158 If the conversion results in an overflow or an underflow condition, then
2159 Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2160
2161 @param[in] Operand Operand to be converted to new type
2162 @param[out] Result Pointer to the result of conversion
2163
2164 @retval RETURN_SUCCESS Successful conversion
2165 @retval RETURN_BUFFER_TOO_SMALL Overflow
2166 @retval RETURN_INVALID_PARAMETER Result is NULL
2167**/
2168RETURN_STATUS
2169EFIAPI
2170SafeInt64ToUint8 (
2171 IN INT64 Operand,
2172 OUT UINT8 *Result
2173 )
2174{
2175 RETURN_STATUS Status;
2176
2177 if (Result == NULL) {
2178 return RETURN_INVALID_PARAMETER;
2179 }
2180
2181 if ((Operand >= 0) && (Operand <= MAX_UINT8)) {
2182 *Result = (UINT8)Operand;
2183 Status = RETURN_SUCCESS;
2184 } else {
2185 *Result = UINT8_ERROR;
2186 Status = RETURN_BUFFER_TOO_SMALL;
2187 }
2188
2189 return Status;
2190}
2191
2192/**
2193 INT64 -> INT16 conversion
2194
2195 Converts the value specified by Operand to a value specified by Result type
2196 and stores the converted value into the caller allocated output buffer
2197 specified by Result. The caller must pass in a Result buffer that is at
2198 least as large as the Result type.
2199
2200 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2201
2202 If the conversion results in an overflow or an underflow condition, then
2203 Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2204
2205 @param[in] Operand Operand to be converted to new type
2206 @param[out] Result Pointer to the result of conversion
2207
2208 @retval RETURN_SUCCESS Successful conversion
2209 @retval RETURN_BUFFER_TOO_SMALL Overflow
2210 @retval RETURN_INVALID_PARAMETER Result is NULL
2211**/
2212RETURN_STATUS
2213EFIAPI
2214SafeInt64ToInt16 (
2215 IN INT64 Operand,
2216 OUT INT16 *Result
2217 )
2218{
2219 RETURN_STATUS Status;
2220
2221 if (Result == NULL) {
2222 return RETURN_INVALID_PARAMETER;
2223 }
2224
2225 if ((Operand >= MIN_INT16) && (Operand <= MAX_INT16)) {
2226 *Result = (INT16)Operand;
2227 Status = RETURN_SUCCESS;
2228 } else {
2229 *Result = INT16_ERROR;
2230 Status = RETURN_BUFFER_TOO_SMALL;
2231 }
2232
2233 return Status;
2234}
2235
2236/**
2237 INT64 -> UINT16 conversion
2238
2239 Converts the value specified by Operand to a value specified by Result type
2240 and stores the converted value into the caller allocated output buffer
2241 specified by Result. The caller must pass in a Result buffer that is at
2242 least as large as the Result type.
2243
2244 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2245
2246 If the conversion results in an overflow or an underflow condition, then
2247 Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2248
2249 @param[in] Operand Operand to be converted to new type
2250 @param[out] Result Pointer to the result of conversion
2251
2252 @retval RETURN_SUCCESS Successful conversion
2253 @retval RETURN_BUFFER_TOO_SMALL Overflow
2254 @retval RETURN_INVALID_PARAMETER Result is NULL
2255**/
2256RETURN_STATUS
2257EFIAPI
2258SafeInt64ToUint16 (
2259 IN INT64 Operand,
2260 OUT UINT16 *Result
2261 )
2262{
2263 RETURN_STATUS Status;
2264
2265 if (Result == NULL) {
2266 return RETURN_INVALID_PARAMETER;
2267 }
2268
2269 if ((Operand >= 0) && (Operand <= MAX_UINT16)) {
2270 *Result = (UINT16)Operand;
2271 Status = RETURN_SUCCESS;
2272 } else {
2273 *Result = UINT16_ERROR;
2274 Status = RETURN_BUFFER_TOO_SMALL;
2275 }
2276
2277 return Status;
2278}
2279
2280/**
2281 INT64 -> INT32 conversion
2282
2283 Converts the value specified by Operand to a value specified by Result type
2284 and stores the converted value into the caller allocated output buffer
2285 specified by Result. The caller must pass in a Result buffer that is at
2286 least as large as the Result type.
2287
2288 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2289
2290 If the conversion results in an overflow or an underflow condition, then
2291 Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2292
2293 @param[in] Operand Operand to be converted to new type
2294 @param[out] Result Pointer to the result of conversion
2295
2296 @retval RETURN_SUCCESS Successful conversion
2297 @retval RETURN_BUFFER_TOO_SMALL Overflow
2298 @retval RETURN_INVALID_PARAMETER Result is NULL
2299**/
2300RETURN_STATUS
2301EFIAPI
2302SafeInt64ToInt32 (
2303 IN INT64 Operand,
2304 OUT INT32 *Result
2305 )
2306{
2307 RETURN_STATUS Status;
2308
2309 if (Result == NULL) {
2310 return RETURN_INVALID_PARAMETER;
2311 }
2312
2313 if ((Operand >= MIN_INT32) && (Operand <= MAX_INT32)) {
2314 *Result = (INT32)Operand;
2315 Status = RETURN_SUCCESS;
2316 } else {
2317 *Result = INT32_ERROR;
2318 Status = RETURN_BUFFER_TOO_SMALL;
2319 }
2320
2321 return Status;
2322}
2323
2324/**
2325 INT64 -> UINT32 conversion
2326
2327 Converts the value specified by Operand to a value specified by Result type
2328 and stores the converted value into the caller allocated output buffer
2329 specified by Result. The caller must pass in a Result buffer that is at
2330 least as large as the Result type.
2331
2332 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2333
2334 If the conversion results in an overflow or an underflow condition, then
2335 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2336
2337 @param[in] Operand Operand to be converted to new type
2338 @param[out] Result Pointer to the result of conversion
2339
2340 @retval RETURN_SUCCESS Successful conversion
2341 @retval RETURN_BUFFER_TOO_SMALL Overflow
2342 @retval RETURN_INVALID_PARAMETER Result is NULL
2343**/
2344RETURN_STATUS
2345EFIAPI
2346SafeInt64ToUint32 (
2347 IN INT64 Operand,
2348 OUT UINT32 *Result
2349 )
2350{
2351 RETURN_STATUS Status;
2352
2353 if (Result == NULL) {
2354 return RETURN_INVALID_PARAMETER;
2355 }
2356
2357 if ((Operand >= 0) && (Operand <= MAX_UINT32)) {
2358 *Result = (UINT32)Operand;
2359 Status = RETURN_SUCCESS;
2360 } else {
2361 *Result = UINT32_ERROR;
2362 Status = RETURN_BUFFER_TOO_SMALL;
2363 }
2364
2365 return Status;
2366}
2367
2368/**
2369 INT64 -> UINT64 conversion
2370
2371 Converts the value specified by Operand to a value specified by Result type
2372 and stores the converted value into the caller allocated output buffer
2373 specified by Result. The caller must pass in a Result buffer that is at
2374 least as large as the Result type.
2375
2376 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2377
2378 If the conversion results in an overflow or an underflow condition, then
2379 Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2380
2381 @param[in] Operand Operand to be converted to new type
2382 @param[out] Result Pointer to the result of conversion
2383
2384 @retval RETURN_SUCCESS Successful conversion
2385 @retval RETURN_BUFFER_TOO_SMALL Overflow
2386 @retval RETURN_INVALID_PARAMETER Result is NULL
2387**/
2388RETURN_STATUS
2389EFIAPI
2390SafeInt64ToUint64 (
2391 IN INT64 Operand,
2392 OUT UINT64 *Result
2393 )
2394{
2395 RETURN_STATUS Status;
2396
2397 if (Result == NULL) {
2398 return RETURN_INVALID_PARAMETER;
2399 }
2400
2401 if (Operand >= 0) {
2402 *Result = (UINT64)Operand;
2403 Status = RETURN_SUCCESS;
2404 } else {
2405 *Result = UINT64_ERROR;
2406 Status = RETURN_BUFFER_TOO_SMALL;
2407 }
2408
2409 return Status;
2410}
2411
2412/**
2413 UINT64 -> INT8 conversion
2414
2415 Converts the value specified by Operand to a value specified by Result type
2416 and stores the converted value into the caller allocated output buffer
2417 specified by Result. The caller must pass in a Result buffer that is at
2418 least as large as the Result type.
2419
2420 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2421
2422 If the conversion results in an overflow or an underflow condition, then
2423 Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2424
2425 @param[in] Operand Operand to be converted to new type
2426 @param[out] Result Pointer to the result of conversion
2427
2428 @retval RETURN_SUCCESS Successful conversion
2429 @retval RETURN_BUFFER_TOO_SMALL Overflow
2430 @retval RETURN_INVALID_PARAMETER Result is NULL
2431**/
2432RETURN_STATUS
2433EFIAPI
2434SafeUint64ToInt8 (
2435 IN UINT64 Operand,
2436 OUT INT8 *Result
2437 )
2438{
2439 RETURN_STATUS Status;
2440
2441 if (Result == NULL) {
2442 return RETURN_INVALID_PARAMETER;
2443 }
2444
2445 if (Operand <= MAX_INT8) {
2446 *Result = (INT8)Operand;
2447 Status = RETURN_SUCCESS;
2448 } else {
2449 *Result = INT8_ERROR;
2450 Status = RETURN_BUFFER_TOO_SMALL;
2451 }
2452
2453 return Status;
2454}
2455
2456/**
2457 UINT64 -> CHAR8 conversion
2458
2459 Converts the value specified by Operand to a value specified by Result type
2460 and stores the converted value into the caller allocated output buffer
2461 specified by Result. The caller must pass in a Result buffer that is at
2462 least as large as the Result type.
2463
2464 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2465
2466 If the conversion results in an overflow or an underflow condition, then
2467 Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2468
2469 @param[in] Operand Operand to be converted to new type
2470 @param[out] Result Pointer to the result of conversion
2471
2472 @retval RETURN_SUCCESS Successful conversion
2473 @retval RETURN_BUFFER_TOO_SMALL Overflow
2474 @retval RETURN_INVALID_PARAMETER Result is NULL
2475**/
2476RETURN_STATUS
2477EFIAPI
2478SafeUint64ToChar8 (
2479 IN UINT64 Operand,
2480 OUT CHAR8 *Result
2481 )
2482{
2483 RETURN_STATUS Status;
2484
2485 if (Result == NULL) {
2486 return RETURN_INVALID_PARAMETER;
2487 }
2488
2489 if (Operand <= MAX_INT8) {
2490 *Result = (INT8)Operand;
2491 Status = RETURN_SUCCESS;
2492 } else {
2493 *Result = CHAR8_ERROR;
2494 Status = RETURN_BUFFER_TOO_SMALL;
2495 }
2496
2497 return Status;
2498}
2499
2500/**
2501 UINT64 -> UINT8 conversion
2502
2503 Converts the value specified by Operand to a value specified by Result type
2504 and stores the converted value into the caller allocated output buffer
2505 specified by Result. The caller must pass in a Result buffer that is at
2506 least as large as the Result type.
2507
2508 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2509
2510 If the conversion results in an overflow or an underflow condition, then
2511 Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2512
2513 @param[in] Operand Operand to be converted to new type
2514 @param[out] Result Pointer to the result of conversion
2515
2516 @retval RETURN_SUCCESS Successful conversion
2517 @retval RETURN_BUFFER_TOO_SMALL Overflow
2518 @retval RETURN_INVALID_PARAMETER Result is NULL
2519**/
2520RETURN_STATUS
2521EFIAPI
2522SafeUint64ToUint8 (
2523 IN UINT64 Operand,
2524 OUT UINT8 *Result
2525 )
2526{
2527 RETURN_STATUS Status;
2528
2529 if (Result == NULL) {
2530 return RETURN_INVALID_PARAMETER;
2531 }
2532
2533 if (Operand <= MAX_UINT8) {
2534 *Result = (UINT8)Operand;
2535 Status = RETURN_SUCCESS;
2536 } else {
2537 *Result = UINT8_ERROR;
2538 Status = RETURN_BUFFER_TOO_SMALL;
2539 }
2540
2541 return Status;
2542}
2543
2544/**
2545 UINT64 -> INT16 conversion
2546
2547 Converts the value specified by Operand to a value specified by Result type
2548 and stores the converted value into the caller allocated output buffer
2549 specified by Result. The caller must pass in a Result buffer that is at
2550 least as large as the Result type.
2551
2552 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2553
2554 If the conversion results in an overflow or an underflow condition, then
2555 Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2556
2557 @param[in] Operand Operand to be converted to new type
2558 @param[out] Result Pointer to the result of conversion
2559
2560 @retval RETURN_SUCCESS Successful conversion
2561 @retval RETURN_BUFFER_TOO_SMALL Overflow
2562 @retval RETURN_INVALID_PARAMETER Result is NULL
2563**/
2564RETURN_STATUS
2565EFIAPI
2566SafeUint64ToInt16 (
2567 IN UINT64 Operand,
2568 OUT INT16 *Result
2569 )
2570{
2571 RETURN_STATUS Status;
2572
2573 if (Result == NULL) {
2574 return RETURN_INVALID_PARAMETER;
2575 }
2576
2577 if (Operand <= MAX_INT16) {
2578 *Result = (INT16)Operand;
2579 Status = RETURN_SUCCESS;
2580 } else {
2581 *Result = INT16_ERROR;
2582 Status = RETURN_BUFFER_TOO_SMALL;
2583 }
2584
2585 return Status;
2586}
2587
2588/**
2589 UINT64 -> UINT16 conversion
2590
2591 Converts the value specified by Operand to a value specified by Result type
2592 and stores the converted value into the caller allocated output buffer
2593 specified by Result. The caller must pass in a Result buffer that is at
2594 least as large as the Result type.
2595
2596 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2597
2598 If the conversion results in an overflow or an underflow condition, then
2599 Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2600
2601 @param[in] Operand Operand to be converted to new type
2602 @param[out] Result Pointer to the result of conversion
2603
2604 @retval RETURN_SUCCESS Successful conversion
2605 @retval RETURN_BUFFER_TOO_SMALL Overflow
2606 @retval RETURN_INVALID_PARAMETER Result is NULL
2607**/
2608RETURN_STATUS
2609EFIAPI
2610SafeUint64ToUint16 (
2611 IN UINT64 Operand,
2612 OUT UINT16 *Result
2613 )
2614{
2615 RETURN_STATUS Status;
2616
2617 if (Result == NULL) {
2618 return RETURN_INVALID_PARAMETER;
2619 }
2620
2621 if (Operand <= MAX_UINT16) {
2622 *Result = (UINT16)Operand;
2623 Status = RETURN_SUCCESS;
2624 } else {
2625 *Result = UINT16_ERROR;
2626 Status = RETURN_BUFFER_TOO_SMALL;
2627 }
2628
2629 return Status;
2630}
2631
2632/**
2633 UINT64 -> INT32 conversion
2634
2635 Converts the value specified by Operand to a value specified by Result type
2636 and stores the converted value into the caller allocated output buffer
2637 specified by Result. The caller must pass in a Result buffer that is at
2638 least as large as the Result type.
2639
2640 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2641
2642 If the conversion results in an overflow or an underflow condition, then
2643 Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2644
2645 @param[in] Operand Operand to be converted to new type
2646 @param[out] Result Pointer to the result of conversion
2647
2648 @retval RETURN_SUCCESS Successful conversion
2649 @retval RETURN_BUFFER_TOO_SMALL Overflow
2650 @retval RETURN_INVALID_PARAMETER Result is NULL
2651**/
2652RETURN_STATUS
2653EFIAPI
2654SafeUint64ToInt32 (
2655 IN UINT64 Operand,
2656 OUT INT32 *Result
2657 )
2658{
2659 RETURN_STATUS Status;
2660
2661 if (Result == NULL) {
2662 return RETURN_INVALID_PARAMETER;
2663 }
2664
2665 if (Operand <= MAX_INT32) {
2666 *Result = (INT32)Operand;
2667 Status = RETURN_SUCCESS;
2668 } else {
2669 *Result = INT32_ERROR;
2670 Status = RETURN_BUFFER_TOO_SMALL;
2671 }
2672
2673 return Status;
2674}
2675
2676/**
2677 UINT64 -> UINT32 conversion
2678
2679 Converts the value specified by Operand to a value specified by Result type
2680 and stores the converted value into the caller allocated output buffer
2681 specified by Result. The caller must pass in a Result buffer that is at
2682 least as large as the Result type.
2683
2684 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2685
2686 If the conversion results in an overflow or an underflow condition, then
2687 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2688
2689 @param[in] Operand Operand to be converted to new type
2690 @param[out] Result Pointer to the result of conversion
2691
2692 @retval RETURN_SUCCESS Successful conversion
2693 @retval RETURN_BUFFER_TOO_SMALL Overflow
2694 @retval RETURN_INVALID_PARAMETER Result is NULL
2695**/
2696RETURN_STATUS
2697EFIAPI
2698SafeUint64ToUint32 (
2699 IN UINT64 Operand,
2700 OUT UINT32 *Result
2701 )
2702{
2703 RETURN_STATUS Status;
2704
2705 if (Result == NULL) {
2706 return RETURN_INVALID_PARAMETER;
2707 }
2708
2709 if (Operand <= MAX_UINT32) {
2710 *Result = (UINT32)Operand;
2711 Status = RETURN_SUCCESS;
2712 } else {
2713 *Result = UINT32_ERROR;
2714 Status = RETURN_BUFFER_TOO_SMALL;
2715 }
2716
2717 return Status;
2718}
2719
2720/**
2721 UINT64 -> INTN conversion
2722
2723 Converts the value specified by Operand to a value specified by Result type
2724 and stores the converted value into the caller allocated output buffer
2725 specified by Result. The caller must pass in a Result buffer that is at
2726 least as large as the Result type.
2727
2728 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2729
2730 If the conversion results in an overflow or an underflow condition, then
2731 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2732
2733 @param[in] Operand Operand to be converted to new type
2734 @param[out] Result Pointer to the result of conversion
2735
2736 @retval RETURN_SUCCESS Successful conversion
2737 @retval RETURN_BUFFER_TOO_SMALL Overflow
2738 @retval RETURN_INVALID_PARAMETER Result is NULL
2739**/
2740RETURN_STATUS
2741EFIAPI
2742SafeUint64ToIntn (
2743 IN UINT64 Operand,
2744 OUT INTN *Result
2745 )
2746{
2747 RETURN_STATUS Status;
2748
2749 if (Result == NULL) {
2750 return RETURN_INVALID_PARAMETER;
2751 }
2752
2753 if (Operand <= MAX_INTN) {
2754 *Result = (INTN)Operand;
2755 Status = RETURN_SUCCESS;
2756 } else {
2757 *Result = INTN_ERROR;
2758 Status = RETURN_BUFFER_TOO_SMALL;
2759 }
2760
2761 return Status;
2762}
2763
2764/**
2765 UINT64 -> INT64 conversion
2766
2767 Converts the value specified by Operand to a value specified by Result type
2768 and stores the converted value into the caller allocated output buffer
2769 specified by Result. The caller must pass in a Result buffer that is at
2770 least as large as the Result type.
2771
2772 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2773
2774 If the conversion results in an overflow or an underflow condition, then
2775 Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2776
2777 @param[in] Operand Operand to be converted to new type
2778 @param[out] Result Pointer to the result of conversion
2779
2780 @retval RETURN_SUCCESS Successful conversion
2781 @retval RETURN_BUFFER_TOO_SMALL Overflow
2782 @retval RETURN_INVALID_PARAMETER Result is NULL
2783**/
2784RETURN_STATUS
2785EFIAPI
2786SafeUint64ToInt64 (
2787 IN UINT64 Operand,
2788 OUT INT64 *Result
2789 )
2790{
2791 RETURN_STATUS Status;
2792
2793 if (Result == NULL) {
2794 return RETURN_INVALID_PARAMETER;
2795 }
2796
2797 if (Operand <= MAX_INT64) {
2798 *Result = (INT64)Operand;
2799 Status = RETURN_SUCCESS;
2800 } else {
2801 *Result = INT64_ERROR;
2802 Status = RETURN_BUFFER_TOO_SMALL;
2803 }
2804
2805 return Status;
2806}
2807
2808//
2809// Addition functions
2810//
2811
2812/**
2813 UINT8 addition
2814
2815 Performs the requested operation using the input parameters into a value
2816 specified by Result type and stores the converted value into the caller
2817 allocated output buffer specified by Result. The caller must pass in a
2818 Result buffer that is at least as large as the Result type.
2819
2820 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2821
2822 If the requested operation results in an overflow or an underflow condition,
2823 then Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2824
2825 @param[in] Augend A number to which addend will be added
2826 @param[in] Addend A number to be added to another
2827 @param[out] Result Pointer to the result of addition
2828
2829 @retval RETURN_SUCCESS Successful addition
2830 @retval RETURN_BUFFER_TOO_SMALL Overflow
2831 @retval RETURN_INVALID_PARAMETER Result is NULL
2832**/
2833RETURN_STATUS
2834EFIAPI
2835SafeUint8Add (
2836 IN UINT8 Augend,
2837 IN UINT8 Addend,
2838 OUT UINT8 *Result
2839 )
2840{
2841 RETURN_STATUS Status;
2842
2843 if (Result == NULL) {
2844 return RETURN_INVALID_PARAMETER;
2845 }
2846
2847 if (((UINT8)(Augend + Addend)) >= Augend) {
2848 *Result = (UINT8)(Augend + Addend);
2849 Status = RETURN_SUCCESS;
2850 } else {
2851 *Result = UINT8_ERROR;
2852 Status = RETURN_BUFFER_TOO_SMALL;
2853 }
2854
2855 return Status;
2856}
2857
2858/**
2859 UINT16 addition
2860
2861 Performs the requested operation using the input parameters into a value
2862 specified by Result type and stores the converted value into the caller
2863 allocated output buffer specified by Result. The caller must pass in a
2864 Result buffer that is at least as large as the Result type.
2865
2866 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2867
2868 If the requested operation results in an overflow or an underflow condition,
2869 then Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2870
2871 @param[in] Augend A number to which addend will be added
2872 @param[in] Addend A number to be added to another
2873 @param[out] Result Pointer to the result of addition
2874
2875 @retval RETURN_SUCCESS Successful addition
2876 @retval RETURN_BUFFER_TOO_SMALL Overflow
2877 @retval RETURN_INVALID_PARAMETER Result is NULL
2878**/
2879RETURN_STATUS
2880EFIAPI
2881SafeUint16Add (
2882 IN UINT16 Augend,
2883 IN UINT16 Addend,
2884 OUT UINT16 *Result
2885 )
2886{
2887 RETURN_STATUS Status;
2888
2889 if (Result == NULL) {
2890 return RETURN_INVALID_PARAMETER;
2891 }
2892
2893 if (((UINT16)(Augend + Addend)) >= Augend) {
2894 *Result = (UINT16)(Augend + Addend);
2895 Status = RETURN_SUCCESS;
2896 } else {
2897 *Result = UINT16_ERROR;
2898 Status = RETURN_BUFFER_TOO_SMALL;
2899 }
2900
2901 return Status;
2902}
2903
2904/**
2905 UINT32 addition
2906
2907 Performs the requested operation using the input parameters into a value
2908 specified by Result type and stores the converted value into the caller
2909 allocated output buffer specified by Result. The caller must pass in a
2910 Result buffer that is at least as large as the Result type.
2911
2912 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2913
2914 If the requested operation results in an overflow or an underflow condition,
2915 then Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2916
2917 @param[in] Augend A number to which addend will be added
2918 @param[in] Addend A number to be added to another
2919 @param[out] Result Pointer to the result of addition
2920
2921 @retval RETURN_SUCCESS Successful addition
2922 @retval RETURN_BUFFER_TOO_SMALL Overflow
2923 @retval RETURN_INVALID_PARAMETER Result is NULL
2924**/
2925RETURN_STATUS
2926EFIAPI
2927SafeUint32Add (
2928 IN UINT32 Augend,
2929 IN UINT32 Addend,
2930 OUT UINT32 *Result
2931 )
2932{
2933 RETURN_STATUS Status;
2934
2935 if (Result == NULL) {
2936 return RETURN_INVALID_PARAMETER;
2937 }
2938
2939 if ((Augend + Addend) >= Augend) {
2940 *Result = (Augend + Addend);
2941 Status = RETURN_SUCCESS;
2942 } else {
2943 *Result = UINT32_ERROR;
2944 Status = RETURN_BUFFER_TOO_SMALL;
2945 }
2946
2947 return Status;
2948}
2949
2950/**
2951 UINT64 addition
2952
2953 Performs the requested operation using the input parameters into a value
2954 specified by Result type and stores the converted value into the caller
2955 allocated output buffer specified by Result. The caller must pass in a
2956 Result buffer that is at least as large as the Result type.
2957
2958 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
2959
2960 If the requested operation results in an overflow or an underflow condition,
2961 then Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
2962
2963 @param[in] Augend A number to which addend will be added
2964 @param[in] Addend A number to be added to another
2965 @param[out] Result Pointer to the result of addition
2966
2967 @retval RETURN_SUCCESS Successful addition
2968 @retval RETURN_BUFFER_TOO_SMALL Overflow
2969 @retval RETURN_INVALID_PARAMETER Result is NULL
2970**/
2971RETURN_STATUS
2972EFIAPI
2973SafeUint64Add (
2974 IN UINT64 Augend,
2975 IN UINT64 Addend,
2976 OUT UINT64 *Result
2977 )
2978{
2979 RETURN_STATUS Status;
2980
2981 if (Result == NULL) {
2982 return RETURN_INVALID_PARAMETER;
2983 }
2984
2985 if ((Augend + Addend) >= Augend) {
2986 *Result = (Augend + Addend);
2987 Status = RETURN_SUCCESS;
2988 } else {
2989 *Result = UINT64_ERROR;
2990 Status = RETURN_BUFFER_TOO_SMALL;
2991 }
2992
2993 return Status;
2994}
2995
2996//
2997// Subtraction functions
2998//
2999
3000/**
3001 UINT8 subtraction
3002
3003 Performs the requested operation using the input parameters into a value
3004 specified by Result type and stores the converted value into the caller
3005 allocated output buffer specified by Result. The caller must pass in a
3006 Result buffer that is at least as large as the Result type.
3007
3008 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3009
3010 If the requested operation results in an overflow or an underflow condition,
3011 then Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3012
3013 @param[in] Minuend A number from which another is to be subtracted.
3014 @param[in] Subtrahend A number to be subtracted from another
3015 @param[out] Result Pointer to the result of subtraction
3016
3017 @retval RETURN_SUCCESS Successful subtraction
3018 @retval RETURN_BUFFER_TOO_SMALL Underflow
3019 @retval RETURN_INVALID_PARAMETER Result is NULL
3020**/
3021RETURN_STATUS
3022EFIAPI
3023SafeUint8Sub (
3024 IN UINT8 Minuend,
3025 IN UINT8 Subtrahend,
3026 OUT UINT8 *Result
3027 )
3028{
3029 RETURN_STATUS Status;
3030
3031 if (Result == NULL) {
3032 return RETURN_INVALID_PARAMETER;
3033 }
3034
3035 if (Minuend >= Subtrahend) {
3036 *Result = (UINT8)(Minuend - Subtrahend);
3037 Status = RETURN_SUCCESS;
3038 } else {
3039 *Result = UINT8_ERROR;
3040 Status = RETURN_BUFFER_TOO_SMALL;
3041 }
3042
3043 return Status;
3044}
3045
3046/**
3047 UINT16 subtraction
3048
3049 Performs the requested operation using the input parameters into a value
3050 specified by Result type and stores the converted value into the caller
3051 allocated output buffer specified by Result. The caller must pass in a
3052 Result buffer that is at least as large as the Result type.
3053
3054 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3055
3056 If the requested operation results in an overflow or an underflow condition,
3057 then Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3058
3059 @param[in] Minuend A number from which another is to be subtracted.
3060 @param[in] Subtrahend A number to be subtracted from another
3061 @param[out] Result Pointer to the result of subtraction
3062
3063 @retval RETURN_SUCCESS Successful subtraction
3064 @retval RETURN_BUFFER_TOO_SMALL Underflow
3065 @retval RETURN_INVALID_PARAMETER Result is NULL
3066**/
3067RETURN_STATUS
3068EFIAPI
3069SafeUint16Sub (
3070 IN UINT16 Minuend,
3071 IN UINT16 Subtrahend,
3072 OUT UINT16 *Result
3073 )
3074{
3075 RETURN_STATUS Status;
3076
3077 if (Result == NULL) {
3078 return RETURN_INVALID_PARAMETER;
3079 }
3080
3081 if (Minuend >= Subtrahend) {
3082 *Result = (UINT16)(Minuend - Subtrahend);
3083 Status = RETURN_SUCCESS;
3084 } else {
3085 *Result = UINT16_ERROR;
3086 Status = RETURN_BUFFER_TOO_SMALL;
3087 }
3088
3089 return Status;
3090}
3091
3092/**
3093 UINT32 subtraction
3094
3095 Performs the requested operation using the input parameters into a value
3096 specified by Result type and stores the converted value into the caller
3097 allocated output buffer specified by Result. The caller must pass in a
3098 Result buffer that is at least as large as the Result type.
3099
3100 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3101
3102 If the requested operation results in an overflow or an underflow condition,
3103 then Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3104
3105 @param[in] Minuend A number from which another is to be subtracted.
3106 @param[in] Subtrahend A number to be subtracted from another
3107 @param[out] Result Pointer to the result of subtraction
3108
3109 @retval RETURN_SUCCESS Successful subtraction
3110 @retval RETURN_BUFFER_TOO_SMALL Underflow
3111 @retval RETURN_INVALID_PARAMETER Result is NULL
3112**/
3113RETURN_STATUS
3114EFIAPI
3115SafeUint32Sub (
3116 IN UINT32 Minuend,
3117 IN UINT32 Subtrahend,
3118 OUT UINT32 *Result
3119 )
3120{
3121 RETURN_STATUS Status;
3122
3123 if (Result == NULL) {
3124 return RETURN_INVALID_PARAMETER;
3125 }
3126
3127 if (Minuend >= Subtrahend) {
3128 *Result = (Minuend - Subtrahend);
3129 Status = RETURN_SUCCESS;
3130 } else {
3131 *Result = UINT32_ERROR;
3132 Status = RETURN_BUFFER_TOO_SMALL;
3133 }
3134
3135 return Status;
3136}
3137
3138/**
3139 UINT64 subtraction
3140
3141 Performs the requested operation using the input parameters into a value
3142 specified by Result type and stores the converted value into the caller
3143 allocated output buffer specified by Result. The caller must pass in a
3144 Result buffer that is at least as large as the Result type.
3145
3146 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3147
3148 If the requested operation results in an overflow or an underflow condition,
3149 then Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3150
3151 @param[in] Minuend A number from which another is to be subtracted.
3152 @param[in] Subtrahend A number to be subtracted from another
3153 @param[out] Result Pointer to the result of subtraction
3154
3155 @retval RETURN_SUCCESS Successful subtraction
3156 @retval RETURN_BUFFER_TOO_SMALL Underflow
3157 @retval RETURN_INVALID_PARAMETER Result is NULL
3158**/
3159RETURN_STATUS
3160EFIAPI
3161SafeUint64Sub (
3162 IN UINT64 Minuend,
3163 IN UINT64 Subtrahend,
3164 OUT UINT64 *Result
3165 )
3166{
3167 RETURN_STATUS Status;
3168
3169 if (Result == NULL) {
3170 return RETURN_INVALID_PARAMETER;
3171 }
3172
3173 if (Minuend >= Subtrahend) {
3174 *Result = (Minuend - Subtrahend);
3175 Status = RETURN_SUCCESS;
3176 } else {
3177 *Result = UINT64_ERROR;
3178 Status = RETURN_BUFFER_TOO_SMALL;
3179 }
3180
3181 return Status;
3182}
3183
3184//
3185// Multiplication functions
3186//
3187
3188/**
3189 UINT8 multiplication
3190
3191 Performs the requested operation using the input parameters into a value
3192 specified by Result type and stores the converted value into the caller
3193 allocated output buffer specified by Result. The caller must pass in a
3194 Result buffer that is at least as large as the Result type.
3195
3196 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3197
3198 If the requested operation results in an overflow or an underflow condition,
3199 then Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3200
3201 @param[in] Multiplicand A number that is to be multiplied by another
3202 @param[in] Multiplier A number by which the multiplicand is to be multiplied
3203 @param[out] Result Pointer to the result of multiplication
3204
3205 @retval RETURN_SUCCESS Successful multiplication
3206 @retval RETURN_BUFFER_TOO_SMALL Overflow
3207 @retval RETURN_INVALID_PARAMETER Result is NULL
3208**/
3209RETURN_STATUS
3210EFIAPI
3211SafeUint8Mult (
3212 IN UINT8 Multiplicand,
3213 IN UINT8 Multiplier,
3214 OUT UINT8 *Result
3215 )
3216{
3217 UINT32 IntermediateResult;
3218
3219 IntermediateResult = ((UINT32)Multiplicand) *((UINT32)Multiplier);
3220
3221 return SafeUint32ToUint8 (IntermediateResult, Result);
3222}
3223
3224/**
3225 UINT16 multiplication
3226
3227 Performs the requested operation using the input parameters into a value
3228 specified by Result type and stores the converted value into the caller
3229 allocated output buffer specified by Result. The caller must pass in a
3230 Result buffer that is at least as large as the Result type.
3231
3232 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3233
3234 If the requested operation results in an overflow or an underflow condition,
3235 then Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3236
3237 @param[in] Multiplicand A number that is to be multiplied by another
3238 @param[in] Multiplier A number by which the multiplicand is to be multiplied
3239 @param[out] Result Pointer to the result of multiplication
3240
3241 @retval RETURN_SUCCESS Successful multiplication
3242 @retval RETURN_BUFFER_TOO_SMALL Overflow
3243 @retval RETURN_INVALID_PARAMETER Result is NULL
3244**/
3245RETURN_STATUS
3246EFIAPI
3247SafeUint16Mult (
3248 IN UINT16 Multiplicand,
3249 IN UINT16 Multiplier,
3250 OUT UINT16 *Result
3251 )
3252{
3253 UINT32 IntermediateResult;
3254
3255 IntermediateResult = ((UINT32)Multiplicand) *((UINT32)Multiplier);
3256
3257 return SafeUint32ToUint16 (IntermediateResult, Result);
3258}
3259
3260/**
3261 UINT32 multiplication
3262
3263 Performs the requested operation using the input parameters into a value
3264 specified by Result type and stores the converted value into the caller
3265 allocated output buffer specified by Result. The caller must pass in a
3266 Result buffer that is at least as large as the Result type.
3267
3268 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3269
3270 If the requested operation results in an overflow or an underflow condition,
3271 then Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3272
3273 @param[in] Multiplicand A number that is to be multiplied by another
3274 @param[in] Multiplier A number by which the multiplicand is to be multiplied
3275 @param[out] Result Pointer to the result of multiplication
3276
3277 @retval RETURN_SUCCESS Successful multiplication
3278 @retval RETURN_BUFFER_TOO_SMALL Overflow
3279 @retval RETURN_INVALID_PARAMETER Result is NULL
3280**/
3281RETURN_STATUS
3282EFIAPI
3283SafeUint32Mult (
3284 IN UINT32 Multiplicand,
3285 IN UINT32 Multiplier,
3286 OUT UINT32 *Result
3287 )
3288{
3289 UINT64 IntermediateResult;
3290
3291 IntermediateResult = ((UINT64)Multiplicand) *((UINT64)Multiplier);
3292
3293 return SafeUint64ToUint32 (IntermediateResult, Result);
3294}
3295
3296/**
3297 UINT64 multiplication
3298
3299 Performs the requested operation using the input parameters into a value
3300 specified by Result type and stores the converted value into the caller
3301 allocated output buffer specified by Result. The caller must pass in a
3302 Result buffer that is at least as large as the Result type.
3303
3304 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3305
3306 If the requested operation results in an overflow or an underflow condition,
3307 then Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3308
3309 @param[in] Multiplicand A number that is to be multiplied by another
3310 @param[in] Multiplier A number by which the multiplicand is to be multiplied
3311 @param[out] Result Pointer to the result of multiplication
3312
3313 @retval RETURN_SUCCESS Successful multiplication
3314 @retval RETURN_BUFFER_TOO_SMALL Overflow
3315 @retval RETURN_INVALID_PARAMETER Result is NULL
3316**/
3317RETURN_STATUS
3318EFIAPI
3319SafeUint64Mult (
3320 IN UINT64 Multiplicand,
3321 IN UINT64 Multiplier,
3322 OUT UINT64 *Result
3323 )
3324{
3325 RETURN_STATUS Status;
3326 UINT32 DwordA;
3327 UINT32 DwordB;
3328 UINT32 DwordC;
3329 UINT32 DwordD;
3330 UINT64 ProductAD;
3331 UINT64 ProductBC;
3332 UINT64 ProductBD;
3333 UINT64 UnsignedResult;
3334
3335 if (Result == NULL) {
3336 return RETURN_INVALID_PARAMETER;
3337 }
3338
3339 ProductAD = 0;
3340 ProductBC = 0;
3341 ProductBD = 0;
3342 UnsignedResult = 0;
3343 Status = RETURN_BUFFER_TOO_SMALL;
3344
3345 //
3346 // 64x64 into 128 is like 32.32 x 32.32.
3347 //
3348 // a.b * c.d = a*(c.d) + .b*(c.d) = a*c + a*.d + .b*c + .b*.d
3349 // back in non-decimal notation where A=a*2^32 and C=c*2^32:
3350 // A*C + A*d + b*C + b*d
3351 // So there are four components to add together.
3352 // result = (a*c*2^64) + (a*d*2^32) + (b*c*2^32) + (b*d)
3353 //
3354 // a * c must be 0 or there would be bits in the high 64-bits
3355 // a * d must be less than 2^32 or there would be bits in the high 64-bits
3356 // b * c must be less than 2^32 or there would be bits in the high 64-bits
3357 // then there must be no overflow of the resulting values summed up.
3358 //
3359 DwordA = (UINT32)RShiftU64 (Multiplicand, 32);
3360 DwordC = (UINT32)RShiftU64 (Multiplier, 32);
3361
3362 //
3363 // common case -- if high dwords are both zero, no chance for overflow
3364 //
3365 if ((DwordA == 0) && (DwordC == 0)) {
3366 DwordB = (UINT32)Multiplicand;
3367 DwordD = (UINT32)Multiplier;
3368
3369 *Result = (((UINT64)DwordB) *(UINT64)DwordD);
3370 Status = RETURN_SUCCESS;
3371 } else {
3372 //
3373 // a * c must be 0 or there would be bits set in the high 64-bits
3374 //
3375 if ((DwordA == 0) ||
3376 (DwordC == 0))
3377 {
3378 DwordD = (UINT32)Multiplier;
3379
3380 //
3381 // a * d must be less than 2^32 or there would be bits set in the high 64-bits
3382 //
3383 ProductAD = MultU64x64 ((UINT64)DwordA, (UINT64)DwordD);
3384 if ((ProductAD & 0xffffffff00000000) == 0) {
3385 DwordB = (UINT32)Multiplicand;
3386
3387 //
3388 // b * c must be less than 2^32 or there would be bits set in the high 64-bits
3389 //
3390 ProductBC = MultU64x64 ((UINT64)DwordB, (UINT64)DwordC);
3391 if ((ProductBC & 0xffffffff00000000) == 0) {
3392 //
3393 // now sum them all up checking for overflow.
3394 // shifting is safe because we already checked for overflow above
3395 //
3396 if (!RETURN_ERROR (SafeUint64Add (LShiftU64 (ProductBC, 32), LShiftU64 (ProductAD, 32), &UnsignedResult))) {
3397 //
3398 // b * d
3399 //
3400 ProductBD = MultU64x64 ((UINT64)DwordB, (UINT64)DwordD);
3401
3402 if (!RETURN_ERROR (SafeUint64Add (UnsignedResult, ProductBD, &UnsignedResult))) {
3403 *Result = UnsignedResult;
3404 Status = RETURN_SUCCESS;
3405 }
3406 }
3407 }
3408 }
3409 }
3410 }
3411
3412 if (RETURN_ERROR (Status)) {
3413 *Result = UINT64_ERROR;
3414 }
3415
3416 return Status;
3417}
3418
3419//
3420// Signed operations
3421//
3422// Strongly consider using unsigned numbers.
3423//
3424// Signed numbers are often used where unsigned numbers should be used.
3425// For example file sizes and array indices should always be unsigned.
3426// Subtracting a larger positive signed number from a smaller positive
3427// signed number with SafeInt32Sub will succeed, producing a negative number,
3428// that then must not be used as an array index (but can occasionally be
3429// used as a pointer index.) Similarly for adding a larger magnitude
3430// negative number to a smaller magnitude positive number.
3431//
3432// This library does not protect you from such errors. It tells you if your
3433// integer operations overflowed, not if you are doing the right thing
3434// with your non-overflowed integers.
3435//
3436// Likewise you can overflow a buffer with a non-overflowed unsigned index.
3437//
3438
3439//
3440// Signed addition functions
3441//
3442
3443/**
3444 INT8 Addition
3445
3446 Performs the requested operation using the input parameters into a value
3447 specified by Result type and stores the converted value into the caller
3448 allocated output buffer specified by Result. The caller must pass in a
3449 Result buffer that is at least as large as the Result type.
3450
3451 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3452
3453 If the requested operation results in an overflow or an underflow condition,
3454 then Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3455
3456 @param[in] Augend A number to which addend will be added
3457 @param[in] Addend A number to be added to another
3458 @param[out] Result Pointer to the result of addition
3459
3460 @retval RETURN_SUCCESS Successful addition
3461 @retval RETURN_BUFFER_TOO_SMALL Overflow
3462 @retval RETURN_INVALID_PARAMETER Result is NULL
3463**/
3464RETURN_STATUS
3465EFIAPI
3466SafeInt8Add (
3467 IN INT8 Augend,
3468 IN INT8 Addend,
3469 OUT INT8 *Result
3470 )
3471{
3472 return SafeInt32ToInt8 (((INT32)Augend) + ((INT32)Addend), Result);
3473}
3474
3475/**
3476 CHAR8 Addition
3477
3478 Performs the requested operation using the input parameters into a value
3479 specified by Result type and stores the converted value into the caller
3480 allocated output buffer specified by Result. The caller must pass in a
3481 Result buffer that is at least as large as the Result type.
3482
3483 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3484
3485 If the requested operation results in an overflow or an underflow condition,
3486 then Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3487
3488 @param[in] Augend A number to which addend will be added
3489 @param[in] Addend A number to be added to another
3490 @param[out] Result Pointer to the result of addition
3491
3492 @retval RETURN_SUCCESS Successful addition
3493 @retval RETURN_BUFFER_TOO_SMALL Overflow
3494 @retval RETURN_INVALID_PARAMETER Result is NULL
3495**/
3496RETURN_STATUS
3497EFIAPI
3498SafeChar8Add (
3499 IN CHAR8 Augend,
3500 IN CHAR8 Addend,
3501 OUT CHAR8 *Result
3502 )
3503{
3504 INT32 Augend32;
3505 INT32 Addend32;
3506
3507 if (Result == NULL) {
3508 return RETURN_INVALID_PARAMETER;
3509 }
3510
3511 Augend32 = (INT32)Augend;
3512 Addend32 = (INT32)Addend;
3513 if ((Augend32 < 0) || (Augend32 > MAX_INT8)) {
3514 *Result = CHAR8_ERROR;
3515 return RETURN_BUFFER_TOO_SMALL;
3516 }
3517
3518 if ((Addend32 < 0) || (Addend32 > MAX_INT8)) {
3519 *Result = CHAR8_ERROR;
3520 return RETURN_BUFFER_TOO_SMALL;
3521 }
3522
3523 return SafeInt32ToChar8 (Augend32 + Addend32, Result);
3524}
3525
3526/**
3527 INT16 Addition
3528
3529 Performs the requested operation using the input parameters into a value
3530 specified by Result type and stores the converted value into the caller
3531 allocated output buffer specified by Result. The caller must pass in a
3532 Result buffer that is at least as large as the Result type.
3533
3534 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3535
3536 If the requested operation results in an overflow or an underflow condition,
3537 then Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3538
3539 @param[in] Augend A number to which addend will be added
3540 @param[in] Addend A number to be added to another
3541 @param[out] Result Pointer to the result of addition
3542
3543 @retval RETURN_SUCCESS Successful addition
3544 @retval RETURN_BUFFER_TOO_SMALL Overflow
3545 @retval RETURN_INVALID_PARAMETER Result is NULL
3546**/
3547RETURN_STATUS
3548EFIAPI
3549SafeInt16Add (
3550 IN INT16 Augend,
3551 IN INT16 Addend,
3552 OUT INT16 *Result
3553 )
3554{
3555 return SafeInt32ToInt16 (((INT32)Augend) + ((INT32)Addend), Result);
3556}
3557
3558/**
3559 INT32 Addition
3560
3561 Performs the requested operation using the input parameters into a value
3562 specified by Result type and stores the converted value into the caller
3563 allocated output buffer specified by Result. The caller must pass in a
3564 Result buffer that is at least as large as the Result type.
3565
3566 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3567
3568 If the requested operation results in an overflow or an underflow condition,
3569 then Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3570
3571 @param[in] Augend A number to which addend will be added
3572 @param[in] Addend A number to be added to another
3573 @param[out] Result Pointer to the result of addition
3574
3575 @retval RETURN_SUCCESS Successful addition
3576 @retval RETURN_BUFFER_TOO_SMALL Overflow
3577 @retval RETURN_INVALID_PARAMETER Result is NULL
3578**/
3579RETURN_STATUS
3580EFIAPI
3581SafeInt32Add (
3582 IN INT32 Augend,
3583 IN INT32 Addend,
3584 OUT INT32 *Result
3585 )
3586{
3587 return SafeInt64ToInt32 (((INT64)Augend) + ((INT64)Addend), Result);
3588}
3589
3590/**
3591 INT64 Addition
3592
3593 Performs the requested operation using the input parameters into a value
3594 specified by Result type and stores the converted value into the caller
3595 allocated output buffer specified by Result. The caller must pass in a
3596 Result buffer that is at least as large as the Result type.
3597
3598 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3599
3600 If the requested operation results in an overflow or an underflow condition,
3601 then Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3602
3603 @param[in] Augend A number to which addend will be added
3604 @param[in] Addend A number to be added to another
3605 @param[out] Result Pointer to the result of addition
3606
3607 @retval RETURN_SUCCESS Successful addition
3608 @retval RETURN_BUFFER_TOO_SMALL Overflow
3609 @retval RETURN_INVALID_PARAMETER Result is NULL
3610**/
3611RETURN_STATUS
3612EFIAPI
3613SafeInt64Add (
3614 IN INT64 Augend,
3615 IN INT64 Addend,
3616 OUT INT64 *Result
3617 )
3618{
3619 RETURN_STATUS Status;
3620
3621 if (Result == NULL) {
3622 return RETURN_INVALID_PARAMETER;
3623 }
3624
3625 //
3626 // * An Addend of zero can never cause underflow or overflow.
3627 //
3628 // * A positive Addend can only cause overflow. The overflow condition is
3629 //
3630 // (Augend + Addend) > MAX_INT64
3631 //
3632 // Subtracting Addend from both sides yields
3633 //
3634 // Augend > (MAX_INT64 - Addend)
3635 //
3636 // This condition can be coded directly in C because the RHS will neither
3637 // underflow nor overflow. That is due to the starting condition:
3638 //
3639 // 0 < Addend <= MAX_INT64
3640 //
3641 // Multiplying all three sides by (-1) yields
3642 //
3643 // 0 > (-Addend) >= (-MAX_INT64)
3644 //
3645 // Adding MAX_INT64 to all three sides yields
3646 //
3647 // MAX_INT64 > (MAX_INT64 - Addend) >= 0
3648 //
3649 // * A negative Addend can only cause underflow. The underflow condition is
3650 //
3651 // (Augend + Addend) < MIN_INT64
3652 //
3653 // Subtracting Addend from both sides yields
3654 //
3655 // Augend < (MIN_INT64 - Addend)
3656 //
3657 // This condition can be coded directly in C because the RHS will neither
3658 // underflow nor overflow. That is due to the starting condition:
3659 //
3660 // MIN_INT64 <= Addend < 0
3661 //
3662 // Multiplying all three sides by (-1) yields
3663 //
3664 // (-MIN_INT64) >= (-Addend) > 0
3665 //
3666 // Adding MIN_INT64 to all three sides yields
3667 //
3668 // 0 >= (MIN_INT64 - Addend) > MIN_INT64
3669 //
3670 if (((Addend > 0) && (Augend > (MAX_INT64 - Addend))) ||
3671 ((Addend < 0) && (Augend < (MIN_INT64 - Addend))))
3672 {
3673 *Result = INT64_ERROR;
3674 Status = RETURN_BUFFER_TOO_SMALL;
3675 } else {
3676 *Result = Augend + Addend;
3677 Status = RETURN_SUCCESS;
3678 }
3679
3680 return Status;
3681}
3682
3683//
3684// Signed subtraction functions
3685//
3686
3687/**
3688 INT8 Subtraction
3689
3690 Performs the requested operation using the input parameters into a value
3691 specified by Result type and stores the converted value into the caller
3692 allocated output buffer specified by Result. The caller must pass in a
3693 Result buffer that is at least as large as the Result type.
3694
3695 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3696
3697 If the requested operation results in an overflow or an underflow condition,
3698 then Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3699
3700 @param[in] Minuend A number from which another is to be subtracted.
3701 @param[in] Subtrahend A number to be subtracted from another
3702 @param[out] Result Pointer to the result of subtraction
3703
3704 @retval RETURN_SUCCESS Successful subtraction
3705 @retval RETURN_BUFFER_TOO_SMALL Underflow
3706 @retval RETURN_INVALID_PARAMETER Result is NULL
3707**/
3708RETURN_STATUS
3709EFIAPI
3710SafeInt8Sub (
3711 IN INT8 Minuend,
3712 IN INT8 Subtrahend,
3713 OUT INT8 *Result
3714 )
3715{
3716 return SafeInt32ToInt8 (((INT32)Minuend) - ((INT32)Subtrahend), Result);
3717}
3718
3719/**
3720 CHAR8 Subtraction
3721
3722 Performs the requested operation using the input parameters into a value
3723 specified by Result type and stores the converted value into the caller
3724 allocated output buffer specified by Result. The caller must pass in a
3725 Result buffer that is at least as large as the Result type.
3726
3727 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3728
3729 If the requested operation results in an overflow or an underflow condition,
3730 then Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3731
3732 @param[in] Minuend A number from which another is to be subtracted.
3733 @param[in] Subtrahend A number to be subtracted from another
3734 @param[out] Result Pointer to the result of subtraction
3735
3736 @retval RETURN_SUCCESS Successful subtraction
3737 @retval RETURN_BUFFER_TOO_SMALL Underflow
3738 @retval RETURN_INVALID_PARAMETER Result is NULL
3739**/
3740RETURN_STATUS
3741EFIAPI
3742SafeChar8Sub (
3743 IN CHAR8 Minuend,
3744 IN CHAR8 Subtrahend,
3745 OUT CHAR8 *Result
3746 )
3747{
3748 INT32 Minuend32;
3749 INT32 Subtrahend32;
3750
3751 if (Result == NULL) {
3752 return RETURN_INVALID_PARAMETER;
3753 }
3754
3755 Minuend32 = (INT32)Minuend;
3756 Subtrahend32 = (INT32)Subtrahend;
3757 if ((Minuend32 < 0) || (Minuend32 > MAX_INT8)) {
3758 *Result = CHAR8_ERROR;
3759 return RETURN_BUFFER_TOO_SMALL;
3760 }
3761
3762 if ((Subtrahend32 < 0) || (Subtrahend32 > MAX_INT8)) {
3763 *Result = CHAR8_ERROR;
3764 return RETURN_BUFFER_TOO_SMALL;
3765 }
3766
3767 return SafeInt32ToChar8 (Minuend32 - Subtrahend32, Result);
3768}
3769
3770/**
3771 INT16 Subtraction
3772
3773 Performs the requested operation using the input parameters into a value
3774 specified by Result type and stores the converted value into the caller
3775 allocated output buffer specified by Result. The caller must pass in a
3776 Result buffer that is at least as large as the Result type.
3777
3778 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3779
3780 If the requested operation results in an overflow or an underflow condition,
3781 then Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3782
3783 @param[in] Minuend A number from which another is to be subtracted.
3784 @param[in] Subtrahend A number to be subtracted from another
3785 @param[out] Result Pointer to the result of subtraction
3786
3787 @retval RETURN_SUCCESS Successful subtraction
3788 @retval RETURN_BUFFER_TOO_SMALL Underflow
3789 @retval RETURN_INVALID_PARAMETER Result is NULL
3790**/
3791RETURN_STATUS
3792EFIAPI
3793SafeInt16Sub (
3794 IN INT16 Minuend,
3795 IN INT16 Subtrahend,
3796 OUT INT16 *Result
3797 )
3798{
3799 return SafeInt32ToInt16 (((INT32)Minuend) - ((INT32)Subtrahend), Result);
3800}
3801
3802/**
3803 INT32 Subtraction
3804
3805 Performs the requested operation using the input parameters into a value
3806 specified by Result type and stores the converted value into the caller
3807 allocated output buffer specified by Result. The caller must pass in a
3808 Result buffer that is at least as large as the Result type.
3809
3810 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3811
3812 If the requested operation results in an overflow or an underflow condition,
3813 then Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3814
3815 @param[in] Minuend A number from which another is to be subtracted.
3816 @param[in] Subtrahend A number to be subtracted from another
3817 @param[out] Result Pointer to the result of subtraction
3818
3819 @retval RETURN_SUCCESS Successful subtraction
3820 @retval RETURN_BUFFER_TOO_SMALL Underflow
3821 @retval RETURN_INVALID_PARAMETER Result is NULL
3822**/
3823RETURN_STATUS
3824EFIAPI
3825SafeInt32Sub (
3826 IN INT32 Minuend,
3827 IN INT32 Subtrahend,
3828 OUT INT32 *Result
3829 )
3830{
3831 return SafeInt64ToInt32 (((INT64)Minuend) - ((INT64)Subtrahend), Result);
3832}
3833
3834/**
3835 INT64 Subtraction
3836
3837 Performs the requested operation using the input parameters into a value
3838 specified by Result type and stores the converted value into the caller
3839 allocated output buffer specified by Result. The caller must pass in a
3840 Result buffer that is at least as large as the Result type.
3841
3842 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3843
3844 If the requested operation results in an overflow or an underflow condition,
3845 then Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3846
3847 @param[in] Minuend A number from which another is to be subtracted.
3848 @param[in] Subtrahend A number to be subtracted from another
3849 @param[out] Result Pointer to the result of subtraction
3850
3851 @retval RETURN_SUCCESS Successful subtraction
3852 @retval RETURN_BUFFER_TOO_SMALL Underflow
3853 @retval RETURN_INVALID_PARAMETER Result is NULL
3854**/
3855RETURN_STATUS
3856EFIAPI
3857SafeInt64Sub (
3858 IN INT64 Minuend,
3859 IN INT64 Subtrahend,
3860 OUT INT64 *Result
3861 )
3862{
3863 RETURN_STATUS Status;
3864
3865 if (Result == NULL) {
3866 return RETURN_INVALID_PARAMETER;
3867 }
3868
3869 //
3870 // * A Subtrahend of zero can never cause underflow or overflow.
3871 //
3872 // * A positive Subtrahend can only cause underflow. The underflow condition
3873 // is:
3874 //
3875 // (Minuend - Subtrahend) < MIN_INT64
3876 //
3877 // Adding Subtrahend to both sides yields
3878 //
3879 // Minuend < (MIN_INT64 + Subtrahend)
3880 //
3881 // This condition can be coded directly in C because the RHS will neither
3882 // underflow nor overflow. That is due to the starting condition:
3883 //
3884 // 0 < Subtrahend <= MAX_INT64
3885 //
3886 // Adding MIN_INT64 to all three sides yields
3887 //
3888 // MIN_INT64 < (MIN_INT64 + Subtrahend) <= (MIN_INT64 + MAX_INT64) = -1
3889 //
3890 // * A negative Subtrahend can only cause overflow. The overflow condition is
3891 //
3892 // (Minuend - Subtrahend) > MAX_INT64
3893 //
3894 // Adding Subtrahend to both sides yields
3895 //
3896 // Minuend > (MAX_INT64 + Subtrahend)
3897 //
3898 // This condition can be coded directly in C because the RHS will neither
3899 // underflow nor overflow. That is due to the starting condition:
3900 //
3901 // MIN_INT64 <= Subtrahend < 0
3902 //
3903 // Adding MAX_INT64 to all three sides yields
3904 //
3905 // -1 = (MAX_INT64 + MIN_INT64) <= (MAX_INT64 + Subtrahend) < MAX_INT64
3906 //
3907 if (((Subtrahend > 0) && (Minuend < (MIN_INT64 + Subtrahend))) ||
3908 ((Subtrahend < 0) && (Minuend > (MAX_INT64 + Subtrahend))))
3909 {
3910 *Result = INT64_ERROR;
3911 Status = RETURN_BUFFER_TOO_SMALL;
3912 } else {
3913 *Result = Minuend - Subtrahend;
3914 Status = RETURN_SUCCESS;
3915 }
3916
3917 return Status;
3918}
3919
3920//
3921// Signed multiplication functions
3922//
3923
3924/**
3925 INT8 multiplication
3926
3927 Performs the requested operation using the input parameters into a value
3928 specified by Result type and stores the converted value into the caller
3929 allocated output buffer specified by Result. The caller must pass in a
3930 Result buffer that is at least as large as the Result type.
3931
3932 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3933
3934 If the requested operation results in an overflow or an underflow condition,
3935 then Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3936
3937 @param[in] Multiplicand A number that is to be multiplied by another
3938 @param[in] Multiplier A number by which the multiplicand is to be multiplied
3939 @param[out] Result Pointer to the result of multiplication
3940
3941 @retval RETURN_SUCCESS Successful multiplication
3942 @retval RETURN_BUFFER_TOO_SMALL Overflow
3943 @retval RETURN_INVALID_PARAMETER Result is NULL
3944**/
3945RETURN_STATUS
3946EFIAPI
3947SafeInt8Mult (
3948 IN INT8 Multiplicand,
3949 IN INT8 Multiplier,
3950 OUT INT8 *Result
3951 )
3952{
3953 return SafeInt32ToInt8 (((INT32)Multiplier) *((INT32)Multiplicand), Result);
3954}
3955
3956/**
3957 CHAR8 multiplication
3958
3959 Performs the requested operation using the input parameters into a value
3960 specified by Result type and stores the converted value into the caller
3961 allocated output buffer specified by Result. The caller must pass in a
3962 Result buffer that is at least as large as the Result type.
3963
3964 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
3965
3966 If the requested operation results in an overflow or an underflow condition,
3967 then Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
3968
3969 @param[in] Multiplicand A number that is to be multiplied by another
3970 @param[in] Multiplier A number by which the multiplicand is to be multiplied
3971 @param[out] Result Pointer to the result of multiplication
3972
3973 @retval RETURN_SUCCESS Successful multiplication
3974 @retval RETURN_BUFFER_TOO_SMALL Overflow
3975 @retval RETURN_INVALID_PARAMETER Result is NULL
3976**/
3977RETURN_STATUS
3978EFIAPI
3979SafeChar8Mult (
3980 IN CHAR8 Multiplicand,
3981 IN CHAR8 Multiplier,
3982 OUT CHAR8 *Result
3983 )
3984{
3985 INT32 Multiplicand32;
3986 INT32 Multiplier32;
3987
3988 if (Result == NULL) {
3989 return RETURN_INVALID_PARAMETER;
3990 }
3991
3992 Multiplicand32 = (INT32)Multiplicand;
3993 Multiplier32 = (INT32)Multiplier;
3994 if ((Multiplicand32 < 0) || (Multiplicand32 > MAX_INT8)) {
3995 *Result = CHAR8_ERROR;
3996 return RETURN_BUFFER_TOO_SMALL;
3997 }
3998
3999 if ((Multiplier32 < 0) || (Multiplier32 > MAX_INT8)) {
4000 *Result = CHAR8_ERROR;
4001 return RETURN_BUFFER_TOO_SMALL;
4002 }
4003
4004 return SafeInt32ToChar8 (Multiplicand32 * Multiplier32, Result);
4005}
4006
4007/**
4008 INT16 multiplication
4009
4010 Performs the requested operation using the input parameters into a value
4011 specified by Result type and stores the converted value into the caller
4012 allocated output buffer specified by Result. The caller must pass in a
4013 Result buffer that is at least as large as the Result type.
4014
4015 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
4016
4017 If the requested operation results in an overflow or an underflow condition,
4018 then Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
4019
4020 @param[in] Multiplicand A number that is to be multiplied by another
4021 @param[in] Multiplier A number by which the multiplicand is to be multiplied
4022 @param[out] Result Pointer to the result of multiplication
4023
4024 @retval RETURN_SUCCESS Successful multiplication
4025 @retval RETURN_BUFFER_TOO_SMALL Overflow
4026 @retval RETURN_INVALID_PARAMETER Result is NULL
4027**/
4028RETURN_STATUS
4029EFIAPI
4030SafeInt16Mult (
4031 IN INT16 Multiplicand,
4032 IN INT16 Multiplier,
4033 OUT INT16 *Result
4034 )
4035{
4036 return SafeInt32ToInt16 (((INT32)Multiplicand) *((INT32)Multiplier), Result);
4037}
4038
4039/**
4040 INT32 multiplication
4041
4042 Performs the requested operation using the input parameters into a value
4043 specified by Result type and stores the converted value into the caller
4044 allocated output buffer specified by Result. The caller must pass in a
4045 Result buffer that is at least as large as the Result type.
4046
4047 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
4048
4049 If the requested operation results in an overflow or an underflow condition,
4050 then Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
4051
4052 @param[in] Multiplicand A number that is to be multiplied by another
4053 @param[in] Multiplier A number by which the multiplicand is to be multiplied
4054 @param[out] Result Pointer to the result of multiplication
4055
4056 @retval RETURN_SUCCESS Successful multiplication
4057 @retval RETURN_BUFFER_TOO_SMALL Overflow
4058 @retval RETURN_INVALID_PARAMETER Result is NULL
4059**/
4060RETURN_STATUS
4061EFIAPI
4062SafeInt32Mult (
4063 IN INT32 Multiplicand,
4064 IN INT32 Multiplier,
4065 OUT INT32 *Result
4066 )
4067{
4068 return SafeInt64ToInt32 (MultS64x64 (Multiplicand, Multiplier), Result);
4069}
4070
4071/**
4072 INT64 multiplication
4073
4074 Performs the requested operation using the input parameters into a value
4075 specified by Result type and stores the converted value into the caller
4076 allocated output buffer specified by Result. The caller must pass in a
4077 Result buffer that is at least as large as the Result type.
4078
4079 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
4080
4081 If the requested operation results in an overflow or an underflow condition,
4082 then Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
4083
4084 @param[in] Multiplicand A number that is to be multiplied by another
4085 @param[in] Multiplier A number by which the multiplicand is to be multiplied
4086 @param[out] Result Pointer to the result of multiplication
4087
4088 @retval RETURN_SUCCESS Successful multiplication
4089 @retval RETURN_BUFFER_TOO_SMALL Overflow
4090 @retval RETURN_INVALID_PARAMETER Result is NULL
4091**/
4092RETURN_STATUS
4093EFIAPI
4094SafeInt64Mult (
4095 IN INT64 Multiplicand,
4096 IN INT64 Multiplier,
4097 OUT INT64 *Result
4098 )
4099{
4100 RETURN_STATUS Status;
4101 UINT64 UnsignedMultiplicand;
4102 UINT64 UnsignedMultiplier;
4103 UINT64 UnsignedResult;
4104
4105 if (Result == NULL) {
4106 return RETURN_INVALID_PARAMETER;
4107 }
4108
4109 //
4110 // Split into sign and magnitude, do unsigned operation, apply sign.
4111 //
4112 if (Multiplicand < 0) {
4113 //
4114 // Avoid negating the most negative number.
4115 //
4116 UnsignedMultiplicand = ((UINT64)(-(Multiplicand + 1))) + 1;
4117 } else {
4118 UnsignedMultiplicand = (UINT64)Multiplicand;
4119 }
4120
4121 if (Multiplier < 0) {
4122 //
4123 // Avoid negating the most negative number.
4124 //
4125 UnsignedMultiplier = ((UINT64)(-(Multiplier + 1))) + 1;
4126 } else {
4127 UnsignedMultiplier = (UINT64)Multiplier;
4128 }
4129
4130 Status = SafeUint64Mult (UnsignedMultiplicand, UnsignedMultiplier, &UnsignedResult);
4131 if (!RETURN_ERROR (Status)) {
4132 if ((Multiplicand < 0) != (Multiplier < 0)) {
4133 if (UnsignedResult > MIN_INT64_MAGNITUDE) {
4134 *Result = INT64_ERROR;
4135 Status = RETURN_BUFFER_TOO_SMALL;
4136 } else if (UnsignedResult == MIN_INT64_MAGNITUDE) {
4137 *Result = MIN_INT64;
4138 } else {
4139 *Result = -((INT64)UnsignedResult);
4140 }
4141 } else {
4142 if (UnsignedResult > MAX_INT64) {
4143 *Result = INT64_ERROR;
4144 Status = RETURN_BUFFER_TOO_SMALL;
4145 } else {
4146 *Result = (INT64)UnsignedResult;
4147 }
4148 }
4149 } else {
4150 *Result = INT64_ERROR;
4151 }
4152
4153 return Status;
4154}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette