comparison src/org/eclipse/jetty/io/AbstractBuffer.java @ 802:3428c60d7cfc

replace jetty jars with source
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 07 Sep 2016 21:15:48 -0600
parents
children 8e9db0bbf4f9
comparison
equal deleted inserted replaced
801:6a21393191c1 802:3428c60d7cfc
1 //
2 // ========================================================================
3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
8 //
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
11 //
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
14 //
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
17 //
18
19 package org.eclipse.jetty.io;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.OutputStream;
24 import java.nio.charset.Charset;
25
26 import org.eclipse.jetty.util.TypeUtil;
27 import org.eclipse.jetty.util.log.Log;
28 import org.eclipse.jetty.util.log.Logger;
29
30 /**
31 *
32 *
33 */
34 public abstract class AbstractBuffer implements Buffer
35 {
36 private static final Logger LOG = Log.getLogger(AbstractBuffer.class);
37
38 private final static boolean __boundsChecking = Boolean.getBoolean("org.eclipse.jetty.io.AbstractBuffer.boundsChecking");
39
40 protected final static String
41 __IMMUTABLE = "IMMUTABLE",
42 __READONLY = "READONLY",
43 __READWRITE = "READWRITE",
44 __VOLATILE = "VOLATILE";
45
46 protected int _access;
47 protected boolean _volatile;
48
49 protected int _get;
50 protected int _put;
51 protected int _hash;
52 protected int _hashGet;
53 protected int _hashPut;
54 protected int _mark;
55 protected String _string;
56 protected View _view;
57
58 /**
59 * Constructor for BufferView
60 *
61 * @param access 0==IMMUTABLE, 1==READONLY, 2==READWRITE
62 */
63 public AbstractBuffer(int access, boolean isVolatile)
64 {
65 if (access == IMMUTABLE && isVolatile)
66 throw new IllegalArgumentException("IMMUTABLE && VOLATILE");
67 setMarkIndex(-1);
68 _access = access;
69 _volatile = isVolatile;
70 }
71
72 /*
73 * @see org.eclipse.io.Buffer#toArray()
74 */
75 public byte[] asArray()
76 {
77 byte[] bytes = new byte[length()];
78 byte[] array = array();
79 if (array != null)
80 System.arraycopy(array, getIndex(), bytes, 0, bytes.length);
81 else
82 peek(getIndex(), bytes, 0, length());
83 return bytes;
84 }
85
86 public ByteArrayBuffer duplicate(int access)
87 {
88 Buffer b=this.buffer();
89 if (this instanceof Buffer.CaseInsensitve || b instanceof Buffer.CaseInsensitve)
90 return new ByteArrayBuffer.CaseInsensitive(asArray(), 0, length(),access);
91 else
92 return new ByteArrayBuffer(asArray(), 0, length(), access);
93 }
94
95 /*
96 * @see org.eclipse.io.Buffer#asNonVolatile()
97 */
98 public Buffer asNonVolatileBuffer()
99 {
100 if (!isVolatile()) return this;
101 return duplicate(_access);
102 }
103
104 public Buffer asImmutableBuffer()
105 {
106 if (isImmutable()) return this;
107 return duplicate(IMMUTABLE);
108 }
109
110 /*
111 * @see org.eclipse.util.Buffer#asReadOnlyBuffer()
112 */
113 public Buffer asReadOnlyBuffer()
114 {
115 if (isReadOnly()) return this;
116 return new View(this, markIndex(), getIndex(), putIndex(), READONLY);
117 }
118
119 public Buffer asMutableBuffer()
120 {
121 if (!isImmutable()) return this;
122
123 Buffer b=this.buffer();
124 if (b.isReadOnly())
125 {
126 return duplicate(READWRITE);
127 }
128 return new View(b, markIndex(), getIndex(), putIndex(), _access);
129 }
130
131 public Buffer buffer()
132 {
133 return this;
134 }
135
136 public void clear()
137 {
138 setMarkIndex(-1);
139 setGetIndex(0);
140 setPutIndex(0);
141 }
142
143 public void compact()
144 {
145 if (isReadOnly()) throw new IllegalStateException(__READONLY);
146 int s = markIndex() >= 0 ? markIndex() : getIndex();
147 if (s > 0)
148 {
149 byte array[] = array();
150 int length = putIndex() - s;
151 if (length > 0)
152 {
153 if (array != null)
154 System.arraycopy(array(), s, array(), 0, length);
155 else
156 poke(0, peek(s, length));
157 }
158 if (markIndex() > 0) setMarkIndex(markIndex() - s);
159 setGetIndex(getIndex() - s);
160 setPutIndex(putIndex() - s);
161 }
162 }
163
164 @Override
165 public boolean equals(Object obj)
166 {
167 if (obj==this)
168 return true;
169
170 // reject non buffers;
171 if (obj == null || !(obj instanceof Buffer)) return false;
172 Buffer b = (Buffer) obj;
173
174 if (this instanceof Buffer.CaseInsensitve || b instanceof Buffer.CaseInsensitve)
175 return equalsIgnoreCase(b);
176
177 // reject different lengths
178 if (b.length() != length()) return false;
179
180 // reject AbstractBuffer with different hash value
181 if (_hash != 0 && obj instanceof AbstractBuffer)
182 {
183 AbstractBuffer ab = (AbstractBuffer) obj;
184 if (ab._hash != 0 && _hash != ab._hash) return false;
185 }
186
187 // Nothing for it but to do the hard grind.
188 int get=getIndex();
189 int bi=b.putIndex();
190 for (int i = putIndex(); i-->get;)
191 {
192 byte b1 = peek(i);
193 byte b2 = b.peek(--bi);
194 if (b1 != b2) return false;
195 }
196 return true;
197 }
198
199 public boolean equalsIgnoreCase(Buffer b)
200 {
201 if (b==this)
202 return true;
203
204 // reject different lengths
205 if (b.length() != length()) return false;
206
207 // reject AbstractBuffer with different hash value
208 if (_hash != 0 && b instanceof AbstractBuffer)
209 {
210 AbstractBuffer ab = (AbstractBuffer) b;
211 if (ab._hash != 0 && _hash != ab._hash) return false;
212 }
213
214 // Nothing for it but to do the hard grind.
215 int get=getIndex();
216 int bi=b.putIndex();
217
218 byte[] array = array();
219 byte[] barray= b.array();
220 if (array!=null && barray!=null)
221 {
222 for (int i = putIndex(); i-->get;)
223 {
224 byte b1 = array[i];
225 byte b2 = barray[--bi];
226 if (b1 != b2)
227 {
228 if ('a' <= b1 && b1 <= 'z') b1 = (byte) (b1 - 'a' + 'A');
229 if ('a' <= b2 && b2 <= 'z') b2 = (byte) (b2 - 'a' + 'A');
230 if (b1 != b2) return false;
231 }
232 }
233 }
234 else
235 {
236 for (int i = putIndex(); i-->get;)
237 {
238 byte b1 = peek(i);
239 byte b2 = b.peek(--bi);
240 if (b1 != b2)
241 {
242 if ('a' <= b1 && b1 <= 'z') b1 = (byte) (b1 - 'a' + 'A');
243 if ('a' <= b2 && b2 <= 'z') b2 = (byte) (b2 - 'a' + 'A');
244 if (b1 != b2) return false;
245 }
246 }
247 }
248 return true;
249 }
250
251 public byte get()
252 {
253 return peek(_get++);
254 }
255
256 public int get(byte[] b, int offset, int length)
257 {
258 int gi = getIndex();
259 int l=length();
260 if (l==0)
261 return -1;
262
263 if (length>l)
264 length=l;
265
266 length = peek(gi, b, offset, length);
267 if (length>0)
268 setGetIndex(gi + length);
269 return length;
270 }
271
272 public Buffer get(int length)
273 {
274 int gi = getIndex();
275 Buffer view = peek(gi, length);
276 setGetIndex(gi + length);
277 return view;
278 }
279
280 public final int getIndex()
281 {
282 return _get;
283 }
284
285 public boolean hasContent()
286 {
287 return _put > _get;
288 }
289
290 @Override
291 public int hashCode()
292 {
293 if (_hash == 0 || _hashGet!=_get || _hashPut!=_put)
294 {
295 int get=getIndex();
296 byte[] array = array();
297 if (array==null)
298 {
299 for (int i = putIndex(); i-- >get;)
300 {
301 byte b = peek(i);
302 if ('a' <= b && b <= 'z')
303 b = (byte) (b - 'a' + 'A');
304 _hash = 31 * _hash + b;
305 }
306 }
307 else
308 {
309 for (int i = putIndex(); i-- >get;)
310 {
311 byte b = array[i];
312 if ('a' <= b && b <= 'z')
313 b = (byte) (b - 'a' + 'A');
314 _hash = 31 * _hash + b;
315 }
316 }
317 if (_hash == 0)
318 _hash = -1;
319 _hashGet=_get;
320 _hashPut=_put;
321
322 }
323 return _hash;
324 }
325
326 public boolean isImmutable()
327 {
328 return _access <= IMMUTABLE;
329 }
330
331 public boolean isReadOnly()
332 {
333 return _access <= READONLY;
334 }
335
336 public boolean isVolatile()
337 {
338 return _volatile;
339 }
340
341 public int length()
342 {
343 return _put - _get;
344 }
345
346 public void mark()
347 {
348 setMarkIndex(_get - 1);
349 }
350
351 public void mark(int offset)
352 {
353 setMarkIndex(_get + offset);
354 }
355
356 public int markIndex()
357 {
358 return _mark;
359 }
360
361 public byte peek()
362 {
363 return peek(_get);
364 }
365
366 public Buffer peek(int index, int length)
367 {
368 if (_view == null)
369 {
370 _view = new View(this, -1, index, index + length, isReadOnly() ? READONLY : READWRITE);
371 }
372 else
373 {
374 _view.update(this.buffer());
375 _view.setMarkIndex(-1);
376 _view.setGetIndex(0);
377 _view.setPutIndex(index + length);
378 _view.setGetIndex(index);
379
380 }
381 return _view;
382 }
383
384 public int poke(int index, Buffer src)
385 {
386 _hash=0;
387 /*
388 if (isReadOnly())
389 throw new IllegalStateException(__READONLY);
390 if (index < 0)
391 throw new IllegalArgumentException("index<0: " + index + "<0");
392 */
393
394 int length=src.length();
395 if (index + length > capacity())
396 {
397 length=capacity()-index;
398 /*
399 if (length<0)
400 throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity());
401 */
402 }
403
404 byte[] src_array = src.array();
405 byte[] dst_array = array();
406 if (src_array != null && dst_array != null)
407 System.arraycopy(src_array, src.getIndex(), dst_array, index, length);
408 else if (src_array != null)
409 {
410 int s=src.getIndex();
411 for (int i=0;i<length;i++)
412 poke(index++,src_array[s++]);
413 }
414 else if (dst_array != null)
415 {
416 int s=src.getIndex();
417 for (int i=0;i<length;i++)
418 dst_array[index++]=src.peek(s++);
419 }
420 else
421 {
422 int s=src.getIndex();
423 for (int i=0;i<length;i++)
424 poke(index++,src.peek(s++));
425 }
426
427 return length;
428 }
429
430
431 public int poke(int index, byte[] b, int offset, int length)
432 {
433 _hash=0;
434 /*
435 if (isReadOnly())
436 throw new IllegalStateException(__READONLY);
437 if (index < 0)
438 throw new IllegalArgumentException("index<0: " + index + "<0");
439 */
440 if (index + length > capacity())
441 {
442 length=capacity()-index;
443 /* if (length<0)
444 throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity());
445 */
446 }
447
448 byte[] dst_array = array();
449 if (dst_array != null)
450 System.arraycopy(b, offset, dst_array, index, length);
451 else
452 {
453 int s=offset;
454 for (int i=0;i<length;i++)
455 poke(index++,b[s++]);
456 }
457 return length;
458 }
459
460 public int put(Buffer src)
461 {
462 int pi = putIndex();
463 int l=poke(pi, src);
464 setPutIndex(pi + l);
465 return l;
466 }
467
468 public void put(byte b)
469 {
470 int pi = putIndex();
471 poke(pi, b);
472 setPutIndex(pi + 1);
473 }
474
475 public int put(byte[] b, int offset, int length)
476 {
477 int pi = putIndex();
478 int l = poke(pi, b, offset, length);
479 setPutIndex(pi + l);
480 return l;
481 }
482
483 public int put(byte[] b)
484 {
485 int pi = putIndex();
486 int l = poke(pi, b, 0, b.length);
487 setPutIndex(pi + l);
488 return l;
489 }
490
491 public final int putIndex()
492 {
493 return _put;
494 }
495
496 public void reset()
497 {
498 if (markIndex() >= 0) setGetIndex(markIndex());
499 }
500
501 public void rewind()
502 {
503 setGetIndex(0);
504 setMarkIndex(-1);
505 }
506
507 public void setGetIndex(int getIndex)
508 {
509 /* bounds checking
510 if (isImmutable())
511 throw new IllegalStateException(__IMMUTABLE);
512 if (getIndex < 0)
513 throw new IllegalArgumentException("getIndex<0: " + getIndex + "<0");
514 if (getIndex > putIndex())
515 throw new IllegalArgumentException("getIndex>putIndex: " + getIndex + ">" + putIndex());
516 */
517 _get = getIndex;
518 _hash=0;
519 }
520
521 public void setMarkIndex(int index)
522 {
523 /*
524 if (index>=0 && isImmutable())
525 throw new IllegalStateException(__IMMUTABLE);
526 */
527 _mark = index;
528 }
529
530 public void setPutIndex(int putIndex)
531 {
532 /* bounds checking
533 if (isImmutable())
534 throw new IllegalStateException(__IMMUTABLE);
535 if (putIndex > capacity())
536 throw new IllegalArgumentException("putIndex>capacity: " + putIndex + ">" + capacity());
537 if (getIndex() > putIndex)
538 throw new IllegalArgumentException("getIndex>putIndex: " + getIndex() + ">" + putIndex);
539 */
540 _put = putIndex;
541 _hash=0;
542 }
543
544 public int skip(int n)
545 {
546 if (length() < n) n = length();
547 setGetIndex(getIndex() + n);
548 return n;
549 }
550
551 public Buffer slice()
552 {
553 return peek(getIndex(), length());
554 }
555
556 public Buffer sliceFromMark()
557 {
558 return sliceFromMark(getIndex() - markIndex() - 1);
559 }
560
561 public Buffer sliceFromMark(int length)
562 {
563 if (markIndex() < 0) return null;
564 Buffer view = peek(markIndex(), length);
565 setMarkIndex(-1);
566 return view;
567 }
568
569 public int space()
570 {
571 return capacity() - _put;
572 }
573
574 public String toDetailString()
575 {
576 StringBuilder buf = new StringBuilder();
577 buf.append("[");
578 buf.append(super.hashCode());
579 buf.append(",");
580 buf.append(this.buffer().hashCode());
581 buf.append(",m=");
582 buf.append(markIndex());
583 buf.append(",g=");
584 buf.append(getIndex());
585 buf.append(",p=");
586 buf.append(putIndex());
587 buf.append(",c=");
588 buf.append(capacity());
589 buf.append("]={");
590 if (markIndex() >= 0)
591 {
592 for (int i = markIndex(); i < getIndex(); i++)
593 {
594 byte b = peek(i);
595 TypeUtil.toHex(b,buf);
596 }
597 buf.append("}{");
598 }
599 int count = 0;
600 for (int i = getIndex(); i < putIndex(); i++)
601 {
602 byte b = peek(i);
603 TypeUtil.toHex(b,buf);
604 if (count++ == 50)
605 {
606 if (putIndex() - i > 20)
607 {
608 buf.append(" ... ");
609 i = putIndex() - 20;
610 }
611 }
612 }
613 buf.append('}');
614 return buf.toString();
615 }
616
617 /* ------------------------------------------------------------ */
618 @Override
619 public String toString()
620 {
621 if (isImmutable())
622 {
623 if (_string == null)
624 _string = new String(asArray(), 0, length());
625 return _string;
626 }
627 return new String(asArray(), 0, length());
628 }
629
630 /* ------------------------------------------------------------ */
631 public String toString(String charset)
632 {
633 try
634 {
635 byte[] bytes=array();
636 if (bytes!=null)
637 return new String(bytes,getIndex(),length(),charset);
638 return new String(asArray(), 0, length(),charset);
639
640 }
641 catch(Exception e)
642 {
643 LOG.warn(e);
644 return new String(asArray(), 0, length());
645 }
646 }
647
648 /* ------------------------------------------------------------ */
649 public String toString(Charset charset)
650 {
651 try
652 {
653 byte[] bytes=array();
654 if (bytes!=null)
655 return new String(bytes,getIndex(),length(),charset);
656 return new String(asArray(), 0, length(),charset);
657 }
658 catch(Exception e)
659 {
660 LOG.warn(e);
661 return new String(asArray(), 0, length());
662 }
663 }
664
665 /* ------------------------------------------------------------ */
666 public String toDebugString()
667 {
668 return getClass()+"@"+super.hashCode();
669 }
670
671 /* ------------------------------------------------------------ */
672 public void writeTo(OutputStream out)
673 throws IOException
674 {
675 byte[] array = array();
676
677 if (array!=null)
678 {
679 out.write(array,getIndex(),length());
680 }
681 else
682 {
683 int len = this.length();
684 byte[] buf=new byte[len>1024?1024:len];
685 int offset=_get;
686 while (len>0)
687 {
688 int l=peek(offset,buf,0,len>buf.length?buf.length:len);
689 out.write(buf,0,l);
690 offset+=l;
691 len-=l;
692 }
693 }
694 clear();
695 }
696
697 /* ------------------------------------------------------------ */
698 public int readFrom(InputStream in,int max) throws IOException
699 {
700 byte[] array = array();
701 int s=space();
702 if (s>max)
703 s=max;
704
705 if (array!=null)
706 {
707 int l=in.read(array,_put,s);
708 if (l>0)
709 _put+=l;
710 return l;
711 }
712 else
713 {
714 byte[] buf=new byte[s>1024?1024:s];
715 int total=0;
716 while (s>0)
717 {
718 int l=in.read(buf,0,buf.length);
719 if (l<0)
720 return total>0?total:-1;
721 int p=put(buf,0,l);
722 assert l==p;
723 s-=l;
724 }
725 return total;
726 }
727 }
728 }