Пример #1
0
 /// <summary>
 ///  指定されたファイルに指定されたヱンコン値をバイナリ形式で保存します。
 /// </summary>
 /// <param name="filename">書き込み先のファイルのパスです。</param>
 /// <param name="obj">書き込む全ての情報を保持するセクションオブジェクトです。</param>
 /// <exception cref="System.ArgumentNullException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.FileStream.FileStream(string, FileMode, FileAccess, FileShare)"/>と
 ///  <see cref="System.IO.FileStream.Write(byte[], int, int)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.ArgumentException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.FileStream.FileStream(string, FileMode, FileAccess, FileShare)"/>と
 ///  <see cref="System.IO.FileStream.Write(byte[], int, int)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.NotSupportedException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.FileStream.FileStream(string, FileMode, FileAccess, FileShare)"/>と
 ///  <see cref="System.IO.FileStream.Write(byte[], int, int)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.IO.FileNotFoundException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.FileStream.FileStream(string, FileMode, FileAccess, FileShare)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.IO.IOException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.FileStream.FileStream(string, FileMode, FileAccess, FileShare)"/>と
 ///  <see cref="System.IO.FileStream.Write(byte[], int, int)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.Security.SecurityException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.FileStream.FileStream(string, FileMode, FileAccess, FileShare)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.IO.DirectoryNotFoundException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.FileStream.FileStream(string, FileMode, FileAccess, FileShare)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.UnauthorizedAccessException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.FileStream.FileStream(string, FileMode, FileAccess, FileShare)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.IO.PathTooLongException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.FileStream.FileStream(string, FileMode, FileAccess, FileShare)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.ArgumentOutOfRangeException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.FileStream.FileStream(string, FileMode, FileAccess, FileShare)"/>と
 ///  <see cref="System.IO.FileStream.Write(byte[], int, int)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.ObjectDisposedException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.FileStream.Write(byte[], int, int)"/>が原因に成り得ます。
 /// </exception>
 public void Save(string filename, YSection obj)
 {
     byte[] data = ToObject(obj);
     using (var fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)) {
         fs.Write(data, 0, data.Length);
     }
 }
Пример #2
0
 /// <summary>
 ///  指定されたヱンコンセクションをバイナリ形式に変換します。
 /// </summary>
 /// <param name="obj">バイナリ形式に変換するヱンコンセクションです。</param>
 /// <returns>変換後のデータを保持するバイト配列です。</returns>
 /// <exception cref="System.ArgumentNullException">
 ///  <paramref name="obj"/>が<see langword="null"/>の場合に発生します。
 /// </exception>
 public byte[] ToObject(YSection obj)
 {
     obj = obj ?? throw new ArgumentNullException(nameof(obj));
     byte[] head   = Header.ToBinary();
     byte[] data   = obj.ToBinary(Header);
     byte[] result = new byte[head.Length + data.Length];
     head.CopyTo(result, 0);
     data.CopyTo(result, head.Length);
     return(result);
 }
Пример #3
0
 /// <summary>
 ///  指定されたファイルに指定されたヱンコンオブジェクトを書き込みます。
 /// </summary>
 /// <param name="filename"><paramref name="obj"/>の保存先のファイル名です。</param>
 /// <param name="obj">保存するヱンコンオブジェクトです。</param>
 /// <param name="type">ヱンコンの種類です。既定でバイナリ形式です。</param>
 /// <exception cref="System.IO.IOException">
 ///  ファイルの出力に失敗した場合に発生します。
 /// </exception>
 public static void Save(string filename, YSection obj, YenconType type = YenconType.Binary)
 {
     try {
         if (type == YenconType.Text)
         {
             StringConverter.Save(filename, obj);
         }
         else if (type == YenconType.Binary)
         {
             BinaryConverter.Save(filename, obj);
         }
     } catch (Exception e) {
         throw new IOException(string.Format(ErrorMessages.YenconFormatRecognition_IOException, filename), e);
     }
 }
