/******************************************************************************* | |
* Copyright 2011 See AUTHORS file. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
******************************************************************************/ | |
package com.badlogic.gdx.utils; | |
import java.io.DataInputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
/** Extends {@link DataInputStream} with additional convenience methods. | |
* @author Nathan Sweet */ | |
public class DataInput extends DataInputStream { | |
private char[] chars = new char[32]; | |
public DataInput (InputStream in) { | |
super(in); | |
} | |
/** Reads a 1-5 byte int. */ | |
public int readInt (boolean optimizePositive) throws IOException { | |
int b = read(); | |
int result = b & 0x7F; | |
if ((b & 0x80) != 0) { | |
b = read(); | |
result |= (b & 0x7F) << 7; | |
if ((b & 0x80) != 0) { | |
b = read(); | |
result |= (b & 0x7F) << 14; | |
if ((b & 0x80) != 0) { | |
b = read(); | |
result |= (b & 0x7F) << 21; | |
if ((b & 0x80) != 0) { | |
b = read(); | |
result |= (b & 0x7F) << 28; | |
} | |
} | |
} | |
} | |
return optimizePositive ? result : ((result >>> 1) ^ -(result & 1)); | |
} | |
/** Reads the length and string of UTF8 characters, or null. | |
* @return May be null. */ | |
public String readString () throws IOException { | |
int charCount = readInt(true); | |
switch (charCount) { | |
case 0: | |
return null; | |
case 1: | |
return ""; | |
} | |
charCount--; | |
if (chars.length < charCount) chars = new char[charCount]; | |
char[] chars = this.chars; | |
// Try to read 7 bit ASCII chars. | |
int charIndex = 0; | |
int b = 0; | |
while (charIndex < charCount) { | |
b = read(); | |
if (b > 127) break; | |
chars[charIndex++] = (char)b; | |
} | |
// If a char was not ASCII, finish with slow path. | |
if (charIndex < charCount) readUtf8_slow(charCount, charIndex, b); | |
return new String(chars, 0, charCount); | |
} | |
private void readUtf8_slow (int charCount, int charIndex, int b) throws IOException { | |
char[] chars = this.chars; | |
while (true) { | |
switch (b >> 4) { | |
case 0: | |
case 1: | |
case 2: | |
case 3: | |
case 4: | |
case 5: | |
case 6: | |
case 7: | |
chars[charIndex] = (char)b; | |
break; | |
case 12: | |
case 13: | |
chars[charIndex] = (char)((b & 0x1F) << 6 | read() & 0x3F); | |
break; | |
case 14: | |
chars[charIndex] = (char)((b & 0x0F) << 12 | (read() & 0x3F) << 6 | read() & 0x3F); | |
break; | |
} | |
if (++charIndex >= charCount) break; | |
b = read() & 0xFF; | |
} | |
} | |
} |