Ejemplo n.º 1
0
        /// <summary>
        /// ディスクにキャッシュしながらレスを読み込む
        /// </summary>
        /// <param name="resSets"></param>
        /// <param name="byteParsed">解析された総バイト数が格納される</param>
        /// <returns>読み込まれたバイト数を返す</returns>
        public override int Read(ResSetCollection resSets, out int byteParsed)
        {
            if (!isOpen)
            {
                throw new InvalidOperationException("ストリームが開かれていません");
            }

            byteParsed = 0;

            ResSetCollection tempCollection = new ResSetCollection();
            int byteCount  = 0;
            int writeCount = 0;

            // キャッシュを読む
            if (storage.IsOpen && storage.CanRead)
            {
                byteCount            = storage.Read(tempCollection, out byteParsed);
                tempCollection.IsNew = false;

                // データがなければキャッシュストリームは閉じる
                if (byteCount == 0)
                {
                    storage.Close();
                    OnCacheComplete(this, new EventArgs());
                    OpenBaseStream(headerInfo);
                }
            }

            // キャッシュがなければ実際に基本ストリームから読み込む
            if (baseReader.IsOpen)
            {
                byteCount            = baseReader.Read(tempCollection, out byteParsed);
                tempCollection.IsNew = true;

                // あぼーんがあった場合、処理を中止。
                if (byteCount == -1)
                {
                    return(-1);
                }

                try
                {
                    if (storage.IsOpen)
                    {
                        writeCount = storage.Write(tempCollection);
                    }
                }
                finally
                {
                    headerInfo.GotByteCount += byteParsed;
                    headerInfo.GotResCount  += tempCollection.Count;
                    headerInfo.NewResCount  += tempCollection.Count;
                }
            }

            resSets.AddRange(tempCollection);
            position += byteCount;

            return(byteCount);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 単独のdatファイル開き、を既得キャッシュとして保存
        /// </summary>
        /// <param name="cache"></param>
        /// <param name="target">単独のdatと関連づける板</param>
        /// <param name="filePath">datファイルのファイルパス</param>
        /// <param name="datNumber">dat番号</param>
        /// <param name="gzip">datファイルがgzip圧縮されていればtrue、そうでなければfalseを指定する</param>
        /// <returns>キャッシュされたスレッドのヘッダ情報を返す</returns>
        public static ThreadHeader OpenDat(Cache cache, BoardInfo target,
                                           string filePath, string datNumber, bool gzip)
        {
            // ヘッダー情報を作成
            ThreadHeader header = TypeCreator.CreateThreadHeader(target.Bbs);

            header.BoardInfo = target;
            header.Key       = datNumber;
            header.UseGzip   = gzip;
            header.Subject   = String.Empty;

            ResSetCollection resItems = new ResSetCollection();

            using (Stream stream = StreamCreator.CreateReader(filePath, gzip))
            {
                X2chThreadParser parser = new X2chThreadParser();

                byte[] buffer = new byte[4096];
                bool   first = true;
                int    offset = 0, read, parsed;

                do
                {
                    // バッファに読み込む
                    read    = stream.Read(buffer, 0, buffer.Length);
                    offset += read;

                    // 解析しResSet構造体の配列を作成
                    ResSet[] array = parser.Parse(buffer, read, out parsed);
                    resItems.AddRange(array);

                    // スレタイを取得しておく
                    if (first && array.Length > 0)
                    {
                        header.Subject = array[0].Tag as String;
                        first          = false;
                    }
                } while (read != 0);

                // 既得バイト数とレス数を設定
                header.GotByteCount = offset;
                header.GotResCount  = resItems.Count;
            }

            // datファイルの最終更新日を取得
            header.LastModified = File.GetLastWriteTime(filePath);

            // 読み込んだレスをキャッシュとして保存
            using (LocalThreadStorage storage =
                       new LocalThreadStorage(cache, header, StorageMode.Write))
            {
                storage.Write(resItems);
            }

            // インデックス情報を生成
            ThreadIndexer.Write(cache, header);

            return(header);
        }