融合增加RRQMCore

This commit is contained in:
若汝棋茗
2021-09-06 22:07:00 +08:00
parent b0756a621f
commit 91aaa337ba
274 changed files with 74990 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
namespace RRQMCore
{
/// <summary>
/// 依赖属性数据验证
/// </summary>
public abstract class DependencyDataValidationAttribute : Attribute
{
/// <summary>
/// 验证
/// </summary>
/// <param name="value"></param>
public abstract void Verify(object value);
}
}

View File

@@ -0,0 +1,32 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace RRQMCore
{
/// <summary>
/// 范围控制
/// </summary>
public class RangeAttribute : DependencyDataValidationAttribute
{
/// <summary>
/// 验证
/// </summary>
/// <param name="value"></param>
public override void Verify(object value)
{
double v = (double)value;
if (v > 10)
{
throw new RRQMCore.Exceptions.RRQMException();
}
}
}
}

View File

@@ -0,0 +1,35 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
namespace RRQMCore
{
/// <summary>
/// 常量
/// </summary>
public class RRQMReadonly
{
#pragma warning disable CS1591 // 缺少对公共可见类型或成员的 XML 注释
public static readonly Type stringType = typeof(string);
public static readonly Type byteType = typeof(byte);
public static readonly Type shortType = typeof(short);
public static readonly Type intType = typeof(int);
public static readonly Type boolType = typeof(bool);
public static readonly Type longType = typeof(long);
public static readonly Type floatType = typeof(float);
public static readonly Type doubleType = typeof(double);
public static readonly Type decimalType = typeof(decimal);
public static readonly Type dateTimeType = typeof(DateTime);
public static readonly Type bytesType = typeof(byte[]);
#pragma warning restore CS1591 // 缺少对公共可见类型或成员的 XML 注释
}
}

View File

@@ -0,0 +1,112 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
namespace RRQMCore
{
/// <summary>
/// 雪花ID生成器(该代码来自网络)
/// </summary>
public class SnowflakeIDGenerator
{
//机器ID
private static long workerId;
private static long twepoch = 687888001020L; //唯一时间,这是一个避免重复的随机量,自行设定不要大于当前时间戳
private static long sequence = 0L;
private static int workerIdBits = 4; //机器码字节数。4个字节用来保存机器码(定义为Long类型会出现最大偏移64位所以左移64位没有意义)
/// <summary>
/// 最大机器ID
/// </summary>
public static long maxWorkerId = -1L ^ (-1L << workerIdBits); //最大机器ID
private static int sequenceBits = 10; //计数器字节数10个字节用来保存计数码
private static int workerIdShift = sequenceBits; //机器码数据左移位数,就是后面计数器占用的位数
private static int timestampLeftShift = sequenceBits + workerIdBits; //时间戳左移动位数就是机器码和计数器总字节数
/// <summary>
/// 一微秒内可以产生计数,如果达到该值则等到下一微妙在进行生成
/// </summary>
public static long sequenceMask = -1L ^ -1L << sequenceBits; //一微秒内可以产生计数,如果达到该值则等到下一微妙在进行生成
private long lastTimestamp = -1L;
/// <summary>
/// 机器码
/// </summary>
/// <param name="workerId"></param>
public SnowflakeIDGenerator(long workerId)
{
if (workerId > maxWorkerId || workerId < 0)
throw new Exception(string.Format("worker Id can't be greater than {0} or less than 0 ", workerId));
SnowflakeIDGenerator.workerId = workerId;
}
/// <summary>
/// 获取ID
/// </summary>
/// <returns></returns>
public long NextID()
{
lock (this)
{
long timestamp = timeGen();
if (this.lastTimestamp == timestamp)
{ //同一微妙中生成ID
SnowflakeIDGenerator.sequence = (SnowflakeIDGenerator.sequence + 1) & SnowflakeIDGenerator.sequenceMask; //用&运算计算该微秒内产生的计数是否已经到达上限
if (SnowflakeIDGenerator.sequence == 0)
{
//一微妙内产生的ID计数已达上限等待下一微妙
timestamp = tillNextMillis(this.lastTimestamp);
}
}
else
{ //不同微秒生成ID
SnowflakeIDGenerator.sequence = 0; //计数清0
}
if (timestamp < lastTimestamp)
{ //如果当前时间戳比上一次生成ID时时间戳还小抛出异常因为不能保证现在生成的ID之前没有生成过
throw new Exception(string.Format("Clock moved backwards. Refusing to generate id for {0} milliseconds",
this.lastTimestamp - timestamp));
}
this.lastTimestamp = timestamp; //把当前时间戳保存为最后生成ID的时间戳
long nextId = (timestamp - twepoch << timestampLeftShift) | SnowflakeIDGenerator.workerId << SnowflakeIDGenerator.workerIdShift | SnowflakeIDGenerator.sequence;
return nextId;
}
}
/// <summary>
/// 获取下一微秒时间戳
/// </summary>
/// <param name="lastTimestamp"></param>
/// <returns></returns>
private long tillNextMillis(long lastTimestamp)
{
long timestamp = timeGen();
while (timestamp <= lastTimestamp)
{
timestamp = timeGen();
}
return timestamp;
}
/// <summary>
/// 生成当前时间戳
/// </summary>
/// <returns></returns>
private long timeGen()
{
return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
}
}
}

View File

@@ -0,0 +1,210 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Collections;
using System.Collections.Generic;
namespace RRQMCore.Concurrent
{
/// <summary>
/// 线程安全的List
/// </summary>
/// <typeparam name="T"></typeparam>
public class ConcurrentList<T> : IList<T>
{
/// <summary>
/// 构造函数
/// </summary>
public ConcurrentList()
{
this.list = new List<T>();
this.locker = new object();
}
private List<T> list;
private object locker;
/// <summary>
/// 获取或设置指定索引处的元素。
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public T this[int index]
{
get
{
lock (locker)
{
return this.list[index];
}
}
set
{
lock (locker)
{
this.list[index] = value;
}
}
}
/// <summary>
/// 获取集合中包含的元素数。
/// </summary>
public int Count { get { lock (locker) { return this.list.Count; } } }
/// <summary>
/// 是否只读
/// </summary>
public bool IsReadOnly { get { return false; } }
/// <summary>
/// 将某项添加到 System.Collections.Generic.ICollection`1 中。
/// </summary>
/// <param name="item"></param>
public void Add(T item)
{
lock (this.locker)
{
this.list.Add(item);
}
}
/// <summary>
/// 从 System.Collections.Generic.ICollection`1 中移除所有项。
/// </summary>
public void Clear()
{
lock (this.locker)
{
this.list.Clear();
}
}
/// <summary>
/// 确定 System.Collections.Generic.ICollection`1 是否包含特定值。
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public bool Contains(T item)
{
lock (this.locker)
{
return this.Contains(item);
}
}
/// <summary>
/// 从特定的 System.Collections.Generic.ICollection`1 索引处开始,将 System.Array 的元素复制到一个 System.Array
/// </summary>
/// <param name="array"></param>
/// <param name="arrayIndex"></param>
public void CopyTo(T[] array, int arrayIndex)
{
lock (this.locker)
{
this.list.CopyTo(array, arrayIndex);
}
}
/// <summary>
/// 返回一个循环访问集合的枚举器。
/// </summary>
/// <returns></returns>
public IEnumerator<T> GetEnumerator()
{
lock (this.locker)
{
return this.list.GetEnumerator();
}
}
/// <summary>
/// 确定 System.Collections.Generic.IList`1 中特定项的索引。
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public int IndexOf(T item)
{
lock (this.locker)
{
return this.IndexOf(item);
}
}
/// <summary>
/// 在 System.Collections.Generic.IList`1 中的指定索引处插入一个项。
/// </summary>
/// <param name="index"></param>
/// <param name="item"></param>
public void Insert(int index, T item)
{
lock (this.locker)
{
this.list.Insert(index, item);
}
}
/// <summary>
/// 从 System.Collections.Generic.ICollection`1 中移除特定对象的第一个匹配项。
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public bool Remove(T item)
{
lock (this.locker)
{
return this.list.Remove(item);
}
}
/// <summary>
/// 从 System.Collections.Generic.List`1 中移除一定范围的元素。
/// </summary>
/// <param name="index"></param>
/// <param name="count"></param>
public void RemoveRange(int index, int count)
{
lock (this.locker)
{
this.list.RemoveRange(index, count);
}
}
/// <summary>
/// 移除位于指定索引处的 System.Collections.Generic.IList`1 项。
/// </summary>
/// <param name="index"></param>
public void RemoveAt(int index)
{
lock (this.locker)
{
this.list.RemoveAt(index);
}
}
IEnumerator IEnumerable.GetEnumerator()
{
lock (this.locker)
{
return this.list.GetEnumerator();
}
}
/// <summary>
/// 重写ToString
/// </summary>
/// <returns></returns>
public override string ToString()
{
return $"Count={this.Count}";
}
}
}

View File

@@ -0,0 +1,21 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace RRQMCore.Data.Converter
{
/// <summary>
/// 集合转换器
/// </summary>
public class CollectionConvert
{
}
}

View File

@@ -0,0 +1,90 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
namespace RRQMCore.Data.Converter
{
/// <summary>
/// 值转换器
/// </summary>
public static class ValueConvert
{
/// <summary>
/// int型转换器
/// </summary>
/// <param name="valueString">数字字符串</param>
/// <param name="defaultValue">默认值</param>
/// <returns>返回值结果</returns>
public static int IntConvert(string valueString, int defaultValue = 0)
{
int result;
if (int.TryParse(valueString, out result))
{
return result;
}
return defaultValue;
}
/// <summary>
/// int型转换器
/// </summary>
/// <param name="valueObject"></param>
/// <returns></returns>
public static int IntConvert(object valueObject)
{
return (int)valueObject;
}
/// <summary>
/// long值转换器
/// </summary>
/// <param name="valueObject"></param>
/// <returns></returns>
public static long LongConvert(object valueObject)
{
return (long)valueObject;
}
/// <summary>
/// 双精度值转换
/// </summary>
/// <param name="valueString">数字字符串</param>
/// <param name="defaultValue">默认值</param>
/// <returns>返回值结果</returns>
public static double DoubleConvert(string valueString, double defaultValue = 0)
{
double result;
if (double.TryParse(valueString, out result))
{
return result;
}
return defaultValue;
}
/// <summary>
/// 枚举类型转换
/// </summary>
/// <typeparam name="T">枚举类型</typeparam>
/// <param name="valueString">枚举字符串</param>
/// <param name="defaultValue">默认值</param>
/// <returns>返回值结果</returns>
public static T EnumConvert<T>(string valueString, T defaultValue = default(T)) where T : struct
{
T result;
if (Enum.TryParse(valueString, out result))
{
return result;
}
return defaultValue;
}
}
}

View File

@@ -0,0 +1,68 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace RRQMCore.Data.Security
{
/// <summary>
/// 数据锁,用于加密或解密
/// </summary>
public static class DataLock
{
/// <summary>
/// 使用3DES加密
/// </summary>
/// <param name="data">待加密字节</param>
/// <param name="encryptKey">加密口令长度为8</param>
/// <returns></returns>
public static byte[] EncryptDES(byte[] data, string encryptKey)
{
byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
byte[] rgbIV = { 0x12, 0x34, 4, 0x78, 0x90, 255, 0xCD, 0xEF };
DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
using (MemoryStream mStream = new MemoryStream())
{
using (CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write))
{
cStream.Write(data, 0, data.Length);
cStream.FlushFinalBlock();
return mStream.ToArray();
}
}
}
/// <summary>
/// 使用3DES解密
/// </summary>
/// <param name="data">待解密字节</param>
/// <param name="decryptionKey">解密口令长度为8</param>
/// <returns></returns>
public static byte[] DecryptDES(byte[] data, string decryptionKey)
{
byte[] rgbKey = Encoding.UTF8.GetBytes(decryptionKey);
byte[] rgbIV = { 0x12, 0x34, 4, 0x78, 0x90, 255, 0xCD, 0xEF };
DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
using (MemoryStream mStream = new MemoryStream())
{
using (CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write))
{
cStream.Write(data, 0, data.Length);
cStream.FlushFinalBlock();
return mStream.ToArray();
}
}
}
}
}

View File

@@ -0,0 +1,720 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
namespace RRQMCore.Data.XML
{
/// <summary>
/// xml主类
/// </summary>
public class XmlTool
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="path">文件路径,包含文件名</param>
public XmlTool(string path)
{
this.path = path;
}
private string path = null;
#region
/// <summary>
/// 单节点,单属性储存
/// </summary>
/// <param name="NodeName">节点名</param>
/// <param name="Attribute_name">属性名</param>
/// <param name="Attribute_value">属性值</param>
public void AttributeStorage(string NodeName, string Attribute_name, string Attribute_value)
{
if (File.Exists(path))
{//存在Xml的文件
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
bool N = false;//节点判断变量
foreach (XmlNode item in nodeList)
{//判断是否存在该节点
if (item.Name == NodeName)
{
N = true;
break;
}
}
if (N == false)
{//不存在节点,属性,建立节点,属性
XmlElement PointName = xml.CreateElement(NodeName);
PointName.SetAttribute(Attribute_name, Attribute_value);
root.AppendChild(PointName);
}
else
{//存在属性进行赋值
XmlNode PointName = xml.SelectSingleNode("Root/" + NodeName);
PointName.Attributes[Attribute_name].Value = Attribute_value;
}
xml.Save(path);
}
else
{
XmlDocument xml = new XmlDocument();
XmlDeclaration dec = xml.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement root = xml.CreateElement("Root");
xml.AppendChild(root);//根元素
XmlElement PointName = xml.CreateElement(NodeName);
PointName.SetAttribute(Attribute_name, Attribute_value);
root.AppendChild(PointName);
xml.Save(path);
}
}
/// <summary>
/// 单节点,多属性存储
/// </summary>
/// <param name="NodeName">节点名</param>
/// <param name="Attribute_name">属性集合</param>
/// <param name="Attribute_value">属性值集合</param>
public void AttributeStorage(string NodeName, string[] Attribute_name, string[] Attribute_value)
{
if (Attribute_name.Length != Attribute_value.Length)
{
Console.WriteLine("属性名数量和属性值数量不一致,无法储存");
return;
}
if (File.Exists(path))
{//存在Xml的文件
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
bool N = false;//节点变量
foreach (XmlNode item in nodeList)
{//判断是否存在该节点
if (item.Name == NodeName)
{
N = true;
break;
}
}
if (N == false)
{//不存在节点,属性,建立节点,属性
XmlElement PointName = xml.CreateElement(NodeName);
for (int i = 0; i < Attribute_name.Length; i++)
{
PointName.SetAttribute(Attribute_name[i], Attribute_value[i]);
root.AppendChild(PointName);
}
}
else
{//存在属性进行赋值
XmlNode PointName = xml.SelectSingleNode("Root/" + NodeName);
for (int i = 0; i < Attribute_name.Length; i++)
{
PointName.Attributes[Attribute_name[i]].Value = Attribute_value[i];
}
}
xml.Save(path);
}
else
{
XmlDocument xml = new XmlDocument();
XmlDeclaration dec = xml.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement root = xml.CreateElement("Root");
xml.AppendChild(root);//根元素
XmlElement PointName = xml.CreateElement(NodeName);
for (int i = 0; i < Attribute_name.Length; i++)
{
PointName.SetAttribute(Attribute_name[i], Attribute_value[i]);
root.AppendChild(PointName);
}
xml.Save(path);
}
}
/// <summary>
/// 单节点,单属性多集合存储
/// </summary>
/// <param name="NodeName">节点集合</param>
/// <param name="Attribute_name">属性名集合</param>
/// <param name="Attribute_value">属性值集合</param>
public void AttributeStorage(string[] NodeName, string[] Attribute_name, string[] Attribute_value)
{
if ((Attribute_name.Length != Attribute_value.Length) && NodeName.Length != Attribute_name.Length)
{
Console.WriteLine("属性名数量和属性值数量不一致,无法储存");
return;
}
if (File.Exists(path))
{//存在Xml的文件
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
for (int i = 0; i < NodeName.Length; i++)
{
bool N = false;//节点变量
foreach (XmlNode item in nodeList)
{//判断是否存在该节点
if (item.Name == NodeName[i])
{
N = true;
break;
}
}
if (N == false)
{//不存在节点,属性,建立节点,属性
XmlElement PointName = xml.CreateElement(NodeName[i]);
PointName.SetAttribute(Attribute_name[i], Attribute_value[i]);
root.AppendChild(PointName);
}
else
{//存在属性进行赋值
XmlNode PointName = xml.SelectSingleNode("Root/" + NodeName);
PointName.Attributes[Attribute_name[i]].Value = Attribute_value[i];
}
xml.Save(path);
}
}
else
{
XmlDocument xml = new XmlDocument();
XmlDeclaration dec = xml.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement root = xml.CreateElement("Root");
xml.AppendChild(root);//根元素
for (int i = 0; i < NodeName.Length; i++)
{
XmlElement PointName = xml.CreateElement(NodeName[i]);
PointName.SetAttribute(Attribute_name[i], Attribute_value[i]);
root.AppendChild(PointName);
xml.Save(path);
}
}
}
/// <summary>
/// 多节点,多属性,多集合存储
/// </summary>
/// <param name="NodeName">节点集合</param>
/// <param name="Attribute_name">属性集合</param>
/// <param name="AttributeNumber">每个节点的属性数量</param>
/// <param name="Attribute_value">属性值集合</param>
public void AttributeStorage(string[] NodeName, string[] Attribute_name, int AttributeNumber, params string[][] Attribute_value)
{
if (File.Exists(path))
{
//存在Xml的文件
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
for (int i = 0; i < NodeName.Length; i++)
{
bool N = false;//节点变量
foreach (XmlNode item in nodeList)
{//判断是否存在该节点
if (item.Name == NodeName[i])
{
N = true;
break;
}
}
if (N == false)
{//不存在节点,属性,建立节点,属性
XmlElement PointName = xml.CreateElement(NodeName[i]);
for (int j = 0; j < AttributeNumber; j++)
{
PointName.SetAttribute(Attribute_name[j], Attribute_value[j][i]);
}
root.AppendChild(PointName);
}
else
{//存在属性进行赋值
XmlNode PointName = xml.SelectSingleNode("Root/" + NodeName[i]);
for (int j = 0; j < AttributeNumber; j++)
{
PointName.Attributes[Attribute_name[j]].Value = Attribute_value[j][i];
}
}
}
xml.Save(path);
}
else
{
XmlDocument xml = new XmlDocument();
XmlDeclaration dec = xml.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement root = xml.CreateElement("Root");
xml.AppendChild(root);//根元素
for (int i = 0; i < NodeName.Length; i++)
{
XmlElement PointName = xml.CreateElement(NodeName[i]);
for (int j = 0; j < AttributeNumber; j++)
{
PointName.SetAttribute(Attribute_name[j], Attribute_value[j][i]);
}
root.AppendChild(PointName);
xml.Save(path);
}
}
}
/// <summary>
/// 节点值存储
/// </summary>
/// <param name="NodeName">节点名</param>
/// <param name="Text">文本</param>
public void NodeStorage(string NodeName, string Text)
{
if (File.Exists(path))
{
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
bool n = false;
foreach (XmlNode item in nodeList)
{
if (item.Name == NodeName)
{
item.InnerText = Text;
n = true;
break;
}
}
if (n == false)
{
XmlElement other = xml.CreateElement(NodeName);
other.InnerText = Text;
root.AppendChild(other);
}
xml.Save(path);
}
else
{
XmlDocument doc = new XmlDocument();
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement Root = doc.CreateElement("Root");
doc.AppendChild(Root);//根元素
XmlElement Node = doc.CreateElement(NodeName);
Node.InnerText = Text;
Root.AppendChild(Node);
doc.Save(path);
}
}
#endregion
#region
/// <summary>
/// 通过节点取值
/// </summary>
/// <param name="NodeName">节点名</param>
/// <returns>取值失败返回null</returns>
public string SearchNode(string NodeName)
{
if (File.Exists(path))
{
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
foreach (XmlNode item in nodeList)
{
if (item.Name == NodeName)
{
return item.InnerText;
}
}
}
return null;
}
/// <summary>
/// 查找数字
/// </summary>
/// <param name="NodeName">节点名</param>
/// <param name="Attribute_name">属性名</param>
/// <returns>取值失败返回0</returns>
public int SearchNumber(string NodeName, string Attribute_name)
{
if (File.Exists(path))
{
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
foreach (XmlNode item in nodeList)
{
if (item.Name == NodeName)
{
if (item.Attributes[Attribute_name] != null)
{
return Convert.ToInt32(item.Attributes[Attribute_name].Value);
}
}
}
}
return 0;
}
/// <summary>
/// 查找属性值
/// </summary>
/// <param name="NodeName">节点名</param>
/// <param name="Attribute_name">属性名</param>
/// <returns>取值失败返回null</returns>
public string SearchWords(string NodeName, string Attribute_name)
{
if (File.Exists(path))
{
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
foreach (XmlNode item in nodeList)
{
if (item.Name == NodeName)
{
if (item.Attributes[Attribute_name] != null)
{
return item.Attributes[Attribute_name].Value;
}
}
}
}
return null;
}
/// <summary>
/// 查找布尔值
/// </summary>
/// <param name="NodeName">节点名</param>
/// <param name="Attribute_name">属性值</param>
/// <returns>返回查找结果查询失败返回false</returns>
public bool SearchBoolean(string NodeName, string Attribute_name)
{
if (File.Exists(path))
{
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
foreach (XmlNode item in nodeList)
{
if (item.Name == NodeName)
{
if (item.Attributes[Attribute_name] != null)
{
try
{
return Convert.ToBoolean(item.Attributes[Attribute_name].Value);
}
catch
{
return false;
}
}
}
}
}
return false;
}
/// <summary>
/// 查找属性值集合
/// </summary>
/// <param name="NodeName">节点名集合</param>
/// <param name="Attribute_name">属性名集合</param>
/// <returns>文件不在返回null单个属性不在返回“空”</returns>
public string[] SearchWords(string[] NodeName, string[] Attribute_name)
{
if (File.Exists(path))
{
string[] s = new string[NodeName.Length];
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
for (int i = 0; i < NodeName.Length; i++)
{
foreach (XmlNode item in nodeList)
{
if (item.Name == NodeName[i])
{
if (item.Attributes[Attribute_name[i]] != null)
{
s[i] = item.Attributes[Attribute_name[i]].Value;
}
else
{
s[i] = "";
}
}
}
}
return s;
}
return null;
}
/// <summary>
/// 通过确切属性值,属性名,查找其他属性值
/// </summary>
/// <param name="Attribute_name1">已知属性名</param>
/// <param name="Attribute_value">已知属性值</param>
/// <param name="Attribute_name2">待查属性名</param>
/// <returns>待查属性值</returns>
public string[] SearchWords(string Attribute_name1, string Attribute_value, string Attribute_name2)
{
List<string> values = new List<string>();
if (File.Exists(path))
{
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
foreach (XmlNode item in nodeList)
{
if (item.Attributes[Attribute_name1] != null)
{
if (item.Attributes[Attribute_name1].Value == Attribute_value)
{
if (item.Attributes[Attribute_name2] != null)
{
values.Add(item.Attributes[Attribute_name2].Value);
}
}
}
}
}
return values.ToArray();
}
/// <summary>
/// 查找节点的所有属性值
/// </summary>
/// <param name="NodeName">节点 名</param>
/// <returns>返回查找键值对查询失败返回null</returns>
public Dictionary<string, string> SearchAllAttributes(string NodeName)
{
Dictionary<string, string> Attributes = new Dictionary<string, string>();
if (File.Exists(path))
{
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
foreach (XmlNode item in nodeList)
{
if (item.Name == NodeName)
{
XmlAttributeCollection attributeCollection = item.Attributes;
if (attributeCollection != null)
{
foreach (XmlAttribute attribute in attributeCollection)
{
Attributes.Add(attribute.Name, attribute.Value);
}
}
return Attributes;
}
}
}
return null;
}
/// <summary>
/// 通过确切属性值,属性名,查找其他属性的布尔值
/// </summary>
/// <param name="Attribute_name1">已知属性名</param>
/// <param name="Attribute_value">已知属性值</param>
/// <param name="Attribute_name2">待查属性名</param>
/// <returns>待查布尔值失败返回false</returns>
public bool SearchBoolean(string Attribute_name1, string Attribute_value, string Attribute_name2)
{
if (File.Exists(path))
{
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
foreach (XmlNode item in nodeList)
{
if (item.Attributes[Attribute_name1].Value == Attribute_value)
{
if (item.Attributes[Attribute_name2] != null)
{
try
{
return Convert.ToBoolean(item.Attributes[Attribute_name2].Value);
}
catch
{
return false;
}
}
}
}
}
return false;
}
#endregion
/// <summary>
/// 按节点名移除节点
/// </summary>
/// <param name="NodeName">节点名</param>
/// <returns>是否移除成功</returns>
public bool RemoveNode(string NodeName)
{
if (File.Exists(path))
{
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
foreach (XmlNode item in nodeList)
{
if (item.Name == NodeName)
{
root.RemoveChild(item);
xml.Save(path);
return true;
}
}
}
return false;
}
/// <summary>
/// 按确切的属性名,属性值删除节点
/// </summary>
/// <param name="Attribute_name">属性名</param>
/// <param name="Attribute_value">属性值</param>
/// <returns>是否移除成功</returns>
public bool RemoveNode(string Attribute_name, string Attribute_value)
{
if (File.Exists(path))
{
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
foreach (XmlNode item in nodeList)
{
if (item.Attributes[Attribute_name] != null)
{
if (item.Attributes[Attribute_name].Value == Attribute_value)
{
root.RemoveChild(item);
xml.Save(path);
return true;
}
}
}
}
return false;
}
/// <summary>
/// 如果节点中有日期属性,把日期之前的节点都删除
/// </summary>
/// <param name="Attribute_name">属性名</param>
/// <param name="dateTime">截止时间</param>
/// <returns>是否删除成功</returns>
public bool RemoveNode(string Attribute_name, DateTime dateTime)
{
if (File.Exists(path))
{
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
for (int i = 0; i < nodeList.Count; i++)
{
if (nodeList[i].Attributes[Attribute_name] != null)
{
DateTime dt = Convert.ToDateTime(nodeList[i].Attributes[Attribute_name].Value);
if (DateTime.Compare(dt, dateTime) < 0)
{
root.RemoveChild(nodeList[i]);
}
}
}
xml.Save(path);
return true;
}
return false;
}
/// <summary>
/// 判断节点是否存在
/// </summary>
/// <param name="NodeName">节点名</param>
/// <returns>返回结果</returns>
public bool NodeExist(string NodeName)
{
if (File.Exists(path))
{
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
foreach (XmlNode item in nodeList)
{
if (item.Name == NodeName)
{
return true;
}
}
}
return false;
}
/// <summary>
/// 删除所有节点,不包含子节点
/// </summary>
/// <returns>返回删除是否成功</returns>
public bool RemoveAllNode()
{
if (File.Exists(path))
{
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlElement root = xml.DocumentElement;
root.RemoveAll();
xml.Save(path);
return true;
}
return false;
}
}
}

View File

@@ -0,0 +1,107 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using RRQMCore.Exceptions;
using System;
using System.Reflection;
namespace RRQMCore.Dependency
{
/// <summary>
/// 依赖项属性
/// </summary>
public class DependencyProperty
{
private DependencyProperty()
{
}
private string name;
/// <summary>
/// 属性名
/// </summary>
public string Name
{
get { return name; }
}
private Type owner;
/// <summary>
/// 所属类型
/// </summary>
public Type Owner
{
get { return owner; }
}
private Type valueType;
/// <summary>
/// 值类型
/// </summary>
public Type ValueType
{
get { return valueType; }
}
private object value;
/// <summary>
/// 默认值
/// </summary>
public object DefauleValue
{
get { return value; }
}
internal void DataValidation(object value)
{
if (value == null)
{
if (typeof(ValueType).IsAssignableFrom(valueType))
{
throw new RRQMException($"属性“{this.name}”赋值类型不允许出现Null");
}
}
else if (!valueType.IsAssignableFrom(value.GetType()))
{
throw new RRQMException($"属性“{this.name}”赋值类型与注册类型不一致,应当注入“{valueType}”类型");
}
}
internal void SetDefauleValue(object value)
{
this.DataValidation(value);
this.value = value;
}
/// <summary>
/// 注册依赖项属性
/// </summary>
/// <param name="propertyName"></param>
/// <param name="valueType"></param>
/// <param name="owner"></param>
/// <param name="value"></param>
/// <returns></returns>
public static DependencyProperty Register(string propertyName, Type valueType, Type owner, object value)
{
FieldInfo fieldInfo = owner.GetField($"{propertyName}Property");
DependencyProperty dp = new DependencyProperty();
dp.name = propertyName;
dp.valueType = valueType;
dp.owner = owner;
dp.SetDefauleValue(value);
return dp;
}
}
}

View File

