diff options
author | Johannes Schickel | 2010-05-05 17:52:59 +0000 |
---|---|---|
committer | Johannes Schickel | 2010-05-05 17:52:59 +0000 |
commit | 388e4b65bf695bf3574a5311ea3806dc54ffe7a0 (patch) | |
tree | 7b370f1bdb1fc6d36ed60648bd8ad48c29efe77a /common | |
parent | 3b5bd3ada729c668b035ca0a418bf0f28d07d104 (diff) | |
download | scummvm-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.cpp | 80 | ||||
-rw-r--r-- | common/str.h | 37 |
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. |