/** * @see * org.apache.commons.compress.archivers.zip.ZipEncoding#encode(java.lang.String) */ public java.nio.ByteBuffer encode(String name) { java.nio.charset.CharsetEncoder enc = this.charset.newEncoder(); enc.onMalformedInput(java.nio.charset.CodingErrorAction.REPORT); enc.onUnmappableCharacter(java.nio.charset.CodingErrorAction.REPORT); java.nio.CharBuffer cb = java.nio.CharBuffer.wrap(name); java.nio.ByteBuffer outJ = java.nio.ByteBuffer.allocate(name.length() + (name.length() + 1) / 2); while (cb.remaining() > 0) { java.nio.charset.CoderResult res = enc.encode(cb, outJ, true); if (res.isUnmappable() || res.isMalformed()) { // write the unmappable characters in utf-16 // pseudo-URL encoding style to ByteBuffer. if (res.length() * 6 > outJ.remaining()) { outJ = ZipEncodingHelper.growBuffer(outJ, outJ.position() + res.length() * 6); } for (int i = 0; i < res.length(); ++i) { ZipEncodingHelper.appendSurrogate(outJ, cb.get()); } } else if (res.isOverflow()) { outJ = ZipEncodingHelper.growBuffer(outJ, 0); } else if (res.isUnderflow()) { enc.flush(outJ); break; } } outJ.limit(outJ.position()); outJ.rewind(); return(outJ); }
/* * Encodes characters starting at the current position of the given input * buffer, and writes the equivalent byte sequence into the given output * buffer from its current position. * <p /> * The buffers' position will be changed with the reading and writing * operation, but their limits and marks will be kept intact. * <p /> * A <code>CoderResult</code> instance will be returned according to * following rules: * <ul> * <li>A {@link CoderResult#malformedForLength(int) malformed input} result * indicates that some malformed input error was encountered, and the * erroneous characters start at the input buffer's position and their * number can be got by result's {@link CoderResult#length() length}. This * kind of result can be returned only if the malformed action is * {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}.</li> * <li>{@link CoderResult#UNDERFLOW CoderResult.UNDERFLOW} indicates that * as many characters as possible in the input buffer have been encoded. If * there is no further input and no characters left in the input buffer then * this task is complete. If this is not the case then the client should * call this method again supplying some more input characters.</li> * <li>{@link CoderResult#OVERFLOW CoderResult.OVERFLOW} indicates that the * output buffer has been filled, while there are still some characters * remaining in the input buffer. This method should be invoked again with a * non-full output buffer.</li> * <li>A {@link CoderResult#unmappableForLength(int) unmappable character} * result indicates that some unmappable character error was encountered, * and the erroneous characters start at the input buffer's position and * their number can be got by result's {@link CoderResult#length() length}. * This kind of result can be returned only on * {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}.</li> * </ul> * <p /> * The <code>endOfInput</code> parameter indicates if the invoker can * provider further input. This parameter is true if and only if the * characters in the current input buffer are all inputs for this encoding * operation. Note that it is common and won't cause an error if the invoker * sets false and then has no more input available, while it may cause an * error if the invoker always sets true in several consecutive invocations. * This would make the remaining input to be treated as malformed input. * input. * <p /> * This method invokes the * {@link #encodeLoop(CharBuffer, ByteBuffer) encodeLoop} method to * implement the basic encode logic for a specific charset. * * @param in * the input buffer. * @param out * the output buffer. * @param endOfInput * true if all the input characters have been provided. * @return a <code>CoderResult</code> instance indicating the result. * @throws IllegalStateException * if the encoding operation has already started or no more * input is needed in this encoding process. * @throws CoderMalfunctionError * If the {@link #encodeLoop(CharBuffer, ByteBuffer) encodeLoop} * method threw an <code>BufferUnderflowException</code> or * <code>BufferUnderflowException</code>. */ public CoderResult encode(java.nio.CharBuffer inJ, java.nio.ByteBuffer outJ, bool endOfInput) { //If the previous step is encode(CharBuffer), then no more input is needed // thus endOfInput should not be false if (status == READY && finished && !endOfInput) { throw new java.lang.IllegalStateException(); } if ((status == FLUSH) || (!endOfInput && status == END)) { throw new java.lang.IllegalStateException(); } CoderResult result; while (true) { try { result = encodeLoop(inJ, outJ); } catch (BufferOverflowException e) { throw new CoderMalfunctionError(e); } catch (BufferUnderflowException e) { throw new CoderMalfunctionError(e); } if (result == CoderResult.UNDERFLOW) { status = endOfInput ? END : ONGOING; if (endOfInput) { int remaining = inJ.remaining(); if (remaining > 0) { result = CoderResult.malformedForLength(remaining); } else { return(result); } } else { return(result); } } else if (result == CoderResult.OVERFLOW) { status = endOfInput ? END : ONGOING; return(result); } CodingErrorAction action = malformAction; if (result.isUnmappable()) { action = unmapAction; } // If the action is IGNORE or REPLACE, we should continue // encoding. if (action == CodingErrorAction.REPLACE) { if (outJ.remaining() < replace.Length) { return(CoderResult.OVERFLOW); } outJ.put(replace); } else { if (action != CodingErrorAction.IGNORE) { return(result); } } inJ.position(inJ.position() + result.length()); } }