예제 #1
0
 private int nameToBackrefNumber(RubyString str) {
   ByteList value = str.getByteList();
   try {
     return pattern.nameToBackrefNumber(
         value.getUnsafeBytes(), value.getBegin(), value.getBegin() + value.getRealSize(), regs);
   } catch (JOniException je) {
     throw getRuntime().newIndexError(je.getMessage());
   }
 }
예제 #2
0
  @JRubyMethod(name = "truncate", required = 1)
  public IRubyObject truncate(IRubyObject len) {
    checkWritable();

    int l = RubyFixnum.fix2int(len);
    int plen = ptr.string.size();
    if (l < 0) {
      throw getRuntime().newErrnoEINVALError("negative legnth");
    }
    ptr.string.resize(l);
    ByteList buf = ptr.string.getByteList();
    if (plen < l) {
      // zero the gap
      Arrays.fill(buf.getUnsafeBytes(), buf.getBegin() + plen, buf.getBegin() + l, (byte) 0);
    }
    return len;
  }
예제 #3
0
 public static int getBackrefNumber(DynamicObject matchData, ByteList value) {
   assert RubyGuards.isRubyMatchData(matchData);
   return Layouts.REGEXP
       .getRegex(Layouts.MATCH_DATA.getFields(matchData).regexp)
       .nameToBackrefNumber(
           value.getUnsafeBytes(),
           value.getBegin(),
           value.getBegin() + value.getRealSize(),
           Layouts.MATCH_DATA.getFields(matchData).region);
 }
예제 #4
0
 @JRubyMethod(name = "ruby=", required = 1)
 public IRubyObject ruby_set(final ThreadContext ctx, IRubyObject arg) {
   RubyString string;
   try {
     string = arg.convertToString();
   } catch (RaiseException re) {
     throw newTypeError(ctx.runtime, arg.getMetaClass(), "String");
   }
   ByteList bytes = string.getByteList();
   value.set(bytes.getUnsafeBytes(), bytes.getBegin(), bytes.getRealSize());
   return arg;
 }
예제 #5
0
  private RubyString strioSubstr(Ruby runtime, int pos, int len) {
    RubyString str = ptr.string;
    ByteList strByteList = str.getByteList();
    byte[] strBytes = strByteList.getUnsafeBytes();
    Encoding enc = str.getEncoding();
    int rlen = str.size() - pos;

    if (len > rlen) len = rlen;
    if (len < 0) len = 0;

    if (len == 0) return RubyString.newEmptyString(runtime);
    return RubyString.newStringShared(runtime, strBytes, strByteList.getBegin() + pos, len, enc);
  }
예제 #6
0
  private void updatePairs(ByteList value, Encoding encoding, Pair[] pairs) {
    Arrays.sort(pairs);

    int length = pairs.length;
    byte[] bytes = value.getUnsafeBytes();
    int p = value.getBegin();
    int s = p;
    int c = 0;

    for (int i = 0; i < length; i++) {
      int q = s + pairs[i].bytePos;
      c += StringSupport.strLength(encoding, bytes, p, q);
      pairs[i].charPos = c;
      p = q;
    }
  }
예제 #7
0
 @JRubyMethod(name = "ruby=")
 public IRubyObject ruby_set(final ThreadContext ctx, IRubyObject arg) {
   RubyString string;
   try {
     string = arg.convertToString();
   } catch (RaiseException re) {
     throw newTypeError(ctx.runtime, arg.getMetaClass(), "String");
   }
   if (string.getEncoding() == UTF8Encoding.INSTANCE
       || string.getEncoding() == USASCIIEncoding.INSTANCE) {
     ByteList bytes = string.getByteList();
     value.set(bytes.getUnsafeBytes(), bytes.getBegin(), bytes.getRealSize());
   } else {
     value.set(string.toString());
   }
   return arg;
 }
예제 #8
0
  private void strioExtend(int pos, int len) {
    int olen;

    checkModifiable();
    olen = ptr.string.size();
    if (pos + len > olen) {
      ptr.string.resize(pos + len);
      if (pos > olen) {
        ByteList ptrByteList = ptr.string.getByteList();
        // zero the gap
        Arrays.fill(
            ptrByteList.getUnsafeBytes(),
            ptrByteList.getBegin() + olen,
            ptrByteList.getBegin() + pos,
            (byte) 0);
      }
    } else {
      ptr.string.modify19();
    }
  }
예제 #9
0
  @JRubyMethod(frame = true)
  public IRubyObject marshal_load(ThreadContext context, IRubyObject str) {
    try {
      ByteList byteList = str.convertToString().getByteList();
      ByteArrayInputStream bais =
          new ByteArrayInputStream(
              byteList.getUnsafeBytes(), byteList.getBegin(), byteList.getRealSize());
      ObjectInputStream ois = new JRubyObjectInputStream(context.getRuntime(), bais);

      object = ois.readObject();

      return this;
    } catch (IOException ioe) {
      throw context.getRuntime().newIOErrorFromException(ioe);
    } catch (ClassNotFoundException cnfe) {
      throw context
          .getRuntime()
          .newTypeError("Class not found unmarshaling Java type: " + cnfe.getLocalizedMessage());
    }
  }
예제 #10
0
  private void updatePairs(ByteList value, Encoding encoding, Pair[] pairs) {
    Arrays.sort(pairs);

    int length = pairs.length;
    byte[] bytes = value.getUnsafeBytes();
    int p = value.getBegin();
    int s = p;
    int c = 0;

    for (int i = 0; i < length; i++) {
      int q = s + pairs[i].bytePos;
      c += StringSupport.strLength(encoding, bytes, p, q);
      pairs[i].charPos = c;
      p = q;
    }

    Pair key = new Pair();
    key.bytePos = begin;
    charOffsets.beg[0] = pairs[Arrays.binarySearch(pairs, key)].charPos;
    key.bytePos = end;
    charOffsets.end[0] = pairs[Arrays.binarySearch(pairs, key)].charPos;
  }
