// strio_getline private IRubyObject getline(ThreadContext context, IRubyObject[] args) { Ruby runtime = context.runtime; IRubyObject str = context.nil; ; int n, limit = -1; switch (args.length) { case 0: str = runtime.getGlobalVariables().get("$/"); break; case 1: { str = args[0]; if (!str.isNil() && !(str instanceof RubyString)) { IRubyObject tmp = str.checkStringType19(); if (tmp.isNil()) { limit = RubyNumeric.num2int(str); if (limit == 0) return runtime.newString(); str = runtime.getGlobalVariables().get("$/"); } else { str = tmp; } } break; } case 2: if (!args[0].isNil()) str = args[0].convertToString(); // 2.0 ignores double nil, 1.9 raises if (runtime.is2_0()) { if (!args[1].isNil()) { limit = RubyNumeric.num2int(args[1]); } } else { limit = RubyNumeric.num2int(args[1]); } break; } if (isEndOfString()) { return context.nil; } ByteList dataByteList = ptr.string.getByteList(); byte[] dataBytes = dataByteList.getUnsafeBytes(); int begin = dataByteList.getBegin(); int s = begin + ptr.pos; int e = begin + dataByteList.getRealSize(); int p; if (limit > 0 && s + limit < e) { e = dataByteList.getEncoding().rightAdjustCharHead(dataBytes, s, s + limit, e); } if (str.isNil()) { str = strioSubstr(runtime, ptr.pos, e - s); } else if ((n = ((RubyString) str).size()) == 0) { // this is not an exact port; the original confused me p = s; // remove leading \n while (dataBytes[p] == '\n') { if (++p == e) { return context.nil; } } s = p; // find next \n or end; if followed by \n, include it too p = memchr(dataBytes, p, '\n', e - p); if (p != -1) { if (++p < e && dataBytes[p] == '\n') { e = p + 1; } else { e = p; } } str = strioSubstr(runtime, s - begin, e - s); } else if (n == 1) { RubyString strStr = (RubyString) str; ByteList strByteList = strStr.getByteList(); if ((p = memchr(dataBytes, s, strByteList.get(0), e - s)) != -1) { e = p + 1; } str = strioSubstr(runtime, ptr.pos, e - s); } else { if (n < e - s) { RubyString strStr = (RubyString) str; ByteList strByteList = strStr.getByteList(); byte[] strBytes = strByteList.getUnsafeBytes(); int[] skip = new int[1 << CHAR_BIT]; int pos; p = strByteList.getBegin(); bm_init_skip(skip, strBytes, p, n); if ((pos = bm_search(strBytes, p, n, dataBytes, s, e - s, skip)) >= 0) { e = s + pos + n; } } str = strioSubstr(runtime, ptr.pos, e - s); } ptr.pos = e - begin; ptr.lineno++; return str; }
private static void blockPostTrace( Ruby runtime, ThreadContext context, String name, RubyModule implClass) { if (runtime.hasEventHooks() && runtime.is2_0()) context.trace(RubyEvent.B_RETURN, name, implClass); }