1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 *	db_item.cc
24 *
25 *	Copyright (c) 1988-2000 by Sun Microsystems, Inc.
26 *	All Rights Reserved.
27 */
28
29#pragma ident	"%Z%%M%	%I%	%E% SMI"
30
31#include <stdio.h>
32#include <string.h>
33#include <ctype.h>
34
35#include "db_headers.h"
36#include "db_item.h"
37#include "nisdb_mt.h"
38
39#define	HASHSHIFT	3
40#define	HASHMASK	0x1f
41
42#ifdef TDRPC
43#define	LOWER(c)	(isupper((c)) ? tolower((c)) : (c))
44extern "C" {
45	int strncasecmp(const char *s1, const char *s2, int n);
46};
47#else
48#define	LOWER(c)	(isupper((c)) ? _tolower((c)) : (c))
49#endif
50
51
52/* Constructor: creates item using given character sequence and length */
53item::item(char *str, int n)
54{
55	len = n;
56	if ((value = new char[len]) == NULL)
57		FATAL("item::item: cannot allocate space", DB_MEMORY_LIMIT);
58
59	(void) memcpy(value, str, len);
60}
61
62
63/* Constructor: creates item by copying given item */
64item::item(item *model)
65{
66	len = model->len;
67	if ((value = new char[len]) == NULL)
68		FATAL(" item::item: cannot allocate space (2)",
69			DB_MEMORY_LIMIT);
70
71	(void) memcpy(value, model->value, len);
72}
73
74/* Prints contents of item to stdout */
75void
76item::print()
77{
78	int i;
79	for (i = 0; i < len; i++)
80		putchar(value[i]);
81}
82
83/* Equality test.  'casein' TRUE means case insensitive test. */
84bool_t
85item::equal(item* other, bool_t casein)
86{
87	if (casein)	// case-insensitive
88		return ((len == other->len) &&
89			(!strncasecmp(value, other->value, len)));
90	else		// case sensitive
91		return ((len == other->len) &&
92			(!memcmp(value, other->value, len)));
93}
94
95bool_t
96item::equal(char* other, int olen, bool_t casein)
97{
98	if (casein)	// case-insensitive
99		return ((len == olen) && (!strncasecmp(value, other, len)));
100	else		// case sensitive
101		return ((len == olen) && (!memcmp(value, other, len)));
102}
103
104/* Return hash value.  'casein' TRUE means case insensitive test. */
105u_int
106item::get_hashval(bool_t casein)
107{
108	int i;
109	u_int hval = 0;
110
111	// we want to separate the cases so that we don't needlessly do
112	// an extra test for the case-sensitive branch in the for loop
113	if (casein) {	// case insensitive
114		for (i = 0; i < len; i++) {
115			hval = ((hval<<HASHSHIFT)^hval);
116			hval += (LOWER(value[i]) & HASHMASK);
117		}
118	}  else {	// case sensitive
119		for (i = 0; i < len; i++) {
120			hval = ((hval<<HASHSHIFT)^hval);
121			hval += (value[i] & HASHMASK);
122		}
123	}
124
125	return (hval);
126}
127