1 //===-- memmem implementation -----------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_INLINE_MEMMEM_H 10 #define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_INLINE_MEMMEM_H 11 12 #include "src/__support/macros/attributes.h" 13 #include "src/__support/macros/config.h" 14 15 #include <stddef.h> 16 17 namespace LIBC_NAMESPACE_DECL { 18 19 template <typename Comp> 20 LIBC_INLINE constexpr static void * 21 inline_memmem(const void *haystack, size_t haystack_len, const void *needle, 22 size_t needle_len, Comp &&comp) { 23 // TODO: simple brute force implementation. This can be 24 // improved upon using well known string matching algorithms. 25 if (!needle_len) 26 return const_cast<void *>(haystack); 27 28 if (needle_len > haystack_len) 29 return nullptr; 30 31 const unsigned char *h = static_cast<const unsigned char *>(haystack); 32 const unsigned char *n = static_cast<const unsigned char *>(needle); 33 for (size_t i = 0; i <= (haystack_len - needle_len); ++i) { 34 size_t j = 0; 35 for (; j < needle_len && !comp(h[i + j], n[j]); ++j) 36 ; 37 if (j == needle_len) 38 return const_cast<unsigned char *>(h + i); 39 } 40 return nullptr; 41 } 42 43 } // namespace LIBC_NAMESPACE_DECL 44 45 #endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_INLINE_MEMMEM_H 46