@@ -0,0 +1,64 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Collections.Concurrent;
namespace RRQMCore.Dependency
{
/// <summary>
/// 依赖项对象
/// </summary>
public class RRQMDependencyObject
{
/// <summary>
/// 构造函数
/// </summary>
public RRQMDependencyObject()
{
this.dp = new ConcurrentDictionary<DependencyProperty, object>();
}
[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
private ConcurrentDictionary<DependencyProperty, object> dp;
/// <summary>
/// 获取值
/// </summary>
/// <param name="dependencyProperty"></param>
/// <returns></returns>
public object GetValue(DependencyProperty dependencyProperty)
{
if (dp.TryGetValue(dependencyProperty, out object value))
{
return value;
}
else
{
return dependencyProperty.DefauleValue;
}
}
/// <summary>
/// 设置值
/// </summary>
/// <param name="dependencyProperty"></param>
/// <param name="value"></param>
public RRQMDependencyObject SetValue(DependencyProperty dependencyProperty, object value)
{
dependencyProperty.DataValidation(value);
dp.AddOrUpdate(dependencyProperty, value, (DependencyProperty dp, object v) =>
{
return value;
});
return this;
}
}
}

View File

@@ -0,0 +1,36 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.Diagnostics;
namespace RRQMCore.Diagnostics
{
/// <summary>
/// 时间测量器
/// </summary>
public class TimeMeasurer
{
/// <summary>
/// 开始运行
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
public static TimeSpan Run(Action action)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
action?.Invoke();
stopwatch.Stop();
return stopwatch.Elapsed;
}
}
}

View File

@@ -0,0 +1,23 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
namespace RRQMCore.Event
{
/// <summary>
/// 若汝棋茗所有事件基类
/// </summary>
public class RRQMEventArgs : EventArgs
{
}
}

View File

@@ -0,0 +1,45 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Collections.Generic;
namespace RRQMCore.Exceptions
{
/// <summary>
/// 错误异常映射表
/// </summary>
public class ErrorExceptionMapping
{
private Dictionary<byte, string> codeInfo = new Dictionary<byte, string>();
/// <summary>
/// 注册错误码信息
/// </summary>
/// <param name="code"></param>
/// <param name="info"></param>
public void RegisterCode(byte code, string info)
{
codeInfo.Add(code, info);
}
/// <summary>
/// 获取代码信息
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
public string GetCodeInfo(byte code)
{
string info;
codeInfo.TryGetValue(code, out info);
return info;
}
}
}

View File

@@ -0,0 +1,34 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
namespace RRQMCore.Exceptions
{
/*
若汝棋茗
*/
/// <summary>
/// 未找到消息异常类
/// </summary>
[Serializable]
public class MessageNotFoundException : RRQMException
{
/// <summary>
///
/// </summary>
/// <param name="mes"></param>
public MessageNotFoundException(string mes) : base(mes)
{
}
}
}

View File

@@ -0,0 +1,34 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
namespace RRQMCore.Exceptions
{
/*
若汝棋茗
*/
/// <summary>
/// 消息已注册
/// </summary>
[Serializable]
public class MessageRegisteredException : RRQMException
{
/// <summary>
///
/// </summary>
/// <param name="mes"></param>
public MessageRegisteredException(string mes) : base(mes)
{
}
}
}

View File

@@ -0,0 +1,48 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
namespace RRQMCore.Exceptions
{
/// <summary>
/// 若汝棋茗程序集异常类基类
/// </summary>
[Serializable]
public class RRQMException : Exception
{
/// <summary>
/// 构造函数
/// </summary>
public RRQMException() : base() { }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="message"></param>
public RRQMException(string message) : base(message) { }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="message"></param>
/// <param name="inner"></param>
public RRQMException(string message, System.Exception inner) : base(message, inner) { }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="info"></param>
/// <param name="context"></param>
protected RRQMException(System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
}

View File

@@ -0,0 +1,94 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Collections.Generic;
namespace RRQMCore.Helper
{
/// <summary>
/// 字节数组扩展类
/// </summary>
public static class BytesHelper
{
/// <summary>
/// 索引包含数组
/// </summary>
/// <param name="srcByteArray"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
/// <param name="subByteArray"></param>
/// <returns></returns>
public static List<int> IndexOfInclude(this byte[] srcByteArray, int offset, int length, byte[] subByteArray)
{
int subByteArrayLen = subByteArray.Length;
List<int> indexes = new List<int>();
if (length < subByteArrayLen)
{
return indexes;
}
int hitLength = 0;
for (int i = offset; i < length; i++)
{
if (srcByteArray[i] == subByteArray[hitLength])
{
hitLength++;
}
else
{
hitLength = 0;
}
if (hitLength == subByteArray.Length)
{
hitLength = 0;
indexes.Add(i);
}
}
return indexes;
}
/// <summary>
/// 索引第一个包含数组
/// </summary>
/// <param name="srcByteArray"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
/// <param name="subByteArray"></param>
/// <returns></returns>
public static int IndexOfFirst(this byte[] srcByteArray, int offset, int length, byte[] subByteArray)
{
if (length < subByteArray.Length)
{
return -1;
}
int hitLength = 0;
for (int i = offset; i < length; i++)
{
if (srcByteArray[i] == subByteArray[hitLength])
{
hitLength++;
}
else
{
hitLength = 0;
}
if (hitLength == subByteArray.Length)
{
return i;
}
}
return -1;
}
}
}

View File

@@ -0,0 +1,33 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.Globalization;
namespace RRQMCore.Helper
{
/// <summary>
/// 日期扩展
/// </summary>
public static class DateTimeHelper
{
/// <summary>
/// 格林尼治标准时间
/// </summary>
/// <param name="dt"></param>
/// <param name="v"></param>
/// <returns></returns>
public static string ToGMTString(this DateTime dt, string v)
{
return dt.ToString("r", CultureInfo.InvariantCulture);
}
}
}

View File

@@ -0,0 +1,125 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace RRQMCore.Helper
{
/// <summary>
/// 字符串扩展
/// </summary>
public static class StringHelper
{
/// <summary>
/// 只按第一个匹配项分割
/// </summary>
/// <param name="str"></param>
/// <param name="split"></param>
/// <returns></returns>
public static string[] SplitFirst(this string str, char split)
{
List<string> s = new List<string>();
int index = str.IndexOf(split);
if (index > 0)
{
s.Add(str.Substring(0, index).Trim());
s.Add(str.Substring(index + 1, str.Length - index - 1).Trim());
}
return s.ToArray();
}
/// <summary>
/// 按字符串分割
/// </summary>
/// <param name="str"></param>
/// <param name="pattern"></param>
/// <returns></returns>
public static string[] Split(this string str, string pattern)
{
return Regex.Split(str, pattern);
}
/// <summary>
/// 只按最后一个匹配项分割
/// </summary>
/// <param name="str"></param>
/// <param name="split"></param>
/// <returns></returns>
public static string[] SplitLast(this string str, char split)
{
List<string> s = new List<string>();
int index = str.LastIndexOf(split);
if (index > 0)
{
s.Add(str.Substring(0, index).Trim());
s.Add(str.Substring(index + 1, str.Length - index - 1).Trim());
}
return s.ToArray();
}
/// <summary>
/// 将字符串转换为指定类型
/// </summary>
/// <param name="str"></param>
/// <param name="type"></param>
/// <returns></returns>
public static object ParseToType(this string str, Type type)
{
dynamic obj = null;
if (type == RRQMReadonly.stringType)
{
obj = str;
}
else if (type == RRQMReadonly.byteType)
{
obj = byte.Parse(str);
}
else if (type == RRQMReadonly.boolType)
{
obj = bool.Parse(str);
}
else if (type == RRQMReadonly.shortType)
{
obj = short.Parse(str);
}
else if (type == RRQMReadonly.intType)
{
obj = int.Parse(str);
}
else if (type == RRQMReadonly.longType)
{
obj = long.Parse(str);
}
else if (type == RRQMReadonly.floatType)
{
obj = float.Parse(str);
}
else if (type == RRQMReadonly.doubleType)
{
obj = double.Parse(str);
}
else if (type == RRQMReadonly.decimalType)
{
obj = decimal.Parse(str);
}
else if (type == RRQMReadonly.dateTimeType)
{
obj = DateTime.Parse(str);
}
return obj;
}
}
}

View File

@@ -0,0 +1,62 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using RRQMCore.Exceptions;
using System;
using System.Reflection;
namespace RRQMCore.Helper
{
/// <summary>
/// Type扩展累类
/// </summary>
public static class TypeHelper
{
/// <summary>
/// 获取类型
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static Type GetRefOutType(this Type type)
{
if (type.FullName.Contains("&"))
{
string typeName = type.FullName.Replace("&", string.Empty);
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (var assembly in assemblies)
{
type = assembly.GetType(typeName);
if (type != null)
{
return type;
}
}
throw new RRQMException($"未能识别类型{typeName}");
}
else
{
return type;
}
}
/// <summary>
/// 获取默认值
/// </summary>
/// <param name="targetType"></param>
/// <returns></returns>
public static object GetDefault(this Type targetType)
{
return targetType.IsValueType ? Activator.CreateInstance(targetType) : null;
}
}
}

View File

@@ -0,0 +1,144 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
namespace RRQMCore.IO
{
/// <summary>
/// 文件操作
/// </summary>
public static class FileControler
{
/// <summary>
/// 获得文件Hash值
/// </summary>
/// <param name="filePath">文件路径</param>
/// <returns></returns>
public static string GetFileHash(string filePath)
{
try
{
HashAlgorithm hash = SHA256.Create();
using (FileStream fileStream = File.OpenRead(filePath))
{
byte[] HashValue = hash.ComputeHash(fileStream);
return BitConverter.ToString(HashValue).Replace("-", "");
}
}
catch
{
return null;
}
}
/// <summary>
/// 获得流Hash值
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
public static string GetStreamHash(Stream stream)
{
try
{
HashAlgorithm hash = SHA256.Create();
byte[] HashValue = hash.ComputeHash(stream);
return BitConverter.ToString(HashValue).Replace("-", "");
}
catch
{
return null;
}
}
/// <summary>
/// 获得文件Hash值
/// </summary>
/// <param name="filePath">文件路径</param>
/// <param name="hash"></param>
/// <returns></returns>
public static string GetFileHash(string filePath, HashAlgorithm hash)
{
try
{
using (FileStream fileStream = File.OpenRead(filePath))
{
byte[] HashValue = hash.ComputeHash(fileStream);
return BitConverter.ToString(HashValue).Replace("-", "");
}
}
catch
{
return null;
}
}
/// <summary>
/// 获得流Hash值
/// </summary>
/// <param name="stream"></param>
/// <param name="hash"></param>
/// <returns></returns>
public static string GetStreamHash(Stream stream, HashAlgorithm hash)
{
try
{
byte[] HashValue = hash.ComputeHash(stream);
return BitConverter.ToString(HashValue).Replace("-", "");
}
catch
{
return null;
}
}
#if NET45_OR_GREATER
[DllImport("kernel32.dll")]
private static extern IntPtr _lopen(string lpPathName, int iReadWrite);
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr hObject);
private const int OF_READWRITE = 2;
private const int OF_SHARE_DENY_NONE = 0x40;
private static readonly IntPtr HFILE_ERROR = new IntPtr(-1);
/// <summary>
/// 判断文件是否被已打开
/// </summary>
/// <param name="fileFullName"></param>
/// <returns></returns>
public static bool FileIsOpen(string fileFullName)
{
if (!File.Exists(fileFullName))
{
return false;
}
IntPtr handle = _lopen(fileFullName, OF_READWRITE | OF_SHARE_DENY_NONE);
if (handle == HFILE_ERROR)
{
return true;
}
CloseHandle(handle);
return false;
}
#endif
}
}

39
RRQMCore/Logger/ILog.cs Normal file
View File

@@ -0,0 +1,39 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
namespace RRQMCore.Log
{
/// <summary>
/// 日志接口
/// </summary>
public interface ILog
{
/// <summary>
/// 日志记录
/// </summary>
/// <param name="logType"></param>
/// <param name="source"></param>
/// <param name="message"></param>
/// <param name="exception"></param>
void Debug(LogType logType, object source, string message, Exception exception);
/// <summary>
/// 日志记录
/// </summary>
/// <param name="logType"></param>
/// <param name="source"></param>
/// <param name="message"></param>
void Debug(LogType logType, object source, string message);
}
}

View File

@@ -0,0 +1,35 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace RRQMCore.Log
{
/// <summary>
/// 日志类型
/// </summary>
public enum LogType
{
/// <summary>
/// 一般消息
/// </summary>
Message,
/// <summary>
/// 警示消息
/// </summary>
Warning,
/// <summary>
/// 错误消息
/// </summary>
Error
}
}

View File

@@ -0,0 +1,815 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using RRQMCore.Exceptions;
using RRQMCore.Serialization;
using RRQMCore.XREF.Newtonsoft.Json;
using System;
using System.IO;
using System.Text;
namespace RRQMCore.ByteManager
{
/// <summary>
/// 字节块流
/// </summary>
public sealed class ByteBlock : Stream, IDisposable
{
internal bool @using;
internal long length;
private byte[] _buffer;
private bool holding;
private long position;
private static float ratio = 1.5f;
/// <summary>
/// 扩容增长比默认为1.5
/// min1
/// </summary>
public static float Ratio
{
get { return ratio; }
set
{
if (value < 1)
{
value = 1;
}
ratio = value;
}
}
internal ByteBlock()
{
}
/// <summary>
/// 字节实例
/// </summary>
public byte[] Buffer
{
get { return _buffer; }
}
/// <summary>
/// 创建一次性内存块
/// </summary>
/// <param name="capacity"></param>
/// <returns></returns>
public static ByteBlock CreateDisposableBlock(int capacity = 1024 * 10)
{
return new ByteBlock()
{
@using = true,
_buffer = new byte[capacity]
};
}
/// <summary>
/// 该字节流块所属集合若值为null则意味着该流块未被管理可能会被GC
/// </summary>
public BytesCollection BytesCollection { get; internal set; }
/// <summary>
/// 可读取
/// </summary>
public override bool CanRead => this.@using;
/// <summary>
/// 支持查找
/// </summary>
public override bool CanSeek => this.@using;
/// <summary>
/// 可写入
/// </summary>
public override bool CanWrite => this.@using;
/// <summary>
/// 容量
/// </summary>
public int Capacity => this._buffer.Length;
/// <summary>
/// 表示持续性持有为True时Dispose将调用无效。
/// </summary>
public bool Holding
{
get { return holding; }
}
/// <summary>
/// Int真实长度
/// </summary>
public int Len { get { return (int)length; } }
/// <summary>
/// 真实长度
/// </summary>
public override long Length { get { return length; } }
/// <summary>
/// int型流位置
/// </summary>
public int Pos
{
get { return (int)position; }
set { position = value; }
}
/// <summary>
/// 流位置
/// </summary>
public override long Position
{
get { return position; }
set { position = value; }
}
/// <summary>
/// 使用状态
/// </summary>
public bool Using
{
get { return @using; }
}
/// <summary>
/// 直接完全释放游离该对象等待GC
/// </summary>
public void AbsoluteDispose()
{
this.@using = false;
this.Position = 0;
this.length = 0;
this.BytesCollection = null;
}
/// <summary>
/// 回收资源
/// </summary>
public new void Dispose()
{
if (this.Holding)
{
return;
}
if (!this.@using)
{
throw new RRQMException("重复释放");
}
this.@using = false;
if (this.BytesCollection != null)
{
this.BytesCollection.BytePool.OnByteBlockRecycle(this);
}
else
{
this._buffer = null;
}
}
/// <summary>
/// 无实际效果
/// </summary>
public override void Flush()
{
}
/// <summary>
/// 读取
/// </summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="count"></param>
/// <returns></returns>
public override int Read(byte[] buffer, int offset, int count)
{
if (!this.@using)
{
throw new RRQMException("内存块已释放");
}
int len = this._buffer.Length - this.position > count ? count : this._buffer.Length - (int)this.position;
Array.Copy(this._buffer, this.position, buffer, offset, len);
this.position += len;
return len;
}
/// <summary>
/// 读取数据
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public int Read(byte[] buffer)
{
return Read(buffer, 0, buffer.Length);
}
/// <summary>
/// 设置流位置
/// </summary>
/// <param name="offset"></param>
/// <param name="origin"></param>
/// <returns></returns>
public override long Seek(long offset, SeekOrigin origin)
{
if (!this.@using)
{
throw new RRQMException("内存块已释放");
}
switch (origin)
{
case SeekOrigin.Begin:
this.position = offset;
break;
case SeekOrigin.Current:
this.position = offset;
break;
case SeekOrigin.End:
this.position = this.length + offset;
break;
}
return this.position;
}
/// <summary>
/// 重新指定Buffer
/// </summary>
public void SetBuffer(byte[] buffer)
{
if (!this.@using)
{
throw new RRQMException("内存块已释放");
}
if (buffer != null)
{
this._buffer = buffer;
}
}
/// <summary>
/// 设置持续持有属性当为False时会自动调用Dispose。
/// </summary>
/// <param name="holding"></param>
public void SetHolding(bool holding)
{
if (!this.@using)
{
throw new RRQMException("内存块已释放");
}
this.holding = holding;
if (!holding)
{
this.Dispose();
}
}
/// <summary>
/// 设置实际长度
/// </summary>
/// <param name="value"></param>
public override void SetLength(long value)
{
if (!this.@using)
{
throw new RRQMException("内存块已释放");
}
if (value > this._buffer.Length)
{
throw new RRQMException("设置值超出容量");
}
this.length = value;
}
/// <summary>
/// 转换为有效内存
/// </summary>
/// <returns></returns>
public byte[] ToArray()
{
if (!this.@using)
{
throw new RRQMException("内存块已释放");
}
byte[] buffer = new byte[this.length];
Array.Copy(this._buffer, 0, buffer, 0, this.length);
return buffer;
}
/// <summary>
/// 写入
/// </summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="count"></param>
public override void Write(byte[] buffer, int offset, int count)
{
if (!this.@using)
{
throw new RRQMException("内存块已释放");
}
if (this._buffer.Length - this.position < count)
{
byte[] newBuffer = new byte[this._buffer.Length + (int)((count + this.position - this._buffer.Length) * ratio)];
Array.Copy(this._buffer, newBuffer, this._buffer.Length);
this._buffer = newBuffer;
}
Array.Copy(buffer, offset, _buffer, this.position, count);
this.position += count;
this.length += count;
}
/// <summary>
/// 写入
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public void Write(byte[] buffer)
{
this.Write(buffer, 0, buffer.Length);
}
#region BytesPackage
/// <summary>
/// 从当前流位置读取一个独立的<see cref="byte"/>数组包
/// </summary>
public byte[] ReadBytesPackage()
{
byte status = this.ReadByte();
if (status == 0)
{
return null;
}
int length = this.ReadInt32();
byte[] data = new byte[length];
Array.Copy(this._buffer, this.position, data, 0, length);
this.position += length;
return data;
}
/// <summary>
/// 写入一个独立的<see cref="byte"/>数组包
/// </summary>
/// <param name="value"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
public void WriteBytesPackage(byte[] value, int offset, int length)
{
if (value == null)
{
this.Write((byte)0);
return;
}
this.Write((byte)1);
this.Write(length);
this.Write(value, offset, length);
}
/// <summary>
/// 写入一个独立的<see cref="byte"/>数组包
/// </summary>
/// <param name="value"></param>
public void WriteBytesPackage(byte[] value)
{
if (value == null)
{
this.WriteBytesPackage(value, 0, 0);
return;
}
this.WriteBytesPackage(value, 0, value.Length);
}
#endregion Int32
#region Int32
/// <summary>
/// 从当前流位置读取一个<see cref="int"/>值
/// </summary>
public int ReadInt32()
{
int value = BitConverter.ToInt32(this._buffer, (int)this.position);
this.position += 4;
return value;
}
/// <summary>
/// 写入<see cref="int"/>值
/// </summary>
/// <param name="value"></param>
public void Write(int value)
{
this.Write(BitConverter.GetBytes(value));
}
#endregion Int32
#region Int16
/// <summary>
/// 从当前流位置读取一个<see cref="short"/>值
/// </summary>
public short ReadInt16()
{
short value = BitConverter.ToInt16(this._buffer, (int)this.position);
this.position += 2;
return value;
}
/// <summary>
/// 写入<see cref="short"/>值
/// </summary>
/// <param name="value"></param>
public void Write(short value)
{
this.Write(BitConverter.GetBytes(value));
}
#endregion Int16
#region Int64
/// <summary>
/// 从当前流位置读取一个<see cref="long"/>值
/// </summary>
public long ReadInt64()
{
long value = BitConverter.ToInt64(this._buffer, (int)this.position);
this.position += 8;
return value;
}
/// <summary>
/// 写入<see cref="long"/>值
/// </summary>
/// <param name="value"></param>
public void Write(long value)
{
this.Write(BitConverter.GetBytes(value));
}
#endregion Int64
#region Boolean
/// <summary>
/// 从当前流位置读取一个<see cref="bool"/>值
/// </summary>
public bool ReadBoolean()
{
bool value = BitConverter.ToBoolean(this._buffer, (int)this.position);
this.position += 1;
return value;
}
/// <summary>
/// 写入<see cref="bool"/>值
/// </summary>
/// <param name="value"></param>
public void Write(bool value)
{
this.Write(BitConverter.GetBytes(value));
}
#endregion Boolean
#region Byte
/// <summary>
/// 从当前流位置读取一个<see cref="byte"/>值
/// </summary>
public new byte ReadByte()
{
byte value = this._buffer[this.position];
this.position++;
return value;
}
/// <summary>
/// 写入<see cref="byte"/>值
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public void Write(byte value)
{
this.Write(new byte[] { value }, 0, 1);
}
#endregion Byte
#region String
/// <summary>
/// 从当前流位置读取一个<see cref="string"/>值
/// </summary>
public string ReadString()
{
byte value = this.ReadByte();
if (value == 0)
{
return null;
}
else if (value == 1)
{
return string.Empty;
}
else
{
ushort len = this.ReadUInt16();
string str = Encoding.UTF8.GetString(this._buffer, (int)this.position, len);
this.position += len;
return str;
}
}
/// <summary>
/// 写入<see cref="string"/>值
/// </summary>
/// <param name="value"></param>
public void Write(string value)
{
if (value == null)
{
this.Write((byte)0);
}
else if (value == string.Empty)
{
this.Write((byte)1);
}
else
{
this.Write((byte)2);
byte[] buffer = Encoding.UTF8.GetBytes(value);
if (buffer.Length > ushort.MaxValue)
{
throw new RRQMException("传输长度超长");
}
this.Write((ushort)buffer.Length);
this.Write(buffer);
}
}
#endregion String
#region Char
/// <summary>
/// 从当前流位置读取一个<see cref="char"/>值
/// </summary>
public char ReadChar()
{
char value = BitConverter.ToChar(this._buffer, (int)this.position);
this.position += 2;
return value;
}
/// <summary>
/// 写入<see cref="char"/>值
/// </summary>
/// <param name="value"></param>
public void Write(char value)
{
this.Write(BitConverter.GetBytes(value));
}
#endregion Char
#region Double
/// <summary>
/// 从当前流位置读取一个<see cref="double"/>值
/// </summary>
public double ReadDouble()
{
double value = BitConverter.ToDouble(this._buffer, (int)this.position);
this.position += 8;
return value;
}
/// <summary>
/// 写入<see cref="double"/>值
/// </summary>
/// <param name="value"></param>
public void Write(double value)
{
this.Write(BitConverter.GetBytes(value));
}
#endregion Double
#region Float
/// <summary>
/// 从当前流位置读取一个<see cref="float"/>值
/// </summary>
public double ReadFloat()
{
float value = BitConverter.ToSingle(this._buffer, (int)this.position);
this.position += 4;
return value;
}
/// <summary>
/// 写入<see cref="float"/>值
/// </summary>
/// <param name="value"></param>
public void Write(float value)
{
this.Write(BitConverter.GetBytes(value));
}
#endregion Float
#region UInt16
/// <summary>
/// 从当前流位置读取一个<see cref="ushort"/>值
/// </summary>
public ushort ReadUInt16()
{
ushort value = BitConverter.ToUInt16(this._buffer, (int)this.position);
this.position += 2;
return value;
}
/// <summary>
/// 写入<see cref="ushort"/>值
/// </summary>
/// <param name="value"></param>
public void Write(ushort value)
{
this.Write(BitConverter.GetBytes(value));
}
#endregion UInt16
#region UInt32
/// <summary>
/// 从当前流位置读取一个<see cref="uint"/>值
/// </summary>
public uint ReadUInt32()
{
uint value = BitConverter.ToUInt32(this._buffer, (int)this.position);
this.position += 4;
return value;
}
/// <summary>
/// 写入<see cref="uint"/>值
/// </summary>
/// <param name="value"></param>
public void Write(uint value)
{
this.Write(BitConverter.GetBytes(value));
}
#endregion UInt32
#region UInt64
/// <summary>
/// 从当前流位置读取一个<see cref="ulong"/>值
/// </summary>
public ulong ReadUInt64()
{
ulong value = BitConverter.ToUInt64(this._buffer, (int)this.position);
this.position += 8;
return value;
}
/// <summary>
/// 写入<see cref="ulong"/>值
/// </summary>
/// <param name="value"></param>
public void Write(ulong value)
{
this.Write(BitConverter.GetBytes(value));
}
#endregion UInt64
#region DateTime
/// <summary>
/// 从当前流位置读取一个<see cref="DateTime"/>值
/// </summary>
public DateTime ReadDateTime()
{
long value = BitConverter.ToInt64(this._buffer, (int)this.position);
this.position += 8;
return DateTime.FromBinary(value);
}
/// <summary>
/// 写入<see cref="DateTime"/>值
/// </summary>
/// <param name="value"></param>
public void Write(DateTime value)
{
this.Write(BitConverter.GetBytes(value.ToBinary()));
}
#endregion DateTime
#region Object
/// <summary>
/// 从当前流位置读取一个泛型值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="serializationType"></param>
/// <returns></returns>
public T ReadObject<T>(SerializationType serializationType = SerializationType.RRQMBinary)
{
int length = this.ReadInt32();
if (length == 0)
{
return default;
}
T obj;
switch (serializationType)
{
case SerializationType.RRQMBinary:
{
obj = SerializeConvert.RRQMBinaryDeserialize<T>(this._buffer, (int)this.position);
}
break;
case SerializationType.SystemBinary:
{
obj = SerializeConvert.BinaryDeserialize<T>(this._buffer, (int)this.position, length);
}
break;
case SerializationType.Json:
{
string jsonString = Encoding.UTF8.GetString(this._buffer, (int)this.position, length);
obj = JsonConvert.DeserializeObject<T>(jsonString);
}
break;
default:
throw new RRQMException("未定义的序列化类型");
}
this.position += length;
return obj;
}
/// <summary>
/// 写入<see cref="object"/>值
/// </summary>
/// <param name="value"></param>
/// <param name="serializationType"></param>
public void WriteObject(object value, SerializationType serializationType = SerializationType.RRQMBinary)
{
if (value == null)
{
this.Write(0);
return;
}
byte[] data;
switch (serializationType)
{
case SerializationType.RRQMBinary:
{
data = SerializeConvert.RRQMBinarySerialize(value, true);
}
break;
case SerializationType.SystemBinary:
{
data = SerializeConvert.BinarySerialize(value);
}
break;
case SerializationType.Json:
{
data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value));
}
break;
default:
throw new RRQMException("未定义的序列化类型");
}
this.Write(data.Length);
this.Write(data);
}
#endregion Object
}
}

View File

