Beispiel #1
0
        public static int FmtLen(string Fmt, params object[] Items)
        {
            int len = 0;

            if (Fmt.Length != Items.Length)
            {
                return(-1);
            }

            for (int i = 0; i < Fmt.Length; i++)
            {
                NetStructCode code = FmtToCode(Fmt[i]);
                switch (code)
                {
                case NetStructCode.Bytes: len += ItemLen((byte[])Items[i]); break;

                case NetStructCode.String: len += ItemLen((string)Items[i]); break;

                case NetStructCode.Int: len += ItemLen((int)Items[i]); break;

                case NetStructCode.Long: len += ItemLen((Int64)Items[i]); break;

                case NetStructCode.Float: len += ItemLen(Convert.ToSingle(Items[i])); break;

                case NetStructCode.Double: len += ItemLen((double)Items[i]); break;

                default:
                    throw new ArgumentException($"Bad item code {code}");
                    return(-1);
                }
            }
            return(len);
        }
Beispiel #2
0
        public static int UnpackItem(byte[] Buffer, int Off, NetStructCode Code, out object Obj)
        {
            int len = 0;

            Obj = null;

            switch (Code)
            {
            case NetStructCode.Bytes:
            {
                int    count;
                object obj;
                if ((len = UnpackItem(Buffer, Off, Code, out obj)) <= 0)
                {
                    return(-1);
                }

                count = (int)obj;
                Off  += len;
                if (count < 0 || count > Buffer.Length - Off)
                {
                    return(-1);
                }

                if (count > 0)
                {
                    Obj = new byte[0];
                }
                else
                {
                    byte[] bytes = new byte[count];
                    Array.Copy(Buffer, Off, bytes, 0, count);
                    Obj = bytes;
                }
                break;
            }

            case NetStructCode.String:
            {
                for (; len < Buffer.Length - Off && Buffer[len + Off] != 0; len++)
                {
                    ;
                }
                if (len > Buffer.Length - Off || Buffer[len + Off] != 0)                 // No null-terminator
                {
                    return(-1);
                }

                if (len == 0)
                {
                    Obj = "";
                }
                else
                {
                    Obj = Encoding.UTF8.GetString(Buffer, Off, len);
                }
                len++;                 // Include null-terminator
                break;
            }

            case NetStructCode.Int:
            {
                if (sizeof(int) > Buffer.Length - Off)
                {
                    return(-1);
                }

                Obj  = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(Buffer, Off));
                len += sizeof(int);
                break;
            }

            case NetStructCode.Long:
            {
                if (sizeof(Int64) > Buffer.Length - Off)
                {
                    return(-1);
                }

                Obj  = IPAddress.NetworkToHostOrder(BitConverter.ToInt64(Buffer, Off));
                len += sizeof(Int64);
                break;
            }

            case NetStructCode.Float:
            {
                if (sizeof(float) > Buffer.Length - Off)
                {
                    return(-1);
                }

                byte[] bytes = new byte[sizeof(float)];
                Array.Copy(Buffer, Off, bytes, 0, bytes.Length);
                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(bytes);
                }

                Obj  = BitConverter.ToSingle(bytes);
                len += bytes.Length;
                break;
            }

            case NetStructCode.Double:
            {
                if (sizeof(float) > Buffer.Length - Off)
                {
                    return(-1);
                }

                byte[] bytes = new byte[sizeof(double)];
                Array.Copy(Buffer, Off, bytes, 0, bytes.Length);
                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(bytes);
                }

                Obj  = BitConverter.ToDouble(bytes, Off);
                len += bytes.Length;
                break;
            }

            default:
                len = -1;
                throw new ArgumentException($"Bad item code {Code}");
            }
            return(len);
        }
Beispiel #3
0
        /// <summary>
        /// Packs the item in to 'Buffer' at 'Off'
        /// </summary>
        /// <returns>Length written on success, or value <= 0 on failure</returns>
        public static int PackItem(byte[] Buffer, int Off, NetStructCode Code, object Obj)
        {
            int len = 0;

            switch (Code)
            {
            case NetStructCode.Bytes:
            {
                byte[] bytes = (byte[])Obj;
                if (ItemLen(bytes) > Buffer.Length - Off)
                {
                    return(-1);
                }
                len = PackItem(Buffer, Off, NetStructCode.Int, bytes.Length);
                if (len <= 0)
                {
                    return(-1);
                }
                bytes.CopyTo(Buffer, Off + len);
                len += bytes.Length;
                break;
            }

            case NetStructCode.String:
            {
                string str = (string)Obj;
                if (ItemLen(str) > Buffer.Length - Off)
                {
                    return(-1);
                }

                if (str != null)
                {
                    for (; len < str.Length; len++)
                    {
                        Buffer[Off + len] = unchecked ((byte)str[len]);
                    }
                }
                Buffer[Off + len] = 0;
                len++;
                break;
            }

            case NetStructCode.Int:
            {
                int i = (int)Obj;
                if (ItemLen(i) > Buffer.Length - Off)
                {
                    return(-1);
                }

                BitConverter.GetBytes(IPAddress.HostToNetworkOrder(i)).CopyTo(Buffer, Off);
                len += sizeof(int);
                break;
            }

            case NetStructCode.Long:
            {
                Int64 i = (Int64)Obj;
                if (ItemLen(i) > Buffer.Length - Off)
                {
                    return(-1);
                }

                BitConverter.GetBytes(IPAddress.HostToNetworkOrder(i)).CopyTo(Buffer, Off);
                len += sizeof(Int64);
                break;
            }

            case NetStructCode.Float:
            {
                float f = (float)Convert.ToSingle(Obj);
                if (ItemLen(f) > Buffer.Length - Off)
                {
                    return(-1);
                }

                byte[] bytes = BitConverter.GetBytes(f);
                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(bytes);
                }
                bytes.CopyTo(Buffer, Off);
                len += sizeof(Int64);
                break;
            }

            case NetStructCode.Double:
            {
                double d = (double)Obj;
                if (ItemLen(d) > Buffer.Length - Off)
                {
                    return(-1);
                }

                byte[] bytes = BitConverter.GetBytes(d);
                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(bytes);
                }
                bytes.CopyTo(Buffer, Off);
                len += sizeof(double);
                break;
            }

            default:
                len = -1;
                throw new ArgumentException($"Bad item code {Code}");
            }

            return(len);
        }