def method_initialize(self, space, args_w): if len(args_w) == 1: address = Coerce.ffi_address(space, args_w[0]) return self._initialize(space, address) elif len(args_w) == 2: sizeof_type = Coerce.int(space, args_w[0]) address = Coerce.ffi_address(space, args_w[1]) return self._initialize(space, address, sizeof_type)
def method_sub(self, space, w_other): if isinstance(w_other, W_TimeObject): return space.newfloat( self.epoch_seconds - Coerce.float(space, w_other)) else: w_time = space.send(space.getclassfor(W_TimeObject), "allocate") w_time._set_epoch_seconds( self.epoch_seconds - Coerce.float(space, w_other)) w_time._set_offset(self.offset) return w_time
def method_sub(self, space, w_other): if isinstance(w_other, W_TimeObject): return space.newfloat(self.epoch_seconds - Coerce.float(space, w_other)) else: w_time = space.send(space.getclassfor(W_TimeObject), "allocate") w_time._set_epoch_seconds(self.epoch_seconds - Coerce.float(space, w_other)) w_time._set_offset(self.offset) return w_time
def method_match(self, space, w_s, w_offset=None): if w_s is space.w_nil: return space.w_nil s = Coerce.str(space, w_s) if w_offset is not None: offset = Coerce.int(space, w_offset) else: offset = 0 ctx = self.make_ctx(s, offset) matched = rsre_core.search_context(ctx) return self.get_match_result(space, ctx, s, matched)
def method_at(self, space, w_time, w_microtime=None): if not (w_time.is_kind_of(space, space.w_numeric) or w_time.is_kind_of(space, space.getclassfor(W_TimeObject))): raise space.error(space.w_TypeError) if w_microtime is not None: microtime = Coerce.float(space, w_microtime) * 0.000001 else: microtime = 0.0 timestamp = Coerce.float(space, w_time) w_time = space.send(self, "new") w_time._set_epoch_seconds(timestamp + microtime) return w_time
def coerce_address(space, w_addressable): if space.is_kind_of(w_addressable, space.w_bignum): return Coerce.int(space, w_addressable) elif space.is_kind_of(w_addressable, space.w_fixnum): return Coerce.int(space, w_addressable) elif space.is_kind_of(w_addressable, space.getclassfor(W_PointerObject)): w_address = space.send(w_addressable, 'address') return coerce_address(space, w_address) else: errmsg = ("can't convert %s into FFI::Pointer" % space.getclass(w_addressable).name) raise space.error(space.w_TypeError, errmsg)
def method_pack(self, space, w_template): template = Coerce.str(space, w_template) result = RPacker(template, space.listview(self)).operate(space) w_result = space.newstr_fromchars(result) if space.is_true(space.send(w_template, "tainted?")): space.send(w_result, "taint") return w_result
def _rand_int(self, space, integer): random = self.random.random() max = Coerce.int(space, integer) if max <= 0: raise space.error(space.w_ArgumentError, "invalid argument") else: return space.newint(int(random * max))
def method_initialize(self, space, w_fd_or_io, w_mode_str_or_int=None, w_opts=None): if isinstance(w_fd_or_io, W_IOObject): fd = w_fd_or_io.fd else: fd = Coerce.int(space, w_fd_or_io) if isinstance(w_mode_str_or_int, W_StringObject): mode = space.str_w(w_mode_str_or_int) if ":" in mode: raise space.error(space.w_NotImplementedError, "encoding for IO.new") elif w_mode_str_or_int is None: mode = None else: raise space.error(space.w_NotImplementedError, "int mode for IO.new") if w_opts is not None: raise space.error(space.w_NotImplementedError, "options hash for IO.new") if mode is None: mode = "r" self.fd = fd return self
def singleton_method_delete(self, space, args_w): for w_path in args_w: path = Coerce.path(space, w_path) try: os.unlink(path) except OSError as e: raise error_for_oserror(space, e) return space.newint(len(args_w))
def singleton_method_chmod(self, space, mode, args_w): for arg_w in args_w: path = Coerce.path(space, arg_w) try: os.chmod(path, mode) except OSError as e: raise error_for_oserror(space, e) return space.newint(len(args_w))
def method_plus(self, space, w_other): if isinstance(w_other, W_TimeObject): raise space.error(space.w_TypeError, "time + time?") w_time = space.send(space.getclassfor(W_TimeObject), "allocate") w_time._set_epoch_seconds(self.epoch_seconds + Coerce.float(space, w_other)) w_time._set_offset(self.offset) return w_time
def method_sleep(self, space, w_duration=None): if w_duration is None: raise space.error(space.w_NotImplementedError) elif space.is_kind_of(w_duration, space.w_string): raise space.error(space.w_TypeError, "can't convert String into time interval") start = time.time() time.sleep(Coerce.float(space, w_duration)) return space.newint(int(round_double(time.time() - start, 0)))
def lt(self, w_a, w_b): w_cmp_res = self.space.compare(w_a, w_b, self.sortblock) if self.space.is_kind_of(w_cmp_res, self.space.w_bignum): return self.space.bigint_w(w_cmp_res).lt(rbigint.fromint(0)) else: return Coerce.bool( self.space, self.space.send(w_cmp_res, "<", [self.space.newint(0)]))
def method_at(self, space, w_time): if not (w_time.is_kind_of(space, space.w_numeric) or w_time.is_kind_of(space, space.getclassfor(W_TimeObject))): raise space.error(space.w_TypeError) timestamp = Coerce.float(space, w_time) w_time = space.send(self, "new") w_time._set_epoch_seconds(timestamp) return w_time
def wrapper(self, space, args_w): if len(args_w) == 2: w_value1, w_value2 = args_w else: # delegate and hope that the gateway will raise an # ArgumentError args = [Coerce.float(space, w_arg) for w_arg in args_w] return func(self, space, args) if space.is_kind_of(w_value1, space.w_numeric): if space.is_kind_of(w_value2, space.w_numeric): value1 = Coerce.float(space, w_value1) value2 = Coerce.int(space, w_value2) return func(self, space, value1, value2) else: raise_type_error(space, w_value2) else: raise_type_error(space, w_value1)
def method_plus(self, space, w_other): if isinstance(w_other, W_TimeObject): raise space.error(space.w_TypeError, "time + time?") w_time = space.send(space.getclassfor(W_TimeObject), "allocate") w_time._set_epoch_seconds( self.epoch_seconds + Coerce.float(space, w_other)) w_time._set_offset(self.offset) return w_time
def method_initialize(self, space, w_source, flags=0): if isinstance(w_source, W_RegexpObject): self.set_source(space, w_source.source, w_source.flags) else: try: self.set_source(space, Coerce.str(space, w_source), flags) except regexp.RegexpError as e: raise space.error(space.w_RegexpError, str(e)) return self
def wrapper(self, space, args_w): f_args = [] for w_arg in args_w: if space.is_kind_of(w_arg, space.w_numeric): f_arg = Coerce.float(space, w_arg) f_args.append(f_arg) else: raise_type_error(space, w_arg) return func(self, space, *f_args)
def method_div(self, space, w_other): if space.is_kind_of(w_other, space.w_float): if space.float_w(w_other) == 0.0: self.raise_zero_division_error(space) else: w_float = space.send(space.newfloat(space.float_w(self)), "/", [w_other]) w_float = space.newfloat(math.floor(Coerce.float(space, w_float))) return space.send(w_float, "to_i") else: return self.divide(space, w_other)
def method_subscript(self, space, w_idx, w_count, w_other=None): if w_other is None: w_other = w_count w_count = None other = Coerce.str(space, w_other) start_idx = -1 end_idx = -1 if space.is_kind_of(w_idx, space.w_string): other_str = space.str_w(w_idx) start_idx = space.str_w(self).find(other_str) end_idx = start_idx + len(other_str) elif space.is_kind_of(w_idx, space.w_regexp): ctx = w_idx.make_ctx(space.str_w(self)) if self.search_context(space, ctx): if w_count is None: start_idx = ctx.match_start end_idx = ctx.match_end elif space.is_kind_of(w_count, space.w_string): raise space.error( space.w_NotImplementedError, "string subscript replace with regexp and named group") else: groupnum = Coerce.int(space, w_count) try: start_idx, end_idx = ctx.span(groupnum) except IndexError: pass else: start_idx, end_idx, as_range, nil = space.subscript_access( self.length(), w_idx, w_count=w_count) if not w_count: end_idx = start_idx + 1 if start_idx < 0 or end_idx < 0: raise space.error(space.w_IndexError, "cannot find substring in string to replace") self.strategy.to_mutable(space, self) self.strategy.delslice(space, self.str_storage, start_idx, end_idx) self.strategy.insert(self.str_storage, start_idx, other) return self
def method_match_operator(self, space, w_s): if w_s is space.w_nil: return space.w_nil s = Coerce.str(space, w_s) ctx = self.make_ctx(s) matched = rsre_core.search_context(ctx) self.get_match_result(space, ctx, s, matched) if matched: return space.newint(ctx.match_start) else: return space.w_nil
def method_subscript(self, space, w_idx, w_count, w_other=None): if w_other is None: w_other = w_count w_count = None other = Coerce.str(space, w_other) start_idx = -1 end_idx = -1 if space.is_kind_of(w_idx, space.w_string): other_str = space.str_w(w_idx) start_idx = space.str_w(self).find(other_str) end_idx = start_idx + len(other_str) elif space.is_kind_of(w_idx, space.w_regexp): ctx = w_idx.make_ctx(space.str_w(self)) if self.search_context(space, ctx): if w_count is None: start_idx = ctx.match_start end_idx = ctx.match_end elif space.is_kind_of(w_count, space.w_string): raise space.error( space.w_NotImplementedError, "string subscript replace with regexp and named group" ) else: groupnum = Coerce.int(space, w_count) try: start_idx, end_idx = ctx.span(groupnum) except IndexError: pass else: start_idx, end_idx, as_range, nil = space.subscript_access(self.length(), w_idx, w_count=w_count) if not w_count: end_idx = start_idx + 1 if start_idx < 0 or end_idx < 0: raise space.error(space.w_IndexError, "cannot find substring in string to replace") self.strategy.to_mutable(space, self) self.strategy.delslice(space, self.str_storage, start_idx, end_idx) self.strategy.insert(self.str_storage, start_idx, other) return self
def method_div(self, space, w_other): if space.is_kind_of(w_other, space.w_float): if space.float_w(w_other) == 0.0: self.raise_zero_division_error(space) else: w_float = space.send(space.newfloat(space.float_w(self)), "/", [w_other]) w_float = space.newfloat( math.floor(Coerce.float(space, w_float))) return space.send(w_float, "to_i") else: return self.divide(space, w_other)
def srand(self, space, seed=None): previous_seed = self.w_seed if seed is None: seed = intmask(self._generate_seed()) else: seed = Coerce.int(space, seed) self.w_seed = space.newint(seed) if previous_seed is None: value = space.newfloat(self.random.random()) else: value = previous_seed self.random = Random(abs(seed)) return value
def month_arg_to_month(space, w_arg): w_month = space.convert_type(w_arg, space.w_string, "to_str", raise_error=False) if w_month is space.w_nil: month = Coerce.int(space, w_arg) else: try: month = MONTHNAMES.index(space.str_w(w_month)) + 1 except ValueError: raise space.error(space.w_ArgumentError, "mon out of range") return month
def method_module_function(self, space, args_w): if not args_w: self.set_default_visibility(space, W_FunctionObject.MODULE_FUNCTION) return self for w_arg in args_w: name = Coerce.symbol(space, w_arg) w_method = self.find_method(space, name) if w_method is None or isinstance(w_method, UndefMethod): cls_name = space.obj_to_s(self) raise space.error(space.w_NameError, "undefined method `%s' for class `%s'" % (name, cls_name)) self.attach_method(space, name, w_method) self.set_method_visibility(space, name, W_FunctionObject.PRIVATE) return self
def method_last(self, space, w_count=None): if w_count is not None: count = Coerce.int(space, w_count) if count < 0: raise space.error(space.w_ArgumentError, "negative array size") start = len(self.items_w) - count if start < 0: start = 0 return space.newarray(self.items_w[start:]) if len(self.items_w) == 0: return space.w_nil else: return self.items_w[len(self.items_w) - 1]
def month_arg_to_month(space, w_arg): w_month = space.convert_type(w_arg, space.w_string, "to_str", raise_error=False) if w_month is space.w_nil: month = Coerce.int(space, w_arg) else: try: month = MONTHNAMES.index(space.str_w(w_month)) + 1 except ValueError: raise space.error( space.w_ArgumentError, "mon out of range" ) return month
def method_sysopen(self, space, w_path, w_mode_str_or_int=None, w_perm=None): perm = 0666 mode = os.O_RDONLY if w_mode_str_or_int is not None: mode, encoding = map_filemode(space, w_mode_str_or_int) if w_perm is not None and w_perm is not space.w_nil: perm = space.int_w(w_perm) path = Coerce.path(space, w_path) try: fd = os.open(path, mode, perm) except OSError as e: raise error_for_oserror(space, e) else: return space.newint(fd)
def method_sysopen(self, space, w_path, w_mode_str_or_int=None, w_perm=None): perm = 0666 mode = os.O_RDONLY if w_mode_str_or_int is not None: mode = map_filemode(space, w_mode_str_or_int) if w_perm is not None and w_perm is not space.w_nil: perm = space.int_w(w_perm) path = Coerce.path(space, w_path) try: fd = os.open(path, mode, perm) except OSError as e: raise error_for_oserror(space, e) else: return space.newint(fd)
def method_module_function(self, space, args_w): if not args_w: self.set_default_visibility(space, W_FunctionObject.MODULE_FUNCTION) return self for w_arg in args_w: name = Coerce.symbol(space, w_arg) w_method = self.find_method(space, name) if w_method is None or isinstance(w_method, UndefMethod): cls_name = space.obj_to_s(self) raise space.error(space.w_NameError, "undefined method `%s' for class `%s'" % (name, cls_name) ) self.attach_method(space, name, w_method) self.set_method_visibility(space, name, W_FunctionObject.PRIVATE) return self
def method_subscript_assign(self, space, key, w_value): if "\0" in key: raise space.error(space.w_ArgumentError, "bad environment variable name") if w_value is space.w_nil: try: del os.environ[key] except (KeyError, OSError): pass return space.w_nil if "=" in key or key == "": raise error_for_errno(space, errno.EINVAL) value = Coerce.str(space, w_value) if "\0" in value: raise space.error(space.w_ArgumentError, "bad environment variable value") os.environ[key] = value return w_value
def find_feature(space, path): assert path is not None if os.path.isfile(path): return path if not path.endswith(".rb"): path += ".rb" if not (path.startswith("/") or path.startswith("./") or path.startswith("../")): w_load_path = space.globals.get(space, "$LOAD_PATH") for w_base in space.listview(w_load_path): base = Coerce.path(space, w_base) full = os.path.join(base, path) if os.path.isfile(full): path = os.path.join(base, path) break return path
def method_new(self, space, args_w): if len(args_w) > 7: raise space.error( space.w_ArgumentError, ("wrong number of arguments (given %d, expected 0..7)" % len(args_w))) if len(args_w) > 6: utc_offset = Coerce.int(space, args_w.pop()) w_time = space.send(self, "gm", args_w) w_time._set_offset(utc_offset) return w_time elif len(args_w) > 1: return space.send(self, "gm", args_w) else: w_time = space.send(self, "allocate") space.send(w_time, "initialize") return w_time
def method_initialize(self, space, w_fd_or_io, w_mode_str_or_int=None, w_opts=None): if isinstance(w_fd_or_io, W_IOObject): fd = w_fd_or_io.fd else: fd = Coerce.int(space, w_fd_or_io) if isinstance(w_mode_str_or_int, W_StringObject): mode = space.str_w(w_mode_str_or_int) elif w_mode_str_or_int is None: mode = None else: raise space.error(space.w_NotImplementedError, "int mode for IO.new") if w_opts is not None: raise space.error(space.w_NotImplementedError, "options hash for IO.new") if mode is None: mode = "r" self.fd = fd return self
def method_now(self, space, args_w): if len(args_w) > 7: raise space.error( space.w_ArgumentError, "wrong number of arguments (given %d, expected 0..7)" % len(args_w)) if len(args_w) > 6: utc_offset = Coerce.int(space, args_w.pop()) w_time = space.send(self, "gm", args_w) w_time._set_offset(utc_offset) return w_time elif len(args_w) > 1: return space.send(self, "gm", args_w) else: w_time = space.send(self, "allocate") space.send(w_time, "initialize") return w_time
def method_to_i(self, space, w_radix=None): if w_radix is None: is_radix = False radix = 10 else: is_radix = True radix = Coerce.int(space, w_radix) s = space.str_w(self) i = 0 length = len(s) while i < length: if not s[i].isspace(): break i += 1 neg = i < length and s[i] == "-" if neg: i += 1 if i < length and s[i] == "+": i += 1 if i < length and s[i] == "0": if i + 1 < length: try: r = RADIX_MAP[s[i + 1]] except KeyError: if radix == 0: radix = 8 else: if not is_radix or radix == r or radix == 0: radix = r i += 2 if radix == 0: radix = 10 if not 2 <= radix <= 36: raise space.error(space.w_ArgumentError, "invalid radix %d" % radix) try: value = self.to_int(s, neg, i, radix) except OverflowError: value = self.to_bigint(s, neg, i, radix) return space.newbigint_fromrbigint(value) else: return space.newint(value)
def method_initialize(self, space, w_fd_or_io, w_mode_str_or_int=None, w_opts=None): if isinstance(w_fd_or_io, W_IOObject): fd = w_fd_or_io.fd else: fd = Coerce.int(space, w_fd_or_io) if w_opts is not None: raise space.error(space.w_NotImplementedError, "options hash for IO.new") mode, mode_str, encoding = map_filemode(space, w_mode_str_or_int) self.fd = fd # Optimization for ReadOnly files, using stream reading # this speedup common file read by 4 times # TODO: rewrite to something better if mode_str == "r" or mode_str == "rb": try: self.stream = streamio.fdopen_as_stream(fd, mode_str) except OSError as e: raise error_for_oserror(space, e) return self
def method_round(self, space): return space.newint(int(round_away(Coerce.float(space, self))))
def method_floor(self, space): return space.newint(int(math.floor(Coerce.float(space, self))))
def _rand_float(self, space, float): random = self.random.random() max = Coerce.float(space, float) if max <= 0: raise space.error(space.w_ArgumentError, "invalid argument") return space.newfloat(random * max)