/[classpath]/inetlib/source/gnu/inet/ldap/BEREncoder.java
ViewVC logotype

Diff of /inetlib/source/gnu/inet/ldap/BEREncoder.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by dog, Thu Oct 21 15:21:55 2004 UTC revision 1.4 by dog, Thu Nov 25 22:15:05 2004 UTC
# Line 58  public class BEREncoder Line 58  public class BEREncoder
58     * Constructor.     * Constructor.
59     * @param utf whether to use UTF-8 for encoding strings     * @param utf whether to use UTF-8 for encoding strings
60     */     */
61    public BEREncoder (boolean utf8)    public BEREncoder(boolean utf8)
62    {    {
63      this (utf8, 1024);      this(utf8, 1024);
64    }    }
65    
66    /**    /**
# Line 68  public class BEREncoder Line 68  public class BEREncoder
68     * @param utf whether to use UTF-8 for encoding strings     * @param utf whether to use UTF-8 for encoding strings
69     * @param initialSize the initial buffer size     * @param initialSize the initial buffer size
70     */     */
71    public BEREncoder (boolean utf8, int initialSize)    public BEREncoder(boolean utf8, int initialSize)
72    {    {
73      this.utf8 = utf8;      this.utf8 = utf8;
74      buffer = new byte[initialSize];      buffer = new byte[initialSize];
# Line 80  public class BEREncoder Line 80  public class BEREncoder
80    /**    /**
81     * Reset this encoder for reuse.     * Reset this encoder for reuse.
82     */     */
83    public void reset ()    public void reset()
84    {    {
85      for (int i = 0; i < offset; i++)      for (int i = 0; i < offset; i++)
86        {        {
# Line 97  public class BEREncoder Line 97  public class BEREncoder
97    /**    /**
98     * Returns the current size of the encoded data.     * Returns the current size of the encoded data.
99     */     */
100    public int size ()    public int size()
101    {    {
102      return offset;      return offset;
103    }    }
# Line 105  public class BEREncoder Line 105  public class BEREncoder
105    /**    /**
106     * Returns the encoded data.     * Returns the encoded data.
107     */     */
108    public byte[] toByteArray ()    public byte[] toByteArray()
109    {    {
110      byte[] ret = new byte[offset];      byte[] ret = new byte[offset];
111      System.arraycopy (buffer, 0, ret, 0, offset);      System.arraycopy(buffer, 0, ret, 0, offset);
112      return ret;      return ret;
113    }    }
114    
# Line 118  public class BEREncoder Line 118  public class BEREncoder
118     * Appends a boolean value.     * Appends a boolean value.
119     * @param value the value     * @param value the value
120     */     */
121    public void append (boolean value)    public void append(boolean value)
122    {    {
123      append (value, BERConstants.BOOLEAN);      append(value, BERConstants.BOOLEAN);
124    }    }
125        
126    /**    /**
# Line 128  public class BEREncoder Line 128  public class BEREncoder
128     * @param value the value     * @param value the value
129     * @param code the type code     * @param code the type code
130     */     */
131    public void append (boolean value, int code)    public void append(boolean value, int code)
132    {    {
133      allocate (3);      allocate(3);
134      buffer[offset++] = (byte) code;      buffer[offset++] = (byte) code;
135      buffer[offset++] = (byte) 1; /* length */      buffer[offset++] = (byte) 1; /* length */
136      buffer[offset++] = value ? (byte) 0xff : (byte) 0;      buffer[offset++] = value ? (byte) 0xff :(byte) 0;
137    }    }
138    
139    // -- 8.3 Encoding of an integer value --    // -- 8.3 Encoding of an integer value --
# Line 142  public class BEREncoder Line 142  public class BEREncoder
142     * Appends an integer value.     * Appends an integer value.
143     * @param value the value     * @param value the value
144     */     */
145    public void append (int value)    public void append(int value)
146    {    {
147      append (value, BERConstants.INTEGER);      append(value, BERConstants.INTEGER);
148    }    }
149        
150    /**    /**
# Line 152  public class BEREncoder Line 152  public class BEREncoder
152     * @param value the value     * @param value the value
153     * @param code the type code     * @param code the type code
154     */     */
155    public void append (int value, int code)    public void append(int value, int code)
156    {    {
157      final int mask = 0xff800000;      final int mask = 0xff800000;
158      int len = 4;      int len = 4;
# Line 161  public class BEREncoder Line 161  public class BEREncoder
161          len--;          len--;
162          value <<= 8;          value <<= 8;
163        }        }
164      allocate (len + 2);      allocate(len + 2);
165      buffer[offset++] = (byte) code;      buffer[offset++] = (byte) code;
166      buffer[offset++] = (byte) len;      buffer[offset++] = (byte) len;
167      for (; len > 0; len--)      for (; len > 0; len--)
# Line 180  public class BEREncoder Line 180  public class BEREncoder
180     * Appends an octetstring value.     * Appends an octetstring value.
181     * @param bytes the value     * @param bytes the value
182     */     */
183    public void append (byte[] bytes)    public void append(byte[] bytes)
184      throws BERException      throws BERException
185    {    {
186      append (bytes, BERConstants.OCTET_STRING);      append(bytes, BERConstants.OCTET_STRING);
187    }    }
188        
189    /**    /**
# Line 193  public class BEREncoder Line 193  public class BEREncoder
193     * @param bytes the value     * @param bytes the value
194     * @param code the type code     * @param code the type code
195     */     */
196    public void append (byte[] bytes, int code)    public void append(byte[] bytes, int code)
197      throws BERException      throws BERException
198    {    {
199      int len = (bytes == null) ? 0 : bytes.length;      int len = (bytes == null) ? 0 : bytes.length;
200      append (bytes, 0, len, code);      append(bytes, 0, len, code);
201    }    }
202    
203    void append (byte[] bytes, int off, int len, int code)    void append(byte[] bytes, int off, int len, int code)
204      throws BERException      throws BERException
205    {    {
206      allocate (len + 5);      allocate(len + 5);
207      buffer[offset++] = (byte) code;      buffer[offset++] = (byte) code;
208      appendLength (len);      appendLength(len);
209      if (len > 0)      if (len > 0)
210        {        {
211          System.arraycopy (bytes, off, buffer, offset, len);          System.arraycopy(bytes, off, buffer, offset, len);
212          offset += len;          offset += len;
213        }        }
214    }    }
# Line 217  public class BEREncoder Line 217  public class BEREncoder
217     * Appends a string value.     * Appends a string value.
218     * @param value the value     * @param value the value
219     */     */
220    public void append (String value)    public void append(String value)
221      throws BERException      throws BERException
222    {    {
223      append (value, BERConstants.UTF8_STRING);      append(value, BERConstants.UTF8_STRING);
224    }    }
225        
226    /**    /**
# Line 228  public class BEREncoder Line 228  public class BEREncoder
228     * @param value the value     * @param value the value
229     * @param code the type code     * @param code the type code
230     */     */
231    public void append (String value, int code)    public void append(String value, int code)
232      throws BERException      throws BERException
233    {    {
234      byte[] bytes = null;      byte[] bytes = null;
# Line 241  public class BEREncoder Line 241  public class BEREncoder
241          String encoding = utf8 ? "UTF-8" : "ISO-8859-1";          String encoding = utf8 ? "UTF-8" : "ISO-8859-1";
242          try          try
243            {            {
244              bytes = value.getBytes (encoding);              bytes = value.getBytes(encoding);
245            }            }
246          catch (UnsupportedEncodingException e)          catch (UnsupportedEncodingException e)
247            {            {
248              throw new BERException ("JVM does not support " + encoding);              throw new BERException("JVM does not support " + encoding);
249            }            }
250        }        }
251      int len = bytes.length;      int len = bytes.length;
252      allocate (len + 5);      allocate(len + 5);
253      buffer[offset++] = (byte) code;      buffer[offset++] = (byte) code;
254      appendLength (len);      appendLength(len);
255      System.arraycopy (bytes, 0, buffer, offset, len);      System.arraycopy(bytes, 0, buffer, offset, len);
256      offset += len;      offset += len;
257    }    }
258    
# Line 261  public class BEREncoder Line 261  public class BEREncoder
261    /**    /**
262     * Appends a BER NULL value.     * Appends a BER NULL value.
263     */     */
264    public void appendNull ()    public void appendNull()
265    {    {
266      allocate (2);      allocate(2);
267      buffer[offset++] = BERConstants.NULL;      buffer[offset++] = BERConstants.NULL;
268      buffer[offset++] = (byte) 0; /* length */      buffer[offset++] = (byte) 0; /* length */
269    }    }
# Line 271  public class BEREncoder Line 271  public class BEREncoder
271    /**    /**
272     * Allocate at least len bytes.     * Allocate at least len bytes.
273     */     */
274    private void allocate (int len)    private void allocate(int len)
275    {    {
276      if (buffer.length - offset < len)      if (buffer.length - offset < len)
277        {        {
# Line 282  public class BEREncoder Line 282  public class BEREncoder
282            }            }
283          while (size - offset < len);          while (size - offset < len);
284          byte[] ret = new byte[size];          byte[] ret = new byte[size];
285          System.arraycopy (buffer, 0, ret, 0, offset);          System.arraycopy(buffer, 0, ret, 0, offset);
286          buffer = ret;          buffer = ret;
287        }        }
288    }    }
# Line 290  public class BEREncoder Line 290  public class BEREncoder
290    /**    /**
291     * Append the specified length for a string.     * Append the specified length for a string.
292     */     */
293    private void appendLength (int len)    private void appendLength(int len)
294      throws BERException      throws BERException
295    {    {
296      if (len < 0x80)      if (len < 0x80)
# Line 305  public class BEREncoder Line 305  public class BEREncoder
305      else if (len < 0x10000)      else if (len < 0x10000)
306        {        {
307          buffer[offset++] = (byte) 0x82;          buffer[offset++] = (byte) 0x82;
308          buffer[offset++] = (byte) (len >> 0x08);          buffer[offset++] = (byte)(len >> 0x08);
309          buffer[offset++] = (byte) (len & 0xff);          buffer[offset++] = (byte)(len & 0xff);
310        }        }
311      else if (len < 0x1000000)      else if (len < 0x1000000)
312        {        {
313          buffer[offset++] = (byte) 0x83;          buffer[offset++] = (byte) 0x83;
314          buffer[offset++] = (byte) (len >> 0x10);          buffer[offset++] = (byte)(len >> 0x10);
315          buffer[offset++] = (byte) (len >> 0x08);          buffer[offset++] = (byte)(len >> 0x08);
316          buffer[offset++] = (byte) (len & 0xff);          buffer[offset++] = (byte)(len & 0xff);
317        }        }
318      else      else
319        {        {
320          throw new BERException ("Data too long: " + len);          throw new BERException("Data too long: " + len);
321        }        }
322    }    }
323    
# Line 325  public class BEREncoder Line 325  public class BEREncoder
325     * Appends an RFC2254 search filter to this encoder.     * Appends an RFC2254 search filter to this encoder.
326     * @param filter the filter expression     * @param filter the filter expression
327     */     */
328    public void appendFilter (String filter)    public void appendFilter(String filter)
329      throws BERException      throws BERException
330    {    {
331      if (filter == null || filter.length () == 0)      if (filter == null || filter.length() == 0)
332        {        {
333          throw new BERException ("Empty filter expression");          throw new BERException("Empty filter expression");
334        }        }
335      final byte[] bytes;      final byte[] bytes;
336      String charset = utf8 ? "UTF-8" : "ISO-8859-1";      String charset = utf8 ? "UTF-8" : "ISO-8859-1";
337      try      try
338        {        {
339          bytes = filter.getBytes (charset);          bytes = filter.getBytes(charset);
340        }        }
341      catch (UnsupportedEncodingException e)      catch (UnsupportedEncodingException e)
342        {        {
343          throw new BERException ("JVM does not support " + charset);          throw new BERException("JVM does not support " + charset);
344        }        }
345      appendFilter (bytes, 0);      appendFilter(bytes, 0);
346    }    }
347    
348    int appendFilter (final byte[] bytes, int off)    int appendFilter(final byte[] bytes, int off)
349      throws BERException      throws BERException
350    {    {
351      int depth = 0;      int depth = 0;
352      while (off < bytes.length)      while(off < bytes.length)
353        {        {
354          switch (bytes[off])          switch (bytes[off])
355            {            {
356            case 0x20: // SP            case 0x20: // SP
357              off++;              off++;
358              break; /* NOOP */              break; /* NOOP */
359            case 0x28: // (            case 0x28: //(
360              depth++;              depth++;
361              off++;              off++;
362              break;              break;
# Line 368  public class BEREncoder Line 368  public class BEREncoder
368                }                }
369              break;              break;
370            case 0x26: // &            case 0x26: // &
371              off = appendFilterList (bytes, off + 1,              off = appendFilterList(bytes, off + 1,
372                                      BERConstants.FILTER_AND);                                     BERConstants.FILTER_AND);
373              break;              break;
374            case 0x2c: // |            case 0x2c: // |
375              off = appendFilterList (bytes, off + 1,              off = appendFilterList(bytes, off + 1,
376                                      BERConstants.FILTER_OR);                                     BERConstants.FILTER_OR);
377              break;              break;
378            case 0x21: // !            case 0x21: // !
379              off = appendFilterList (bytes, off + 1,              off = appendFilterList(bytes, off + 1,
380                                      BERConstants.FILTER_NOT);                                     BERConstants.FILTER_NOT);
381              break;              break;
382            default:            default:
383              off = appendFilterItem (bytes, off);              off = appendFilterItem(bytes, off);
384            }            }
385        }        }
386      if (depth != 0)      if (depth != 0)
387        {        {
388          //System.err.println("depth="+depth+", off="+off);          //System.err.println("depth="+depth+", off="+off);
389          throw new BERException ("Unbalanced parentheses");          throw new BERException("Unbalanced parentheses");
390        }        }
391      return off;      return off;
392    }    }
393    
394    int appendFilterList (final byte[] bytes, int off, int code)    int appendFilterList(final byte[] bytes, int off, int code)
395      throws BERException      throws BERException
396    {    {
397      BEREncoder sequence = new BEREncoder (utf8);      BEREncoder sequence = new BEREncoder(utf8);
398      while (off < bytes.length && bytes[off] == '(')      while (off < bytes.length && bytes[off] == '(')
399        {        {
400          off = sequence.appendFilter (bytes, off);          off = sequence.appendFilter(bytes, off);
401        }        }
402      append (sequence.toByteArray (), code);      append(sequence.toByteArray(), code);
403      return off;      return off;
404    }    }
405    
406    int appendFilterItem (final byte[] bytes, int off)    int appendFilterItem(final byte[] bytes, int off)
407      throws BERException      throws BERException
408    {    {
409      int ei = indexOf (bytes, (byte) 0x3d, off); // =      int ei = indexOf(bytes,(byte) 0x3d, off); // =
410      if (ei == -1)      if (ei == -1)
411        {        {
412          throw new BERException ("Missing '='");          throw new BERException("Missing '='");
413        }        }
414      int end = ei;      int end = ei;
415      int code;      int code;
416      BEREncoder item = new BEREncoder (utf8);      BEREncoder item = new BEREncoder(utf8);
417      switch (bytes[ei - 1])      switch (bytes[ei - 1])
418        {        {
419        case 0x7e: // ~ approx        case 0x7e: // ~ approx
# Line 430  public class BEREncoder Line 430  public class BEREncoder
430          break;          break;
431        case 0x3a: // : ext        case 0x3a: // : ext
432          code = BERConstants.FILTER_EXTENSIBLE;          code = BERConstants.FILTER_EXTENSIBLE;
433          // TODO return appendFilterExtensibleMatch (bytes, off, ei);          // TODO return appendFilterExtensibleMatch(bytes, off, ei);
434          break;          break;
435        default: // equal/substring        default: // equal/substring
436          int si = indexOf (bytes, (byte) 0x2a, ei + 1); // *          int si = indexOf(bytes,(byte) 0x2a, ei + 1); // *
437          if (si == -1)          if (si == -1)
438            {            {
439              code = BERConstants.FILTER_EQUAL;              code = BERConstants.FILTER_EQUAL;
# Line 448  public class BEREncoder Line 448  public class BEREncoder
448              else              else
449                {                {
450                  // substring                  // substring
451                  BEREncoder substring = new BEREncoder (utf8);                  BEREncoder substring = new BEREncoder(utf8);
452                  substring.append (bytes, off, end, BERConstants.OCTET_STRING);                  substring.append(bytes, off, end, BERConstants.OCTET_STRING);
453                  end = indexOf (bytes, (byte) 0x29, ei + 1); // )                  end = indexOf(bytes,(byte) 0x29, ei + 1); // )
454                  if (end == -1)                  if (end == -1)
455                    {                    {
456                      throw new BERException ("No terminating ')'");                      throw new BERException("No terminating ')'");
457                    }                    }
458                  BEREncoder value = new BEREncoder (utf8);                  BEREncoder value = new BEREncoder(utf8);
459                  value.append (unencode (bytes, ei + 1, end));                  value.append(unencode(bytes, ei + 1, end));
460                  substring.append (value.toByteArray (), 48);                  substring.append(value.toByteArray(), 48);
461                  append (substring.toByteArray (),                  append(substring.toByteArray(),
462                          BERConstants.FILTER_SUBSTRING);                         BERConstants.FILTER_SUBSTRING);
463                  off = end;                  off = end;
464                  return off;                  return off;
465                }                }
466            }            }
467                        
468        }        }
469      item.append (bytes, off, (end - off), BERConstants.OCTET_STRING);      item.append(bytes, off,(end - off), BERConstants.OCTET_STRING);
470      end = indexOf (bytes, (byte) 0x29, ei + 1); // )      end = indexOf(bytes,(byte) 0x29, ei + 1); // )
471      if (end == -1)      if (end == -1)
472        {        {
473          throw new BERException ("No terminating ')'");          throw new BERException("No terminating ')'");
474        }        }
475      if (code != BERConstants.FILTER_PRESENT)      if (code != BERConstants.FILTER_PRESENT)
476        {        {
477          item.append (unencode (bytes, ei + 1, end));          item.append(unencode(bytes, ei + 1, end));
478        }        }
479      append (item.toByteArray (), code);      append(item.toByteArray(), code);
480      off = end;      off = end;
481      return off;      return off;
482    }    }
# Line 486  public class BEREncoder Line 486  public class BEREncoder
486     * octet-string, starting at the given index. The filterlist terminator     * octet-string, starting at the given index. The filterlist terminator
487     * ')' stops the search.     * ')' stops the search.
488     */     */
489    static int indexOf (final byte[] bytes, byte c, int off)    static int indexOf(final byte[] bytes, byte c, int off)
490    {    {
491      for (int i = off; i < bytes.length; i++)      for (int i = off; i < bytes.length; i++)
492        {        {
# Line 508  public class BEREncoder Line 508  public class BEREncoder
508     * This routine converts each character encoded as "\xx" where xx is the ASCII     * This routine converts each character encoded as "\xx" where xx is the ASCII
509     * character code to a single character.     * character code to a single character.
510     */     */
511    static byte[] unencode (final byte[] bytes, int off, int end)    static byte[] unencode(final byte[] bytes, int off, int end)
512      throws BERException      throws BERException
513    {    {
514      byte[] buf = new byte[end - off];      byte[] buf = new byte[end - off];
515      int pos = 0;      int pos = 0;
516      int bsi = indexOf (bytes, (byte) 0x5c, off); // \      int bsi = indexOf(bytes,(byte) 0x5c, off); // \
517      while (bsi != -1)      while(bsi != -1)
518        {        {
519          if (bsi + 3 > end)          if (bsi + 3 > end)
520            {            {
521              throw new BERException ("Illegal filter value encoding");              throw new BERException("Illegal filter value encoding");
522            }            }
523          int l = bsi - off;          int l = bsi - off;
524          System.arraycopy (bytes, off, buf, pos, l);          System.arraycopy(bytes, off, buf, pos, l);
525          pos += l;          pos += l;
526          int c = Character.digit ((char) bytes[bsi + 2], 0x10);          int c = Character.digit((char) bytes[bsi + 2], 0x10);
527          c += Character.digit ((char) bytes[bsi + 1], 0x10) * 0x10;          c += Character.digit((char) bytes[bsi + 1], 0x10) * 0x10;
528          buf[pos++] = (byte) c;          buf[pos++] = (byte) c;
529          off += l + 3;          off += l + 3;
530          bsi = indexOf (bytes, (byte) 0x5c, off); // \          bsi = indexOf(bytes,(byte) 0x5c, off); // \
531        }        }
532      int l = end - off;      int l = end - off;
533      System.arraycopy (bytes, off, buf, pos, l);      System.arraycopy(bytes, off, buf, pos, l);
534      pos += l;      pos += l;
535      off += l;      off += l;
536      if (pos != buf.length)      if (pos != buf.length)
537        {        {
538          byte[] swap = new byte[pos];          byte[] swap = new byte[pos];
539          System.arraycopy (buf, 0, swap, 0, pos);          System.arraycopy(buf, 0, swap, 0, pos);
540          buf = swap;          buf = swap;
541        }        }
542      return buf;      return buf;
543    }    }
544        
545  }  }
546    

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26