Bir projemde kullanmak üzere yazdığım sınıfı paylaşmak istiyorum. Bu sınıf, PHP'de bulunan "serialize" ve "unserialize" fonksiyonlarının C# halleri yer almaktadır.
Referanslar;
using System.Collections; using System.Globalization;Sınıfın kodları;
public class Serializer
{
private readonly NumberFormatInfo _NumberFormatInfo;
private Encoding _Encoding = new UTF8Encoding();
private bool _SafeXml = true;
private int _Position;
private Dictionary<ArrayList, bool> _SeenArrayLists;
private Dictionary<Hashtable, bool> _SeenHashtables;
public Serializer()
{
_NumberFormatInfo = new NumberFormatInfo();
_NumberFormatInfo.NumberDecimalSeparator = ".";
_NumberFormatInfo.NumberGroupSeparator = "";
}
public string Serialize(dynamic Object)
{
_SeenArrayLists = new Dictionary<ArrayList, bool>();
_SeenHashtables = new Dictionary<Hashtable, bool>();
return _Serialize(Object, new StringBuilder()).ToString();
}
public dynamic Unserialize(string String)
{
_Position = 0;
return _Unserialize(String);
}
private StringBuilder _Serialize(dynamic Object, StringBuilder StringBuilder)
{
if (Object == null)
{
return StringBuilder.Append("N;");
}
if (Object is string)
{
var String = (string) Object;
if (_SafeXml)
{
String = String.Replace("\r\n", "\n");
String = String.Replace("\r", "\n");
}
return StringBuilder.Append("s:" + _Encoding.GetByteCount(String) + ":\"" + String + "\";");
}
if (Object is bool)
{
return StringBuilder.Append("b:" + (((bool) Object) ? "1" : "0") + ";");
}
if (Object is int)
{
var Integer = (int) Object;
return StringBuilder.Append("i:" + Integer.ToString(_NumberFormatInfo) + ";");
}
if (Object is double)
{
var Double = (double) Object;
return StringBuilder.Append("d:" + Double.ToString(_NumberFormatInfo) + ";");
}
if (Object is ArrayList)
{
if (_SeenArrayLists.ContainsKey((ArrayList) Object))
{
return StringBuilder.Append("N;");
}
_SeenArrayLists.Add((ArrayList) Object, true);
var ArrayList = (ArrayList) Object;
StringBuilder.Append("a:" + ArrayList.Count + ":{");
for (int Index = 0; Index < ArrayList.Count; Index++)
{
_Serialize(Index, StringBuilder);
_Serialize(ArrayList[Index], StringBuilder);
}
StringBuilder.Append("}");
return StringBuilder;
}
if (Object is Hashtable)
{
if (_SeenHashtables.ContainsKey((Hashtable) Object))
{
return StringBuilder.Append("N;");
}
_SeenHashtables.Add((Hashtable) Object, true);
var HashtableObject = (Hashtable) Object;
StringBuilder.Append("a:" + HashtableObject.Count + ":{");
foreach (DictionaryEntry Entry in HashtableObject)
{
_Serialize(Entry.Key, StringBuilder);
_Serialize(Entry.Value, StringBuilder);
}
StringBuilder.Append("}");
return StringBuilder;
}
return StringBuilder;
}
private dynamic _Unserialize(string String)
{
if (String == null || String.Length <= _Position)
{
return new Object();
}
int StartPosition, EndPosition, Length;
string StringLength;
switch (String[_Position])
{
case 'N':
_Position += 2;
return null;
case 'b':
char CharBool = String[_Position + 2];
_Position += 4;
return CharBool == '1';
case 'i':
StartPosition = String.IndexOf(":", _Position, StringComparison.Ordinal) + 1;
EndPosition = String.IndexOf(";", StartPosition, StringComparison.Ordinal);
string StringInteger = String.Substring(StartPosition, EndPosition - StartPosition);
_Position += 3 + StringInteger.Length;
return Int32.Parse(StringInteger, _NumberFormatInfo);
case 'd':
StartPosition = String.IndexOf(":", _Position, StringComparison.Ordinal) + 1;
EndPosition = String.IndexOf(";", StartPosition, StringComparison.Ordinal);
string StringDouble = String.Substring(StartPosition, EndPosition - StartPosition);
_Position += 3 + StringDouble.Length;
return Int32.Parse(StringDouble, _NumberFormatInfo);
case 's':
StartPosition = String.IndexOf(":", _Position, StringComparison.Ordinal) + 1;
EndPosition = String.IndexOf(":", StartPosition, StringComparison.Ordinal);
StringLength = String.Substring(StartPosition, EndPosition - StartPosition);
int ByteLength = Int32.Parse(StringLength);
Length = ByteLength;
if ((EndPosition + 2 + Length) >= String.Length)
{
Length = String.Length - 2 - EndPosition;
}
string StringString = String.Substring(EndPosition + 2, Length);
while (_Encoding.GetByteCount(StringString) > ByteLength)
{
Length--;
StringString = String.Substring(EndPosition + 2, Length);
}
_Position += 6 + StringLength.Length + Length;
if (_SafeXml)
{
StringString = StringString.Replace("\n", "\r\n");
}
return StringString;
case 'a':
StartPosition = String.IndexOf(":", _Position, StringComparison.Ordinal) + 1;
EndPosition = String.IndexOf(":", StartPosition, StringComparison.Ordinal);
StringLength = String.Substring(StartPosition, EndPosition - StartPosition);
Length = Int32.Parse(StringLength);
var StringHashtable = new Hashtable(Length);
var StringArrayList = new ArrayList(Length);
_Position += 4 + StringLength.Length;
for (int Index = 0; Index < Length; Index++)
{
object Key = _Unserialize(String);
object Value = _Unserialize(String);
if (StringArrayList != null)
{
if (Key is int && (int) Key == StringArrayList.Count)
{
StringArrayList.Add(Value);
}
else
{
StringArrayList = null;
}
}
StringHashtable[Key] = Value;
}
_Position++;
if (_Position < String.Length && String[_Position] == ';')
{
_Position++;
}
if (StringArrayList != null)
{
return StringArrayList;
}
return StringHashtable;
default:
return "";
}
}
}Sınıfın desteklediği veri türleri;- array (Hashtable)
- boolean
- double
- string
- integer
Sınıfın kullanımı;
/*
<?php
header('Content-Type: text/plain; charset=UTF-8');
$users = array(
array(
'id' => 1
),
array(
'id' => 2
)
);
echo serialize($users);
?>
*/
string SerializedTestData = "a:2:{i:0;a:1:{s:2:\"id\";i:1;}i:1;a:1:{s:2:\"id\";i:2;}}";
Serializer Serializer = new Serializer();
dynamic UnserializedTestData = Serializer.Unserialize(SerializedTestData);
foreach (dynamic Item in UnserializedTestData)
{
Console.WriteLine("Item: " + Item["id"]);
}
Console.ReadKey();Çıktı;