/* * VsqBPList.cs * Copyright (c) 2008-2009 kbinani * * This file is part of Boare.Lib.Vsq. * * Boare.Lib.Vsq is free software; you can redistribute it and/or * modify it under the terms of the BSD License. * * Boare.Lib.Vsq is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ using System; using System.Collections.Generic; using System.Text; using System.IO; namespace Boare.Lib.Vsq { /// /// BPListのデータ部分を取り扱うためのクラス。 /// [Serializable] public class VsqBPList : ICloneable { private SortedList m_list = new SortedList(); public int Default = 0; public int Maximum = 127; public int Minimum = 0; /// /// このリストに設定されたidの最大値.次にデータ点が追加されたときは,個の値+1がidとして利用される.削除された場合でも減らない /// private int m_max_id = 0; private class KeyClockIterator : Iterator { private SortedList m_list; private int m_pos; public KeyClockIterator( SortedList list ) { m_list = list; m_pos = -1; } public bool hasNext() { if ( m_pos + 1 < m_list.Keys.Count ) { return true; } else { return false; } } public object next() { m_pos++; return m_list.Keys[m_pos]; } public void remove() { if ( 0 <= m_pos && m_pos < m_list.Keys.Count ) { int key = m_list.Keys[m_pos]; m_list.Remove( key ); } } } public VsqBPList() : this( 0, 0, 64 ) { } /// /// XMLシリアライズ用 /// public string Data { get { string ret = ""; int count = -1; foreach ( int key in m_list.Keys ) { count++; ret += (count == 0 ? "" : "," ) + key + "=" + m_list[key].value; } return ret; } set { m_list.Clear(); m_max_id = 0; string[] spl = value.Split( ',' ); for ( int i = 0; i < spl.Length; i++ ) { string[] spl2 = spl[i].Split( '=' ); if ( spl2.Length < 2 ) { continue; } try { m_list.Add( int.Parse( spl2[0] ), new VsqBPPair( int.Parse( spl2[1] ), m_max_id + 1 ) ); m_max_id++; } catch ( Exception ex ) { #if DEBUG Console.WriteLine( " ex=" + ex ); Console.WriteLine( " i=" + i + "; spl2[0]=" + spl2[0] + "; spl2[1]=" + spl2[1] ); #endif } } } } /// /// このVsqBPListの同一コピーを作成します /// /// public object Clone() { VsqBPList res = new VsqBPList( Default, Minimum, Maximum ); foreach ( int key in m_list.Keys ) { res.m_list.Add( key, m_list[key] ); } return res; } /// /// コンストラクタ。デフォルト値はココで指定する。 /// /// public VsqBPList( int default_value, int minimum, int maximum ) { Default = default_value; Maximum = maximum; Minimum = minimum; m_max_id = 0; } /// /// このリストに設定された最大値を取得します。 /// public int getMaximum() { return Maximum; } /// /// このリストに設定された最小値を取得します /// public int getMinimum() { return Minimum; } public Iterator keyClockIterator() { return new KeyClockIterator( m_list ); } public void remove( int clock ) { if ( m_list.ContainsKey( clock ) ) { m_list.Remove( clock ); } } public bool isContainsKey( int clock ) { return m_list.ContainsKey( clock ); } public int getCount() { return m_list.Count; } public int[] getKeys() { List t = new List(); foreach( int key in m_list.Keys ){ t.Add( key ); } return t.ToArray(); } public void clear() { m_list.Clear(); } /// /// 新しいデータ点を追加します。 /// /// /// public void add( int clock, int value ) { lock ( m_list ) { if ( m_list.ContainsKey( clock ) ) { VsqBPPair v = m_list[clock]; v.value = value; m_list[clock] = v; } else { VsqBPPair v = new VsqBPPair( value, m_max_id + 1 ); m_max_id++; m_list.Add( clock, v ); } } } public int getElement( int index ) { return m_list[m_list.Keys[index]].value; } public int getKeyClock( int index ) { return m_list.Keys[index]; } public int findValueFromID( int id ) { int c = m_list.Keys.Count; foreach ( int key in m_list.Keys ) { if ( m_list[key].id == id ) { return m_list[key].value; } } return Default; } public void setValueForID( int id, int value ) { int c = m_list.Keys.Count; foreach ( int key in m_list.Keys ) { if ( m_list[key].id == id ) { VsqBPPair v = m_list[key]; v.value = value; m_list[key] = v; break; } } } public int getValue( int clock, ref int index ) { if ( m_list.Count == 0 ) { return Default; } else { if ( index < 0 ) { index = 0; } for ( int i = index ; i < m_list.Keys.Count; i++ ) { int keyclock = m_list.Keys[i]; if ( clock < keyclock ) { if ( i > 0 ) { index = i; return m_list[m_list.Keys[i - 1]].value; } else { index = i; return Default; } } } index = m_list.Keys.Count - 1; return m_list[m_list.Keys[m_list.Keys.Count - 1]].value; } } public int getValue( int clock ) { if ( m_list.Count == 0 ) { return Default; } else { for ( int i = 0; i < m_list.Keys.Count; i++ ) { int keyclock = m_list.Keys[i]; if ( clock < keyclock ) { if ( i > 0 ) { return m_list[m_list.Keys[i - 1]].value; } else { return Default; } } } return m_list[m_list.Keys[m_list.Keys.Count - 1]].value; } } /// /// このBPListのデフォルト値を取得します /// public int getDefault() { return Default; } /// /// このBPListの内容をテキストファイルに書き出します /// /// public void print( StreamWriter writer ) { bool first = true; foreach ( int key in m_list.Keys ) { int val = m_list[key].value; if ( first ) { writer.WriteLine( key + "=" + val ); first = false; } else { writer.WriteLine( key + "=" + val ); } } } /// /// このBPListの内容をテキストファイルに書き出します /// /// public void print( TextMemoryStream writer, int start, string header ) { bool first = true; foreach ( int key in m_list.Keys ) { if ( start <= key ) { if ( first ) { writer.writeLine( header ); first = false; } int val = m_list[key].value; writer.writeLine( key + "=" + val ); } } } /// /// テキストファイルからデータ点を読込み、現在のリストに追加します /// /// /// public string appendFromText( TextMemoryStream reader ) { string last_line = reader.readLine(); while ( !last_line.StartsWith( "[" ) ) { string[] spl = last_line.Split( new char[] { '=' } ); int i1 = int.Parse( spl[0] ); int i2 = int.Parse( spl[1] ); VsqBPPair v = new VsqBPPair( i2, m_max_id + 1 ); m_max_id++; m_list.Add( i1, v ); if ( reader.peek() < 0 ) { break; } else { last_line = reader.readLine(); } } return last_line; } } }