Beispiel #1
0
        /// <summary>
        /// 生きているスレとdat落ちしているスレを分離
        /// </summary>
        /// <param name="oldBoard">ログが存在する板</param>
        /// <param name="newBoard">生きているスレの移転先</param>
        /// <param name="leaveItems">dat落ちしているスレが格納される</param>
        /// <param name="liveItems">生きているスレが格納される</param>
        private void Separate(BoardInfo oldBoard, BoardInfo newBoard,
                              out List <ThreadHeader> leaveItems, out List <ThreadHeader> liveItems)
        {
            leaveItems = new List <ThreadHeader>();
            liveItems  = new List <ThreadHeader>();

            if (cache.Exists(oldBoard))
            {
                List <ThreadHeader> oldItems   = GotThreadListIndexer.Read(cache, oldBoard);
                List <ThreadHeader> newItems   = new List <ThreadHeader>();
                ThreadListReader    listReader = null;

                if (oldItems.Count > 0)
                {
                    try {
                        listReader = TypeCreator.CreateThreadListReader(newBoard.Bbs);
                        listReader.Open(newBoard);

                        while (listReader.Read(newItems) != 0)
                        {
                            ;
                        }

                        // 移転先のスレ一覧に存在するログのみ移転 (dat落ちしているスレは移転しない)
                        foreach (ThreadHeader header in oldItems)
                        {
                            Predicate <ThreadHeader> p = new Predicate <ThreadHeader>(delegate(ThreadHeader h)
                            {
                                return(h.Key == header.Key);
                            });

                            if (newItems.Exists(p))
                            {
                                // 生きているスレの板情報を移転先板に書き換える
                                if (ThreadIndexer.Read(cache, header) != null)
                                {
                                    ThreadIndexer.Delete(cache, header);

                                    liveItems.Add(header);
                                    header.BoardInfo = newBoard;

                                    ThreadIndexer.Write(cache, header);
                                }
                            }
                            else
                            {
                                leaveItems.Add(header);
                            }
                        }
                    }
                    finally {
                        if (listReader != null)
                        {
                            listReader.Close();
                        }
                    }
                }
            }
        }
        public void Indexing(BoardInfo bi, string[] datFiles, DatIndexingCallback callback)
        {
            LocalThreadReader reader = new LocalThreadReader(new X2chThreadParser());
            float             length = datFiles.Length, current = 0;

            if (length == 0)
            {
                return;
            }

            foreach (string path in datFiles)
            {
                ThreadHeader header = new X2chThreadHeader();
                header.BoardInfo = bi;
                header.Key       = Path.GetFileNameWithoutExtension(path);
                int parsed;

                try
                {
                    if (!reader.__Open(path))
                    {
                        continue;
                    }

                    ResSetCollection buffer = new ResSetCollection();
                    int byteCount           = 0;

                    while (reader.Read(buffer, out parsed) != 0)
                    {
                        byteCount += parsed;
                    }

                    if (buffer.Count > 0)
                    {
                        header.GotByteCount = byteCount;
                        header.ResCount     = buffer.Count;
                        header.GotResCount  = buffer.Count;
                        header.LastModified = File.GetLastWriteTime(path);
                        header.UseGzip      = false;
                        header.Subject      = buffer[0].Tag as String;

                        ThreadIndexer.Write(
                            Path.ChangeExtension(path, ".idx"), header);
                    }

                    if (callback != null)
                    {
                        callback(++current / length * 100f);
                    }
                }
                finally
                {
                    reader.Close();
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// oldBoardからnewBoardにログを移動
        /// </summary>
        /// <param name="oldItems"></param>
        /// <param name="newBoard"></param>
        private void CopyDatFiles(BoardInfo oldItems, BoardInfo newBoard)
        {
            string fromFolder = cache.GetFolderPath(oldItems);
            string toFolder   = cache.GetFolderPath(newBoard, true);

            string[] fileNames = Directory.GetFiles(fromFolder, "*.dat*");            // .dat .dat.gz を検索

            foreach (string fromPath in fileNames)
            {
                try {
                    string fromName = Path.GetFileName(fromPath);
                    string destPath = Path.Combine(toFolder, fromName);

                    File.Copy(fromPath, destPath, true);
                    File.Delete(fromPath);

                    int token = fromName.IndexOf('.');
                    if (token != -1)
                    {
                        string key           = fromName.Substring(0, token);
                        string fromIndexFile = Path.Combine(fromFolder, key + ".idx");
                        string toIndexFile   = Path.Combine(toFolder, key + ".idx");

                        ThreadHeader h = ThreadIndexer.Read(fromIndexFile);

                        if (h != null)
                        {
                            h.BoardInfo.Server = newBoard.Server;

                            ThreadIndexer.Write(toIndexFile, h);

                            File.Delete(fromIndexFile);
                        }
                    }
                }
                catch (IOException ex)
                {
                    TwinDll.Output(ex);
                }
            }
        }
        private void OpenInternal()
        {
            CompleteStatus status = CompleteStatus.Success;

            try
            {
                try
                {
                    isWaiting = true;
                    OnLoading(new EventArgs());
                }
                finally
                {
                    isWaiting = false;
                }
                if (canceled)
                {
                    return;
                }

                // 開く処理を行う
                if (modeOpen)
                {
                    Invoke(new MethodInvoker(Opening));
                }

                // キャッシュを読み込み表示
                ReadCache(resCollection);

                if (canceled)
                {
                    return;
                }

                Invoke(new MethodInvoker(WriteBegin));

                if (canceled)
                {
                    return;
                }

                if (modeOpen)
                {
                    Invoke(new WriteResMethodInvoker(Write), new object[] { resCollection });

                    // スクロール位置を復元 (値が0の場合は復元しない)
                    if (modeOpen && headerInfo.Position != 0.0f)
                    {
                        Invoke(new PositionMethodInvoker(SetScrollPosition),
                               new object[] { headerInfo.Position });
                    }
                }

Retry:
                try
                {
                    // サーバーに接続
                    if (OpenReader())
                    {
                        if (canceled)
                        {
                            return;
                        }

                        Reading();

                        // あぼーんを検知した場合
                        if (aboneDetected)
                        {
                        }
                    }
                    else
                    {
                        headerInfo.NewResCount = 0;
                        ThreadIndexer.Write(Cache, headerInfo);
                    }
                }
                finally
                {
                    if (reader != null)
                    {
                        reader.Close();
                    }
                }

                // 再試行が要求された場合、最初から
                if (retried)
                {
                    goto Retry;
                }

                if (canceled)
                {
                    return;
                }


                Invoke(new MethodInvoker(WriteEnd));
            }
            catch (Exception ex)
            {
                status = CompleteStatus.Error;
                //			isOpen = false; #10/15
                TwinDll.Output(ex);
                OnStatusTextChanged(ex.Message);
            }
            finally
            {
                // 中止された場合はETagをリセット
                if (canceled)
                {
                    headerInfo.ETag = String.Empty;
                }

                indicesValues.Clear();

                canceled = false;

                lock (syncObject)
                    thread = null;

                if (status == CompleteStatus.Success)
                {
                    OnStatusTextChanged(
                        String.Format("{0}の読み込みを完了 (新着: {1}件)",
                                      headerInfo.Subject, headerInfo.NewResCount));
                }
                /** 9/26 追加 **/
                else if (reader is X2chAuthenticateThreadReader)
                {
                    X2chRokkaResponseState rokkaState = ((X2chAuthenticateThreadReader)reader).RokkaResponseState;
                    if (rokkaState != X2chRokkaResponseState.Success)
                    {
                        TwinDll.Output("RokkaResponseState: {0}, URL: {1}, ", rokkaState, headerInfo.Url);
                    }
                    OnStatusTextChanged(String.Format("RokkaResponseState: {0}", rokkaState));
                }
                /****/

                IsReading             = false;
                lastCompletedDateTime = DateTime.Now;

                OnComplete(new CompleteEventArgs(status));
            }
        }
        /// <summary>
        /// データを読み込む&書き込む
        /// </summary>
        private void Reading()
        {
            ResSetCollection items = new ResSetCollection(),
                             buffer = new ResSetCollection();
            int read = -1, byteParsed, totalByteCount = 0;

            while (read != 0)
            {
                if (canceled)
                {
                    return;
                }

                read = reader.Read(buffer, out byteParsed);

                // あぼーんを検知した場合、処理を中止。
                if (read == -1)
                {
                    aboneDetected = true;
                    return;
                }

                totalByteCount += byteParsed;

                items.AddRange(buffer);

                // 逐次受信の場合はビューアに書き込む
                if (!isPackageReception)
                {
                    if (canceled)
                    {
                        return;
                    }

                    Invoke(new WriteResMethodInvoker(WriteInternal), new object[] { buffer });
                }
                buffer.Clear();

                OnReceive(new ReceiveEventArgs(
                              reader.Length, reader.Position, read));

                OnStatusTextChanged(
                    String.Format("{0} 受信中 ({1}/{2})",
                                  headerInfo.Subject, reader.Position, reader.Length));
            }

            // 一括受信の場合はここで一気にフラッシュ
            if (isPackageReception)
            {
                if (canceled)
                {
                    return;
                }

                Invoke(new WriteResMethodInvoker(WriteInternal), new object[] { items });
            }

            try
            {
                // スレッドのインデックス情報を保存
                storage            = new LocalThreadStorage(Cache, headerInfo, StorageMode.Write);
                storage.BufferSize = bufferSize;
                storage.Write(items);

                headerInfo.GotByteCount += totalByteCount;
                headerInfo.GotResCount  += items.Count;
                headerInfo.NewResCount   = items.Count;
                ThreadIndexer.Write(Cache, headerInfo);
            }
            catch (Exception ex)
            {
                TwinDll.Output(ex);
            }
            finally
            {
                storage.Close();
            }

            SaveThreadListIndices();
        }