//---------------------------------------------------------------------
        // 文字解析
        //---------------------------------------------------------------------
        /// <summary>キー文字列の取得。</summary>
        /// <param name="buffer">内部バッファ。</param>
        /// <param name="iter">イテレータ。</param>
        /// <returns>キーリスト。</returns>
        internal static List <string> GetKeys(this TomlInnerBuffer.TomlIter iter)
        {
            var res = new List <string>();

            while (iter.GetChar(0).ch1 > 0)
            {
                iter.SkipSpace();               // 1

                var key = iter.GetKey();        // 2
                if (key != null)
                {
                    res.Add(key);
                    if (iter.GetChar(0).ch1 != '.')     // 3
                    {
                        break;
                    }
                    iter.Skip(1);
                }
                else
                {
                    break;
                }
            }
            return(res);
        }
Exemplo n.º 2
0
        /// <summary>値の解析を行う。</summary>
        /// <param name="iter">イテレータ。</param>
        /// <returns>値情報。</returns>
        private ITomlValue AnalisysValue(TomlInnerBuffer.TomlIter iter)
        {
            ITomlValue value = null;

            // インラインテーブル、配列、日付の確認
            //
            // 1. インラインテーブルを解析する
            // 2. 配列を解析する
            // 3. 値を取得する
            iter.SkipSpace();
            if (iter.GetChar(0).ch1 == '{')         // 1
            {
                iter.Skip(1);
                value = this.GetInlineTable(iter);
            }
            else if (iter.GetChar(0).ch1 == '[')    // 2
            {
                iter.Skip(1);
                value = this.GetValueArray(iter);
            }
            else
            {
                value = this.ConvertValue(iter);    // 3
            }

            return(value);
        }
Exemplo n.º 3
0
        //---------------------------------------------------------------------
        // テーブル解析
        //---------------------------------------------------------------------
        /// <summary>テーブルを作成する。</summary>
        /// <param name="iter">イテレータ。</param>
        /// <param name="table">カレントテーブル。</param>
        private void AnalisysTable(TomlInnerBuffer.TomlIter iter, TomlTable table)
        {
            // '.' で区切られたテーブル名を事前に収集する
            var keyPtr = iter.GetKeys();

            // テーブルが閉じられているか確認
            if (!iter.CloseTable())
            {
                throw new TomlAnalisysException(Resources.TABLE_SYNTAX_ERR, iter);
            }

            // テーブルを作成する
            //
            // 1. テーブル参照を取得
            // 2. エラーが有れば終了
            // 3. 既に作成済みならばカレントを変更
            // 4. 作成されていなければテーブルを作成し、カレントに設定
            TomlTable curTable = table;
            TomlTable newTable = null;

            foreach (var keystr in keyPtr)
            {
                switch (curTable.SearchPathTable(keystr, out newTable))      // 1
                {
                case 0:                                                      // 2
                    throw new TomlAnalisysException(Resources.TABLE_REDEFINITION_ERR, iter);

                case 1:
                    curTable = newTable;                                    // 3
                    break;

                default:
                    newTable = new TomlTable();                             // 4
                    curTable.AddKeyAndValue(keystr, newTable);
                    curTable = newTable;
                    break;
                }
            }

            // 空白は読み捨てておく
            iter.SkipSpace();

            // カレントのテーブルを設定
            this.current = curTable;
            if (!this.current.IsDefined)
            {
                this.current.IsDefined = true;
            }
            else
            {
                throw new TomlAnalisysException(Resources.DEFINED_KEY_ERR, iter);
            }
        }
        /// <summary>']' の後、次が改行/終端/コメントならば真を返す。</summary>
        /// <param name="iter">イテレータ。</param>
        /// <returns>改行/終端/コメントならば真。</returns>
        internal static bool CloseTable(this TomlInnerBuffer.TomlIter iter)
        {
            UTF8 c;

            // 空白を読み飛ばす
            iter.SkipSpace();

            // ] の判定
            if (iter.GetChar(0).ch1 != ']')
            {
                return(false);
            }
            iter.Skip(1);

            // 空白を読み飛ばす
            iter.SkipSpace();

            // 文字を判定
            c = iter.GetChar(0);
            return(c.ch1 == '#' || c.ch1 == '\r' || c.ch1 == '\n' || c.ch1 == 0);
        }
        /// <summary>キー文字列を取得する。</summary>
        /// <param name="iter">イテレータ。</param>
        /// <returns>キー文字列。</returns>
        internal static string GetKey(this TomlInnerBuffer.TomlIter iter)
        {
            var  buf = new List <byte>();
            UTF8 c;

            // 空白を読み飛ばす
            iter.SkipSpace();

            // 範囲の開始、終了位置で評価
            //
            // 1. 一文字取得する
            // 2. キー使用可能文字か判定する
            // 3. " なら文字列としてキー文字列を取得する
            while ((c = iter.GetChar(0)).ch1 != 0)          // 1
            {
                if ((c.ch1 >= 'a' && c.ch1 <= 'z') ||       // 2
                    (c.ch1 >= 'A' && c.ch1 <= 'Z') ||
                    (c.ch1 >= '0' && c.ch1 <= '9') ||
                    c.ch1 == '_' || c.ch1 == '-')
                {
                    c.Expand(buf);
                    iter.Skip(1);
                }
                else if (c.ch1 == '"' && buf.Count <= 0)    // 3
                {
                    iter.Skip(1);
                    return(iter.GetStringValue());
                }
                else
                {
                    break;
                }
            }

            // バイトリストを文字列に変換して返す
            if (buf.Count > 0)
            {
                return(Encoding.UTF8.GetString(buf.ToArray()));
            }
            else
            {
                throw new TomlAnalisysException(Resources.KEY_ANALISYS_ERR, iter);
            }
        }
