aboutsummaryrefslogtreecommitdiff
path: root/java/com/xagasoft/gats/GatsOutputStream.java
blob: d4d0632b7f0e2274a9fc9a09f818b70db4fb2ed9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
 * Copyright (C) 2007-2013 Xagasoft, All rights reserved.
 *
 * This file is part of the libgats library and is released under the
 * terms of the license contained in the file LICENSE.
 */

package com.xagasoft.gats;

import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;

/**
 * Facilitates writing GatsObjects to an OutputStream.  This doesn't really
 * inherit from OutputStream, so maybe it would make more sense to call it
 * something else, but this is how it is right now.  Use the writeObject
 * function to write any given GatsObject to the OutputStream.
 * <p>
 * Each time you write an object with this class it actually writes a Gats
 * Packet data structure which consists of a 5 byte header followed by the
 * encoded GatsObject data.  In the packet header is information about which
 * version of Gats is in use, which options are enabled, etc.  This ensures
 * that Gats is backward compatible.
 * <p>
 * According to the GATS standard only fully formed Gats packets may be written
 * to files or sockets to ensure integrity and context.  Since each packet can
 * only contain one GatsObject that means that each writeObject call should
 * write one fully formed message or data structure to ensure maximum
 * efficiency.
 * <p>
 * The OutputStream is written to frequently, and often in small increments, so
 * it is highly advisable to pass in a BufferedOutputStream or similar structure
 * to ensure maximum performance.
 * <p>
 * The Gats format stipulates that all zero bytes found in between packets are
 * simply ignored, which allows you to pad streams of sequential Gats objects
 * if necessary.  This can be handy in some encoding/compression/encryption
 * schemes.
 *@see com.xagasoft.gats.GatsInputStream
 */
public class GatsOutputStream
{
	private OutputStream os;

	public GatsOutputStream( OutputStream os )
	{
		this.os = os;
	}

	/**
	 * Write an object to the provided output stream.
	 *@return The total number of bytes written.
	 */
	public int writeObject( GatsObject obj ) throws java.io.IOException
	{
		ByteArrayOutputStream bos1 = new ByteArrayOutputStream();

		obj.write( bos1 );

		ByteArrayOutputStream bos2 = new ByteArrayOutputStream(
			5 + bos1.size()
			);

		DataOutputStream dos = new DataOutputStream( bos2 );
		dos.writeByte( 1 );
		dos.writeInt( bos1.size()+5 );
		bos2.write( bos1.toByteArray() );

		os.write( bos2.toByteArray() );
		return bos1.size()+5;
	}
};