git-svn-id: https://stereo.googlecode.com/svn/trunk@441 c67ee986-0855-0410-825f-15918...
[stereo.git] / DACPServer / src / dacp / DACPWriter.java
blobe3491b4d2c8df41bcf5c4c99d392b33d0f0be856
1 package dacp;
3 import interfaces.Constants;
5 import java.io.ByteArrayOutputStream;
6 import java.io.IOException;
7 import java.io.OutputStream;
8 import java.io.UnsupportedEncodingException;
9 import java.util.List;
11 import api.Node;
12 import api.Writer;
14 public class DACPWriter implements Writer {
16 private final OutputStream stream;
17 private int bytes = 0;
18 private int nodes = 0;
20 public DACPWriter(OutputStream stream) {
21 this.stream = stream;
24 public void appendBoolean(Constants code, boolean value) {
25 check(code, new int[] {Constants.BYTE, Constants.SIGNED_BYTE});
26 write(code.code, 1, value?1:0);
29 public void appendByte(Constants code, byte value) {
30 check(code, new int[] {Constants.BYTE, Constants.SIGNED_BYTE});
31 write(code.code, 1, value);
34 public void appendShort(Constants code, short value) {
35 check(code, new int[] {Constants.SHORT, Constants.SIGNED_SHORT});
36 write(code.code, 2, value);
39 public void appendBytes(Constants code, byte[] value) {
40 check(code, new int[] {});
41 write(code.code, value.length, value);
44 public void appendInteger(Constants code, int value) {
45 check(code, new int[] {Constants.INTEGER, Constants.SIGNED_INTEGER});
46 write(code.code, 4, value);
49 public void appendLong(Constants code, long value) {
50 check(code, new int[] {Constants.LONG, Constants.SIGNED_LONG});
51 write(code.code, 8, value);
54 public void appendLongLong(Constants code, int[] value) {
55 check(code, new int[] {Constants.LONG_LONG});
56 write(code.code, 16, value);
59 public void appendNode(Node node) {
60 check(node.type(), new int[] { Constants.COMPOSITE });
61 ByteArrayOutputStream stream = new ByteArrayOutputStream();
62 Writer w = new DACPWriter(stream);
63 node.write(w);
65 try {
66 writeNum(node.type().code, 4);
67 writeNum(stream.size(), 4);
68 stream.writeTo(this.stream);
70 catch (IOException ex) {
71 System.err.println("error writing to output stream");
72 ex.printStackTrace();
76 public void appendString(Constants code, String value) {
77 check(code, new int[] { Constants.STRING, Constants.COMPOSITE });
78 byte[] bytes;
79 if (value != null) {
80 try {
81 bytes = value.getBytes("UTF-8");
83 catch (UnsupportedEncodingException ex) {
84 bytes = value.getBytes();
85 System.err.println("UTF-8 not supported: DACPWriter.java");
88 else {
89 bytes = new byte[0];
91 write(code.code, bytes.length, bytes);
94 public void appendVersion(Constants code, byte[] value) {
95 check(code, new int[] { Constants.VERSION });
96 write(code.code, value.length, value);
99 public void appendDate(Constants code, int value) {
100 check(code, new int[] { Constants.DATE });
101 write(code.code, 4, value);
104 public void appendList(final Constants code, final byte type, final List<? extends Node> list) {
105 check(code, new int[] { Constants.COMPOSITE });
107 appendByte(Constants.dmap_updatetype, type);
108 appendInteger(Constants.dmap_specifiedtotalcount, list.size());
109 appendInteger(Constants.dmap_returnedcount, list.size());
111 appendNode(new Node() {
112 public Constants type() {
113 return code;
115 public void write(Writer writer) {
116 for (Node n: list) {
117 writer.appendNode(n);
123 private void check(Constants code, int[] types) {
124 for (int t: types) {
125 if (code.type == t) return;
127 throw new RuntimeException(code.longName + " appended as incorrect type, expected " + code.type);
130 private void write(int code, int length, int value) {
131 try {
132 writeNum(code, 4);
133 writeNum(length, 4);
134 writeNum(value, length);
136 nodes++;
138 catch (IOException ex) {
139 System.err.println("error writing to output stream");
140 ex.printStackTrace();
144 private void write(int code, int length, byte[] value) {
145 try {
146 writeNum(code, 4);
147 writeNum(length, 4);
148 stream.write(value);
149 bytes += length;
151 nodes++;
153 catch (IOException ex) {
154 System.err.println("error writing to output stream");
155 ex.printStackTrace();
159 private void write(int code, int length, long value) {
160 try {
161 writeNum(code, 4);
162 writeNum(length, 4);
163 writeNum((int)(value>>32), 4);
164 writeNum((int)(value&0xFFFFFFFF), 4);
166 nodes++;
168 catch (IOException ex) {
169 System.err.println("error writing to output stream");
170 ex.printStackTrace();
174 private void write(int code, int length, int[] value) {
175 try {
176 writeNum(code, 4);
177 writeNum(length, 4);
178 for (int i: value) {
179 writeNum(i, 4);
182 nodes++;
184 catch (IOException ex) {
185 System.err.println("error writing to output stream");
186 ex.printStackTrace();
190 private void writeNum(int var, int num) throws IOException {
191 switch (num) {
192 case 4:
193 stream.write(var>>24);
194 stream.write((var>>16)%256);
195 case 2:
196 stream.write((var>>8)%256);
197 case 1:
198 stream.write(var%256);
199 break;
200 default:
201 throw new IOException("Unsupported number length: " + num);
204 bytes += num;