/// <summary> /// 保存数据 /// </summary> /// <param name="writer">树型包写入器实例</param> /// <param name="password">密码,为空将会是默认密码。</param> public unsafe void Save(System.IO.Stream writer, byte[] password = null) { if (writer == null) { throw new ArgumentNullException("writer", "树型包写入器不能为 null 。"); } if (!writer.CanWrite) { throw new ArgumentNullException("writer", "树型包写入器当前不能进行写入操作。"); } if (password == null || password.Length == 0 || password == _defaultBinaryWavePassword) { if (_packageEntry.EncryptType != PackageEncryptTypes.BinaryWave_EmptyPassword) { _packageEntry.EncryptType = PackageEncryptTypes.BinaryWave_DefaultPassword; } password = _defaultBinaryWavePassword; } else { if (_packageEntry.EncryptType != PackageEncryptTypes.BinaryWave_EmptyPassword) { _packageEntry.EncryptType = PackageEncryptTypes.BinaryWave_CustomPassword; } } //if (writer.Closed) // throw new ObjectDisposedException("writer", "树型包写入器已经关闭。"); #region header 1 //StartFlag writer.Write(HeaderEntry.StartFlag, 0, HeaderEntry.StartFlag.Length); byte[] buffer = new byte[8]; //Version,EncryptType buffer[0] = (byte)(_packageEntry.Version * 10); buffer[0] += (byte)_packageEntry.EncryptType; //KeyIgnoreCase,HasAttributes,HasComment if (_packageEntry.KeyIgnoreCase) { buffer[1] = 100; } else { buffer[1] = 0; } _packageEntry.HasAttributes = _attributes != null && _attributes.Count > 0; if (_packageEntry.HasAttributes) { buffer[1] += 10; } _packageEntry.HasComment = !string.IsNullOrEmpty(_comment); if (_packageEntry.HasComment) { buffer[1] += 1; } writer.Write(buffer, 0, 2); #endregion using (Symbol.Encryption.BinaryEncryptionStream binaryEncryptionStream = new Symbol.Encryption.BinaryEncryptionStream(writer, password, EncryptType == PackageEncryptTypes.BinaryWave_EmptyPassword)) { int int32Var; #region header 2 //AttributesLength if (_packageEntry.HasAttributes) { if (_packageEntry.EncryptType == PackageEncryptTypes.BinaryWave_EmptyPassword) { _attributes.EncryptType = _packageEntry.EncryptType; } _packageEntry.AttributesData = _attributes.Save(); _packageEntry.AttributesLength = _packageEntry.AttributesData.Length; int32Var = _packageEntry.AttributesLength; Marshal.Copy((IntPtr)(&int32Var), buffer, 0, 4); binaryEncryptionStream.Write(buffer, 0, 4); } //CommentLength if (_packageEntry.HasComment) { _packageEntry.CommentData = System.Text.Encoding.UTF8.GetBytes(_comment); _packageEntry.CommentLength = _packageEntry.CommentData.Length; int32Var = _packageEntry.CommentLength; Marshal.Copy((IntPtr)(&int32Var), buffer, 0, 4); binaryEncryptionStream.Write(buffer, 0, 4); } //KeysCount int32Var = _entries.Count; Marshal.Copy((IntPtr)(&int32Var), buffer, 0, 4); binaryEncryptionStream.Write(buffer, 0, 4); //AttributesData if (_packageEntry.HasAttributes) { binaryEncryptionStream.Write(_packageEntry.AttributesData, 0, _packageEntry.AttributesData.Length); } //CommentData if (_packageEntry.HasComment) { binaryEncryptionStream.Write(_packageEntry.CommentData, 0, _packageEntry.CommentData.Length); } #endregion //header clear _packageEntry.AttributesData = null; _packageEntry.AttributesLength = 0; _packageEntry.CommentData = null; _packageEntry.CommentLength = 0; #region keys IEntry entry2; KeyEntry keyEntry; ushort uShortVar = 0; ulong uInt64Var = 0; byte[] bufferValueData = null; //Keys foreach (System.Collections.Generic.KeyValuePair <string, Entry> item in _entries) { entry2 = item.Value; keyEntry = entry2.KeyEntry; keyEntry.KeyData = System.Text.Encoding.UTF8.GetBytes(item.Key); uShortVar = keyEntry.KeyLength = (ushort)keyEntry.KeyData.Length; //0 1 ,KeyLength ushort Marshal.Copy((IntPtr)(&uShortVar), buffer, 0, 2); //ValueType,byte ,1 buffer[2] = (byte)keyEntry.ValueType; //Nullable,ArrayType if (keyEntry.Nullable) { buffer[3] = 100; } else { buffer[3] = 0; } buffer[3] += (byte)keyEntry.ArrayType; //HasAttributes,CompressType keyEntry.HasAttributes = item.Value.Attributes != null && item.Value.Attributes.Count > 0; if (keyEntry.HasAttributes) { buffer[4] = 100; if (_packageEntry.EncryptType == PackageEncryptTypes.BinaryWave_EmptyPassword) { item.Value.Attributes.EncryptType = _packageEntry.EncryptType; } keyEntry.AttributesData = item.Value.Attributes.Save(); keyEntry.AttributesLength = keyEntry.AttributesData.Length; } else { buffer[4] = 0; } buffer[4] += (byte)keyEntry.CompressType; binaryEncryptionStream.Write(buffer, 0, 5); if (keyEntry.HasAttributes) //AttributesLength { int32Var = keyEntry.AttributesLength; Marshal.Copy((IntPtr)(&int32Var), buffer, 0, 4); binaryEncryptionStream.Write(buffer, 0, 4); } //ValueDataLength if (!keyEntry.Nullable) { bufferValueData = PackageValueData(keyEntry, item.Value); int32Var = keyEntry.ValueDataLength = bufferValueData.Length; Marshal.Copy((IntPtr)(&int32Var), buffer, 0, 4); binaryEncryptionStream.Write(buffer, 0, 4); //CRC32 uInt64Var = keyEntry.CRC32 = Symbol.Encryption.CRC32EncryptionHelper.Encrypt(bufferValueData); Marshal.Copy((IntPtr)(&uInt64Var), buffer, 0, 8); binaryEncryptionStream.Write(buffer, 0, 8); } //KeyData binaryEncryptionStream.Write(keyEntry.KeyData, 0, keyEntry.KeyLength); //AttributesData if (keyEntry.HasAttributes) { binaryEncryptionStream.Write(keyEntry.AttributesData, 0, keyEntry.AttributesLength); } //ValueData if (!keyEntry.Nullable) { // if (keyEntry.CompressType == PackageCompressTypes.NonEncrypt_NonCompress) { binaryEncryptionStream.BaseWrite(bufferValueData, 0, keyEntry.ValueDataLength); } else { binaryEncryptionStream.Write(bufferValueData, 0, keyEntry.ValueDataLength); } } bufferValueData = null; keyEntry.AttributesData = null; keyEntry.KeyData = null; entry2 = null; } #endregion } }
/// <summary> /// 加载数据 /// </summary> /// <param name="reader">树型包读取器实例</param> /// <param name="password">密码,为空将会是默认密码。</param> /// <returns>返回加载后的树型包实例。</returns> public static unsafe TreePackage Load(System.IO.Stream reader, byte[] password = null) { //if (reader == null) // throw new ArgumentNullException("reader", "树型包读取器不能为 null 。"); if (reader == null) { return(null); } if (!reader.CanRead) { throw new ArgumentNullException("reader", "树型包读取器不能进行读取操作。"); } //if (reader.Closed) // throw new ObjectDisposedException("reader", "树型包读取器已经关闭。"); #region header 1 byte[] buffer = new byte[8]; if (reader.Read(buffer, 0, 4) != 4) //位数不够 { return(null); } //错误的标识 if (buffer[0] != HeaderEntry.StartFlag[0] || buffer[1] != HeaderEntry.StartFlag[1] || buffer[2] != HeaderEntry.StartFlag[2] || buffer[3] != HeaderEntry.StartFlag[3]) { return(null); } HeaderEntry packageEntry = new HeaderEntry(); packageEntry.Started = true; //Version,EncryptType if (reader.Read(buffer, 0, 2) != 2) { return(null); } if (buffer[0] > 9) { packageEntry.Version = (byte)(buffer[0] / 10); buffer[0] -= (byte)(packageEntry.Version * 10); } packageEntry.EncryptType = (PackageEncryptTypes)buffer[0]; //KeyIgnoreCase,HasAttributes,HasComment if (buffer[1] >= 100) { packageEntry.KeyIgnoreCase = true; buffer[1] -= 100; } if (buffer[1] >= 10) { packageEntry.HasAttributes = true; buffer[1] -= 10; } if (buffer[1] == 1) { packageEntry.HasComment = true; } #endregion if (password == null || password.Length == 0 || password == _defaultBinaryWavePassword) { password = _defaultBinaryWavePassword; if (packageEntry.EncryptType != PackageEncryptTypes.BinaryWave_EmptyPassword) { packageEntry.EncryptType = PackageEncryptTypes.BinaryWave_DefaultPassword; } } else { if (packageEntry.EncryptType != PackageEncryptTypes.BinaryWave_EmptyPassword) { packageEntry.EncryptType = PackageEncryptTypes.BinaryWave_CustomPassword; } } TreePackage result = null; using (Symbol.Encryption.BinaryEncryptionStream binaryEncryptionStream = new Symbol.Encryption.BinaryEncryptionStream(reader, password, packageEntry.EncryptType == PackageEncryptTypes.BinaryWave_EmptyPassword)) { int int32Var; #region header 2 //AttributesLength if (packageEntry.HasAttributes) { if (binaryEncryptionStream.Read(buffer, 0, 4) != 4) { return(null); } Marshal.Copy(buffer, 0, (IntPtr)(&int32Var), 4); packageEntry.AttributesLength = int32Var; } //CommentLength if (packageEntry.HasComment) { if (binaryEncryptionStream.Read(buffer, 0, 4) != 4) { return(null); } Marshal.Copy(buffer, 0, (IntPtr)(&int32Var), 4); packageEntry.CommentLength = int32Var; } //KeysCount if (binaryEncryptionStream.Read(buffer, 0, 4) != 4) { return(null); } Marshal.Copy(buffer, 0, (IntPtr)(&int32Var), 4); packageEntry.KeysCount = int32Var; //AttributesData if (packageEntry.HasAttributes) { packageEntry.AttributesData = new byte[packageEntry.AttributesLength]; if (binaryEncryptionStream.Read(packageEntry.AttributesData, 0, packageEntry.AttributesLength) != packageEntry.AttributesLength) { return(null); } } //CommentData if (packageEntry.HasComment) { packageEntry.CommentData = new byte[packageEntry.CommentLength]; if (binaryEncryptionStream.Read(packageEntry.CommentData, 0, packageEntry.CommentLength) != packageEntry.CommentLength) { return(null); } } #endregion result = new TreePackage(packageEntry); #region Keys //Keys ushort uShortVar = 0; ulong uInt64Var = 0; KeyEntry keyEntry; byte[] bufferValueData = null; Entry entry = null; for (int keyIndex = 0; keyIndex < packageEntry.KeysCount; keyIndex++) { #region Header if (binaryEncryptionStream.Read(buffer, 0, 5) != 5) { return(null); } //KeyLength Marshal.Copy(buffer, 0, (IntPtr)(&uShortVar), 2); keyEntry = new KeyEntry(); keyEntry.KeyLength = uShortVar; if (keyEntry.KeyLength == 0) { return(null); } //ValueType keyEntry.ValueType = (PackageValueTypes)buffer[2]; //Nullable|ArrayType if (buffer[3] >= 100) { keyEntry.Nullable = true; buffer[3] -= 100; } keyEntry.ArrayType = (PackageArrayTypes)buffer[3]; //HasAttributes,CompressType if (buffer[4] >= 100) { keyEntry.HasAttributes = true; buffer[4] -= 100; } keyEntry.CompressType = (PackageCompressTypes)buffer[4]; if (keyEntry.HasAttributes) //AttributesLength { if (binaryEncryptionStream.Read(buffer, 0, 4) != 4) { return(null); } Marshal.Copy(buffer, 0, (IntPtr)(&int32Var), 4); keyEntry.AttributesLength = int32Var; } //ValueDataLength if (!keyEntry.Nullable) { if (binaryEncryptionStream.Read(buffer, 0, 4) != 4) { return(null); } Marshal.Copy(buffer, 0, (IntPtr)(&int32Var), 4); keyEntry.ValueDataLength = int32Var; //CRC32 if (binaryEncryptionStream.Read(buffer, 0, 8) != 8) { return(null); } Marshal.Copy(buffer, 0, (IntPtr)(&uInt64Var), 8); keyEntry.CRC32 = uInt64Var; } #endregion #region Data //KeyData keyEntry.KeyData = new byte[keyEntry.KeyLength]; if (binaryEncryptionStream.Read(keyEntry.KeyData, 0, keyEntry.KeyLength) != keyEntry.KeyLength) { return(null); } //AttributesData if (keyEntry.HasAttributes) { keyEntry.AttributesData = new byte[keyEntry.AttributesLength]; if (binaryEncryptionStream.Read(keyEntry.AttributesData, 0, keyEntry.AttributesLength) != keyEntry.AttributesLength) { return(null); } } entry = new Entry(keyEntry); ((IEntry)entry).SetIsAdd(false); //ValueData if (!keyEntry.Nullable) { bufferValueData = new byte[keyEntry.ValueDataLength]; if (keyEntry.CompressType == PackageCompressTypes.NonEncrypt_NonCompress) { if (binaryEncryptionStream.BaseRead(bufferValueData, 0, keyEntry.ValueDataLength) != keyEntry.ValueDataLength) { return(null); } } else { if (binaryEncryptionStream.Read(bufferValueData, 0, keyEntry.ValueDataLength) != keyEntry.ValueDataLength) { return(null); } } uInt64Var = Symbol.Encryption.CRC32EncryptionHelper.Encrypt(bufferValueData); if (uInt64Var != keyEntry.CRC32) { throw new System.IO.InvalidDataException(string.Format("“{0}”的CRC32数据验证失败。应为:{1:X8},实际:{2:X8}", entry.Key, keyEntry.CRC32, uInt64Var)); } UnPackageValueData(keyEntry, entry, bufferValueData, result); } else { entry.Value = null; } #endregion bufferValueData = null; result.Add(entry); } #endregion } return(result); }