private void SerializeType(Type type, object value, TableMemberAttribute attribute) { if (type.IsPrimitive) { SerializePrimitive(type, value); } else if (type.IsEnum) { var underlyingType = type.GetEnumUnderlyingType(); SerializeType(underlyingType, value, attribute); } else if (type.IsArray) { SerializeArray(type, (Array)value, attribute); } else if (type.IsClass || type.IsValueType) { if (type == typeof(string)) { SerializeString((string)value, attribute); } else { SerializeClassOrValueType(type, value); } } else { throw new NotImplementedException("Type not implemented"); } }
private object DeserializeType(Type type, TableMemberAttribute attribute, int segmentLength = -1) { if (type.IsPrimitive) { return(DeserializePrimitive(type)); } else if (type.IsEnum) { var underlyingType = type.GetEnumUnderlyingType(); return(Enum.ToObject(type, DeserializePrimitive(underlyingType))); } else if (type.IsArray) { return(DeserializeArray(type, attribute, segmentLength)); } else if (type.IsClass || type.IsValueType) { if (type == typeof(string)) { return(DeserializeString(attribute)); } else { return(DeserializeClassOrValueType(type)); } } else { throw new NotImplementedException("Type not implemented"); } }
private void SerializeMember(object instance, MemberInfo memberInfo, TableMemberAttribute attribute) { var type = memberInfo.GetMemberType(); var value = memberInfo.GetValue <object>(instance); SerializeType(type, value, attribute); }
private void SerializeArray(Type type, Array array, TableMemberAttribute attribute) { var elementType = type.GetElementType(); for (int i = 0; i < array.Length; i++) { SerializeType(elementType, array.GetValue(i), attribute); } }
private Array DeserializeComplexArray(Type elementType, TableMemberAttribute attribute, int elementCount) { Array array = Array.CreateInstance(elementType, elementCount); for (int i = 0; i < array.Length; i++) { array.SetValue(DeserializeType(elementType, attribute), i); } return(array); }
private string DeserializeString(TableMemberAttribute attribute) { if (attribute.FixedStringLength == -1) { throw new Exception("Fixed string length must be specified"); } var bytes = mReader.ReadBytes(attribute.FixedStringLength); var str = string.Empty; for (int i = 0; i < bytes.Length; i++) { if (bytes[i] == 0) { break; } if (bytes[i] >= 0x80) { str += (char)(bytes[i++] | bytes[i] << 8); } else { str += (char)bytes[i]; } } mReader.SeekCurrent(1); /* * var bytes = mReader.ReadBytes(attribute.FixedStringLength); * var str = string.Empty; * for (int i = 0; i < bytes.Length; i++) * { * if (bytes[i] == 0) * break; * * if (bytes[i] >= 0x80) * { * str += TextEncoding.GetCharacter((ushort) (bytes[i++] << 8 | bytes[i])); * } * else * { * str += TextEncoding.GetCharacter(bytes[i]); * } * } */ return(str); }
private void DeserializeSegment(object instance, MemberInfo memberInfo, TableMemberAttribute attribute) { int segmentLength = ReadSegmentLength(); long segmentEnd = mReader.Position + segmentLength; DeserializeMember(instance, memberInfo, attribute, segmentLength); if (mReader.Position < segmentEnd) { throw new Exception("Not enough data read from table segment"); } else if (mReader.Position > segmentEnd) { throw new Exception("Read past end of table segment"); } mReader.Position = AlignmentHelper.Align(mReader.Position, 16); }
private Array DeserializeArray(Type type, TableMemberAttribute attribute, int segmentLength = -1) { var elementType = type.GetElementType(); int elementCount = attribute.FixedArrayLength; if (elementCount == -1 && attribute.MemberType == TableMemberType.Segment) { if (segmentLength == -1) { throw new ArgumentOutOfRangeException(nameof(segmentLength), "Segment length should be equal to or more than 0"); } if (!elementType.IsPrimitive) { throw new Exception("A segment with implicit array length must be of a primitive type"); } int elementSize = Marshal.SizeOf(elementType); elementCount = segmentLength / elementSize; } if (elementType.IsPrimitive) { return(DeserializePrimitiveArray(elementType, elementCount)); } else if (elementType.IsEnum) { var array = DeserializePrimitiveArray(elementType.GetEnumUnderlyingType(), elementCount); var array2 = Array.CreateInstance(elementType, elementCount); for (int i = 0; i < array.Length; i++) { array2.SetValue(Enum.ToObject(elementType, array.GetValue(i)), i); } return(array2); } else { return(DeserializeComplexArray(elementType, attribute, elementCount)); } }
private void SerializeSegment(object instance, MemberInfo memberInfo, TableMemberAttribute attribute) { // save position & write dummy value mWriter.EnqueuePosition(); mWriter.Write((int)0); // write segment data SerializeMember(instance, memberInfo, attribute); // save end position for calculating segment length & continuing mWriter.EnqueuePosition(); // seek back to write the segment length mWriter.SeekBeginToDequeuedPosition(); mWriter.Write((int)((mWriter.PeekEnqueuedPosition() - mWriter.BaseStream.Position) - 4)); // seek back to continue writing mWriter.SeekBeginToDequeuedPosition(); // write alignment padding WriteSegmentPadding(); }
private void SerializeVariableLengthStringSegmentPair(object instance, MemberInfo memberInfo, TableMemberAttribute attribute) { // get strings from the field or property var strings = memberInfo.GetValue <string[]>(instance); // calculate the size of the index buffer and write it to the stream int indexBufferSize = strings.Length * sizeof(short); mWriter.Write(indexBufferSize); // calculate the size of the string buffer while also writing out the // start index of each individual string int stringBufferSize = 0; foreach (var s in strings) { // write the starting index of each string mWriter.Write((short)stringBufferSize); foreach (char c in s) { if (c >= 0x80) { stringBufferSize += 2; } else { stringBufferSize += 1; } } // 0 terminator stringBufferSize += 1; } // write padding WriteSegmentPadding(); // write the size of the string buffer mWriter.Write(stringBufferSize); foreach (var s in strings) { for (var i = 0; i < s.Length; i++) { if (s[i] >= 0x80) { mWriter.Write((byte)(s[i] & 0x00FF)); mWriter.Write((byte)((s[i] & 0xFF00) >> 8)); } else { mWriter.Write((byte)(s[i] & 0x00FF)); } } mWriter.Write((byte)0); } // write padding WriteSegmentPadding(); }
private void SerializeString(string value, TableMemberAttribute attribute) { if (attribute.FixedStringLength == -1) { throw new Exception("Fixed string length must be specified"); } var bytes = Encoding.Unicode.GetBytes(value); int bytesWritten = 0; for (int i = 0; i < bytes.Length; i++) { if (bytesWritten == attribute.FixedStringLength) { break; } /* * if (bytes[i] >= 0x80) * { * mWriter.Write(bytes[i++]); * mWriter.Write(bytes[i]); * bytesWritten += 2; * } * else * { */ mWriter.Write(bytes[i++]); bytesWritten += 1; //} } int leftOver = (attribute.FixedStringLength + 1) - bytesWritten; while (leftOver > 0) { mWriter.Write((byte)0); leftOver--; } /* * int bytesWritten = 0; * for (int i = 0; i < value.Length; i++) * { * ushort characterCode = TextEncoding.GetCharacterCode(value[i]); * if (characterCode <= 0x7F) * { * mWriter.Write((byte) (characterCode & 0x00FF)); * bytesWritten += 1; * } * else * { * mWriter.Write((byte) (characterCode & 0xFF00)); * mWriter.Write((byte) (characterCode & 0x00FF)); * bytesWritten += 2; * } * } * * int leftOver = attribute.FixedStringLength - bytesWritten; * while (leftOver-- > 0) * mWriter.Write((byte)0); */ }
private void DeserializeVariableLengthStringSegmentPair(object instance, MemberInfo memberInfo, TableMemberAttribute attribute) { int segmentLength = ReadSegmentLength(); var indices = mReader.ReadInt16s(segmentLength / sizeof(short)); mReader.Position = AlignmentHelper.Align(mReader.Position, 16); segmentLength = ReadSegmentLength(); var bytes = mReader.ReadBytes(segmentLength); mReader.Position = AlignmentHelper.Align(mReader.Position, 16); var stringBuilder = new StringBuilder(bytes.Length); var strings = new string[indices.Length]; for (int i = 0; i < strings.Length; i++) { int byteIndex = indices[i]; while (true) { if (bytes[byteIndex] == 0) { break; } if (bytes[byteIndex] >= 0x80) { stringBuilder.Append((char)(bytes[byteIndex++] | bytes[byteIndex] << 8)); } else { stringBuilder.Append((char)bytes[byteIndex]); } byteIndex++; } strings[i] = stringBuilder.ToString(); stringBuilder.Clear(); } memberInfo.SetValue(instance, strings); }
private void DeserializeMember(object instance, MemberInfo memberInfo, TableMemberAttribute attribute, int segmentLength = -1) { var type = memberInfo.GetMemberType(); memberInfo.SetValue(instance, DeserializeType(type, attribute, segmentLength)); }