@@ -0,0 +1,274 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using RRQMCore.Exceptions;
using System;
using System.Collections;
using System.Collections.Generic;
namespace RRQMCore.ByteManager
{
/// <summary>
/// 字节池
/// </summary>
public class BytePool : IEnumerable<ByteBlock>
{
/// <summary>
/// 构造函数
/// </summary>
public BytePool() : this(1024 * 1024 * 100, 1024 * 1024)
{
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="maxSize">字节池最大值</param>
/// <param name="maxBlockSize">单个Block最大值</param>
public BytePool(long maxSize, int maxBlockSize)
{
this.MaxSize = maxSize;
this.MaxBlockSize = maxBlockSize;
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="maxSize">字节池最大值</param>
public BytePool(long maxSize) : this(maxSize, 1024 * 1024)
{
this.MaxSize = maxSize;
}
private static BytePool bytePool = new BytePool(1024 * 1024 * 512, 1024 * 1024 * 5);
/// <summary>
/// 默认内存池,
/// 内存池最大512Mb
/// 单体最大5Mb。
/// </summary>
public static BytePool Default { get { return bytePool; } }
/// <summary>
/// 允许的内存池最大值,默认为100M Byte
/// </summary>
public long MaxSize { get; set; }
/// <summary>
/// 单个块最大值默认为1Mb
/// </summary>
public int MaxBlockSize { get; set; }
private long freeSize;
/// <summary>
/// 已创建的块的最大值
/// </summary>
public long CreatedBlockSize { get; private set; }
private BytesDictionary bytesDictionary = new BytesDictionary();
/// <summary>
/// 获取ByteBlock
/// </summary>
/// <param name="byteSize">长度</param>
/// <param name="equalSize">要求长度相同</param>
/// <returns></returns>
public ByteBlock GetByteBlock(long byteSize, bool equalSize)
{
ByteBlock byteBlock;
if (byteSize > MaxBlockSize)
{
//创建字节块,但是不进入管理池
byteBlock = CreatByteBlock(byteSize, false);
}
else
{
if (CreatedBlockSize < byteSize)
{
//请求长度大于已创建最大长度。
//重新创建
byteBlock = CreatByteBlock(byteSize);
}
else
{
BytesCollection bytesCollection;
//搜索已创建集合
if (bytesDictionary.TryGet(byteSize, out bytesCollection))
{
if (bytesCollection.TryGet(out byteBlock))
{
byteBlock.@using = true;
byteBlock.Position = 0;
byteBlock.length = 0;
freeSize -= byteBlock.Capacity;
return byteBlock;
}
}
if (!equalSize)
{
foreach (var item in bytesDictionary.Keys)
{
if (item > byteSize)
{
if (this.bytesDictionary.TryGet(item, out bytesCollection))
{
if (bytesCollection.TryGet(out byteBlock))
{
byteBlock.@using = true;
byteBlock.Position = 0;
byteBlock.length = 0;
freeSize -= byteBlock.Capacity;
return byteBlock;
}
}
}
}
}
//未搜索到
byteBlock = CreatByteBlock(byteSize);
}
}
byteBlock.@using = true;
byteBlock.Position = 0;
byteBlock.length = 0;
return byteBlock;
}
/// <summary>
/// 获取ByteBlock
/// </summary>
/// <param name="byteSize"></param>
/// <returns></returns>
public ByteBlock GetByteBlock(long byteSize)
{
ByteBlock byteBlock = this.GetByteBlock(byteSize, false);
if (byteBlock.Position > 0)
{
}
return byteBlock;
}
/// <summary>
/// 获取最大长度的ByteBlock
/// </summary>
/// <returns></returns>
public ByteBlock GetByteBlock()
{
return this.GetByteBlock(this.MaxBlockSize, true);
}
private ByteBlock CreatByteBlock(long byteSize, bool isBelongPool = true)
{
if (byteSize < 0)
{
throw new RRQMException("申请内存的长度不能小于0");
}
ByteBlock byteBlock = new ByteBlock();
byteBlock.@using = true;
byteBlock.SetBuffer(new byte[byteSize]);
if (isBelongPool)
{
BytesCollection bytesCollection;
lock (this)
{
if (!this.bytesDictionary.TryGet(byteSize, out bytesCollection))
{
bytesCollection = new BytesCollection(byteSize);
}
}
bytesCollection.BytePool = this;
byteBlock.BytesCollection = bytesCollection;
return byteBlock;
}
else
{
//创建,但不管理
return byteBlock;
}
}
internal void OnByteBlockRecycle(ByteBlock byteBlock)
{
BytesCollection bytesCollection;
this.CreatedBlockSize = Math.Max(CreatedBlockSize, byteBlock.Capacity);
if (MaxSize - freeSize >= byteBlock.Capacity)
{
freeSize += byteBlock.Capacity;
if (this.bytesDictionary.TryGet(byteBlock.Capacity, out bytesCollection))
{
bytesCollection.BytePool = this;
bytesCollection.Add(byteBlock);
}
else
{
lock (this)
{
bytesCollection = new BytesCollection(byteBlock.Capacity);
if (this.bytesDictionary.TryAdd(byteBlock.Capacity, bytesCollection))
{
bytesCollection.BytePool = this;
bytesCollection.Add(byteBlock);
}
}
}
}
else
{
long size = 0;
foreach (var item in this.bytesDictionary.Keys)
{
if (this.bytesDictionary.TryGet(item, out BytesCollection collection))
{
size += collection.FreeSize;
}
}
this.freeSize = size;
byteBlock.AbsoluteDispose();
}
}
/// <summary>
/// 返回迭代器
/// </summary>
/// <returns></returns>
public IEnumerator<ByteBlock> GetEnumerator()
{
List<ByteBlock> blocks = new List<ByteBlock>();
foreach (var item in bytesDictionary.Keys)
{
if (bytesDictionary.TryGet(item, out BytesCollection bytesCollection))
{
blocks.AddRange(bytesCollection.ToList());
}
}
return blocks.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
List<ByteBlock> blocks = new List<ByteBlock>();
foreach (var item in bytesDictionary.Keys)
{
if (bytesDictionary.TryGet(item, out BytesCollection bytesCollection))
{
blocks.AddRange(bytesCollection.ToList());
}
}
return blocks.GetEnumerator();
}
}
}

View File

@@ -0,0 +1,68 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace RRQMCore.ByteManager
{
/// <summary>
/// 字节块集合
/// </summary>
[DebuggerDisplay("Count = {bytes.Count}")]
public class BytesCollection
{
internal long size;
internal BytesCollection(long size)
{
this.size = size;
}
/// <summary>
/// 可用空间
/// </summary>
public long FreeSize { get { return this.size * this.bytes.Count; } }
/// <summary>
/// 所属字节池
/// </summary>
public BytePool BytePool { get; internal set; }
private ConcurrentQueue<ByteBlock> bytes = new ConcurrentQueue<ByteBlock>();
/// <summary>
/// 获取当前实例中的空闲的Block
/// </summary>
/// <returns></returns>
public bool TryGet(out ByteBlock byteBlock)
{
return this.bytes.TryDequeue(out byteBlock);
}
/// <summary>
/// 向当前集合添加Block
/// </summary>
/// <param name="byteBlock"></param>
public void Add(ByteBlock byteBlock)
{
byteBlock.BytesCollection = this;
this.bytes.Enqueue(byteBlock);
}
internal List<ByteBlock> ToList()
{
return this.bytes.ToList();
}
}
}

View File

@@ -0,0 +1,46 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Collections.Concurrent;
using System.Collections.Generic;
namespace RRQMCore.ByteManager
{
/// <summary>
/// 字节块集合字典索引。
/// </summary>
public class BytesDictionary
{
internal BytesDictionary()
{
this.bytesDic = new ConcurrentDictionary<long, BytesCollection>();
}
private ConcurrentDictionary<long, BytesCollection> bytesDic;
internal ICollection<long> Keys { get { return this.bytesDic.Keys; } }
internal bool ContainsKey(long key)
{
return bytesDic.ContainsKey(key);
}
internal bool TryGet(long key, out BytesCollection bytesCollection)
{
return bytesDic.TryGetValue(key, out bytesCollection);
}
internal bool TryAdd(long key, BytesCollection bytesCollection)
{
return this.bytesDic.TryAdd(key, bytesCollection);
}
}
}

View File

@@ -0,0 +1,31 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
namespace RRQMCore.Pool
{
/// <summary>
/// 对象池接口
/// </summary>
public interface IObjectPool : IDisposable
{
/// <summary>
/// 可使用数量
/// </summary>
int FreeSize { get; }
/// <summary>
/// 清空池中对象
/// </summary>
void Clear();
}
}

View File

@@ -0,0 +1,40 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace RRQMCore.Pool
{
/// <summary>
/// 对象池单位接口
/// </summary>
public interface IPoolObject
{
/// <summary>
/// 是否为新建对象
/// </summary>
bool NewCreate { get; set; }
/// <summary>
/// 初创建对象
/// </summary>
void Create();
/// <summary>
/// 重新创建对象
/// </summary>
void Recreate();
/// <summary>
/// 销毁对象
/// </summary>
void Destroy();
}
}

View File

@@ -0,0 +1,146 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
namespace RRQMCore.Pool
{
/// <summary>
/// 对象池
/// </summary>
/// <typeparam name="T"></typeparam>
public class ObjectPool<T> : IObjectPool where T : IPoolObject
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="capacity"></param>
public ObjectPool(int capacity)
{
this.Capacity = capacity;
}
/// <summary>
/// 构造函数
/// </summary>
public ObjectPool()
{
}
private ConcurrentQueue<T> queue = new ConcurrentQueue<T>();
private bool autoCreate = true;
/// <summary>
/// 是否自动生成
/// </summary>
public bool AutoCreate
{
get { return autoCreate; }
set { autoCreate = value; }
}
/// <summary>
/// 对象池容量
/// </summary>
public int Capacity { get; set; }
/// <summary>
/// 可使用(创建)数量
/// </summary>
public int FreeSize { get { return this.freeSize; } }
private int freeSize;
/// <summary>
/// 清除池中所有对象
/// </summary>
public void Clear()
{
while (this.queue.TryDequeue(out _))
{
}
}
/// <summary>
/// 获取对象T
/// </summary>
/// <returns></returns>
public T GetObject()
{
T t;
if (this.queue.TryDequeue(out t))
{
t.Recreate();
t.NewCreate = false;
Interlocked.Decrement(ref this.freeSize);
return t;
}
if (this.autoCreate)
{
t = (T)Activator.CreateInstance(typeof(T));
t.Create();
t.NewCreate = true;
}
return t;
}
/// <summary>
/// 获取所有对象
/// </summary>
/// <returns></returns>
public T[] GetAllObject()
{
List<T> ts = new List<T>();
while (this.queue.TryDequeue(out T t))
{
ts.Add(t);
}
return ts.ToArray();
}
/// <summary>
/// 预获取
/// </summary>
/// <returns></returns>
public T PreviewGetObject()
{
T t;
this.queue.TryPeek(out t);
return t;
}
/// <summary>
/// 注销对象
/// </summary>
/// <param name="t"></param>
public void DestroyObject(T t)
{
t.Destroy();
if (this.freeSize < this.Capacity)
{
Interlocked.Increment(ref this.freeSize);
this.queue.Enqueue(t);
}
}
/// <summary>
/// 释放对象
/// </summary>
public void Dispose()
{
this.Clear();
}
}
}

BIN
RRQMCore/RRQM.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

BIN
RRQMCore/RRQM.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

60
RRQMCore/RRQMCore.csproj Normal file
View File

@@ -0,0 +1,60 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;netcoreapp3.1;netstandard2.0</TargetFrameworks>
<Authors>若汝棋茗</Authors>
<PackageIcon>RRQM.png</PackageIcon>
<Copyright>Copyright © 2021 若汝棋茗</Copyright>
<Version>5.6.0</Version>
<SignAssembly>true</SignAssembly>
<Description>此程序集是RRQM的核心开源库其中包含了内存池、高性能序列化、日志接口在内的很多基本内容。
更新内容:
增加ByteBlock独立读写功能。
增加ByteBlock创建临时对象。
修改只有在net45及其以上版本才可以判断文件是否打开。
特别说明本程序集在源码里内嵌了Newtonsoft.Json 11.0.3,但为防止冲突,已修改其命名空间。
特此感谢其作者!!!
附带其Githubhttps://github.com/JamesNK/Newtonsoft.Json</Description>
<PackageProjectUrl>https://gitee.com/RRQM_OS/RRQMCore</PackageProjectUrl>
<AssemblyOriginatorKeyFile>RRQM.pfx</AssemblyOriginatorKeyFile>
<ApplicationIcon>RRQM.ico</ApplicationIcon>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<PackageTags>MemoryPool,ObjectPool,Serialize,Tool</PackageTags>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netstandard2.0|AnyCPU'">
<DocumentationFile>bin\Debug\netstandard2.0\RRQMCore.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|netstandard2.0|AnyCPU'">
<DocumentationFile>bin\Release\netstandard2.0\RRQMCore.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net45|AnyCPU'">
<DocumentationFile>bin\Debug\net45\RRQMCore.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net45|AnyCPU'">
<DocumentationFile>bin\Release\net45\RRQMCore.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netcoreapp3.1|AnyCPU'">
<DocumentationFile>bin\Debug\netcoreapp3.1\RRQMCore.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|netcoreapp3.1|AnyCPU'">
<DocumentationFile>bin\Release\netcoreapp3.1\RRQMCore.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<None Include="..\LICENSE">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
<None Include="RRQM.png">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,283 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using RRQMCore.Exceptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace RRQMCore.Run
{
/*
若汝棋茗
*/
/// <summary>
/// 消息通知类
/// </summary>
public class AppMessenger
{
/// <summary>
/// 注册已加载程序集中直接或间接继承自IMassage接口的所有类并创建新实例
/// </summary>
public void RegistAll()
{
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IMessage))))
.ToArray();
foreach (var v in types)
{
IMessage message = (IMessage)Activator.CreateInstance(v);
MethodInfo[] methods = message.GetType().GetMethods();
foreach (var item in methods)
{
RegistMethodAttribute attribute = item.GetCustomAttribute<RegistMethodAttribute>();
if (attribute != null)
{
if (attribute.Token == null)
{
Default.Register(message, item.Name, item);
}
else
{
Default.Register(message, attribute.Token, item);
}
}
}
}
}
private static AppMessenger instance;
/// <summary>
/// 默认单例实例
/// </summary>
public static AppMessenger Default
{
get
{
if (instance == null)
{
instance = new AppMessenger();
}
return instance;
}
}
private Dictionary<string, TokenInstance> tokenAndInstance = new Dictionary<string, TokenInstance>();
/// <summary>
/// 注册消息
/// </summary>
/// <param name="messageObject"></param>
/// <param name="token"></param>
/// <param name="action"></param>
/// <exception cref="MessageRegisteredException"></exception>
public void Register(IMessage messageObject, string token, Action action)
{
TokenInstance tokenInstance = new TokenInstance();
tokenInstance.MessageObject = messageObject;
tokenInstance.MethodInfo = action.Method;
try
{
tokenAndInstance.Add(token, tokenInstance);
}
catch (Exception)
{
throw new MessageRegisteredException("该Token消息已注册");
}
}
/// <summary>
/// 注册消息
/// </summary>
/// <param name="messageObject"></param>
public void Register(IMessage messageObject)
{
MethodInfo[] methods = messageObject.GetType().GetMethods();
foreach (var item in methods)
{
RegistMethodAttribute attribute = item.GetCustomAttribute<RegistMethodAttribute>();
if (attribute != null)
{
if (attribute.Token == null)
{
Default.Register(messageObject, item.Name, item);
}
else
{
Default.Register(messageObject, attribute.Token, item);
}
}
}
}
/// <summary>
/// 注册消息
/// </summary>
/// <param name="messageObject"></param>
/// <param name="token"></param>
/// <param name="methodInfo"></param>
/// <exception cref="MessageRegisteredException"></exception>
public void Register(IMessage messageObject, string token, MethodInfo methodInfo)
{
TokenInstance tokenInstance = new TokenInstance();
tokenInstance.MessageObject = messageObject;
tokenInstance.MethodInfo = methodInfo;
try
{
tokenAndInstance.Add(token, tokenInstance);
}
catch (Exception)
{
throw new MessageRegisteredException("该Token消息已注册");
}
}
/// <summary>
/// 注册消息
/// </summary>
/// <typeparam name="T">参数类型</typeparam>
/// <param name="messageObject"></param>
/// <param name="token"></param>
/// <param name="action"></param>
/// <exception cref="MessageRegisteredException"></exception>
public void Register<T>(IMessage messageObject, string token, Action<T> action)
{
TokenInstance tokenInstance = new TokenInstance();
tokenInstance.MessageObject = messageObject;
tokenInstance.MethodInfo = action.Method;
try
{
tokenAndInstance.Add(token, tokenInstance);
}
catch (Exception)
{
throw new MessageRegisteredException("该Token消息已注册");
}
}
/// <summary>
/// 注册
/// </summary>
/// <typeparam name="T">参数类型</typeparam>
/// <typeparam name="TReturn">返回值类型</typeparam>
/// <param name="messageObject"></param>
/// <param name="token"></param>
/// <param name="action"></param>
public void Register<T, TReturn>(IMessage messageObject, string token, Func<T, TReturn> action)
{
TokenInstance tokenInstance = new TokenInstance();
tokenInstance.MessageObject = messageObject;
tokenInstance.MethodInfo = action.Method;
try
{
tokenAndInstance.Add(token, tokenInstance);
}
catch (Exception)
{
throw new MessageRegisteredException("该Token消息已注册");
}
}
/// <summary>
/// 注册
/// </summary>
/// <typeparam name="TReturn">返回值类型</typeparam>
/// <param name="messageObject"></param>
/// <param name="token"></param>
/// <param name="action"></param>
public void Register<TReturn>(IMessage messageObject, string token, Func<TReturn> action)
{
TokenInstance tokenInstance = new TokenInstance();
tokenInstance.MessageObject = messageObject;
tokenInstance.MethodInfo = action.Method;
try
{
tokenAndInstance.Add(token, tokenInstance);
}
catch (Exception)
{
throw new MessageRegisteredException("该Token消息已注册");
}
}
/// <summary>
/// 卸载消息
/// </summary>
/// <param name="messageObject"></param>
public void Unregister(IMessage messageObject)
{
List<string> key = new List<string>();
foreach (var item in tokenAndInstance.Keys)
{
if (messageObject == tokenAndInstance[item].MessageObject)
{
key.Add(item);
}
}
foreach (var item in key)
{
tokenAndInstance.Remove(item);
}
}
/// <summary>
/// 清除所有消息
/// </summary>
public void Clear()
{
tokenAndInstance.Clear();
}
/// <summary>
/// 发送消息
/// </summary>
/// <param name="token"></param>
/// <param name="parameters"></param>
/// <exception cref="MessageNotFoundException"></exception>
public void Send(string token, params object[] parameters)
{
try
{
tokenAndInstance[token].MethodInfo.Invoke(tokenAndInstance[token].MessageObject, parameters);
}
catch (KeyNotFoundException)
{
throw new MessageNotFoundException("未找到该消息");
}
}
/// <summary>
/// 发送消息
/// </summary>
/// <typeparam name="T">返回值类型</typeparam>
/// <param name="token"></param>
/// <param name="parameters"></param>
/// <returns></returns>
/// <exception cref="MessageNotFoundException"></exception>
public T Send<T>(string token, params object[] parameters)
{
try
{
return (T)tokenAndInstance[token].MethodInfo.Invoke(tokenAndInstance[token].MessageObject, parameters);
}
catch (KeyNotFoundException)
{
throw new MessageNotFoundException("未找到该消息");
}
}
}
}

View File

@@ -0,0 +1,21 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace RRQMCore.Run
{
/// <summary>
/// 消息接口
/// </summary>
public interface IMessage
{
}
}

View File

