Kaynağa Gözat

Added strlncat.

Branimir Karadžić 9 yıl önce
ebeveyn
işleme
c9ffb1e01d
3 değiştirilmiş dosya ile 36 ekleme ve 81 silme
  1. 5 2
      include/bx/string.h
  2. 16 79
      src/string.cpp
  3. 15 0
      tests/string_test.cpp

+ 5 - 2
include/bx/string.h

@@ -131,6 +131,9 @@ namespace bx
 	/// including zero terminator. Copy will be terminated with '\0'.
 	/// including zero terminator. Copy will be terminated with '\0'.
 	size_t strlncpy(char* _dst, size_t _dstSize, const char* _src, size_t _num = INT32_MAX);
 	size_t strlncpy(char* _dst, size_t _dstSize, const char* _src, size_t _num = INT32_MAX);
 
 
+	///
+	size_t strlncat(char* _dst, size_t _dstSize, const char* _src, size_t _num = INT32_MAX);
+
 	///
 	///
 	const char* strnchr(const char* _str, char _ch, size_t _max = INT32_MAX);
 	const char* strnchr(const char* _str, char _ch, size_t _max = INT32_MAX);
 
 
@@ -207,14 +210,14 @@ namespace bx
 	/// Copy src to string dst of size siz.  At most siz-1 characters
 	/// Copy src to string dst of size siz.  At most siz-1 characters
 	/// will be copied.  Always NUL terminates (unless siz == 0).
 	/// will be copied.  Always NUL terminates (unless siz == 0).
 	/// Returns strlen(src); if retval >= siz, truncation occurred.
 	/// Returns strlen(src); if retval >= siz, truncation occurred.
-	size_t strlcpy(char* _dst, const char* _src, size_t _siz);
+	size_t strlcpy(char* _dst, const char* _src, size_t _max);
 
 
 	/// Appends src to string dst of size siz (unlike strncat, siz is the
 	/// Appends src to string dst of size siz (unlike strncat, siz is the
 	/// full size of dst, not space left).  At most siz-1 characters
 	/// full size of dst, not space left).  At most siz-1 characters
 	/// will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
 	/// will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
 	/// Returns strlen(src) + MIN(siz, strlen(initial dst)).
 	/// Returns strlen(src) + MIN(siz, strlen(initial dst)).
 	/// If retval >= siz, truncation occurred.
 	/// If retval >= siz, truncation occurred.
-	size_t strlcat(char* _dst, const char* _src, size_t _siz);
+	size_t strlcat(char* _dst, const char* _src, size_t _max);
 
 
 	///
 	///
 	uint32_t hashMurmur2A(const StringView& _data);
 	uint32_t hashMurmur2A(const StringView& _data);

+ 16 - 79
src/string.cpp

@@ -127,6 +127,17 @@ namespace bx
 		return num;
 		return num;
 	}
 	}
 
 
+	size_t strlncat(char* _dst, size_t _dstSize, const char* _src, size_t _num)
+	{
+		BX_CHECK(NULL != _dst, "_dst can't be NULL!");
+		BX_CHECK(NULL != _src, "_src can't be NULL!");
+		BX_CHECK(0 < _dstSize, "_dstSize can't be 0!");
+
+		const size_t max = _dstSize;
+		const size_t len = strnlen(_dst, max);
+		return strlncpy(&_dst[len], max-len, _src, _num);
+	}
+
 	const char* strnchr(const char* _str, char _ch, size_t _max)
 	const char* strnchr(const char* _str, char _ch, size_t _max)
 	{
 	{
 		for (size_t ii = 0, len = strnlen(_str, _max); ii < len; ++ii)
 		for (size_t ii = 0, len = strnlen(_str, _max); ii < len; ++ii)
@@ -455,88 +466,14 @@ namespace bx
 		snprintf(_out, _count, "%0.2f %c%c", size, "BkMGTPEZY"[idx], idx > 0 ? 'B' : '\0');
 		snprintf(_out, _count, "%0.2f %c%c", size, "BkMGTPEZY"[idx], idx > 0 ? 'B' : '\0');
 	}
 	}
 
 
-	/*
-	 * Copyright (c) 1998 Todd C. Miller <[email protected]>
-	 *
-	 * Permission to use, copy, modify, and distribute this software for any
-	 * purpose with or without fee is hereby granted, provided that the above
-	 * copyright notice and this permission notice appear in all copies.
-	 *
-	 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-	 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-	 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-	 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-	 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-	 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-	 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-	 */
-	size_t strlcpy(char* _dst, const char* _src, size_t _siz)
-	{
-		char* dd = _dst;
-		const char* ss = _src;
-		size_t nn = _siz;
-
-		/* Copy as many bytes as will fit */
-		if (nn != 0)
-		{
-			while (--nn != 0)
-			{
-				if ( (*dd++ = *ss++) == '\0')
-				{
-					break;
-				}
-			}
-		}
-
-		/* Not enough room in dst, add NUL and traverse rest of src */
-		if (nn == 0)
-		{
-			if (_siz != 0)
-			{
-				*dd = '\0';  /* NUL-terminate dst */
-			}
-
-			while (*ss++)
-			{
-			}
-		}
-
-		return(ss - _src - 1); /* count does not include NUL */
+	size_t strlcpy(char* _dst, const char* _src, size_t _max)
+	{
+		return strlncpy(_dst, _max, _src);
 	}
 	}
 
 
-	size_t strlcat(char* _dst, const char* _src, size_t _siz)
+	size_t strlcat(char* _dst, const char* _src, size_t _max)
 	{
 	{
-		char* dd = _dst;
-		const char *s = _src;
-		size_t nn = _siz;
-		size_t dlen;
-
-		/* Find the end of dst and adjust bytes left but don't go past end */
-		while (nn-- != 0 && *dd != '\0')
-		{
-			dd++;
-		}
-
-		dlen = dd - _dst;
-		nn = _siz - dlen;
-
-		if (nn == 0)
-		{
-			return(dlen + strnlen(s));
-		}
-
-		while (*s != '\0')
-		{
-			if (nn != 1)
-			{
-				*dd++ = *s;
-				nn--;
-			}
-			s++;
-		}
-		*dd = '\0';
-
-		return(dlen + (s - _src)); /* count does not include NUL */
+		return strlncat(_dst, _max, _src);
 	}
 	}
 
 
 } // namespace bx
 } // namespace bx

+ 15 - 0
tests/string_test.cpp

@@ -53,6 +53,21 @@ TEST_CASE("strlncpy", "")
 	REQUIRE(num == 4);
 	REQUIRE(num == 4);
 }
 }
 
 
+TEST_CASE("strlncat", "")
+{
+	char dst[128] = { '\0' };
+
+	REQUIRE(0 == bx::strlncat(dst, 1, "cat") );
+
+	REQUIRE(4 == bx::strlncpy(dst, 5, "copy") );
+	REQUIRE(3 == bx::strlncat(dst, 8, "cat") );
+	REQUIRE(0 == bx::strncmp(dst, "copycat") );
+
+	REQUIRE(1 == bx::strlncat(dst, BX_COUNTOF(dst), "------", 1) );
+	REQUIRE(3 == bx::strlncat(dst, BX_COUNTOF(dst), "cat") );
+	REQUIRE(0 == bx::strncmp(dst, "copycat-cat") );
+}
+
 TEST_CASE("strincmp", "")
 TEST_CASE("strincmp", "")
 {
 {
 	REQUIRE(0 == bx::strincmp("test", "test") );
 	REQUIRE(0 == bx::strincmp("test", "test") );