Exemple #1
0
        //[TestMore]
        public bool RemoveData(string key)
        {
            long iIdx = 0;
            int  iLen = 0, CurrentIndexSize = GetIndexSize();

            if (!ExistsDataKey(key, out iIdx, out iLen))
            {
                return(false);
            }
            else
            {
                //remove index data, make as dirty
                IndexObject.Remove(key);
                SetKeyCount(GetKeyCount() - 1);

                byte[] idxBytes = FileWrapHelper.GetBytes(IndexObject);
                //更新索引内容实际大小
                if (UpdateDynamicBytes((long)GetNextIndexWriteOffset(), idxBytes, CurrentIndexSize, 24))
                {
                    IncrementIndexSize();
                    UpdateDynamicBytes((long)GetNextIndexWriteOffset(), idxBytes, CurrentIndexSize, 24);

                    _currentDatOffset = GetOffSetDat <int>(_internalReader, 12);
                    CurrentIndexSize  = GetIndexSize();
                }

                #region Update Dirty Block
                SortedList <long, DirtyBlock> dObjs = GetStoreDirtyData();
                DirtyBlock dBlock = new DirtyBlock {
                    DataIndex = iIdx, Length = iLen
                };
                if (DirtyObject.ContainsKey(dBlock.DataIndex))
                {
                    //[impossible]
                    DirtyObject[dBlock.DataIndex] = dBlock;
                }
                else
                {
                    DirtyObject.Add(dBlock.DataIndex, dBlock);
                }

                byte[] dBytes = FileWrapHelper.GetBytes(DirtyObject);
                if (UpdateDynamicBytes((long)(HEAD_SUMMARY_BYTES + CurrentIndexSize), dBytes, MAX_DIRTYBLOCK_SIZE, HEAD_SUMMARY_BYTES - 9))
                {
                    ClearDirtyData();
                    UpdateDynamicBytes((long)(HEAD_SUMMARY_BYTES + CurrentIndexSize), dBytes, MAX_DIRTYBLOCK_SIZE, HEAD_SUMMARY_BYTES - 9);
                }
                #endregion

                return(true);
            }
        }
Exemple #2
0
 internal SortedList <string, KeyValueState> GetIndexObject(int?idxCount)
 {
     if (IndexObject == null)
     {
         byte[] idxBytes = ReadData((long)GetNextIndexWriteOffset(),
                                    (idxCount.HasValue && idxCount.Value != 0) ? idxCount.Value : GetIndexRealSize());
         //Console.WriteLine("Idx Len: {0}", idxBytes.Length);
         if (idxBytes.Length > 0)
         {
             //Console.WriteLine("Restore");
             IndexObject = FileWrapHelper.GetObject <SortedList <string, KeyValueState> >(idxBytes);
         }
         else
         {
             IndexObject = new SortedList <string, KeyValueState>(StringComparer.Ordinal);
         }
     }
     return(IndexObject);
 }
Exemple #3
0
 internal SortedList <long, DirtyBlock> GetStoreDirtyData()
 {
     if (DirtyObject == null)
     {
         int dCount = GetDirtyBlockRealSize();
         if (dCount > 0)
         {
             byte[] idxBytes = ReadData((long)(HEAD_SUMMARY_BYTES + GetIndexSize()), dCount);
             if (idxBytes.Length > 0)
             {
                 DirtyObject = FileWrapHelper.GetObject <SortedList <long, DirtyBlock> >(idxBytes);
             }
         }
         else
         {
             DirtyObject = new SortedList <long, DirtyBlock>();
         }
     }
     return(DirtyObject);
 }
