Ejemplo n.º 1
0
        private static int AboneDetecting(ResSetCollection oldItems, ResSetCollection newItems)
        {
            ResSetCollection temp = new ResSetCollection();

            for (int i = 0; i < oldItems.Count; i++)
            {
                ResSet old = oldItems[i];

                ResSet _new = newItems[i];
                temp.Add(_new);


                if (IsAboned(_new, old))
                {
                    old.IsServerAboned = true;
                    oldItems[i]        = old;
                }
            }

            X2chThreadFormatter formatter = new X2chThreadFormatter();

            string datStr = formatter.Format(temp);

            byte[] rawBytes = Encoding.GetEncoding("shift_jis").GetBytes(datStr);

            int newByteOffset = rawBytes.Length;

            // これが正しいバイトオフセットになる・・・はず。
            return(newByteOffset);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// スレッドをhtml形式で保存
        /// </summary>
        /// <param name="cache">キャッシュ情報</param>
        /// <param name="header">保存するスレッド</param>
        /// <param name="filePath">保存先ファイルパス</param>
        public static void SaveHtml(Cache cache, ThreadHeader header, string filePath, ThreadSkinBase skin)
        {
            if (filePath == null)
            {
                throw new ArgumentNullException("filePath");
            }

            if (cache == null)
            {
                throw new ArgumentNullException("cache");
            }

            if (header == null)
            {
                throw new ArgumentNullException("header");
            }

            // datの存在するパスを取得
            string fromPath = cache.GetDatPath(header);

            ThreadStorage reader = null;
            StreamWriter  writer = null;

            try {
                // 読み込みストリームを開く
                reader = new LocalThreadStorage(cache, header, StorageMode.Read);
                // 書き込みストリームを開く
                writer = new StreamWriter(filePath, false, TwinDll.DefaultEncoding);

                ResSetCollection items = new ResSetCollection();

                if (skin == null)
                {
                    skin = new HtmlSkin();
                }

                // ヘッダを書き込む
                writer.WriteLine(skin.GetHeader(header));

                // 本文を書き込む
                while (reader.Read(items) != 0)
                {
                    ;
                }
                writer.WriteLine(skin.Convert(items));

                // フッタを書き込む
                writer.WriteLine(skin.GetFooter(header));
            }
            finally {
                if (reader != null)
                {
                    reader.Close();
                }
                if (writer != null)
                {
                    writer.Close();
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// あぼーんされたレスを見つけ出し、差分取得可能なバイトオフセットを見つけて、新しいオフセットに訂正する
        /// </summary>
        /// <param name="oldItems"></param>
        /// <param name="headerInfo"></param>
        /// <returns></returns>
        public static int Test(ResSetCollection oldItems, ThreadHeader headerInfo)
        {
            ThreadHeader     h      = new X2chThreadHeader(headerInfo as X2chThreadHeader);
            X2chThreadReader reader = new X2chThreadReader();

            try
            {
                if (reader.Open(h))
                {
                    ResSetCollection newItems = new ResSetCollection();

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

                    int correctlyOffset = AboneDetecting(oldItems, newItems);

                    // 訂正された新しいオフセット
                    return(correctlyOffset);
                }

                return(-1);
            }
            finally
            {
                reader.Close();
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// レスを読み込む
        /// </summary>
        /// <param name="resSets"></param>
        /// <param name="byteParsed"></param>
        /// <returns></returns>
        public override int Read(ResSetCollection resSets, out int byteParsed)
        {
            if (resSets == null)
            {
                throw new ArgumentNullException("resSets");
            }
            if (!isOpen)
            {
                throw new InvalidOperationException("ストリームが開かれていません");
            }

            // バッファにデータを読み込む
            int byteCount = baseStream.Read(buffer, 0, buffer.Length);

            // 解析してコレクションに格納
            ICollection collect = dataParser.Parse(buffer, byteCount, out byteParsed);

            foreach (ResSet resSet in collect)
            {
                ResSet res = resSet;
                res.Index = index++;
                resSets.Add(res);

                if (res.Index == 1 && res.Tag != null)
                {
                    headerInfo.Subject = (string)res.Tag;
                }
            }

            // 実際に読み込まれたバイト数を計算
            position += byteCount;

            return(byteCount);
        }
Ejemplo n.º 5
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);
        }
        /// <summary>
        /// 指定したインデックス番号のレスのみを読み込む
        /// </summary>
        /// <param name="cache"></param>
        /// <param name="header"></param>
        /// <param name="indices"></param>
        /// <returns></returns>
        public static ResSetCollection ReadResSet(Cache cache, ThreadHeader header, int[] indices)
        {
            ResSetCollection items = new ResSetCollection();
            ResSetCollection temp  = new ResSetCollection();

            using (LocalThreadStorage sto = new LocalThreadStorage(cache, header, StorageMode.Read))
            {
                while (sto.Read(temp) != 0)
                {
                    ;
                }

                foreach (ResSet res in temp)
                {
                    foreach (int index in indices)
                    {
                        if (res.Index == index)
                        {
                            items.Add(res);
                        }
                    }
                }

                temp.Clear();
                temp = null;
            }

            return(items);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// レスを読み込む
        /// </summary>
        /// <param name="resSets"></param>
        /// <param name="byteParsed">解析されたバイト数が格納される</param>
        /// <returns>読み込まれた総byte数を返す</returns>
        public override int Read(ResSetCollection resSets, out int byteParsed)
        {
            if (resSets == null)
            {
                throw new ArgumentNullException("resSets");
            }
            if (!isOpen)
            {
                throw new InvalidOperationException("ストリームが開かれていません");
            }

            // バッファにデータを読み込む
            int readCount = baseStream.Read(buffer, 0, buffer.Length);

            // 解析してコレクションに格納
            ResSet[] items = dataParser.Parse(buffer, readCount, out byteParsed);

            foreach (ResSet resSet in items)
            {
                ResSet res = resSet;
                res.Index = index++;
                resSets.Add(res);
            }

            // 実際に読み込まれたバイト数を計算
            position += readCount;

            return(readCount);
        }
Ejemplo n.º 8
0
        public void Write(string filePath, ThreadHeader header,
                          ResSetCollection resCollection)
        {
            Stream stream = StreamCreator.CreateWriter(filePath, useGzip, true);

            header.UseGzip = useGzip;

            try {
                ThreadFormatter formatter = new X2chThreadFormatter();
                string          textData  = formatter.Format(resCollection);
                byte[]          byteData  = TwinDll.DefaultEncoding.GetBytes(textData);

                stream.Write(byteData, 0, byteData.Length);
            }
            finally {
                if (stream != null)
                {
                    stream.Close();
                }
            }

            // インデックスファイルを作成
            string indexPath = GetIndexPath(filePath);

            ThreadIndexer.Write(indexPath, header);
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
0
        private ResSetCollection GetResCollection(XmlDocument doc, XmlNode resset)
        {
            ResSetCollection collection = new ResSetCollection();

            foreach (XmlNode child in resset.SelectNodes("res"))
            {
                XmlNode num = child.Attributes.GetNamedItem("num");
                if (num == null)
                {
                    throw new ConvertException("num属性が存在しません");
                }

                // state属性は無視
                // ...

                XmlNode name = child.SelectSingleNode("name");
                if (name == null)
                {
                    throw new ConvertException("<name>要素が存在しません");
                }

                XmlNode email = child.SelectSingleNode("email");
                if (email == null)
                {
                    throw new ConvertException("<email>要素が存在しません");
                }

                XmlNode timestamp = child.SelectSingleNode("timestamp");
                if (timestamp == null)
                {
                    throw new ConvertException("<timestamp>要素が存在しません");
                }

                XmlNode message = child.SelectSingleNode("message");
                if (message == null)
                {
                    throw new ConvertException("<message>要素が存在しません");
                }

                int index;
                Int32.TryParse(num.Value, out index);

                ResSet res = new ResSet(
                    index,
                    name.InnerText,
                    email.InnerText,
                    timestamp.InnerText,
                    message.InnerText);

                collection.Add(res);
            }

            return(collection);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// レスを読み込む
        /// </summary>
        /// <param name="resSets"></param>
        /// <param name="byteParsed"></param>
        /// <returns></returns>
        public override int Read(ResSetCollection resSets, out int byteParsed)
        {
            if (resSets == null)
            {
                throw new ArgumentNullException("resSets");
            }
            if (!isOpen)
            {
                throw new InvalidOperationException("ストリームが開かれていません");
            }

            // バッファにデータを読み込む
            int byteCount = baseStream.Read(buffer, 0, buffer.Length);

            // あぼーんチェック
            if (aboneCheck && byteCount > 0)
            {
                if (buffer[0] != '\n')
                {
                    OnABone();
                    byteParsed = 0;

                    headerInfo.ETag         = String.Empty;
                    headerInfo.LastModified = DateTime.MinValue;

                    return(-1);
                }

                buffer     = RemoveHeader(buffer, byteCount, 1);
                byteCount -= 1;
                aboneCheck = false;
            }

            // 解析してコレクションに格納
            ICollection collect = dataParser.Parse(buffer, byteCount, out byteParsed);

            foreach (ResSet resSet in collect)
            {
                ResSet res = resSet;
                res.Index = index++;
                resSets.Add(res);

                if (res.Index == 1 && res.Tag != null)
                {
                    headerInfo.Subject = (string)res.Tag;
                }
            }

            // 実際に読み込まれたバイト数を計算
            position += byteCount;

            return(byteCount);
        }
Ejemplo n.º 12
0
        private XmlNode CreateThreadElement(XmlDocument doc,
                                            ThreadHeader header, ResSetCollection resCollection)
        {
            // サーバー属性を作成
            XmlAttribute serv = doc.CreateAttribute("server");

            serv.Value = header.BoardInfo.Server;

            // 板属性を作成
            XmlAttribute board = doc.CreateAttribute("board");

            board.Value = header.BoardInfo.Path;

            // key属性を作成
            XmlAttribute key = doc.CreateAttribute("key");

            key.Value = header.Key;

            // <thread></thread>要素を作成
            XmlNode thread = doc.CreateElement("thread");

            thread.Attributes.Append(serv);
            thread.Attributes.Append(board);
            thread.Attributes.Append(key);

            // タイトル要素を作成
            XmlNode title = doc.CreateElement("title");

            title.AppendChild(doc.CreateCDataSection(header.Subject));
            thread.AppendChild(title);

            // info要素を作成
            XmlAttribute lastmod = doc.CreateAttribute("last-modified");

            lastmod.Value = header.LastModified.ToString("R");             // RFC1123 パターン

            XmlAttribute size = doc.CreateAttribute("size");

            size.Value = header.GotByteCount.ToString();

            XmlNode info = doc.CreateElement("info");

            info.Attributes.Append(lastmod);
            info.Attributes.Append(size);
            thread.AppendChild(info);

            // <res-set></res-set>要素を作成
            XmlNode children = CreateResSetChildren(doc, resCollection);

            thread.AppendChild(children);

            return(thread);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// スレッドをdat形式で保存
        /// </summary>
        /// <param name="cache">キャッシュ情報</param>
        /// <param name="header">保存するスレッド</param>
        /// <param name="filePath">保存先ファイルパス</param>
        public static void SaveDat(Cache cache, ThreadHeader header, string filePath)
        {
            if (cache == null)
            {
                throw new ArgumentNullException("cache");
            }

            if (header == null)
            {
                throw new ArgumentNullException("header");
            }

            if (filePath == null)
            {
                throw new ArgumentNullException("filePath");
            }

            // datの存在するパスを取得
            string fromPath = cache.GetDatPath(header);

            ThreadStorage reader = null;
            StreamWriter  writer = null;

            ResSetCollection    items     = new ResSetCollection();
            X2chThreadFormatter formatter = new X2chThreadFormatter();

            try {
                // 読み込みストリームを開く
                reader = new LocalThreadStorage(cache, header, StorageMode.Read);
                // 書き込みストリームを開く
                writer = new StreamWriter(filePath, false, Encoding.GetEncoding("Shift_Jis"));

                // すべて読み込む
                while (reader.Read(items) != 0)
                {
                    ;
                }
                writer.Write(formatter.Format(items));
            }
            finally {
                if (reader != null)
                {
                    reader.Close();
                }
                if (writer != null)
                {
                    writer.Close();
                }
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// レスを読み込む
        /// </summary>
        /// <param name="resSets"></param>
        /// <param name="byteParsed"></param>
        /// <returns></returns>
        public override int Read(ResSetCollection resSets, out int byteParsed)
        {
            if (resSets == null)
            {
                throw new ArgumentNullException("resSets");
            }
            if (!isOpen)
            {
                throw new InvalidOperationException("ストリームが開かれていません");
            }

            // バッファにデータを読み込む
            int byteCount = baseStream.Read(buffer, 0, buffer.Length);

            // 解析してコレクションに格納
            ICollection collect = dataParser.Parse(buffer, byteCount, out byteParsed);

            foreach (ResSet resSet in collect)
            {
                ResSet res = resSet;
                if (res.Index <= 0)
                {
                    res.Index = index++;
                }

                // JBBSあぼーん対策
                //int aboneCount = (res.Index - prevIndex) - 1; // 直前のレス番号と比較し、飛んでいるレス数を求める
                //if (prevIndex != -1 && aboneCount > 1)
                //{
                //    // まちBBS、JBBSではレスをdat自体から削除するあぼーんがあるため、
                //    // 解析の際にレス番号が飛んでしまいレス番号が狂ってしまう。
                //    // なのでダミーのあぼーんレスを挿入しておく
                //    for (int i = 0; i < aboneCount; i++)
                //        resSets.Add(ResSet.ABoneResSet);
                //}
                prevIndex = res.Index;

                resSets.Add(res);

                if (res.Index == 1 && res.Tag != null)
                {
                    headerInfo.Subject = (string)res.Tag;
                }
            }

            // 実際に読み込まれたバイト数を計算
            position += byteCount;

            return(byteCount);
        }
Ejemplo n.º 15
0
        private XmlNode CreateResSetChildren(XmlDocument doc, ResSetCollection resCollection)
        {
            // レスコレクション要素を作成
            XmlNode children = doc.CreateElement("res-set");

            foreach (ResSet res in resCollection)
            {
                // レス番号を表す、num属性を作成
                XmlAttribute num = doc.CreateAttribute("num");
                num.Value = res.Index.ToString();

                // レスの状態を表す、state属性を作成
                XmlAttribute state = doc.CreateAttribute("state");
                state.Value = "normal";

                // レス要素を作成
                XmlNode child = doc.CreateElement("res");
                child.Attributes.Append(num);
                child.Attributes.Append(state);

                // 名前
                XmlNode name = doc.CreateElement("name");
                name.AppendChild(doc.CreateCDataSection(res.Name));

                // Email
                XmlNode email = doc.CreateElement("email");
                email.AppendChild(doc.CreateCDataSection(res.Email));

                // 日付
                XmlNode timestamp = doc.CreateElement("timestamp");
                timestamp.AppendChild(doc.CreateCDataSection(res.DateString));

                // メッセージ
                XmlNode message = doc.CreateElement("message");
                message.AppendChild(doc.CreateCDataSection(res.Body));

                child.AppendChild(name);
                child.AppendChild(email);
                child.AppendChild(timestamp);
                child.AppendChild(message);
                children.AppendChild(child);
            }

            return(children);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// resCollectionを書式化して文字列に変換
        /// </summary>
        /// <param name="resCollection"></param>
        /// <returns></returns>
        public override string Format(ResSetCollection resCollection)
        {
            if (resCollection == null)
            {
                throw new ArgumentNullException("resCollection");
            }

            StringBuilder sb =
                new StringBuilder(512 * resCollection.Count);

            foreach (ResSet res in resCollection)
            {
                string result = Format(res);
                sb.Append(result);
            }

            return(sb.ToString());
        }
Ejemplo n.º 17
0
        /// <summary>
        /// monalog形式のスレッドをキャッシュとして保存
        /// </summary>
        /// <param name="cache"></param>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static ThreadHeader OpenMonalog(Cache cache, string filePath)
        {
            ResSetCollection resItems = null;
            ThreadHeader     header   = null;

            MonalogConverter conv = new MonalogConverter();

            conv.Read(filePath, out header, out resItems);

            using (LocalThreadStorage storage =
                       new LocalThreadStorage(cache, header, StorageMode.Write))
            {
                storage.Write(resItems);
            }

            ThreadIndexer.Write(cache, header);

            return(header);
        }
Ejemplo n.º 18
0
        public void Read(string filePath, out ThreadHeader header,
                         out ResSetCollection resCollection)
        {
            // .idxファイルへのパスを求める
            string indexPath = GetIndexPath(filePath);

            if (!File.Exists(indexPath))
            {
                throw new FileNotFoundException("インデックスファイルが存在しません");
            }

            // インデックス情報を読み込む
            header = ThreadIndexer.Read(indexPath);
            if (header == null)
            {
                throw new ConvertException("インデックスファイルの読み込みに失敗しました");
            }

            resCollection = ReadFile(filePath, header.UseGzip);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// スレッドをmonalog形式で保存
        /// </summary>
        /// <param name="cache">キャッシュ情報</param>
        /// <param name="header">保存するスレッド</param>
        /// <param name="filePath">保存先ファイルパス</param>
        public static void SaveMonalog(Cache cache, ThreadHeader header, string filePath)
        {
            if (filePath == null)
            {
                throw new ArgumentNullException("filePath");
            }

            if (cache == null)
            {
                throw new ArgumentNullException("cache");
            }

            if (header == null)
            {
                throw new ArgumentNullException("header");
            }

            // datの存在するパスを取得
            string           fromPath = cache.GetDatPath(header);
            MonalogConverter conv     = new MonalogConverter();

            ThreadStorage    reader = null;
            ResSetCollection items  = new ResSetCollection();

            try {
                reader = new LocalThreadStorage(cache, header, StorageMode.Read);
                while (reader.Read(items) != 0)
                {
                    ;
                }
                conv.Write(filePath, header, items);
            }
            finally {
                if (reader != null)
                {
                    reader.Close();
                }
            }
        }
Ejemplo n.º 20
0
        private ResSetCollection ReadFile(string filePath, bool gzip)
        {
            ResSetCollection resCollection = new ResSetCollection();
            Stream           stream        = StreamCreator.CreateReader(filePath, gzip);
            ThreadParser     dataParser    = new X2chThreadParser();

            try {
                byte[] buffer = new byte[10240];
                int    readCount = 0, index = 1;

                do
                {
                    // バッファにデータを読み込む
                    readCount = stream.Read(buffer, 0, buffer.Length);
                    int parsed;

                    // 解析してコレクションに格納
                    ICollection collect = dataParser.Parse(buffer, readCount, out parsed);

                    foreach (ResSet resSet in collect)
                    {
                        ResSet res = resSet;
                        res.Index = index++;

                        resCollection.Add(res);
                    }
                } while (readCount != 0);
            }
            finally {
                if (stream != null)
                {
                    stream.Close();
                }
            }

            return(resCollection);
        }
Ejemplo n.º 21
0
        /// <summary>
        /// resCollectionをファイルに書き込む
        /// </summary>
        /// <param name="resCollection">スレッドの内容が格納されたResSetCollectionクラス</param>
        /// <returns>実際に書き込まれたバイト数</returns>
        public override int Write(ResSetCollection resCollection)
        {
            if (!CanWrite)
            {
                throw new NotSupportedException("書き込み用に開かれていません");
            }
            if (resCollection == null)
            {
                throw new ArgumentNullException("resCollection");
            }
            if (!isOpen)
            {
                throw new InvalidOperationException("ストリームが開かれていません");
            }

            string textData = formatter.Format(resCollection);

            byte[] byteData = encoding.GetBytes(textData);

            baseStream.Write(byteData, 0, byteData.Length);
            position += byteData.Length;

            return(byteData.Length);
        }
Ejemplo n.º 22
0
        public void Write(string filePath, ThreadHeader header,
                          ResSetCollection resCollection)
        {
            XmlDocument doc = new XmlDocument();

            // バージョン属性を作成
            XmlAttribute version = doc.CreateAttribute("version");

            version.Value = "1.0";

            // ルートを作成
            XmlNode root = doc.CreateElement("monalog", "http://www.monazilla.org/Monalog/1.0");

            root.Attributes.Append(version);

            // スレッド要素を作成
            XmlNode thread = CreateThreadElement(doc, header, resCollection);

            root.AppendChild(thread);
            doc.AppendChild(root);

            // エンコーダをShift_Jisで保存
            XmlTextWriter writer = null;

            try {
                writer            = new XmlTextWriter(filePath, Encoding.GetEncoding("Shift_Jis"));
                writer.Formatting = Formatting.Indented;
                doc.Save(writer);
            }
            finally {
                if (writer != null)
                {
                    writer.Close();
                }
            }
        }
Ejemplo n.º 23
0
        /// <summary>
        /// 巡回開始
        /// </summary>
        public override void Patrol()
        {
            try {
                ThreadReaderRelay reader = null;
                BbsType           bbs    = BbsType.None;

                foreach (ThreadHeader header in Items)
                {
                    if (header.Pastlog || header.IsLimitOverThread)
                    {
                        continue;
                    }

                    ResSetCollection temp  = new ResSetCollection();
                    BoardInfo        board = header.BoardInfo;

                    // リーダーを作成
                    if (bbs != board.Bbs)
                    {
                        reader = null;
                        reader = new ThreadReaderRelay(Cache, TypeCreator.CreateThreadReader(board.Bbs));
                        bbs    = board.Bbs;
                    }

                    // 取得前の新着を保存
                    int newResCount = header.NewResCount;

                    try {
                        OnStatusTextChanged(header.Subject + " の巡回中...");

                        ClientBase.Connect.WaitOne();

                        PatrolEventArgs e = new PatrolEventArgs(header);
                        OnPatroling(e);

                        if (!e.Cancel)
                        {
                            // 新着のみを読み取る
                            reader.ReadCache = false;

                            if (reader.Open(header))
                            {
                                while (reader.Read(temp) != 0)
                                {
                                    ;
                                }
                            }
                        }
                    }
                    catch {}
                    finally {
                        if (reader != null)
                        {
                            reader.Close();
                        }
                        ClientBase.Connect.Set();
                    }

                    if (header.NewResCount > 0)
                    {
                        // 前回の新着を足して、インデックスを保存
                        header.NewResCount += newResCount;
                        OnUpdated(new PatrolEventArgs(header));
                    }
                }
            }
            finally {
                OnStatusTextChanged("巡回を完了しました");
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        /// ディスクにキャッシュしながらスレッド一覧を読み込む
        /// </summary>
        /// <param name="resSets"></param>
        /// <returns></returns>
        public override int Read(ResSetCollection resSets)
        {
            int byteParsed;

            return(Read(resSets, out byteParsed));
        }
Ejemplo n.º 25
0
 /// <summary>
 /// resCollectionをファイルに書き込む
 /// </summary>
 public abstract int Write(ResSetCollection resCollection);
Ejemplo n.º 26
0
 /// <summary>
 /// 指定したレスコレクションを書式化して文字列に変換
 /// </summary>
 public abstract string Format(ResSetCollection resCollection);
Ejemplo n.º 27
0
 /// <summary>
 /// データを解析してresCollectionに格納
 /// </summary>
 /// <returns>読み込まれたバイト数。末端の場合は 0。あぼーんを検知した場合は -1 を返す</returns>
 public abstract int Read(ResSetCollection resCollection);
Ejemplo n.º 28
0
 /// <summary>
 /// データを解析してresCollectionに格納
 /// </summary>
 /// <returns>読み込まれたバイト数。末端の場合は 0。あぼーんを検知した場合は -1 を返す</returns>
 public abstract int Read(ResSetCollection resCollection, out int byteParsed);
Ejemplo n.º 29
0
        public void Read(string filePath, out ThreadHeader header,
                         out ResSetCollection resCollection)
        {
            XmlDocument doc = new XmlDocument();

            doc.Load(filePath);

            header        = TypeCreator.CreateThreadHeader(BbsType.X2ch);
            resCollection = new ResSetCollection();

            // ルート要素を取得
            XmlNode root = doc.DocumentElement;

            // <thread>要素の処理
            XmlNode thread = root.SelectSingleNode("thread");

            if (thread == null)
            {
                throw new ConvertException("<thread>要素が存在しません");
            }

            XmlNode serv = thread.Attributes.GetNamedItem("server");

            if (serv == null)
            {
                throw new ConvertException("server属性が存在しません");
            }

            XmlNode board = thread.Attributes.GetNamedItem("board");

            if (board == null)
            {
                throw new ConvertException("board属性が存在しません");
            }

            XmlNode key = thread.Attributes.GetNamedItem("key");

            if (key == null)
            {
                throw new ConvertException("key属性が存在しません");
            }

            // スレッドタイトルを取得
            XmlNode title = thread.SelectSingleNode("title");

            if (title == null)
            {
                throw new ConvertException("<title>要素が存在しません");
            }

            // <info>要素の処理
            XmlNode info = thread.SelectSingleNode("info");

            if (info == null)
            {
                throw new ConvertException("<info>要素が存在しません");
            }

            XmlNode lastmod = info.Attributes.GetNamedItem("last-modified");

            if (lastmod == null)
            {
                throw new ConvertException("last-modified属性が存在しません");
            }

            XmlNode size = info.Attributes.GetNamedItem("size");

            if (size == null)
            {
                throw new ConvertException("size属性が存在しません");
            }

            // スレッドの情報を設定
            header.Key = key.Value;
            header.BoardInfo.Server = serv.Value;
            header.BoardInfo.Path   = board.Value;
            header.Subject          = title.InnerText;
            header.LastModified     = DateTime.Parse(lastmod.Value);

            int gotByteCount;

            if (Int32.TryParse(size.Value, out gotByteCount))
            {
                header.GotByteCount = gotByteCount;
            }

            // <res-set>要素の処理
            XmlNode children = thread.SelectSingleNode("res-set");

            if (children == null)
            {
                throw new ConvertException("<res-set>要素が存在しません");
            }

            resCollection      = GetResCollection(doc, children);
            header.GotResCount = resCollection.Count;
        }
Ejemplo n.º 30
0
        /// <summary>
        /// レスを読み込む
        /// </summary>
        /// <param name="resSets"></param>
        /// <returns>読み込まれた総byte数を返す</returns>
        public override int Read(ResSetCollection resSets)
        {
            int temp;

            return(Read(resSets, out temp));
        }