1b219ad3183b00fbc520e36b962c3eb1d3e9384feNathanSweet/*******************************************************************************
2b219ad3183b00fbc520e36b962c3eb1d3e9384feNathanSweet * Copyright 2011 See AUTHORS file.
3b219ad3183b00fbc520e36b962c3eb1d3e9384feNathanSweet *
4b219ad3183b00fbc520e36b962c3eb1d3e9384feNathanSweet * Licensed under the Apache License, Version 2.0 (the "License");
5b219ad3183b00fbc520e36b962c3eb1d3e9384feNathanSweet * you may not use this file except in compliance with the License.
6b219ad3183b00fbc520e36b962c3eb1d3e9384feNathanSweet * You may obtain a copy of the License at
7b219ad3183b00fbc520e36b962c3eb1d3e9384feNathanSweet *
8b219ad3183b00fbc520e36b962c3eb1d3e9384feNathanSweet *   http://www.apache.org/licenses/LICENSE-2.0
9b219ad3183b00fbc520e36b962c3eb1d3e9384feNathanSweet *
10b219ad3183b00fbc520e36b962c3eb1d3e9384feNathanSweet * Unless required by applicable law or agreed to in writing, software
11b219ad3183b00fbc520e36b962c3eb1d3e9384feNathanSweet * distributed under the License is distributed on an "AS IS" BASIS,
12b219ad3183b00fbc520e36b962c3eb1d3e9384feNathanSweet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b219ad3183b00fbc520e36b962c3eb1d3e9384feNathanSweet * See the License for the specific language governing permissions and
14b219ad3183b00fbc520e36b962c3eb1d3e9384feNathanSweet * limitations under the License.
15b97b34a82af276a09bec2885854dc391ec65023dNathanSweet ******************************************************************************/
16b97b34a82af276a09bec2885854dc391ec65023dNathanSweet
1724041b573d0cb157432276f19c2be1f83b954eb7nathan.sweetpackage com.badlogic.gdx.utils;
1824041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet
19f19a2bf2e1397ffe5aeae538d7edcc07c4f7f32bNathanSweetimport java.io.ByteArrayOutputStream;
2024041b573d0cb157432276f19c2be1f83b954eb7nathan.sweetimport java.io.DataOutputStream;
2124041b573d0cb157432276f19c2be1f83b954eb7nathan.sweetimport java.io.IOException;
2224041b573d0cb157432276f19c2be1f83b954eb7nathan.sweetimport java.io.OutputStream;
2324041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet
2424041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet/** Extends {@link DataOutputStream} with additional convenience methods.
2524041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet * @author Nathan Sweet */
2624041b573d0cb157432276f19c2be1f83b954eb7nathan.sweetpublic class DataOutput extends DataOutputStream {
2724041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet	public DataOutput (OutputStream out) {
2824041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		super(out);
2924041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet	}
3024041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet
3124041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet	/** Writes a 1-5 byte int.
3224041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet	 * @param optimizePositive If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be
3324041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet	 *           inefficient (5 bytes). */
3424041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet	public int writeInt (int value, boolean optimizePositive) throws IOException {
3524041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		if (!optimizePositive) value = (value << 1) ^ (value >> 31);
3624041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		if (value >>> 7 == 0) {
3724041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			write((byte)value);
3824041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			return 1;
3924041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		}
4024041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		write((byte)((value & 0x7F) | 0x80));
4124041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		if (value >>> 14 == 0) {
4224041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			write((byte)(value >>> 7));
4324041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			return 2;
4424041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		}
4524041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		write((byte)(value >>> 7 | 0x80));
4624041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		if (value >>> 21 == 0) {
4724041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			write((byte)(value >>> 14));
4824041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			return 3;
4924041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		}
5024041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		write((byte)(value >>> 14 | 0x80));
5124041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		if (value >>> 28 == 0) {
5224041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			write((byte)(value >>> 21));
5324041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			return 4;
5424041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		}
5524041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		write((byte)(value >>> 21 | 0x80));
5624041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		write((byte)(value >>> 28));
5724041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		return 5;
5824041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet	}
5924041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet
6024041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet	/** Writes a length and then the string as UTF8.
6124041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet	 * @param value May be null. */
6224041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet	public void writeString (String value) throws IOException {
6324041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		if (value == null) {
6424041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			write(0);
6524041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			return;
6624041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		}
6724041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		int charCount = value.length();
6824041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		if (charCount == 0) {
6924041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			writeByte(1);
7024041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			return;
7124041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		}
7224041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		writeInt(charCount + 1, true);
7324041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		// Try to write 8 bit chars.
7424041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		int charIndex = 0;
7524041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		for (; charIndex < charCount; charIndex++) {
7624041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			int c = value.charAt(charIndex);
7724041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			if (c > 127) break;
7824041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			write((byte)c);
7924041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		}
8024041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		if (charIndex < charCount) writeString_slow(value, charCount, charIndex);
8124041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet	}
8224041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet
8324041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet	private void writeString_slow (String value, int charCount, int charIndex) throws IOException {
8424041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		for (; charIndex < charCount; charIndex++) {
8524041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			int c = value.charAt(charIndex);
8624041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			if (c <= 0x007F) {
8724041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet				write((byte)c);
8824041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			} else if (c > 0x07FF) {
8924041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet				write((byte)(0xE0 | c >> 12 & 0x0F));
9024041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet				write((byte)(0x80 | c >> 6 & 0x3F));
9124041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet				write((byte)(0x80 | c & 0x3F));
9224041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			} else {
9324041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet				write((byte)(0xC0 | c >> 6 & 0x1F));
9424041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet				write((byte)(0x80 | c & 0x3F));
9524041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet			}
9624041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet		}
9724041b573d0cb157432276f19c2be1f83b954eb7nathan.sweet	}
98b97b34a82af276a09bec2885854dc391ec65023dNathanSweet}
99