Exemple #4
0
        private void BuildEmptyFile()
        {
            _internalWriter.Write(Encoding.ASCII.GetBytes("KVS 1.0 "));                             //文件版本                      +8
            _internalWriter.Write(BitConverter.GetBytes(HeadIndexLength));                          //索引空间长度                  +4

            _internalWriter.Write(BitConverter.GetBytes((int)0));                                   //数据索引偏移量                +4
            _internalWriter.Write(BitConverter.GetBytes((long)0));                                  //下次写入数据索引              +8

            byte[] idxBytes = FileWrapHelper.GetBytes(new SortedList <string, KeyValueState>(StringComparer.Ordinal));
            KeepPositionWrite(HEAD_SUMMARY_BYTES, idxBytes);
            _internalWriter.Write(BitConverter.GetBytes(idxBytes.Length));                          //索引有效数据长度              +4

            _internalWriter.Write(BitConverter.GetBytes(MAX_DIRTYBLOCK_SIZE));                      //DirtyBlock空间长度            +4

            byte[] dbBytes = FileWrapHelper.GetBytes(new SortedList <long, DirtyBlock>());
            KeepPositionWrite(HEAD_SUMMARY_BYTES + HeadIndexLength, dbBytes);
            _internalWriter.Write(BitConverter.GetBytes(dbBytes.Length));                           //DirtyBlock有效数据长度        +4

            _internalWriter.Write(BitConverter.GetBytes((int)0));                                   //所有键值总数                  +4
            _internalWriter.Write('\n');                                                            //                              +1
        }
Exemple #5
0
        public static void DecryptStream(Stream fin, Stream fout, string password, WrapProgressCallBack callback)
        {
            int size = (int)fin.Length;              // the size of the file for progress notification

            byte[] bytes    = new byte[BUFFER_SIZE]; // byte buffer
            int    read     = -1;                    // the amount of bytes read from the stream
            int    value    = 0;
            int    outValue = 0;                     // the amount of bytes written out

            // read off the IV and Salt
            byte[] IV = new byte[16];
            fin.Read(IV, 0, 16);

            byte[] salt = new byte[16];
            fin.Read(salt, 0, 16);

            // create the crypting stream
            SymmetricAlgorithm sma = FileWrapHelper.CreateRijndael(password, salt);

            sma.IV = IV;

            value = 32;      // the value for the progress
            long lSize = -1; // the size stored in the input stream

            // create the hashing object, so that we can verify the file
            HashAlgorithm hasher = SHA256.Create();

            // create the cryptostreams that will process the file
            using (CryptoStream cin = new CryptoStream(fin, sma.CreateDecryptor(), CryptoStreamMode.Read),
                   chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write))
            {
                // read size from file
                BinaryReader br = new BinaryReader(cin);
                lSize = br.ReadInt64();

                ulong tag = br.ReadUInt64();
                if (FC_TAG != tag)
                {
                    throw new FileWrapException("File Corrupted!");
                }

                //determine number of reads to process on the file
                long numReads = lSize / BUFFER_SIZE;

                // determine what is left of the file, after numReads
                long slack = (long)lSize % BUFFER_SIZE;

                // read the buffer_sized chunks
                for (int i = 0; i < numReads; ++i)
                {
                    read = cin.Read(bytes, 0, bytes.Length);
                    fout.Write(bytes, 0, read);
                    chash.Write(bytes, 0, read);
                    value    += read;
                    outValue += read;
                    if (callback != null)
                    {
                        callback(0, size, value);
                    }
                }

                // now read the slack
                if (slack > 0)
                {
                    read = cin.Read(bytes, 0, (int)slack);
                    fout.Write(bytes, 0, read);
                    chash.Write(bytes, 0, read);
                    value    += read;
                    outValue += read;
                    if (callback != null)
                    {
                        callback(0, size, value);
                    }
                }
                // flush and close the hashing stream
                chash.Flush();
                chash.Close();

                // flush and close the output file
                fout.Flush();
                fout.Close();

                // read the current hash value
                byte[] curHash = hasher.Hash;

                // get and compare the current and old hash values
                byte[] oldHash = new byte[hasher.HashSize / 8];
                read = cin.Read(oldHash, 0, oldHash.Length);
                if ((oldHash.Length != read) || (!CheckByteArrays(oldHash, curHash)))
                {
                    throw new FileWrapException("File Corrupted!");
                }
            }

            // make sure the written and stored size are equal
            if (outValue != lSize)
            {
                throw new FileWrapException("File Sizes don't match!");
            }
        }