@@ -0,0 +1,47 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
namespace RRQMCore.Run
{
/*
若汝棋茗
*/
/// <summary>
/// 注册为消息
/// </summary>
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
public sealed class RegistMethodAttribute : Attribute
{
/// <summary>
/// 构造函数
/// </summary>
public RegistMethodAttribute()
{
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="token"></param>
public RegistMethodAttribute(string token)
{
this.Token = token;
}
/// <summary>
/// 标识
/// </summary>
public string Token { get; set; }
}
}

View File

@@ -0,0 +1,21 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Reflection;
namespace RRQMCore.Run
{
internal class TokenInstance
{
internal IMessage MessageObject { get; set; }
internal MethodInfo MethodInfo { get; set; }
}
}

View File

@@ -0,0 +1,53 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.Threading;
using System.Threading.Tasks;
namespace RRQMCore.Run
{
/// <summary>
/// 时间执行
/// </summary>
public class TimeRun
{
/// <summary>
/// 执行
/// </summary>
/// <param name="action"></param>
/// <param name="timeSpan"></param>
public static void Run(Action action, TimeSpan timeSpan)
{
Task.Run(() =>
{
WaitHandle waitHandle = new AutoResetEvent(false);
waitHandle.WaitOne(timeSpan);
action?.Invoke();
});
}
/// <summary>
/// 执行
/// </summary>
/// <param name="action"></param>
/// <param name="seconds"></param>
public static void Run(Action action, double seconds)
{
Task.Run(() =>
{
WaitHandle waitHandle = new AutoResetEvent(false);
waitHandle.WaitOne(TimeSpan.FromSeconds(seconds));
action?.Invoke();
});
}
}
}

View File

@@ -0,0 +1,139 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using RRQMCore.Exceptions;
using System;
using System.Collections.Concurrent;
using System.Threading;
namespace RRQMCore.Run
{
/// <summary>
/// 等待处理数据
/// </summary>
/// <typeparam name="T"></typeparam>
public class RRQMWaitHandle<T> : IDisposable where T : WaitResult
{
/// <summary>
/// 构造函数
/// </summary>
public RRQMWaitHandle()
{
this.waitDic = new ConcurrentDictionary<int, WaitData<T>>();
this.waitQueue = new ConcurrentQueue<WaitData<T>>();
}
private ConcurrentDictionary<int, WaitData<T>> waitDic;
private ConcurrentQueue<WaitData<T>> waitQueue;
private int signCount;
/// <summary>
/// 获取一个可等待对象
/// </summary>
public WaitData<T> GetWaitData(T result)
{
if (signCount == int.MaxValue)
{
signCount = 0;
}
WaitData<T> waitData;
if (this.waitQueue.TryDequeue(out waitData))
{
result.Sign = Interlocked.Increment(ref signCount);
waitData.LoadResult(result);
this.waitDic.TryAdd(result.Sign, waitData);
return waitData;
}
waitData = new WaitData<T>();
result.Sign = Interlocked.Increment(ref signCount);
waitData.LoadResult(result);
this.waitDic.TryAdd(result.Sign, waitData);
return waitData;
}
/// <summary>
/// 让等待对象恢复运行
/// </summary>
/// <param name="sign"></param>
public void SetRun(int sign)
{
WaitData<T> waitData;
if (this.waitDic.TryRemove(sign, out waitData))
{
waitData.Set();
}
}
/// <summary>
/// 让等待对象恢复运行
/// </summary>
/// <param name="sign"></param>
/// <param name="waitResult"></param>
public void SetRun(int sign, T waitResult)
{
WaitData<T> waitData;
if (this.waitDic.TryRemove(sign, out waitData))
{
waitData.Set(waitResult);
}
}
/// <summary>
/// 让等待对象恢复运行
/// </summary>
/// <param name="waitResult"></param>
public void SetRun(T waitResult)
{
WaitData<T> waitData;
if (this.waitDic.TryRemove(waitResult.Sign, out waitData))
{
waitData.Set(waitResult);
}
}
/// <summary>
/// 销毁
/// </summary>
/// <param name="waitData"></param>
public void Destroy(WaitData<T> waitData)
{
if (waitData._dispose)
{
throw new RRQMException("waitData已销毁");
}
if (this.waitDic.TryRemove(waitData.WaitResult.Sign, out _))
{
waitData.Reset();
this.waitQueue.Enqueue(waitData);
}
}
/// <summary>
/// 释放
/// </summary>
public void Dispose()
{
foreach (var item in waitDic.Values)
{
item.Dispose();
}
foreach (var item in this.waitQueue)
{
item.Dispose();
}
this.waitDic.Clear();
while (this.waitQueue.TryDequeue(out _))
{
}
}
}
}

View File

@@ -0,0 +1,108 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.Threading;
namespace RRQMCore.Run
{
/// <summary>
/// 等待数据对象
/// </summary>
/// <typeparam name="T"></typeparam>
public class WaitData<T> : IDisposable
{
/// <summary>
/// 构造函数
/// </summary>
public WaitData()
{
this.waitHandle = new AutoResetEvent(false);
}
private EventWaitHandle waitHandle;
private T waitResult;
private WaitDataStatus status;
/// <summary>
/// 等待数据结果
/// </summary>
public T WaitResult
{
get { return waitResult; }
}
/// <summary>
/// 状态
/// </summary>
public WaitDataStatus Status { get => status; }
/// <summary>
/// 载入结果
/// </summary>
public void LoadResult(T result)
{
this.waitResult = result;
}
/// <summary>
/// 等待指定毫秒
/// </summary>
/// <param name="millisecond"></param>
public bool Wait(int millisecond)
{
this.status = WaitDataStatus.Waiting;
bool signSuccess = this.waitHandle.WaitOne(millisecond);
this.status = WaitDataStatus.Running;
return signSuccess;
}
/// <summary>
/// 使等待的线程继续执行
/// </summary>
public void Set()
{
this.waitHandle.Set();
}
/// <summary>
/// Reset
/// </summary>
public bool Reset()
{
return this.waitHandle.Reset();
}
/// <summary>
/// 使等待的线程继续执行
/// </summary>
/// <param name="waitResult">等待结果</param>
public void Set(T waitResult)
{
this.waitResult = waitResult;
this.waitHandle.Set();
}
internal bool _dispose;
/// <summary>
/// 回收
/// </summary>
public void Dispose()
{
this.status = WaitDataStatus.Disposed;
this._dispose = true;
this.waitResult = default;
this.waitHandle.Dispose();
}
}
}

View File

@@ -0,0 +1,34 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace RRQMCore.Run
{
/// <summary>
/// 等待数据状态
/// </summary>
public enum WaitDataStatus : byte
{
/// <summary>
/// 等待中
/// </summary>
Waiting,
/// <summary>
/// 运行中
/// </summary>
Running,
/// <summary>
/// 已释放
/// </summary>
Disposed
}
}

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
namespace RRQMCore.Run
{
/// <summary>
/// 等待返回类
/// </summary>
[Serializable]
public class WaitResult
{
/// <summary>
/// 消息
/// </summary>
protected string message;
/// <summary>
/// 标记
/// </summary>
protected int sign;
/// <summary>
/// 状态
/// </summary>
protected byte status;
/// <summary>
/// 消息
/// </summary>
public string Message
{
get { return message; }
set { message = value; }
}
/// <summary>
/// 标记
/// </summary>
public int Sign
{
get { return sign; }
set { sign = value; }
}
/// <summary>
/// 状态
/// </summary>
public byte Status
{
get { return status; }
set { status = value; }
}
}
}

View File

@@ -0,0 +1,28 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.Reflection;
namespace RRQMCore.Serialization
{
internal class InstanceObject
{
internal InstanceType instanceType;
internal Type Type;
internal object Instance;
internal Type[] ArgTypes;
internal Type[] ProTypes;
internal PropertyInfo[] Properties;
internal MethodInfo AddMethod;
internal MethodInfo ToArrayMethod;
}
}

View File

@@ -0,0 +1,22 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace RRQMCore.Serialization
{
internal enum InstanceType
{
Class,
List,
Array,
Dictionary
}
}

View File

@@ -0,0 +1,492 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using RRQMCore.ByteManager;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace RRQMCore.Serialization
{
/// <summary>
/// 该序列化以二进制方式进行,但是不支持接口、抽象类、继承类等成员的序列化。
/// </summary>
public class RRQMBinaryFormatter
{
#region Serialize
/// <summary>
/// 序列化对象
/// </summary>
/// <param name="stream">流</param>
/// <param name="graph">对象</param>
/// <param name="reserveAttributeName">保留属性名</param>
public void Serialize(ByteBlock stream, object graph, bool reserveAttributeName)
{
this.reserveAttributeName = reserveAttributeName;
stream.Position = 1;
SerializeObject(stream, graph);
if (reserveAttributeName)
{
stream.Buffer[0] = 1;
}
else
{
stream.Buffer[0] = 0;
}
stream.SetLength(stream.Position);
}
/// <summary>
/// 序列化对象
/// </summary>
/// <param name="stream"></param>
/// <param name="graph"></param>
public void Serialize(ByteBlock stream, object graph)
{
Serialize(stream, graph, false);
}
/// <summary>
/// 保留属性名
/// </summary>
private bool reserveAttributeName;
private int SerializeObject(ByteBlock stream, object graph)
{
int len = 0;
byte[] data = null;
long startPosition = stream.Position;
long endPosition;
if (graph != null)
{
if (graph is string str)
{
data = Encoding.UTF8.GetBytes(str);
}
else if (graph is byte by)
{
data = new byte[] { by };
}
else if (graph is bool b)
{
data = BitConverter.GetBytes(b);
}
else if (graph is short s)
{
data = BitConverter.GetBytes(s);
}
else if (graph is int)
{
data = BitConverter.GetBytes((int)graph);
}
else if (graph is long l)
{
data = BitConverter.GetBytes(l);
}
else if (graph is float f)
{
data = BitConverter.GetBytes(f);
}
else if (graph is double d)
{
data = BitConverter.GetBytes(d);
}
else if (graph is DateTime time)
{
data = Encoding.UTF8.GetBytes(time.Ticks.ToString());
}
else if (graph is Enum)
{
var enumValType = Enum.GetUnderlyingType(graph.GetType());
if (enumValType == RRQMReadonly.byteType)
{
data = new byte[] { (byte)graph };
}
else if (enumValType == RRQMReadonly.shortType)
{
data = BitConverter.GetBytes((short)graph);
}
else if (enumValType == RRQMReadonly.intType)
{
data = BitConverter.GetBytes((int)graph);
}
else
{
data = BitConverter.GetBytes((long)graph);
}
}
else if (graph is byte[])
{
data = (byte[])graph;
}
else
{
stream.Position += 4;
Type type = graph.GetType();
if (typeof(IEnumerable).IsAssignableFrom(type))
{
len += SerializeIEnumerable(stream, (IEnumerable)graph);
}
else
{
len += SerializeClass(stream, graph, type);
}
}
if (data != null)
{
len = data.Length;
endPosition = len + startPosition + 4;
}
else
{
endPosition = stream.Position;
}
}
else
{
endPosition = startPosition + 4;
}
byte[] lenBuffer = BitConverter.GetBytes(len);
stream.Position = startPosition;
stream.Write(lenBuffer, 0, lenBuffer.Length);
if (data != null)
{
stream.Write(data, 0, data.Length);
}
stream.Position = endPosition;
return len + 4;
}
private int SerializeClass(ByteBlock stream, object obj, Type type)
{
int len = 0;
if (obj != null)
{
PropertyInfo[] propertyInfos = this.GetProperties(type);
foreach (PropertyInfo property in propertyInfos)
{
if (reserveAttributeName)
{
byte[] propertyBytes = Encoding.UTF8.GetBytes(property.Name);
if (propertyBytes.Length > 255)
{
throw new RRQMCore.Exceptions.RRQMException($"属性名:{property.Name}超长");
}
byte lenBytes = (byte)propertyBytes.Length;
stream.Write(lenBytes);
stream.Write(propertyBytes, 0, propertyBytes.Length);
len += propertyBytes.Length + 1;
}
len += SerializeObject(stream, property.GetValue(obj, null));
}
}
return len;
}
private int SerializeIEnumerable(ByteBlock stream, IEnumerable param)
{
int len = 0;
if (param != null)
{
foreach (object item in param)
{
len += SerializeObject(stream, item);
}
}
return len;
}
#endregion Serialize
#region Deserialize
/// <summary>
/// 反序列化
/// </summary>
/// <param name="data"></param>
/// <param name="offset"></param>
/// <param name="type"></param>
/// <returns></returns>
public object Deserialize(byte[] data, int offset, Type type)
{
if (data[offset] == 0)
{
this.reserveAttributeName = false;
}
else if (data[offset] == 1)
{
this.reserveAttributeName = true;
}
else
{
throw new RRQMCore.Exceptions.RRQMException("数据流解析错误");
}
offset += 1;
return Deserialize(type, data, ref offset);
}
private object Deserialize(Type type, byte[] datas, ref int offset)
{
dynamic obj = null;
int len = BitConverter.ToInt32(datas, offset);
offset += 4;
if (len > 0)
{
if (type == RRQMReadonly.stringType)
{
obj = Encoding.UTF8.GetString(datas, offset, len);
}
else if (type == RRQMReadonly.byteType)
{
obj = datas[offset];
}
else if (type == RRQMReadonly.boolType)
{
obj = (BitConverter.ToBoolean(datas, offset));
}
else if (type == RRQMReadonly.shortType)
{
obj = (BitConverter.ToInt16(datas, offset));
}
else if (type == RRQMReadonly.intType)
{
obj = (BitConverter.ToInt32(datas, offset));
}
else if (type == RRQMReadonly.longType)
{
obj = (BitConverter.ToInt64(datas, offset));
}
else if (type == RRQMReadonly.floatType)
{
obj = (BitConverter.ToSingle(datas, offset));
}
else if (type == RRQMReadonly.doubleType)
{
obj = (BitConverter.ToDouble(datas, offset));
}
else if (type == RRQMReadonly.decimalType)
{
obj = (BitConverter.ToDouble(datas, offset));
}
else if (type == RRQMReadonly.dateTimeType)
{
obj = (new DateTime(long.Parse(Encoding.UTF8.GetString(datas, offset, len))));
}
else if (type.BaseType == typeof(Enum))
{
Type enumType = Enum.GetUnderlyingType(type);
if (enumType == typeof(byte))
{
obj = Enum.ToObject(type, datas[offset]);
}
else if (enumType == typeof(short))
{
obj = Enum.ToObject(type, BitConverter.ToInt16(datas, offset));
}
else if (enumType == typeof(int))
{
obj = Enum.ToObject(type, BitConverter.ToInt32(datas, offset));
}
else
{
obj = Enum.ToObject(type, BitConverter.ToInt64(datas, offset));
}
}
else if (type == RRQMReadonly.bytesType)
{
byte[] data = new byte[len];
Buffer.BlockCopy(datas, offset, data, 0, len);
obj = data;
}
else if (type.IsClass)
{
obj = DeserializeClass(type, datas, offset, len);
}
else
{
throw new Exception("未定义的类型:" + type.ToString());
}
}
offset += len;
return obj;
}
private object DeserializeClass(Type type, byte[] datas, int offset, int length)
{
InstanceObject instanceObject = GetOrAddInstance(type);
switch (instanceObject.instanceType)
{
case InstanceType.Class:
{
if (reserveAttributeName)
{
int index = offset;
while (offset - index < length && (length >= 4))
{
int len = datas[offset];
string propertyName = Encoding.UTF8.GetString(datas, offset + 1, len);
offset += len + 1;
PropertyInfo propertyInfo = type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
if (propertyInfo == null)
{
continue;
}
object obj = Deserialize(propertyInfo.PropertyType, datas, ref offset);
propertyInfo.SetValue(instanceObject.Instance, obj);
}
}
else
{
foreach (var item in instanceObject.Properties)
{
object obj = Deserialize(item.PropertyType, datas, ref offset);
item.SetValue(instanceObject.Instance, obj);
}
}
break;
}
case InstanceType.List:
{
int index = offset;
while (offset - index < length && (length >= 4))
{
object obj = Deserialize(instanceObject.ArgTypes[0], datas, ref offset);
instanceObject.AddMethod.Invoke(instanceObject.Instance, new object[] { obj });
}
break;
}
case InstanceType.Array:
{
int index = offset;
while (offset - index < length && (length >= 4))
{
object obj = Deserialize(instanceObject.ArgTypes[0], datas, ref offset);
instanceObject.AddMethod.Invoke(instanceObject.Instance, new object[] { obj });
}
instanceObject.ToArrayMethod.Invoke(instanceObject.Instance, null);
break;
}
case InstanceType.Dictionary:
{
int index = offset;
while (offset - index < length && (length >= 4))
{
offset += 4;
if (reserveAttributeName)
{
offset += datas[offset] + 1;
}
object key = Deserialize(instanceObject.ArgTypes[0], datas, ref offset);
if (reserveAttributeName)
{
offset += datas[offset] + 1;
}
object value = Deserialize(instanceObject.ArgTypes[1], datas, ref offset);
if (key != null)
{
instanceObject.AddMethod.Invoke(instanceObject.Instance, new object[] { key, value });
}
}
break;
}
default:
break;
}
return instanceObject.Instance;
}
#endregion Deserialize
private PropertyInfo[] GetProperties(Type type)
{
return type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
}
private static readonly ConcurrentDictionary<string, InstanceObject> InstanceCache = new ConcurrentDictionary<string, InstanceObject>();
private InstanceObject GetOrAddInstance(Type type)
{
if (type.IsArray && !type.IsGenericType)
{
type = typeof(List<>).MakeGenericType(type.GetElementType());
InstanceObject typeInfo = InstanceCache.GetOrAdd(type.FullName, (v) =>
{
InstanceObject instanceObject = new InstanceObject();
instanceObject.Type = type;
instanceObject.ArgTypes = type.GetGenericArguments();
instanceObject.instanceType = InstanceType.Array;
instanceObject.Properties = this.GetProperties(type);
instanceObject.ProTypes = instanceObject.Properties.Select(a => a.PropertyType).ToArray();
instanceObject.AddMethod = type.GetMethod("Add");
instanceObject.ToArrayMethod = type.GetMethod("ToArray");
return instanceObject;
});
typeInfo.Instance = Activator.CreateInstance(type);
return typeInfo;
}
else if (type.IsClass)
{
InstanceObject typeInfo = InstanceCache.GetOrAdd(type.FullName, (v) =>
{
InstanceObject instanceObject = new InstanceObject();
instanceObject.Type = type;
instanceObject.Properties = this.GetProperties(type);
instanceObject.ProTypes = instanceObject.Properties.Select(a => a.PropertyType).ToArray();
if (type.IsGenericType)
{
instanceObject.AddMethod = type.GetMethod("Add");
instanceObject.ToArrayMethod = type.GetMethod("ToArray");
instanceObject.ArgTypes = type.GetGenericArguments();
type = type.GetGenericTypeDefinition().MakeGenericType(instanceObject.ArgTypes);
if (instanceObject.ArgTypes.Length == 1)
{
instanceObject.instanceType = InstanceType.List;
}
else
{
instanceObject.instanceType = InstanceType.Dictionary;
}
}
else
{
instanceObject.instanceType = InstanceType.Class;
}
return instanceObject;
});
typeInfo.Instance = Activator.CreateInstance(type);
return typeInfo;
}
return null;
}
}
}

View File

@@ -0,0 +1,45 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RRQMCore.Serialization
{
/// <summary>
/// 序列化类型
/// </summary>
public enum SerializationType:byte
{
/// <summary>
/// 若汝棋茗内置
/// </summary>
RRQMBinary,
/// <summary>
/// 系统二进制
/// </summary>
SystemBinary,
/// <summary>
/// Json
/// </summary>
Json,
/// <summary>
/// Xml
/// </summary>
Xml
}
}

View File

@@ -0,0 +1,377 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using RRQMCore.ByteManager;
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Xml.Serialization;
namespace RRQMCore.Serialization
{
/// <summary>
/// 高性能序列化器
/// </summary>
public static class SerializeConvert
{
#region
/// <summary>
/// 普通二进制序列化对象
/// </summary>
/// <param name="obj">数据对象</param>
/// <returns></returns>
public static byte[] BinarySerialize(object obj)
{
using (MemoryStream serializeStream = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(serializeStream, obj);
return serializeStream.ToArray();
}
}
/// <summary>
/// 二进制序列化对象至文件
/// </summary>
/// <param name="obj">数据对象</param>
/// <param name="path">路径</param>
public static void BinarySerializeToFile(object obj, string path)
{
using (FileStream serializeStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(serializeStream, obj);
serializeStream.Close();
}
}
/// <summary>
/// 二进制序列化对象
/// </summary>
/// <param name="stream"></param>
/// <param name="obj"></param>
public static void BinarySerialize(Stream stream, object obj)
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(stream, obj);
}
#endregion
#region
/// <summary>
/// 从Byte[]中反序列化
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="data"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
/// <param name="binder"></param>
/// <returns></returns>
public static T BinaryDeserialize<T>(byte[] data, int offset, int length, SerializationBinder binder = null)
{
using (MemoryStream DeserializeStream = new MemoryStream(data, offset, length))
{
DeserializeStream.Position = 0;
BinaryFormatter bf = new BinaryFormatter();
if (binder != null)
{
bf.Binder = binder;
}
return (T)bf.Deserialize(DeserializeStream);
}
}
/// <summary>
/// 反序列化
/// </summary>
/// <param name="data"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
/// <param name="binder"></param>
/// <returns></returns>
public static object BinaryDeserialize(byte[] data, int offset, int length, SerializationBinder binder = null)
{
using (MemoryStream DeserializeStream = new MemoryStream(data, offset, length))
{
DeserializeStream.Position = 0;
BinaryFormatter bf = new BinaryFormatter();
if (binder != null)
{
bf.Binder = binder;
}
return bf.Deserialize(DeserializeStream);
}
}
/// <summary>
/// 从Stream中反序列化
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="stream"></param>
/// <param name="binder"></param>
/// <returns></returns>
public static T BinaryDeserialize<T>(Stream stream, SerializationBinder binder = null)
{
BinaryFormatter bf = new BinaryFormatter();
if (binder != null)
{
bf.Binder = binder;
}
return (T)bf.Deserialize(stream);
}
/// <summary>
/// 将二进制文件数据反序列化为指定类型对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="path"></param>
/// <returns></returns>
public static T BinaryDeserializeFromFile<T>(string path)
{
using (FileStream serializeStream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
BinaryFormatter bf = new BinaryFormatter();
return (T)bf.Deserialize(serializeStream);
}
}
/// <summary>
/// 将二进制数据反序列化为指定类型对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="data"></param>
/// <returns></returns>
public static T BinaryDeserialize<T>(byte[] data)
{
return BinaryDeserialize<T>(data, 0, data.Length);
}
/// <summary>
/// 从Byte[]中反序列化
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="data"></param>
/// <param name="binder"></param>
/// <returns></returns>
public static T BinaryDeserialize<T>(byte[] data, SerializationBinder binder = null)
{
return BinaryDeserialize<T>(data, 0, data.Length, binder);
}
#endregion
#region RRQM二进制序列化
/// <summary>
/// RRQM二进制序列化对象
/// </summary>
/// <param name="stream"></param>
/// <param name="obj"></param>
/// <param name="reserveAttributeName"></param>
/// <returns></returns>
public static void RRQMBinarySerialize(ByteBlock stream, object obj, bool reserveAttributeName)
{
RRQMBinaryFormatter bf = new RRQMBinaryFormatter();
bf.Serialize(stream, obj, reserveAttributeName);
}
/// <summary>
/// RRQM二进制序列化对象
/// </summary>
/// <param name="obj"></param>
/// <param name="reserveAttributeName"></param>
/// <returns></returns>
public static byte[] RRQMBinarySerialize(object obj, bool reserveAttributeName)
{
using (ByteBlock byteBlock = new ByteBlock() { @using = true })
{
byteBlock.SetBuffer(new byte[1024 * 10]);
RRQMBinarySerialize(byteBlock, obj, reserveAttributeName);
return byteBlock.ToArray();
}
}
#endregion RRQM二进制序列化
#region RRQM二进制反序列化
/// <summary>
/// 反序列化
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="data"></param>
/// <param name="offset"></param>
/// <returns></returns>
public static T RRQMBinaryDeserialize<T>(byte[] data, int offset)
{
RRQMBinaryFormatter bf = new RRQMBinaryFormatter();
return (T)bf.Deserialize(data, offset, typeof(T));
}
/// <summary>
/// 反序列化
/// </summary>
/// <param name="data"></param>
/// <param name="offset"></param>
/// <param name="type"></param>
/// <returns></returns>
public static object RRQMBinaryDeserialize(byte[] data, int offset, Type type)
{
RRQMBinaryFormatter bf = new RRQMBinaryFormatter();
return bf.Deserialize(data, offset, type);
}
/// <summary>
/// 从Byte[]中反序列化
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="data"></param>
/// <returns></returns>
public static T RRQMBinaryDeserialize<T>(byte[] data)
{
return RRQMBinaryDeserialize<T>(data, 0);
}
#endregion RRQM二进制反序列化
#region Xml序列化和反序列化
/// <summary>
/// Xml序列化数据对象
/// </summary>
/// <param name="obj">数据对象</param>
/// <param name="encoding">编码格式</param>
/// <returns></returns>
public static string XmlSerializeToString(object obj, Encoding encoding)
{
return encoding.GetString(XmlSerializeToBytes(obj));
}
/// <summary>
/// Xml序列化数据对象
/// </summary>
/// <param name="obj">数据对象</param>
/// <returns></returns>
public static string XmlSerializeToString(object obj)
{
return XmlSerializeToString(obj, Encoding.UTF8);
}
/// <summary>
/// Xml序列化数据对象
/// </summary>
/// <param name="obj">数据对象</param>
/// <returns></returns>
public static byte[] XmlSerializeToBytes(object obj)
{
using (MemoryStream fileStream = new MemoryStream())
{
XmlSerializer xml = new XmlSerializer(obj.GetType());
xml.Serialize(fileStream, obj);
return fileStream.ToArray();
}
}
/// <summary>
/// Xml序列化至文件
/// </summary>
/// <param name="obj"></param>
/// <param name="path"></param>
public static void XmlSerializeToFile(object obj, string path)
{
using (FileStream fileStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
XmlSerializer xml = new XmlSerializer(obj.GetType());
xml.Serialize(fileStream, obj);
fileStream.Close();
}
}
/// <summary>
/// Xml反序列化
/// </summary>
/// <typeparam name="T">反序列化类型</typeparam>
/// <param name="datas">数据</param>
/// <returns></returns>
public static T XmlDeserializeFromBytes<T>(byte[] datas)
{
XmlSerializer xmlserializer = new XmlSerializer(typeof(T));
using (Stream xmlstream = new MemoryStream(datas))
{
return (T)xmlserializer.Deserialize(xmlstream);
}
}
/// <summary>
/// Xml反序列化
/// </summary>
/// <param name="datas"></param>
/// <param name="type"></param>
/// <returns></returns>
public static object XmlDeserializeFromBytes(byte[] datas, Type type)
{
XmlSerializer xmlserializer = new XmlSerializer(type);
using (Stream xmlstream = new MemoryStream(datas))
{
return xmlserializer.Deserialize(xmlstream);
}
}
/// <summary>
/// Xml反序列化
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="xmlString">xml字符串</param>
/// <param name="encoding">编码格式</param>
/// <returns></returns>
public static T XmlDeserializeFromString<T>(string xmlString, Encoding encoding)
{
XmlSerializer xmlserializer = new XmlSerializer(typeof(T));
using (Stream xmlstream = new MemoryStream(encoding.GetBytes(xmlString)))
{
return (T)xmlserializer.Deserialize(xmlstream);
}
}
/// <summary>
/// Xml反序列化
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="xmlString">xml字符串</param>
/// <returns></returns>
public static T XmlDeserializeFromString<T>(string xmlString)
{
return XmlDeserializeFromString<T>(xmlString, Encoding.UTF8);
}
/// <summary>
/// Xml反序列化
/// </summary>
/// <typeparam name="T">反序列化类型</typeparam>
/// <param name="path">文件路径</param>
/// <returns></returns>
public static T XmlDeserializeFromFile<T>(string path)
{
using (Stream xmlstream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
XmlSerializer xmlserializer = new XmlSerializer(typeof(T));
return (T)xmlserializer.Deserialize(xmlstream);
}
}
#endregion Xml序列化和反序列化
}
}

View File

@@ -0,0 +1,58 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System;
namespace RRQMCore.XREF.Newtonsoft.Json.Bson
{
internal enum BsonBinaryType : byte
{
Binary = 0x00,
Function = 0x01,
[Obsolete("This type has been deprecated in the BSON specification. Use Binary instead.")]
BinaryOld = 0x02,
[Obsolete("This type has been deprecated in the BSON specification. Use Uuid instead.")]
UuidOld = 0x03,
Uuid = 0x04,
Md5 = 0x05,
UserDefined = 0x80
}
}

View File