Exemplo n.º 6
0
        /// <summary>テーブル配列を作成する。</summary>
        /// <param name="iter">イテレータ。</param>
        /// <param name="table">カレントテーブル。</param>
        private void AnalisysTableArray(TomlInnerBuffer.TomlIter iter, TomlTable table)
        {
            // '.' で区切られたテーブル名を事前に収集する
            var keyPtr = iter.GetKeys();

            // テーブル配列が閉じられているか確認
            if (!iter.CloseTableArray())
            {
                throw new TomlAnalisysException(Resources.TABLE_ARRAY_SYNTAX_ERR, iter);
            }

            // 最下層のテーブル以外のテーブル参照を収集する
            //
            // 1. テーブル参照を取得
            // 2. エラーが有れば終了
            // 3. 既に作成済みならばカレントを変更
            // 4. 作成されていなければテーブルを作成し、カレントに設定
            TomlTable curTable = table;
            TomlTable newTable = null;
            string    keystr   = "";

            for (int i = 0; i < keyPtr.Count - 1; ++i)
            {
                keystr = keyPtr[i];

                switch (curTable.SearchPathTable(keystr, out newTable))     // 1
                {
                case 0:                                                     // 2
                    throw new TomlAnalisysException(Resources.TABLE_REDEFINITION_ERR, iter);

                case 1:
                    curTable = newTable;                                    // 3
                    break;

                default:
                    newTable = new TomlTable();                             // 4
                    curTable.AddKeyAndValue(keystr, newTable);
                    curTable = newTable;
                    break;
                }
            }

            // 最下層のテーブルは新規作成となる
            //
            // 1. 登録する名前(キー文字列)を取得
            // 2. 親のテーブルに最下層のテーブル名が登録されている
            //    2-1. 登録されている名前のデータを取得する
            //    2-2. テーブル配列が登録されているならば、新規テーブルを作成し、カレントテーブルとする
            //    2-3. テーブル配列でないならばエラーとする
            // 3. 親のテーブルに最下層のテーブル名が登録されていない
            //    3-1. テーブル配列を作成し、テーブルを追加、追加されたテーブルが次のカレントテーブルになる
            keystr = keyPtr[keyPtr.Count - 1];                              // 1

            if (curTable.Contains(keystr))                                  // 2-1
            {
                var val = curTable.Member(keystr);
                if (val.ValueType == TomlValueType.TomlTableArrayValue)     // 2-2
                {
                    newTable = new TomlTable();
                    ((Array <TomlTable>)val).Add(newTable);
                }
                else                                                        // 2-3
                {
                    throw new TomlAnalisysException(Resources.DEFINED_KEY_ERR, iter);
                }
            }
            else
            {
                newTable = new TomlTable();                                 // 3-1
                var newArr = TomlValue.Create(new TomlTable[] { newTable });
                curTable.AddKeyAndValue(keystr, newArr);
            }

            // カレントのテーブルを作成したテーブルに変更
            this.current = newTable;
            iter.SkipSpace();
        }
Exemplo n.º 7
0
        //---------------------------------------------------------------------
        // キー/値解析
        //---------------------------------------------------------------------
        /// <summary>キーと値のペアを取得する。</summary>
        /// <param name="iter">イテレータ。</param>
        /// <param name="table">対象テーブル。</param>
        /// <param name="lastNoCheck">改行確認するならば真。</param>
        /// <returns>追加できたならば真。</returns>
        private bool AnalisysKeyAndValue(TomlInnerBuffer.TomlIter iter,
                                         TomlTable table,
                                         bool lastNoCheck)
        {
            // キー文字列を取得する
            //
            // 1. キー文字列を取得
            // 2. キー以降の空白を読み飛ばす
            // 3. = で連結しているか確認
            var keyPtr = iter.GetKeys();            // 1

            iter.SkipSpace();                       // 2
            if (iter.GetChar(0).ch1 != '=')         // 3
            {
                throw new TomlAnalisysException(Resources.KEY_ANALISYS_ERR, iter);
            }

            // 値を取得する
            //
            // 1. 値が取得できるか
            // 2. 無効値であるか
            iter.Skip(1);
            var val = this.AnalisysValue(iter);     // 1

            if (val.ValueType == TomlValueType.TomlNoneValue)
            {
                return(false);                       // 2
            }

            // 改行まで確認
            if (!lastNoCheck && !iter.CheckLineEndOrComment())
            {
                throw new TomlAnalisysException(Resources.KEY_VALUE_ERR, iter);
            }

            // '.' で指定されたテーブル参照を収集する
            //
            // 1. テーブル参照を取得
            // 2. エラーが有れば終了
            // 3. 既に作成済みならばカレントを変更
            // 4. 作成されていなければテーブルを作成し、カレントに設定
            TomlTable curTable = table;
            TomlTable newTable = null;

            for (int i = 0; i < keyPtr.Count - 1; ++i)
            {
                var keystr = keyPtr[i];

                switch (curTable.SearchPathTable(keystr, out newTable))     // 1
                {
                case 0:                                                     // 2
                    throw new TomlAnalisysException(Resources.TABLE_REDEFINITION_ERR, iter);

                case 1:
                    curTable = newTable;                                    // 3
                    break;

                default:
                    newTable = new TomlTable();                             // 4
                    curTable.AddKeyAndValue(keystr, newTable);
                    curTable = newTable;
                    break;
                }
            }

            // 最終のテーブルに値を割り当てる
            var laststr = keyPtr[keyPtr.Count - 1];

            if (!curTable.Contains(laststr))
            {
                curTable.AddKeyAndValue(laststr, val);
                return(true);
            }
            else
            {
                throw new TomlAnalisysException(Resources.DEFINED_KEY_ERR, iter);
            }
        }