tcsncat_s.inl 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. //
  2. // Copyright (c) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
  4. //
  5. /***
  6. *tcsncat_s.inl - general implementation of _tcscpy_s
  7. *
  8. *
  9. *Purpose:
  10. * This file contains the general algorithm for strncat_s and its variants.
  11. *
  12. ****/
  13. _FUNC_PROLOGUE
  14. errno_t __cdecl _FUNC_NAME(_CHAR *_DEST, size_t _SIZE, const _CHAR *_SRC, size_t _COUNT)
  15. {
  16. _CHAR *p;
  17. size_t available;
  18. if (_COUNT == 0 && _DEST == NULL && _SIZE == 0)
  19. {
  20. /* this case is allowed; nothing to do */
  21. _RETURN_NO_ERROR;
  22. }
  23. /* validation section */
  24. _VALIDATE_STRING(_DEST, _SIZE);
  25. if (_COUNT != 0)
  26. {
  27. _VALIDATE_POINTER_RESET_STRING(_SRC, _DEST, _SIZE);
  28. }
  29. p = _DEST;
  30. available = _SIZE;
  31. while (available > 0 && *p != 0)
  32. {
  33. p++;
  34. available--;
  35. }
  36. if (available == 0)
  37. {
  38. _RESET_STRING(_DEST, _SIZE);
  39. _RETURN_DEST_NOT_NULL_TERMINATED(_DEST, _SIZE);
  40. }
  41. if (_COUNT == _TRUNCATE)
  42. {
  43. while ((*p++ = *_SRC++) != 0 && --available > 0)
  44. {
  45. }
  46. }
  47. else
  48. {
  49. _ASSERT_EXPR((!_CrtGetCheckCount() || _COUNT < available), "Buffer is too small");
  50. while (_COUNT > 0 && (*p++ = *_SRC++) != 0 && --available > 0)
  51. {
  52. _COUNT--;
  53. }
  54. if (_COUNT == 0)
  55. {
  56. *p = 0;
  57. }
  58. }
  59. if (available == 0)
  60. {
  61. if (_COUNT == _TRUNCATE)
  62. {
  63. _DEST[_SIZE - 1] = 0;
  64. _RETURN_TRUNCATE;
  65. }
  66. _RESET_STRING(_DEST, _SIZE);
  67. _RETURN_BUFFER_TOO_SMALL(_DEST, _SIZE);
  68. }
  69. _FILL_STRING(_DEST, _SIZE, _SIZE - available + 1);
  70. _RETURN_NO_ERROR;
  71. }