1 /*
2  *	wadname.h
3  *	AYM 2000-04-13
4  */
5 
6 
7 /*
8 This file is part of Yadex.
9 
10 Yadex incorporates code from DEU 5.21 that was put in the public domain in
11 1994 by Rapha�l Quinet and Brendon Wyber.
12 
13 The rest of Yadex is Copyright � 1997-2003 Andr� Majorel and others.
14 
15 This program is free software; you can redistribute it and/or modify it under
16 the terms of the GNU General Public License as published by the Free Software
17 Foundation; either version 2 of the License, or (at your option) any later
18 version.
19 
20 This program is distributed in the hope that it will be useful, but WITHOUT
21 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
23 
24 You should have received a copy of the GNU General Public License along with
25 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
26 Place, Suite 330, Boston, MA 02111-1307, USA.
27 */
28 
29 
30 #ifndef YH_WADNAME
31 #define YH_WADNAME
32 
33 
34 #include <memory.h>
35 #include <ctype.h>
36 
37 #include "wstructs.h"
38 
39 
40 /*
41  *	Wad_name - the name of a wad directory entry
42  *
43  *	This class is used to store a wad directory entry name.
44  *	It provides the following guarantees :
45  *
46  *	- there is minimal memory overhead,
47  *
48  *	- the name is stored in CAPITALS and padded to the
49  *	  maximum length with NULs so that the comparison of two
50  *	  names can be done with memcmp() instead of
51  *	  y_strnicmp(). This is very important for performance
52  *	  reasons.
53  */
54 struct Wad_name
55 {
56   inline Wad_name ();
57   inline Wad_name (const Wad_name& source);
58   inline Wad_name (const char *source);
59   inline Wad_name& operator=  (const char *source);
60   inline bool      operator== (const Wad_name& ref) const;
61   inline bool      operator== (const char *ref) const;
62   inline bool      less       (const Wad_name& other) const;
63   inline bool      has_prefix (const Wad_name& prefix) const;
64   wad_name_t name;
65 };
66 
67 
68 /*
69  *	default ctor
70  */
Wad_name()71 inline Wad_name::Wad_name ()
72 {
73   memset (name, '\0', sizeof name);
74 }
75 
76 
77 /*
78  *	initialize from a trusted source
79  *
80  *	The source *must* be already upper-cased and padded with
81  *	NULs.
82  */
83 
Wad_name(const Wad_name & source)84 inline Wad_name::Wad_name (const Wad_name& source)
85 {
86   memcpy (name, source.name, sizeof name);
87 }
88 
89 
90 /*
91  *	initialize from an untrusted source
92  */
Wad_name(const char * source)93 inline Wad_name::Wad_name (const char *source)
94 {
95   char *p;
96   char *const pmax = name + sizeof name;
97   for (p = name; *source != '\0' && p < pmax; p++)
98     *p = toupper (*source++);
99   // Pad with NULs to the end
100   for (; p < pmax; p++)
101     *p = '\0';
102 }
103 
104 
105 /*
106  *	initialize from an untrusted source
107  */
108 inline Wad_name& Wad_name::operator= (const char *source)
109 {
110   char *p;
111   char *const pmax = name + sizeof name;
112   for (p = name; *source != '\0' && p < pmax; p++)
113     *p = toupper (*source++);
114   // Pad with NULs to the end
115   for (; p < pmax; p++)
116     *p = '\0';
117   return *this;
118 }
119 
120 
121 /*
122  *	compare two Wad_name objects for equality
123  */
124 inline bool Wad_name::operator== (const Wad_name& ref) const
125 {
126   return this == &ref || ! memcmp (name, ref.name, sizeof name);
127 }
128 
129 
130 /*
131  *	compare for equality with an untrusted char[8]
132  */
133 inline bool Wad_name::operator== (const char *ref) const
134 {
135   return ! y_strnicmp (name, ref, sizeof name);
136 }
137 
138 
139 /*
140  *	less - less operator for map
141  *
142  *	This is the operator suitable for use in a map. See
143  *	Lump_dir for an example.
144  *
145  *	Return true iff <this> is "smaller" (lexicographically
146  *	speaking) than <other>, false otherwise.
147  */
less(const Wad_name & other)148 inline bool Wad_name::less (const Wad_name& other) const
149 {
150   const char *p1 = name;
151   const char *p2 = other.name;
152   if (*p1 < *p2) return true; if (*p1++ > *p2++) return false;
153   if (*p1 < *p2) return true; if (*p1++ > *p2++) return false;
154   if (*p1 < *p2) return true; if (*p1++ > *p2++) return false;
155   if (*p1 < *p2) return true; if (*p1++ > *p2++) return false;
156   if (*p1 < *p2) return true; if (*p1++ > *p2++) return false;
157   if (*p1 < *p2) return true; if (*p1++ > *p2++) return false;
158   if (*p1 < *p2) return true; if (*p1++ > *p2++) return false;
159   if (*p1 < *p2) return true;
160   return false;
161   // Supposedly slower
162   //return memcmp (name, other.name, sizeof name) < 0;
163 }
164 
165 
166 #endif
167