private IRubyObject _iconv(RubyString str, int start, int end) {
if (fromEncoding == null) {
throw getRuntime().newArgumentError("closed iconv");
}
ByteList bytes = str.getByteList();
// treat start and end as start...end for end >= 0, start..end for end < 0
if (start < 0) {
start += bytes.length();
}
if (end < 0) {
end += 1 + bytes.length();
} else if (end > bytes.length()) {
end = bytes.length();
}
if (start < 0 || end < start) { // invalid ranges result in an empty string
return RubyString.newEmptyString(getRuntime());
}
ByteBuffer buf = ByteBuffer.wrap(bytes.unsafeBytes(), bytes.begin() + start, end - start);
try {
CharBuffer cbuf = fromEncoding.decode(buf);
buf = toEncoding.encode(cbuf);
} catch (MalformedInputException e) {
} catch (UnmappableCharacterException e) {
} catch (CharacterCodingException e) {
throw getRuntime().newInvalidEncoding("invalid sequence");
} catch (IllegalStateException e) {
}
byte[] arr = buf.array();
return getRuntime().newString(new ByteList(arr, 0, buf.limit()));
}