001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package com.db4o.internal.handlers;
022:
023: import com.db4o.*;
024: import com.db4o.foundation.*;
025: import com.db4o.internal.*;
026: import com.db4o.internal.query.processor.*;
027: import com.db4o.marshall.*;
028: import com.db4o.reflect.*;
029:
030: /**
031: * n-dimensional array
032: * @exclude
033: */
034: public class MultidimensionalArrayHandler extends ArrayHandler {
035:
036: public MultidimensionalArrayHandler(ObjectContainerBase stream,
037: TypeHandler4 a_handler, boolean a_isPrimitive) {
038: super (stream, a_handler, a_isPrimitive);
039: }
040:
041: protected MultidimensionalArrayHandler(TypeHandler4 template) {
042: super (template);
043: }
044:
045: public final Object[] allElements(Object array) {
046: return allElements(arrayReflector(), array);
047: }
048:
049: public static Object[] allElements(final ReflectArray reflectArray,
050: Object array) {
051: int[] dim = reflectArray.dimensions(array);
052: Object[] flat = new Object[elementCount(dim)];
053: reflectArray.flatten(array, dim, 0, flat, 0);
054: return flat;
055: }
056:
057: public final int elementCount(Transaction a_trans, Buffer a_bytes) {
058: return elementCount(readDimensions(a_trans, a_bytes,
059: ReflectClassByRef.IGNORED));
060: }
061:
062: protected static final int elementCount(int[] a_dim) {
063: int elements = a_dim[0];
064: for (int i = 1; i < a_dim.length; i++) {
065: elements = elements * a_dim[i];
066: }
067: return elements;
068: }
069:
070: public final byte identifier() {
071: return Const4.YAPARRAYN;
072: }
073:
074: public int ownLength(Object obj) {
075: int[] dim = arrayReflector().dimensions(obj);
076: return Const4.OBJECT_LENGTH
077: + (Const4.INT_LENGTH * (2 + dim.length));
078: }
079:
080: protected int readElementsDefrag(BufferPair readers) {
081: int numDimensions = super .readElementsDefrag(readers);
082: int[] dimensions = new int[numDimensions];
083: for (int i = 0; i < numDimensions; i++) {
084: dimensions[i] = readers.readInt();
085: }
086: return elementCount(dimensions);
087: }
088:
089: public void readSubCandidates(int handlerVersion, Buffer reader,
090: QCandidates candidates) {
091: if (Deploy.debug) {
092: reader.readBegin(identifier());
093: }
094: IntArrayByRef dimensions = new IntArrayByRef();
095: Object arr = readCreate(candidates.i_trans, reader, dimensions);
096: if (arr == null) {
097: return;
098: }
099: readSubCandidates(handlerVersion, reader, candidates,
100: elementCount(dimensions.value));
101: }
102:
103: protected Object readCreate(Transaction trans, ReadBuffer buffer,
104: IntArrayByRef dimensions) {
105: ReflectClassByRef classByRef = new ReflectClassByRef();
106: dimensions.value = readDimensions(trans, buffer, classByRef);
107: ReflectClass clazz = newInstanceReflectClass(classByRef);
108: if (clazz == null) {
109: return null;
110: }
111: return arrayReflector().newInstance(clazz, dimensions.value);
112: }
113:
114: private final int[] readDimensions(Transaction trans,
115: ReadBuffer buffer, ReflectClassByRef clazz) {
116: int[] dim = new int[readElementsAndClass(trans, buffer, clazz)];
117: for (int i = 0; i < dim.length; i++) {
118: dim[i] = buffer.readInt();
119: }
120: return dim;
121: }
122:
123: private Object element(Object a_array, int a_position) {
124: try {
125: return arrayReflector().get(a_array, a_position);
126: } catch (Exception e) {
127: return null;
128: }
129: }
130:
131: public Object read(ReadContext context) {
132:
133: if (Deploy.debug) {
134: Debug.readBegin(context, Const4.YAPARRAYN);
135: }
136:
137: IntArrayByRef dimensions = new IntArrayByRef();
138: Object array = readCreate(context.transaction(), context,
139: dimensions);
140:
141: if (array != null) {
142: Object[] objects = new Object[elementCount(dimensions.value)];
143: for (int i = 0; i < objects.length; i++) {
144: objects[i] = context.readObject(_handler);
145: }
146: arrayReflector().shape(objects, 0, array, dimensions.value,
147: 0);
148: }
149:
150: if (Deploy.debug) {
151: Debug.readEnd(context);
152: }
153:
154: return array;
155: }
156:
157: public void write(WriteContext context, Object obj) {
158:
159: if (Deploy.debug) {
160: Debug.writeBegin(context, Const4.YAPARRAYN);
161: }
162:
163: int classID = classID(obj);
164: context.writeInt(classID);
165:
166: int[] dim = arrayReflector().dimensions(obj);
167: context.writeInt(dim.length);
168: for (int i = 0; i < dim.length; i++) {
169: context.writeInt(dim[i]);
170: }
171:
172: Object[] objects = allElements(obj);
173: for (int i = 0; i < objects.length; i++) {
174: context.writeObject(_handler, element(objects, i));
175: }
176:
177: if (Deploy.debug) {
178: Debug.writeEnd(context);
179: }
180: }
181:
182: }
|