KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > quercus > env > BinaryBuilderValue


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.quercus.env;
31
32 import java.io.IOException JavaDoc;
33 import java.io.InputStream JavaDoc;
34 import java.io.ObjectInputStream JavaDoc;
35 import java.io.ObjectOutputStream JavaDoc;
36 import java.io.OutputStream JavaDoc;
37 import java.io.PrintWriter JavaDoc;
38 import java.io.Serializable JavaDoc;
39
40 /**
41  * Represents a 8-bit binary builder
42  */

43 public class BinaryBuilderValue extends BinaryValue
44   implements Serializable JavaDoc
45 {
46   private byte []_buffer;
47   private int _length;
48
49   private String JavaDoc _value;
50
51   public BinaryBuilderValue()
52   {
53     _buffer = new byte[128];
54   }
55
56   public BinaryBuilderValue(int capacity)
57   {
58     if (capacity < 64)
59       capacity = 128;
60     else
61       capacity = 2 * capacity;
62
63     _buffer = new byte[capacity];
64   }
65
66   public BinaryBuilderValue(byte []buffer, int offset, int length)
67   {
68     _buffer = new byte[length];
69     _length = length;
70
71     System.arraycopy(buffer, offset, _buffer, 0, length);
72   }
73
74   public BinaryBuilderValue(byte []buffer)
75   {
76     this(buffer, 0, buffer.length);
77   }
78   
79   public BinaryBuilderValue(Byte JavaDoc []buffer)
80   {
81     int length = buffer.length;
82     
83     _buffer = new byte[length];
84     _length = length;
85     
86     for (int i = 0; i < length; i++) {
87       _buffer[i] = buffer[i].byteValue();
88     }
89   }
90
91   public BinaryBuilderValue(String JavaDoc value)
92   {
93     this(value.getBytes());
94   }
95
96   /**
97    * Returns the value.
98    */

99   public String JavaDoc getValue()
100   {
101     return toString();
102   }
103
104   /**
105    * Returns the type.
106    */

107   public String JavaDoc getType()
108   {
109     return "string";
110   }
111
112   /**
113    * Returns true for a long
114    */

115   public boolean isLongConvertible()
116   {
117     byte []buffer = _buffer;
118     int len = _length;
119
120     if (len == 0)
121       return false;
122
123     for (int i = 0; i < len; i++) {
124       int ch = _buffer[i];
125
126       if (! ('0' <= ch && ch <= '9'))
127         return false;
128     }
129
130     return true;
131   }
132
133   /**
134    * Returns true for a double
135    */

136   public boolean isDouble()
137   {
138     return getNumericType() == IS_DOUBLE;
139   }
140
141   /**
142    * Returns true for a number
143    */

144   public boolean isNumber()
145   {
146     return getNumericType() != IS_STRING;
147   }
148
149   /**
150    * Returns true for a scalar
151    */

152   public boolean isScalar()
153   {
154     return true;
155   }
156
157   /**
158    * Converts to a double.
159    */

160   protected int getNumericType()
161   {
162     byte []buffer = _buffer;
163     int len = _length;
164
165     if (len == 0)
166       return IS_STRING;
167
168     int i = 0;
169     int ch = 0;
170     boolean hasPoint = false;
171
172     if (i < len && ((ch = buffer[i]) == '+' || ch == '-')) {
173       i++;
174     }
175
176     if (len <= i)
177       return IS_STRING;
178
179     ch = buffer[i];
180
181     if (ch == '.') {
182       for (i++; i < len && '0' <= (ch = buffer[i]) && ch <= '9'; i++) {
183         return IS_DOUBLE;
184       }
185
186       return IS_STRING;
187     }
188     else if (! ('0' <= ch && ch <= '9'))
189       return IS_STRING;
190
191     for (; i < len && '0' <= (ch = buffer[i]) && ch <= '9'; i++) {
192     }
193
194     if (len <= i)
195       return IS_LONG;
196     else if (ch == '.' || ch == 'e' || ch == 'E') {
197       for (i++;
198            i < len && ('0' <= (ch = buffer[i]) && ch <= '9' ||
199                        ch == '+' || ch == '-' || ch == 'e' || ch == 'E');
200            i++) {
201       }
202
203       if (i < len)
204         return IS_STRING;
205       else
206         return IS_DOUBLE;
207     }
208     else
209       return IS_STRING;
210   }
211
212   /**
213    * Converts to a boolean.
214    */

215   public boolean toBoolean()
216   {
217     if (_length == 0)
218       return false;
219     else if (_length == 1 && _buffer[0] == '0')
220       return false;
221     else
222       return true;
223   }
224
225   /**
226    * Converts to a long.
227    */

228   public long toLong()
229   {
230     return toLong(_buffer, 0, _length);
231   }
232
233   /**
234    * Converts to a double.
235    */

236   public double toDouble()
237   {
238     byte []buffer = _buffer;
239     int len = _length;
240     int i = 0;
241     int ch = 0;
242
243     if (i < len && ((ch = buffer[i]) == '+' || ch == '-')) {
244       i++;
245     }
246
247     for (; i < len && '0' <= (ch = buffer[i]) && ch <= '9'; i++) {
248     }
249
250     if (ch == '.') {
251       for (i++; i < len && '0' <= (ch = buffer[i]) && ch <= '9'; i++) {
252       }
253
254       if (i == 1)
255     return 0;
256     }
257
258     if (ch == 'e' || ch == 'E') {
259       int e = i++;
260
261       if (i < len && (ch = buffer[i]) == '+' || ch == '-') {
262         i++;
263       }
264
265       for (; i < len && '0' <= (ch = buffer[i]) && ch <= '9'; i++) {
266       }
267
268       if (i == e + 1)
269         i = e;
270     }
271
272     if (i == 0)
273       return 0;
274
275     try {
276       if (i == len)
277     return Double.parseDouble(toString());
278       else
279     return Double.parseDouble(new String JavaDoc(_buffer, 0, i));
280     } catch (NumberFormatException JavaDoc e) {
281       return 0;
282     }
283   }
284
285   /**
286    * Convert to an input stream.
287    */

288   public InputStream JavaDoc toInputStream()
289   {
290     return new BuilderInputStream();
291   }
292
293   /**
294    * Converts to a string.
295    */

296   public String JavaDoc toString()
297   {
298     // XXX: encoding
299
if (_value == null)
300       _value = new String JavaDoc(_buffer, 0, _length);
301
302     return _value;
303   }
304
305   /**
306    * Converts to an object.
307    */

308   public Object JavaDoc toJavaObject()
309   {
310     if (_value == null)
311       _value = new String JavaDoc(_buffer, 0, _length);
312
313     return _value;
314   }
315
316   /**
317    * Append to a string builder.
318    */

319   public void appendTo(BinaryBuilderValue bb)
320   {
321     bb.append(_buffer, 0, _length);
322   }
323
324   /**
325    * Append to a string builder.
326    */

327   public void appendTo(StringBuilderValue sb)
328   {
329     toUnicodeValue(Env.getInstance()).appendTo(sb);
330   }
331
332   /**
333    * Converts to a key.
334    */

335   public Value toKey()
336   {
337     byte []buffer = _buffer;
338     int len = _length;
339
340     if (len == 0)
341       return this;
342
343     int sign = 1;
344     long value = 0;
345
346     int i = 0;
347     int ch = buffer[i];
348     if (ch == '-') {
349       sign = -1;
350       i++;
351     }
352
353     for (; i < len; i++) {
354       ch = buffer[i];
355
356       if ('0' <= ch && ch <= '9')
357         value = 10 * value + ch - '0';
358       else
359         return this;
360     }
361
362     return new LongValue(sign * value);
363   }
364
365   /**
366    * Converts to a byte array, with no consideration of character encoding.
367    * Each character becomes one byte, characters with values above 255 are
368    * not correctly preserved.
369    */

370   public byte[] toBytes()
371   {
372     byte []buffer = _buffer;
373
374     int len = _length;
375     byte[] bytes = new byte[_length];
376     System.arraycopy(_buffer, 0, bytes, 0, _length);
377
378     return bytes;
379   }
380
381   //
382
// Operations
383
//
384

385   /**
386    * Returns the character at an index
387    */

388   public Value get(Value key)
389   {
390     return charValueAt(key.toLong());
391   }
392
393   /**
394    * Returns the character at an index
395    */

396   public Value getRef(Value key)
397   {
398     return charValueAt(key.toLong());
399   }
400
401   /**
402    * Returns the character at an index
403    */

404   @Override JavaDoc
405   public Value charValueAt(long index)
406   {
407     int len = _length;
408
409     if (index < 0 || len <= index)
410       return StringValue.EMPTY;
411     else
412       return StringValue.create((char) (_buffer[(int) index] & 0xff));
413   }
414
415   /**
416    * sets the character at an index
417    */

418   /*
419   public Value setCharAt(long index, String value)
420   {
421     int len = _length;
422
423     if (index < 0 || len <= index)
424       return this;
425     else {
426       StringBuilderValue sb = new StringBuilderValue(_buffer, 0, (int) index);
427       sb.append(value);
428       sb.append(_buffer, (int) (index + 1), (int) (len - index - 1));
429
430       return sb;
431     }
432   }
433   */

434
435   //
436
// CharSequence
437
//
438

439   /**
440    * Returns the length of the string.
441    */

442   @Override JavaDoc
443   public int length()
444   {
445     return _length;
446   }
447
448   /**
449    * Returns the character at a particular location
450    */

451   @Override JavaDoc
452   public char charAt(int index)
453   {
454     return (char) (_buffer[index] & 0xff);
455   }
456
457   /**
458    * Returns a subsequence
459    */

460   @Override JavaDoc
461   public CharSequence JavaDoc subSequence(int start, int end)
462   {
463     if (end <= start)
464       return StringValue.EMPTY;
465     
466     byte []newBuffer = new byte[end - start];
467     
468     System.arraycopy(_buffer, start, newBuffer, 0, end - start);
469              
470     return new BinaryBuilderValue(newBuffer, 0, end - start);
471   }
472
473   //
474
// Java generator code
475
//
476

477   /**
478    * Prints the value.
479    * @param env
480    */

481   public void print(Env env)
482   {
483     env.write(_buffer, 0, _length);
484   }
485
486   /**
487    * Serializes the value.
488    */

489   public void serialize(StringBuilder JavaDoc sb)
490   {
491     sb.append("s:");
492     sb.append(_length);
493     sb.append(":\"");
494     sb.append(toString());
495     sb.append("\";");
496   }
497
498   //
499
// append code
500
//
501

502   /**
503    * Append a Java string to the value.
504    */

505   @Override JavaDoc
506   public final StringValue append(String JavaDoc s)
507   {
508     StringBuilderValue sb = new StringBuilderValue();
509
510     appendTo(sb);
511     sb.append(s);
512
513     return sb;
514   }
515
516   /**
517    * Append a Java string to the value.
518    */

519   @Override JavaDoc
520   public final StringValue append(String JavaDoc s, int start, int end)
521   {
522     StringBuilderValue sb = new StringBuilderValue();
523
524     appendTo(sb);
525     sb.append(s, start, end);
526
527     return sb;
528   }
529
530   /**
531    * Append a Java char to the value.
532    */

533   @Override JavaDoc
534   public final StringValue append(char ch)
535   {
536     StringBuilderValue sb = new StringBuilderValue();
537
538     appendTo(sb);
539     sb.append(ch);
540
541     return sb;
542   }
543
544   /**
545    * Append a Java buffer to the value.
546    */

547   @Override JavaDoc
548   public final StringValue append(char []buf, int offset, int length)
549   {
550     StringBuilderValue sb = new StringBuilderValue();
551
552     appendTo(sb);
553     sb.append(buf, offset, length);
554
555     return sb;
556   }
557
558   /**
559    * Append a Java buffer to the value.
560    */

561   @Override JavaDoc
562   public final StringValue append(CharSequence JavaDoc buf, int head, int tail)
563   {
564     int length = tail - head;
565     
566     if (_buffer.length < _length + length)
567       ensureCapacity(_length + length);
568
569     if (buf instanceof BinaryBuilderValue) {
570       BinaryBuilderValue sb = (BinaryBuilderValue) buf;
571       
572       System.arraycopy(sb._buffer, head, _buffer, _length, tail - head);
573
574       _length += tail - head;
575
576       return this;
577     }
578     else {
579       StringBuilderValue sb = new StringBuilderValue();
580
581       appendTo(sb);
582       sb.append(buf, head, tail);
583
584       return sb;
585     }
586   }
587
588   /**
589    * Append a Java buffer to the value.
590    */

591   // @Override
592
public final StringValue append(BinaryBuilderValue sb, int head, int tail)
593   {
594     int length = tail - head;
595     
596     if (_buffer.length < _length + length)
597       ensureCapacity(_length + length);
598
599     System.arraycopy(sb._buffer, head, _buffer, _length, tail - head);
600
601     _length += tail - head;
602
603     return this;
604   }
605
606   /**
607    * Append a Java value to the value.
608    */

609   @Override JavaDoc
610   public final StringValue append(Value v)
611   {
612     if (v.isUnicode()) {
613       StringBuilderValue sb = new StringBuilderValue();
614
615       appendTo(sb);
616       v.appendTo(sb);
617
618       return sb;
619     }
620     else {
621       v.appendTo(this);
622
623       return this;
624     }
625   }
626
627   /**
628    * Append a buffer to the value.
629    */

630   public final StringValue append(byte []buf, int offset, int length)
631   {
632     if (_buffer.length < _length + length)
633       ensureCapacity(_length + length);
634
635     System.arraycopy(buf, offset, _buffer, _length, length);
636
637     _length += length;
638
639     return this;
640   }
641
642   /**
643    * Append a double to the value.
644    */

645   public final StringValue append(byte []buf)
646   {
647     return append(buf, 0, buf.length);
648   }
649
650   /**
651    * Append a byte to the value.
652    */

653   public final StringValue append(byte v)
654   {
655     if (_buffer.length < _length + 1)
656       ensureCapacity(_length + 1);
657
658     _buffer[_length++] = v;
659
660     return this;
661   }
662
663   /**
664    * Append a byte to the value.
665    */

666   public final StringValue appendByte(int v)
667   {
668     if (_buffer.length < _length + 1)
669       ensureCapacity(_length + 1);
670
671     _buffer[_length++] = (byte) v;
672
673     return this;
674   }
675
676   /**
677    * Append a Java boolean to the value.
678    */

679   @Override JavaDoc
680   public final StringValue append(boolean v)
681   {
682     return appendBytes(v ? "true" : "false");
683   }
684
685   /**
686    * Append a Java long to the value.
687    */

688   @Override JavaDoc
689   public StringValue append(long v)
690   {
691     return appendBytes(String.valueOf(v));
692   }
693
694   /**
695    * Append a Java double to the value.
696    */

697   @Override JavaDoc
698   public StringValue append(double v)
699   {
700     return appendBytes(String.valueOf(v));
701   }
702
703   /**
704    * Append a bytes to the value.
705    */

706   public StringValue appendBytes(String JavaDoc s)
707   {
708     //XXX: encoding?
709

710     int sublen = s.length();
711
712     if (_buffer.length < _length + sublen)
713       ensureCapacity(_length + sublen);
714
715     for (int i = 0; i < sublen; i++) {
716       _buffer[_length++] = (byte) s.charAt(i);
717     }
718
719     return this;
720   }
721
722   /**
723    * Prepares for reading.
724    */

725   public void prepareReadBuffer()
726   {
727     ensureCapacity(_buffer.length + 1);
728   }
729
730   /**
731    * Returns the buffer.
732    */

733   public byte []getBuffer()
734   {
735     return _buffer;
736   }
737
738   /**
739    * Returns the offset.
740    */

741   public int getOffset()
742   {
743     return _length;
744   }
745
746   /**
747    * Sets the offset.
748    */

749   public void setOffset(int offset)
750   {
751     _length = offset;
752   }
753
754   /**
755    * Returns the current capacity.
756    */

757   public int getLength()
758   {
759     return _buffer.length;
760   }
761
762   /**
763    * Returns an OutputStream.
764    */

765   public OutputStream JavaDoc getOutputStream()
766   {
767     return new BuilderOutputStream();
768   }
769
770   private void ensureCapacity(int newCapacity)
771   {
772     if (newCapacity <= _buffer.length)
773       return;
774     else if (newCapacity < 4096)
775       newCapacity = 4 * newCapacity;
776     else
777       newCapacity = newCapacity + 4096;
778
779     byte []buffer = new byte[newCapacity];
780     System.arraycopy(_buffer, 0, buffer, 0, _length);
781
782     _buffer = buffer;
783   }
784
785   /**
786    * Returns the hash code.
787    */

788   public int hashCode()
789   {
790     int hash = 37;
791
792     int length = _length;
793
794     byte []buffer = _buffer;
795     for (int i = 0; i < length; i++) {
796       hash = 65521 * hash + (buffer[i] & 0xff);
797     }
798
799     return hash;
800   }
801
802   public boolean equals(Object JavaDoc o)
803   {
804     if (o instanceof BinaryBuilderValue) {
805       BinaryBuilderValue value = (BinaryBuilderValue) o;
806
807       int length = _length;
808       
809       if (length != value._length)
810     return false;
811
812       byte []bufferA = _buffer;
813       byte []bufferB = value._buffer;
814
815       for (int i = length - 1; i >= 0; i--) {
816     if (bufferA[i] != bufferB[i])
817       return false;
818       }
819
820       return true;
821     }
822     else if (o instanceof StringValue) {
823       StringValue value = (StringValue) o;
824
825       int length = _length;
826       if (length != value.length())
827     return false;
828
829       byte []buffer = _buffer;
830
831       for (int i = length - 1; i >= 0; i--) {
832     if ((buffer[i] & 0xff) != value.charAt(i))
833       return false;
834       }
835
836       return true;
837     }
838     else
839       return false;
840   }
841
842   //
843
// Java generator code
844
//
845

846   /**
847    * Generates code to recreate the expression.
848    *
849    * @param out the writer to the Java source code.
850    */

851   public void generate(PrintWriter JavaDoc out)
852     throws IOException JavaDoc
853   {
854     out.print("new BinaryBuilderValue(\"");
855     printJavaString(out, toString());
856     out.print("\")");
857   }
858   
859   //
860
// Java serialization code
861
//
862

863   private void writeObject(ObjectOutputStream JavaDoc out)
864     throws IOException JavaDoc
865   {
866     out.writeInt(_length);
867     out.write(_buffer, 0, _length);
868   }
869   
870   private void readObject(ObjectInputStream JavaDoc in)
871     throws ClassNotFoundException JavaDoc, IOException JavaDoc
872   {
873     _length = in.readInt();
874     _buffer = new byte[_length];
875     
876     in.read(_buffer, 0, _length);
877   }
878
879   class BinaryInputStream extends InputStream JavaDoc {
880     private int _offset;
881
882     /**
883      * Reads the next byte.
884      */

885     public int read()
886     {
887       if (_offset < _length)
888     return _buffer[_offset++];
889       else
890     return -1;
891     }
892
893     /**
894      * Reads into a buffer.
895      */

896     public int read(byte []buffer, int offset, int length)
897     {
898       int sublen = _length - _offset;
899
900       if (length < sublen)
901     sublen = length;
902
903       if (sublen <= 0)
904     return -1;
905
906       System.arraycopy(_buffer, _offset, buffer, offset, sublen);
907
908       _offset += sublen;
909
910       return sublen;
911     }
912   }
913
914   class BuilderInputStream extends InputStream JavaDoc {
915     private int _index;
916     
917     /**
918      * Reads the next byte.
919      */

920     public int read()
921     {
922       if (_index < _length)
923     return _buffer[_index++] & 0xff;
924       else
925     return -1;
926     }
927
928     /**
929      * Reads into a buffer.
930      */

931     public int read(byte []buffer, int offset, int length)
932     {
933       int sublen = _length - _index;
934
935       if (length < sublen)
936     sublen = length;
937
938       if (sublen <= 0)
939     return -1;
940
941       System.arraycopy(_buffer, _index, buffer, offset, sublen);
942
943       _index += sublen;
944
945       return sublen;
946     }
947   }
948
949   class BuilderOutputStream extends OutputStream JavaDoc {
950     /**
951      * Writes the next byte.
952      */

953     public void write(int ch)
954     {
955       append(ch);
956     }
957
958     /**
959      * Reads into a buffer.
960      */

961     public void write(byte []buffer, int offset, int length)
962     {
963       append(buffer, offset, length);
964     }
965   }
966 }
967
968
Popular Tags