Changeset 12321


Ignore:
Timestamp:
01/01/10 18:26:24 (11 years ago)
Author:
ehuelsmann
Message:

Fix ticket #75: infinite loop while writing unmappable

characters to an output stream - while at it,
fix the input side too.

Location:
trunk/abcl/src/org/armedbear/lisp/util
Files:
2 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/abcl/src/org/armedbear/lisp/util/RandomAccessCharacterFile.java

    r12318 r12321  
    281281        fcn = raf.getChannel();
    282282
    283         cset = (encoding == null) ? Charset.defaultCharset() : Charset.forName(encoding);
     283        setEncoding(encoding);
     284        bbuf = ByteBuffer.allocate(BUFSIZ);
     285
     286        // there is no readable data available in the buffers.
     287        bbuf.flip();
     288
     289        // there is no write pending data in the buffers.
     290        bbufIsDirty = false;
     291
     292        bbufIsReadable = false;
     293
     294        bbufpos = fcn.position();
     295
     296        reader = new RandomAccessReader();
     297        writer = new RandomAccessWriter();
     298        inputStream = new RandomAccessInputStream();
     299        outputStream = new RandomAccessOutputStream();
     300    }
     301
     302    public void setEncoding(String encoding) {
     303        cset = (encoding == null)
     304            ? Charset.defaultCharset() : Charset.forName(encoding);
    284305        cdec = cset.newDecoder();
    285306        cdec.onMalformedInput(CodingErrorAction.REPLACE);
    286307        cdec.onUnmappableCharacter(CodingErrorAction.REPLACE);
    287308        cenc = cset.newEncoder();
    288 
    289         bbuf = ByteBuffer.allocate(BUFSIZ);
    290 
    291         // there is no readable data available in the buffers.
    292         bbuf.flip();
    293 
    294         // there is no write pending data in the buffers.
    295         bbufIsDirty = false;
    296 
    297         bbufIsReadable = false;
    298 
    299         bbufpos = fcn.position();
    300 
    301         reader = new RandomAccessReader();
    302         writer = new RandomAccessWriter();
    303         inputStream = new RandomAccessInputStream();
    304         outputStream = new RandomAccessOutputStream();
    305309    }
    306310
     
    366370            CoderResult r = cdec.decode(bbuf, cbuf, atEof );
    367371            decodeWasUnderflow = (CoderResult.UNDERFLOW == r);
     372            if (r.isMalformed())
     373                // When reading encoded Unicode, we'd expect to require
     374                // catching MalformedInput
     375                throw new RACFMalformedInputException(bbuf.position(),
     376                                                      bbuf.get(bbuf.position()),
     377                                                      cset.name());
     378            if (r.isUnmappable())
     379                // Since we're mapping TO unicode, we'd expect to be able
     380                // to map all characters
     381                Debug.assertTrue(false);
     382            if (CoderResult.OVERFLOW == r)
     383                Debug.assertTrue(false);
    368384        }
    369385        if (cbuf.remaining() == len) {
     
    388404    }
    389405
    390     private final void encodeAndWrite(CharBuffer cbuf, boolean flush, boolean endOfFile) throws IOException {
     406    private final void encodeAndWrite(CharBuffer cbuf, boolean flush,
     407                                      boolean endOfFile) throws IOException {
    391408        while (cbuf.remaining() > 0) {
    392409            CoderResult r = cenc.encode(cbuf, bbuf, endOfFile);
     
    396413                bbuf.clear();
    397414            }
     415            if (r.isUnmappable()) {
     416                throw new RACFUnmappableCharacterException(cbuf.position(),
     417                                                           cbuf.charAt(cbuf.position()),
     418                                                           cset.name());
     419            }
     420            if (r.isMalformed()) {
     421                // We don't really expect Malformed, but not handling it
     422                // will cause an infinite loop if we don't...
     423                throw new RACFMalformedInputException(cbuf.position(),
     424                                                      cbuf.charAt(cbuf.position()),
     425                                                      cset.name());
     426            }
     427            if (CoderResult.UNDERFLOW == r)
     428                Debug.assertTrue(false);
    398429        }
    399430        if (bbuf.position() > 0 && bbufIsDirty && flush) {
Note: See TracChangeset for help on using the changeset viewer.