Skip to content

Commit e4c89f9

Browse files
qzedandersson
authored andcommitted
lib/ucs2_string: Add UCS-2 strscpy function
Add a ucs2_strscpy() function for UCS-2 strings. The behavior is equivalent to the standard strscpy() function, just for 16-bit character UCS-2 strings. Signed-off-by: Maximilian Luz <[email protected]> Reviewed-by: Bjorn Andersson <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Bjorn Andersson <[email protected]>
1 parent 0bb80ec commit e4c89f9

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

include/linux/ucs2_string.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ typedef u16 ucs2_char_t;
1010
unsigned long ucs2_strnlen(const ucs2_char_t *s, size_t maxlength);
1111
unsigned long ucs2_strlen(const ucs2_char_t *s);
1212
unsigned long ucs2_strsize(const ucs2_char_t *data, unsigned long maxlength);
13+
ssize_t ucs2_strscpy(ucs2_char_t *dst, const ucs2_char_t *src, size_t count);
1314
int ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len);
1415

1516
unsigned long ucs2_utf8size(const ucs2_char_t *src);

lib/ucs2_string.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,58 @@ ucs2_strsize(const ucs2_char_t *data, unsigned long maxlength)
3232
}
3333
EXPORT_SYMBOL(ucs2_strsize);
3434

35+
/**
36+
* ucs2_strscpy() - Copy a UCS2 string into a sized buffer.
37+
*
38+
* @dst: Pointer to the destination buffer where to copy the string to.
39+
* @src: Pointer to the source buffer where to copy the string from.
40+
* @count: Size of the destination buffer, in UCS2 (16-bit) characters.
41+
*
42+
* Like strscpy(), only for UCS2 strings.
43+
*
44+
* Copy the source string @src, or as much of it as fits, into the destination
45+
* buffer @dst. The behavior is undefined if the string buffers overlap. The
46+
* destination buffer @dst is always NUL-terminated, unless it's zero-sized.
47+
*
48+
* Return: The number of characters copied into @dst (excluding the trailing
49+
* %NUL terminator) or -E2BIG if @count is 0 or @src was truncated due to the
50+
* destination buffer being too small.
51+
*/
52+
ssize_t ucs2_strscpy(ucs2_char_t *dst, const ucs2_char_t *src, size_t count)
53+
{
54+
long res;
55+
56+
/*
57+
* Ensure that we have a valid amount of space. We need to store at
58+
* least one NUL-character.
59+
*/
60+
if (count == 0 || WARN_ON_ONCE(count > INT_MAX / sizeof(*dst)))
61+
return -E2BIG;
62+
63+
/*
64+
* Copy at most 'count' characters, return early if we find a
65+
* NUL-terminator.
66+
*/
67+
for (res = 0; res < count; res++) {
68+
ucs2_char_t c;
69+
70+
c = src[res];
71+
dst[res] = c;
72+
73+
if (!c)
74+
return res;
75+
}
76+
77+
/*
78+
* The loop above terminated without finding a NUL-terminator,
79+
* exceeding the 'count': Enforce proper NUL-termination and return
80+
* error.
81+
*/
82+
dst[count - 1] = 0;
83+
return -E2BIG;
84+
}
85+
EXPORT_SYMBOL(ucs2_strscpy);
86+
3587
int
3688
ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len)
3789
{

0 commit comments

Comments
 (0)