Пример #1
0
        public override object Call1(Class last_class, object ary, Frame caller, Proc block, object fmt)
        {

            int p, pend, idx;
            int len, items, ptr;
            string fmtString, fromString;
            char type;
            object from;
            int plen;
            System.Text.StringBuilder res;

            fmtString = String.StringValue(fmt, caller);
            p = 0;
            pend = fmtString.Length;
            res = new System.Text.StringBuilder();

            items = ((Array)ary).Count;
            idx = 0;

            while (p < pend)
            {
                if (fmtString.Length != pend)
                {
                    new RuntimeError("format string modified");
                }
                type = fmtString[p++];
                if (char.IsWhiteSpace(type)) //TEST: IsWhiteSpace() must be equivalent to isspace()
                {
                    continue;
                }
                if (type == '#') //eat comments
                {
                    while ((p < pend) && (fmtString[p] != '\n'))
                    {
                        p++;
                    }
                    continue;
                }
                if (p < pend && (fmtString[p] == '_' || fmtString[p] == '!')) //'_' and '!' can only come after "sSiIlL"
                {
                    const string natstr = "sSiIlL";

                    if (natstr.IndexOf(type) != -1)
                    {
                        p++;
                    }
                    else
                    {
                        throw new ArgumentError(string.Format(CultureInfo.InvariantCulture, "'{0}' allowed only after types {1}", fmtString[p], natstr)).raise(caller);
                    }
                }
                if (p < pend && fmtString[p] == '*') /* set data length */
                {
                    if ("@Xxu".IndexOf(type) != -1)
                    {
                        len = 0;
                    }
                    else
                    {
                        len = items;
                    }
                    p++;
                }
                else if (p < pend && char.IsDigit(fmtString[p]))
                {
                    int numStart = p;
                    int numEnd = p + 1;
                    while (numEnd < pend)
                    {
                        if (char.IsDigit(fmtString[numEnd]))
                        {
                            numEnd++;
                        }
                        else
                        {
                            break;
                        }
                    }
                    len = int.Parse(fmtString.Substring(numStart, numEnd - numStart), CultureInfo.InvariantCulture);
                }
                else
                {
                    len = 1;
                }

                switch (type)
                {
                    case 'A':
                        goto case 'Z';
                    case 'a':
                        goto case 'Z';
                    case 'B':
                        goto case 'Z';
                    case 'b':
                        goto case 'Z';
                    case 'H':
                        goto case 'Z';
                    case 'h':
                        goto case 'Z';
                    case 'Z':
                        from = Pack.NEXTFROM(caller, ary, ref idx, ref items);


                        if (from == null)
                        {
                            fromString = "";
                            ptr = 0;
                            plen = 0;
                        }
                        else
                        {
                            fromString = String.StringValue(from, caller);
                            ptr = 0;
                            plen = fromString.Length;
                        }

                        if (fmtString[p - 1] == '*')
                        {
                            len = plen;
                        }
                        switch (type)
                        {
                            case 'a':        /* arbitrary binary string (null padded)  */
                                goto case 'Z';
                            case 'A':        /* ASCII string (space padded) */
                                goto case 'Z';
                            case 'Z':        /* null terminated ASCII string  */
                                if (plen >= len)
                                {
                                    res.Append(fromString.Substring(0, len));
                                    if (fmtString[p - 1] == '*' && type == 'Z')
                                    {
                                        res.Append("\0");
                                    }
                                }
                                else
                                {
                                    res.Append(fromString);
                                    len -= plen;
                                    if (type == 'A')
                                    {
                                        res.Append(' ', len);
                                    }
                                    else //type == 'Z' or type == 'a'
                                    {
                                        res.Append('\0', len);
                                    }
                                }
                                break;
                            case 'b':        /* bit string (ascending) */
                                {
                                    int aByte = 0;
                                    int i, j = 0;

                                    if (len > plen)
                                    {
                                        j = (len - plen + 1) / 2;
                                        len = plen;
                                    }
                                    for (i = 0; i++ < len; ptr++)
                                    {
                                        if ((fromString[ptr] & 1) > 0)
                                        {
                                            aByte |= 128;
                                        }
                                        if ((i & 7) > 0)
                                        {
                                            aByte >>= 1;
                                        }
                                        else
                                        {
                                            char c = (char)aByte;
                                            res.Append((char)c);
                                            aByte = 0;
                                        }
                                    }
                                    if ((len & 7) > 0)
                                    {
                                        char c;
                                        aByte >>= 7 - (len & 7);
                                        c = (char)aByte;
                                        res.Append(c);
                                    }
                                    len = j;
                                    res.Append('\0', len); //goto grow;                                     
                                }
                                break;
                            case 'B':        /* bit string (descending) */
                                {
                                    int aByte = 0;
                                    int i, j = 0;

                                    if (len > plen)
                                    {
                                        j = (len - plen + 1) / 2;
                                        len = plen;
                                    }
                                    for (i = 0; i++ < len; ptr++)
                                    {
                                        aByte |= fromString[ptr] & 1;
                                        if ((i & 7) > 0)
                                        {
                                            aByte <<= 1;
                                        }
                                        else
                                        {
                                            char c = (char)aByte;
                                            res.Append(c);
                                            aByte = 0;
                                        }
                                    }
                                    if ((len & 7) > 0)
                                    {
                                        char c;
                                        aByte <<= 7 - (len & 7);
                                        c = (char)aByte;
                                        res.Append(c);
                                    }
                                    len = j;
                                    res.Append('\0', len); //goto grow;     
                                }
                                break;
                            case 'h':        /* hex string (low nibble first) */
                                {
                                    int aByte = 0;
                                    int i, j = 0;


                                    if (len > plen)
                                    {
                                        j = (len - plen + 1) / 2;
                                        len = plen;
                                    }
                                    for (i = 0; i++ < len; ptr++)
                                    {
                                        if (char.IsLetter(fromString[ptr]))
                                        {
                                            aByte |= (((fromString[ptr] & 15) + 9) & 15) << 4;
                                        }
                                        else
                                        {
                                            aByte |= (fromString[ptr] & 15) << 4;
                                        }
                                        if ((i & 1) > 0)
                                        {
                                            aByte >>= 4;
                                        }
                                        else
                                        {
                                            char c = (char)aByte;
                                            res.Append(c);
                                            aByte = 0;
                                        }
                                    }
                                    if ((len & 1) > 0)
                                    {
                                        char c = (char)aByte;
                                        res.Append(c);
                                    }
                                    len = j;
                                    res.Append('\0', len); //goto grow;  
                                }
                                break;
                            case 'H':        /* hex string (high nibble first) */
                                {
                                    int aByte = 0;
                                    int i, j = 0;

                                    if (len > plen)
                                    {
                                        j = (len - plen + 1) / 2;
                                        len = plen;
                                    }
                                    for (i = 0; i++ < len; ptr++)
                                    {
                                        if (char.IsLetter(fromString[ptr]))
                                        {
                                            aByte |= ((fromString[ptr] & 15) + 9) & 15;
                                        }
                                        else
                                        {
                                            aByte |= fromString[ptr] & 15;
                                        }
                                        if ((i & 1) > 0)
                                        {
                                            aByte <<= 4;
                                        }
                                        else
                                        {
                                            char c = (char)aByte;
                                            res.Append(c);
                                            aByte = 0;
                                        }
                                    }
                                    if ((len & 1) > 0)
                                    {
                                        char c = (char)aByte;
                                        res.Append(c);
                                    }
                                    len = j;
                                    res.Append('\0', len);
                                }
                                break;
                        }
                        break;
                    case 'c': /* signed char */
                        goto case 'C';
                    case 'C': /* unsigned char */
                        while (len-- > 0)
                        {
                            char c;

                            from = Pack.NEXTFROM(caller, ary, ref idx, ref items);

                            c = (char)(Pack.num2i32(from, caller) & 0xFF);
                            res.Append(c);
                        }
                        break;
                    case 's':        /* signed short */
                        goto case 'S';
                    case 'S':        /* unsigned short */
                        while (len-- > 0)
                        {
                            ushort s;

                            from = Pack.NEXTFROM(caller, ary, ref idx, ref items);

                            s = (ushort)Pack.num2i32(from, caller);
                            byte[] b = System.BitConverter.GetBytes(s);
                            Pack.rb_str_buf_cat(res, b, 2);
                        }
                        break;
                    case 'i':        /* signed int */
                        goto case 'L';
                    case 'I':        /* unsigned int */
                        goto case 'L';
                    case 'l':        /* signed long */
                        goto case 'L';
                    case 'L':        /* unsigned long */
                        while (len-- > 0)
                        {
                            uint i;

                            from = Pack.NEXTFROM(caller, ary, ref idx, ref items);

                            i = Pack.num2i32(from, caller);
                            byte[] b = System.BitConverter.GetBytes(i);
                            Pack.rb_str_buf_cat(res, b, 4);
                        }
                        break;
                    case 'q':        /* signed quad (64bit) int */
                        goto case 'Q';
                    case 'Q':        /* unsigned quad (64bit) int */
                        while (len-- > 0)
                        {
                            ulong ul;

                            from = Pack.NEXTFROM(caller, ary, ref idx, ref items);
                            ul = Pack.num2i64(from, caller);
                            byte[] b = System.BitConverter.GetBytes(ul);
                            Pack.rb_str_buf_cat(res, b, 8);
                        }
                        break;
                    case 'n':        /* unsigned short (network byte-order)  */
                        while (len-- > 0)
                        {
                            ushort s;

                            from = Pack.NEXTFROM(caller, ary, ref idx, ref items);

                            s = (ushort)Pack.num2i32(from, caller);
                            byte[] b = System.BitConverter.GetBytes(s);
                            if (!Pack.isBigEndian())
                            {
                                Pack.swap(b);
                            }
                            Pack.rb_str_buf_cat(res, b, 2);
                        }
                        break;
                    case 'N':        /* unsigned long (network byte-order) */

                        while (len-- > 0)
                        {
                            uint l;

                            from = Pack.NEXTFROM(caller, ary, ref idx, ref items);

                            l = Pack.num2i32(from, caller);
                            byte[] b = System.BitConverter.GetBytes(l);
                            if (!Pack.isBigEndian())
                            {
                                Pack.swap(b);
                            }
                            Pack.rb_str_buf_cat(res, b, 4);
                        }

                        break;
                    case 'v':        /* unsigned short (VAX byte-order) */
                        while (len-- > 0)
                        {
                            from = Pack.NEXTFROM(caller, ary, ref idx, ref items);

                            ushort s;
                            s = (ushort)Pack.num2i32(from, caller);
                            byte[] b = System.BitConverter.GetBytes(s);
                            if (Pack.isBigEndian())
                            {
                                Pack.swap(b);
                            }
                            Pack.rb_str_buf_cat(res, b, 2);
                        }
                        break;
                    case 'V':        /* unsigned long (VAX byte-order) */
                        while (len-- > 0)
                        {
                            from = Pack.NEXTFROM(caller, ary, ref idx, ref items);

                            uint l;

                            l = Pack.num2i32(from, caller);
                            byte[] s = System.BitConverter.GetBytes(l);
                            if (Pack.isBigEndian())
                            {
                                Pack.swap(s);
                            }
                            Pack.rb_str_buf_cat(res, s, 4);
                        }
                        break;
                    case 'f':        /* single precision float in native format */
                        goto case 'F';
                    case 'F':        /* ditto */
                        while (len-- > 0)
                        {
                            float f;

                            from = Pack.NEXTFROM(caller, ary, ref idx, ref items);
                            f = (float)((Float)Float.rb_Float(from, caller)).value;
                            byte[] s = System.BitConverter.GetBytes(f);
                            Pack.rb_str_buf_cat(res, s, 4);
                        }
                        break;
                    case 'e':        /* single precision float in VAX byte-order */
                        while (len-- > 0)
                        {
                            float f;
                            byte[] ftmp;

                            from = Pack.NEXTFROM(caller, ary, ref idx, ref items);
                            f = (float)((Float)Float.rb_Float(from, caller)).value;
                            ftmp = System.BitConverter.GetBytes(f);
                            if (Pack.isBigEndian())
                            {
                                Pack.swap(ftmp);
                            }
                            Pack.rb_str_buf_cat(res, ftmp, 4);
                        }
                        break;
                    case 'E':        /* double precision float in VAX byte-order */
                        while (len-- > 0)
                        {
                            double d;
                            byte[] dtmp;

                            from = Pack.NEXTFROM(caller, ary, ref idx, ref items);
                            d = ((Float)Float.rb_Float(from, caller)).value;
                            dtmp = System.BitConverter.GetBytes(d);
                            if (Pack.isBigEndian())
                            {
                                Pack.swap(dtmp);
                            }
                            Pack.rb_str_buf_cat(res, dtmp, 8);
                        }
                        break;
                    case 'd':        /* double precision float in native format */
                        goto case 'D';
                    case 'D':        /* ditto */
                        while (len-- > 0)
                        {
                            double d;

                            from = Pack.NEXTFROM(caller, ary, ref idx, ref items);
                            d = ((Float)Float.rb_Float(from, caller)).value;
                            Pack.rb_str_buf_cat(res, System.BitConverter.GetBytes(d), 8);
                        }
                        break;
                    case 'g':       /* single precision float in network byte-order */
                        while (len-- > 0)
                        {
                            float f;
                            byte[] ftmp;

                            from = Pack.NEXTFROM(caller, ary, ref idx, ref items);
                            f = (float)((Float)Float.rb_Float(from, caller)).value;
                            ftmp = System.BitConverter.GetBytes(f);

                            if (!Pack.isBigEndian())
                            {
                                Pack.swap(ftmp);
                            }
                            Pack.rb_str_buf_cat(res, ftmp, 4);
                        }
                        break;

                    case 'G':        /* double precision float in network byte-order */

                        while (len-- > 0)
                        {
                            double d;
                            byte[] dtmp;

                            from = Pack.NEXTFROM(caller, ary, ref idx, ref items);
                            d = ((Float)Float.rb_Float(from, caller)).value;
                            dtmp = System.BitConverter.GetBytes(d);
                            if (!Pack.isBigEndian())
                            {
                                Pack.swap(dtmp);
                            }
                            Pack.rb_str_buf_cat(res, dtmp, 8);

                        }
                        break;
                    case 'x':        /* null byte */
                        //grow:
                        res.Append('\0', len);
                        break;
                    case 'X':        /* back up byte */
                        //shrink:
                        plen = res.Length;
                        if (plen < len)
                        {
                            throw new ArgumentError("X outside of string").raise(caller);
                        }
                        res.Length = plen - len;
                        break;
                    case '@':        /* null fill to absolute position */
                        len -= res.Length;
                        if (len > 0) res.Append('\0', len); //goto grow:
                        len = -len;
                        if (len > 0) goto case 'X';
                        break;
                    case '%':
                        throw new ArgumentError("% is not supported").raise(caller); //FIX when merge.
                    case 'U':        /* Unicode character */
                        while (len-- > 0)
                        {
                            int l;
                            char[] buf = new char[8];
                            int le;

                            from = Pack.NEXTFROM(caller, ary, ref idx, ref items);
                            from = Integer.rb_to_int(from, caller);
                            l = Numeric.rb_num2long(from, caller);
                            if (l < 0)
                            {
                                throw new RangeError("pack(U): value out of range").raise(caller);
                            }
                            le = Pack.uv_to_utf8(caller, buf, (uint)l);
                            Pack.rb_str_buf_cat(res, buf, le);
                        }
                        break;
                    case 'u':        /* uuencoded string */
                        goto case 'm';
                    case 'm':        /* base64 encoded string */
                        string frmString;
                        from = Pack.NEXTFROM(caller, ary, ref idx, ref items);
                        frmString = String.StringValue(from, caller);
                        ptr = 0;
                        plen = frmString.Length;

                        if (len <= 2)
                        {
                            len = 45;
                        }
                        else
                        {
                            len = len / 3 * 3;
                        }

                        while (plen > 0)
                        {
                            int todo;


                            if (plen > len)
                            {
                                todo = len;
                            }
                            else
                            {
                                todo = plen;
                            }
                            Pack.encodes(res, frmString.Substring(ptr), todo, type);
                            plen -= todo;
                            ptr += todo;
                        }
                        break;
                    case 'M': /* quoted-printable encoded string */
                        from = String.ObjectAsString(Pack.NEXTFROM(caller, ary, ref idx, ref items), caller);
                        if (len <= 1)
                        {
                            len = 72;
                        }
                        Pack.qpencodes(res, from, len);
                        break;
                    case 'P':        /* pointer to packed byte string */
                        throw new NotImplementedError("The pack(\"P\") method is not implemented on this platform").raise(caller);
                    case 'p':        /* pointer to string */
                        throw new NotImplementedError("The pack(\"p\") method is not implemented on this platform").raise(caller);
                    case 'w':        /* BER compressed integer  */
                        while (len-- > 0)
                        {
                            uint ul;
                            System.Text.StringBuilder buf = new System.Text.StringBuilder();
                            char c;
                            int bufs, bufe;
                            //char c, *bufs, *bufe;

                            from = Pack.NEXTFROM(caller, ary, ref idx, ref items);
                            if (from is Bignum)
                            {
                                object big128 = new Bignum(128);
                                while (from is Bignum)
                                {
                                    from = Ruby.Methods.rb_big_divmod.singleton.Call1(last_class, from, caller, null, big128);
                                    c = (char)(Numeric.rb_num2long(((Array)from).value[1], caller) | 0x80);
                                    Pack.rb_str_buf_cat(buf, new char[] { c }, 1);
                                    from = ((Array)from).value[0];
                                }
                            }

                            {
                                int l = Numeric.rb_num2long(from, caller);
                                if (l < 0)
                                {
                                    throw new ArgumentError("cannot compress negative numbers").raise(caller);
                                }
                                ul = (uint)l;
                            }

                            while (ul > 0)
                            {
                                c = (char)((ul & 0x7f) | 0x80);
                                Pack.rb_str_buf_cat(buf, new char[] { c }, 1);
                                ul >>= 7;
                            }

                            if (buf.Length > 0)
                            {
                                bufs = 0;
                                bufe = buf.Length - 1;
                                buf[bufs] = (char)(buf[bufs] & 0x7f); /* clear continue bit */
                                while (bufs < bufe) /* reverse */
                                {
                                    c = buf[bufs];
                                    buf[bufs++] = buf[bufe];
                                    buf[bufe--] = c;
                                }
                                Pack.rb_str_buf_cat(res, buf.ToString().ToCharArray(), buf.Length);
                            }
                            else
                            {
                                c = (char)0;
                                Pack.rb_str_buf_cat(res, new char[] { c }, 1);
                            }
                        }
                        break;

                    default:
                        break;
                }
            }

            return new String(res.ToString());
        }
