public static ShardKey <TRecord, TChild> FromExternalString(string value) { var aValues = StringExtensions.SerializeFromExternalString(value); int orgnLen = aValues[0] & 3; var orgn = System.Text.Encoding.UTF8.GetString(aValues, 1, orgnLen)[0]; var pos = orgnLen + 1; short shardId = ShardKey <TRecord> .ConvertFromBytes(aValues, ref pos, typeof(short)); TRecord recordId = ShardKey <TRecord> .ConvertFromBytes(aValues, ref pos, typeof(TRecord)); TChild childId = ShardKey <TRecord> .ConvertFromBytes(aValues, ref pos, typeof(TChild)); return(new ShardKey <TRecord, TChild>(orgn, shardId, recordId, childId)); }
internal static dynamic ConvertFromBytes(byte[] data, ref int position, Type valueType) { if (valueType == typeof(int)) { position += 4; return(BitConverter.ToInt32(data, position - 4)); } if (valueType == typeof(long)) { position += 8; return(BitConverter.ToInt64(data, position - 8)); } if (valueType == typeof(byte)) { position += 1; return(data[position - 1]); } if (valueType == typeof(short)) { position += 2; return(BitConverter.ToInt16(data, position - 2)); } if (valueType == typeof(char)) { position += 2; return(BitConverter.ToChar(data, position - 2)); } if (valueType == typeof(decimal)) { var i0 = BitConverter.ToInt32(data, position); var i1 = BitConverter.ToInt32(data, position + 4); var i2 = BitConverter.ToInt32(data, position + 8); var i3 = BitConverter.ToInt32(data, position + 12); position += 16; return((dynamic) new Decimal(new int[] { i0, i1, i2, i3 })); } if (valueType == typeof(double)) { position += 8; return(BitConverter.ToDouble(data, position - 8)); } if (valueType == typeof(float)) { position += 4; return(BitConverter.ToSingle(data, position - 4)); } if (valueType == typeof(uint)) { position += 4; return(BitConverter.ToUInt32(data, position - 4)); } if (valueType == typeof(ulong)) { position += 8; return(BitConverter.ToUInt64(data, position - 8)); } if (valueType == typeof(ushort)) { position += 2; return(BitConverter.ToUInt16(data, position - 2)); } if (valueType == typeof(sbyte)) { position += 1; return((sbyte)((int)data[position - 1] - 128)); } if (valueType == typeof(bool)) { position += 1; return(BitConverter.ToBoolean(data, position - 1)); } if (valueType == typeof(DateTime)) { position += 8; return(new DateTime(BitConverter.ToInt64(data, position - 8))); } if (valueType == typeof(string)) { if (data[position] == 0) { position += 1; return((string)null); } var len = (int)data[position] >> 1; position += len + 1; return(System.Text.Encoding.UTF8.GetString(data, position - len, len)); } if (valueType == typeof(Enum)) { var baseType = Enum.GetUnderlyingType(valueType); return(ShardKey <TRecord> .ConvertFromBytes(data, ref position, baseType)); } if (valueType == typeof(Nullable)) { var isNull = BitConverter.ToBoolean(data, position); position += 1; if (isNull) { return(null); } var baseType = Nullable.GetUnderlyingType(valueType); return(ConvertFromBytes(data, ref position, baseType)); } if (valueType == typeof(Guid)) { var result = new Guid(new byte[] { data[position], data[position + 1], data[position + 2], data[position + 3], data[position + 4], data[position + 5], data[position + 6], data[position + 7], data[position + 8], data[position + 9], data[position + 10], data[position + 11], data[position + 12], data[position + 13], data[position + 14], data[position + 15] }); position += 16; return(result); } else { throw new Exception($"Could not recognized the type {valueType.ToString()}."); } }