예제 #1
0
        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>
        /// textを解析
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        protected virtual string Parse(string text)
        {
            if (text == null)
            {
                throw new ArgumentNullException("text");
            }

            try
            {
                // 2ch_Xを検索する正規表現
                Regex regex2chx = new Regex(@"<!--\s*?(2ch_X:\w+)\s*?-->",
                                            RegexOptions.IgnoreCase | RegexOptions.Singleline);

                // タイトルを検索する正規表現
                Regex regext = new Regex(@"<title>(?<t>.+?)</title>",
                                         RegexOptions.IgnoreCase | RegexOptions.Singleline);

                // 本文を検索する正規表現
                Regex regexb = new Regex(@"(<body.*?>(?<b>.+)</body>)|(</head>(?<b>.+)</body>)",
                                         RegexOptions.IgnoreCase | RegexOptions.Singleline);

                // タイトルを取得
                Match match0 = regext.Match(text);
                if (match0.Success)
                {
                    title    = match0.Groups["t"].Value;
                    response = TitleToStatus(title);
                }

                // 2ch_Xを取得
                Match match1 = regex2chx.Match(text);
                if (match1.Success)
                {
                    response = x2chXToStatus(match1.Value);
                }

                // 本文を取得(タグを取り除く)
                Match match2 = regexb.Match(text);
                if (match2.Success)
                {
                    string result = match2.Groups["b"].Value;

                    if (result.IndexOf("書き込み確認") != -1)
                    {
                        response = PostResponse.Cookie;
                    }

                    else if (result.IndexOf("クッキーをオンにしてちょ") != -1)
                    {
                        response = PostResponse.Cookie;
                    }

                    else if (result.IndexOf("ERROR - 593") != -1)
                    {
                        response = PostResponse.Samba;

                        Match m = Regex.Match(result, "593 (?<cnt>\\d+) sec");
                        if (m.Success)
                        {
                            Int32.TryParse(m.Groups["cnt"].Value, out sambaCount);
                        }
                    }

                    result    = Regex.Replace(result, "<br>", "\r\n", RegexOptions.IgnoreCase);
                    result    = Regex.Replace(result, "<hr>", "\r\n", RegexOptions.IgnoreCase);
                    result    = Regex.Replace(result, "</?[^>]+>", "");
                    result    = Regex.Replace(result, "\t", "");
                    result    = Regex.Replace(result, "(\r\n|\r|\n){2,}", "\r\n", RegexOptions.Singleline);
                    plainText = result;


                    if (response == PostResponse.Cookie)
                    {
                        MatchCollection matches = Regex.Matches(text, "<input type=hidden name=\"?(\\w+?)\"? value=\"?(\\w+?)\"?>", RegexOptions.IgnoreCase);

                        foreach (Match m in matches)
                        {
                            string name  = m.Groups[1].Value;
                            string value = m.Groups[2].Value;

                            hiddenParamsDic.Add(name, value);
#if DEBUG
                            Console.WriteLine("{0}={1}", name, value);
#endif
                        }
                    }
                }

                if (plainText == String.Empty)
                {
                    plainText = htmlText;
                }
            }
            catch (Exception ex)
            {
                TwinDll.Output(ex.ToString());
            }

            return(plainText);
        }
예제 #3
0
        /// <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();
        }