summaryrefslogtreecommitdiff
path: root/src/pal/src/safecrt/mbusafecrt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/pal/src/safecrt/mbusafecrt.cpp')
-rw-r--r--src/pal/src/safecrt/mbusafecrt.cpp249
1 files changed, 249 insertions, 0 deletions
diff --git a/src/pal/src/safecrt/mbusafecrt.cpp b/src/pal/src/safecrt/mbusafecrt.cpp
new file mode 100644
index 0000000000..4446f77fd1
--- /dev/null
+++ b/src/pal/src/safecrt/mbusafecrt.cpp
@@ -0,0 +1,249 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/***
+* mbusafecrt.c - implementaion of support functions and data for MBUSafeCRT
+*
+
+*
+* Purpose:
+* This file contains the implementation of support functions and
+* data for MBUSafeCRT declared in mbusafecrt.h and mbusafecrt_internal.h.
+****/
+
+#include "pal/palinternal.h"
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+
+#include "mbusafecrt_internal.h"
+
+/* global data */
+tSafeCRT_AssertFuncPtr sMBUSafeCRTAssertFunc = NULL;
+
+/***
+* MBUSafeCRTSetAssertFunc - Set the function called when an assert fails.
+****/
+
+void MBUSafeCRTSetAssertFunc( tSafeCRT_AssertFuncPtr inAssertFuncPtr )
+{
+ /* set it */
+ sMBUSafeCRTAssertFunc = inAssertFuncPtr;
+}
+
+/***
+* _putc_nolock - putc for the miniFILE stream.
+****/
+
+int _putc_nolock( char inChar, miniFILE* inStream )
+{
+ int returnValue = EOF;
+
+ inStream->_cnt -= sizeof( char );
+
+ if ( ( inStream->_cnt ) >= 0 )
+ {
+ *( inStream->_ptr ) = inChar;
+ inStream->_ptr += sizeof( char );
+ returnValue = ( int )inChar;
+ }
+
+ return returnValue;
+}
+
+/***
+* _putwc_nolock - putwc for the miniFILE stream.
+****/
+
+int _putwc_nolock( wchar_t inChar, miniFILE* inStream )
+{
+ int returnValue = WEOF;
+
+ inStream->_cnt -= sizeof( wchar_t );
+
+ if ( ( inStream->_cnt ) >= 0 )
+ {
+ *( ( wchar_t* )( inStream->_ptr ) ) = inChar;
+ inStream->_ptr += sizeof( wchar_t );
+ returnValue = ( int )inChar;
+ }
+
+ return returnValue;
+}
+
+/***
+* _getc_nolock - getc for the miniFILE stream.
+****/
+
+int _getc_nolock( miniFILE* inStream )
+{
+ int returnValue = EOF;
+
+ if ( ( inStream->_cnt ) >= ( int )( sizeof( char ) ) )
+ {
+ inStream->_cnt -= sizeof( char );
+ returnValue = ( int )( *( inStream->_ptr ) );
+ inStream->_ptr += sizeof( char );
+ }
+
+ return returnValue;
+}
+
+/***
+* _getwc_nolock - getc for the miniFILE stream.
+****/
+
+int _getwc_nolock( miniFILE* inStream )
+{
+ int returnValue = EOF;
+
+ if ( ( inStream->_cnt ) >= ( int )( sizeof( wchar_t ) ) )
+ {
+ inStream->_cnt -= sizeof( wchar_t );
+ returnValue = ( int )( *( ( wchar_t* )( inStream->_ptr ) ) );
+ inStream->_ptr += sizeof( wchar_t );
+ }
+
+ return returnValue;
+}
+
+/***
+* _ungetc_nolock - ungetc for the miniFILE stream.
+****/
+
+int _ungetc_nolock( char inChar, miniFILE* inStream )
+{
+ int returnValue = EOF;
+
+ if ( ( size_t )( ( inStream->_ptr ) - ( inStream->_base ) ) >= ( sizeof( char ) ) )
+ {
+ inStream->_cnt += sizeof( char );
+ inStream->_ptr -= sizeof( char );
+ return ( int )inChar;
+ }
+
+ return returnValue;
+}
+
+/***
+* _ungetwc_nolock - ungetwc for the miniFILE stream.
+****/
+
+int _ungetwc_nolock( wchar_t inChar, miniFILE* inStream )
+{
+ int returnValue = WEOF;
+
+ if ( ( size_t )( ( inStream->_ptr ) - ( inStream->_base ) ) >= ( sizeof( wchar_t ) ) )
+ {
+ inStream->_cnt += sizeof( wchar_t );
+ inStream->_ptr -= sizeof( wchar_t );
+ returnValue = ( unsigned short )inChar;
+ }
+
+ return returnValue;
+}
+
+
+/***
+* _safecrt_cfltcvt - convert a float to an ascii string.
+****/
+
+/* routine used for floating-point output */
+#define FORMATSIZE 30
+
+// taken from output.inl
+#define FL_ALTERNATE 0x00080 /* alternate form requested */
+
+errno_t _safecrt_cfltcvt(double *arg, char *buffer, size_t sizeInBytes, int type, int precision, int flags)
+{
+ char format[FORMATSIZE];
+ size_t formatlen = 0;
+ int retvalue;
+
+ if (flags & 1)
+ {
+ type -= 'a' - 'A';
+ }
+ formatlen = 0;
+ format[formatlen++] = '%';
+ if (flags & FL_ALTERNATE)
+ {
+ format[formatlen++] = '#';
+ }
+ format[formatlen++] = '.';
+ _itoa_s(precision, format + formatlen, FORMATSIZE - formatlen, 10);
+ formatlen = strlen(format);
+ format[formatlen++] = (char)type;
+ format[formatlen] = 0;
+
+ buffer[sizeInBytes - 1] = 0;
+ retvalue = snprintf(buffer, sizeInBytes, format, *arg);
+ if (buffer[sizeInBytes - 1] != 0 || retvalue <= 0)
+ {
+ buffer[0] = 0;
+ return EINVAL;
+ }
+ return 0;
+}
+
+
+/***
+* _safecrt_fassign - convert a string into a float or double.
+****/
+
+void _safecrt_fassign(int flag, void* argument, char* number )
+{
+ if ( flag != 0 ) // double
+ {
+ double dblValue = strtod(number, NULL);
+ *( ( double* )argument ) = dblValue;
+ }
+ else // float
+ {
+ float fltValue = strtof(number, NULL);
+ *( ( float* )argument ) = fltValue;
+ }
+}
+
+
+/***
+* _safecrt_wfassign - convert a wchar_t string into a float or double.
+****/
+
+void _safecrt_wfassign(int flag, void* argument, wchar_t* number )
+{
+ // We cannot use system functions for this - they
+ // assume that wchar_t is four bytes, while we assume
+ // two. So, we need to convert to a regular char string
+ // without using any system functions. To do this,
+ // we'll assume that the numbers are in the 0-9 range and
+ // do a simple conversion.
+
+ char* numberAsChars = ( char* )number;
+ int position = 0;
+
+ // do the convert
+ while ( number[ position ] != 0 )
+ {
+ numberAsChars[ position ] = ( char )( number[ position ] & 0x00FF );
+ position++;
+ }
+ numberAsChars[ position ] = ( char )( number[ position ] & 0x00FF );
+
+ // call the normal char version
+ _safecrt_fassign( flag, argument, numberAsChars );
+}
+
+
+/***
+* _minimal_chartowchar - do a simple char to wchar conversion.
+****/
+
+int _minimal_chartowchar( wchar_t* outWChar, const char* inChar )
+{
+ *outWChar = ( wchar_t )( ( unsigned short )( ( unsigned char )( *inChar ) ) );
+ return 1;
+}
+
+