KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > util > OctetComparator


1 package com.quadcap.util;
2
3 /* Copyright 1997 - 2003 Quadcap Software. All rights reserved.
4  *
5  * This software is distributed under the Quadcap Free Software License.
6  * This software may be used or modified for any purpose, personal or
7  * commercial. Open Source redistributions are permitted. Commercial
8  * redistribution of larger works derived from, or works which bundle
9  * this software requires a "Commercial Redistribution License"; see
10  * http://www.quadcap.com/purchase.
11  *
12  * Redistributions qualify as "Open Source" under one of the following terms:
13  *
14  * Redistributions are made at no charge beyond the reasonable cost of
15  * materials and delivery.
16  *
17  * Redistributions are accompanied by a copy of the Source Code or by an
18  * irrevocable offer to provide a copy of the Source Code for up to three
19  * years at the cost of materials and delivery. Such redistributions
20  * must allow further use, modification, and redistribution of the Source
21  * Code under substantially the same terms as this license.
22  *
23  * Redistributions of source code must retain the copyright notices as they
24  * appear in each source code file, these license terms, and the
25  * disclaimer/limitation of liability set forth as paragraph 6 below.
26  *
27  * Redistributions in binary form must reproduce this Copyright Notice,
28  * these license terms, and the disclaimer/limitation of liability set
29  * forth as paragraph 6 below, in the documentation and/or other materials
30  * provided with the distribution.
31  *
32  * The Software is provided on an "AS IS" basis. No warranty is
33  * provided that the Software is free of defects, or fit for a
34  * particular purpose.
35  *
36  * Limitation of Liability. Quadcap Software shall not be liable
37  * for any damages suffered by the Licensee or any third party resulting
38  * from use of the Software.
39  */

40
41 import java.util.Comparator JavaDoc;
42
43 /**
44  * This class implements a comparator for octet strings.
45  *
46  * @author Stan Bailes
47  */