Пример #4
0
        private YSection ParseInternal(IReadOnlyList <Token> tokens)
        {
            // 戻り値用変数の準備
            var result = new YSection();

            for (int i = 0; i < tokens.Count;)
            {
                switch (tokens[i].Type)
                {
                case TokenType.Name:                         // 名前なら
                    // 名前を保持
                    string name = tokens[i].SourceText;
                    // カウンタを進める
                    ++i;
                    // 等号じゃなかったらエラー
                    if (tokens[i].Type != TokenType.Equal)
                    {
                        throw new InvalidSyntaxException(tokens[i]);
                    }
                    // カウンタを進める
                    ++i;
                    // 型指定子を使って型を特定する
                    YNode node;
                    switch (tokens[i].Type)
                    {
                    case TokenType.NullOrEmpty:                                     // 空値なら
                        // カウンタを進める
                        ++i;
                        // インスタンスの生成
                        node = new YNullOrEmpty();
                        break;

                    case TokenType.CommentChar:                                     // コメントなら
                        // カウンタを進める
                        ++i;
                        // インスタンスの生成
                        var com = new YComment();
                        com.HasName = true;                                         // 名前あり
                        // コメント文字列があるなら
                        if (tokens[i].Type == TokenType.CommentText)
                        {
                            com.SetValue(tokens[i].SourceText);
                            ++i;
                        }
                        node = com;
                        break;

                    case TokenType.SectionStart:                                     // セクションなら
                        // カウンタを進める
                        ++i;
                        // 新しいリストにセクションの終わりまでの字句を追加する
                        var list = new List <Token>();
                        int j    = 1;
                        while (j > 0)
                        {
                            if (tokens[i].Type == TokenType.SectionStart)
                            {
                                ++j;
                            }
                            if (tokens[i].Type == TokenType.SectionEnd)
                            {
                                --j;
                            }
                            // リストに追加する
                            list.Add(tokens[i]);
                            // カウンタを進める
                            ++i;
                        }
                        // 終端の SectionEnd を削除
                        list.RemoveAt(list.Count - 1);
                        // 右の処理は必要ない? //// カウンタを進める //++i;
                        // インスタンスの生成
                        node = this.ParseInternal(list);
                        break;

                    case TokenType.String:                                     // 文字列なら
                        // インスタンスの生成
                        var str = new YString();
                        str.SetEscapedText(tokens[i].SourceText);
                        // カウンタを進める
                        ++i;
                        node = str;
                        break;

                    case TokenType.Number:                                     // 数値なら
                        // インスタンスの生成
                        var num = new YNumber();
                        num.UInt64Value = ulong.Parse(tokens[i].SourceText);
                        // カウンタを進める
                        ++i;
                        node = num;
                        break;

                    case TokenType.Boolean:                                     // 論理値なら
                        // インスタンスの生成
                        var flg = new YBoolean();
                        flg.Flag = tokens[i].SourceText == "T";
                        // カウンタを進める
                        ++i;
                        node = flg;
                        break;

                    default:                                     // それ以外、例外を発生させる
                        throw new InvalidSyntaxException(tokens[i]);
                    }
                    node.Name = name;
                    result.Add(node);
                    break;

                case TokenType.CommentChar:                         // コメントなら
                    // カウンタを進める
                    ++i;
                    // インスタンスの生成
                    var obj = new YComment();
                    // プロパティの設定
                    obj.Name    = Guid.NewGuid().ToString().Replace("{", "").Replace("}", "").Replace("-", "_");
                    obj.HasName = false;
                    // もしコメント文字列があるなら設定
                    if (tokens[i].Type == TokenType.CommentText)
                    {
                        obj.SetValue(tokens[i].SourceText);
                        ++i;
                    }
                    // 結果に追加
                    result.Add(obj);
                    break;

                default:                         // それ以外、例外を発生させる
                    throw new InvalidSyntaxException(tokens[i]);
                }
            }

            // 結果を返す
            return(result);
        }