예제 #11
0
  @Override
  public IRubyObject each_charInternal(final ThreadContext context, final Block block) {
    checkReadable();

    Ruby runtime = context.runtime;
    ByteList bytes = data.internal.getByteList();
    int len = bytes.getRealSize();
    int end = bytes.getBegin() + len;
    Encoding enc = runtime.is1_9() ? bytes.getEncoding() : runtime.getKCode().getEncoding();
    while (data.pos < len) {
      int pos = (int) data.pos;
      int n = StringSupport.length(enc, bytes.getUnsafeBytes(), pos, end);

      if (len < pos + n) n = len - pos;

      data.pos += n;

      block.yield(context, data.internal.makeShared19(runtime, pos, n));
    }

    return this;
  }
예제 #12
0
  public synchronized ByteList fgets(ByteList separatorString)
      throws IOException, BadDescriptorException {
    checkReadable();
    ensureRead();

    if (separatorString == null) {
      return readall();
    }

    final ByteList separator =
        (separatorString == PARAGRAPH_DELIMETER) ? PARAGRAPH_SEPARATOR : separatorString;

    descriptor.checkOpen();

    if (feof()) {
      return null;
    }

    int c = read();

    if (c == -1) {
      return null;
    }

    // unread back
    buffer.position(buffer.position() - 1);

    ByteList buf = new ByteList(40);

    byte first = separator.getUnsafeBytes()[separator.getBegin()];

    LineLoop:
    while (true) {
      ReadLoop:
      while (true) {
        byte[] bytes = buffer.array();
        int offset = buffer.position();
        int max = buffer.limit();

        // iterate over remainder of buffer until we find a match
        for (int i = offset; i < max; i++) {
          c = bytes[i];
          if (c == first) {
            // terminate and advance buffer when we find our char
            buf.append(bytes, offset, i - offset);
            if (i >= max) {
              buffer.clear();
            } else {
              buffer.position(i + 1);
            }
            break ReadLoop;
          }
        }

        // no match, append remainder of buffer and continue with next block
        buf.append(bytes, offset, buffer.remaining());
        int read = refillBuffer();
        if (read == -1) break LineLoop;
      }

      // found a match above, check if remaining separator characters match, appending as we go
      for (int i = 0; i < separator.getRealSize(); i++) {
        if (c == -1) {
          break LineLoop;
        } else if (c != separator.getUnsafeBytes()[separator.getBegin() + i]) {
          buf.append(c);
          continue LineLoop;
        }
        buf.append(c);
        if (i < separator.getRealSize() - 1) {
          c = read();
        }
      }
      break;
    }

    if (separatorString == PARAGRAPH_DELIMETER) {
      while (c == separator.getUnsafeBytes()[separator.getBegin()]) {
        c = read();
      }
      ungetc(c);
    }

    return buf;
  }
예제 #13
0
  @JRubyMethod(name = "read", optional = 2)
  public IRubyObject read(ThreadContext context, IRubyObject[] args) {
    checkReadable();

    Ruby runtime = context.runtime;
    IRubyObject str = runtime.getNil();
    int len;
    boolean binary = false;

    switch (args.length) {
      case 2:
        str = args[1];
        if (!str.isNil()) {
          str = str.convertToString();
          ((RubyString) str).modify();
        }
      case 1:
        if (!args[0].isNil()) {
          len = RubyNumeric.fix2int(args[0]);

          if (len < 0) {
            throw getRuntime().newArgumentError("negative length " + len + " given");
          }
          if (len > 0 && isEndOfString()) {
            if (!str.isNil()) ((RubyString) str).resize(0);
            return getRuntime().getNil();
          }
          binary = true;
          break;
        }
      case 0:
        len = ptr.string.size();
        if (len <= ptr.pos) {
          if (str.isNil()) {
            str = runtime.newString();
          } else {
            ((RubyString) str).resize(0);
          }

          return str;
        } else {
          len -= ptr.pos;
        }
        break;
      default:
        throw getRuntime().newArgumentError(args.length, 0);
    }

    if (str.isNil()) {
      str = strioSubstr(runtime, ptr.pos, len);
      if (binary) ((RubyString) str).setEncoding(ASCIIEncoding.INSTANCE);
    } else {
      int rest = ptr.string.size() - ptr.pos;
      if (len > rest) len = rest;
      ((RubyString) str).resize(len);
      ByteList strByteList = ((RubyString) str).getByteList();
      byte[] strBytes = strByteList.getUnsafeBytes();
      ByteList dataByteList = ptr.string.getByteList();
      byte[] dataBytes = dataByteList.getUnsafeBytes();
      System.arraycopy(
          dataBytes, dataByteList.getBegin() + ptr.pos, strBytes, strByteList.getBegin(), len);
      if (binary) {
        ((RubyString) str).setEncoding(ASCIIEncoding.INSTANCE);
      } else {
        ((RubyString) str).setEncoding(ptr.string.getEncoding());
      }
    }
    ptr.pos += ((RubyString) str).size();
    return str;
  }
예제 #14
0
  // 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;
  }
예제 #15
0
 public Entry findAliasEntry(ByteList bytes) {
   return aliases.get(
       bytes.getUnsafeBytes(), bytes.getBegin(), bytes.getBegin() + bytes.getRealSize());
 }
예제 #16
0
 public Entry findEncodingEntry(ByteList bytes) {
   return encodings.get(
       bytes.getUnsafeBytes(), bytes.getBegin(), bytes.getBegin() + bytes.getRealSize());
 }