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