Exemple #6
0
        public static void EncryptStream(Stream fin, Stream fout, string password, WrapProgressCallBack callback)
        {
            long lSize = fin.Length;              // the size of the input file for storing
            int  size  = (int)lSize;              // the size of the input file for progress

            byte[] bytes = new byte[BUFFER_SIZE]; // the buffer
            int    read  = -1;                    // the amount of bytes read from the input file
            int    value = 0;                     // the amount overall read from the input file for progress

            // generate IV and Salt
            byte[] IV   = GenerateRandomBytes(16);
            byte[] salt = GenerateRandomBytes(16);

            // create the crypting object
            SymmetricAlgorithm sma = FileWrapHelper.CreateRijndael(password, salt);

            sma.IV = IV;

            // write the IV and salt to the beginning of the file
            fout.Write(IV, 0, IV.Length);
            fout.Write(salt, 0, salt.Length);

            // create the hashing and crypto streams
            HashAlgorithm hasher = SHA256.Create();

            using (CryptoStream cout = new CryptoStream(fout, sma.CreateEncryptor(), CryptoStreamMode.Write),
                   chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write))
            {
                // write the size of the file to the output file
                BinaryWriter bw = new BinaryWriter(cout);
                bw.Write(lSize);

                // write the file cryptor tag to the file
                bw.Write(FC_TAG);

                // read and the write the bytes to the crypto stream in BUFFER_SIZEd chunks
                while ((read = fin.Read(bytes, 0, bytes.Length)) != 0)
                {
                    cout.Write(bytes, 0, read);
                    chash.Write(bytes, 0, read);
                    value += read;
                    if (callback != null)
                    {
                        callback(0, size, value);
                    }
                }
                // flush and close the hashing object
                chash.Flush();
                chash.Close();

                // read the hash
                byte[] hash = hasher.Hash;

                // write the hash to the end of the file
                cout.Write(hash, 0, hash.Length);

                // flush and close the cryptostream
                cout.Flush();
                cout.Close();
                cout.Dispose();
            }
        }
