note description: "Summary description for {INTEGER_X_ASSIGNMENT}." author: "Colin LeMahieu" date: "$Date$" revision: "$Revision$" quote: "The object and practice of liberty lies in the limitation of governmental power. - General Douglas MacArthur" deferred class INTEGER_X_ASSIGNMENT inherit INTEGER_X_FACILITIES SPECIAL_ASSIGNMENT rename set_str as set_str_special end MP_BASES feature swap (target: READABLE_INTEGER_X; other_a: READABLE_INTEGER_X) -- Swap the values `rop1' and `rop2' efficiently. local other_size: INTEGER_32 other_pointer: SPECIAL [NATURAL_32] do other_size := other_a.count other_pointer := other_a.item other_a.count := target.count other_a.item := target.item target.count := other_size target.item := other_pointer end set_str (target: READABLE_INTEGER_X; str: READABLE_STRING_8; base_a: INTEGER) -- Set the value of `rop' from `str', a null-terminated C string in base `base'. -- White space is allowed in the string, and is simply ignored. -- The base may vary from 2 to 62, or if base is 0, then the leading characters -- are used: 0x and 0X for hexadecimal, 0b and 0B for binary, 0 for octal, or -- decimal otherwise. -- For bases up to 36, case is ignored; upper-case and lower-case letters have -- the same value. -- For bases 37 to 62, upper-case letter represent the usual 10..35 while -- lower-case letter represent 36..61. -- This function returns 0 if the entire string is a valid number in base base. -- Otherwise it returns -1. require base_a <= 62 base_a >= 2 or base_a = 0 local base: INTEGER str_offset: INTEGER s: SPECIAL [NATURAL_8] s_offset: INTEGER begs: INTEGER i: INTEGER xsize: INTEGER c: CHARACTER negative: BOOLEAN digit_value: CHARACTER_STRATEGY str_size: INTEGER dig: NATURAL_8 do base := base_a if base > 36 then create {CASE_SENSITIVE_STRATEGY}digit_value else create {CASE_INSENSITIVE_STRATEGY}digit_value end from str_offset := 1 c := ' ' until not c.is_space or not str.valid_index (str_offset) loop c := str [str_offset] str_offset := str_offset + 1 end if c = '-' then negative := True c := str [str_offset] str_offset := str_offset + 1 end if digit_value.text_to_number (c.code.to_natural_8) >= if base = 0 then 10 else base end then (create {INTEGER_X_STRING_EXCEPTION}).raise end if base = 0 then base := 10 if c = '0' then base := 8 if str.valid_index (str_offset) then c := str [str_offset] end str_offset := str_offset + 1 if c = 'x' or c = 'X' then base := 16 c := str [str_offset] str_offset := str_offset + 1 elseif c = 'b' or c = 'B' then base := 2 c := str [str_offset] str_offset := str_offset + 1 end end end from until c /= '0' and not c.is_space or not str.valid_index (str_offset) loop c := str [str_offset] str_offset := str_offset + 1 end if c.code = 0 then target.count := 0 target.item [0] := 0 else str_size := str.count - str_offset + 2 create s.make_filled (0, str_size) from i := 0 until i >= str_size loop if not c.is_space then dig := digit_value.text_to_number (c.code.to_natural_8) if dig.to_integer_32 >= base then (create {INTEGER_X_STRING_EXCEPTION}).raise end s [s_offset] := dig s_offset := s_offset + 1 end if str.valid_index (str_offset) then c := str [str_offset] end str_offset := str_offset + 1 i := i + 1 end str_size := s_offset - begs xsize := (str_size / chars_per_bit_exactly (base)).truncated_to_integer // 32 + 2 target.resize (xsize) xsize := set_str_special (target.item, 0, s, begs, str_size, base) if negative then target.count := -xsize else target.count := xsize end end end end