aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorJohannes Schickel2010-05-05 17:52:59 +0000
committerJohannes Schickel2010-05-05 17:52:59 +0000
commit388e4b65bf695bf3574a5311ea3806dc54ffe7a0 (patch)
tree7b370f1bdb1fc6d36ed60648bd8ad48c29efe77a /common
parent3b5bd3ada729c668b035ca0a418bf0f28d07d104 (diff)
downloadscummvm-rg350-388e4b65bf695bf3574a5311ea3806dc54ffe7a0.tar.gz
scummvm-rg350-388e4b65bf695bf3574a5311ea3806dc54ffe7a0.tar.bz2
scummvm-rg350-388e4b65bf695bf3574a5311ea3806dc54ffe7a0.zip
Add a custom implementation of OpenBSD's strlcat and strlcpy.
This includes both an implementation and some basic unit tests for the above mentioned functions. svn-id: r48953
Diffstat (limited to 'common')
-rw-r--r--common/str.cpp80
-rw-r--r--common/str.h37
2 files changed, 117 insertions, 0 deletions
diff --git a/common/str.cpp b/common/str.cpp
index 56ef39cb82..5e771c8b4d 100644
--- a/common/str.cpp
+++ b/common/str.cpp
@@ -739,4 +739,84 @@ String tag2string(uint32 tag) {
return Common::String(str);
}
+size_t strlcpy(char *dst, const char *src, size_t size) {
+ // Our backup of the source's start, we need this
+ // to calculate the source's length.
+ const char * const srcStart = src;
+
+ // In case a non-empty size was specified we
+ // copy over (size - 1) bytes at max.
+ if (size != 0) {
+ // Copy over (size - 1) bytes at max.
+ while (--size != 0) {
+ if ((*dst++ = *src) == 0)
+ break;
+ ++src;
+ }
+
+ // In case the source string was longer than the
+ // destination, we need to add a terminating
+ // zero.
+ if (size == 0)
+ *dst = 0;
+ }
+
+ // Move to the terminating zero of the source
+ // string, we need this to determin the length
+ // of the source string.
+ while (*src)
+ ++src;
+
+ // Return the source string's length.
+ return src - srcStart;
+}
+
+size_t strlcat(char *dst, const char *src, size_t size) {
+ // In case the destination buffer does not contain
+ // space for at least 1 character, we will just
+ // return the source string's length.
+ if (size == 0)
+ return strlen(src);
+
+ // Our backup of the source's start, we need this
+ // to calculate the source's length.
+ const char * const srcStart = src;
+
+ // Our backup of the destination's start, we need
+ // this to calculate the destination's length.
+ const char * const dstStart = dst;
+
+ // Search the end of the destination, but do not
+ // move past the terminating zero.
+ while (size-- != 0 && *dst != 0)
+ ++dst;
+
+ // Calculate the destination's length;
+ const size_t dstLength = dst - dstStart;
+
+ // In case we reached the end of the destination
+ // buffer before we had a chance to append any
+ // characters we will just return the destination
+ // length plus the source string's length.
+ if (size == 0)
+ return dstLength + strlen(srcStart);
+
+ // Copy over all of the source that fits
+ // the destination buffer. We also need
+ // to take the terminating zero we will
+ // add into consideration.
+ while (size-- != 0 && *src != 0)
+ *dst++ = *src++;
+ *dst = 0;
+
+ // Move to the terminating zero of the source
+ // string, we need this to determin the length
+ // of the source string.
+ while (*src)
+ ++src;
+
+ // Return the total length of the result string
+ return dstLength + (src - srcStart);
+}
+
} // End of namespace Common
diff --git a/common/str.h b/common/str.h
index 0cdd3e8c10..12e2b0d2d3 100644
--- a/common/str.h
+++ b/common/str.h
@@ -326,6 +326,43 @@ bool matchString(const char *str, const char *pat, bool ignoreCase = false, bool
String tag2string(uint32 tag);
/**
+ * Copy up to size - 1 characters from src to dst and also zero terminate the
+ * result. Note that src must be a zero terminated string.
+ *
+ * In case size is zero this function just returns the length of the source
+ * string.
+ *
+ * @note This is modeled after OpenBSD's strlcpy. See the manpage here:
+ * http://www.openbsd.org/cgi-bin/man.cgi?query=strlcpy
+ *
+ * @param dst The destination buffer.
+ * @param src The source string.
+ * @param size The size of the destination buffer.
+ * @return The length of the (non-truncated) result, i.e. strlen(src).
+ */
+size_t strlcpy(char *dst, const char *src, size_t size);
+
+/**
+ * Append the string src to the string dst. Note that both src and dst must be
+ * zero terminated. The result will be zero terminated. At most
+ * "size - strlen(dst) - 1" bytes will be appended.
+ *
+ * In case the dst string does not contain a zero within the first "size" bytes
+ * the dst string will not be changed and size + strlen(src) is returned.
+ *
+ * @note This is modeled after OpenBSD's strlcat. See the manpage here:
+ * http://www.openbsd.org/cgi-bin/man.cgi?query=strlcat
+ *
+ * @param dst The string the source string should be appended to.
+ * @param src The source string.
+ * @param size The (total) size of the destination buffer.
+ * @return The length of the (non-truncated) result. That is
+ * strlen(dst) + strlen(src). In case strlen(dst) > size
+ * size + strlen(src) is returned.
+ */
+size_t strlcat(char *dst, const char *src, size_t size);
+
+/**
* Convenience wrapper for tag2string which "returns" a C string.
* Note: It is *NOT* safe to do anything with the return value other than directly
* copying or printing it.