You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ch...@apache.org on 2009/02/20 04:53:00 UTC

svn commit: r746129 - in /activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf: AsciiBuffer.java Buffer.java UTF8Buffer.java compiler/AltJavaGenerator.java compiler/TextFormat.java

Author: chirino
Date: Fri Feb 20 03:52:57 2009
New Revision: 746129

URL: http://svn.apache.org/viewvc?rev=746129&view=rev
Log:
Adding support for UTF8 and Ascii based buffers.  This should help make it more clear what type of encoding is being used string stored in a buffer feild.


Added:
    activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/AsciiBuffer.java
    activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/UTF8Buffer.java
Modified:
    activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/Buffer.java
    activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/AltJavaGenerator.java
    activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TextFormat.java

Added: activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/AsciiBuffer.java
URL: http://svn.apache.org/viewvc/activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/AsciiBuffer.java?rev=746129&view=auto
==============================================================================
--- activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/AsciiBuffer.java (added)
+++ activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/AsciiBuffer.java Fri Feb 20 03:52:57 2009
@@ -0,0 +1,75 @@
+package org.apache.activemq.protobuf;
+
+
+final public class AsciiBuffer extends Buffer {
+
+    private int hashCode;
+
+    public AsciiBuffer(Buffer other) {
+        super(other);
+    }
+
+    public AsciiBuffer(byte[] data, int offset, int length) {
+        super(data, offset, length);
+    }
+
+    public AsciiBuffer(byte[] data) {
+        super(data);
+    }
+
+    public AsciiBuffer(String input) {
+        super(encode(input));
+    }
+
+    public AsciiBuffer compact() {
+        if (length != data.length) {
+            return new AsciiBuffer(toByteArray());
+        }
+        return this;
+    }
+
+    public String toString()
+    {
+        return decode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if( obj==this )
+            return true;
+         
+         if( obj==null || obj.getClass()!=AsciiBuffer.class )
+            return false;
+         
+         return equals((Buffer)obj);
+    }
+    
+    @Override
+    public int hashCode() {
+        if( hashCode==0 ) {
+            hashCode = super.hashCode();;
+        }
+        return hashCode;
+    }
+    
+    static public byte[] encode(String value)
+    {
+        int size = value.length();
+        byte rc[] = new byte[size];
+        for( int i=0; i < size; i++ ) {
+            rc[i] = (byte)(value.charAt(i)&0xFF);
+        }
+        return rc;
+    }
+    static public String decode(Buffer value)
+    {
+        int size = value.getLength();
+        char rc[] = new char[size];
+        for( int i=0; i < size; i++ ) {
+            rc[i] = (char)(value.byteAt(i) & 0xFF );
+        }
+        return new String(rc);
+    }
+
+    
+}

Modified: activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/Buffer.java
URL: http://svn.apache.org/viewvc/activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/Buffer.java?rev=746129&r1=746128&r2=746129&view=diff
==============================================================================
--- activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/Buffer.java (original)
+++ activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/Buffer.java Fri Feb 20 03:52:57 2009
@@ -17,25 +17,20 @@
 
 package org.apache.activemq.protobuf;
 
-import java.io.UnsupportedEncodingException;
+import java.util.List;
 
