tcsncpy_s.inl 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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. *tcsncpy_s.inl - general implementation of _tcsncpy_s
  7. *
  8. *
  9. *Purpose:
  10. * This file contains the general algorithm for strncpy_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. /* notice that the source string pointer can be NULL in this case */
  28. _RESET_STRING(_DEST, _SIZE);
  29. _RETURN_NO_ERROR;
  30. }
  31. _VALIDATE_POINTER_RESET_STRING(_SRC, _DEST, _SIZE);
  32. p = _DEST;
  33. available = _SIZE;
  34. if (_COUNT == _TRUNCATE)
  35. {
  36. while ((*p++ = *_SRC++) != 0 && --available > 0)
  37. {
  38. }
  39. }
  40. else
  41. {
  42. _ASSERT_EXPR((!_CrtGetCheckCount() || _COUNT < _SIZE), "Buffer is too small");
  43. while ((*p++ = *_SRC++) != 0 && --available > 0 && --_COUNT > 0)
  44. {
  45. }
  46. if (_COUNT == 0)
  47. {
  48. *p = 0;
  49. }
  50. }
  51. if (available == 0)
  52. {
  53. if (_COUNT == _TRUNCATE)
  54. {
  55. _DEST[_SIZE - 1] = 0;
  56. _RETURN_TRUNCATE;
  57. }
  58. _RESET_STRING(_DEST, _SIZE);
  59. _RETURN_BUFFER_TOO_SMALL(_DEST, _SIZE);
  60. }
  61. _FILL_STRING(_DEST, _SIZE, _SIZE - available + 1);
  62. _RETURN_NO_ERROR;
  63. }