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