Exemple #7
0
        //[TestMore]
        public bool StoreKeyData(string key, byte[] kDat)
        {
            long iIdx = 0;
            int  iLen = 0, CurrentIndexSize = GetIndexSize();
            //Read
            long nDataIndex = GetOffSetDat <long>(_internalReader, 16);

            if (nDataIndex == 0)
            {
                nDataIndex = HEAD_SUMMARY_BYTES + (long)CurrentIndexSize + MAX_DIRTYBLOCK_SIZE;
            }
            //Console.WriteLine("Store Index: {0}", nDataIndex);

            bool addNew = false, append = false;
            SortedList <string, KeyValueState> idxObj = GetIndexObject(null);

            KeyValueState kState = new KeyValueState();

            kState.Key    = key;
            kState.Length = kDat.Length;

            if (idxObj == null)
            {
                IndexObject = new SortedList <string, KeyValueState>(StringComparer.Ordinal);
                addNew      = true;
            }
            else
            {
                if (!ExistsDataKey(key, out iIdx, out iLen))
                {
                    addNew = true;
                    append = true;
                    //Console.WriteLine("Note Exists Key" + key);
                }
                else
                {
                    KeyValueState oldState = IndexObject[key];
                    if ((oldState.Length + oldState.ChipSize) >= kDat.Length)
                    {
                        append = false;

                        //Location Update
                        nDataIndex       = oldState.DataIndex + _currentDatOffset;
                        kState.DataIndex = oldState.DataIndex;
                        kState.ChipSize  = (oldState.Length + oldState.ChipSize) - kDat.Length;
                    }
                    else
                    {
                        kState.ChipSize = 0;
                        Console.WriteLine("old:{0}, new:{1}, other:{2}", oldState.DataIndex, nDataIndex, nDataIndex - _currentDatOffset);
                        if (nDataIndex == (oldState.DataIndex + _currentDatOffset + oldState.Length + oldState.ChipSize))
                        {
                            append = false;

                            nDataIndex       = oldState.DataIndex + _currentDatOffset;
                            kState.DataIndex = oldState.DataIndex;

                            //下次写入数据索引
                            KeepPositionWrite(16, BitConverter.GetBytes(nDataIndex + kDat.LongLength));

                            //Console.WriteLine("Location Append");
                        }
                        else
                        {
                            append = true;
                            SortedList <long, DirtyBlock> dirtyDat = GetStoreDirtyData();
                            #region Dirty Block
                            DirtyBlock dBlock = new DirtyBlock {
                                DataIndex = oldState.DataIndex, Length = oldState.Length + kState.ChipSize
                            };
                            //Console.WriteLine("Dirty: {0}+{1}", dBlock.DataIndex, dBlock.Length);
                            if (DirtyObject.ContainsKey(dBlock.DataIndex))
                            {
                                //[impossible]
                                DirtyObject[dBlock.DataIndex] = dBlock;
                            }
                            else
                            {
                                DirtyObject.Add(dBlock.DataIndex, dBlock);
                            }

                            byte[] dBytes = FileWrapHelper.GetBytes(DirtyObject);
                            if (UpdateDynamicBytes((long)(HEAD_SUMMARY_BYTES + CurrentIndexSize), dBytes, MAX_DIRTYBLOCK_SIZE, HEAD_SUMMARY_BYTES - 9))
                            {
                                ClearDirtyData();
                                UpdateDynamicBytes((long)(HEAD_SUMMARY_BYTES + CurrentIndexSize), dBytes, MAX_DIRTYBLOCK_SIZE, HEAD_SUMMARY_BYTES - 9);
                            }
                            #endregion
                        }
                    }
                }
            }

            if (append)
            {
                //在DirtyBlock总查找可用空间(TODO)

                storeStream.SetLength(storeStream.Length + kDat.Length);
                //下次写入数据索引
                KeepPositionWrite(16, BitConverter.GetBytes(nDataIndex + kDat.LongLength));

                //Console.WriteLine("test:{0}, {1}, {2}", nDataIndex, _currentDatOffset, nDataIndex - _currentDatOffset);
                kState.DataIndex = nDataIndex - _currentDatOffset;
            }

            if (addNew)
            {
                kState.ChipSize = 0;
                IndexObject.Add(key, kState);
                SetKeyCount(GetKeyCount() + 1);
                //Console.WriteLine("ADD New: Set {0}", GetKeyCount());
            }
            else
            {
                IndexObject[key] = kState;
            }

            byte[] idxBytes   = FileWrapHelper.GetBytes(IndexObject);
            bool   blnIndxAdd = false;
            //更新索引内容实际大小
            if (UpdateDynamicBytes((long)GetNextIndexWriteOffset(), idxBytes, CurrentIndexSize, 24))
            {
                IncrementIndexSize();
                nDataIndex += INDEX_INCREMENT_STEP;
                UpdateDynamicBytes((long)GetNextIndexWriteOffset(), idxBytes, CurrentIndexSize, 24);
                _currentDatOffset = GetOffSetDat <int>(_internalReader, 12);

                blnIndxAdd = true;
            }

            //Console.WriteLine("DataOffSet: {0}", _currentDatOffset);
            //Console.WriteLine("Store Index: {0}", nDataIndex);

            KeepPositionWrite(nDataIndex, kDat);

            //修改下次写入位置
            if (blnIndxAdd == true)
            {
                KeepPositionWrite(16, BitConverter.GetBytes(nDataIndex + kDat.LongLength));
            }
            return(true);
        }