001: /*
002: * $Id: ASCIIXMLDecoder.java,v 1.5 2004/07/11 09:37:37 yuvalo Exp $
003: *
004: * (C) Copyright 2002-2004 by Yuval Oren. All rights reserved.
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: package com.bluecast.xml;
020:
021: import com.bluecast.io.CharsetDecoder;
022: import com.bluecast.io.IllegalCharException;
023:
024: import java.io.CharConversionException;
025:
026: /**
027: * A decoder for ASCII XML. Also converts carriage returns into linefeeds
028: * and CRLF to LF. Checks for invalid XML characters.
029: *
030: * @author Yuval Oren, yuval@bluecast.com
031: * @version $Revision: 1.5 $
032: */
033: final public class ASCIIXMLDecoder implements XMLDecoder {
034: private boolean sawCR = false;
035:
036: public CharsetDecoder newCharsetDecoder() {
037: return newXMLDecoder();
038: }
039:
040: public XMLDecoder newXMLDecoder() {
041: return new ASCIIXMLDecoder();
042: }
043:
044: public int minBytesPerChar() {
045: return 1;
046: }
047:
048: public int maxBytesPerChar() {
049: return 1;
050: }
051:
052: public void reset() {
053: sawCR = false;
054: }
055:
056: public void decode(byte[] in_buf, int in_off, int in_len,
057: char[] out_buf, int out_off, int out_len, int[] result)
058: throws CharConversionException {
059: internalDecode(in_buf, in_off, in_len, out_buf, out_off,
060: out_len, result, false);
061: }
062:
063: public void decodeXMLDecl(byte[] in_buf, int in_off, int in_len,
064: char[] out_buf, int out_off, int out_len, int[] result)
065: throws CharConversionException {
066: internalDecode(in_buf, in_off, in_len, out_buf, out_off,
067: out_len, result, true);
068: }
069:
070: private void internalDecode(byte[] in_buf, int in_off, int in_len,
071: char[] out_buf, int out_off, int out_len, int[] result,
072: boolean decodeDecl) throws CharConversionException {
073: int i, o;
074: inputLoop: for (i = o = 0; i < in_len && o < out_len; i++) {
075: char c = (char) (0x7F & in_buf[in_off + i]);
076: if (c >= 0x20) {
077: sawCR = false;
078: out_buf[out_off + o++] = (char) c;
079: } else {
080: switch (c) {
081: case '\n':
082: if (sawCR) {
083: sawCR = false;
084: } else
085: out_buf[out_off + o++] = '\n';
086: break;
087:
088: case '\r':
089: sawCR = true;
090: out_buf[out_off + o++] = '\n';
091: break;
092:
093: case '\t':
094: out_buf[out_off + o++] = '\t';
095: break;
096:
097: default:
098: if (decodeDecl)
099: break inputLoop;
100: else
101: throw new IllegalCharException(
102: "Illegal XML character: 0x"
103: + Integer.toHexString(c));
104: }
105: }
106: }
107: result[0] = i;
108: result[1] = o;
109: }
110: }
|