Reserved for internal use.
Exemplo n.º 1
0
        /// <summary>
        /// Reserved for internal use.
        /// </summary>
        internal static object GetData(byte[] buff, ref int pos, ActionType action, out int count, out int index, ref DataType type, ref int cachePosition)
        {
            count = 0;
            index = 0;
            object value = null;

            if (pos == buff.Length)
            {
                pos = -1;
                return(null);
            }
            bool knownType = type != DataType.None;

            if (!knownType)
            {
                type = (DataType)buff[pos++];
            }
            if (type == DataType.None)
            {
                return(value);
            }
            if (pos == buff.Length)
            {
                pos = -1;
                return(null);
            }
            int size = buff.Length - pos;

            if (type == DataType.Array ||
                type == DataType.Structure)
            {
                count = GXCommon.GetObjectCount(buff, ref pos);
                if (action == ActionType.Count)
                {
                    return(value); //Don't go further. Only object's count is resolved.
                }
                if (cachePosition > pos)
                {
                    pos = cachePosition;
                }
                size = buff.Length - pos;
                if (count != 0 && size < 1)
                {
                    pos = -1;
                    return(null);
                }
                List <object> arr = new List <object>(count);
                for (index = 0; index != count; ++index)
                {
                    DataType itemType = DataType.None;
                    int      colCount, colIndex;
                    int      tmpPos = 0;
                    object   tmp    = GetData(buff, ref pos, ActionType.None, out colCount, out colIndex, ref itemType, ref tmpPos);
                    if (colCount == colIndex && pos != -1)
                    {
                        arr.Add(tmp);
                    }
                    if (pos == -1)
                    {
                        break;
                    }
                    else
                    {
                        cachePosition = pos;
                    }
                }
                if (index == count && pos != -1)
                {
                    cachePosition = buff.Length;
                }
                value = arr.ToArray();
            }
            else if (type == DataType.Boolean)
            {
                value = buff[pos++] != 0;
            }
            else if (type == DataType.BitString)
            {
                int oldPos = pos;
                int cnt    = GetObjectCount(buff, ref pos);
                size -= pos - oldPos;
                double t = cnt;
                t /= 8;
                if (cnt % 8 != 0)
                {
                    ++t;
                }
                int byteCnt = (int)Math.Floor(t);
                if (size < byteCnt) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                string str = "";
                while (cnt > 0)
                {
                    str += ToBitString(buff[pos++], cnt);
                    cnt -= 8;
                }
                value = str;
            }
            else if (type == DataType.Int32)
            {
                if (size < 4) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = GXCommon.GetInt32(buff, ref pos);
            }
            else if (type == DataType.UInt32)
            {
                if (size < 4) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = GXCommon.GetUInt32(buff, ref pos);
            }
            else if (type == DataType.StringUTF8)
            {
                int len = 0;
                if (knownType)
                {
                    len = buff.Length;
                }
                else
                {
                    len = GXCommon.GetObjectCount(buff, ref pos);
                    if (buff.Length - pos < len) //If there is not enough data available.
                    {
                        pos = -1;
                        return(null);
                    }
                }
                if (len > 0)
                {
                    value = ASCIIEncoding.UTF8.GetString(GXCommon.RawData(buff, ref pos, len));
                }
                else
                {
                    value = "";
                }
            }
            else if (type == DataType.String)
            {
                int len = 0;
                if (knownType)
                {
                    len = buff.Length;
                }
                else
                {
                    len = GXCommon.GetObjectCount(buff, ref pos);
                    if (buff.Length - pos < len) //If there is not enough data available.
                    {
                        pos = -1;
                        return(null);
                    }
                }
                if (len > 0)
                {
                    bool octetString = false;
                    if (knownType)
                    {
                        //Check that this is not octet string.
                        foreach (byte it in buff)
                        {
                            if (it != 0 && it < 0x20)
                            {
                                octetString = true;
                                break;
                            }
                        }
                    }
                    if (octetString)
                    {
                        StringBuilder sb = new StringBuilder(3 * buff.Length);
                        foreach (byte it in buff)
                        {
                            sb.Append(it);
                            sb.Append('.');
                        }
                        sb.Remove(sb.Length - 1, 1);
                        value = sb.ToString();
                    }
                    else
                    {
                        //Remove '\0' from string if used.
                        while (len > 0 && buff[len - 1] == 0)
                        {
                            --len;
                        }
                        value = ASCIIEncoding.ASCII.GetString(GXCommon.RawData(buff, ref pos, len));
                    }
                }
            }
            //Example Logical name is octet string, so do not change to string...
            else if (type == DataType.OctetString)
            {
                int len = 0;
                if (knownType)
                {
                    len = buff.Length;
                }
                else
                {
                    len = GXCommon.GetObjectCount(buff, ref pos);
                    if (buff.Length - pos < len) //If there is not enough data available.
                    {
                        pos = -1;
                        return(null);
                    }
                }
                value = GXCommon.RawData(buff, ref pos, len);
            }
            else if (type == DataType.BinaryCodedDesimal)
            {
                int len;
                if (knownType)
                {
                    len = buff.Length;
                }
                else
                {
                    len = GXCommon.GetObjectCount(buff, ref pos);
                }
                StringBuilder bcd = new StringBuilder(len * 2);
                for (int a = 0; a != len; ++a)
                {
                    int idHigh = buff[pos] >> 4;
                    int idLow  = buff[pos] & 0x0F;
                    ++pos;
                    bcd.Append(string.Format("{0}{1}", idHigh, idLow));
                }
                return(bcd.ToString());
            }
            else if (type == DataType.Int8)
            {
                value = (sbyte)buff[pos++];
            }
            else if (type == DataType.Int16)
            {
                if (size < 2) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = GXCommon.GetInt16(buff, ref pos);
            }
            else if (type == DataType.UInt8)
            {
                value = buff[pos++];
            }
            else if (type == DataType.UInt16)
            {
                if (size < 2) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = GXCommon.GetUInt16(buff, ref pos);
            }
            else if (type == DataType.CompactArray)
            {
                throw new Exception("Invalid data type.");
            }
            else if (type == DataType.Int64)
            {
                if (size < 8) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = GXCommon.GetInt64(buff, ref pos);
            }
            else if (type == DataType.UInt64)
            {
                if (size < 8) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = GXCommon.GetUInt64(buff, ref pos);
            }
            else if (type == DataType.Enum)
            {
                if (size < 1) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = buff[pos++];
            }
            else if (type == DataType.Float32)
            {
                if (size < 4) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = GXCommon.ToFloat(buff, ref pos);
            }
            else if (type == DataType.Float64)
            {
                if (size < 8) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = GXCommon.ToDouble(buff, ref pos);
            }
            else if (type == DataType.DateTime)
            {
                if (size < 12) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                GXDateTime dt = new GXDateTime();
                //Get year.
                int year = GXCommon.GetUInt16(buff, ref pos);
                if (year == 0xFFFF || year == 0)
                {
                    year     = DateTime.MinValue.Year;
                    dt.Skip |= DateTimeSkips.Year;
                }
                //Get month
                int month = buff[pos++];
                if (month == 0 || month == 0xFF || month == 0xFE || month == 0xFD)
                {
                    month    = 1;
                    dt.Skip |= DateTimeSkips.Month;
                }
                int day = buff[pos++];
                if (day < 1 || day == 0xFF)
                {
                    day      = 1;
                    dt.Skip |= DateTimeSkips.Day;
                }
                else if (day == 0xFD || day == 0xFE)
                {
                    day = DateTime.DaysInMonth(year, month) + (sbyte)day + 2;
                }
                //Skip week day
                ++pos;
                //Get time.
                int hours = buff[pos++];
                if (hours == 0xFF)
                {
                    hours    = 0;
                    dt.Skip |= DateTimeSkips.Hour;
                }
                int minutes = buff[pos++];
                if (minutes == 0xFF)
                {
                    minutes  = 0;
                    dt.Skip |= DateTimeSkips.Minute;
                }
                int seconds = buff[pos++];
                if (seconds == 0xFF)
                {
                    seconds  = 0;
                    dt.Skip |= DateTimeSkips.Second;
                }
                int milliseconds = buff[pos++];
                if (milliseconds != 0xFF && milliseconds != 0)
                {
                    milliseconds *= 10;
                }
                else
                {
                    milliseconds = 0;
                    dt.Skip     |= DateTimeSkips.Ms;
                }
                int deviation = GXCommon.GetInt16(buff, ref pos);
                dt.Status = (ClockStatus)buff[pos++];
                if ((deviation & 0xFFFF) != 0x8000 && year != 1)
                {
                    dt.Value = DateTime.SpecifyKind(new DateTime(year, month, day, hours, minutes, seconds, milliseconds), DateTimeKind.Utc);
                    dt.Value = dt.Value.AddMinutes(deviation);
                    dt.Value = dt.Value.ToLocalTime();
                }
                else //Use current time if deviation is not defined.
                {
                    dt.Value = new DateTime(year, month, day, hours, minutes, seconds, milliseconds);
                }
                value = dt;
            }
            else if (type == DataType.Date)
            {
                if (size < 5) //If there is not enough data available.
                {
                    pos = 0xFF;
                    return(null);
                }
                //Get year.
                int year = GXCommon.GetUInt16(buff, ref pos);
                //IskraEmeco meter returns bytes in wrong order.
                if (year != 0xFFFF && year > 2100)
                {
                    pos -= 2;
                    year = buff[pos++] | buff[pos++] << 8;
                    //If Actaris SL 7000 and ACE 6000 returns invalid date.
                    if (year == 0x5C13)
                    {
                        year = -1;
                    }
                }
                //Get month
                int month = buff[pos++];
                int day   = buff[pos++];
                //Skip week day
                int DayOfWeek = buff[pos++];
                //If day of week are not used.
                GXDateTime dt = new GXDateTime(year, month, day, -1, -1, 1, -1);
                return(dt);
            }
            else if (type == DataType.Time)
            {
                if (size < 4) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                //Get time.
                int        hours        = buff[pos++];
                int        minutes      = buff[pos++];
                int        seconds      = buff[pos++];
                int        milliseconds = buff[pos++];
                GXDateTime dt           = new GXDateTime(-1, -1, -1, hours, minutes, seconds, milliseconds);
                value = dt;
            }
            else
            {
                throw new Exception("Invalid data type.");
            }
            return(value);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Reserved for internal use.
        /// </summary>
        /// <param name="buff"></param>
        /// <param name="type"></param>
        /// <param name="value"></param>
        public static void SetData(List <byte> buff, DataType type, object value)
        {
            bool        reverse = true;
            List <byte> tmp     = new List <byte>();

            //If byte array is added do not add type.
            if ((type == DataType.Array || type == DataType.Structure) && value is byte[])
            {
                buff.AddRange((byte[])value);
                return;
            }
            if (type == DataType.None)
            {
                value = null;
            }
            else if (type == DataType.Boolean)
            {
                value = (byte)(Convert.ToBoolean(value) ? 1 : 0);
            }
            else if (type == DataType.BitString)
            {
                byte val   = 0;
                int  index = 0;
                if (value is string)
                {
                    string str = value as string;
                    SetObjectCount(str.Length, tmp);
                    foreach (char it in str)
                    {
                        if (it == '1')
                        {
                            val |= (byte)(1 << index++);
                        }
                        else if (it == '0')
                        {
                            index++;
                        }
                        else
                        {
                            throw new ArgumentException("Not a bit string.");
                        }
                        if (index == 8)
                        {
                            index = 0;
                            tmp.Add(val);
                            val = 0;
                        }
                    }
                    if (index != 0)
                    {
                        tmp.Add(val);
                    }
                    value   = tmp.ToArray();
                    reverse = false;
                }
                else if (value is byte[])
                {
                    byte[] arr = value as byte[];
                    SetObjectCount(arr.Length, tmp);
                    tmp.AddRange(arr);
                    value   = tmp.ToArray();
                    reverse = false;
                }
                else if (value is bool[])
                {
                    bool[] arr = value as bool[];
                    SetObjectCount(arr.Length, tmp);
                    foreach (bool it in arr)
                    {
                        if (it)
                        {
                            val |= (byte)(1 << index++);
                        }
                        else
                        {
                            ++index;
                        }
                        if (index == 8)
                        {
                            index = 0;
                            tmp.Add(val);
                            val = 0;
                        }
                    }
                    if (index != 0)
                    {
                        tmp.Add(val);
                    }
                    value   = tmp.ToArray();
                    reverse = false;
                }
                else if (value == null)
                {
                    tmp.Add(0);
                    value   = tmp.ToArray();
                    reverse = false;
                }
                else
                {
                    throw new Exception("BitString must give as string.");
                }
            }
            else if (type == DataType.Int32)
            {
                value = Convert.ToInt32(value);
            }
            else if (type == DataType.UInt32)
            {
                value = Convert.ToUInt32(value);
            }
            else if (type == DataType.String)
            {
                if (value != null)
                {
                    string str = value.ToString();
                    SetObjectCount(str.Length, tmp);
                    tmp.AddRange(ASCIIEncoding.ASCII.GetBytes(str));
                }
                else
                {
                    SetObjectCount(0, tmp);
                }
                value   = tmp.ToArray();
                reverse = false;
            }
            else if (type == DataType.StringUTF8)
            {
                if (value != null)
                {
                    string str  = value.ToString();
                    byte[] tmp1 = ASCIIEncoding.UTF8.GetBytes(str);
                    SetObjectCount(tmp1.Length, tmp);
                    tmp.AddRange(tmp1);
                }
                else
                {
                    SetObjectCount(0, tmp);
                }
                value   = tmp.ToArray();
                reverse = false;
            }
            else if (type == DataType.Array || type == DataType.Structure)
            {
                if (value != null)
                {
                    Array arr = (Array)value;
                    SetObjectCount(arr.Length, tmp);
                    foreach (object it in arr)
                    {
                        SetData(tmp, GetValueType(it), it);
                    }
                }
                else
                {
                    SetObjectCount(0, tmp);
                }
                value   = tmp.ToArray();
                reverse = false;
            }
            else if (type == DataType.OctetString)
            {
                reverse = false;
                if (value is string)
                {
                    if ((value as string) == "")
                    {
                        SetObjectCount(0, tmp);
                        value = tmp.ToArray();
                    }
                    else
                    {
                        string[] items = (value as string).Split('.');
                        tmp.Clear();
                        SetObjectCount(items.Length, tmp);
                        foreach (string it in items)
                        {
                            tmp.Add(byte.Parse(it));
                        }
                        value = tmp.ToArray();
                    }
                }
                else if (value == null)
                {
                    SetObjectCount(0, tmp);
                    value = tmp.ToArray();
                }
                else if (value is byte[])
                {
                    SetObjectCount((value as byte[]).Length, tmp);
                    tmp.AddRange(value as byte[]);
                    value = tmp.ToArray();
                }
                else if (value is GXDateTime)
                {
                    value = GetDateTime(value as GXDateTime);
                }
                else if (value is DateTime)
                {
                    value = GetDateTime(new GXDateTime(Convert.ToDateTime(value)));
                }
                else
                {
                    value = Convert.ToString(value);
                }
            }
            else if (type == DataType.BinaryCodedDesimal)
            {
                if (!(value is string))
                {
                    throw new Exception("BCD value must give as string.");
                }
                string str = value.ToString().Trim();
                int    len = str.Length;
                if (len % 2 != 0)
                {
                    str = "0" + str;
                    ++len;
                }
                len /= 2;
                List <byte> val = new List <byte>(len);
                val.Add((byte)(len));
                for (int pos = 0; pos != len; ++pos)
                {
                    byte ch1 = byte.Parse(str.Substring(2 * pos, 1));
                    byte ch2 = byte.Parse(str.Substring(2 * pos + 1, 1));
                    val.Add((byte)(ch1 << 4 | ch2));
                }
                reverse = false;
                value   = val.ToArray();
            }
            else if (type == DataType.Int8)
            {
                value = Convert.ToSByte(value);
            }
            else if (type == DataType.Int16)
            {
                value = (short)Convert.ToInt32(value);
            }
            else if (type == DataType.UInt8)
            {
                value = Convert.ToByte(value);
            }
            else if (type == DataType.UInt16)
            {
                value = Convert.ToUInt16(value);
            }
            else if (type == DataType.CompactArray)
            {
                throw new Exception("Invalid data type.");
            }
            else if (type == DataType.Int64)
            {
                value = Convert.ToInt64(value);
            }
            else if (type == DataType.UInt64)
            {
                value = Convert.ToUInt64(value);
            }
            else if (type == DataType.Enum)
            {
                value = Convert.ToByte(value);
            }
            else if (type == DataType.Float32)
            {
                value = Convert.ToSingle(value);
            }
            else if (type == DataType.Float64)
            {
                value = Convert.ToDouble(value);
            }
            else if (type == DataType.DateTime)
            {
                type = DataType.OctetString;
                if (value is GXDateTime)
                {
                    value = GetDateTime(value as GXDateTime);
                }
                else
                {
                    value = GetDateTime(new GXDateTime(Convert.ToDateTime(value)));
                }
                reverse = false;
            }
            else if (type == DataType.Date)
            {
                GXDateTime dt;
                if (value is GXDateTime)
                {
                    dt = value as GXDateTime;
                }
                else if (value is DateTime)
                {
                    dt = new GXDateTime((DateTime)value);
                }
                else
                {
                    throw new Exception("Invalid date format.");
                }
                type = DataType.OctetString;
                //Add size
                tmp.Add(5);
                //Add year.
                if ((dt.Skip & DateTimeSkips.Year) != 0)
                {
                    GXCommon.SetUInt16(0xFFFF, tmp);
                }
                else
                {
                    GXCommon.SetUInt16((ushort)dt.Value.Year, tmp);
                }
                //Add month.
                if (dt.DaylightSavingsBegin)
                {
                    tmp.Add(0xFE);
                }
                else if (dt.DaylightSavingsEnd)
                {
                    tmp.Add(0xFD);
                }
                else if ((dt.Skip & DateTimeSkips.Month) != 0)
                {
                    tmp.Add(0xFF);
                }
                else
                {
                    tmp.Add((byte)dt.Value.Month);
                }

                if ((dt.Skip & DateTimeSkips.Day) != 0)
                {
                    tmp.Add(0xFF);
                }
                else
                {
                    tmp.Add((byte)dt.Value.Day);
                }
                //Week day is not spesified.
                tmp.Add(0xFF);
                value   = tmp.ToArray();
                reverse = false;
            }
            else if (type == DataType.Time)
            {
                GXDateTime dt;
                if (value is GXDateTime)
                {
                    dt = value as GXDateTime;
                }
                else if (value is DateTime)
                {
                    dt = new GXDateTime((DateTime)value);
                }
                else
                {
                    throw new Exception("Invalid date format.");
                }
                type = DataType.OctetString;
                //Add size
                tmp.Add(4);
                //Add time.
                if ((dt.Skip & DateTimeSkips.Hour) != 0)
                {
                    tmp.Add(0xFF);
                }
                else
                {
                    tmp.Add((byte)dt.Value.Hour);
                }

                if ((dt.Skip & DateTimeSkips.Minute) != 0)
                {
                    tmp.Add(0xFF);
                }
                else
                {
                    tmp.Add((byte)dt.Value.Minute);
                }

                if ((dt.Skip & DateTimeSkips.Second) != 0)
                {
                    tmp.Add(0xFF);
                }
                else
                {
                    tmp.Add((byte)dt.Value.Second);
                }
                tmp.Add((byte)0xFF); //Hundredths of second is not used.
                value   = tmp.ToArray();
                reverse = false;
            }
            else
            {
                throw new Exception("Invalid data type.");
            }
            buff.Add((byte)type);
            if (value != null)
            {
                byte[] data = Gurux.Shared.GXCommon.GetAsByteArray(value);
                if (reverse)
                {
                    Array.Reverse(data);
                }
                buff.AddRange(data);
            }
        }
Exemplo n.º 3
0
        static byte[] GetDateTime(GXDateTime dt)
        {
            if (dt.Value == DateTime.MinValue)
            {
                dt.Value = DateTime.SpecifyKind(new DateTime(2000, 1, 1).Date, DateTimeKind.Utc);
            }
            else if (dt.Value == DateTime.MaxValue)
            {
                dt.Value = DateTime.SpecifyKind(DateTime.Now.AddYears(1).Date, DateTimeKind.Utc);
            }
            DateTime tm;

            //If used normal time.
            if ((dt.Skip & DateTimeSkips.Devitation) == 0)
            {
                tm = dt.Value;
            }
            else //If devitation is skipped.
            {
                //If value is given as UTC time.
                if (TimeZone.CurrentTimeZone.GetUtcOffset(dt.Value).TotalMinutes == 0)
                {
                    tm = dt.Value;
                }
                else
                {
                    tm = dt.Value.ToUniversalTime();
                }
            }
            List <byte> tmp = new List <byte>();

            //Add size
            tmp.Add(12);
            if ((dt.Skip & DateTimeSkips.Year) == 0)
            {
                GXCommon.SetUInt16((ushort)tm.Year, tmp);
            }
            else
            {
                GXCommon.SetUInt16((ushort)0xFFFF, tmp);
            }
            if ((dt.Skip & DateTimeSkips.Month) == 0)
            {
                if (dt.DaylightSavingsBegin)
                {
                    tmp.Add(0xFE);
                }
                else if (dt.DaylightSavingsEnd)
                {
                    tmp.Add(0xFD);
                }
                else
                {
                    tmp.Add((byte)tm.Month);
                }
            }
            else
            {
                tmp.Add(0xFF);
            }
            if ((dt.Skip & DateTimeSkips.Day) == 0)
            {
                tmp.Add((byte)tm.Day);
            }
            else
            {
                tmp.Add(0xFF);
            }
            //Week day is not spesified.
            //Standard defines. tmp.Add(0xFF);
            tmp.Add(0xFF);
            //Add time.
            if ((dt.Skip & DateTimeSkips.Hour) == 0)
            {
                tmp.Add((byte)tm.Hour);
            }
            else
            {
                tmp.Add(0xFF);
            }

            if ((dt.Skip & DateTimeSkips.Minute) == 0)
            {
                tmp.Add((byte)tm.Minute);
            }
            else
            {
                tmp.Add(0xFF);
            }
            if ((dt.Skip & DateTimeSkips.Second) == 0)
            {
                tmp.Add((byte)tm.Second);
            }
            else
            {
                tmp.Add(0xFF);
            }

            if ((dt.Skip & DateTimeSkips.Ms) == 0)
            {
                tmp.Add((byte)(tm.Millisecond / 10));
            }
            else
            {
                tmp.Add((byte)0xFF); //Hundredths of second is not used.
            }
            //Add deviation.
            if ((dt.Skip & DateTimeSkips.Devitation) == 0)
            {
                short devitation = (short)TimeZone.CurrentTimeZone.GetUtcOffset(dt.Value).TotalMinutes;
                GXCommon.SetInt16(devitation, tmp);
            }
            else //deviation not used.
            {
                tmp.Add((byte)0x00);
                tmp.Add((byte)0x00);
            }
            //Add clock_status
            tmp.Add((byte)dt.Status);
            return(tmp.ToArray());
        }