1/*
2 *  SerializedRope.java
3 *  Copyright (C) 2007 Amin Ahmad.
4 *
5 *  This file is part of Java Ropes.
6 *
7 *  Java Ropes is free software: you can redistribute it and/or modify
8 *  it under the terms of the GNU General Public License as published by
9 *  the Free Software Foundation, either version 3 of the License, or
10 *  (at your option) any later version.
11 *
12 *  Java Ropes is distributed in the hope that it will be useful,
13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *  GNU General Public License for more details.
16 *
17 *  You should have received a copy of the GNU General Public License
18 *  along with Java Ropes.  If not, see <http://www.gnu.org/licenses/>.
19 *
20 *  Amin Ahmad can be contacted at amin.ahmad@gmail.com or on the web at
21 *  www.ahmadsoft.org.
22 */
23package org.ahmadsoft.ropes.impl;
24
25import java.io.Externalizable;
26import java.io.IOException;
27import java.io.ObjectInput;
28import java.io.ObjectOutput;
29import java.io.ObjectStreamException;
30
31import org.ahmadsoft.ropes.Rope;
32
33/**
34 * An instance of this class replaces ropes during the serialization
35 * process. This class serializes into string form, and deserializes
36 * into a <code>FlatRope</code>. <code>readResolve</code> returns the
37 * flat rope.
38 * <p>
39 * The purpose of this class is to provide a performant serialization
40 * mechanism for Ropes. The ideal serial form of a rope is as a String,
41 * regardless of the particular in-memory representation.
42 * @author Amin Ahmad
43 */
44final class SerializedRope implements Externalizable {
45
46	/**
47	 * The rope.
48	 */
49	private Rope rope;
50
51	/**
52	 * Public no-arg constructor for use during serialization.
53	 */
54	public SerializedRope() {}
55
56	/**
57	 * Create a new concatenation rope from two ropes.
58	 * @param left the first rope.
59	 * @param right the second rope.
60	 */
61	public SerializedRope(final Rope rope) {
62		this.rope = rope;
63	}
64
65	@Override
66	public void readExternal(final ObjectInput in) throws IOException,
67			ClassNotFoundException {
68		// Read the UTF string and build a rope from it. This should
69		// result in a FlatRope.
70		this.rope = Rope.BUILDER.build(in.readUTF());
71	}
72
73	private Object readResolve() throws ObjectStreamException {
74		// Substitute an instance of this class with the deserialized
75		// rope.
76		return this.rope;
77	}
78
79	@Override
80	public void writeExternal(final ObjectOutput out) throws IOException {
81		// Evaluate the rope (toString()) and write as UTF. Unfortunately,
82		// this requires O(n) temporarily-allocated heap space.
83		out.writeUTF(this.rope.toString());
84	}
85}
86