Beispiel #1
0
        public bool ReceiveData(ClientInfo cInfo, string fileNameR, Stream fdR, long sizeR, string fileName, Stream fd, int totalSize)
        {
            IOStream f = cInfo.IoStream;

            byte[]    file_sum1 = new byte[CheckSum.MD4_SUM_LENGTH];
            byte[]    file_sum2 = new byte[CheckSum.MD4_SUM_LENGTH];
            byte[]    data      = new byte[Match.CHUNK_SIZE];
            SumStruct sum       = new SumStruct();
            MapFile   mapBuf    = null;
            Sender    sender    = new Sender(options);

            sender.ReadSumHead(cInfo, ref sum);
            int    offset = 0;
            UInt32 len;

            if (fdR != null && sizeR > 0)
            {
                int mapSize = (int)Math.Max(sum.bLength * 2, 16 * 1024);
                mapBuf = new MapFile(fdR, (int)sizeR, mapSize, (int)sum.bLength);
                if (options.verbose > 2)
                {
                    Log.WriteLine("recv mapped " + fileNameR + " of size " + sizeR);
                }
                ;
            }
            Sum s = new Sum(options);

            s.Init(options.checksumSeed);

            int   i;
            Token token = new Token(options);

            while ((i = token.ReceiveToken(f, ref data, 0)) != 0)
            {
                if (options.doProgress)
                {
                    Progress.ShowProgress(offset, totalSize);
                }

                if (i > 0)
                {
                    if (options.verbose > 3)
                    {
                        Log.WriteLine("data recv " + i + " at " + offset);
                    }
                    Options.stats.literalData += i;
                    s.Update(data, 0, i);
                    if (fd != null && FileIO.WriteFile(fd, data, 0, i) != i)
                    {
                        goto report_write_error;
                    }
                    offset += i;
                    continue;
                }

                i = -(i + 1);
                int offset2 = (int)(i * sum.bLength);
                len = sum.bLength;
                if (i == sum.count - 1 && sum.remainder != 0)
                {
                    len = sum.remainder;
                }

                Options.stats.matchedData += len;

                if (options.verbose > 3)
                {
                    Log.WriteLine("chunk[" + i + "] of size " + len + " at " + offset2 + " offset=" + offset);
                }

                byte[] map = null;
                int    off = 0;
                if (mapBuf != null)
                {
                    off = mapBuf.MapPtr(offset2, (int)len);
                    map = mapBuf.p;

                    token.SeeToken(map, offset, (int)len);
                    s.Update(map, off, (int)len);
                }

                if (options.inplace)
                {
                    if (offset == offset2 && fd != null)
                    {
                        offset += (int)len;
                        if (fd.Seek(len, SeekOrigin.Current) != offset)
                        {
                            MainClass.Exit("seek failed on " + Util.fullFileName(fileName), cInfo);
                        }
                        continue;
                    }
                }
                if (fd != null && FileIO.WriteFile(fd, map, off, (int)len) != (int)len)
                {
                    goto report_write_error;
                }
                offset += (int)len;
            }

            if (options.doProgress)
            {
                Progress.EndProgress(totalSize);
            }
            if (fd != null && offset > 0 && FileIO.SparseEnd(fd) != 0)
            {
                MainClass.Exit("write failed on " + Util.fullFileName(fileName), cInfo);
            }

            file_sum1 = s.End();

            if (mapBuf != null)
            {
                mapBuf = null;
            }

            file_sum2 = f.ReadBuf(CheckSum.MD4_SUM_LENGTH);
            if (options.verbose > 2)
            {
                Log.WriteLine("got fileSum");
            }
            if (fd != null && Util.MemCmp(file_sum1, 0, file_sum2, 0, CheckSum.MD4_SUM_LENGTH) != 0)
            {
                return(false);
            }
            return(true);

report_write_error:
            {
                MainClass.Exit("write failed on " + Util.fullFileName(fileName), cInfo);
            }
            return(true);
        }