// RuntimeForStatic base library | C+- (SysRoutine) | Author: Sergei Y.Kitáev
#include "Precompiled.h"
#include "SharedIncludes.h"
namespace RuntimeForStatic {
//==================================================================================================

int $SZ::Length($A,PCWSTR source) $fatal_error_on_failure
{
   $$VERIFY_POINTER_ARG( source );
   int l = -1;
   $LOOP
   {
      if ( ++l == INT_MAX )
         Fail_SourceStringTooLong($ci);
      if ( !*source++ )
         return l;
   }
}
bool $SZ::IsEmpty($A,PCWSTR source)
{
   $$VERIFY_POINTER_ARG( source );
   return *source == L'\0';
}

PWSTR $SZ::Copy($A,PCWSTR source,PWSTR destination,int destCapacity) $fatal_error_on_failure
                                                                     $ret_target
{
   $$VERIFY_POINTER_ARG( source );
   $$VERIFY_POINTER_ARG( destination );
   int l = -1;
   $LOOP
   {
      if ( ++l == INT_MAX ) 
         Fail_SourceStringTooLong($ci);
      if (!( *destination++ = *source++ ))
         return destination;
   }
}
bool $SZ::TruncCopy($A,PCWSTR source,PWSTR destination,int destCapacity) $ret_target
{
   $$VERIFY_POINTER_ARG( source );
   $$VERIFY_POINTER_ARG( destination );
   $$VERIFY_POSITIVE_VALUE_ARG( destCapacity );
   int l = -1;
   while ( l < destCapacity-1 )
   {
      if ( ++l == INT_MAX ) 
         Fail_SourceStringTooLong($ci);
      if (!( *destination++ = *source++ ))
         return l;
   }
   *destination = L'\0';
   return destination;
}

//==================================================================================================

PWSTR $SZ::Duplicate($AM,PCWSTR source) $fatal_error_on_failure $needs_free
{
   return Duplicate($ci,$ci, source );
}
PWSTR $SZ::DuplicateNS($AM,PCWSTR source) $null_on_failure $last_error $needs_free
{
   return DuplicateNS($ci,$ci, source );
}

//--------------------------------------------------------------------------------------------------

PWSTR $SZ::Duplicate($A,$M,PCWSTR source) $fatal_error_on_failure $needs_free
{
   auto rslt = HelpersRT::DuplicateSZ($ci,$m, source );
   if ( !rslt )
      $FatalError::RaiseMemoryAllocationFailure();
   return rslt;
}
PWSTR $SZ::DuplicateNS($A,$M,PCWSTR source) $null_on_failure $last_error $needs_free
{
   auto rslt = HelpersRT::DuplicateSZ($ci,$m, source );
   return rslt ? $RESET_LE( rslt ) :
      $SET_ERROR_LE( $StaticMessages::MemoryAllocationFailure() );
}

//==================================================================================================

PWSTR $SZ::FormatAlloc($AM,PCWSTR messageFmt, ... ) $fatal_error_on_failure $needs_free
{
   $$VERIFY_POINTER_ARG( messageFmt );
   va_list argList;
   PWSTR rslt = FormatAllocVA($ci, $VA_COMPLEMENT( messageFmt, argList ) );
   va_end( argList );
   return rslt;
}
PWSTR $SZ::FormatAllocVA($AM,PCWSTR messageFmt,va_list argList) $fatal_error_on_failure $needs_free
{
   return FormatAllocVA($ci,$ci, messageFmt, argList );
}

PWSTR $SZ::FormatAllocNS($AM,PCWSTR messageFmt, ... ) $null_on_failure $last_error $needs_free
{
   $$VERIFY_POINTER_ARG( messageFmt );
   va_list argList;
   PWSTR rslt = FormatAllocVANS($ci, $VA_COMPLEMENT( messageFmt, argList ) );
   va_end( argList );
   return rslt;
}
PWSTR $SZ::FormatAllocVANS($AM,PCWSTR messageFmt,va_list argList) $null_on_failure
                                                                  $last_error
                                                                  $needs_free
{
   return FormatAllocVANS($ci,$ci, messageFmt, argList );
}

//--------------------------------------------------------------------------------------------------

PWSTR $SZ::FormatAlloc($A,$M,PCWSTR messageFmt, ... ) $fatal_error_on_failure $needs_free
{
   $$VERIFY_POINTER_ARG( messageFmt );
   va_list argList;
   PWSTR rslt = FormatAllocVA($ci,$m, $VA_COMPLEMENT( messageFmt, argList ) );
   va_end( argList );
   return rslt;
}
PWSTR $SZ::FormatAllocVA($A,$M,PCWSTR messageFmt,va_list argList) $fatal_error_on_failure
                                                                  $needs_free
{
   PWSTR rslt = HelpersRT::FormatAllocVA($ci,$m, messageFmt, argList );
   if ( !rslt ) $FatalError::RaiseMemoryAllocationFailure();
   return rslt;
}

PWSTR $SZ::FormatAllocNS($A,$M,PCWSTR messageFmt, ... ) $null_on_failure $last_error $needs_free
{
   $$VERIFY_POINTER_ARG( messageFmt );
   va_list argList;
   PWSTR rslt = FormatAllocVANS($ci,$m, $VA_COMPLEMENT( messageFmt, argList ) );
   va_end( argList );
   return rslt;
}
PWSTR $SZ::FormatAllocVANS($A,$M,PCWSTR messageFmt,va_list argList) $null_on_failure
                                                                    $last_error
                                                                    $needs_free
{
   PWSTR rslt = HelpersRT::FormatAllocVA($ci,$m, messageFmt, argList );
   return rslt ? $RESET_LE( rslt ) :
      $SET_ERROR_LE( $StaticMessages::MemoryAllocationFailure() );
}

//==================================================================================================

int $SZ::VerifyLength($A,SIZE_T length) $fatal_error_on_failure
{
   if ( length >= INT_MAX )
      $INCORRECT_ARGUMENT_WITH_MESSAGE_1( length, SourceStringTooLong_MessgeFmt(), INT_MAX - 1 );
   return (int)length;
}
void $SZ::Fail_SourceStringTooLong($A)
{
   $FatalError::RaiseFmt($$CI, SourceStringTooLong_MessgeFmt(), INT_MAX - 1 );
}
PCWSTR $SZ::SourceStringTooLong_MessgeFmt()
{
   return $TEXT(
      L"Source string is too long.\r\n"
      L"Maximum length is %d (INT_MAX-1) characters.",
      L"Слишком длинная исходная строка.\r\n"
      L"Максимальная длина составляет %d (INT_MAX-1) символов." );
}

//==================================================================================================
} // RuntimeForStatic
