1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2002,2008 Oracle.  All rights reserved.
5 *
6 * $Id: PrimitiveArrayFormat.java,v 1.1 2008/02/07 17:12:27 mark Exp $
7 */
8
9package com.sleepycat.persist.impl;
10
11import java.lang.reflect.Array;
12import java.util.IdentityHashMap;
13import java.util.Map;
14import java.util.Set;
15
16import com.sleepycat.persist.raw.RawObject;
17
18/**
19 * An array of primitives having one dimension.  Multidimensional arrays are
20 * handled by {@link ObjectArrayFormat}.
21 *
22 * @author Mark Hayes
23 */
24public class PrimitiveArrayFormat extends Format {
25
26    private static final long serialVersionUID = 8285299924106073591L;
27
28    private SimpleFormat componentFormat;
29
30    PrimitiveArrayFormat(Class type) {
31        super(type);
32    }
33
34    @Override
35    public boolean isArray() {
36        return true;
37    }
38
39    @Override
40    public int getDimensions() {
41        return 1;
42    }
43
44    @Override
45    public Format getComponentType() {
46        return componentFormat;
47    }
48
49    @Override
50    void collectRelatedFormats(Catalog catalog,
51                               Map<String,Format> newFormats) {
52        /* Component type is simple and simple type formats are predefined. */
53    }
54
55    @Override
56    void initialize(Catalog catalog, int initVersion) {
57        componentFormat = (SimpleFormat)
58            catalog.getFormat(getType().getComponentType());
59    }
60
61    @Override
62    Object newArray(int len) {
63        return Array.newInstance(getType(), len);
64    }
65
66    @Override
67    public Object newInstance(EntityInput input, boolean rawAccess) {
68        int len = input.readArrayLength();
69        if (rawAccess) {
70            return new RawObject(this, new Object[len]);
71        } else {
72            return componentFormat.newPrimitiveArray(len, input);
73        }
74    }
75
76    @Override
77    public Object readObject(Object o, EntityInput input, boolean rawAccess) {
78        if (rawAccess) {
79            Object[] a = ((RawObject) o).getElements();
80            for (int i = 0; i < a.length; i += 1) {
81                a[i] = componentFormat.newInstance(input, true);
82                componentFormat.readObject(a[i], input, true);
83            }
84        }
85        /* Else, do nothing -- newInstance reads the value. */
86        return o;
87    }
88
89    @Override
90    void writeObject(Object o, EntityOutput output, boolean rawAccess) {
91        if (rawAccess) {
92            Object[] a = ((RawObject) o).getElements();
93            output.writeArrayLength(a.length);
94            for (int i = 0; i < a.length; i += 1) {
95                componentFormat.writeObject(a[i], output, true);
96            }
97        } else {
98            componentFormat.writePrimitiveArray(o, output);
99        }
100    }
101
102    @Override
103    Object convertRawObject(Catalog catalog,
104                            boolean rawAccess,
105                            RawObject rawObject,
106                            IdentityHashMap converted) {
107        RawArrayInput input = new RawArrayInput
108            (catalog, rawAccess, converted, rawObject, componentFormat);
109        Object a = newInstance(input, rawAccess);
110        converted.put(rawObject, a);
111        return readObject(a, input, rawAccess);
112    }
113
114    @Override
115    void skipContents(RecordInput input) {
116        int len = input.readPackedInt();
117        componentFormat.skipPrimitiveArray(len, input);
118    }
119
120    @Override
121    void copySecMultiKey(RecordInput input, Format keyFormat, Set results) {
122        int len = input.readPackedInt();
123        componentFormat.copySecMultiKeyPrimitiveArray(len, input, results);
124    }
125
126    @Override
127    boolean evolve(Format newFormat, Evolver evolver) {
128        evolver.useOldFormat(this, newFormat);
129        return true;
130    }
131}
132