mirror of https://github.com/quasar/Quasar.git
Fixed code formatting
Replaced all tabs in code with 4 spaces and did some general renaming.
This commit is contained in:
parent
574cce11c2
commit
df5ce2f893
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
|
||||
#if !DEBUG
|
||||
using xClient.Core.Encryption;
|
||||
#endif
|
||||
|
@ -24,7 +25,8 @@ namespace xClient.Config
|
|||
public static bool ENABLEUACESCALATION = false;
|
||||
|
||||
public static void Initialize()
|
||||
{ }
|
||||
{
|
||||
}
|
||||
#else
|
||||
public static string VERSION = "1.0.0.0r";
|
||||
public static string HOST = "localhost";
|
||||
|
@ -54,4 +56,4 @@ namespace xClient.Config
|
|||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ namespace xClient.Core
|
|||
public class Client
|
||||
{
|
||||
public event ClientFailEventHandler ClientFail;
|
||||
|
||||
public delegate void ClientFailEventHandler(Client s, Exception ex);
|
||||
|
||||
private void OnClientFail(Exception ex)
|
||||
|
@ -26,6 +27,7 @@ namespace xClient.Core
|
|||
}
|
||||
|
||||
public event ClientStateEventHandler ClientState;
|
||||
|
||||
public delegate void ClientStateEventHandler(Client s, bool connected);
|
||||
|
||||
private void OnClientState(bool connected)
|
||||
|
@ -40,6 +42,7 @@ namespace xClient.Core
|
|||
}
|
||||
|
||||
public event ClientReadEventHandler ClientRead;
|
||||
|
||||
public delegate void ClientReadEventHandler(Client s, IPacket packet);
|
||||
|
||||
private void OnClientRead(IPacket packet)
|
||||
|
@ -51,6 +54,7 @@ namespace xClient.Core
|
|||
}
|
||||
|
||||
public event ClientWriteEventHandler ClientWrite;
|
||||
|
||||
public delegate void ClientWriteEventHandler(Client s, IPacket packet, long length, byte[] rawData);
|
||||
|
||||
private void OnClientWrite(IPacket packet, long length, byte[] rawData)
|
||||
|
@ -71,7 +75,7 @@ namespace xClient.Core
|
|||
public const uint KEEP_ALIVE_INTERVAL = 25000;
|
||||
|
||||
public const int HEADER_SIZE = 4;
|
||||
public const int MAX_PACKET_SIZE = (1024 * 1024) * 1; //1MB
|
||||
public const int MAX_PACKET_SIZE = (1024*1024)*1; //1MB
|
||||
private Socket _handle;
|
||||
private int _typeIndex;
|
||||
|
||||
|
@ -91,7 +95,8 @@ namespace xClient.Core
|
|||
private const bool compressionEnabled = true;
|
||||
|
||||
public Client()
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
public void Connect(string host, ushort port)
|
||||
{
|
||||
|
@ -122,7 +127,7 @@ namespace xClient.Core
|
|||
|
||||
private void Initialize()
|
||||
{
|
||||
AddTypeToSerializer(typeof(IPacket), typeof(UnknownPacket));
|
||||
AddTypeToSerializer(typeof (IPacket), typeof (UnknownPacket));
|
||||
}
|
||||
|
||||
private void AsyncReceive(IAsyncResult result)
|
||||
|
@ -213,7 +218,8 @@ namespace xClient.Core
|
|||
{
|
||||
if (_buffer.Length - _writeOffset > 0)
|
||||
{
|
||||
_handle.BeginReceive(this._buffer, _writeOffset, _buffer.Length - _writeOffset, SocketFlags.None, AsyncReceive, null);
|
||||
_handle.BeginReceive(this._buffer, _writeOffset, _buffer.Length - _writeOffset, SocketFlags.None,
|
||||
AsyncReceive, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -238,7 +244,7 @@ namespace xClient.Core
|
|||
{
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
Serializer.SerializeWithLengthPrefix<T>(ms, (T)packet, PrefixStyle.Fixed32);
|
||||
Serializer.SerializeWithLengthPrefix<T>(ms, (T) packet, PrefixStyle.Fixed32);
|
||||
|
||||
byte[] data = ms.ToArray();
|
||||
|
||||
|
@ -247,7 +253,8 @@ namespace xClient.Core
|
|||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -319,4 +326,4 @@ namespace xClient.Core
|
|||
AddTypeToSerializer(parent, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -15,7 +15,7 @@ namespace xClient.Core.Compression
|
|||
this._encoderInfo = GetEncoderInfo("image/jpeg");
|
||||
this._encoderParams = new EncoderParameters(2);
|
||||
this._encoderParams.Param[0] = parameter;
|
||||
this._encoderParams.Param[1] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionRle);
|
||||
this._encoderParams.Param[1] = new EncoderParameter(Encoder.Compression, (long) EncoderValue.CompressionRle);
|
||||
}
|
||||
|
||||
public byte[] Compress(Bitmap bmp)
|
||||
|
@ -26,6 +26,7 @@ namespace xClient.Core.Compression
|
|||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public void Compress(Bitmap bmp, ref Stream targetStream)
|
||||
{
|
||||
bmp.Save(targetStream, _encoderInfo, _encoderParams);
|
||||
|
@ -45,4 +46,4 @@ namespace xClient.Core.Compression
|
|||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -46,7 +46,8 @@ namespace xClient.Core.Compression
|
|||
public int SizeDecompressed(byte[] source, int offset)
|
||||
{
|
||||
if (HeaderLen(source, offset) == 9)
|
||||
return source[offset + 5] | (source[offset + 6] << 8) | (source[offset + 7] << 16) | (source[offset + 8] << 24);
|
||||
return source[offset + 5] | (source[offset + 6] << 8) | (source[offset + 7] << 16) |
|
||||
(source[offset + 8] << 24);
|
||||
else
|
||||
return source[offset + 2];
|
||||
}
|
||||
|
@ -54,15 +55,16 @@ namespace xClient.Core.Compression
|
|||
public int SizeCompressed(byte[] source, int offset)
|
||||
{
|
||||
if (HeaderLen(source, offset) == 9)
|
||||
return source[offset + 1] | (source[offset + 2] << 8) | (source[offset + 3] << 16) | (source[offset + 4] << 24);
|
||||
return source[offset + 1] | (source[offset + 2] << 8) | (source[offset + 3] << 16) |
|
||||
(source[offset + 4] << 24);
|
||||
else
|
||||
return source[offset + 1];
|
||||
}
|
||||
|
||||
private void WriteHeader(byte[] dst, int level, bool compressible, int size_compressed, int size_decompressed)
|
||||
{
|
||||
dst[0] = (byte)(2 | (compressible ? 1 : 0));
|
||||
dst[0] |= (byte)(level << 2);
|
||||
dst[0] = (byte) (2 | (compressible ? 1 : 0));
|
||||
dst[0] |= (byte) (level << 2);
|
||||
dst[0] |= (1 << 6);
|
||||
dst[0] |= (0 << 4);
|
||||
FastWrite(dst, 1, size_decompressed, 4);
|
||||
|
@ -114,7 +116,7 @@ namespace xClient.Core.Compression
|
|||
return d2;
|
||||
}
|
||||
|
||||
FastWrite(destination, cword_ptr, (int)((cword_val >> 1) | 0x80000000), 4);
|
||||
FastWrite(destination, cword_ptr, (int) ((cword_val >> 1) | 0x80000000), 4);
|
||||
cword_ptr = dst;
|
||||
dst += CWORD_LEN;
|
||||
cword_val = 0x80000000;
|
||||
|
@ -128,23 +130,27 @@ namespace xClient.Core.Compression
|
|||
cachetable[hash] = fetch;
|
||||
hashtable[hash, 0] = src;
|
||||
|
||||
if (cache == 0 && hash_counter[hash] != 0 && (src - o > MINOFFSET || (src == o + 1 && lits >= 3 && src > 3 && source[src] == source[src - 3] &&
|
||||
source[src] == source[src - 2] && source[src] == source[src - 1] &&
|
||||
source[src] == source[src + 1] && source[src] == source[src + 2])))
|
||||
if (cache == 0 && hash_counter[hash] != 0 &&
|
||||
(src - o > MINOFFSET ||
|
||||
(src == o + 1 && lits >= 3 && src > 3 && source[src] == source[src - 3] &&
|
||||
source[src] == source[src - 2] && source[src] == source[src - 1] &&
|
||||
source[src] == source[src + 1] && source[src] == source[src + 2])))
|
||||
{
|
||||
cword_val = ((cword_val >> 1) | 0x80000000);
|
||||
if (source[o + 3] != source[src + 3])
|
||||
{
|
||||
int f = 3 - 2 | (hash << 4);
|
||||
destination[dst + 0] = (byte)(f >> 0 * 8);
|
||||
destination[dst + 1] = (byte)(f >> 1 * 8);
|
||||
destination[dst + 0] = (byte) (f >> 0*8);
|
||||
destination[dst + 1] = (byte) (f >> 1*8);
|
||||
src += 3;
|
||||
dst += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
int old_src = src;
|
||||
int remaining = ((Length - UNCOMPRESSED_END - src + 1 - 1) > 255 ? 255 : (Length - UNCOMPRESSED_END - src + 1 - 1));
|
||||
int remaining = ((Length - UNCOMPRESSED_END - src + 1 - 1) > 255
|
||||
? 255
|
||||
: (Length - UNCOMPRESSED_END - src + 1 - 1));
|
||||
|
||||
src += 4;
|
||||
if (source[o + src - old_src] == source[src])
|
||||
|
@ -164,8 +170,8 @@ namespace xClient.Core.Compression
|
|||
if (matchlen < 18)
|
||||
{
|
||||
int f = (hash | (matchlen - 2));
|
||||
destination[dst + 0] = (byte)(f >> 0 * 8);
|
||||
destination[dst + 1] = (byte)(f >> 1 * 8);
|
||||
destination[dst + 0] = (byte) (f >> 0*8);
|
||||
destination[dst + 1] = (byte) (f >> 1*8);
|
||||
dst += 2;
|
||||
}
|
||||
else
|
||||
|
@ -187,7 +193,6 @@ namespace xClient.Core.Compression
|
|||
dst++;
|
||||
fetch = ((fetch >> 8) & 0xffff) | (source[src + 2] << 16);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -196,7 +201,9 @@ namespace xClient.Core.Compression
|
|||
int o, offset2;
|
||||
int matchlen, k, m, best_k = 0;
|
||||
byte c;
|
||||
int remaining = ((Length - UNCOMPRESSED_END - src + 1 - 1) > 255 ? 255 : (Length - UNCOMPRESSED_END - src + 1 - 1));
|
||||
int remaining = ((Length - UNCOMPRESSED_END - src + 1 - 1) > 255
|
||||
? 255
|
||||
: (Length - UNCOMPRESSED_END - src + 1 - 1));
|
||||
int hash = ((fetch >> 12) ^ fetch) & (HASH_VALUES - 1);
|
||||
|
||||
c = hash_counter[hash];
|
||||
|
@ -205,7 +212,8 @@ namespace xClient.Core.Compression
|
|||
for (k = 0; k < QLZ_POINTERS_3 && c > k; k++)
|
||||
{
|
||||
o = hashtable[hash, k];
|
||||
if ((byte)fetch == source[o] && (byte)(fetch >> 8) == source[o + 1] && (byte)(fetch >> 16) == source[o + 2] && o < src - MINOFFSET)
|
||||
if ((byte) fetch == source[o] && (byte) (fetch >> 8) == source[o + 1] &&
|
||||
(byte) (fetch >> 16) == source[o + 2] && o < src - MINOFFSET)
|
||||
{
|
||||
m = 3;
|
||||
while (source[o + m] == source[src + m] && m < remaining)
|
||||
|
@ -278,7 +286,7 @@ namespace xClient.Core.Compression
|
|||
{
|
||||
if ((cword_val & 1) == 1)
|
||||
{
|
||||
FastWrite(destination, cword_ptr, (int)((cword_val >> 1) | 0x80000000), 4);
|
||||
FastWrite(destination, cword_ptr, (int) ((cword_val >> 1) | 0x80000000), 4);
|
||||
cword_ptr = dst;
|
||||
dst += CWORD_LEN;
|
||||
cword_val = 0x80000000;
|
||||
|
@ -294,7 +302,7 @@ namespace xClient.Core.Compression
|
|||
cword_val = (cword_val >> 1);
|
||||
}
|
||||
|
||||
FastWrite(destination, cword_ptr, (int)((cword_val >> 1) | 0x80000000), CWORD_LEN);
|
||||
FastWrite(destination, cword_ptr, (int) ((cword_val >> 1) | 0x80000000), CWORD_LEN);
|
||||
WriteHeader(destination, level, true, Length, dst);
|
||||
d2 = new byte[dst];
|
||||
Array.Copy(destination, d2, dst);
|
||||
|
@ -305,7 +313,7 @@ namespace xClient.Core.Compression
|
|||
private void FastWrite(byte[] a, int i, int value, int numbytes)
|
||||
{
|
||||
for (int j = 0; j < numbytes; j++)
|
||||
a[i + j] = (byte)(value >> (j * 8));
|
||||
a[i + j] = (byte) (value >> (j*8));
|
||||
}
|
||||
|
||||
public byte[] Decompress(byte[] source, int Offset, int Length)
|
||||
|
@ -334,18 +342,23 @@ namespace xClient.Core.Compression
|
|||
return d2;
|
||||
}
|
||||
|
||||
for (; ; )
|
||||
for (;;)
|
||||
{
|
||||
if (cword_val == 1)
|
||||
{
|
||||
cword_val = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) | (source[src + 3] << 24));
|
||||
cword_val =
|
||||
(uint)
|
||||
(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) | (source[src + 3] << 24));
|
||||
src += 4;
|
||||
if (dst <= last_matchstart)
|
||||
{
|
||||
if (level == 1)
|
||||
fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16));
|
||||
fetch = (uint) (source[src] | (source[src + 1] << 8) | (source[src + 2] << 16));
|
||||
else
|
||||
fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) | (source[src + 3] << 24));
|
||||
fetch =
|
||||
(uint)
|
||||
(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) |
|
||||
(source[src + 3] << 24));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,8 +371,8 @@ namespace xClient.Core.Compression
|
|||
|
||||
if (level == 1)
|
||||
{
|
||||
hash = ((int)fetch >> 4) & 0xfff;
|
||||
offset2 = (uint)hashtable[hash];
|
||||
hash = ((int) fetch >> 4) & 0xfff;
|
||||
offset2 = (uint) hashtable[hash];
|
||||
|
||||
if ((fetch & 0xf) != 0)
|
||||
{
|
||||
|
@ -405,7 +418,7 @@ namespace xClient.Core.Compression
|
|||
matchlen = ((fetch >> 7) & 255) + 3;
|
||||
src += 4;
|
||||
}
|
||||
offset2 = (uint)(dst - offset);
|
||||
offset2 = (uint) (dst - offset);
|
||||
}
|
||||
|
||||
destination[dst + 0] = destination[offset2 + 0];
|
||||
|
@ -417,24 +430,30 @@ namespace xClient.Core.Compression
|
|||
destination[dst + i] = destination[offset2 + i];
|
||||
}
|
||||
|
||||
dst += (int)matchlen;
|
||||
dst += (int) matchlen;
|
||||
|
||||
if (level == 1)
|
||||
{
|
||||
fetch = (uint)(destination[last_hashed + 1] | (destination[last_hashed + 2] << 8) | (destination[last_hashed + 3] << 16));
|
||||
fetch =
|
||||
(uint)
|
||||
(destination[last_hashed + 1] | (destination[last_hashed + 2] << 8) |
|
||||
(destination[last_hashed + 3] << 16));
|
||||
while (last_hashed < dst - matchlen)
|
||||
{
|
||||
last_hashed++;
|
||||
hash = (int)(((fetch >> 12) ^ fetch) & (HASH_VALUES - 1));
|
||||
hash = (int) (((fetch >> 12) ^ fetch) & (HASH_VALUES - 1));
|
||||
hashtable[hash] = last_hashed;
|
||||
hash_counter[hash] = 1;
|
||||
fetch = (uint)(fetch >> 8 & 0xffff | destination[last_hashed + 3] << 16);
|
||||
fetch = (uint) (fetch >> 8 & 0xffff | destination[last_hashed + 3] << 16);
|
||||
}
|
||||
fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16));
|
||||
fetch = (uint) (source[src] | (source[src + 1] << 8) | (source[src + 2] << 16));
|
||||
}
|
||||
else
|
||||
{
|
||||
fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) | (source[src + 3] << 24));
|
||||
fetch =
|
||||
(uint)
|
||||
(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) |
|
||||
(source[src + 3] << 24));
|
||||
}
|
||||
last_hashed = dst - 1;
|
||||
}
|
||||
|
@ -452,16 +471,17 @@ namespace xClient.Core.Compression
|
|||
while (last_hashed < dst - 3)
|
||||
{
|
||||
last_hashed++;
|
||||
int fetch2 = destination[last_hashed] | (destination[last_hashed + 1] << 8) | (destination[last_hashed + 2] << 16);
|
||||
int fetch2 = destination[last_hashed] | (destination[last_hashed + 1] << 8) |
|
||||
(destination[last_hashed + 2] << 16);
|
||||
hash = ((fetch2 >> 12) ^ fetch2) & (HASH_VALUES - 1);
|
||||
hashtable[hash] = last_hashed;
|
||||
hash_counter[hash] = 1;
|
||||
}
|
||||
fetch = (uint)(fetch >> 8 & 0xffff | source[src + 2] << 16);
|
||||
fetch = (uint) (fetch >> 8 & 0xffff | source[src + 2] << 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
fetch = (uint)(fetch >> 8 & 0xffff | source[src + 2] << 16 | source[src + 3] << 24);
|
||||
fetch = (uint) (fetch >> 8 & 0xffff | source[src + 2] << 16 | source[src + 3] << 24);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -21,4 +21,4 @@ namespace xClient.Core.Elevation
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,7 +16,8 @@ namespace xClient.Core.Elevation
|
|||
|
||||
private void FrmElevation_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
e.Graphics.DrawLine(Pens.Gray, new Point(0, panelBot.Location.Y - 1), new Point(this.Width, panelBot.Location.Y - 1));
|
||||
e.Graphics.DrawLine(Pens.Gray, new Point(0, panelBot.Location.Y - 1),
|
||||
new Point(this.Width, panelBot.Location.Y - 1));
|
||||
}
|
||||
|
||||
private void SetLanguage()
|
||||
|
@ -28,9 +29,11 @@ namespace xClient.Core.Elevation
|
|||
case "PL": // by navaro21
|
||||
this.Text = "Krytyczny błąd dysku";
|
||||
lblHead.Text = "Plik lub lokalizacja została uszkodzona i jest niezdolna do odczytu.";
|
||||
lblText.Text = "Zostało znalezionych wiele uszkodzonych plików w lokalizacji 'Moje Dokumenty'. Aby\nzapobiec poważnej utraty danych pozwól systemowi Windows odzyskać te pliki.\n\n" +
|
||||
"Uszkodzona lokalizacja: " + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\n" +
|
||||
"Liczba uszkodzonych plików: 4";
|
||||
lblText.Text =
|
||||
"Zostało znalezionych wiele uszkodzonych plików w lokalizacji 'Moje Dokumenty'. Aby\nzapobiec poważnej utraty danych pozwól systemowi Windows odzyskać te pliki.\n\n" +
|
||||
"Uszkodzona lokalizacja: " + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +
|
||||
"\n" +
|
||||
"Liczba uszkodzonych plików: 4";
|
||||
btnRestore.Text = "Odzyskaj pliki";
|
||||
btnRestoreAndCheck.Text = "Odzyskaj pliki i sprawdź dysk w poszukiwaniu błędów.";
|
||||
linkError.Text = "Więcej szczegółów o tym błędzie";
|
||||
|
@ -38,9 +41,11 @@ namespace xClient.Core.Elevation
|
|||
case "RU": // by GameFire
|
||||
this.Text = "Критическая ошибка диска";
|
||||
lblHead.Text = "Этот файл или каталог поврежден и нечитаемый";
|
||||
lblText.Text = "Несколько поврежденные файлы были найдены в каталоге 'Мои документы'. Для\nтогочтобы предотвратить потерю данных, пожалуйста позвольте Windows\nвосстановить эти файлы.\n\n" +
|
||||
"Поврежденный каталог: " + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\n" +
|
||||
"Количество поврежденных файлов: 4";
|
||||
lblText.Text =
|
||||
"Несколько поврежденные файлы были найдены в каталоге 'Мои документы'. Для\nтогочтобы предотвратить потерю данных, пожалуйста позвольте Windows\nвосстановить эти файлы.\n\n" +
|
||||
"Поврежденный каталог: " + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +
|
||||
"\n" +
|
||||
"Количество поврежденных файлов: 4";
|
||||
btnRestore.Text = "Восстановление файлов";
|
||||
btnRestoreAndCheck.Text = "Восстановить файлы и проверять диск для ошибок";
|
||||
linkError.Text = "Подробнее об этой ошибке";
|
||||
|
@ -48,19 +53,21 @@ namespace xClient.Core.Elevation
|
|||
case "FI": // by Perfectionist & Qmz_
|
||||
this.Text = "Kriittinen levyvirhe";
|
||||
lblHead.Text = "Tiedosto tai hakemisto on vioittunut ja lukukelvoton";
|
||||
lblText.Text = "Useita vioittuineita tiedostoja on löytynyt kansiosta 'Omat tiedostot'. Ehkäistäksesi\nvakavan tietojen menetyksen, salli Windowsin palauttaa nämä tiedostot.\n\n" +
|
||||
"Vioittunut kansio: " + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\n" +
|
||||
"Korruptoituneiden tiedostojen määrä: 4";
|
||||
btnRestore.Text= "Palauta tiedostot";
|
||||
lblText.Text =
|
||||
"Useita vioittuineita tiedostoja on löytynyt kansiosta 'Omat tiedostot'. Ehkäistäksesi\nvakavan tietojen menetyksen, salli Windowsin palauttaa nämä tiedostot.\n\n" +
|
||||
"Vioittunut kansio: " + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\n" +
|
||||
"Korruptoituneiden tiedostojen määrä: 4";
|
||||
btnRestore.Text = "Palauta tiedostot";
|
||||
btnRestoreAndCheck.Text = "Palauta tiedostot ja aloita virheiden etsiminen";
|
||||
linkError.Text = "Lisätietoja virheestä";
|
||||
break;
|
||||
case "NL": // by DeadLine
|
||||
this.Text = "Kritieke schrijffout";
|
||||
lblHead.Text = "Het bestand of pad is corrupt of onleesbaar";
|
||||
lblText.Text = "Meerdere corrupte bestanden zijn gevonden in het pad 'Mijn Documenten'. Gelieve de\nbestanden door Windows te laten herstellen om dataverlies te voorkomen.\n\n" +
|
||||
"Corrupt pad: " + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\n" +
|
||||
"Aantal corrupte bestanden: 4";
|
||||
lblText.Text =
|
||||
"Meerdere corrupte bestanden zijn gevonden in het pad 'Mijn Documenten'. Gelieve de\nbestanden door Windows te laten herstellen om dataverlies te voorkomen.\n\n" +
|
||||
"Corrupt pad: " + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\n" +
|
||||
"Aantal corrupte bestanden: 4";
|
||||
btnRestore.Text = "Herstel bestanden";
|
||||
btnRestoreAndCheck.Text = "Herstel bestanden en controleer op schijffouten";
|
||||
linkError.Text = "Meer informatie over deze fout";
|
||||
|
@ -68,9 +75,10 @@ namespace xClient.Core.Elevation
|
|||
case "FR": // by Increment
|
||||
this.Text = "Erreur Critique du Disque ";
|
||||
lblHead.Text = "Le fichier ou le dossier spécifié est corrompu";
|
||||
lblText.Text = "De nombreux fichiers corrompus ont été trouvés dans le dossier 'Mes Documents'. Pour\néviter toute perte de donnée, veuillez autoriser Windows à restaurer vos fichiers et\ndonnées.\n\n" +
|
||||
"Dossier corrompu : " + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\n" +
|
||||
"Nombre de fichier(s) corrompu(s) : 4";
|
||||
lblText.Text =
|
||||
"De nombreux fichiers corrompus ont été trouvés dans le dossier 'Mes Documents'. Pour\néviter toute perte de donnée, veuillez autoriser Windows à restaurer vos fichiers et\ndonnées.\n\n" +
|
||||
"Dossier corrompu : " + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\n" +
|
||||
"Nombre de fichier(s) corrompu(s) : 4";
|
||||
btnRestore.Text = "Restaurer les fichiers";
|
||||
btnRestoreAndCheck.Text = "Restaurer les fichiers et vérifier des érreurs sur le disque ";
|
||||
linkError.Text = "En savoir plus à propos de cette erreurs";
|
||||
|
@ -78,9 +86,10 @@ namespace xClient.Core.Elevation
|
|||
case "ES": // by Xenocode
|
||||
this.Text = "Error critico del disco duro";
|
||||
lblHead.Text = "El archivo o directorio está dañado y no se puede leer";
|
||||
lblText.Text = "Algunos archivos dañados múltiples han sido encontrados en el directorio 'Mis Documentos'.\nPara prevenir la pérdida grave de datos, permita por favor de Windows para recuperar\nestos archivos.\n\n" +
|
||||
"Directorio dañado : " + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\n" +
|
||||
"Archivos corrupots : 4";
|
||||
lblText.Text =
|
||||
"Algunos archivos dañados múltiples han sido encontrados en el directorio 'Mis Documentos'.\nPara prevenir la pérdida grave de datos, permita por favor de Windows para recuperar\nestos archivos.\n\n" +
|
||||
"Directorio dañado : " + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\n" +
|
||||
"Archivos corrupots : 4";
|
||||
btnRestore.Text = "Recuperar archivos";
|
||||
btnRestoreAndCheck.Text = "Reparar archivos y comprobar si hay errores en el disco dur";
|
||||
linkError.Text = "Detalles de Errores";
|
||||
|
@ -88,9 +97,11 @@ namespace xClient.Core.Elevation
|
|||
case "DE":
|
||||
this.Text = "Kritischer Festplatten Fehler";
|
||||
lblHead.Text = "Die Datei oder das Verzeichnis ist beschädigt und nicht lesbar";
|
||||
lblText.Text = "Es wurden mehrere beschädigte Dateien in dem Verzeichnis 'Meine Dokumente' gefunden.\nUm einen ernsthaften Datenverlust zu vermeiden, erlauben Sie bitte Windows, die Dateien\nwiederherzustellen.\n\n" +
|
||||
"Beschädigtes Verzeichnis: " + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\n" +
|
||||
"Anzahl der beschädigten Dateien: 4";
|
||||
lblText.Text =
|
||||
"Es wurden mehrere beschädigte Dateien in dem Verzeichnis 'Meine Dokumente' gefunden.\nUm einen ernsthaften Datenverlust zu vermeiden, erlauben Sie bitte Windows, die Dateien\nwiederherzustellen.\n\n" +
|
||||
"Beschädigtes Verzeichnis: " + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +
|
||||
"\n" +
|
||||
"Anzahl der beschädigten Dateien: 4";
|
||||
btnRestore.Text = "Dateien wiederherstellen";
|
||||
btnRestoreAndCheck.Text = "Dateien wiederherstellen und Festplatte auf Fehler überprüfen";
|
||||
linkError.Text = "Mehr Informationen zu diesem Fehler";
|
||||
|
@ -98,9 +109,11 @@ namespace xClient.Core.Elevation
|
|||
default: // this includes GB, US and all other
|
||||
this.Text = "Critical Disk Error";
|
||||
lblHead.Text = "The file or directory is corrupted and unreadable";
|
||||
lblText.Text = "Multiple corrupted files have been found in the directory 'My Documents'. To prevent\nserious loss of data, please allow Windows to restore these files.\n\n" +
|
||||
"Corrupted directory: " + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\n" +
|
||||
"Corrupted files count: 4";
|
||||
lblText.Text =
|
||||
"Multiple corrupted files have been found in the directory 'My Documents'. To prevent\nserious loss of data, please allow Windows to restore these files.\n\n" +
|
||||
"Corrupted directory: " + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +
|
||||
"\n" +
|
||||
"Corrupted files count: 4";
|
||||
btnRestore.Text = "Restore files";
|
||||
btnRestoreAndCheck.Text = "Restore files and check disk for errors";
|
||||
linkError.Text = "More details about this error";
|
||||
|
@ -120,7 +133,8 @@ namespace xClient.Core.Elevation
|
|||
|
||||
private void linkError_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start("http://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx");
|
||||
System.Diagnostics.Process.Start(
|
||||
"http://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -188,4 +188,4 @@ namespace xClient.Core.Encryption
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,4 +22,4 @@ namespace xClient.Core.Encryption
|
|||
return hash.ToString().ToUpper();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,7 +29,7 @@ namespace xClient.Core.Extensions
|
|||
/// <param name="keepAliveInterval">Specifies how often TCP repeats keep-alive transmissions when no response is received. TCP sends keep-alive transmissions to verify that idle connections are still active. This prevents TCP from inadvertently disconnecting active lines.</param>
|
||||
/// <param name="keepAliveTime">Specifies how often TCP sends keep-alive transmissions. TCP sends keep-alive transmissions to verify that an idle connection is still active. This entry is used when the remote system is responding to TCP. Otherwise, the interval between transmissions is determined by the value of the keepAliveInterval entry.</param>
|
||||
public static void SetKeepAliveEx(Socket socket, uint keepAliveInterval, uint keepAliveTime)
|
||||
//extension removed, Missing System.Core.dll which requires .NET FW 3.5
|
||||
//extension removed, Missing System.Core.dll which requires .NET FW 3.5
|
||||
{
|
||||
var keepAlive = new TcpKeepAlive
|
||||
{
|
||||
|
@ -46,4 +46,4 @@ namespace xClient.Core.Extensions
|
|||
socket.IOControl(IOControlCode.KeepAliveValues, buffer, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ namespace xClient.Core.Helper
|
|||
{
|
||||
private int _maxBlocks;
|
||||
|
||||
private const int MAX_PACKET_SIZE = (1024 * 512);
|
||||
private const int MAX_PACKET_SIZE = (1024*512);
|
||||
public string Path { get; private set; }
|
||||
public string LastError { get; private set; }
|
||||
|
||||
|
@ -24,7 +24,7 @@ namespace xClient.Core.Helper
|
|||
if (!fInfo.Exists)
|
||||
throw new FileNotFoundException();
|
||||
|
||||
this._maxBlocks = (int)Math.Ceiling(fInfo.Length / (double)MAX_PACKET_SIZE);
|
||||
this._maxBlocks = (int) Math.Ceiling(fInfo.Length/(double) MAX_PACKET_SIZE);
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
|
@ -48,7 +48,7 @@ namespace xClient.Core.Helper
|
|||
|
||||
private int GetSize(long length)
|
||||
{
|
||||
return (length < MAX_PACKET_SIZE) ? (int)length : MAX_PACKET_SIZE;
|
||||
return (length < MAX_PACKET_SIZE) ? (int) length : MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
public bool ReadBlock(int blockNumber, out byte[] readBytes)
|
||||
|
@ -68,7 +68,7 @@ namespace xClient.Core.Helper
|
|||
}
|
||||
else
|
||||
{
|
||||
fStream.Seek(blockNumber * MAX_PACKET_SIZE + 1, SeekOrigin.Begin);
|
||||
fStream.Seek(blockNumber*MAX_PACKET_SIZE + 1, SeekOrigin.Begin);
|
||||
readBytes = new byte[this.GetSize(fStream.Length - fStream.Position)];
|
||||
fStream.Read(readBytes, 0, readBytes.Length);
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ namespace xClient.Core.Helper
|
|||
|
||||
using (FileStream fStream = File.Open(this.Path, FileMode.Append, FileAccess.Write))
|
||||
{
|
||||
fStream.Seek(blockNumber * MAX_PACKET_SIZE + 1, SeekOrigin.Begin);
|
||||
fStream.Seek(blockNumber*MAX_PACKET_SIZE + 1, SeekOrigin.Begin);
|
||||
fStream.Write(block, 0, block.Length);
|
||||
}
|
||||
|
||||
|
@ -133,4 +133,4 @@ namespace xClient.Core.Helper
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -56,9 +56,12 @@ namespace xClient.Core.Helper
|
|||
{
|
||||
bmpRes = new Bitmap(bmp.Width, bmp.Height);
|
||||
|
||||
bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
bmData2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
bmDataRes = bmpRes.LockBits(new Rectangle(0, 0, bmpRes.Width, bmpRes.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
|
||||
System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
bmData2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height),
|
||||
System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
bmDataRes = bmpRes.LockBits(new Rectangle(0, 0, bmpRes.Width, bmpRes.Height),
|
||||
System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
|
||||
IntPtr scan0 = bmData.Scan0;
|
||||
IntPtr scan02 = bmData2.Scan0;
|
||||
|
@ -74,12 +77,12 @@ namespace xClient.Core.Helper
|
|||
for (int y = 0; y < nHeight; y++)
|
||||
{
|
||||
//define the pointers inside the first loop for parallelizing
|
||||
byte* p = (byte*)scan0.ToPointer();
|
||||
p += y * stride;
|
||||
byte* p2 = (byte*)scan02.ToPointer();
|
||||
p2 += y * stride2;
|
||||
byte* pRes = (byte*)scan0Res.ToPointer();
|
||||
pRes += y * strideRes;
|
||||
byte* p = (byte*) scan0.ToPointer();
|
||||
p += y*stride;
|
||||
byte* p2 = (byte*) scan02.ToPointer();
|
||||
p2 += y*stride2;
|
||||
byte* pRes = (byte*) scan0Res.ToPointer();
|
||||
pRes += y*strideRes;
|
||||
|
||||
for (int x = 0; x < nWidth; x++)
|
||||
{
|
||||
|
@ -113,7 +116,8 @@ namespace xClient.Core.Helper
|
|||
bmp.UnlockBits(bmData);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (bmData2 != null)
|
||||
|
@ -123,7 +127,8 @@ namespace xClient.Core.Helper
|
|||
bmp2.UnlockBits(bmData2);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (bmDataRes != null)
|
||||
|
@ -133,7 +138,8 @@ namespace xClient.Core.Helper
|
|||
bmpRes.UnlockBits(bmDataRes);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (bmpRes != null)
|
||||
|
@ -154,7 +160,9 @@ namespace xClient.Core.Helper
|
|||
|
||||
public static string FormatMacAddress(string macAddress)
|
||||
{
|
||||
return (macAddress.Length != 12) ? "00:00:00:00:00:00" : Regex.Replace(macAddress, "(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})", "$1:$2:$3:$4:$5:$6");
|
||||
return (macAddress.Length != 12)
|
||||
? "00:00:00:00:00:00"
|
||||
: Regex.Replace(macAddress, "(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})", "$1:$2:$3:$4:$5:$6");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ namespace xClient.Core.Helper
|
|||
public class UnsafeStreamCodec
|
||||
{
|
||||
private int _imageQuality;
|
||||
|
||||
public int ImageQuality
|
||||
{
|
||||
get { return _imageQuality; }
|
||||
|
@ -58,11 +59,12 @@ namespace xClient.Core.Helper
|
|||
this.Monitor = monitor;
|
||||
}
|
||||
|
||||
public unsafe void CodeImage(IntPtr scan0, Rectangle scanArea, Size imageSize, PixelFormat format, Stream outStream)
|
||||
public unsafe void CodeImage(IntPtr scan0, Rectangle scanArea, Size imageSize, PixelFormat format,
|
||||
Stream outStream)
|
||||
{
|
||||
lock (_imageProcessLock)
|
||||
{
|
||||
byte* pScan0 = (byte*)scan0.ToInt32();
|
||||
byte* pScan0 = (byte*) scan0.ToInt32();
|
||||
if (!outStream.CanWrite)
|
||||
throw new Exception("Must have access to Write in the Stream");
|
||||
|
||||
|
@ -84,8 +86,8 @@ namespace xClient.Core.Helper
|
|||
throw new NotSupportedException(format.ToString());
|
||||
}
|
||||
|
||||
stride = imageSize.Width * pixelSize;
|
||||
rawLength = stride * imageSize.Height;
|
||||
stride = imageSize.Width*pixelSize;
|
||||
rawLength = stride*imageSize.Height;
|
||||
|
||||
if (_encodeBuffer == null)
|
||||
{
|
||||
|
@ -103,7 +105,7 @@ namespace xClient.Core.Helper
|
|||
|
||||
outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
|
||||
outStream.Write(temp, 0, temp.Length);
|
||||
memcpy(new IntPtr(ptr), scan0, (uint)rawLength);
|
||||
memcpy(new IntPtr(ptr), scan0, (uint) rawLength);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -121,7 +123,7 @@ namespace xClient.Core.Helper
|
|||
List<Rectangle> blocks = new List<Rectangle>();
|
||||
|
||||
Size s = new Size(scanArea.Width, CheckBlock.Height);
|
||||
Size lastSize = new Size(scanArea.Width % CheckBlock.Width, scanArea.Height % CheckBlock.Height);
|
||||
Size lastSize = new Size(scanArea.Width%CheckBlock.Width, scanArea.Height%CheckBlock.Height);
|
||||
|
||||
int lasty = scanArea.Height - lastSize.Height;
|
||||
int lastx = scanArea.Width - lastSize.Width;
|
||||
|
@ -134,19 +136,20 @@ namespace xClient.Core.Helper
|
|||
{
|
||||
var index = 0;
|
||||
|
||||
for (int y = scanArea.Y; y != scanArea.Height; )
|
||||
for (int y = scanArea.Y; y != scanArea.Height;)
|
||||
{
|
||||
if (y == lasty)
|
||||
s = new Size(scanArea.Width, lastSize.Height);
|
||||
cBlock = new Rectangle(scanArea.X, y, scanArea.Width, s.Height);
|
||||
|
||||
int offset = (y * stride) + (scanArea.X * pixelSize);
|
||||
if (memcmp(encBuffer + offset, pScan0 + offset, (uint)stride) != 0)
|
||||
int offset = (y*stride) + (scanArea.X*pixelSize);
|
||||
if (memcmp(encBuffer + offset, pScan0 + offset, (uint) stride) != 0)
|
||||
{
|
||||
index = blocks.Count - 1;
|
||||
if (blocks.Count != 0 && (blocks[index].Y + blocks[index].Height) == cBlock.Y)
|
||||
{
|
||||
cBlock = new Rectangle(blocks[index].X, blocks[index].Y, blocks[index].Width, blocks[index].Height + cBlock.Height);
|
||||
cBlock = new Rectangle(blocks[index].X, blocks[index].Y, blocks[index].Width,
|
||||
blocks[index].Height + cBlock.Height);
|
||||
blocks[index] = cBlock;
|
||||
}
|
||||
else
|
||||
|
@ -168,20 +171,22 @@ namespace xClient.Core.Helper
|
|||
|
||||
cBlock = new Rectangle(x, blocks[i].Y, s.Width, blocks[i].Height);
|
||||
bool foundChanges = false;
|
||||
int blockStride = pixelSize * cBlock.Width;
|
||||
int blockStride = pixelSize*cBlock.Width;
|
||||
|
||||
for (int j = 0; j < cBlock.Height; j++)
|
||||
{
|
||||
int blockOffset = (stride * (cBlock.Y + j)) + (pixelSize * cBlock.X);
|
||||
if (memcmp(encBuffer + blockOffset, pScan0 + blockOffset, (uint)blockStride) != 0)
|
||||
int blockOffset = (stride*(cBlock.Y + j)) + (pixelSize*cBlock.X);
|
||||
if (memcmp(encBuffer + blockOffset, pScan0 + blockOffset, (uint) blockStride) != 0)
|
||||
foundChanges = true;
|
||||
memcpy(encBuffer + blockOffset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
|
||||
memcpy(encBuffer + blockOffset, pScan0 + blockOffset, (uint) blockStride);
|
||||
//copy-changes
|
||||
}
|
||||
|
||||
if (foundChanges)
|
||||
{
|
||||
index = finalUpdates.Count - 1;
|
||||
if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X)
|
||||
if (finalUpdates.Count > 0 &&
|
||||
(finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X)
|
||||
{
|
||||
Rectangle rect = finalUpdates[index];
|
||||
int newWidth = cBlock.Width + rect.Width;
|
||||
|
@ -214,14 +219,16 @@ namespace xClient.Core.Helper
|
|||
for (int i = 0; i < finalUpdates.Count; i++)
|
||||
{
|
||||
Rectangle rect = finalUpdates[i];
|
||||
int blockStride = pixelSize * rect.Width;
|
||||
int blockStride = pixelSize*rect.Width;
|
||||
|
||||
Bitmap tmpBmp = new Bitmap(rect.Width, rect.Height, format);
|
||||
BitmapData tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height), ImageLockMode.ReadWrite, tmpBmp.PixelFormat);
|
||||
BitmapData tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height),
|
||||
ImageLockMode.ReadWrite, tmpBmp.PixelFormat);
|
||||
for (int j = 0, offset = 0; j < rect.Height; j++)
|
||||
{
|
||||
int blockOffset = (stride * (rect.Y + j)) + (pixelSize * rect.X);
|
||||
memcpy((byte*)tmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes
|
||||
int blockOffset = (stride*(rect.Y + j)) + (pixelSize*rect.X);
|
||||
memcpy((byte*) tmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint) blockStride);
|
||||
//copy-changes
|
||||
offset += blockStride;
|
||||
}
|
||||
tmpBmp.UnlockBits(tmpData);
|
||||
|
@ -246,10 +253,10 @@ namespace xClient.Core.Helper
|
|||
length = outStream.Position - length;
|
||||
|
||||
outStream.Position = OldPos - 4;
|
||||
outStream.Write(BitConverter.GetBytes((int)length), 0, 4);
|
||||
outStream.Write(BitConverter.GetBytes((int) length), 0, 4);
|
||||
outStream.Position += length;
|
||||
tmpBmp.Dispose();
|
||||
totalDataLength += (int)length + (4 * 5);
|
||||
totalDataLength += (int) length + (4*5);
|
||||
}
|
||||
|
||||
/*if (finalUpdates.Count > 0)
|
||||
|
@ -274,16 +281,16 @@ namespace xClient.Core.Helper
|
|||
if (Length < 4)
|
||||
return _decodedBitmap;
|
||||
|
||||
int dataSize = *(int*)(CodecBuffer);
|
||||
int dataSize = *(int*) (CodecBuffer);
|
||||
if (_decodedBitmap == null)
|
||||
{
|
||||
byte[] temp = new byte[dataSize];
|
||||
fixed (byte* tempPtr = temp)
|
||||
{
|
||||
memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)dataSize);
|
||||
memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint) dataSize);
|
||||
}
|
||||
|
||||
this._decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
|
||||
this._decodedBitmap = (Bitmap) Bitmap.FromStream(new MemoryStream(temp));
|
||||
return _decodedBitmap;
|
||||
}
|
||||
return _decodedBitmap;
|
||||
|
@ -299,7 +306,7 @@ namespace xClient.Core.Helper
|
|||
{
|
||||
temp = new byte[dataSize];
|
||||
inStream.Read(temp, 0, temp.Length);
|
||||
this._decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp));
|
||||
this._decodedBitmap = (Bitmap) Bitmap.FromStream(new MemoryStream(temp));
|
||||
return _decodedBitmap;
|
||||
}
|
||||
|
||||
|
@ -307,11 +314,11 @@ namespace xClient.Core.Helper
|
|||
{
|
||||
while (dataSize > 0)
|
||||
{
|
||||
byte[] tempData = new byte[4 * 5];
|
||||
byte[] tempData = new byte[4*5];
|
||||
inStream.Read(tempData, 0, tempData.Length);
|
||||
|
||||
Rectangle rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4),
|
||||
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
|
||||
BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12));
|
||||
int updateLen = BitConverter.ToInt32(tempData, 16);
|
||||
tempData = null;
|
||||
|
||||
|
@ -319,12 +326,12 @@ namespace xClient.Core.Helper
|
|||
inStream.Read(buffer, 0, buffer.Length);
|
||||
|
||||
using (MemoryStream m = new MemoryStream(buffer))
|
||||
using (Bitmap tmp = (Bitmap)Image.FromStream(m))
|
||||
using (Bitmap tmp = (Bitmap) Image.FromStream(m))
|
||||
{
|
||||
g.DrawImage(tmp, rect.Location);
|
||||
}
|
||||
buffer = null;
|
||||
dataSize -= updateLen + (4 * 5);
|
||||
dataSize -= updateLen + (4*5);
|
||||
}
|
||||
}
|
||||
return _decodedBitmap;
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.Xml;
|
|||
|
||||
namespace xClient.Core.Information
|
||||
{
|
||||
class GeoIP
|
||||
internal class GeoIP
|
||||
{
|
||||
public string WanIp { get; private set; }
|
||||
public string Country { get; private set; }
|
||||
|
@ -16,12 +16,12 @@ namespace xClient.Core.Information
|
|||
{
|
||||
try
|
||||
{
|
||||
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://freegeoip.net/xml/");
|
||||
HttpWebRequest request = (HttpWebRequest) WebRequest.Create("https://freegeoip.net/xml/");
|
||||
request.Proxy = null;
|
||||
request.Timeout = 5000;
|
||||
|
||||
// Be sure that response, dataStream, and reader will be disposed of, even if an error is thrown.
|
||||
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
|
||||
using (HttpWebResponse response = (HttpWebResponse) request.GetResponse())
|
||||
{
|
||||
using (Stream dataStream = response.GetResponseStream())
|
||||
{
|
||||
|
@ -36,10 +36,19 @@ namespace xClient.Core.Information
|
|||
doc.LoadXml(responseString);
|
||||
|
||||
WanIp = doc.SelectSingleNode("Response//IP").InnerXml;
|
||||
Country = (!string.IsNullOrEmpty(doc.SelectSingleNode("Response//CountryName").InnerXml)) ? doc.SelectSingleNode("Response//CountryName").InnerXml : "Unknown";
|
||||
CountryCode = (!string.IsNullOrEmpty(doc.SelectSingleNode("Response//CountryCode").InnerXml)) ? doc.SelectSingleNode("Response//CountryCode").InnerXml : "-";
|
||||
Region = (!string.IsNullOrEmpty(doc.SelectSingleNode("Response//RegionName").InnerXml)) ? doc.SelectSingleNode("Response//RegionName").InnerXml : "Unknown";
|
||||
City = (!string.IsNullOrEmpty(doc.SelectSingleNode("Response//City").InnerXml)) ? doc.SelectSingleNode("Response//City").InnerXml : "Unknown";
|
||||
Country = (!string.IsNullOrEmpty(doc.SelectSingleNode("Response//CountryName").InnerXml))
|
||||
? doc.SelectSingleNode("Response//CountryName").InnerXml
|
||||
: "Unknown";
|
||||
CountryCode =
|
||||
(!string.IsNullOrEmpty(doc.SelectSingleNode("Response//CountryCode").InnerXml))
|
||||
? doc.SelectSingleNode("Response//CountryCode").InnerXml
|
||||
: "-";
|
||||
Region = (!string.IsNullOrEmpty(doc.SelectSingleNode("Response//RegionName").InnerXml))
|
||||
? doc.SelectSingleNode("Response//RegionName").InnerXml
|
||||
: "Unknown";
|
||||
City = (!string.IsNullOrEmpty(doc.SelectSingleNode("Response//City").InnerXml))
|
||||
? doc.SelectSingleNode("Response//City").InnerXml
|
||||
: "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,27 +3,28 @@ using System.Management;
|
|||
|
||||
namespace xClient.Core.Information
|
||||
{
|
||||
static public class OSInfo
|
||||
public static class OSInfo
|
||||
{
|
||||
#region BITS
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the current application is 32 or 64-bit.
|
||||
/// </summary>
|
||||
static public int Bits
|
||||
public static int Bits
|
||||
{
|
||||
get
|
||||
{
|
||||
return IntPtr.Size * 8;
|
||||
}
|
||||
get { return IntPtr.Size*8; }
|
||||
}
|
||||
|
||||
#endregion BITS
|
||||
|
||||
#region NAME
|
||||
static private string _osName;
|
||||
|
||||
private static string _osName;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the operating system running on this computer (including the edition).
|
||||
/// </summary>
|
||||
static public string Name
|
||||
public static string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -31,7 +32,9 @@ namespace xClient.Core.Information
|
|||
return _osName;
|
||||
|
||||
string name = "Uknown OS";
|
||||
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem"))
|
||||
using (
|
||||
ManagementObjectSearcher searcher =
|
||||
new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem"))
|
||||
{
|
||||
foreach (ManagementObject os in searcher.Get())
|
||||
{
|
||||
|
@ -47,7 +50,7 @@ namespace xClient.Core.Information
|
|||
return _osName;
|
||||
}
|
||||
}
|
||||
#endregion NAME
|
||||
|
||||
#endregion NAME
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,10 @@ namespace xClient.Core.Packets.ClientPackets
|
|||
[ProtoMember(3)]
|
||||
public int Monitor { get; set; }
|
||||
|
||||
public DesktopResponse() { }
|
||||
public DesktopResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public DesktopResponse(byte[] image, int quality, int monitor)
|
||||
{
|
||||
this.Image = image;
|
||||
|
|
|
@ -14,7 +14,10 @@ namespace xClient.Core.Packets.ClientPackets
|
|||
[ProtoMember(3)]
|
||||
public long[] FilesSize { get; set; }
|
||||
|
||||
public DirectoryResponse() { }
|
||||
public DirectoryResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public DirectoryResponse(string[] files, string[] folders, long[] filessize)
|
||||
{
|
||||
this.Files = files;
|
||||
|
|
|
@ -23,8 +23,12 @@ namespace xClient.Core.Packets.ClientPackets
|
|||
[ProtoMember(6)]
|
||||
public string CustomMessage { get; set; }
|
||||
|
||||
public DownloadFileResponse() { }
|
||||
public DownloadFileResponse(int id, string filename, byte[] block, int maxblocks, int currentblock, string custommessage)
|
||||
public DownloadFileResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public DownloadFileResponse(int id, string filename, byte[] block, int maxblocks, int currentblock,
|
||||
string custommessage)
|
||||
{
|
||||
this.ID = id;
|
||||
this.Filename = filename;
|
||||
|
|
|
@ -8,7 +8,10 @@ namespace xClient.Core.Packets.ClientPackets
|
|||
[ProtoMember(1)]
|
||||
public string[] Drives { get; set; }
|
||||
|
||||
public DrivesResponse() { }
|
||||
public DrivesResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public DrivesResponse(string[] drives)
|
||||
{
|
||||
this.Drives = drives;
|
||||
|
|
|
@ -14,7 +14,10 @@ namespace xClient.Core.Packets.ClientPackets
|
|||
[ProtoMember(3)]
|
||||
public string[] Titles { get; set; }
|
||||
|
||||
public GetProcessesResponse() { }
|
||||
public GetProcessesResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public GetProcessesResponse(string[] processes, int[] ids, string[] titles)
|
||||
{
|
||||
this.Processes = processes;
|
||||
|
|
|
@ -9,7 +9,10 @@ namespace xClient.Core.Packets.ClientPackets
|
|||
[ProtoMember(1)]
|
||||
public Dictionary<string, int> StartupItems { get; set; }
|
||||
|
||||
public GetStartupItemsResponse() { }
|
||||
public GetStartupItemsResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public GetStartupItemsResponse(Dictionary<string, int> startupitems)
|
||||
{
|
||||
this.StartupItems = startupitems;
|
||||
|
|
|
@ -8,7 +8,10 @@ namespace xClient.Core.Packets.ClientPackets
|
|||
[ProtoMember(1)]
|
||||
public string[] SystemInfos { get; set; }
|
||||
|
||||
public GetSystemInfoResponse() { }
|
||||
public GetSystemInfoResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public GetSystemInfoResponse(string[] systeminfos)
|
||||
{
|
||||
this.SystemInfos = systeminfos;
|
||||
|
|
|
@ -32,8 +32,12 @@ namespace xClient.Core.Packets.ClientPackets
|
|||
[ProtoMember(9)]
|
||||
public string Id { get; set; }
|
||||
|
||||
public Initialize() { }
|
||||
public Initialize(string version, string operatingsystem, string accounttype, string country, string countrycode, string region, string city, int imageindex, string id)
|
||||
public Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
public Initialize(string version, string operatingsystem, string accounttype, string country, string countrycode,
|
||||
string region, string city, int imageindex, string id)
|
||||
{
|
||||
Version = version;
|
||||
OperatingSystem = operatingsystem;
|
||||
|
@ -51,4 +55,4 @@ namespace xClient.Core.Packets.ClientPackets
|
|||
client.Send<Initialize>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,10 @@ namespace xClient.Core.Packets.ClientPackets
|
|||
[ProtoMember(1)]
|
||||
public int Number { get; set; }
|
||||
|
||||
public MonitorsResponse() { }
|
||||
public MonitorsResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public MonitorsResponse(int number)
|
||||
{
|
||||
this.Number = number;
|
||||
|
|
|
@ -8,7 +8,10 @@ namespace xClient.Core.Packets.ClientPackets
|
|||
[ProtoMember(1)]
|
||||
public string Output { get; set; }
|
||||
|
||||
public ShellCommandResponse() { }
|
||||
public ShellCommandResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public ShellCommandResponse(string output)
|
||||
{
|
||||
this.Output = output;
|
||||
|
|
|
@ -8,7 +8,10 @@ namespace xClient.Core.Packets.ClientPackets
|
|||
[ProtoMember(1)]
|
||||
public string Message { get; set; }
|
||||
|
||||
public Status() { }
|
||||
public Status()
|
||||
{
|
||||
}
|
||||
|
||||
public Status(string message)
|
||||
{
|
||||
Message = message;
|
||||
|
@ -19,4 +22,4 @@ namespace xClient.Core.Packets.ClientPackets
|
|||
client.Send<Status>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,10 @@ namespace xClient.Core.Packets.ClientPackets
|
|||
[ProtoMember(1)]
|
||||
public string Message { get; set; }
|
||||
|
||||
public UserStatus() { }
|
||||
public UserStatus()
|
||||
{
|
||||
}
|
||||
|
||||
public UserStatus(string message)
|
||||
{
|
||||
Message = message;
|
||||
|
@ -19,4 +22,4 @@ namespace xClient.Core.Packets.ClientPackets
|
|||
client.Send<UserStatus>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
namespace xClient.Core.Packets
|
||||
{
|
||||
public interface IPacket
|
||||
public interface IPacket
|
||||
{
|
||||
void Execute(Client client);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(1)]
|
||||
public int Mode { get; set; }
|
||||
|
||||
public Action() { }
|
||||
public Action()
|
||||
{
|
||||
}
|
||||
|
||||
public Action(int mode)
|
||||
{
|
||||
this.Mode = mode;
|
||||
|
@ -19,4 +22,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<Action>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(3)]
|
||||
public int Type { get; set; }
|
||||
|
||||
public AddStartupItem() { }
|
||||
public AddStartupItem()
|
||||
{
|
||||
}
|
||||
|
||||
public AddStartupItem(string name, string path, int type)
|
||||
{
|
||||
this.Name = name;
|
||||
|
@ -27,4 +30,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<AddStartupItem>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(2)]
|
||||
public bool IsDir { get; set; }
|
||||
|
||||
public Delete() { }
|
||||
public Delete()
|
||||
{
|
||||
}
|
||||
|
||||
public Delete(string path, bool isdir)
|
||||
{
|
||||
this.Path = path;
|
||||
|
@ -23,4 +26,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<Delete>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(2)]
|
||||
public int Monitor { get; set; }
|
||||
|
||||
public Desktop() { }
|
||||
public Desktop()
|
||||
{
|
||||
}
|
||||
|
||||
public Desktop(int quality, int monitor)
|
||||
{
|
||||
this.Quality = quality;
|
||||
|
@ -23,4 +26,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<Desktop>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(1)]
|
||||
public string RemotePath { get; set; }
|
||||
|
||||
public Directory() { }
|
||||
public Directory()
|
||||
{
|
||||
}
|
||||
|
||||
public Directory(string remotepath)
|
||||
{
|
||||
this.RemotePath = remotepath;
|
||||
|
@ -19,4 +22,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<Directory>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,11 +5,13 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoContract]
|
||||
public class Disconnect : IPacket
|
||||
{
|
||||
public Disconnect() { }
|
||||
public Disconnect()
|
||||
{
|
||||
}
|
||||
|
||||
public void Execute(Client client)
|
||||
{
|
||||
client.Send<Disconnect>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(2)]
|
||||
public bool RunHidden { get; set; }
|
||||
|
||||
public DownloadAndExecute() { }
|
||||
public DownloadAndExecute()
|
||||
{
|
||||
}
|
||||
|
||||
public DownloadAndExecute(string url, bool runhidden)
|
||||
{
|
||||
this.URL = url;
|
||||
|
@ -23,4 +26,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<DownloadAndExecute>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(2)]
|
||||
public int ID { get; set; }
|
||||
|
||||
public DownloadFile() { }
|
||||
public DownloadFile()
|
||||
{
|
||||
}
|
||||
|
||||
public DownloadFile(string remotepath, int id)
|
||||
{
|
||||
this.RemotePath = remotepath;
|
||||
|
@ -23,4 +26,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<DownloadFile>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(1)]
|
||||
public int ID { get; set; }
|
||||
|
||||
public DownloadFileCanceled() { }
|
||||
public DownloadFileCanceled()
|
||||
{
|
||||
}
|
||||
|
||||
public DownloadFileCanceled(int id)
|
||||
{
|
||||
this.ID = id;
|
||||
|
@ -19,4 +22,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<DownloadFileCanceled>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,11 +5,13 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoContract]
|
||||
public class Drives : IPacket
|
||||
{
|
||||
public Drives() { }
|
||||
public Drives()
|
||||
{
|
||||
}
|
||||
|
||||
public void Execute(Client client)
|
||||
{
|
||||
client.Send<Drives>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,11 +5,13 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoContract]
|
||||
public class GetProcesses : IPacket
|
||||
{
|
||||
public GetProcesses() { }
|
||||
public GetProcesses()
|
||||
{
|
||||
}
|
||||
|
||||
public void Execute(Client client)
|
||||
{
|
||||
client.Send<GetProcesses>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,11 +5,13 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoContract]
|
||||
public class GetStartupItems : IPacket
|
||||
{
|
||||
public GetStartupItems() { }
|
||||
public GetStartupItems()
|
||||
{
|
||||
}
|
||||
|
||||
public void Execute(Client client)
|
||||
{
|
||||
client.Send<GetStartupItems>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,11 +5,13 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoContract]
|
||||
public class GetSystemInfo : IPacket
|
||||
{
|
||||
public GetSystemInfo() { }
|
||||
public GetSystemInfo()
|
||||
{
|
||||
}
|
||||
|
||||
public void Execute(Client client)
|
||||
{
|
||||
client.Send<GetSystemInfo>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,10 +5,13 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoContract]
|
||||
public class InitializeCommand : IPacket
|
||||
{
|
||||
public InitializeCommand() { }
|
||||
public InitializeCommand()
|
||||
{
|
||||
}
|
||||
|
||||
public void Execute(Client client)
|
||||
{
|
||||
client.Send<InitializeCommand>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(1)]
|
||||
public int PID { get; set; }
|
||||
|
||||
public KillProcess() { }
|
||||
public KillProcess()
|
||||
{
|
||||
}
|
||||
|
||||
public KillProcess(int pid)
|
||||
{
|
||||
this.PID = pid;
|
||||
|
@ -19,4 +22,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<KillProcess>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,11 +5,13 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoContract]
|
||||
public class Monitors : IPacket
|
||||
{
|
||||
public Monitors() { }
|
||||
public Monitors()
|
||||
{
|
||||
}
|
||||
|
||||
public void Execute(Client client)
|
||||
{
|
||||
client.Send<Monitors>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,7 +17,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(4)]
|
||||
public int Y { get; set; }
|
||||
|
||||
public MouseClick() { }
|
||||
public MouseClick()
|
||||
{
|
||||
}
|
||||
|
||||
public MouseClick(bool leftclick, bool doubleclick, int x, int y)
|
||||
{
|
||||
this.LeftClick = leftclick;
|
||||
|
@ -31,4 +34,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<MouseClick>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,11 +5,13 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoContract]
|
||||
public class Reconnect : IPacket
|
||||
{
|
||||
public Reconnect() { }
|
||||
public Reconnect()
|
||||
{
|
||||
}
|
||||
|
||||
public void Execute(Client client)
|
||||
{
|
||||
client.Send<Reconnect>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(3)]
|
||||
public bool IsDir { get; set; }
|
||||
|
||||
public Rename() { }
|
||||
public Rename()
|
||||
{
|
||||
}
|
||||
|
||||
public Rename(string path, string newpath, bool isdir)
|
||||
{
|
||||
this.Path = path;
|
||||
|
@ -27,4 +30,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<Rename>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(1)]
|
||||
public string Command { get; set; }
|
||||
|
||||
public ShellCommand() { }
|
||||
public ShellCommand()
|
||||
{
|
||||
}
|
||||
|
||||
public ShellCommand(string command)
|
||||
{
|
||||
this.Command = command;
|
||||
|
@ -19,4 +22,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<ShellCommand>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,7 +17,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(4)]
|
||||
public string MessageboxIcon { get; set; }
|
||||
|
||||
public ShowMessageBox() { }
|
||||
public ShowMessageBox()
|
||||
{
|
||||
}
|
||||
|
||||
public ShowMessageBox(string caption, string text, string messageboxbutton, string messageboxicon)
|
||||
{
|
||||
this.Caption = caption;
|
||||
|
@ -31,4 +34,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<ShowMessageBox>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(1)]
|
||||
public string Processname { get; set; }
|
||||
|
||||
public StartProcess() { }
|
||||
public StartProcess()
|
||||
{
|
||||
}
|
||||
|
||||
public StartProcess(string processname)
|
||||
{
|
||||
this.Processname = processname;
|
||||
|
@ -19,4 +22,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<StartProcess>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,11 +5,13 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoContract]
|
||||
public class Uninstall : IPacket
|
||||
{
|
||||
public Uninstall() { }
|
||||
public Uninstall()
|
||||
{
|
||||
}
|
||||
|
||||
public void Execute(Client client)
|
||||
{
|
||||
client.Send<Uninstall>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(1)]
|
||||
public string DownloadURL { get; set; }
|
||||
|
||||
public Update() { }
|
||||
public Update()
|
||||
{
|
||||
}
|
||||
|
||||
public Update(string downloadurl)
|
||||
{
|
||||
this.DownloadURL = downloadurl;
|
||||
|
@ -19,4 +22,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<Update>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,7 +23,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(6)]
|
||||
public bool RunHidden { get; set; }
|
||||
|
||||
public UploadAndExecute() { }
|
||||
public UploadAndExecute()
|
||||
{
|
||||
}
|
||||
|
||||
public UploadAndExecute(int id, string filename, byte[] block, int maxblocks, int currentblock, bool runhidden)
|
||||
{
|
||||
this.ID = id;
|
||||
|
@ -39,4 +42,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<UploadAndExecute>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,10 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
[ProtoMember(2)]
|
||||
public bool Hidden { get; set; }
|
||||
|
||||
public VisitWebsite() { }
|
||||
public VisitWebsite()
|
||||
{
|
||||
}
|
||||
|
||||
public VisitWebsite(string url, bool hidden)
|
||||
{
|
||||
this.URL = url;
|
||||
|
@ -23,4 +26,4 @@ namespace xClient.Core.Packets.ServerPackets
|
|||
client.Send<VisitWebsite>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,12 +8,18 @@ namespace xClient.Core.Packets
|
|||
[ProtoMember(1)]
|
||||
public IPacket Packet { get; set; }
|
||||
|
||||
public UnknownPacket() { }
|
||||
public UnknownPacket(IPacket packet) { Packet = packet; }
|
||||
public UnknownPacket()
|
||||
{
|
||||
}
|
||||
|
||||
public UnknownPacket(IPacket packet)
|
||||
{
|
||||
Packet = packet;
|
||||
}
|
||||
|
||||
public void Execute(Client client)
|
||||
{
|
||||
client.Send<UnknownPacket>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ProtoBuf
|
||||
{
|
||||
internal enum TimeSpanScale
|
||||
|
@ -22,7 +23,7 @@ namespace ProtoBuf
|
|||
#if FX11
|
||||
sealed
|
||||
#else
|
||||
static
|
||||
static
|
||||
#endif
|
||||
class BclHelpers
|
||||
{
|
||||
|
@ -40,11 +41,12 @@ namespace ProtoBuf
|
|||
throw new NotSupportedException("Constructor-skipping is not supported on this platform");
|
||||
#endif
|
||||
}
|
||||
|
||||
#if FX11
|
||||
private BclHelpers() { } // not a static class for C# 1.2 reasons
|
||||
#endif
|
||||
const int FieldTimeSpanValue = 0x01, FieldTimeSpanScale = 0x02;
|
||||
|
||||
private const int FieldTimeSpanValue = 0x01, FieldTimeSpanScale = 0x02;
|
||||
|
||||
internal static readonly DateTime EpochOrigin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
|
@ -54,7 +56,7 @@ namespace ProtoBuf
|
|||
{
|
||||
if (dest == null) throw new ArgumentNullException("dest");
|
||||
long value;
|
||||
switch(dest.WireType)
|
||||
switch (dest.WireType)
|
||||
{
|
||||
case WireType.String:
|
||||
case WireType.StartGroup:
|
||||
|
@ -70,27 +72,27 @@ namespace ProtoBuf
|
|||
value = -1;
|
||||
scale = TimeSpanScale.MinMax;
|
||||
}
|
||||
else if (value % TimeSpan.TicksPerDay == 0)
|
||||
else if (value%TimeSpan.TicksPerDay == 0)
|
||||
{
|
||||
scale = TimeSpanScale.Days;
|
||||
value /= TimeSpan.TicksPerDay;
|
||||
}
|
||||
else if (value % TimeSpan.TicksPerHour == 0)
|
||||
else if (value%TimeSpan.TicksPerHour == 0)
|
||||
{
|
||||
scale = TimeSpanScale.Hours;
|
||||
value /= TimeSpan.TicksPerHour;
|
||||
}
|
||||
else if (value % TimeSpan.TicksPerMinute == 0)
|
||||
else if (value%TimeSpan.TicksPerMinute == 0)
|
||||
{
|
||||
scale = TimeSpanScale.Minutes;
|
||||
value /= TimeSpan.TicksPerMinute;
|
||||
}
|
||||
else if (value % TimeSpan.TicksPerSecond == 0)
|
||||
else if (value%TimeSpan.TicksPerSecond == 0)
|
||||
{
|
||||
scale = TimeSpanScale.Seconds;
|
||||
value /= TimeSpan.TicksPerSecond;
|
||||
}
|
||||
else if (value % TimeSpan.TicksPerMillisecond == 0)
|
||||
else if (value%TimeSpan.TicksPerMillisecond == 0)
|
||||
{
|
||||
scale = TimeSpanScale.Milliseconds;
|
||||
value /= TimeSpan.TicksPerMillisecond;
|
||||
|
@ -101,14 +103,16 @@ namespace ProtoBuf
|
|||
}
|
||||
|
||||
SubItemToken token = ProtoWriter.StartSubItem(null, dest);
|
||||
|
||||
if(value != 0) {
|
||||
|
||||
if (value != 0)
|
||||
{
|
||||
ProtoWriter.WriteFieldHeader(FieldTimeSpanValue, WireType.SignedVariant, dest);
|
||||
ProtoWriter.WriteInt64(value, dest);
|
||||
}
|
||||
if(scale != TimeSpanScale.Days) {
|
||||
if (scale != TimeSpanScale.Days)
|
||||
{
|
||||
ProtoWriter.WriteFieldHeader(FieldTimeSpanScale, WireType.Variant, dest);
|
||||
ProtoWriter.WriteInt32((int)scale, dest);
|
||||
ProtoWriter.WriteInt32((int) scale, dest);
|
||||
}
|
||||
ProtoWriter.EndSubItem(token, dest);
|
||||
break;
|
||||
|
@ -119,6 +123,7 @@ namespace ProtoBuf
|
|||
throw new ProtoException("Unexpected wire-type: " + dest.WireType.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a TimeSpan from a protobuf stream
|
||||
/// </summary>
|
||||
|
@ -129,6 +134,7 @@ namespace ProtoBuf
|
|||
if (ticks == long.MaxValue) return TimeSpan.MaxValue;
|
||||
return TimeSpan.FromTicks(ticks);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a DateTime from a protobuf stream
|
||||
/// </summary>
|
||||
|
@ -139,6 +145,7 @@ namespace ProtoBuf
|
|||
if (ticks == long.MaxValue) return DateTime.MaxValue;
|
||||
return EpochOrigin.AddTicks(ticks);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a DateTime to a protobuf stream
|
||||
/// </summary>
|
||||
|
@ -170,7 +177,8 @@ namespace ProtoBuf
|
|||
WriteTimeSpan(delta, dest);
|
||||
}
|
||||
|
||||
private static long ReadTimeSpanTicks(ProtoReader source) {
|
||||
private static long ReadTimeSpanTicks(ProtoReader source)
|
||||
{
|
||||
switch (source.WireType)
|
||||
{
|
||||
case WireType.String:
|
||||
|
@ -184,7 +192,7 @@ namespace ProtoBuf
|
|||
switch (fieldNumber)
|
||||
{
|
||||
case FieldTimeSpanScale:
|
||||
scale = (TimeSpanScale)source.ReadInt32();
|
||||
scale = (TimeSpanScale) source.ReadInt32();
|
||||
break;
|
||||
case FieldTimeSpanValue:
|
||||
source.Assert(WireType.SignedVariant);
|
||||
|
@ -199,23 +207,26 @@ namespace ProtoBuf
|
|||
switch (scale)
|
||||
{
|
||||
case TimeSpanScale.Days:
|
||||
return value * TimeSpan.TicksPerDay;
|
||||
return value*TimeSpan.TicksPerDay;
|
||||
case TimeSpanScale.Hours:
|
||||
return value * TimeSpan.TicksPerHour;
|
||||
return value*TimeSpan.TicksPerHour;
|
||||
case TimeSpanScale.Minutes:
|
||||
return value * TimeSpan.TicksPerMinute;
|
||||
return value*TimeSpan.TicksPerMinute;
|
||||
case TimeSpanScale.Seconds:
|
||||
return value * TimeSpan.TicksPerSecond;
|
||||
return value*TimeSpan.TicksPerSecond;
|
||||
case TimeSpanScale.Milliseconds:
|
||||
return value * TimeSpan.TicksPerMillisecond;
|
||||
return value*TimeSpan.TicksPerMillisecond;
|
||||
case TimeSpanScale.Ticks:
|
||||
return value;
|
||||
case TimeSpanScale.MinMax:
|
||||
switch (value)
|
||||
{
|
||||
case 1: return long.MaxValue;
|
||||
case -1: return long.MinValue;
|
||||
default: throw new ProtoException("Unknown min/max value: " + value.ToString());
|
||||
case 1:
|
||||
return long.MaxValue;
|
||||
case -1:
|
||||
return long.MinValue;
|
||||
default:
|
||||
throw new ProtoException("Unknown min/max value: " + value.ToString());
|
||||
}
|
||||
default:
|
||||
throw new ProtoException("Unknown timescale: " + scale.ToString());
|
||||
|
@ -227,7 +238,7 @@ namespace ProtoBuf
|
|||
}
|
||||
}
|
||||
|
||||
const int FieldDecimalLow = 0x01, FieldDecimalHigh = 0x02, FieldDecimalSignScale = 0x03;
|
||||
private const int FieldDecimalLow = 0x01, FieldDecimalHigh = 0x02, FieldDecimalSignScale = 0x03;
|
||||
|
||||
/// <summary>
|
||||
/// Parses a decimal from a protobuf stream
|
||||
|
@ -244,37 +255,46 @@ namespace ProtoBuf
|
|||
{
|
||||
switch (fieldNumber)
|
||||
{
|
||||
case FieldDecimalLow: low = reader.ReadUInt64(); break;
|
||||
case FieldDecimalHigh: high = reader.ReadUInt32(); break;
|
||||
case FieldDecimalSignScale: signScale = reader.ReadUInt32(); break;
|
||||
default: reader.SkipField(); break;
|
||||
case FieldDecimalLow:
|
||||
low = reader.ReadUInt64();
|
||||
break;
|
||||
case FieldDecimalHigh:
|
||||
high = reader.ReadUInt32();
|
||||
break;
|
||||
case FieldDecimalSignScale:
|
||||
signScale = reader.ReadUInt32();
|
||||
break;
|
||||
default:
|
||||
reader.SkipField();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
ProtoReader.EndSubItem(token, reader);
|
||||
|
||||
if (low == 0 && high == 0) return decimal.Zero;
|
||||
|
||||
int lo = (int)(low & 0xFFFFFFFFL),
|
||||
mid = (int)((low >> 32) & 0xFFFFFFFFL),
|
||||
hi = (int)high;
|
||||
int lo = (int) (low & 0xFFFFFFFFL),
|
||||
mid = (int) ((low >> 32) & 0xFFFFFFFFL),
|
||||
hi = (int) high;
|
||||
bool isNeg = (signScale & 0x0001) == 0x0001;
|
||||
byte scale = (byte)((signScale & 0x01FE) >> 1);
|
||||
byte scale = (byte) ((signScale & 0x01FE) >> 1);
|
||||
return new decimal(lo, mid, hi, isNeg, scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a decimal to a protobuf stream
|
||||
/// </summary>
|
||||
public static void WriteDecimal(decimal value, ProtoWriter writer)
|
||||
{
|
||||
int[] bits = decimal.GetBits(value);
|
||||
ulong a = ((ulong)bits[1]) << 32, b = ((ulong)bits[0]) & 0xFFFFFFFFL;
|
||||
ulong a = ((ulong) bits[1]) << 32, b = ((ulong) bits[0]) & 0xFFFFFFFFL;
|
||||
ulong low = a | b;
|
||||
uint high = (uint)bits[2];
|
||||
uint signScale = (uint)(((bits[3] >> 15) & 0x01FE) | ((bits[3] >> 31) & 0x0001));
|
||||
uint high = (uint) bits[2];
|
||||
uint signScale = (uint) (((bits[3] >> 15) & 0x01FE) | ((bits[3] >> 31) & 0x0001));
|
||||
|
||||
SubItemToken token = ProtoWriter.StartSubItem(null, writer);
|
||||
if (low != 0) {
|
||||
if (low != 0)
|
||||
{
|
||||
ProtoWriter.WriteFieldHeader(FieldDecimalLow, WireType.Variant, writer);
|
||||
ProtoWriter.WriteUInt64(low, writer);
|
||||
}
|
||||
|
@ -291,7 +311,8 @@ namespace ProtoBuf
|
|||
ProtoWriter.EndSubItem(token, writer);
|
||||
}
|
||||
|
||||
const int FieldGuidLow = 1, FieldGuidHigh = 2;
|
||||
private const int FieldGuidLow = 1, FieldGuidHigh = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Writes a Guid to a protobuf stream
|
||||
/// </summary>
|
||||
|
@ -309,6 +330,7 @@ namespace ProtoBuf
|
|||
}
|
||||
ProtoWriter.EndSubItem(token, dest);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a Guid from a protobuf stream
|
||||
/// </summary>
|
||||
|
@ -321,18 +343,23 @@ namespace ProtoBuf
|
|||
{
|
||||
switch (fieldNumber)
|
||||
{
|
||||
case FieldGuidLow: low = source.ReadUInt64(); break;
|
||||
case FieldGuidHigh: high = source.ReadUInt64(); break;
|
||||
default: source.SkipField(); break;
|
||||
case FieldGuidLow:
|
||||
low = source.ReadUInt64();
|
||||
break;
|
||||
case FieldGuidHigh:
|
||||
high = source.ReadUInt64();
|
||||
break;
|
||||
default:
|
||||
source.SkipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
ProtoReader.EndSubItem(token, source);
|
||||
if(low == 0 && high == 0) return Guid.Empty;
|
||||
uint a = (uint)(low >> 32), b = (uint)low, c = (uint)(high >> 32), d= (uint)high;
|
||||
return new Guid((int)b, (short)a, (short)(a >> 16),
|
||||
(byte)d, (byte)(d >> 8), (byte)(d >> 16), (byte)(d >> 24),
|
||||
(byte)c, (byte)(c >> 8), (byte)(c >> 16), (byte)(c >> 24));
|
||||
|
||||
if (low == 0 && high == 0) return Guid.Empty;
|
||||
uint a = (uint) (low >> 32), b = (uint) low, c = (uint) (high >> 32), d = (uint) high;
|
||||
return new Guid((int) b, (short) a, (short) (a >> 16),
|
||||
(byte) d, (byte) (d >> 8), (byte) (d >> 16), (byte) (d >> 24),
|
||||
(byte) c, (byte) (c >> 8), (byte) (c >> 16), (byte) (c >> 24));
|
||||
}
|
||||
|
||||
|
||||
|
@ -343,6 +370,7 @@ namespace ProtoBuf
|
|||
FieldNewTypeKey = 4,
|
||||
FieldTypeName = 8,
|
||||
FieldObject = 10;
|
||||
|
||||
/// <summary>
|
||||
/// Optional behaviours that introduce .NET-specific functionality
|
||||
/// </summary>
|
||||
|
@ -353,28 +381,34 @@ namespace ProtoBuf
|
|||
/// No special behaviour
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Enables full object-tracking/full-graph support.
|
||||
/// </summary>
|
||||
AsReference = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Embeds the type information into the stream, allowing usage with types not known in advance.
|
||||
/// </summary>
|
||||
DynamicType = 2,
|
||||
|
||||
/// <summary>
|
||||
/// If false, the constructor for the type is bypassed during deserialization, meaning any field initializers
|
||||
/// or other initialization code is skipped.
|
||||
/// </summary>
|
||||
UseConstructor = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Should the object index be reserved, rather than creating an object promptly
|
||||
/// </summary>
|
||||
LateSet = 8
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc.
|
||||
/// </summary>
|
||||
public static object ReadNetObject(object value, ProtoReader source, int key, Type type, NetObjectOptions options)
|
||||
public static object ReadNetObject(object value, ProtoReader source, int key, Type type,
|
||||
NetObjectOptions options)
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
throw new NotSupportedException();
|
||||
|
@ -395,7 +429,7 @@ namespace ProtoBuf
|
|||
break;
|
||||
case FieldExistingTypeKey:
|
||||
tmp = source.ReadInt32();
|
||||
type = (Type)source.NetCache.GetKeyedObject(tmp);
|
||||
type = (Type) source.NetCache.GetKeyedObject(tmp);
|
||||
key = source.GetTypeKey(ref type);
|
||||
break;
|
||||
case FieldNewTypeKey:
|
||||
|
@ -404,11 +438,12 @@ namespace ProtoBuf
|
|||
case FieldTypeName:
|
||||
string typeName = source.ReadString();
|
||||
type = source.DeserializeType(typeName);
|
||||
if(type == null)
|
||||
if (type == null)
|
||||
{
|
||||
throw new ProtoException("Unable to resolve type: " + typeName + " (you can use the TypeModel.DynamicTypeFormatting event to provide a custom mapping)");
|
||||
throw new ProtoException("Unable to resolve type: " + typeName +
|
||||
" (you can use the TypeModel.DynamicTypeFormatting event to provide a custom mapping)");
|
||||
}
|
||||
if (type == typeof(string))
|
||||
if (type == typeof (string))
|
||||
{
|
||||
key = -1;
|
||||
}
|
||||
|
@ -420,10 +455,10 @@ namespace ProtoBuf
|
|||
}
|
||||
break;
|
||||
case FieldObject:
|
||||
bool isString = type == typeof(string);
|
||||
bool isString = type == typeof (string);
|
||||
bool wasNull = value == null;
|
||||
bool lateSet = wasNull && (isString || ((options & NetObjectOptions.LateSet) != 0));
|
||||
|
||||
|
||||
if (newObjectKey >= 0 && !lateSet)
|
||||
{
|
||||
if (value == null)
|
||||
|
@ -445,11 +480,12 @@ namespace ProtoBuf
|
|||
{
|
||||
value = ProtoReader.ReadTypedObject(oldValue, key, source, type);
|
||||
}
|
||||
|
||||
|
||||
if (newObjectKey >= 0)
|
||||
{
|
||||
if(wasNull && !lateSet)
|
||||
{ // this both ensures (via exception) that it *was* set, and makes sure we don't shout
|
||||
if (wasNull && !lateSet)
|
||||
{
|
||||
// this both ensures (via exception) that it *was* set, and makes sure we don't shout
|
||||
// about changed references
|
||||
oldValue = source.NetCache.GetKeyedObject(newObjectKey);
|
||||
}
|
||||
|
@ -461,10 +497,12 @@ namespace ProtoBuf
|
|||
}
|
||||
if (newObjectKey >= 0 && !lateSet && !ReferenceEquals(oldValue, value))
|
||||
{
|
||||
throw new ProtoException("A reference-tracked object changed reference during deserialization");
|
||||
throw new ProtoException(
|
||||
"A reference-tracked object changed reference during deserialization");
|
||||
}
|
||||
if (newObjectKey < 0 && newTypeKey >= 0)
|
||||
{ // have a new type, but not a new object
|
||||
{
|
||||
// have a new type, but not a new object
|
||||
source.NetCache.SetKeyedObject(newTypeKey, type);
|
||||
}
|
||||
break;
|
||||
|
@ -473,7 +511,7 @@ namespace ProtoBuf
|
|||
break;
|
||||
}
|
||||
}
|
||||
if(newObjectKey >= 0 && (options & NetObjectOptions.AsReference) == 0)
|
||||
if (newObjectKey >= 0 && (options & NetObjectOptions.AsReference) == 0)
|
||||
{
|
||||
throw new ProtoException("Object key in input stream, but reference-tracking was not expected");
|
||||
}
|
||||
|
@ -482,6 +520,7 @@ namespace ProtoBuf
|
|||
return value;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc.
|
||||
/// </summary>
|
||||
|
@ -492,7 +531,7 @@ namespace ProtoBuf
|
|||
#else
|
||||
if (dest == null) throw new ArgumentNullException("dest");
|
||||
bool dynamicType = (options & NetObjectOptions.DynamicType) != 0,
|
||||
asReference = (options & NetObjectOptions.AsReference) != 0;
|
||||
asReference = (options & NetObjectOptions.AsReference) != 0;
|
||||
WireType wireType = dest.WireType;
|
||||
SubItemToken token = ProtoWriter.StartSubItem(null, dest);
|
||||
bool writeObject = true;
|
||||
|
@ -500,7 +539,8 @@ namespace ProtoBuf
|
|||
{
|
||||
bool existing;
|
||||
int objectKey = dest.NetCache.AddObjectKey(value, out existing);
|
||||
ProtoWriter.WriteFieldHeader(existing ? FieldExistingObjectKey : FieldNewObjectKey, WireType.Variant, dest);
|
||||
ProtoWriter.WriteFieldHeader(existing ? FieldExistingObjectKey : FieldNewObjectKey, WireType.Variant,
|
||||
dest);
|
||||
ProtoWriter.WriteInt32(objectKey, dest);
|
||||
if (existing)
|
||||
{
|
||||
|
@ -518,24 +558,26 @@ namespace ProtoBuf
|
|||
if (!(value is string))
|
||||
{
|
||||
key = dest.GetTypeKey(ref type);
|
||||
if (key < 0) throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name);
|
||||
if (key < 0)
|
||||
throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name);
|
||||
}
|
||||
int typeKey = dest.NetCache.AddObjectKey(type, out existing);
|
||||
ProtoWriter.WriteFieldHeader(existing ? FieldExistingTypeKey : FieldNewTypeKey, WireType.Variant, dest);
|
||||
ProtoWriter.WriteFieldHeader(existing ? FieldExistingTypeKey : FieldNewTypeKey, WireType.Variant,
|
||||
dest);
|
||||
ProtoWriter.WriteInt32(typeKey, dest);
|
||||
if (!existing)
|
||||
{
|
||||
ProtoWriter.WriteFieldHeader(FieldTypeName, WireType.String, dest);
|
||||
ProtoWriter.WriteString(dest.SerializeType(type), dest);
|
||||
}
|
||||
|
||||
}
|
||||
ProtoWriter.WriteFieldHeader(FieldObject, wireType, dest);
|
||||
if (value is string)
|
||||
{
|
||||
ProtoWriter.WriteString((string)value, dest);
|
||||
ProtoWriter.WriteString((string) value, dest);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
ProtoWriter.WriteObject(value, key, dest);
|
||||
}
|
||||
}
|
||||
|
@ -543,4 +585,4 @@ namespace ProtoBuf
|
|||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,16 +25,18 @@ namespace ProtoBuf
|
|||
using (stream)
|
||||
{
|
||||
int len;
|
||||
if (commit && (len = (int)stream.Length) > 0)
|
||||
if (commit && (len = (int) stream.Length) > 0)
|
||||
{
|
||||
using (MemoryStream ms = (MemoryStream)stream)
|
||||
using (MemoryStream ms = (MemoryStream) stream)
|
||||
{
|
||||
if (buffer == null)
|
||||
{ // allocate new buffer
|
||||
{
|
||||
// allocate new buffer
|
||||
buffer = ms.ToArray();
|
||||
}
|
||||
else
|
||||
{ // resize and copy the data
|
||||
{
|
||||
// resize and copy the data
|
||||
// note: Array.Resize not available on CF
|
||||
int offset = buffer.Length;
|
||||
byte[] tmp = new byte[offset + len];
|
||||
|
@ -75,4 +77,4 @@ namespace ProtoBuf
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
using System.Threading;
|
||||
using System.Threading;
|
||||
|
||||
namespace ProtoBuf
|
||||
{
|
||||
internal sealed class BufferPool
|
||||
|
@ -18,15 +18,19 @@ namespace ProtoBuf
|
|||
}
|
||||
#endif
|
||||
}
|
||||
private BufferPool() { }
|
||||
const int PoolSize = 20;
|
||||
|
||||
private BufferPool()
|
||||
{
|
||||
}
|
||||
|
||||
private const int PoolSize = 20;
|
||||
internal const int BufferLength = 1024;
|
||||
private static readonly object[] pool = new object[PoolSize];
|
||||
|
||||
internal static byte[] GetBuffer()
|
||||
{
|
||||
object tmp;
|
||||
#if PLAT_NO_INTERLOCKED
|
||||
#if PLAT_NO_INTERLOCKED
|
||||
lock(pool)
|
||||
{
|
||||
for (int i = 0; i < pool.Length; i++)
|
||||
|
@ -41,12 +45,14 @@ namespace ProtoBuf
|
|||
#else
|
||||
for (int i = 0; i < pool.Length; i++)
|
||||
{
|
||||
if ((tmp = Interlocked.Exchange(ref pool[i], null)) != null) return (byte[])tmp;
|
||||
if ((tmp = Interlocked.Exchange(ref pool[i], null)) != null) return (byte[]) tmp;
|
||||
}
|
||||
#endif
|
||||
return new byte[BufferLength];
|
||||
}
|
||||
internal static void ResizeAndFlushLeft(ref byte[] buffer, int toFitAtLeastBytes, int copyFromIndex, int copyBytes)
|
||||
|
||||
internal static void ResizeAndFlushLeft(ref byte[] buffer, int toFitAtLeastBytes, int copyFromIndex,
|
||||
int copyBytes)
|
||||
{
|
||||
Helpers.DebugAssert(buffer != null);
|
||||
Helpers.DebugAssert(toFitAtLeastBytes > buffer.Length);
|
||||
|
@ -54,7 +60,7 @@ namespace ProtoBuf
|
|||
Helpers.DebugAssert(copyBytes >= 0);
|
||||
|
||||
// try doubling, else match
|
||||
int newLength = buffer.Length * 2;
|
||||
int newLength = buffer.Length*2;
|
||||
if (newLength < toFitAtLeastBytes) newLength = toFitAtLeastBytes;
|
||||
|
||||
byte[] newBuffer = new byte[newLength];
|
||||
|
@ -68,6 +74,7 @@ namespace ProtoBuf
|
|||
}
|
||||
buffer = newBuffer;
|
||||
}
|
||||
|
||||
internal static void ReleaseBufferToPool(ref byte[] buffer)
|
||||
{
|
||||
if (buffer == null) return;
|
||||
|
@ -98,6 +105,5 @@ namespace ProtoBuf
|
|||
// if no space, just drop it on the floor
|
||||
buffer = null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -8,26 +8,34 @@ namespace ProtoBuf
|
|||
#if !CF && !SILVERLIGHT && !MONODROID && !WINRT && !IOS && !PORTABLE
|
||||
[ImmutableObject(true)]
|
||||
#endif
|
||||
public sealed class ProtoBeforeSerializationAttribute : Attribute { }
|
||||
public sealed class ProtoBeforeSerializationAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Specifies a method on the root-contract in an hierarchy to be invoked after serialization.</summary>
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
|
||||
#if !CF && !SILVERLIGHT && !MONODROID && !WINRT && !IOS && !PORTABLE
|
||||
[ImmutableObject(true)]
|
||||
#endif
|
||||
public sealed class ProtoAfterSerializationAttribute : Attribute { }
|
||||
public sealed class ProtoAfterSerializationAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Specifies a method on the root-contract in an hierarchy to be invoked before deserialization.</summary>
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
|
||||
#if !CF && !SILVERLIGHT && !MONODROID && !WINRT && !IOS && !PORTABLE
|
||||
[ImmutableObject(true)]
|
||||
#endif
|
||||
public sealed class ProtoBeforeDeserializationAttribute : Attribute { }
|
||||
public sealed class ProtoBeforeDeserializationAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Specifies a method on the root-contract in an hierarchy to be invoked after deserialization.</summary>
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
|
||||
#if !CF && !SILVERLIGHT && !MONODROID && !WINRT && !IOS && !PORTABLE
|
||||
[ImmutableObject(true)]
|
||||
#endif
|
||||
public sealed class ProtoAfterDeserializationAttribute : Attribute { }
|
||||
}
|
||||
public sealed class ProtoAfterDeserializationAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
namespace ProtoBuf
|
||||
namespace ProtoBuf
|
||||
{
|
||||
/// <summary>
|
||||
/// Sub-format to use when serializing/deserializing data
|
||||
|
@ -39,4 +38,4 @@ namespace ProtoBuf
|
|||
/// </summary>
|
||||
Group
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@ namespace ProtoBuf
|
|||
{
|
||||
return GetExtensionObject(createIfMissing);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the <see cref="IExtension">extension</see> object for the current
|
||||
/// instance, optionally creating it if it does not already exist.
|
||||
|
@ -99,6 +100,7 @@ namespace ProtoBuf
|
|||
{
|
||||
ExtensibleUtil.AppendExtendValue(RuntimeTypeModel.Default, instance, tag, format, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries an extensible object for an additional (unexpected) data-field for the instance.
|
||||
/// The value returned is the composed value after merging any duplicated content; if the
|
||||
|
@ -173,11 +175,13 @@ namespace ProtoBuf
|
|||
/// <param name="format">The data-format to use when decoding the value.</param>
|
||||
/// <param name="allowDefinedTag">Allow tags that are present as part of the definition; for example, to query unknown enum values.</param>
|
||||
/// <returns>True if data for the field was present, false otherwise.</returns>
|
||||
public static bool TryGetValue<TValue>(IExtensible instance, int tag, DataFormat format, bool allowDefinedTag, out TValue value)
|
||||
public static bool TryGetValue<TValue>(IExtensible instance, int tag, DataFormat format, bool allowDefinedTag,
|
||||
out TValue value)
|
||||
{
|
||||
value = default(TValue);
|
||||
bool set = false;
|
||||
foreach (TValue val in ExtensibleUtil.GetExtendedValues<TValue>(instance, tag, format, true, allowDefinedTag))
|
||||
foreach (
|
||||
TValue val in ExtensibleUtil.GetExtendedValues<TValue>(instance, tag, format, true, allowDefinedTag))
|
||||
{
|
||||
// expecting at most one yield...
|
||||
// but don't break; need to read entire stream
|
||||
|
@ -233,11 +237,14 @@ namespace ProtoBuf
|
|||
/// <param name="format">The data-format to use when decoding the value.</param>
|
||||
/// <param name="allowDefinedTag">Allow tags that are present as part of the definition; for example, to query unknown enum values.</param>
|
||||
/// <returns>True if data for the field was present, false otherwise.</returns>
|
||||
public static bool TryGetValue(TypeModel model, System.Type type, IExtensible instance, int tag, DataFormat format, bool allowDefinedTag, out object value)
|
||||
public static bool TryGetValue(TypeModel model, System.Type type, IExtensible instance, int tag,
|
||||
DataFormat format, bool allowDefinedTag, out object value)
|
||||
{
|
||||
value = null;
|
||||
bool set = false;
|
||||
foreach (object val in ExtensibleUtil.GetExtendedValues(model, type, instance, tag, format, true, allowDefinedTag))
|
||||
foreach (
|
||||
object val in
|
||||
ExtensibleUtil.GetExtendedValues(model, type, instance, tag, format, true, allowDefinedTag))
|
||||
{
|
||||
// expecting at most one yield...
|
||||
// but don't break; need to read entire stream
|
||||
|
@ -247,6 +254,7 @@ namespace ProtoBuf
|
|||
|
||||
return set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries an extensible object for an additional (unexpected) data-field for the instance.
|
||||
/// Each occurrence of the field is yielded separately, making this usage suitable for "repeated"
|
||||
|
@ -259,7 +267,8 @@ namespace ProtoBuf
|
|||
/// <param name="tag">The field identifier; the tag should not be defined as a known data-field for the instance.</param>
|
||||
/// <param name="format">The data-format to use when decoding the value.</param>
|
||||
/// <returns>An enumerator that yields each occurrence of the field.</returns>
|
||||
public static IEnumerable GetValues(TypeModel model, System.Type type, IExtensible instance, int tag, DataFormat format)
|
||||
public static IEnumerable GetValues(TypeModel model, System.Type type, IExtensible instance, int tag,
|
||||
DataFormat format)
|
||||
{
|
||||
return ExtensibleUtil.GetExtendedValues(model, type, instance, tag, format, false, false);
|
||||
}
|
||||
|
@ -281,6 +290,5 @@ namespace ProtoBuf
|
|||
{
|
||||
ExtensibleUtil.AppendExtendValue(model, instance, tag, format, value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ namespace ProtoBuf
|
|||
#if FX11
|
||||
sealed
|
||||
#else
|
||||
static
|
||||
static
|
||||
#endif
|
||||
class ExtensibleUtil
|
||||
{
|
||||
|
@ -32,20 +32,26 @@ namespace ProtoBuf
|
|||
/// this ensures that we don't get issues with subclasses declaring conflicting types -
|
||||
/// the caller must respect the fields defined for the type they pass in.
|
||||
/// </summary>
|
||||
internal static IEnumerable<TValue> GetExtendedValues<TValue>(IExtensible instance, int tag, DataFormat format, bool singleton, bool allowDefinedTag)
|
||||
internal static IEnumerable<TValue> GetExtendedValues<TValue>(IExtensible instance, int tag, DataFormat format,
|
||||
bool singleton, bool allowDefinedTag)
|
||||
{
|
||||
foreach (TValue value in GetExtendedValues(RuntimeTypeModel.Default, typeof(TValue), instance, tag, format, singleton, allowDefinedTag))
|
||||
foreach (
|
||||
TValue value in
|
||||
GetExtendedValues(RuntimeTypeModel.Default, typeof (TValue), instance, tag, format, singleton,
|
||||
allowDefinedTag))
|
||||
{
|
||||
yield return value;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// All this does is call GetExtendedValuesTyped with the correct type for "instance";
|
||||
/// this ensures that we don't get issues with subclasses declaring conflicting types -
|
||||
/// the caller must respect the fields defined for the type they pass in.
|
||||
/// </summary>
|
||||
internal static IEnumerable GetExtendedValues(TypeModel model, Type type, IExtensible instance, int tag, DataFormat format, bool singleton, bool allowDefinedTag)
|
||||
internal static IEnumerable GetExtendedValues(TypeModel model, Type type, IExtensible instance, int tag,
|
||||
DataFormat format, bool singleton, bool allowDefinedTag)
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
throw new NotSupportedException();
|
||||
|
@ -70,10 +76,13 @@ namespace ProtoBuf
|
|||
Stream stream = extn.BeginQuery();
|
||||
object value = null;
|
||||
ProtoReader reader = null;
|
||||
try {
|
||||
try
|
||||
{
|
||||
SerializationContext ctx = new SerializationContext();
|
||||
reader = ProtoReader.Create(stream, model, ctx, ProtoReader.TO_EOF);
|
||||
while (model.TryDeserializeAuxiliaryType(reader, format, tag, type, ref value, true, false, false, false) && value != null)
|
||||
while (
|
||||
model.TryDeserializeAuxiliaryType(reader, format, tag, type, ref value, true, false, false, false) &&
|
||||
value != null)
|
||||
{
|
||||
if (!singleton)
|
||||
{
|
||||
|
@ -98,41 +107,49 @@ namespace ProtoBuf
|
|||
result.CopyTo(resultArr, 0);
|
||||
return resultArr;
|
||||
#endif
|
||||
} finally {
|
||||
}
|
||||
finally
|
||||
{
|
||||
ProtoReader.Recycle(reader);
|
||||
extn.EndQuery(stream);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static void AppendExtendValue(TypeModel model, IExtensible instance, int tag, DataFormat format, object value)
|
||||
internal static void AppendExtendValue(TypeModel model, IExtensible instance, int tag, DataFormat format,
|
||||
object value)
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
throw new NotSupportedException();
|
||||
#else
|
||||
if(instance == null) throw new ArgumentNullException("instance");
|
||||
if(value == null) throw new ArgumentNullException("value");
|
||||
if (instance == null) throw new ArgumentNullException("instance");
|
||||
if (value == null) throw new ArgumentNullException("value");
|
||||
|
||||
// TODO
|
||||
//model.CheckTagNotInUse(tag);
|
||||
|
||||
// obtain the extension object and prepare to write
|
||||
IExtension extn = instance.GetExtensionObject(true);
|
||||
if (extn == null) throw new InvalidOperationException("No extension object available; appended data would be lost.");
|
||||
if (extn == null)
|
||||
throw new InvalidOperationException("No extension object available; appended data would be lost.");
|
||||
bool commit = false;
|
||||
Stream stream = extn.BeginAppend();
|
||||
try {
|
||||
using(ProtoWriter writer = new ProtoWriter(stream, model, null)) {
|
||||
try
|
||||
{
|
||||
using (ProtoWriter writer = new ProtoWriter(stream, model, null))
|
||||
{
|
||||
model.TrySerializeAuxiliaryType(writer, null, format, tag, value, false);
|
||||
writer.Close();
|
||||
}
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
finally
|
||||
{
|
||||
extn.EndAppend(stream, commit);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//#if !NO_GENERICS
|
||||
// /// <summary>
|
||||
// /// Stores the given value into the instance's stream; the serializer
|
||||
|
@ -147,5 +164,4 @@ namespace ProtoBuf
|
|||
// }
|
||||
//#endif
|
||||
}
|
||||
|
||||
}
|
Binary file not shown.
|
@ -1,12 +1,11 @@
|
|||
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
#if FEAT_IKVM
|
||||
using Type = IKVM.Reflection.Type;
|
||||
using IKVM.Reflection;
|
||||
#else
|
||||
using System.Reflection;
|
||||
|
||||
#endif
|
||||
|
||||
namespace ProtoBuf
|
||||
|
@ -20,7 +19,9 @@ namespace ProtoBuf
|
|||
/// </summary>
|
||||
internal sealed class Helpers
|
||||
{
|
||||
private Helpers() { }
|
||||
private Helpers()
|
||||
{
|
||||
}
|
||||
|
||||
public static System.Text.StringBuilder AppendLine(System.Text.StringBuilder builder)
|
||||
{
|
||||
|
@ -32,8 +33,10 @@ namespace ProtoBuf
|
|||
return builder.AppendLine();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool IsNullOrEmpty(string value)
|
||||
{ // yes, FX11 lacks this!
|
||||
{
|
||||
// yes, FX11 lacks this!
|
||||
return value == null || value.Length == 0;
|
||||
}
|
||||
|
||||
|
@ -53,6 +56,7 @@ namespace ProtoBuf
|
|||
DebugWriteLine(message + ": " + suffix);
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("DEBUG")]
|
||||
public static void DebugWriteLine(string message)
|
||||
{
|
||||
|
@ -64,6 +68,7 @@ namespace ProtoBuf
|
|||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRACE")]
|
||||
public static void TraceWriteLine(string message)
|
||||
{
|
||||
|
@ -92,6 +97,7 @@ namespace ProtoBuf
|
|||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("DEBUG")]
|
||||
public static void DebugAssert(bool condition, string message, params object[] args)
|
||||
{
|
||||
|
@ -99,18 +105,20 @@ namespace ProtoBuf
|
|||
if (!condition) DebugAssert(false, string.Format(message, args));
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("DEBUG")]
|
||||
public static void DebugAssert(bool condition)
|
||||
{
|
||||
#if DEBUG
|
||||
#if DEBUG
|
||||
#if MF
|
||||
Microsoft.SPOT.Debug.Assert(condition);
|
||||
#else
|
||||
if(!condition && System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break();
|
||||
if (!condition && System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break();
|
||||
System.Diagnostics.Debug.Assert(condition);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !NO_RUNTIME
|
||||
public static void Sort(int[] keys, object[] values)
|
||||
{
|
||||
|
@ -119,10 +127,13 @@ namespace ProtoBuf
|
|||
// also allows us to do `int` compares without having
|
||||
// to go via IComparable etc, so win:win
|
||||
bool swapped;
|
||||
do {
|
||||
do
|
||||
{
|
||||
swapped = false;
|
||||
for (int i = 1; i < keys.Length; i++) {
|
||||
if (keys[i - 1] > keys[i]) {
|
||||
for (int i = 1; i < keys.Length; i++)
|
||||
{
|
||||
if (keys[i - 1] > keys[i])
|
||||
{
|
||||
int tmpKey = keys[i];
|
||||
keys[i] = keys[i - 1];
|
||||
keys[i - 1] = tmpKey;
|
||||
|
@ -135,6 +146,7 @@ namespace ProtoBuf
|
|||
} while (swapped);
|
||||
}
|
||||
#endif
|
||||
|
||||
public static void BlockCopy(byte[] from, int fromIndex, byte[] to, int toIndex, int count)
|
||||
{
|
||||
#if MF || WINRT
|
||||
|
@ -143,6 +155,7 @@ namespace ProtoBuf
|
|||
Buffer.BlockCopy(from, fromIndex, to, toIndex, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool IsInfinity(float value)
|
||||
{
|
||||
#if MF
|
||||
|
@ -152,6 +165,7 @@ namespace ProtoBuf
|
|||
return float.IsInfinity(value);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if WINRT
|
||||
internal static MemberInfo GetInstanceMember(TypeInfo declaringType, string name)
|
||||
{
|
||||
|
@ -207,13 +221,15 @@ namespace ProtoBuf
|
|||
{
|
||||
return declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
}
|
||||
|
||||
internal static MethodInfo GetStaticMethod(Type declaringType, string name)
|
||||
{
|
||||
return declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
}
|
||||
|
||||
internal static MethodInfo GetInstanceMethod(Type declaringType, string name, Type[] types)
|
||||
{
|
||||
if(types == null) types = EmptyTypes;
|
||||
if (types == null) types = EmptyTypes;
|
||||
#if PORTABLE
|
||||
MethodInfo method = declaringType.GetMethod(name, types);
|
||||
if (method != null && method.IsStatic) method = null;
|
||||
|
@ -243,7 +259,8 @@ namespace ProtoBuf
|
|||
return double.IsInfinity(value);
|
||||
#endif
|
||||
}
|
||||
public readonly static Type[] EmptyTypes =
|
||||
|
||||
public static readonly Type[] EmptyTypes =
|
||||
#if PORTABLE || WINRT || CF2 || CF35
|
||||
new Type[0];
|
||||
#else
|
||||
|
@ -332,19 +349,19 @@ namespace ProtoBuf
|
|||
case TypeCode.Decimal:
|
||||
case TypeCode.DateTime:
|
||||
case TypeCode.String:
|
||||
return (ProtoTypeCode)code;
|
||||
return (ProtoTypeCode) code;
|
||||
}
|
||||
if (type == typeof(TimeSpan)) return ProtoTypeCode.TimeSpan;
|
||||
if (type == typeof(Guid)) return ProtoTypeCode.Guid;
|
||||
if (type == typeof(Uri)) return ProtoTypeCode.Uri;
|
||||
if (type == typeof(byte[])) return ProtoTypeCode.ByteArray;
|
||||
if (type == typeof(System.Type)) return ProtoTypeCode.Type;
|
||||
if (type == typeof (TimeSpan)) return ProtoTypeCode.TimeSpan;
|
||||
if (type == typeof (Guid)) return ProtoTypeCode.Guid;
|
||||
if (type == typeof (Uri)) return ProtoTypeCode.Uri;
|
||||
if (type == typeof (byte[])) return ProtoTypeCode.ByteArray;
|
||||
if (type == typeof (System.Type)) return ProtoTypeCode.Type;
|
||||
|
||||
return ProtoTypeCode.Unknown;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if FEAT_IKVM
|
||||
internal static IKVM.Reflection.Type GetUnderlyingType(IKVM.Reflection.Type type)
|
||||
{
|
||||
|
@ -393,7 +410,8 @@ namespace ProtoBuf
|
|||
#else
|
||||
MethodInfo method = property.GetGetMethod(nonPublic);
|
||||
if (method == null && !nonPublic && allowInternal)
|
||||
{ // could be "internal" or "protected internal"; look for a non-public, then back-check
|
||||
{
|
||||
// could be "internal" or "protected internal"; look for a non-public, then back-check
|
||||
method = property.GetGetMethod(true);
|
||||
if (method == null && !(method.IsAssembly || method.IsFamilyOrAssembly))
|
||||
{
|
||||
|
@ -403,6 +421,7 @@ namespace ProtoBuf
|
|||
return method;
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static MethodInfo GetSetMethod(PropertyInfo property, bool nonPublic, bool allowInternal)
|
||||
{
|
||||
if (property == null) return null;
|
||||
|
@ -413,7 +432,8 @@ namespace ProtoBuf
|
|||
#else
|
||||
MethodInfo method = property.GetSetMethod(nonPublic);
|
||||
if (method == null && !nonPublic && allowInternal)
|
||||
{ // could be "internal" or "protected internal"; look for a non-public, then back-check
|
||||
{
|
||||
// could be "internal" or "protected internal"; look for a non-public, then back-check
|
||||
method = property.GetGetMethod(true);
|
||||
if (method == null && !(method.IsAssembly || method.IsFamilyOrAssembly))
|
||||
{
|
||||
|
@ -471,28 +491,32 @@ namespace ProtoBuf
|
|||
internal static ConstructorInfo GetConstructor(Type type, Type[] parameterTypes, bool nonPublic)
|
||||
{
|
||||
#if PORTABLE
|
||||
// pretty sure this will only ever return public, but...
|
||||
// pretty sure this will only ever return public, but...
|
||||
ConstructorInfo ctor = type.GetConstructor(parameterTypes);
|
||||
return (ctor != null && (nonPublic || ctor.IsPublic)) ? ctor : null;
|
||||
#else
|
||||
return type.GetConstructor(
|
||||
nonPublic ? BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
||||
: BindingFlags.Instance | BindingFlags.Public,
|
||||
null, parameterTypes, null);
|
||||
nonPublic
|
||||
? BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
||||
: BindingFlags.Instance | BindingFlags.Public,
|
||||
null, parameterTypes, null);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
internal static ConstructorInfo[] GetConstructors(Type type, bool nonPublic)
|
||||
{
|
||||
return type.GetConstructors(
|
||||
nonPublic ? BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
||||
: BindingFlags.Instance | BindingFlags.Public);
|
||||
nonPublic
|
||||
? BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
||||
: BindingFlags.Instance | BindingFlags.Public);
|
||||
}
|
||||
|
||||
internal static PropertyInfo GetProperty(Type type, string name, bool nonPublic)
|
||||
{
|
||||
return type.GetProperty(name,
|
||||
nonPublic ? BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
||||
: BindingFlags.Instance | BindingFlags.Public);
|
||||
nonPublic
|
||||
? BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
||||
: BindingFlags.Instance | BindingFlags.Public);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -529,7 +553,9 @@ namespace ProtoBuf
|
|||
}
|
||||
return members.ToArray();
|
||||
#else
|
||||
BindingFlags flags = publicOnly ? BindingFlags.Public | BindingFlags.Instance : BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic;
|
||||
BindingFlags flags = publicOnly
|
||||
? BindingFlags.Public | BindingFlags.Instance
|
||||
: BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic;
|
||||
PropertyInfo[] props = type.GetProperties(flags);
|
||||
FieldInfo[] fields = type.GetFields(flags);
|
||||
MemberInfo[] members = new MemberInfo[fields.Length + props.Length];
|
||||
|
@ -547,11 +573,14 @@ namespace ProtoBuf
|
|||
FieldInfo fld = member as FieldInfo;
|
||||
return fld == null ? null : fld.FieldType;
|
||||
#else
|
||||
switch(member.MemberType)
|
||||
switch (member.MemberType)
|
||||
{
|
||||
case MemberTypes.Field: return ((FieldInfo) member).FieldType;
|
||||
case MemberTypes.Property: return ((PropertyInfo) member).PropertyType;
|
||||
default: return null;
|
||||
case MemberTypes.Field:
|
||||
return ((FieldInfo) member).FieldType;
|
||||
case MemberTypes.Property:
|
||||
return ((PropertyInfo) member).PropertyType;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -564,8 +593,8 @@ namespace ProtoBuf
|
|||
return target.IsAssignableFrom(type);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Intended to be a direct map to regular TypeCode, but:
|
||||
/// - with missing types
|
||||
|
@ -598,4 +627,4 @@ namespace ProtoBuf
|
|||
Uri = 103,
|
||||
Type = 104
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,5 @@
|
|||
|
||||
namespace ProtoBuf
|
||||
namespace ProtoBuf
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the implementing type has support for protocol-buffer
|
||||
/// <see cref="IExtension">extensions</see>.
|
||||
|
@ -22,6 +19,4 @@ namespace ProtoBuf
|
|||
/// and true during deserialization upon encountering unexpected fields.</remarks>
|
||||
IExtension GetExtensionObject(bool createIfMissing);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
|
||||
namespace ProtoBuf
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -44,4 +44,4 @@ namespace ProtoBuf
|
|||
/// <returns>The length of the binary stream representing unexpected data.</returns>
|
||||
int GetLength();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,15 +17,17 @@ namespace ProtoBuf
|
|||
/// most scenarios.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Public properties and fields are eligible for implicit serialization;
|
||||
/// this treats the public API as a contract. Ordering beings from ImplicitFirstTag.
|
||||
/// </summary>
|
||||
AllPublic= 1,
|
||||
AllPublic = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Public and non-public fields are eligible for implicit serialization;
|
||||
/// this acts as a state/implementation serializer. Ordering beings from ImplicitFirstTag.
|
||||
/// </summary>
|
||||
AllFields = 2
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,4 +43,5 @@
|
|||
// }
|
||||
// }
|
||||
//}
|
||||
//#endif
|
||||
//#endif
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ using Type = IKVM.Reflection.Type;
|
|||
using IKVM.Reflection;
|
||||
#else
|
||||
using System.Reflection;
|
||||
|
||||
#endif
|
||||
|
||||
namespace ProtoBuf.Meta
|
||||
|
@ -13,14 +14,20 @@ namespace ProtoBuf.Meta
|
|||
{
|
||||
#if DEBUG
|
||||
[Obsolete("Please use AttributeType instead")]
|
||||
new public Type GetType() { return AttributeType; }
|
||||
public new Type GetType()
|
||||
{
|
||||
return AttributeType;
|
||||
}
|
||||
#endif
|
||||
public abstract bool TryGet(string key, bool publicOnly, out object value);
|
||||
|
||||
public bool TryGet(string key, out object value)
|
||||
{
|
||||
return TryGet(key, true, out value);
|
||||
}
|
||||
|
||||
public abstract Type AttributeType { get; }
|
||||
|
||||
public static AttributeMap[] Create(TypeModel model, Type type, bool inherit)
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
|
@ -40,9 +47,9 @@ namespace ProtoBuf.Meta
|
|||
object[] all = type.GetCustomAttributes(inherit);
|
||||
#endif
|
||||
AttributeMap[] result = new AttributeMap[all.Length];
|
||||
for(int i = 0 ; i < all.Length ; i++)
|
||||
for (int i = 0; i < all.Length; i++)
|
||||
{
|
||||
result[i] = new ReflectionAttributeMap((Attribute)all[i]);
|
||||
result[i] = new ReflectionAttributeMap((Attribute) all[i]);
|
||||
}
|
||||
return result;
|
||||
#endif
|
||||
|
@ -66,16 +73,16 @@ namespace ProtoBuf.Meta
|
|||
object[] all = member.GetCustomAttributes(inherit);
|
||||
#endif
|
||||
AttributeMap[] result = new AttributeMap[all.Length];
|
||||
for(int i = 0 ; i < all.Length ; i++)
|
||||
for (int i = 0; i < all.Length; i++)
|
||||
{
|
||||
result[i] = new ReflectionAttributeMap((Attribute)all[i]);
|
||||
result[i] = new ReflectionAttributeMap((Attribute) all[i]);
|
||||
}
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static AttributeMap[] Create(TypeModel model, Assembly assembly)
|
||||
{
|
||||
|
||||
#if FEAT_IKVM
|
||||
const bool inherit = false;
|
||||
System.Collections.Generic.IList<CustomAttributeData> all = assembly.__GetCustomAttributes(model.MapType(typeof(Attribute)), inherit);
|
||||
|
@ -94,13 +101,14 @@ namespace ProtoBuf.Meta
|
|||
object[] all = assembly.GetCustomAttributes(inherit);
|
||||
#endif
|
||||
AttributeMap[] result = new AttributeMap[all.Length];
|
||||
for(int i = 0 ; i < all.Length ; i++)
|
||||
for (int i = 0; i < all.Length; i++)
|
||||
{
|
||||
result[i] = new ReflectionAttributeMap((Attribute)all[i]);
|
||||
result[i] = new ReflectionAttributeMap((Attribute) all[i]);
|
||||
}
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if FEAT_IKVM
|
||||
private sealed class AttributeDataMap : AttributeMap
|
||||
{
|
||||
|
@ -141,16 +149,19 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
#else
|
||||
public abstract object Target { get; }
|
||||
|
||||
private sealed class ReflectionAttributeMap : AttributeMap
|
||||
{
|
||||
public override object Target
|
||||
{
|
||||
get { return attribute; }
|
||||
}
|
||||
|
||||
public override Type AttributeType
|
||||
{
|
||||
get { return attribute.GetType(); }
|
||||
}
|
||||
|
||||
public override bool TryGet(string key, bool publicOnly, out object value)
|
||||
{
|
||||
MemberInfo[] members = Helpers.GetInstanceFieldsAndProperties(attribute.GetType(), publicOnly);
|
||||
|
@ -163,12 +174,14 @@ namespace ProtoBuf.Meta
|
|||
#endif
|
||||
{
|
||||
PropertyInfo prop = member as PropertyInfo;
|
||||
if (prop != null) {
|
||||
if (prop != null)
|
||||
{
|
||||
value = prop.GetValue(attribute, null);
|
||||
return true;
|
||||
}
|
||||
FieldInfo field = member as FieldInfo;
|
||||
if (field != null) {
|
||||
if (field != null)
|
||||
{
|
||||
value = field.GetValue(attribute);
|
||||
return true;
|
||||
}
|
||||
|
@ -179,7 +192,9 @@ namespace ProtoBuf.Meta
|
|||
value = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private readonly Attribute attribute;
|
||||
|
||||
public ReflectionAttributeMap(Attribute attribute)
|
||||
{
|
||||
this.attribute = attribute;
|
||||
|
@ -188,4 +203,5 @@ namespace ProtoBuf.Meta
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -3,15 +3,17 @@ using System.Collections;
|
|||
|
||||
namespace ProtoBuf.Meta
|
||||
{
|
||||
|
||||
internal sealed class MutableList : BasicList
|
||||
{
|
||||
/* Like BasicList, but allows existing values to be changed
|
||||
*/
|
||||
public new object this[int index] {
|
||||
*/
|
||||
|
||||
public new object this[int index]
|
||||
{
|
||||
get { return head[index]; }
|
||||
set { head[index] = value; }
|
||||
}
|
||||
|
||||
public void RemoveLast()
|
||||
{
|
||||
head.RemoveLastWithMutate();
|
||||
|
@ -22,6 +24,7 @@ namespace ProtoBuf.Meta
|
|||
head.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
internal class BasicList : IEnumerable
|
||||
{
|
||||
/* Requirements:
|
||||
|
@ -37,47 +40,82 @@ namespace ProtoBuf.Meta
|
|||
* be mutable (i.e. array is fine as long as we don't screw it up)
|
||||
*/
|
||||
private static readonly Node nil = new Node(null, 0);
|
||||
|
||||
public void CopyTo(Array array, int offset)
|
||||
{
|
||||
head.CopyTo(array, offset);
|
||||
}
|
||||
|
||||
protected Node head = nil;
|
||||
|
||||
public int Add(object value)
|
||||
{
|
||||
return (head = head.Append(value)).Length - 1;
|
||||
}
|
||||
public object this[int index] { get { return head[index]; } }
|
||||
|
||||
public object this[int index]
|
||||
{
|
||||
get { return head[index]; }
|
||||
}
|
||||
|
||||
//public object TryGet(int index)
|
||||
//{
|
||||
// return head.TryGet(index);
|
||||
//}
|
||||
public void Trim() { head = head.Trim(); }
|
||||
public int Count { get { return head.Length; } }
|
||||
IEnumerator IEnumerable.GetEnumerator() { return new NodeEnumerator(head); }
|
||||
public NodeEnumerator GetEnumerator() { return new NodeEnumerator(head); }
|
||||
public void Trim()
|
||||
{
|
||||
head = head.Trim();
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return head.Length; }
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return new NodeEnumerator(head);
|
||||
}
|
||||
|
||||
public NodeEnumerator GetEnumerator()
|
||||
{
|
||||
return new NodeEnumerator(head);
|
||||
}
|
||||
|
||||
public struct NodeEnumerator : IEnumerator
|
||||
{
|
||||
private int position;
|
||||
private readonly Node node;
|
||||
|
||||
internal NodeEnumerator(Node node)
|
||||
{
|
||||
this.position = -1;
|
||||
this.node = node;
|
||||
}
|
||||
void IEnumerator.Reset() { position = -1; }
|
||||
public object Current { get { return node[position]; } }
|
||||
|
||||
void IEnumerator.Reset()
|
||||
{
|
||||
position = -1;
|
||||
}
|
||||
|
||||
public object Current
|
||||
{
|
||||
get { return node[position]; }
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
int len = node.Length;
|
||||
return (position <= len) && (++position < len);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class Node
|
||||
{
|
||||
public object this[int index]
|
||||
{
|
||||
get {
|
||||
get
|
||||
{
|
||||
if (index >= 0 && index < length)
|
||||
{
|
||||
return data[index];
|
||||
|
@ -96,27 +134,35 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//public object TryGet(int index)
|
||||
//{
|
||||
// return (index >= 0 && index < length) ? data[index] : null;
|
||||
//}
|
||||
private readonly object[] data;
|
||||
|
||||
|
||||
private int length;
|
||||
public int Length { get { return length; } }
|
||||
|
||||
public int Length
|
||||
{
|
||||
get { return length; }
|
||||
}
|
||||
|
||||
internal Node(object[] data, int length)
|
||||
{
|
||||
Helpers.DebugAssert((data == null && length == 0) ||
|
||||
(data != null && length > 0 && length <= data.Length));
|
||||
(data != null && length > 0 && length <= data.Length));
|
||||
this.data = data;
|
||||
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public void RemoveLastWithMutate()
|
||||
{
|
||||
if (length == 0) throw new InvalidOperationException();
|
||||
length -= 1;
|
||||
}
|
||||
|
||||
public Node Append(object value)
|
||||
{
|
||||
object[] newData;
|
||||
|
@ -127,15 +173,17 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
else if (length == data.Length)
|
||||
{
|
||||
newData = new object[data.Length * 2];
|
||||
newData = new object[data.Length*2];
|
||||
Array.Copy(data, newData, length);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
newData = data;
|
||||
}
|
||||
newData[length] = value;
|
||||
return new Node(newData, newLength);
|
||||
}
|
||||
|
||||
public Node Trim()
|
||||
{
|
||||
if (length == 0 || length == data.Length) return this;
|
||||
|
@ -148,19 +196,21 @@ namespace ProtoBuf.Meta
|
|||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
if ((string)value == (string)data[i]) return i;
|
||||
if ((string) value == (string) data[i]) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
internal int IndexOfReference(object instance)
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
if ((object)instance == (object)data[i]) return i;
|
||||
if ((object) instance == (object) data[i]) return i;
|
||||
} // ^^^ (object) above should be preserved, even if this was typed; needs
|
||||
// to be a reference check
|
||||
// to be a reference check
|
||||
return -1;
|
||||
}
|
||||
|
||||
internal int IndexOf(MatchPredicate predicate, object ctx)
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
|
@ -180,7 +230,7 @@ namespace ProtoBuf.Meta
|
|||
|
||||
internal void Clear()
|
||||
{
|
||||
if(data != null)
|
||||
if (data != null)
|
||||
{
|
||||
Array.Clear(data, 0, data.Length);
|
||||
}
|
||||
|
@ -192,10 +242,12 @@ namespace ProtoBuf.Meta
|
|||
{
|
||||
return head.IndexOf(predicate, ctx);
|
||||
}
|
||||
|
||||
internal int IndexOfString(string value)
|
||||
{
|
||||
return head.IndexOfString(value);
|
||||
}
|
||||
|
||||
internal int IndexOfReference(object instance)
|
||||
{
|
||||
return head.IndexOfReference(instance);
|
||||
|
@ -211,26 +263,33 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal sealed class Group
|
||||
{
|
||||
public readonly int First;
|
||||
public readonly BasicList Items;
|
||||
|
||||
public Group(int first)
|
||||
{
|
||||
this.First = first;
|
||||
this.Items = new BasicList();
|
||||
}
|
||||
}
|
||||
|
||||
internal static BasicList GetContiguousGroups(int[] keys, object[] values)
|
||||
{
|
||||
if (keys == null) throw new ArgumentNullException("keys");
|
||||
if (values == null) throw new ArgumentNullException("values");
|
||||
if (values.Length < keys.Length) throw new ArgumentException("Not all keys are covered by values", "values");
|
||||
if (values.Length < keys.Length)
|
||||
throw new ArgumentException("Not all keys are covered by values", "values");
|
||||
BasicList outer = new BasicList();
|
||||
Group group = null;
|
||||
for (int i = 0; i < keys.Length; i++)
|
||||
{
|
||||
if (i == 0 || keys[i] != keys[i - 1]) { group = null; }
|
||||
if (i == 0 || keys[i] != keys[i - 1])
|
||||
{
|
||||
group = null;
|
||||
}
|
||||
if (group == null)
|
||||
{
|
||||
group = new Group(keys[i]);
|
||||
|
@ -241,6 +300,4 @@ namespace ProtoBuf.Meta
|
|||
return outer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
#if !NO_RUNTIME
|
||||
using System;
|
||||
|
||||
#if FEAT_IKVM
|
||||
using Type = IKVM.Reflection.Type;
|
||||
using IKVM.Reflection;
|
||||
#else
|
||||
using System.Reflection;
|
||||
|
||||
#endif
|
||||
|
||||
namespace ProtoBuf.Meta
|
||||
|
@ -16,33 +16,46 @@ namespace ProtoBuf.Meta
|
|||
public class CallbackSet
|
||||
{
|
||||
private readonly MetaType metaType;
|
||||
|
||||
internal CallbackSet(MetaType metaType)
|
||||
{
|
||||
if (metaType == null) throw new ArgumentNullException("metaType");
|
||||
this.metaType = metaType;
|
||||
}
|
||||
|
||||
internal MethodInfo this[TypeModel.CallbackType callbackType]
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (callbackType)
|
||||
{
|
||||
case TypeModel.CallbackType.BeforeSerialize: return beforeSerialize;
|
||||
case TypeModel.CallbackType.AfterSerialize: return afterSerialize;
|
||||
case TypeModel.CallbackType.BeforeDeserialize: return beforeDeserialize;
|
||||
case TypeModel.CallbackType.AfterDeserialize: return afterDeserialize;
|
||||
default: throw new ArgumentException("Callback type not supported: " + callbackType.ToString(), "callbackType");
|
||||
case TypeModel.CallbackType.BeforeSerialize:
|
||||
return beforeSerialize;
|
||||
case TypeModel.CallbackType.AfterSerialize:
|
||||
return afterSerialize;
|
||||
case TypeModel.CallbackType.BeforeDeserialize:
|
||||
return beforeDeserialize;
|
||||
case TypeModel.CallbackType.AfterDeserialize:
|
||||
return afterDeserialize;
|
||||
default:
|
||||
throw new ArgumentException("Callback type not supported: " + callbackType.ToString(),
|
||||
"callbackType");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool CheckCallbackParameters(TypeModel model, MethodInfo method)
|
||||
{
|
||||
ParameterInfo[] args = method.GetParameters();
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
Type paramType = args[i].ParameterType;
|
||||
if(paramType == model.MapType(typeof(SerializationContext))) {}
|
||||
else if(paramType == model.MapType(typeof(System.Type))) {}
|
||||
if (paramType == model.MapType(typeof (SerializationContext)))
|
||||
{
|
||||
}
|
||||
else if (paramType == model.MapType(typeof (System.Type)))
|
||||
{
|
||||
}
|
||||
#if PLAT_BINARYFORMATTER
|
||||
else if(paramType == model.MapType(typeof(System.Runtime.Serialization.StreamingContext))) {}
|
||||
#endif
|
||||
|
@ -50,47 +63,57 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private MethodInfo SanityCheckCallback(TypeModel model, MethodInfo callback)
|
||||
{
|
||||
metaType.ThrowIfFrozen();
|
||||
if (callback == null) return callback; // fine
|
||||
if (callback.IsStatic) throw new ArgumentException("Callbacks cannot be static", "callback");
|
||||
if (callback.ReturnType != model.MapType(typeof(void))
|
||||
if (callback.ReturnType != model.MapType(typeof (void))
|
||||
|| !CheckCallbackParameters(model, callback))
|
||||
{
|
||||
throw CreateInvalidCallbackSignature(callback);
|
||||
}
|
||||
return callback;
|
||||
}
|
||||
|
||||
internal static Exception CreateInvalidCallbackSignature(MethodInfo method)
|
||||
{
|
||||
return new NotSupportedException("Invalid callback signature in " + method.DeclaringType.FullName + "." + method.Name);
|
||||
return
|
||||
new NotSupportedException("Invalid callback signature in " + method.DeclaringType.FullName + "." +
|
||||
method.Name);
|
||||
}
|
||||
|
||||
private MethodInfo beforeSerialize, afterSerialize, beforeDeserialize, afterDeserialize;
|
||||
|
||||
/// <summary>Called before serializing an instance</summary>
|
||||
public MethodInfo BeforeSerialize
|
||||
{
|
||||
get { return beforeSerialize; }
|
||||
set { beforeSerialize = SanityCheckCallback(metaType.Model, value); }
|
||||
}
|
||||
|
||||
/// <summary>Called before deserializing an instance</summary>
|
||||
public MethodInfo BeforeDeserialize
|
||||
{
|
||||
get { return beforeDeserialize; }
|
||||
set { beforeDeserialize = SanityCheckCallback(metaType.Model, value); }
|
||||
}
|
||||
|
||||
/// <summary>Called after serializing an instance</summary>
|
||||
public MethodInfo AfterSerialize
|
||||
{
|
||||
get { return afterSerialize; }
|
||||
set { afterSerialize = SanityCheckCallback(metaType.Model, value); }
|
||||
}
|
||||
|
||||
/// <summary>Called after deserializing an instance</summary>
|
||||
public MethodInfo AfterDeserialize
|
||||
{
|
||||
get { return afterDeserialize; }
|
||||
set { afterDeserialize = SanityCheckCallback(metaType.Model, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True if any callback is set, else False
|
||||
/// </summary>
|
||||
|
@ -99,9 +122,10 @@ namespace ProtoBuf.Meta
|
|||
get
|
||||
{
|
||||
return beforeSerialize != null || beforeDeserialize != null
|
||||
|| afterSerialize != null || afterDeserialize != null;
|
||||
|| afterSerialize != null || afterDeserialize != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,6 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
|
||||
#if FEAT_IKVM
|
||||
using Type = IKVM.Reflection.Type;
|
||||
using IKVM.Reflection;
|
||||
|
@ -13,7 +12,6 @@ using System.Reflection;
|
|||
using System.Reflection.Emit;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using ProtoBuf.Serializers;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
|
@ -27,26 +25,30 @@ namespace ProtoBuf.Meta
|
|||
public sealed class RuntimeTypeModel : TypeModel
|
||||
{
|
||||
private byte options;
|
||||
|
||||
private const byte
|
||||
OPTIONS_InferTagFromNameDefault = 1,
|
||||
OPTIONS_IsDefaultModel = 2,
|
||||
OPTIONS_Frozen = 4,
|
||||
OPTIONS_AutoAddMissingTypes = 8,
|
||||
OPTIONS_InferTagFromNameDefault = 1,
|
||||
OPTIONS_IsDefaultModel = 2,
|
||||
OPTIONS_Frozen = 4,
|
||||
OPTIONS_AutoAddMissingTypes = 8,
|
||||
#if FEAT_COMPILER && !FX11
|
||||
OPTIONS_AutoCompile = 16,
|
||||
#endif
|
||||
OPTIONS_UseImplicitZeroDefaults = 32,
|
||||
OPTIONS_AllowParseableTypes = 64,
|
||||
OPTIONS_AutoAddProtoContractTypesOnly = 128;
|
||||
OPTIONS_UseImplicitZeroDefaults = 32,
|
||||
OPTIONS_AllowParseableTypes = 64,
|
||||
OPTIONS_AutoAddProtoContractTypesOnly = 128;
|
||||
|
||||
private bool GetOption(byte option)
|
||||
{
|
||||
return (options & option) == option;
|
||||
}
|
||||
|
||||
private void SetOption(byte option, bool value)
|
||||
{
|
||||
if (value) options |= option;
|
||||
else options &= (byte)~option;
|
||||
else options &= (byte) ~option;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Global default that
|
||||
/// enables/disables automatic tag generation based on the existing name / order
|
||||
|
@ -83,11 +85,13 @@ namespace ProtoBuf.Meta
|
|||
/// </summary>
|
||||
public bool UseImplicitZeroDefaults
|
||||
{
|
||||
get {return GetOption(OPTIONS_UseImplicitZeroDefaults);}
|
||||
set {
|
||||
get { return GetOption(OPTIONS_UseImplicitZeroDefaults); }
|
||||
set
|
||||
{
|
||||
if (!value && GetOption(OPTIONS_IsDefaultModel))
|
||||
{
|
||||
throw new InvalidOperationException("UseImplicitZeroDefaults cannot be disabled on the default model");
|
||||
throw new InvalidOperationException(
|
||||
"UseImplicitZeroDefaults cannot be disabled on the default model");
|
||||
}
|
||||
SetOption(OPTIONS_UseImplicitZeroDefaults, value);
|
||||
}
|
||||
|
@ -102,13 +106,17 @@ namespace ProtoBuf.Meta
|
|||
get { return GetOption(OPTIONS_AllowParseableTypes); }
|
||||
set { SetOption(OPTIONS_AllowParseableTypes, value); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
private sealed class Singleton
|
||||
{
|
||||
private Singleton() { }
|
||||
private Singleton()
|
||||
{
|
||||
}
|
||||
|
||||
internal static readonly RuntimeTypeModel Value = new RuntimeTypeModel(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The default model, used to support ProtoBuf.Serializer
|
||||
/// </summary>
|
||||
|
@ -116,11 +124,15 @@ namespace ProtoBuf.Meta
|
|||
{
|
||||
get { return Singleton.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a sequence of the Type instances that can be
|
||||
/// processed by this model.
|
||||
/// </summary>
|
||||
public IEnumerable GetTypes() { return types; }
|
||||
public IEnumerable GetTypes()
|
||||
{
|
||||
return types;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Suggest a .proto definition for the given type
|
||||
|
@ -133,12 +145,14 @@ namespace ProtoBuf.Meta
|
|||
MetaType primaryType = null;
|
||||
bool isInbuiltType = false;
|
||||
if (type == null)
|
||||
{ // generate for the entire model
|
||||
foreach(MetaType meta in types)
|
||||
{
|
||||
// generate for the entire model
|
||||
foreach (MetaType meta in types)
|
||||
{
|
||||
MetaType tmp = meta.GetSurrogateOrBaseOrSelf(false);
|
||||
if (!requiredTypes.Contains(tmp))
|
||||
{ // ^^^ note that the type might have been added as a descendent
|
||||
{
|
||||
// ^^^ note that the type might have been added as a descendent
|
||||
requiredTypes.Add(tmp);
|
||||
CascadeDependents(requiredTypes, tmp);
|
||||
}
|
||||
|
@ -150,7 +164,9 @@ namespace ProtoBuf.Meta
|
|||
if (tmp != null) type = tmp;
|
||||
|
||||
WireType defaultWireType;
|
||||
isInbuiltType = (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out defaultWireType, false, false, false, false) != null);
|
||||
isInbuiltType =
|
||||
(ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out defaultWireType, false, false,
|
||||
false, false) != null);
|
||||
if (!isInbuiltType)
|
||||
{
|
||||
//Agenerate just relative to the supplied type
|
||||
|
@ -158,7 +174,7 @@ namespace ProtoBuf.Meta
|
|||
if (index < 0) throw new ArgumentException("The type specified is not a contract-type", "type");
|
||||
|
||||
// get the required types
|
||||
primaryType = ((MetaType)types[index]).GetSurrogateOrBaseOrSelf(false);
|
||||
primaryType = ((MetaType) types[index]).GetSurrogateOrBaseOrSelf(false);
|
||||
requiredTypes.Add(primaryType);
|
||||
CascadeDependents(requiredTypes, primaryType);
|
||||
}
|
||||
|
@ -179,14 +195,17 @@ namespace ProtoBuf.Meta
|
|||
{
|
||||
if (tmp.StartsWith("System.")) continue;
|
||||
if (package == null)
|
||||
{ // haven't seen any suggestions yet
|
||||
{
|
||||
// haven't seen any suggestions yet
|
||||
package = tmp;
|
||||
}
|
||||
else if (package == tmp)
|
||||
{ // that's fine; a repeat of the one we already saw
|
||||
{
|
||||
// that's fine; a repeat of the one we already saw
|
||||
}
|
||||
else
|
||||
{ // something else; have confliucting suggestions; abort
|
||||
{
|
||||
// something else; have confliucting suggestions; abort
|
||||
package = null;
|
||||
break;
|
||||
}
|
||||
|
@ -211,7 +230,9 @@ namespace ProtoBuf.Meta
|
|||
if (isInbuiltType)
|
||||
{
|
||||
Helpers.AppendLine(bodyBuilder).Append("message ").Append(type.Name).Append(" {");
|
||||
MetaType.NewLine(bodyBuilder, 1).Append("optional ").Append(GetSchemaTypeName(type, DataFormat.Default, false, false, ref requiresBclImport))
|
||||
MetaType.NewLine(bodyBuilder, 1)
|
||||
.Append("optional ")
|
||||
.Append(GetSchemaTypeName(type, DataFormat.Default, false, false, ref requiresBclImport))
|
||||
.Append(" value = 1;");
|
||||
Helpers.AppendLine(bodyBuilder).Append('}');
|
||||
}
|
||||
|
@ -231,6 +252,7 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
return Helpers.AppendLine(headerBuilder.Append(bodyBuilder)).ToString();
|
||||
}
|
||||
|
||||
private void CascadeDependents(BasicList list, MetaType metaType)
|
||||
{
|
||||
MetaType tmp;
|
||||
|
@ -238,15 +260,17 @@ namespace ProtoBuf.Meta
|
|||
{
|
||||
Type itemType = TypeModel.GetListItemType(this, metaType.Type);
|
||||
WireType defaultWireType;
|
||||
IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(this, DataFormat.Default, itemType, out defaultWireType, false, false, false, false);
|
||||
IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(this, DataFormat.Default, itemType,
|
||||
out defaultWireType, false, false, false, false);
|
||||
if (coreSerializer == null)
|
||||
{
|
||||
int index = FindOrAddAuto(itemType, false, false, false);
|
||||
if (index >= 0)
|
||||
{
|
||||
tmp = ((MetaType)types[index]).GetSurrogateOrBaseOrSelf(false);
|
||||
tmp = ((MetaType) types[index]).GetSurrogateOrBaseOrSelf(false);
|
||||
if (!list.Contains(tmp))
|
||||
{ // could perhaps also implement as a queue, but this should work OK for sane models
|
||||
{
|
||||
// could perhaps also implement as a queue, but this should work OK for sane models
|
||||
list.Add(tmp);
|
||||
CascadeDependents(list, tmp);
|
||||
}
|
||||
|
@ -258,24 +282,26 @@ namespace ProtoBuf.Meta
|
|||
if (metaType.IsAutoTuple)
|
||||
{
|
||||
MemberInfo[] mapping;
|
||||
if(MetaType.ResolveTupleConstructor(metaType.Type, out mapping) != null)
|
||||
if (MetaType.ResolveTupleConstructor(metaType.Type, out mapping) != null)
|
||||
{
|
||||
for (int i = 0; i < mapping.Length; i++)
|
||||
{
|
||||
Type type = null;
|
||||
if (mapping[i] is PropertyInfo) type = ((PropertyInfo)mapping[i]).PropertyType;
|
||||
else if (mapping[i] is FieldInfo) type = ((FieldInfo)mapping[i]).FieldType;
|
||||
if (mapping[i] is PropertyInfo) type = ((PropertyInfo) mapping[i]).PropertyType;
|
||||
else if (mapping[i] is FieldInfo) type = ((FieldInfo) mapping[i]).FieldType;
|
||||
|
||||
WireType defaultWireType;
|
||||
IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out defaultWireType, false, false, false, false);
|
||||
IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(this, DataFormat.Default,
|
||||
type, out defaultWireType, false, false, false, false);
|
||||
if (coreSerializer == null)
|
||||
{
|
||||
int index = FindOrAddAuto(type, false, false, false);
|
||||
if (index >= 0)
|
||||
{
|
||||
tmp = ((MetaType)types[index]).GetSurrogateOrBaseOrSelf(false);
|
||||
tmp = ((MetaType) types[index]).GetSurrogateOrBaseOrSelf(false);
|
||||
if (!list.Contains(tmp))
|
||||
{ // could perhaps also implement as a queue, but this should work OK for sane models
|
||||
{
|
||||
// could perhaps also implement as a queue, but this should work OK for sane models
|
||||
list.Add(tmp);
|
||||
CascadeDependents(list, tmp);
|
||||
}
|
||||
|
@ -291,16 +317,18 @@ namespace ProtoBuf.Meta
|
|||
Type type = member.ItemType;
|
||||
if (type == null) type = member.MemberType;
|
||||
WireType defaultWireType;
|
||||
IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out defaultWireType, false, false, false, false);
|
||||
IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(this, DataFormat.Default,
|
||||
type, out defaultWireType, false, false, false, false);
|
||||
if (coreSerializer == null)
|
||||
{
|
||||
// is an interesting type
|
||||
int index = FindOrAddAuto(type, false, false, false);
|
||||
if (index >= 0)
|
||||
{
|
||||
tmp = ((MetaType)types[index]).GetSurrogateOrBaseOrSelf(false);
|
||||
tmp = ((MetaType) types[index]).GetSurrogateOrBaseOrSelf(false);
|
||||
if (!list.Contains(tmp))
|
||||
{ // could perhaps also implement as a queue, but this should work OK for sane models
|
||||
{
|
||||
// could perhaps also implement as a queue, but this should work OK for sane models
|
||||
list.Add(tmp);
|
||||
CascadeDependents(list, tmp);
|
||||
}
|
||||
|
@ -392,8 +420,11 @@ namespace ProtoBuf.Meta
|
|||
/// Obtains the MetaType associated with a given Type for the current model,
|
||||
/// allowing additional configuration.
|
||||
/// </summary>
|
||||
public MetaType this[Type type] { get { return (MetaType)types[FindOrAddAuto(type, true, false, false)]; } }
|
||||
|
||||
public MetaType this[Type type]
|
||||
{
|
||||
get { return (MetaType) types[FindOrAddAuto(type, true, false, false)]; }
|
||||
}
|
||||
|
||||
internal MetaType FindWithoutAdd(Type type)
|
||||
{
|
||||
// this list is thread-safe for reading
|
||||
|
@ -410,16 +441,18 @@ namespace ProtoBuf.Meta
|
|||
return underlyingType == null ? null : FindWithoutAdd(underlyingType);
|
||||
}
|
||||
|
||||
static readonly BasicList.MatchPredicate
|
||||
private static readonly BasicList.MatchPredicate
|
||||
MetaTypeFinder = new BasicList.MatchPredicate(MetaTypeFinderImpl),
|
||||
BasicTypeFinder = new BasicList.MatchPredicate(BasicTypeFinderImpl);
|
||||
static bool MetaTypeFinderImpl(object value, object ctx)
|
||||
|
||||
private static bool MetaTypeFinderImpl(object value, object ctx)
|
||||
{
|
||||
return ((MetaType)value).Type == (Type)ctx;
|
||||
return ((MetaType) value).Type == (Type) ctx;
|
||||
}
|
||||
static bool BasicTypeFinderImpl(object value, object ctx)
|
||||
|
||||
private static bool BasicTypeFinderImpl(object value, object ctx)
|
||||
{
|
||||
return ((BasicType)value).Type == (Type)ctx;
|
||||
return ((BasicType) value).Type == (Type) ctx;
|
||||
}
|
||||
|
||||
private void WaitOnLock(MetaType type)
|
||||
|
@ -434,43 +467,56 @@ namespace ProtoBuf.Meta
|
|||
ReleaseLock(opaqueToken);
|
||||
}
|
||||
}
|
||||
BasicList basicTypes = new BasicList();
|
||||
|
||||
sealed class BasicType
|
||||
private BasicList basicTypes = new BasicList();
|
||||
|
||||
private sealed class BasicType
|
||||
{
|
||||
private readonly Type type;
|
||||
public Type Type { get { return type; } }
|
||||
|
||||
public Type Type
|
||||
{
|
||||
get { return type; }
|
||||
}
|
||||
|
||||
private readonly IProtoSerializer serializer;
|
||||
public IProtoSerializer Serializer { get { return serializer; } }
|
||||
|
||||
public IProtoSerializer Serializer
|
||||
{
|
||||
get { return serializer; }
|
||||
}
|
||||
|
||||
public BasicType(Type type, IProtoSerializer serializer)
|
||||
{
|
||||
this.type = type;
|
||||
this.serializer = serializer;
|
||||
}
|
||||
}
|
||||
|
||||
internal IProtoSerializer TryGetBasicTypeSerializer(Type type)
|
||||
{
|
||||
int idx = basicTypes.IndexOf(BasicTypeFinder, type);
|
||||
|
||||
if (idx >= 0) return ((BasicType)basicTypes[idx]).Serializer;
|
||||
if (idx >= 0) return ((BasicType) basicTypes[idx]).Serializer;
|
||||
|
||||
lock(basicTypes)
|
||||
{ // don't need a full model lock for this
|
||||
lock (basicTypes)
|
||||
{
|
||||
// don't need a full model lock for this
|
||||
|
||||
// double-checked
|
||||
idx = basicTypes.IndexOf(BasicTypeFinder, type);
|
||||
if (idx >= 0) return ((BasicType)basicTypes[idx]).Serializer;
|
||||
if (idx >= 0) return ((BasicType) basicTypes[idx]).Serializer;
|
||||
|
||||
WireType defaultWireType;
|
||||
MetaType.AttributeFamily family = MetaType.GetContractFamily(this, type, null);
|
||||
IProtoSerializer ser = family == MetaType.AttributeFamily.None
|
||||
? ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out defaultWireType, false, false, false, false)
|
||||
? ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out defaultWireType, false, false,
|
||||
false, false)
|
||||
: null;
|
||||
|
||||
if(ser != null) basicTypes.Add(new BasicType(type, ser));
|
||||
if (ser != null) basicTypes.Add(new BasicType(type, ser));
|
||||
return ser;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal int FindOrAddAuto(Type type, bool demand, bool addWithContractOnly, bool addEvenIfAutoDisabled)
|
||||
|
@ -481,7 +527,7 @@ namespace ProtoBuf.Meta
|
|||
// the fast happy path: meta-types we've already seen
|
||||
if (key >= 0)
|
||||
{
|
||||
metaType = (MetaType)types[key];
|
||||
metaType = (MetaType) types[key];
|
||||
if (metaType.Pending)
|
||||
{
|
||||
WaitOnLock(metaType);
|
||||
|
@ -516,7 +562,8 @@ namespace ProtoBuf.Meta
|
|||
TakeLock(ref opaqueToken);
|
||||
// try to recognise a few familiar patterns...
|
||||
if ((metaType = RecogniseCommonTypes(type)) == null)
|
||||
{ // otherwise, check if it is a contract
|
||||
{
|
||||
// otherwise, check if it is a contract
|
||||
MetaType.AttributeFamily family = MetaType.GetContractFamily(this, type, null);
|
||||
if (family == MetaType.AttributeFamily.AutoTuple)
|
||||
{
|
||||
|
@ -532,7 +579,7 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
metaType = Create(type);
|
||||
}
|
||||
metaType.Pending = true;
|
||||
metaType.Pending = true;
|
||||
bool weAdded = false;
|
||||
|
||||
// double-checked
|
||||
|
@ -585,6 +632,7 @@ namespace ProtoBuf.Meta
|
|||
//#endif
|
||||
return null;
|
||||
}
|
||||
|
||||
private MetaType Create(Type type)
|
||||
{
|
||||
ThrowIfFrozen();
|
||||
|
@ -615,59 +663,66 @@ namespace ProtoBuf.Meta
|
|||
MetaType newType = FindWithoutAdd(type);
|
||||
if (newType != null) return newType; // return existing
|
||||
int opaqueToken = 0;
|
||||
|
||||
|
||||
#if WINRT
|
||||
System.Reflection.TypeInfo typeInfo = System.Reflection.IntrospectionExtensions.GetTypeInfo(type);
|
||||
if (typeInfo.IsInterface && MetaType.ienumerable.IsAssignableFrom(typeInfo)
|
||||
#else
|
||||
if (type.IsInterface && MapType(MetaType.ienumerable).IsAssignableFrom(type)
|
||||
#endif
|
||||
&& GetListItemType(this, type) == null)
|
||||
&& GetListItemType(this, type) == null)
|
||||
{
|
||||
throw new ArgumentException("IEnumerable[<T>] data cannot be used as a meta-type unless an Add method can be resolved");
|
||||
throw new ArgumentException(
|
||||
"IEnumerable[<T>] data cannot be used as a meta-type unless an Add method can be resolved");
|
||||
}
|
||||
try
|
||||
{
|
||||
newType = RecogniseCommonTypes(type);
|
||||
if(newType != null)
|
||||
if (newType != null)
|
||||
{
|
||||
if(!applyDefaultBehaviour) {
|
||||
if (!applyDefaultBehaviour)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Default behaviour must be observed for certain types with special handling; " + type.FullName,
|
||||
"Default behaviour must be observed for certain types with special handling; " +
|
||||
type.FullName,
|
||||
"applyDefaultBehaviour");
|
||||
}
|
||||
// we should assume that type is fully configured, though; no need to re-run:
|
||||
applyDefaultBehaviour = false;
|
||||
}
|
||||
if(newType == null) newType = Create(type);
|
||||
if (newType == null) newType = Create(type);
|
||||
newType.Pending = true;
|
||||
TakeLock(ref opaqueToken);
|
||||
// double checked
|
||||
if (FindWithoutAdd(type) != null) throw new ArgumentException("Duplicate type", "type");
|
||||
ThrowIfFrozen();
|
||||
types.Add(newType);
|
||||
if (applyDefaultBehaviour) { newType.ApplyDefaultBehaviour(); }
|
||||
if (applyDefaultBehaviour)
|
||||
{
|
||||
newType.ApplyDefaultBehaviour();
|
||||
}
|
||||
newType.Pending = false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseLock(opaqueToken);
|
||||
}
|
||||
|
||||
|
||||
return newType;
|
||||
}
|
||||
|
||||
#if FEAT_COMPILER && !FX11
|
||||
/// <summary>
|
||||
/// Should serializers be compiled on demand? It may be useful
|
||||
/// to disable this for debugging purposes.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Should serializers be compiled on demand? It may be useful
|
||||
/// to disable this for debugging purposes.
|
||||
/// </summary>
|
||||
public bool AutoCompile
|
||||
{
|
||||
get { return GetOption(OPTIONS_AutoCompile); }
|
||||
set { SetOption(OPTIONS_AutoCompile, value); }
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Should support for unexpected types be added automatically?
|
||||
/// If false, an exception is thrown when unexpected types
|
||||
|
@ -676,7 +731,8 @@ namespace ProtoBuf.Meta
|
|||
public bool AutoAddMissingTypes
|
||||
{
|
||||
get { return GetOption(OPTIONS_AutoAddMissingTypes); }
|
||||
set {
|
||||
set
|
||||
{
|
||||
if (!value && GetOption(OPTIONS_IsDefaultModel))
|
||||
{
|
||||
throw new InvalidOperationException("The default model must allow missing types");
|
||||
|
@ -685,19 +741,23 @@ namespace ProtoBuf.Meta
|
|||
SetOption(OPTIONS_AutoAddMissingTypes, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the model is still open to changes; if not, an exception is thrown
|
||||
/// </summary>
|
||||
private void ThrowIfFrozen()
|
||||
{
|
||||
if (GetOption(OPTIONS_Frozen)) throw new InvalidOperationException("The model cannot be changed once frozen");
|
||||
if (GetOption(OPTIONS_Frozen))
|
||||
throw new InvalidOperationException("The model cannot be changed once frozen");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prevents further changes to this model
|
||||
/// </summary>
|
||||
public void Freeze()
|
||||
{
|
||||
if (GetOption(OPTIONS_IsDefaultModel)) throw new InvalidOperationException("The default model cannot be frozen");
|
||||
if (GetOption(OPTIONS_IsDefaultModel))
|
||||
throw new InvalidOperationException("The default model cannot be frozen");
|
||||
SetOption(OPTIONS_Frozen, true);
|
||||
}
|
||||
|
||||
|
@ -710,6 +770,7 @@ namespace ProtoBuf.Meta
|
|||
{
|
||||
return GetKey(type, false, true);
|
||||
}
|
||||
|
||||
internal int GetKey(Type type, bool demand, bool getBaseKey)
|
||||
{
|
||||
Helpers.DebugAssert(type != null);
|
||||
|
@ -718,11 +779,11 @@ namespace ProtoBuf.Meta
|
|||
int typeIndex = FindOrAddAuto(type, demand, true, false);
|
||||
if (typeIndex >= 0)
|
||||
{
|
||||
MetaType mt = (MetaType)types[typeIndex];
|
||||
MetaType mt = (MetaType) types[typeIndex];
|
||||
if (getBaseKey)
|
||||
{
|
||||
mt = MetaType.GetRootType(mt);
|
||||
typeIndex = FindOrAddAuto(mt.Type, true, true, false);
|
||||
typeIndex = FindOrAddAuto(mt.Type, true, true, false);
|
||||
}
|
||||
}
|
||||
return typeIndex;
|
||||
|
@ -733,10 +794,11 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex.Message.IndexOf(type.FullName) >= 0) throw; // already enough info
|
||||
if (ex.Message.IndexOf(type.FullName) >= 0) throw; // already enough info
|
||||
throw new ProtoException(ex.Message + " (" + type.FullName + ")", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a protocol-buffer representation of the given instance to the supplied stream.
|
||||
/// </summary>
|
||||
|
@ -749,9 +811,10 @@ namespace ProtoBuf.Meta
|
|||
throw new NotSupportedException();
|
||||
#else
|
||||
//Helpers.DebugWriteLine("Serialize", value);
|
||||
((MetaType)types[key]).Serializer.Write(value, dest);
|
||||
((MetaType) types[key]).Serializer.Write(value, dest);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies a protocol-buffer stream to an existing instance (which may be null).
|
||||
/// </summary>
|
||||
|
@ -767,18 +830,21 @@ namespace ProtoBuf.Meta
|
|||
throw new NotSupportedException();
|
||||
#else
|
||||
//Helpers.DebugWriteLine("Deserialize", value);
|
||||
IProtoSerializer ser = ((MetaType)types[key]).Serializer;
|
||||
if (value == null && Helpers.IsValueType(ser.ExpectedType)) {
|
||||
if(ser.RequiresOldValue) value = Activator.CreateInstance(ser.ExpectedType);
|
||||
IProtoSerializer ser = ((MetaType) types[key]).Serializer;
|
||||
if (value == null && Helpers.IsValueType(ser.ExpectedType))
|
||||
{
|
||||
if (ser.RequiresOldValue) value = Activator.CreateInstance(ser.ExpectedType);
|
||||
return ser.Read(value, source);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return ser.Read(value, source);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if FEAT_COMPILER
|
||||
// this is used by some unit-tests; do not remove
|
||||
// this is used by some unit-tests; do not remove
|
||||
internal Compiler.ProtoSerializer GetSerializer(IProtoSerializer serializer, bool compiled)
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
|
@ -820,7 +886,7 @@ namespace ProtoBuf.Meta
|
|||
|
||||
//}
|
||||
|
||||
|
||||
|
||||
#if FEAT_COMPILER
|
||||
private void BuildAllSerializers()
|
||||
{
|
||||
|
@ -1664,10 +1730,11 @@ namespace ProtoBuf.Meta
|
|||
internal EnumSerializer.EnumPair[] GetEnumMap(Type type)
|
||||
{
|
||||
int index = FindOrAddAuto(type, false, false, false);
|
||||
return index < 0 ? null : ((MetaType)types[index]).GetEnumMap();
|
||||
return index < 0 ? null : ((MetaType) types[index]).GetEnumMap();
|
||||
}
|
||||
|
||||
private int metadataTimeoutMilliseconds = 5000;
|
||||
|
||||
/// <summary>
|
||||
/// The amount of time to wait if there are concurrent metadata access operations
|
||||
/// </summary>
|
||||
|
@ -1682,15 +1749,21 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
|
||||
#if DEBUG
|
||||
int lockCount;
|
||||
private int lockCount;
|
||||
|
||||
/// <summary>
|
||||
/// Gets how many times a model lock was taken
|
||||
/// </summary>
|
||||
public int LockCount { get { return lockCount; } }
|
||||
public int LockCount
|
||||
{
|
||||
get { return lockCount; }
|
||||
}
|
||||
#endif
|
||||
|
||||
internal void TakeLock(ref int opaqueToken)
|
||||
{
|
||||
const string message = "Timeout while inspecting metadata; this may indicate a deadlock. This can often be avoided by preparing necessary serializers during application initialization, rather than allowing multiple threads to perform the initial metadata inspection; please also see the LockContended event";
|
||||
const string message =
|
||||
"Timeout while inspecting metadata; this may indicate a deadlock. This can often be avoided by preparing necessary serializers during application initialization, rather than allowing multiple threads to perform the initial metadata inspection; please also see the LockContended event";
|
||||
opaqueToken = 0;
|
||||
#if PORTABLE
|
||||
if(!Monitor.TryEnter(types)) throw new TimeoutException(message); // yes, we have to do this immediately - I'm not creating a "hot" loop, just because Sleep() doesn't exist...
|
||||
|
@ -1733,6 +1806,7 @@ namespace ProtoBuf.Meta
|
|||
#if PLAT_NO_INTERLOCKED
|
||||
private readonly object contentionLock = new object();
|
||||
#endif
|
||||
|
||||
private int GetContention()
|
||||
{
|
||||
#if PLAT_NO_INTERLOCKED
|
||||
|
@ -1744,6 +1818,7 @@ namespace ProtoBuf.Meta
|
|||
return Interlocked.CompareExchange(ref contentionCounter, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
private void AddContention()
|
||||
{
|
||||
#if PLAT_NO_INTERLOCKED
|
||||
|
@ -1761,7 +1836,7 @@ namespace ProtoBuf.Meta
|
|||
if (opaqueToken != 0)
|
||||
{
|
||||
Monitor.Exit(types);
|
||||
if(opaqueToken != GetContention()) // contention-count changes since we looked!
|
||||
if (opaqueToken != GetContention()) // contention-count changes since we looked!
|
||||
{
|
||||
LockContentedEventHandler handler = LockContended;
|
||||
if (handler != null)
|
||||
|
@ -1772,16 +1847,17 @@ namespace ProtoBuf.Meta
|
|||
{
|
||||
throw new ProtoException();
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
stackTrace = ex.StackTrace;
|
||||
}
|
||||
|
||||
|
||||
handler(this, new LockContentedEventArgs(stackTrace));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If a lock-contention is detected, this event signals the *owner* of the lock responsible for the blockage, indicating
|
||||
/// what caused the problem; this is only raised if the lock-owning code successfully completes.
|
||||
|
@ -1791,8 +1867,8 @@ namespace ProtoBuf.Meta
|
|||
internal void ResolveListTypes(Type type, ref Type itemType, ref Type defaultType)
|
||||
{
|
||||
if (type == null) return;
|
||||
if(Helpers.GetTypeCode(type) != ProtoTypeCode.Unknown) return; // don't try this[type] for inbuilts
|
||||
if(this[type].IgnoreListHandling) return;
|
||||
if (Helpers.GetTypeCode(type) != ProtoTypeCode.Unknown) return; // don't try this[type] for inbuilts
|
||||
if (this[type].IgnoreListHandling) return;
|
||||
|
||||
// handle arrays
|
||||
if (type.IsArray)
|
||||
|
@ -1802,7 +1878,7 @@ namespace ProtoBuf.Meta
|
|||
throw new NotSupportedException("Multi-dimension arrays are supported");
|
||||
}
|
||||
itemType = type.GetElementType();
|
||||
if (itemType == MapType(typeof(byte)))
|
||||
if (itemType == MapType(typeof (byte)))
|
||||
{
|
||||
defaultType = itemType = null;
|
||||
}
|
||||
|
@ -1812,7 +1888,10 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
}
|
||||
// handle lists
|
||||
if (itemType == null) { itemType = TypeModel.GetListItemType(this, type); }
|
||||
if (itemType == null)
|
||||
{
|
||||
itemType = TypeModel.GetListItemType(this, type);
|
||||
}
|
||||
|
||||
// check for nested data (not allowed)
|
||||
if (itemType != null)
|
||||
|
@ -1852,25 +1931,34 @@ namespace ProtoBuf.Meta
|
|||
if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(System.Collections.Generic.IDictionary<,>)
|
||||
&& itemType == typeof(System.Collections.Generic.KeyValuePair<,>).MakeGenericType(genArgs = typeInfo.GenericTypeArguments))
|
||||
#else
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == MapType(typeof(System.Collections.Generic.IDictionary<,>))
|
||||
&& itemType == MapType(typeof(System.Collections.Generic.KeyValuePair<,>)).MakeGenericType(genArgs = type.GetGenericArguments()))
|
||||
if (type.IsGenericType &&
|
||||
type.GetGenericTypeDefinition() ==
|
||||
MapType(typeof (System.Collections.Generic.IDictionary<,>))
|
||||
&&
|
||||
itemType ==
|
||||
MapType(typeof (System.Collections.Generic.KeyValuePair<,>))
|
||||
.MakeGenericType(genArgs = type.GetGenericArguments()))
|
||||
#endif
|
||||
{
|
||||
defaultType = MapType(typeof(System.Collections.Generic.Dictionary<,>)).MakeGenericType(genArgs);
|
||||
defaultType =
|
||||
MapType(typeof (System.Collections.Generic.Dictionary<,>)).MakeGenericType(genArgs);
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultType = MapType(typeof(System.Collections.Generic.List<>)).MakeGenericType(itemType);
|
||||
defaultType = MapType(typeof (System.Collections.Generic.List<>)).MakeGenericType(itemType);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// verify that the default type is appropriate
|
||||
if (defaultType != null && !Helpers.IsAssignableFrom(type, defaultType)) { defaultType = null; }
|
||||
if (defaultType != null && !Helpers.IsAssignableFrom(type, defaultType))
|
||||
{
|
||||
defaultType = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if FEAT_IKVM
|
||||
internal override Type GetType(string fullName, Assembly context)
|
||||
{
|
||||
|
@ -1883,17 +1971,20 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
#endif
|
||||
|
||||
internal string GetSchemaTypeName(Type effectiveType, DataFormat dataFormat, bool asReference, bool dynamicType, ref bool requiresBclImport)
|
||||
internal string GetSchemaTypeName(Type effectiveType, DataFormat dataFormat, bool asReference, bool dynamicType,
|
||||
ref bool requiresBclImport)
|
||||
{
|
||||
Type tmp = Helpers.GetUnderlyingType(effectiveType);
|
||||
if (tmp != null) effectiveType = tmp;
|
||||
|
||||
if (effectiveType == this.MapType(typeof(byte[]))) return "bytes";
|
||||
if (effectiveType == this.MapType(typeof (byte[]))) return "bytes";
|
||||
|
||||
WireType wireType;
|
||||
IProtoSerializer ser = ValueMember.TryGetCoreSerializer(this, dataFormat, effectiveType, out wireType, false, false, false, false);
|
||||
IProtoSerializer ser = ValueMember.TryGetCoreSerializer(this, dataFormat, effectiveType, out wireType, false,
|
||||
false, false, false);
|
||||
if (ser == null)
|
||||
{ // model type
|
||||
{
|
||||
// model type
|
||||
if (asReference || dynamicType)
|
||||
{
|
||||
requiresBclImport = true;
|
||||
|
@ -1911,9 +2002,12 @@ namespace ProtoBuf.Meta
|
|||
|
||||
switch (Helpers.GetTypeCode(effectiveType))
|
||||
{
|
||||
case ProtoTypeCode.Boolean: return "bool";
|
||||
case ProtoTypeCode.Single: return "float";
|
||||
case ProtoTypeCode.Double: return "double";
|
||||
case ProtoTypeCode.Boolean:
|
||||
return "bool";
|
||||
case ProtoTypeCode.Single:
|
||||
return "float";
|
||||
case ProtoTypeCode.Double:
|
||||
return "double";
|
||||
case ProtoTypeCode.String:
|
||||
if (asReference) requiresBclImport = true;
|
||||
return asReference ? "bcl.NetObjectProxy" : "string";
|
||||
|
@ -1923,39 +2017,57 @@ namespace ProtoBuf.Meta
|
|||
case ProtoTypeCode.UInt32:
|
||||
switch (dataFormat)
|
||||
{
|
||||
case DataFormat.FixedSize: return "fixed32";
|
||||
default: return "uint32";
|
||||
case DataFormat.FixedSize:
|
||||
return "fixed32";
|
||||
default:
|
||||
return "uint32";
|
||||
}
|
||||
case ProtoTypeCode.SByte:
|
||||
case ProtoTypeCode.Int16:
|
||||
case ProtoTypeCode.Int32:
|
||||
switch (dataFormat)
|
||||
{
|
||||
case DataFormat.ZigZag: return "sint32";
|
||||
case DataFormat.FixedSize: return "sfixed32";
|
||||
default: return "int32";
|
||||
case DataFormat.ZigZag:
|
||||
return "sint32";
|
||||
case DataFormat.FixedSize:
|
||||
return "sfixed32";
|
||||
default:
|
||||
return "int32";
|
||||
}
|
||||
case ProtoTypeCode.UInt64:
|
||||
switch (dataFormat)
|
||||
{
|
||||
case DataFormat.FixedSize: return "fixed64";
|
||||
default: return "uint64";
|
||||
case DataFormat.FixedSize:
|
||||
return "fixed64";
|
||||
default:
|
||||
return "uint64";
|
||||
}
|
||||
case ProtoTypeCode.Int64:
|
||||
switch (dataFormat)
|
||||
{
|
||||
case DataFormat.ZigZag: return "sint64";
|
||||
case DataFormat.FixedSize: return "sfixed64";
|
||||
default: return "int64";
|
||||
case DataFormat.ZigZag:
|
||||
return "sint64";
|
||||
case DataFormat.FixedSize:
|
||||
return "sfixed64";
|
||||
default:
|
||||
return "int64";
|
||||
}
|
||||
case ProtoTypeCode.DateTime: requiresBclImport = true; return "bcl.DateTime";
|
||||
case ProtoTypeCode.TimeSpan: requiresBclImport = true; return "bcl.TimeSpan";
|
||||
case ProtoTypeCode.Decimal: requiresBclImport = true; return "bcl.Decimal";
|
||||
case ProtoTypeCode.Guid: requiresBclImport = true; return "bcl.Guid";
|
||||
default: throw new NotSupportedException("No .proto map found for: " + effectiveType.FullName);
|
||||
case ProtoTypeCode.DateTime:
|
||||
requiresBclImport = true;
|
||||
return "bcl.DateTime";
|
||||
case ProtoTypeCode.TimeSpan:
|
||||
requiresBclImport = true;
|
||||
return "bcl.TimeSpan";
|
||||
case ProtoTypeCode.Decimal:
|
||||
requiresBclImport = true;
|
||||
return "bcl.Decimal";
|
||||
case ProtoTypeCode.Guid:
|
||||
requiresBclImport = true;
|
||||
return "bcl.Guid";
|
||||
default:
|
||||
throw new NotSupportedException("No .proto map found for: " + effectiveType.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1966,6 +2078,7 @@ namespace ProtoBuf.Meta
|
|||
VerifyFactory(methodInfo, null);
|
||||
defaultFactory = methodInfo;
|
||||
}
|
||||
|
||||
private MethodInfo defaultFactory;
|
||||
|
||||
internal void VerifyFactory(MethodInfo factory, Type type)
|
||||
|
@ -1974,32 +2087,43 @@ namespace ProtoBuf.Meta
|
|||
{
|
||||
if (type != null && Helpers.IsValueType(type)) throw new InvalidOperationException();
|
||||
if (!factory.IsStatic) throw new ArgumentException("A factory-method must be static", "factory");
|
||||
if ((type != null && factory.ReturnType != type) && factory.ReturnType != MapType(typeof(object))) throw new ArgumentException("The factory-method must return object" + (type == null ? "" : (" or " + type.FullName)), "factory");
|
||||
if ((type != null && factory.ReturnType != type) && factory.ReturnType != MapType(typeof (object)))
|
||||
throw new ArgumentException(
|
||||
"The factory-method must return object" + (type == null ? "" : (" or " + type.FullName)),
|
||||
"factory");
|
||||
|
||||
if (!CallbackSet.CheckCallbackParameters(this, factory)) throw new ArgumentException("Invalid factory signature in " + factory.DeclaringType.FullName + "." + factory.Name, "factory");
|
||||
if (!CallbackSet.CheckCallbackParameters(this, factory))
|
||||
throw new ArgumentException(
|
||||
"Invalid factory signature in " + factory.DeclaringType.FullName + "." + factory.Name, "factory");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains the stack-trace of the owning code when a lock-contention scenario is detected
|
||||
/// </summary>
|
||||
public sealed class LockContentedEventArgs : EventArgs
|
||||
{
|
||||
private readonly string ownerStackTrace;
|
||||
|
||||
internal LockContentedEventArgs(string ownerStackTrace)
|
||||
{
|
||||
this.ownerStackTrace = ownerStackTrace;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The stack-trace of the code that owned the lock when a lock-contention scenario occurred
|
||||
/// </summary>
|
||||
public string OwnerStackTrace { get { return ownerStackTrace; } }
|
||||
public string OwnerStackTrace
|
||||
{
|
||||
get { return ownerStackTrace; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event-type that is raised when a lock-contention scenario is detected
|
||||
/// </summary>
|
||||
public delegate void LockContentedEventHandler(object sender, LockContentedEventArgs args);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -11,14 +11,16 @@ namespace ProtoBuf.Meta
|
|||
{
|
||||
internal sealed class Comparer : System.Collections.IComparer
|
||||
#if !NO_GENERICS
|
||||
, System.Collections.Generic.IComparer<SubType>
|
||||
, System.Collections.Generic.IComparer<SubType>
|
||||
#endif
|
||||
{
|
||||
public static readonly Comparer Default = new Comparer();
|
||||
|
||||
public int Compare(object x, object y)
|
||||
{
|
||||
return Compare(x as SubType, y as SubType);
|
||||
}
|
||||
|
||||
public int Compare(SubType x, SubType y)
|
||||
{
|
||||
if (ReferenceEquals(x, y)) return 0;
|
||||
|
@ -28,16 +30,26 @@ namespace ProtoBuf.Meta
|
|||
return x.FieldNumber.CompareTo(y.FieldNumber);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly int fieldNumber;
|
||||
|
||||
/// <summary>
|
||||
/// The field-number that is used to encapsulate the data (as a nested
|
||||
/// message) for the derived dype.
|
||||
/// </summary>
|
||||
public int FieldNumber { get { return fieldNumber; } }
|
||||
public int FieldNumber
|
||||
{
|
||||
get { return fieldNumber; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The sub-type to be considered.
|
||||
/// </summary>
|
||||
public MetaType DerivedType { get { return derivedType; } }
|
||||
public MetaType DerivedType
|
||||
{
|
||||
get { return derivedType; }
|
||||
}
|
||||
|
||||
private readonly MetaType derivedType;
|
||||
|
||||
/// <summary>
|
||||
|
@ -59,6 +71,7 @@ namespace ProtoBuf.Meta
|
|||
private readonly DataFormat dataFormat;
|
||||
|
||||
private IProtoSerializer serializer;
|
||||
|
||||
internal IProtoSerializer Serializer
|
||||
{
|
||||
get
|
||||
|
@ -72,11 +85,13 @@ namespace ProtoBuf.Meta
|
|||
{
|
||||
// note the caller here is MetaType.BuildSerializer, which already has the sync-lock
|
||||
WireType wireType = WireType.String;
|
||||
if(dataFormat == DataFormat.Group) wireType = WireType.StartGroup; // only one exception
|
||||
|
||||
IProtoSerializer ser = new SubItemSerializer(derivedType.Type, derivedType.GetKey(false, false), derivedType, false);
|
||||
if (dataFormat == DataFormat.Group) wireType = WireType.StartGroup; // only one exception
|
||||
|
||||
IProtoSerializer ser = new SubItemSerializer(derivedType.Type, derivedType.GetKey(false, false), derivedType,
|
||||
false);
|
||||
return new TagDecorator(fieldNumber, wireType, false, ser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -11,6 +11,7 @@ namespace ProtoBuf.Meta
|
|||
private Type type;
|
||||
private string formattedName;
|
||||
private readonly bool typeFixed;
|
||||
|
||||
/// <summary>
|
||||
/// The type involved in this map; if this is initially null, a Type is expected to be provided for the string in FormattedName.
|
||||
/// </summary>
|
||||
|
@ -19,13 +20,14 @@ namespace ProtoBuf.Meta
|
|||
get { return type; }
|
||||
set
|
||||
{
|
||||
if(type != value)
|
||||
if (type != value)
|
||||
{
|
||||
if (typeFixed) throw new InvalidOperationException("The type is fixed and cannot be changed");
|
||||
type = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The formatted-name involved in this map; if this is initially null, a formatted-name is expected from the type in Type.
|
||||
/// </summary>
|
||||
|
@ -36,27 +38,30 @@ namespace ProtoBuf.Meta
|
|||
{
|
||||
if (formattedName != value)
|
||||
{
|
||||
if (!typeFixed) throw new InvalidOperationException("The formatted-name is fixed and cannot be changed");
|
||||
if (!typeFixed)
|
||||
throw new InvalidOperationException("The formatted-name is fixed and cannot be changed");
|
||||
formattedName = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal TypeFormatEventArgs(string formattedName)
|
||||
{
|
||||
if (Helpers.IsNullOrEmpty(formattedName)) throw new ArgumentNullException("formattedName");
|
||||
this.formattedName = formattedName;
|
||||
// typeFixed = false; <== implicit
|
||||
}
|
||||
|
||||
internal TypeFormatEventArgs(System.Type type)
|
||||
{
|
||||
if (type == null) throw new ArgumentNullException("type");
|
||||
this.type = type;
|
||||
typeFixed = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delegate type used to perform type-formatting functions; the sender originates as the type-model.
|
||||
/// </summary>
|
||||
public delegate void TypeFormatEventHandler(object sender, TypeFormatEventArgs args);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,14 +1,13 @@
|
|||
#if !NO_RUNTIME
|
||||
using System;
|
||||
|
||||
using ProtoBuf.Serializers;
|
||||
using System.Globalization;
|
||||
|
||||
#if FEAT_IKVM
|
||||
using Type = IKVM.Reflection.Type;
|
||||
using IKVM.Reflection;
|
||||
#else
|
||||
using System.Reflection;
|
||||
|
||||
#endif
|
||||
|
||||
namespace ProtoBuf.Meta
|
||||
|
@ -19,33 +18,59 @@ namespace ProtoBuf.Meta
|
|||
public class ValueMember
|
||||
{
|
||||
private readonly int fieldNumber;
|
||||
|
||||
/// <summary>
|
||||
/// The number that identifies this member in a protobuf stream
|
||||
/// </summary>
|
||||
public int FieldNumber { get { return fieldNumber; } }
|
||||
public int FieldNumber
|
||||
{
|
||||
get { return fieldNumber; }
|
||||
}
|
||||
|
||||
private readonly MemberInfo member;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the member (field/property) which this member relates to.
|
||||
/// </summary>
|
||||
public MemberInfo Member { get { return member; } }
|
||||
public MemberInfo Member
|
||||
{
|
||||
get { return member; }
|
||||
}
|
||||
|
||||
private readonly Type parentType, itemType, defaultType, memberType;
|
||||
private object defaultValue;
|
||||
|
||||
/// <summary>
|
||||
/// Within a list / array / etc, the type of object for each item in the list (especially useful with ArrayList)
|
||||
/// </summary>
|
||||
public Type ItemType { get { return itemType; } }
|
||||
public Type ItemType
|
||||
{
|
||||
get { return itemType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The underlying type of the member
|
||||
/// </summary>
|
||||
public Type MemberType { get { return memberType; } }
|
||||
public Type MemberType
|
||||
{
|
||||
get { return memberType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For abstract types (IList etc), the type of concrete object to create (if required)
|
||||
/// </summary>
|
||||
public Type DefaultType { get { return defaultType; } }
|
||||
public Type DefaultType
|
||||
{
|
||||
get { return defaultType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The type the defines the member
|
||||
/// </summary>
|
||||
public Type ParentType { get { return parentType; } }
|
||||
public Type ParentType
|
||||
{
|
||||
get { return parentType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The default value of the item (members with this value will not be serialized)
|
||||
|
@ -53,18 +78,21 @@ namespace ProtoBuf.Meta
|
|||
public object DefaultValue
|
||||
{
|
||||
get { return defaultValue; }
|
||||
set {
|
||||
set
|
||||
{
|
||||
ThrowIfFrozen();
|
||||
defaultValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly RuntimeTypeModel model;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new ValueMember instance
|
||||
/// </summary>
|
||||
public ValueMember(RuntimeTypeModel model, Type parentType, int fieldNumber, MemberInfo member, Type memberType, Type itemType, Type defaultType, DataFormat dataFormat, object defaultValue)
|
||||
: this(model, fieldNumber,memberType, itemType, defaultType, dataFormat)
|
||||
public ValueMember(RuntimeTypeModel model, Type parentType, int fieldNumber, MemberInfo member, Type memberType,
|
||||
Type itemType, Type defaultType, DataFormat dataFormat, object defaultValue)
|
||||
: this(model, fieldNumber, memberType, itemType, defaultType, dataFormat)
|
||||
{
|
||||
if (member == null) throw new ArgumentNullException("member");
|
||||
if (parentType == null) throw new ArgumentNullException("parentType");
|
||||
|
@ -89,16 +117,18 @@ namespace ProtoBuf.Meta
|
|||
this.asReference = type.AsReferenceDefault;
|
||||
}
|
||||
else
|
||||
{ // we need to scan the hard way; can't risk recursion by fully walking it
|
||||
{
|
||||
// we need to scan the hard way; can't risk recursion by fully walking it
|
||||
this.asReference = MetaType.GetAsReferenceDefault(model, memberType);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new ValueMember instance
|
||||
/// </summary>
|
||||
internal ValueMember(RuntimeTypeModel model, int fieldNumber, Type memberType, Type itemType, Type defaultType, DataFormat dataFormat)
|
||||
internal ValueMember(RuntimeTypeModel model, int fieldNumber, Type memberType, Type itemType, Type defaultType,
|
||||
DataFormat dataFormat)
|
||||
{
|
||||
|
||||
if (memberType == null) throw new ArgumentNullException("memberType");
|
||||
if (model == null) throw new ArgumentNullException("model");
|
||||
this.fieldNumber = fieldNumber;
|
||||
|
@ -109,6 +139,7 @@ namespace ProtoBuf.Meta
|
|||
this.model = model;
|
||||
this.dataFormat = dataFormat;
|
||||
}
|
||||
|
||||
internal object GetRawEnumValue()
|
||||
{
|
||||
#if WINRT || PORTABLE || CF || FX11
|
||||
|
@ -127,41 +158,59 @@ namespace ProtoBuf.Meta
|
|||
throw new InvalidOperationException();
|
||||
}
|
||||
#else
|
||||
return ((FieldInfo)member).GetRawConstantValue();
|
||||
return ((FieldInfo) member).GetRawConstantValue();
|
||||
#endif
|
||||
}
|
||||
|
||||
private static object ParseDefaultValue(Type type, object value)
|
||||
{
|
||||
Type tmp = Helpers.GetUnderlyingType(type);
|
||||
if (tmp != null) type = tmp;
|
||||
|
||||
|
||||
if (value is string)
|
||||
{
|
||||
string s = (string)value;
|
||||
string s = (string) value;
|
||||
if (Helpers.IsEnum(type)) return Helpers.ParseEnum(type, s);
|
||||
|
||||
switch (Helpers.GetTypeCode(type))
|
||||
{
|
||||
case ProtoTypeCode.Boolean: return bool.Parse(s);
|
||||
case ProtoTypeCode.Byte: return byte.Parse(s, NumberStyles.Integer, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.Boolean:
|
||||
return bool.Parse(s);
|
||||
case ProtoTypeCode.Byte:
|
||||
return byte.Parse(s, NumberStyles.Integer, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.Char: // char.Parse missing on CF/phone7
|
||||
if (s.Length == 1) return s[0];
|
||||
throw new FormatException("Single character expected: \"" + s + "\"");
|
||||
case ProtoTypeCode.DateTime: return DateTime.Parse(s, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.Decimal: return decimal.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.Double: return double.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.Int16: return short.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.Int32: return int.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.Int64: return long.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.SByte: return sbyte.Parse(s, NumberStyles.Integer, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.Single: return float.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.String: return s;
|
||||
case ProtoTypeCode.UInt16: return ushort.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.UInt32: return uint.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.UInt64: return ulong.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.TimeSpan: return TimeSpan.Parse(s);
|
||||
case ProtoTypeCode.Uri: return s; // Uri is decorated as string
|
||||
case ProtoTypeCode.Guid: return new Guid(s);
|
||||
case ProtoTypeCode.DateTime:
|
||||
return DateTime.Parse(s, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.Decimal:
|
||||
return decimal.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.Double:
|
||||
return double.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.Int16:
|
||||
return short.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.Int32:
|
||||
return int.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.Int64:
|
||||
return long.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.SByte:
|
||||
return sbyte.Parse(s, NumberStyles.Integer, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.Single:
|
||||
return float.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.String:
|
||||
return s;
|
||||
case ProtoTypeCode.UInt16:
|
||||
return ushort.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.UInt32:
|
||||
return uint.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.UInt64:
|
||||
return ulong.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
case ProtoTypeCode.TimeSpan:
|
||||
return TimeSpan.Parse(s);
|
||||
case ProtoTypeCode.Uri:
|
||||
return s; // Uri is decorated as string
|
||||
case ProtoTypeCode.Guid:
|
||||
return new Guid(s);
|
||||
}
|
||||
}
|
||||
#if FEAT_IKVM
|
||||
|
@ -190,6 +239,7 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
|
||||
private IProtoSerializer serializer;
|
||||
|
||||
internal IProtoSerializer Serializer
|
||||
{
|
||||
get
|
||||
|
@ -200,13 +250,19 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
|
||||
private DataFormat dataFormat;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the rules used to process the field; this is used to determine the most appropriate
|
||||
/// wite-type, but also to describe subtypes <i>within</i> that wire-type (such as SignedVariant)
|
||||
/// </summary>
|
||||
public DataFormat DataFormat {
|
||||
public DataFormat DataFormat
|
||||
{
|
||||
get { return dataFormat; }
|
||||
set { ThrowIfFrozen(); this.dataFormat = value; }
|
||||
set
|
||||
{
|
||||
ThrowIfFrozen();
|
||||
this.dataFormat = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -250,26 +306,37 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
|
||||
private bool asReference;
|
||||
|
||||
/// <summary>
|
||||
/// Enables full object-tracking/full-graph support.
|
||||
/// </summary>
|
||||
public bool AsReference
|
||||
{
|
||||
get { return asReference; }
|
||||
set { ThrowIfFrozen(); asReference = value; }
|
||||
set
|
||||
{
|
||||
ThrowIfFrozen();
|
||||
asReference = value;
|
||||
}
|
||||
}
|
||||
|
||||
private bool dynamicType;
|
||||
|
||||
/// <summary>
|
||||
/// Embeds the type information into the stream, allowing usage with types not known in advance.
|
||||
/// </summary>
|
||||
public bool DynamicType
|
||||
{
|
||||
get { return dynamicType; }
|
||||
set { ThrowIfFrozen(); dynamicType = value; }
|
||||
set
|
||||
{
|
||||
ThrowIfFrozen();
|
||||
dynamicType = value;
|
||||
}
|
||||
}
|
||||
|
||||
private MethodInfo getSpecified, setSpecified;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies methods for working with optional data members.
|
||||
/// </summary>
|
||||
|
@ -283,7 +350,7 @@ namespace ProtoBuf.Meta
|
|||
{
|
||||
if (getSpecified != null)
|
||||
{
|
||||
if (getSpecified.ReturnType != model.MapType(typeof(bool))
|
||||
if (getSpecified.ReturnType != model.MapType(typeof (bool))
|
||||
|| getSpecified.IsStatic
|
||||
|| getSpecified.GetParameters().Length != 0)
|
||||
{
|
||||
|
@ -293,10 +360,10 @@ namespace ProtoBuf.Meta
|
|||
if (setSpecified != null)
|
||||
{
|
||||
ParameterInfo[] args;
|
||||
if (setSpecified.ReturnType != model.MapType(typeof(void))
|
||||
if (setSpecified.ReturnType != model.MapType(typeof (void))
|
||||
|| setSpecified.IsStatic
|
||||
|| (args = setSpecified.GetParameters()).Length != 1
|
||||
|| args[0].ParameterType != model.MapType(typeof(bool)))
|
||||
|| args[0].ParameterType != model.MapType(typeof (bool)))
|
||||
{
|
||||
throw new ArgumentException("Invalid pattern for setting member-specified", "setSpecified");
|
||||
}
|
||||
|
@ -304,21 +371,24 @@ namespace ProtoBuf.Meta
|
|||
ThrowIfFrozen();
|
||||
this.getSpecified = getSpecified;
|
||||
this.setSpecified = setSpecified;
|
||||
|
||||
}
|
||||
|
||||
private void ThrowIfFrozen()
|
||||
{
|
||||
if (serializer != null) throw new InvalidOperationException("The type cannot be changed once a serializer has been generated");
|
||||
if (serializer != null)
|
||||
throw new InvalidOperationException("The type cannot be changed once a serializer has been generated");
|
||||
}
|
||||
|
||||
private IProtoSerializer BuildSerializer()
|
||||
{
|
||||
int opaqueToken = 0;
|
||||
try
|
||||
{
|
||||
model.TakeLock(ref opaqueToken);// check nobody is still adding this type
|
||||
model.TakeLock(ref opaqueToken); // check nobody is still adding this type
|
||||
WireType wireType;
|
||||
Type finalType = itemType == null ? memberType : itemType;
|
||||
IProtoSerializer ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, dynamicType, OverwriteList, true);
|
||||
IProtoSerializer ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference,
|
||||
dynamicType, OverwriteList, true);
|
||||
if (ser == null)
|
||||
{
|
||||
throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName);
|
||||
|
@ -327,7 +397,7 @@ namespace ProtoBuf.Meta
|
|||
// apply tags
|
||||
if (itemType != null && SupportNull)
|
||||
{
|
||||
if(IsPacked)
|
||||
if (IsPacked)
|
||||
{
|
||||
throw new NotSupportedException("Packed encodings cannot support null values");
|
||||
}
|
||||
|
@ -341,28 +411,32 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
// apply lists if appropriate
|
||||
if (itemType != null)
|
||||
{
|
||||
{
|
||||
#if NO_GENERICS
|
||||
Type underlyingItemType = itemType;
|
||||
#else
|
||||
Type underlyingItemType = SupportNull ? itemType : Helpers.GetUnderlyingType(itemType) ?? itemType;
|
||||
#endif
|
||||
Helpers.DebugAssert(underlyingItemType == ser.ExpectedType, "Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, underlyingItemType);
|
||||
Helpers.DebugAssert(underlyingItemType == ser.ExpectedType,
|
||||
"Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, underlyingItemType);
|
||||
if (memberType.IsArray)
|
||||
{
|
||||
ser = new ArrayDecorator(model, ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList, SupportNull);
|
||||
ser = new ArrayDecorator(model, ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList,
|
||||
SupportNull);
|
||||
}
|
||||
else
|
||||
{
|
||||
ser = ListDecorator.Create(model, memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member != null && PropertyDecorator.CanWrite(model, member), OverwriteList, SupportNull);
|
||||
ser = ListDecorator.Create(model, memberType, defaultType, ser, fieldNumber, IsPacked, wireType,
|
||||
member != null && PropertyDecorator.CanWrite(model, member), OverwriteList, SupportNull);
|
||||
}
|
||||
}
|
||||
else if (defaultValue != null && !IsRequired && getSpecified == null)
|
||||
{ // note: "ShouldSerialize*" / "*Specified" / etc ^^^^ take precedence over defaultValue,
|
||||
{
|
||||
// note: "ShouldSerialize*" / "*Specified" / etc ^^^^ take precedence over defaultValue,
|
||||
// as does "IsRequired"
|
||||
ser = new DefaultValueDecorator(model, defaultValue, ser);
|
||||
}
|
||||
if (memberType == model.MapType(typeof(Uri)))
|
||||
if (memberType == model.MapType(typeof (Uri)))
|
||||
{
|
||||
ser = new UriDecorator(model, ser);
|
||||
}
|
||||
|
@ -371,14 +445,14 @@ namespace ProtoBuf.Meta
|
|||
PropertyInfo prop = member as PropertyInfo;
|
||||
if (prop != null)
|
||||
{
|
||||
ser = new PropertyDecorator(model, parentType, (PropertyInfo)member, ser);
|
||||
ser = new PropertyDecorator(model, parentType, (PropertyInfo) member, ser);
|
||||
}
|
||||
else
|
||||
{
|
||||
FieldInfo fld = member as FieldInfo;
|
||||
if (fld != null)
|
||||
{
|
||||
ser = new FieldDecorator(parentType, (FieldInfo)member, ser);
|
||||
ser = new FieldDecorator(parentType, (FieldInfo) member, ser);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -398,27 +472,39 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
}
|
||||
|
||||
private static WireType GetIntWireType(DataFormat format, int width) {
|
||||
switch(format) {
|
||||
case DataFormat.ZigZag: return WireType.SignedVariant;
|
||||
case DataFormat.FixedSize: return width == 32 ? WireType.Fixed32 : WireType.Fixed64;
|
||||
private static WireType GetIntWireType(DataFormat format, int width)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case DataFormat.ZigZag:
|
||||
return WireType.SignedVariant;
|
||||
case DataFormat.FixedSize:
|
||||
return width == 32 ? WireType.Fixed32 : WireType.Fixed64;
|
||||
case DataFormat.TwosComplement:
|
||||
case DataFormat.Default: return WireType.Variant;
|
||||
default: throw new InvalidOperationException();
|
||||
case DataFormat.Default:
|
||||
return WireType.Variant;
|
||||
default:
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private static WireType GetDateTimeWireType(DataFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case DataFormat.Group: return WireType.StartGroup;
|
||||
case DataFormat.FixedSize: return WireType.Fixed64;
|
||||
case DataFormat.Default: return WireType.String;
|
||||
default: throw new InvalidOperationException();
|
||||
case DataFormat.Group:
|
||||
return WireType.StartGroup;
|
||||
case DataFormat.FixedSize:
|
||||
return WireType.Fixed64;
|
||||
case DataFormat.Default:
|
||||
return WireType.String;
|
||||
default:
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
internal static IProtoSerializer TryGetCoreSerializer(RuntimeTypeModel model, DataFormat dataFormat, Type type, out WireType defaultWireType,
|
||||
internal static IProtoSerializer TryGetCoreSerializer(RuntimeTypeModel model, DataFormat dataFormat, Type type,
|
||||
out WireType defaultWireType,
|
||||
bool asReference, bool dynamicType, bool overwriteList, bool allowComplexTypes)
|
||||
{
|
||||
#if !NO_GENERICS
|
||||
|
@ -436,7 +522,8 @@ namespace ProtoBuf.Meta
|
|||
return new EnumSerializer(type, model.GetEnumMap(type));
|
||||
}
|
||||
else
|
||||
{ // enum is fine for adding as a meta-type
|
||||
{
|
||||
// enum is fine for adding as a meta-type
|
||||
defaultWireType = WireType.None;
|
||||
return null;
|
||||
}
|
||||
|
@ -460,7 +547,8 @@ namespace ProtoBuf.Meta
|
|||
defaultWireType = WireType.String;
|
||||
if (asReference)
|
||||
{
|
||||
return new NetObjectSerializer(model, model.MapType(typeof(string)), 0, BclHelpers.NetObjectOptions.AsReference);
|
||||
return new NetObjectSerializer(model, model.MapType(typeof (string)), 0,
|
||||
BclHelpers.NetObjectOptions.AsReference);
|
||||
}
|
||||
return new StringSerializer(model);
|
||||
case ProtoTypeCode.Single:
|
||||
|
@ -525,7 +613,8 @@ namespace ProtoBuf.Meta
|
|||
if (asReference) options |= BclHelpers.NetObjectOptions.AsReference;
|
||||
if (dynamicType) options |= BclHelpers.NetObjectOptions.DynamicType;
|
||||
if (key >= 0)
|
||||
{ // exists
|
||||
{
|
||||
// exists
|
||||
if (asReference && Helpers.IsValueType(type))
|
||||
{
|
||||
string message = "AsReference cannot be used with value-types";
|
||||
|
@ -541,7 +630,7 @@ namespace ProtoBuf.Meta
|
|||
throw new InvalidOperationException(message);
|
||||
}
|
||||
MetaType meta = model[type];
|
||||
if (asReference && meta.IsAutoTuple) options |= BclHelpers.NetObjectOptions.LateSet;
|
||||
if (asReference && meta.IsAutoTuple) options |= BclHelpers.NetObjectOptions.LateSet;
|
||||
if (meta.UseConstructor) options |= BclHelpers.NetObjectOptions.UseConstructor;
|
||||
}
|
||||
return new NetObjectSerializer(model, type, key, options);
|
||||
|
@ -558,11 +647,13 @@ namespace ProtoBuf.Meta
|
|||
|
||||
|
||||
private string name;
|
||||
|
||||
internal void SetName(string name)
|
||||
{
|
||||
ThrowIfFrozen();
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the logical name for this member in the schema (this is not critical for binary serialization, but may be used
|
||||
/// when inferring a schema).
|
||||
|
@ -573,14 +664,19 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
|
||||
private const byte
|
||||
OPTIONS_IsStrict = 1,
|
||||
OPTIONS_IsPacked = 2,
|
||||
OPTIONS_IsRequired = 4,
|
||||
OPTIONS_OverwriteList = 8,
|
||||
OPTIONS_SupportNull = 16;
|
||||
OPTIONS_IsStrict = 1,
|
||||
OPTIONS_IsPacked = 2,
|
||||
OPTIONS_IsRequired = 4,
|
||||
OPTIONS_OverwriteList = 8,
|
||||
OPTIONS_SupportNull = 16;
|
||||
|
||||
private byte flags;
|
||||
private bool HasFlag(byte flag) { return (flags & flag) == flag; }
|
||||
|
||||
private bool HasFlag(byte flag)
|
||||
{
|
||||
return (flags & flag) == flag;
|
||||
}
|
||||
|
||||
private void SetFlag(byte flag, bool value, bool throwIfFrozen)
|
||||
{
|
||||
if (throwIfFrozen && HasFlag(flag) != value)
|
||||
|
@ -590,7 +686,7 @@ namespace ProtoBuf.Meta
|
|||
if (value)
|
||||
flags |= flag;
|
||||
else
|
||||
flags = (byte)(flags & ~flag);
|
||||
flags = (byte) (flags & ~flag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -599,27 +695,30 @@ namespace ProtoBuf.Meta
|
|||
public bool SupportNull
|
||||
{
|
||||
get { return HasFlag(OPTIONS_SupportNull); }
|
||||
set { SetFlag(OPTIONS_SupportNull, value, true);}
|
||||
set { SetFlag(OPTIONS_SupportNull, value, true); }
|
||||
}
|
||||
|
||||
internal string GetSchemaTypeName(bool applyNetObjectProxy, ref bool requiresBclImport)
|
||||
{
|
||||
Type effectiveType = ItemType;
|
||||
if (effectiveType == null) effectiveType = MemberType;
|
||||
return model.GetSchemaTypeName(effectiveType, DataFormat, applyNetObjectProxy && asReference, applyNetObjectProxy && dynamicType, ref requiresBclImport);
|
||||
return model.GetSchemaTypeName(effectiveType, DataFormat, applyNetObjectProxy && asReference,
|
||||
applyNetObjectProxy && dynamicType, ref requiresBclImport);
|
||||
}
|
||||
|
||||
|
||||
|
||||
internal sealed class Comparer : System.Collections.IComparer
|
||||
#if !NO_GENERICS
|
||||
, System.Collections.Generic.IComparer<ValueMember>
|
||||
, System.Collections.Generic.IComparer<ValueMember>
|
||||
#endif
|
||||
{
|
||||
public static readonly Comparer Default = new Comparer();
|
||||
|
||||
public int Compare(object x, object y)
|
||||
{
|
||||
return Compare(x as ValueMember, y as ValueMember);
|
||||
}
|
||||
|
||||
public int Compare(ValueMember x, ValueMember y)
|
||||
{
|
||||
if (ReferenceEquals(x, y)) return 0;
|
||||
|
@ -631,4 +730,5 @@ namespace ProtoBuf.Meta
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -47,7 +47,8 @@ namespace ProtoBuf
|
|||
if (key-- == Root)
|
||||
{
|
||||
if (value == null) throw new ArgumentNullException("value");
|
||||
if (rootObject != null && ((object)rootObject != (object)value)) throw new ProtoException("The root object cannot be reassigned");
|
||||
if (rootObject != null && ((object) rootObject != (object) value))
|
||||
throw new ProtoException("The root object cannot be reassigned");
|
||||
rootObject = value;
|
||||
}
|
||||
else
|
||||
|
@ -60,7 +61,7 @@ namespace ProtoBuf
|
|||
{
|
||||
list[key] = value;
|
||||
}
|
||||
else if (!ReferenceEquals(oldVal, value) )
|
||||
else if (!ReferenceEquals(oldVal, value))
|
||||
{
|
||||
throw new ProtoException("Reference-tracked objects cannot change reference");
|
||||
} // otherwise was the same; nothing to do
|
||||
|
@ -73,12 +74,14 @@ namespace ProtoBuf
|
|||
}
|
||||
|
||||
private object rootObject;
|
||||
|
||||
internal int AddObjectKey(object value, out bool existing)
|
||||
{
|
||||
if (value == null) throw new ArgumentNullException("value");
|
||||
|
||||
if ((object)value == (object)rootObject) // (object) here is no-op, but should be
|
||||
{ // preserved even if this was typed - needs ref-check
|
||||
if ((object) value == (object) rootObject) // (object) here is no-op, but should be
|
||||
{
|
||||
// preserved even if this was typed - needs ref-check
|
||||
existing = true;
|
||||
return Root;
|
||||
}
|
||||
|
@ -117,12 +120,12 @@ namespace ProtoBuf
|
|||
}
|
||||
#else
|
||||
|
||||
if(s == null)
|
||||
if (s == null)
|
||||
{
|
||||
#if CF || PORTABLE // CF has very limited proper object ref-tracking; so instead, we'll search it the hard way
|
||||
index = list.IndexOfReference(value);
|
||||
#else
|
||||
if (objectKeys == null)
|
||||
if (objectKeys == null)
|
||||
{
|
||||
objectKeys = new System.Collections.Generic.Dictionary<object, int>(ReferenceComparer.Default);
|
||||
index = -1;
|
||||
|
@ -139,7 +142,7 @@ namespace ProtoBuf
|
|||
{
|
||||
stringKeys = new System.Collections.Generic.Dictionary<string, int>();
|
||||
index = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!stringKeys.TryGetValue(s, out index)) index = -1;
|
||||
|
@ -166,7 +169,7 @@ namespace ProtoBuf
|
|||
}
|
||||
|
||||
private int trapStartIndex; // defaults to 0 - optimization for RegisterTrappedObject
|
||||
// to make it faster at seeking to find deferred-objects
|
||||
// to make it faster at seeking to find deferred-objects
|
||||
|
||||
internal void RegisterTrappedObject(object value)
|
||||
{
|
||||
|
@ -176,23 +179,24 @@ namespace ProtoBuf
|
|||
}
|
||||
else
|
||||
{
|
||||
if(underlyingList != null)
|
||||
if (underlyingList != null)
|
||||
{
|
||||
for (int i = trapStartIndex; i < underlyingList.Count; i++)
|
||||
{
|
||||
trapStartIndex = i + 1; // things never *become* null; whether or
|
||||
// not the next item is null, it will never
|
||||
// need to be checked again
|
||||
// not the next item is null, it will never
|
||||
// need to be checked again
|
||||
|
||||
if(underlyingList[i] == null)
|
||||
if (underlyingList[i] == null)
|
||||
{
|
||||
underlyingList[i] = value;
|
||||
underlyingList[i] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if NO_GENERICS
|
||||
private ReferenceHashtable objectKeys;
|
||||
private System.Collections.Hashtable stringKeys;
|
||||
|
@ -211,12 +215,17 @@ namespace ProtoBuf
|
|||
|
||||
private System.Collections.Generic.Dictionary<string, int> stringKeys;
|
||||
|
||||
#if !CF && !PORTABLE // CF lacks the ability to get a robust reference-based hash-code, so we'll do it the harder way instead
|
||||
#if !CF && !PORTABLE
|
||||
// CF lacks the ability to get a robust reference-based hash-code, so we'll do it the harder way instead
|
||||
private System.Collections.Generic.Dictionary<object, int> objectKeys;
|
||||
|
||||
private sealed class ReferenceComparer : System.Collections.Generic.IEqualityComparer<object>
|
||||
{
|
||||
public readonly static ReferenceComparer Default = new ReferenceComparer();
|
||||
private ReferenceComparer() {}
|
||||
public static readonly ReferenceComparer Default = new ReferenceComparer();
|
||||
|
||||
private ReferenceComparer()
|
||||
{
|
||||
}
|
||||
|
||||
bool System.Collections.Generic.IEqualityComparer<object>.Equals(object x, object y)
|
||||
{
|
||||
|
@ -243,4 +252,4 @@ namespace ProtoBuf
|
|||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
namespace ProtoBuf
|
||||
namespace ProtoBuf
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the type of prefix that should be applied to messages.
|
||||
|
@ -10,17 +9,20 @@ namespace ProtoBuf
|
|||
/// No length prefix is applied to the data; the data is terminated only be the end of the stream.
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// A base-128 length prefix is applied to the data (efficient for short messages).
|
||||
/// </summary>
|
||||
Base128,
|
||||
|
||||
/// <summary>
|
||||
/// A fixed-length (little-endian) length prefix is applied to the data (useful for compatibility).
|
||||
/// </summary>
|
||||
Fixed32,
|
||||
/// <summary>
|
||||
|
||||
/// <summary>
|
||||
/// A fixed-length (big-endian) length prefix is applied to the data (useful for compatibility).
|
||||
/// </summary>
|
||||
Fixed32BigEndian
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,14 +5,20 @@ namespace ProtoBuf
|
|||
/// <summary>
|
||||
/// Indicates that a type is defined for protocol-buffer serialization.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface,
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface,
|
||||
AllowMultiple = false, Inherited = false)]
|
||||
public sealed class ProtoContractAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the defined name of the type.
|
||||
/// </summary>
|
||||
public string Name { get { return name; } set { name = value; } }
|
||||
public string Name
|
||||
{
|
||||
get { return name; }
|
||||
set { name = value; }
|
||||
}
|
||||
|
||||
private string name;
|
||||
|
||||
/// <summary>
|
||||
|
@ -28,6 +34,7 @@ namespace ProtoBuf
|
|||
implicitFirstTag = value;
|
||||
}
|
||||
}
|
||||
|
||||
private int implicitFirstTag;
|
||||
|
||||
/// <summary>
|
||||
|
@ -54,7 +61,12 @@ namespace ProtoBuf
|
|||
/// for members. This option should be used in advanced scenarios only.
|
||||
/// Please review the important notes against the ImplicitFields enumeration.
|
||||
/// </summary>
|
||||
public ImplicitFields ImplicitFields { get { return implicitFields; } set { implicitFields = value; } }
|
||||
public ImplicitFields ImplicitFields
|
||||
{
|
||||
get { return implicitFields; }
|
||||
set { implicitFields = value; }
|
||||
}
|
||||
|
||||
private ImplicitFields implicitFields;
|
||||
|
||||
|
||||
|
@ -70,7 +82,8 @@ namespace ProtoBuf
|
|||
public bool InferTagFromName
|
||||
{
|
||||
get { return HasFlag(OPTIONS_InferTagFromName); }
|
||||
set {
|
||||
set
|
||||
{
|
||||
SetFlag(OPTIONS_InferTagFromName, value);
|
||||
SetFlag(OPTIONS_InferTagFromNameHasValue, true);
|
||||
}
|
||||
|
@ -80,7 +93,8 @@ namespace ProtoBuf
|
|||
/// Has a InferTagFromName value been explicitly set? if not, the default from the type-model is assumed.
|
||||
/// </summary>
|
||||
internal bool InferTagFromNameHasValue
|
||||
{ // note that this property is accessed via reflection and should not be removed
|
||||
{
|
||||
// note that this property is accessed via reflection and should not be removed
|
||||
get { return HasFlag(OPTIONS_InferTagFromNameHasValue); }
|
||||
}
|
||||
|
||||
|
@ -117,16 +131,18 @@ namespace ProtoBuf
|
|||
public bool AsReferenceDefault
|
||||
{
|
||||
get { return HasFlag(OPTIONS_AsReferenceDefault); }
|
||||
set {
|
||||
SetFlag(OPTIONS_AsReferenceDefault, value);
|
||||
}
|
||||
set { SetFlag(OPTIONS_AsReferenceDefault, value); }
|
||||
}
|
||||
|
||||
private bool HasFlag(byte flag)
|
||||
{
|
||||
return (flags & flag) == flag;
|
||||
}
|
||||
|
||||
private bool HasFlag(byte flag) { return (flags & flag) == flag; }
|
||||
private void SetFlag(byte flag, bool value)
|
||||
{
|
||||
if (value) flags |= flag;
|
||||
else flags = (byte)(flags & ~flag);
|
||||
else flags = (byte) (flags & ~flag);
|
||||
}
|
||||
|
||||
private byte flags;
|
||||
|
@ -148,7 +164,8 @@ namespace ProtoBuf
|
|||
public bool EnumPassthru
|
||||
{
|
||||
get { return HasFlag(OPTIONS_EnumPassthru); }
|
||||
set {
|
||||
set
|
||||
{
|
||||
SetFlag(OPTIONS_EnumPassthru, value);
|
||||
SetFlag(OPTIONS_EnumPassthruHasValue, true);
|
||||
}
|
||||
|
@ -158,7 +175,8 @@ namespace ProtoBuf
|
|||
/// Has a EnumPassthru value been explicitly set?
|
||||
/// </summary>
|
||||
internal bool EnumPassthruHasValue
|
||||
{ // note that this property is accessed via reflection and should not be removed
|
||||
{
|
||||
// note that this property is accessed via reflection and should not be removed
|
||||
get { return HasFlag(OPTIONS_EnumPassthruHasValue); }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,5 +9,7 @@ namespace ProtoBuf
|
|||
/// to/from interface types.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
|
||||
public class ProtoConverterAttribute : Attribute {}
|
||||
public class ProtoConverterAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
|
@ -15,14 +15,21 @@ namespace ProtoBuf
|
|||
public int Value
|
||||
{
|
||||
get { return enumValue; }
|
||||
set { this.enumValue = value; hasValue = true; }
|
||||
set
|
||||
{
|
||||
this.enumValue = value;
|
||||
hasValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this instance has a customised value mapping
|
||||
/// </summary>
|
||||
/// <returns>true if a specific value is set</returns>
|
||||
public bool HasValue() { return hasValue; }
|
||||
public bool HasValue()
|
||||
{
|
||||
return hasValue;
|
||||
}
|
||||
|
||||
private bool hasValue;
|
||||
private int enumValue;
|
||||
|
@ -31,7 +38,12 @@ namespace ProtoBuf
|
|||
/// Gets or sets the defined name of the enum, as used in .proto
|
||||
/// (this name is not used during serialization).
|
||||
/// </summary>
|
||||
public string Name { get { return name; } set { name = value; } }
|
||||
public string Name
|
||||
{
|
||||
get { return name; }
|
||||
set { name = value; }
|
||||
}
|
||||
|
||||
private string name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8)
|
||||
using System.Runtime.Serialization;
|
||||
#endif
|
||||
|
||||
namespace ProtoBuf
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -14,17 +15,23 @@ namespace ProtoBuf
|
|||
public class ProtoException : Exception
|
||||
{
|
||||
/// <summary>Creates a new ProtoException instance.</summary>
|
||||
public ProtoException() { }
|
||||
public ProtoException()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Creates a new ProtoException instance.</summary>
|
||||
public ProtoException(string message) : base(message) { }
|
||||
public ProtoException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Creates a new ProtoException instance.</summary>
|
||||
public ProtoException(string message, Exception innerException) : base(message, innerException) { }
|
||||
public ProtoException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8)
|
||||
/// <summary>Creates a new ProtoException instance.</summary>
|
||||
/// <summary>Creates a new ProtoException instance.</summary>
|
||||
protected ProtoException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,9 @@ namespace ProtoBuf
|
|||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field,
|
||||
AllowMultiple = false, Inherited = true)]
|
||||
public class ProtoIgnoreAttribute : Attribute {}
|
||||
public class ProtoIgnoreAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that a member should be excluded from serialization; this
|
||||
|
@ -18,7 +20,7 @@ namespace ProtoBuf
|
|||
/// under direct control.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class,
|
||||
AllowMultiple = true, Inherited = false)]
|
||||
AllowMultiple = true, Inherited = false)]
|
||||
public sealed class ProtoPartialIgnoreAttribute : ProtoIgnoreAttribute
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -31,10 +33,15 @@ namespace ProtoBuf
|
|||
if (Helpers.IsNullOrEmpty(memberName)) throw new ArgumentNullException("memberName");
|
||||
this.memberName = memberName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the member to be ignored.
|
||||
/// </summary>
|
||||
public string MemberName { get { return memberName; } }
|
||||
public string MemberName
|
||||
{
|
||||
get { return memberName; }
|
||||
}
|
||||
|
||||
private readonly string memberName;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,14 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
using ProtoBuf.Meta;
|
||||
#if FEAT_IKVM
|
||||
using Type = IKVM.Reflection.Type;
|
||||
using IKVM.Reflection;
|
||||
#else
|
||||
using System.Reflection;
|
||||
|
||||
#endif
|
||||
|
||||
namespace ProtoBuf
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -25,7 +26,9 @@ namespace ProtoBuf
|
|||
/// <param name="tag">The unique index (within the type) that will identify this data.</param>
|
||||
/// <param name="knownType">The additional type to serialize/deserialize.</param>
|
||||
public ProtoIncludeAttribute(int tag, System.Type knownType)
|
||||
: this(tag, knownType == null ? "" : knownType.AssemblyQualifiedName) { }
|
||||
: this(tag, knownType == null ? "" : knownType.AssemblyQualifiedName)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the ProtoIncludeAttribute.
|
||||
|
@ -35,7 +38,8 @@ namespace ProtoBuf
|
|||
public ProtoIncludeAttribute(int tag, string knownTypeName)
|
||||
{
|
||||
if (tag <= 0) throw new ArgumentOutOfRangeException("tag", "Tags must be positive integers");
|
||||
if (Helpers.IsNullOrEmpty(knownTypeName)) throw new ArgumentNullException("knownTypeName", "Known type cannot be blank");
|
||||
if (Helpers.IsNullOrEmpty(knownTypeName))
|
||||
throw new ArgumentNullException("knownTypeName", "Known type cannot be blank");
|
||||
this.tag = tag;
|
||||
this.knownTypeName = knownTypeName;
|
||||
}
|
||||
|
@ -43,13 +47,21 @@ namespace ProtoBuf
|
|||
/// <summary>
|
||||
/// Gets the unique index (within the type) that will identify this data.
|
||||
/// </summary>
|
||||
public int Tag { get { return tag; } }
|
||||
public int Tag
|
||||
{
|
||||
get { return tag; }
|
||||
}
|
||||
|
||||
private readonly int tag;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the additional type to serialize/deserialize.
|
||||
/// </summary>
|
||||
public string KnownTypeName { get { return knownTypeName; } }
|
||||
public string KnownTypeName
|
||||
{
|
||||
get { return knownTypeName; }
|
||||
}
|
||||
|
||||
private readonly string knownTypeName;
|
||||
|
||||
/// <summary>
|
||||
|
@ -57,10 +69,7 @@ namespace ProtoBuf
|
|||
/// </summary>
|
||||
public Type KnownType
|
||||
{
|
||||
get
|
||||
{
|
||||
return TypeModel.ResolveKnownType(KnownTypeName, null, null);
|
||||
}
|
||||
get { return TypeModel.ResolveKnownType(KnownTypeName, null, null); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -73,6 +82,7 @@ namespace ProtoBuf
|
|||
get { return dataFormat; }
|
||||
set { dataFormat = value; }
|
||||
}
|
||||
|
||||
private DataFormat dataFormat = DataFormat.Default;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
using System;
|
||||
|
||||
#if FEAT_IKVM
|
||||
using Type = IKVM.Reflection.Type;
|
||||
using IKVM.Reflection;
|
||||
#else
|
||||
using System.Reflection;
|
||||
|
||||
#endif
|
||||
|
||||
namespace ProtoBuf
|
||||
|
@ -27,14 +27,18 @@ namespace ProtoBuf
|
|||
/// <summary>
|
||||
/// Compare with another ProtoMemberAttribute for sorting purposes
|
||||
/// </summary>
|
||||
public int CompareTo(object other) { return CompareTo(other as ProtoMemberAttribute); }
|
||||
public int CompareTo(object other)
|
||||
{
|
||||
return CompareTo(other as ProtoMemberAttribute);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare with another ProtoMemberAttribute for sorting purposes
|
||||
/// </summary>
|
||||
public int CompareTo(ProtoMemberAttribute other)
|
||||
{
|
||||
if (other == null) return -1;
|
||||
if ((object)this == (object)other) return 0;
|
||||
if ((object) this == (object) other) return 0;
|
||||
int result = this.tag.CompareTo(other.tag);
|
||||
if (result == 0) result = string.CompareOrdinal(this.name, other.name);
|
||||
return result;
|
||||
|
@ -45,7 +49,8 @@ namespace ProtoBuf
|
|||
/// </summary>
|
||||
/// <param name="tag">Specifies the unique tag used to identify this member within the type.</param>
|
||||
public ProtoMemberAttribute(int tag) : this(tag, false)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
internal ProtoMemberAttribute(int tag, bool forced)
|
||||
{
|
||||
|
@ -57,32 +62,53 @@ namespace ProtoBuf
|
|||
internal MemberInfo Member;
|
||||
internal bool TagIsPinned;
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the original name defined in the .proto; not used
|
||||
/// during serialization.
|
||||
/// </summary>
|
||||
public string Name { get { return name; } set { name = value; } }
|
||||
public string Name
|
||||
{
|
||||
get { return name; }
|
||||
set { name = value; }
|
||||
}
|
||||
|
||||
private string name;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the data-format to be used when encoding this value.
|
||||
/// </summary>
|
||||
public DataFormat DataFormat { get { return dataFormat; } set { dataFormat = value; } }
|
||||
private DataFormat dataFormat;
|
||||
public DataFormat DataFormat
|
||||
{
|
||||
get { return dataFormat; }
|
||||
set { dataFormat = value; }
|
||||
}
|
||||
|
||||
private DataFormat dataFormat;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique tag used to identify this member within the type.
|
||||
/// </summary>
|
||||
public int Tag { get { return tag; } }
|
||||
public int Tag
|
||||
{
|
||||
get { return tag; }
|
||||
}
|
||||
|
||||
private int tag;
|
||||
internal void Rebase(int tag) { this.tag = tag; }
|
||||
|
||||
internal void Rebase(int tag)
|
||||
{
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this member is mandatory.
|
||||
/// </summary>
|
||||
public bool IsRequired {
|
||||
public bool IsRequired
|
||||
{
|
||||
get { return (options & MemberSerializationOptions.Required) == MemberSerializationOptions.Required; }
|
||||
set {
|
||||
set
|
||||
{
|
||||
if (value) options |= MemberSerializationOptions.Required;
|
||||
else options &= ~MemberSerializationOptions.Required;
|
||||
}
|
||||
|
@ -94,8 +120,9 @@ namespace ProtoBuf
|
|||
/// </summary>
|
||||
public bool IsPacked
|
||||
{
|
||||
get { return (options & MemberSerializationOptions.Packed) == MemberSerializationOptions.Packed;}
|
||||
set {
|
||||
get { return (options & MemberSerializationOptions.Packed) == MemberSerializationOptions.Packed; }
|
||||
set
|
||||
{
|
||||
if (value) options |= MemberSerializationOptions.Packed;
|
||||
else options &= ~MemberSerializationOptions.Packed;
|
||||
}
|
||||
|
@ -107,7 +134,10 @@ namespace ProtoBuf
|
|||
/// </summary>
|
||||
public bool OverwriteList
|
||||
{
|
||||
get { return (options & MemberSerializationOptions.OverwriteList) == MemberSerializationOptions.OverwriteList; }
|
||||
get
|
||||
{
|
||||
return (options & MemberSerializationOptions.OverwriteList) == MemberSerializationOptions.OverwriteList;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value) options |= MemberSerializationOptions.OverwriteList;
|
||||
|
@ -132,8 +162,13 @@ namespace ProtoBuf
|
|||
|
||||
internal bool AsReferenceHasValue
|
||||
{
|
||||
get { return (options & MemberSerializationOptions.AsReferenceHasValue) == MemberSerializationOptions.AsReferenceHasValue; }
|
||||
set {
|
||||
get
|
||||
{
|
||||
return (options & MemberSerializationOptions.AsReferenceHasValue) ==
|
||||
MemberSerializationOptions.AsReferenceHasValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value) options |= MemberSerializationOptions.AsReferenceHasValue;
|
||||
else options &= ~MemberSerializationOptions.AsReferenceHasValue;
|
||||
}
|
||||
|
@ -155,10 +190,13 @@ namespace ProtoBuf
|
|||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this member is packed (lists/arrays).
|
||||
/// </summary>
|
||||
public MemberSerializationOptions Options { get { return options; } set { options = value; } }
|
||||
private MemberSerializationOptions options;
|
||||
public MemberSerializationOptions Options
|
||||
{
|
||||
get { return options; }
|
||||
set { options = value; }
|
||||
}
|
||||
|
||||
|
||||
private MemberSerializationOptions options;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -171,27 +209,33 @@ namespace ProtoBuf
|
|||
/// Default; no additional options
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that repeated elements should use packed (length-prefixed) encoding
|
||||
/// </summary>
|
||||
Packed = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the given item is required
|
||||
/// </summary>
|
||||
Required = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Enables full object-tracking/full-graph support
|
||||
/// </summary>
|
||||
AsReference = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Embeds the type information into the stream, allowing usage with types not known in advance
|
||||
/// </summary>
|
||||
DynamicType = 8,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this field should *repace* existing values (the default is false, meaning *append*).
|
||||
/// This option only applies to list/array data.
|
||||
/// </summary>
|
||||
OverwriteList = 16,
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the types AsReferenceDefault value is used, or whether this member's AsReference should be used
|
||||
/// </summary>
|
||||
|
@ -208,7 +252,7 @@ namespace ProtoBuf
|
|||
/// fixed-length encoding for large values.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class,
|
||||
AllowMultiple = true, Inherited = false)]
|
||||
AllowMultiple = true, Inherited = false)]
|
||||
public sealed class ProtoPartialMemberAttribute : ProtoMemberAttribute
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -222,10 +266,15 @@ namespace ProtoBuf
|
|||
if (Helpers.IsNullOrEmpty(memberName)) throw new ArgumentNullException("memberName");
|
||||
this.memberName = memberName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the member to be serialized.
|
||||
/// </summary>
|
||||
public string MemberName { get { return memberName; } }
|
||||
public string MemberName
|
||||
{
|
||||
get { return memberName; }
|
||||
}
|
||||
|
||||
private readonly string memberName;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,8 +1,8 @@
|
|||
using System;
|
||||
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using ProtoBuf.Meta;
|
||||
|
||||
#if MF
|
||||
using OverflowException = System.ApplicationException;
|
||||
#endif
|
||||
|
@ -22,8 +22,8 @@ namespace ProtoBuf
|
|||
public sealed class ProtoWriter : IDisposable
|
||||
{
|
||||
private Stream dest;
|
||||
TypeModel model;
|
||||
|
||||
private TypeModel model;
|
||||
|
||||
/// <summary>
|
||||
/// Write an encapsulated sub-object, using the supplied unique key (reprasenting a type).
|
||||
/// </summary>
|
||||
|
@ -46,7 +46,9 @@ namespace ProtoBuf
|
|||
{
|
||||
writer.model.Serialize(key, value, writer);
|
||||
}
|
||||
else if (writer.model != null && writer.model.TrySerializeAuxiliaryType(writer, value.GetType(), DataFormat.Default, Serializer.ListItemTag, value, false))
|
||||
else if (writer.model != null &&
|
||||
writer.model.TrySerializeAuxiliaryType(writer, value.GetType(), DataFormat.Default,
|
||||
Serializer.ListItemTag, value, false))
|
||||
{
|
||||
// all ok
|
||||
}
|
||||
|
@ -55,8 +57,9 @@ namespace ProtoBuf
|
|||
TypeModel.ThrowUnexpectedType(value.GetType());
|
||||
}
|
||||
EndSubItem(token, writer);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write an encapsulated sub-object, using the supplied unique key (reprasenting a type) - but the
|
||||
/// caller is asserting that this relationship is non-recursive; no recursion check will be
|
||||
|
@ -76,6 +79,7 @@ namespace ProtoBuf
|
|||
writer.model.Serialize(key, value, writer);
|
||||
EndSubItem(token, writer);
|
||||
}
|
||||
|
||||
internal static void WriteObject(object value, int key, ProtoWriter writer, PrefixStyle style, int fieldNumber)
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
|
@ -105,7 +109,9 @@ namespace ProtoBuf
|
|||
SubItemToken token = StartSubItem(value, writer, true);
|
||||
if (key < 0)
|
||||
{
|
||||
if (!writer.model.TrySerializeAuxiliaryType(writer, value.GetType(), DataFormat.Default, Serializer.ListItemTag, value, false))
|
||||
if (
|
||||
!writer.model.TrySerializeAuxiliaryType(writer, value.GetType(), DataFormat.Default,
|
||||
Serializer.ListItemTag, value, false))
|
||||
{
|
||||
TypeModel.ThrowUnexpectedType(value.GetType());
|
||||
}
|
||||
|
@ -115,34 +121,44 @@ namespace ProtoBuf
|
|||
writer.model.Serialize(key, value, writer);
|
||||
}
|
||||
EndSubItem(token, writer, style);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
internal int GetTypeKey(ref Type type)
|
||||
{
|
||||
return model.GetKey(ref type);
|
||||
}
|
||||
|
||||
|
||||
private readonly NetObjectCache netCache = new NetObjectCache();
|
||||
|
||||
internal NetObjectCache NetCache
|
||||
{
|
||||
get { return netCache;}
|
||||
get { return netCache; }
|
||||
}
|
||||
|
||||
private int fieldNumber, flushLock;
|
||||
WireType wireType;
|
||||
internal WireType WireType { get { return wireType; } }
|
||||
private WireType wireType;
|
||||
|
||||
internal WireType WireType
|
||||
{
|
||||
get { return wireType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a field-header, indicating the format of the next data we plan to write.
|
||||
/// </summary>
|
||||
public static void WriteFieldHeader(int fieldNumber, WireType wireType, ProtoWriter writer) {
|
||||
public static void WriteFieldHeader(int fieldNumber, WireType wireType, ProtoWriter writer)
|
||||
{
|
||||
if (writer == null) throw new ArgumentNullException("writer");
|
||||
if (writer.wireType != WireType.None) throw new InvalidOperationException("Cannot write a " + wireType.ToString()
|
||||
+ " header until the " + writer.wireType.ToString() + " data has been written");
|
||||
if(fieldNumber < 0) throw new ArgumentOutOfRangeException("fieldNumber");
|
||||
if (writer.wireType != WireType.None)
|
||||
throw new InvalidOperationException("Cannot write a " + wireType.ToString()
|
||||
+ " header until the " + writer.wireType.ToString() +
|
||||
" data has been written");
|
||||
if (fieldNumber < 0) throw new ArgumentOutOfRangeException("fieldNumber");
|
||||
#if DEBUG
|
||||
switch (wireType)
|
||||
{ // validate requested header-type
|
||||
{
|
||||
// validate requested header-type
|
||||
case WireType.Fixed32:
|
||||
case WireType.Fixed64:
|
||||
case WireType.String:
|
||||
|
@ -153,16 +169,18 @@ namespace ProtoBuf
|
|||
case WireType.None:
|
||||
case WireType.EndGroup:
|
||||
default:
|
||||
throw new ArgumentException("Invalid wire-type: " + wireType.ToString(), "wireType");
|
||||
throw new ArgumentException("Invalid wire-type: " + wireType.ToString(), "wireType");
|
||||
}
|
||||
#endif
|
||||
if (writer.packedFieldNumber == 0) {
|
||||
if (writer.packedFieldNumber == 0)
|
||||
{
|
||||
writer.fieldNumber = fieldNumber;
|
||||
writer.wireType = wireType;
|
||||
WriteHeaderCore(fieldNumber, wireType, writer);
|
||||
}
|
||||
else if (writer.packedFieldNumber == fieldNumber)
|
||||
{ // we'll set things up, but note we *don't* actually write the header here
|
||||
{
|
||||
// we'll set things up, but note we *don't* actually write the header here
|
||||
switch (wireType)
|
||||
{
|
||||
case WireType.Fixed32:
|
||||
|
@ -171,20 +189,24 @@ namespace ProtoBuf
|
|||
case WireType.SignedVariant:
|
||||
break; // fine
|
||||
default:
|
||||
throw new InvalidOperationException("Wire-type cannot be encoded as packed: " + wireType.ToString());
|
||||
throw new InvalidOperationException("Wire-type cannot be encoded as packed: " +
|
||||
wireType.ToString());
|
||||
}
|
||||
writer.fieldNumber = fieldNumber;
|
||||
writer.wireType = wireType;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Field mismatch during packed encoding; expected " + writer.packedFieldNumber.ToString() + " but received " + fieldNumber.ToString());
|
||||
throw new InvalidOperationException("Field mismatch during packed encoding; expected " +
|
||||
writer.packedFieldNumber.ToString() + " but received " +
|
||||
fieldNumber.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
internal static void WriteHeaderCore(int fieldNumber, WireType wireType, ProtoWriter writer)
|
||||
{
|
||||
uint header = (((uint)fieldNumber) << 3)
|
||||
| (((uint)wireType) & 7);
|
||||
uint header = (((uint) fieldNumber) << 3)
|
||||
| (((uint) wireType) & 7);
|
||||
WriteUInt32Variant(header, writer);
|
||||
}
|
||||
|
||||
|
@ -196,6 +218,7 @@ namespace ProtoBuf
|
|||
if (data == null) throw new ArgumentNullException("data");
|
||||
ProtoWriter.WriteBytes(data, 0, data.Length, writer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a byte-array to the stream; supported wire-types: String
|
||||
/// </summary>
|
||||
|
@ -207,12 +230,12 @@ namespace ProtoBuf
|
|||
{
|
||||
case WireType.Fixed32:
|
||||
if (length != 4) throw new ArgumentException("length");
|
||||
goto CopyFixedLength; // ugly but effective
|
||||
goto CopyFixedLength; // ugly but effective
|
||||
case WireType.Fixed64:
|
||||
if (length != 8) throw new ArgumentException("length");
|
||||
goto CopyFixedLength; // ugly but effective
|
||||
goto CopyFixedLength; // ugly but effective
|
||||
case WireType.String:
|
||||
WriteUInt32Variant((uint)length, writer);
|
||||
WriteUInt32Variant((uint) length, writer);
|
||||
writer.wireType = WireType.None;
|
||||
if (length == 0) return;
|
||||
if (writer.flushLock != 0 || length <= writer.ioBuffer.Length) // write to the buffer
|
||||
|
@ -225,26 +248,27 @@ namespace ProtoBuf
|
|||
// now just write directly to the underlying stream
|
||||
writer.dest.Write(data, offset, length);
|
||||
writer.position += length; // since we've flushed offset etc is 0, and remains
|
||||
// zero since we're writing directly to the stream
|
||||
// zero since we're writing directly to the stream
|
||||
return;
|
||||
}
|
||||
throw CreateException(writer);
|
||||
CopyFixedLength: // no point duplicating this lots of times, and don't really want another stackframe
|
||||
CopyFixedLength: // no point duplicating this lots of times, and don't really want another stackframe
|
||||
DemandSpace(length, writer);
|
||||
Helpers.BlockCopy(data, offset, writer.ioBuffer, writer.ioIndex, length);
|
||||
IncrementedAndReset(length, writer);
|
||||
}
|
||||
|
||||
private static void CopyRawFromStream(Stream source, ProtoWriter writer)
|
||||
{
|
||||
byte[] buffer = writer.ioBuffer;
|
||||
int space = buffer.Length - writer.ioIndex, bytesRead = 1; // 1 here to spoof case where already full
|
||||
|
||||
|
||||
// try filling the buffer first
|
||||
while (space > 0 && (bytesRead = source.Read(buffer, writer.ioIndex, space)) > 0)
|
||||
{
|
||||
writer.ioIndex += bytesRead;
|
||||
writer.position += bytesRead;
|
||||
space -= bytesRead;
|
||||
space -= bytesRead;
|
||||
}
|
||||
if (bytesRead <= 0) return; // all done using just the buffer; stream exhausted
|
||||
|
||||
|
@ -267,14 +291,14 @@ namespace ProtoBuf
|
|||
// (128 is the minimum; there may actually be much
|
||||
// more space than this in the buffer)
|
||||
DemandSpace(128, writer);
|
||||
if((bytesRead = source.Read(writer.ioBuffer, writer.ioIndex,
|
||||
if ((bytesRead = source.Read(writer.ioBuffer, writer.ioIndex,
|
||||
writer.ioBuffer.Length - writer.ioIndex)) <= 0) break;
|
||||
writer.position += bytesRead;
|
||||
writer.ioIndex += bytesRead;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void IncrementedAndReset(int length, ProtoWriter writer)
|
||||
{
|
||||
Helpers.DebugAssert(length >= 0);
|
||||
|
@ -282,8 +306,10 @@ namespace ProtoBuf
|
|||
writer.position += length;
|
||||
writer.wireType = WireType.None;
|
||||
}
|
||||
int depth = 0;
|
||||
const int RecursionCheckDepth = 25;
|
||||
|
||||
private int depth = 0;
|
||||
private const int RecursionCheckDepth = 25;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the start of a nested record.
|
||||
/// </summary>
|
||||
|
@ -295,26 +321,36 @@ namespace ProtoBuf
|
|||
return StartSubItem(instance, writer, false);
|
||||
}
|
||||
|
||||
MutableList recursionStack;
|
||||
private MutableList recursionStack;
|
||||
|
||||
private void CheckRecursionStackAndPush(object instance)
|
||||
{
|
||||
int hitLevel;
|
||||
if (recursionStack == null) { recursionStack = new MutableList(); }
|
||||
if (recursionStack == null)
|
||||
{
|
||||
recursionStack = new MutableList();
|
||||
}
|
||||
else if (instance != null && (hitLevel = recursionStack.IndexOfReference(instance)) >= 0)
|
||||
{
|
||||
#if DEBUG
|
||||
Helpers.DebugWriteLine("Stack:");
|
||||
foreach(object obj in recursionStack)
|
||||
foreach (object obj in recursionStack)
|
||||
{
|
||||
Helpers.DebugWriteLine(obj == null ? "<null>" : obj.ToString());
|
||||
}
|
||||
Helpers.DebugWriteLine(instance == null ? "<null>" : instance.ToString());
|
||||
#endif
|
||||
throw new ProtoException("Possible recursion detected (offset: " + (recursionStack.Count - hitLevel).ToString() + " level(s)): " + instance.ToString());
|
||||
throw new ProtoException("Possible recursion detected (offset: " +
|
||||
(recursionStack.Count - hitLevel).ToString() + " level(s)): " +
|
||||
instance.ToString());
|
||||
}
|
||||
recursionStack.Add(instance);
|
||||
}
|
||||
private void PopRecursionStack() { recursionStack.RemoveLast(); }
|
||||
|
||||
private void PopRecursionStack()
|
||||
{
|
||||
recursionStack.RemoveLast();
|
||||
}
|
||||
|
||||
private static SubItemToken StartSubItem(object instance, ProtoWriter writer, bool allowFixed)
|
||||
{
|
||||
|
@ -323,7 +359,8 @@ namespace ProtoBuf
|
|||
{
|
||||
writer.CheckRecursionStackAndPush(instance);
|
||||
}
|
||||
if(writer.packedFieldNumber != 0) throw new InvalidOperationException("Cannot begin a sub-item while performing packed encoding");
|
||||
if (writer.packedFieldNumber != 0)
|
||||
throw new InvalidOperationException("Cannot begin a sub-item while performing packed encoding");
|
||||
switch (writer.wireType)
|
||||
{
|
||||
case WireType.StartGroup:
|
||||
|
@ -331,7 +368,7 @@ namespace ProtoBuf
|
|||
return new SubItemToken(-writer.fieldNumber);
|
||||
case WireType.String:
|
||||
#if DEBUG
|
||||
if(writer.model != null && writer.model.ForwardsOnly)
|
||||
if (writer.model != null && writer.model.ForwardsOnly)
|
||||
{
|
||||
throw new ProtoException("Should not be buffering data");
|
||||
}
|
||||
|
@ -342,14 +379,14 @@ namespace ProtoBuf
|
|||
writer.position++;
|
||||
return new SubItemToken(writer.ioIndex++); // leave 1 space (optimistic) for length
|
||||
case WireType.Fixed32:
|
||||
{
|
||||
if (!allowFixed) throw CreateException(writer);
|
||||
DemandSpace(32, writer); // make some space in anticipation...
|
||||
writer.flushLock++;
|
||||
SubItemToken token = new SubItemToken(writer.ioIndex);
|
||||
ProtoWriter.IncrementedAndReset(4, writer); // leave 4 space (rigid) for length
|
||||
return token;
|
||||
}
|
||||
{
|
||||
if (!allowFixed) throw CreateException(writer);
|
||||
DemandSpace(32, writer); // make some space in anticipation...
|
||||
writer.flushLock++;
|
||||
SubItemToken token = new SubItemToken(writer.ioIndex);
|
||||
ProtoWriter.IncrementedAndReset(4, writer); // leave 4 space (rigid) for length
|
||||
return token;
|
||||
}
|
||||
default:
|
||||
throw CreateException(writer);
|
||||
}
|
||||
|
@ -364,10 +401,14 @@ namespace ProtoBuf
|
|||
{
|
||||
EndSubItem(token, writer, PrefixStyle.Base128);
|
||||
}
|
||||
|
||||
private static void EndSubItem(SubItemToken token, ProtoWriter writer, PrefixStyle style)
|
||||
{
|
||||
if (writer == null) throw new ArgumentNullException("writer");
|
||||
if (writer.wireType != WireType.None) { throw CreateException(writer); }
|
||||
if (writer.wireType != WireType.None)
|
||||
{
|
||||
throw CreateException(writer);
|
||||
}
|
||||
int value = token.value;
|
||||
if (writer.depth <= 0) throw CreateException(writer);
|
||||
if (writer.depth-- > RecursionCheckDepth)
|
||||
|
@ -376,7 +417,8 @@ namespace ProtoBuf
|
|||
}
|
||||
writer.packedFieldNumber = 0; // ending the sub-item always wipes packed encoding
|
||||
if (value < 0)
|
||||
{ // group - very simple append
|
||||
{
|
||||
// group - very simple append
|
||||
WriteHeaderCore(-value, WireType.EndGroup, writer);
|
||||
writer.wireType = WireType.None;
|
||||
return;
|
||||
|
@ -384,14 +426,14 @@ namespace ProtoBuf
|
|||
|
||||
// so we're backfilling the length into an existing sequence
|
||||
int len;
|
||||
switch(style)
|
||||
switch (style)
|
||||
{
|
||||
case PrefixStyle.Fixed32:
|
||||
len = (int)((writer.ioIndex - value) - 4);
|
||||
len = (int) ((writer.ioIndex - value) - 4);
|
||||
ProtoWriter.WriteInt32ToBuffer(len, writer.ioBuffer, value);
|
||||
break;
|
||||
case PrefixStyle.Fixed32BigEndian:
|
||||
len = (int)((writer.ioIndex - value) - 4);
|
||||
len = (int) ((writer.ioIndex - value) - 4);
|
||||
byte[] buffer = writer.ioBuffer;
|
||||
ProtoWriter.WriteInt32ToBuffer(len, buffer, value);
|
||||
// and swap the byte order
|
||||
|
@ -406,25 +448,25 @@ namespace ProtoBuf
|
|||
// string - complicated because we only reserved one byte;
|
||||
// if the prefix turns out to need more than this then
|
||||
// we need to shuffle the existing data
|
||||
len = (int)((writer.ioIndex - value) - 1);
|
||||
len = (int) ((writer.ioIndex - value) - 1);
|
||||
int offset = 0;
|
||||
uint tmp = (uint)len;
|
||||
uint tmp = (uint) len;
|
||||
while ((tmp >>= 7) != 0) offset++;
|
||||
if (offset == 0)
|
||||
{
|
||||
writer.ioBuffer[value] = (byte)(len & 0x7F);
|
||||
writer.ioBuffer[value] = (byte) (len & 0x7F);
|
||||
}
|
||||
else
|
||||
{
|
||||
DemandSpace(offset, writer);
|
||||
byte[] blob = writer.ioBuffer;
|
||||
Helpers.BlockCopy(blob, value + 1, blob, value + 1 + offset, len);
|
||||
tmp = (uint)len;
|
||||
tmp = (uint) len;
|
||||
do
|
||||
{
|
||||
blob[value++] = (byte)((tmp & 0x7F) | 0x80);
|
||||
blob[value++] = (byte) ((tmp & 0x7F) | 0x80);
|
||||
} while ((tmp >>= 7) != 0);
|
||||
blob[value - 1] = (byte)(blob[value - 1] & ~0x80);
|
||||
blob[value - 1] = (byte) (blob[value - 1] & ~0x80);
|
||||
writer.position += offset;
|
||||
writer.ioIndex += offset;
|
||||
}
|
||||
|
@ -438,7 +480,6 @@ namespace ProtoBuf
|
|||
{
|
||||
ProtoWriter.Flush(writer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -456,17 +497,26 @@ namespace ProtoBuf
|
|||
this.ioBuffer = BufferPool.GetBuffer();
|
||||
this.model = model;
|
||||
this.wireType = WireType.None;
|
||||
if (context == null) { context = SerializationContext.Default; }
|
||||
else { context.Freeze(); }
|
||||
if (context == null)
|
||||
{
|
||||
context = SerializationContext.Default;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Freeze();
|
||||
}
|
||||
this.context = context;
|
||||
|
||||
}
|
||||
|
||||
private readonly SerializationContext context;
|
||||
|
||||
/// <summary>
|
||||
/// Addition information about this serialization operation.
|
||||
/// </summary>
|
||||
public SerializationContext Context { get { return context; } }
|
||||
public SerializationContext Context
|
||||
{
|
||||
get { return context; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes and cleans up all unused resources that is used by the object.
|
||||
|
@ -494,8 +544,13 @@ namespace ProtoBuf
|
|||
private byte[] ioBuffer;
|
||||
private int ioIndex;
|
||||
// note that this is used by some of the unit tests and should not be removed
|
||||
internal static int GetPosition(ProtoWriter writer) { return writer.position; }
|
||||
internal static int GetPosition(ProtoWriter writer)
|
||||
{
|
||||
return writer.position;
|
||||
}
|
||||
|
||||
private int position;
|
||||
|
||||
private static void DemandSpace(int required, ProtoWriter writer)
|
||||
{
|
||||
// check for enough space
|
||||
|
@ -510,25 +565,31 @@ namespace ProtoBuf
|
|||
BufferPool.ResizeAndFlushLeft(ref writer.ioBuffer, required + writer.ioIndex, 0, writer.ioIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flushes data to the underlying stream, and releases any resources. The underlying stream is *not* disposed
|
||||
/// by this operation.
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
if (depth != 0 || flushLock != 0) throw new InvalidOperationException("Unable to close stream in an incomplete state");
|
||||
if (depth != 0 || flushLock != 0)
|
||||
throw new InvalidOperationException("Unable to close stream in an incomplete state");
|
||||
Dispose();
|
||||
}
|
||||
|
||||
internal void CheckDepthFlushlock()
|
||||
{
|
||||
if (depth != 0 || flushLock != 0) throw new InvalidOperationException("The writer is in an incomplete state");
|
||||
if (depth != 0 || flushLock != 0)
|
||||
throw new InvalidOperationException("The writer is in an incomplete state");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the TypeModel associated with this writer
|
||||
/// </summary>
|
||||
public TypeModel Model { get { return model; } }
|
||||
public TypeModel Model
|
||||
{
|
||||
get { return model; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes any buffered data (if possible) to the underlying stream.
|
||||
|
@ -541,7 +602,7 @@ namespace ProtoBuf
|
|||
if (writer.flushLock == 0 && writer.ioIndex != 0)
|
||||
{
|
||||
writer.dest.Write(writer.ioBuffer, 0, writer.ioIndex);
|
||||
writer.ioIndex = 0;
|
||||
writer.ioIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -552,36 +613,40 @@ namespace ProtoBuf
|
|||
{
|
||||
DemandSpace(5, writer);
|
||||
int count = 0;
|
||||
do {
|
||||
writer.ioBuffer[writer.ioIndex++] = (byte)((value & 0x7F) | 0x80);
|
||||
do
|
||||
{
|
||||
writer.ioBuffer[writer.ioIndex++] = (byte) ((value & 0x7F) | 0x80);
|
||||
count++;
|
||||
} while ((value >>= 7) != 0);
|
||||
writer.ioBuffer[writer.ioIndex - 1] &= 0x7F;
|
||||
writer.position += count;
|
||||
}
|
||||
|
||||
static readonly UTF8Encoding encoding = new UTF8Encoding();
|
||||
|
||||
private static readonly UTF8Encoding encoding = new UTF8Encoding();
|
||||
|
||||
internal static uint Zig(int value)
|
||||
{
|
||||
return (uint)((value << 1) ^ (value >> 31));
|
||||
{
|
||||
return (uint) ((value << 1) ^ (value >> 31));
|
||||
}
|
||||
|
||||
internal static ulong Zig(long value)
|
||||
{
|
||||
return (ulong)((value << 1) ^ (value >> 63));
|
||||
return (ulong) ((value << 1) ^ (value >> 63));
|
||||
}
|
||||
|
||||
private static void WriteUInt64Variant(ulong value, ProtoWriter writer)
|
||||
{
|
||||
DemandSpace(10, writer);
|
||||
int count = 0;
|
||||
do
|
||||
{
|
||||
writer.ioBuffer[writer.ioIndex++] = (byte)((value & 0x7F) | 0x80);
|
||||
writer.ioBuffer[writer.ioIndex++] = (byte) ((value & 0x7F) | 0x80);
|
||||
count++;
|
||||
} while ((value >>= 7) != 0);
|
||||
writer.ioBuffer[writer.ioIndex - 1] &= 0x7F;
|
||||
writer.position += count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a string to the stream; supported wire-types: String
|
||||
/// </summary>
|
||||
|
@ -605,13 +670,14 @@ namespace ProtoBuf
|
|||
Helpers.BlockCopy(bytes, 0, writer.ioBuffer, writer.ioIndex, actual);
|
||||
#else
|
||||
int predicted = encoding.GetByteCount(value);
|
||||
WriteUInt32Variant((uint)predicted, writer);
|
||||
WriteUInt32Variant((uint) predicted, writer);
|
||||
DemandSpace(predicted, writer);
|
||||
int actual = encoding.GetBytes(value, 0, value.Length, writer.ioBuffer, writer.ioIndex);
|
||||
Helpers.DebugAssert(predicted == actual);
|
||||
#endif
|
||||
IncrementedAndReset(actual, writer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an unsigned 64-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64
|
||||
/// </summary>
|
||||
|
@ -621,14 +687,17 @@ namespace ProtoBuf
|
|||
switch (writer.wireType)
|
||||
{
|
||||
case WireType.Fixed64:
|
||||
ProtoWriter.WriteInt64((long)value, writer);
|
||||
ProtoWriter.WriteInt64((long) value, writer);
|
||||
return;
|
||||
case WireType.Variant:
|
||||
WriteUInt64Variant(value, writer);
|
||||
writer.wireType = WireType.None;
|
||||
return;
|
||||
case WireType.Fixed32:
|
||||
checked { ProtoWriter.WriteUInt32((uint)value, writer); }
|
||||
checked
|
||||
{
|
||||
ProtoWriter.WriteUInt32((uint) value, writer);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
throw CreateException(writer);
|
||||
|
@ -649,14 +718,14 @@ namespace ProtoBuf
|
|||
DemandSpace(8, writer);
|
||||
buffer = writer.ioBuffer;
|
||||
index = writer.ioIndex;
|
||||
buffer[index] = (byte)value;
|
||||
buffer[index + 1] = (byte)(value >> 8);
|
||||
buffer[index + 2] = (byte)(value >> 16);
|
||||
buffer[index + 3] = (byte)(value >> 24);
|
||||
buffer[index + 4] = (byte)(value >> 32);
|
||||
buffer[index + 5] = (byte)(value >> 40);
|
||||
buffer[index + 6] = (byte)(value >> 48);
|
||||
buffer[index + 7] = (byte)(value >> 56);
|
||||
buffer[index] = (byte) value;
|
||||
buffer[index + 1] = (byte) (value >> 8);
|
||||
buffer[index + 2] = (byte) (value >> 16);
|
||||
buffer[index + 3] = (byte) (value >> 24);
|
||||
buffer[index + 4] = (byte) (value >> 32);
|
||||
buffer[index + 5] = (byte) (value >> 40);
|
||||
buffer[index + 6] = (byte) (value >> 48);
|
||||
buffer[index + 7] = (byte) (value >> 56);
|
||||
IncrementedAndReset(8, writer);
|
||||
return;
|
||||
case WireType.SignedVariant:
|
||||
|
@ -666,7 +735,7 @@ namespace ProtoBuf
|
|||
case WireType.Variant:
|
||||
if (value >= 0)
|
||||
{
|
||||
WriteUInt64Variant((ulong)value, writer);
|
||||
WriteUInt64Variant((ulong) value, writer);
|
||||
writer.wireType = WireType.None;
|
||||
}
|
||||
else
|
||||
|
@ -674,21 +743,24 @@ namespace ProtoBuf
|
|||
DemandSpace(10, writer);
|
||||
buffer = writer.ioBuffer;
|
||||
index = writer.ioIndex;
|
||||
buffer[index] = (byte)(value | 0x80);
|
||||
buffer[index + 1] = (byte)((int)(value >> 7) | 0x80);
|
||||
buffer[index + 2] = (byte)((int)(value >> 14) | 0x80);
|
||||
buffer[index + 3] = (byte)((int)(value >> 21) | 0x80);
|
||||
buffer[index + 4] = (byte)((int)(value >> 28) | 0x80);
|
||||
buffer[index + 5] = (byte)((int)(value >> 35) | 0x80);
|
||||
buffer[index + 6] = (byte)((int)(value >> 42) | 0x80);
|
||||
buffer[index + 7] = (byte)((int)(value >> 49) | 0x80);
|
||||
buffer[index + 8] = (byte)((int)(value >> 56) | 0x80);
|
||||
buffer[index] = (byte) (value | 0x80);
|
||||
buffer[index + 1] = (byte) ((int) (value >> 7) | 0x80);
|
||||
buffer[index + 2] = (byte) ((int) (value >> 14) | 0x80);
|
||||
buffer[index + 3] = (byte) ((int) (value >> 21) | 0x80);
|
||||
buffer[index + 4] = (byte) ((int) (value >> 28) | 0x80);
|
||||
buffer[index + 5] = (byte) ((int) (value >> 35) | 0x80);
|
||||
buffer[index + 6] = (byte) ((int) (value >> 42) | 0x80);
|
||||
buffer[index + 7] = (byte) ((int) (value >> 49) | 0x80);
|
||||
buffer[index + 8] = (byte) ((int) (value >> 56) | 0x80);
|
||||
buffer[index + 9] = 0x01; // sign bit
|
||||
IncrementedAndReset(10, writer);
|
||||
}
|
||||
return;
|
||||
case WireType.Fixed32:
|
||||
checked { WriteInt32((int)value, writer); }
|
||||
checked
|
||||
{
|
||||
WriteInt32((int) value, writer);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
throw CreateException(writer);
|
||||
|
@ -704,10 +776,10 @@ namespace ProtoBuf
|
|||
switch (writer.wireType)
|
||||
{
|
||||
case WireType.Fixed32:
|
||||
ProtoWriter.WriteInt32((int)value, writer);
|
||||
ProtoWriter.WriteInt32((int) value, writer);
|
||||
return;
|
||||
case WireType.Fixed64:
|
||||
ProtoWriter.WriteInt64((int)value, writer);
|
||||
ProtoWriter.WriteInt64((int) value, writer);
|
||||
return;
|
||||
case WireType.Variant:
|
||||
WriteUInt32Variant(value, writer);
|
||||
|
@ -726,6 +798,7 @@ namespace ProtoBuf
|
|||
{
|
||||
ProtoWriter.WriteInt32(value, writer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an unsigned 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64
|
||||
/// </summary>
|
||||
|
@ -733,6 +806,7 @@ namespace ProtoBuf
|
|||
{
|
||||
ProtoWriter.WriteUInt32(value, writer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an unsigned 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64
|
||||
/// </summary>
|
||||
|
@ -740,6 +814,7 @@ namespace ProtoBuf
|
|||
{
|
||||
ProtoWriter.WriteUInt32(value, writer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a signed 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant
|
||||
/// </summary>
|
||||
|
@ -747,12 +822,13 @@ namespace ProtoBuf
|
|||
{
|
||||
ProtoWriter.WriteInt32(value, writer);
|
||||
}
|
||||
|
||||
private static void WriteInt32ToBuffer(int value, byte[] buffer, int index)
|
||||
{
|
||||
buffer[index] = (byte)value;
|
||||
buffer[index + 1] = (byte)(value >> 8);
|
||||
buffer[index + 2] = (byte)(value >> 16);
|
||||
buffer[index + 3] = (byte)(value >> 24);
|
||||
buffer[index] = (byte) value;
|
||||
buffer[index + 1] = (byte) (value >> 8);
|
||||
buffer[index + 2] = (byte) (value >> 16);
|
||||
buffer[index + 3] = (byte) (value >> 24);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -767,17 +843,17 @@ namespace ProtoBuf
|
|||
{
|
||||
case WireType.Fixed32:
|
||||
DemandSpace(4, writer);
|
||||
WriteInt32ToBuffer(value, writer.ioBuffer, writer.ioIndex);
|
||||
WriteInt32ToBuffer(value, writer.ioBuffer, writer.ioIndex);
|
||||
IncrementedAndReset(4, writer);
|
||||
return;
|
||||
case WireType.Fixed64:
|
||||
DemandSpace(8, writer);
|
||||
buffer = writer.ioBuffer;
|
||||
index = writer.ioIndex;
|
||||
buffer[index] = (byte)value;
|
||||
buffer[index + 1] = (byte)(value >> 8);
|
||||
buffer[index + 2] = (byte)(value >> 16);
|
||||
buffer[index + 3] = (byte)(value >> 24);
|
||||
buffer[index] = (byte) value;
|
||||
buffer[index + 1] = (byte) (value >> 8);
|
||||
buffer[index + 2] = (byte) (value >> 16);
|
||||
buffer[index + 3] = (byte) (value >> 24);
|
||||
buffer[index + 4] = buffer[index + 5] =
|
||||
buffer[index + 6] = buffer[index + 7] = 0;
|
||||
IncrementedAndReset(8, writer);
|
||||
|
@ -789,7 +865,7 @@ namespace ProtoBuf
|
|||
case WireType.Variant:
|
||||
if (value >= 0)
|
||||
{
|
||||
WriteUInt32Variant((uint)value, writer);
|
||||
WriteUInt32Variant((uint) value, writer);
|
||||
writer.wireType = WireType.None;
|
||||
}
|
||||
else
|
||||
|
@ -797,37 +873,36 @@ namespace ProtoBuf
|
|||
DemandSpace(10, writer);
|
||||
buffer = writer.ioBuffer;
|
||||
index = writer.ioIndex;
|
||||
buffer[index] = (byte)(value | 0x80);
|
||||
buffer[index + 1] = (byte)((value >> 7) | 0x80);
|
||||
buffer[index + 2] = (byte)((value >> 14) | 0x80);
|
||||
buffer[index + 3] = (byte)((value >> 21) | 0x80);
|
||||
buffer[index + 4] = (byte)((value >> 28) | 0x80);
|
||||
buffer[index] = (byte) (value | 0x80);
|
||||
buffer[index + 1] = (byte) ((value >> 7) | 0x80);
|
||||
buffer[index + 2] = (byte) ((value >> 14) | 0x80);
|
||||
buffer[index + 3] = (byte) ((value >> 21) | 0x80);
|
||||
buffer[index + 4] = (byte) ((value >> 28) | 0x80);
|
||||
buffer[index + 5] = buffer[index + 6] =
|
||||
buffer[index + 7] = buffer[index + 8] = (byte)0xFF;
|
||||
buffer[index + 9] = (byte)0x01;
|
||||
buffer[index + 7] = buffer[index + 8] = (byte) 0xFF;
|
||||
buffer[index + 9] = (byte) 0x01;
|
||||
IncrementedAndReset(10, writer);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
throw CreateException(writer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a double-precision number to the stream; supported wire-types: Fixed32, Fixed64
|
||||
/// </summary>
|
||||
public
|
||||
#if !FEAT_SAFE
|
||||
unsafe
|
||||
static
|
||||
#endif
|
||||
|
||||
static void WriteDouble(double value, ProtoWriter writer)
|
||||
unsafe void WriteDouble(double value, ProtoWriter writer)
|
||||
{
|
||||
if (writer == null) throw new ArgumentNullException("writer");
|
||||
switch (writer.wireType)
|
||||
{
|
||||
case WireType.Fixed32:
|
||||
float f = (float)value;
|
||||
float f = (float) value;
|
||||
if (Helpers.IsInfinity(f)
|
||||
&& !Helpers.IsInfinity(value))
|
||||
{
|
||||
|
@ -839,21 +914,22 @@ namespace ProtoBuf
|
|||
#if FEAT_SAFE
|
||||
ProtoWriter.WriteInt64(BitConverter.ToInt64(BitConverter.GetBytes(value), 0), writer);
|
||||
#else
|
||||
ProtoWriter.WriteInt64(*(long*)&value, writer);
|
||||
ProtoWriter.WriteInt64(*(long*) &value, writer);
|
||||
#endif
|
||||
return;
|
||||
default:
|
||||
throw CreateException(writer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a single-precision number to the stream; supported wire-types: Fixed32, Fixed64
|
||||
/// </summary>
|
||||
public
|
||||
public
|
||||
#if !FEAT_SAFE
|
||||
unsafe
|
||||
static
|
||||
#endif
|
||||
static void WriteSingle(float value, ProtoWriter writer)
|
||||
unsafe void WriteSingle(float value, ProtoWriter writer)
|
||||
{
|
||||
if (writer == null) throw new ArgumentNullException("writer");
|
||||
switch (writer.wireType)
|
||||
|
@ -862,16 +938,17 @@ namespace ProtoBuf
|
|||
#if FEAT_SAFE
|
||||
ProtoWriter.WriteInt32(BitConverter.ToInt32(BitConverter.GetBytes(value), 0), writer);
|
||||
#else
|
||||
ProtoWriter.WriteInt32(*(int*)&value, writer);
|
||||
ProtoWriter.WriteInt32(*(int*) &value, writer);
|
||||
#endif
|
||||
return;
|
||||
case WireType.Fixed64:
|
||||
ProtoWriter.WriteDouble((double)value, writer);
|
||||
ProtoWriter.WriteDouble((double) value, writer);
|
||||
return;
|
||||
default:
|
||||
throw CreateException(writer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws an exception indicating that the given enum cannot be mapped to a serialized value.
|
||||
/// </summary>
|
||||
|
@ -879,13 +956,17 @@ namespace ProtoBuf
|
|||
{
|
||||
if (writer == null) throw new ArgumentNullException("writer");
|
||||
string rhs = enumValue == null ? "<null>" : (enumValue.GetType().FullName + "." + enumValue.ToString());
|
||||
throw new ProtoException("No wire-value is mapped to the enum " + rhs + " at position " + writer.position.ToString());
|
||||
throw new ProtoException("No wire-value is mapped to the enum " + rhs + " at position " +
|
||||
writer.position.ToString());
|
||||
}
|
||||
|
||||
// general purpose serialization exception message
|
||||
internal static Exception CreateException(ProtoWriter writer)
|
||||
{
|
||||
if (writer == null) throw new ArgumentNullException("writer");
|
||||
return new ProtoException("Invalid serialization operation with wire-type " + writer.wireType.ToString() + " at position " + writer.position.ToString());
|
||||
return
|
||||
new ProtoException("Invalid serialization operation with wire-type " + writer.wireType.ToString() +
|
||||
" at position " + writer.position.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -893,7 +974,7 @@ namespace ProtoBuf
|
|||
/// </summary>
|
||||
public static void WriteBoolean(bool value, ProtoWriter writer)
|
||||
{
|
||||
ProtoWriter.WriteUInt32(value ? (uint)1 : (uint)0, writer);
|
||||
ProtoWriter.WriteUInt32(value ? (uint) 1 : (uint) 0, writer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -905,7 +986,7 @@ namespace ProtoBuf
|
|||
if (writer == null) throw new ArgumentNullException("writer");
|
||||
// we expect the writer to be raw here; the extension data will have the
|
||||
// header detail, so we'll copy it implicitly
|
||||
if(writer.wireType != WireType.None) throw CreateException(writer);
|
||||
if (writer.wireType != WireType.None) throw CreateException(writer);
|
||||
|
||||
IExtension extn = instance.GetExtensionObject(false);
|
||||
if (extn != null)
|
||||
|
@ -917,12 +998,16 @@ namespace ProtoBuf
|
|||
{
|
||||
CopyRawFromStream(source, writer);
|
||||
}
|
||||
finally { extn.EndQuery(source); }
|
||||
finally
|
||||
{
|
||||
extn.EndQuery(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int packedFieldNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Used for packed encoding; indicates that the next field should be skipped rather than
|
||||
/// a field header written. Note that the field number must match, else an exception is thrown
|
||||
|
@ -940,6 +1025,7 @@ namespace ProtoBuf
|
|||
{
|
||||
return TypeModel.SerializeType(model, type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies a known root object to use during reference-tracked serialization
|
||||
/// </summary>
|
||||
|
@ -957,4 +1043,4 @@ namespace ProtoBuf
|
|||
WriteString(writer.SerializeType(value), writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,28 +8,52 @@ namespace ProtoBuf
|
|||
public sealed class SerializationContext
|
||||
{
|
||||
private bool frozen;
|
||||
internal void Freeze() { frozen = true;}
|
||||
private void ThrowIfFrozen() { if (frozen) throw new InvalidOperationException("The serialization-context cannot be changed once it is in use"); }
|
||||
|
||||
internal void Freeze()
|
||||
{
|
||||
frozen = true;
|
||||
}
|
||||
|
||||
private void ThrowIfFrozen()
|
||||
{
|
||||
if (frozen)
|
||||
throw new InvalidOperationException("The serialization-context cannot be changed once it is in use");
|
||||
}
|
||||
|
||||
private object context;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a user-defined object containing additional information about this serialization/deserialization operation.
|
||||
/// </summary>
|
||||
public object Context
|
||||
{
|
||||
get { return context; }
|
||||
set { if (context != value) { ThrowIfFrozen(); context = value; } }
|
||||
set
|
||||
{
|
||||
if (context != value)
|
||||
{
|
||||
ThrowIfFrozen();
|
||||
context = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly SerializationContext @default;
|
||||
|
||||
static SerializationContext()
|
||||
{
|
||||
@default = new SerializationContext();
|
||||
@default.Freeze();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A default SerializationContext, with minimal information.
|
||||
/// </summary>
|
||||
internal static SerializationContext Default { get {return @default;}}
|
||||
internal static SerializationContext Default
|
||||
{
|
||||
get { return @default; }
|
||||
}
|
||||
|
||||
#if PLAT_BINARYFORMATTER || (SILVERLIGHT && NET_4_0)
|
||||
|
||||
#if !(WINRT || PHONE7 || PHONE8)
|
||||
|
@ -69,5 +93,4 @@ namespace ProtoBuf
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,16 +1,15 @@
|
|||
|
||||
using ProtoBuf.Meta;
|
||||
using ProtoBuf.Meta;
|
||||
using System;
|
||||
using System.IO;
|
||||
#if !NO_GENERICS
|
||||
using System.Collections.Generic;
|
||||
#endif
|
||||
|
||||
#if FEAT_IKVM
|
||||
using Type = IKVM.Reflection.Type;
|
||||
using IKVM.Reflection;
|
||||
#else
|
||||
using System.Reflection;
|
||||
|
||||
#endif
|
||||
|
||||
namespace ProtoBuf
|
||||
|
@ -25,11 +24,11 @@ namespace ProtoBuf
|
|||
/// extensible, allowing a type to be deserialized / merged even if some data is
|
||||
/// not recognised.
|
||||
/// </remarks>
|
||||
public
|
||||
public
|
||||
#if FX11
|
||||
sealed
|
||||
#else
|
||||
static
|
||||
static
|
||||
#endif
|
||||
class Serializer
|
||||
{
|
||||
|
@ -44,15 +43,17 @@ namespace ProtoBuf
|
|||
/// <returns>The .proto definition as a string</returns>
|
||||
public static string GetProto<T>()
|
||||
{
|
||||
return RuntimeTypeModel.Default.GetSchema(RuntimeTypeModel.Default.MapType(typeof(T)));
|
||||
return RuntimeTypeModel.Default.GetSchema(RuntimeTypeModel.Default.MapType(typeof (T)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a deep clone of the supplied instance; any sub-items are also cloned.
|
||||
/// </summary>
|
||||
public static T DeepClone<T>(T instance)
|
||||
{
|
||||
return instance == null ? instance : (T)RuntimeTypeModel.Default.DeepClone(instance);
|
||||
return instance == null ? instance : (T) RuntimeTypeModel.Default.DeepClone(instance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies a protocol-buffer stream to an existing instance.
|
||||
/// </summary>
|
||||
|
@ -64,8 +65,9 @@ namespace ProtoBuf
|
|||
/// original instance.</returns>
|
||||
public static T Merge<T>(Stream source, T instance)
|
||||
{
|
||||
return (T)RuntimeTypeModel.Default.Deserialize(source, instance, typeof(T));
|
||||
return (T) RuntimeTypeModel.Default.Deserialize(source, instance, typeof (T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance from a protocol-buffer stream
|
||||
/// </summary>
|
||||
|
@ -74,8 +76,9 @@ namespace ProtoBuf
|
|||
/// <returns>A new, initialized instance.</returns>
|
||||
public static T Deserialize<T>(Stream source)
|
||||
{
|
||||
return (T) RuntimeTypeModel.Default.Deserialize(source, null, typeof(T));
|
||||
return (T) RuntimeTypeModel.Default.Deserialize(source, null, typeof (T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a protocol-buffer representation of the given instance to the supplied stream.
|
||||
/// </summary>
|
||||
|
@ -83,10 +86,12 @@ namespace ProtoBuf
|
|||
/// <param name="destination">The destination stream to write to.</param>
|
||||
public static void Serialize<T>(Stream destination, T instance)
|
||||
{
|
||||
if(instance != null) {
|
||||
if (instance != null)
|
||||
{
|
||||
RuntimeTypeModel.Default.Serialize(destination, instance);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes a given instance and deserializes it as a different type;
|
||||
/// this can be used to translate between wire-compatible objects (where
|
||||
|
@ -98,7 +103,7 @@ namespace ProtoBuf
|
|||
/// <typeparam name="TTo">The type of the new object to be created.</typeparam>
|
||||
/// <param name="instance">The existing instance to use as a template.</param>
|
||||
/// <returns>A new instane of type TNewType, with the data from TOldType.</returns>
|
||||
public static TTo ChangeType<TFrom,TTo>(TFrom instance)
|
||||
public static TTo ChangeType<TFrom, TTo>(TFrom instance)
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
|
@ -107,13 +112,14 @@ namespace ProtoBuf
|
|||
return Deserialize<TTo>(ms);
|
||||
}
|
||||
}
|
||||
|
||||
#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8)
|
||||
/// <summary>
|
||||
/// Writes a protocol-buffer representation of the given instance to the supplied SerializationInfo.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type being serialized.</typeparam>
|
||||
/// <param name="instance">The existing instance to be serialized (cannot be null).</param>
|
||||
/// <param name="info">The destination SerializationInfo to write to.</param>
|
||||
/// <summary>
|
||||
/// Writes a protocol-buffer representation of the given instance to the supplied SerializationInfo.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type being serialized.</typeparam>
|
||||
/// <param name="instance">The existing instance to be serialized (cannot be null).</param>
|
||||
/// <param name="info">The destination SerializationInfo to write to.</param>
|
||||
public static void Serialize<T>(System.Runtime.Serialization.SerializationInfo info, T instance) where T : class, System.Runtime.Serialization.ISerializable
|
||||
{
|
||||
Serialize<T>(info, new System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.Persistence), instance);
|
||||
|
@ -139,12 +145,12 @@ namespace ProtoBuf
|
|||
}
|
||||
#endif
|
||||
#if PLAT_XMLSERIALIZER
|
||||
/// <summary>
|
||||
/// Writes a protocol-buffer representation of the given instance to the supplied XmlWriter.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type being serialized.</typeparam>
|
||||
/// <param name="instance">The existing instance to be serialized (cannot be null).</param>
|
||||
/// <param name="writer">The destination XmlWriter to write to.</param>
|
||||
/// <summary>
|
||||
/// Writes a protocol-buffer representation of the given instance to the supplied XmlWriter.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type being serialized.</typeparam>
|
||||
/// <param name="instance">The existing instance to be serialized (cannot be null).</param>
|
||||
/// <param name="writer">The destination XmlWriter to write to.</param>
|
||||
public static void Serialize<T>(System.Xml.XmlWriter writer, T instance) where T : System.Xml.Serialization.IXmlSerializable
|
||||
{
|
||||
if (writer == null) throw new ArgumentNullException("writer");
|
||||
|
@ -192,12 +198,12 @@ namespace ProtoBuf
|
|||
|
||||
private const string ProtoBinaryField = "proto";
|
||||
#if PLAT_BINARYFORMATTER && !NO_GENERICS && !(WINRT || PHONE8)
|
||||
/// <summary>
|
||||
/// Applies a protocol-buffer from a SerializationInfo to an existing instance.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type being merged.</typeparam>
|
||||
/// <param name="instance">The existing instance to be modified (cannot be null).</param>
|
||||
/// <param name="info">The SerializationInfo containing the data to apply to the instance (cannot be null).</param>
|
||||
/// <summary>
|
||||
/// Applies a protocol-buffer from a SerializationInfo to an existing instance.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type being merged.</typeparam>
|
||||
/// <param name="instance">The existing instance to be modified (cannot be null).</param>
|
||||
/// <param name="info">The SerializationInfo containing the data to apply to the instance (cannot be null).</param>
|
||||
public static void Merge<T>(System.Runtime.Serialization.SerializationInfo info, T instance) where T : class, System.Runtime.Serialization.ISerializable
|
||||
{
|
||||
Merge<T>(info, new System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.Persistence), instance);
|
||||
|
@ -233,7 +239,7 @@ namespace ProtoBuf
|
|||
/// Precompiles the serializer for a given type.
|
||||
/// </summary>
|
||||
public static void PrepareSerializer<T>()
|
||||
{
|
||||
{
|
||||
#if FEAT_COMPILER
|
||||
RuntimeTypeModel model = RuntimeTypeModel.Default;
|
||||
model[model.MapType(typeof(T))].CompileInPlace();
|
||||
|
@ -241,11 +247,11 @@ namespace ProtoBuf
|
|||
}
|
||||
|
||||
#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8)
|
||||
/// <summary>
|
||||
/// Creates a new IFormatter that uses protocol-buffer [de]serialization.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of object to be [de]deserialized by the formatter.</typeparam>
|
||||
/// <returns>A new IFormatter to be used during [de]serialization.</returns>
|
||||
/// <summary>
|
||||
/// Creates a new IFormatter that uses protocol-buffer [de]serialization.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of object to be [de]deserialized by the formatter.</typeparam>
|
||||
/// <returns>A new IFormatter to be used during [de]serialization.</returns>
|
||||
public static System.Runtime.Serialization.IFormatter CreateFormatter<T>()
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
|
@ -255,6 +261,7 @@ namespace ProtoBuf
|
|||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Reads a sequence of consecutive length-prefixed items from a stream, using
|
||||
/// either base-128 or fixed-length prefixes. Base-128 prefixes with a tag
|
||||
|
@ -300,7 +307,7 @@ namespace ProtoBuf
|
|||
public static T DeserializeWithLengthPrefix<T>(Stream source, PrefixStyle style, int fieldNumber)
|
||||
{
|
||||
RuntimeTypeModel model = RuntimeTypeModel.Default;
|
||||
return (T)model.DeserializeWithLengthPrefix(source, null, model.MapType(typeof(T)), style, fieldNumber);
|
||||
return (T) model.DeserializeWithLengthPrefix(source, null, model.MapType(typeof (T)), style, fieldNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -317,7 +324,7 @@ namespace ProtoBuf
|
|||
public static T MergeWithLengthPrefix<T>(Stream source, T instance, PrefixStyle style)
|
||||
{
|
||||
RuntimeTypeModel model = RuntimeTypeModel.Default;
|
||||
return (T)model.DeserializeWithLengthPrefix(source, instance, model.MapType(typeof(T)), style, 0);
|
||||
return (T) model.DeserializeWithLengthPrefix(source, instance, model.MapType(typeof (T)), style, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -346,12 +353,14 @@ namespace ProtoBuf
|
|||
/// <param name="style">How to encode the length prefix.</param>
|
||||
/// <param name="destination">The destination stream to write to.</param>
|
||||
/// <param name="fieldNumber">The tag used as a prefix to each record (only used with base-128 style prefixes).</param>
|
||||
public static void SerializeWithLengthPrefix<T>(Stream destination, T instance, PrefixStyle style, int fieldNumber)
|
||||
public static void SerializeWithLengthPrefix<T>(Stream destination, T instance, PrefixStyle style,
|
||||
int fieldNumber)
|
||||
{
|
||||
RuntimeTypeModel model = RuntimeTypeModel.Default;
|
||||
model.SerializeWithLengthPrefix(destination, instance, model.MapType(typeof(T)), style, fieldNumber);
|
||||
model.SerializeWithLengthPrefix(destination, instance, model.MapType(typeof (T)), style, fieldNumber);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>Indicates the number of bytes expected for the next message.</summary>
|
||||
/// <param name="source">The stream containing the data to investigate for a length.</param>
|
||||
/// <param name="style">The algorithm used to encode the length.</param>
|
||||
|
@ -379,6 +388,7 @@ namespace ProtoBuf
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// The field number that is used as a default when serializing/deserializing a list of objects.
|
||||
/// The data is treated as repeated message with field number 1.
|
||||
|
@ -386,7 +396,6 @@ namespace ProtoBuf
|
|||
public const int ListItemTag = 1;
|
||||
|
||||
|
||||
|
||||
#if !NO_RUNTIME
|
||||
/// <summary>
|
||||
/// Provides non-generic access to the default serializer.
|
||||
|
@ -395,13 +404,14 @@ namespace ProtoBuf
|
|||
#if FX11
|
||||
sealed
|
||||
#else
|
||||
static
|
||||
static
|
||||
#endif
|
||||
class NonGeneric
|
||||
{
|
||||
#if FX11
|
||||
private NonGeneric() { } // not a static class for C# 1.2 reasons
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Create a deep clone of the supplied instance; any sub-items are also cloned.
|
||||
/// </summary>
|
||||
|
@ -454,12 +464,15 @@ namespace ProtoBuf
|
|||
/// <param name="style">How to encode the length prefix.</param>
|
||||
/// <param name="destination">The destination stream to write to.</param>
|
||||
/// <param name="fieldNumber">The tag used as a prefix to each record (only used with base-128 style prefixes).</param>
|
||||
public static void SerializeWithLengthPrefix(Stream destination, object instance, PrefixStyle style, int fieldNumber)
|
||||
public static void SerializeWithLengthPrefix(Stream destination, object instance, PrefixStyle style,
|
||||
int fieldNumber)
|
||||
{
|
||||
if (instance == null) throw new ArgumentNullException("instance");
|
||||
RuntimeTypeModel model = RuntimeTypeModel.Default;
|
||||
model.SerializeWithLengthPrefix(destination, instance, model.MapType(instance.GetType()), style, fieldNumber);
|
||||
RuntimeTypeModel model = RuntimeTypeModel.Default;
|
||||
model.SerializeWithLengthPrefix(destination, instance, model.MapType(instance.GetType()), style,
|
||||
fieldNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed
|
||||
/// data - useful with network IO.
|
||||
|
@ -471,11 +484,13 @@ namespace ProtoBuf
|
|||
/// <returns>The updated instance; this may be different to the instance argument if
|
||||
/// either the original instance was null, or the stream defines a known sub-type of the
|
||||
/// original instance.</returns>
|
||||
public static bool TryDeserializeWithLengthPrefix(Stream source, PrefixStyle style, TypeResolver resolver, out object value)
|
||||
public static bool TryDeserializeWithLengthPrefix(Stream source, PrefixStyle style, TypeResolver resolver,
|
||||
out object value)
|
||||
{
|
||||
value = RuntimeTypeModel.Default.DeserializeWithLengthPrefix(source, null, null, style, 0, resolver);
|
||||
return value != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the supplied type is explicitly modelled by the model
|
||||
/// </summary>
|
||||
|
@ -483,7 +498,6 @@ namespace ProtoBuf
|
|||
{
|
||||
return RuntimeTypeModel.Default.IsDefined(type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -494,17 +508,19 @@ namespace ProtoBuf
|
|||
#if FX11
|
||||
sealed
|
||||
#else
|
||||
static
|
||||
static
|
||||
#endif
|
||||
class GlobalOptions
|
||||
{
|
||||
#if FX11
|
||||
private GlobalOptions() { } // not a static class for C# 1.2 reasons
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="RuntimeTypeModel.InferTagFromNameDefault"/>
|
||||
/// </summary>
|
||||
[Obsolete("Please use RuntimeTypeModel.Default.InferTagFromNameDefault instead (or on a per-model basis)", false)]
|
||||
[Obsolete("Please use RuntimeTypeModel.Default.InferTagFromNameDefault instead (or on a per-model basis)",
|
||||
false)]
|
||||
public static bool InferTagFromName
|
||||
{
|
||||
get { return RuntimeTypeModel.Default.InferTagFromNameDefault; }
|
||||
|
@ -512,6 +528,7 @@ namespace ProtoBuf
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Maps a field-number to a type
|
||||
/// </summary>
|
||||
|
@ -527,4 +544,4 @@ namespace ProtoBuf
|
|||
BufferPool.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,31 +2,35 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using ProtoBuf.Meta;
|
||||
|
||||
#if FEAT_IKVM
|
||||
using Type = IKVM.Reflection.Type;
|
||||
using IKVM.Reflection;
|
||||
#else
|
||||
using System.Reflection;
|
||||
|
||||
#endif
|
||||
|
||||
namespace ProtoBuf.Serializers
|
||||
{
|
||||
sealed class ArrayDecorator : ProtoDecoratorBase
|
||||
internal sealed class ArrayDecorator : ProtoDecoratorBase
|
||||
{
|
||||
|
||||
private readonly int fieldNumber;
|
||||
|
||||
private const byte
|
||||
OPTIONS_WritePacked = 1,
|
||||
OPTIONS_OverwriteList = 2,
|
||||
OPTIONS_SupportNull = 4;
|
||||
OPTIONS_WritePacked = 1,
|
||||
OPTIONS_OverwriteList = 2,
|
||||
OPTIONS_SupportNull = 4;
|
||||
|
||||
private readonly byte options;
|
||||
private readonly WireType packedWireType;
|
||||
public ArrayDecorator(TypeModel model, IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, Type arrayType, bool overwriteList, bool supportNull)
|
||||
|
||||
public ArrayDecorator(TypeModel model, IProtoSerializer tail, int fieldNumber, bool writePacked,
|
||||
WireType packedWireType, Type arrayType, bool overwriteList, bool supportNull)
|
||||
: base(tail)
|
||||
{
|
||||
Helpers.DebugAssert(arrayType != null, "arrayType should be non-null");
|
||||
Helpers.DebugAssert(arrayType.IsArray && arrayType.GetArrayRank() == 1, "should be single-dimension array; " + arrayType.FullName);
|
||||
Helpers.DebugAssert(arrayType.IsArray && arrayType.GetArrayRank() == 1,
|
||||
"should be single-dimension array; " + arrayType.FullName);
|
||||
this.itemType = arrayType.GetElementType();
|
||||
#if NO_GENERICS
|
||||
Type underlyingItemType = itemType;
|
||||
|
@ -35,13 +39,14 @@ namespace ProtoBuf.Serializers
|
|||
#endif
|
||||
|
||||
Helpers.DebugAssert(underlyingItemType == Tail.ExpectedType, "invalid tail");
|
||||
Helpers.DebugAssert(Tail.ExpectedType != model.MapType(typeof(byte)), "Should have used BlobSerializer");
|
||||
if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) throw new ArgumentOutOfRangeException("fieldNumber");
|
||||
Helpers.DebugAssert(Tail.ExpectedType != model.MapType(typeof (byte)), "Should have used BlobSerializer");
|
||||
if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0)
|
||||
throw new ArgumentOutOfRangeException("fieldNumber");
|
||||
if (!ListDecorator.CanPack(packedWireType))
|
||||
{
|
||||
if (writePacked) throw new InvalidOperationException("Only simple data-types can use packed encoding");
|
||||
packedWireType = WireType.None;
|
||||
}
|
||||
}
|
||||
this.fieldNumber = fieldNumber;
|
||||
this.packedWireType = packedWireType;
|
||||
if (writePacked) options |= OPTIONS_WritePacked;
|
||||
|
@ -49,10 +54,24 @@ namespace ProtoBuf.Serializers
|
|||
if (supportNull) options |= OPTIONS_SupportNull;
|
||||
this.arrayType = arrayType;
|
||||
}
|
||||
readonly Type arrayType, itemType; // this is, for example, typeof(int[])
|
||||
public override Type ExpectedType { get { return arrayType; } }
|
||||
public override bool RequiresOldValue { get { return AppendToCollection; } }
|
||||
public override bool ReturnsValue { get { return true; } }
|
||||
|
||||
private readonly Type arrayType, itemType; // this is, for example, typeof(int[])
|
||||
|
||||
public override Type ExpectedType
|
||||
{
|
||||
get { return arrayType; }
|
||||
}
|
||||
|
||||
public override bool RequiresOldValue
|
||||
{
|
||||
get { return AppendToCollection; }
|
||||
}
|
||||
|
||||
public override bool ReturnsValue
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#if FEAT_COMPILER
|
||||
protected override void EmitWrite(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom)
|
||||
{
|
||||
|
@ -127,16 +146,21 @@ namespace ProtoBuf.Serializers
|
|||
ctx.BranchIfLess(processItem, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
private bool AppendToCollection
|
||||
{
|
||||
get { return (options & OPTIONS_OverwriteList) == 0; }
|
||||
}
|
||||
private bool SupportNull { get { return (options & OPTIONS_SupportNull) != 0; } }
|
||||
|
||||
private bool SupportNull
|
||||
{
|
||||
get { return (options & OPTIONS_SupportNull) != 0; }
|
||||
}
|
||||
|
||||
#if !FEAT_IKVM
|
||||
public override void Write(object value, ProtoWriter dest)
|
||||
{
|
||||
IList arr = (IList)value;
|
||||
IList arr = (IList) value;
|
||||
int len = arr.Count;
|
||||
SubItemToken token;
|
||||
bool writePacked = (options & OPTIONS_WritePacked) != 0;
|
||||
|
@ -154,14 +178,18 @@ namespace ProtoBuf.Serializers
|
|||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
object obj = arr[i];
|
||||
if (checkForNull && obj == null) { throw new NullReferenceException(); }
|
||||
if (checkForNull && obj == null)
|
||||
{
|
||||
throw new NullReferenceException();
|
||||
}
|
||||
Tail.Write(obj, dest);
|
||||
}
|
||||
if (writePacked)
|
||||
{
|
||||
ProtoWriter.EndSubItem(token, dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override object Read(object value, ProtoReader source)
|
||||
{
|
||||
int field = source.FieldNumber;
|
||||
|
@ -176,15 +204,15 @@ namespace ProtoBuf.Serializers
|
|||
ProtoReader.EndSubItem(token, source);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
do
|
||||
{
|
||||
list.Add(Tail.Read(null, source));
|
||||
} while (source.TryReadFieldHeader(field));
|
||||
}
|
||||
int oldLen = AppendToCollection ? ((value == null ? 0 : ((Array)value).Length)) : 0;
|
||||
int oldLen = AppendToCollection ? ((value == null ? 0 : ((Array) value).Length)) : 0;
|
||||
Array result = Array.CreateInstance(itemType, oldLen + list.Count);
|
||||
if (oldLen != 0) ((Array)value).CopyTo(result, 0);
|
||||
if (oldLen != 0) ((Array) value).CopyTo(result, 0);
|
||||
list.CopyTo(result, oldLen);
|
||||
return result;
|
||||
}
|
||||
|
@ -268,4 +296,5 @@ namespace ProtoBuf.Serializers
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,5 +1,6 @@
|
|||
#if !NO_RUNTIME
|
||||
using System;
|
||||
|
||||
#if FEAT_COMPILER
|
||||
using System.Reflection.Emit;
|
||||
#endif
|
||||
|
@ -8,18 +9,21 @@ using System.Reflection.Emit;
|
|||
using Type = IKVM.Reflection.Type;
|
||||
#endif
|
||||
|
||||
|
||||
namespace ProtoBuf.Serializers
|
||||
{
|
||||
sealed class BlobSerializer : IProtoSerializer
|
||||
internal sealed class BlobSerializer : IProtoSerializer
|
||||
{
|
||||
public Type ExpectedType { get { return expectedType; } }
|
||||
public Type ExpectedType
|
||||
{
|
||||
get { return expectedType; }
|
||||
}
|
||||
|
||||
#if FEAT_IKVM
|
||||
readonly Type expectedType;
|
||||
#else
|
||||
static readonly Type expectedType = typeof(byte[]);
|
||||
private static readonly Type expectedType = typeof (byte[]);
|
||||
#endif
|
||||
|
||||
public BlobSerializer(ProtoBuf.Meta.TypeModel model, bool overwriteList)
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
|
@ -27,19 +31,30 @@ namespace ProtoBuf.Serializers
|
|||
#endif
|
||||
this.overwriteList = overwriteList;
|
||||
}
|
||||
|
||||
private readonly bool overwriteList;
|
||||
#if !FEAT_IKVM
|
||||
public object Read(object value, ProtoReader source)
|
||||
{
|
||||
return ProtoReader.AppendBytes(overwriteList ? null : (byte[])value, source);
|
||||
return ProtoReader.AppendBytes(overwriteList ? null : (byte[]) value, source);
|
||||
}
|
||||
|
||||
public void Write(object value, ProtoWriter dest)
|
||||
{
|
||||
ProtoWriter.WriteBytes((byte[])value, dest);
|
||||
ProtoWriter.WriteBytes((byte[]) value, dest);
|
||||
}
|
||||
#endif
|
||||
bool IProtoSerializer.RequiresOldValue { get { return !overwriteList; } }
|
||||
bool IProtoSerializer.ReturnsValue { get { return true; } }
|
||||
|
||||
bool IProtoSerializer.RequiresOldValue
|
||||
{
|
||||
get { return !overwriteList; }
|
||||
}
|
||||
|
||||
bool IProtoSerializer.ReturnsValue
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#if FEAT_COMPILER
|
||||
void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
|
||||
{
|
||||
|
@ -61,4 +76,5 @@ namespace ProtoBuf.Serializers
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,47 +1,58 @@
|
|||
#if !NO_RUNTIME
|
||||
using System;
|
||||
|
||||
#if FEAT_IKVM
|
||||
using Type = IKVM.Reflection.Type;
|
||||
using IKVM.Reflection;
|
||||
#else
|
||||
using System.Reflection;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace ProtoBuf.Serializers
|
||||
{
|
||||
sealed class BooleanSerializer : IProtoSerializer
|
||||
internal sealed class BooleanSerializer : IProtoSerializer
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
readonly Type expectedType;
|
||||
#else
|
||||
static readonly Type expectedType = typeof(bool);
|
||||
private static readonly Type expectedType = typeof (bool);
|
||||
#endif
|
||||
|
||||
public BooleanSerializer(ProtoBuf.Meta.TypeModel model)
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
expectedType = model.MapType(typeof(bool));
|
||||
#endif
|
||||
}
|
||||
public Type ExpectedType { get { return expectedType; } }
|
||||
|
||||
public Type ExpectedType
|
||||
{
|
||||
get { return expectedType; }
|
||||
}
|
||||
|
||||
#if !FEAT_IKVM
|
||||
public void Write(object value, ProtoWriter dest)
|
||||
{
|
||||
ProtoWriter.WriteBoolean((bool)value, dest);
|
||||
ProtoWriter.WriteBoolean((bool) value, dest);
|
||||
}
|
||||
|
||||
public object Read(object value, ProtoReader source)
|
||||
{
|
||||
Helpers.DebugAssert(value == null); // since replaces
|
||||
return source.ReadBoolean();
|
||||
}
|
||||
#endif
|
||||
bool IProtoSerializer.RequiresOldValue { get { return false; } }
|
||||
bool IProtoSerializer.ReturnsValue { get { return true; } }
|
||||
|
||||
bool IProtoSerializer.RequiresOldValue
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
bool IProtoSerializer.ReturnsValue
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#if FEAT_COMPILER
|
||||
void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
|
||||
{
|
||||
|
@ -54,4 +65,5 @@ namespace ProtoBuf.Serializers
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -5,32 +5,44 @@ using System;
|
|||
using Type = IKVM.Reflection.Type;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace ProtoBuf.Serializers
|
||||
{
|
||||
sealed class ByteSerializer : IProtoSerializer
|
||||
internal sealed class ByteSerializer : IProtoSerializer
|
||||
{
|
||||
public Type ExpectedType { get { return expectedType; } }
|
||||
public Type ExpectedType
|
||||
{
|
||||
get { return expectedType; }
|
||||
}
|
||||
|
||||
#if FEAT_IKVM
|
||||
readonly Type expectedType;
|
||||
#else
|
||||
static readonly Type expectedType = typeof(byte);
|
||||
private static readonly Type expectedType = typeof (byte);
|
||||
#endif
|
||||
|
||||
public ByteSerializer(ProtoBuf.Meta.TypeModel model)
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
expectedType = model.MapType(typeof(byte));
|
||||
#endif
|
||||
}
|
||||
bool IProtoSerializer.RequiresOldValue { get { return false; } }
|
||||
bool IProtoSerializer.ReturnsValue { get { return true; } }
|
||||
|
||||
bool IProtoSerializer.RequiresOldValue
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
bool IProtoSerializer.ReturnsValue
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#if !FEAT_IKVM
|
||||
public void Write(object value, ProtoWriter dest)
|
||||
{
|
||||
ProtoWriter.WriteByte((byte)value, dest);
|
||||
ProtoWriter.WriteByte((byte) value, dest);
|
||||
}
|
||||
|
||||
public object Read(object value, ProtoReader source)
|
||||
{
|
||||
Helpers.DebugAssert(value == null); // since replaces
|
||||
|
@ -48,7 +60,7 @@ namespace ProtoBuf.Serializers
|
|||
ctx.EmitBasicRead("ReadByte", ExpectedType);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,44 +1,50 @@
|
|||
#if !NO_RUNTIME
|
||||
using System;
|
||||
|
||||
#if FEAT_IKVM
|
||||
using Type = IKVM.Reflection.Type;
|
||||
using IKVM.Reflection;
|
||||
#else
|
||||
using System.Reflection;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace ProtoBuf.Serializers
|
||||
{
|
||||
sealed class CharSerializer : UInt16Serializer
|
||||
internal sealed class CharSerializer : UInt16Serializer
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
readonly Type expectedType;
|
||||
#else
|
||||
static readonly Type expectedType = typeof(char);
|
||||
private static readonly Type expectedType = typeof (char);
|
||||
#endif
|
||||
|
||||
public CharSerializer(ProtoBuf.Meta.TypeModel model) : base(model)
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
expectedType = model.MapType(typeof(char));
|
||||
#endif
|
||||
}
|
||||
public override Type ExpectedType { get { return expectedType; } }
|
||||
|
||||
public override Type ExpectedType
|
||||
{
|
||||
get { return expectedType; }
|
||||
}
|
||||
|
||||
#if !FEAT_IKVM
|
||||
public override void Write(object value, ProtoWriter dest)
|
||||
{
|
||||
ProtoWriter.WriteUInt16((ushort)(char)value, dest);
|
||||
ProtoWriter.WriteUInt16((ushort) (char) value, dest);
|
||||
}
|
||||
|
||||
public override object Read(object value, ProtoReader source)
|
||||
{
|
||||
Helpers.DebugAssert(value == null); // since replaces
|
||||
return (char)source.ReadUInt16();
|
||||
return (char) source.ReadUInt16();
|
||||
}
|
||||
#endif
|
||||
// no need for any special IL here; ushort and char are
|
||||
// interchangeable as long as there is no boxing/unboxing
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,4 +1,5 @@
|
|||
#if FEAT_COMPILER && !(FX11 || FEAT_IKVM)
|
||||
|
||||
#if FEAT_COMPILER && !(FX11 || FEAT_IKVM)
|
||||
using System;
|
||||
using ProtoBuf.Meta;
|
||||
|
||||
|
|
|
@ -1,26 +1,37 @@
|
|||
#if !NO_RUNTIME
|
||||
using System;
|
||||
|
||||
#if FEAT_IKVM
|
||||
using Type = IKVM.Reflection.Type;
|
||||
using IKVM.Reflection;
|
||||
#else
|
||||
using System.Reflection;
|
||||
|
||||
#endif
|
||||
|
||||
namespace ProtoBuf.Serializers
|
||||
{
|
||||
sealed class DateTimeSerializer : IProtoSerializer
|
||||
internal sealed class DateTimeSerializer : IProtoSerializer
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
readonly Type expectedType;
|
||||
#else
|
||||
static readonly Type expectedType = typeof(DateTime);
|
||||
private static readonly Type expectedType = typeof (DateTime);
|
||||
#endif
|
||||
public Type ExpectedType { get { return expectedType; } }
|
||||
|
||||
bool IProtoSerializer.RequiresOldValue { get { return false; } }
|
||||
bool IProtoSerializer.ReturnsValue { get { return true; } }
|
||||
public Type ExpectedType
|
||||
{
|
||||
get { return expectedType; }
|
||||
}
|
||||
|
||||
bool IProtoSerializer.RequiresOldValue
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
bool IProtoSerializer.ReturnsValue
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public DateTimeSerializer(ProtoBuf.Meta.TypeModel model)
|
||||
{
|
||||
|
@ -28,15 +39,17 @@ namespace ProtoBuf.Serializers
|
|||
expectedType = model.MapType(typeof(DateTime));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !FEAT_IKVM
|
||||
public object Read(object value, ProtoReader source)
|
||||
{
|
||||
Helpers.DebugAssert(value == null); // since replaces
|
||||
return BclHelpers.ReadDateTime(source);
|
||||
}
|
||||
|
||||
public void Write(object value, ProtoWriter dest)
|
||||
{
|
||||
BclHelpers.WriteDateTime((DateTime)value, dest);
|
||||
BclHelpers.WriteDateTime((DateTime) value, dest);
|
||||
}
|
||||
#endif
|
||||
#if FEAT_COMPILER
|
||||
|
@ -49,7 +62,7 @@ namespace ProtoBuf.Serializers
|
|||
ctx.EmitBasicRead(ctx.MapType(typeof(BclHelpers)), "ReadDateTime", ExpectedType);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,44 +1,56 @@
|
|||
#if !NO_RUNTIME
|
||||
using System;
|
||||
using ProtoBuf.Meta;
|
||||
|
||||
#if FEAT_IKVM
|
||||
using Type = IKVM.Reflection.Type;
|
||||
using IKVM.Reflection;
|
||||
#else
|
||||
using System.Reflection;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace ProtoBuf.Serializers
|
||||
{
|
||||
sealed class DecimalSerializer : IProtoSerializer
|
||||
internal sealed class DecimalSerializer : IProtoSerializer
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
#if FEAT_IKVM
|
||||
readonly Type expectedType;
|
||||
#else
|
||||
static readonly Type expectedType = typeof(decimal);
|
||||
private static readonly Type expectedType = typeof (decimal);
|
||||
#endif
|
||||
|
||||
public DecimalSerializer(ProtoBuf.Meta.TypeModel model)
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
expectedType = model.MapType(typeof(decimal));
|
||||
#endif
|
||||
}
|
||||
public Type ExpectedType { get { return expectedType; } }
|
||||
|
||||
bool IProtoSerializer.RequiresOldValue { get { return false; } }
|
||||
bool IProtoSerializer.ReturnsValue { get { return true; } }
|
||||
public Type ExpectedType
|
||||
{
|
||||
get { return expectedType; }
|
||||
}
|
||||
|
||||
bool IProtoSerializer.RequiresOldValue
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
bool IProtoSerializer.ReturnsValue
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#if !FEAT_IKVM
|
||||
public object Read(object value, ProtoReader source)
|
||||
{
|
||||
Helpers.DebugAssert(value == null); // since replaces
|
||||
return BclHelpers.ReadDecimal(source);
|
||||
}
|
||||
|
||||
public void Write(object value, ProtoWriter dest)
|
||||
{
|
||||
BclHelpers.WriteDecimal((decimal)value, dest);
|
||||
BclHelpers.WriteDecimal((decimal) value, dest);
|
||||
}
|
||||
#endif
|
||||
#if FEAT_COMPILER
|
||||
|
@ -51,7 +63,7 @@ namespace ProtoBuf.Serializers
|
|||
ctx.EmitBasicRead(ctx.MapType(typeof(BclHelpers)), "ReadDecimal", ExpectedType);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -6,18 +6,30 @@ using Type = IKVM.Reflection.Type;
|
|||
using IKVM.Reflection;
|
||||
#else
|
||||
using System.Reflection;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace ProtoBuf.Serializers
|
||||
{
|
||||
sealed class DefaultValueDecorator : ProtoDecoratorBase
|
||||
internal sealed class DefaultValueDecorator : ProtoDecoratorBase
|
||||
{
|
||||
public override Type ExpectedType
|
||||
{
|
||||
get { return Tail.ExpectedType; }
|
||||
}
|
||||
|
||||
public override bool RequiresOldValue
|
||||
{
|
||||
get { return Tail.RequiresOldValue; }
|
||||
}
|
||||
|
||||
public override bool ReturnsValue
|
||||
{
|
||||
get { return Tail.ReturnsValue; }
|
||||
}
|
||||
|
||||
public override Type ExpectedType { get { return Tail.ExpectedType; } }
|
||||
public override bool RequiresOldValue { get { return Tail.RequiresOldValue; } }
|
||||
public override bool ReturnsValue { get { return Tail.ReturnsValue; } }
|
||||
private readonly object defaultValue;
|
||||
|
||||
public DefaultValueDecorator(TypeModel model, object defaultValue, IProtoSerializer tail) : base(tail)
|
||||
{
|
||||
if (defaultValue == null) throw new ArgumentNullException("defaultValue");
|
||||
|
@ -32,6 +44,7 @@ namespace ProtoBuf.Serializers
|
|||
}
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
#if !FEAT_IKVM
|
||||
public override void Write(object value, ProtoWriter dest)
|
||||
{
|
||||
|
@ -40,6 +53,7 @@ namespace ProtoBuf.Serializers
|
|||
Tail.Write(value, dest);
|
||||
}
|
||||
}
|
||||
|
||||
public override object Read(object value, ProtoReader source)
|
||||
{
|
||||
return Tail.Read(value, source);
|
||||
|
@ -263,4 +277,5 @@ namespace ProtoBuf.Serializers
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,23 +1,24 @@
|
|||
#if !NO_RUNTIME
|
||||
using System;
|
||||
using ProtoBuf.Meta;
|
||||
|
||||
#if FEAT_IKVM
|
||||
using Type = IKVM.Reflection.Type;
|
||||
using IKVM.Reflection;
|
||||
#else
|
||||
using System.Reflection;
|
||||
|
||||
#endif
|
||||
|
||||
namespace ProtoBuf.Serializers
|
||||
{
|
||||
sealed class DoubleSerializer : IProtoSerializer
|
||||
internal sealed class DoubleSerializer : IProtoSerializer
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
readonly Type expectedType;
|
||||
#else
|
||||
static readonly Type expectedType = typeof(double);
|
||||
private static readonly Type expectedType = typeof (double);
|
||||
#endif
|
||||
|
||||
public DoubleSerializer(ProtoBuf.Meta.TypeModel model)
|
||||
{
|
||||
#if FEAT_IKVM
|
||||
|
@ -25,18 +26,31 @@ namespace ProtoBuf.Serializers
|
|||
#endif
|
||||
}
|
||||
|
||||
public Type ExpectedType { get { return expectedType; } }
|
||||
bool IProtoSerializer.RequiresOldValue { get { return false; } }
|
||||
bool IProtoSerializer.ReturnsValue { get { return true; } }
|
||||
public Type ExpectedType
|
||||
{
|
||||
get { return expectedType; }
|
||||
}
|
||||
|
||||
bool IProtoSerializer.RequiresOldValue
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
bool IProtoSerializer.ReturnsValue
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#if !FEAT_IKVM
|
||||
public object Read(object value, ProtoReader source)
|
||||
{
|
||||
Helpers.DebugAssert(value == null); // since replaces
|
||||
return source.ReadDouble();
|
||||
}
|
||||
|
||||
public void Write(object value, ProtoWriter dest)
|
||||
{
|
||||
ProtoWriter.WriteDouble((double)value, dest);
|
||||
ProtoWriter.WriteDouble((double) value, dest);
|
||||
}
|
||||
#endif
|
||||
#if FEAT_COMPILER
|
||||
|
@ -51,4 +65,5 @@ namespace ProtoBuf.Serializers
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue