├── .gitignore ├── LICENSE ├── README.md ├── lib └── .gitignore ├── nuspec ├── Platform.NET.nuspec └── Platform.Xml.Serialization.nuspec ├── src ├── .nuget │ ├── NuGet.Config │ ├── NuGet.exe │ └── NuGet.targets ├── Platform.NET.sln ├── Platform.Xml.Serialization │ ├── AbstractGetterSetter.cs │ ├── AbstractXmlConfigurationSectionHandler.cs │ ├── Attributes │ │ ├── XmlSerializationAttribute.cs │ │ └── XmlTypeSerializerTypeAttribute.cs │ ├── CachingXmlSerializerFactory.cs │ ├── ColorSerializer.cs │ ├── ComplexTypeTypeSerializer.cs │ ├── DictionaryTypeSerializer.cs │ ├── EnumTypeSerializer.cs │ ├── FieldGetterSetter.cs │ ├── GuidSerializer.cs │ ├── IGetterSetter.cs │ ├── ISerializationStateListener.cs │ ├── ISerializationUnhandledMarkupListener.cs │ ├── ISerializationUnknownNodeListener.cs │ ├── IVariableSubstitutor.cs │ ├── IXmlDeserializationEndListener.cs │ ├── IXmlDeserializationStartListener.cs │ ├── IXmlListElementDynamicTypeProvider.cs │ ├── IXmlPolymorphicTypeProvider.cs │ ├── IXmlSerializationEndListener.cs │ ├── IXmlSerializationShouldSerializeProvider.cs │ ├── IXmlSerializationStartListener.cs │ ├── IXmlSerializerSerializable.cs │ ├── ListTypeSerializer.cs │ ├── Platform.Xml.Serialization.csproj │ ├── Platform.Xml.Serialization.wdx │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── PropertyGetterSetter.cs │ ├── RuntimeTypeTypeSerializer.cs │ ├── SerializationContext.cs │ ├── SerializationMemberInfo.cs │ ├── SerializationParameters.cs │ ├── SerializeMembers.cs │ ├── SerializerOptions.cs │ ├── StandardTypeSerializerFactory.cs │ ├── StringableTypeSerializer.cs │ ├── TextResources.Designer.cs │ ├── TextResources.resx │ ├── TypeSerializerCache.cs │ ├── TypeSerializerFactory.cs │ ├── TypeSerializers │ │ ├── AnyTypeTypeSerializer.cs │ │ ├── ComplexTypeTypeSerializer.cs │ │ ├── DateTimeTypeSerializer.cs │ │ ├── DictionaryTypeSerializer.cs │ │ ├── EnumTypeSerializer.cs │ │ └── ListTypeSerializer.cs │ ├── XmlApproachAttribute.cs │ ├── XmlAttributeAttribute.cs │ ├── XmlCDataAttribute.cs │ ├── XmlConfigurationBlockSectionHandler.cs │ ├── XmlDateTimeFormatAttribute.cs │ ├── XmlDictionaryElementTypeAttribute.cs │ ├── XmlElementAttribute.cs │ ├── XmlEnvironmentVariableSubstitutor.cs │ ├── XmlExcludeAttribute.cs │ ├── XmlFormatAttribute.cs │ ├── XmlListElementAttribute.cs │ ├── XmlListElementDynamicTypeProviderAttribute.cs │ ├── XmlNodeNodeTypeSerializer.cs │ ├── XmlPolymorphicTypeAttribute.cs │ ├── XmlReaderHelper.cs │ ├── XmlSerializationAttribute.cs │ ├── XmlSerializeBaseAttribute.cs │ ├── XmlSerializeEnumAsIntAttribute.cs │ ├── XmlSerializedObjectLoader.cs │ ├── XmlSerializer.cs │ ├── XmlSerializerException.cs │ ├── XmlSerializerFactory.cs │ ├── XmlSerializerNamespaces.cs │ ├── XmlTextAttribute.cs │ ├── XmlTreatAsNullIfEmptyAttribute.cs │ ├── XmlTypeSerializerTypeAttribute.cs │ ├── XmlVariableSubstitutionAttribute.cs │ ├── XmlVerifyRuntimeTypeAttribute.cs │ ├── datetimetypeserializer.cs │ ├── typeserializer.cs │ └── typeserializerwithsimpletextsupport.cs └── Platform │ ├── AbstractMeter.cs │ ├── AbstractModel.cs │ ├── AbstractRunnable.cs │ ├── AbstractTask.cs │ ├── Action.cs │ ├── ActionUtils.cs │ ├── ActivatorUtils.cs │ ├── ArrayEqualityComparer.cs │ ├── ArrayUtils.cs │ ├── AssemblyInfo.cs │ ├── AutoLock.cs │ ├── BigEndianByteQuad.cs │ ├── CachedValue.cs │ ├── CharUtils.cs │ ├── Collections │ ├── ArrayQueue.cs │ ├── BlockingQueue.cs │ ├── BoundedFifoBuffer.cs │ ├── BufferOverflowException.cs │ ├── BufferUnderflowException.cs │ ├── CircularFifoBuffer.cs │ ├── CollectionBase.cs │ ├── CollectionEnumerable.cs │ ├── DictionaryExtensions.cs │ ├── IBlockingQueue.cs │ ├── IQueue.cs │ ├── IReadOnlyCollection.cs │ ├── IReadOnlyList.cs │ ├── ListUtils.cs │ ├── QueueBase.cs │ ├── ReadOnlyCollectionReadOnlyListAdapter.cs │ ├── ReadOnlyList.cs │ ├── ReferenceDictionary.cs │ ├── ReferenceDictionaryEventArgs.cs │ ├── TimedReferenceDictionary.cs │ └── WeakReferenceDictionary.cs │ ├── ComparisonComparator.cs │ ├── ConfigurationBlock.cs │ ├── ConverterUtils.cs │ ├── DataflowDirection.cs │ ├── DateTimeFormats.cs │ ├── Direction.cs │ ├── EnumerableUtils.cs │ ├── EnvironmentUtils.cs │ ├── Func.cs │ ├── FuncUtils.cs │ ├── HashValue.cs │ ├── IAutoLock.cs │ ├── ICacheable.cs │ ├── IKeyed.cs │ ├── IKeyedValued.cs │ ├── IMeter.cs │ ├── IModel.cs │ ├── INamed.cs │ ├── IO │ ├── ChunkingStream.cs │ ├── FifoStream.cs │ ├── ILineReader.cs │ ├── IStreamWithEvents.cs │ ├── InteractiveCryptoStream.cs │ ├── MeteringStream.cs │ ├── PartialStream.cs │ ├── StreamCopier.cs │ ├── StreamUtils.cs │ ├── StreamWrapper.cs │ └── TextReaderUtils.cs │ ├── IObjectCache.cs │ ├── IOwned.cs │ ├── IRefreshable.cs │ ├── IRunnable.cs │ ├── ISyncLocked.cs │ ├── ITask.cs │ ├── ITuple.cs │ ├── IValued.cs │ ├── IWrapperObject.cs │ ├── Int32Utils.cs │ ├── LeftOrRight.cs │ ├── Linq │ ├── ExpressionComparer.cs │ ├── ExpressionComparerOptions.cs │ ├── ExpressionEqualityComparer.cs │ ├── ExpressionHasher.cs │ ├── ExpressionVisitor.cs │ └── LambdaExpressionCompilerWithMemberPopulateSupport.cs │ ├── LogicalOperation.cs │ ├── MathUtils.cs │ ├── MeterEventArgs.cs │ ├── MeterWrapper.cs │ ├── MutableMeter.cs │ ├── NamedUtils.cs │ ├── Network │ └── Time │ │ ├── NetworkTimeClient.cs │ │ ├── NtpNetworkTimeClient.cs │ │ └── NtpPacket.cs │ ├── NumericConstants.cs │ ├── ObjectActivator.cs │ ├── ObjectReferenceIdentityEqualityComparer.cs │ ├── Pair.cs │ ├── Platform.1.0.0.341.nupkg │ ├── Platform.NET.nuspec │ ├── Platform.csproj │ ├── PredicateUtils.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── PropertyWiseEqualityComparer.cs │ ├── Quad.cs │ ├── Reference.cs │ ├── References │ ├── IReferenceQueue.cs │ ├── NotifyingWeakReference.cs │ ├── Reference.cs │ ├── ReferenceQueueBase.cs │ ├── TimedReference.cs │ └── WeakReference.cs │ ├── Reflection │ ├── ConstructorInfoUtils.cs │ ├── MemberInfoUtils.cs │ └── MethodInfoUtils.cs │ ├── ReownedMeter.cs │ ├── Runtime │ └── Interop │ │ └── MarshalUtils.cs │ ├── SoftReference.cs │ ├── StopRequestedException.cs │ ├── StringUriUtils.cs │ ├── StringUtils.cs │ ├── TaskExceptionEventArgs.cs │ ├── TaskUtils.cs │ ├── Text │ ├── CharArrayReader.cs │ ├── RegularExpressions │ │ ├── RegexBasedPredicateHelper.cs │ │ └── RegexCache.cs │ └── TextConversion.cs │ ├── Threading │ ├── MeterValueEvent.cs │ └── ThreadPriorityContext.cs │ ├── Triple.cs │ ├── TypeUtils.cs │ ├── Utilities │ ├── InvocationQueue.cs │ └── RecylingObjectPool.cs │ ├── Validation │ ├── BaseValidationAttribute.cs │ ├── DefaultPropertyValidator.cs │ ├── DefaultPropertyValidatorProvider.cs │ ├── DefaultValueAttribute.cs │ ├── IPropertyValidationContext.cs │ ├── IValidator.cs │ ├── ObjectExtensions.cs │ ├── PropertyValidationContext.cs │ ├── PropertyValidator.cs │ ├── PropertyValidatorProvider.cs │ ├── SizeConstraintAttribute.cs │ ├── SizeFlexibility.cs │ ├── UniqueAttribute.cs │ ├── UnsetValueAttribute.cs │ ├── ValidationAttribute.cs │ ├── ValidationContext.cs │ ├── ValidationException.cs │ ├── ValidationResult.cs │ ├── Validator.cs │ ├── ValidatorFactory.cs │ ├── ValidatorOptions.cs │ ├── Validators │ │ ├── ExpressionTreeBasedValidator.cs │ │ ├── ExpressionTreeBasedValidatorFactory.cs │ │ └── StringExpressionParser.cs │ ├── ValueExpressionConstraintAttribute.cs │ ├── ValuePatternConstraint.cs │ ├── ValueRangeConstraintAttribute.cs │ └── ValueRequiredAttribute.cs │ ├── ValueBox.cs │ └── WeakEventHandlerProxy.cs └── tests ├── Platform.Tests ├── EnumerableUtilsTests.cs ├── FifoBufferTests.cs ├── InvocationQueueTests.cs ├── ListUtilsTests.cs ├── MathUtilsTests.cs ├── MethodInfoUtilsTests.cs ├── Platform.Tests.csproj ├── Properties │ └── AssemblyInfo.cs ├── TestPropertyWiseEqualityComparer.cs ├── TextConversionTests.cs ├── TypeUtilsTests.cs ├── Validation │ ├── PageRequest.cs │ ├── Person.cs │ ├── SearchRequest.cs │ ├── TestBasicValidation.cs │ └── User.cs └── packages.config └── Platform.Xml.Serialization.Tests ├── BasicSerializerTests.cs ├── Customer.cs ├── DictionaryTests.cs ├── DynamicPersonTypeProvider.cs ├── Employee.cs ├── FormatTests.cs ├── FriendlyPerson.cs ├── InheritanceTests.cs ├── InnerTextTest.cs ├── ListTest.cs ├── NamespaceTests.cs ├── Person.cs ├── Platform.Xml.Serialization.Tests.csproj ├── Properties └── AssemblyInfo.cs ├── SerializeIfNullTests.cs ├── XmlNodeTests.cs └── packages.config /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | 11 | [Dd]ebug/ 12 | [Rr]elease/ 13 | x64/ 14 | build/ 15 | [Bb]in/ 16 | [Oo]bj/ 17 | 18 | # MSTest test Results 19 | [Tt]est[Rr]esult*/ 20 | [Bb]uild[Ll]og.* 21 | 22 | *_i.c 23 | *_p.c 24 | *.ilk 25 | *.meta 26 | *.obj 27 | *.pch 28 | *.pdb 29 | *.pgc 30 | *.pgd 31 | *.rsp 32 | *.sbr 33 | *.tlb 34 | *.tli 35 | *.tlh 36 | *.tmp 37 | *.tmp_proj 38 | *.log 39 | *.vspscc 40 | *.vssscc 41 | .builds 42 | *.pidb 43 | *.log 44 | *.scc 45 | 46 | # Visual C++ cache files 47 | ipch/ 48 | *.aps 49 | *.ncb 50 | *.opensdf 51 | *.sdf 52 | *.cachefile 53 | 54 | # Visual Studio profiler 55 | *.psess 56 | *.vsp 57 | *.vspx 58 | 59 | # Guidance Automation Toolkit 60 | *.gpState 61 | 62 | # ReSharper is a .NET coding add-in 63 | _ReSharper*/ 64 | *.[Rr]e[Ss]harper 65 | 66 | # TeamCity is a build add-in 67 | _TeamCity* 68 | 69 | # DotCover is a Code Coverage Tool 70 | *.dotCover 71 | 72 | # NCrunch 73 | *.ncrunch* 74 | .*crunch*.local.xml 75 | 76 | # Installshield output folder 77 | [Ee]xpress/ 78 | 79 | # DocProject is a documentation generator add-in 80 | DocProject/buildhelp/ 81 | DocProject/Help/*.HxT 82 | DocProject/Help/*.HxC 83 | DocProject/Help/*.hhc 84 | DocProject/Help/*.hhk 85 | DocProject/Help/*.hhp 86 | DocProject/Help/Html2 87 | DocProject/Help/html 88 | 89 | # Click-Once directory 90 | publish/ 91 | 92 | # Publish Web Output 93 | *.Publish.xml 94 | *.pubxml 95 | 96 | # NuGet Packages Directory 97 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 98 | #packages/ 99 | 100 | # Windows Azure Build Output 101 | csx 102 | *.build.csdef 103 | 104 | # Windows Store app package directory 105 | AppPackages/ 106 | 107 | # Others 108 | sql/ 109 | *.Cache 110 | ClientBin/ 111 | [Ss]tyle[Cc]op.* 112 | ~$* 113 | *~ 114 | *.dbmdl 115 | *.[Pp]ublish.xml 116 | *.pfx 117 | *.publishsettings 118 | 119 | # RIA/Silverlight projects 120 | Generated_Code/ 121 | 122 | # Backup & report files from converting an old project file to a newer 123 | # Visual Studio version. Backup files are not needed, because we have git ;-) 124 | _UpgradeReport_Files/ 125 | Backup*/ 126 | UpgradeLog*.XML 127 | UpgradeLog*.htm 128 | 129 | # SQL Server files 130 | App_Data/*.mdf 131 | App_Data/*.ldf 132 | 133 | # ========================= 134 | # Windows detritus 135 | # ========================= 136 | 137 | # Windows image file caches 138 | Thumbs.db 139 | ehthumbs.db 140 | 141 | # Folder config file 142 | Desktop.ini 143 | 144 | # Recycle Bin used on file shares 145 | $RECYCLE.BIN/ 146 | 147 | # Mac crap 148 | .DS_Store 149 | 150 | # NuGet Packages 151 | lib/Packages/ 152 | src/packages/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2004-2013 Thong Nguyen (tumtumtum@gmail.com), Platform.NET 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the Platform.NET nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /lib/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/platformdotnet/Platform/68aef5248b6559a85a914965bcc08696623d1aea/lib/.gitignore -------------------------------------------------------------------------------- /nuspec/Platform.NET.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Platform.NET 5 | $version$ 6 | Platform.NET System Library 7 | A cross-platform library of useful classes and extensions for C# and .NET 8 | Thong Nguyen 9 | Thong Nguyen 10 | https://raw.github.com/platformdotnet/Platform/master/LICENSE 11 | https://github.com/platformdotnet/Platform 12 | false 13 | 14 | Platform.NET 15 | 16 | A cross-platform library of useful classes and extensions for C# and .NET. 17 | 18 | $releasenotes$ 19 | Copyright (c) 2003-2016 Thong Nguyen (tumtumtum@gmail.com) 20 | task text utility string extensions base64 ntp invocationqueue utility weakreference meteringstream expressionvisitor linq ringbuffer fifobuffer circular 21 | 22 | -------------------------------------------------------------------------------- /nuspec/Platform.Xml.Serialization.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Platform.Xml.Serialization 5 | $version$ 6 | Platform.NET XmlSerialization Library 7 | 8 | Thong Nguyen 9 | Thong Nguyen 10 | https://raw.github.com/platformdotnet/Platform/master/LICENSE 11 | https://github.com/platformdotnet/Platform 12 | false 13 | A cross-platform, clean and extensible XML serializer for .NET 14 | $releasenotes$ 15 | Copyright (c) 2003-2015 Thong Nguyen (tumtumtum@gmail.com) 16 | platform xml serialization serializer 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/.nuget/NuGet.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/platformdotnet/Platform/68aef5248b6559a85a914965bcc08696623d1aea/src/.nuget/NuGet.exe -------------------------------------------------------------------------------- /src/Platform.NET.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 2012 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Platform", "Platform\Platform.csproj", "{31199C34-A7F0-4D69-B2CF-E9CE05262618}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Platform.Xml.Serialization", "Platform.Xml.Serialization\Platform.Xml.Serialization.csproj", "{CBB73076-7381-4FDD-907F-7097A8AB04E6}" 6 | EndProject 7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Platform.Tests", "..\tests\Platform.Tests\Platform.Tests.csproj", "{48BBE7EA-88F9-4A46-9EED-ADFF60427BF5}" 8 | EndProject 9 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Platform.Xml.Serialization.Tests", "..\tests\Platform.Xml.Serialization.Tests\Platform.Xml.Serialization.Tests.csproj", "{8682A3CE-4664-4535-B31D-8A7FB7C04266}" 10 | EndProject 11 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{6462CBA9-FD4F-4BF5-9846-866601FB1A31}" 12 | ProjectSection(SolutionItems) = preProject 13 | .nuget\NuGet.Config = .nuget\NuGet.Config 14 | .nuget\NuGet.exe = .nuget\NuGet.exe 15 | .nuget\NuGet.targets = .nuget\NuGet.targets 16 | EndProjectSection 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Release|Any CPU = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {31199C34-A7F0-4D69-B2CF-E9CE05262618}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {31199C34-A7F0-4D69-B2CF-E9CE05262618}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {31199C34-A7F0-4D69-B2CF-E9CE05262618}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {31199C34-A7F0-4D69-B2CF-E9CE05262618}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {CBB73076-7381-4FDD-907F-7097A8AB04E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {CBB73076-7381-4FDD-907F-7097A8AB04E6}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {CBB73076-7381-4FDD-907F-7097A8AB04E6}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {CBB73076-7381-4FDD-907F-7097A8AB04E6}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {48BBE7EA-88F9-4A46-9EED-ADFF60427BF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {48BBE7EA-88F9-4A46-9EED-ADFF60427BF5}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {48BBE7EA-88F9-4A46-9EED-ADFF60427BF5}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {48BBE7EA-88F9-4A46-9EED-ADFF60427BF5}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {8682A3CE-4664-4535-B31D-8A7FB7C04266}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {8682A3CE-4664-4535-B31D-8A7FB7C04266}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {8682A3CE-4664-4535-B31D-8A7FB7C04266}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {8682A3CE-4664-4535-B31D-8A7FB7C04266}.Release|Any CPU.Build.0 = Release|Any CPU 40 | EndGlobalSection 41 | GlobalSection(SolutionProperties) = preSolution 42 | HideSolutionNode = FALSE 43 | EndGlobalSection 44 | EndGlobal 45 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/AbstractGetterSetter.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | public abstract class AbstractGetterSetter 6 | : IGetterSetter 7 | { 8 | protected MemberInfo memberInfo; 9 | 10 | protected AbstractGetterSetter(MemberInfo memberInfo) 11 | { 12 | this.memberInfo = memberInfo; 13 | } 14 | 15 | public abstract object GetValue(object obj); 16 | public abstract void SetValue(object obj, object val); 17 | } 18 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/AbstractXmlConfigurationSectionHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml; 3 | using System.Configuration; 4 | 5 | namespace Platform.Xml.Serialization 6 | { 7 | public abstract class AbstractXmlConfigurationSectionHandler 8 | : IConfigurationSectionHandler 9 | where T : new() 10 | { 11 | private readonly XmlSerializer serializer; 12 | 13 | protected AbstractXmlConfigurationSectionHandler(Type type) 14 | : this(XmlSerializer.New()) 15 | { 16 | } 17 | 18 | protected AbstractXmlConfigurationSectionHandler(XmlSerializer serializer) 19 | { 20 | this.serializer = serializer; 21 | } 22 | 23 | public virtual object Create(object parent, object configContext, System.Xml.XmlNode section) 24 | { 25 | return serializer.Deserialize(new XmlNodeReader(section)); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/Attributes/XmlTypeSerializerTypeAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | 4 | namespace Platform.Xml.Serialization 5 | { 6 | public class XmlTypeSerializerTypeAttribute 7 | : XmlSerializationAttribute 8 | { 9 | /// 10 | /// 11 | /// 12 | public Type SerializerType 13 | { 14 | get 15 | { 16 | return m_SerializerType; 17 | } 18 | 19 | set 20 | { 21 | m_SerializerType = value; 22 | } 23 | } 24 | /// 25 | /// 26 | /// 27 | private Type m_SerializerType; 28 | 29 | /// 30 | /// 31 | /// 32 | /// 33 | public XmlTypeSerializerTypeAttribute(Type serializerType) 34 | { 35 | m_SerializerType = serializerType; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/CachingXmlSerializerFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Platform.Xml.Serialization 5 | { 6 | /// 7 | /// An that supports caching of serializers 8 | /// 9 | public class CachingXmlSerializerFactory 10 | : XmlSerializerFactory 11 | { 12 | private Dictionary, object> cache = new Dictionary, object>(); 13 | private Dictionary, object> cacheForDynamic = new Dictionary, object>(); 14 | 15 | /// 16 | /// 17 | /// 18 | public override XmlSerializer NewXmlSerializer() 19 | { 20 | return this.NewXmlSerializer(null); 21 | } 22 | 23 | /// 24 | /// 25 | /// 26 | public override XmlSerializer NewXmlSerializer(Type type) 27 | { 28 | return this.NewXmlSerializer(type, null); 29 | } 30 | 31 | /// 32 | /// 33 | /// 34 | public override XmlSerializer NewXmlSerializer(Type type, SerializerOptions options) 35 | { 36 | object value; 37 | 38 | var key = new Pair(type, options); 39 | 40 | if (!this.cacheForDynamic.TryGetValue(key, out value)) 41 | { 42 | if (options == null) 43 | { 44 | value = new XmlSerializer(type); 45 | } 46 | else 47 | { 48 | value = new XmlSerializer(type, options); 49 | } 50 | 51 | this.cacheForDynamic = new Dictionary, object>(this.cacheForDynamic) { [key] = value }; 52 | } 53 | 54 | return (XmlSerializer)value; 55 | } 56 | 57 | /// 58 | /// 59 | /// 60 | public override XmlSerializer NewXmlSerializer(SerializerOptions options) 61 | { 62 | object value; 63 | 64 | var key = new Pair(typeof(T), options); 65 | 66 | if (!this.cache.TryGetValue(key, out value)) 67 | { 68 | if (options == null) 69 | { 70 | value = new XmlSerializer(); 71 | } 72 | else 73 | { 74 | value = new XmlSerializer(options); 75 | } 76 | 77 | this.cache = new Dictionary, object>(this.cache) { [key] = value }; 78 | } 79 | 80 | return (XmlSerializer)value; 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/ColorSerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | 4 | namespace Platform.Xml.Serialization 5 | { 6 | public class ColorSerializer 7 | : StringableTypeSerializer 8 | { 9 | public ColorSerializer(Type type, SerializationMemberInfo memberInfo, TypeSerializerCache cache, SerializerOptions options) 10 | : base(type, memberInfo, cache,options) 11 | { 12 | } 13 | 14 | public override string Serialize(object obj, SerializationContext state) 15 | { 16 | if (obj == null) 17 | { 18 | return ""; 19 | } 20 | 21 | if (((Color)obj).ToKnownColor() != 0) 22 | { 23 | return ((Color)obj).Name; 24 | } 25 | else 26 | { 27 | return ColorTranslator.ToHtml((Color)obj); 28 | } 29 | } 30 | 31 | /// 32 | /// 33 | /// 34 | public override object Deserialize(string value, SerializationContext state) 35 | { 36 | try 37 | { 38 | return ColorTranslator.FromHtml(value); 39 | } 40 | catch (Exception) 41 | { 42 | return Color.FromName(value); 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/EnumTypeSerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | public class EnumTypeSerializer 6 | : TypeSerializerWithSimpleTextSupport 7 | { 8 | public override Type SupportedType => this.supportedType; 9 | 10 | private readonly Type supportedType; 11 | 12 | public EnumTypeSerializer(SerializationMemberInfo memberInfo, TypeSerializerCache cache, SerializerOptions options) 13 | { 14 | supportedType = memberInfo.ReturnType; 15 | 16 | if (!typeof(Enum).IsAssignableFrom(supportedType)) 17 | { 18 | throw new ArgumentException(this.GetType().Name + " only works with Enum types"); 19 | } 20 | } 21 | 22 | public override string Serialize(object obj, SerializationContext state) 23 | { 24 | var attribute = (XmlSerializeEnumAsIntAttribute)state.GetCurrentMemberInfo().GetFirstApplicableAttribute(typeof(XmlSerializeEnumAsIntAttribute)); 25 | 26 | if (attribute != null && attribute.Value) 27 | { 28 | return Convert.ToInt32(obj).ToString(); 29 | } 30 | 31 | return Enum.Format(supportedType, obj, "G"); 32 | } 33 | 34 | public override object Deserialize(string value, SerializationContext state) 35 | { 36 | return Enum.Parse(supportedType, value, true); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/FieldGetterSetter.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | public class FieldGetterSetter 6 | : AbstractGetterSetter 7 | { 8 | public FieldGetterSetter(MemberInfo memberInfo) 9 | : base(memberInfo) 10 | { 11 | } 12 | 13 | public override object GetValue(object obj) 14 | { 15 | return ((FieldInfo)this.memberInfo).GetValue(obj); 16 | } 17 | 18 | public override void SetValue(object obj, object val) 19 | { 20 | if (!((FieldInfo)this.memberInfo).IsInitOnly) 21 | { 22 | ((FieldInfo)this.memberInfo).SetValue(obj, val); 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/GuidSerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | public class GuidSerializer 6 | : StringableTypeSerializer 7 | { 8 | public GuidSerializer(Type type, SerializationMemberInfo memberInfo, TypeSerializerCache cache, SerializerOptions options) 9 | : base(type, memberInfo,cache,options) 10 | { 11 | } 12 | 13 | /// 14 | /// 15 | /// 16 | public override object Deserialize(string value, SerializationContext state) 17 | { 18 | return new Guid(value); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/IGetterSetter.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Xml.Serialization 2 | { 3 | public interface IGetterSetter 4 | { 5 | object GetValue(object obj); 6 | void SetValue(object obj, object val); 7 | } 8 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/ISerializationStateListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | 4 | namespace Platform.Xml.Serialization 5 | { 6 | /// 7 | /// Interface for objects that want to know when they're being serialized by 8 | /// an XmlSerializer. 9 | /// 10 | public interface ISerializationStateListener 11 | { 12 | /// 13 | /// Called when the object is about to be serialized. 14 | /// 15 | /// 16 | /// This method is called on an object before its properties have been serilized. 17 | /// 18 | /// 19 | void SerializationStart(SerializationParameters parameters); 20 | 21 | /// 22 | /// Called when an object has been serialized. 23 | /// 24 | /// 25 | /// This method is called on an object after its properties have been serialized. 26 | /// 27 | /// 28 | void SerializationEnd(SerializationParameters parameters); 29 | 30 | /// 31 | /// Called when an object is about to be deserialized. 32 | /// 33 | /// 34 | /// This method is called on an object after it has been constructed but 35 | /// before its properties have been set. 36 | /// 37 | /// 38 | void DeserializationStart(SerializationParameters parameters); 39 | 40 | /// 41 | /// Called when an object has been deseriazlied. 42 | /// 43 | /// 44 | /// This method is called on an object after its properties have been set. 45 | /// 46 | /// 47 | void DeserializationEnd(SerializationParameters parameters); 48 | } 49 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/ISerializationUnhandledMarkupListener.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Xml.Serialization 2 | { 3 | public interface ISerializationUnhandledMarkupListener 4 | { 5 | void UnhandledAttribute(string name, string value); 6 | void UnhandledOther(string xml); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/ISerializationUnknownNodeListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml; 3 | 4 | namespace Platform.Xml.Serialization 5 | { 6 | /// 7 | /// 8 | public interface ISerializationUnhandledMarkupListener 9 | { 10 | void UnhandledAttribute(string name, string value); 11 | void UnhandledOther(string markup); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/IVariableSubstitutor.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Xml.Serialization 2 | { 3 | public interface IVariableSubstitutor 4 | { 5 | string Substitute(string value); 6 | } 7 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/IXmlDeserializationEndListener.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Xml.Serialization 2 | { 3 | public interface IXmlDeserializationEndListener 4 | { 5 | /// 6 | /// Called when an object has been deseriazlied. 7 | /// 8 | /// 9 | /// This method is called on an object after its properties have been set. 10 | /// 11 | /// 12 | void XmlDeserializationEnd(SerializationParameters parameters); 13 | } 14 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/IXmlDeserializationStartListener.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Xml.Serialization 2 | { 3 | public interface IXmlDeserializationStartListener 4 | { 5 | /// 6 | /// Called when an object is about to be deserialized. 7 | /// 8 | /// 9 | /// This method is called on an object after it has been constructed but 10 | /// before its properties have been set. 11 | /// 12 | /// 13 | void XmlDeserializationStart(SerializationParameters parameters); 14 | } 15 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/IXmlListElementDynamicTypeProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Xml.Serialization 2 | { 3 | public interface IXmlListElementDynamicTypeProvider 4 | : IXmlDynamicTypeProvider 5 | { 6 | string GetName(object instance); 7 | } 8 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/IXmlPolymorphicTypeProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml; 3 | 4 | namespace Platform.Xml.Serialization 5 | { 6 | public interface IXmlDynamicTypeProvider 7 | { 8 | Type GetType(object instance); 9 | Type GetType(XmlReader reader); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/IXmlSerializationEndListener.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Xml.Serialization 2 | { 3 | public interface IXmlSerializationEndListener 4 | { 5 | /// 6 | /// Called when an object has been serialized. 7 | /// 8 | /// 9 | /// This method is called on an object after its properties have been serialized. 10 | /// 11 | /// 12 | void XmlSerializationEnd(SerializationParameters parameters); 13 | } 14 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/IXmlSerializationShouldSerializeProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Xml.Serialization 2 | { 3 | public interface IXmlSerializationShouldSerializeProvider 4 | { 5 | bool ShouldSerialize(SerializerOptions options, SerializationParameters parameters); 6 | } 7 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/IXmlSerializationStartListener.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Xml.Serialization 2 | { 3 | public interface IXmlSerializationStartListener 4 | { 5 | /// 6 | /// Called when the object is about to be serialized. 7 | /// 8 | /// 9 | /// This method is called on an object before its properties have been serilized. 10 | /// 11 | /// 12 | void XmlSerializationStart(SerializationParameters parameters); 13 | } 14 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/IXmlSerializerSerializable.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Xml.Serialization 2 | { 3 | public interface IXmlSerializerSerializable 4 | { 5 | XmlSerializer GetXmlSerializer(); 6 | } 7 | 8 | public interface IXmlSerializerSerializable 9 | : IXmlSerializerSerializable 10 | where T : new() 11 | { 12 | new XmlSerializer GetXmlSerializer(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/Platform.Xml.Serialization.wdx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | WorkspaceModel 8 | WORKSPACE 9 | 10 | 11 | 12 | 13 | (0,0) 14 | (0,0) 15 | {E6211B3D-4356-41B8-9568-40CC3343605B} 16 | Closed 17 | 100 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/platformdotnet/Platform/68aef5248b6559a85a914965bcc08696623d1aea/src/Platform.Xml.Serialization/Properties/AssemblyInfo.cs -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/PropertyGetterSetter.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | public class PropertyGetterSetter 6 | : AbstractGetterSetter 7 | { 8 | public PropertyGetterSetter(MemberInfo memberInfo) 9 | : base(memberInfo) 10 | { 11 | } 12 | 13 | public override object GetValue(object obj) 14 | { 15 | if (((PropertyInfo)this.memberInfo).CanRead) 16 | { 17 | return ((PropertyInfo)this.memberInfo).GetValue(obj, null); 18 | } 19 | 20 | return null; 21 | } 22 | 23 | public override void SetValue(object obj, object val) 24 | { 25 | if (((PropertyInfo)this.memberInfo).CanWrite) 26 | { 27 | ((PropertyInfo)this.memberInfo).SetValue(obj, val, null); 28 | } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/RuntimeTypeTypeSerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | public class RuntimeTypeTypeSerializer 6 | : TypeSerializerWithSimpleTextSupport 7 | { 8 | private readonly XmlSerializationAttribute[] verifyAttributes; 9 | 10 | public RuntimeTypeTypeSerializer(SerializationMemberInfo memberInfo, TypeSerializerCache cache, SerializerOptions options) 11 | { 12 | verifyAttributes = (XmlSerializationAttribute[])memberInfo.GetApplicableAttributes(typeof(XmlVerifyRuntimeTypeAttribute)); 13 | } 14 | 15 | public override Type SupportedType => typeof(Type); 16 | 17 | public override string Serialize(object obj, SerializationContext state) 18 | { 19 | var ok = verifyAttributes.Length == 0; 20 | 21 | foreach (XmlVerifyRuntimeTypeAttribute attribute in verifyAttributes) 22 | { 23 | if (attribute.VerifiesAgainst(obj.GetType())) 24 | { 25 | ok = true; 26 | break; 27 | } 28 | } 29 | 30 | if (!ok) 31 | { 32 | throw new XmlSerializerException("Invalid type"); 33 | } 34 | 35 | return ((Type)obj).AssemblyQualifiedName; 36 | } 37 | 38 | public override object Deserialize(string value, SerializationContext state) 39 | { 40 | bool ok = verifyAttributes.Length == 0; 41 | 42 | var type = Type.GetType(value); 43 | 44 | if (type == null) 45 | { 46 | throw new TypeLoadException("The type could not be loaded: " + value); 47 | } 48 | 49 | foreach (XmlVerifyRuntimeTypeAttribute attribute in verifyAttributes) 50 | { 51 | if (attribute.VerifiesAgainst(type)) 52 | { 53 | ok = true; 54 | break; 55 | } 56 | } 57 | 58 | if (!ok) 59 | { 60 | throw new XmlSerializerException("Invalid type"); 61 | } 62 | 63 | return type; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/SerializationParameters.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Platform.Xml.Serialization 5 | { 6 | public class SerializationParameters 7 | { 8 | private readonly IDictionary parameters; 9 | 10 | private static readonly SerializationParameters empty = new SerializationParameters(); 11 | 12 | public static SerializationParameters Empty => empty; 13 | 14 | public XmlSerializerNamespaces Namespaces 15 | { 16 | get; 17 | private set; 18 | } 19 | 20 | public SerializationParameters() 21 | { 22 | this.Namespaces = new XmlSerializerNamespaces(); 23 | parameters = new Dictionary(StringComparer.CurrentCultureIgnoreCase); 24 | } 25 | 26 | public virtual object this[string name] 27 | { 28 | get 29 | { 30 | return parameters[name]; 31 | } 32 | 33 | set 34 | { 35 | if (this == empty) 36 | { 37 | return; 38 | } 39 | 40 | parameters[name] = value; 41 | } 42 | } 43 | 44 | public virtual bool ContainsByName(string name) 45 | { 46 | return parameters.ContainsKey(name); 47 | } 48 | 49 | public virtual bool TryGetValue(string name, out object value) 50 | { 51 | return parameters.TryGetValue(name, out value); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/SerializeMembers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | [Flags] 6 | public enum SerializeMembers 7 | { 8 | None = 0, 9 | Attributed = 1, 10 | Fields = 2, 11 | Properties = 3, 12 | FieldsAndProperties = Fields | Properties 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/SerializerOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | public class SerializerOptions 6 | { 7 | public static readonly string WriteXmlheader = "WriteXmlheader"; 8 | private static readonly SerializerOptions empty = new SerializerOptions(); 9 | 10 | private readonly Dictionary options = new Dictionary(); 11 | 12 | public static SerializerOptions Empty => empty; 13 | 14 | public object GetOption(string name) 15 | { 16 | return this.options[name]; 17 | } 18 | 19 | public bool TryGetValue(string name, out object value) 20 | { 21 | return this.options.TryGetValue(name, out value); 22 | } 23 | 24 | public SerializerOptions(params object[] options) 25 | { 26 | for (var i = 0; i < options.Length; i += 2) 27 | { 28 | this.options[options[i].ToString()] = options[i + 1]; 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/StringableTypeSerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Platform.Xml.Serialization 5 | { 6 | /// 7 | /// A that supports serializing 8 | /// various primitive types to and from strings. 9 | /// 10 | public class StringableTypeSerializer 11 | : TypeSerializerWithSimpleTextSupport 12 | { 13 | private readonly bool formatSpecified = false; 14 | 15 | private readonly XmlFormatAttribute formatAttribute; 16 | 17 | public override bool MemberBound => true; 18 | 19 | public override Type SupportedType => this.supportedType; 20 | 21 | public static List SupportedTypes => new List() 22 | { 23 | typeof(bool), 24 | typeof(byte), 25 | typeof(char), 26 | typeof(decimal), 27 | typeof(double), 28 | typeof(float), 29 | typeof(int), 30 | typeof(long), 31 | typeof(sbyte), 32 | typeof(short), 33 | typeof(string), 34 | typeof(uint), 35 | typeof(ulong), 36 | typeof(ushort) 37 | }; 38 | 39 | private readonly Type supportedType; 40 | 41 | public StringableTypeSerializer(Type type, SerializationMemberInfo memberInfo, TypeSerializerCache cache, SerializerOptions options) 42 | { 43 | supportedType = type; 44 | if (memberInfo != null) 45 | { 46 | formatAttribute= (XmlFormatAttribute) memberInfo.GetFirstApplicableAttribute(typeof (XmlFormatAttribute)); 47 | } 48 | 49 | formatSpecified = formatAttribute != null; 50 | } 51 | 52 | /// 53 | /// 54 | /// 55 | public override string Serialize(object obj, SerializationContext state) 56 | { 57 | if (obj is IFormattable && formatSpecified) 58 | { 59 | return (obj as IFormattable).ToString(formatAttribute.Format, formatAttribute.CultureInfo); 60 | } 61 | 62 | if (obj == null) 63 | { 64 | return string.Empty; 65 | } 66 | 67 | return obj.ToString(); 68 | } 69 | 70 | /// 71 | /// 72 | /// 73 | public override object Deserialize(string value, SerializationContext state) 74 | { 75 | if (formatSpecified) 76 | { 77 | return Convert.ChangeType(value, supportedType, formatAttribute.CultureInfo); 78 | } 79 | 80 | return Convert.ChangeType(value, supportedType); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/TypeSerializerFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | public abstract class TypeSerializerFactory 6 | { 7 | public abstract TypeSerializer NewTypeSerializerBySupportedType(Type supportedType, SerializationMemberInfo memberInfo, TypeSerializerCache cache); 8 | public abstract TypeSerializer NewTypeSerializerBySupportedType(Type supportedType, TypeSerializerCache cache); 9 | public abstract TypeSerializer NewTypeSerializerBySerializerType(Type serializerType, SerializationMemberInfo memberInfo, TypeSerializerCache cache); 10 | public abstract TypeSerializer NewTypeSerializerBySerializerType(Type serializerType, TypeSerializerCache cache); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/TypeSerializers/EnumTypeSerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | /// 6 | /// Summary description for EnumTypeSerializer. 7 | /// 8 | public class EnumTypeSerializer 9 | : TypeSerializerWithSimpleTextSupport 10 | { 11 | /// 12 | /// 13 | /// 14 | public override Type SupportedType 15 | { 16 | get 17 | { 18 | return m_Type; 19 | } 20 | } 21 | 22 | private Type m_Type; 23 | 24 | public EnumTypeSerializer(SerializationMemberInfo memberInfo, TypeSerializerCache cache, SerializerOptions options) 25 | { 26 | m_Type = memberInfo.LogicalType; 27 | 28 | if (!typeof(Enum).IsAssignableFrom(m_Type)) 29 | { 30 | throw new ArgumentException(this.GetType().Name + " only works with Enum types"); 31 | } 32 | } 33 | 34 | public override string Serialize(object obj, SerializationState state) 35 | { 36 | return Enum.GetName(m_Type, obj); 37 | } 38 | 39 | public override object Deserialize(string value, SerializationState state) 40 | { 41 | return Enum.Parse(m_Type, value, true); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlApproachAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = true)] 6 | public abstract class XmlApproachAttribute 7 | : XmlSerializationAttribute 8 | { 9 | public virtual string Name { get; set; } 10 | public virtual bool SerializeUnattribted { get; set; } 11 | public virtual bool MakeNameLowercase { get; set; } 12 | public virtual bool UseNameFromAttributedType { get; set; } 13 | public virtual string Namespace { get; set; } 14 | public virtual Type Type { get; set; } 15 | public virtual Type SerializerType { get; set; } 16 | public virtual bool SerializeIfNull { get; set; } 17 | 18 | protected XmlApproachAttribute() 19 | { 20 | Namespace = ""; 21 | MakeNameLowercase = false; 22 | Name = ""; 23 | } 24 | 25 | protected XmlApproachAttribute(Type type) 26 | : this("", type) 27 | { 28 | } 29 | 30 | protected XmlApproachAttribute(string name) 31 | { 32 | Namespace = ""; 33 | MakeNameLowercase = false; 34 | Name = name; 35 | } 36 | 37 | protected XmlApproachAttribute(string name, Type type) 38 | { 39 | Namespace = ""; 40 | MakeNameLowercase = false; 41 | Type = type; 42 | Name = name; 43 | } 44 | 45 | protected XmlApproachAttribute(string ns, string name, Type type) 46 | { 47 | MakeNameLowercase = false; 48 | Type = type; 49 | Name = name; 50 | Namespace = ns; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlAttributeAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = true)] 6 | public class XmlAttributeAttribute 7 | : XmlApproachAttribute 8 | { 9 | public XmlAttributeAttribute() 10 | { 11 | } 12 | 13 | public XmlAttributeAttribute(Type type) 14 | : base(type) 15 | { 16 | } 17 | 18 | public XmlAttributeAttribute(string name) 19 | : base(name) 20 | { 21 | } 22 | 23 | public XmlAttributeAttribute(string name, Type type) 24 | : base(name, type) 25 | { 26 | } 27 | 28 | public XmlAttributeAttribute(string ns, string name, Type type) 29 | : base(ns, name, type) 30 | { 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlCDataAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = true)] 6 | public class XmlCDataAttribute 7 | : XmlSerializationAttribute 8 | { 9 | public bool Enabled { get; set; } 10 | 11 | public XmlCDataAttribute() 12 | { 13 | this.Enabled = true; 14 | } 15 | 16 | public XmlCDataAttribute(bool enabled) 17 | { 18 | this.Enabled = enabled; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlConfigurationBlockSectionHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Xml; 2 | using System.Configuration; 3 | using Platform.Xml.Serialization; 4 | 5 | namespace Platform 6 | { 7 | public class XmlConfigurationBlockSectionHandler 8 | : IConfigurationSectionHandler 9 | where T : new() 10 | { 11 | public object Create(object parent, object configContext, XmlNode section) 12 | { 13 | var serializer = XmlSerializer.New(); 14 | 15 | var retval = serializer.Deserialize(new XmlNodeReader(section)); 16 | 17 | return retval; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlDateTimeFormatAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = true)] 6 | public class XmlDateTimeFormatAttribute 7 | : XmlSerializationAttribute 8 | { 9 | public string Format { get; set; } 10 | 11 | public XmlDateTimeFormatAttribute(string format) 12 | { 13 | this.Format = format; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlDictionaryElementTypeAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | public class XmlDictionaryElementTypeAttribute 6 | : XmlElementAttribute 7 | { 8 | public virtual Type ElementType { get; set; } 9 | public virtual string TypeAlias { get; set; } 10 | 11 | public XmlDictionaryElementTypeAttribute(Type elementType, string typeAlias) 12 | { 13 | this.ElementType = elementType; 14 | this.TypeAlias = typeAlias; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlElementAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = true)] 6 | public class XmlElementAttribute 7 | : XmlApproachAttribute 8 | { 9 | public XmlElementAttribute() 10 | { 11 | ValueNodeAttributeName = "value"; 12 | } 13 | 14 | public XmlElementAttribute(Type type) 15 | : base(type) 16 | { 17 | ValueNodeAttributeName = "value"; 18 | } 19 | 20 | public XmlElementAttribute(string name) 21 | : base(name) 22 | { 23 | ValueNodeAttributeName = "value"; 24 | } 25 | 26 | public XmlElementAttribute(string name, Type type) 27 | : base(name, type) 28 | { 29 | ValueNodeAttributeName = "value"; 30 | } 31 | 32 | public XmlElementAttribute(string ns, string name, Type type) 33 | : base(ns, name, type) 34 | { 35 | ValueNodeAttributeName = "value"; 36 | } 37 | 38 | /// 39 | /// Set to true if you would like node to be serialized as a node with the data stored 40 | /// in an attribute named ValueAttributeName rather than inside the element itself. 41 | /// 42 | public bool SerializeAsValueNode 43 | { 44 | get; 45 | set; 46 | } 47 | 48 | public string ValueNodeAttributeName 49 | { 50 | get; 51 | set; 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlEnvironmentVariableSubstitutor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace Platform.Xml.Serialization 5 | { 6 | public class XmlEnvironmentVariableSubstitutor 7 | : IVariableSubstitutor 8 | { 9 | private static readonly Regex staticRegex; 10 | 11 | static XmlEnvironmentVariableSubstitutor() 12 | { 13 | staticRegex = new Regex 14 | ( 15 | @" 16 | \$\((?([a-zA-Z]+[a-zA-Z_]*))\) 17 | ", 18 | RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace 19 | ); 20 | } 21 | 22 | protected static string EnvironmentVariableMatchEvaluator(Match value) 23 | { 24 | var name = value.Groups["name"].Value; 25 | 26 | return Environment.GetEnvironmentVariable(name); 27 | } 28 | 29 | public virtual string Substitute(string value) => staticRegex.Replace(value, EnvironmentVariableMatchEvaluator); 30 | } 31 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlExcludeAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = false)] 6 | public class XmlExcludeAttribute 7 | : XmlSerializationAttribute 8 | { 9 | } 10 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlFormatAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | 4 | namespace Platform.Xml.Serialization 5 | { 6 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = true)] 7 | public class XmlFormatAttribute : XmlSerializationAttribute 8 | { 9 | public string Format { get; set; } 10 | public bool CultureSet { get; private set; } 11 | 12 | private string culture; 13 | 14 | public string Culture 15 | { 16 | get { return culture; } 17 | set 18 | { 19 | this.CultureSet = true; 20 | culture = value; 21 | } 22 | } 23 | 24 | public CultureInfo CultureInfo => this.CultureSet ? new CultureInfo(this.Culture) : CultureInfo.CurrentCulture; 25 | 26 | public XmlFormatAttribute(string format) 27 | { 28 | this.Format = format; 29 | } 30 | 31 | public XmlFormatAttribute(string format, string culture) : this(format) 32 | { 33 | this.Culture = culture; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlListElementAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | /// 6 | /// Describes the types of the items in a list to be serialized. 7 | /// 8 | /// 9 | ///

10 | /// You need to mark any IList field or property to be serialized with this attribute 11 | /// at least once. The attribute is used to map an element name to the type 12 | /// of object contained in the list. 13 | ///

14 | ///
15 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = true)] 16 | public class XmlListElementAttribute 17 | : XmlElementAttribute 18 | { 19 | public virtual string Alias 20 | { 21 | get 22 | { 23 | if (this.MakeNameLowercase) 24 | return this.Name.ToLowerInvariant(); 25 | return this.Name; 26 | } 27 | 28 | set 29 | { 30 | this.Name = value; 31 | } 32 | } 33 | 34 | public virtual Type ItemType { get { return this.Type; } set { this.Type = value; } } 35 | 36 | /// 37 | /// Specifies a list item's type. 38 | /// 39 | /// 40 | /// The type's name will be used as the alias for all elements with the type. 41 | /// If the type has been attributed with an XmlElement attribute then the alias 42 | /// specified in that attribute will be used. 43 | /// 44 | /// The type of element the list can contain. 45 | public XmlListElementAttribute(Type itemType) 46 | : this(itemType, itemType.Name) 47 | { 48 | } 49 | 50 | /// 51 | /// Specifies a list item's type. 52 | /// 53 | /// 54 | /// The supplied alias will be used to map the actual element Type with 55 | /// an XML element. 56 | /// 57 | /// 58 | /// 59 | public XmlListElementAttribute(Type itemType, string alias) 60 | : base(alias, itemType) 61 | { 62 | } 63 | 64 | public XmlListElementAttribute(string alias) 65 | : base(alias, null) 66 | { 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlListElementDynamicTypeProviderAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = true)] 6 | public class XmlListElementDynamicTypeProviderAttribute 7 | : XmlSerializationAttribute 8 | { 9 | public Type ProviderType { get; set; } 10 | 11 | public XmlListElementDynamicTypeProviderAttribute(Type providerType) 12 | { 13 | this.ProviderType = providerType; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlNodeNodeTypeSerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml; 3 | 4 | namespace Platform.Xml.Serialization 5 | { 6 | public class XmlNodeNodeTypeSerializer 7 | : TypeSerializer 8 | { 9 | public static readonly XmlNodeNodeTypeSerializer Default = new XmlNodeNodeTypeSerializer(); 10 | 11 | public override Type SupportedType => typeof(XmlNode); 12 | 13 | public override bool MemberBound => false; 14 | 15 | private static void WriteNode(XmlReader reader, XmlWriter writer) 16 | { 17 | while (reader.Read()) 18 | { 19 | switch (reader.NodeType) 20 | { 21 | case XmlNodeType.Element: 22 | writer.WriteStartElement(reader.Name); 23 | break; 24 | case XmlNodeType.Text: 25 | writer.WriteString(reader.Value); 26 | break; 27 | case XmlNodeType.CDATA: 28 | writer.WriteCData(reader.Value); 29 | break; 30 | case XmlNodeType.ProcessingInstruction: 31 | writer.WriteProcessingInstruction(reader.Name, reader.Value); 32 | break; 33 | case XmlNodeType.Comment: 34 | writer.WriteComment(reader.Value); 35 | break; 36 | case XmlNodeType.XmlDeclaration: 37 | break; 38 | case XmlNodeType.Document: 39 | break; 40 | case XmlNodeType.DocumentType: 41 | break; 42 | case XmlNodeType.EntityReference: 43 | break; 44 | case XmlNodeType.EndElement: 45 | writer.WriteEndElement(); 46 | break; 47 | } 48 | } 49 | } 50 | 51 | public override void Serialize(object obj, System.Xml.XmlWriter writer, SerializationContext state) 52 | { 53 | foreach (XmlNode child in ((XmlNode)obj).ChildNodes) 54 | { 55 | var reader = new XmlNodeReader(child); 56 | 57 | WriteNode(reader, writer); 58 | } 59 | } 60 | 61 | public override object Deserialize(System.Xml.XmlReader reader, SerializationContext state) 62 | { 63 | var document = new XmlDocument(); 64 | 65 | document.LoadXml(reader.ReadOuterXml()); 66 | 67 | return document.FirstChild; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlPolymorphicTypeAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | public class XmlPolymorphicTypeAttribute 6 | : XmlSerializationAttribute 7 | { 8 | public Type PolymorphicTypeProvider { get; set; } 9 | 10 | public XmlPolymorphicTypeAttribute(Type polymorphicTypeProvider) 11 | { 12 | PolymorphicTypeProvider = polymorphicTypeProvider; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlSerializationAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | public abstract class XmlSerializationAttribute 6 | : Attribute 7 | { 8 | protected XmlSerializationAttribute() 9 | { 10 | Constraints = ""; 11 | } 12 | 13 | public string Constraints { get; set; } 14 | 15 | /// 16 | /// Tests if this attribute should be applied/considered when serializing. 17 | /// 18 | /// 19 | internal virtual bool Applies(SerializerOptions options) 20 | { 21 | if (Constraints.Length > 0) 22 | { 23 | var constraints = Constraints.Split(';'); 24 | 25 | foreach (string s in constraints) 26 | { 27 | object value; 28 | var forNotEquals = true; 29 | 30 | var namevalue = s.Split(new string[] { "!=" }, StringSplitOptions.None); 31 | 32 | if (namevalue.Length < 2) 33 | { 34 | namevalue = s.Split('='); 35 | 36 | forNotEquals = false; 37 | } 38 | 39 | if (!options.TryGetValue(namevalue[0], out value)) 40 | { 41 | if (forNotEquals) 42 | { 43 | return true; 44 | 45 | } 46 | return false; 47 | } 48 | 49 | if (forNotEquals) 50 | { 51 | if (value.ToString().EqualsIgnoreCase(namevalue[1])) 52 | { 53 | return false; 54 | } 55 | } 56 | else 57 | { 58 | if (!value.ToString().EqualsIgnoreCase(namevalue[1])) 59 | { 60 | return false; 61 | } 62 | } 63 | } 64 | } 65 | 66 | return true; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlSerializeBaseAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] 6 | public class XmlSerializeBaseAttribute 7 | : XmlSerializationAttribute 8 | { 9 | public bool SerializeBase { get; set; } 10 | 11 | public XmlSerializeBaseAttribute() 12 | { 13 | } 14 | 15 | public XmlSerializeBaseAttribute(bool serializeBase) 16 | { 17 | SerializeBase = serializeBase; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlSerializeEnumAsIntAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Xml.Serialization 2 | { 3 | public class XmlSerializeEnumAsIntAttribute 4 | : XmlAttributeAttribute 5 | { 6 | public bool Value { get; set; } 7 | 8 | public XmlSerializeEnumAsIntAttribute() 9 | : this(true) 10 | { 11 | } 12 | 13 | public XmlSerializeEnumAsIntAttribute(bool value) 14 | { 15 | this.Value = value; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlSerializerException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | public class XmlSerializerException 6 | : ApplicationException 7 | { 8 | public XmlSerializerException() 9 | { 10 | } 11 | 12 | public XmlSerializerException(string message) 13 | : base(message) 14 | { 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlSerializerFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | /// 6 | /// A factory that creates objects. 7 | /// 8 | public abstract class XmlSerializerFactory 9 | { 10 | /// 11 | /// Gets an instance of the default XmlSerializer. 12 | /// 13 | /// 14 | public static XmlSerializerFactory Default { get; } = new CachingXmlSerializerFactory(); 15 | 16 | /// 17 | /// Creates a new 18 | /// 19 | /// The serializer's supported object type 20 | /// A new 21 | public abstract XmlSerializer NewXmlSerializer(); 22 | 23 | /// 24 | /// Creates a new 25 | /// 26 | /// The serializer's supported object type 27 | /// The options for the serializer 28 | /// A new 29 | public abstract XmlSerializer NewXmlSerializer(SerializerOptions options); 30 | 31 | /// 32 | /// Creates a new 33 | /// 34 | /// The type supported by the serializer 35 | /// A new 36 | public abstract XmlSerializer NewXmlSerializer(Type type); 37 | 38 | /// 39 | /// Creates a new 40 | /// 41 | /// The type supported by the serializer 42 | /// The options for the serializer 43 | /// A new 44 | public abstract XmlSerializer NewXmlSerializer(Type type, SerializerOptions options); 45 | } 46 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlSerializerNamespaces.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Specialized; 3 | 4 | namespace Platform.Xml.Serialization 5 | { 6 | /// 7 | /// Summary description for XmlSerializerNamespaces. 8 | /// 9 | public class XmlSerializerNamespaces 10 | { 11 | private readonly IDictionary prefixes; 12 | private readonly IDictionary namespaces; 13 | 14 | public XmlSerializerNamespaces() 15 | { 16 | namespaces = CollectionsUtil.CreateCaseInsensitiveHashtable(); 17 | prefixes = CollectionsUtil.CreateCaseInsensitiveHashtable(); 18 | } 19 | 20 | internal IEnumerable GetPrefixes() 21 | { 22 | return prefixes.Values; 23 | } 24 | 25 | public void Add(string prefix, string ns) 26 | { 27 | namespaces[prefix] = ns; 28 | prefixes[ns] = prefix; 29 | } 30 | 31 | public string GetNamespace(string prefix) 32 | { 33 | return (string)namespaces[prefix]; 34 | } 35 | 36 | public string GetPrefix(string ns) 37 | { 38 | return (string)prefixes[ns]; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlTextAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = true)] 6 | public class XmlTextAttribute 7 | : XmlSerializationAttribute 8 | { 9 | } 10 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlTreatAsNullIfEmptyAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = false)] 6 | public class XmlTreatAsNullIfEmptyAttribute 7 | : XmlSerializationAttribute 8 | { 9 | } 10 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlTypeSerializerTypeAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | public class XmlTypeSerializerTypeAttribute 6 | : XmlSerializationAttribute 7 | { 8 | public Type SerializerType { get; set; } 9 | 10 | public XmlTypeSerializerTypeAttribute(Type serializerType) 11 | { 12 | SerializerType = serializerType; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlVariableSubstitutionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = true)] 6 | public class XmlVariableSubstitutionAttribute 7 | : XmlSerializationAttribute 8 | { 9 | public Type SubstitutorType { get; set; } 10 | 11 | public XmlVariableSubstitutionAttribute() 12 | : this(typeof(XmlEnvironmentVariableSubstitutor)) 13 | { 14 | } 15 | 16 | public XmlVariableSubstitutionAttribute(Type substitutorType) 17 | { 18 | this.SubstitutorType = substitutorType; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/XmlVerifyRuntimeTypeAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace Platform.Xml.Serialization 5 | { 6 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = true)] 7 | public class XmlVerifyRuntimeTypeAttribute 8 | : XmlSerializationAttribute 9 | { 10 | public Type[] Types { get; set; } 11 | 12 | public XmlVerifyRuntimeTypeAttribute(params Type[] types) 13 | : this(LogicalOperation.All, types) 14 | { 15 | } 16 | 17 | public XmlVerifyRuntimeTypeAttribute(LogicalOperation logicalCheck, params Type[] types) 18 | { 19 | this.Types = types; 20 | } 21 | 22 | public virtual bool VerifiesAgainst(Type type) 23 | { 24 | return this.Types.Any(t => t.IsAssignableFrom(type)); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/datetimetypeserializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | public class DateTimeTypeSerializer 6 | : TypeSerializerWithSimpleTextSupport 7 | { 8 | private readonly bool formatSpecified = false; 9 | 10 | private readonly XmlDateTimeFormatAttribute formatAttribute; 11 | 12 | public override bool MemberBound => true; 13 | 14 | public override Type SupportedType => typeof(DateTime); 15 | 16 | public DateTimeTypeSerializer(SerializationMemberInfo memberInfo, TypeSerializerCache cache, SerializerOptions options) 17 | { 18 | formatAttribute = (XmlDateTimeFormatAttribute)memberInfo.GetFirstApplicableAttribute(typeof(XmlDateTimeFormatAttribute)); 19 | 20 | if (formatAttribute == null) 21 | { 22 | formatAttribute = new XmlDateTimeFormatAttribute("G"); 23 | formatSpecified = false; 24 | } 25 | else 26 | { 27 | formatSpecified = true; 28 | } 29 | } 30 | 31 | public override string Serialize(object obj, SerializationContext state) 32 | { 33 | return ((DateTime)obj).ToString(formatAttribute.Format); 34 | } 35 | 36 | public override object Deserialize(string value, SerializationContext state) 37 | { 38 | if (formatSpecified) 39 | { 40 | try 41 | { 42 | return DateTime.ParseExact(value, formatAttribute.Format, System.Globalization.CultureInfo.CurrentCulture); 43 | } 44 | catch 45 | { 46 | } 47 | } 48 | 49 | return DateTime.Parse(value); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/typeserializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml; 3 | 4 | namespace Platform.Xml.Serialization 5 | { 6 | /// 7 | /// Abstract base class for classes that support serializing objects. 8 | /// 9 | public abstract class TypeSerializer 10 | { 11 | /// 12 | /// Returns true if this serializer can only be used with a specific member. 13 | /// 14 | public virtual bool MemberBound => false; 15 | 16 | /// 17 | /// Returns the type that this serializer supports. 18 | /// 19 | public abstract Type SupportedType 20 | { 21 | get; 22 | } 23 | 24 | /// 25 | /// 26 | /// 27 | /// 28 | /// 29 | /// 30 | public abstract void Serialize(object obj, XmlWriter writer, SerializationContext state); 31 | 32 | /// 33 | /// 34 | /// 35 | /// 36 | /// 37 | /// 38 | public abstract object Deserialize(XmlReader reader, SerializationContext state); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Platform.Xml.Serialization/typeserializerwithsimpletextsupport.cs: -------------------------------------------------------------------------------- 1 | using System.Xml; 2 | 3 | namespace Platform.Xml.Serialization 4 | { 5 | /// 6 | /// Abstract base class for classes that support serializing of objects. 7 | /// 8 | /// 9 | /// Serializers of this type also support seralizing objects to a simple text representation. 10 | /// Only types are serialized with a TypeSerializerWithSimpleTextSupport can be serialized 11 | /// to an XML attribute. 12 | /// 13 | public abstract class TypeSerializerWithSimpleTextSupport 14 | : TypeSerializer 15 | { 16 | public abstract string Serialize(object obj, SerializationContext state); 17 | public abstract object Deserialize(string value, SerializationContext state); 18 | 19 | public override void Serialize(object obj, XmlWriter writer, SerializationContext state) 20 | { 21 | writer.WriteString(Serialize(obj, state)); 22 | } 23 | 24 | public override object Deserialize(XmlReader reader, SerializationContext state) 25 | { 26 | var s = XmlReaderHelper.ReadCurrentNodeValue(reader); 27 | 28 | if (state.GetCurrentMemberInfo().Substitutor != null) 29 | { 30 | s = state.GetCurrentMemberInfo().Substitutor.Substitute(s); 31 | } 32 | 33 | return Deserialize(s, state); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Platform/AbstractModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | /// 8 | /// Base class for all implementations 9 | /// 10 | public abstract class AbstractModel 11 | : MarshalByRefObject, IModel 12 | { 13 | /// 14 | /// An event that is raised when a major change occurs in the model. 15 | /// 16 | public virtual event EventHandler MajorChange; 17 | 18 | /// 19 | /// Raises the event 20 | /// 21 | protected virtual void OnMajorChange() 22 | { 23 | this.MajorChange?.Invoke(this, EventArgs.Empty); 24 | } 25 | 26 | /// 27 | /// Gets the owner of the current object 28 | /// 29 | public virtual object Owner => null; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Platform/AbstractRunnable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | /// 8 | /// Base class for all implementations 9 | /// 10 | public abstract class AbstractRunnable 11 | : MarshalByRefObject, IRunnable 12 | { 13 | /// 14 | /// Performs the Run operation 15 | /// 16 | public abstract void Run(); 17 | } 18 | } -------------------------------------------------------------------------------- /src/Platform/Action.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | namespace Platform 4 | { 5 | /// 6 | /// A subroutine with five parameters 7 | /// 8 | public delegate void Action(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5); 9 | 10 | /// 11 | /// A subroutine with six parameters 12 | /// 13 | public delegate void Action(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6); 14 | 15 | /// 16 | /// A subroutine with seven parameters 17 | /// 18 | public delegate void Action(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7); 19 | 20 | /// 21 | /// A subroutine with eight parameters 22 | /// 23 | public delegate void Action(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8); 24 | } -------------------------------------------------------------------------------- /src/Platform/ActivatorUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | using System.Linq.Expressions; 5 | 6 | namespace Platform 7 | { 8 | public class ActivatorUtils 9 | { 10 | private static Func constructor; 11 | 12 | public static T CreateInstance() 13 | { 14 | if (constructor != null) 15 | { 16 | return constructor(); 17 | } 18 | else 19 | { 20 | var body = Expression.New(typeof(T)); 21 | 22 | var ctor = Expression.Lambda>(body).Compile(); 23 | 24 | constructor = ctor; 25 | 26 | return ctor(); 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Platform/ArrayEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System.Linq; 4 | using System.Collections.Generic; 5 | 6 | namespace Platform 7 | { 8 | public class ArrayEqualityComparer 9 | : IEqualityComparer 10 | { 11 | public static readonly ArrayEqualityComparer Default = new ArrayEqualityComparer(EqualityComparer.Default); 12 | 13 | private readonly IEqualityComparer elementComparer; 14 | 15 | public ArrayEqualityComparer(IEqualityComparer elementComparer) 16 | { 17 | this.elementComparer = elementComparer; 18 | } 19 | 20 | public virtual bool Equals(T[] first, T[] second) 21 | { 22 | if (first == second) 23 | { 24 | return true; 25 | } 26 | 27 | if (first == null || second == null) 28 | { 29 | return false; 30 | } 31 | 32 | if (first.Length != second.Length) 33 | { 34 | return false; 35 | } 36 | 37 | for (var i = 0; i < first.Length; i++) 38 | { 39 | if (!this.elementComparer.Equals(first[i], second[i])) 40 | { 41 | return false; 42 | } 43 | } 44 | 45 | return true; 46 | } 47 | 48 | public virtual int GetHashCode(T[] array) 49 | { 50 | if (array == null) 51 | { 52 | return 0; 53 | } 54 | 55 | return array.Aggregate(0, (current, element) => current ^ this.elementComparer.GetHashCode(element)); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Platform/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | // 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | // 8 | [assembly: AssemblyTitle("Platform.NET")] 9 | [assembly: AssemblyDescription("Cross Platform Object Oriented Library")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("(Thong Nguyen (tum@veridicus.com)")] 12 | [assembly: AssemblyProduct("Platform.VirtualFileSystem")] 13 | [assembly: AssemblyCopyright("Copyright (c) 2002 - 2004 Thong Nguyen")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 18 | // Version information for an assembly consists of the following four values: 19 | // 20 | // Major Version 21 | // Minor Version 22 | // Build Number 23 | // Revision 24 | // 25 | // You can specify all the values or you can default the Revision and Build Numbers 26 | // by using the '*' as shown below: 27 | 28 | [assembly: AssemblyVersion("0.5.0")] 29 | 30 | // 31 | // In order to sign your assembly you must specify a key to use. Refer to the 32 | // Microsoft .NET Framework documentation for more information on assembly signing. 33 | // 34 | // Use the attributes below to control which key is used for signing. 35 | // 36 | // Notes: 37 | // (*) If no key is specified, the assembly is not signed. 38 | // (*) KeyName refers to a key that has been installed in the Crypto Service 39 | // Provider (CSP) on your machine. KeyFile refers to a file which contains 40 | // a key. 41 | // (*) If the KeyFile and the KeyName values are both specified, the 42 | // following processing occurs: 43 | // (1) If the KeyName can be found in the CSP, that key is used. 44 | // (2) If the KeyName does not exist and the KeyFile does exist, the key 45 | // in the KeyFile is installed into the CSP and used. 46 | // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. 47 | // When specifying the KeyFile, the location of the KeyFile should be 48 | // relative to the project output directory which is 49 | // %Project Directory%\obj\. For example, if your KeyFile is 50 | // located in the project directory, you would specify the AssemblyKeyFile 51 | // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] 52 | // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework 53 | // documentation for more information on this. 54 | // 55 | [assembly: AssemblyDelaySign(false)] 56 | [assembly: AssemblyKeyFile("")] 57 | [assembly: AssemblyKeyName("")] 58 | -------------------------------------------------------------------------------- /src/Platform/AutoLock.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | using System.Threading; 5 | 6 | namespace Platform 7 | { 8 | /// 9 | /// An implementation that uses a monitor for the lock. 10 | /// 11 | public class AutoLock 12 | : IAutoLock 13 | { 14 | /// 15 | /// The monitor this is based upon. 16 | /// 17 | private readonly object lockObject; 18 | 19 | /// 20 | /// Creates a new using the new 21 | /// as the monitor for locking. 22 | /// 23 | public AutoLock() 24 | { 25 | lockObject = this; 26 | } 27 | 28 | /// 29 | /// Creates a new using the supplied object 30 | /// as the monitor for locking. 31 | /// 32 | /// The object for locking 33 | public AutoLock(object lockObject) 34 | { 35 | this.lockObject = lockObject; 36 | } 37 | 38 | /// 39 | /// Locks the current object's monitor. 40 | /// 41 | /// The current object 42 | public virtual AutoLock Lock() => (AutoLock)((IAutoLock)this).Lock(); 43 | 44 | /// 45 | /// Unlocks the current object's monitor. 46 | /// 47 | /// The current object 48 | public virtual AutoLock Unlock() => (AutoLock)((IAutoLock)this).Unlock(); 49 | 50 | /// 51 | /// Locks the current object's monitor. 52 | /// 53 | /// The current object 54 | IAutoLock IAutoLock.Lock() 55 | { 56 | Monitor.Enter(lockObject); 57 | 58 | return this; 59 | } 60 | 61 | /// 62 | /// Unlocks the current object's monitor. 63 | /// 64 | /// The current object 65 | IAutoLock IAutoLock.Unlock() 66 | { 67 | Monitor.Exit(lockObject); 68 | 69 | return this; 70 | } 71 | 72 | /// 73 | /// Unlocks the current object's monitor. 74 | /// 75 | void IDisposable.Dispose() => this.Unlock(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/Platform/CachedValue.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | /// 8 | /// Caches a value and automatically retrieves the new value 9 | /// if the cached value is invalidated by a call to . 10 | /// 11 | /// The type of value to cache 12 | public struct CachedValue 13 | : IValued 14 | { 15 | /// 16 | /// The cached value. 17 | /// 18 | object IValued.Value => this.Value; 19 | 20 | /// 21 | /// The function that gets the current up-to-date value. 22 | /// 23 | public Func ValueGetter { get; } 24 | 25 | /// 26 | /// The cached value. 27 | /// 28 | public T Value 29 | { 30 | get 31 | { 32 | if (gotValue) 33 | { 34 | return value; 35 | } 36 | else 37 | { 38 | lock (typeof(CachedValue)) 39 | { 40 | if (gotValue) 41 | { 42 | return value; 43 | } 44 | else 45 | { 46 | var currentValue = this.ValueGetter(); 47 | 48 | System.Threading.Thread.MemoryBarrier(); 49 | 50 | this.value = currentValue; 51 | this.gotValue = true; 52 | 53 | return this.value; 54 | } 55 | } 56 | } 57 | } 58 | } 59 | /// 60 | /// 61 | /// 62 | private T value; 63 | 64 | private volatile bool gotValue; 65 | 66 | /// 67 | /// Constructs a new . The object's 68 | /// value will retrieved at the next call to 69 | /// 70 | /// A function that retrieves the value on demand 71 | public CachedValue(Func valueGetter) 72 | : this() 73 | { 74 | gotValue = false; 75 | value = default(T); 76 | 77 | this.ValueGetter = valueGetter; 78 | } 79 | 80 | /// 81 | /// Invalidates the current value. The next reference to 82 | /// will cause a new value to be loaded by the 83 | /// 84 | public void Invalidate() 85 | { 86 | gotValue = false; 87 | value = default(T); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/Platform/CharUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | /// 8 | /// Provides extension methods for chars 9 | /// 10 | public static class CharUtils 11 | { 12 | /// 13 | /// Returns True if the char is an ascii letter (A-Z, a-z) or a digit (0-9). 14 | /// 15 | /// The character to check 16 | /// True if the char is an ascii letter or digit 17 | public static bool IsAsciiLetterOrDigit(this char c) 18 | { 19 | return (((c >= 48) && (c <= 57)) // 0-9 20 | || ((c >= 65) && (c <= 90)) // A-Z 21 | || ((c >= 97) && (c <= 122))); // a-z 22 | } 23 | 24 | /// 25 | /// Returns true if the char is a hexadecimal digit (0-9, A-F, a-f). 26 | /// 27 | /// The character to check 28 | /// True if the char is a hexadecimal digit 29 | public static bool IsHexDigit(this char c) 30 | { 31 | return Uri.IsHexDigit(c); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Platform/Collections/BlockingQueue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | 4 | namespace Platform.Collections 5 | { 6 | public class BlockingQueue 7 | : QueueBase, IBlockingQueue 8 | { 9 | public static readonly TimeSpan DefaultTimeout = TimeSpan.FromMilliseconds(-1); 10 | 11 | private readonly IQueue queue; 12 | private readonly object lockObject = new object(); 13 | 14 | public BlockingQueue() 15 | : this(new ArrayQueue()) 16 | { 17 | } 18 | 19 | public BlockingQueue(IQueue backingQueue) 20 | : this(backingQueue, DefaultTimeout) 21 | { 22 | } 23 | 24 | public BlockingQueue(IQueue backingQueue, TimeSpan timeout) 25 | { 26 | this.queue = backingQueue; 27 | } 28 | 29 | public override int Count 30 | { 31 | get 32 | { 33 | lock (this.lockObject) 34 | { 35 | return queue.Count; 36 | } 37 | } 38 | } 39 | 40 | public override void Enqueue(T item) 41 | { 42 | lock (this.lockObject) 43 | { 44 | this.queue.Enqueue(item); 45 | 46 | Monitor.Pulse(this.lockObject); 47 | } 48 | } 49 | 50 | public override void Enqueue(T[] items, int offset, int count) 51 | { 52 | lock (this.lockObject) 53 | { 54 | this.queue.Enqueue(items, offset, count); 55 | 56 | Monitor.Pulse(this.lockObject); 57 | } 58 | } 59 | 60 | public override T Dequeue() 61 | { 62 | return Dequeue(Timeout.Infinite); 63 | } 64 | 65 | public virtual T Dequeue(int timeout) 66 | { 67 | return Dequeue(TimeSpan.FromMilliseconds(timeout)); 68 | } 69 | 70 | public virtual T Dequeue(TimeSpan timeout) 71 | { 72 | T value; 73 | 74 | if (TryDequeue(timeout, out value)) 75 | { 76 | return value; 77 | } 78 | else 79 | { 80 | throw new TimeoutException(); 81 | } 82 | } 83 | 84 | public override bool TryDequeue(out T value) 85 | { 86 | return TryDequeue(DefaultTimeout, out value); 87 | } 88 | 89 | public override bool TryPeek(out T value) 90 | { 91 | lock (this.lockObject) 92 | { 93 | if (this.Count == 0) 94 | { 95 | value = default(T); 96 | 97 | return false; 98 | } 99 | else 100 | { 101 | value = this.queue.Peek(); 102 | 103 | return true; 104 | } 105 | } 106 | } 107 | 108 | public virtual bool TryDequeue(TimeSpan timeout, out T value) 109 | { 110 | lock (this.lockObject) 111 | { 112 | while (true) 113 | { 114 | if (this.Count == 0) 115 | { 116 | if (!Monitor.Wait(this.lockObject, timeout)) 117 | { 118 | value = default(T); 119 | 120 | return false; 121 | } 122 | } 123 | else 124 | { 125 | break; 126 | } 127 | } 128 | 129 | value = this.queue.Dequeue(); 130 | } 131 | 132 | return true; 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/Platform/Collections/BufferOverflowException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Collections 4 | { 5 | public class BufferOverflowException 6 | : Exception 7 | { 8 | public BufferOverflowException() 9 | { 10 | } 11 | 12 | public BufferOverflowException(string message) 13 | : base(message) 14 | { 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Platform/Collections/BufferUnderflowException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Collections 4 | { 5 | public class BufferUnderflowException 6 | : Exception 7 | { 8 | public BufferUnderflowException() 9 | { 10 | } 11 | 12 | public BufferUnderflowException(string message) 13 | : base(message) 14 | { 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Platform/Collections/CircularFifoBuffer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Collections 4 | { 5 | public class CircularFifoBuffer 6 | : BoundedFifoBuffer 7 | { 8 | public CircularFifoBuffer(int capacity, T[] buffer = null) 9 | : base(capacity, buffer) 10 | { 11 | } 12 | 13 | public override void Write(T[] buffer, int offset, int length) 14 | { 15 | var capacity = this.Capacity; 16 | var end = (this.position + this.Length) % capacity; 17 | 18 | if (length >= capacity) 19 | { 20 | var sourceOffset = offset + length - capacity; 21 | 22 | Array.Copy(buffer, sourceOffset, bytes, 0, capacity); 23 | 24 | this.position = 0; 25 | this.Length = this.bytes.Length; 26 | } 27 | else 28 | { 29 | var x = Math.Min(capacity - end, length); 30 | Array.Copy(buffer, offset, bytes, end, x); 31 | 32 | Array.Copy(buffer, offset + x, bytes, 0, length - x); 33 | 34 | if (this.Length + length > capacity) 35 | { 36 | this.position = (this.position + ((this.Length + length) - capacity)) % capacity; 37 | this.Length = capacity; 38 | } 39 | else 40 | { 41 | this.Length += length; 42 | } 43 | } 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/Platform/Collections/CollectionBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | 6 | namespace Platform.Collections 7 | { 8 | public class CollectionBase 9 | : ICollection 10 | { 11 | public virtual IEnumerator GetEnumerator() 12 | { 13 | throw new NotImplementedException(); 14 | } 15 | 16 | IEnumerator IEnumerable.GetEnumerator() 17 | { 18 | return this.GetEnumerator(); 19 | } 20 | 21 | public virtual void Add(T item) 22 | { 23 | throw new NotImplementedException(); 24 | } 25 | 26 | public virtual void Clear() 27 | { 28 | throw new NotImplementedException(); 29 | } 30 | 31 | public virtual bool Contains(T item) 32 | { 33 | return Enumerable.Contains(this, item); 34 | } 35 | 36 | public virtual void CopyTo(T[] array, int arrayIndex) 37 | { 38 | throw new NotImplementedException(); 39 | } 40 | 41 | public virtual bool Remove(T item) 42 | { 43 | throw new NotImplementedException(); 44 | } 45 | 46 | public virtual int Count { get { throw new NotImplementedException(); } } 47 | 48 | public virtual bool IsReadOnly { get { throw new NotImplementedException(); } } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Platform/Collections/CollectionEnumerable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections.Generic; 4 | 5 | namespace Platform.Collections 6 | { 7 | /// 8 | /// Used to convert any into an . 9 | /// 10 | /// The type of object stored in the collection 11 | public class EnumerableCollectionAdapter 12 | : ICollection 13 | { 14 | private readonly Func GetCount; 15 | private readonly IEnumerable Enumerable; 16 | 17 | /// 18 | /// Constructs a new . 19 | /// 20 | /// The enumerable that this collection will use 21 | /// The number of elements in the enumerable 22 | public EnumerableCollectionAdapter(IEnumerable enumerable, int count) 23 | : this(enumerable, () => count) 24 | { 25 | } 26 | 27 | /// 28 | /// Constructs a new . 29 | /// 30 | /// The enumerable that this collection will use 31 | /// A function that returns the cou nt of the enumerable 32 | public EnumerableCollectionAdapter(IEnumerable enumerable, Func getCount) 33 | { 34 | this.GetCount = getCount; 35 | this.Enumerable = enumerable; 36 | } 37 | 38 | #region ICollection Members 39 | 40 | public virtual void Add(T item) 41 | { 42 | throw new NotSupportedException(); 43 | } 44 | 45 | public virtual void Clear() 46 | { 47 | throw new NotSupportedException(); 48 | } 49 | 50 | public virtual bool Contains(T item) 51 | { 52 | return this.Enumerable.Contains(item); 53 | } 54 | 55 | public virtual void CopyTo(T[] array, int arrayIndex) 56 | { 57 | foreach (T value in this) 58 | { 59 | array[arrayIndex++] = value; 60 | } 61 | } 62 | 63 | public virtual int Count 64 | { 65 | get 66 | { 67 | return this.GetCount(); 68 | } 69 | } 70 | 71 | public virtual bool IsReadOnly 72 | { 73 | get 74 | { 75 | return true; 76 | } 77 | } 78 | 79 | public virtual bool Remove(T item) 80 | { 81 | throw new NotSupportedException(); 82 | } 83 | 84 | #endregion 85 | 86 | #region IEnumerable Members 87 | 88 | public virtual IEnumerator GetEnumerator() 89 | { 90 | return Enumerable.GetEnumerator(); 91 | } 92 | 93 | #endregion 94 | 95 | #region IEnumerable Members 96 | 97 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 98 | { 99 | return this.GetEnumerator(); 100 | } 101 | 102 | #endregion 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/Platform/Collections/DictionaryExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Platform.Collections 4 | { 5 | public static class DictionaryExtensions 6 | { 7 | public static V GetValueOrDefault(this Dictionary dictionary, K key) 8 | { 9 | V result; 10 | 11 | if (dictionary.TryGetValue(key, out result)) 12 | { 13 | return result; 14 | } 15 | 16 | return default(V); 17 | } 18 | 19 | public static V? GetValueOrNull(this Dictionary dictionary, K key) 20 | where V : struct 21 | { 22 | V result; 23 | 24 | if (dictionary.TryGetValue(key, out result)) 25 | { 26 | return result; 27 | } 28 | 29 | return null; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Platform/Collections/IBlockingQueue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Collections 4 | { 5 | /// 6 | /// Defines an interface for queues that support blocking. 7 | /// 8 | /// 9 | /// Blocking queues block on all dequeue operations until 10 | /// an item is available or any specified timeout expires. 11 | /// 12 | /// 13 | interface IBlockingQueue 14 | : IQueue 15 | { 16 | /// 17 | /// Gets the next item in the queue. 18 | /// 19 | /// The amount of time to wait for the item to dequeue 20 | /// If the dequeue operation times out 21 | /// The next item in the queue 22 | T Dequeue(int timeout); 23 | 24 | /// 25 | /// Gets the next item in the queue. 26 | /// 27 | /// The amount of time to wait for the item to dequeue 28 | /// If the dequeue operation times out 29 | /// The next item in the queue 30 | T Dequeue(TimeSpan timeout); 31 | 32 | /// 33 | /// Tries to get the next item in the queue. 34 | /// 35 | /// The amount of time to wait for the item to dequeue 36 | /// A variable in which to store the next item (if available before the timeout period) 37 | /// True if an item was returned before the timeout period otherwise false 38 | bool TryDequeue(TimeSpan timeout, out T value); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Platform/Collections/IQueue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Platform.Collections 5 | { 6 | /// 7 | /// Interface for all objects that implement a queue. 8 | /// 9 | /// The type of value stored in the queue 10 | public interface IQueue 11 | : ICollection 12 | { 13 | /// 14 | /// Enqueues an item onto the collection. 15 | /// 16 | /// 17 | void Enqueue(T item); 18 | 19 | /// 20 | /// Enqueues an array of items into the queue. 21 | /// 22 | /// The array of items to enqueue 23 | /// The offset within the array to start enqueing from 24 | /// The number of items from the array to enqueue 25 | void Enqueue(T[] items, int offset, int count); 26 | 27 | /// 28 | /// Dequeues the next item in the collection. 29 | /// 30 | /// When an item is not available 31 | /// The next item in the queue (an exception is thrown if none is available) 32 | T Dequeue(); 33 | 34 | /// 35 | /// Tries to dequeue the next item in the collection. 36 | /// 37 | /// A variable to store the value if available 38 | /// True if an item is available and has been returned otherwise False 39 | bool TryDequeue(out T item); 40 | 41 | /// 42 | /// Returns the next item in the queue without removing it from the queue. 43 | /// 44 | /// No item is avilable in the queue 45 | /// The next item if one is available otherwise throws an 46 | T Peek(); 47 | 48 | /// 49 | /// Returns the next item in the queue without removing it from the queue. 50 | /// 51 | /// A variable to store the next item 52 | /// No item is avilable in the queue 53 | /// True if an item was available and returned 54 | bool TryPeek(out T item); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Platform/Collections/IReadOnlyCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Platform.Collections 4 | { 5 | public interface IReadOnlyCollection 6 | : IEnumerable 7 | { 8 | int Count { get; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Platform/Collections/IReadOnlyList.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Collections 2 | { 3 | public interface IReadOnlyList 4 | : IReadOnlyCollection 5 | { 6 | T this[int index] { get; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Platform/Collections/QueueBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Collections 4 | { 5 | public abstract class QueueBase 6 | : CollectionBase, IQueue 7 | { 8 | public abstract void Enqueue(T item); 9 | 10 | public virtual void Enqueue(T[] items, int offset, int count) 11 | { 12 | for (var i = offset; i < offset + count; i++) 13 | { 14 | Enqueue(items[i]); 15 | } 16 | } 17 | 18 | public virtual T Dequeue() 19 | { 20 | T value; 21 | 22 | if (TryDequeue(out value)) 23 | { 24 | return value; 25 | } 26 | 27 | throw new InvalidOperationException(); 28 | } 29 | 30 | public virtual T Peek() 31 | { 32 | T value; 33 | 34 | if (TryPeek(out value)) 35 | { 36 | return value; 37 | } 38 | 39 | throw new InvalidOperationException(); 40 | } 41 | 42 | public abstract bool TryDequeue(out T value); 43 | public abstract bool TryPeek(out T value); 44 | 45 | public override void Add(T item) 46 | { 47 | Enqueue(item); 48 | } 49 | 50 | public override bool Remove(T item) 51 | { 52 | throw new NotSupportedException(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Platform/Collections/ReadOnlyCollectionReadOnlyListAdapter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | 5 | namespace Platform.Collections 6 | { 7 | public class ReadOnlyCollectionReadOnlyListAdapter 8 | : IReadOnlyList 9 | { 10 | private readonly ReadOnlyCollection inner; 11 | public int Count { get { return this.inner.Count; } } 12 | public T this[int value] { get { return this.inner[value]; } } 13 | 14 | public ReadOnlyCollectionReadOnlyListAdapter(ReadOnlyCollection inner) 15 | { 16 | this.inner = inner; 17 | } 18 | 19 | public virtual IEnumerator GetEnumerator() 20 | { 21 | return this.inner.GetEnumerator(); 22 | } 23 | 24 | IEnumerator IEnumerable.GetEnumerator() 25 | { 26 | return this.GetEnumerator(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Platform/Collections/ReadOnlyList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | 4 | namespace Platform.Collections 5 | { 6 | public class ReadOnlyList 7 | : IReadOnlyList 8 | { 9 | private readonly IList innerList; 10 | 11 | public int Count => this.innerList.Count; 12 | public T this[int index] => this.innerList[index]; 13 | 14 | public ReadOnlyList(params T[] values) 15 | : this(new List(values)) 16 | { 17 | } 18 | 19 | public ReadOnlyList(IEnumerable items) 20 | : this(items is ReadOnlyList ? (IList)items : new List(items)) 21 | { 22 | } 23 | 24 | public ReadOnlyList(IList innerList) 25 | { 26 | this.innerList = innerList; 27 | } 28 | 29 | public IEnumerator GetEnumerator() 30 | { 31 | return this.innerList.GetEnumerator(); 32 | } 33 | 34 | IEnumerator IEnumerable.GetEnumerator() 35 | { 36 | return this.GetEnumerator(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Platform/Collections/ReferenceDictionaryEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Collections 4 | { 5 | public class ReferenceDictionaryEventArgs 6 | : EventArgs 7 | { 8 | public K Key { get; private set; } 9 | 10 | public V Value { get; private set; } 11 | 12 | public ReferenceDictionaryEventArgs(K key, V value) 13 | { 14 | this.Key = key; 15 | this.Value = value; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Platform/ComparisonComparator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | namespace Platform 7 | { 8 | /// 9 | /// Wraps a and converts it into an 10 | /// 11 | /// 12 | public class ComparisonComparer 13 | : IComparer 14 | { 15 | private readonly Comparison comparison; 16 | 17 | /// 18 | /// Constructs a new . 19 | /// 20 | /// The the current object will wrap. 21 | public ComparisonComparer(Comparison comparison) 22 | { 23 | this.comparison = comparison; 24 | } 25 | 26 | /// 27 | /// Compares and using the inner . 28 | /// 29 | public virtual int Compare(T x, T y) => this.comparison(x, y); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Platform/ConfigurationBlock.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System.Collections.Generic; 4 | using System.Configuration; 5 | 6 | namespace Platform 7 | { 8 | public class ConfigurationBlock 9 | { 10 | private static readonly IDictionary BlockCache; 11 | 12 | static ConfigurationBlock() 13 | { 14 | BlockCache = new Dictionary(); 15 | } 16 | 17 | public static T Load(string configurationPath) 18 | { 19 | return Load(configurationPath, true); 20 | } 21 | 22 | public static T Load(string configurationPath, bool reload) 23 | { 24 | T retval; 25 | 26 | lock (BlockCache) 27 | { 28 | if (!reload) 29 | { 30 | if (BlockCache.TryGetValue(configurationPath, out retval)) 31 | { 32 | return retval; 33 | } 34 | } 35 | 36 | retval = (T)ConfigurationManager.GetSection(configurationPath); 37 | 38 | BlockCache[configurationPath] = retval; 39 | } 40 | 41 | return retval; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Platform/ConverterUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | public class ConverterUtils 8 | { 9 | public static Converter NoConvert { get; } = value => (O)(object)value; 10 | } 11 | } -------------------------------------------------------------------------------- /src/Platform/DataflowDirection.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | namespace Platform 4 | { 5 | public enum DataflowDirection 6 | { 7 | None, 8 | Incoming, 9 | Outgoing, 10 | IncomingAndOutgoing 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Platform/DateTimeFormats.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | /// 8 | /// Provides useful format strings for . 9 | /// 10 | public static class DateTimeFormats 11 | { 12 | /// 13 | /// A date time in sortable format: "yyyy-MM-dd HH:mm" 14 | /// 15 | public const string FullSortableUtcDateTimeString = "yyyy-MM-dd HH:mm"; 16 | 17 | /// 18 | /// A date time in sortable format: "yyyy-MM-dd HH:mm:ss" 19 | /// 20 | public const string SortableUtcDateTimeFormatWithSecondsString = "yyyy-MM-dd HH:mm:ss"; 21 | 22 | /// 23 | /// A date time in sortable format: "yyyy-MM-dd HH:mm:ss.fffffff" 24 | /// 25 | public const string SortableUtcDateTimeFormatWithFractionSecondsString = "yyyy-MM-dd HH:mm:ss.fffffff"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Platform/Direction.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | /// 8 | /// An enumeration of directions. North is equivalent to Top 9 | /// and Left is equivalent to West. 10 | /// 11 | [Flags] 12 | public enum Direction 13 | { 14 | None = 0, 15 | North = 1, 16 | South = 2, 17 | West = 4, 18 | East = 8, 19 | Top = 1, 20 | Bottom = 2, 21 | Left = 4, 22 | Right = 8 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Platform/Func.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | namespace Platform 4 | { 5 | public delegate R Func(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5); 6 | public delegate R Func(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6); 7 | public delegate R Func(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7); 8 | public delegate R Func(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 t8); 9 | } 10 | -------------------------------------------------------------------------------- /src/Platform/IAutoLock.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | /// 8 | /// An interface for objects that can be locked and unlocked. 9 | /// Please refer to . 10 | /// 11 | public interface IAutoLock 12 | : IDisposable 13 | { 14 | /// 15 | /// Locks the object. 16 | /// 17 | /// The current object 18 | IAutoLock Lock(); 19 | 20 | /// 21 | /// Unlocks the object. 22 | /// 23 | /// The current object 24 | IAutoLock Unlock(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Platform/ICacheable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform 4 | { 5 | /// 6 | /// Summary description for ICacheable. 7 | /// 8 | public interface ICacheable 9 | { 10 | event EventHandler CacheabilityChanged; 11 | 12 | /// 13 | /// If this property is true then the object can be removed from the cache when it spills. This can be 14 | /// used to keep the object alive even if there are no other references to the object. 15 | /// If this property is false then the object may automatically be removed from the cache at any time. 16 | /// 17 | bool IsWeakCacheable 18 | { 19 | get; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Platform/IKeyed.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | namespace Platform 4 | { 5 | /// 6 | /// Interface for objects that contain a property. 7 | /// 8 | public interface IKeyed 9 | { 10 | /// 11 | /// The . 12 | /// 13 | object Key 14 | { 15 | get; 16 | } 17 | } 18 | 19 | /// 20 | /// Interface for objects that contain a property. 21 | /// 22 | public interface IKeyed 23 | : IKeyed 24 | { 25 | /// 26 | /// The . 27 | /// 28 | new T Key 29 | { 30 | get; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Platform/IKeyedValued.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | namespace Platform 4 | { 5 | public interface IKeyedValued 6 | : IKeyed, IValued 7 | { 8 | } 9 | 10 | public interface IKeyedValued 11 | : IKeyed, IValued 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Platform/IMeter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | /// 8 | /// An interface that provides on a view onto an object that provides a certain value 9 | /// including maximum and minimum possible values. An object 10 | /// is analogous to a real world meter such as a power meter or petrol gage. 11 | /// 12 | public interface IMeter 13 | : IModel, IValued 14 | { 15 | /// 16 | /// An event that is raised when the changes. 17 | /// 18 | event EventHandler ValueChanged; 19 | 20 | /// 21 | /// The maximum possible value for the meter. 22 | /// 23 | object MaximumValue { get; } 24 | 25 | /// 26 | /// The minimum possible value for the meter. 27 | /// 28 | object MinimumValue { get; } 29 | 30 | /// 31 | /// The current value for the meter. 32 | /// 33 | object CurrentValue { get; } 34 | 35 | /// 36 | /// Returns a value between 0 and 1 that represents how far along the 37 | /// is between the 38 | /// and . 39 | /// 40 | double Percentage { get; } 41 | 42 | /// 43 | /// Gets the units (as a string) that the meter should be measured in. 44 | /// 45 | string Units { get; } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Platform/IModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | /// 8 | /// A base interface for model classes (classes that contain state). 9 | /// 10 | public interface IModel 11 | : IOwned 12 | { 13 | /// 14 | /// An event that is raised when a major change occurs in the model. 15 | /// 16 | event EventHandler MajorChange; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Platform/INamed.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | namespace Platform 4 | { 5 | /// 6 | /// Interface implemented by classes which support a readonly Name property. 7 | /// 8 | public interface INamed 9 | { 10 | /// 11 | /// Gets the name of the object. 12 | /// 13 | string Name { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Platform/IO/ILineReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.IO 4 | { 5 | /// 6 | /// An interface for supporting of reading lines with timeouts. Usually used with the method. 7 | /// 8 | /// 9 | public interface ILineReader 10 | : IDisposable 11 | { 12 | /// 13 | /// Reads a single line. 14 | /// 15 | /// The line read 16 | string ReadLine(); 17 | 18 | /// 19 | /// Reads a single line 20 | /// 21 | /// The timeout period to cancel reading the line 22 | /// The line read 23 | /// True if a line was read before the timeout period 24 | bool ReadLine(TimeSpan timeout, out string line); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Platform/IO/IStreamWithEvents.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.IO 4 | { 5 | public interface IStreamWithEvents 6 | { 7 | event EventHandler BeforeClose; 8 | event EventHandler AfterClose; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Platform/IObjectCache.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | namespace Platform 4 | { 5 | /// 6 | /// An interface for classes that can cache objects. 7 | /// 8 | /// The type used to key objects 9 | /// The type of objects stored in the cache 10 | public interface IObjectCache 11 | { 12 | /// 13 | /// Gets the maximum capacity of the cache (may be 0 if unknown). 14 | /// 15 | int MaximumCapacity { get; } 16 | 17 | /// 18 | /// Gets the amount of objects in the cache. 19 | /// 20 | int Count { get; } 21 | 22 | /// 23 | /// Adds an object to the cache. 24 | /// 25 | /// The key for the object 26 | /// The object 27 | void Push(K key, V value); 28 | 29 | /// 30 | /// Removes an object from the cache. 31 | /// 32 | /// The key for the object 33 | /// True if the object was found and removed 34 | bool Evict(K key); 35 | 36 | /// 37 | /// Flushes the cache. 38 | /// 39 | void Flush(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Platform/IOwned.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | namespace Platform 4 | { 5 | /// 6 | /// An interface for objects that have an owner. 7 | /// 8 | public interface IOwned 9 | { 10 | /// 11 | /// Gets the owner of the current object. 12 | /// 13 | object Owner { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Platform/IRefreshable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | namespace Platform 4 | { 5 | /// 6 | /// An interface for objects that can be refreshed. 7 | /// 8 | public interface IRefreshable 9 | { 10 | /// 11 | /// Refreshes the current object (what refresh means depends on the object). 12 | /// 13 | void Refresh(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Platform/IRunnable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | namespace Platform 4 | { 5 | /// 6 | /// Interface for objects that can be run. 7 | /// 8 | public interface IRunnable 9 | { 10 | /// 11 | /// Runs the object (usually in the current thread) 12 | /// 13 | void Run(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Platform/ISyncLocked.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | namespace Platform 4 | { 5 | /// 6 | /// An interface for objects that can be locked using the using statement 7 | /// and contain an object that can be used with the lock statement. 8 | /// 9 | public interface ISyncLocked 10 | { 11 | /// 12 | /// Gets the object used to synchronize the current object. 13 | /// 14 | object SyncLock { get; } 15 | 16 | /// 17 | /// Returns the but does not acquire it, 18 | /// 19 | /// The for the current object 20 | IAutoLock GetAutoLock(); 21 | 22 | /// 23 | /// Acquires the and returns it. 24 | /// 25 | /// The for the current object 26 | IAutoLock AquireAutoLock(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Platform/ITuple.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | namespace Platform 4 | { 5 | /// 6 | /// An interface for Tuples data types. 7 | /// 8 | public interface ITuple 9 | { 10 | /// 11 | /// Gets the number of elements held by the tuple. 12 | /// 13 | int Size { get; } 14 | 15 | /// 16 | /// Gets the tuple element at the given index. 17 | /// 18 | /// The tuple type 19 | /// The index of the elment to get (0 based) 20 | /// The element 21 | T GetAt(int index); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Platform/IValued.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | namespace Platform 4 | { 5 | /// 6 | /// Interface implemented by classes which support a readonly Value property. 7 | /// 8 | public interface IValued 9 | { 10 | object Value { get; } 11 | } 12 | 13 | /// 14 | /// Interface implemented by classes which support a readonly Value property. 15 | /// 16 | public interface IValued 17 | : IValued 18 | { 19 | new T Value { get; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Platform/IWrapperObject.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | namespace Platform 4 | { 5 | /// 6 | /// An interface implemented by objects that are wrappers. 7 | /// 8 | /// The type of object being wrapped 9 | public interface IWrapperObject 10 | { 11 | T Wrappee { get; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Platform/Int32Utils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | /// 8 | /// Provides extension methods for the type. 9 | /// 10 | public static class Int32Utils 11 | { 12 | /// 13 | /// Gets an integer from a single hex character 14 | /// 15 | /// The single hex character 16 | /// The integer 17 | public static int FromHex(this char digit) 18 | { 19 | if ((((digit < '0') || (digit > '9')) && ((digit < 'A') || (digit > 'F'))) && ((digit < 'a') || (digit > 'f'))) 20 | { 21 | throw new ArgumentException("digit"); 22 | } 23 | 24 | return FromHexNoCheck(digit); 25 | } 26 | 27 | /// 28 | /// Gets an integer from a single hex character without checking whether the character is 29 | /// a valid hex character. 30 | /// 31 | /// The single hex character 32 | /// The integer 33 | internal static int FromHexNoCheck(this char digit) 34 | { 35 | if (digit > '9') 36 | { 37 | return (((digit <= 'F') ? (digit - 'A') : (digit - 'a')) + '\n'); 38 | } 39 | return (digit - '0'); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Platform/LeftOrRight.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | namespace Platform 4 | { 5 | /// 6 | /// An enumeration that has a value of either or . 7 | /// 8 | public enum LeftOrRight 9 | { 10 | Left = 0, 11 | Right = 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Platform/Linq/ExpressionComparerOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Linq 4 | { 5 | [Flags] 6 | public enum ExpressionComparerOptions 7 | { 8 | None = 0, 9 | IgnoreConstantValues 10 | } 11 | } -------------------------------------------------------------------------------- /src/Platform/Linq/ExpressionEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq.Expressions; 3 | 4 | namespace Platform.Linq 5 | { 6 | public class ExpressionEqualityComparer 7 | : IEqualityComparer 8 | { 9 | private readonly ExpressionComparerOptions options; 10 | public static readonly ExpressionEqualityComparer Default = new ExpressionEqualityComparer(); 11 | 12 | public ExpressionEqualityComparer() 13 | : this(ExpressionComparerOptions.None) 14 | { 15 | } 16 | 17 | public ExpressionEqualityComparer(ExpressionComparerOptions options) 18 | { 19 | this.options = options; 20 | } 21 | 22 | public bool Equals(Expression x, Expression y) 23 | { 24 | return ExpressionComparer.Equals(x, y, this.options); 25 | } 26 | 27 | public int GetHashCode(Expression obj) 28 | { 29 | return ExpressionHasher.Hash(obj, this.options); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/Platform/LogicalOperation.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | /// 8 | /// An enumeration of logical operators. 9 | /// 10 | [Flags] 11 | public enum LogicalOperation 12 | { 13 | None = 0, 14 | And = 1, 15 | Or = 2, 16 | Any = 4, 17 | Nand = 8, 18 | Xor = 16, 19 | Nor = 32, 20 | All = And | Or | Any | Nand | Xor | Nor 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Platform/MeterEventArgs.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | /// 8 | /// Contains event information for the interface. 9 | /// 10 | public class MeterEventArgs 11 | : EventArgs, IValued 12 | { 13 | /// 14 | /// Gets the current value () 15 | /// 16 | public virtual object Value => this.NewValue; 17 | 18 | /// 19 | /// Gets the current value () 20 | /// 21 | object IValued.Value => this.NewValue; 22 | 23 | /// 24 | /// Gets the current value. 25 | /// 26 | public virtual object NewValue 27 | { 28 | get; } 29 | 30 | /// 31 | /// Gets the previous value 32 | /// 33 | public virtual object OldValue { get; private set; } 34 | 35 | /// 36 | /// Constructs a new . 37 | /// 38 | /// The new value 39 | /// The old value 40 | public MeterEventArgs(object newValue, object oldValue) 41 | { 42 | this.NewValue = newValue; 43 | this.OldValue = oldValue; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/Platform/NamedUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | /// 8 | /// Provides useful related utility methods. 9 | /// 10 | public static class NamedUtils 11 | { 12 | /// 13 | /// Gets a predicate that validates whether an object has a certain name. 14 | /// 15 | /// The object type (must implement ) 16 | /// The name to validate against the object 17 | /// A new predicate 18 | public static Predicate IsName(string name) 19 | where T : INamed 20 | { 21 | return IsName(name, StringComparison.CurrentCulture); 22 | } 23 | 24 | /// 25 | /// Gets a predicate that validates whether an object has a certain name. 26 | /// 27 | /// The object type (must implement ) 28 | /// The name to validate against the object 29 | /// The type of string comparison to use 30 | /// A new predicate 31 | public static Predicate IsName(string name, StringComparison comparisonType) 32 | where T : INamed 33 | { 34 | return value => value.Name.Equals(name, comparisonType); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Platform/Network/Time/NetworkTimeClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Network.Time 4 | { 5 | /// 6 | /// Base class for any network time client. 7 | /// 8 | public abstract class NetworkTimeClient 9 | : AbstractTask, IValued 10 | { 11 | /// 12 | /// The name of the time server 13 | /// 14 | public string ServerName { get; set; } 15 | 16 | /// 17 | /// The port the time server is listening on 18 | /// 19 | public int Port { get; set; } 20 | 21 | /// 22 | /// Constructs a new 23 | /// 24 | /// The name of the time server 25 | /// The port the time server is listening on 26 | protected NetworkTimeClient(string serverName, int port) 27 | { 28 | this.Port = port; 29 | this.ServerName = serverName; 30 | } 31 | 32 | /// 33 | /// The current value from the time server (or null if no value) 34 | /// 35 | public abstract TimeSpan? Value { get; } 36 | 37 | /// 38 | /// The current value from the time server (or null if no value). Value will 39 | /// be returned as a nullable . 40 | /// 41 | object IValued.Value => this.Value; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Platform/NumericConstants.cs: -------------------------------------------------------------------------------- 1 | namespace Platform 2 | { 3 | /// 4 | /// Contains commonly used numeric constants. 5 | /// 6 | public static class NumericConstants 7 | { 8 | /// 9 | /// Size in bytes of 1KiB (1 Kibibyte) 10 | /// 11 | public const long SizeInBytes_1KiB = 1024L * 1024; 12 | 13 | /// 14 | /// Size in bytes of 1MiB (1 Mebibyte) 15 | /// 16 | public const long SizeInBytes_1MiB = 1024L * 1024 * 1024; 17 | 18 | /// 19 | /// Size in bytes of 1GiB (1 Gibibyte) 20 | /// 21 | public const long SizeInBytes_1GiB = 1024L * 1024 * 1024 * 1024; 22 | 23 | /// 24 | /// Size in bytes of 1GiB (1 Tebibyte) 25 | /// 26 | public const long SizeInBytes_1TiB = 1024L * 1024 * 1024 * 1024 * 1024; 27 | 28 | /// 29 | /// Size in bytes of 1Kb (1 Kilobyte) 30 | /// 31 | public const long SizeInBytes_1KB = 1000L * 1000; 32 | 33 | /// 34 | /// Size in bytes of 1MB (1 Megabyte) 35 | /// 36 | public const long SizeInBytes_1MB = 1000L * 1000 * 1000; 37 | 38 | /// 39 | /// Size in bytes of 1GB (1 Gigabyte) 40 | /// 41 | public const long SizeInBytes_1GB = 1000L * 1000 * 1000 * 1000; 42 | 43 | /// 44 | /// Size in bytes of 1TB (1 Terabyte) 45 | /// 46 | public const long SizeInBytes_1TB = 1000L * 1000 * 1000 * 1000 * 1000; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Platform/ObjectActivator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | /// 8 | /// A delegate that creates an object from a type. 9 | /// 10 | /// 11 | /// The type of object to create. 12 | /// 13 | /// The newly created object 14 | public delegate object ObjectActivator(Type type); 15 | 16 | /// 17 | /// A delegate that creates an object from a type. 18 | /// 19 | /// The type of object to return 20 | /// 21 | /// The type of object to create. Type must be or be 22 | /// a child of 23 | /// 24 | /// The newly created object 25 | public delegate V ObjectActivator(Type type); 26 | } 27 | -------------------------------------------------------------------------------- /src/Platform/ObjectReferenceIdentityEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | namespace Platform 7 | { 8 | public class ObjectReferenceIdentityEqualityComparer 9 | : IEqualityComparer 10 | where T : class 11 | { 12 | public static readonly ObjectReferenceIdentityEqualityComparer Default = new ObjectReferenceIdentityEqualityComparer(); 13 | 14 | public bool Equals(T x, T y) 15 | { 16 | return object.ReferenceEquals(x, y); 17 | } 18 | 19 | public int GetHashCode(T obj) 20 | { 21 | if (obj == null) 22 | { 23 | throw new ArgumentNullException(nameof(obj)); 24 | } 25 | 26 | return obj.GetHashCode(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Platform/Platform.1.0.0.341.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/platformdotnet/Platform/68aef5248b6559a85a914965bcc08696623d1aea/src/Platform/Platform.1.0.0.341.nupkg -------------------------------------------------------------------------------- /src/Platform/Platform.NET.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Platform.NET 5 | $version$ 6 | Platform.NET System Library 7 | Thong Nguyen 8 | Thong Nguyen 9 | https://raw.github.com/platformdotnet/Platform/master/LICENSE 10 | https://github.com/platformdotnet/Platform.VirtualFileSystem 11 | false 12 | $description$ 13 | Initial release 14 | Copyright (c) 2003-2013 Thong Nguyen (tumtumtum@gmail.com) 15 | task text utility string extensions ntp invocationqueue 16 | 17 | -------------------------------------------------------------------------------- /src/Platform/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("Platform.NET System Library")] 8 | [assembly: AssemblyDescription("A cross-platform libary with useful utility classes for .NET")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("Thong Nguyen")] 11 | [assembly: AssemblyProduct("Platform.NET")] 12 | [assembly: AssemblyCopyright("Copyright © 2004-1013 Thong Nguyen (tumtumtum@gmail.com)")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("6638f832-0052-4238-a67e-43d6854df3c3")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | [assembly: AssemblyVersion("1.0.0.0")] 32 | [assembly: AssemblyFileVersion("1.0.0.0")] 33 | -------------------------------------------------------------------------------- /src/Platform/PropertyWiseEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Reflection; 5 | using Platform.Reflection; 6 | 7 | namespace Platform 8 | { 9 | public class PropertyWiseEqualityComparer 10 | : IEqualityComparer 11 | { 12 | private readonly Func comparerBuilder; 13 | public static readonly PropertyWiseEqualityComparer Default = new PropertyWiseEqualityComparer(); 14 | public static readonly PropertyWiseEqualityComparer DefaultUsingReferenceEqualty = new PropertyWiseEqualityComparer(Expression.ReferenceEqual); 15 | 16 | private Func comparerFunction; 17 | 18 | public PropertyWiseEqualityComparer() 19 | : this((x, y) => Expression.Call(Expression.Property(null, typeof(EqualityComparer<>).MakeGenericType(x.Type).GetProperty("Default", BindingFlags.Public | BindingFlags.Static)), 20 | TypeUtils.GetMethod>(c => c.Equals(null, null)).GetMethodOnTypeReplacingTypeGenericArgs(x.Type), x, y)) 21 | { 22 | } 23 | 24 | public PropertyWiseEqualityComparer(Func equalityComparerFromType) 25 | : this((x, y) => Expression.Call(Expression.Constant(equalityComparerFromType(x.Type)), TypeUtils.GetMethod>(c => c.Equals(null, null)).GetMethodOnTypeReplacingTypeGenericArgs(x.Type), x, y)) 26 | { 27 | } 28 | 29 | public PropertyWiseEqualityComparer(Func comparerBuilder) 30 | { 31 | this.comparerBuilder = comparerBuilder; 32 | } 33 | 34 | public virtual bool Equals(T x, T y) 35 | { 36 | if (comparerFunction == null) 37 | { 38 | Expression body = null; 39 | var left = Expression.Parameter(typeof(T), "left"); 40 | var right = Expression.Parameter(typeof(T), "right"); 41 | 42 | foreach (var property in typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public)) 43 | { 44 | var expression = comparerBuilder(Expression.Property(left, property), Expression.Property(right, property)); 45 | 46 | body = body == null ? expression : Expression.AndAlso(body, expression); 47 | } 48 | 49 | if (body != null) 50 | { 51 | comparerFunction = Expression.Lambda>(body, left, right).Compile(); 52 | } 53 | else 54 | { 55 | comparerFunction = Expression.Lambda>(Expression.Constant(true), left, right).Compile(); 56 | } 57 | } 58 | 59 | return comparerFunction(x, y); 60 | } 61 | 62 | public virtual int GetHashCode(T obj) 63 | { 64 | if (obj == null) 65 | { 66 | throw new ArgumentNullException(nameof(obj)); 67 | } 68 | 69 | return obj.GetHashCode(); 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /src/Platform/Reference.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform 4 | { 5 | /// 6 | /// Summary description for Reference. 7 | /// 8 | public abstract class Reference 9 | { 10 | public object Target 11 | { 12 | get 13 | { 14 | return m_Target; 15 | } 16 | set 17 | { 18 | m_Target = value; 19 | } 20 | } 21 | private object m_Target; 22 | 23 | protected Reference(object target) 24 | { 25 | m_Target = target; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Platform/References/IReferenceQueue.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.References 2 | { 3 | /// 4 | /// An interface implemented objects that want to know when a 5 | /// target has been collected. 6 | /// 7 | /// The target 8 | /// 9 | public interface IReferenceQueue 10 | where T : class 11 | { 12 | /// 13 | /// This method is called whenever the garbage collector has collected a 14 | /// target. 15 | /// 16 | /// The reference whose target has been collected 17 | void Enqueue(Reference reference); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Platform/References/NotifyingWeakReference.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.References 4 | { 5 | /// 6 | /// A that fires an event after its target has been finalized 7 | /// 8 | /// The type of the target that the reference points to 9 | public class NotifyingWeakReference 10 | : WeakReference 11 | where T : class 12 | { 13 | /// 14 | /// An event that is raised a reference target is collected. The event 15 | /// will be raised on the garbage collector finalizer thread. 16 | /// 17 | public virtual event EventHandler ReferenceCollected; 18 | 19 | protected virtual void OnReferenceCollected(EventArgs eventArgs) 20 | { 21 | var eventHandler = this.ReferenceCollected; 22 | 23 | eventHandler?.Invoke(this, eventArgs); 24 | } 25 | 26 | private class GarbageCollectionListener 27 | { 28 | private readonly NotifyingWeakReference notifyingReference; 29 | 30 | public GarbageCollectionListener(NotifyingWeakReference notifyingReference) 31 | { 32 | this.notifyingReference = notifyingReference; 33 | } 34 | 35 | ~GarbageCollectionListener() 36 | { 37 | if (notifyingReference.Target == null) 38 | { 39 | notifyingReference.OnReferenceCollected(EventArgs.Empty); 40 | } 41 | else 42 | { 43 | // ReSharper disable once ObjectCreationAsStatement 44 | new GarbageCollectionListener(notifyingReference); 45 | } 46 | } 47 | } 48 | 49 | /// 50 | /// Constructs a new 51 | /// 52 | /// The reference target 53 | public NotifyingWeakReference(T value) 54 | : base(value) 55 | { 56 | // ReSharper disable once ObjectCreationAsStatement 57 | new GarbageCollectionListener(this); 58 | } 59 | 60 | /// 61 | /// Constructs a new 62 | /// 63 | /// The reference target 64 | /// 65 | /// True if the current reference should continue to reference the target 66 | /// after it has been resurrected. 67 | /// 68 | public NotifyingWeakReference(T value, bool trackResurrection) 69 | : base(value, null, trackResurrection) 70 | { 71 | // ReSharper disable once ObjectCreationAsStatement 72 | new GarbageCollectionListener(this); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Platform/References/WeakReference.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.References 4 | { 5 | /// 6 | /// A generic implementation that supports GC monitoring using . 7 | /// 8 | public class WeakReference 9 | : Reference 10 | where T : class 11 | { 12 | private readonly WeakReference systemReference; 13 | 14 | /// 15 | /// Constructs a new with the given target. 16 | /// 17 | /// 18 | public WeakReference(T target) 19 | : this(target, null) 20 | { 21 | } 22 | 23 | public WeakReference(T target, IReferenceQueue queue) 24 | : this(target, queue, false) 25 | { 26 | } 27 | 28 | public WeakReference(T target, IReferenceQueue queue, bool trackResurrection) 29 | : base(queue) 30 | { 31 | systemReference = new System.WeakReference(target, trackResurrection); 32 | 33 | CreateFinalizerListener(); 34 | } 35 | 36 | /// 37 | /// The reference target. 38 | /// 39 | public override T Target => (T)this.systemReference.Target; 40 | 41 | /// 42 | /// Gets weather the reference continues to reference the target 43 | /// if it has been resurrected. 44 | /// 45 | public virtual bool TackResurrection => this.systemReference.TrackResurrection; 46 | 47 | /// 48 | /// Clears the target that the points to. 49 | /// 50 | public override void Clear() 51 | { 52 | systemReference.Target = null; 53 | 54 | Enqueue(); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Platform/Reflection/ConstructorInfoUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Reflection; 4 | 5 | namespace Platform.Reflection 6 | { 7 | public static class ConstructorInfoUtils 8 | { 9 | public static ConstructorInfo GetConstructorOnGenericType(this ConstructorInfo constructorInfo) 10 | { 11 | return constructorInfo.GetConstructorOnTypeReplacingTypeGenericArgs(); 12 | } 13 | 14 | public static ConstructorInfo GetConstructorOnTypeReplacingTypeGenericArgs(this ConstructorInfo constructorInfo, params Type[] types) 15 | { 16 | if (constructorInfo.DeclaringType == null) 17 | { 18 | throw new ArgumentException("Does not have a declaring genericArgument", nameof(constructorInfo)); 19 | } 20 | 21 | if (!constructorInfo.DeclaringType.IsGenericType) 22 | { 23 | throw new ArgumentException("Declaring type of constructor is not generic", nameof(constructorInfo)); 24 | } 25 | 26 | var genericDeclaringType = constructorInfo 27 | .DeclaringType 28 | .GetGenericTypeDefinition(); 29 | 30 | if (types == null || types.Length == 0) 31 | { 32 | types = genericDeclaringType.GetGenericArguments(); 33 | } 34 | 35 | var constructorInfoParameters = constructorInfo.GetParameters(); 36 | 37 | var realisedTypeFromGenericParam1 = genericDeclaringType.GetGenericArguments() 38 | .Select((k, i) => new { k, v = constructorInfo.DeclaringType?.GetGenericArguments()[i] }) 39 | .ToDictionary(c => c.k, c => c.v); 40 | 41 | var realisedTypeFromGenericParam2 = genericDeclaringType.GetGenericArguments() 42 | .Select((k, i) => new { k, v = types[i] }) 43 | .ToDictionary(c => c.k, c => c.v); 44 | 45 | var result1 = genericDeclaringType 46 | .GetConstructors() 47 | .Where(c => c.GetParameters().Length == constructorInfoParameters.Length) 48 | .Select(c => new { constructor = c, currentTypes = TypeUtils.Substitute(c.GetParameters().Select(d => d.ParameterType), realisedTypeFromGenericParam1), newTypes = TypeUtils.Substitute(c.GetParameters().Select(d => d.ParameterType), realisedTypeFromGenericParam2) }) 49 | .SingleOrDefault(c => c.currentTypes.SequenceEqual(constructorInfoParameters.Select(d => d.ParameterType))); 50 | 51 | if (result1 == null) 52 | { 53 | return null; 54 | } 55 | 56 | return genericDeclaringType.MakeGenericType(types).GetConstructor(result1.newTypes); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Platform/Reflection/MethodInfoUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Reflection; 4 | 5 | namespace Platform.Reflection 6 | { 7 | public static class MethodInfoUtils 8 | { 9 | public static MethodInfo GetGenericMethodOrRegular(this MethodInfo methodInfo) 10 | { 11 | return methodInfo.IsGenericMethod ? methodInfo.GetGenericMethodDefinition() : methodInfo; 12 | } 13 | 14 | public static MethodInfo GetMethodOnGenericType(this MethodInfo methodInfo) 15 | { 16 | return methodInfo.GetMethodOnTypeReplacingTypeGenericArgs(); 17 | } 18 | 19 | public static MethodInfo GetMethodOnTypeReplacingTypeGenericArgs(this MethodInfo methodInfo, params Type[] types) 20 | { 21 | if (methodInfo.DeclaringType == null) 22 | { 23 | throw new ArgumentException("Does not have a declaring genericArgument", nameof(methodInfo)); 24 | } 25 | 26 | if (!methodInfo.DeclaringType.IsGenericType) 27 | { 28 | throw new ArgumentException("Declaring type of method is not generic", nameof(methodInfo)); 29 | } 30 | 31 | var genericDeclaringType = methodInfo 32 | .DeclaringType 33 | .GetGenericTypeDefinition(); 34 | 35 | if (types == null || types.Length == 0) 36 | { 37 | types = genericDeclaringType.GetGenericArguments(); 38 | } 39 | 40 | var methodInfoParameters = methodInfo.GetParameters(); 41 | 42 | var realisedTypeFromGenericParam1 = genericDeclaringType.GetGenericArguments() 43 | .Select((k, i) => new { k, v = methodInfo.DeclaringType?.GetGenericArguments()[i] }) 44 | .ToDictionary(c => c.k, c => c.v); 45 | 46 | var realisedTypeFromGenericParam2 = genericDeclaringType.GetGenericArguments() 47 | .Select((k, i) => new { k, v = types[i] }) 48 | .ToDictionary(c => c.k, c => c.v); 49 | 50 | var result1 = genericDeclaringType 51 | .GetMethods() 52 | .Where(c => c.Name == methodInfo.Name) 53 | .Where(c => c.GetParameters().Length == methodInfoParameters.Length) 54 | .Select(c => new { constructor = c, currentTypes = TypeUtils.Substitute(c.GetParameters().Select(d => d.ParameterType), realisedTypeFromGenericParam1), newTypes = TypeUtils.Substitute(c.GetParameters().Select(d => d.ParameterType), realisedTypeFromGenericParam2) }) 55 | .SingleOrDefault(c => c.currentTypes.SequenceEqual(methodInfoParameters.Select(d => d.ParameterType))); 56 | 57 | if (result1 == null) 58 | { 59 | return null; 60 | } 61 | 62 | return genericDeclaringType.MakeGenericType(types).GetMethod(methodInfo.Name, result1.newTypes); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Platform/ReownedMeter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | namespace Platform 4 | { 5 | /// 6 | /// A that allows a meter's owner to be changed. 7 | /// 8 | public class ReownedMeter 9 | : MeterWrapper 10 | { 11 | /// 12 | /// Creates a new 13 | /// 14 | /// The new owner for the meter 15 | /// The meter to wrap 16 | public ReownedMeter(object newOwner, IMeter meter) 17 | : base(meter) 18 | { 19 | this.Owner = newOwner; 20 | } 21 | 22 | public override object Owner { get; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Platform/Runtime/Interop/MarshalUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace Platform.Runtime.Interop 5 | { 6 | /// 7 | /// Provides extension methods and static utility methods for the class. 8 | /// 9 | public class MarshalUtils 10 | { 11 | /// 12 | /// Serializes a structure into raw bytes 13 | /// 14 | /// The struture to serialize 15 | /// 16 | public static byte[] RawSerialize(T structure) 17 | where T : struct 18 | { 19 | return RawSerialize((object)structure); 20 | } 21 | 22 | /// 23 | /// Serializes a structure into raw bytes 24 | /// 25 | /// The struture to serialize 26 | /// 27 | public static byte[] RawSerialize(object structure) 28 | { 29 | var rawsize = Marshal.SizeOf(structure); 30 | var buffer = Marshal.AllocHGlobal(rawsize); 31 | 32 | Marshal.StructureToPtr(structure, buffer, false); 33 | var rawdata = new byte[rawsize]; 34 | Marshal.Copy(buffer, rawdata, 0, rawsize); 35 | Marshal.FreeHGlobal(buffer); 36 | 37 | return rawdata; 38 | } 39 | 40 | /// 41 | /// Deserialize a structure from bytes 42 | /// 43 | /// The type of the structure to deserialize 44 | /// The data that makes up the structure 45 | /// The deserialized structure 46 | public static T RawDeserialize(byte[] rawdata) 47 | where T : struct 48 | { 49 | return (T)RawDeserialize(rawdata, typeof(T)); 50 | } 51 | 52 | /// 53 | /// Deserialize a structure from bytes 54 | /// 55 | /// The type of the structure to deserialize 56 | /// The data that makes up the structure 57 | /// The deserialized structure 58 | public static object RawDeserialize(byte[] rawdata, Type type) 59 | { 60 | var rawsize = Marshal.SizeOf(type); 61 | 62 | if (rawsize > rawdata.Length) 63 | { 64 | return null; 65 | } 66 | 67 | var buffer = Marshal.AllocHGlobal(rawsize); 68 | Marshal.Copy(rawdata, 0, buffer, rawsize); 69 | var retval = Marshal.PtrToStructure(buffer, type); 70 | Marshal.FreeHGlobal(buffer); 71 | 72 | return retval; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Platform/SoftReference.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | 4 | namespace Platform 5 | { 6 | /// 7 | /// Summary description for SoftReference. 8 | /// 9 | public class SoftReference 10 | : Reference 11 | { 12 | WeakReference weakTarget; 13 | 14 | public SoftReference(object target) 15 | : base(target) 16 | { 17 | weakTarget = new WeakReference(target); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Platform/StopRequestedException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | /// 8 | /// Exception used to unravel the stack when a task or operation 9 | /// is cancelled or stopped. 10 | /// 11 | public class StopRequestedException 12 | : Exception 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Platform/TaskExceptionEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform 4 | { 5 | /// 6 | /// Class that holds event information for task events. 7 | /// 8 | /// 9 | /// 10 | public class TaskExceptionEventArgs 11 | : EventArgs 12 | { 13 | public TaskExceptionEventArgs(Exception exception) 14 | { 15 | this.Exception = exception; 16 | } 17 | 18 | /// 19 | /// Exception 20 | /// 21 | public virtual Exception Exception { get; private set; } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Platform/TaskUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | using System.Threading; 5 | 6 | namespace Platform 7 | { 8 | /// 9 | /// Provides extension methods and static utility methods for ITasks objects. 10 | /// 11 | public static class TaskUtils 12 | { 13 | public static void WaitForFinish(this ITask task) 14 | { 15 | task.WaitForAnyTaskState(TaskState.Finished); 16 | } 17 | 18 | /// 19 | /// Waits for a task to reach one or more given states 20 | /// 21 | /// The task to wait on 22 | /// The task states to wait for 23 | public static void WaitForAnyTaskState(this ITask task, params TaskState[] taskStates) 24 | { 25 | WaitForAnyTaskState(task, value => Array.IndexOf(taskStates, value) >= 0); 26 | } 27 | 28 | /// 29 | /// Waits for a task to reach one or more given states 30 | /// 31 | /// The task to wait on 32 | /// A timeout 33 | /// The task states to wait for 34 | /// True if the task reached any of the given states or false if the timeout period occured first 35 | public static bool WaitForAnyTaskState(this ITask task, TimeSpan timeout, params TaskState[] taskStates) 36 | { 37 | return WaitForAnyTaskState(task, timeout, value => Array.IndexOf(taskStates, value) >= 0); 38 | } 39 | 40 | /// 41 | /// Waits for a task to reach a given state 42 | /// 43 | /// The task to wait on 44 | /// A predicate that validates for a given state 45 | public static void WaitForAnyTaskState(this ITask task, Predicate acceptState) 46 | { 47 | WaitForAnyTaskState(task, TimeSpan.FromMilliseconds(-1), acceptState); 48 | } 49 | 50 | /// 51 | /// Waits for a task to reach a given state 52 | /// 53 | /// The task to wait on 54 | /// A predicate that validates for a given state 55 | /// A timeout 56 | public static bool WaitForAnyTaskState(this ITask task, TimeSpan timeout, Predicate acceptState) 57 | { 58 | if (acceptState(task.TaskState)) 59 | { 60 | return true; 61 | } 62 | 63 | var obj = new object(); 64 | 65 | task.TaskStateChanged += delegate 66 | { 67 | lock (obj) 68 | { 69 | Monitor.PulseAll(obj); 70 | } 71 | }; 72 | 73 | while (true) 74 | { 75 | lock (obj) 76 | { 77 | if (acceptState(task.TaskState)) 78 | { 79 | return true; 80 | } 81 | 82 | if (!Monitor.Wait(obj, timeout)) 83 | { 84 | return false; 85 | } 86 | } 87 | } 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/Platform/Text/CharArrayReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Platform.Text 5 | { 6 | /// 7 | /// A reader that reads from an array of . 8 | /// 9 | public class CharArrayReader 10 | : TextReader 11 | { 12 | private int offset; 13 | private int endIndex; 14 | private char[] array; 15 | 16 | /// 17 | /// Constructs a new 18 | /// 19 | /// The array of chars to read from 20 | public CharArrayReader(char[] array) 21 | : this(array, 0) 22 | { 23 | } 24 | 25 | /// 26 | /// Constructs a new 27 | /// 28 | /// The array of chars to read from 29 | /// The offset within the array to start reading from 30 | public CharArrayReader(char[] array, int offset) 31 | : this(array, offset, array.Length - offset) 32 | { 33 | } 34 | 35 | /// 36 | /// Constructs a new 37 | /// 38 | /// The array of chars to read from 39 | /// The offset within the array to start reading from 40 | /// The number of chars to read 41 | public CharArrayReader(char[] array, int offset, int count) 42 | { 43 | Attach(array, offset, count); 44 | } 45 | 46 | private void Attach(char[] array, int offset, int count) 47 | { 48 | endIndex = offset + count - 1; 49 | 50 | if (endIndex > array.Length - 1) 51 | { 52 | throw new ArgumentOutOfRangeException("offset"); 53 | } 54 | 55 | this.offset = offset; 56 | this.array = array; 57 | } 58 | 59 | public override int Peek() 60 | { 61 | if (offset > endIndex) 62 | { 63 | return -1; 64 | } 65 | 66 | return array[offset]; 67 | } 68 | 69 | public override int Read() 70 | { 71 | if (offset > endIndex) 72 | { 73 | return -1; 74 | } 75 | 76 | return array[offset++]; 77 | } 78 | 79 | public override int Read(char[] buffer, int index, int count) 80 | { 81 | if (offset > endIndex) 82 | { 83 | return -1; 84 | } 85 | 86 | count = Math.Min(count, endIndex - offset + 1); 87 | 88 | Array.Copy(array, offset, buffer, index, count); 89 | 90 | offset += count; 91 | 92 | return count; 93 | } 94 | 95 | public override int ReadBlock(char[] buffer, int index, int count) 96 | { 97 | return Read(buffer, index, count); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/Platform/Text/RegularExpressions/RegexBasedPredicateHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | using System.Text.RegularExpressions; 5 | 6 | namespace Platform.Text.RegularExpressions 7 | { 8 | /// 9 | /// A helper class for creating predicate based on a regular expression. 10 | /// Use the to create actual regular expression predicate. 11 | /// 12 | public class RegexBasedPredicateHelper 13 | { 14 | /// 15 | /// The regular expression 16 | /// 17 | public virtual Regex Regex { get; } 18 | 19 | /// 20 | /// Creates a new from the given . 21 | /// 22 | /// The 23 | protected internal RegexBasedPredicateHelper(string regex) 24 | : this(new Regex(regex)) 25 | { 26 | } 27 | 28 | /// 29 | /// Creates a new from the given . 30 | /// 31 | /// The 32 | protected internal RegexBasedPredicateHelper(Regex regex) 33 | { 34 | this.Regex = regex; 35 | } 36 | 37 | public static bool IsRegexBasedPredicate(Predicate regexBasedPredicate) 38 | { 39 | return regexBasedPredicate.Target is RegexBasedPredicateHelper; 40 | } 41 | 42 | /// 43 | /// Gets the regular expression from the given predicate. 44 | /// 45 | /// 46 | /// The given predicate was not created by 47 | /// The associated with the 48 | public static Regex GetRegexFromPredicate(Predicate regexBasedPredicate) 49 | { 50 | var predicateHelper = regexBasedPredicate.Target as RegexBasedPredicateHelper; 51 | 52 | if (predicateHelper == null) 53 | { 54 | throw new ArgumentException($"Must be a predicateHelper created from {typeof(RegexBasedPredicateHelper).Name}"); 55 | } 56 | 57 | return predicateHelper.Regex; 58 | } 59 | 60 | public virtual bool Accept(string value) 61 | { 62 | return this.Regex.IsMatch(value); 63 | } 64 | 65 | public virtual Predicate ToPredicate() 66 | { 67 | return this; 68 | } 69 | 70 | public static implicit operator Predicate(RegexBasedPredicateHelper predicateHelper) 71 | { 72 | return predicateHelper.Accept; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Platform/Text/RegularExpressions/RegexCache.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text.RegularExpressions; 4 | using Platform.Collections; 5 | 6 | namespace Platform.Text.RegularExpressions 7 | { 8 | public class RegexCache 9 | { 10 | public static readonly RegexCache Default = new RegexCache(TimeSpan.FromMinutes(60)); 11 | 12 | private struct CacheKey 13 | { 14 | internal readonly string regex; 15 | internal readonly RegexOptions options; 16 | 17 | public CacheKey(string regex, RegexOptions options) 18 | { 19 | this.regex = regex; 20 | this.options = options; 21 | } 22 | } 23 | 24 | private class CacheKeyEqualityComparer 25 | : IEqualityComparer 26 | { 27 | public static readonly CacheKeyEqualityComparer Default = new CacheKeyEqualityComparer(); 28 | 29 | public bool Equals(CacheKey x, CacheKey y) 30 | { 31 | return x.options == y.options && x.regex == y.regex; 32 | } 33 | 34 | public int GetHashCode(CacheKey obj) 35 | { 36 | return (obj.regex == null ? 0 : obj.regex.GetHashCode() ^ (int)obj.options); 37 | } 38 | } 39 | 40 | private readonly IDictionary cache; 41 | 42 | public RegexCache(TimeSpan timeout) 43 | { 44 | cache = new TimedReferenceDictionary(timeout, CacheKeyEqualityComparer.Default); 45 | } 46 | 47 | public Regex Create(string regex, RegexOptions options) 48 | { 49 | lock (cache) 50 | { 51 | Regex retval; 52 | var key = new CacheKey(regex, options); 53 | 54 | if (cache.TryGetValue(key, out retval)) 55 | { 56 | return retval; 57 | } 58 | 59 | options |= RegexOptions.Compiled; 60 | 61 | retval = new Regex(regex, options); 62 | 63 | cache[key] = retval; 64 | 65 | return retval; 66 | } 67 | } 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /src/Platform/Threading/ThreadPriorityContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | 4 | namespace Platform.Threading 5 | { 6 | /// 7 | /// Class for temporarily changing a thread's priority using the C# using statement 8 | /// 9 | /// 10 | /// The current thread's priority is changed to the provided priority until the 11 | /// object is disposed. 12 | /// 13 | public class ThreadPriorityContext 14 | : IDisposable 15 | { 16 | /// 17 | /// The original thread priority 18 | /// 19 | private readonly ThreadPriority originalPriority; 20 | 21 | /// 22 | /// Constructs a new with the given priority 23 | /// 24 | /// The priority to change the current thread to 25 | public ThreadPriorityContext(ThreadPriority priority) 26 | { 27 | originalPriority = priority; 28 | 29 | Thread.CurrentThread.Priority = priority; 30 | } 31 | 32 | /// 33 | /// Changes the current thread's priority back to the original value 34 | /// 35 | void IDisposable.Dispose() 36 | { 37 | Thread.CurrentThread.Priority = originalPriority; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Platform/Validation/BaseValidationAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Validation 4 | { 5 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter)] 6 | public class BaseValidationAttribute 7 | : Attribute, INamed 8 | { 9 | public virtual string Name 10 | { 11 | get 12 | { 13 | if (this.GetType().Name.EndsWith("Attribute")) 14 | { 15 | return this.GetType().Name; 16 | } 17 | else 18 | { 19 | var name = this.GetType().Name; 20 | 21 | return name.Substring(0, name.Length - "Attribute".Length); 22 | } 23 | } 24 | } 25 | 26 | public virtual string CreateExceptionString(IPropertyValidationContext context) 27 | { 28 | return $@"{this.Name}"; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Platform/Validation/DefaultPropertyValidator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | 4 | namespace Platform.Validation 5 | { 6 | public class DefaultPropertyValidator 7 | : PropertyValidator 8 | { 9 | private readonly ValidationAttribute attribute; 10 | 11 | public DefaultPropertyValidator(ValidationAttribute attribute) 12 | { 13 | this.attribute = attribute; 14 | } 15 | 16 | public override ValidationResult Validate(PropertyValidationContext propertyValidationContext) 17 | { 18 | return this.attribute.Validate(propertyValidationContext); 19 | } 20 | 21 | public override Expression, ValidationResult>> GetValidationExpression() 22 | { 23 | return this.attribute.GetValidateExpression(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Platform/Validation/DefaultPropertyValidatorProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Validation 2 | { 3 | public class DefaultPropertyValidatorProvider 4 | : PropertyValidatorProvider 5 | { 6 | public override PropertyValidator GetPropertyValidator(ValidationAttribute validationAttribute) 7 | { 8 | return new DefaultPropertyValidator(validationAttribute); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Platform/Validation/DefaultValueAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Validation 4 | { 5 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter)] 6 | public class DefaultValueAttribute 7 | : BaseValidationAttribute 8 | { 9 | public object Value { get; set; } 10 | public string ValueExpression { get; set; } 11 | 12 | public DefaultValueAttribute() 13 | { 14 | } 15 | 16 | public DefaultValueAttribute(object value) 17 | { 18 | this.Value = value; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Platform/Validation/IPropertyValidationContext.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace Platform.Validation 4 | { 5 | public interface IPropertyValidationContext 6 | { 7 | BaseValidationAttribute ValidationAttribute { get; } 8 | object ObjectValue { get; } 9 | PropertyInfo PropertyInfo { get; } 10 | object PropertyValue { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Platform/Validation/IValidator.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Validation 2 | { 3 | public interface IValidator 4 | { 5 | ValidationResult Validate(object value); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/Platform/Validation/ObjectExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Validation 2 | { 3 | public static class ObjectExtensions 4 | { 5 | public static ValidationResult Validate(this T obj) 6 | where T : class 7 | { 8 | return Validator.NewValidator().Validate(obj); 9 | } 10 | 11 | public static ValidationResult Validate(this T obj, ValidatorOptions options) 12 | where T : class 13 | { 14 | return Validator.NewValidator(options).Validate(obj); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Platform/Validation/PropertyValidationContext.cs: -------------------------------------------------------------------------------- 1 | using System.Linq.Expressions; 2 | using System.Reflection; 3 | 4 | namespace Platform.Validation 5 | { 6 | public struct PropertyValidationContext 7 | : IPropertyValidationContext 8 | { 9 | public BaseValidationAttribute ValidationAttribute { get; } 10 | 11 | public ValidationContext ValidationContext { get; } 12 | 13 | object IPropertyValidationContext.ObjectValue => this.ObjectValue; 14 | 15 | public OBJECT_TYPE ObjectValue => this.ValidationContext.ObjectValue; 16 | 17 | public PropertyInfo PropertyInfo { get; internal set; } 18 | 19 | public PROPERTY_TYPE PropertyValue { get; } 20 | 21 | object IPropertyValidationContext.PropertyValue => this.PropertyValue; 22 | 23 | public static Expression GetCurrentValueExpression(ParameterExpression propertyValidationContextExpression) 24 | { 25 | return Expression.Property(propertyValidationContextExpression, "PropertyValue"); 26 | } 27 | 28 | public PropertyValidationContext(ValidationContext validationContext, PropertyInfo currentPropertyInfo, BaseValidationAttribute validationAttribute, PROPERTY_TYPE propertyValue) 29 | : this() 30 | { 31 | this.PropertyValue = propertyValue; 32 | this.ValidationContext = validationContext; 33 | this.ValidationAttribute = validationAttribute; 34 | this.PropertyInfo = currentPropertyInfo; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Platform/Validation/PropertyValidator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Reflection; 4 | 5 | namespace Platform.Validation 6 | { 7 | public abstract class PropertyValidator 8 | { 9 | public static MethodInfo ValidateMethod = typeof(PropertyValidator).GetMethod("Validate", BindingFlags.Static | BindingFlags.Public); 10 | public static MethodInfo GetValidationExpressionMethod = typeof(PropertyValidator).GetMethod("GetValidationExpression", BindingFlags.Static | BindingFlags.Public); 11 | 12 | public abstract ValidationResult Validate(PropertyValidationContext propertyValidationContext); 13 | public abstract Expression, ValidationResult>> GetValidationExpression(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Platform/Validation/PropertyValidatorProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Validation 2 | { 3 | public abstract class PropertyValidatorProvider 4 | { 5 | public abstract PropertyValidator GetPropertyValidator(ValidationAttribute validationAttribute); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/Platform/Validation/SizeFlexibility.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Validation 2 | { 3 | public enum SizeFlexibility 4 | { 5 | Variable, 6 | Fixed, 7 | LargeVariable 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Platform/Validation/UniqueAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Validation 4 | { 5 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter)] 6 | public class UniqueAttribute 7 | : ValidationAttribute 8 | { 9 | public bool Unique { get; set; } 10 | 11 | public UniqueAttribute() 12 | : this(true) 13 | { 14 | } 15 | 16 | public UniqueAttribute(bool unique) 17 | { 18 | this.Unique = unique; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Platform/Validation/UnsetValueAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Validation 4 | { 5 | [AttributeUsage(AttributeTargets.Property|AttributeTargets.Parameter)] 6 | public class UnsetValueAttribute 7 | : BaseValidationAttribute 8 | { 9 | public object Value { get; set; } 10 | public string ValueExpression { get; set; } 11 | 12 | public UnsetValueAttribute() 13 | { 14 | } 15 | 16 | public UnsetValueAttribute(object valueExpression) 17 | { 18 | this.Value = valueExpression; 19 | } 20 | 21 | public UnsetValueAttribute(string valueExpression) 22 | { 23 | this.ValueExpression = valueExpression; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Platform/Validation/ValidationAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | 4 | namespace Platform.Validation 5 | { 6 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Parameter)] 7 | public abstract class ValidationAttribute 8 | : BaseValidationAttribute 9 | { 10 | protected virtual string GetErrorCode() 11 | { 12 | return this.GetType().Name; 13 | } 14 | 15 | public virtual Expression, ValidationResult>> GetValidateExpression() 16 | { 17 | return null; 18 | } 19 | 20 | public virtual ValidationResult Validate(PropertyValidationContext propertyValidationContext) 21 | { 22 | throw new NotImplementedException(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Platform/Validation/ValidationContext.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace Platform.Validation 4 | { 5 | public class ValidationContext 6 | { 7 | public OBJECT_TYPE ObjectValue { get; } 8 | public PropertyInfo CurrentPropertyInfo { get; internal set; } 9 | public ValidatorOptions ValidatorOptions { get; internal set; } 10 | 11 | public U GetPropertyValue(string propertyName) 12 | { 13 | return (U)this.ObjectValue.GetType().GetProperty(propertyName).GetValue(this.ObjectValue, null); 14 | } 15 | 16 | public ValidationContext(OBJECT_TYPE objectValue) 17 | { 18 | this.ObjectValue = objectValue; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Platform/Validation/ValidationException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Validation 4 | { 5 | public class ValidationException 6 | : Exception 7 | { 8 | public IPropertyValidationContext PropertyValidationContext { get; } 9 | 10 | public static string CreateExceptionString(IPropertyValidationContext context) 11 | { 12 | return $"The property '{context.PropertyInfo.ReflectedType.Name}.{context.PropertyInfo.Name}' with the value '{(context.PropertyValue == null ? "null" : Convert.ToString(context.PropertyValue))}' failed {context.ValidationAttribute.Name} validation with result: {context.ValidationAttribute.CreateExceptionString(context)}"; 13 | } 14 | 15 | public ValidationException(IPropertyValidationContext context) 16 | : base(CreateExceptionString(context)) 17 | { 18 | this.PropertyValidationContext = context; 19 | } 20 | 21 | public string ValidationMessage => this.PropertyValidationContext.ValidationAttribute.CreateExceptionString(this.PropertyValidationContext); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Platform/Validation/ValidationResult.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Reflection; 4 | 5 | namespace Platform.Validation 6 | { 7 | public struct ValidationResult 8 | { 9 | public static readonly ValidationResult Success = new ValidationResult(new ValidationException[0]); 10 | 11 | public bool IsSuccess => this.ValidationExceptions.Count == 0; 12 | 13 | public List ValidationExceptions { get; private set; } 14 | 15 | public static readonly MethodInfo CreateResultMethodInfo = typeof(ValidationResult).GetMethod("CreateResult", BindingFlags.Static | BindingFlags.Public); 16 | 17 | public static ValidationResult CreateResult(bool success, IPropertyValidationContext propertyValidationContext) 18 | { 19 | if (success) 20 | { 21 | return ValidationResult.Success; 22 | } 23 | 24 | return new ValidationResult(new ValidationException(propertyValidationContext)); 25 | } 26 | 27 | 28 | public ValidationResult(IEnumerable exceptions) 29 | : this() 30 | { 31 | this.ValidationExceptions = new List(exceptions); 32 | } 33 | 34 | public ValidationResult(ValidationException exception) 35 | : this() 36 | { 37 | this.ValidationExceptions = new List() { exception }; 38 | } 39 | 40 | public ValidationResult(params ValidationException[] exceptions) 41 | : this() 42 | { 43 | this.ValidationExceptions = new List(exceptions); 44 | } 45 | 46 | public ValidationResult(List exceptions) 47 | : this() 48 | { 49 | this.ValidationExceptions = exceptions ?? new List(0); 50 | } 51 | 52 | public static readonly MethodInfo MergeWithMethodInfo = typeof(ValidationResult).GetMethod("MergeWith"); 53 | 54 | public ValidationResult MergeWith(ValidationResult validationResult) 55 | { 56 | if (validationResult.IsSuccess) 57 | { 58 | return this; 59 | } 60 | 61 | if (validationResult.ValidationExceptions.Count == 0) 62 | { 63 | return this; 64 | } 65 | 66 | return new ValidationResult(this.ValidationExceptions.Concat(validationResult.ValidationExceptions)); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Platform/Validation/Validator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Validation 4 | { 5 | public class Validator 6 | { 7 | public static IValidator NewValidator(Type type, ValidatorOptions options) 8 | { 9 | return ValidatorFactory.Default.NewValidator(type, options); 10 | } 11 | 12 | public static Validator NewValidator() 13 | { 14 | return Validator.NewValidator(); 15 | } 16 | } 17 | 18 | public abstract class Validator 19 | : IValidator 20 | { 21 | public ValidatorOptions ValidatorOptions 22 | { 23 | get; 24 | private set; 25 | } 26 | 27 | protected Validator(ValidatorOptions validatorOptions) 28 | { 29 | this.ValidatorOptions = validatorOptions; 30 | } 31 | 32 | public ValidationResult Validate(object value) 33 | { 34 | return Validate((T)value); 35 | } 36 | 37 | public abstract ValidationResult Validate(T value); 38 | 39 | public static Validator NewValidator() 40 | { 41 | return ValidatorFactory.Default.NewValidator(ValidatorOptions.Empty); 42 | } 43 | 44 | public static IValidator NewValidator(Type type, ValidatorOptions options) 45 | { 46 | return ValidatorFactory.Default.NewValidator(type, options); 47 | } 48 | 49 | public static Validator NewValidator(ValidatorOptions options) 50 | { 51 | return ValidatorFactory.Default.NewValidator(options); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Platform/Validation/ValidatorOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Platform.Validation 4 | { 5 | public class ValidatorOptions 6 | { 7 | public static readonly ValidatorOptions Empty = new ValidatorOptions(); 8 | 9 | public IDictionary Properties { get; } 10 | public PropertyValidatorProvider PropertyValidatorProvider { get; private set; } 11 | 12 | public ValidatorOptions() 13 | { 14 | this.Properties = new SortedDictionary(); 15 | this.PropertyValidatorProvider = new DefaultPropertyValidatorProvider(); 16 | } 17 | 18 | public override bool Equals(object obj) 19 | { 20 | if (obj == this) 21 | { 22 | return true; 23 | } 24 | 25 | var typedObj = obj as ValidatorOptions; 26 | 27 | if (typedObj == null) 28 | { 29 | return false; 30 | } 31 | 32 | if (typedObj.Properties == this.Properties) 33 | { 34 | return true; 35 | } 36 | 37 | if (typedObj.Properties.Count != this.Properties.Count) 38 | { 39 | return false; 40 | } 41 | 42 | foreach (var keyValuePair in this.Properties) 43 | { 44 | string value; 45 | 46 | if (!typedObj.Properties.TryGetValue(keyValuePair.Key, out value)) 47 | { 48 | return false; 49 | } 50 | 51 | if (value != keyValuePair.Value) 52 | { 53 | return false; 54 | } 55 | } 56 | 57 | return true; 58 | } 59 | 60 | public override int GetHashCode() 61 | { 62 | var retval = 0; 63 | 64 | foreach (var value in this.Properties.Values) 65 | { 66 | retval ^= value.GetHashCode(); 67 | } 68 | 69 | return retval; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Platform/Validation/Validators/ExpressionTreeBasedValidatorFactory.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Validation.Validators 2 | { 3 | public class ExpressionTreeBasedValidatorFactory 4 | : ValidatorFactory 5 | { 6 | protected override Validator DoNewValidator(ValidatorOptions options) 7 | { 8 | return new ExpressionTreeBasedValidator(options); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Platform/Validation/ValueExpressionConstraintAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using Platform.Validation.Validators; 4 | 5 | namespace Platform.Validation 6 | { 7 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = true)] 8 | public class ValueExpressionConstraintAttribute 9 | : ValidationAttribute 10 | { 11 | public string ConstraintExpression { get; set; } 12 | 13 | public ValueExpressionConstraintAttribute(string constraintExpression) 14 | { 15 | this.ConstraintExpression = constraintExpression; 16 | } 17 | 18 | public override string CreateExceptionString(IPropertyValidationContext context) 19 | { 20 | return $@"Value is '{context.PropertyValue}' but must satisfy: {this.ConstraintExpression}"; 21 | } 22 | 23 | public override Expression, ValidationResult>> GetValidateExpression() 24 | { 25 | var propertyValidationContext = Expression.Parameter(typeof(PropertyValidationContext), "propertyValidationContext"); 26 | 27 | var parsedConstraintExpression = StringExpressionParser.Parse(propertyValidationContext, this.ConstraintExpression); 28 | 29 | var constraintExpression = Expression.Call 30 | ( 31 | null, 32 | ValidationResult.CreateResultMethodInfo, 33 | parsedConstraintExpression, 34 | Expression.Convert(propertyValidationContext, typeof(IPropertyValidationContext)) 35 | ); 36 | 37 | return Expression.Lambda, ValidationResult>>(constraintExpression, propertyValidationContext); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Platform/Validation/ValuePatternConstraint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace Platform.Validation 6 | { 7 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter)] 8 | public class ValuePatternConstraint 9 | : ValidationAttribute 10 | { 11 | public string Pattern 12 | { 13 | get 14 | { 15 | return this.pattern; 16 | } 17 | set 18 | { 19 | this.pattern = value; 20 | patternRegex = new Regex(value, RegexOptions.Compiled); 21 | } 22 | } 23 | private string pattern; 24 | internal Regex patternRegex; 25 | 26 | public bool AllowDefault 27 | { 28 | get; 29 | set; 30 | } 31 | 32 | public ValuePatternConstraint() 33 | : this("") 34 | { 35 | } 36 | 37 | public ValuePatternConstraint(string pattern) 38 | { 39 | this.Pattern = pattern; 40 | } 41 | 42 | public override string CreateExceptionString(IPropertyValidationContext context) 43 | { 44 | return $@"The value does not match the regex pattern: {this.pattern}"; 45 | } 46 | 47 | public override Expression, ValidationResult>> GetValidateExpression() 48 | { 49 | return c => (this.AllowDefault && c.PropertyValue == null) ? ValidationResult.Success : (this.patternRegex.IsMatch(c.PropertyValue.ToString()) ? ValidationResult.Success : new ValidationResult(new ValidationException(c))); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Platform/Validation/ValueRequiredAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | 4 | namespace Platform.Validation 5 | { 6 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter)] 7 | public class ValueRequiredAttribute 8 | : ValidationAttribute 9 | { 10 | public bool Required { get; set; } 11 | 12 | public ValueRequiredAttribute() 13 | : this(true) 14 | { 15 | } 16 | 17 | public ValueRequiredAttribute(bool required) 18 | { 19 | this.Required = required; 20 | } 21 | 22 | public override string CreateExceptionString(IPropertyValidationContext context) 23 | { 24 | return "Must not be null, default or empty string"; 25 | } 26 | 27 | public override Expression, ValidationResult>> GetValidateExpression() 28 | { 29 | var defaultValue = (PROPERTY_TYPE)typeof(PROPERTY_TYPE).GetDefaultValue(); 30 | 31 | if (typeof(PROPERTY_TYPE).IsValueType) 32 | { 33 | return value => value.PropertyValue.Equals(defaultValue) ? new ValidationResult(new ValidationException(value)) : ValidationResult.Success; 34 | } 35 | else if (typeof(PROPERTY_TYPE) == typeof(string)) 36 | { 37 | return value => String.IsNullOrEmpty((string)(object)value.PropertyValue) ? new ValidationResult(new ValidationException(value)) : ValidationResult.Success; 38 | } 39 | else if (typeof(PROPERTY_TYPE).GetProperty("Count") != null) 40 | { 41 | var parameter = Expression.Parameter(typeof(PropertyValidationContext), "propertyValidationContext"); 42 | 43 | var nulltest = Expression.Equal(Expression.Property(parameter, "PropertyValue"), Expression.Constant(null, typeof(PROPERTY_TYPE))); 44 | var counttest = Expression.Equal(Expression.Property(Expression.Property(parameter, "PropertyValue"), "Count"), Expression.Constant(0)); 45 | 46 | var newValidationException = Expression.New(typeof(ValidationException).GetConstructor(new[] { typeof(IPropertyValidationContext) }), Expression.Convert(parameter, typeof(IPropertyValidationContext))); 47 | 48 | var iftrue = Expression.New(typeof(ValidationResult).GetConstructor(new[] { typeof(ValidationException) }), newValidationException); 49 | 50 | var iffalse = Expression.Field(null, typeof(ValidationResult).GetField("Success", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)); 51 | 52 | var body = Expression.Condition(Expression.OrElse(nulltest, counttest), iftrue, iffalse); 53 | 54 | return Expression.Lambda, ValidationResult>>(body, parameter); 55 | } 56 | else 57 | { 58 | return value => value.PropertyValue == null ? new ValidationResult(new ValidationException(value)) : ValidationResult.Success; 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Platform/ValueBox.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Thong Nguyen (tumtumtum@gmail.com) 2 | 3 | using System; 4 | 5 | namespace Platform 6 | { 7 | /// 8 | /// A class that contains a value and allows it to be set and get. 9 | /// This class is useful for holding structures or immutable values (such as strings) 10 | /// so that they can be passed to methods that can change them. 11 | /// 12 | /// 13 | /// The type of value to contain. 14 | /// 15 | public sealed class ValueBox 16 | : IValued 17 | { 18 | /// 19 | /// Gets or sets the contained value. 20 | /// 21 | public T Value { get; set; } 22 | 23 | /// 24 | /// Gets the contained value. 25 | /// 26 | object IValued.Value => this.Value; 27 | 28 | /// 29 | /// Constructs a new with the default 30 | /// value for . 31 | /// 32 | public ValueBox() 33 | : this(default(T)) 34 | { 35 | } 36 | 37 | /// 38 | /// Constructs a new with the given value. 39 | /// 40 | /// The value the should contain. 41 | public ValueBox(T value) 42 | { 43 | this.Value = value; 44 | } 45 | 46 | /// 47 | /// Returns the as a string by calling 48 | /// 49 | /// A string representation of 50 | public override string ToString() 51 | { 52 | return Convert.ToString(this.Value); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/Platform.Tests/EnumerableUtilsTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace Platform.Tests 4 | { 5 | [TestFixture] 6 | public class EnumerableUtilsTests 7 | { 8 | [Test] 9 | public void Test_Fold1() 10 | { 11 | var x = new int[] { 1, 2, 3 }; 12 | 13 | Assert.AreEqual(6, x.Fold((a, b) => a + b)); 14 | } 15 | 16 | [Test] 17 | public void Test_Fold2() 18 | { 19 | var x = new int[] { 1, 2, 3 }; 20 | 21 | Assert.AreEqual(10, x.Fold(4, (a, b) => a + b)); 22 | } 23 | 24 | [Test] 25 | public void Test_Fold_String() 26 | { 27 | var array = new [] { "a", "b", "c" }; 28 | 29 | Assert.AreEqual("a,b,c", array.Fold((x,y) => x + "," + y)); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/Platform.Tests/InvocationQueueTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using NUnit.Framework; 3 | using Platform.Utilities; 4 | 5 | namespace Platform.Tests 6 | { 7 | [TestFixture] 8 | public class InvocationQueueTests 9 | { 10 | [Test] 11 | public void Test_Queue_Items_And_Run_In_Order() 12 | { 13 | var list = new List(); 14 | var expectedList = new List(); 15 | 16 | var queue = new InvocationQueue(); 17 | 18 | for (var i = 0; i < 100; i++) 19 | { 20 | var j = i; 21 | 22 | expectedList.Add(i); 23 | 24 | queue.Enqueue(() => list.Add(j)); 25 | } 26 | 27 | Assert.That(list.Count, Is.EqualTo(0)); 28 | 29 | queue.Start(); 30 | queue.Enqueue(queue.Stop); 31 | 32 | queue.WaitForAnyTaskState(TaskState.Stopped, TaskState.Finished); 33 | 34 | Assert.AreEqual(expectedList, list); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/Platform.Tests/ListUtilsTests.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using NUnit.Framework; 3 | using Platform.Collections; 4 | 5 | namespace Platform.Tests 6 | { 7 | [TestFixture] 8 | public class ListUtilsTests 9 | { 10 | [Test] 11 | public static void Test_Fast_Index_Of() 12 | { 13 | var s = "Hello World World".ToList(); 14 | 15 | var x = s.FastIndexOf("World".ToList()); 16 | Assert.AreEqual(6, x); 17 | 18 | x = s.FastIndexOf(7, "World".ToList()); 19 | Assert.AreEqual(12, x); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Platform.Tests/MathUtilsTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace Platform.Tests 4 | { 5 | [TestFixture] 6 | public class MathUtilsTests 7 | { 8 | [Test] 9 | public void Test_Modulus() 10 | { 11 | Assert.AreEqual(-2, MathUtils.Modulus(4, -3)); 12 | Assert.AreEqual(2, MathUtils.Modulus(-4, 3)); 13 | Assert.AreEqual(1, MathUtils.Modulus(-11, 3)); 14 | Assert.AreEqual(-1, MathUtils.Modulus(11, -3)); 15 | 16 | Assert.AreEqual(0, MathUtils.Modulus(9, 3)); 17 | Assert.AreEqual(1, MathUtils.Modulus(9, 2)); 18 | Assert.AreEqual(1, MathUtils.Modulus(-9, 2)); 19 | Assert.AreEqual(0, MathUtils.Modulus(-9, 3)); 20 | Assert.AreEqual(3, MathUtils.Modulus(-9, 4)); 21 | Assert.AreEqual(-1, MathUtils.Modulus(-9, -4)); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/Platform.Tests/MethodInfoUtilsTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NUnit.Framework; 4 | using Platform.Reflection; 5 | 6 | namespace Platform.Tests 7 | { 8 | [TestFixture] 9 | public class MethodInfoUtilsTests 10 | { 11 | private struct Test 12 | { 13 | public Test(IEnumerable x) 14 | { 15 | } 16 | 17 | public void Foo(out Z z, U[] u) 18 | { 19 | z = default(Z); 20 | } 21 | } 22 | 23 | [Test] 24 | public void Test1() 25 | { 26 | string x; 27 | 28 | 29 | var method = TypeUtils.GetMethod>(c => c.TryGetValue("", out x)); 30 | 31 | var method2 = method.GetMethodOnGenericType(); 32 | 33 | Assert.AreEqual(typeof(Dictionary<,>).GetMethod("TryGetValue"), method2); 34 | 35 | var method3 = method.GetMethodOnTypeReplacingTypeGenericArgs(typeof(int), typeof(int)); 36 | } 37 | 38 | [Test] 39 | public void Test2() 40 | { 41 | var ctor = TypeUtils.GetConstructor(() => new Test(new int[1])); 42 | 43 | ctor = ctor.GetConstructorOnTypeReplacingTypeGenericArgs(typeof(int), typeof(string)); 44 | 45 | Assert.IsNotNull(ctor); 46 | Assert.AreEqual(typeof(int), ctor.DeclaringType?.GetGenericArguments()[0]); 47 | Assert.AreEqual(typeof(string), ctor.DeclaringType?.GetGenericArguments()[1]); 48 | } 49 | 50 | [Test] 51 | public void Test3() 52 | { 53 | int i; 54 | var method = TypeUtils.GetMethod>(c => c.Foo(out i, new string[0])); 55 | 56 | method = method.GetMethodOnTypeReplacingTypeGenericArgs(typeof(string), typeof(long)); 57 | 58 | Assert.IsNotNull(method); 59 | Assert.AreEqual(typeof(string), method.DeclaringType?.GetGenericArguments()[0]); 60 | Assert.AreEqual(typeof(long), method.DeclaringType?.GetGenericArguments()[1]); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/Platform.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("Platform.Tests")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("Platform.Tests")] 12 | [assembly: AssemblyCopyright("Copyright © 2013")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("75f27090-5d79-4b55-9b34-fabb99943335")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /tests/Platform.Tests/TestPropertyWiseEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace Platform.Tests 4 | { 5 | [TestFixture] 6 | public class TestPropertyWiseEqualityComparer 7 | { 8 | public class User 9 | { 10 | public int Age { get; set; } 11 | public string Name { get; set; } 12 | } 13 | 14 | [Test] 15 | public void Test() 16 | { 17 | var user1 = new User { Name = "Harrison", Age = 1 }; 18 | var user2 = new User { Name = "Mars", Age = 12 }; 19 | 20 | Assert.IsTrue(PropertyWiseEqualityComparer.Default.Equals(user1, user1)); 21 | Assert.IsFalse(PropertyWiseEqualityComparer.Default.Equals(user1, user2)); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/Platform.Tests/TextConversionTests.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using NUnit.Framework; 3 | using Platform.Text; 4 | 5 | namespace Platform.Tests 6 | { 7 | [TestFixture] 8 | public class TextConversionTests 9 | { 10 | [Test] 11 | public void Test_HexStringConversion() 12 | { 13 | const string complex = "http://github.com/+123%$"; 14 | 15 | var s = TextConversion.ToEscapedHexString(complex); 16 | 17 | Assert.AreEqual("http%3A%2F%2Fgithub%2Ecom%2F%2B123%25%24", s); 18 | 19 | s = TextConversion.FromEscapedHexString(s); 20 | 21 | Assert.AreEqual(complex, s); 22 | } 23 | 24 | [Test] 25 | public void Test_Base64() 26 | { 27 | var bytes = Encoding.ASCII.GetBytes(""); 28 | var s = TextConversion.ToBase64String(bytes); 29 | 30 | bytes = Encoding.ASCII.GetBytes("H"); 31 | s = TextConversion.ToBase64String(bytes); 32 | Assert.AreEqual("SA==", s); 33 | Assert.AreEqual(TextConversion.FromBase64String(s), bytes); 34 | 35 | bytes = Encoding.ASCII.GetBytes("He"); 36 | s = TextConversion.ToBase64String(bytes); 37 | Assert.AreEqual("SGU=", s); 38 | Assert.AreEqual(TextConversion.FromBase64String(s), bytes); 39 | 40 | bytes = Encoding.ASCII.GetBytes("Hel"); 41 | s = TextConversion.ToBase64String(bytes); 42 | Assert.AreEqual("SGVs", s); 43 | Assert.AreEqual(TextConversion.FromBase64String(s), bytes); 44 | 45 | bytes = Encoding.ASCII.GetBytes("Hell"); 46 | s = TextConversion.ToBase64String(bytes); 47 | Assert.AreEqual("SGVsbA==", s); 48 | Assert.AreEqual(TextConversion.FromBase64String(s), bytes); 49 | 50 | bytes = Encoding.ASCII.GetBytes("Hello"); 51 | s = TextConversion.ToBase64String(bytes); 52 | Assert.AreEqual("SGVsbG8=", s); 53 | Assert.AreEqual(TextConversion.FromBase64String(s), bytes); 54 | } 55 | 56 | [Test] 57 | public void Test_Soundex1() 58 | { 59 | const string name1 = "Euler"; 60 | const string name2 = "Gauss"; 61 | 62 | var soundex1 = TextConversion.ToSoundex(name1); 63 | var soundex2 = TextConversion.ToSoundex(name2); 64 | 65 | Assert.AreEqual("E460", soundex1); 66 | Assert.AreEqual("G200", soundex2); 67 | } 68 | 69 | [Test] 70 | public void Test_Soundex2() 71 | { 72 | const string name1 = "Hilbert"; 73 | const string name2 = "Heilbronn"; 74 | 75 | var soundex1 = TextConversion.ToSoundex(name1); 76 | var soundex2 = TextConversion.ToSoundex(name2); 77 | 78 | Assert.AreEqual(soundex1, soundex2); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /tests/Platform.Tests/TypeUtilsTests.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using NUnit.Framework; 3 | 4 | namespace Platform.Tests 5 | { 6 | [TestFixture] 7 | public class TypeUtilsTests 8 | { 9 | [Test] 10 | public void Test_GetMethod_Static() 11 | { 12 | Assert.IsNotNull(TypeUtils.GetMethod(() => string.Format(string.Empty, new object[0]))); 13 | } 14 | 15 | [Test] 16 | public void Test_GetConstructor() 17 | { 18 | Assert.IsNotNull(TypeUtils.GetMember(() => new TypeUtilsTests()) as ConstructorInfo); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/Platform.Tests/Validation/PageRequest.cs: -------------------------------------------------------------------------------- 1 | using Platform.Validation; 2 | 3 | namespace Platform.Tests.Validation 4 | { 5 | public class PageRequest 6 | { 7 | [ValueRangeConstraint(MinimumValue = 0, AllowDefault = true)] 8 | public long UserId 9 | { 10 | get; 11 | set; 12 | } 13 | 14 | [ValueRangeConstraint(MinimumValue = 0)] 15 | public int Skip 16 | { 17 | get; 18 | set; 19 | } 20 | 21 | [DefaultValue(20)] 22 | [ValueRangeConstraint(MinimumValue = 0)] 23 | public int Take 24 | { 25 | get; 26 | set; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /tests/Platform.Tests/Validation/Person.cs: -------------------------------------------------------------------------------- 1 | using Platform.Validation; 2 | 3 | namespace Platform.Tests.Validation 4 | { 5 | public class Person 6 | { 7 | [ValueRequired] 8 | [SizeConstraint(MinimumLength = 1, MaximumLength = 10)] 9 | public string Name 10 | { 11 | get; 12 | set; 13 | } 14 | 15 | public string Email 16 | { 17 | get; 18 | set; 19 | } 20 | 21 | [UnsetValue(ValueExpression = "-1 * -1 - 2")] 22 | [DefaultValue(ValueExpression = "{Maximum} + 1")] 23 | public int Minimum 24 | { 25 | get; 26 | set; 27 | } 28 | 29 | public int Maximum 30 | { 31 | get; 32 | set; 33 | } 34 | 35 | [ValueRangeConstraint(MinimumValue = 0)] 36 | public long Id 37 | { 38 | get; 39 | set; 40 | } 41 | 42 | [ValueRequired] 43 | [ValueRangeConstraint(MinimumValue = 0, MaximumValue = 10)] 44 | public int Age 45 | { 46 | get; 47 | set; 48 | } 49 | 50 | [ValueRangeConstraint(MinimumValue = 0, MaximumValue = 10000, AllowDefault = true)] 51 | [DefaultValue(1001)] 52 | public int? LibraryAccountNo 53 | { 54 | get; 55 | set; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tests/Platform.Tests/Validation/SearchRequest.cs: -------------------------------------------------------------------------------- 1 | using Platform.Validation; 2 | 3 | namespace Platform.Tests.Validation 4 | { 5 | public class SearchRequest 6 | { 7 | public int Start 8 | { 9 | get; 10 | set; 11 | } 12 | 13 | [ValueExpressionConstraint("{value} > {Start}")] 14 | public int End 15 | { 16 | get; 17 | set; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/Platform.Tests/Validation/User.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Platform.Validation; 3 | 4 | namespace Platform.Tests.Validation 5 | { 6 | public class User 7 | { 8 | [DefaultValue(Value = "Fernando")] 9 | [ValuePatternConstraint("^[A-Za-z]+$", AllowDefault = true)] 10 | public string Name 11 | { 12 | get; 13 | set; 14 | } 15 | 16 | [ValueRequired] 17 | public List Tags 18 | { 19 | get; 20 | set; 21 | } 22 | 23 | [ValueRequired] 24 | [ValueRangeConstraint(MinimumValue = 0, AllowDefault = false)] 25 | public decimal? HairLength 26 | { 27 | get; 28 | set; 29 | } 30 | 31 | [ValueRangeConstraint(MinimumValue = 1, AllowDefault = true)] 32 | public long? Length 33 | { 34 | get; 35 | set; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/Platform.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /tests/Platform.Xml.Serialization.Tests/BasicSerializerTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | 4 | namespace Platform.Xml.Serialization.Tests 5 | { 6 | [TestFixture] 7 | public class BasicSerializerTests 8 | { 9 | [Test] 10 | public virtual void TestSimpleSerialization() 11 | { 12 | var serializer = XmlSerializer.New(); 13 | 14 | var person1 = new Person 15 | { 16 | Name = "Tum" 17 | }; 18 | 19 | var xml = serializer.SerializeToString(person1); 20 | 21 | var person2 = serializer.Deserialize(xml); 22 | 23 | Assert.AreEqual(person1, person2); 24 | } 25 | 26 | [Test] 27 | public virtual void TestDateAndNullableDate() 28 | { 29 | var serializer = XmlSerializer.New(); 30 | 31 | var person1 = new Person 32 | { 33 | Name = "Person 1", 34 | Birthdate = new DateTime(1980, 1, 1), 35 | Deathdate = null 36 | }; 37 | 38 | var xml = serializer.SerializeToString(person1); 39 | 40 | var person2 = serializer.Deserialize(xml); 41 | 42 | Assert.AreEqual(person1.Deathdate, person2.Deathdate); 43 | Assert.AreEqual(person1, person2); 44 | 45 | // Try with non-null deathdate 46 | 47 | person1 = new Person 48 | { 49 | Name = "Dinosaur", 50 | Birthdate = DateTime.MinValue, 51 | Deathdate = DateTime.MinValue.AddYears(1000) 52 | }; 53 | 54 | xml = serializer.SerializeToString(person1); 55 | 56 | person2 = serializer.Deserialize(xml); 57 | 58 | Assert.AreEqual(person1.Deathdate, person2.Deathdate); 59 | 60 | Assert.AreEqual(person1, person2); 61 | } 62 | 63 | [Test] 64 | public virtual void TestPropertyWithDynamicType() 65 | { 66 | var serializer = XmlSerializer.New(); 67 | 68 | var employee = new Employee 69 | { 70 | Name = "Employee 1" 71 | }; 72 | 73 | var person1 = new FriendlyPerson 74 | { 75 | Name = "Friendly Person", 76 | Friend = employee 77 | }; 78 | 79 | var xml = serializer.SerializeToString(person1); 80 | 81 | Console.WriteLine(xml); 82 | 83 | var person2 = serializer.Deserialize(xml); 84 | 85 | Assert.AreEqual(person1, person2); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /tests/Platform.Xml.Serialization.Tests/Customer.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Xml.Serialization.Tests 2 | { 3 | [XmlElement("Person")] 4 | public class Customer 5 | : Person 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/Platform.Xml.Serialization.Tests/DictionaryTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NUnit.Framework; 4 | 5 | namespace Platform.Xml.Serialization.Tests 6 | { 7 | [TestFixture] 8 | public class DictionaryTests 9 | { 10 | [SetUp] 11 | public void SetUp() 12 | { 13 | } 14 | 15 | [TearDown] 16 | public void TearDown() 17 | { 18 | } 19 | 20 | [XmlElement] 21 | public class Foo 22 | { 23 | [XmlElement("Options", typeof(Dictionary))] 24 | [XmlDictionaryElementType(typeof(int), "int")] 25 | 26 | public Dictionary Dictionary { get; set; } 27 | 28 | public Foo() 29 | { 30 | this.Dictionary = new Dictionary(); 31 | 32 | this.Dictionary["One"] = 1; 33 | this.Dictionary["Two"] = 2; 34 | } 35 | } 36 | 37 | [Test] 38 | public void Test_Basic_Dictionary_Serialization() 39 | { 40 | var foo = new Foo(); 41 | 42 | var serializer = XmlSerializer.New(); 43 | 44 | serializer.Serialize(foo, Console.Out); 45 | var s1 = serializer.SerializeToString(foo); 46 | 47 | foo = serializer.Deserialize(s1); 48 | serializer.Serialize(foo, Console.Out); 49 | var s2 = serializer.SerializeToString(foo); 50 | 51 | Assert.AreEqual(s1, s2); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/Platform.Xml.Serialization.Tests/DynamicPersonTypeProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization.Tests 4 | { 5 | public class DynamicPersonTypeProvider 6 | : IXmlDynamicTypeProvider 7 | { 8 | public virtual Type GetType(object instance) 9 | { 10 | return instance.GetType(); 11 | } 12 | 13 | public virtual Type GetType(System.Xml.XmlReader reader) 14 | { 15 | if (!reader.HasAttributes) 16 | { 17 | return null; 18 | } 19 | 20 | var typeName = reader.GetAttribute("type"); 21 | 22 | if (typeName == null) 23 | { 24 | return null; 25 | } 26 | 27 | var type = Type.GetType(this.GetType().Namespace + "." + typeName + "Person", false); 28 | 29 | return type; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/Platform.Xml.Serialization.Tests/Employee.cs: -------------------------------------------------------------------------------- 1 | namespace Platform.Xml.Serialization.Tests 2 | { 3 | [XmlElement("Person")] 4 | public class Employee 5 | : Person 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/Platform.Xml.Serialization.Tests/FriendlyPerson.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Platform.Xml.Serialization.Tests 4 | { 5 | [XmlElement("Person")] 6 | public class FriendlyPerson 7 | : Person 8 | { 9 | [XmlElement, XmlPolymorphicType(typeof(DynamicPersonTypeProvider))] 10 | public virtual Person Friend { get; set; } 11 | 12 | public override int GetHashCode() 13 | { 14 | return base.GetHashCode(); 15 | } 16 | 17 | public override bool Equals(object obj) 18 | { 19 | var friendlyPersonFriend = obj as FriendlyPerson; 20 | 21 | if (friendlyPersonFriend == null) 22 | { 23 | return false; 24 | } 25 | 26 | if (!Object.Equals(this.Friend, friendlyPersonFriend.Friend)) 27 | { 28 | return false; 29 | } 30 | 31 | return base.Equals(obj); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/Platform.Xml.Serialization.Tests/InheritanceTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace Platform.Xml.Serialization.Tests 4 | { 5 | [TestFixture] 6 | public class InheritanceTests 7 | { 8 | [XmlElement] 9 | public class Animal 10 | { 11 | public Animal() 12 | { 13 | this.Name = "Mars"; 14 | } 15 | 16 | [XmlElement] 17 | public string Name 18 | { 19 | get; 20 | private set; 21 | } 22 | } 23 | 24 | [XmlElement] 25 | public class Cat 26 | : Animal 27 | { 28 | [XmlElement] 29 | public string Growl 30 | { 31 | get; 32 | set; 33 | } 34 | } 35 | 36 | [Test] 37 | public void Test_Serialization_Of_Inherited_Types() 38 | { 39 | var cat = new Cat() 40 | { 41 | Growl = "meow" 42 | }; 43 | 44 | var serializer = XmlSerializer.New(); 45 | 46 | var s = serializer.SerializeToString(cat); 47 | 48 | var cat2 = serializer.Deserialize(s); 49 | 50 | Assert.AreEqual("meow", cat2.Growl); 51 | Assert.AreEqual("Mars", cat2.Name); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/Platform.Xml.Serialization.Tests/ListTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NUnit.Framework; 4 | 5 | namespace Platform.Xml.Serialization.Tests 6 | { 7 | [TestFixture] 8 | public class ListTest 9 | { 10 | /// 11 | /// This test failed before this fix 12 | /// 13 | [Test] 14 | public void SerializeAndDeserializeLower() 15 | { 16 | var test = new ListHolderLower() 17 | { 18 | new ListItemLower() 19 | }; 20 | var xml = XmlSerializer.New().SerializeToString(test); 21 | var obj = XmlSerializer.New().Deserialize(xml); 22 | Assert.IsTrue(obj.Count == 1, "List should contain one element"); 23 | } 24 | 25 | [Test] 26 | public void SerializeAndDeserializeNormal() 27 | { 28 | var test = new ListHolder() 29 | { 30 | new ListItem() 31 | }; 32 | var xml = XmlSerializer.New().SerializeToString(test); 33 | var obj = XmlSerializer.New().Deserialize(xml); 34 | Assert.IsTrue(obj.Count == 1, "List should contain one element"); 35 | } 36 | 37 | [Test] 38 | public void Test_Serialize_List() 39 | { 40 | var foo = new Foo() { As = new [] { new B() } }; 41 | 42 | XmlSerializer.New().SerializeToString(foo); 43 | } 44 | } 45 | 46 | public class A 47 | { 48 | } 49 | 50 | public class B : A 51 | { 52 | } 53 | 54 | [XmlElement] 55 | public class Foo 56 | { 57 | [XmlElement] 58 | [XmlListElement("A", ItemType = typeof(A), SerializeAsValueNode = true, ValueNodeAttributeName = "Name")] 59 | public A[] As { get; set; } 60 | } 61 | 62 | [XmlElement(MakeNameLowercase=true)] 63 | [XmlListElement(typeof(ListItemLower),MakeNameLowercase=true)] 64 | public class ListHolderLower : List 65 | { 66 | 67 | } 68 | 69 | [XmlElement(MakeNameLowercase=true)] 70 | public class ListItemLower 71 | { 72 | [XmlAttribute] 73 | public int Property { get; set; } 74 | } 75 | 76 | 77 | [XmlElement] 78 | [XmlListElement(typeof(ListItem))] 79 | public class ListHolder : List 80 | { 81 | 82 | } 83 | 84 | [XmlElement] 85 | public class ListItem 86 | { 87 | [XmlAttribute] 88 | public int Property { get; set; } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /tests/Platform.Xml.Serialization.Tests/NamespaceTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace Platform.Xml.Serialization.Tests 4 | { 5 | [TestFixture] 6 | public class NamespaceTests 7 | { 8 | [Test] 9 | public void NamespaceOnlyOnParent() 10 | { 11 | var test = new Parent() 12 | { 13 | Child = new Child() 14 | { 15 | Property = "Test" 16 | } 17 | }; 18 | 19 | var xml = XmlSerializer.New().SerializeToString(test); 20 | Assert.IsFalse(xml.Contains("")); 21 | Assert.IsTrue(xml.Contains("")); 22 | } 23 | } 24 | 25 | [XmlElement(Namespace = "http://mynamespace.org/test")] 26 | public class Parent 27 | { 28 | [XmlElement] 29 | public Child Child { get; set; } 30 | } 31 | 32 | [XmlElement] 33 | public class Child 34 | { 35 | [XmlElement] 36 | public string Property { get; set; } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/Platform.Xml.Serialization.Tests/Person.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace Platform.Xml.Serialization.Tests 5 | { 6 | [XmlElement] 7 | public class Person 8 | { 9 | [XmlAttribute("type")] 10 | public virtual string PersonType 11 | { 12 | get 13 | { 14 | return Regex.Replace(this.GetType().Name, "Person$", ""); 15 | } 16 | } 17 | 18 | [XmlAttribute(MakeNameLowercase=true)] 19 | public virtual string Name { get; set; } 20 | 21 | [XmlAttribute(MakeNameLowercase = true)] 22 | public virtual DateTime Birthdate { get; set; } 23 | 24 | [XmlElement] 25 | public virtual DateTime? Deathdate { get; set; } 26 | 27 | public override bool Equals(object obj) 28 | { 29 | var person = obj as Person; 30 | 31 | if (person == null) 32 | { 33 | return false; 34 | } 35 | 36 | if (person.Name != this.Name) 37 | { 38 | return false; 39 | } 40 | 41 | if (!Object.Equals(person.Birthdate, this.Birthdate)) 42 | { 43 | return false; 44 | } 45 | 46 | if (!Object.Equals(person.Deathdate, this.Deathdate)) 47 | { 48 | return false; 49 | } 50 | 51 | return true; 52 | } 53 | 54 | public override int GetHashCode() 55 | { 56 | return this.Name.GetHashCode(); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tests/Platform.Xml.Serialization.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("Platform.Xml.Serialization.Tests")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("Platform.Xml.Serialization.Tests")] 12 | [assembly: AssemblyCopyright("Copyright © 2013")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("030f0c3f-70c5-4b22-92ae-8272a73ab65b")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /tests/Platform.Xml.Serialization.Tests/SerializeIfNullTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace Platform.Xml.Serialization.Tests 4 | { 5 | [TestFixture] 6 | public class SerializeIfNullTests 7 | { 8 | 9 | [Test] 10 | public void ShouldSerializeNullProperty() 11 | { 12 | var item = new ItemWithSerializableNullProperty(); 13 | var xml = XmlSerializer.New().SerializeToString(item).Replace("\n","").Replace("\r","").Replace("\t",""); 14 | Assert.True(xml.Equals(" ")); 15 | } 16 | 17 | [Test] 18 | public void ShouldNotSerializeNullProperty() 19 | { 20 | var item = new ItemWithNullProperty(); 21 | var xml = XmlSerializer.New().SerializeToString(item).Replace("\n", "").Replace("\r", "").Replace("\t", ""); 22 | Assert.True(xml.Equals("")); 23 | } 24 | 25 | [XmlElement] 26 | public class ItemWithSerializableNullProperty 27 | { 28 | [XmlElement(SerializeIfNull = true)] 29 | public string Test { get; set; } 30 | } 31 | 32 | [XmlElement] 33 | public class ItemWithNullProperty 34 | { 35 | [XmlElement] 36 | public string Test { get; set; } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/Platform.Xml.Serialization.Tests/XmlNodeTests.cs: -------------------------------------------------------------------------------- 1 | using System.Xml; 2 | using NUnit.Framework; 3 | 4 | namespace Platform.Xml.Serialization.Tests 5 | { 6 | [TestFixture] 7 | public class XmlNodeTests 8 | { 9 | [SetUp] 10 | public void SetUp() 11 | { 12 | } 13 | 14 | [TearDown] 15 | public void TearDown() 16 | { 17 | } 18 | 19 | [XmlElement] 20 | public class Foo 21 | { 22 | [XmlElement] 23 | public string S = "Hello"; 24 | 25 | [XmlElement] 26 | public XmlNode T; 27 | 28 | [XmlElement] 29 | public string U = "There"; 30 | 31 | [XmlElement] 32 | public XmlNode V; 33 | 34 | public Foo() 35 | { 36 | this.T = new XmlDocument().CreateElement("T"); 37 | this.T.InnerText = "POKWER"; 38 | 39 | this.V = new XmlDocument().CreateElement("V"); 40 | this.V.InnerText = "HMM"; 41 | } 42 | } 43 | 44 | [Test, Category("IgnoreOnMono")] 45 | public void Test1() 46 | { 47 | var foo = new Foo(); 48 | var serializer = XmlSerializer.New(); 49 | 50 | var s1 = serializer.SerializeToString(foo); 51 | 52 | foo = serializer.Deserialize(s1); 53 | 54 | var s2 = serializer.SerializeToString(foo); 55 | 56 | Assert.AreEqual(s1, s2); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tests/Platform.Xml.Serialization.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | --------------------------------------------------------------------------------