poi/src/java/org/apache/poi/util/LittleEndianBig5Stream.java

108 lines
3.2 KiB
Java

/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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 org.apache.poi.util;
import java.io.ByteArrayInputStream;
/**
* Stream that converts MSOffice's way of storing Big5, with
* zero-byte padding for ASCII and in LittleEndianOrder.
*/
@Internal
public class LittleEndianBig5Stream extends ByteArrayInputStream {
private static final int EOF = -1;
private static final int INVALID_PAIR = -2;
private static final int EMPTY_TRAILING = -3;
//the char that is logically trailing in Big5 encoding
//however in LittleEndian order, this is the first encountered.
int trailing = EMPTY_TRAILING;
public LittleEndianBig5Stream(byte[] buf) {
super(buf);
}
public LittleEndianBig5Stream(byte[] buf, int offset, int length) {
super(buf, offset, length);
}
@Override
public int read() {
if (trailing != EMPTY_TRAILING) {
int tmp = trailing;
trailing = EMPTY_TRAILING;
return tmp;
}
int leading = readNext();
while (leading == INVALID_PAIR) {
leading = readNext();
}
if (leading == EOF) {
return EOF;
}
return leading;
}
//returns leading, sets trailing appropriately
//returns -1 if it hits the end of the stream
//returns -2 for an invalid big5 code pair
private final int readNext() {
trailing = super.read();
if (trailing == -1) {
return EOF;
}
int leading = super.read();
if (leading == EOF) {
return EOF;
}
int lead = leading&0xff;
if (lead > 0x80) {
return leading;
} else if (lead == 0) {
int ret = trailing;
trailing = EMPTY_TRAILING;
return ret;
} else {
int ret = trailing;
trailing = EMPTY_TRAILING;
return ret;
//return INVALID_PAIR;
}
}
@Override
public int read(byte[] buff, int off, int len) {
int bytesRead = 0;
for (int i = off; i < off+len; i++) {
int b = read();
if (b == -1) {
if (bytesRead == 0) {
return -1;
} else {
return bytesRead;
}
}
bytesRead++;
buff[i] = (byte)b;
}
return bytesRead;
}
}