private bool IsTypeMatch(SpField f, SpObject o) { if (f == null || f.Type == null || o == null) { return(false); } if (f.IsTable && o.IsTable()) { return(true); } else if (f.Type == mTypeManager.String) { if (o.IsString()) { return(true); } } else if (f.Type == mTypeManager.Boolean) { if (o.IsBoolean()) { return(true); } } else if (f.Type == mTypeManager.Integer) { if (o.IsInt() || o.IsLong()) { return(true); } } else if (o.IsTable()) { return(true); } return(false); }
private bool EncodeInternal(SpType type, SpObject obj) { if (mStream == null || type == null || obj == null) { return(false); } // buildin type decoding should not be here if (mTypeManager.IsBuildinType(type)) { return(false); } int begin = mStream.Position; // fn. will be update later short fn = 0; mStream.Write(fn); List <KeyValuePair <SpObject, SpField> > objs = new List <KeyValuePair <SpObject, SpField> >(); int current_tag = -1; Dictionary <int, SpField> .ValueCollection.Enumerator en = type.Fields.Values.GetEnumerator(); while (en.MoveNext()) { SpField f = en.Current; if (f == null) { return(false); } SpObject o = obj[f.Name]; if (o == null || IsTypeMatch(f, o) == false) { continue; } if (f.Tag <= current_tag) { return(false); } if (f.Tag - current_tag > 1) { mStream.Write((short)(2 * (f.Tag - current_tag - 1) - 1)); fn++; } bool standalone = true; if (f.IsTable == false) { if (f.Type == mTypeManager.Boolean) { int value = o.AsBoolean() ? 1 : 0; mStream.Write((short)((value + 1) * 2)); standalone = false; } else if (f.Type == mTypeManager.Integer) { int value = o.AsInt(); if (value >= 0 && value < 0x7fff) { mStream.Write((short)((value + 1) * 2)); standalone = false; } } } if (standalone) { objs.Add(new KeyValuePair <SpObject, SpField>(o, f)); mStream.Write((short)0); } fn++; current_tag = f.Tag; } List <KeyValuePair <SpObject, SpField> > .Enumerator e = objs.GetEnumerator(); while (e.MoveNext()) { KeyValuePair <SpObject, SpField> entry = e.Current; if (entry.Value.IsTable) { int array_begin = mStream.Position; int size = 0; mStream.Write(size); if (entry.Value.Type == mTypeManager.Integer) { byte len = 4; Dictionary <object, SpObject> .Enumerator enumerator = entry.Key.AsTable().GetEnumerator(); while (enumerator.MoveNext()) { SpObject o = enumerator.Current.Value; if (o.IsLong()) { len = 8; break; } } mStream.Write(len); enumerator = entry.Key.AsTable().GetEnumerator(); while (enumerator.MoveNext()) { SpObject o = enumerator.Current.Value; if (len == 4) { mStream.Write(o.AsInt()); } else { mStream.Write(o.AsLong()); } } } else if (entry.Value.Type == mTypeManager.Boolean) { Dictionary <object, SpObject> .Enumerator enumerator = entry.Key.AsTable().GetEnumerator(); while (enumerator.MoveNext()) { SpObject o = enumerator.Current.Value; mStream.Write((byte)(o.AsBoolean() ? 1 : 0)); } } else if (entry.Value.Type == mTypeManager.String) { Dictionary <object, SpObject> .Enumerator enumerator = entry.Key.AsTable().GetEnumerator(); while (enumerator.MoveNext()) { SpObject o = enumerator.Current.Value; byte[] b = Encoding.UTF8.GetBytes(o.AsString()); mStream.Write(b.Length); mStream.Write(b); } } else { Dictionary <object, SpObject> .Enumerator enumerator = entry.Key.AsTable().GetEnumerator(); while (enumerator.MoveNext()) { SpObject o = enumerator.Current.Value; int obj_begin = mStream.Position; int obj_size = 0; mStream.Write(obj_size); if (EncodeInternal(entry.Value.Type, o) == false) { return(false); } int obj_end = mStream.Position; obj_size = (int)(obj_end - obj_begin - 4); mStream.Position = obj_begin; mStream.Write(obj_size); mStream.Position = obj_end; } } int array_end = mStream.Position; size = (int)(array_end - array_begin - 4); mStream.Position = array_begin; mStream.Write(size); mStream.Position = array_end; } else { if (entry.Key.IsString()) { byte[] b = Encoding.UTF8.GetBytes(entry.Key.AsString()); mStream.Write(b.Length); mStream.Write(b); } else if (entry.Key.IsInt()) { mStream.Write((int)4); mStream.Write(entry.Key.AsInt()); } else if (entry.Key.IsLong()) { mStream.Write((int)8); mStream.Write(entry.Key.AsLong()); } else if (entry.Key.IsBoolean()) { // boolean should not be here return(false); } else { int obj_begin = mStream.Position; int obj_size = 0; mStream.Write(obj_size); if (EncodeInternal(entry.Value.Type, entry.Key) == false) { return(false); } int obj_end = mStream.Position; obj_size = (int)(obj_end - obj_begin - 4); mStream.Position = obj_begin; mStream.Write(obj_size); mStream.Position = obj_end; } } } int end = mStream.Position; mStream.Position = begin; mStream.Write(fn); mStream.Position = end; return(true); }