@@ -0,0 +1,361 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
using System;
using System.Globalization;
using System.IO;
using System.Text;
namespace RRQMCore.XREF.Newtonsoft.Json.Bson
{
internal class BsonBinaryWriter
{
private static readonly Encoding Encoding = new UTF8Encoding(false);
private readonly BinaryWriter _writer;
private byte[] _largeByteBuffer;
public DateTimeKind DateTimeKindHandling { get; set; }
public BsonBinaryWriter(BinaryWriter writer)
{
DateTimeKindHandling = DateTimeKind.Utc;
_writer = writer;
}
public void Flush()
{
_writer.Flush();
}
public void Close()
{
#if HAVE_STREAM_READER_WRITER_CLOSE
_writer.Close();
#else
_writer.Dispose();
#endif
}
public void WriteToken(BsonToken t)
{
CalculateSize(t);
WriteTokenInternal(t);
}
private void WriteTokenInternal(BsonToken t)
{
switch (t.Type)
{
case BsonType.Object:
{
BsonObject value = (BsonObject)t;
_writer.Write(value.CalculatedSize);
foreach (BsonProperty property in value)
{
_writer.Write((sbyte)property.Value.Type);
WriteString((string)property.Name.Value, property.Name.ByteCount, null);
WriteTokenInternal(property.Value);
}
_writer.Write((byte)0);
}
break;
case BsonType.Array:
{
BsonArray value = (BsonArray)t;
_writer.Write(value.CalculatedSize);
ulong index = 0;
foreach (BsonToken c in value)
{
_writer.Write((sbyte)c.Type);
WriteString(index.ToString(CultureInfo.InvariantCulture), MathUtils.IntLength(index), null);
WriteTokenInternal(c);
index++;
}
_writer.Write((byte)0);
}
break;
case BsonType.Integer:
{
BsonValue value = (BsonValue)t;
_writer.Write(Convert.ToInt32(value.Value, CultureInfo.InvariantCulture));
}
break;
case BsonType.Long:
{
BsonValue value = (BsonValue)t;
_writer.Write(Convert.ToInt64(value.Value, CultureInfo.InvariantCulture));
}
break;
case BsonType.Number:
{
BsonValue value = (BsonValue)t;
_writer.Write(Convert.ToDouble(value.Value, CultureInfo.InvariantCulture));
}
break;
case BsonType.String:
{
BsonString value = (BsonString)t;
WriteString((string)value.Value, value.ByteCount, value.CalculatedSize - 4);
}
break;
case BsonType.Boolean:
_writer.Write(t == BsonBoolean.True);
break;
case BsonType.Null:
case BsonType.Undefined:
break;
case BsonType.Date:
{
BsonValue value = (BsonValue)t;
long ticks = 0;
if (value.Value is DateTime)
{
DateTime dateTime = (DateTime)value.Value;
if (DateTimeKindHandling == DateTimeKind.Utc)
{
dateTime = dateTime.ToUniversalTime();
}
else if (DateTimeKindHandling == DateTimeKind.Local)
{
dateTime = dateTime.ToLocalTime();
}
ticks = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(dateTime, false);
}
#if HAVE_DATE_TIME_OFFSET
else
{
DateTimeOffset dateTimeOffset = (DateTimeOffset)value.Value;
ticks = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(dateTimeOffset.UtcDateTime, dateTimeOffset.Offset);
}
#endif
_writer.Write(ticks);
}
break;
case BsonType.Binary:
{
BsonBinary value = (BsonBinary)t;
byte[] data = (byte[])value.Value;
_writer.Write(data.Length);
_writer.Write((byte)value.BinaryType);
_writer.Write(data);
}
break;
case BsonType.Oid:
{
BsonValue value = (BsonValue)t;
byte[] data = (byte[])value.Value;
_writer.Write(data);
}
break;
case BsonType.Regex:
{
BsonRegex value = (BsonRegex)t;
WriteString((string)value.Pattern.Value, value.Pattern.ByteCount, null);
WriteString((string)value.Options.Value, value.Options.ByteCount, null);
}
break;
default:
throw new ArgumentOutOfRangeException(nameof(t), "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type));
}
}
private void WriteString(string s, int byteCount, int? calculatedlengthPrefix)
{
if (calculatedlengthPrefix != null)
{
_writer.Write(calculatedlengthPrefix.GetValueOrDefault());
}
WriteUtf8Bytes(s, byteCount);
_writer.Write((byte)0);
}
public void WriteUtf8Bytes(string s, int byteCount)
{
if (s != null)
{
if (byteCount <= 256)
{
if (_largeByteBuffer == null)
{
_largeByteBuffer = new byte[256];
}
Encoding.GetBytes(s, 0, s.Length, _largeByteBuffer, 0);
_writer.Write(_largeByteBuffer, 0, byteCount);
}
else
{
byte[] bytes = Encoding.GetBytes(s);
_writer.Write(bytes);
}
}
}
private int CalculateSize(int stringByteCount)
{
return stringByteCount + 1;
}
private int CalculateSizeWithLength(int stringByteCount, bool includeSize)
{
int baseSize = (includeSize)
? 5 // size bytes + terminator
: 1; // terminator
return baseSize + stringByteCount;
}
private int CalculateSize(BsonToken t)
{
switch (t.Type)
{
case BsonType.Object:
{
BsonObject value = (BsonObject)t;
int bases = 4;
foreach (BsonProperty p in value)
{
int size = 1;
size += CalculateSize(p.Name);
size += CalculateSize(p.Value);
bases += size;
}
bases += 1;
value.CalculatedSize = bases;
return bases;
}
case BsonType.Array:
{
BsonArray value = (BsonArray)t;
int size = 4;
ulong index = 0;
foreach (BsonToken c in value)
{
size += 1;
size += CalculateSize(MathUtils.IntLength(index));
size += CalculateSize(c);
index++;
}
size += 1;
value.CalculatedSize = size;
return value.CalculatedSize;
}
case BsonType.Integer:
return 4;
case BsonType.Long:
return 8;
case BsonType.Number:
return 8;
case BsonType.String:
{
BsonString value = (BsonString)t;
string s = (string)value.Value;
value.ByteCount = (s != null) ? Encoding.GetByteCount(s) : 0;
value.CalculatedSize = CalculateSizeWithLength(value.ByteCount, value.IncludeLength);
return value.CalculatedSize;
}
case BsonType.Boolean:
return 1;
case BsonType.Null:
case BsonType.Undefined:
return 0;
case BsonType.Date:
return 8;
case BsonType.Binary:
{
BsonBinary value = (BsonBinary)t;
byte[] data = (byte[])value.Value;
value.CalculatedSize = 4 + 1 + data.Length;
return value.CalculatedSize;
}
case BsonType.Oid:
return 12;
case BsonType.Regex:
{
BsonRegex value = (BsonRegex)t;
int size = 0;
size += CalculateSize(value.Pattern);
size += CalculateSize(value.Options);
value.CalculatedSize = size;
return value.CalculatedSize;
}
default:
throw new ArgumentOutOfRangeException(nameof(t), "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type));
}
}
}
}

View File

@@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
using System;
namespace RRQMCore.XREF.Newtonsoft.Json.Bson
{
/// <summary>
/// Represents a BSON Oid (object id).
/// </summary>
[Obsolete("BSON reading and writing has been moved to its own package. See https://www.nuget.org/packages/RRQMCore.XREF.Newtonsoft.Json.Bson for more details.")]
public class BsonObjectId
{
/// <summary>
/// Gets or sets the value of the Oid.
/// </summary>
/// <value>The value of the Oid.</value>
public byte[] Value { get; }
/// <summary>
/// Initializes a new instance of the <see cref="BsonObjectId"/> class.
/// </summary>
/// <param name="value">The Oid value.</param>
public BsonObjectId(byte[] value)
{
ValidationUtils.ArgumentNotNull(value, nameof(value));
if (value.Length != 12)
{
throw new ArgumentException("An ObjectId must be 12 bytes", nameof(value));
}
Value = value;
}
}
}

View File

@@ -0,0 +1,869 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using RRQMCore.XREF.Newtonsoft.Json.Serialization;
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
namespace RRQMCore.XREF.Newtonsoft.Json.Bson
{
/// <summary>
/// Represents a reader that provides fast, non-cached, forward-only access to serialized BSON data.
/// </summary>
[Obsolete("BSON reading and writing has been moved to its own package. See https://www.nuget.org/packages/RRQMCore.XREF.Newtonsoft.Json.Bson for more details.")]
public class BsonReader : JsonReader
{
private const int MaxCharBytesSize = 128;
private static readonly byte[] SeqRange1 = new byte[] { 0, 127 }; // range of 1-byte sequence
private static readonly byte[] SeqRange2 = new byte[] { 194, 223 }; // range of 2-byte sequence
private static readonly byte[] SeqRange3 = new byte[] { 224, 239 }; // range of 3-byte sequence
private static readonly byte[] SeqRange4 = new byte[] { 240, 244 }; // range of 4-byte sequence
private readonly BinaryReader _reader;
private readonly List<ContainerContext> _stack;
private byte[] _byteBuffer;
private char[] _charBuffer;
private BsonType _currentElementType;
private BsonReaderState _bsonReaderState;
private ContainerContext _currentContext;
private bool _readRootValueAsArray;
private bool _jsonNet35BinaryCompatibility;
private DateTimeKind _dateTimeKindHandling;
private enum BsonReaderState
{
Normal = 0,
ReferenceStart = 1,
ReferenceRef = 2,
ReferenceId = 3,
CodeWScopeStart = 4,
CodeWScopeCode = 5,
CodeWScopeScope = 6,
CodeWScopeScopeObject = 7,
CodeWScopeScopeEnd = 8
}
private class ContainerContext
{
public readonly BsonType Type;
public int Length;
public int Position;
public ContainerContext(BsonType type)
{
Type = type;
}
}
/// <summary>
/// Gets or sets a value indicating whether binary data reading should be compatible with incorrect Json.NET 3.5 written binary.
/// </summary>
/// <value>
/// <c>true</c> if binary data reading will be compatible with incorrect Json.NET 3.5 written binary; otherwise, <c>false</c>.
/// </value>
[Obsolete("JsonNet35BinaryCompatibility will be removed in a future version of Json.NET.")]
public bool JsonNet35BinaryCompatibility
{
get => _jsonNet35BinaryCompatibility;
set => _jsonNet35BinaryCompatibility = value;
}
/// <summary>
/// Gets or sets a value indicating whether the root object will be read as a JSON array.
/// </summary>
/// <value>
/// <c>true</c> if the root object will be read as a JSON array; otherwise, <c>false</c>.
/// </value>
public bool ReadRootValueAsArray
{
get => _readRootValueAsArray;
set => _readRootValueAsArray = value;
}
/// <summary>
/// Gets or sets the <see cref="DateTimeKind" /> used when reading <see cref="DateTime"/> values from BSON.
/// </summary>
/// <value>The <see cref="DateTimeKind" /> used when reading <see cref="DateTime"/> values from BSON.</value>
public DateTimeKind DateTimeKindHandling
{
get => _dateTimeKindHandling;
set => _dateTimeKindHandling = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="BsonReader"/> class.
/// </summary>
/// <param name="stream">The <see cref="Stream"/> containing the BSON data to read.</param>
public BsonReader(Stream stream)
: this(stream, false, DateTimeKind.Local)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BsonReader"/> class.
/// </summary>
/// <param name="reader">The <see cref="BinaryReader"/> containing the BSON data to read.</param>
public BsonReader(BinaryReader reader)
: this(reader, false, DateTimeKind.Local)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BsonReader"/> class.
/// </summary>
/// <param name="stream">The <see cref="Stream"/> containing the BSON data to read.</param>
/// <param name="readRootValueAsArray">if set to <c>true</c> the root object will be read as a JSON array.</param>
/// <param name="dateTimeKindHandling">The <see cref="DateTimeKind" /> used when reading <see cref="DateTime"/> values from BSON.</param>
public BsonReader(Stream stream, bool readRootValueAsArray, DateTimeKind dateTimeKindHandling)
{
ValidationUtils.ArgumentNotNull(stream, nameof(stream));
_reader = new BinaryReader(stream);
_stack = new List<ContainerContext>();
_readRootValueAsArray = readRootValueAsArray;
_dateTimeKindHandling = dateTimeKindHandling;
}
/// <summary>
/// Initializes a new instance of the <see cref="BsonReader"/> class.
/// </summary>
/// <param name="reader">The <see cref="BinaryReader"/> containing the BSON data to read.</param>
/// <param name="readRootValueAsArray">if set to <c>true</c> the root object will be read as a JSON array.</param>
/// <param name="dateTimeKindHandling">The <see cref="DateTimeKind" /> used when reading <see cref="DateTime"/> values from BSON.</param>
public BsonReader(BinaryReader reader, bool readRootValueAsArray, DateTimeKind dateTimeKindHandling)
{
ValidationUtils.ArgumentNotNull(reader, nameof(reader));
_reader = reader;
_stack = new List<ContainerContext>();
_readRootValueAsArray = readRootValueAsArray;
_dateTimeKindHandling = dateTimeKindHandling;
}
private string ReadElement()
{
_currentElementType = ReadType();
string elementName = ReadString();
return elementName;
}
/// <summary>
/// Reads the next JSON token from the underlying <see cref="Stream"/>.
/// </summary>
/// <returns>
/// <c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
/// </returns>
public override bool Read()
{
try
{
bool success;
switch (_bsonReaderState)
{
case BsonReaderState.Normal:
success = ReadNormal();
break;
case BsonReaderState.ReferenceStart:
case BsonReaderState.ReferenceRef:
case BsonReaderState.ReferenceId:
success = ReadReference();
break;
case BsonReaderState.CodeWScopeStart:
case BsonReaderState.CodeWScopeCode:
case BsonReaderState.CodeWScopeScope:
case BsonReaderState.CodeWScopeScopeObject:
case BsonReaderState.CodeWScopeScopeEnd:
success = ReadCodeWScope();
break;
default:
throw JsonReaderException.Create(this, "Unexpected state: {0}".FormatWith(CultureInfo.InvariantCulture, _bsonReaderState));
}
if (!success)
{
SetToken(JsonToken.None);
return false;
}
return true;
}
catch (EndOfStreamException)
{
SetToken(JsonToken.None);
return false;
}
}
/// <summary>
/// Changes the reader's state to <see cref="JsonReader.State.Closed"/>.
/// If <see cref="JsonReader.CloseInput"/> is set to <c>true</c>, the underlying <see cref="Stream"/> is also closed.
/// </summary>
public override void Close()
{
base.Close();
if (CloseInput)
{
#if HAVE_STREAM_READER_WRITER_CLOSE
_reader?.Close();
#else
_reader?.Dispose();
#endif
}
}
private bool ReadCodeWScope()
{
switch (_bsonReaderState)
{
case BsonReaderState.CodeWScopeStart:
SetToken(JsonToken.PropertyName, "$code");
_bsonReaderState = BsonReaderState.CodeWScopeCode;
return true;
case BsonReaderState.CodeWScopeCode:
// total CodeWScope size - not used
ReadInt32();
SetToken(JsonToken.String, ReadLengthString());
_bsonReaderState = BsonReaderState.CodeWScopeScope;
return true;
case BsonReaderState.CodeWScopeScope:
if (CurrentState == State.PostValue)
{
SetToken(JsonToken.PropertyName, "$scope");
return true;
}
else
{
SetToken(JsonToken.StartObject);
_bsonReaderState = BsonReaderState.CodeWScopeScopeObject;
ContainerContext newContext = new ContainerContext(BsonType.Object);
PushContext(newContext);
newContext.Length = ReadInt32();
return true;
}
case BsonReaderState.CodeWScopeScopeObject:
bool result = ReadNormal();
if (result && TokenType == JsonToken.EndObject)
{
_bsonReaderState = BsonReaderState.CodeWScopeScopeEnd;
}
return result;
case BsonReaderState.CodeWScopeScopeEnd:
SetToken(JsonToken.EndObject);
_bsonReaderState = BsonReaderState.Normal;
return true;
default:
throw new ArgumentOutOfRangeException();
}
}
private bool ReadReference()
{
switch (CurrentState)
{
case State.ObjectStart:
{
SetToken(JsonToken.PropertyName, JsonTypeReflector.RefPropertyName);
_bsonReaderState = BsonReaderState.ReferenceRef;
return true;
}
case State.Property:
{
if (_bsonReaderState == BsonReaderState.ReferenceRef)
{
SetToken(JsonToken.String, ReadLengthString());
return true;
}
else if (_bsonReaderState == BsonReaderState.ReferenceId)
{
SetToken(JsonToken.Bytes, ReadBytes(12));
return true;
}
else
{
throw JsonReaderException.Create(this, "Unexpected state when reading BSON reference: " + _bsonReaderState);
}
}
case State.PostValue:
{
if (_bsonReaderState == BsonReaderState.ReferenceRef)
{
SetToken(JsonToken.PropertyName, JsonTypeReflector.IdPropertyName);
_bsonReaderState = BsonReaderState.ReferenceId;
return true;
}
else if (_bsonReaderState == BsonReaderState.ReferenceId)
{
SetToken(JsonToken.EndObject);
_bsonReaderState = BsonReaderState.Normal;
return true;
}
else
{
throw JsonReaderException.Create(this, "Unexpected state when reading BSON reference: " + _bsonReaderState);
}
}
default:
throw JsonReaderException.Create(this, "Unexpected state when reading BSON reference: " + CurrentState);
}
}
private bool ReadNormal()
{
switch (CurrentState)
{
case State.Start:
{
JsonToken token = (!_readRootValueAsArray) ? JsonToken.StartObject : JsonToken.StartArray;
BsonType type = (!_readRootValueAsArray) ? BsonType.Object : BsonType.Array;
SetToken(token);
ContainerContext newContext = new ContainerContext(type);
PushContext(newContext);
newContext.Length = ReadInt32();
return true;
}
case State.Complete:
case State.Closed:
return false;
case State.Property:
{
ReadType(_currentElementType);
return true;
}
case State.ObjectStart:
case State.ArrayStart:
case State.PostValue:
ContainerContext context = _currentContext;
if (context == null)
{
return false;
}
int lengthMinusEnd = context.Length - 1;
if (context.Position < lengthMinusEnd)
{
if (context.Type == BsonType.Array)
{
ReadElement();
ReadType(_currentElementType);
return true;
}
else
{
SetToken(JsonToken.PropertyName, ReadElement());
return true;
}
}
else if (context.Position == lengthMinusEnd)
{
if (ReadByte() != 0)
{
throw JsonReaderException.Create(this, "Unexpected end of object byte value.");
}
PopContext();
if (_currentContext != null)
{
MovePosition(context.Length);
}
JsonToken endToken = (context.Type == BsonType.Object) ? JsonToken.EndObject : JsonToken.EndArray;
SetToken(endToken);
return true;
}
else
{
throw JsonReaderException.Create(this, "Read past end of current container context.");
}
case State.ConstructorStart:
break;
case State.Constructor:
break;
case State.Error:
break;
case State.Finished:
break;
default:
throw new ArgumentOutOfRangeException();
}
return false;
}
private void PopContext()
{
_stack.RemoveAt(_stack.Count - 1);
if (_stack.Count == 0)
{
_currentContext = null;
}
else
{
_currentContext = _stack[_stack.Count - 1];
}
}
private void PushContext(ContainerContext newContext)
{
_stack.Add(newContext);
_currentContext = newContext;
}
private byte ReadByte()
{
MovePosition(1);
return _reader.ReadByte();
}
private void ReadType(BsonType type)
{
switch (type)
{
case BsonType.Number:
double d = ReadDouble();
if (_floatParseHandling == FloatParseHandling.Decimal)
{
SetToken(JsonToken.Float, Convert.ToDecimal(d, CultureInfo.InvariantCulture));
}
else
{
SetToken(JsonToken.Float, d);
}
break;
case BsonType.String:
case BsonType.Symbol:
SetToken(JsonToken.String, ReadLengthString());
break;
case BsonType.Object:
{
SetToken(JsonToken.StartObject);
ContainerContext newContext = new ContainerContext(BsonType.Object);
PushContext(newContext);
newContext.Length = ReadInt32();
break;
}
case BsonType.Array:
{
SetToken(JsonToken.StartArray);
ContainerContext newContext = new ContainerContext(BsonType.Array);
PushContext(newContext);
newContext.Length = ReadInt32();
break;
}
case BsonType.Binary:
BsonBinaryType binaryType;
byte[] data = ReadBinary(out binaryType);
object value = (binaryType != BsonBinaryType.Uuid)
? data
: (object)new Guid(data);
SetToken(JsonToken.Bytes, value);
break;
case BsonType.Undefined:
SetToken(JsonToken.Undefined);
break;
case BsonType.Oid:
byte[] oid = ReadBytes(12);
SetToken(JsonToken.Bytes, oid);
break;
case BsonType.Boolean:
bool b = Convert.ToBoolean(ReadByte());
SetToken(JsonToken.Boolean, b);
break;
case BsonType.Date:
long ticks = ReadInt64();
DateTime utcDateTime = DateTimeUtils.ConvertJavaScriptTicksToDateTime(ticks);
DateTime dateTime;
switch (DateTimeKindHandling)
{
case DateTimeKind.Unspecified:
dateTime = DateTime.SpecifyKind(utcDateTime, DateTimeKind.Unspecified);
break;
case DateTimeKind.Local:
dateTime = utcDateTime.ToLocalTime();
break;
default:
dateTime = utcDateTime;
break;
}
SetToken(JsonToken.Date, dateTime);
break;
case BsonType.Null:
SetToken(JsonToken.Null);
break;
case BsonType.Regex:
string expression = ReadString();
string modifiers = ReadString();
string regex = @"/" + expression + @"/" + modifiers;
SetToken(JsonToken.String, regex);
break;
case BsonType.Reference:
SetToken(JsonToken.StartObject);
_bsonReaderState = BsonReaderState.ReferenceStart;
break;
case BsonType.Code:
SetToken(JsonToken.String, ReadLengthString());
break;
case BsonType.CodeWScope:
SetToken(JsonToken.StartObject);
_bsonReaderState = BsonReaderState.CodeWScopeStart;
break;
case BsonType.Integer:
SetToken(JsonToken.Integer, (long)ReadInt32());
break;
case BsonType.TimeStamp:
case BsonType.Long:
SetToken(JsonToken.Integer, ReadInt64());
break;
default:
throw new ArgumentOutOfRangeException(nameof(type), "Unexpected BsonType value: " + type);
}
}
private byte[] ReadBinary(out BsonBinaryType binaryType)
{
int dataLength = ReadInt32();
binaryType = (BsonBinaryType)ReadByte();
#pragma warning disable 612,618
// the old binary type has the data length repeated in the data for some reason
if (binaryType == BsonBinaryType.BinaryOld && !_jsonNet35BinaryCompatibility)
{
dataLength = ReadInt32();
}
#pragma warning restore 612,618
return ReadBytes(dataLength);
}
private string ReadString()
{
EnsureBuffers();
StringBuilder builder = null;
int totalBytesRead = 0;
// used in case of left over multibyte characters in the buffer
int offset = 0;
while (true)
{
int count = offset;
byte b;
while (count < MaxCharBytesSize && (b = _reader.ReadByte()) > 0)
{
_byteBuffer[count++] = b;
}
int byteCount = count - offset;
totalBytesRead += byteCount;
if (count < MaxCharBytesSize && builder == null)
{
// pref optimization to avoid reading into a string builder
// if string is smaller than the buffer then return it directly
int length = Encoding.UTF8.GetChars(_byteBuffer, 0, byteCount, _charBuffer, 0);
MovePosition(totalBytesRead + 1);
return new string(_charBuffer, 0, length);
}
else
{
// calculate the index of the end of the last full character in the buffer
int lastFullCharStop = GetLastFullCharStop(count - 1);
int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, lastFullCharStop + 1, _charBuffer, 0);
if (builder == null)
{
builder = new StringBuilder(MaxCharBytesSize * 2);
}
builder.Append(_charBuffer, 0, charCount);
if (lastFullCharStop < byteCount - 1)
{
offset = byteCount - lastFullCharStop - 1;
// copy left over multi byte characters to beginning of buffer for next iteration
Array.Copy(_byteBuffer, lastFullCharStop + 1, _byteBuffer, 0, offset);
}
else
{
// reached end of string
if (count < MaxCharBytesSize)
{
MovePosition(totalBytesRead + 1);
return builder.ToString();
}
offset = 0;
}
}
}
}
private string ReadLengthString()
{
int length = ReadInt32();
MovePosition(length);
string s = GetString(length - 1);
_reader.ReadByte();
return s;
}
private string GetString(int length)
{
if (length == 0)
{
return string.Empty;
}
EnsureBuffers();
StringBuilder builder = null;
int totalBytesRead = 0;
// used in case of left over multibyte characters in the buffer
int offset = 0;
do
{
int count = ((length - totalBytesRead) > MaxCharBytesSize - offset)
? MaxCharBytesSize - offset
: length - totalBytesRead;
int byteCount = _reader.Read(_byteBuffer, offset, count);
if (byteCount == 0)
{
throw new EndOfStreamException("Unable to read beyond the end of the stream.");
}
totalBytesRead += byteCount;
// Above, byteCount is how many bytes we read this time.
// Below, byteCount is how many bytes are in the _byteBuffer.
byteCount += offset;
if (byteCount == length)
{
// pref optimization to avoid reading into a string builder
// first iteration and all bytes read then return string directly
int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, byteCount, _charBuffer, 0);
return new string(_charBuffer, 0, charCount);
}
else
{
int lastFullCharStop = GetLastFullCharStop(byteCount - 1);
if (builder == null)
{
builder = new StringBuilder(length);
}
int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, lastFullCharStop + 1, _charBuffer, 0);
builder.Append(_charBuffer, 0, charCount);
if (lastFullCharStop < byteCount - 1)
{
offset = byteCount - lastFullCharStop - 1;
// copy left over multi byte characters to beginning of buffer for next iteration
Array.Copy(_byteBuffer, lastFullCharStop + 1, _byteBuffer, 0, offset);
}
else
{
offset = 0;
}
}
} while (totalBytesRead < length);
return builder.ToString();
}
private int GetLastFullCharStop(int start)
{
int lookbackPos = start;
int bis = 0;
while (lookbackPos >= 0)
{
bis = BytesInSequence(_byteBuffer[lookbackPos]);
if (bis == 0)
{
lookbackPos--;
continue;
}
else if (bis == 1)
{
break;
}
else
{
lookbackPos--;
break;
}
}
if (bis == start - lookbackPos)
{
//Full character.
return start;
}
else
{
return lookbackPos;
}
}
private int BytesInSequence(byte b)
{
if (b <= SeqRange1[1])
{
return 1;
}
if (b >= SeqRange2[0] && b <= SeqRange2[1])
{
return 2;
}
if (b >= SeqRange3[0] && b <= SeqRange3[1])
{
return 3;
}
if (b >= SeqRange4[0] && b <= SeqRange4[1])
{
return 4;
}
return 0;
}
private void EnsureBuffers()
{
if (_byteBuffer == null)
{
_byteBuffer = new byte[MaxCharBytesSize];
}
if (_charBuffer == null)
{
int charBufferSize = Encoding.UTF8.GetMaxCharCount(MaxCharBytesSize);
_charBuffer = new char[charBufferSize];
}
}
private double ReadDouble()
{
MovePosition(8);
return _reader.ReadDouble();
}
private int ReadInt32()
{
MovePosition(4);
return _reader.ReadInt32();
}
private long ReadInt64()
{
MovePosition(8);
return _reader.ReadInt64();
}
private BsonType ReadType()
{
MovePosition(1);
return (BsonType)_reader.ReadSByte();
}
private void MovePosition(int count)
{
_currentContext.Position += count;
}
private byte[] ReadBytes(int count)
{
MovePosition(count);
return _reader.ReadBytes(count);
}
}
}

View File

@@ -0,0 +1,179 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System.Collections;
using System.Collections.Generic;
namespace RRQMCore.XREF.Newtonsoft.Json.Bson
{
internal abstract class BsonToken
{
public abstract BsonType Type { get; }
public BsonToken Parent { get; set; }
public int CalculatedSize { get; set; }
}
internal class BsonObject : BsonToken, IEnumerable<BsonProperty>
{
private readonly List<BsonProperty> _children = new List<BsonProperty>();
public void Add(string name, BsonToken token)
{
_children.Add(new BsonProperty { Name = new BsonString(name, false), Value = token });
token.Parent = this;
}
public override BsonType Type => BsonType.Object;
public IEnumerator<BsonProperty> GetEnumerator()
{
return _children.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
internal class BsonArray : BsonToken, IEnumerable<BsonToken>
{
private readonly List<BsonToken> _children = new List<BsonToken>();
public void Add(BsonToken token)
{
_children.Add(token);
token.Parent = this;
}
public override BsonType Type => BsonType.Array;
public IEnumerator<BsonToken> GetEnumerator()
{
return _children.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
internal class BsonEmpty : BsonToken
{
public static readonly BsonToken Null = new BsonEmpty(BsonType.Null);
public static readonly BsonToken Undefined = new BsonEmpty(BsonType.Undefined);
private BsonEmpty(BsonType type)
{
Type = type;
}
public override BsonType Type { get; }
}
internal class BsonValue : BsonToken
{
private readonly object _value;
private readonly BsonType _type;
public BsonValue(object value, BsonType type)
{
_value = value;
_type = type;
}
public object Value => _value;
public override BsonType Type => _type;
}
internal class BsonBoolean : BsonValue
{
public static readonly BsonBoolean False = new BsonBoolean(false);
public static readonly BsonBoolean True = new BsonBoolean(true);
private BsonBoolean(bool value)
: base(value, BsonType.Boolean)
{
}
}
internal class BsonString : BsonValue
{
public int ByteCount { get; set; }
public bool IncludeLength { get; }
public BsonString(object value, bool includeLength)
: base(value, BsonType.String)
{
IncludeLength = includeLength;
}
}
internal class BsonBinary : BsonValue
{
public BsonBinaryType BinaryType { get; set; }
public BsonBinary(byte[] value, BsonBinaryType binaryType)
: base(value, BsonType.Binary)
{
BinaryType = binaryType;
}
}
internal class BsonRegex : BsonToken
{
public BsonString Pattern { get; set; }
public BsonString Options { get; set; }
public BsonRegex(string pattern, string options)
{
Pattern = new BsonString(pattern, false);
Options = new BsonString(options, false);
}
public override BsonType Type => BsonType.Regex;
}
internal class BsonProperty
{
public BsonString Name { get; set; }
public BsonToken Value { get; set; }
}
}

View File

@@ -0,0 +1,64 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
namespace RRQMCore.XREF.Newtonsoft.Json.Bson
{
internal enum BsonType : sbyte
{
Number = 1,
String = 2,
Object = 3,
Array = 4,
Binary = 5,
Undefined = 6,
Oid = 7,
Boolean = 8,
Date = 9,
Null = 10,
Regex = 11,
Reference = 12,
Code = 13,
Symbol = 14,
CodeWScope = 15,
Integer = 16,
TimeStamp = 17,
Long = 18,
MinKey = -1,
MaxKey = 127
}
}

View File

@@ -0,0 +1,551 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System;
using System.IO;
#if HAVE_BIG_INTEGER
using System.Numerics;
#endif
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
using System.Globalization;
namespace RRQMCore.XREF.Newtonsoft.Json.Bson
{
/// <summary>
/// Represents a writer that provides a fast, non-cached, forward-only way of generating BSON data.
/// </summary>
[Obsolete("BSON reading and writing has been moved to its own package. See https://www.nuget.org/packages/RRQMCore.XREF.Newtonsoft.Json.Bson for more details.")]
public class BsonWriter : JsonWriter
{
private readonly BsonBinaryWriter _writer;
private BsonToken _root;
private BsonToken _parent;
private string _propertyName;
/// <summary>
/// Gets or sets the <see cref="DateTimeKind" /> used when writing <see cref="DateTime"/> values to BSON.
/// When set to <see cref="DateTimeKind.Unspecified" /> no conversion will occur.
/// </summary>
/// <value>The <see cref="DateTimeKind" /> used when writing <see cref="DateTime"/> values to BSON.</value>
public DateTimeKind DateTimeKindHandling
{
get => _writer.DateTimeKindHandling;
set => _writer.DateTimeKindHandling = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="BsonWriter"/> class.
/// </summary>
/// <param name="stream">The <see cref="Stream"/> to write to.</param>
public BsonWriter(Stream stream)
{
ValidationUtils.ArgumentNotNull(stream, nameof(stream));
_writer = new BsonBinaryWriter(new BinaryWriter(stream));
}
/// <summary>
/// Initializes a new instance of the <see cref="BsonWriter"/> class.
/// </summary>
/// <param name="writer">The <see cref="BinaryWriter"/> to write to.</param>
public BsonWriter(BinaryWriter writer)
{
ValidationUtils.ArgumentNotNull(writer, nameof(writer));
_writer = new BsonBinaryWriter(writer);
}
/// <summary>
/// Flushes whatever is in the buffer to the underlying <see cref="Stream"/> and also flushes the underlying stream.
/// </summary>
public override void Flush()
{
_writer.Flush();
}
/// <summary>
/// Writes the end.
/// </summary>
/// <param name="token">The token.</param>
protected override void WriteEnd(JsonToken token)
{
base.WriteEnd(token);
RemoveParent();
if (Top == 0)
{
_writer.WriteToken(_root);
}
}
/// <summary>
/// Writes a comment <c>/*...*/</c> containing the specified text.
/// </summary>
/// <param name="text">Text to place inside the comment.</param>
public override void WriteComment(string text)
{
throw JsonWriterException.Create(this, "Cannot write JSON comment as BSON.", null);
}
/// <summary>
/// Writes the start of a constructor with the given name.
/// </summary>
/// <param name="name">The name of the constructor.</param>
public override void WriteStartConstructor(string name)
{
throw JsonWriterException.Create(this, "Cannot write JSON constructor as BSON.", null);
}
/// <summary>
/// Writes raw JSON.
/// </summary>
/// <param name="json">The raw JSON to write.</param>
public override void WriteRaw(string json)
{
throw JsonWriterException.Create(this, "Cannot write raw JSON as BSON.", null);
}
/// <summary>
/// Writes raw JSON where a value is expected and updates the writer's state.
/// </summary>
/// <param name="json">The raw JSON to write.</param>
public override void WriteRawValue(string json)
{
throw JsonWriterException.Create(this, "Cannot write raw JSON as BSON.", null);
}
/// <summary>
/// Writes the beginning of a JSON array.
/// </summary>
public override void WriteStartArray()
{
base.WriteStartArray();
AddParent(new BsonArray());
}
/// <summary>
/// Writes the beginning of a JSON object.
/// </summary>
public override void WriteStartObject()
{
base.WriteStartObject();
AddParent(new BsonObject());
}
/// <summary>
/// Writes the property name of a name/value pair on a JSON object.
/// </summary>
/// <param name="name">The name of the property.</param>
public override void WritePropertyName(string name)
{
base.WritePropertyName(name);
_propertyName = name;
}
/// <summary>
/// Closes this writer.
/// If <see cref="JsonWriter.CloseOutput"/> is set to <c>true</c>, the underlying <see cref="Stream"/> is also closed.
/// If <see cref="JsonWriter.AutoCompleteOnClose"/> is set to <c>true</c>, the JSON is auto-completed.
/// </summary>
public override void Close()
{
base.Close();
if (CloseOutput)
{
_writer?.Close();
}
}
private void AddParent(BsonToken container)
{
AddToken(container);
_parent = container;
}
private void RemoveParent()
{
_parent = _parent.Parent;
}
private void AddValue(object value, BsonType type)
{
AddToken(new BsonValue(value, type));
}
internal void AddToken(BsonToken token)
{
if (_parent != null)
{
BsonObject bo = _parent as BsonObject;
if (bo != null)
{
bo.Add(_propertyName, token);
_propertyName = null;
}
else
{
((BsonArray)_parent).Add(token);
}
}
else
{
if (token.Type != BsonType.Object && token.Type != BsonType.Array)
{
throw JsonWriterException.Create(this, "Error writing {0} value. BSON must start with an Object or Array.".FormatWith(CultureInfo.InvariantCulture, token.Type), null);
}
_parent = token;
_root = token;
}
}
#region WriteValue methods
/// <summary>
/// Writes a <see cref="Object"/> value.
/// An error will raised if the value cannot be written as a single JSON token.
/// </summary>
/// <param name="value">The <see cref="Object"/> value to write.</param>
public override void WriteValue(object value)
{
#if HAVE_BIG_INTEGER
if (value is BigInteger)
{
SetWriteState(JsonToken.Integer, null);
AddToken(new BsonBinary(((BigInteger)value).ToByteArray(), BsonBinaryType.Binary));
}
else
#endif
{
base.WriteValue(value);
}
}
/// <summary>
/// Writes a null value.
/// </summary>
public override void WriteNull()
{
base.WriteNull();
AddToken(BsonEmpty.Null);
}
/// <summary>
/// Writes an undefined value.
/// </summary>
public override void WriteUndefined()
{
base.WriteUndefined();
AddToken(BsonEmpty.Undefined);
}
/// <summary>
/// Writes a <see cref="String"/> value.
/// </summary>
/// <param name="value">The <see cref="String"/> value to write.</param>
public override void WriteValue(string value)
{
base.WriteValue(value);
AddToken(value == null ? BsonEmpty.Null : new BsonString(value, true));
}
/// <summary>
/// Writes a <see cref="Int32"/> value.
/// </summary>
/// <param name="value">The <see cref="Int32"/> value to write.</param>
public override void WriteValue(int value)
{
base.WriteValue(value);
AddValue(value, BsonType.Integer);
}
/// <summary>
/// Writes a <see cref="UInt32"/> value.
/// </summary>
/// <param name="value">The <see cref="UInt32"/> value to write.</param>
public override void WriteValue(uint value)
{
if (value > int.MaxValue)
{
throw JsonWriterException.Create(this, "Value is too large to fit in a signed 32 bit integer. BSON does not support unsigned values.", null);
}
base.WriteValue(value);
AddValue(value, BsonType.Integer);
}
/// <summary>
/// Writes a <see cref="Int64"/> value.
/// </summary>
/// <param name="value">The <see cref="Int64"/> value to write.</param>
public override void WriteValue(long value)
{
base.WriteValue(value);
AddValue(value, BsonType.Long);
}
/// <summary>
/// Writes a <see cref="UInt64"/> value.
/// </summary>
/// <param name="value">The <see cref="UInt64"/> value to write.</param>
public override void WriteValue(ulong value)
{
if (value > long.MaxValue)
{
throw JsonWriterException.Create(this, "Value is too large to fit in a signed 64 bit integer. BSON does not support unsigned values.", null);
}
base.WriteValue(value);
AddValue(value, BsonType.Long);
}
/// <summary>
/// Writes a <see cref="Single"/> value.
/// </summary>
/// <param name="value">The <see cref="Single"/> value to write.</param>
public override void WriteValue(float value)
{
base.WriteValue(value);
AddValue(value, BsonType.Number);
}
/// <summary>
/// Writes a <see cref="Double"/> value.
/// </summary>
/// <param name="value">The <see cref="Double"/> value to write.</param>
public override void WriteValue(double value)
{
base.WriteValue(value);
AddValue(value, BsonType.Number);
}
/// <summary>
/// Writes a <see cref="Boolean"/> value.
/// </summary>
/// <param name="value">The <see cref="Boolean"/> value to write.</param>
public override void WriteValue(bool value)
{
base.WriteValue(value);
AddToken(value ? BsonBoolean.True : BsonBoolean.False);
}
/// <summary>
/// Writes a <see cref="Int16"/> value.
/// </summary>
/// <param name="value">The <see cref="Int16"/> value to write.</param>
public override void WriteValue(short value)
{
base.WriteValue(value);
AddValue(value, BsonType.Integer);
}
/// <summary>
/// Writes a <see cref="UInt16"/> value.
/// </summary>
/// <param name="value">The <see cref="UInt16"/> value to write.</param>
public override void WriteValue(ushort value)
{
base.WriteValue(value);
AddValue(value, BsonType.Integer);
}
/// <summary>
/// Writes a <see cref="Char"/> value.
/// </summary>
/// <param name="value">The <see cref="Char"/> value to write.</param>
public override void WriteValue(char value)
{
base.WriteValue(value);
string s = null;
#if HAVE_CHAR_TO_STRING_WITH_CULTURE
s = value.ToString(CultureInfo.InvariantCulture);
#else
s = value.ToString();
#endif
AddToken(new BsonString(s, true));
}
/// <summary>
/// Writes a <see cref="Byte"/> value.
/// </summary>
/// <param name="value">The <see cref="Byte"/> value to write.</param>
public override void WriteValue(byte value)
{
base.WriteValue(value);
AddValue(value, BsonType.Integer);
}
/// <summary>
/// Writes a <see cref="SByte"/> value.
/// </summary>
/// <param name="value">The <see cref="SByte"/> value to write.</param>
public override void WriteValue(sbyte value)
{
base.WriteValue(value);
AddValue(value, BsonType.Integer);
}
/// <summary>
/// Writes a <see cref="Decimal"/> value.
/// </summary>
/// <param name="value">The <see cref="Decimal"/> value to write.</param>
public override void WriteValue(decimal value)
{
base.WriteValue(value);
AddValue(value, BsonType.Number);
}
/// <summary>
/// Writes a <see cref="DateTime"/> value.
/// </summary>
/// <param name="value">The <see cref="DateTime"/> value to write.</param>
public override void WriteValue(DateTime value)
{
base.WriteValue(value);
value = DateTimeUtils.EnsureDateTime(value, DateTimeZoneHandling);
AddValue(value, BsonType.Date);
}
#if HAVE_DATE_TIME_OFFSET
/// <summary>
/// Writes a <see cref="DateTimeOffset"/> value.
/// </summary>
/// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
public override void WriteValue(DateTimeOffset value)
{
base.WriteValue(value);
AddValue(value, BsonType.Date);
}
#endif
/// <summary>
/// Writes a <see cref="Byte"/>[] value.
/// </summary>
/// <param name="value">The <see cref="Byte"/>[] value to write.</param>
public override void WriteValue(byte[] value)
{
if (value == null)
{
WriteNull();
return;
}
base.WriteValue(value);
AddToken(new BsonBinary(value, BsonBinaryType.Binary));
}
/// <summary>
/// Writes a <see cref="Guid"/> value.
/// </summary>
/// <param name="value">The <see cref="Guid"/> value to write.</param>
public override void WriteValue(Guid value)
{
base.WriteValue(value);
AddToken(new BsonBinary(value.ToByteArray(), BsonBinaryType.Uuid));
}
/// <summary>
/// Writes a <see cref="TimeSpan"/> value.
/// </summary>
/// <param name="value">The <see cref="TimeSpan"/> value to write.</param>
public override void WriteValue(TimeSpan value)
{
base.WriteValue(value);
AddToken(new BsonString(value.ToString(), true));
}
/// <summary>
/// Writes a <see cref="Uri"/> value.
/// </summary>
/// <param name="value">The <see cref="Uri"/> value to write.</param>
public override void WriteValue(Uri value)
{
if (value == null)
{
WriteNull();
return;
}
base.WriteValue(value);
AddToken(new BsonString(value.ToString(), true));
}
#endregion WriteValue methods
/// <summary>
/// Writes a <see cref="Byte"/>[] value that represents a BSON object id.
/// </summary>
/// <param name="value">The Object ID value to write.</param>
public void WriteObjectId(byte[] value)
{
ValidationUtils.ArgumentNotNull(value, nameof(value));
if (value.Length != 12)
{
throw JsonWriterException.Create(this, "An object id must be 12 bytes", null);
}
// hack to update the writer state
SetWriteState(JsonToken.Undefined, null);
AddValue(value, BsonType.Oid);
}
/// <summary>
/// Writes a BSON regex.
/// </summary>
/// <param name="pattern">The regex pattern.</param>
/// <param name="options">The regex options.</param>
public void WriteRegex(string pattern, string options)
{
ValidationUtils.ArgumentNotNull(pattern, nameof(pattern));
// hack to update the writer state
SetWriteState(JsonToken.Undefined, null);
AddToken(new BsonRegex(pattern, options));
}
}
}

View File

@@ -0,0 +1,56 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Specifies how constructors are used when initializing objects during deserialization by the <see cref="JsonSerializer"/>.
/// </summary>
public enum ConstructorHandling
{
/// <summary>
/// First attempt to use the public default constructor, then fall back to a single parameterized constructor, then to the non-public default constructor.
/// </summary>
Default = 0,
/// <summary>
/// Json.NET will use a non-public default constructor before falling back to a parameterized constructor.
/// </summary>
AllowNonPublicDefaultConstructor = 1
}
}

View File

@@ -0,0 +1,224 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
#if HAVE_LINQ || HAVE_ADO_NET
using System;
using System.Globalization;
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
using System.Collections.Generic;
#if HAVE_ADO_NET
using System.Data.SqlTypes;
#endif
namespace RRQMCore.XREF.Newtonsoft.Json.Converters
{
/// <summary>
/// Converts a binary value to and from a base 64 string value.
/// </summary>
public class BinaryConverter : JsonConverter
{
#if HAVE_LINQ
private const string BinaryTypeName = "System.Data.Linq.Binary";
private const string BinaryToArrayName = "ToArray";
private static ReflectionObject _reflectionObject;
#endif
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
return;
}
byte[] data = GetByteArray(value);
writer.WriteValue(data);
}
private byte[] GetByteArray(object value)
{
#if HAVE_LINQ
if (value.GetType().FullName == BinaryTypeName)
{
EnsureReflectionObject(value.GetType());
return (byte[])_reflectionObject.GetValue(value, BinaryToArrayName);
}
#endif
#if HAVE_ADO_NET
if (value is SqlBinary binary)
{
return binary.Value;
}
#endif
throw new JsonSerializationException("Unexpected value type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
}
#if HAVE_LINQ
private static void EnsureReflectionObject(Type t)
{
if (_reflectionObject == null)
{
_reflectionObject = ReflectionObject.Create(t, t.GetConstructor(new[] { typeof(byte[]) }), BinaryToArrayName);
}
}
#endif
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
if (!ReflectionUtils.IsNullable(objectType))
{
throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
}
return null;
}
byte[] data;
if (reader.TokenType == JsonToken.StartArray)
{
data = ReadByteArray(reader);
}
else if (reader.TokenType == JsonToken.String)
{
// current token is already at base64 string
// unable to call ReadAsBytes so do it the old fashion way
string encodedData = reader.Value.ToString();
data = Convert.FromBase64String(encodedData);
}
else
{
throw JsonSerializationException.Create(reader, "Unexpected token parsing binary. Expected String or StartArray, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
Type t = (ReflectionUtils.IsNullableType(objectType))
? Nullable.GetUnderlyingType(objectType)
: objectType;
#if HAVE_LINQ
if (t.FullName == BinaryTypeName)
{
EnsureReflectionObject(t);
return _reflectionObject.Creator(data);
}
#endif
#if HAVE_ADO_NET
if (t == typeof(SqlBinary))
{
return new SqlBinary(data);
}
#endif
throw JsonSerializationException.Create(reader, "Unexpected object type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, objectType));
}
private byte[] ReadByteArray(JsonReader reader)
{
List<byte> byteList = new List<byte>();
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.Integer:
byteList.Add(Convert.ToByte(reader.Value, CultureInfo.InvariantCulture));
break;
case JsonToken.EndArray:
return byteList.ToArray();
case JsonToken.Comment:
// skip
break;
default:
throw JsonSerializationException.Create(reader, "Unexpected token when reading bytes: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
}
throw JsonSerializationException.Create(reader, "Unexpected end when reading bytes.");
}
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
#if HAVE_LINQ
if (objectType.FullName == BinaryTypeName)
{
return true;
}
#endif
#if HAVE_ADO_NET
if (objectType == typeof(SqlBinary) || objectType == typeof(SqlBinary?))
{
return true;
}
#endif
return false;
}
}
}
#endif

View File

@@ -0,0 +1,104 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using RRQMCore.XREF.Newtonsoft.Json.Bson;
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
using System;
using System.Globalization;
namespace RRQMCore.XREF.Newtonsoft.Json.Converters
{
/// <summary>
/// Converts a <see cref="BsonObjectId"/> to and from JSON and BSON.
/// </summary>
[Obsolete("BSON reading and writing has been moved to its own package. See https://www.nuget.org/packages/RRQMCore.XREF.Newtonsoft.Json.Bson for more details.")]
public class BsonObjectIdConverter : JsonConverter
{
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
BsonObjectId objectId = (BsonObjectId)value;
if (writer is BsonWriter bsonWriter)
{
bsonWriter.WriteObjectId(objectId.Value);
}
else
{
writer.WriteValue(objectId.Value);
}
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType != JsonToken.Bytes)
{
throw new JsonSerializationException("Expected Bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
byte[] value = (byte[])reader.Value;
return new BsonObjectId(value);
}
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(BsonObjectId));
}
}
}

View File

@@ -0,0 +1,112 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System;
namespace RRQMCore.XREF.Newtonsoft.Json.Converters
{
/// <summary>
/// Creates a custom object.
/// </summary>
/// <typeparam name="T">The object type to convert.</typeparam>
public abstract class CustomCreationConverter<T> : JsonConverter
{
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotSupportedException("CustomCreationConverter should only be used while deserializing.");
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
T value = Create(objectType);
if (value == null)
{
throw new JsonSerializationException("No object created.");
}
serializer.Populate(reader, value);
return value;
}
/// <summary>
/// Creates an object which will then be populated by the serializer.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>The created object.</returns>
public abstract T Create(Type objectType);
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
/// <summary>
/// Gets a value indicating whether this <see cref="JsonConverter"/> can write JSON.
/// </summary>
/// <value>
/// <c>true</c> if this <see cref="JsonConverter"/> can write JSON; otherwise, <c>false</c>.
/// </value>
public override bool CanWrite => false;
}
}