Пример #2
0
        public override object Call1(Class last_class, object str, Frame caller, Proc block, object fmt)
        {
            string hexdigits = "0123456789abcdef0123456789ABCDEFx";
            string fmtString, strString;
            int s, send; //str
            int p, pend; //fmt
            object ary;
            char type;
            int len;
            bool star = false;
            int tmp;

            fmtString = String.StringValue(fmt, caller);
            strString = String.StringValue(str, caller);
            s = 0;
            send = strString.Length;
            p = 0;
            pend = fmtString.Length;

            ary = new Array();
            while (p < pend)
            {
                type = fmtString[p++];

                if (char.IsWhiteSpace(type)) continue;
                if (type == '#') //eat comments
                {
                    while ((p < pend) && (fmtString[p] != '\n'))
                    {
                        p++;
                    }
                    continue;
                }
                if (p < pend && (fmtString[p] == '_' || fmtString[p] == '!')) //'_' and '!' can only come after "sSiIlL"
                {
                    const string natstr = "sSiIlL";

                    if (natstr.IndexOf(type) != -1)
                    {
                        p++;
                    }
                    else
                    {
                        throw new ArgumentError(string.Format(CultureInfo.InvariantCulture, "'{0}' allowed only after types {1}", fmtString[p], natstr)).raise(caller);
                    }
                }
                if (p >= pend)
                {
                    len = 1;
                }
                else if (fmtString[p] == '*')
                {
                    star = true;
                    len = send - s;
                    p++;
                }
                else if (p < pend && char.IsDigit(fmtString[p]))
                {
                    int numStart = p;
                    int numEnd = p + 1;
                    while (numEnd < pend)
                    {
                        if (char.IsDigit(fmtString[numEnd]))
                        {
                            numEnd++;
                        }
                        else
                        {
                            break;
                        }
                    }
                    len = int.Parse(fmtString.Substring(numStart, numEnd - numStart), CultureInfo.InvariantCulture);
                }
                else
                {
                    len = (type != '@') ? 1 : 0;
                }
                int t;
                switch (type)
                {
                    case '%':
                        throw new ArgumentError("% is not supported").raise(caller);
                    case 'A':
                        if (len > send - s)
                        {
                            len = send - s;
                        }
                        int end = len;
                        t = s + len - 1;
                        while (t >= s)
                        {
                            if (strString[t] != ' ' && strString[t] != '\0') break;
                            t--; len--;
                        }
                        ((Array)ary).value.Add(String.infected_str_new(s, len, strString));
                        s += end;
                        break;
                    case 'Z':
                        {
                            t = s;

                            if (len > send - s) len = send - s;
                            while (t < s + len && t <= send && strString[t] != '\0') t++;
                            ((Array)ary).value.Add(String.infected_str_new(s, t - s, strString));
                            if (t < send) t++;
                            s = star ? t : s + len;
                        }
                        break;
                    case 'a':
                        if (len > send - s) len = send - s;
                        ((Array)ary).value.Add(String.infected_str_new(s, len, strString));
                        s += len;
                        break;
                    case 'b':
                        {
                            System.Text.StringBuilder bitStrBuilder = new System.Text.StringBuilder();
                            object bitstr;
                            int bits;
                            int i;

                            if ((p > 0 && fmtString[p - 1] == '*') || len > (send - s) * 8)
                            {
                                len = (send - s) * 8;
                            }
                            bits = 0;
                            for (i = 0; i < len; i++)
                            {
                                if ((i & 7) > 0)
                                {
                                    bits >>= 1;
                                }
                                else
                                {
                                    bits = (byte)strString[s++];
                                }
                                bitStrBuilder.Append(((bits & 1) > 0) ? '1' : '0');
                            }
                            bitstr = new String(bitStrBuilder.ToString());
                            ((Array)ary).value.Add(bitstr);
                        }
                        break;
                    case 'B':
                        {
                            System.Text.StringBuilder bitStrBuilder = new System.Text.StringBuilder();
                            object bitstr;
                            int bits;
                            int i;

                            if ((p > 0 && fmtString[p - 1] == '*') || len > (send - s) * 8)
                            {
                                len = (send - s) * 8;
                            }
                            bits = 0;
                            for (i = 0; i < len; i++)
                            {
                                if ((i & 7) > 0)
                                {
                                    bits <<= 1;
                                }
                                else
                                {
                                    bits = strString[s++];
                                }
                                bitStrBuilder.Append(((bits & 128) > 0) ? '1' : '0');
                            }
                            bitstr = new String(bitStrBuilder.ToString());
                            ((Array)ary).value.Add(bitstr);
                        }
                        break;
                    case 'h':
                        {
                            System.Text.StringBuilder bitStrBuilder = new System.Text.StringBuilder();
                            object bitstr;
                            int bits;
                            int i;

                            if ((p > 0 && fmtString[p - 1] == '*') || len > (send - s) * 8)
                            {
                                len = (send - s) * 2;
                            }
                            bits = 0;

                            for (i = 0; i < len; i++)
                            {
                                if ((i & 1) > 0)
                                {
                                    bits >>= 4;
                                }
                                else
                                {
                                    bits = strString[s++];
                                }
                                bitStrBuilder.Append(hexdigits[bits & 15]);
                            }
                            bitstr = new String(bitStrBuilder.ToString());
                            ((Array)ary).value.Add(bitstr);
                        }
                        break;
                    case 'H':
                        {
                            System.Text.StringBuilder bitStrBuilder = new System.Text.StringBuilder();
                            object bitstr;
                            int bits;
                            int i;

                            if ((p > 0 && fmtString[p - 1] == '*') || len > (send - s) * 8)
                            {
                                len = (send - s) * 2;
                            }
                            bits = 0;
                            for (i = 0; i < len; i++)
                            {
                                if ((i & 1) > 0)
                                {
                                    bits <<= 4;
                                }
                                else
                                {
                                    bits = strString[s++];
                                }
                                bitStrBuilder.Append(hexdigits[(bits >> 4) & 15]);
                            }
                            bitstr = new String(bitStrBuilder.ToString());
                            ((Array)ary).value.Add(bitstr);
                        }
                        break;
                    case 'c':
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 1);
                        while (len-- > 0)
                        {
                            int c = (byte)strString[s++];
                            if (c > 127) c -= 256; //integer is signed
                            ((Array)ary).value.Add(c);
                        }
                        tmp = Pack.PACK_ITEM_ADJUST(ary, tmp);
                        break;
                    case 'C':
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 1);
                        while (len-- > 0)
                        {
                            int c = (byte)strString[s++];
                            ((Array)ary).value.Add(c);
                        }
                        tmp = Pack.PACK_ITEM_ADJUST(ary, tmp);
                        break;
                    case 's':
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 2);
                        while (len-- > 0)
                        {
                            short sTmp;
                            sTmp = System.BitConverter.ToInt16(new byte[] { (byte)strString[s], (byte)strString[s + 1] }, 0);
                            s += 2;
                            ((Array)ary).value.Add((int)sTmp);
                        }
                        tmp = Pack.PACK_ITEM_ADJUST(ary, tmp);
                        break;
                    case 'S':
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 2);
                        while (len-- > 0)
                        {
                            ushort sTmp;
                            sTmp = System.BitConverter.ToUInt16(new byte[] { (byte)strString[s], (byte)strString[s + 1] }, 0);
                            s += 2;
                            ((Array)ary).value.Add((int)sTmp);
                        }
                        tmp = Pack.PACK_ITEM_ADJUST(ary, tmp);
                        break;
                    case 'i':
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 4);
                        while (len-- > 0)
                        {
                            int sTmp;
                            sTmp = System.BitConverter.ToInt32(new byte[] { (byte)strString[s], (byte)strString[s + 1], 
                                (byte)strString[s + 2], (byte)strString[s + 3]}, 0);
                            s += 4;
                            ((Array)ary).value.Add(sTmp);
                        }
                        tmp = Pack.PACK_ITEM_ADJUST(ary, tmp);
                        break;
                    case 'I':
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 4);
                        while (len-- > 0)
                        {
                            uint sTmp;
                            sTmp = System.BitConverter.ToUInt32(new byte[] { (byte)strString[s], (byte)strString[s + 1], 
                                (byte)strString[s + 2], (byte)strString[s + 3]}, 0);
                            s += 4;
                            ((Array)ary).value.Add(Bignum.rb_uint2inum(sTmp, caller));
                        }
                        tmp = Pack.PACK_ITEM_ADJUST(ary, tmp);
                        break;
                    case 'l':
                        goto case 'i';
                    case 'L':
                        goto case 'I';
                    case 'q': //signed quadword 
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 8);
                        while (len-- > 0)
                        {
                            long qTmp = System.BitConverter.ToInt64(new byte[]{(byte)strString[s],
                                (byte)strString[s + 1], (byte)strString[s + 2], (byte)strString[s + 3], (byte)strString[s + 4],
                                (byte)strString[s + 5], (byte)strString[s + 6], (byte)strString[s + 7]}, 0);
                            s += 8;
                            ((Array)ary).value.Add(Pack.i64_2_num(qTmp, caller));
                        }
                        tmp = Pack.PACK_ITEM_ADJUST(ary, tmp);
                        break;
                    case 'Q': //unsigned quadword 
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 8);
                        while (len-- > 0)
                        {
                            ulong QTmp = System.BitConverter.ToUInt64(new byte[]{(byte)strString[s],
                                (byte)strString[s + 1], (byte)strString[s + 2], (byte)strString[s + 3], (byte)strString[s + 4],
                                (byte)strString[s + 5], (byte)strString[s + 6], (byte)strString[s + 7]}, 0);
                            s += 8;
                            ((Array)ary).value.Add(Pack.ui64_2_num(QTmp, caller));
                        }
                        break;
                    case 'n':
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 2);
                        while (len-- > 0)
                        {
                            ushort nTmp = 0;
                            byte[] nTmpArray = new byte[] { (byte)strString[s], (byte)strString[s + 1] };
                            if (!Pack.isBigEndian())
                            {
                                Pack.swap(nTmpArray);
                            }
                            nTmp = System.BitConverter.ToUInt16(nTmpArray, 0);
                            s += 2;
                            ((Array)ary).value.Add((int)nTmp);
                        }
                        tmp = Pack.PACK_ITEM_ADJUST(ary, (int)tmp);
                        break;
                    case 'N':
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 4);
                        while (len-- > 0)
                        {
                            uint NTmp = 0;
                            byte[] NTmpArray = new byte[] { (byte)strString[s], (byte)strString[s + 1],
                                (byte)strString[2], (byte)strString[3]};
                            if (!Pack.isBigEndian())
                            {
                                Pack.swap(NTmpArray);
                            }
                            NTmp = System.BitConverter.ToUInt32(NTmpArray, 0);
                            s += 4;
                            ((Array)ary).value.Add(Bignum.rb_uint2inum(NTmp, caller));
                        }
                        tmp = Pack.PACK_ITEM_ADJUST(ary, (int)tmp);
                        break;
                    case 'v':
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 2);
                        while (len-- > 0)
                        {
                            ushort vTmp = 0;
                            byte[] vTmpArray = new byte[] { (byte)strString[s], (byte)strString[s + 1] };
                            if (Pack.isBigEndian())
                            {
                                Pack.swap(vTmpArray);
                            }
                            vTmp = System.BitConverter.ToUInt16(vTmpArray, 0);
                            s += 2;
                            ((Array)ary).value.Add((int)vTmp);
                        }
                        tmp = Pack.PACK_ITEM_ADJUST(ary, (int)tmp);
                        break;
                    case 'V':
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 4);
                        while (len-- > 0)
                        {
                            uint VTmp = 0;
                            byte[] VTmpArray = new byte[] { (byte)strString[s], (byte)strString[s + 1], 
                                (byte)strString[s + 2], (byte)strString[s + 3]};
                            if (Pack.isBigEndian())
                            {
                                Pack.swap(VTmpArray);
                            }

                            VTmp = System.BitConverter.ToUInt32(VTmpArray, 0);
                            s += 4;
                            ((Array)ary).value.Add(Bignum.rb_uint2inum(VTmp, caller));
                        }
                        tmp = Pack.PACK_ITEM_ADJUST(ary, (int)tmp);
                        break;
                    case 'f':
                        goto case 'F';
                    case 'F':
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 4);
                        while (len-- > 0)
                        {
                            float FTmp;
                            FTmp = System.BitConverter.ToSingle(new byte[] { (byte)strString[s], (byte)strString[s + 1], 
                                (byte)strString[s + 2], (byte)strString[s + 3] }, 0);
                            s += 4;
                            ((Array)ary).value.Add(new Float(FTmp)); 
                        }
                        tmp = Pack.PACK_ITEM_ADJUST(ary, (int)tmp);
                        break;
                    case 'e':
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 4);
                        while (len-- > 0)
                        {
                            float eTmp;
                            byte[] eTmpArray = new byte[]{ (byte)strString[s], (byte)strString[s + 1],
                                (byte)strString[s + 2], (byte)strString[s + 3]};
                            if (Pack.isBigEndian())
                            {
                                Pack.swap(eTmpArray);
                            }
                            s += 4;
                            eTmp = System.BitConverter.ToSingle(eTmpArray, 0);
                            ((Array)ary).value.Add(new Float(eTmp));
                        }
                        tmp = Pack.PACK_ITEM_ADJUST(ary, (int)tmp);
                        break;
                    case 'E':
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 8);
                        while (len-- > 0)
                        {
                            double ETmp;
                            byte[] ETmpArray = new byte[]{(byte)strString[s],
                                (byte)strString[s + 1], (byte)strString[s + 2], (byte)strString[s + 3], (byte)strString[s + 4],
                                (byte)strString[s + 5], (byte)strString[s + 6], (byte)strString[s + 7]};
                            if (Pack.isBigEndian())
                            {
                                Pack.swap(ETmpArray);
                            }
                            s += 8;
                            ETmp = System.BitConverter.ToDouble(ETmpArray, 0);
                            ((Array)ary).value.Add(new Float(ETmp));
                        }
                        tmp = Pack.PACK_ITEM_ADJUST(ary, (int)tmp);
                        break;
                    case 'D':
                        goto case 'd';
                    case 'd':
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 8);
                        while (len-- > 0)
                        {
                            double dTmp;
                            byte[] dTmpArray = new byte[]{(byte)strString[s],
                                (byte)strString[s + 1], (byte)strString[s + 2], (byte)strString[s + 3], (byte)strString[s + 4],
                                (byte)strString[s + 5], (byte)strString[s + 6], (byte)strString[s + 7]};
                            s += 8;
                            dTmp = System.BitConverter.ToDouble(dTmpArray, 0);
                            ((Array)ary).value.Add(new Float(dTmp));
                        }
                        tmp = Pack.PACK_ITEM_ADJUST(ary, (int)tmp);
                        break;
                    case 'g':
                        tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 4);
                        while (len-- > 0)
                        {
                            float gTmp;
                            byte[] gTmpArray = new byte[]{ (byte)strString[s], (byte)strString[s + 1],
                                (byte)strString[s + 2], (byte)strString[s + 3]};
                            if (!Pack.isBigEndian())
                            {
                                Pack.swap(gTmpArray);
                            }
                            s += 4;
                            gTmp = System.BitConverter.ToSingle(gTmpArray, 0);
                            ((Array)ary).value.Add(new Float(gTmp));
                        }
                        tmp = Pack.PACK_ITEM_ADJUST(ary, (int)tmp);
                        break;
                    case 'G':
                        {
                            tmp = Pack.PACK_LENGTH_ADJUST(s, send, ref len, star, 8);
                            while (len-- > 0)
                            {
                                double GTmp;
                                byte[] GTmpArray = new byte[]{(byte)strString[s],
                                (byte)strString[s + 1], (byte)strString[s + 2], (byte)strString[s + 3], (byte)strString[s + 4],
                                (byte)strString[s + 5], (byte)strString[s + 6], (byte)strString[s + 7]};
                                if (!Pack.isBigEndian())
                                {
                                    Pack.swap(GTmpArray);
                                }
                                s += 8;
                                GTmp = System.BitConverter.ToDouble(GTmpArray, 0);
                                ((Array)ary).value.Add(new Float(GTmp));
                            }
                            tmp = Pack.PACK_ITEM_ADJUST(ary, (int)tmp);
                            break;
                        }
                    case 'U': 
                        if (len > send - s) len = send - s;
                        while (len > 0 && s < send)
                        {
                            int alen = send - s;
                            uint l;

                            l = (uint)Pack.utf8_to_uv(caller, strString,  s, ref alen);
                            s += alen; len--;
                            ((Array)ary).value.Add(Bignum.rb_uint2inum(l, caller));                           
                        }
                        break;
                    case 'u':
                        {


                            object buf = String.infected_str_new(0, (send - s) * 3/4, strString);
                            string ptrString = ((String)buf).value;
                            System.Text.StringBuilder ptrStringBuilder = new System.Text.StringBuilder(ptrString);
                            int ptr = 0;
                            int total = 0;

                            while (s < send && strString[s] > ' ' && strString[s] < 'a')
                            {

                                int a, b, c, d;
                                char[] hunk = new char[4];
                                
                                hunk[3] = '\0';

                                len = (strString[s++] - ' ') & 0x3f;
                                total += len;
                                if (total > ((String)buf).value.Length)
                                {
                                    len -= total - ((String)buf).value.Length;
                                    total = ((String)buf).value.Length;
                                }
                                while (len > 0)
                                {
                                    int mlen = len > 3 ? 3 : len;

                                    if (s < send && strString[s] >= ' ')
                                        a = (strString[s++] - ' ') & 0x3f;
                                    else
                                        a = 0;
                                    if (s < send && strString[s] >= ' ')
                                        b = (strString[s++] - ' ') & 0x3f;
                                    else
                                        b = 0;
                                    if (s < send && strString[s] >= ' ')
                                        c = (strString[s++] - ' ') & 0x3f;
                                    else
                                        c = 0;
                                    if (s < send && strString[s] >= ' ')
                                        d = (strString[s++] - ' ') & 0x3f;
                                    else
                                        d = 0;
                                    hunk[0] = (char)(byte)(a << 2 | b >> 4);
                                    hunk[1] = (char)(byte)(b << 4 | c >> 2);
                                    hunk[2] = (char)(byte)(c << 6 | d);
                                    for(int j = 0; j < mlen; j++){
                                        ptrStringBuilder[ptr + j] = hunk[j];
                                    }
                                    ptr += mlen;
                                    len -= mlen;                                    
                                }
                                if (s < send && strString[s] == '\r') s++;
                                if (s < send && strString[s] == '\n') s++;
                                else if(s < send && (s + 1 == send || strString[s + 1] == '\n')){
                                    s += 2; /* possible checksum byte */
                                }
                            }

                            ptrStringBuilder.Length = total;
                            ((String)buf).value = ptrStringBuilder.ToString();
                            ((Array)ary).value.Add(buf);
                        }
                        break;
                    case 'm':
                        {
                            object buf = String.infected_str_new(0, (send - s) * 3 / 4, strString);
                            System.Text.StringBuilder ptrString = new System.Text.StringBuilder(((String)buf).value);
                            int ptr = 0;
                            int a = -1, b = -1, c = 0, d = 0;

                            if (first > 0)
                            {
                                int i;
                                first = 0;

                                for (i = 0; i < 256; i++)
                                {
                                    b64_xtable[i] = -1;
                                }
                                for (i = 0; i < 64; i++)
                                {
                                    b64_xtable[(int)Pack.b64_table[i]] = i;
                                }
                            }
                            while (s < send)
                            {
                                while (strString[s] == '\r' || strString[s] == '\n') { s++; }
                                if ((a = b64_xtable[(int)strString[s]]) == -1) break;
                                if (!(s+1 < send) || (b = b64_xtable[(int)strString[s + 1]]) == -1) break;
                                if (!(s+2 < send) || (c = b64_xtable[(int)strString[s + 2]]) == -1) break;
                                if (!(s+3 < send) || (d = b64_xtable[(int)strString[s + 3]]) == -1) break;
                                ptrString[ptr++] = (char)(byte)(a << 2 | b >> 4);
                                ptrString[ptr++] = (char)(byte)(b << 4 | c >> 2);
                                ptrString[ptr++] = (char)(byte)(c << 6 | d);
                                s += 4;
                            }
                            if (a != -1 && b != -1)
                            {
                                if (s + 2 < send && strString[ptr++] == '=')
                                    ptrString[ptr++] = (char)(byte)(a << 2 | b >> 4);
                                if (c != -1 && s + 3 < send && strString[s + 3] == '=')
                                {
                                    ptrString[ptr++] = (char)(byte)(a << 2 | b >> 4);
                                    ptrString[ptr++] = (char)(byte)(b << 4 | c >> 2);
                                }
                            }
                            ptrString.Length = ptr;
                            ((String)buf).value = ptrString.ToString();
                            ((Array)ary).value.Add(buf);
                        }
                        break;
                    case 'M':
                        {
                            object buf = String.infected_str_new(0, send - s, strString);
                            System.Text.StringBuilder ptrString = new System.Text.StringBuilder(((String)buf).value);
                            int ptr = 0;
                            int c1, c2;

                            while(s < send){
                                if (strString[s] == '=')
                                {
                                    if (++s == send) break;
                                    if (strString[s] != '\n')
                                    {
                                        if ((c1 = Pack.hex2num(strString[s])) == -1) break;
                                        if (++s == send) break;
                                        if ((c2 = Pack.hex2num(strString[s])) == -1) break;
                                        ptrString[ptr++] = (char)(byte)(c1 << 4 | c2);
                                    }
                                }
                                else
                                {
                                    ptrString[ptr++] = strString[s];
                                }
                                s++;
                            }
                            ptrString.Length = ptr;
                            ((String)buf).value = ptrString.ToString();
                            ((Array)ary).value.Add(buf);
                        }
                        break;
                    case 'X':
                        if (len > s)
                            throw new ArgumentError("X outside of string").raise(caller);
                        s -= len;
                        break;
                    case 'x':
                        if (len > send - s)
                            throw new ArgumentError("X outside of string").raise(caller);
                        s += len;
                        break;
                    case 'P':        /* pointer to packed byte string */
                        throw new NotImplementedError("The pack(\"P\") method is not implemented on this platform").raise(caller);
                    case 'p':        /* pointer to string */
                        throw new NotImplementedError("The pack(\"p\") method is not implemented on this platform").raise(caller);
                    case 'w':
                        {
                            uint ul = 0;
                            uint ulmask = ((uint)0xfe) << 4 - 1 * 8;

                            while (len > 0 && s < send)
                            {
                                ul <<= 7;
                                ul |= (byte)(strString[s] & 0x7f);

                                if (!((strString[s++] & 0x80) > 0))
                                {
                                    ((Array)ary).value.Add(Bignum.rb_uint2inum(ul, caller));
                                    len--;
                                    ul = 0;
                                }
                                else if ((ul & ulmask) > 0) {
                                    object big = new Bignum(ul);
                                    object big128 = new Bignum(128);
                                    while (s < send)
                                    {
                                        big = Ruby.Methods.rb_big_mul.singleton.Call1(last_class, big, caller, null, big128);
                                        big = Ruby.Methods.rb_big_plus.singleton.Call1(last_class, big, caller, null, Bignum.rb_uint2inum((byte)(strString[s] & 0x7f), caller));
                                    }
                                    if (!((strString[s++] & 0x80) > 0))
                                    {
                                        ((Array)ary).value.Add(big);
                                        len--;
                                        ul = 0;
                                        break;
                                    }
                                }
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
            return ary;
        }
Пример #3
0
        private Bignum rb_big_rand(Bignum max, double rand)
        {
            Bignum b = new Bignum(max.value * rand);

            return new Bignum(b.value % max.value);
        }
Пример #4
0
        public override object Call(Class last_class, object recv, Frame caller, Proc block, Array args)
        {
            object fmt;
            string fmtString;
            int p, end;
            System.Text.StringBuilder result = new System.Text.StringBuilder();

            int width, prec, flags = Sprintf.FNONE;
            int nextArg = 1;
            int posArg = 0;
            //int tainted = 0;
            object nextValue;
            object tmp = null;
            object str;

            fmt = args[0];
            //if (OBJ_TAINTED(fmt)) tainted = 1;
            fmtString = String.StringValue(fmt, caller);
            //    fmt = rb_str_new4(fmt); - tainted work being done in this method
            p = 0; //p = RSTRING(fmt)->ptr;
            end = fmtString.Length;

            for (; p < end; p++)
            {
                int t;
                int n;

                for (t = p; t < end && fmtString[t] != '%'; t++) ; //skip over preceding chars
                result.Append(fmtString.Substring(p, t - p));
                if (t >= end)
                {
                    /* end of fmt string */
                    goto sprint_exit;
                }
                p = t + 1;  /* skip '%' */

                width = prec = -1;
                nextValue = null;

            retry:
                switch (fmtString[p])
                {
                    case ' ':
                        flags |= Sprintf.FSPACE; //leave a space at the start of positive numbers.
                        p++;
                        goto retry;

                    case '#':
                        flags |= Sprintf.FSHARP;
                        p++;
                        goto retry;

                    case '+':
                        flags |= Sprintf.FPLUS;
                        p++;
                        goto retry;

                    case '-':
                        flags |= Sprintf.FMINUS;
                        p++;
                        goto retry;

                    case '0':
                        flags |= Sprintf.FZERO;
                        p++;
                        goto retry;

                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                    case '8':
                    case '9':
                        n = 0;
                        for (; p < end && char.IsDigit(fmtString[p]); p++)
                        {
                            n = 10 * n + (fmtString[p] - '0');
                        }
                        if (p >= end)
                        {
                            throw new ArgumentError("malformed format string - %[0-9]").raise(caller);
                        }
                        if (fmtString[p] == '$')
                        {
                            if (nextValue != null)
                            {
                                throw new ArgumentError(string.Format(CultureInfo.InvariantCulture, "value given twice - {0}$", n)).raise(caller);
                            }
                            nextValue = Sprintf.GETPOSARG(caller, n, ref posArg, args);
                            p++;
                            goto retry;
                        }
                        width = n;
                        flags |= Sprintf.FWIDTH;
                        goto retry;

                    case '*':
                        if ((flags & Sprintf.FWIDTH) > 0)
                        {
                            throw new ArgumentError("width given twice").raise(caller);
                        }
                        flags |= Sprintf.FWIDTH;
                        width = Sprintf.GETASTER(ref t, ref p, out n, end, fmtString,
                            ref posArg, ref nextArg, nextValue, tmp, args, caller);
                        if (width < 0)
                        {
                            flags |= Sprintf.FMINUS;
                            width = -width;
                        }
                        p++;
                        goto retry;

                    case '.':
                        if ((flags & Sprintf.FPREC) > 0)
                        {
                            throw new ArgumentError("precision given twice").raise(caller);
                        }
                        flags |= Sprintf.FPREC;

                        prec = 0;
                        p++;
                        if (fmtString[p] == '*')
                        {
                            prec = Sprintf.GETASTER(ref t, ref p, out n, end, fmtString,
                            ref posArg, ref nextArg, nextValue, tmp, args, caller);
                            if (prec < 0) /* ignore negative precision */
                            {
                                flags &= ~Sprintf.FPREC;
                            }
                            p++;
                            goto retry;
                        }
                        for (; p < end && char.IsDigit(fmtString[p]); p++)
                        {
                            prec = 10 * prec + (fmtString[p] - '0');
                        }
                        if (p >= end)
                        {
                            throw new ArgumentError("malformed format string - %%.[0-9]").raise(caller);
                        }
                        goto retry;
                    case '\n':
                        p--;
                        goto case '%';
                    case '\0':
                        goto case '%';
                    case '%':
                        if (flags != Sprintf.FNONE)
                        {
                            throw new ArgumentError("illegal format character - %").raise(caller);
                        }
                        result.Append("%");
                        break;
                    case 'c':
                        {
                            object val = Sprintf.GETARG(caller, ref posArg, ref nextArg, nextValue, args);
                            int c;
                            if (!((flags & Sprintf.FMINUS) > 0))
                            {
                                while (--width > 0)
                                {
                                    result.Append(" ");
                                }
                            }
                            c = Numeric.rb_num2long(val, caller) & 0xff;
                            result.Append((char)(byte)c);
                            while (--width > 0)
                            {
                                result.Append(" ");
                            }
                        }
                        break;
                    case 's':
                        goto case 'p';
                    case 'p':
                        {
                            object arg = Sprintf.GETARG(caller, ref posArg, ref nextArg, nextValue, args);
                            int len;

                            if (fmtString[p] == 'p') arg = Object.Inspect(arg, caller);
                            str = String.ObjectAsString(arg, caller);
                            //if (OBJ_TAINTED(str)) tainted = 1;
                            len = ((String)str).value.Length;
                            if ((flags & Sprintf.FPREC) > 0)
                            {
                                if (prec < len)
                                {
                                    len = prec;
                                }
                            }
                            if ((flags & Sprintf.FWIDTH) > 0)
                            {
                                if (width > len)
                                {
                                    width -= len;
                                    if (!((flags & Sprintf.FMINUS) > 0))
                                    {
                                        while (width-- > 0)
                                        {
                                            result.Append(' ');
                                        }
                                    }
                                    result.Append(((String)str).value.Substring(0, len));
                                    if ((flags & Sprintf.FMINUS) > 0)
                                    {
                                        while (width-- > 0)
                                        {
                                            result.Append(' ');
                                        }
                                    }
                                    break;
                                }
                            }
                            result.Append(((String)str).value.Substring(0, len));
                        }
                        break;

                    case 'd':
                    case 'i':
                    case 'o':
                    case 'x':
                    case 'X':
                    case 'b':
                    case 'B':
                    case 'u':
                        {
                            object val = Sprintf.GETARG(caller, ref posArg, ref nextArg, nextValue, args);
                            string prefix = "";
                            int sign = 0;
                            int v = 0;
                            int bignum = 0;
                            int numBase = 0;
                            char sc = '\0';
                            string fbuf = "";
                            string nbuf = "";
                            int s = 0;
                            string sString = "";
                            int tt = 0;
                            string ttString = "";
                            object tmp2;
                            //int pos;
                            int len;

                            switch (fmtString[p])
                            {
                                case 'd':
                                    goto case 'i';
                                case 'i':
                                    sign = 1; break;
                                case 'o':
                                case 'x':
                                case 'X':
                                case 'b':
                                case 'B':
                                case 'u':
                                default:
                                    if ((flags & (Sprintf.FPLUS | Sprintf.FSPACE)) > 0) sign = 1;
                                    break;
                            }
                            if ((flags & Sprintf.FSHARP) > 0)
                            {
                                switch (fmtString[p])
                                {
                                    case 'o':
                                        prefix = "0"; break;
                                    case 'x':
                                        prefix = "0x"; break;
                                    case 'X':
                                        prefix = "0X"; break;
                                    case 'b':
                                        prefix = "0b"; break;
                                    case 'B':
                                        prefix = "0B"; break;
                                }
                                if (prefix.Length > 0)
                                {
                                    width -= prefix.Length;
                                }
                            }
                        bin_retry:
                            if (val is Float)
                            {
                                val = new Bignum(((Float)val).value);
                                if (val is int) goto bin_retry;
                                bignum = 1;
                            }
                            else if (val is String)
                            {
                                val = String.rb_str_to_inum(val, caller, 0, true); //TEST - should base be 0?
                                goto bin_retry;
                            }
                            else if (val is Bignum)
                            {
                                bignum = 1;
                            }
                            else if (val is int)
                            {
                                v = (int)val;
                            }
                            else
                            {
                                val = Integer.rb_Integer(val, caller);
                                goto bin_retry;
                            }
                            switch (fmtString[p])
                            {
                                case 'o':
                                    numBase = 8; break;
                                case 'x':
                                case 'X':
                                    numBase = 16; break;
                                case 'b':
                                case 'B':
                                    numBase = 2; break;
                                case 'u':
                                case 'd':
                                case 'i':
                                default:
                                    numBase = 10; break;
                            }
                            if (bignum == 0)
                            {
                                if (numBase == 2)
                                {
                                    val = new Bignum(v);
                                    goto bin_retry;
                                }
                                if (sign != 0)
                                {
                                    char c = fmtString[p];
                                    if (c == 'i') c = 'd'; /* %d and %i are identical */
                                    if (v < 0)
                                    {
                                        v = -v;
                                        sc = '-';
                                        width--;
                                    }
                                    else if ((flags & Sprintf.FPLUS) > 0)
                                    {
                                        sc = '+';
                                        width--;
                                    }
                                    else if ((flags & Sprintf.FSPACE) > 0)
                                    {
                                        sc = ' ';
                                        width--;
                                    }
                                    fbuf = Sprintf.sprintf("%%l%c", c);
                                    nbuf = Sprintf.sprintf(fbuf, v);
                                    s = 0;//s = nbuf;
                                    sString = nbuf;
                                    goto format_integer;
                                }
                                s = 0;//s = nbuf;
                                if (v < 0)
                                {
                                    if (numBase == 10)
                                    {
                                        Errors.rb_warning("negative number for %%u specifier");
                                    }
                                    if (!((flags & (Sprintf.FPREC | Sprintf.FZERO)) > 0))
                                    {
                                        nbuf = nbuf.Insert(s, "..");
                                        s += 2;
                                    }
                                }
                                fbuf = Sprintf.sprintf("%%l%c", fmtString[p] == 'X' ? 'x' : fmtString[p]);
                                nbuf = nbuf.Substring(0, s) + Sprintf.sprintf(fbuf, v);
                                if (v < 0)
                                {
                                    char d = '\0';
                                    Sprintf.remove_sign_bits(nbuf.Substring(s), numBase);
                                    switch (numBase)
                                    {
                                        case 16:
                                            d = 'f'; break;
                                        case 8:
                                            d = '7'; break;
                                    }
                                    if (d != '\0' && (nbuf[s] != d))
                                    {
                                        nbuf.Insert(s, d.ToString());
                                    }
                                }
                                s = 0;//s = nbuf;
                                sString = nbuf;
                                goto format_integer;
                            }
                            //bignums between here and format_integer
                            if (sign > 0)
                            {
                                tmp2 = ((Bignum)val).value.ToString((uint)numBase); //tmp2 = rb_big2str(val, numBase);
                                s = 0;
                                sString = (string)tmp2;
                                if (sString[s] == '-')
                                {
                                    s++;
                                    sc = '-';
                                    width--;
                                }
                                else if ((flags & Sprintf.FPLUS) > 0)
                                {
                                    sc = '+';
                                    width--;
                                }
                                else if ((flags & Sprintf.FSPACE) > 0)
                                {
                                    sc = ' ';
                                    width--;
                                }
                                goto format_integer;
                            }
                            //negative bignum from now on
                            if (((Bignum)val).value < (IronMath.integer.make(0)))
                            {
                                val = new Bignum(((Bignum)val).value);
                                //must be equivalent to rb_big_2comp(val); TEST
                                new Bignum(~((Bignum)val).value);
                            }
                            tmp2 = new String(((Bignum)val).value.ToString((uint)numBase)); //tmp2 = rb_big2str(val, numBase);
                            s = 0;//              s = RSTRING(tmp2)->ptr;
                            sString = ((String)tmp2).value;
                            if (sString[s] == '-')
                            {
                                if (numBase == 10)
                                {
                                    Errors.rb_warning("negative number for %%u specifier");
                                    s++;
                                }
                                else
                                {
                                    sString = Sprintf.remove_sign_bits(sString.Substring(++s), numBase);
                                    tmp2 = new String();
                                    tt = 0;
                                    ttString = ((String)tmp2).value;
                                    if (!((flags & (Sprintf.FPREC | Sprintf.FZERO)) > 0))
                                    {
                                        ttString.Insert(tt, "..");
                                        tt += 2;
                                    }
                                    switch (numBase)
                                    {
                                        case 16:
                                            if (sString[0] != 'f')
                                            {
                                                ttString += "f"; //strcpy(t++, "f");
                                                tt++;
                                            }
                                            break;
                                        case 8:
                                            if (sString[0] != 'f')
                                            {
                                                ttString += "7"; //strcpy(t++, "7");
                                                tt++;
                                            }
                                            break;
                                        case 2:
                                            if (sString[0] != 'f')
                                            {
                                                ttString += "1"; //strcpy(t++, "1");
                                                tt++;
                                            }
                                            break;
                                    }
                                    ttString += sString; //check //strcpy(t, s);
                                    bignum = 2;
                                }
                            }
                            s = 0;
                            sString = ((String)tmp2).value;
                        format_integer:
                            //pos = -1;
                            len = sString.Length;
                            if (fmtString[p] == 'X')
                            {
                                sString = sString.ToUpperInvariant();
                            }
                            if ((flags & (Sprintf.FZERO | Sprintf.FPREC)) == Sprintf.FZERO)
                            {
                                prec = width;
                                width = 0;
                            }
                            else
                            {
                                if (prec < len) prec = len;
                                width -= prec;
                            }

                            if (!((flags & Sprintf.FMINUS) > 0))
                            {
                                while (width-- > 0)
                                {
                                    result.Append(' ');
                                }
                            }
                            if (sc != '\0')
                            {
                                result.Append(sc);
                            }
                            if (prefix.Length > 0)
                            {
                                result.Append(prefix);
                            }
                            if (bignum == 0 && v < 0)
                            {
                                char c = Sprintf.sign_bits(numBase, fmtString[p]);
                                while (len < prec--)
                                {
                                    result.Append(c);
                                }
                            }
                            else
                            {
                                char c;

                                if ((bignum != 0) && ((Bignum)val).value < (IronMath.integer.make(0)))
                                {
                                    c = Sprintf.sign_bits(numBase, fmtString[p]);
                                }
                                else
                                {
                                    c = '0';
                                }
                                while (len < prec--)
                                {
                                    result.Append(c);
                                }
                            }
                            result.Append(sString.Substring(s, len));
                            while (width-- > 0)
                            {
                                result.Append(' ');
                            }
                        }
                        break;
                    case 'f':
                    case 'g':
                    case 'G':
                    case 'e':
                    case 'E':
                        {
                            object val = Sprintf.GETARG(caller, ref posArg, ref nextArg, nextValue, args);
                            double fval;
                            int i = 0;
                            int need = 6;
                            string fbuf;

                            fval = Float.rb_Float(val, caller).value;
                            if (double.IsNaN(fval) || double.IsInfinity(fval))
                            {
                                string expr;

                                if (double.IsNaN(fval))
                                {
                                    expr = "NaN";
                                }
                                else
                                {
                                    expr = "Inf";
                                }
                                need = expr.Length;
                                if ((!double.IsNaN(fval) && fval < 0.0) || ((flags & Sprintf.FPLUS) != 0))
                                {
                                    need++;
                                }
                                if (((flags & Sprintf.FWIDTH) != 0) && need < width)
                                {
                                    need = width;
                                }
                                //TODO - may need a blen count. 
                                //                  sprintf(&buf[blen], "%*s", need, "");
                                if ((flags & Sprintf.FMINUS) != 0)
                                {
                                    if (!double.IsNaN(fval) && fval < 0.0)
                                    {
                                        result.Append('-'); //buf[blen++] = '-';
                                    }
                                    else if ((flags & Sprintf.FPLUS) != 0)
                                    {
                                        result.Append('+'); //buf[blen++] = '+';
                                    }
                                    else if ((flags & Sprintf.FSPACE) != 0)
                                    {
                                        result.Append(' '); //blen++;
                                    }
                                    result.Append(expr); //strncpy(&buf[blen], expr, strlen(expr));
                                }
                                else if ((flags & Sprintf.FZERO) != 0)
                                {
                                    if (!double.IsNaN(fval) && fval < 0.0)
                                    {
                                        result.Append('-');//buf[blen++] = '-';
                                        need--;
                                    }
                                    else if ((flags & Sprintf.FPLUS) != 0)
                                    {
                                        result.Append('+');    //buf[blen++] = '+';
                                        need--;
                                    }
                                    else if ((flags & Sprintf.FSPACE) != 0)
                                    {
                                        result.Append(' '); //blen++;
                                        need--;
                                    }
                                    while (need-- - expr.Length > 0)
                                    {
                                        result.Append('0');
                                    }
                                    result.Append(expr); //strncpy(&buf[blen], expr, strlen(expr));                                    
                                }
                                else
                                {
                                    if (!double.IsNaN(fval) && fval < 0.0)
                                        //run this - may need a blen count. 
                                        //could buffer overflow - check this out
                                        result[need - expr.Length - 1] = '-';  //buf[blen + need - strlen(expr) - 1] = '-';
                                    else if ((flags & Sprintf.FPLUS) != 0)
                                        result[need - expr.Length - 1] = '-';  //buf[blen + need - strlen(expr) - 1] = '+';
                                    //TODO - may need a blen count
                                    //strncpy(&buf[blen + need - strlen(expr)], expr, strlen(expr));
                                }
                                //blen += strlen(&buf[blen]);
                                break;
                            }

                            fbuf = Sprintf.fmt_setup(fmtString[p], flags, width, prec);
                            need = 0;
                            if (fmtString[p] != 'e' && fmtString[p] != 'E')
                            {
                                i = int.MinValue;
                                object frexpResult = Ruby.Methods.math_frexp.singleton.Call1(last_class, null, caller, block, new Float(fval));
                                i = (int)((Array)frexpResult).value[1]; //get the exponent
                                if (i > 0)
                                {
                                    need = Sprintf.BIT_DIGITS(i);
                                }
                            }
                            need += ((flags & Sprintf.FPREC) > 0) ? prec : 6;
                            if (((flags & Sprintf.FWIDTH) != 0) && need < width)
                            {
                                need = width;
                            }

                            need += 20;
                            result.Append(Sprintf.sprintf(fbuf, fval));  //              sprintf(&buf[blen], fbuf, fval);  
                            //may need to include belen calcs?
                            //              blen += strlen(&buf[blen]); 
                        }
                        break;
                    default:
                        if (char.IsLetterOrDigit(fmtString[p]) || fmtString[p] == ' ')
                            throw new ArgumentError(string.Format(CultureInfo.InvariantCulture, "malformed format string - %{0}", fmtString)).raise(caller);
                        else
                            throw new ArgumentError("malformed format string").raise(caller);
                }
                flags = Sprintf.FNONE;
            }
            
        sprint_exit:
            //    /* XXX - We cannot validiate the number of arguments because
            //    *       the format string may contain `n$'-style argument selector.
            //    */

            if (Eval.Test(Options.ruby_verbose.value) && posArg >= 0 && nextArg < args.Count) {
                throw new ArgumentError("too many arguments for format string").raise(caller);
            }

            String res = new String(result.ToString());
            //TODO:
            //    if (tainted) OBJ_TAINT(result);
            return res;
        }
Пример #5
0
        public override object Call1(Class last_class, object recv, Frame caller, Proc block, object param0)
        {
            if (recv is int)
                recv = new Bignum((double)(int)recv);

            if (param0 is int)
            {
                return Bignum.NormaliseUsing(((Bignum)recv).value * (int)param0);
            }
            else if (param0 is Bignum)
            {
                return Bignum.NormaliseUsing(((Bignum)recv).value * ((Bignum)param0).value);
            }
            else if (param0 is Float)
            {
                return new Float((double)((Bignum)recv).value * ((Float)param0).value);
            }
            else
            {
                return Numeric.rb_num_coerce_bin(recv, param0, "*", caller);
            }
        }
Пример #6
0
        internal static object r_object0(Frame caller, load_arg arg, object proc, ref int ivp, object extmod)
        {
            object v = null;
            int type = r_byte(caller, arg);
            int id;

            switch (type)
            {
                case TYPE_LINK: //TEST:

                    id = r_long(caller, arg);
                    v = Ruby.Methods.rb_hash_aref.singleton.Call1(null, arg.data, caller, null, id);
                    if (v == null)
                    {
                        throw new ArgumentError("dump format error (unlinked)").raise(caller);
                    }
                    return v;

                case TYPE_IVAR: //TEST:
                    {
                        int ivar = 1;
                        v = r_object0(caller, arg, null, ref ivar, extmod);
                        if (ivar > 0) r_ivar(caller, v, arg);                        
                    }
                break;

                case TYPE_EXTENDED: //TEST:
                    {
                        object m = path2module(r_unique(caller, arg), caller);
                        if (extmod == null)
                        {
                            extmod = new Array();
                            ((Array)extmod).value.Add(m);
                        }

                        int temp = 0;
                        v = r_object0(caller, arg, null, ref temp, extmod);
                        while (((Array)extmod).value.Count > 0)
                        {
                            m = ((Array)extmod).value[((Array)extmod).value.Count - 1];
                            ((Array)extmod).value.RemoveAt(((Array)extmod).value.Count - 1);
                            Class.rb_extend_object(caller, v, (Class)m);
                        }
                    }
                break;

                case TYPE_UCLASS:
                    {
                        object c = path2class(caller, r_unique(caller, arg));

                        if (((Class)c)._type == Class.Type.Singleton)
                        {
                            throw new TypeError("singleton can't be loaded").raise(caller);
                        }
                        int temp = 0;
                        v = r_object0(caller, arg, null, ref temp, extmod);
                        if (rb_special_const_p(v) || v is Object || (v is Class && ((Class)v)._type == Class.Type.Class))
                        {
                            throw new ArgumentError("dump format error (user class)").raise(caller);
                        }
                        if ((v is Class && ((Class)v)._type == Class.Type.Module) || !RTEST(Ruby.Methods.rb_class_inherited_p.singleton.Call1(null, c, caller, null, ((Basic)v).my_class)))
                        {
                            object tmp = new Object((Class)c);

                            //TODO: Write this comparison
                            //if (TYPE(v) != TYPE(tmp))
                            //{
                            //    throw new ArgumentError("dump format error (user class)").raise(caller);
                            //}
                        }
                        ((Basic)v).my_class = (Class)c;
                    }
                    break;

                case TYPE_NIL:
                    v = null;
                    break;

                case TYPE_TRUE:
                    v = true;
                    break;

                case TYPE_FALSE:
                    v = false;
                    break;

                case TYPE_FIXNUM:
                    {
                        v = r_long(caller, arg);
                    }
                    break;

                case TYPE_FLOAT:
                    {
                        double d;
                        object str = r_bytes(caller, arg);
                        string ptr = ((String)str).value;

                        if (ptr.Equals("nan"))
                        {
                            d = double.NaN;
                        }
                        else if (ptr.Equals("inf"))
                        {
                            d = double.PositiveInfinity;
                        }
                        else if (ptr.Equals("-inf"))
                        {
                            d = double.NegativeInfinity;
                        }
                        else if (ptr.Equals("-0"))
                        {
                            d = -0.0;
                        }
                        else
                        {
                            int e = 0;
                            d = String.strtod(ptr, 0, out e);
                            d = load_mantissa(d, ptr.Substring(e), ((String)str).value.Length - e);
                        }

                        v = new Float(d);
                        r_entry(caller, v, arg);
                    }
                    break;

                case TYPE_BIGNUM:
                    {
                        int len;
                        uint[] digits;
                        object data;

                        int sign = ((char)r_byte(caller, arg) == '+') ? 1 : -1;

                        len = r_long(caller, arg);
                        data = r_bytes0(caller, len * 2, arg);

                        int bigLen = (len + 1) * 2 / SIZEOF_BDIGITS;                      

                        //extract data to bytes
                        digits = new uint[bigLen];
                        byte[] digitData = new byte[bigLen * SIZEOF_BDIGITS];
                        char[] charDigitData = ((String)data).value.ToCharArray();
                        for (int i = 0; i < ((String)data).value.Length; i++)
                        {
                            digitData[i] = (byte)charDigitData[i];
                        }
                        //save data to digits
                        for (int uintCount = 0; uintCount < digits.Length; uintCount++)
                        {
                            digits[uintCount] = System.BitConverter.ToUInt32(digitData, (uintCount * 4));
                        }
                        v = new Bignum(new IronMath.integer(sign, digits));
                        r_entry(caller, v, arg);
                    }
                    break;
                case TYPE_STRING:
                    v = r_entry(caller, r_string(caller, arg), arg);
                    break;

                case TYPE_REGEXP:
                    {
                        object str = r_bytes(caller, arg);
                        int options = r_byte(caller, arg);
                        v = r_entry(caller, new Regexp(((String)str).value, options), arg);
                    }
                    break;

                case TYPE_ARRAY:
                    {
                        int len = r_long(caller, arg);

                        v = new Array();
                        r_entry(caller, v, arg);
                        while (len-- > 0)
                        {
                            ((Array)v).value.Add(r_object(caller, arg));
                        }
                    }
                    break;

                case TYPE_HASH:
                case TYPE_HASH_DEF:
                    {
                        int len = r_long(caller, arg);

                        v = new Hash();
                        r_entry(caller, v, arg);
                        while (len-- > 0)
                        {
                            object key = r_object(caller, arg);
                            object value = r_object(caller, arg);
                            ((Hash)v).Add(key, value);
                        }
                        if (type == TYPE_HASH_DEF)
                        {
                            ((Hash)v).defaultValue = r_object(caller, arg);
                        }
                    }
                    break;

                case TYPE_STRUCT:
                    {
                        Class klass;
                        object mem;
                        object[] values;
                        int len;
                        int slot;

                        string klassPath = r_unique(caller, arg);
                        klass = (Class)path2class(caller, klassPath);
                        mem = Ruby.Methods.rb_struct_s_members.singleton.Call0(klass, klass, caller, null);
                        if (mem == null)
                        {
                            throw new TypeError("uninitialized struct").raise(caller);
                        }
                        len = r_long(caller, arg);
                        values = new object[len];
                        for (int i = 0; i < len; i++)
                        {
                            slot = r_symbol(caller, arg);

                            if ((string)((Array)mem).value[i] != Symbol.rb_id2name((uint)slot))
                            {
                                string errorString = string.Format(CultureInfo.InvariantCulture, "struct {0} not compatible (:{1} for :{2})",
                                    rb_class2name(klass, caller),
                                    Symbol.rb_id2name((uint)slot),
                                    ((Array)mem).value[i]);

                                throw new TypeError(errorString).raise(caller);
                            }
                            values[i] = r_object(caller, arg);
                        }

                        v = Ruby.Methods.rb_class_new_instance.singleton.Call(klass, klass, caller, null, new Array(values));
                        r_entry(caller, v, arg);
                    }
                    break;
                case TYPE_USERDEF:
                    {
                        object klass = path2class(caller, r_unique(caller, arg));
                        object data;

                        if (!Eval.RespondTo(klass, s_load))
                        {
                            throw new TypeError(string.Format(CultureInfo.InvariantCulture, "class {0} needs to have method `_load'", rb_class2name(klass, caller))).raise(caller);
                        }

                        data = r_string(caller, arg);
                        if (ivp > 0)
                        {
                            r_ivar(caller, data, arg);
                            ivp = 0;
                        }
                        v = Eval.CallPrivate1(klass, caller, s_load, null, data);
                        r_entry(caller, v, arg);                        
                    }
                    break;
                case TYPE_USRMARSHAL: 
                    {
                        object klass = path2class(caller, r_unique(caller, arg));
                        object data;

                        v = Ruby.Methods.rb_obj_alloc.singleton.Call0(null, klass, caller, null);
                        if (extmod != null)
                        {
                            while (((Array)extmod).value.Count > 0)
                            {
                                object m = ((Array)extmod).value[((Array)extmod).value.Count - 1];
                                ((Array)extmod).value.RemoveAt(((Array)extmod).value.Count - 1);
                                Class.rb_extend_object(caller, v, (Class)m);
                            }
                        }
                        if (!Eval.RespondTo(v, s_mload))
                        {
                            throw new TypeError(string.Format(CultureInfo.InvariantCulture, "instance of {0} needs to have method `marshal_load'", rb_class2name(klass, caller))).raise(caller);
                        }
                        r_entry(caller, v, arg);
                        data = r_object(caller, arg);
                        Eval.CallPrivate1(v, caller, s_mload, null, data);
                    }
                    break;

                case TYPE_OBJECT:
                    {
                        object klass = path2class(caller, r_unique(caller, arg));
                        v = Ruby.Methods.rb_obj_alloc.singleton.Call0(null, klass, caller, null);
                        if (!(v is Object))
                        {
                            throw new ArgumentError("dump format error").raise(caller);
                        }
                        r_entry(caller, v, arg);
                        r_ivar(caller, v, arg);
                    }
                    break;

                case TYPE_DATA://TEST
                    {
                        object klass = path2class(caller, r_unique(caller, arg));
                        if (Eval.RespondTo(klass, s_alloc))
                        {
                            type_data_warn = true; //TEST: static int warn = Qtrue; - test that this is equivalent note the 'STATIC' keyword
                            if (type_data_warn)
                            {
                                Errors.rb_warn("define `allocate' instead of `_alloc'");
                                type_data_warn = false;
                            }
                            v = Eval.CallPrivate0(klass, caller, s_alloc, null);
                        }
                        else
                        {
                            v = Ruby.Methods.rb_obj_alloc.singleton.Call0(null, klass, caller, null);
                        }
                        if (!(v is Data))
                        {
                            throw new ArgumentError("dump format error").raise(caller);
                        }
                        r_entry(caller, v, arg);
                        if (!Eval.RespondTo(v, s_load_data))
                        {
                            throw new TypeError(string.Format(CultureInfo.InvariantCulture, "class {0} needs to have instance method `_load_data'", rb_class2name(klass, caller))).raise(caller);
                        }
                        int temp = 0;
                        Eval.CallPrivate1(v, caller, s_load_data, null, r_object0(caller, arg, null, ref temp, extmod));
                    }
                break;

                case TYPE_MODULE_OLD: //TEST:
                    {                     
                        object str = r_bytes(caller, arg);
                        v = rb_path2class(caller, ((String)str).value);
                        r_entry(caller, v, arg);
                    }
                break;

                case TYPE_CLASS:
                    {
                        object str = r_bytes(caller, arg);
                        v = path2class(caller, ((String)str).value);
                        r_entry(caller, v, arg);
                    }
                    break;
                case TYPE_MODULE: //TEST:
                    {                        
                        object str = r_bytes(caller, arg);

                        v = path2module(((String)str).value, caller);
                        r_entry(caller, v, arg);
                    }
                    break;

                case TYPE_SYMBOL: //TEST:
                    v = new Symbol((uint)r_symreal(caller, arg));
                    break;

                case TYPE_SYMLINK: //TEST:
                    return new Symbol((uint)r_symlink(caller, arg));

                default:
                    throw new ArgumentError(string.Format(CultureInfo.InvariantCulture, "dump format error(0x{0})", type)).raise(caller);
            }

            if (proc != null) //TEST:
            {
                Eval.CallPrivate1(proc, caller, "call", null, v);
            }
            return v;

        }
Пример #7
0
 internal static ulong rb_big2uquad_pack(Bignum b, Frame caller)
 {
     if (b.value < 0)
     {
         Bignum positiveBignum = new Bignum(b.value * -1);
         return ((ulong)((long)rb_big2uquad(positiveBignum, caller) * -1) & 0xFFFFFFFFFFFFFFFF);
     }
     else
     {
         return rb_big2uquad(b, caller);
     }
 }
Пример #8
0
        internal static ulong rb_big2uquad(Bignum b, Frame caller)
        {
            if (b.value > ulong.MaxValue || b.value < ulong.MinValue)
            {
                throw new RangeError("bignum too big to convert into `quad int'").raise(caller);
            }

            return b.value.ToUInt64();
        }
Пример #9
0
 internal static uint rb_big2ulong_pack(Bignum b, Frame caller)
 {
     if (b.value < 0)
     {
         Bignum positiveBignum = new Bignum(b.value * -1);
         return (uint)((rb_big2ulong(positiveBignum, caller) * -1) & 0xFFFFFFFF);
     }
     else
     {
         return rb_big2ulong(b, caller);
     }
 }
Пример #10
0
        internal static uint rb_big2ulong(Bignum b, Frame caller)
        {
            if (b.value > uint.MaxValue || b.value < uint.MinValue)
            {
                throw new RangeError("bignum too big to convert into `unsigned long'").raise(caller);
            }

            return b.value.ToUInt32();
        }
Пример #11
0
        public override object Call(Class last_class, object recv, Frame caller, Proc block, Array argv)
        {
            IO io = (IO)recv;

            int whence = IO.SEEK_SET;
            IO fptr;
            long pos;

            if (Class.rb_scan_args(caller, argv, 1, 1, false) == 2)
            {
                whence = Numeric.rb_num2long(argv[1], caller);
            }
            pos = Numeric.rb_num2long(argv[0], caller);
            fptr = IO.GetOpenFile(caller, io);
            if ((fptr.mode & IO.FMODE_WRITABLE) > 0 && (fptr.mode & IO.FMODE_WBUF) > 0)
            {
                Errors.rb_warn("sysseek for buffered IO");
            }
            try
            {
                SeekOrigin so;
                if (whence == IO.SEEK_END)
                    so = SeekOrigin.End;
                else if (whence == IO.SEEK_CUR)
                    so = SeekOrigin.Current;
                else //if (whence == IO.SEEK_SET) // default to begin
                    so = SeekOrigin.Begin;

                pos = fptr.f.Seek(pos, so);
            }
            catch (System.IO.IOException ioe)
            {
                throw SystemCallError.rb_sys_fail(fptr._path, ioe, caller).raise(caller);
            }
            if (pos == -1)
                throw SystemCallError.rb_sys_fail(fptr._path, new IOException(), caller).raise(caller);

            Bignum bpos = new Bignum(pos);

            return Bignum.NormaliseUsing(bpos.value);
        }