Beispiel #1
0
        /// <summary>
        /// Loads next <see cref="LToken"/> from the specified <see cref="LuaTableTextReader"/>.
        /// </summary>
        /// <param name="reader">The reader from which to load the next <see cref="LToken"/>.</param>
        /// <exception cref="ArgumentNullException"><paramref name="reader"/> is <c>null</c>.</exception>
        /// <exception cref="LuaTableReaderException">There are unexpected input in the <paramref name="reader"/>.</exception>
        /// <returns>The loaded Lua token.</returns>
        public static LToken Load(LuaTableTextReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            if (reader.CurrentToken == LuaTableReaderToken.None)
            {
                reader.Read();
            }
            SkipComments(reader);
            switch (reader.CurrentToken)
            {
            case LuaTableReaderToken.None:
            case LuaTableReaderToken.TableStart:
                return(LTable.Load(reader));

            case LuaTableReaderToken.Key:
                return(LField.Load(reader));

            case LuaTableReaderToken.Value:
                return(LValue.Load(reader));

            default:
                throw MakeUnexpectedTokenException(reader);
            }
        }
Beispiel #2
0
        public bool RemoveByName(LValue name)
        {
            if (name == null || name.TokenType == LTokenType.Nil)
            {
                return(false);
            }

            if (fieldsDict.Count == 0)
            {
                // Positional fields only
                // Fast route
                if (name.TokenType == LTokenType.Integer)
                {
                    var intName = (int)name;
                    if (intName <= 0 || intName > Items.Count)
                    {
                        return(false);
                    }
                    Items.RemoveAt(intName - 1);
                    return(true);
                }
            }

            // Named field
            if (fieldsDict.TryGetValue(name, out var field))
            {
                var success = Items.Remove(field);
                Debug.Assert(success);
                return(true);
            }

            // Positional field
            if (name.TokenType == LTokenType.Integer)
            {
                var intName = (int)name;
                // Sanity check
                if (intName <= 0 || intName > Items.Count)
                {
                    return(false);
                }
                int positionalIndex = 0;
                for (int i = 0; i < Items.Count; i++)
                {
                    if (Items[i].Name == null)
                    {
                        positionalIndex++;
                        if (intName == positionalIndex)
                        {
                            Items.RemoveAt(i);
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Beispiel #3
0
 /// <summary>
 /// Initializes a new Lua table field with the specified name and value.
 /// </summary>
 /// <param name="name">Name of the field. Use <c>null</c> for positional field.</param>
 /// <param name="value">Value of the field. Can be <c>null</c>, which means <see cref="LValue.Nil"/>.</param>
 /// <exception cref="ArgumentException"><paramref name="name"/>.<see cref="LValue.TokenType"/> is <see cref="LTokenType.Nil"/>.</exception>
 public LField(LValue name, LToken value)
 {
     if (name != null && name.TokenType == LTokenType.Nil)
     {
         throw new ArgumentException("Cannot use nil as field name.");
     }
     Name   = name;
     _Value = value ?? LValue.Nil;
 }
Beispiel #4
0
 public LField FieldFromName(LValue name, bool allowsCreation)
 {
     Debug.Assert(name != null && name.TokenType != LTokenType.Nil);
     if (name.TokenType == LTokenType.Integer)
     {
         return(FieldFromName((int)name, name, allowsCreation));
     }
     // Named field
     if (fieldsDict.TryGetValue(name, out var field))
     {
         return(field);
     }
     return(null);
 }
Beispiel #5
0
 /// <summary>
 /// Inserts a field or value at the end of the table expression.
 /// </summary>
 /// <param name="content">The field or value of the field.</param>
 public void Add(object content)
 {
     if (content is LField field)
     {
         Add(field);
     }
     else if (content is LToken value)
     {
         Add(value);
     }
     else
     {
         var tv = new LValue(content);
         Add(tv);
     }
 }
Beispiel #6
0
        public new static LField Load(LuaTableTextReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            if (reader.CurrentToken == LuaTableReaderToken.None)
            {
                reader.Read();
            }
            SkipComments(reader);
            LValue key = null;

            if (reader.CurrentToken == LuaTableReaderToken.Key)
            {
                key = new LValue(reader.CurrentValue);
                reader.Read();
                SkipComments(reader);
            }
            LToken value = LToken.Load(reader);

            return(new LField(key, value));
        }
Beispiel #7
0
        public LField FieldFromName(int name, LValue nameRef, bool allowsCreation)
        {
            if (nameRef != null && fieldsDict.TryGetValue(name, out var field))
            {
                return(field);
            }

            if (fieldsDict.Count == 0)
            {
                // Positional fields only
                // Fast route
                if (name <= 0 || name > Items.Count)
                {
                    if (!allowsCreation)
                    {
                        return(null);
                    }
                    var f = new LField(name == Items.Count ? null : new LValue(name), null);
                    Items.Add(f);
                    return(f);
                }

                return(Items[name - 1]);
            }

            // Positional field
            // Sanity check
            if (name <= 0 || name > Items.Count - fieldsDict.Count)
            {
                var nr = nameRef ?? new LValue(name);
                if (fieldsDict.TryGetValue(nr, out var f))
                {
                    return(f);
                }
                if (!allowsCreation)
                {
                    return(null);
                }
                f = new LField(name > 0 && name - 1 == Items.Count - fieldsDict.Count ? null : nr, null);
                Items.Add(f);
                return(f);
            }

            // Get the positional field
            int positionalIndex = 0;

            foreach (var i in Items)
            {
                if (i.Name != null)
                {
                    continue;
                }
                positionalIndex++;
                if (name == positionalIndex)
                {
                    return(i);
                }
            }
#if NETSTANDARD2_0
            Debug.Fail("Should not execute to here.");
#else
            Debug.Assert(false);
#endif
            return(null);
        }
Beispiel #8
0
 /// <summary>
 /// Inserts a field at the end of the table expression.
 /// </summary>
 /// <param name="name">The name of the new field to be appended.</param>
 /// <param name="value">The value of the new field to be appended. <c>null</c> will be treated the same as <see cref="LValue.Nil"/>.</param>
 public void Add(LValue name, LToken value)
 {
     store.Add(new LField(name, value));
 }
Beispiel #9
0
 /// <summary>
 /// Tries to get the field instance with the specified field name.
 /// </summary>
 /// <param name="name">The field name.</param>
 /// <returns>The field instance, or <c>null</c> if no matching field exists.</returns>
 public LField Field(LValue name)
 {
     return(store.FieldFromName(name, false));
 }
Beispiel #10
0
 /// <summary>
 /// Gets/sets the field value associated with the specified field key.
 /// </summary>
 /// <param name="name">The key of the field to set or get.</param>
 /// <returns>The value of the specified field, or <c>null</c> if the field does not exist.</returns>
 public override LToken this[LValue name]
 {
     get { return(store.FieldFromName(name, false)?.Value); }
     set { store.FieldFromName(name, true).Value = value; }
 }
Beispiel #11
0
 /// <summary>
 /// Removes a field from table by its field name.
 /// </summary>
 /// <param name="name">Field name.</param>
 /// <returns>Whether a matching item has been removed.</returns>
 /// <remarks>To remvoe a positional field, pass a numeric value to the <paramref name="name"/> parameter.</remarks>
 public bool Remove(LValue name)
 {
     return(store.RemoveByName(name));
 }