Пример #1
0
        /// <summary>
        /// Sets an entry value in the table if it does not exist.
        /// </summary>
        /// <param name="name">The entry name</param>
        /// <param name="value">The value to set</param>
        /// <returns>False if the type does not match existing value</returns>
        public static bool SetDefaultEntryBoolean(string name, bool value)
        {
#if CORE
            return(CoreMethods.SetDefaultEntryBoolean(name, value));
#else
            return(Storage.Instance.SetDefaultEntryValue(name, Value.MakeBoolean(value)));
#endif
        }
Пример #2
0
        /// <summary>
        /// Sets an entry value
        /// </summary>
        /// <remarks>If the type of the new value differs from the type currently
        /// stored and the force parameter is false (default), returns error and
        /// does not update value. If force is true, the value type in the
        /// table is changed</remarks>
        /// <param name="name">The entry name</param>
        /// <param name="value">The value to set</param>
        /// <param name="force">True to force an update even if types are different</param>
        /// <returns>True on success, otherwise false</returns>
        public static bool SetEntryBoolean(string name, bool value, bool force = false)
        {
#if CORE
            return(CoreMethods.SetEntryBoolean(name, value, force));
#else
            if (force)
            {
                Storage.Instance.SetEntryTypeValue(name, Value.MakeBoolean(value));
                return(true);
            }
            return(Storage.Instance.SetEntryValue(name, Value.MakeBoolean(value)));
#endif
        }