48 public class OctetComparator implements Comparator JavaDoc {
49     boolean reverse = false;
50     boolean casemap = false;
51
52     static OctetComparator cmp = new OctetComparator();
53     static OctetComparator casecmp = new OctetComparator(true,false);
54     /**
55      * Construct a new octet comparator.
56      */

57     public OctetComparator() {}
58
59     public OctetComparator(boolean casemap, boolean reverse) {
60         this.casemap = casemap;
61         this.reverse = reverse;
62     }
63     
64     /**
65      * Ordering: is object 'a' <i>less, equal, or greater</i> than object 'b'?
66      *
67      * <p>(From the ACAP draft: draft-ietf-acap-spec-06.txt)
68      *
69      * <p>Ordering comparators can determine the ordinal precedence of any
70      * two values. When used for ordering, a comparator's name can be
71      * prefixed with "+" or "-" to indicate that the ordering should be
72      * normal order or reversed order respectively. If no prefix is
73      * included, "+" is assumed.
74      *
75      * <p>A comparator may designate certain values as having
76      * an undefined ordinal precedence. Such values collate with equal
77      * value after all other values regardless of whether normal or reverse
78      * ordering is used.
79      *
80      * @param a the first object to compare
81      * @param b the second object
82      * @return if a < b return -1 else if a > b return 1 else return 0
83      */

84     public int compare(Object JavaDoc a, Object JavaDoc b) {
85         OctetString oa = (OctetString)a;
86         OctetString ob = (OctetString)b;
87
88     int before = reverse ? 1 : -1;
89     int after = 0 - before;
90
91     byte[] va = getBytes(oa);
92     byte[] vb = getBytes(ob);
93     int i = 0;
94     while (i < va.length && i < vb.length) {
95         if (va[i] < vb[i]) return before;
96         if (va[i] > vb[i]) return after;
97         i++;
98     }
99     if (i < vb.length) return before;
100     if (i < va.length) return after;
101     return 0;
102     }
103
104     /**
105      * Determine if the search value is a prefix of the object being
106      * searched. In the case of a prefix search on a multi-value,
107      * the match is successful if the value is a prefix of any one of
108      * the muliple values.
109      *
110      * @param obj the "first" object to compare, normally the candidate
111      * object in a SEARCH operation.
112      * @param val the "second" object, normally the constant value
113      * specified in the SEARCH operation.
114      * @return true if <b>val</b> is a prefix of <b>obj</b>.
115      */

116     public boolean prefixMatch(OctetString obj, OctetString val) {
117     byte[] va = getBytes(val);
118     byte[] vb = getBytes(obj);
119     if (va.length > vb.length) return false;
120     for (int i = 0; i < va.length; i++) {
121         if (va[i] != vb[i]) return false;
122     }
123     return true;
124     }
125
126     /**
127      * Determine if the search value is a substring of the object being
128      * searched. In the case of a substring search on a multi-value,
129      * the match is successful if the value is a substring of any one of
130      * the muliple values.
131      *
132      * @param obj the "first" object to compare, normally the candidate
133      * object in a SEARCH operation.
134      * @param val the "second" object, normally the constant value
135      * specified in the SEARCH operation.
136      * @return true if <b>val</b> is a substring of <b>obj</b>.
137      */

138     public boolean substringMatch(OctetString obj, OctetString val) {
139     byte[] va = getBytes(obj);
140     byte[] vb = getBytes(val);
141     int left = va.length - vb.length;
142     for (int i = 0; i <= left; i++) {
143         boolean match = true;
144         for (int j = 0; match && j < vb.length; j++) {
145         match = va[i+j] == vb[j];
146         }
147         if (match) return true;
148     }
149     return false;
150     }
151
152
153     /**
154      * Determine if the search value matches a glob-style pattern.
155      *
156      * @param obj the object to compare.
157      * @param pattern the pattern
158      * @return true if <b>obj</b> matches the pattern specified by
159      * <b>pattern</b>.
160      */

161     public boolean patternMatch(OctetString obj, OctetString pattern) {
162     byte[] va = getBytes(obj);
163     byte[] vb = getBytes(pattern);
164     return pMatch(va, 0, vb, 0);
165     }
166
167     boolean pMatch(byte[] va, int a, byte[] vb, int b) {
168     while (b < vb.length) {
169         byte p = vb[b++];
170         switch (p) {
171         case (byte)'*':
172                 if (a >= va.length || b >= vb.length) return true;
173         while (a < va.length) {
174             if (pMatch(va, a++, vb, b)) return true;
175         }
176         return false;
177         case (byte)'?':
178         if (a++ >= va.length) return false;
179         break;
180         case (byte)'\\':
181         if (b >= vb.length) return false;
182         p = vb[b++];
183                 // fall through...
184
default:
185         if (a >= va.length) return false;
186         if (va[a++] != p) return false;
187         }
188     }
189     return a >= va.length;
190     }
191         
192     int pMatchOrder(byte[] va, int a, byte[] vb, int b) {
193     int ret = 0;
194     while (b < vb.length) {
195         byte p = vb[b++];
196         switch (p) {
197         case (byte)'*':
198         while (a < va.length) {
199             ret = pMatchOrder(va, a++, vb, b);
200             if (ret == 0) return ret;
201         }
202         return ret;
203         case (byte)'?':
204         if (a++ >= va.length) return -1;
205         break;
206         case (byte)'\\':
207         if (b >= vb.length) return 1;
208         p = vb[b++];
209                 // fall through...
210
default:
211         if (a >= va.length) return -1;
212         byte q = va[a++];
213         if (q < p) return -1;
214         if (q > p) return 1;
215         }
216     }
217     return a >= va.length ? 0 : 1;
218     }
219
220     /**
221      * The layer above which "i;octet" and "i;ascii-casemap" are the
222      * same comparator.
223      *
224      * @param obj the object whose bytes we want.
225      */

226     byte[] getBytes(OctetString obj) {
227     byte[] b = obj.getBytes();
228     if (casemap) {
229             byte[] cb = new byte[b.length];
230         for (int i = 0; i < b.length; i++) {
231         byte c = b[i];
232         if (c >= 'a' && c <= 'z')
233                     cb[i] = (byte)(c - 32);
234                 else
235                     cb[i] = c;
236         }
237             b = cb;
238     }
239     return b;
240     }
241 }
242
Popular Tags