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