Пример #5
0
        private YSection ReadSection(BinaryReader br)
        {
            var result = new YSection();

            // キーの数を取得
            uint kc = br.ReadUInt32();

            // キーの数だけ繰り返す
            for (uint i = 0; i < kc; ++i)
            {
                // 名前の文字列長を取得
                ulong nmsz;
                switch (Header.KeyNameSize)
                {
                // 8ビット
                case KeyNameSize.HWord:
                    nmsz = br.ReadByte();
                    break;

                // 16ビット
                case KeyNameSize.Word:
                    nmsz = br.ReadUInt16();
                    break;

                // 32ビット
                case KeyNameSize.DWord:
                    nmsz = br.ReadUInt32();
                    break;

#if false
                // 64ビット
                case KeyNameSize.QWord:
                    nmsz = br.ReadUInt64();
                    break;
#endif
                default:
                    // ここには来ない筈
                    nmsz = 0;
                    break;
                }
                // 文字列値分のバイト配列を取得
                byte[] bName = br.ReadBytes(unchecked ((int)(nmsz)));
                // バイト配列をデコードして名前に変換
                string name = Header.GetEncoding().GetString(bName);
                // 型識別子の取得
                byte t = br.ReadByte();
                // 値の取得
                YNode node;
                switch (t)
                {
                // セクション
                case 0x01:
                    node = ReadSection(br);
                    break;

                // 文字列
                case 0x02:
                    var    str  = new YString();
                    int    sz   = br.ReadInt32();
                    byte[] bStr = br.ReadBytes(sz);
                    string val  = Encoding.Unicode.GetString(bStr);
                    str.SetEscapedText(val);
                    node = str;
                    break;

                // 整数値
                case 0x03:
                    node = new YNumber()
                    {
                        UInt64Value = br.ReadUInt64()
                    };
                    break;

                // 真理値
                case 0x04:
                    node = new YBoolean()
                    {
                        Flag = true
                    };
                    break;

                // 偽理値
                case 0x05:
                    node = new YBoolean()
                    {
                        Flag = false
                    };
                    break;

                // NULL値 | 空値
                default:                         // case 0x00:
                    node = new YNullOrEmpty();
                    break;
                }
                // 名前を設定して現在のセクションに追加
                node.Name = name;
                result.Add(node);
            }

            // 作成したセクションを呼び出し元に返す
            return(result);
        }
Пример #6
0
 /// <summary>
 ///  指定されたヱンコンセクションを文字列に変換します。
 /// </summary>
 /// <param name="obj">文字列に変換するヱンコンセクションです。</param>
 /// <returns>変換後のデータを保持する文字列です。</returns>
 /// <exception cref="System.ArgumentNullException">
 ///  <paramref name="obj"/>が<see langword="null"/>の場合に発生します。
 /// </exception>
 public string ToObject(YSection obj)
 {
     return(obj?.ToString() ?? throw new ArgumentNullException(nameof(obj)));
 }
Пример #7
0
 /// <summary>
 ///  指定されたファイルに指定されたヱンコン値をテキスト形式で保存します。
 /// </summary>
 /// <param name="filename">書き込み先のファイルのパスです。</param>
 /// <param name="obj">書き込む全ての情報を保持するセクションオブジェクトです。</param>
 /// <exception cref="System.ArgumentNullException">
 ///  <paramref name="obj"/>が<see langword="null"/>の場合に発生します。
 /// </exception>
 /// <exception cref="System.UnauthorizedAccessException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.StreamWriter.StreamWriter(string, bool, Encoding)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.ArgumentException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.StreamWriter.StreamWriter(string, bool, Encoding)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.IO.DirectoryNotFoundException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.StreamWriter.StreamWriter(string, bool, Encoding)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.IO.IOException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.StreamWriter.StreamWriter(string, bool, Encoding)"/>と
 ///  <see cref="System.IO.StreamWriter.Write(string)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.IO.PathTooLongException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.StreamWriter.StreamWriter(string, bool, Encoding)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.Security.SecurityException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.StreamWriter.StreamWriter(string, bool, Encoding)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.ObjectDisposedException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.StreamWriter.Write(string)"/>が原因に成り得ます。
 /// </exception>
 /// <exception cref="System.NotSupportedException">
 ///  この関数で利用しているオブジェクトがこの例外を発生させる可能性があります。
 ///  <see cref="System.IO.StreamWriter.Write(string)"/>が原因に成り得ます。
 /// </exception>
 public void Save(string filename, YSection obj)
 {
     using (var sw = new StreamWriter(filename, false, Encoding.Unicode)) {
         sw.Write(this.ToObject(obj));
     }
 }