1 /* 2 * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <stddef.h> /* size_t */ 32 33 /* 34 * Fill @count bytes of memory pointed to by @dst with @val 35 */ 36 void *memset(void *dst, int val, size_t count) 37 { 38 char *ptr = dst; 39 40 while (count--) 41 *ptr++ = val; 42 43 return dst; 44 } 45 46 /* 47 * Compare @len bytes of @s1 and @s2 48 */ 49 int memcmp(const void *s1, const void *s2, size_t len) 50 { 51 const char *s = s1; 52 const char *d = s2; 53 char dc; 54 char sc; 55 56 while (len--) { 57 sc = *s++; 58 dc = *d++; 59 if (sc - dc) 60 return (sc - dc); 61 } 62 63 return 0; 64 } 65 66 /* 67 * Copy @len bytes from @src to @dst 68 */ 69 void *memcpy(void *dst, const void *src, size_t len) 70 { 71 const char *s = src; 72 char *d = dst; 73 74 while (len--) 75 *d++ = *s++; 76 77 return dst; 78 } 79 80 /* 81 * Move @len bytes from @src to @dst 82 */ 83 void *memmove(void *dst, const void *src, size_t len) 84 { 85 /* 86 * The following test makes use of unsigned arithmetic overflow to 87 * more efficiently test the condition !(src <= dst && dst < str+len). 88 * It also avoids the situation where the more explicit test would give 89 * incorrect results were the calculation str+len to overflow (though 90 * that issue is probably moot as such usage is probably undefined 91 * behaviour and a bug anyway. 92 */ 93 if ((size_t)dst - (size_t)src >= len) { 94 /* destination not in source data, so can safely use memcpy */ 95 return memcpy(dst, src, len); 96 } else { 97 /* copy backwards... */ 98 const char *end = dst; 99 const char *s = (const char *)src + len; 100 char *d = (char *)dst + len; 101 while (d != end) 102 *--d = *--s; 103 } 104 return dst; 105 } 106 107 /* 108 * Scan @len bytes of @src for value @c 109 */ 110 void *memchr(const void *src, int c, size_t len) 111 { 112 const char *s = src; 113 114 while (len--) { 115 if (*s == c) 116 return (void *) s; 117 s++; 118 } 119 120 return NULL; 121 } 122