View File

@@ -0,0 +1,138 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
#if HAVE_ADO_NET
using System;
using System.Data;
using RRQMCore.XREF.Newtonsoft.Json.Serialization;
namespace RRQMCore.XREF.Newtonsoft.Json.Converters
{
/// <summary>
/// Converts a <see cref="DataSet"/> to and from JSON.
/// </summary>
public class DataSetConverter : JsonConverter
{
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
return;
}
DataSet dataSet = (DataSet)value;
DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver;
DataTableConverter converter = new DataTableConverter();
writer.WriteStartObject();
foreach (DataTable table in dataSet.Tables)
{
writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(table.TableName) : table.TableName);
converter.WriteJson(writer, table, serializer);
}
writer.WriteEndObject();
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
// handle typed datasets
DataSet ds = (objectType == typeof(DataSet))
? new DataSet()
: (DataSet)Activator.CreateInstance(objectType);
DataTableConverter converter = new DataTableConverter();
reader.ReadAndAssert();
while (reader.TokenType == JsonToken.PropertyName)
{
DataTable dt = ds.Tables[(string)reader.Value];
bool exists = (dt != null);
dt = (DataTable)converter.ReadJson(reader, typeof(DataTable), dt, serializer);
if (!exists)
{
ds.Tables.Add(dt);
}
reader.ReadAndAssert();
}
return ds;
}
/// <summary>
/// Determines whether this instance can convert the specified value type.
/// </summary>
/// <param name="valueType">Type of the value.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type valueType)
{
return typeof(DataSet).IsAssignableFrom(valueType);
}
}
}
#endif

View File

@@ -0,0 +1,269 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
#if HAVE_ADO_NET
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
using System;
using System.Data;
using RRQMCore.XREF.Newtonsoft.Json.Serialization;
namespace RRQMCore.XREF.Newtonsoft.Json.Converters
{
/// <summary>
/// Converts a <see cref="DataTable"/> to and from JSON.
/// </summary>
public class DataTableConverter : JsonConverter
{
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
return;
}
DataTable table = (DataTable)value;
DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver;
writer.WriteStartArray();
foreach (DataRow row in table.Rows)
{
writer.WriteStartObject();
foreach (DataColumn column in row.Table.Columns)
{
object columnValue = row[column];
if (serializer.NullValueHandling == NullValueHandling.Ignore && (columnValue == null || columnValue == DBNull.Value))
{
continue;
}
writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(column.ColumnName) : column.ColumnName);
serializer.Serialize(writer, columnValue);
}
writer.WriteEndObject();
}
writer.WriteEndArray();
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
if (!(existingValue is DataTable dt))
{
// handle typed datasets
dt = (objectType == typeof(DataTable))
? new DataTable()
: (DataTable)Activator.CreateInstance(objectType);
}
// DataTable is inside a DataSet
// populate the name from the property name
if (reader.TokenType == JsonToken.PropertyName)
{
dt.TableName = (string)reader.Value;
reader.ReadAndAssert();
if (reader.TokenType == JsonToken.Null)
{
return dt;
}
}
if (reader.TokenType != JsonToken.StartArray)
{
throw JsonSerializationException.Create(reader, "Unexpected JSON token when reading DataTable. Expected StartArray, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
reader.ReadAndAssert();
while (reader.TokenType != JsonToken.EndArray)
{
CreateRow(reader, dt, serializer);
reader.ReadAndAssert();
}
return dt;
}
private static void CreateRow(JsonReader reader, DataTable dt, JsonSerializer serializer)
{
DataRow dr = dt.NewRow();
reader.ReadAndAssert();
while (reader.TokenType == JsonToken.PropertyName)
{
string columnName = (string)reader.Value;
reader.ReadAndAssert();
DataColumn column = dt.Columns[columnName];
if (column == null)
{
Type columnType = GetColumnDataType(reader);
column = new DataColumn(columnName, columnType);
dt.Columns.Add(column);
}
if (column.DataType == typeof(DataTable))
{
if (reader.TokenType == JsonToken.StartArray)
{
reader.ReadAndAssert();
}
DataTable nestedDt = new DataTable();
while (reader.TokenType != JsonToken.EndArray)
{
CreateRow(reader, nestedDt, serializer);
reader.ReadAndAssert();
}
dr[columnName] = nestedDt;
}
else if (column.DataType.IsArray && column.DataType != typeof(byte[]))
{
if (reader.TokenType == JsonToken.StartArray)
{
reader.ReadAndAssert();
}
List<object> o = new List<object>();
while (reader.TokenType != JsonToken.EndArray)
{
o.Add(reader.Value);
reader.ReadAndAssert();
}
Array destinationArray = Array.CreateInstance(column.DataType.GetElementType(), o.Count);
((IList)o).CopyTo(destinationArray, 0);
dr[columnName] = destinationArray;
}
else
{
object columnValue = (reader.Value != null)
? serializer.Deserialize(reader, column.DataType) ?? DBNull.Value
: DBNull.Value;
dr[columnName] = columnValue;
}
reader.ReadAndAssert();
}
dr.EndEdit();
dt.Rows.Add(dr);
}
private static Type GetColumnDataType(JsonReader reader)
{
JsonToken tokenType = reader.TokenType;
switch (tokenType)
{
case JsonToken.Integer:
case JsonToken.Boolean:
case JsonToken.Float:
case JsonToken.String:
case JsonToken.Date:
case JsonToken.Bytes:
return reader.ValueType;
case JsonToken.Null:
case JsonToken.Undefined:
return typeof(string);
case JsonToken.StartArray:
reader.ReadAndAssert();
if (reader.TokenType == JsonToken.StartObject)
{
return typeof(DataTable); // nested datatable
}
Type arrayType = GetColumnDataType(reader);
return arrayType.MakeArrayType();
default:
throw JsonSerializationException.Create(reader, "Unexpected JSON token when reading DataTable: {0}".FormatWith(CultureInfo.InvariantCulture, tokenType));
}
}
/// <summary>
/// Determines whether this instance can convert the specified value type.
/// </summary>
/// <param name="valueType">Type of the value.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type valueType)
{
return typeof(DataTable).IsAssignableFrom(valueType);
}
}
}
#endif

View File

@@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System;
namespace RRQMCore.XREF.Newtonsoft.Json.Converters
{
/// <summary>
/// Provides a base class for converting a <see cref="DateTime"/> to and from JSON.
/// </summary>
public abstract class DateTimeConverterBase : JsonConverter
{
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
if (objectType == typeof(DateTime) || objectType == typeof(DateTime?))
{
return true;
}
#if HAVE_DATE_TIME_OFFSET
if (objectType == typeof(DateTimeOffset) || objectType == typeof(DateTimeOffset?))
{
return true;
}
#endif
return false;
}
}
}

View File

@@ -0,0 +1,295 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
#if HAVE_FSHARP_TYPES
using RRQMCore.XREF.Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
#if !HAVE_LINQ
using RRQMCore.XREF.Newtonsoft.Json.Utilities.LinqBridge;
#else
using System.Linq;
#endif
using System.Reflection;
using RRQMCore.XREF.Newtonsoft.Json.Serialization;
using System.Globalization;
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
namespace RRQMCore.XREF.Newtonsoft.Json.Converters
{
/// <summary>
/// Converts a F# discriminated union type to and from JSON.
/// </summary>
public class DiscriminatedUnionConverter : JsonConverter
{
#region UnionDefinition
internal class Union
{
public List<UnionCase> Cases;
public FSharpFunction TagReader { get; set; }
}
internal class UnionCase
{
public int Tag;
public string Name;
public PropertyInfo[] Fields;
public FSharpFunction FieldReader;
public FSharpFunction Constructor;
}
#endregion UnionDefinition
private const string CasePropertyName = "Case";
private const string FieldsPropertyName = "Fields";
private static readonly ThreadSafeStore<Type, Union> UnionCache = new ThreadSafeStore<Type, Union>(CreateUnion);
private static readonly ThreadSafeStore<Type, Type> UnionTypeLookupCache = new ThreadSafeStore<Type, Type>(CreateUnionTypeLookup);
private static Type CreateUnionTypeLookup(Type t)
{
// this lookup is because cases with fields are derived from union type
// need to get declaring type to avoid duplicate Unions in cache
// hacky but I can't find an API to get the declaring type without GetUnionCases
object[] cases = (object[])FSharpUtils.GetUnionCases(null, t, null);
object caseInfo = cases.First();
Type unionType = (Type)FSharpUtils.GetUnionCaseInfoDeclaringType(caseInfo);
return unionType;
}
private static Union CreateUnion(Type t)
{
Union u = new Union();
u.TagReader = (FSharpFunction)FSharpUtils.PreComputeUnionTagReader(null, t, null);
u.Cases = new List<UnionCase>();
object[] cases = (object[])FSharpUtils.GetUnionCases(null, t, null);
foreach (object unionCaseInfo in cases)
{
UnionCase unionCase = new UnionCase();
unionCase.Tag = (int)FSharpUtils.GetUnionCaseInfoTag(unionCaseInfo);
unionCase.Name = (string)FSharpUtils.GetUnionCaseInfoName(unionCaseInfo);
unionCase.Fields = (PropertyInfo[])FSharpUtils.GetUnionCaseInfoFields(unionCaseInfo);
unionCase.FieldReader = (FSharpFunction)FSharpUtils.PreComputeUnionReader(null, unionCaseInfo, null);
unionCase.Constructor = (FSharpFunction)FSharpUtils.PreComputeUnionConstructor(null, unionCaseInfo, null);
u.Cases.Add(unionCase);
}
return u;
}
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver;
Type unionType = UnionTypeLookupCache.Get(value.GetType());
Union union = UnionCache.Get(unionType);
int tag = (int)union.TagReader.Invoke(value);
UnionCase caseInfo = union.Cases.Single(c => c.Tag == tag);
writer.WriteStartObject();
writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(CasePropertyName) : CasePropertyName);
writer.WriteValue(caseInfo.Name);
if (caseInfo.Fields != null && caseInfo.Fields.Length > 0)
{
object[] fields = (object[])caseInfo.FieldReader.Invoke(value);
writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(FieldsPropertyName) : FieldsPropertyName);
writer.WriteStartArray();
foreach (object field in fields)
{
serializer.Serialize(writer, field);
}
writer.WriteEndArray();
}
writer.WriteEndObject();
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
UnionCase caseInfo = null;
string caseName = null;
JArray fields = null;
// start object
reader.ReadAndAssert();
while (reader.TokenType == JsonToken.PropertyName)
{
string propertyName = reader.Value.ToString();
if (string.Equals(propertyName, CasePropertyName, StringComparison.OrdinalIgnoreCase))
{
reader.ReadAndAssert();
Union union = UnionCache.Get(objectType);
caseName = reader.Value.ToString();
caseInfo = union.Cases.SingleOrDefault(c => c.Name == caseName);
if (caseInfo == null)
{
throw JsonSerializationException.Create(reader, "No union type found with the name '{0}'.".FormatWith(CultureInfo.InvariantCulture, caseName));
}
}
else if (string.Equals(propertyName, FieldsPropertyName, StringComparison.OrdinalIgnoreCase))
{
reader.ReadAndAssert();
if (reader.TokenType != JsonToken.StartArray)
{
throw JsonSerializationException.Create(reader, "Union fields must been an array.");
}
fields = (JArray)JToken.ReadFrom(reader);
}
else
{
throw JsonSerializationException.Create(reader, "Unexpected property '{0}' found when reading union.".FormatWith(CultureInfo.InvariantCulture, propertyName));
}
reader.ReadAndAssert();
}
if (caseInfo == null)
{
throw JsonSerializationException.Create(reader, "No '{0}' property with union name found.".FormatWith(CultureInfo.InvariantCulture, CasePropertyName));
}
object[] typedFieldValues = new object[caseInfo.Fields.Length];
if (caseInfo.Fields.Length > 0 && fields == null)
{
throw JsonSerializationException.Create(reader, "No '{0}' property with union fields found.".FormatWith(CultureInfo.InvariantCulture, FieldsPropertyName));
}
if (fields != null)
{
if (caseInfo.Fields.Length != fields.Count)
{
throw JsonSerializationException.Create(reader, "The number of field values does not match the number of properties defined by union '{0}'.".FormatWith(CultureInfo.InvariantCulture, caseName));
}
for (int i = 0; i < fields.Count; i++)
{
JToken t = fields[i];
PropertyInfo fieldProperty = caseInfo.Fields[i];
typedFieldValues[i] = t.ToObject(fieldProperty.PropertyType, serializer);
}
}
object[] args = { typedFieldValues };
return caseInfo.Constructor.Invoke(args);
}
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
if (typeof(IEnumerable).IsAssignableFrom(objectType))
{
return false;
}
// all fsharp objects have CompilationMappingAttribute
// get the fsharp assembly from the attribute and initialize latebound methods
object[] attributes;
#if HAVE_FULL_REFLECTION
attributes = objectType.GetCustomAttributes(true);
#else
attributes = objectType.GetTypeInfo().GetCustomAttributes(true).ToArray();
#endif
bool isFSharpType = false;
foreach (object attribute in attributes)
{
Type attributeType = attribute.GetType();
if (attributeType.FullName == "Microsoft.FSharp.Core.CompilationMappingAttribute")
{
FSharpUtils.EnsureInitialized(attributeType.Assembly());
isFSharpType = true;
break;
}
}
if (!isFSharpType)
{
return false;
}
return (bool)FSharpUtils.IsUnion(null, objectType, null);
}
}
}
#endif

View File

@@ -0,0 +1,169 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
#if HAVE_ENTITY_FRAMEWORK
using System;
using RRQMCore.XREF.Newtonsoft.Json.Serialization;
using System.Globalization;
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
namespace RRQMCore.XREF.Newtonsoft.Json.Converters
{
/// <summary>
/// Converts an Entity Framework <see cref="T:System.Data.EntityKeyMember"/> to and from JSON.
/// </summary>
public class EntityKeyMemberConverter : JsonConverter
{
private const string EntityKeyMemberFullTypeName = "System.Data.EntityKeyMember";
private const string KeyPropertyName = "Key";
private const string TypePropertyName = "Type";
private const string ValuePropertyName = "Value";
private static ReflectionObject _reflectionObject;
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
EnsureReflectionObject(value.GetType());
DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver;
string keyName = (string)_reflectionObject.GetValue(value, KeyPropertyName);
object keyValue = _reflectionObject.GetValue(value, ValuePropertyName);
Type keyValueType = keyValue?.GetType();
writer.WriteStartObject();
writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(KeyPropertyName) : KeyPropertyName);
writer.WriteValue(keyName);
writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(TypePropertyName) : TypePropertyName);
writer.WriteValue(keyValueType?.FullName);
writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(ValuePropertyName) : ValuePropertyName);
if (keyValueType != null)
{
if (JsonSerializerInternalWriter.TryConvertToString(keyValue, keyValueType, out string valueJson))
{
writer.WriteValue(valueJson);
}
else
{
writer.WriteValue(keyValue);
}
}
else
{
writer.WriteNull();
}
writer.WriteEndObject();
}
private static void ReadAndAssertProperty(JsonReader reader, string propertyName)
{
reader.ReadAndAssert();
if (reader.TokenType != JsonToken.PropertyName || !string.Equals(reader.Value.ToString(), propertyName, StringComparison.OrdinalIgnoreCase))
{
throw new JsonSerializationException("Expected JSON property '{0}'.".FormatWith(CultureInfo.InvariantCulture, propertyName));
}
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
EnsureReflectionObject(objectType);
object entityKeyMember = _reflectionObject.Creator();
ReadAndAssertProperty(reader, KeyPropertyName);
reader.ReadAndAssert();
_reflectionObject.SetValue(entityKeyMember, KeyPropertyName, reader.Value.ToString());
ReadAndAssertProperty(reader, TypePropertyName);
reader.ReadAndAssert();
string type = reader.Value.ToString();
Type t = Type.GetType(type);
ReadAndAssertProperty(reader, ValuePropertyName);
reader.ReadAndAssert();
_reflectionObject.SetValue(entityKeyMember, ValuePropertyName, serializer.Deserialize(reader, t));
reader.ReadAndAssert();
return entityKeyMember;
}
private static void EnsureReflectionObject(Type objectType)
{
if (_reflectionObject == null)
{
_reflectionObject = ReflectionObject.Create(objectType, KeyPropertyName, ValuePropertyName);
}
}
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
return objectType.AssignableToTypeName(EntityKeyMemberFullTypeName, false);
}
}
}
#endif

View File

@@ -0,0 +1,187 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
#if HAVE_DYNAMIC
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Globalization;
using System.Linq;
using System.Text;
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
namespace RRQMCore.XREF.Newtonsoft.Json.Converters
{
/// <summary>
/// Converts an <see cref="ExpandoObject"/> to and from JSON.
/// </summary>
public class ExpandoObjectConverter : JsonConverter
{
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
// can write is set to false
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return ReadValue(reader);
}
private object ReadValue(JsonReader reader)
{
if (!reader.MoveToContent())
{
throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject.");
}
switch (reader.TokenType)
{
case JsonToken.StartObject:
return ReadObject(reader);
case JsonToken.StartArray:
return ReadList(reader);
default:
if (JsonTokenUtils.IsPrimitiveToken(reader.TokenType))
{
return reader.Value;
}
throw JsonSerializationException.Create(reader, "Unexpected token when converting ExpandoObject: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
}
private object ReadList(JsonReader reader)
{
IList<object> list = new List<object>();
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.Comment:
break;
default:
object v = ReadValue(reader);
list.Add(v);
break;
case JsonToken.EndArray:
return list;
}
}
throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject.");
}
private object ReadObject(JsonReader reader)
{
IDictionary<string, object> expandoObject = new ExpandoObject();
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.PropertyName:
string propertyName = reader.Value.ToString();
if (!reader.Read())
{
throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject.");
}
object v = ReadValue(reader);
expandoObject[propertyName] = v;
break;
case JsonToken.Comment:
break;
case JsonToken.EndObject:
return expandoObject;
}
}
throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject.");
}
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(ExpandoObject));
}
/// <summary>
/// Gets a value indicating whether this <see cref="JsonConverter"/> can write JSON.
/// </summary>
/// <value>
/// <c>true</c> if this <see cref="JsonConverter"/> can write JSON; otherwise, <c>false</c>.
/// </value>
public override bool CanWrite
{
get { return false; }
}
}
}
#endif

View File

