1*04e0dc4aSTimo Kreuzer //
2*04e0dc4aSTimo Kreuzer // lfind.cpp
3*04e0dc4aSTimo Kreuzer //
4*04e0dc4aSTimo Kreuzer // Copyright (c) Microsoft Corporation. All rights reserved.
5*04e0dc4aSTimo Kreuzer //
6*04e0dc4aSTimo Kreuzer // Defines _lfind(), which performs a linear search over an array.
7*04e0dc4aSTimo Kreuzer //
8*04e0dc4aSTimo Kreuzer #include <corecrt_internal.h>
9*04e0dc4aSTimo Kreuzer #include <search.h>
10*04e0dc4aSTimo Kreuzer
11*04e0dc4aSTimo Kreuzer #ifdef _M_CEE
12*04e0dc4aSTimo Kreuzer #define __fileDECL __clrcall
13*04e0dc4aSTimo Kreuzer #else
14*04e0dc4aSTimo Kreuzer #define __fileDECL __cdecl
15*04e0dc4aSTimo Kreuzer #endif
16*04e0dc4aSTimo Kreuzer
17*04e0dc4aSTimo Kreuzer
18*04e0dc4aSTimo Kreuzer
19*04e0dc4aSTimo Kreuzer #ifdef __USE_CONTEXT
20*04e0dc4aSTimo Kreuzer #define __COMPARE(context, p1, p2) (*compare)(context, p1, p2)
21*04e0dc4aSTimo Kreuzer #else
22*04e0dc4aSTimo Kreuzer #define __COMPARE(context, p1, p2) (*compare)(p1, p2)
23*04e0dc4aSTimo Kreuzer #endif
24*04e0dc4aSTimo Kreuzer
25*04e0dc4aSTimo Kreuzer // Performs a linear search over the array, looking for the value 'key' in an
26*04e0dc4aSTimo Kreuzer // array of 'num' elements of 'width' bytes in size. Returns a pointer to the
27*04e0dc4aSTimo Kreuzer // matching element if found. Otherwise, returns nullptr.
28*04e0dc4aSTimo Kreuzer //
29*04e0dc4aSTimo Kreuzer // Parameters:
30*04e0dc4aSTimo Kreuzer // * key: The key for which to search
31*04e0dc4aSTimo Kreuzer // * base: A pointer to the initial element of the array to be searched
32*04e0dc4aSTimo Kreuzer // * num: The number of elements in the array.
33*04e0dc4aSTimo Kreuzer // * width: The size of each element, in bytes.
34*04e0dc4aSTimo Kreuzer // * comp: Pointer to a function returning analog of strcmp for strings, but
35*04e0dc4aSTimo Kreuzer // supplied by the caller for comparing the array elements. It
36*04e0dc4aSTimo Kreuzer // accepts two pointers to elements; returns negative if 1 < 2;
37*04e0dc4aSTimo Kreuzer // zero if 1 == 2, and positive if 1 > 2.
38*04e0dc4aSTimo Kreuzer #ifndef _M_CEE
39*04e0dc4aSTimo Kreuzer extern "C"
40*04e0dc4aSTimo Kreuzer #endif
41*04e0dc4aSTimo Kreuzer #ifdef __USE_CONTEXT
_lfind_s(void const * const key,void const * const base,unsigned int * const num,size_t const width,int (__fileDECL * const compare)(void *,void const *,void const *),void * const context)42*04e0dc4aSTimo Kreuzer void* __fileDECL _lfind_s(
43*04e0dc4aSTimo Kreuzer void const* const key,
44*04e0dc4aSTimo Kreuzer void const* const base,
45*04e0dc4aSTimo Kreuzer unsigned int* const num,
46*04e0dc4aSTimo Kreuzer size_t const width,
47*04e0dc4aSTimo Kreuzer int (__fileDECL* const compare)(void*, void const*, void const*),
48*04e0dc4aSTimo Kreuzer void* const context
49*04e0dc4aSTimo Kreuzer )
50*04e0dc4aSTimo Kreuzer #else // __USE_CONTEXT
51*04e0dc4aSTimo Kreuzer void* __fileDECL _lfind(
52*04e0dc4aSTimo Kreuzer void const* const key,
53*04e0dc4aSTimo Kreuzer void const* const base,
54*04e0dc4aSTimo Kreuzer unsigned int* const num,
55*04e0dc4aSTimo Kreuzer unsigned int const width,
56*04e0dc4aSTimo Kreuzer int (__fileDECL* const compare)(void const*, void const*)
57*04e0dc4aSTimo Kreuzer )
58*04e0dc4aSTimo Kreuzer #endif // __USE_CONTEXT
59*04e0dc4aSTimo Kreuzer {
60*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN(key != nullptr, EINVAL, nullptr);
61*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN(num != nullptr, EINVAL, nullptr);
62*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN(base != nullptr || *num == 0, EINVAL, nullptr);
63*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN(width > 0, EINVAL, nullptr);
64*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN(compare != nullptr, EINVAL, nullptr);
65*04e0dc4aSTimo Kreuzer
66*04e0dc4aSTimo Kreuzer char const* const first = static_cast<char const*>(base);
67*04e0dc4aSTimo Kreuzer char const* const last = first + *num * width;
68*04e0dc4aSTimo Kreuzer
69*04e0dc4aSTimo Kreuzer for (char const* p = first; p != last; p += width)
70*04e0dc4aSTimo Kreuzer {
71*04e0dc4aSTimo Kreuzer if (__COMPARE(context, key, const_cast<char*>(p)) == 0)
72*04e0dc4aSTimo Kreuzer {
73*04e0dc4aSTimo Kreuzer return const_cast<char*>(p);
74*04e0dc4aSTimo Kreuzer }
75*04e0dc4aSTimo Kreuzer }
76*04e0dc4aSTimo Kreuzer
77*04e0dc4aSTimo Kreuzer return nullptr;
78*04e0dc4aSTimo Kreuzer }
79*04e0dc4aSTimo Kreuzer
80*04e0dc4aSTimo Kreuzer #undef __COMPARE
81