public String Serialize(object obj) { SerializeState state = new SerializeState(); this.Serialize(obj, state); return(state.sb.ToString()); }
//Serialize(object obj) private void Serialize(Object obj, SerializeState state) { StringBuilder sb = state.sb; if (obj == null) { sb.Append("N;"); } else if (obj is string str) { if (XmlSafe) { str = str.Replace("rn", "n"); //replace rn with n str = str.Replace("r", "n"); //replace r not followed by n with a single n Should we do this? } sb.Append("s:" + StringEncoding.GetByteCount(str) + ":" + str + ";"); } else if (obj is bool b) { sb.Append("b:" + (b ? "1" : "0") + ";"); } else if (obj is int objInt) { sb.Append("i:" + objInt.ToString(_nfi) + ";"); } else if (obj is double objDbl) { sb.Append("d:" + objDbl.ToString(_nfi) + ";"); } else if ((obj is IReadOnlyDictionary <object, object>) || (obj is IDictionary <object, object>)) { if (state.seenCollections.Contains(obj)) { sb.Append("N;"); } else { state.seenCollections.Add(obj); IEnumerable <KeyValuePair <Object, Object> > asDictEnum = (IEnumerable <KeyValuePair <Object, Object> >)obj; sb.Append("a:" + asDictEnum.Count() + ":{"); foreach (var entry in asDictEnum) { this.Serialize(entry.Key, state); this.Serialize(entry.Value, state); } sb.Append("}"); } } else if (obj is IEnumerable <object> enumerable) { if (state.seenCollections.Contains(enumerable)) { sb.Append("N;"); } else { state.seenCollections.Add(enumerable); IReadOnlyList <Object> asList = enumerable as IReadOnlyList <Object>; // T[] / Array<T> implements IReadOnlyList<T> already. if (asList == null) { asList = enumerable.ToList(); } sb.Append("a:" + asList.Count + ":{"); Int32 i = 0; foreach (Object item in asList) { this.Serialize(i, state); this.Serialize(item, state); i++; } sb.Append("}"); } } else { throw new SerializationException("Value could not be serialized."); } }