/// <summary> /// <code> /// sigo.Get("user/name") => sigo.Get1("user").Get1("name") /// sigo.Get("user") => sigo.Get1("user") /// sigo.Get("/") => sigo /// </code> /// </summary> public static ISigo Get(ISigo sigo, string path) { if (IsLooped(sigo)) { return(sigo); } if (string.IsNullOrEmpty(path)) { return(sigo); } if (!path.Contains('/')) { return(sigo.Get1(path)); } var keys = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); foreach (var key in keys) { sigo = sigo.Get1(key); if (IsLooped(sigo)) { return(sigo); } } return(sigo); }
/// <summary> /// try to return part of a if a is frozen /// try to return part of b if b is frozen /// return new sigo /// </summary> public static ISigo Merge(ISigo a, ISigo b) { ISigo r; if (b is SigoLeaf) { r = b; return(Select(r, a, b)); } if (a is SigoLeaf) { if ((b.Flags & Bits.M) == 0) { r = a; return(Select(r, a, b)); } r = Merge(Sigo.Create(Bits.LMR), b); return(Select(r, a, b)); } r = Sigo.Create(Bits.Proton(a.Flags | b.Flags)); var keys = a.Keys.Union(b.Keys); foreach (var key in keys) { r = r.Set1(key, Merge(a.Get1(key), b.Get1(key))); } return(Select(r, a, b)); }
public static TestInfo CreateInfo(ISigo t) { lock (caches) { var info = new TestInfo(t); caches.Add(info); return(info); } }
private static void LoadConfiguration() { try { config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); context = Sigo.Parse(config.AppSettings.Settings["context"].Value); } catch (Exception) { // ignored } }
public ISigo Set1(string key, ISigo value) { switch (value.Flags & Bits.CPLMR) { case Bits.MR: return(this); case Bits.LMR: return(Sigo.Create(Bits.LMR)); default: return(Sigo.Create(Bits.LMR).Set1(key, value)); } }
/// <summary> /// A looped sigo is a sigo that returns itself /// The result is depends on how the default children is defined /// </summary> public static bool IsLooped(ISigo sigo) { switch (sigo.Flags & (-256 + 8 + 7)) { case 0: case 3: return(true); default: return(false); } }
public void NonEmptyTree_areNotFrozen_after_creating_or_changing() { // non empty tree are not frozen after creating SigoAssert.False(tree.IsFrozen()); // not frozen after changing tree = tree.Freeze().Set1("v", Sigo.From("v+")); SigoAssert.False(tree.IsFrozen()); // leafs and elements are frozen always frozen SigoAssert.True(leaf.IsFrozen()); SigoAssert.True(e3.IsFrozen()); }
private ISigo Change(int rf, string key, ISigo value) { if (Bits.IsFrozen(rf)) { return(new SigoTree(Bits.RemoveFrozen(rf), DictCloneSet(key, value))); } else { Flags = rf; DictSet(key, value); return(this); } }
/// <summary> /// Lightweight implementation of comparison /// see Object.is() in javascript /// </summary> public static bool Same(ISigo a, ISigo b) { if (ReferenceEquals(a, b)) { return(true); } if (Bits.IsLeaf(a.Flags) && Bits.IsLeaf(b.Flags)) { return(Equals(a.Data, b.Data)); } return(false); }
private static ISigo Select(ISigo r, ISigo a, ISigo b) { if (a.IsFrozen() && Sigo.Equals(r, a)) { return(a); } if (b.IsFrozen() && Sigo.Equals(r, b)) { return(b); } return(r); }
public static ISigo SetN(ISigo sigo, IReadOnlyList <string> keys, ISigo value, int start) { switch (keys.Count - start) { case 0: return(value); case 1: return(sigo.Set1(keys[start], value)); default: { var key = keys[start]; return(sigo.Set1(key, SetN(sigo.Get1(key), keys, value, start + 1))); } } }
private ISigo Add(int rf, string key, ISigo value) { rf = Bits.CountUp(rf); if (Bits.IsFrozen(rf)) { return(new SigoTree(Bits.RemoveFrozen(rf), DictCloneAdd(key, value))); } else { Flags = rf; DictAdd(key, value); return(this); } }
public static ISigo Clone(ISigo a) { if (a.IsFrozen()) { return(a); } var ret = Sigo.Create(a.Flags & 7); foreach (var e in a) { ret = ret.Set1(e.Key, Clone(e.Value)); } return(ret); }
public static bool Equals(ISigo a, ISigo b) { if (ReferenceEquals(a, b)) { return(true); } if (Bits.IsSame(a.Flags, b.Flags) == false) { return(false); } return(Bits.IsLeaf(a.Flags) ? Equals(a.Data, b.Data) : a.All(e => Equals(e.Value, b.Get1(e.Key)))); }
public static ISigo Set(ISigo sigo, string path, ISigo value) { if (string.IsNullOrEmpty(path)) { return(value); } if (!Paths.ShouldSplit(path)) { return(sigo.Set1(path, value)); } var keys = Paths.Split(path); return(SetN(sigo, keys, value, 0)); }
public static ISigo Solid(int lm1, ISigo b) { // {3} * {0, x:{3}} ISigo ret = null; // new if b not frozen or miss some lm1 if (16 + lm1 != ((16 + lm1) & b.Flags)) { ret = Sigo.Create(7 & (lm1 | b.Flags)); } foreach (var e in b) { var k = e.Key; var bk = e.Value; var rk = Solid(3, bk); if (ret != null) { ret = ret.Set1(k, rk); } else { if (ReferenceEquals(rk, bk)) { continue; } ret = Sigo.Create(7 & (lm1 | b.Flags)); foreach (var t in b) { if (t.Key != k) { ret = ret.Set1(t.Key, t.Value); } else { ret = ret.Set1(k, rk); break; } } } } return(ret ?? b); }
public GetTests() { V = Sigo.From("V"); A = Sigo.Create(0).Set1("x", Sigo.From(1)).Set1("y", Sigo.From(2)); B = Sigo.Create(0).Set1("x", Sigo.From(3)).Set1("y", Sigo.From(4)); AB = Sigo.Create(3, "A", A, "B", B); E = new ISigo[8]; for (var i = 0; i < 8; i++) { E[i] = Sigo.Create(i); } All = new List <ISigo> { A, B, AB, V }; All.AddRange(E); }
public static int GetHashCode(ISigo a) { if (a == null) { return(0); } var fa = a.Flags; if (Bits.IsLeaf(fa)) { return(a.Data != null?a.Data.GetHashCode() : 0); } return(a.Aggregate( Bits.Proton(fa) * 11, (sum, e) => unchecked (sum + e.Key.GetHashCode() * 7 + GetHashCode(e.Value) * 3))); }
// TODO do we need detect circular object? public StringBuilder WriteSigo(StringBuilder sb, ISigo sigo, int level) { if (sigo.IsLeaf()) { return(WriteAny(sb, sigo.Data, level)); } sb.Append('{'); var first = true; if (!IgnoreFlag || !CanIgnoreFlag(sigo)) { sb.Append(sigo.Flags & 7); first = false; } if (sigo.Count > 0) { foreach (var e in sigo) { if (first) { first = false; WriteSep(sb, level, 0); } else { WriteSep(sb, level, 1); } WriteKey(sb, e.Key); WriteColon(sb); WriteSigo(sb, e.Value, level + 1); } WriteSep(sb, level, 2); } sb.Append('}'); return(sb); }
public static ISigo UpLM(ISigo a, int f) { if (f != (f & 6)) { throw new ArgumentException("only L, M protons accepted"); } if (a.Flags == (a.Flags | f)) { return(a); } // {4, x: {3}} * {6} => {6|4, x:{3}} var ret = Sigo.Create(a.Flags | f); foreach (var e in a) { ret.Set1(e.Key, e.Value); } return(ret); }
public ISigo Set1(string key, ISigo value) { if (TryGetValue(key, out var old)) { if (value.Same(old)) { return(this); } var rf = Flags; var vf = value.Flags; rf = Bits.LeftEffect(rf, vf); if (Bits.IsDef(rf, vf)) { return(Delete(rf, key)); } else { return(Change(rf, key, value)); } } else { var rf = Flags; var vf = value.Flags; rf = Bits.LeftEffect(rf, vf); if (Bits.IsDef(rf, vf)) { return(SetFlags(rf)); } else { return(Add(rf, key, value)); } } }
private static ISigo Merge(ISigo a, ISigo b) { var r = ImplMerge.Merge(a, b); return(r); }
public static ISigo Merge(ISigo a, ISigo b) { if (ReferenceEquals(a, b)) { // test: same return(a); } var fa = a.Flags; var fb = b.Flags; #region leaf if (Bits.IsLeaf(fb)) { if (Bits.IsLeaf(fa)) { // test: PP_return_a_if_same return(Equals(a.Data, b.Data) ? a : b); } // test: SP_return_b_if_not_same return(b); } if (Bits.IsLeaf(fa)) { if (Bits.HasM(fb)) { return(Merge(7, b)); } else { return(a); } } #endregion leaf if (fb < 256) { if (fa < 256) { // test: EE_return_E return(Sigo.Create(7 & (fa | fb))); } else { if (Bits.HasR(fb)) { // {6, x:1} * {1} // test: NE1_return_E return(Sigo.Create(7 & (fa | fb))); } else { // {6, x:1} * {0} // {0, x:{3}} * {2} // test: NE0_return_a_if_frozen_and_flag_unchanged fb = (fb & 7) + 16; if (fb == (fa & fb)) { return(a); } // test: NE0_return_new_if_a_is_not_frozen // test: NE0_return_new_if_r_flag_change var ret = Sigo.Create(7 & (fa | fb)); foreach (var e in a) { ret = ret.Set1(e.Key, e.Value.Clone()); } return(ret); } } } else { // *N if (fa < 256) { if (Bits.HasR(fa)) { // {1} * {x:1} // test: E0 } else { // {0} * {x: {0}} } } else { if (Bits.HasR(fb)) { // {7, x:1} * {6, y:2} } else { // {7 x:1} * {3, x:{0}} } } } throw new NotImplementedException($"{a} * {b}"); }
public static ISigo Merge(ISigo a, int fb) { return(null); }
public static ISigo Merge(int fa, ISigo b) { return(null); }
public SigoWraper(ISigo sigo) { Sigo = sigo; }
public ValueSchema(object value) { Value = Sigo.From(value); }
public static ISigo Parse(string src, ISigo input, out ISigo output) { return(new SigoParser(src).Parse(input, out output)); }
public static string ToString(this ISigo sigo, Writer writer) { return(writer.WriteSigo(new StringBuilder(), sigo, 0).ToString()); }
public static bool IsTree(this ISigo sigo) { return(Bits.IsTree(sigo.Flags)); }