add list accessor and do some refactoring

git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_opentype@322 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AFlatValueAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AFlatValueAccessor.java
index 130d597..83c3791 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AFlatValueAccessor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AFlatValueAccessor.java
@@ -22,11 +22,7 @@
 import edu.uci.ics.asterix.runtime.util.container.IElementFactory;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.IValueReference;
 
-public class AFlatValueAccessor implements IBinaryAccessor {
-
-    private byte[] data;
-    private int start;
-    private int len;
+public class AFlatValueAccessor extends AbstractBinaryAccessor {
 
     public static IElementFactory<IBinaryAccessor, IAType> FACTORY = new IElementFactory<IBinaryAccessor, IAType>() {
         public AFlatValueAccessor createElement(IAType type) {
@@ -39,28 +35,6 @@
     }
 
     @Override
-    public void reset(byte[] data, int start, int len) {
-        this.data = data;
-        this.start = start;
-        this.len = len;
-    }
-
-    @Override
-    public byte[] getBytes() {
-        return data;
-    }
-
-    @Override
-    public int getStartIndex() {
-        return start;
-    }
-
-    @Override
-    public int getLength() {
-        return len;
-    }
-
-    @Override
     public boolean equals(Object o) {
         if (!(o instanceof IValueReference))
             return false;
@@ -69,7 +43,10 @@
         int ostart = ivf.getStartIndex();
         int olen = ivf.getLength();
 
-        if (len != olen)
+        byte[] data = getBytes();
+        int start = getStartIndex();
+        int len = getLength();
+        if ( len!= olen)
             return false;
         for (int i = 0; i < len; i++) {
             if (data[start + i] != odata[ostart + i])
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AListAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AListAccessor.java
index 2aa4152..8599d38 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AListAccessor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AListAccessor.java
@@ -1,45 +1,118 @@
 package edu.uci.ics.asterix.runtime.accessors;
 
+import java.io.DataOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AbstractCollectionType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
 import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
 import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
 import edu.uci.ics.asterix.runtime.accessors.visitor.IBinaryAccessorVisitor;
+import edu.uci.ics.asterix.runtime.util.ResettableByteArrayOutputStream;
 import edu.uci.ics.asterix.runtime.util.container.IElementFactory;
 
-public class AListAccessor implements IBinaryAccessor {
+public class AListAccessor extends AbstractBinaryAccessor {
 
     public static IElementFactory<IBinaryAccessor, IAType> FACTORY = new IElementFactory<IBinaryAccessor, IAType>() {
         public IBinaryAccessor createElement(IAType type) {
-            return new AListAccessor();
+            return new AListAccessor((AbstractCollectionType) type);
         }
     };
 
-    private AListAccessor() {
+    private AbstractCollectionType inputType;
+    private IAType itemType;
+    private ATypeTag itemTag;
+    private boolean typedItemList = false;
 
+    private List<IBinaryAccessor> items = new ArrayList<IBinaryAccessor>();
+    private List<IBinaryAccessor> itemTags = new ArrayList<IBinaryAccessor>();
+    private AccessorAllocator allocator = new AccessorAllocator();
+
+    private byte[] typeBuffer = new byte[32768];
+    private ResettableByteArrayOutputStream typeBos = new ResettableByteArrayOutputStream();
+    private DataOutputStream typeDos = new DataOutputStream(typeBos);
+
+    private byte[] dataBuffer = new byte[32768];
+    private ResettableByteArrayOutputStream dataBos = new ResettableByteArrayOutputStream();
+    private DataOutputStream dataDos = new DataOutputStream(dataBos);
+
+    private AListAccessor(AbstractCollectionType inputType) {
+        this.inputType = inputType;
+        if (inputType != null && inputType.getItemType() != null) {
+            itemType = inputType.getItemType();
+            if (itemType.getTypeTag() == ATypeTag.ANY) {
+                typedItemList = false;
+            } else {
+                typedItemList = true;
+                itemTag = inputType.getItemType().getTypeTag();
+            }
+        } else {
+            this.typedItemList = false;
+        }
+    }
+
+    private void reset() {
+        allocator.reset();
+        items.clear();
+        
+        typeBos.setByteArray(typeBuffer, 0);
+        dataBos.setByteArray(dataBuffer, 0);
+    }
+
+    public List<IBinaryAccessor> getItems() {
+        return items;
+    }
+
+    public List<IBinaryAccessor> getItemTags() {
+        return itemTags;
     }
 
     @Override
-    public byte[] getBytes() {
-        // TODO Auto-generated method stub
-        return null;
-    }
+    public void reset(byte[] b, int s, int len) {
+        reset();
 
-    @Override
-    public int getLength() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int getStartIndex() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public void reset(byte[] b, int start, int len) {
-        // TODO Auto-generated method stub
-
+        int numberOfitems = AInt32SerializerDeserializer.getInt(b, s + 6);
+        int itemOffset;
+        if (typedItemList) {
+            switch (itemTag) {
+                case STRING:
+                case RECORD:
+                case ORDEREDLIST:
+                case UNORDEREDLIST:
+                case ANY:
+                    itemOffset = s + 10 + (numberOfitems * 4);
+                    break;
+                default:
+                    itemOffset = s + 10;
+            }
+        } else
+            itemOffset = s + 10 + (numberOfitems * 4);
+        int itemLength = 0;
+        try {
+            if (typedItemList) {
+                for (int i = 0; i < numberOfitems; i++) {
+                    itemLength = NonTaggedFormatUtil.getFieldValueLength(b, itemOffset, itemTag, false);
+                    IBinaryAccessor field = allocator.allocateFieldValue(itemType);
+                    field.reset(b, itemOffset, itemLength);
+                    itemOffset += itemLength;
+                }
+            } else {
+                for (int i = 0; i < numberOfitems; i++) {
+                    itemTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b[itemOffset]);
+                    itemLength = NonTaggedFormatUtil.getFieldValueLength(b, itemOffset, itemTag, true) + 1;
+                    IBinaryAccessor field = allocator.allocateFieldValue(itemType);
+                    field.reset(b, itemOffset, itemLength);
+                    itemOffset += itemLength;
+                }
+            }
+        } catch (AsterixException e) {
+            throw new IllegalStateException(e);
+        }
     }
 
     @Override
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/ARecordAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/ARecordAccessor.java
index bad1acb..686aa8e 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/ARecordAccessor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/ARecordAccessor.java
@@ -36,7 +36,7 @@
 import edu.uci.ics.asterix.runtime.util.container.IElementFactory;
 import edu.uci.ics.hyracks.api.dataflow.value.INullWriter;
 
-public class ARecordAccessor implements IBinaryAccessor {
+public class ARecordAccessor extends AbstractBinaryAccessor {
 
     public static IElementFactory<IBinaryAccessor, IAType> FACTORY = new IElementFactory<IBinaryAccessor, IAType>() {
         public IBinaryAccessor createElement(IAType type) {
@@ -69,10 +69,6 @@
     private ATypeTag typeTag;
     private IBinaryAccessor nullReference = AFlatValueAccessor.FACTORY.createElement(null);
 
-    private byte[] data;
-    private int start;
-    private int len;
-
     public ARecordAccessor(ARecordType inputType) {
         this.inputRecType = inputType;
         IAType[] fieldTypes = inputType.getFieldTypes();
@@ -140,9 +136,7 @@
     public void reset(byte[] b, int start, int len) {
         // clear the previous states
         reset();
-        this.data = b;
-        this.start = start;
-        this.len = len;
+        super.reset(b, start, len);
 
         boolean isExpanded = false;
         int openPartOffset = 0;
@@ -273,21 +267,6 @@
     }
 
     @Override
-    public byte[] getBytes() {
-        return data;
-    }
-
-    @Override
-    public int getStartIndex() {
-        return start;
-    }
-
-    @Override
-    public int getLength() {
-        return len;
-    }
-
-    @Override
     public <R, T> R accept(IBinaryAccessorVisitor<R, T> vistor, T tag) throws AsterixException {
         return vistor.visit(this, tag);
     }
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AbstractBinaryAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AbstractBinaryAccessor.java
new file mode 100644
index 0000000..644a04d
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AbstractBinaryAccessor.java
@@ -0,0 +1,33 @@
+package edu.uci.ics.asterix.runtime.accessors;
+
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+
+public abstract class AbstractBinaryAccessor implements IBinaryAccessor {
+
+    private byte[] data;
+    private int start;
+    private int len;
+    
+    @Override
+    public byte[] getBytes() {
+        return data;
+    }
+
+    @Override
+    public int getLength() {
+        return len;
+    }
+
+    @Override
+    public int getStartIndex() {
+        return start;
+    }
+
+    @Override
+    public void reset(byte[] b, int start, int len) {
+        this.data = b;
+        this.start = start;
+        this.len = len;
+    }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/base/DefaultOpenFieldType.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/base/DefaultOpenFieldType.java
index b7eef18..1544f66 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/base/DefaultOpenFieldType.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/base/DefaultOpenFieldType.java
@@ -1,10 +1,23 @@
 package edu.uci.ics.asterix.runtime.accessors.base;
 
+import edu.uci.ics.asterix.om.types.AOrderedListType;
 import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.AUnorderedListType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
 import edu.uci.ics.asterix.om.types.IAType;
 
 public class DefaultOpenFieldType {
 
     // nested open field rec type
-    public static ARecordType NESTED_OPEN_RECORD_TYPE = new ARecordType("nested-open", new String[] {}, new IAType[] {}, true);
+    public static ARecordType NESTED_OPEN_RECORD_TYPE = new ARecordType("nested-open", new String[] {},
+            new IAType[] {}, true);
+
+    // nested open list type
+    public static AOrderedListType NESTED_OPEN_AORDERED_LIST_TYPE = new AOrderedListType(BuiltinType.ANY,
+            "nested-ordered-list");
+
+    // nested open list type
+    public static AUnorderedListType NESTED_OPEN_AUNORDERED_LIST_TYPE = new AUnorderedListType(BuiltinType.ANY,
+            "nested-unordered-list");
+
 }