-final public class Buffer {
+public class Buffer {
 
-    public byte[] data;
-    public int offset;
-    public int length;
+    final public byte[] data;
+    final public int offset;
+    final public int length;
 
-    public Buffer() {
+    public Buffer(Buffer other) {
+        this(other.data, other.offset, other.length);
     }
-    
-    public Buffer(String input) {
-        this( encode(input) );
-    }
-    
+
     public Buffer(byte data[]) {
-        this.data = data;
-        this.offset = 0;
-        this.length = data.length;
+        this(data, 0, data.length);
     }
 
     public Buffer(byte data[], int offset, int length) {
@@ -44,107 +39,143 @@
         this.length = length;
     }
 
-
-    public byte[] getData() {
-        return data;
+    @Deprecated
+    public Buffer(String value) {
+        this(UTF8Buffer.encode(value));
     }
 
-    public int getLength() {
-        return length;
-    }
+    public final Buffer slice(int low, int high) {
+        int sz;
 
-    public int getOffset() {
-        return offset;
+        if (high < 0) {
+            sz = length + high;
+        } else {
+            sz = high - low;
+        }
+
+        if (sz < 0) {
+            sz = 0;
+        }
+
+        return new Buffer(data, offset + low, sz);
     }
 
-    public void setData(byte[] data) {
-        this.data = data;
+    public final byte[] getData() {
+        return data;
     }
 
-    public void setLength(int length) {
-        this.length = length;
+    public final int getLength() {
+        return length;
     }
 
-    public void setOffset(int offset) {
-        this.offset = offset;
+    public final int getOffset() {
+        return offset;
     }
 
-    public void compact() {
+    public Buffer compact() {
         if (length != data.length) {
-            byte t[] = new byte[length];
-            System.arraycopy(data, offset, t, 0, length);
-            data = t;
-            offset = 0;
+            return new Buffer(toByteArray());
         }
+        return this;
     }
-    
-    public byte[] toByteArray() {
+
+    final public byte[] toByteArray() {
         if (length != data.length) {
             byte t[] = new byte[length];
             System.arraycopy(data, offset, t, 0, length);
-            data = t;
-            offset = 0;
         }
         return data;
     }
 
-    public String toStringUtf8() {
-        try {
-            return new String(data, offset, length, "UTF-8");
-        } catch (UnsupportedEncodingException e) {
-            throw new RuntimeException("A UnsupportedEncodingException was thrown for teh UTF-8 encoding. (This should never happen)");
-        }
-    }
-
     public byte byteAt(int i) {
-        return data[offset+i];
-    }
-    
-    private static byte[] encode(String input) {
-        try {
-            return input.getBytes("UTF-8");
-        } catch (UnsupportedEncodingException e) {
-            throw new RuntimeException("A UnsupportedEncodingException was thrown for teh UTF-8 encoding. (This should never happen)");
-        }
+        return data[offset + i];
     }
 
+
     @Override
     public int hashCode() {
-        byte []target = new byte[4];
-        for(int i=0; i < length; i++) {
-            target[i%4] ^= data[offset+i];
+        byte[] target = new byte[4];
+        for (int i = 0; i < length; i++) {
+            target[i % 4] ^= data[offset + i];
         }
-        return target[0]<<24 | target[1]<<16 | target[2]<<8 | target[3];
+        return target[0] << 24 | target[1] << 16 | target[2] << 8 | target[3];
     }
-    
+
     @Override
     public boolean equals(Object obj) {
-        if( obj==this )
-           return true;
-        
-        if( obj==null || obj.getClass()!=Buffer.class )
-           return false;
-        
-        return equals((Buffer)obj);
-     }
-     
-     public boolean equals(Buffer obj) {
-        if( length != obj.length ) {
+        if (obj == this)
+            return true;
+
+        if (obj == null || obj.getClass() != Buffer.class)
+            return false;
+
+        return equals((Buffer) obj);
+    }
+
+    final public boolean equals(Buffer obj) {
+        if (length != obj.length) {
             return false;
         }
-        for(int i=0; i < length; i++) {
-           if( obj.data[obj.offset+i] != data[offset+i] ) {
-               return false;
-           }
+        for (int i = 0; i < length; i++) {
+            if (obj.data[obj.offset + i] != data[offset + i]) {
+                return false;
+            }
         }
         return true;
-     }
+    }
 
-     public BufferInputStream newInput() {
-         return new BufferInputStream(this);
-     }
-     
-     public BufferOutputStream newOutput() {
-         return new BufferOutputStream(this);
-     }
+    final public BufferInputStream newInput() {
+        return new BufferInputStream(this);
+    }
+
+    final public BufferOutputStream newOutput() {
+        return new BufferOutputStream(this);
+    }
+
+    final public boolean isEmpty() {
+        return length == 0;
+    }
+
+    final public boolean contains(byte value) {
+        return indexOf(value, 0) >= 0;
+    }
+
+    final public int indexOf(byte value, int pos) {
+        for (int i = pos; i < length; i++) {
+            if (data[offset + i] == value) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    final public static Buffer join(List<Buffer> items, Buffer seperator) {
+        if (items.isEmpty())
+            return new Buffer(seperator.data, 0, 0);
+
+        int size = 0;
+        for (Buffer item : items) {
+            size += item.length;
+        }
+        size += seperator.length * (items.size() - 1);
+
+        int pos = 0;
+        byte data[] = new byte[size];
+        for (Buffer item : items) {
+            if (pos != 0) {
+                System.arraycopy(seperator.data, seperator.offset, data, pos, seperator.length);
+                pos += seperator.length;
+            }
+            System.arraycopy(item.data, item.offset, data, pos, item.length);
+            pos += item.length;
+        }
+
+        return new Buffer(data, 0, size);
+    }
+
+    @Deprecated
+    public String toStringUtf8() {
+        return UTF8Buffer.decode(this);
+    }
+        
 }

Added: activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/UTF8Buffer.java
URL: http://svn.apache.org/viewvc/activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/UTF8Buffer.java?rev=746129&view=auto
==============================================================================
--- activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/UTF8Buffer.java (added)
+++ activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/UTF8Buffer.java Fri Feb 20 03:52:57 2009
@@ -0,0 +1,75 @@
+package org.apache.activemq.protobuf;
+
+import java.io.UnsupportedEncodingException;
+
+final public class UTF8Buffer extends Buffer {
+
+    int hashCode;
+    
+    public UTF8Buffer(Buffer other) {
+        super(other);
+    }
+
+    public UTF8Buffer(byte[] data, int offset, int length) {
+        super(data, offset, length);
+    }
+
+    public UTF8Buffer(byte[] data) {
+        super(data);
+    }
+
+    public UTF8Buffer(String input) {
+        super(encode(input));
+    }
+
+    public UTF8Buffer compact() {
+        if (length != data.length) {
+            return new UTF8Buffer(toByteArray());
+        }
+        return this;
+    }
+
+    public String toString()
+    {
+        return decode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if( obj==this )
+            return true;
+         
+         if( obj==null || obj.getClass()!=UTF8Buffer.class )
+            return false;
+         
+         return equals((Buffer)obj);
+    }
+    
+    @Override
+    public int hashCode() {
+        if( hashCode==0 ) {
+            hashCode = super.hashCode();;
+        }
+        return hashCode;
+    }
+    
+    static public byte[] encode(String value)
+    {
+        try {
+            return value.getBytes("UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException("A UnsupportedEncodingException was thrown for teh UTF-8 encoding. (This should never happen)");
+        }
+    }
+
+    static public String decode(Buffer buffer)
+    {
+        try {
+            return new String(buffer.getData(), buffer.getOffset(), buffer.getLength(), "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException("A UnsupportedEncodingException was thrown for teh UTF-8 encoding. (This should never happen)");
+        }
+    }
+    
+
+}

Modified: activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/AltJavaGenerator.java
URL: http://svn.apache.org/viewvc/activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/AltJavaGenerator.java?rev=746129&r1=746128&r2=746129&view=diff
==============================================================================
--- activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/AltJavaGenerator.java (original)
+++ activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/AltJavaGenerator.java Fri Feb 20 03:52:57 2009
@@ -1096,14 +1096,18 @@
 						indent();
 						p(setter + "(input.readString());");
 					} else if (field.getType() == FieldDescriptor.BYTES_TYPE) {
-						p("case "
-								+ makeTag(field.getTag(),
-										WIRETYPE_LENGTH_DELIMITED) + ":");
+						p("case "+ makeTag(field.getTag(), WIRETYPE_LENGTH_DELIMITED) + ":");
 						indent();
-						p(setter + "(input.readBytes());");
+			            String override = getOption(field.getOptions(), "java_override_type", null);
+			            if( "AsciiBuffer".equals(override) ) {
+                            p(setter + "(new org.apache.activemq.protobuf.AsciiBuffer(input.readBytes()));");
+			            } else if( "UTF8Buffer".equals(override) ) {
+                            p(setter + "(new org.apache.activemq.protobuf.UTF8Buffer(input.readBytes()));");
+			            } else {
+	                        p(setter + "(input.readBytes());");
+			            }						
 					} else if (field.getType() == FieldDescriptor.BOOL_TYPE) {
-						p("case " + makeTag(field.getTag(), WIRETYPE_VARINT)
-								+ ":");
+						p("case " + makeTag(field.getTag(), WIRETYPE_VARINT)+ ":");
 						indent();
 						p(setter + "(input.readBool());");
 					} else if (field.getType() == FieldDescriptor.DOUBLE_TYPE) {
@@ -1339,7 +1343,7 @@
                 } else if( field.getType() == FieldDescriptor.BYTES_TYPE ) {
                     p("byte b[] = new byte[in.readInt()];");
                     p("in.readFully(b);");
-                    p("f_"+lname+".add(new org.apache.activemq.protobuf.Buffer(b));");
+                    p("f_"+lname+".add(new "+type+"(b));");
                 } else if (field.getTypeDescriptor().isEnum() ) {
                     p("f_"+lname+".add(" + type + ".valueOf(in.readShort()));");
                 } else {
@@ -1394,7 +1398,7 @@
                     indent();
                     p("byte b[] = new byte[size];");
                     p("in.readFully(b);");
-                    p("f_"+lname+" = new org.apache.activemq.protobuf.Buffer(b);");
+                    p("f_"+lname+" = new "+type+"(b);");
                     p("b_"+lname+" = true;");
                     unindent();
                     p("} else {");
@@ -1919,7 +1923,7 @@
             if( field.isStringType() ) {
                 return asJavaString(defaultOption.getValue());
             } else if( field.getType() == FieldDescriptor.BYTES_TYPE ) {
-                return "new org.apache.activemq.protobuf.Buffer("+asJavaString(defaultOption.getValue())+")";
+                return "new "+javaType(field)+"("+asJavaString(defaultOption.getValue())+")";
             } else if( field.isInteger32Type() ) {
                 int v;
                 if( field.getType() == FieldDescriptor.UINT32_TYPE ) {
@@ -2123,10 +2127,27 @@
             return "java.lang.Float";
         }
         if( field.getType() == FieldDescriptor.STRING_TYPE ) {
-            return "java.lang.String";
+            // TODO: support handling string fields as buffers.
+//            String override = getOption(field.getOptions(), "java_override_type", null);
+//            if( "AsciiBuffer".equals(override) ) {
+//                return "org.apache.activemq.protobuf.AsciiBuffer";
+//            } else if( "UTF8Buffer".equals(override) ) {
+//                return "org.apache.activemq.protobuf.UTF8Buffer";
+//            } else if( "Buffer".equals(override) ) {
+//                return "org.apache.activemq.protobuf.Buffer";
+//            } else {
+                return "java.lang.String";
+//            }
         }
         if( field.getType() == FieldDescriptor.BYTES_TYPE ) {
-            return "org.apache.activemq.protobuf.Buffer";
+            String override = getOption(field.getOptions(), "java_override_type", null);
+            if( "AsciiBuffer".equals(override) ) {
+                return "org.apache.activemq.protobuf.AsciiBuffer";
+            } else if( "UTF8Buffer".equals(override) ) {
+                return "org.apache.activemq.protobuf.UTF8Buffer";
+            } else {
+                return "org.apache.activemq.protobuf.Buffer";
+            }
         }
         if( field.getType() == FieldDescriptor.BOOL_TYPE ) {
             return "java.lang.Boolean";
@@ -2150,10 +2171,27 @@
             return "float";
         }
         if( field.getType() == FieldDescriptor.STRING_TYPE ) {
-            return "java.lang.String";
+            // TODO: support handling string fields as buffers.
+//            String override = getOption(field.getOptions(), "java_override_type", null);
+//            if( "AsciiBuffer".equals(override) ) {
+//                return "org.apache.activemq.protobuf.AsciiBuffer";
+//            } else if( "UTF8Buffer".equals(override) ) {
+//                return "org.apache.activemq.protobuf.UTF8Buffer";
+//            } else if( "Buffer".equals(override) ) {
+//                return "org.apache.activemq.protobuf.Buffer";
+//            } else {
+                return "java.lang.String";
+//            }
         }
         if( field.getType() == FieldDescriptor.BYTES_TYPE ) {
-            return "org.apache.activemq.protobuf.Buffer";
+            String override = getOption(field.getOptions(), "java_override_type", null);
+            if( "AsciiBuffer".equals(override) ) {
+                return "org.apache.activemq.protobuf.AsciiBuffer";
+            } else if( "UTF8Buffer".equals(override) ) {
+                return "org.apache.activemq.protobuf.UTF8Buffer";
+            } else {
+                return "org.apache.activemq.protobuf.Buffer";
+            }
         }
         if( field.getType() == FieldDescriptor.BOOL_TYPE ) {
             return "boolean";

Modified: activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TextFormat.java
URL: http://svn.apache.org/viewvc/activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TextFormat.java?rev=746129&r1=746128&r2=746129&view=diff
==============================================================================
--- activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TextFormat.java (original)
+++ activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TextFormat.java Fri Feb 20 03:52:57 2009
@@ -23,6 +23,7 @@
 import java.util.regex.Pattern;
 
 import org.apache.activemq.protobuf.Buffer;
+import org.apache.activemq.protobuf.UTF8Buffer;
 
 /** 
  * Provide ascii text parsing and formatting support for proto2 instances.
@@ -370,7 +371,7 @@
      * value.  Otherwise, throw a {@link ParseException}.
      */
     public String consumeString() throws ParseException {
-      return consumeBuffer().toStringUtf8();
+      return new UTF8Buffer(consumeBuffer()).toString();
     }
 
     /**
@@ -598,7 +599,7 @@
    * individually as a 3-digit octal escape.  Yes, it's weird.
    */
   static String escapeText(String input) {
-    return escapeBytes(new Buffer(input));
+    return escapeBytes(new UTF8Buffer(input));
   }
 
   /**
@@ -606,7 +607,7 @@
    * Two-digit hex escapes (starting with "\x") are also recognized.
    */
   static String unescapeText(String input) throws InvalidEscapeSequence {
-    return unescapeBytes(input).toStringUtf8();
+    return new UTF8Buffer(unescapeBytes(input)).toString();
   }
 
   /** Is this an octal digit? */