@@ -0,0 +1,207 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
using System;
using System.Globalization;
namespace RRQMCore.XREF.Newtonsoft.Json.Converters
{
/// <summary>
/// Converts a <see cref="DateTime"/> to and from the ISO 8601 date format (e.g. <c>"2008-04-12T12:53Z"</c>).
/// </summary>
public class IsoDateTimeConverter : DateTimeConverterBase
{
private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind;
private string _dateTimeFormat;
private CultureInfo _culture;
/// <summary>
/// Gets or sets the date time styles used when converting a date to and from JSON.
/// </summary>
/// <value>The date time styles used when converting a date to and from JSON.</value>
public DateTimeStyles DateTimeStyles
{
get => _dateTimeStyles;
set => _dateTimeStyles = value;
}
/// <summary>
/// Gets or sets the date time format used when converting a date to and from JSON.
/// </summary>
/// <value>The date time format used when converting a date to and from JSON.</value>
public string DateTimeFormat
{
get => _dateTimeFormat ?? string.Empty;
set => _dateTimeFormat = (string.IsNullOrEmpty(value)) ? null : value;
}
/// <summary>
/// Gets or sets the culture used when converting a date to and from JSON.
/// </summary>
/// <value>The culture used when converting a date to and from JSON.</value>
public CultureInfo Culture
{
get => _culture ?? CultureInfo.CurrentCulture;
set => _culture = value;
}
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
string text;
if (value is DateTime dateTime)
{
if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
|| (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
{
dateTime = dateTime.ToUniversalTime();
}
text = dateTime.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
}
#if HAVE_DATE_TIME_OFFSET
else if (value is DateTimeOffset dateTimeOffset)
{
if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
|| (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
{
dateTimeOffset = dateTimeOffset.ToUniversalTime();
}
text = dateTimeOffset.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
}
#endif
else
{
throw new JsonSerializationException("Unexpected value when converting date. Expected DateTime or DateTimeOffset, got {0}.".FormatWith(CultureInfo.InvariantCulture, ReflectionUtils.GetObjectType(value)));
}
writer.WriteValue(text);
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
bool nullable = ReflectionUtils.IsNullableType(objectType);
if (reader.TokenType == JsonToken.Null)
{
if (!nullable)
{
throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
}
return null;
}
#if HAVE_DATE_TIME_OFFSET
Type t = (nullable)
? Nullable.GetUnderlyingType(objectType)
: objectType;
#endif
if (reader.TokenType == JsonToken.Date)
{
#if HAVE_DATE_TIME_OFFSET
if (t == typeof(DateTimeOffset))
{
return (reader.Value is DateTimeOffset) ? reader.Value : new DateTimeOffset((DateTime)reader.Value);
}
// converter is expected to return a DateTime
if (reader.Value is DateTimeOffset offset)
{
return offset.DateTime;
}
#endif
return reader.Value;
}
if (reader.TokenType != JsonToken.String)
{
throw JsonSerializationException.Create(reader, "Unexpected token parsing date. Expected String, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
string dateText = reader.Value.ToString();
if (string.IsNullOrEmpty(dateText) && nullable)
{
return null;
}
#if HAVE_DATE_TIME_OFFSET
if (t == typeof(DateTimeOffset))
{
if (!string.IsNullOrEmpty(_dateTimeFormat))
{
return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
}
else
{
return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles);
}
}
#endif
if (!string.IsNullOrEmpty(_dateTimeFormat))
{
return DateTime.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
}
else
{
return DateTime.Parse(dateText, Culture, _dateTimeStyles);
}
}
}
}

View File

@@ -0,0 +1,137 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
using System;
using System.Globalization;
namespace RRQMCore.XREF.Newtonsoft.Json.Converters
{
/// <summary>
/// Converts a <see cref="DateTime"/> to and from a JavaScript <c>Date</c> constructor (e.g. <c>new Date(52231943)</c>).
/// </summary>
public class JavaScriptDateTimeConverter : DateTimeConverterBase
{
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
long ticks;
if (value is DateTime dateTime)
{
DateTime utcDateTime = dateTime.ToUniversalTime();
ticks = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(utcDateTime);
}
#if HAVE_DATE_TIME_OFFSET
else if (value is DateTimeOffset dateTimeOffset)
{
DateTimeOffset utcDateTimeOffset = dateTimeOffset.ToUniversalTime();
ticks = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(utcDateTimeOffset.UtcDateTime);
}
#endif
else
{
throw new JsonSerializationException("Expected date object value.");
}
writer.WriteStartConstructor("Date");
writer.WriteValue(ticks);
writer.WriteEndConstructor();
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing property value of the JSON that is being converted.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
if (!ReflectionUtils.IsNullable(objectType))
{
throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
}
return null;
}
if (reader.TokenType != JsonToken.StartConstructor || !string.Equals(reader.Value.ToString(), "Date", StringComparison.Ordinal))
{
throw JsonSerializationException.Create(reader, "Unexpected token or value when parsing date. Token: {0}, Value: {1}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType, reader.Value));
}
reader.Read();
if (reader.TokenType != JsonToken.Integer)
{
throw JsonSerializationException.Create(reader, "Unexpected token parsing date. Expected Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
long ticks = (long)reader.Value;
DateTime d = DateTimeUtils.ConvertJavaScriptTicksToDateTime(ticks);
reader.Read();
if (reader.TokenType != JsonToken.EndConstructor)
{
throw JsonSerializationException.Create(reader, "Unexpected token parsing date. Expected EndConstructor, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
#if HAVE_DATE_TIME_OFFSET
Type t = (ReflectionUtils.IsNullableType(objectType))
? Nullable.GetUnderlyingType(objectType)
: objectType;
if (t == typeof(DateTimeOffset))
{
return new DateTimeOffset(d);
}
#endif
return d;
}
}
}

View File

@@ -0,0 +1,165 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using RRQMCore.XREF.Newtonsoft.Json.Serialization;
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
using System;
using System.Collections.Generic;
namespace RRQMCore.XREF.Newtonsoft.Json.Converters
{
/// <summary>
/// Converts a <see cref="KeyValuePair{TKey,TValue}"/> to and from JSON.
/// </summary>
public class KeyValuePairConverter : JsonConverter
{
private const string KeyName = "Key";
private const string ValueName = "Value";
private static readonly ThreadSafeStore<Type, ReflectionObject> ReflectionObjectPerType = new ThreadSafeStore<Type, ReflectionObject>(InitializeReflectionObject);
private static ReflectionObject InitializeReflectionObject(Type t)
{
IList<Type> genericArguments = t.GetGenericArguments();
Type keyType = genericArguments[0];
Type valueType = genericArguments[1];
return ReflectionObject.Create(t, t.GetConstructor(new[] { keyType, valueType }), KeyName, ValueName);
}
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
ReflectionObject reflectionObject = ReflectionObjectPerType.Get(value.GetType());
DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver;
writer.WriteStartObject();
writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(KeyName) : KeyName);
serializer.Serialize(writer, reflectionObject.GetValue(value, KeyName), reflectionObject.GetType(KeyName));
writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(ValueName) : ValueName);
serializer.Serialize(writer, reflectionObject.GetValue(value, ValueName), reflectionObject.GetType(ValueName));
writer.WriteEndObject();
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
if (!ReflectionUtils.IsNullableType(objectType))
{
throw JsonSerializationException.Create(reader, "Cannot convert null value to KeyValuePair.");
}
return null;
}
object key = null;
object value = null;
reader.ReadAndAssert();
Type t = ReflectionUtils.IsNullableType(objectType)
? Nullable.GetUnderlyingType(objectType)
: objectType;
ReflectionObject reflectionObject = ReflectionObjectPerType.Get(t);
JsonContract keyContract = serializer.ContractResolver.ResolveContract(reflectionObject.GetType(KeyName));
JsonContract valueContract = serializer.ContractResolver.ResolveContract(reflectionObject.GetType(ValueName));
while (reader.TokenType == JsonToken.PropertyName)
{
string propertyName = reader.Value.ToString();
if (string.Equals(propertyName, KeyName, StringComparison.OrdinalIgnoreCase))
{
reader.ReadForTypeAndAssert(keyContract, false);
key = serializer.Deserialize(reader, keyContract.UnderlyingType);
}
else if (string.Equals(propertyName, ValueName, StringComparison.OrdinalIgnoreCase))
{
reader.ReadForTypeAndAssert(valueContract, false);
value = serializer.Deserialize(reader, valueContract.UnderlyingType);
}
else
{
reader.Skip();
}
reader.ReadAndAssert();
}
return reflectionObject.Creator(key, value);
}
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
Type t = (ReflectionUtils.IsNullableType(objectType))
? Nullable.GetUnderlyingType(objectType)
: objectType;
if (t.IsValueType() && t.IsGenericType())
{
return (t.GetGenericTypeDefinition() == typeof(KeyValuePair<,>));
}
return false;
}
}
}

View File

@@ -0,0 +1,253 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using RRQMCore.XREF.Newtonsoft.Json.Bson;
using RRQMCore.XREF.Newtonsoft.Json.Serialization;
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
using System;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
namespace RRQMCore.XREF.Newtonsoft.Json.Converters
{
/// <summary>
/// Converts a <see cref="Regex"/> to and from JSON and BSON.
/// </summary>
public class RegexConverter : JsonConverter
{
private const string PatternName = "Pattern";
private const string OptionsName = "Options";
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
return;
}
Regex regex = (Regex)value;
#pragma warning disable 618
if (writer is BsonWriter bsonWriter)
{
WriteBson(bsonWriter, regex);
}
#pragma warning restore 618
else
{
WriteJson(writer, regex, serializer);
}
}
private bool HasFlag(RegexOptions options, RegexOptions flag)
{
return ((options & flag) == flag);
}
#pragma warning disable 618
private void WriteBson(BsonWriter writer, Regex regex)
{
// Regular expression - The first cstring is the regex pattern, the second
// is the regex options string. Options are identified by characters, which
// must be stored in alphabetical order. Valid options are 'i' for case
// insensitive matching, 'm' for multiline matching, 'x' for verbose mode,
// 'l' to make \w, \W, etc. locale dependent, 's' for dotall mode
// ('.' matches everything), and 'u' to make \w, \W, etc. match unicode.
string options = null;
if (HasFlag(regex.Options, RegexOptions.IgnoreCase))
{
options += "i";
}
if (HasFlag(regex.Options, RegexOptions.Multiline))
{
options += "m";
}
if (HasFlag(regex.Options, RegexOptions.Singleline))
{
options += "s";
}
options += "u";
if (HasFlag(regex.Options, RegexOptions.ExplicitCapture))
{
options += "x";
}
writer.WriteRegex(regex.ToString(), options);
}
#pragma warning restore 618
private void WriteJson(JsonWriter writer, Regex regex, JsonSerializer serializer)
{
DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver;
writer.WriteStartObject();
writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(PatternName) : PatternName);
writer.WriteValue(regex.ToString());
writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(OptionsName) : OptionsName);
serializer.Serialize(writer, regex.Options);
writer.WriteEndObject();
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.StartObject:
return ReadRegexObject(reader, serializer);
case JsonToken.String:
return ReadRegexString(reader);
case JsonToken.Null:
return null;
}
throw JsonSerializationException.Create(reader, "Unexpected token when reading Regex.");
}
private object ReadRegexString(JsonReader reader)
{
string regexText = (string)reader.Value;
if (regexText.Length > 0 && regexText[0] == '/')
{
int patternOptionDelimiterIndex = regexText.LastIndexOf('/');
if (patternOptionDelimiterIndex > 0)
{
string patternText = regexText.Substring(1, patternOptionDelimiterIndex - 1);
string optionsText = regexText.Substring(patternOptionDelimiterIndex + 1);
RegexOptions options = MiscellaneousUtils.GetRegexOptions(optionsText);
return new Regex(patternText, options);
}
}
throw JsonSerializationException.Create(reader, "Regex pattern must be enclosed by slashes.");
}
private Regex ReadRegexObject(JsonReader reader, JsonSerializer serializer)
{
string pattern = null;
RegexOptions? options = null;
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.PropertyName:
string propertyName = reader.Value.ToString();
if (!reader.Read())
{
throw JsonSerializationException.Create(reader, "Unexpected end when reading Regex.");
}
if (string.Equals(propertyName, PatternName, StringComparison.OrdinalIgnoreCase))
{
pattern = (string)reader.Value;
}
else if (string.Equals(propertyName, OptionsName, StringComparison.OrdinalIgnoreCase))
{
options = serializer.Deserialize<RegexOptions>(reader);
}
else
{
reader.Skip();
}
break;
case JsonToken.Comment:
break;
case JsonToken.EndObject:
if (pattern == null)
{
throw JsonSerializationException.Create(reader, "Error deserializing Regex. No pattern found.");
}
return new Regex(pattern, options ?? RegexOptions.None);
}
}
throw JsonSerializationException.Create(reader, "Unexpected end when reading Regex.");
}
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
return objectType.Name == nameof(Regex) && IsRegex(objectType);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private bool IsRegex(Type objectType)
{
return (objectType == typeof(Regex));
}
}
}

View File

@@ -0,0 +1,192 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
using System;
using System.Globalization;
#if !HAVE_LINQ
#else
using System.Linq;
#endif
namespace RRQMCore.XREF.Newtonsoft.Json.Converters
{
/// <summary>
/// Converts an <see cref="Enum"/> to and from its name string value.
/// </summary>
public class StringEnumConverter : JsonConverter
{
/// <summary>
/// Gets or sets a value indicating whether the written enum text should be camel case.
/// The default value is <c>false</c>.
/// </summary>
/// <value><c>true</c> if the written enum text will be camel case; otherwise, <c>false</c>.</value>
public bool CamelCaseText { get; set; }
/// <summary>
/// Gets or sets a value indicating whether integer values are allowed when deserializing.
/// The default value is <c>true</c>.
/// </summary>
/// <value><c>true</c> if integers are allowed when deserializing; otherwise, <c>false</c>.</value>
public bool AllowIntegerValues { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="StringEnumConverter"/> class.
/// </summary>
public StringEnumConverter()
{
AllowIntegerValues = true;
}
/// <summary>
/// Initializes a new instance of the <see cref="StringEnumConverter"/> class.
/// </summary>
/// <param name="camelCaseText"><c>true</c> if the written enum text will be camel case; otherwise, <c>false</c>.</param>
public StringEnumConverter(bool camelCaseText)
: this()
{
CamelCaseText = camelCaseText;
}
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
return;
}
Enum e = (Enum)value;
if (!EnumUtils.TryToString(e.GetType(), value, CamelCaseText, out string enumName))
{
if (!AllowIntegerValues)
{
throw JsonSerializationException.Create(null, writer.ContainerPath, "Integer value {0} is not allowed.".FormatWith(CultureInfo.InvariantCulture, e.ToString("D")), null);
}
// enum value has no name so write number
writer.WriteValue(value);
}
else
{
writer.WriteValue(enumName);
}
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
if (!ReflectionUtils.IsNullableType(objectType))
{
throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
}
return null;
}
bool isNullable = ReflectionUtils.IsNullableType(objectType);
Type t = isNullable ? Nullable.GetUnderlyingType(objectType) : objectType;
try
{
if (reader.TokenType == JsonToken.String)
{
string enumText = reader.Value.ToString();
if (enumText == string.Empty && isNullable)
{
return null;
}
return EnumUtils.ParseEnum(t, enumText, !AllowIntegerValues);
}
if (reader.TokenType == JsonToken.Integer)
{
if (!AllowIntegerValues)
{
throw JsonSerializationException.Create(reader, "Integer value {0} is not allowed.".FormatWith(CultureInfo.InvariantCulture, reader.Value));
}
return ConvertUtils.ConvertOrCast(reader.Value, CultureInfo.InvariantCulture, t);
}
}
catch (Exception ex)
{
throw JsonSerializationException.Create(reader, "Error converting value {0} to type '{1}'.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.FormatValueForPrint(reader.Value), objectType), ex);
}
// we don't actually expect to get here.
throw JsonSerializationException.Create(reader, "Unexpected token {0} when parsing enum.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
Type t = (ReflectionUtils.IsNullableType(objectType))
? Nullable.GetUnderlyingType(objectType)
: objectType;
return t.IsEnum();
}
}
}

View File

@@ -0,0 +1,145 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
using System;
using System.Globalization;
namespace RRQMCore.XREF.Newtonsoft.Json.Converters
{
/// <summary>
/// Converts a <see cref="DateTime"/> to and from Unix epoch time
/// </summary>
public class UnixDateTimeConverter : DateTimeConverterBase
{
internal static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
long ticks;
if (value is DateTime dateTime)
{
ticks = (long)(dateTime.ToUniversalTime() - UnixEpoch).TotalSeconds;
}
#if HAVE_DATE_TIME_OFFSET
else if (value is DateTimeOffset dateTimeOffset)
{
ticks = (long)(dateTimeOffset.ToUniversalTime() - UnixEpoch).TotalSeconds;
}
#endif
else
{
throw new JsonSerializationException("Expected date object value.");
}
if (ticks < 0)
{
throw new JsonSerializationException("Cannot convert date value that is before Unix epoch of 00:00:00 UTC on 1 January 1970.");
}
writer.WriteValue(ticks);
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing property value of the JSON that is being converted.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
bool nullable = ReflectionUtils.IsNullable(objectType);
if (reader.TokenType == JsonToken.Null)
{
if (!nullable)
{
throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
}
return null;
}
long ticks;
if (reader.TokenType == JsonToken.Integer)
{
ticks = (long)reader.Value;
}
else if (reader.TokenType == JsonToken.String)
{
if (!long.TryParse((string)reader.Value, out ticks))
{
throw JsonSerializationException.Create(reader, "Cannot convert invalid value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
}
}
else
{
throw JsonSerializationException.Create(reader, "Unexpected token parsing date. Expected Integer or String, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
if (ticks >= 0)
{
DateTime d = UnixEpoch.AddSeconds(ticks);
#if HAVE_DATE_TIME_OFFSET
Type t = (nullable)
? Nullable.GetUnderlyingType(objectType)
: objectType;
if (t == typeof(DateTimeOffset))
{
return new DateTimeOffset(d, TimeSpan.Zero);
}
#endif
return d;
}
else
{
throw JsonSerializationException.Create(reader, "Cannot convert value that is before Unix epoch of 00:00:00 UTC on 1 January 1970 to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
}
}
}
}

View File

@@ -0,0 +1,119 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
using System;
using System.Globalization;
namespace RRQMCore.XREF.Newtonsoft.Json.Converters
{
/// <summary>
/// Converts a <see cref="Version"/> to and from a string (e.g. <c>"1.2.3.4"</c>).
/// </summary>
public class VersionConverter : JsonConverter
{
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
}
else if (value is Version)
{
writer.WriteValue(value.ToString());
}
else
{
throw new JsonSerializationException("Expected Version object value");
}
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing property value of the JSON that is being converted.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
else
{
if (reader.TokenType == JsonToken.String)
{
try
{
Version v = new Version((string)reader.Value);
return v;
}
catch (Exception ex)
{
throw JsonSerializationException.Create(reader, "Error parsing version string: {0}".FormatWith(CultureInfo.InvariantCulture, reader.Value), ex);
}
}
else
{
throw JsonSerializationException.Create(reader, "Unexpected token or value when parsing version. Token: {0}, Value: {1}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType, reader.Value));
}
}
}
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Version);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,56 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Specifies how dates are formatted when writing JSON text.
/// </summary>
public enum DateFormatHandling
{
/// <summary>
/// Dates are written in the ISO 8601 format, e.g. <c>"2012-03-21T05:40Z"</c>.
/// </summary>
IsoDateFormat,
/// <summary>
/// Dates are written in the Microsoft JSON format, e.g. <c>"\/Date(1198908717056)\/"</c>.
/// </summary>
MicrosoftDateFormat
}
}

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Specifies how date formatted strings, e.g. <c>"\/Date(1198908717056)\/"</c> and <c>"2012-03-21T05:40Z"</c>, are parsed when reading JSON text.
/// </summary>
public enum DateParseHandling
{
/// <summary>
/// Date formatted strings are not parsed to a date type and are read as strings.
/// </summary>
None = 0,
/// <summary>
/// Date formatted strings, e.g. <c>"\/Date(1198908717056)\/"</c> and <c>"2012-03-21T05:40Z"</c>, are parsed to <see cref="DateTime"/>.
/// </summary>
DateTime = 1,
#if HAVE_DATE_TIME_OFFSET
/// <summary>
/// Date formatted strings, e.g. <c>"\/Date(1198908717056)\/"</c> and <c>"2012-03-21T05:40Z"</c>, are parsed to <see cref="DateTimeOffset"/>.
/// </summary>
DateTimeOffset = 2
#endif
}
}

View File

@@ -0,0 +1,69 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System;
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Specifies how to treat the time value when converting between string and <see cref="DateTime"/>.
/// </summary>
public enum DateTimeZoneHandling
{
/// <summary>
/// Treat as local time. If the <see cref="DateTime"/> object represents a Coordinated Universal Time (UTC), it is converted to the local time.
/// </summary>
Local = 0,
/// <summary>
/// Treat as a UTC. If the <see cref="DateTime"/> object represents a local time, it is converted to a UTC.
/// </summary>
Utc = 1,
/// <summary>
/// Treat as a local time if a <see cref="DateTime"/> is being converted to a string.
/// If a string is being converted to <see cref="DateTime"/>, convert to a local time if a time zone is specified.
/// </summary>
Unspecified = 2,
/// <summary>
/// Time zone information should be preserved when converting.
/// </summary>
RoundtripKind = 3
}
}

View File

@@ -0,0 +1,80 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System;
using System.ComponentModel;
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Specifies default value handling options for the <see cref="JsonSerializer"/>.
/// </summary>
/// <example>
/// <code lang="cs" source="..\Src\RRQMCore.XREF.Newtonsoft.Json.Tests\Documentation\SerializationTests.cs" region="ReducingSerializedJsonSizeDefaultValueHandlingObject" title="DefaultValueHandling Class" />
/// <code lang="cs" source="..\Src\RRQMCore.XREF.Newtonsoft.Json.Tests\Documentation\SerializationTests.cs" region="ReducingSerializedJsonSizeDefaultValueHandlingExample" title="DefaultValueHandling Ignore Example" />
/// </example>
[Flags]
public enum DefaultValueHandling
{
/// <summary>
/// Include members where the member value is the same as the member's default value when serializing objects.
/// Included members are written to JSON. Has no effect when deserializing.
/// </summary>
Include = 0,
/// <summary>
/// Ignore members where the member value is the same as the member's default value when serializing objects
/// so that it is not written to JSON.
/// This option will ignore all default values (e.g. <c>null</c> for objects and nullable types; <c>0</c> for integers,
/// decimals and floating point numbers; and <c>false</c> for booleans). The default value ignored can be changed by
/// placing the <see cref="DefaultValueAttribute"/> on the property.
/// </summary>
Ignore = 1,
/// <summary>
/// Members with a default value but no JSON will be set to their default value when deserializing.
/// </summary>
Populate = 2,
/// <summary>
/// Ignore members where the member value is the same as the member's default value when serializing objects
/// and set members to their default value when deserializing.
/// </summary>
IgnoreAndPopulate = Ignore | Populate
}
}

View File

@@ -0,0 +1,65 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System;
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Specifies float format handling options when writing special floating point numbers, e.g. <see cref="Double.NaN"/>,
/// <see cref="Double.PositiveInfinity"/> and <see cref="Double.NegativeInfinity"/> with <see cref="JsonWriter"/>.
/// </summary>
public enum FloatFormatHandling
{
/// <summary>
/// Write special floating point values as strings in JSON, e.g. <c>"NaN"</c>, <c>"Infinity"</c>, <c>"-Infinity"</c>.
/// </summary>
String = 0,
/// <summary>
/// Write special floating point values as symbols in JSON, e.g. <c>NaN</c>, <c>Infinity</c>, <c>-Infinity</c>.
/// Note that this will produce non-valid JSON.
/// </summary>
Symbol = 1,
/// <summary>
/// Write special floating point values as the property's default value in JSON, e.g. 0.0 for a <see cref="Double"/> property, <c>null</c> for a <see cref="Nullable{T}"/> of <see cref="Double"/> property.
/// </summary>
DefaultValue = 2
}
}

View File

@@ -0,0 +1,56 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Specifies how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text.
/// </summary>
public enum FloatParseHandling
{
/// <summary>
/// Floating point numbers are parsed to <see cref="Double"/>.
/// </summary>
Double = 0,
/// <summary>
/// Floating point numbers are parsed to <see cref="Decimal"/>.
/// </summary>
Decimal = 1
}
}

View File

@@ -0,0 +1,34 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#if HAVE_OBSOLETE_FORMATTER_ASSEMBLY_STYLE
namespace System.Runtime.Serialization.Formatters
{
/// <summary>
/// Indicates the method that will be used during deserialization for locating and loading assemblies.
/// </summary>
[Obsolete("FormatterAssemblyStyle is obsolete. Use TypeNameAssemblyFormatHandling instead.")]
public enum FormatterAssemblyStyle
{
/// <summary>
/// In simple mode, the assembly used during deserialization need not match exactly the assembly used during serialization. Specifically, the version numbers need not match as the <see cref="M:System.Reflection.Assembly.LoadWithPartialName(String)"/> method is used to load the assembly.
/// </summary>
Simple = 0,
/// <summary>
/// In full mode, the assembly used during deserialization must match exactly the assembly used during serialization. The <see cref="System.Reflection.Assembly.Load"/> is used to load the assembly.
/// </summary>
Full = 1
}
}
#endif

View File

@@ -0,0 +1,56 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Specifies formatting options for the <see cref="JsonTextWriter"/>.
/// </summary>
public enum Formatting
{
/// <summary>
/// No special formatting is applied. This is the default.
/// </summary>
None = 0,
/// <summary>
/// Causes child objects to be indented according to the <see cref="JsonTextWriter.Indentation"/> and <see cref="JsonTextWriter.IndentChar"/> settings.
/// </summary>
Indented = 1
}
}

View File

@@ -0,0 +1,33 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Provides an interface for using pooled arrays.
/// </summary>
/// <typeparam name="T">The array type content.</typeparam>
public interface IArrayPool<T>
{
/// <summary>
/// Rent an array from the pool. This array must be returned when it is no longer needed.
/// </summary>
/// <param name="minimumLength">The minimum required length of the array. The returned array may be longer.</param>
/// <returns>The rented array from the pool. This array must be returned when it is no longer needed.</returns>
T[] Rent(int minimumLength);
/// <summary>
/// Return an array to the pool.
/// </summary>
/// <param name="array">The array that is being returned.</param>
void Return(T[] array);
}
}

View File

@@ -0,0 +1,66 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Provides an interface to enable a class to return line and position information.
/// </summary>
public interface IJsonLineInfo
{
/// <summary>
/// Gets a value indicating whether the class can return line information.
/// </summary>
/// <returns>
/// <c>true</c> if <see cref="LineNumber"/> and <see cref="LinePosition"/> can be provided; otherwise, <c>false</c>.
/// </returns>
bool HasLineInfo();
/// <summary>
/// Gets the current line number.
/// </summary>
/// <value>The current line number or 0 if no line information is available (for example, when <see cref="HasLineInfo"/> returns <c>false</c>).</value>
int LineNumber { get; }
/// <summary>
/// Gets the current line position.
/// </summary>
/// <value>The current line position or 0 if no line information is available (for example, when <see cref="HasLineInfo"/> returns <c>false</c>).</value>
int LinePosition { get; }
}
}

View File

@@ -0,0 +1,86 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System;
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Instructs the <see cref="JsonSerializer"/> how to serialize the collection.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
public sealed class JsonArrayAttribute : JsonContainerAttribute
{
private bool _allowNullItems;
/// <summary>
/// Gets or sets a value indicating whether null items are allowed in the collection.
/// </summary>
/// <value><c>true</c> if null items are allowed in the collection; otherwise, <c>false</c>.</value>
public bool AllowNullItems
{
get => _allowNullItems;
set => _allowNullItems = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonArrayAttribute"/> class.
/// </summary>
public JsonArrayAttribute()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonObjectAttribute"/> class with a flag indicating whether the array can contain null items.
/// </summary>
/// <param name="allowNullItems">A flag indicating whether the array can contain null items.</param>
public JsonArrayAttribute(bool allowNullItems)
{
_allowNullItems = allowNullItems;
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonArrayAttribute"/> class with the specified container Id.
/// </summary>
/// <param name="id">The container Id.</param>
public JsonArrayAttribute(string id)
: base(id)
{
}
}
}

View File

@@ -0,0 +1,50 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System;
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Instructs the <see cref="JsonSerializer"/> to use the specified constructor when deserializing that object.
/// </summary>
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)]
public sealed class JsonConstructorAttribute : Attribute
{
}
}

View File

