// 戻り値は次のインデックス位置 public int Parse(string source, int offset) { if (string.IsNullOrEmpty(source) == true || source.Length == 0) { // 構文エラー return(-1); } //---------------------------------- if (m_Entities == null) { m_Entities = new List <object>(); } else { m_Entities.Clear(); } //---------------------------------- int l = source.Length; offset = Skip(source, offset); if (offset >= l) { return(offset); // 終了(結果 null) } if (source[offset] != '[') { // 構文エラー return(-1); } offset++; //----------------------------------------------------- object value = null; int w = 0; int f = -1; char c; int i, o = -1, m; bool escape = false; for (i = offset; i < l; i++) { // 値 if (w == 0) { // Value 前 i = Skip(source, i); if (i >= l) { // 構文エラー([ が ] で閉じられていない) m_Entities.Clear(); return(-1); } c = source[i]; // ラベルの外側 if (c == ']') { // いきなり終了 f = i + 1; break; } else if (c == ',') { // 次の項目へ m_Entities.Add(""); } else if (c == '{') { // 値は JsonObject JsonObject jo = new JsonObject(); i = jo.Parse(source, i); if (i < 0 || i >= l) { // 構文エラー([ が ] で閉じられていない) m_Entities.Clear(); return(-1); } i--; value = jo; w = 3; // 閉じへ } else if (c == '[') { // 値は JsonArray JsonArray ja = new JsonArray(); i = ja.Parse(source, i); if (i < 0 || i >= l) { // 構文エラー([ が ] で閉じられていない) m_Entities.Clear(); return(-1); } i--; value = ja; w = 3; // 閉じへ } else // if( c == ' ' || c == '\r' || c == '\n' || c == '\t' ) // { // // 読み飛ばし // } // else { o = i; if (c != '"') { // 数値 w = 1; } else { // 文字 w = 2; } } } else if (w == 1) { // Value 中(数値) c = source[i]; if (c == ',' || c == ']' || c < 0x21 || c > 0x7E) { // 数値切り出し m = i - o; string s; if (m > 0) { s = source.Substring(o, m); } else { s = ""; } value = s; i--; // 1文字前へ w = 3; // 閉じへ } } else if (w == 2) { // Value 中(文字) c = source[i]; if (c == '\\') { // エスケープ escape = true; } else { if (escape == true) { // エスケープ解除 escape = false; } else { if (c == '"') { // 文字列切り出し m = (i + 1) - o; string s; if (m > 0) { s = source.Substring(o, m); } else { s = ""; } value = s; w = 3; // 閉じへ } } } } else if (w == 3) { // Value 後 i = Skip(source, i); if (i >= l) { // 構文エラー([ が ] で閉じられていない) m_Entities.Clear(); return(-1); } c = source[i]; if (c == ',' || c == ']') { // 次の項目へ // ここで tValue が null 以外であることはありえない m_Entities.Add(value); value = null; if (c == ']') { // 無事終了 f = i + 1; break; } w = 0; // 選別へ } else // if( c == ' ' || c == '\r' || c == '\n' || c == '\t' ) // { // // 読み飛ばし // } // else { // 構文エラー(不正な文字) m_Entities.Clear(); return(-1); } } } if (f < 0) { // 構文エラー m_Entities.Clear(); return(-1); } // 成功 return(f); }
// 戻り値は次のインデックス位置 public int Parse(string source, int offset) { if (string.IsNullOrEmpty(source) == true || source.Length == 0) { // 構文エラー return(-1); } //---------------------------------- if (m_Entities == null) { m_Entities = new Dictionary <string, object>(); } else { m_Entities.Clear(); } //---------------------------------- int l = source.Length; offset = Skip(source, offset); if (offset >= l) { return(offset); // 終了(結果 null) } if (source[offset] != '{') { // 構文エラー return(-1); } offset++; //----------------------------------------------------- string label = ""; object value = null; int p = 0; int w = 0; int f = -1; char c; int i, o = -1, m; bool escape = false; for (i = offset; i < l; i++) { if (p == 0) { // 名 if (w == 0) { // Label 前 i = Skip(source, i); if (i >= l) { // 構文エラー({ が } で閉じられていない) m_Entities.Clear(); return(-1); } c = source[i]; // ラベルの外側 if (c == '}') { // いきなり終了 f = i + 1; break; } else if (c == ',') { // 項目省略 // JsonObject の場合は何もしない } else if (c == '"') { o = i; w = 1; // キーワードの内側 } else // if( c == ' ' || c == '\r' || c == '\n' || c == '\t' ) // { // // 読み飛ばし // } // else { // 構文エラー(不正な文字) m_Entities.Clear(); return(-1); } } else if (w == 1) { // Label 中 c = source[i]; // ラベルの内側 if (c == '\\') { // エスケープ escape = true; } else { if (escape == true) { // エスケープ解除 escape = false; } else { if (c == '"') { m = (i - 1) - (o + 1) + 1; if (m < 1) { // 構文エラー(ラベル名が定義されていない) m_Entities.Clear(); return(-1); } label = source.Substring(o + 1, m); w = 2; // キーワードの外側 } } } } else if (w == 2) { // Label 後 i = Skip(source, i); if (i >= l) { // 構文エラー({ が } で閉じられていない) m_Entities.Clear(); return(-1); } c = source[i]; // 名が終わった if (c == ':') { p = 1; // 値へ w = 0; } else // if( c == ' ' || c == '\r' || c == '\n' || c == '\t' ) // { // // 読み飛ばし // } // else { // 構文エラー(不正な文字) m_Entities.Clear(); return(-1); } } } else { // 値 if (w == 0) { // Value 前 i = Skip(source, i); if (i >= l) { // 構文エラー({ が } で閉じられていない) m_Entities.Clear(); return(-1); } c = source[i]; if (c == ',' || c == '}') { // 値は空 value = ""; if (m_Entities.ContainsKey(label) == true) { m_Entities.Remove(label); } m_Entities.Add(label, value); if (c == '}') { // 無事終了 f = i + 1; break; } p = 0; // 名へ w = 0; } else if (c == '{') { // 値は JsonObject JsonObject jo = new JsonObject(); i = jo.Parse(source, i); if (i < 0 || i >= l) { // 構文エラー({ が } で閉じられていない) m_Entities.Clear(); return(-1); } i--; value = jo; w = 3; // 閉じへ } else if (c == '[') { // 値は JsonArray JsonArray ja = new JsonArray(); i = ja.Parse(source, i); if (i < 0 || i >= l) { // 構文エラー({ が } で閉じられていない) m_Entities.Clear(); return(-1); } i--; value = ja; w = 3; // 閉じへ } else // if( c == ' ' || c == '\r' || c == '\n' || c == '\t' ) // { // // 読み飛ばし // } // else { // 数値か文字 o = i; if (c != '"') { // 数値 w = 1; } else { // 文字 w = 2; } } } else if (w == 1) { // Value 中(数値) // 数値 c = source[i]; if (c == ',' || c == '}' || c < 0x21 || c > 0x7E) { // 数値切り出し m = i - o; string s; if (m > 0) { s = source.Substring(o, m); } else { s = ""; } value = s; i--; // 1文字前へ w = 3; // 閉じへ } } else if (w == 2) { // Value 中(文字) // 文字 c = source[i]; if (c == '\\') { // エスケープ escape = true; } else { if (escape == true) { // エスケープ解除 escape = false; } else { if (c == '"') { // 文字列切り出し m = (i + 1) - o; string s; if (m > 0) { s = source.Substring(o, m); } else { s = "\"\""; } value = s; w = 3; // 閉じへ } } } } else if (w == 3) { // Value 後 i = Skip(source, i); if (i >= l) { // 構文エラー({ が } で閉じられていない) m_Entities.Clear(); return(-1); } c = source[i]; if (c == ',' || c == '}') { // 次の項目へ if (m_Entities.ContainsKey(label) == true) { m_Entities.Remove(label); } m_Entities.Add(label, value); if (c == '}') { // 無事終了 f = i + 1; break; } p = 0; // 名へ w = 0; } else // if( c == ' ' || c == '\r' || c == '\n' || c == '\t' ) // { // // 読み飛ばし // } // else { // 構文エラー(不正な文字) m_Entities.Clear(); return(-1); } } } } if (f < 0) { // 構文エラー m_Entities.Clear(); return(-1); } // 成功 return(f); }