• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src/router/db-4.8.30/java/src/com/sleepycat/bind/serial/
1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2000-2009 Oracle.  All rights reserved.
5 *
6 * $Id$
7 */
8
9package com.sleepycat.bind.serial;
10
11import java.io.ByteArrayOutputStream;
12import java.io.IOException;
13import java.io.ObjectOutputStream;
14import java.io.ObjectStreamClass;
15import java.io.ObjectStreamConstants;
16import java.io.OutputStream;
17
18import com.sleepycat.db.DatabaseException;
19import com.sleepycat.util.RuntimeExceptionWrapper;
20
21/**
22 * A specialized <code>ObjectOutputStream</code> that stores class description
23 * information in a <code>ClassCatalog</code>.  It is used by
24 * <code>SerialBinding</code>.
25 *
26 * <p>This class is used instead of an {@link ObjectOutputStream}, which it
27 * extends, to write a compact object stream.  For writing objects to a
28 * database normally one of the serial binding classes is used.  {@link
29 * SerialOutput} is used when an {@link ObjectOutputStream} is needed along
30 * with compact storage.  A {@link ClassCatalog} must be supplied, however, to
31 * stored shared class descriptions.</p>
32 *
33 * <p>The {@link ClassCatalog} is used to store class definitions rather than
34 * embedding these into the stream.  Instead, a class format identifier is
35 * embedded into the stream.  This identifier is then used by {@link
36 * SerialInput} to load the class format to deserialize the object.</p>
37 *
38 * @see <a href="SerialBinding.html#evolution">Class Evolution</a>
39 *
40 * @author Mark Hayes
41 */
42public class SerialOutput extends ObjectOutputStream {
43
44    /*
45     * Serialization version constants. Instead of hardcoding these we get them
46     * by creating a SerialOutput, which itself guarantees that we'll always
47     * use a PROTOCOL_VERSION_2 header.
48     */
49    private final static byte[] STREAM_HEADER;
50    static {
51        ByteArrayOutputStream baos = new ByteArrayOutputStream();
52        try {
53            new SerialOutput(baos, null);
54        } catch (IOException e) {
55            throw new RuntimeExceptionWrapper(e);
56        }
57        STREAM_HEADER = baos.toByteArray();
58    }
59
60    private ClassCatalog classCatalog;
61
62    /**
63     * Creates a serial output stream.
64     *
65     * @param out is the output stream to which the compact serialized objects
66     * will be written.
67     *
68     * @param classCatalog is the catalog to which the class descriptions for
69     * the serialized objects will be written.
70     */
71    public SerialOutput(OutputStream out, ClassCatalog classCatalog)
72        throws IOException {
73
74        super(out);
75        this.classCatalog = classCatalog;
76
77        /* guarantee that we'll always use the same serialization format */
78
79        useProtocolVersion(ObjectStreamConstants.PROTOCOL_VERSION_2);
80    }
81
82    // javadoc is inherited
83    protected void writeClassDescriptor(ObjectStreamClass classdesc)
84        throws IOException {
85
86        try {
87            byte[] id = classCatalog.getClassID(classdesc);
88            writeByte(id.length);
89            write(id);
90        } catch (DatabaseException e) {
91            /*
92             * Do not throw IOException from here since ObjectOutputStream
93             * will write the exception to the stream, which causes another
94             * call here, etc.
95             */
96            throw new RuntimeExceptionWrapper(e);
97        } catch (ClassNotFoundException e) {
98            throw new RuntimeExceptionWrapper(e);
99        }
100    }
101
102    /**
103     * Returns the fixed stream header used for all serialized streams in
104     * PROTOCOL_VERSION_2 format.  To save space this header can be removed and
105     * serialized streams before storage and inserted before deserializing.
106     * {@link SerialOutput} always uses PROTOCOL_VERSION_2 serialization format
107     * to guarantee that this header is fixed.  {@link SerialBinding} removes
108     * this header from serialized streams automatically.
109     *
110     * @return the fixed stream header.
111     */
112    public static byte[] getStreamHeader() {
113
114        return STREAM_HEADER;
115    }
116}
117