diff --git a/src/KeePassLib2Android/KeePassLib2Android.csproj b/src/KeePassLib2Android/KeePassLib2Android.csproj
index d925d883..712720e4 100644
--- a/src/KeePassLib2Android/KeePassLib2Android.csproj
+++ b/src/KeePassLib2Android/KeePassLib2Android.csproj
@@ -47,6 +47,9 @@
SdkOnly
+
+ ..\ProtoBuf\protobuf-net.dll
+
@@ -126,6 +129,7 @@
+
diff --git a/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs b/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs
index 03456962..4eff0c4a 100644
--- a/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs
+++ b/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs
@@ -127,8 +127,34 @@ namespace KeePassLib.Serialization
}
else m_randomStream = null; // No random stream for plain-text files
- ReadXmlStreamed(readerStream, hashedStream);
- // ReadXmlDom(readerStream);
+ // Test: read to memory
+ var stopWatch = Stopwatch.StartNew();
+ var memStream = new MemoryStream((int)hashedStream.Length);
+ CopyStream(readerStream, memStream);
+ readerStream.Close();
+ readerStream = memStream;
+ System.Diagnostics.Debug.WriteLine(String.Format("Copy input stream: {0}ms", stopWatch.ElapsedMilliseconds));
+
+ var isXml = memStream.ReadByte() == '<';
+ memStream.Seek(0, SeekOrigin.Begin);
+
+ if (isXml)
+ {
+ stopWatch.Restart();
+
+ ReadXmlStreamed(readerStream, hashedStream);
+ System.Diagnostics.Debug.WriteLine(String.Format("ReadXmlStreamed: {0}ms", stopWatch.ElapsedMilliseconds));
+
+ }
+ else
+ {
+ stopWatch.Restart();
+
+ KdbpFile.ReadDocument(m_pwDatabase, readerStream, m_pbProtectedStreamKey, m_pbHashOfHeader);
+
+ System.Diagnostics.Debug.WriteLine(String.Format("KdbpFile.ReadDocument: {0}ms", stopWatch.ElapsedMilliseconds));
+
+ }
readerStream.Close();
// GC.KeepAlive(br);
@@ -141,6 +167,17 @@ namespace KeePassLib.Serialization
finally { CommonCleanUpRead(sSource, hashedStream); }
}
+ public static void CopyStream(Stream input, Stream output)
+ {
+ byte[] buffer = new byte[4096];
+ int read;
+ while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ output.Write(buffer, 0, read);
+ }
+ output.Seek(0, SeekOrigin.Begin);
+ }
+
private void CommonCleanUpRead(Stream sSource, HashingStreamEx hashedStream)
{
hashedStream.Close();
diff --git a/src/KeePassLib2Android/Serialization/KdbxFile.Write.cs b/src/KeePassLib2Android/Serialization/KdbxFile.Write.cs
index 802feaf0..fbc31e6c 100644
--- a/src/KeePassLib2Android/Serialization/KdbxFile.Write.cs
+++ b/src/KeePassLib2Android/Serialization/KdbxFile.Write.cs
@@ -122,11 +122,16 @@ namespace KeePassLib.Serialization
writerStream = hashedStream;
else { Debug.Assert(false); throw new FormatException("KdbFormat"); }
+ /*
m_xmlWriter = new XmlTextWriter(writerStream, encNoBom);
WriteDocument(pgDataSource);
m_xmlWriter.Flush();
m_xmlWriter.Close();
+ */
+
+ KdbpFile.WriteDocument(m_pwDatabase, writerStream, m_pbProtectedStreamKey, m_pbHashOfHeader);
+
writerStream.Close();
}
finally { CommonCleanUpWrite(sSaveTo, hashedStream); }
diff --git a/src/KeePassLib2Android/Serialization/ProtoBuf/KdbpFile.cs b/src/KeePassLib2Android/Serialization/ProtoBuf/KdbpFile.cs
new file mode 100644
index 00000000..326d391b
--- /dev/null
+++ b/src/KeePassLib2Android/Serialization/ProtoBuf/KdbpFile.cs
@@ -0,0 +1,1425 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ProtoBuf;
+using System.Drawing;
+using KeePassLib.Collections;
+using KeePassLib.Security;
+using KeePassLib.Cryptography;
+using System.IO;
+using ProtoBuf.Meta;
+
+namespace KeePassLib.Serialization
+{
+ internal class KdbpFile
+ {
+ public static void WriteDocument(PwDatabase database, Stream stream, byte[] protectedStreamKey, byte[] hashOfHeader)
+ {
+ var context = new SerializationContext
+ {
+ Context = new BufferContext(database,
+ new CryptoRandomStream(CrsAlgorithm.Salsa20, protectedStreamKey), hashOfHeader)
+ };
+
+ RuntimeTypeModel.Default.Serialize(stream, new PwDatabaseBuffer(database), context);
+ }
+
+ public static void ReadDocument(PwDatabase database, Stream stream, byte[] protectedStreamKey, byte[] expectedHashOfHeader)
+ {
+
+ var context = new BufferContext(database, new CryptoRandomStream(CrsAlgorithm.Salsa20, protectedStreamKey));
+
+ // Deserialisation will occur into the database already in context.
+ RuntimeTypeModel.Default.Deserialize(stream, null, typeof(PwDatabaseBuffer), new SerializationContext { Context = context });
+
+ if (expectedHashOfHeader.Length > 0 &&
+ !KeePassLib.Utility.MemUtil.ArraysEqual(context.HeaderHash, expectedHashOfHeader))
+ {
+ throw new IOException(KeePassLib.Resources.KLRes.FileCorrupted);
+ }
+ }
+
+ private class BufferContext
+ {
+ // ProtectedBinary objects may be referred to multipe times by entry histories, so reference them only once by ensuring a 1:1 mapping to the buffer wrapping them.
+ public readonly Dictionary BinaryPool = new Dictionary();
+
+ public readonly PwDatabase Database;
+ public readonly CryptoRandomStream RandomStream;
+ public byte[] HeaderHash;
+
+ public BufferContext(PwDatabase database, CryptoRandomStream randomStream, byte[] pbHashOfHeader = null)
+ {
+ Database = database;
+ RandomStream = randomStream;
+ HeaderHash = pbHashOfHeader;
+ }
+ }
+
+ [ProtoContract]
+ private class PwDatabaseBuffer
+ {
+ #region Serialization
+
+ private PwDatabase mDatabase;
+ private PwDeletedObjectListBuffer mDeletedObjects;
+ private PwCustomIconListBuffer mCustomIcons;
+
+ public PwDatabaseBuffer(PwDatabase database)
+ {
+ mDatabase = database;
+ mDeletedObjects = new PwDeletedObjectListBuffer(mDatabase.DeletedObjects);
+ mCustomIcons = new PwCustomIconListBuffer(mDatabase.CustomIcons);
+ }
+
+ [ProtoBeforeSerialization]
+ private void BeforeSerialization(SerializationContext context)
+ {
+ var bufferContext = (BufferContext)context.Context;
+
+ System.Diagnostics.Debug.Assert(mDatabase == bufferContext.Database);
+
+ HeaderHash = bufferContext.HeaderHash;
+ }
+ #endregion
+
+ #region Deserialization
+ private PwDatabaseBuffer()
+ {
+ }
+
+ [ProtoBeforeDeserialization]
+ private void BeforeDeserialization(SerializationContext context)
+ {
+ var bufferContext = (BufferContext)context.Context;
+
+ mDatabase = bufferContext.Database;
+ mDeletedObjects = new PwDeletedObjectListBuffer(mDatabase.DeletedObjects);
+ mCustomIcons = new PwCustomIconListBuffer(mDatabase.CustomIcons);
+ }
+
+ [ProtoAfterDeserialization]
+ private void AfterDeserialization(SerializationContext context)
+ {
+ var bufferContext = (BufferContext)context.Context;
+
+ bufferContext.HeaderHash = HeaderHash;
+ }
+ #endregion
+
+ [ProtoMember(1)]
+ public string Generator
+ {
+ get { return PwDatabase.LocalizedAppName; }
+ set { /* Ignore */ }
+ }
+
+ [ProtoMember(2, OverwriteList = true)]
+ public byte[] HeaderHash;
+
+ [ProtoMember(3)]
+ public string Name
+ {
+ get { return mDatabase.Name; }
+ set { mDatabase.Name = value; }
+ }
+
+ [ProtoMember(4)]
+ public DateTime NameChanged
+ {
+ get { return mDatabase.NameChanged; }
+ set { mDatabase.NameChanged = value; }
+ }
+
+ [ProtoMember(5)]
+ public string Description
+ {
+ get { return mDatabase.Description; }
+ set { mDatabase.Description = value; }
+ }
+
+ [ProtoMember(6)]
+ public DateTime DescriptionChanged
+ {
+ get { return mDatabase.DescriptionChanged; }
+ set { mDatabase.DescriptionChanged = value; }
+ }
+
+ [ProtoMember(7)]
+ public string DefaultUserName
+ {
+ get { return mDatabase.DefaultUserName; }
+ set { mDatabase.DefaultUserName = value; }
+ }
+
+ [ProtoMember(8)]
+ public DateTime DefaultUserNameChanged
+ {
+ get { return mDatabase.DefaultUserNameChanged; }
+ set { mDatabase.DefaultUserNameChanged = value; }
+ }
+
+ [ProtoMember(9)]
+ public uint MaintenanceHistoryDays
+ {
+ get { return mDatabase.MaintenanceHistoryDays; }
+ set { mDatabase.MaintenanceHistoryDays = value; }
+ }
+
+ [ProtoMember(10)]
+ public int Color
+ {
+ get { return mDatabase.Color.ToArgb(); }
+ set { mDatabase.Color = System.Drawing.Color.FromArgb(value); }
+ }
+
+ [ProtoMember(11)]
+ public DateTime MasterKeyChanged
+ {
+ get { return mDatabase.MasterKeyChanged; }
+ set { mDatabase.MasterKeyChanged = value; }
+ }
+
+ [ProtoMember(12)]
+ public long MasterKeyChangeRec
+ {
+ get { return mDatabase.MasterKeyChangeRec; }
+ set { mDatabase.MasterKeyChangeRec = value; }
+ }
+
+ [ProtoMember(13)]
+ public long MasterKeyChangeForce
+ {
+ get { return mDatabase.MasterKeyChangeForce; }
+ set { mDatabase.MasterKeyChangeForce = value; }
+ }
+
+ [ProtoMember(14)]
+ public MemoryProtectionConfigBuffer MemoryProtection
+ {
+ get { return new MemoryProtectionConfigBuffer(mDatabase.MemoryProtection); }
+ set { mDatabase.MemoryProtection = value.MemoryProtectionConfig; }
+ }
+
+ [ProtoMember(15)]
+ public PwCustomIconListBuffer CustomIcons
+ {
+ get { return mCustomIcons; }
+ }
+
+ [ProtoMember(16)]
+ public bool RecycleBinEnabled
+ {
+ get { return mDatabase.RecycleBinEnabled; }
+ set { mDatabase.RecycleBinEnabled = value; }
+ }
+
+ [ProtoMember(17, OverwriteList = true)]
+ public byte[] RecycleBinUuid
+ {
+ get { return mDatabase.RecycleBinUuid.UuidBytes; }
+ set { mDatabase.RecycleBinUuid = new PwUuid(value); }
+ }
+
+ [ProtoMember(18)]
+ public DateTime RecycleBinChanged
+ {
+ get { return mDatabase.RecycleBinChanged; }
+ set { mDatabase.RecycleBinChanged = value; }
+ }
+
+ [ProtoMember(19, OverwriteList = true)]
+ public byte[] EntryTemplatesGroup
+ {
+ get { return mDatabase.EntryTemplatesGroup.UuidBytes; }
+ set { mDatabase.EntryTemplatesGroup = new PwUuid(value); }
+ }
+
+ [ProtoMember(20)]
+ public DateTime EntryTemplatesGroupChanged
+ {
+ get { return mDatabase.EntryTemplatesGroupChanged; }
+ set { mDatabase.EntryTemplatesGroupChanged = value; }
+ }
+
+ [ProtoMember(21)]
+ public int HistoryMaxItems
+ {
+ get { return mDatabase.HistoryMaxItems; }
+ set { mDatabase.HistoryMaxItems = value; }
+ }
+
+ [ProtoMember(22)]
+ public long HistoryMaxSize
+ {
+ get { return mDatabase.HistoryMaxSize; }
+ set { mDatabase.HistoryMaxSize = value; }
+ }
+
+ [ProtoMember(23, OverwriteList = true)]
+ public byte[] LastSelectedGroup
+ {
+ get { return mDatabase.LastSelectedGroup.UuidBytes; }
+ set { mDatabase.LastSelectedGroup = new PwUuid(value); }
+ }
+
+ [ProtoMember(24, OverwriteList = true)]
+ public byte[] LastTopVisibleGroup
+ {
+ get { return mDatabase.LastTopVisibleGroup.UuidBytes; }
+ set { mDatabase.LastTopVisibleGroup = new PwUuid(value); }
+ }
+
+ [ProtoMember(25)]
+ public StringDictionaryExBuffer CustomData
+ {
+ get { return new StringDictionaryExBuffer(mDatabase.CustomData); }
+ set { mDatabase.CustomData = value.StringDictionaryEx; }
+ }
+
+ [ProtoMember(27)]
+ public PwGroupBuffer RootGroup
+ {
+ get { return new PwGroupBuffer(mDatabase.RootGroup); }
+ set { mDatabase.RootGroup = value.Group; }
+ }
+
+ [ProtoMember(28)]
+ public PwDeletedObjectListBuffer DeletedObjects
+ {
+ get { return mDeletedObjects; }
+ }
+ }
+
+ [ProtoContract]
+ private class StringDictionaryExBuffer : IEnumerable>
+ {
+ #region Serialization
+ private StringDictionaryEx mStringDictionaryEx;
+
+ public StringDictionaryExBuffer(StringDictionaryEx stringDictionaryEx)
+ {
+ mStringDictionaryEx = stringDictionaryEx;
+ }
+ #endregion
+
+ #region Deserialization
+ private StringDictionaryExBuffer()
+ {
+ mStringDictionaryEx = new StringDictionaryEx();
+ }
+
+ public StringDictionaryEx StringDictionaryEx { get { return mStringDictionaryEx; } }
+
+ public void Add(KeyValuePair kvp)
+ {
+ mStringDictionaryEx.Set(kvp.Key, kvp.Value);
+ }
+ #endregion
+
+ public IEnumerator> GetEnumerator()
+ {
+ return mStringDictionaryEx.GetEnumerator();
+ }
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+ }
+
+ [ProtoContract]
+ private class PwCustomIconListBuffer : IEnumerable
+ {
+ private List mCustomIcons;
+ #region Serialization
+ public PwCustomIconListBuffer(List customIcons)
+ {
+ mCustomIcons = customIcons;
+ }
+ #endregion
+
+ #region Deserialization
+ public void Add(PwCustomIconBuffer item)
+ {
+ mCustomIcons.Add(item.CustomIcon);
+ }
+ #endregion
+
+ public IEnumerator GetEnumerator()
+ {
+ foreach (var customIcon in mCustomIcons)
+ {
+ yield return new PwCustomIconBuffer(customIcon);
+ }
+ }
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+ }
+
+ [ProtoContract]
+ private class PwCustomIconBuffer
+ {
+ #region Serialization
+ private PwCustomIcon mCustomIcon;
+ public PwCustomIconBuffer(PwCustomIcon CustomIcon)
+ {
+ mCustomIcon = CustomIcon;
+ Uuid = mCustomIcon.Uuid.UuidBytes;
+ ImageData = mCustomIcon.ImageDataPng;
+ }
+ #endregion
+
+ #region Deserialization
+ private PwCustomIconBuffer()
+ {
+ }
+
+ [ProtoAfterDeserialization]
+ private void AfterDeserialization(SerializationContext context)
+ {
+ mCustomIcon = new PwCustomIcon(new PwUuid(Uuid), ImageData);
+ }
+
+ public PwCustomIcon CustomIcon { get { return mCustomIcon; } }
+ #endregion
+
+ [ProtoMember(1, OverwriteList = true)]
+ public byte[] Uuid;
+
+ [ProtoMember(2, OverwriteList = true)]
+ public byte[] ImageData;
+ }
+
+ [ProtoContract]
+ private class MemoryProtectionConfigBuffer
+ {
+ #region Serialization
+ private readonly MemoryProtectionConfig mMemoryProtectionConfig;
+
+ public MemoryProtectionConfigBuffer(MemoryProtectionConfig memoryProtectionConfig)
+ {
+ mMemoryProtectionConfig = memoryProtectionConfig;
+ }
+ #endregion
+
+ #region Deserialization
+ private MemoryProtectionConfigBuffer()
+ {
+ mMemoryProtectionConfig = new MemoryProtectionConfig();
+ }
+
+ public MemoryProtectionConfig MemoryProtectionConfig { get { return mMemoryProtectionConfig; } }
+ #endregion
+
+ [ProtoMember(1)]
+ public bool ProtectTitle
+ {
+ get { return mMemoryProtectionConfig.ProtectTitle; }
+ set { mMemoryProtectionConfig.ProtectTitle = value; }
+ }
+
+ [ProtoMember(2)]
+ public bool ProtectUserName
+ {
+ get { return mMemoryProtectionConfig.ProtectUserName; }
+ set { mMemoryProtectionConfig.ProtectUserName = value; }
+ }
+
+ [ProtoMember(3)]
+ public bool ProtectPassword
+ {
+ get { return mMemoryProtectionConfig.ProtectPassword; }
+ set { mMemoryProtectionConfig.ProtectPassword = value; }
+ }
+
+ [ProtoMember(4)]
+ public bool ProtectUrl
+ {
+ get { return mMemoryProtectionConfig.ProtectUrl; }
+ set { mMemoryProtectionConfig.ProtectUrl = value; }
+ }
+
+ [ProtoMember(5)]
+ public bool ProtectNotes
+ {
+ get { return mMemoryProtectionConfig.ProtectNotes; }
+ set { mMemoryProtectionConfig.ProtectNotes = value; }
+ }
+ }
+
+ [ProtoContract]
+ private class PwDeletedObjectListBuffer : PwObjectListBufferBase
+ {
+ #region Serialization
+ public PwDeletedObjectListBuffer(PwObjectList objectList)
+ : base(objectList)
+ {
+ }
+
+ protected override PwDeletedObjectBuffer CreateBuffer(PwDeletedObject item)
+ {
+ return new PwDeletedObjectBuffer(item);
+ }
+ #endregion
+
+ #region Deserialization
+ private PwDeletedObjectListBuffer()
+ : base()
+ {
+ }
+
+ public override void Add(PwDeletedObjectBuffer item)
+ {
+ ObjectList.Add(item.DeletedObject);
+ }
+ #endregion
+ }
+
+ [ProtoContract]
+ private class PwDeletedObjectBuffer
+ {
+ #region Serialization
+ private readonly PwDeletedObject mDeletedObject;
+
+ public PwDeletedObjectBuffer(PwDeletedObject deletedObject)
+ {
+ mDeletedObject = deletedObject;
+ }
+ #endregion
+
+ #region Deserialization
+ private PwDeletedObjectBuffer()
+ {
+ mDeletedObject = new PwDeletedObject();
+ }
+
+ public PwDeletedObject DeletedObject { get { return mDeletedObject; } }
+ #endregion
+
+ [ProtoMember(1, OverwriteList = true)]
+ public byte[] Uuid
+ {
+ get { return mDeletedObject.Uuid.UuidBytes; }
+ set { mDeletedObject.Uuid = new PwUuid(value); }
+ }
+
+ [ProtoMember(2)]
+ public DateTime DeletionTime
+ {
+ get { return mDeletedObject.DeletionTime; }
+ set { mDeletedObject.DeletionTime = value; }
+ }
+ }
+
+ [ProtoContract]
+ private class PwGroupBuffer
+ {
+ #region Serialization
+ private readonly PwGroup mGroup;
+ private readonly PwGroupEntryListBuffer mEntries;
+ private readonly PwGroupGroupListBuffer mGroups;
+
+ public PwGroupBuffer(PwGroup group)
+ {
+ mGroup = group;
+ mEntries = new PwGroupEntryListBuffer(mGroup);
+ mGroups = new PwGroupGroupListBuffer(mGroup);
+ }
+ #endregion
+
+ #region Deserialization
+ private PwGroupBuffer()
+ {
+ mGroup = new PwGroup(false, false);
+ mEntries = new PwGroupEntryListBuffer(mGroup);
+ mGroups = new PwGroupGroupListBuffer(mGroup);
+ }
+
+ public PwGroup Group { get { return mGroup; } }
+ #endregion
+
+ [ProtoMember(1, OverwriteList = true)]
+ public byte[] Uuid
+ {
+ get { return mGroup.Uuid.UuidBytes; }
+ set { mGroup.Uuid = new PwUuid(value); }
+ }
+
+ [ProtoMember(2)]
+ public string Name
+ {
+ get { return mGroup.Name; }
+ set { mGroup.Name = value; }
+ }
+
+ [ProtoMember(3)]
+ public string Notes
+ {
+ get { return mGroup.Notes; }
+ set { mGroup.Notes = value; }
+ }
+
+ [ProtoMember(4)]
+ public PwIcon IconId
+ {
+ get { return mGroup.IconId; }
+ set { mGroup.IconId = value; }
+ }
+
+ [ProtoMember(5, OverwriteList = true)]
+ public byte[] CustomIconUuid
+ {
+ get { return mGroup.CustomIconUuid.UuidBytes; }
+ set { mGroup.CustomIconUuid = new PwUuid(value); }
+ }
+
+ [ProtoMember(6)]
+ public bool IsExpanded
+ {
+ get { return mGroup.IsExpanded; }
+ set { mGroup.IsExpanded = value; }
+ }
+
+ [ProtoMember(7)]
+ public string DefaultAutoTypeSequence
+ {
+ get { return mGroup.DefaultAutoTypeSequence; }
+ set { mGroup.DefaultAutoTypeSequence = value; }
+ }
+
+ [ProtoMember(8)]
+ public DateTime LastModificationTime
+ {
+ get { return mGroup.LastModificationTime; }
+ set { mGroup.LastModificationTime = value; }
+ }
+
+ [ProtoMember(9)]
+ public DateTime CreationTime
+ {
+ get { return mGroup.CreationTime; }
+ set { mGroup.CreationTime = value; }
+ }
+
+ [ProtoMember(10)]
+ public DateTime LastAccessTime
+ {
+ get { return mGroup.LastAccessTime; }
+ set { mGroup.LastAccessTime = value; }
+ }
+
+ [ProtoMember(11)]
+ public DateTime ExpiryTime
+ {
+ get { return mGroup.ExpiryTime; }
+ set { mGroup.ExpiryTime = value; }
+ }
+
+ [ProtoMember(12)]
+ public bool Expires
+ {
+ get { return mGroup.Expires; }
+ set { mGroup.Expires = value; }
+ }
+
+ [ProtoMember(13)]
+ public ulong UsageCount
+ {
+ get { return mGroup.UsageCount; }
+ set { mGroup.UsageCount = value; }
+ }
+
+ [ProtoMember(14)]
+ public DateTime LocationChanged
+ {
+ get { return mGroup.LocationChanged; }
+ set { mGroup.LocationChanged = value; }
+ }
+
+ [ProtoMember(15)]
+ public bool? EnableAutoType
+ {
+ get { return mGroup.EnableAutoType; }
+ set { mGroup.EnableAutoType = value; }
+ }
+
+ [ProtoMember(16)]
+ public bool? EnableSearching
+ {
+ get { return mGroup.EnableSearching; }
+ set { mGroup.EnableSearching = value; }
+ }
+
+ [ProtoMember(17, OverwriteList = true)]
+ public byte[] LastTopVisibleEntry
+ {
+ get { return mGroup.LastTopVisibleEntry.UuidBytes; }
+ set { mGroup.LastTopVisibleEntry = new PwUuid(value); }
+ }
+
+ [ProtoMember(18)]
+ public PwGroupGroupListBuffer Groups
+ {
+ get { return mGroups; }
+ }
+
+ [ProtoMember(19)]
+ public PwGroupEntryListBuffer Entries
+ {
+ get { return mEntries; }
+ }
+ }
+
+ private abstract class PwObjectListBufferBase : IEnumerable
+ where TData : class, KeePassLib.Interfaces.IDeepCloneable
+ {
+ #region Serialization
+ private PwObjectList mObjectList;
+
+ protected PwObjectListBufferBase(PwObjectList objectList)
+ {
+ mObjectList = objectList;
+ }
+
+ protected abstract TDataBuffer CreateBuffer(TData item);
+ #endregion
+
+ #region Deserialization
+ protected PwObjectListBufferBase()
+ {
+ mObjectList = new PwObjectList();
+ }
+
+ public PwObjectList ObjectList { get { return mObjectList; } }
+
+ public abstract void Add(TDataBuffer item);
+ #endregion
+
+ public IEnumerator GetEnumerator()
+ {
+ foreach (var item in mObjectList)
+ {
+ yield return CreateBuffer(item);
+ }
+ }
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+ }
+
+ [ProtoContract]
+ private class PwGroupGroupListBuffer : PwObjectListBufferBase
+ {
+ #region Serialization
+ private PwGroup mGroup;
+ public PwGroupGroupListBuffer(PwGroup group)
+ : base(group.Groups)
+ {
+ mGroup = group;
+ }
+
+ protected override PwGroupBuffer CreateBuffer(PwGroup item)
+ {
+ return new PwGroupBuffer(item);
+ }
+ #endregion
+
+ #region Deserialization
+ public override void Add(PwGroupBuffer item)
+ {
+ mGroup.AddGroup(item.Group, true);
+ }
+ #endregion
+ }
+
+ [ProtoContract]
+ private class PwGroupEntryListBuffer : PwObjectListBufferBase
+ {
+ #region Serialization
+ private PwGroup mGroup;
+ public PwGroupEntryListBuffer(PwGroup group)
+ : base(group.Entries)
+ {
+ mGroup = group;
+ }
+
+ protected override PwEntryBuffer CreateBuffer(PwEntry item)
+ {
+ return new PwEntryBuffer(item);
+ }
+ #endregion
+
+ #region Deserialization
+ public override void Add(PwEntryBuffer item)
+ {
+ mGroup.AddEntry(item.Entry, true);
+ }
+ #endregion
+ }
+
+ [ProtoContract]
+ private class PwEntryListBuffer : PwObjectListBufferBase
+ {
+ #region Serialization
+ public PwEntryListBuffer(PwObjectList entryList)
+ : base(entryList)
+ {
+ }
+
+ protected override PwEntryBuffer CreateBuffer(PwEntry item)
+ {
+ return new PwEntryBuffer(item);
+ }
+ #endregion
+
+ #region Deserialization
+ private PwEntryListBuffer()
+ : base()
+ {
+ }
+
+ public override void Add(PwEntryBuffer item)
+ {
+ ObjectList.Add(item.Entry);
+ }
+ #endregion
+ }
+
+ [ProtoContract]
+ private class PwEntryBuffer
+ {
+ #region Serialization
+ private readonly PwEntry mEntry;
+ private ProtectedStandardFieldDictionaryBuffer mEntryStandardStrings;
+ private ProtectedCustomFieldDictionaryBuffer mEntryCustomStrings;
+ private NamedProtectedBinaryListBuffer mEntryBinaries;
+
+ public PwEntryBuffer(PwEntry entry)
+ {
+ mEntry = entry;
+ }
+
+ [ProtoBeforeSerialization]
+ private void BeforeSerialization(SerializationContext context)
+ {
+ var bufferContext = (BufferContext)context.Context;
+
+ // ProtectedStringDictionaryBuffer nver gets its own ProtoBeforeSerialization called as it's a list of objects rather than an object itself
+ List> customFields;
+ mEntryStandardStrings = new ProtectedStandardFieldDictionaryBuffer(mEntry.Strings, (int)mEntry.Strings.UCount, bufferContext, out customFields);
+ mEntryCustomStrings = new ProtectedCustomFieldDictionaryBuffer(customFields);
+ mEntryBinaries = new NamedProtectedBinaryListBuffer(mEntry.Binaries, (int)mEntry.Binaries.UCount, bufferContext);
+ }
+ #endregion
+
+ #region Deserialization
+ private PwEntryBuffer()
+ {
+ mEntry = new PwEntry(false, false);
+ mEntryStandardStrings = new ProtectedStandardFieldDictionaryBuffer(mEntry.Strings);
+ mEntryCustomStrings = new ProtectedCustomFieldDictionaryBuffer(mEntry.Strings);
+ mEntryBinaries = new NamedProtectedBinaryListBuffer(mEntry.Binaries);
+ }
+
+ public PwEntry Entry { get { return mEntry; } }
+ #endregion
+
+ [ProtoMember(1, OverwriteList = true)]
+ public byte[] Uuid
+ {
+ get { return mEntry.Uuid.UuidBytes; }
+ set { mEntry.SetUuid(new PwUuid(value), false); }
+ }
+
+ [ProtoMember(2)]
+ public PwIcon IconId
+ {
+ get { return mEntry.IconId; }
+ set { mEntry.IconId = value; }
+ }
+
+ [ProtoMember(3, OverwriteList = true)]
+ public byte[] CustomIconUuid
+ {
+ get { return mEntry.CustomIconUuid.UuidBytes; }
+ set { mEntry.CustomIconUuid = new PwUuid(value); }
+ }
+
+ [ProtoMember(4)]
+ public int ForegroundColor
+ {
+ get { return mEntry.ForegroundColor.ToArgb(); }
+ set { mEntry.ForegroundColor = Color.FromArgb(value); }
+ }
+
+ [ProtoMember(5)]
+ public int BackgroundColor
+ {
+ get { return mEntry.BackgroundColor.ToArgb(); }
+ set { mEntry.BackgroundColor = Color.FromArgb(value); }
+ }
+
+ [ProtoMember(6)]
+ public string OverrideUrl
+ {
+ get { return mEntry.OverrideUrl; }
+ set { mEntry.OverrideUrl = value; }
+ }
+
+ [ProtoMember(7)]
+ public IList Tags
+ {
+ get { return mEntry.Tags; }
+ }
+
+ [ProtoMember(8)]
+ public DateTime LastModificationTime
+ {
+ get { return mEntry.LastModificationTime; }
+ set { mEntry.LastModificationTime = value; }
+ }
+
+ [ProtoMember(9)]
+ public DateTime CreationTime
+ {
+ get { return mEntry.CreationTime; }
+ set { mEntry.CreationTime = value; }
+ }
+
+ [ProtoMember(10)]
+ public DateTime LastAccessTime
+ {
+ get { return mEntry.LastAccessTime; }
+ set { mEntry.LastAccessTime = value; }
+ }
+
+ [ProtoMember(11)]
+ public DateTime ExpiryTime
+ {
+ get { return mEntry.ExpiryTime; }
+ set { mEntry.ExpiryTime = value; }
+ }
+
+ [ProtoMember(12)]
+ public bool Expires
+ {
+ get { return mEntry.Expires; }
+ set { mEntry.Expires = value; }
+ }
+
+ [ProtoMember(13)]
+ public ulong UsageCount
+ {
+ get { return mEntry.UsageCount; }
+ set { mEntry.UsageCount = value; }
+ }
+
+ [ProtoMember(14)]
+ public DateTime LocationChanged
+ {
+ get { return mEntry.LocationChanged; }
+ set { mEntry.LocationChanged = value; }
+ }
+
+ [ProtoMember(15)]
+ public ProtectedStandardFieldDictionaryBuffer StandardStrings
+ {
+ get { return mEntryStandardStrings; }
+ }
+
+ [ProtoMember(16)]
+ public ProtectedCustomFieldDictionaryBuffer CustomStrings
+ {
+ get { return mEntryCustomStrings; }
+ }
+
+ [ProtoMember(17, AsReference = true)]
+ public NamedProtectedBinaryListBuffer Binaries
+ {
+ get { return mEntryBinaries; }
+ }
+
+ [ProtoMember(18)]
+ public AutoTypeConfigBuffer AutoType
+ {
+ get { return new AutoTypeConfigBuffer(mEntry.AutoType); }
+ set { mEntry.AutoType = value.AutoTypeConfig; }
+ }
+
+ [ProtoMember(19)]
+ public PwEntryListBuffer History
+ {
+ get { return new PwEntryListBuffer(mEntry.History); }
+ set { mEntry.History = value.ObjectList; }
+ }
+
+ }
+
+ private abstract class ProtectedStringDictionaryBuffer : IEnumerable>
+ {
+ #region Serialization
+ private List> mProtectedStringBuffers;
+
+ ///
+ /// Serialisation constructor. Reads strings from dictionary, does not write to it
+ ///
+ protected ProtectedStringDictionaryBuffer(int capacity)
+ {
+ mProtectedStringBuffers = new List>(capacity);
+ }
+
+ protected void AddStringField(TKey key, ProtectedString value, bool? overrideProtect)
+ {
+ mProtectedStringBuffers.Add(new KeyValuePair(key, new ProtectedStringBuffer(value, overrideProtect)));
+ }
+
+ public IEnumerator> GetEnumerator()
+ {
+ return mProtectedStringBuffers.GetEnumerator();
+ }
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+ #endregion
+
+ #region Deserialization
+ private readonly ProtectedStringDictionary mDictionary;
+
+ ///
+ /// Deerialisation constructor. Writes strings to dictionary, does read from it
+ ///
+ protected ProtectedStringDictionaryBuffer(ProtectedStringDictionary dictionary)
+ {
+ mDictionary = dictionary;
+ }
+
+ public void Add(KeyValuePair item)
+ {
+ mDictionary.Set(GetFieldName(item.Key), item.Value.ProtectedString);
+ }
+
+ protected abstract string GetFieldName(TKey key);
+
+ #endregion
+ }
+
+ [ProtoContract]
+ private class ProtectedCustomFieldDictionaryBuffer : ProtectedStringDictionaryBuffer
+ {
+ public ProtectedCustomFieldDictionaryBuffer(List> entryStrings)
+ : base(entryStrings.Count)
+ {
+ foreach (var kvp in entryStrings)
+ {
+ System.Diagnostics.Debug.Assert(!PwDefs.IsStandardField(kvp.Key));
+ AddStringField(kvp.Key, kvp.Value, null);
+ }
+ }
+
+ public ProtectedCustomFieldDictionaryBuffer(ProtectedStringDictionary dictionary)
+ : base(dictionary)
+ { }
+
+ protected override string GetFieldName(string key)
+ {
+ return key;
+ }
+ }
+
+ [ProtoContract]
+ private class ProtectedStandardFieldDictionaryBuffer : ProtectedStringDictionaryBuffer
+ {
+ public enum StandardField
+ {
+ Title,
+ UserName,
+ Password,
+ Url,
+ Notes
+ }
+
+ public ProtectedStandardFieldDictionaryBuffer(IEnumerable> entryStrings, int entryStringCount, BufferContext context,
+ out List> customFields) // Perf optimisation - return the custom fields so we don't have to determine them again
+ : base(entryStringCount)
+ {
+ customFields = new List>(entryStringCount);
+
+ var database = context.Database;
+
+ foreach (var kvp in entryStrings)
+ {
+ var field = GetField(kvp.Key);
+
+ if (field.HasValue)
+ {
+ // Logic from KdbxFile.Write
+
+ bool? overrideProtect = null;
+ // Adjust memory protection setting (which might be different
+ // from the database default, e.g. due to an import which
+ // didn't specify the correct setting)
+ switch (field.Value)
+ {
+ case StandardField.Title:
+ overrideProtect = database.MemoryProtection.ProtectTitle;
+ break;
+ case StandardField.UserName:
+ overrideProtect = database.MemoryProtection.ProtectUserName;
+ break;
+ case StandardField.Password:
+ overrideProtect = database.MemoryProtection.ProtectPassword;
+ break;
+ case StandardField.Url:
+ overrideProtect = database.MemoryProtection.ProtectUrl;
+ break;
+ case StandardField.Notes:
+ overrideProtect = database.MemoryProtection.ProtectNotes;
+ break;
+ }
+
+ AddStringField(field.Value, kvp.Value, overrideProtect);
+ }
+ else
+ {
+ customFields.Add(kvp);
+ }
+ }
+ }
+
+ private static StandardField? GetField(string fieldName)
+ {
+ switch (fieldName)
+ {
+ case PwDefs.TitleField:
+ return StandardField.Title;
+ case PwDefs.UserNameField:
+ return StandardField.UserName;
+ case PwDefs.PasswordField:
+ return StandardField.Password;
+ case PwDefs.UrlField:
+ return StandardField.Url;
+ case PwDefs.NotesField:
+ return StandardField.Notes;
+
+ default:
+ System.Diagnostics.Debug.Assert(!PwDefs.IsStandardField(fieldName));
+ return null;
+ }
+ }
+
+ public ProtectedStandardFieldDictionaryBuffer(ProtectedStringDictionary dictionary)
+ : base(dictionary)
+ { }
+
+ protected override string GetFieldName(StandardField key)
+ {
+ switch (key)
+ {
+ case StandardField.Title:
+ return PwDefs.TitleField;
+ case StandardField.UserName:
+ return PwDefs.UserNameField;
+ case StandardField.Password:
+ return PwDefs.PasswordField;
+ case StandardField.Url:
+ return PwDefs.UrlField;
+ case StandardField.Notes:
+ return PwDefs.NotesField;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+ }
+
+ [ProtoContract]
+ private class ProtectedStringBuffer
+ {
+ #region Serialisation
+ private ProtectedString mProtectedString;
+
+ public ProtectedStringBuffer(ProtectedString protectedString, bool? overrideProtect)
+ {
+ mProtectedString = protectedString;
+ IsProtected = overrideProtect.GetValueOrDefault(mProtectedString.IsProtected);
+ }
+
+ [ProtoBeforeSerialization]
+ private void BeforeSerialization(SerializationContext context)
+ {
+ if (IsProtected)
+ {
+ Value = mProtectedString.ReadXorredString(((BufferContext)context.Context).RandomStream);
+ }
+ else
+ {
+ Value = mProtectedString.ReadUtf8();
+ }
+ }
+ #endregion
+
+ #region Deserialisation
+ private ProtectedStringBuffer()
+ {
+ }
+
+ [ProtoAfterDeserialization]
+ private void AfterDeserialization(SerializationContext context)
+ {
+ if (IsProtected)
+ {
+ byte[] pbPad = ((BufferContext)context.Context).RandomStream.GetRandomBytes((uint)Value.Length);
+ mProtectedString = new ProtectedString(IsProtected, new XorredBuffer(Value, pbPad));
+ }
+ else
+ {
+ mProtectedString = new ProtectedString(IsProtected, Value);
+ }
+ }
+
+ public ProtectedString ProtectedString { get { return mProtectedString; } }
+
+ #endregion
+
+ [ProtoMember(1)]
+ public bool IsProtected;
+
+ [ProtoMember(2, OverwriteList = true)]
+ public byte[] Value;
+ }
+
+ [ProtoContract]
+ private class NamedProtectedBinaryListBuffer : IEnumerable
+ {
+ #region Serialisation
+ private readonly List mNamedBinaries;
+
+ public NamedProtectedBinaryListBuffer(IEnumerable> binaries, int binariesCount, BufferContext context)
+ {
+ mNamedBinaries = new List(binariesCount);
+ foreach (var kvp in binaries)
+ {
+ NamedProtectedBinaryBuffer namedProtectedBinaryBuffer;
+ if (!context.BinaryPool.TryGetValue(kvp.Value, out namedProtectedBinaryBuffer))
+ {
+ // Hasn't been put in the pool yet, so create it
+ namedProtectedBinaryBuffer = new NamedProtectedBinaryBuffer(kvp);
+ context.BinaryPool.Add(kvp.Value, namedProtectedBinaryBuffer);
+ }
+ mNamedBinaries.Add(namedProtectedBinaryBuffer);
+ }
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return mNamedBinaries.GetEnumerator();
+ }
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+ #endregion
+
+ #region Deserialization
+ private readonly ProtectedBinaryDictionary mBinaryDictionary;
+
+ public NamedProtectedBinaryListBuffer(ProtectedBinaryDictionary binaryDictionary)
+ {
+ mBinaryDictionary = binaryDictionary;
+ }
+
+ public void Add(NamedProtectedBinaryBuffer item)
+ {
+ mBinaryDictionary.Set(item.Name, item.ProtectedBinary);
+ }
+ #endregion
+ }
+
+ [ProtoContract]
+ private class NamedProtectedBinaryBuffer
+ {
+ #region Serialization
+ private ProtectedBinary mProtectedBinary;
+ public NamedProtectedBinaryBuffer(KeyValuePair namedBinary)
+ {
+ Name = namedBinary.Key;
+ mProtectedBinary = namedBinary.Value;
+ IsProtected = mProtectedBinary.IsProtected;
+ }
+
+ [ProtoBeforeSerialization]
+ private void BeforeSerialization(SerializationContext context)
+ {
+ if (IsProtected)
+ {
+ Value = mProtectedBinary.ReadXorredData(((BufferContext)context.Context).RandomStream);
+ }
+ else
+ {
+ Value = mProtectedBinary.ReadData();
+ }
+ }
+ #endregion
+
+ #region Deserialisation
+ private NamedProtectedBinaryBuffer()
+ {
+ }
+
+ [ProtoAfterDeserialization]
+ private void AfterDeserialization(SerializationContext context)
+ {
+ if (IsProtected)
+ {
+ byte[] pbPad = ((BufferContext)context.Context).RandomStream.GetRandomBytes((uint)Value.Length);
+ mProtectedBinary = new ProtectedBinary(IsProtected, new XorredBuffer(Value, pbPad));
+ }
+ else
+ {
+ mProtectedBinary = new ProtectedBinary(IsProtected, Value);
+ }
+ }
+
+ public ProtectedBinary ProtectedBinary { get { return mProtectedBinary; } }
+
+ #endregion
+
+ [ProtoMember(1)]
+ public string Name;
+
+ [ProtoMember(2)]
+ public bool IsProtected;
+
+ [ProtoMember(3, OverwriteList = true)]
+ public byte[] Value;
+ }
+
+ [ProtoContract]
+ private class AutoTypeConfigBuffer
+ {
+ private readonly AutoTypeAssociationsBuffer mAutoTypeAssociationsBuffer;
+ #region Serialization
+ private AutoTypeConfig mAutoTypeConfig;
+ public AutoTypeConfigBuffer(AutoTypeConfig autoTypeConfig)
+ {
+ mAutoTypeConfig = autoTypeConfig;
+ mAutoTypeAssociationsBuffer = new AutoTypeAssociationsBuffer(mAutoTypeConfig);
+ }
+ #endregion
+
+ #region Deserialization
+ private AutoTypeConfigBuffer()
+ {
+ mAutoTypeConfig = new AutoTypeConfig();
+ mAutoTypeAssociationsBuffer = new AutoTypeAssociationsBuffer(mAutoTypeConfig);
+ }
+
+ public AutoTypeConfig AutoTypeConfig { get { return mAutoTypeConfig; } }
+ #endregion
+
+ [ProtoMember(1)]
+ public bool Enabled
+ {
+ get { return mAutoTypeConfig.Enabled; }
+ set { mAutoTypeConfig.Enabled = value; }
+ }
+
+ [ProtoMember(2)]
+ public AutoTypeObfuscationOptions ObfuscationOptions
+ {
+ get { return mAutoTypeConfig.ObfuscationOptions; }
+ set { mAutoTypeConfig.ObfuscationOptions = value; }
+ }
+
+ [ProtoMember(3)]
+ public string DefaultSequence
+ {
+ get { return mAutoTypeConfig.DefaultSequence; }
+ set { mAutoTypeConfig.DefaultSequence = value; }
+ }
+
+ [ProtoMember(4)]
+ public AutoTypeAssociationsBuffer Associations
+ {
+ get { return mAutoTypeAssociationsBuffer; }
+ }
+ }
+
+ [ProtoContract]
+ private class AutoTypeAssociationsBuffer : IEnumerable
+ {
+ #region Serialization
+ private AutoTypeConfig mAutoTypeConfig;
+
+ public AutoTypeAssociationsBuffer(AutoTypeConfig autoTypeConfig)
+ {
+ mAutoTypeConfig = autoTypeConfig;
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ foreach (var autoTypeAssociation in mAutoTypeConfig.Associations)
+ {
+ yield return new AutoTypeAssociationBuffer(autoTypeAssociation);
+ }
+ }
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+ #endregion
+
+ #region Deserialization
+ public void Add(AutoTypeAssociationBuffer value)
+ {
+ mAutoTypeConfig.Add(value.AutoTypeAssociation);
+ }
+ #endregion
+ }
+
+ [ProtoContract]
+ private class AutoTypeAssociationBuffer
+ {
+ #region Serialization
+ private AutoTypeAssociation mAutoTypeAssociation;
+
+ public AutoTypeAssociationBuffer(AutoTypeAssociation autoTypeAssociation)
+ {
+ mAutoTypeAssociation = autoTypeAssociation;
+ }
+ #endregion
+
+ #region Deserialization
+ private AutoTypeAssociationBuffer()
+ {
+ mAutoTypeAssociation = new AutoTypeAssociation();
+ }
+
+ public AutoTypeAssociation AutoTypeAssociation { get { return mAutoTypeAssociation; } }
+ #endregion
+
+ [ProtoMember(1)]
+ public string WindowName
+ {
+ get { return mAutoTypeAssociation.WindowName; }
+ set { mAutoTypeAssociation.WindowName = value; }
+ }
+
+ [ProtoMember(2)]
+ public string Sequence
+ {
+ get { return mAutoTypeAssociation.Sequence; }
+ set { mAutoTypeAssociation.Sequence = value; }
+ }
+ }
+ }
+}
diff --git a/src/ProtoBuf/protobuf-net.dll b/src/ProtoBuf/protobuf-net.dll
new file mode 100644
index 00000000..adc83a91
Binary files /dev/null and b/src/ProtoBuf/protobuf-net.dll differ
diff --git a/src/ProtoBuf/protobuf-net.pdb b/src/ProtoBuf/protobuf-net.pdb
new file mode 100644
index 00000000..838b0bbe
Binary files /dev/null and b/src/ProtoBuf/protobuf-net.pdb differ
diff --git a/src/ProtoBuf/protobuf-net.xml b/src/ProtoBuf/protobuf-net.xml
new file mode 100644
index 00000000..3451e38c
--- /dev/null
+++ b/src/ProtoBuf/protobuf-net.xml
@@ -0,0 +1,2747 @@
+
+
+
+ protobuf-net
+
+
+
+
+ Provides support for common .NET types that do not have a direct representation
+ in protobuf, using the definitions from bcl.proto
+
+
+
+
+ Creates a new instance of the specified type, bypassing the constructor.
+
+ The type to create
+ The new instance
+ If the platform does not support constructor-skipping
+
+
+
+ Writes a TimeSpan to a protobuf stream
+
+
+
+
+ Parses a TimeSpan from a protobuf stream
+
+
+
+
+ Parses a DateTime from a protobuf stream
+
+
+
+
+ Writes a DateTime to a protobuf stream
+
+
+
+
+ Parses a decimal from a protobuf stream
+
+
+
+
+ Writes a decimal to a protobuf stream
+
+
+
+
+ Writes a Guid to a protobuf stream
+
+
+
+
+ Parses a Guid from a protobuf stream
+
+
+
+
+ Reads an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc.
+
+
+
+
+ Writes an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc.
+
+
+
+
+ Optional behaviours that introduce .NET-specific functionality
+
+
+
+
+ No special behaviour
+
+
+
+
+ Enables full object-tracking/full-graph support.
+
+
+
+
+ Embeds the type information into the stream, allowing usage with types not known in advance.
+
+
+
+
+ If false, the constructor for the type is bypassed during deserialization, meaning any field initializers
+ or other initialization code is skipped.
+
+
+
+
+ Should the object index be reserved, rather than creating an object promptly
+
+
+
+
+ Provides a simple buffer-based implementation of an extension object.
+
+
+
+
+ Provides addition capability for supporting unexpected fields during
+ protocol-buffer serialization/deserialization. This allows for loss-less
+ round-trip/merge, even when the data is not fully understood.
+
+
+
+
+ Requests a stream into which any unexpected fields can be persisted.
+
+ A new stream suitable for storing data.
+
+
+
+ Indicates that all unexpected fields have now been stored. The
+ implementing class is responsible for closing the stream. If
+ "commit" is not true the data may be discarded.
+
+ The stream originally obtained by BeginAppend.
+ True if the append operation completed successfully.
+
+
+
+ Requests a stream of the unexpected fields previously stored.
+
+ A prepared stream of the unexpected fields.
+
+
+
+ Indicates that all unexpected fields have now been read. The
+ implementing class is responsible for closing the stream.
+
+ The stream originally obtained by BeginQuery.
+
+
+
+ Requests the length of the raw binary stream; this is used
+ when serializing sub-entities to indicate the expected size.
+
+ The length of the binary stream representing unexpected data.
+
+
+ Specifies a method on the root-contract in an hierarchy to be invoked before serialization.
+
+
+ Specifies a method on the root-contract in an hierarchy to be invoked after serialization.
+
+
+ Specifies a method on the root-contract in an hierarchy to be invoked before deserialization.
+
+
+ Specifies a method on the root-contract in an hierarchy to be invoked after deserialization.
+
+
+
+ Pushes a null reference onto the stack. Note that this should only
+ be used to return a null (or set a variable to null); for null-tests
+ use BranchIfTrue / BranchIfFalse.
+
+
+
+
+ Creates a new "using" block (equivalent) around a variable;
+ the variable must exist, and note that (unlike in C#) it is
+ the variables *final* value that gets disposed. If you need
+ *original* disposal, copy your variable first.
+
+ It is the callers responsibility to ensure that the variable's
+ scope fully-encapsulates the "using"; if not, the variable
+ may be re-used (and thus re-assigned) unexpectedly.
+
+
+
+
+ Sub-format to use when serializing/deserializing data
+
+
+
+
+ Uses the default encoding for the data-type.
+
+
+
+
+ When applied to signed integer-based data (including Decimal), this
+ indicates that zigzag variant encoding will be used. This means that values
+ with small magnitude (regardless of sign) take a small amount
+ of space to encode.
+
+
+
+
+ When applied to signed integer-based data (including Decimal), this
+ indicates that two's-complement variant encoding will be used.
+ This means that any -ve number will take 10 bytes (even for 32-bit),
+ so should only be used for compatibility.
+
+
+
+
+ When applied to signed integer-based data (including Decimal), this
+ indicates that a fixed amount of space will be used.
+
+
+
+
+ When applied to a sub-message, indicates that the value should be treated
+ as group-delimited.
+
+
+
+
+ Simple base class for supporting unexpected fields allowing
+ for loss-less round-tips/merge, even if the data is not understod.
+ The additional fields are (by default) stored in-memory in a buffer.
+
+ As an example of an alternative implementation, you might
+ choose to use the file system (temporary files) as the back-end, tracking
+ only the paths [such an object would ideally be IDisposable and use
+ a finalizer to ensure that the files are removed].
+
+
+
+
+ Indicates that the implementing type has support for protocol-buffer
+ extensions.
+
+ Can be implemented by deriving from Extensible.
+
+
+
+ Retrieves the extension object for the current
+ instance, optionally creating it if it does not already exist.
+
+ Should a new extension object be
+ created if it does not already exist?
+ The extension object if it exists (or was created), or null
+ if the extension object does not exist or is not available.
+ The createIfMissing argument is false during serialization,
+ and true during deserialization upon encountering unexpected fields.
+
+
+
+ Retrieves the extension object for the current
+ instance, optionally creating it if it does not already exist.
+
+ Should a new extension object be
+ created if it does not already exist?
+ The extension object if it exists (or was created), or null
+ if the extension object does not exist or is not available.
+ The createIfMissing argument is false during serialization,
+ and true during deserialization upon encountering unexpected fields.
+
+
+
+ Provides a simple, default implementation for extension support,
+ optionally creating it if it does not already exist. Designed to be called by
+ classes implementing .
+
+ Should a new extension object be
+ created if it does not already exist?
+ The extension field to check (and possibly update).
+ The extension object if it exists (or was created), or null
+ if the extension object does not exist or is not available.
+ The createIfMissing argument is false during serialization,
+ and true during deserialization upon encountering unexpected fields.
+
+
+
+ Appends the value as an additional (unexpected) data-field for the instance.
+ Note that for non-repeated sub-objects, this equates to a merge operation;
+ for repeated sub-objects this adds a new instance to the set; for simple
+ values the new value supercedes the old value.
+
+ Note that appending a value does not remove the old value from
+ the stream; avoid repeatedly appending values for the same field.
+ The type of the value to append.
+ The extensible object to append the value to.
+ The field identifier; the tag should not be defined as a known data-field for the instance.
+ The value to append.
+
+
+
+ Appends the value as an additional (unexpected) data-field for the instance.
+ Note that for non-repeated sub-objects, this equates to a merge operation;
+ for repeated sub-objects this adds a new instance to the set; for simple
+ values the new value supercedes the old value.
+
+ Note that appending a value does not remove the old value from
+ the stream; avoid repeatedly appending values for the same field.
+ The data-type of the field.
+ The data-format to use when encoding the value.
+ The extensible object to append the value to.
+ The field identifier; the tag should not be defined as a known data-field for the instance.
+ The value to append.
+
+
+
+ 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
+ value is "repeated" (a list), then use GetValues instead.
+
+ The data-type of the field.
+ The extensible object to obtain the value from.
+ The field identifier; the tag should not be defined as a known data-field for the instance.
+ The effective value of the field, or the default value if not found.
+
+
+
+ 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
+ value is "repeated" (a list), then use GetValues instead.
+
+ The data-type of the field.
+ The extensible object to obtain the value from.
+ The field identifier; the tag should not be defined as a known data-field for the instance.
+ The data-format to use when decoding the value.
+ The effective value of the field, or the default value if not found.
+
+
+
+ Queries an extensible object for an additional (unexpected) data-field for the instance.
+ The value returned (in "value") is the composed value after merging any duplicated content;
+ if the value is "repeated" (a list), then use GetValues instead.
+
+ The data-type of the field.
+ The effective value of the field, or the default value if not found.
+ The extensible object to obtain the value from.
+ The field identifier; the tag should not be defined as a known data-field for the instance.
+ True if data for the field was present, false otherwise.
+
+
+
+ Queries an extensible object for an additional (unexpected) data-field for the instance.
+ The value returned (in "value") is the composed value after merging any duplicated content;
+ if the value is "repeated" (a list), then use GetValues instead.
+
+ The data-type of the field.
+ The effective value of the field, or the default value if not found.
+ The extensible object to obtain the value from.
+ The field identifier; the tag should not be defined as a known data-field for the instance.
+ The data-format to use when decoding the value.
+ True if data for the field was present, false otherwise.
+
+
+
+ Queries an extensible object for an additional (unexpected) data-field for the instance.
+ The value returned (in "value") is the composed value after merging any duplicated content;
+ if the value is "repeated" (a list), then use GetValues instead.
+
+ The data-type of the field.
+ The effective value of the field, or the default value if not found.
+ The extensible object to obtain the value from.
+ The field identifier; the tag should not be defined as a known data-field for the instance.
+ The data-format to use when decoding the value.
+ Allow tags that are present as part of the definition; for example, to query unknown enum values.
+ True if data for the field was present, false otherwise.
+
+
+
+ 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"
+ (list) fields.
+
+ The extended data is processed lazily as the enumerator is iterated.
+ The data-type of the field.
+ The extensible object to obtain the value from.
+ The field identifier; the tag should not be defined as a known data-field for the instance.
+ An enumerator that yields each occurrence of the field.
+
+
+
+ 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"
+ (list) fields.
+
+ The extended data is processed lazily as the enumerator is iterated.
+ The data-type of the field.
+ The extensible object to obtain the value from.
+ The field identifier; the tag should not be defined as a known data-field for the instance.
+ The data-format to use when decoding the value.
+ An enumerator that yields each occurrence of the field.
+
+
+
+ Queries an extensible object for an additional (unexpected) data-field for the instance.
+ The value returned (in "value") is the composed value after merging any duplicated content;
+ if the value is "repeated" (a list), then use GetValues instead.
+
+ The data-type of the field.
+ The model to use for configuration.
+ The effective value of the field, or the default value if not found.
+ The extensible object to obtain the value from.
+ The field identifier; the tag should not be defined as a known data-field for the instance.
+ The data-format to use when decoding the value.
+ Allow tags that are present as part of the definition; for example, to query unknown enum values.
+ True if data for the field was present, false otherwise.
+
+
+
+ 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"
+ (list) fields.
+
+ The extended data is processed lazily as the enumerator is iterated.
+ The model to use for configuration.
+ The data-type of the field.
+ The extensible object to obtain the value from.
+ The field identifier; the tag should not be defined as a known data-field for the instance.
+ The data-format to use when decoding the value.
+ An enumerator that yields each occurrence of the field.
+
+
+
+ Appends the value as an additional (unexpected) data-field for the instance.
+ Note that for non-repeated sub-objects, this equates to a merge operation;
+ for repeated sub-objects this adds a new instance to the set; for simple
+ values the new value supercedes the old value.
+
+ Note that appending a value does not remove the old value from
+ the stream; avoid repeatedly appending values for the same field.
+ The model to use for configuration.
+ The data-format to use when encoding the value.
+ The extensible object to append the value to.
+ The field identifier; the tag should not be defined as a known data-field for the instance.
+ The value to append.
+
+
+
+ This class acts as an internal wrapper allowing us to do a dynamic
+ methodinfo invoke; an't put into Serializer as don't want on public
+ API; can't put into Serializer<T> since we need to invoke
+ accross classes, which isn't allowed in Silverlight)
+
+
+
+
+ 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.
+
+
+
+
+ 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.
+
+
+
+
+ Not all frameworks are created equal (fx1.1 vs fx2.0,
+ micro-framework, compact-framework,
+ silverlight, etc). This class simply wraps up a few things that would
+ otherwise make the real code unnecessarily messy, providing fallback
+ implementations if necessary.
+
+
+
+
+ Intended to be a direct map to regular TypeCode, but:
+ - with missing types
+ - existing on WinRT
+
+
+
+
+ Specifies the method used to infer field tags for members of the type
+ under consideration. Tags are deduced using the invariant alphabetic
+ sequence of the members' names; this makes implicit field tags very brittle,
+ and susceptible to changes such as field names (normally an isolated
+ change).
+
+
+
+
+ No members are serialized implicitly; all members require a suitable
+ attribute such as [ProtoMember]. This is the recmomended mode for
+ most scenarios.
+
+
+
+
+ Public properties and fields are eligible for implicit serialization;
+ this treats the public API as a contract. Ordering beings from ImplicitFirstTag.
+
+
+
+
+ Public and non-public fields are eligible for implicit serialization;
+ this acts as a state/implementation serializer. Ordering beings from ImplicitFirstTag.
+
+
+
+
+ Represents the set of serialization callbacks to be used when serializing/deserializing a type.
+
+
+
+ Called before serializing an instance
+
+
+ Called before deserializing an instance
+
+
+ Called after serializing an instance
+
+
+ Called after deserializing an instance
+
+
+
+ True if any callback is set, else False
+
+
+
+
+ Represents a type at runtime for use with protobuf, allowing the field mappings (etc) to be defined
+
+
+
+
+ Get the name of the type being represented
+
+
+
+
+ Adds a known sub-type to the inheritance model
+
+
+
+
+ Adds a known sub-type to the inheritance model
+
+
+
+
+ Assigns the callbacks to use during serialiation/deserialization.
+
+ The method (or null) called before serialization begins.
+ The method (or null) called when serialization is complete.
+ The method (or null) called before deserialization begins (or when a new instance is created during deserialization).
+ The method (or null) called when deserialization is complete.
+ The set of callbacks.
+
+
+
+ Assigns the callbacks to use during serialiation/deserialization.
+
+ The name of the method (or null) called before serialization begins.
+ The name of the method (or null) called when serialization is complete.
+ The name of the method (or null) called before deserialization begins (or when a new instance is created during deserialization).
+ The name of the method (or null) called when deserialization is complete.
+ The set of callbacks.
+
+
+
+ Designate a factory-method to use to create instances of this type
+
+
+
+
+ Designate a factory-method to use to create instances of this type
+
+
+
+
+ Throws an exception if the type has been made immutable
+
+
+
+
+ Adds a member (by name) to the MetaType
+
+
+
+
+ Adds a member (by name) to the MetaType, returning the ValueMember rather than the fluent API.
+ This is otherwise identical to Add.
+
+
+
+
+ Adds a member (by name) to the MetaType
+
+
+
+
+ Performs serialization of this type via a surrogate; all
+ other serialization options are ignored and handled
+ by the surrogate's configuration.
+
+
+
+
+ Adds a set of members (by name) to the MetaType
+
+
+
+
+ Adds a member (by name) to the MetaType
+
+
+
+
+ Adds a member (by name) to the MetaType, including an itemType and defaultType for representing lists
+
+
+
+
+ Adds a member (by name) to the MetaType, including an itemType and defaultType for representing lists, returning the ValueMember rather than the fluent API.
+ This is otherwise identical to Add.
+
+
+
+
+ Returns the ValueMember instances associated with this type
+
+
+
+
+ Returns the SubType instances associated with this type
+
+
+
+
+ Compiles the serializer for this type; this is *not* a full
+ standalone compile, but can significantly boost performance
+ while allowing additional types to be added.
+
+ An in-place compile can access non-public types / members
+
+
+
+ Gets the base-type for this type
+
+
+
+
+ When used to compile a model, should public serialization/deserialzation methods
+ be included for this type?
+
+
+
+
+ Should this type be treated as a reference by default?
+
+
+
+
+ Indicates whether the current type has defined callbacks
+
+
+
+
+ Indicates whether the current type has defined subtypes
+
+
+
+
+ Returns the set of callbacks defined for this type
+
+
+
+
+ Gets or sets the name of this contract.
+
+
+
+
+ The runtime type that the meta-type represents
+
+
+
+
+ Gets or sets whether the type should use a parameterless constructor (the default),
+ or whether the type should skip the constructor completely. This option is not supported
+ on compact-framework.
+
+
+
+
+ The concrete type to create when a new instance of this type is needed; this may be useful when dealing
+ with dynamic proxies, or with interface-based APIs
+
+
+
+
+ Returns the ValueMember that matchs a given field number, or null if not found
+
+
+
+
+ Returns the ValueMember that matchs a given member (property/field), or null if not found
+
+
+
+
+ Gets or sets a value indicating that an enum should be treated directly as an int/short/etc, rather
+ than enforcing .proto enum rules. This is useful *in particul* for [Flags] enums.
+
+
+
+
+ Gets or sets a value indicating that this type should NOT be treated as a list, even if it has
+ familiar list-like characteristics (enumerable, add, etc)
+
+
+
+
+ Provides protobuf serialization support for a number of types that can be defined at runtime
+
+
+
+
+ Provides protobuf serialization support for a number of types
+
+
+
+
+ Resolve a System.Type to the compiler-specific type
+
+
+
+
+ Resolve a System.Type to the compiler-specific type
+
+
+
+
+ This is the more "complete" version of Serialize, which handles single instances of mapped types.
+ The value is written as a complete field, including field-header and (for sub-objects) a
+ length-prefix
+ In addition to that, this provides support for:
+ - basic values; individual int / string / Guid / etc
+ - IEnumerable sequences of any type handled by TrySerializeAuxiliaryType
+
+
+
+
+
+ Writes a protocol-buffer representation of the given instance to the supplied stream.
+
+ The existing instance to be serialized (cannot be null).
+ The destination stream to write to.
+
+
+
+ Writes a protocol-buffer representation of the given instance to the supplied stream.
+
+ The existing instance to be serialized (cannot be null).
+ The destination stream to write to.
+ Additional information about this serialization operation.
+
+
+
+ Writes a protocol-buffer representation of the given instance to the supplied writer.
+
+ The existing instance to be serialized (cannot be null).
+ The destination writer to write to.
+
+
+
+ Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed
+ data - useful with network IO.
+
+ The type being merged.
+ The existing instance to be modified (can be null).
+ The binary stream to apply to the instance (cannot be null).
+ How to encode the length prefix.
+ The tag used as a prefix to each record (only used with base-128 style prefixes).
+ 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.
+
+
+
+ Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed
+ data - useful with network IO.
+
+ The type being merged.
+ The existing instance to be modified (can be null).
+ The binary stream to apply to the instance (cannot be null).
+ How to encode the length prefix.
+ The tag used as a prefix to each record (only used with base-128 style prefixes).
+ Used to resolve types on a per-field basis.
+ 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.
+
+
+
+ Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed
+ data - useful with network IO.
+
+ The type being merged.
+ The existing instance to be modified (can be null).
+ The binary stream to apply to the instance (cannot be null).
+ How to encode the length prefix.
+ The tag used as a prefix to each record (only used with base-128 style prefixes).
+ Used to resolve types on a per-field basis.
+ Returns the number of bytes consumed by this operation (includes length-prefix overheads and any skipped data).
+ 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.
+
+
+
+ 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
+ are directly comparable to serializing multiple items in succession
+ (use the tag to emulate the implicit behavior
+ when serializing a list/array). When a tag is
+ specified, any records with different tags are silently omitted. The
+ tag is ignored. The tag is ignores for fixed-length prefixes.
+
+ The binary stream containing the serialized records.
+ The prefix style used in the data.
+ The tag of records to return (if non-positive, then no tag is
+ expected and all records are returned).
+ On a field-by-field basis, the type of object to deserialize (can be null if "type" is specified).
+ The type of object to deserialize (can be null if "resolver" is specified).
+ The sequence of deserialized objects.
+
+
+
+ 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
+ are directly comparable to serializing multiple items in succession
+ (use the tag to emulate the implicit behavior
+ when serializing a list/array). When a tag is
+ specified, any records with different tags are silently omitted. The
+ tag is ignored. The tag is ignores for fixed-length prefixes.
+
+ The binary stream containing the serialized records.
+ The prefix style used in the data.
+ The tag of records to return (if non-positive, then no tag is
+ expected and all records are returned).
+ On a field-by-field basis, the type of object to deserialize (can be null if "type" is specified).
+ The type of object to deserialize (can be null if "resolver" is specified).
+ The sequence of deserialized objects.
+ Additional information about this serialization operation.
+
+
+
+ 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
+ are directly comparable to serializing multiple items in succession
+ (use the tag to emulate the implicit behavior
+ when serializing a list/array). When a tag is
+ specified, any records with different tags are silently omitted. The
+ tag is ignored. The tag is ignores for fixed-length prefixes.
+
+ The type of object to deserialize.
+ The binary stream containing the serialized records.
+ The prefix style used in the data.
+ The tag of records to return (if non-positive, then no tag is
+ expected and all records are returned).
+ The sequence of deserialized objects.
+
+
+
+ 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
+ are directly comparable to serializing multiple items in succession
+ (use the tag to emulate the implicit behavior
+ when serializing a list/array). When a tag is
+ specified, any records with different tags are silently omitted. The
+ tag is ignored. The tag is ignores for fixed-length prefixes.
+
+ The type of object to deserialize.
+ The binary stream containing the serialized records.
+ The prefix style used in the data.
+ The tag of records to return (if non-positive, then no tag is
+ expected and all records are returned).
+ The sequence of deserialized objects.
+ Additional information about this serialization operation.
+
+
+
+ Writes a protocol-buffer representation of the given instance to the supplied stream,
+ with a length-prefix. This is useful for socket programming,
+ as DeserializeWithLengthPrefix can be used to read the single object back
+ from an ongoing stream.
+
+ The type being serialized.
+ The existing instance to be serialized (cannot be null).
+ How to encode the length prefix.
+ The destination stream to write to.
+ The tag used as a prefix to each record (only used with base-128 style prefixes).
+
+
+
+ Writes a protocol-buffer representation of the given instance to the supplied stream,
+ with a length-prefix. This is useful for socket programming,
+ as DeserializeWithLengthPrefix can be used to read the single object back
+ from an ongoing stream.
+
+ The type being serialized.
+ The existing instance to be serialized (cannot be null).
+ How to encode the length prefix.
+ The destination stream to write to.
+ The tag used as a prefix to each record (only used with base-128 style prefixes).
+ Additional information about this serialization operation.
+
+
+
+ Applies a protocol-buffer stream to an existing instance (which may be null).
+
+ The type (including inheritance) to consider.
+ The existing instance to be modified (can be null).
+ The binary stream to apply to the instance (cannot be null).
+ 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.
+
+
+
+ Applies a protocol-buffer stream to an existing instance (which may be null).
+
+ The type (including inheritance) to consider.
+ The existing instance to be modified (can be null).
+ The binary stream to apply to the instance (cannot be null).
+ 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.
+ Additional information about this serialization operation.
+
+
+
+ Applies a protocol-buffer stream to an existing instance (which may be null).
+
+ The type (including inheritance) to consider.
+ The existing instance to be modified (can be null).
+ The binary stream to apply to the instance (cannot be null).
+ The number of bytes to consume.
+ 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.
+
+
+
+ Applies a protocol-buffer stream to an existing instance (which may be null).
+
+ The type (including inheritance) to consider.
+ The existing instance to be modified (can be null).
+ The binary stream to apply to the instance (cannot be null).
+ The number of bytes to consume (or -1 to read to the end of the stream).
+ 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.
+ Additional information about this serialization operation.
+
+
+
+ Applies a protocol-buffer reader to an existing instance (which may be null).
+
+ The type (including inheritance) to consider.
+ The existing instance to be modified (can be null).
+ The reader to apply to the instance (cannot be null).
+ 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.
+
+
+
+ This is the more "complete" version of Deserialize, which handles single instances of mapped types.
+ The value is read as a complete field, including field-header and (for sub-objects) a
+ length-prefix..kmc
+
+ In addition to that, this provides support for:
+ - basic values; individual int / string / Guid / etc
+ - IList sets of any type handled by TryDeserializeAuxiliaryType
+
+
+
+
+ Creates a new runtime model, to which the caller
+ can add support for a range of types. A model
+ can be used "as is", or can be compiled for
+ optimal performance.
+
+
+
+
+ Applies common proxy scenarios, resolving the actual type to consider
+
+
+
+
+ Indicates whether the supplied type is explicitly modelled by the model
+
+
+
+
+ Provides the key that represents a given type in the current model.
+ The type is also normalized for proxies at the same time.
+
+
+
+
+ Provides the key that represents a given type in the current model.
+
+
+
+
+ Writes a protocol-buffer representation of the given instance to the supplied stream.
+
+ Represents the type (including inheritance) to consider.
+ The existing instance to be serialized (cannot be null).
+ The destination stream to write to.
+
+
+
+ Applies a protocol-buffer stream to an existing instance (which may be null).
+
+ Represents the type (including inheritance) to consider.
+ The existing instance to be modified (can be null).
+ The binary stream to apply to the instance (cannot be null).
+ 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.
+
+
+
+ Create a deep clone of the supplied instance; any sub-items are also cloned.
+
+
+
+
+ Indicates that while an inheritance tree exists, the exact type encountered was not
+ specified in that hierarchy and cannot be processed.
+
+
+
+
+ Indicates that the given type was not expected, and cannot be processed.
+
+
+
+
+ Indicates that the given type cannot be constructed; it may still be possible to
+ deserialize into existing instances.
+
+
+
+
+ Returns true if the type supplied is either a recognised contract type,
+ or a *list* of a recognised contract type.
+
+ Note that primitives always return false, even though the engine
+ will, if forced, try to serialize such
+ True if this type is recognised as a serializable entity, else false
+
+
+
+ Returns true if the type supplied is a basic type with inbuilt handling,
+ a recognised contract type, or a *list* of a basic / contract type.
+
+
+
+
+ Returns true if the type supplied is a basic type with inbuilt handling,
+ or a *list* of a basic type with inbuilt handling
+
+
+
+
+ Suggest a .proto definition for the given type
+
+ The type to generate a .proto definition for, or null to generate a .proto that represents the entire model
+ The .proto definition as a string
+
+
+
+ Creates a new IFormatter that uses protocol-buffer [de]serialization.
+
+ A new IFormatter to be used during [de]serialization.
+ The type of object to be [de]deserialized by the formatter.
+
+
+
+ Used to provide custom services for writing and parsing type names when using dynamic types. Both parsing and formatting
+ are provided on a single API as it is essential that both are mapped identically at all times.
+
+
+
+
+ Indicates the type of callback to be used
+
+
+
+
+ Invoked before an object is serialized
+
+
+
+
+ Invoked after an object is serialized
+
+
+
+
+ Invoked before an object is deserialized (or when a new instance is created)
+
+
+
+
+ Invoked after an object is deserialized
+
+
+
+
+ Returns a sequence of the Type instances that can be
+ processed by this model.
+
+
+
+
+ Suggest a .proto definition for the given type
+
+ The type to generate a .proto definition for, or null to generate a .proto that represents the entire model
+ The .proto definition as a string
+
+
+
+ Adds support for an additional type in this model, optionally
+ appplying inbuilt patterns. If the type is already known to the
+ model, the existing type is returned **without** applying
+ any additional behaviour.
+
+ Inbuilt patterns include:
+ [ProtoContract]/[ProtoMember(n)]
+ [DataContract]/[DataMember(Order=n)]
+ [XmlType]/[XmlElement(Order=n)]
+ [On{Des|S}erializ{ing|ed}]
+ ShouldSerialize*/*Specified
+
+ The type to be supported
+ Whether to apply the inbuilt configuration patterns (via attributes etc), or
+ just add the type with no additional configuration (the type must then be manually configured).
+ The MetaType representing this type, allowing
+ further configuration.
+
+
+
+ Verifies that the model is still open to changes; if not, an exception is thrown
+
+
+
+
+ Prevents further changes to this model
+
+
+
+
+ Provides the key that represents a given type in the current model.
+
+
+
+
+ Writes a protocol-buffer representation of the given instance to the supplied stream.
+
+ Represents the type (including inheritance) to consider.
+ The existing instance to be serialized (cannot be null).
+ The destination stream to write to.
+
+
+
+ Applies a protocol-buffer stream to an existing instance (which may be null).
+
+ Represents the type (including inheritance) to consider.
+ The existing instance to be modified (can be null).
+ The binary stream to apply to the instance (cannot be null).
+ 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.
+
+
+
+ Compiles the serializers individually; this is *not* a full
+ standalone compile, but can significantly boost performance
+ while allowing additional types to be added.
+
+ An in-place compile can access non-public types / members
+
+
+
+ Fully compiles the current model into a static-compiled model instance
+
+ A full compilation is restricted to accessing public types / members
+ An instance of the newly created compiled type-model
+
+
+
+ Fully compiles the current model into a static-compiled serialization dll
+ (the serialization dll still requires protobuf-net for support services).
+
+ A full compilation is restricted to accessing public types / members
+ The name of the TypeModel class to create
+ The path for the new dll
+ An instance of the newly created compiled type-model
+
+
+
+ Fully compiles the current model into a static-compiled serialization dll
+ (the serialization dll still requires protobuf-net for support services).
+
+ A full compilation is restricted to accessing public types / members
+ An instance of the newly created compiled type-model
+
+
+
+ Designate a factory-method to use to create instances of any type; note that this only affect types seen by the serializer *after* setting the factory.
+
+
+
+
+ Global default that
+ enables/disables automatic tag generation based on the existing name / order
+ of the defined members. See
+ for usage and important warning / explanation.
+ You must set the global default before attempting to serialize/deserialize any
+ impacted type.
+
+
+
+
+ Global default that determines whether types are considered serializable
+ if they have [DataContract] / [XmlType]. With this enabled, ONLY
+ types marked as [ProtoContract] are added automatically.
+
+
+
+
+ Global switch that enables or disables the implicit
+ handling of "zero defaults"; meanning: if no other default is specified,
+ it assumes bools always default to false, integers to zero, etc.
+
+ If this is disabled, no such assumptions are made and only *explicit*
+ default values are processed. This is enabled by default to
+ preserve similar logic to v1.
+
+
+
+
+ Global switch that determines whether types with a .ToString() and a Parse(string)
+ should be serialized as strings.
+
+
+
+
+ The default model, used to support ProtoBuf.Serializer
+
+
+
+
+ Obtains the MetaType associated with a given Type for the current model,
+ allowing additional configuration.
+
+
+
+
+ Should serializers be compiled on demand? It may be useful
+ to disable this for debugging purposes.
+
+
+
+
+ Should support for unexpected types be added automatically?
+ If false, an exception is thrown when unexpected types
+ are encountered.
+
+
+
+
+ The amount of time to wait if there are concurrent metadata access operations
+
+
+
+
+ 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.
+
+
+
+
+ Represents configuration options for compiling a model to
+ a standalone assembly.
+
+
+
+
+ Import framework options from an existing type
+
+
+
+
+ The TargetFrameworkAttribute FrameworkName value to burn into the generated assembly
+
+
+
+
+ The TargetFrameworkAttribute FrameworkDisplayName value to burn into the generated assembly
+
+
+
+
+ The name of the TypeModel class to create
+
+
+
+
+ The path for the new dll
+
+
+
+
+ The runtime version for the generated assembly
+
+
+
+
+ The runtime version for the generated assembly
+
+
+
+
+ The acecssibility of the generated serializer
+
+
+
+
+ Type accessibility
+
+
+
+
+ Available to all callers
+
+
+
+
+ Available to all callers in the same assembly, or assemblies specified via [InternalsVisibleTo(...)]
+
+
+
+
+ Contains the stack-trace of the owning code when a lock-contention scenario is detected
+
+
+
+
+ The stack-trace of the code that owned the lock when a lock-contention scenario occurred
+
+
+
+
+ Event-type that is raised when a lock-contention scenario is detected
+
+
+
+
+ Represents an inherited type in a type hierarchy.
+
+
+
+
+ Creates a new SubType instance.
+
+ The field-number that is used to encapsulate the data (as a nested
+ message) for the derived dype.
+ The sub-type to be considered.
+ Specific encoding style to use; in particular, Grouped can be used to avoid buffering, but is not the default.
+
+
+
+ The field-number that is used to encapsulate the data (as a nested
+ message) for the derived dype.
+
+
+
+
+ The sub-type to be considered.
+
+
+
+
+ Event arguments needed to perform type-formatting functions; this could be resolving a Type to a string suitable for serialization, or could
+ be requesting a Type from a string. If no changes are made, a default implementation will be used (from the assembly-qualified names).
+
+
+
+
+ The type involved in this map; if this is initially null, a Type is expected to be provided for the string in FormattedName.
+
+
+
+
+ The formatted-name involved in this map; if this is initially null, a formatted-name is expected from the type in Type.
+
+
+
+
+ Delegate type used to perform type-formatting functions; the sender originates as the type-model.
+
+
+
+
+ Represents a member (property/field) that is mapped to a protobuf field
+
+
+
+
+ Creates a new ValueMember instance
+
+
+
+
+ Creates a new ValueMember instance
+
+
+
+
+ Specifies methods for working with optional data members.
+
+ Provides a method (null for none) to query whether this member should
+ be serialized; it must be of the form "bool {Method}()". The member is only serialized if the
+ method returns true.
+ Provides a method (null for none) to indicate that a member was
+ deserialized; it must be of the form "void {Method}(bool)", and will be called with "true"
+ when data is found.
+
+
+
+ The number that identifies this member in a protobuf stream
+
+
+
+
+ Gets the member (field/property) which this member relates to.
+
+
+
+
+ Within a list / array / etc, the type of object for each item in the list (especially useful with ArrayList)
+
+
+
+
+ The underlying type of the member
+
+
+
+
+ For abstract types (IList etc), the type of concrete object to create (if required)
+
+
+
+
+ The type the defines the member
+
+
+
+
+ The default value of the item (members with this value will not be serialized)
+
+
+
+
+ Specifies the rules used to process the field; this is used to determine the most appropriate
+ wite-type, but also to describe subtypes within that wire-type (such as SignedVariant)
+
+
+
+
+ Indicates whether this field should follow strict encoding rules; this means (for example) that if a "fixed32"
+ is encountered when "variant" is defined, then it will fail (throw an exception) when parsing. Note that
+ when serializing the defined type is always used.
+
+
+
+
+ Indicates whether this field should use packed encoding (which can save lots of space for repeated primitive values).
+ This option only applies to list/array data of primitive types (int, double, etc).
+
+
+
+
+ Indicates whether this field should *repace* existing values (the default is false, meaning *append*).
+ This option only applies to list/array data.
+
+
+
+
+ Indicates whether this field is mandatory.
+
+
+
+
+ Enables full object-tracking/full-graph support.
+
+
+
+
+ Embeds the type information into the stream, allowing usage with types not known in advance.
+
+
+
+
+ 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).
+
+
+
+
+ Should lists have extended support for null values? Note this makes the serialization less efficient.
+
+
+
+
+ Specifies the type of prefix that should be applied to messages.
+
+
+
+
+ No length prefix is applied to the data; the data is terminated only be the end of the stream.
+
+
+
+
+ A base-128 length prefix is applied to the data (efficient for short messages).
+
+
+
+
+ A fixed-length (little-endian) length prefix is applied to the data (useful for compatibility).
+
+
+
+
+ A fixed-length (big-endian) length prefix is applied to the data (useful for compatibility).
+
+
+
+
+ Indicates that a type is defined for protocol-buffer serialization.
+
+
+
+
+ Gets or sets the defined name of the type.
+
+
+
+
+ Gets or sets the fist offset to use with implicit field tags;
+ only uesd if ImplicitFields is set.
+
+
+
+
+ If specified, alternative contract markers (such as markers for XmlSerailizer or DataContractSerializer) are ignored.
+
+
+
+
+ If specified, do NOT treat this type as a list, even if it looks like one.
+
+
+
+
+ Gets or sets the mechanism used to automatically infer field tags
+ for members. This option should be used in advanced scenarios only.
+ Please review the important notes against the ImplicitFields enumeration.
+
+
+
+
+ Enables/disables automatic tag generation based on the existing name / order
+ of the defined members. This option is not used for members marked
+ with ProtoMemberAttribute, as intended to provide compatibility with
+ WCF serialization. WARNING: when adding new fields you must take
+ care to increase the Order for new elements, otherwise data corruption
+ may occur.
+
+ If not explicitly specified, the default is assumed from Serializer.GlobalOptions.InferTagFromName.
+
+
+
+ Has a InferTagFromName value been explicitly set? if not, the default from the type-model is assumed.
+
+
+
+
+ Specifies an offset to apply to [DataMember(Order=...)] markers;
+ this is useful when working with mex-generated classes that have
+ a different origin (usually 1 vs 0) than the original data-contract.
+
+ This value is added to the Order of each member.
+
+
+
+
+ If true, the constructor for the type is bypassed during deserialization, meaning any field initializers
+ or other initialization code is skipped.
+
+
+
+
+ Should this type be treated as a reference by default? Please also see the implications of this,
+ as recorded on ProtoMemberAttribute.AsReference
+
+
+
+
+ Used to define protocol-buffer specific behavior for
+ enumerated values.
+
+
+
+
+ Indicates whether this instance has a customised value mapping
+
+ true if a specific value is set
+
+
+
+ Gets or sets the specific value to use for this enum during serialization.
+
+
+
+
+ Gets or sets the defined name of the enum, as used in .proto
+ (this name is not used during serialization).
+
+
+
+
+ Indicates an error during serialization/deserialization of a proto stream.
+
+
+
+ Creates a new ProtoException instance.
+
+
+ Creates a new ProtoException instance.
+
+
+ Creates a new ProtoException instance.
+
+
+ Creates a new ProtoException instance.
+
+
+
+ Indicates that a member should be excluded from serialization; this
+ is only normally used when using implict fields.
+
+
+
+
+ Indicates that a member should be excluded from serialization; this
+ is only normally used when using implict fields. This allows
+ ProtoIgnoreAttribute usage
+ even for partial classes where the individual members are not
+ under direct control.
+
+
+
+
+ Creates a new ProtoPartialIgnoreAttribute instance.
+
+ Specifies the member to be ignored.
+
+
+
+ The name of the member to be ignored.
+
+
+
+
+ Indicates the known-types to support for an individual
+ message. This serializes each level in the hierarchy as
+ a nested message to retain wire-compatibility with
+ other protocol-buffer implementations.
+
+
+
+
+ Creates a new instance of the ProtoIncludeAttribute.
+
+ The unique index (within the type) that will identify this data.
+ The additional type to serialize/deserialize.
+
+
+
+ Creates a new instance of the ProtoIncludeAttribute.
+
+ The unique index (within the type) that will identify this data.
+ The additional type to serialize/deserialize.
+
+
+
+ Gets the unique index (within the type) that will identify this data.
+
+
+
+
+ Gets the additional type to serialize/deserialize.
+
+
+
+
+ Gets the additional type to serialize/deserialize.
+
+
+
+
+ Specifies whether the inherited sype's sub-message should be
+ written with a length-prefix (default), or with group markers.
+
+
+
+
+ Declares a member to be used in protocol-buffer serialization, using
+ the given Tag. A DataFormat may be used to optimise the serialization
+ format (for instance, using zigzag encoding for negative numbers, or
+ fixed-length encoding for large values.
+
+
+
+
+ Compare with another ProtoMemberAttribute for sorting purposes
+
+
+
+
+ Compare with another ProtoMemberAttribute for sorting purposes
+
+
+
+
+ Creates a new ProtoMemberAttribute instance.
+
+ Specifies the unique tag used to identify this member within the type.
+
+
+
+ Gets or sets the original name defined in the .proto; not used
+ during serialization.
+
+
+
+
+ Gets or sets the data-format to be used when encoding this value.
+
+
+
+
+ Gets the unique tag used to identify this member within the type.
+
+
+
+
+ Gets or sets a value indicating whether this member is mandatory.
+
+
+
+
+ Gets a value indicating whether this member is packed.
+ This option only applies to list/array data of primitive types (int, double, etc).
+
+
+
+
+ Indicates whether this field should *repace* existing values (the default is false, meaning *append*).
+ This option only applies to list/array data.
+
+
+
+
+ Enables full object-tracking/full-graph support.
+
+
+
+
+ Embeds the type information into the stream, allowing usage with types not known in advance.
+
+
+
+
+ Gets or sets a value indicating whether this member is packed (lists/arrays).
+
+
+
+
+ Additional (optional) settings that control serialization of members
+
+
+
+
+ Default; no additional options
+
+
+
+
+ Indicates that repeated elements should use packed (length-prefixed) encoding
+
+
+
+
+ Indicates that the given item is required
+
+
+
+
+ Enables full object-tracking/full-graph support
+
+
+
+
+ Embeds the type information into the stream, allowing usage with types not known in advance
+
+
+
+
+ Indicates whether this field should *repace* existing values (the default is false, meaning *append*).
+ This option only applies to list/array data.
+
+
+
+
+ Determines whether the types AsReferenceDefault value is used, or whether this member's AsReference should be used
+
+
+
+
+ Declares a member to be used in protocol-buffer serialization, using
+ the given Tag and MemberName. This allows ProtoMemberAttribute usage
+ even for partial classes where the individual members are not
+ under direct control.
+ A DataFormat may be used to optimise the serialization
+ format (for instance, using zigzag encoding for negative numbers, or
+ fixed-length encoding for large values.
+
+
+
+
+ Creates a new ProtoMemberAttribute instance.
+
+ Specifies the unique tag used to identify this member within the type.
+ Specifies the member to be serialized.
+
+
+
+ The name of the member to be serialized.
+
+
+
+
+ A stateful reader, used to read a protobuf stream. Typical usage would be (sequentially) to call
+ ReadFieldHeader and (after matching the field) an appropriate Read* method.
+
+
+
+
+ Creates a new reader against a stream
+
+ The source stream
+ The model to use for serialization; this can be null, but this will impair the ability to deserialize sub-objects
+ Additional context about this serialization operation
+
+
+
+ Creates a new reader against a stream
+
+ The source stream
+ The model to use for serialization; this can be null, but this will impair the ability to deserialize sub-objects
+ Additional context about this serialization operation
+ The number of bytes to read, or -1 to read until the end of the stream
+
+
+
+ Releases resources used by the reader, but importantly does not Dispose the
+ underlying stream; in many typical use-cases the stream is used for different
+ processes, so it is assumed that the consumer will Dispose their stream separately.
+
+
+
+
+ Reads an unsigned 32-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64
+
+
+
+
+ Reads a signed 16-bit integer from the stream: Variant, Fixed32, Fixed64, SignedVariant
+
+
+
+
+ Reads an unsigned 16-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64
+
+
+
+
+ Reads an unsigned 8-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64
+
+
+
+
+ Reads a signed 8-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant
+
+
+
+
+ Reads a signed 32-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant
+
+
+
+
+ Reads a signed 64-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant
+
+
+
+
+ Reads a string from the stream (using UTF8); supported wire-types: String
+
+
+
+
+ Throws an exception indication that the given value cannot be mapped to an enum.
+
+
+
+
+ Reads a double-precision number from the stream; supported wire-types: Fixed32, Fixed64
+
+
+
+
+ Reads (merges) a sub-message from the stream, internally calling StartSubItem and EndSubItem, and (in between)
+ parsing the message in accordance with the model associated with the reader
+
+
+
+
+ Makes the end of consuming a nested message in the stream; the stream must be either at the correct EndGroup
+ marker, or all fields of the sub-message must have been consumed (in either case, this means ReadFieldHeader
+ should return zero)
+
+
+
+
+ Begins consuming a nested message in the stream; supported wire-types: StartGroup, String
+
+ The token returned must be help and used when callining EndSubItem
+
+
+
+ Reads a field header from the stream, setting the wire-type and retuning the field number. If no
+ more fields are available, then 0 is returned. This methods respects sub-messages.
+
+
+
+
+ Looks ahead to see whether the next field in the stream is what we expect
+ (typically; what we've just finished reading - for example ot read successive list items)
+
+
+
+
+ Compares the streams current wire-type to the hinted wire-type, updating the reader if necessary; for example,
+ a Variant may be updated to SignedVariant. If the hinted wire-type is unrelated then no change is made.
+
+
+
+
+ Verifies that the stream's current wire-type is as expected, or a specialized sub-type (for example,
+ SignedVariant) - in which case the current wire-type is updated. Otherwise an exception is thrown.
+
+
+
+
+ Discards the data for the current field.
+
+
+
+
+ Reads an unsigned 64-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64
+
+
+
+
+ Reads a single-precision number from the stream; supported wire-types: Fixed32, Fixed64
+
+
+
+
+ Reads a boolean value from the stream; supported wire-types: Variant, Fixed32, Fixed64
+
+
+
+
+
+ Reads a byte-sequence from the stream, appending them to an existing byte-sequence (which can be null); supported wire-types: String
+
+
+
+
+ Reads the length-prefix of a message from a stream without buffering additional data, allowing a fixed-length
+ reader to be created.
+
+
+
+
+ Reads a little-endian encoded integer. An exception is thrown if the data is not all available.
+
+
+
+
+ Reads a big-endian encoded integer. An exception is thrown if the data is not all available.
+
+
+
+
+ Reads a varint encoded integer. An exception is thrown if the data is not all available.
+
+
+
+
+ Reads a string (of a given lenth, in bytes) directly from the source into a pre-existing buffer. An exception is thrown if the data is not all available.
+
+
+
+
+ Reads a given number of bytes directly from the source. An exception is thrown if the data is not all available.
+
+
+
+
+ Reads a string (of a given lenth, in bytes) directly from the source. An exception is thrown if the data is not all available.
+
+
+
+
+ Reads the length-prefix of a message from a stream without buffering additional data, allowing a fixed-length
+ reader to be created.
+
+
+
+ The number of bytes consumed; 0 if no data available
+
+
+
+ Copies the current field into the instance as extension data
+
+
+
+
+ Indicates whether the reader still has data remaining in the current sub-item,
+ additionally setting the wire-type for the next field if there is more data.
+ This is used when decoding packed data.
+
+
+
+
+ Utility method, not intended for public use; this helps maintain the root object is complex scenarios
+
+
+
+
+ Reads a Type from the stream, using the model's DynamicTypeFormatting if appropriate; supported wire-types: String
+
+
+
+
+ Merge two objects using the details from the current reader; this is used to change the type
+ of objects when an inheritance relationship is discovered later than usual during deserilazation.
+
+
+
+
+ Gets the number of the field being processed.
+
+
+
+
+ Indicates the underlying proto serialization format on the wire.
+
+
+
+
+ Gets / sets a flag indicating whether strings should be checked for repetition; if
+ true, any repeated UTF-8 byte sequence will result in the same String instance, rather
+ than a second instance of the same string. Enabled by default. Note that this uses
+ a custom interner - the system-wide string interner is not used.
+
+
+
+
+ Addition information about this deserialization operation.
+
+
+
+
+ Returns the position of the current reader (note that this is not necessarily the same as the position
+ in the underlying stream, if multiple readers are used on the same stream)
+
+
+
+
+ Get the TypeModel associated with this reader
+
+
+
+
+ Represents an output stream for writing protobuf data.
+
+ Why is the API backwards (static methods with writer arguments)?
+ See: http://marcgravell.blogspot.com/2010/03/last-will-be-first-and-first-will-be.html
+
+
+
+
+ Write an encapsulated sub-object, using the supplied unique key (reprasenting a type).
+
+ The object to write.
+ The key that uniquely identifies the type within the model.
+ The destination.
+
+
+
+ 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
+ performed.
+
+ The object to write.
+ The key that uniquely identifies the type within the model.
+ The destination.
+
+
+
+ Writes a field-header, indicating the format of the next data we plan to write.
+
+
+
+
+ Writes a byte-array to the stream; supported wire-types: String
+
+
+
+
+ Writes a byte-array to the stream; supported wire-types: String
+
+
+
+
+ Indicates the start of a nested record.
+
+ The instance to write.
+ The destination.
+ A token representing the state of the stream; this token is given to EndSubItem.
+
+
+
+ Indicates the end of a nested record.
+
+ The token obtained from StartubItem.
+ The destination.
+
+
+
+ Creates a new writer against a stream
+
+ The destination stream
+ The model to use for serialization; this can be null, but this will impair the ability to serialize sub-objects
+ Additional context about this serialization operation
+
+
+
+ Flushes data to the underlying stream, and releases any resources. The underlying stream is *not* disposed
+ by this operation.
+
+
+
+
+ Writes any buffered data (if possible) to the underlying stream.
+
+ The writer to flush
+ It is not always possible to fully flush, since some sequences
+ may require values to be back-filled into the byte-stream.
+
+
+
+ Writes an unsigned 32-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64
+
+
+
+
+ Writes a string to the stream; supported wire-types: String
+
+
+
+
+ Writes an unsigned 64-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64
+
+
+
+
+ Writes a signed 64-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant
+
+
+
+
+ Writes an unsigned 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64
+
+
+
+
+ Writes a signed 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant
+
+
+
+
+ Writes an unsigned 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64
+
+
+
+
+ Writes an unsigned 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64
+
+
+
+
+ Writes a signed 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant
+
+
+
+
+ Writes a signed 32-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant
+
+
+
+
+ Writes a double-precision number to the stream; supported wire-types: Fixed32, Fixed64
+
+
+
+
+ Writes a single-precision number to the stream; supported wire-types: Fixed32, Fixed64
+
+
+
+
+ Throws an exception indicating that the given enum cannot be mapped to a serialized value.
+
+
+
+
+ Writes a boolean to the stream; supported wire-types: Variant, Fixed32, Fixed64
+
+
+
+
+ Copies any extension data stored for the instance to the underlying stream
+
+
+
+
+ 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
+ when the attempt is made to write the (incorrect) field. The wire-type is taken from the
+ subsequent call to WriteFieldHeader. Only primitive types can be packed.
+
+
+
+
+ Specifies a known root object to use during reference-tracked serialization
+
+
+
+
+ Writes a Type to the stream, using the model's DynamicTypeFormatting if appropriate; supported wire-types: String
+
+
+
+
+ Addition information about this serialization operation.
+
+
+
+
+ Get the TypeModel associated with this writer
+
+
+
+
+ Additional information about a serialization operation
+
+
+
+
+ Convert a SerializationContext to a StreamingContext
+
+
+
+
+ Convert a StreamingContext to a SerializationContext
+
+
+
+
+ Gets or sets a user-defined object containing additional information about this serialization/deserialization operation.
+
+
+
+
+ A default SerializationContext, with minimal information.
+
+
+
+
+ Gets or sets the source or destination of the transmitted data.
+
+
+
+
+ Provides protocol-buffer serialization capability for concrete, attributed types. This
+ is a *default* model, but custom serializer models are also supported.
+
+
+ Protocol-buffer serialization is a compact binary format, designed to take
+ advantage of sparse data and knowledge of specific data types; it is also
+ extensible, allowing a type to be deserialized / merged even if some data is
+ not recognised.
+
+
+
+
+ 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.
+
+
+
+
+ Suggest a .proto definition for the given type
+
+ The type to generate a .proto definition for
+ The .proto definition as a string
+
+
+
+ Create a deep clone of the supplied instance; any sub-items are also cloned.
+
+
+
+
+ Applies a protocol-buffer stream to an existing instance.
+
+ The type being merged.
+ The existing instance to be modified (can be null).
+ The binary stream to apply to the instance (cannot be null).
+ 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.
+
+
+
+ Creates a new instance from a protocol-buffer stream
+
+ The type to be created.
+ The binary stream to apply to the new instance (cannot be null).
+ A new, initialized instance.
+
+
+
+ Writes a protocol-buffer representation of the given instance to the supplied stream.
+
+ The existing instance to be serialized (cannot be null).
+ The destination stream to write to.
+
+
+
+ Serializes a given instance and deserializes it as a different type;
+ this can be used to translate between wire-compatible objects (where
+ two .NET types represent the same data), or to promote/demote a type
+ through an inheritance hierarchy.
+
+ No assumption of compatibility is made between the types.
+ The type of the object being copied.
+ The type of the new object to be created.
+ The existing instance to use as a template.
+ A new instane of type TNewType, with the data from TOldType.
+
+
+
+ Writes a protocol-buffer representation of the given instance to the supplied SerializationInfo.
+
+ The type being serialized.
+ The existing instance to be serialized (cannot be null).
+ The destination SerializationInfo to write to.
+
+
+
+ Writes a protocol-buffer representation of the given instance to the supplied SerializationInfo.
+
+ The type being serialized.
+ The existing instance to be serialized (cannot be null).
+ The destination SerializationInfo to write to.
+ Additional information about this serialization operation.
+
+
+
+ Writes a protocol-buffer representation of the given instance to the supplied XmlWriter.
+
+ The type being serialized.
+ The existing instance to be serialized (cannot be null).
+ The destination XmlWriter to write to.
+
+
+
+ Applies a protocol-buffer from an XmlReader to an existing instance.
+
+ The type being merged.
+ The existing instance to be modified (cannot be null).
+ The XmlReader containing the data to apply to the instance (cannot be null).
+
+
+
+ Applies a protocol-buffer from a SerializationInfo to an existing instance.
+
+ The type being merged.
+ The existing instance to be modified (cannot be null).
+ The SerializationInfo containing the data to apply to the instance (cannot be null).
+
+
+
+ Applies a protocol-buffer from a SerializationInfo to an existing instance.
+
+ The type being merged.
+ The existing instance to be modified (cannot be null).
+ The SerializationInfo containing the data to apply to the instance (cannot be null).
+ Additional information about this serialization operation.
+
+
+
+ Precompiles the serializer for a given type.
+
+
+
+
+ Creates a new IFormatter that uses protocol-buffer [de]serialization.
+
+ The type of object to be [de]deserialized by the formatter.
+ A new IFormatter to be used during [de]serialization.
+
+
+
+ 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
+ are directly comparable to serializing multiple items in succession
+ (use the tag to emulate the implicit behavior
+ when serializing a list/array). When a tag is
+ specified, any records with different tags are silently omitted. The
+ tag is ignored. The tag is ignores for fixed-length prefixes.
+
+ The type of object to deserialize.
+ The binary stream containing the serialized records.
+ The prefix style used in the data.
+ The tag of records to return (if non-positive, then no tag is
+ expected and all records are returned).
+ The sequence of deserialized objects.
+
+
+
+ Creates a new instance from a protocol-buffer stream that has a length-prefix
+ on data (to assist with network IO).
+
+ The type to be created.
+ The binary stream to apply to the new instance (cannot be null).
+ How to encode the length prefix.
+ A new, initialized instance.
+
+
+
+ Creates a new instance from a protocol-buffer stream that has a length-prefix
+ on data (to assist with network IO).
+
+ The type to be created.
+ The binary stream to apply to the new instance (cannot be null).
+ How to encode the length prefix.
+ The expected tag of the item (only used with base-128 prefix style).
+ A new, initialized instance.
+
+
+
+ Applies a protocol-buffer stream to an existing instance, using length-prefixed
+ data - useful with network IO.
+
+ The type being merged.
+ The existing instance to be modified (can be null).
+ The binary stream to apply to the instance (cannot be null).
+ How to encode the length prefix.
+ 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.
+
+
+
+ Writes a protocol-buffer representation of the given instance to the supplied stream,
+ with a length-prefix. This is useful for socket programming,
+ as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back
+ from an ongoing stream.
+
+ The type being serialized.
+ The existing instance to be serialized (cannot be null).
+ How to encode the length prefix.
+ The destination stream to write to.
+
+
+
+ Writes a protocol-buffer representation of the given instance to the supplied stream,
+ with a length-prefix. This is useful for socket programming,
+ as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back
+ from an ongoing stream.
+
+ The type being serialized.
+ The existing instance to be serialized (cannot be null).
+ How to encode the length prefix.
+ The destination stream to write to.
+ The tag used as a prefix to each record (only used with base-128 style prefixes).
+
+
+ Indicates the number of bytes expected for the next message.
+ The stream containing the data to investigate for a length.
+ The algorithm used to encode the length.
+ The length of the message, if it could be identified.
+ True if a length could be obtained, false otherwise.
+
+
+ Indicates the number of bytes expected for the next message.
+ The buffer containing the data to investigate for a length.
+ The offset of the first byte to read from the buffer.
+ The number of bytes to read from the buffer.
+ The algorithm used to encode the length.
+ The length of the message, if it could be identified.
+ True if a length could be obtained, false otherwise.
+
+
+
+ Releases any internal buffers that have been reserved for efficiency; this does not affect any serialization
+ operations; simply: it can be used (optionally) to release the buffers for garbage collection (at the expense
+ of having to re-allocate a new buffer for the next operation, rather than re-use prior buffers).
+
+
+
+
+ Provides non-generic access to the default serializer.
+
+
+
+
+ Create a deep clone of the supplied instance; any sub-items are also cloned.
+
+
+
+
+ Writes a protocol-buffer representation of the given instance to the supplied stream.
+
+ The existing instance to be serialized (cannot be null).
+ The destination stream to write to.
+
+
+
+ Creates a new instance from a protocol-buffer stream
+
+ The type to be created.
+ The binary stream to apply to the new instance (cannot be null).
+ A new, initialized instance.
+
+
+ Applies a protocol-buffer stream to an existing instance.
+ The existing instance to be modified (cannot be null).
+ The binary stream to apply to the instance (cannot be null).
+ The updated instance
+
+
+
+ Writes a protocol-buffer representation of the given instance to the supplied stream,
+ with a length-prefix. This is useful for socket programming,
+ as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back
+ from an ongoing stream.
+
+ The existing instance to be serialized (cannot be null).
+ How to encode the length prefix.
+ The destination stream to write to.
+ The tag used as a prefix to each record (only used with base-128 style prefixes).
+
+
+
+ Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed
+ data - useful with network IO.
+
+ The existing instance to be modified (can be null).
+ The binary stream to apply to the instance (cannot be null).
+ How to encode the length prefix.
+ Used to resolve types on a per-field basis.
+ 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.
+
+
+
+ Indicates whether the supplied type is explicitly modelled by the model
+
+
+
+
+ Global switches that change the behavior of protobuf-net
+
+
+
+
+
+
+
+
+
+ Maps a field-number to a type
+
+
+
+
+ Perform the steps necessary to serialize this data.
+
+ The value to be serialized.
+ The writer entity that is accumulating the output data.
+
+
+
+ Perform the steps necessary to deserialize this data.
+
+ The current value, if appropriate.
+ The reader providing the input data.
+ The updated / replacement value.
+
+
+ Emit the IL necessary to perform the given actions
+ to serialize this data.
+
+ Details and utilities for the method being generated.
+ The source of the data to work against;
+ If the value is only needed once, then LoadValue is sufficient. If
+ the value is needed multiple times, then note that a "null"
+ means "the top of the stack", in which case you should create your
+ own copy - GetLocalWithValue.
+
+
+
+ Emit the IL necessary to perform the given actions to deserialize this data.
+
+ Details and utilities for the method being generated.
+ For nested values, the instance holding the values; note
+ that this is not always provided - a null means not supplied. Since this is always
+ a variable or argument, it is not necessary to consume this value.
+
+
+
+ The type that this serializer is intended to work for.
+
+
+
+
+ Indicates whether a Read operation replaces the existing value, or
+ extends the value. If false, the "value" parameter to Read is
+ discarded, and should be passed in as null.
+
+
+
+
+ Now all Read operations return a value (although most do); if false no
+ value should be expected.
+
+
+
+
+ Used to hold particulars relating to nested objects. This is opaque to the caller - simply
+ give back the token you are given at the end of an object.
+
+
+
+
+ Indicates the encoding used to represent an individual value in a protobuf stream
+
+
+
+
+ Represents an error condition
+
+
+
+
+ Base-128 variant-length encoding
+
+
+
+
+ Fixed-length 8-byte encoding
+
+
+
+
+ Length-variant-prefixed encoding
+
+
+
+
+ Indicates the start of a group
+
+
+
+
+ Indicates the end of a group
+
+
+
+
+ Fixed-length 4-byte encoding
+ 10
+
+
+
+ This is not a formal wire-type in the "protocol buffers" spec, but
+ denotes a variant integer that should be interpreted using
+ zig-zag semantics (so -ve numbers aren't a significant overhead)
+
+
+
+