public String toString() {
        if (_size == 0) {
            return UNDEFINED;
        }

        if (_longMode && (_bytes[0] & 0xFF) == Buffer.LONGREC_TYPE && (_size >= Buffer.LONGREC_SIZE)) {
            return toStringLongMode();
        }

        int saveDepth = _depth;
        int saveLevel = _level;
        int saveNext = _next;
        int saveEnd = _end;
        StringBuilder sb = new StringBuilder();
        setStreamMode(true);
        try {
            boolean first = true;
            while (_next < _size) {
                if (!first) {
                    sb.append(",");
                }
                first = false;
                decodeDisplayable(true, sb, null);
            }
        } catch (ConversionException e) {
            int truncatedSize = Math.min(_size - _next, 256);
            sb.append("ConversionException " + e.getCause() + " index=" + _next + " size=" + (_size - _next) + ": "
                    + Util.hexDump(_bytes, 0, truncatedSize));
        } catch (Exception e) {
            sb.append("Exception " + e + " while decoding value at index=" + _next + ": " + e);
        } finally {
            _end = saveEnd;
            _next = saveNext;
            _level = saveLevel;
            _depth = saveDepth;
        }
        return sb.toString();
    }