@@ -0,0 +1,194 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using RRQMCore.XREF.Newtonsoft.Json.Serialization;
using System;
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Instructs the <see cref="JsonSerializer"/> how to serialize the object.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
public abstract class JsonContainerAttribute : Attribute
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
public string Id { get; set; }
/// <summary>
/// Gets or sets the title.
/// </summary>
/// <value>The title.</value>
public string Title { get; set; }
/// <summary>
/// Gets or sets the description.
/// </summary>
/// <value>The description.</value>
public string Description { get; set; }
/// <summary>
/// Gets or sets the collection's items converter.
/// </summary>
/// <value>The collection's items converter.</value>
public Type ItemConverterType { get; set; }
/// <summary>
/// The parameter list to use when constructing the <see cref="JsonConverter"/> described by <see cref="ItemConverterType"/>.
/// If <c>null</c>, the default constructor is used.
/// When non-<c>null</c>, there must be a constructor defined in the <see cref="JsonConverter"/> that exactly matches the number,
/// order, and type of these parameters.
/// </summary>
/// <example>
/// <code>
/// [JsonContainer(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })]
/// </code>
/// </example>
public object[] ItemConverterParameters { get; set; }
/// <summary>
/// Gets or sets the <see cref="Type"/> of the <see cref="NamingStrategy"/>.
/// </summary>
/// <value>The <see cref="Type"/> of the <see cref="NamingStrategy"/>.</value>
public Type NamingStrategyType
{
get => _namingStrategyType;
set
{
_namingStrategyType = value;
NamingStrategyInstance = null;
}
}
/// <summary>
/// The parameter list to use when constructing the <see cref="NamingStrategy"/> described by <see cref="NamingStrategyType"/>.
/// If <c>null</c>, the default constructor is used.
/// When non-<c>null</c>, there must be a constructor defined in the <see cref="NamingStrategy"/> that exactly matches the number,
/// order, and type of these parameters.
/// </summary>
/// <example>
/// <code>
/// [JsonContainer(NamingStrategyType = typeof(MyNamingStrategy), NamingStrategyParameters = new object[] { 123, "Four" })]
/// </code>
/// </example>
public object[] NamingStrategyParameters
{
get => _namingStrategyParameters;
set
{
_namingStrategyParameters = value;
NamingStrategyInstance = null;
}
}
internal NamingStrategy NamingStrategyInstance { get; set; }
// yuck. can't set nullable properties on an attribute in C#
// have to use this approach to get an unset default state
internal bool? _isReference;
internal bool? _itemIsReference;
internal ReferenceLoopHandling? _itemReferenceLoopHandling;
internal TypeNameHandling? _itemTypeNameHandling;
private Type _namingStrategyType;
private object[] _namingStrategyParameters;
/// <summary>
/// Gets or sets a value that indicates whether to preserve object references.
/// </summary>
/// <value>
/// <c>true</c> to keep object reference; otherwise, <c>false</c>. The default is <c>false</c>.
/// </value>
public bool IsReference
{
get => _isReference ?? default(bool);
set => _isReference = value;
}
/// <summary>
/// Gets or sets a value that indicates whether to preserve collection's items references.
/// </summary>
/// <value>
/// <c>true</c> to keep collection's items object references; otherwise, <c>false</c>. The default is <c>false</c>.
/// </value>
public bool ItemIsReference
{
get => _itemIsReference ?? default(bool);
set => _itemIsReference = value;
}
/// <summary>
/// Gets or sets the reference loop handling used when serializing the collection's items.
/// </summary>
/// <value>The reference loop handling.</value>
public ReferenceLoopHandling ItemReferenceLoopHandling
{
get => _itemReferenceLoopHandling ?? default(ReferenceLoopHandling);
set => _itemReferenceLoopHandling = value;
}
/// <summary>
/// Gets or sets the type name handling used when serializing the collection's items.
/// </summary>
/// <value>The type name handling.</value>
public TypeNameHandling ItemTypeNameHandling
{
get => _itemTypeNameHandling ?? default(TypeNameHandling);
set => _itemTypeNameHandling = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonContainerAttribute"/> class.
/// </summary>
protected JsonContainerAttribute()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonContainerAttribute"/> class with the specified container Id.
/// </summary>
/// <param name="id">The container Id.</param>
protected JsonContainerAttribute(string id)
{
Id = id;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,160 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
using System;
using System.Globalization;
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Converts an object to and from JSON.
/// </summary>
public abstract class JsonConverter
{
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public abstract void WriteJson(JsonWriter writer, object value, JsonSerializer serializer);
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public abstract object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer);
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public abstract bool CanConvert(Type objectType);
/// <summary>
/// Gets a value indicating whether this <see cref="JsonConverter"/> can read JSON.
/// </summary>
/// <value><c>true</c> if this <see cref="JsonConverter"/> can read JSON; otherwise, <c>false</c>.</value>
public virtual bool CanRead => true;
/// <summary>
/// Gets a value indicating whether this <see cref="JsonConverter"/> can write JSON.
/// </summary>
/// <value><c>true</c> if this <see cref="JsonConverter"/> can write JSON; otherwise, <c>false</c>.</value>
public virtual bool CanWrite => true;
}
/// <summary>
/// Converts an object to and from JSON.
/// </summary>
/// <typeparam name="T">The object type to convert.</typeparam>
public abstract class JsonConverter<T> : JsonConverter
{
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public sealed override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (!(value != null ? value is T : ReflectionUtils.IsNullable(typeof(T))))
{
throw new JsonSerializationException("Converter cannot write specified value to JSON. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
}
WriteJson(writer, (T)value, serializer);
}
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public abstract void WriteJson(JsonWriter writer, T value, JsonSerializer serializer);
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public sealed override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
bool existingIsNull = existingValue == null;
if (!(existingIsNull || existingValue is T))
{
throw new JsonSerializationException("Converter cannot read JSON with the specified existing value. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
}
return ReadJson(reader, objectType, existingIsNull ? default(T) : (T)existingValue, !existingIsNull, serializer);
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read. If there is no existing value then <c>null</c> will be used.</param>
/// <param name="hasExistingValue">The existing value has a value.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public abstract T ReadJson(JsonReader reader, Type objectType, T existingValue, bool hasExistingValue, JsonSerializer serializer);
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public sealed override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
}
}

View File

@@ -0,0 +1,88 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System;
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Instructs the <see cref="JsonSerializer"/> to use the specified <see cref="JsonConverter"/> when serializing the member or class.
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Parameter, AllowMultiple = false)]
public sealed class JsonConverterAttribute : Attribute
{
private readonly Type _converterType;
/// <summary>
/// Gets the <see cref="Type"/> of the <see cref="JsonConverter"/>.
/// </summary>
/// <value>The <see cref="Type"/> of the <see cref="JsonConverter"/>.</value>
public Type ConverterType => _converterType;
/// <summary>
/// The parameter list to use when constructing the <see cref="JsonConverter"/> described by <see cref="ConverterType"/>.
/// If <c>null</c>, the default constructor is used.
/// </summary>
public object[] ConverterParameters { get; }
/// <summary>
/// Initializes a new instance of the <see cref="JsonConverterAttribute"/> class.
/// </summary>
/// <param name="converterType">Type of the <see cref="JsonConverter"/>.</param>
public JsonConverterAttribute(Type converterType)
{
if (converterType == null)
{
throw new ArgumentNullException(nameof(converterType));
}
_converterType = converterType;
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonConverterAttribute"/> class.
/// </summary>
/// <param name="converterType">Type of the <see cref="JsonConverter"/>.</param>
/// <param name="converterParameters">Parameter list to use when constructing the <see cref="JsonConverter"/>. Can be <c>null</c>.</param>
public JsonConverterAttribute(Type converterType, params object[] converterParameters)
: this(converterType)
{
ConverterParameters = converterParameters;
}
}
}

View File

@@ -0,0 +1,49 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System.Collections.ObjectModel;
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Represents a collection of <see cref="JsonConverter"/>.
/// </summary>
public class JsonConverterCollection : Collection<JsonConverter>
{
}
}

View File

@@ -0,0 +1,65 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System;
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Instructs the <see cref="JsonSerializer"/> how to serialize the collection.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
public sealed class JsonDictionaryAttribute : JsonContainerAttribute
{
/// <summary>
/// Initializes a new instance of the <see cref="JsonDictionaryAttribute"/> class.
/// </summary>
public JsonDictionaryAttribute()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonDictionaryAttribute"/> class with the specified container Id.
/// </summary>
/// <param name="id">The container Id.</param>
public JsonDictionaryAttribute(string id)
: base(id)
{
}
}
}

View File

@@ -0,0 +1,101 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System;
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// The exception thrown when an error occurs during JSON serialization or deserialization.
/// </summary>
#if HAVE_BINARY_EXCEPTION_SERIALIZATION
[Serializable]
#endif
public class JsonException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="JsonException"/> class.
/// </summary>
public JsonException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonException"/> class
/// with a specified error message.
/// </summary>
/// <param name="message">The error message that explains the reason for the exception.</param>
public JsonException(string message)
: base(message)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonException"/> class
/// with a specified error message and a reference to the inner exception that is the cause of this exception.
/// </summary>
/// <param name="message">The error message that explains the reason for the exception.</param>
/// <param name="innerException">The exception that is the cause of the current exception, or <c>null</c> if no inner exception is specified.</param>
public JsonException(string message, Exception innerException)
: base(message, innerException)
{
}
#if HAVE_BINARY_EXCEPTION_SERIALIZATION
/// <summary>
/// Initializes a new instance of the <see cref="JsonException"/> class.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
/// <exception cref="ArgumentNullException">The <paramref name="info"/> parameter is <c>null</c>.</exception>
/// <exception cref="SerializationException">The class name is <c>null</c> or <see cref="Exception.HResult"/> is zero (0).</exception>
public JsonException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
#endif
internal static JsonException Create(IJsonLineInfo lineInfo, string path, string message)
{
message = JsonPosition.FormatMessage(lineInfo, path, message);
return new JsonException(message);
}
}
}

View File

@@ -0,0 +1,48 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Instructs the <see cref="JsonSerializer"/> to deserialize properties with no matching class member into the specified collection
/// and write values during serialization.
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public class JsonExtensionDataAttribute : Attribute
{
/// <summary>
/// Gets or sets a value that indicates whether to write extension data when serializing the object.
/// </summary>
/// <value>
/// <c>true</c> to write extension data when serializing the object; otherwise, <c>false</c>. The default is <c>true</c>.
/// </value>
public bool WriteData { get; set; }
/// <summary>
/// Gets or sets a value that indicates whether to read extension data when deserializing the object.
/// </summary>
/// <value>
/// <c>true</c> to read extension data when deserializing the object; otherwise, <c>false</c>. The default is <c>true</c>.
/// </value>
public bool ReadData { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="JsonExtensionDataAttribute"/> class.
/// </summary>
public JsonExtensionDataAttribute()
{
WriteData = true;
ReadData = true;
}
}
}

View File

@@ -0,0 +1,50 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System;
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Instructs the <see cref="JsonSerializer"/> not to serialize the public field or public read/write property value.
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public sealed class JsonIgnoreAttribute : Attribute
{
}
}

View File

@@ -0,0 +1,114 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System;
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Instructs the <see cref="JsonSerializer"/> how to serialize the object.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)]
public sealed class JsonObjectAttribute : JsonContainerAttribute
{
private MemberSerialization _memberSerialization = MemberSerialization.OptOut;
// yuck. can't set nullable properties on an attribute in C#
// have to use this approach to get an unset default state
internal Required? _itemRequired;
internal NullValueHandling? _itemNullValueHandling;
/// <summary>
/// Gets or sets the member serialization.
/// </summary>
/// <value>The member serialization.</value>
public MemberSerialization MemberSerialization
{
get => _memberSerialization;
set => _memberSerialization = value;
}
/// <summary>
/// Gets or sets how the object's properties with null values are handled during serialization and deserialization.
/// </summary>
/// <value>How the object's properties with null values are handled during serialization and deserialization.</value>
public NullValueHandling ItemNullValueHandling
{
get => _itemNullValueHandling ?? default(NullValueHandling);
set => _itemNullValueHandling = value;
}
/// <summary>
/// Gets or sets a value that indicates whether the object's properties are required.
/// </summary>
/// <value>
/// A value indicating whether the object's properties are required.
/// </value>
public Required ItemRequired
{
get => _itemRequired ?? default(Required);
set => _itemRequired = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonObjectAttribute"/> class.
/// </summary>
public JsonObjectAttribute()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonObjectAttribute"/> class with the specified member serialization.
/// </summary>
/// <param name="memberSerialization">The member serialization.</param>
public JsonObjectAttribute(MemberSerialization memberSerialization)
{
MemberSerialization = memberSerialization;
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonObjectAttribute"/> class with the specified container Id.
/// </summary>
/// <param name="id">The container Id.</param>
public JsonObjectAttribute(string id)
: base(id)
{
}
}
}

View File

@@ -0,0 +1,193 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
namespace RRQMCore.XREF.Newtonsoft.Json
{
internal enum JsonContainerType
{
None = 0,
Object = 1,
Array = 2,
Constructor = 3
}
internal struct JsonPosition
{
private static readonly char[] SpecialCharacters = { '.', ' ', '\'', '/', '"', '[', ']', '(', ')', '\t', '\n', '\r', '\f', '\b', '\\', '\u0085', '\u2028', '\u2029' };
internal JsonContainerType Type;
internal int Position;
internal string PropertyName;
internal bool HasIndex;
public JsonPosition(JsonContainerType type)
{
Type = type;
HasIndex = TypeHasIndex(type);
Position = -1;
PropertyName = null;
}
internal int CalculateLength()
{
switch (Type)
{
case JsonContainerType.Object:
return PropertyName.Length + 5;
case JsonContainerType.Array:
case JsonContainerType.Constructor:
return MathUtils.IntLength((ulong)Position) + 2;
default:
throw new ArgumentOutOfRangeException(nameof(Type));
}
}
internal void WriteTo(StringBuilder sb, ref StringWriter writer, ref char[] buffer)
{
switch (Type)
{
case JsonContainerType.Object:
string propertyName = PropertyName;
if (propertyName.IndexOfAny(SpecialCharacters) != -1)
{
sb.Append(@"['");
if (writer == null)
{
writer = new StringWriter(sb);
}
JavaScriptUtils.WriteEscapedJavaScriptString(writer, propertyName, '\'', false, JavaScriptUtils.SingleQuoteCharEscapeFlags, StringEscapeHandling.Default, null, ref buffer);
sb.Append(@"']");
}
else
{
if (sb.Length > 0)
{
sb.Append('.');
}
sb.Append(propertyName);
}
break;
case JsonContainerType.Array:
case JsonContainerType.Constructor:
sb.Append('[');
sb.Append(Position);
sb.Append(']');
break;
}
}
internal static bool TypeHasIndex(JsonContainerType type)
{
return (type == JsonContainerType.Array || type == JsonContainerType.Constructor);
}
internal static string BuildPath(List<JsonPosition> positions, JsonPosition? currentPosition)
{
int capacity = 0;
if (positions != null)
{
for (int i = 0; i < positions.Count; i++)
{
capacity += positions[i].CalculateLength();
}
}
if (currentPosition != null)
{
capacity += currentPosition.GetValueOrDefault().CalculateLength();
}
StringBuilder sb = new StringBuilder(capacity);
StringWriter writer = null;
char[] buffer = null;
if (positions != null)
{
foreach (JsonPosition state in positions)
{
state.WriteTo(sb, ref writer, ref buffer);
}
}
if (currentPosition != null)
{
currentPosition.GetValueOrDefault().WriteTo(sb, ref writer, ref buffer);
}
return sb.ToString();
}
internal static string FormatMessage(IJsonLineInfo lineInfo, string path, string message)
{
// don't add a fullstop and space when message ends with a new line
if (!message.EndsWith(Environment.NewLine, StringComparison.Ordinal))
{
message = message.Trim();
if (!message.EndsWith('.'))
{
message += ".";
}
message += " ";
}
message += "Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path);
if (lineInfo != null && lineInfo.HasLineInfo())
{
message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition);
}
message += ".";
return message;
}
}
}

View File

@@ -0,0 +1,237 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using RRQMCore.XREF.Newtonsoft.Json.Serialization;
using System;
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// Instructs the <see cref="JsonSerializer"/> to always serialize the member with the specified name.
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false)]
public sealed class JsonPropertyAttribute : Attribute
{
// yuck. can't set nullable properties on an attribute in C#
// have to use this approach to get an unset default state
internal NullValueHandling? _nullValueHandling;
internal DefaultValueHandling? _defaultValueHandling;
internal ReferenceLoopHandling? _referenceLoopHandling;
internal ObjectCreationHandling? _objectCreationHandling;
internal TypeNameHandling? _typeNameHandling;
internal bool? _isReference;
internal int? _order;
internal Required? _required;
internal bool? _itemIsReference;
internal ReferenceLoopHandling? _itemReferenceLoopHandling;
internal TypeNameHandling? _itemTypeNameHandling;
/// <summary>
/// Gets or sets the <see cref="JsonConverter"/> used when serializing the property's collection items.
/// </summary>
/// <value>The collection's items <see cref="JsonConverter"/>.</value>
public Type ItemConverterType { get; set; }
/// <summary>
/// The parameter list to use when constructing the <see cref="JsonConverter"/> described by <see cref="ItemConverterType"/>.
/// If <c>null</c>, the default constructor is used.
/// When non-<c>null</c>, there must be a constructor defined in the <see cref="JsonConverter"/> that exactly matches the number,
/// order, and type of these parameters.
/// </summary>
/// <example>
/// <code>
/// [JsonProperty(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })]
/// </code>
/// </example>
public object[] ItemConverterParameters { get; set; }
/// <summary>
/// Gets or sets the <see cref="Type"/> of the <see cref="NamingStrategy"/>.
/// </summary>
/// <value>The <see cref="Type"/> of the <see cref="NamingStrategy"/>.</value>
public Type NamingStrategyType { get; set; }
/// <summary>
/// The parameter list to use when constructing the <see cref="NamingStrategy"/> described by <see cref="JsonPropertyAttribute.NamingStrategyType"/>.
/// If <c>null</c>, the default constructor is used.
/// When non-<c>null</c>, there must be a constructor defined in the <see cref="NamingStrategy"/> that exactly matches the number,
/// order, and type of these parameters.
/// </summary>
/// <example>
/// <code>
/// [JsonProperty(NamingStrategyType = typeof(MyNamingStrategy), NamingStrategyParameters = new object[] { 123, "Four" })]
/// </code>
/// </example>
public object[] NamingStrategyParameters { get; set; }
/// <summary>
/// Gets or sets the null value handling used when serializing this property.
/// </summary>
/// <value>The null value handling.</value>
public NullValueHandling NullValueHandling
{
get => _nullValueHandling ?? default(NullValueHandling);
set => _nullValueHandling = value;
}
/// <summary>
/// Gets or sets the default value handling used when serializing this property.
/// </summary>
/// <value>The default value handling.</value>
public DefaultValueHandling DefaultValueHandling
{
get => _defaultValueHandling ?? default(DefaultValueHandling);
set => _defaultValueHandling = value;
}
/// <summary>
/// Gets or sets the reference loop handling used when serializing this property.
/// </summary>
/// <value>The reference loop handling.</value>
public ReferenceLoopHandling ReferenceLoopHandling
{
get => _referenceLoopHandling ?? default(ReferenceLoopHandling);
set => _referenceLoopHandling = value;
}
/// <summary>
/// Gets or sets the object creation handling used when deserializing this property.
/// </summary>
/// <value>The object creation handling.</value>
public ObjectCreationHandling ObjectCreationHandling
{
get => _objectCreationHandling ?? default(ObjectCreationHandling);
set => _objectCreationHandling = value;
}
/// <summary>
/// Gets or sets the type name handling used when serializing this property.
/// </summary>
/// <value>The type name handling.</value>
public TypeNameHandling TypeNameHandling
{
get => _typeNameHandling ?? default(TypeNameHandling);
set => _typeNameHandling = value;
}
/// <summary>
/// Gets or sets whether this property's value is serialized as a reference.
/// </summary>
/// <value>Whether this property's value is serialized as a reference.</value>
public bool IsReference
{
get => _isReference ?? default(bool);
set => _isReference = value;
}
/// <summary>
/// Gets or sets the order of serialization of a member.
/// </summary>
/// <value>The numeric order of serialization.</value>
public int Order
{
get => _order ?? default(int);
set => _order = value;
}
/// <summary>
/// Gets or sets a value indicating whether this property is required.
/// </summary>
/// <value>
/// A value indicating whether this property is required.
/// </value>
public Required Required
{
get => _required ?? Required.Default;
set => _required = value;
}
/// <summary>
/// Gets or sets the name of the property.
/// </summary>
/// <value>The name of the property.</value>
public string PropertyName { get; set; }
/// <summary>
/// Gets or sets the reference loop handling used when serializing the property's collection items.
/// </summary>
/// <value>The collection's items reference loop handling.</value>
public ReferenceLoopHandling ItemReferenceLoopHandling
{
get => _itemReferenceLoopHandling ?? default(ReferenceLoopHandling);
set => _itemReferenceLoopHandling = value;
}
/// <summary>
/// Gets or sets the type name handling used when serializing the property's collection items.
/// </summary>
/// <value>The collection's items type name handling.</value>
public TypeNameHandling ItemTypeNameHandling
{
get => _itemTypeNameHandling ?? default(TypeNameHandling);
set => _itemTypeNameHandling = value;
}
/// <summary>
/// Gets or sets whether this property's collection items are serialized as a reference.
/// </summary>
/// <value>Whether this property's collection items are serialized as a reference.</value>
public bool ItemIsReference
{
get => _itemIsReference ?? default(bool);
set => _itemIsReference = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonPropertyAttribute"/> class.
/// </summary>
public JsonPropertyAttribute()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonPropertyAttribute"/> class with the specified name.
/// </summary>
/// <param name="propertyName">Name of the property.</param>
public JsonPropertyAttribute(string propertyName)
{
PropertyName = propertyName;
}
}
}

View File

@@ -0,0 +1,261 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
#if HAVE_ASYNC
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using RRQMCore.XREF.Newtonsoft.Json.Utilities;
namespace RRQMCore.XREF.Newtonsoft.Json
{
public abstract partial class JsonReader
{
/// <summary>
/// Asynchronously reads the next JSON token from the source.
/// </summary>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
/// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous read. The <see cref="Task{TResult}.Result"/>
/// property returns <c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.</returns>
/// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.</remarks>
public virtual Task<bool> ReadAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return cancellationToken.CancelIfRequestedAsync<bool>() ?? Read().ToAsync();
}
/// <summary>
/// Asynchronously skips the children of the current token.
/// </summary>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
/// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.</remarks>
public async Task SkipAsync(CancellationToken cancellationToken = default(CancellationToken))
{
if (TokenType == JsonToken.PropertyName)
{
await ReadAsync(cancellationToken).ConfigureAwait(false);
}
if (JsonTokenUtils.IsStartToken(TokenType))
{
int depth = Depth;
while (await ReadAsync(cancellationToken).ConfigureAwait(false) && depth < Depth)
{
}
}
}
internal async Task ReaderReadAndAssertAsync(CancellationToken cancellationToken)
{
if (!await ReadAsync(cancellationToken).ConfigureAwait(false))
{
throw CreateUnexpectedEndException();
}
}
/// <summary>
/// Asynchronously reads the next JSON token from the source as a <see cref="Nullable{T}"/> of <see cref="bool"/>.
/// </summary>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
/// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous read. The <see cref="Task{TResult}.Result"/>
/// property returns the <see cref="Nullable{T}"/> of <see cref="bool"/>. This result will be <c>null</c> at the end of an array.</returns>
/// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.</remarks>
public virtual Task<bool?> ReadAsBooleanAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return cancellationToken.CancelIfRequestedAsync<bool?>() ?? Task.FromResult(ReadAsBoolean());
}
/// <summary>
/// Asynchronously reads the next JSON token from the source as a <see cref="byte"/>[].
/// </summary>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
/// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous read. The <see cref="Task{TResult}.Result"/>
/// property returns the <see cref="byte"/>[]. This result will be <c>null</c> at the end of an array.</returns>
/// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.</remarks>
public virtual Task<byte[]> ReadAsBytesAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return cancellationToken.CancelIfRequestedAsync<byte[]>() ?? Task.FromResult(ReadAsBytes());
}
internal async Task<byte[]> ReadArrayIntoByteArrayAsync(CancellationToken cancellationToken)
{
List<byte> buffer = new List<byte>();
while (true)
{
if (!await ReadAsync(cancellationToken).ConfigureAwait(false))
{
SetToken(JsonToken.None);
}
if (ReadArrayElementIntoByteArrayReportDone(buffer))
{
byte[] d = buffer.ToArray();
SetToken(JsonToken.Bytes, d, false);
return d;
}
}
}
/// <summary>
/// Asynchronously reads the next JSON token from the source as a <see cref="Nullable{T}"/> of <see cref="DateTime"/>.
/// </summary>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
/// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous read. The <see cref="Task{TResult}.Result"/>
/// property returns the <see cref="Nullable{T}"/> of <see cref="DateTime"/>. This result will be <c>null</c> at the end of an array.</returns>
/// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.</remarks>
public virtual Task<DateTime?> ReadAsDateTimeAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return cancellationToken.CancelIfRequestedAsync<DateTime?>() ?? Task.FromResult(ReadAsDateTime());
}
/// <summary>
/// Asynchronously reads the next JSON token from the source as a <see cref="Nullable{T}"/> of <see cref="DateTimeOffset"/>.
/// </summary>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
/// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous read. The <see cref="Task{TResult}.Result"/>
/// property returns the <see cref="Nullable{T}"/> of <see cref="DateTimeOffset"/>. This result will be <c>null</c> at the end of an array.</returns>
/// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.</remarks>
public virtual Task<DateTimeOffset?> ReadAsDateTimeOffsetAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return cancellationToken.CancelIfRequestedAsync<DateTimeOffset?>() ?? Task.FromResult(ReadAsDateTimeOffset());
}
/// <summary>
/// Asynchronously reads the next JSON token from the source as a <see cref="Nullable{T}"/> of <see cref="decimal"/>.
/// </summary>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
/// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous read. The <see cref="Task{TResult}.Result"/>
/// property returns the <see cref="Nullable{T}"/> of <see cref="decimal"/>. This result will be <c>null</c> at the end of an array.</returns>
/// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.</remarks>
public virtual Task<decimal?> ReadAsDecimalAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return cancellationToken.CancelIfRequestedAsync<decimal?>() ?? Task.FromResult(ReadAsDecimal());
}
/// <summary>
/// Asynchronously reads the next JSON token from the source as a <see cref="Nullable{T}"/> of <see cref="double"/>.
/// </summary>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
/// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous read. The <see cref="Task{TResult}.Result"/>
/// property returns the <see cref="Nullable{T}"/> of <see cref="double"/>. This result will be <c>null</c> at the end of an array.</returns>
/// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.</remarks>
public virtual Task<double?> ReadAsDoubleAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(ReadAsDouble());
}
/// <summary>
/// Asynchronously reads the next JSON token from the source as a <see cref="Nullable{T}"/> of <see cref="int"/>.
/// </summary>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
/// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous read. The <see cref="Task{TResult}.Result"/>
/// property returns the <see cref="Nullable{T}"/> of <see cref="int"/>. This result will be <c>null</c> at the end of an array.</returns>
/// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.</remarks>
public virtual Task<int?> ReadAsInt32Async(CancellationToken cancellationToken = default(CancellationToken))
{
return cancellationToken.CancelIfRequestedAsync<int?>() ?? Task.FromResult(ReadAsInt32());
}
/// <summary>
/// Asynchronously reads the next JSON token from the source as a <see cref="string"/>.
/// </summary>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
/// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous read. The <see cref="Task{TResult}.Result"/>
/// property returns the <see cref="string"/>. This result will be <c>null</c> at the end of an array.</returns>
/// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.</remarks>
public virtual Task<string> ReadAsStringAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return cancellationToken.CancelIfRequestedAsync<string>() ?? Task.FromResult(ReadAsString());
}
internal async Task<bool> ReadAndMoveToContentAsync(CancellationToken cancellationToken)
{
return await ReadAsync(cancellationToken).ConfigureAwait(false) && await MoveToContentAsync(cancellationToken).ConfigureAwait(false);
}
internal Task<bool> MoveToContentAsync(CancellationToken cancellationToken)
{
switch (TokenType)
{
case JsonToken.None:
case JsonToken.Comment:
return MoveToContentFromNonContentAsync(cancellationToken);
default:
return AsyncUtils.True;
}
}
private async Task<bool> MoveToContentFromNonContentAsync(CancellationToken cancellationToken)
{
while (true)
{
if (!await ReadAsync(cancellationToken).ConfigureAwait(false))
{
return false;
}
switch (TokenType)
{
case JsonToken.None:
case JsonToken.Comment:
break;
default:
return true;
}
}
}
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,159 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在RRQMCore.XREF命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion License
using System;
namespace RRQMCore.XREF.Newtonsoft.Json
{
/// <summary>
/// The exception thrown when an error occurs while reading JSON text.
/// </summary>
#if HAVE_BINARY_EXCEPTION_SERIALIZATION
[Serializable]
#endif
public class JsonReaderException : JsonException
{
/// <summary>
/// Gets the line number indicating where the error occurred.
/// </summary>
/// <value>The line number indicating where the error occurred.</value>
public int LineNumber { get; }
/// <summary>
/// Gets the line position indicating where the error occurred.
/// </summary>
/// <value>The line position indicating where the error occurred.</value>
public int LinePosition { get; }
/// <summary>
/// Gets the path to the JSON where the error occurred.
/// </summary>
/// <value>The path to the JSON where the error occurred.</value>
public string Path { get; }
/// <summary>
/// Initializes a new instance of the <see cref="JsonReaderException"/> class.
/// </summary>
public JsonReaderException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonReaderException"/> class
/// with a specified error message.
/// </summary>
/// <param name="message">The error message that explains the reason for the exception.</param>
public JsonReaderException(string message)
: base(message)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonReaderException"/> class
/// with a specified error message and a reference to the inner exception that is the cause of this exception.
/// </summary>
/// <param name="message">The error message that explains the reason for the exception.</param>
/// <param name="innerException">The exception that is the cause of the current exception, or <c>null</c> if no inner exception is specified.</param>
public JsonReaderException(string message, Exception innerException)
: base(message, innerException)
{
}
#if HAVE_BINARY_EXCEPTION_SERIALIZATION
/// <summary>
/// Initializes a new instance of the <see cref="JsonReaderException"/> class.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
/// <exception cref="ArgumentNullException">The <paramref name="info"/> parameter is <c>null</c>.</exception>
/// <exception cref="SerializationException">The class name is <c>null</c> or <see cref="Exception.HResult"/> is zero (0).</exception>
public JsonReaderException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
#endif
/// <summary>
/// Initializes a new instance of the <see cref="JsonReaderException"/> class
/// with a specified error message, JSON path, line number, line position, and a reference to the inner exception that is the cause of this exception.
/// </summary>
/// <param name="message">The error message that explains the reason for the exception.</param>
/// <param name="path">The path to the JSON where the error occurred.</param>
/// <param name="lineNumber">The line number indicating where the error occurred.</param>
/// <param name="linePosition">The line position indicating where the error occurred.</param>
/// <param name="innerException">The exception that is the cause of the current exception, or <c>null</c> if no inner exception is specified.</param>
public JsonReaderException(string message, string path, int lineNumber, int linePosition, Exception innerException)
: base(message, innerException)
{
Path = path;
LineNumber = lineNumber;
LinePosition = linePosition;
}
internal static JsonReaderException Create(JsonReader reader, string message)
{
return Create(reader, message, null);
}
internal static JsonReaderException Create(JsonReader reader, string message, Exception ex)
{
return Create(reader as IJsonLineInfo, reader.Path, message, ex);
}
internal static JsonReaderException Create(IJsonLineInfo lineInfo, string path, string message, Exception ex)
{
message = JsonPosition.FormatMessage(lineInfo, path, message);
int lineNumber;
int linePosition;
if (lineInfo != null && lineInfo.HasLineInfo())
{
lineNumber = lineInfo.LineNumber;
linePosition = lineInfo.LinePosition;
}
else
{
lineNumber = 0;
linePosition = 0;
}
return new JsonReaderException(message, path, lineNumber, linePosition, ex);
}
}
}

Some files were not shown because too many files have changed in this diff Show More