Пример #3
0
        public async Task <bool> LoadPersistentAsync(Stream stream, Action <int, string> warn)
        {
            int lineNum = 1;

            List <StoragePair> entries = new List <StoragePair>();

            List <bool>   boolArray   = new List <bool>();
            List <double> doubleArray = new List <double>();
            List <string> stringArray = new List <string>();

            using (StreamReader reader = new StreamReader(stream))
            {
                string lineStr;
                while ((lineStr = await reader.ReadLineAsync().ConfigureAwait(false)) != null)
                {
                    string line = lineStr.Trim();
                    if (line != string.Empty && line[0] != ';' && line[0] != '#')
                    {
                        break;
                    }
                }

                if (lineStr != "[NetworkTables Storage 3.0]")
                {
                    warn?.Invoke(lineNum, "header line mismatch, ignoring rest of file");
                    return(false);
                }

                while ((lineStr = await reader.ReadLineAsync().ConfigureAwait(false)) != null)
                {
                    string line = lineStr.Trim();
                    ++lineNum;

                    if (line == string.Empty || line[0] == ';' || line[0] == '#')
                    {
                        continue;
                    }

                    string[] split   = line.Split(new[] { ' ' }, 2);
                    var      typeTok = split[0];
                    line = split[1];
                    NtType type = NtType.Unassigned;
                    if (typeTok == "boolean")
                    {
                        type = NtType.Boolean;
                    }
                    else if (typeTok == "double")
                    {
                        type = NtType.Double;
                    }
                    else if (typeTok == "string")
                    {
                        type = NtType.String;
                    }
                    else if (typeTok == "raw")
                    {
                        type = NtType.Raw;
                    }
                    else if (typeTok == "array")
                    {
                        split = line.Split(new[] { ' ' }, 2);
                        var arrayTok = split[0];
                        line = split[1];
                        if (arrayTok == "boolean")
                        {
                            type = NtType.BooleanArray;
                        }
                        else if (arrayTok == "double")
                        {
                            type = NtType.DoubleArray;
                        }
                        else if (arrayTok == "string")
                        {
                            type = NtType.StringArray;
                        }
                    }

                    if (type == NtType.Unassigned)
                    {
                        warn?.Invoke(lineNum, "unrecognized type");
                        continue;
                    }

                    string nameTok;
                    ReadStringToken(out nameTok, out line, line);
                    if (string.IsNullOrEmpty(nameTok))
                    {
                        warn?.Invoke(lineNum, "unterminated name string");
                        continue;
                    }
                    string name;
                    UnescapeString(nameTok, out name);

                    line = line.TrimStart('\t');
                    if (string.IsNullOrEmpty(line) || line[0] != '=')
                    {
                        warn?.Invoke(lineNum, "expected = after name");
                        continue;
                    }
                    line = line.Substring(1).TrimStart(' ', '\t');

                    Value  value = null;
                    string str;
                    switch (type)
                    {
                    case NtType.Boolean:
                        if (line == "true")
                        {
                            value = Value.MakeBoolean(true);
                        }
                        else if (line == "false")
                        {
                            value = Value.MakeBoolean(false);
                        }
                        else
                        {
                            warn?.Invoke(lineNum, "unrecognized boolean value, not 'true' or 'false'");
                            continue;
                        }
                        break;

                    case NtType.Double:
                        str = line;
                        double tmpDouble;
                        var    tmpBoolean = double.TryParse(str, out tmpDouble);
                        if (!tmpBoolean)
                        {
                            warn?.Invoke(lineNum, "invalid double value");
                            continue;
                        }
                        value = Value.MakeDouble(tmpDouble);
                        break;

                    case NtType.String:
                        string strTok;
                        ReadStringToken(out strTok, out line, line);
                        if (string.IsNullOrEmpty(strTok))
                        {
                            warn?.Invoke(lineNum, "missing string value");
                            continue;
                        }
                        if (strTok[strTok.Length - 1] != '"')
                        {
                            warn?.Invoke(lineNum, "unterminated string value");
                            continue;
                        }
                        UnescapeString(strTok, out str);
                        value = Value.MakeString(str);
                        break;

                    case NtType.Raw:
                        value = Value.MakeRaw(Convert.FromBase64String(line));
                        break;

                    case NtType.BooleanArray:
                        value = ReadBooleanArray(line, lineNum, boolArray, warn);
                        if (value == null)
                        {
                            continue;
                        }
                        break;

                    case NtType.DoubleArray:
                        value = ReadDoubleArray(line, lineNum, doubleArray, warn);
                        if (value == null)
                        {
                            continue;
                        }
                        break;

                    case NtType.StringArray:
                        value = ReadStringArray(line, lineNum, stringArray, warn);
                        if (value == null)
                        {
                            continue;
                        }
                        break;
                    }
                    if (name.Length != 0 && value != null)
                    {
                        entries.Add(new StoragePair(name, value));
                    }
                }

                List <Message> msgs = new List <Message>();

                IDisposable monitor = null;
                try
                {
                    monitor = await m_monitor.EnterAsync().ConfigureAwait(false);

                    foreach (var i in entries)
                    {
                        Entry entry;
                        if (!m_entries.TryGetValue(i.First, out entry))
                        {
                            entry = new Entry(i.First);
                            m_entries.Add(i.First, entry);
                        }
                        var oldValue = entry.Value;
                        entry.Value = i.Second;
                        bool wasPersist = entry.IsPersistent();
                        if (!wasPersist)
                        {
                            entry.Flags |= EntryFlags.Persistent;
                        }

                        if (m_server && entry.Id == 0xffff)
                        {
                            uint id = (uint)m_idMap.Count;
                            entry.Id = id;
                            m_idMap.Add(entry);
                        }

                        if (m_notifier.LocalNotifiers())
                        {
                            if (oldValue != null)
                            {
                                m_notifier.NotifyEntry(i.First, i.Second, (NotifyFlags.NotifyNew | NotifyFlags.NotifyLocal));
                            }
                            else if (oldValue != i.Second)
                            {
                                NotifyFlags notifyFlags = NotifyFlags.NotifyUpdate | NotifyFlags.NotifyLocal;
                                if (!wasPersist)
                                {
                                    notifyFlags |= NotifyFlags.NotifyFlagsChanged;
                                }
                                m_notifier.NotifyEntry(i.First, i.Second, notifyFlags);
                            }
                        }

                        if (m_queueOutgoing == null)
                        {
                            continue;
                        }
                        ++entry.SeqNum;

                        if (oldValue == null || oldValue.Type != i.Second.Type)
                        {
                            msgs.Add(Message.EntryAssign(i.First, entry.Id, entry.SeqNum.Value, i.Second, entry.Flags));
                        }
                        else if (entry.Id != 0xffff)
                        {
                            if (oldValue != i.Second)
                            {
                                msgs.Add(Message.EntryUpdate(entry.Id, entry.SeqNum.Value, i.Second));
                            }
                            if (!wasPersist)
                            {
                                msgs.Add(Message.FlagsUpdate(entry.Id, entry.Flags));
                            }
                        }
                    }

                    if (m_queueOutgoing != null)
                    {
                        var         queuOutgoing    = m_queueOutgoing;
                        IDisposable monitorToUnlock = Interlocked.Exchange(ref monitor, null);
                        monitorToUnlock.Dispose();
                        foreach (var msg in msgs)
                        {
                            queuOutgoing(msg, null, null);
                        }
                    }
                }
                finally
                {
                    monitor?.Dispose();
                }
            }
            return(true);
        }